From 2ebd2cbac7ffa53492a75f655b374a4f37c73115 Mon Sep 17 00:00:00 2001 From: TJ Egan Date: Thu, 19 Oct 2023 10:29:42 -0400 Subject: [PATCH] refactor(React): initialize default props with serially stable values (#14720) * refactor(React): initialize default props with serially stable values * refactor(React): fix more components * test(React): update snapshots * refactor(React): remove mroe default props * fix(React): adjust tests to use required props * chore(Storybook): fix console warnings by adding required props * refactor(React): remove more default props * chore(test): update snapshots * refactor(React): remove more default props, some required props * refactor(React): initialize default props with serially stable values * refactor(React): fix more components * test(React): update snapshots * refactor(React): remove mroe default props * fix(React): adjust tests to use required props * chore(Storybook): fix console warnings by adding required props * refactor(React): remove more default props * chore(test): update snapshots * refactor(React): remove more default props, some required props * refactor(React): remove more defaultProps from components * chore(snapshots): update snapshots * refactor(DataTable): remove default props * chore(test): update snapshots * fix(React): clean up a few more components * fix(Slider): remove defaultProps from Slider --- .../src/builders/react/components/Icon.js | 21 +- .../__snapshots__/PublicAPI-test.js.snap | 524 ++---------------- .../src/components/CustomDataTable.js | 18 +- .../Accordion/Accordion.Skeleton.tsx | 6 - .../src/components/Checkbox/Checkbox.tsx | 10 +- .../src/components/CodeSnippet/CodeSnippet.js | 18 +- .../src/components/ComboBox/ComboBox.tsx | 28 +- .../ComposedModal/ComposedModal.tsx | 5 +- .../components/ComposedModal/ModalFooter.tsx | 14 +- .../components/ComposedModal/ModalHeader.tsx | 6 +- .../ContentSwitcher.stories.js | 4 +- .../ContentSwitcher/ContentSwitcher.tsx | 17 +- packages/react/src/components/Copy/Copy.js | 13 +- .../src/components/CopyButton/CopyButton.js | 17 +- .../src/components/DataTable/DataTable.tsx | 36 +- .../react/src/components/DataTable/Table.tsx | 5 - .../components/DataTable/TableBatchAction.js | 17 +- .../DataTable/TableBatchActions.tsx | 4 - .../src/components/DataTable/TableBody.tsx | 9 +- .../src/components/DataTable/TableHeader.tsx | 12 +- .../components/DataTable/TableSelectAll.tsx | 6 +- .../src/components/DataTable/TableToolbar.tsx | 40 +- .../components/DataTable/TableToolbarMenu.tsx | 9 +- .../DataTable/TableToolbarSearch.tsx | 20 +- .../DataTable/__tests__/DataTable-test.js | 6 +- .../__tests__/TableToolbarMenu-test.js | 2 +- .../stories/DataTable-toolbar.stories.js | 10 +- .../src/components/DataTable/tools/sorting.js | 4 +- .../src/components/DatePicker/DatePicker.tsx | 8 +- .../src/components/Dropdown/Dropdown-test.js | 5 +- .../src/components/Dropdown/Dropdown.mdx | 14 + .../src/components/Dropdown/Dropdown.tsx | 22 +- .../FileUploader/FileUploader.stories.js | 1 + .../components/FileUploader/FileUploader.tsx | 26 +- .../FileUploader/FileUploaderButton.tsx | 5 +- .../FileUploaderDropContainer.tsx | 11 +- .../FileUploader/FileUploaderItem.tsx | 9 +- .../src/components/FileUploader/Filename.tsx | 21 +- .../__tests__/FileUploader-test.js | 1 + .../FileUploaderDropContainer-test.js | 35 +- .../__tests__/FluidDropdown-test.js | 5 +- .../src/components/FluidSearch/FluidSearch.js | 7 - .../components/FormGroup/FormGroup.stories.js | 2 +- .../src/components/FormGroup/FormGroup.tsx | 12 +- .../react/src/components/ListBox/ListBox.tsx | 13 +- .../components/ListBox/ListBoxMenuIcon.tsx | 6 +- .../components/ListBox/ListBoxMenuItem.tsx | 17 +- .../components/ListBox/ListBoxSelection.tsx | 32 +- .../ListBox/next/ListBoxSelection.js | 31 +- .../components/ListBox/next/ListBoxTrigger.js | 14 +- packages/react/src/components/Modal/Modal.js | 36 +- .../components/ModalWrapper/ModalWrapper.js | 35 +- .../MultiSelect/FilterableMultiSelect.js | 39 +- .../MultiSelect/MultiSelect.stories.js | 2 +- .../components/MultiSelect/MultiSelect.tsx | 55 +- .../MultiSelect/MultiSelectPropTypes.js | 4 +- .../components/MultiSelect/tools/sorting.js | 4 +- .../components/Notification/Notification.tsx | 85 ++- .../stories/InlineNotification.stories.js | 2 - .../components/OverflowMenu/OverflowMenu.js | 55 +- .../Pagination/experimental/PageSelector.js | 13 +- .../Pagination/experimental/Pagination.js | 51 +- .../ProgressIndicator/ProgressIndicator.js | 6 +- .../src/components/RadioTile/RadioTile.js | 10 +- .../src/components/Search/Search.Skeleton.tsx | 10 +- .../react/src/components/Select/Select.tsx | 21 +- .../components/SelectItem/SelectItem-test.js | 20 +- .../src/components/SelectItem/SelectItem.tsx | 15 +- .../SelectItemGroup/SelectItemGroup.tsx | 6 +- .../components/SkeletonText/SkeletonText.tsx | 7 - .../react/src/components/Slider/Slider.tsx | 48 +- .../react/src/components/Switch/Switch.tsx | 11 +- .../src/components/TextArea/TextArea.tsx | 47 +- .../TextInput/ControlledPasswordInput.tsx | 32 +- .../src/components/TileGroup/TileGroup.js | 8 +- .../react/src/components/UIShell/Content.js | 6 +- .../src/components/UIShell/SideNavFooter.js | 8 +- .../src/components/UIShell/SideNavIcon.tsx | 8 +- packages/react/src/internal/FloatingMenu.js | 10 +- packages/react/src/internal/Selection.js | 4 - packages/react/src/internal/noopFn.ts | 8 + 81 files changed, 549 insertions(+), 1295 deletions(-) create mode 100644 packages/react/src/internal/noopFn.ts diff --git a/packages/icon-build-helpers/src/builders/react/components/Icon.js b/packages/icon-build-helpers/src/builders/react/components/Icon.js index 9f2e6320615c..87c020fe564a 100644 --- a/packages/icon-build-helpers/src/builders/react/components/Icon.js +++ b/packages/icon-build-helpers/src/builders/react/components/Icon.js @@ -9,7 +9,14 @@ import PropTypes from 'prop-types'; import React from 'react'; const Icon = React.forwardRef(function Icon( - { className, children, tabIndex, ...rest }, + { + className, + children, + tabIndex, + xmlns = 'http://www.w3.org/2000/svg', + preserveAspectRatio = 'xMidYMid meet', + ...rest + }, ref ) { const { tabindex, ...props } = getAttributes({ @@ -29,6 +36,14 @@ const Icon = React.forwardRef(function Icon( props.ref = ref; } + if (xmlns) { + props.xmlns = xmlns; + } + + if (preserveAspectRatio) { + props.preserveAspectRatio = preserveAspectRatio; + } + return React.createElement('svg', props, children); }); @@ -46,9 +61,5 @@ Icon.propTypes = { width: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), xmlns: PropTypes.string, }; -Icon.defaultProps = { - xmlns: 'http://www.w3.org/2000/svg', - preserveAspectRatio: 'xMidYMid meet', -}; export default Icon; diff --git a/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap b/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap index b6f8fd33a77b..1b2a21b0d253 100644 --- a/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap +++ b/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap @@ -67,11 +67,6 @@ Map { }, }, "AccordionSkeleton" => Object { - "defaultProps": Object { - "align": "end", - "count": 4, - "open": true, - }, "propTypes": Object { "align": Object { "args": Array [ @@ -97,15 +92,6 @@ Map { }, }, "ActionableNotification" => Object { - "defaultProps": Object { - "closeOnEscape": true, - "hasFocus": true, - "hideCloseButton": false, - "inline": false, - "kind": "error", - "onCloseButtonClick": [Function], - "role": "alertdialog", - }, "propTypes": Object { "actionButtonLabel": Object { "type": "string", @@ -143,7 +129,6 @@ Map { "warning-alt", ], ], - "isRequired": true, "type": "oneOf", }, "lowContrast": Object { @@ -466,10 +451,6 @@ Map { }, "Checkbox" => Object { "$$typeof": Symbol(react.forward_ref), - "defaultProps": Object { - "indeterminate": false, - "onChange": [Function], - }, "propTypes": Object { "checked": Object { "type": "bool", @@ -622,13 +603,6 @@ Map { "render": [Function], }, "CodeSnippet" => Object { - "defaultProps": Object { - "aria-label": "Copy to clipboard", - "showLessText": "Show less", - "showMoreText": "Show more", - "type": "single", - "wrapText": false, - }, "propTypes": Object { "align": Object { "args": Array [ @@ -1079,15 +1053,6 @@ Map { }, "ComboBox" => Object { "$$typeof": Symbol(react.forward_ref), - "defaultProps": Object { - "aria-label": "Choose an item", - "direction": "bottom", - "disabled": false, - "itemToElement": null, - "itemToString": [Function], - "shouldFilterItem": [Function], - "type": "default", - }, "propTypes": Object { "aria-label": Object { "type": "string", @@ -1336,15 +1301,6 @@ Map { "translateWithId": Object { "type": "func", }, - "type": Object { - "args": Array [ - Array [ - "default", - "inline", - ], - ], - "type": "oneOf", - }, "warn": Object { "type": "bool", }, @@ -1407,9 +1363,6 @@ Map { }, "ComposedModal" => Object { "$$typeof": Symbol(react.forward_ref), - "defaultProps": Object { - "selectorPrimaryFocus": "[data-modal-primary-focus]", - }, "propTypes": Object { "aria-label": Object { "type": "string", @@ -1604,9 +1557,6 @@ Map { }, }, "Content" => Object { - "defaultProps": Object { - "tagName": "main", - }, "propTypes": Object { "children": Object { "type": "node", @@ -1624,15 +1574,6 @@ Map { }, "ControlledPasswordInput" => Object { "$$typeof": Symbol(react.forward_ref), - "defaultProps": Object { - "disabled": false, - "helperText": "", - "invalid": false, - "invalidText": "", - "onChange": [Function], - "onClick": [Function], - "size": undefined, - }, "propTypes": Object { "className": Object { "type": "string", @@ -1737,11 +1678,6 @@ Map { "render": [Function], }, "Copy" => Object { - "defaultProps": Object { - "feedback": "Copied!", - "feedbackTimeout": 2000, - "onClick": [Function], - }, "propTypes": Object { "align": Object { "args": Array [ @@ -1779,12 +1715,6 @@ Map { }, }, "CopyButton" => Object { - "defaultProps": Object { - "feedback": "Copied!", - "feedbackTimeout": 2000, - "iconDescription": "Copy to clipboard", - "onClick": [Function], - }, "propTypes": Object { "align": Object { "args": Array [ @@ -1821,10 +1751,6 @@ Map { "DangerButton" => Object {}, "DataTable" => Object { "Table": Object { - "defaultProps": Object { - "isSortable": false, - "overflowMenuOnHover": true, - }, "propTypes": Object { "children": Object { "type": "node", @@ -1873,28 +1799,6 @@ Map { }, }, "TableBatchAction": Object { - "defaultProps": Object { - "iconDescription": "Add", - "renderIcon": Object { - "$$typeof": Symbol(react.forward_ref), - "propTypes": Object { - "size": Object { - "args": Array [ - Array [ - Object { - "type": "number", - }, - Object { - "type": "string", - }, - ], - ], - "type": "oneOfType", - }, - }, - "render": [Function], - }, - }, "propTypes": Object { "hasIconOnly": Object { "type": "bool", @@ -1916,9 +1820,6 @@ Map { }, }, "TableBatchActions": Object { - "defaultProps": Object { - "translateWithId": [Function], - }, "propTypes": Object { "children": Object { "type": "node", @@ -1955,9 +1856,6 @@ Map { ], }, "TableBody": Object { - "defaultProps": Object { - "aria-live": "polite", - }, "propTypes": Object { "aria-live": Object { "args": Array [ @@ -2106,11 +2004,6 @@ Map { }, "TableHeader": Object { "$$typeof": Symbol(react.forward_ref), - "defaultProps": Object { - "isSortable": false, - "scope": "col", - "translateWithId": [Function], - }, "propTypes": Object { "children": Object { "type": "node", @@ -2134,7 +2027,6 @@ Map { "type": "func", }, "scope": Object { - "isRequired": true, "type": "string", }, "sortDirection": Object { @@ -2167,9 +2059,6 @@ Map { }, }, "TableSelectAll": Object { - "defaultProps": Object { - "ariaLabel": "Select all rows in the table", - }, "propTypes": Object { "ariaLabel": Object { "isRequired": true, @@ -2239,12 +2128,11 @@ Map { }, }, "TableToolbar": Object { - "defaultProps": Object { - "aria-label": "data table toolbar", - }, "propTypes": Object { - "aria-label": [Function], - "aria-labelledby": [Function], + "aria-label": Object { + "type": "string", + }, + "ariaLabel": [Function], "children": Object { "type": "node", }, @@ -2284,28 +2172,6 @@ Map { }, }, "TableToolbarMenu": Object { - "defaultProps": Object { - "iconDescription": "Settings", - "renderIcon": Object { - "$$typeof": Symbol(react.forward_ref), - "propTypes": Object { - "size": Object { - "args": Array [ - Array [ - Object { - "type": "number", - }, - Object { - "type": "string", - }, - ], - ], - "type": "oneOfType", - }, - }, - "render": [Function], - }, - }, "propTypes": Object { "children": Object { "isRequired": true, @@ -2315,7 +2181,6 @@ Map { "type": "string", }, "iconDescription": Object { - "isRequired": true, "type": "string", }, "renderIcon": Object { @@ -2334,12 +2199,6 @@ Map { }, }, "TableToolbarSearch": Object { - "defaultProps": Object { - "onClear": [Function], - "persistent": false, - "tabIndex": "0", - "translateWithId": [Function], - }, "propTypes": Object { "children": Object { "type": "node", @@ -2413,19 +2272,10 @@ Map { "type": "oneOfType", }, "translateWithId": Object { - "isRequired": true, "type": "func", }, }, }, - "defaultProps": Object { - "filterRows": [Function], - "locale": "en", - "overflowMenuOnHover": true, - "size": "lg", - "sortRow": [Function], - "translateWithId": [Function], - }, "propTypes": Object { "experimentalAutoAlign": Object { "type": "bool", @@ -2699,10 +2549,30 @@ Map { "type": "oneOfType", }, "maxDate": Object { - "type": "string", + "args": Array [ + Array [ + Object { + "type": "string", + }, + Object { + "type": "number", + }, + ], + ], + "type": "oneOfType", }, "minDate": Object { - "type": "string", + "args": Array [ + Array [ + Object { + "type": "string", + }, + Object { + "type": "number", + }, + ], + ], + "type": "oneOfType", }, "onChange": Object { "type": "func", @@ -2911,15 +2781,6 @@ Map { }, "Dropdown" => Object { "$$typeof": Symbol(react.forward_ref), - "defaultProps": Object { - "direction": "bottom", - "disabled": false, - "helperText": "", - "itemToElement": null, - "itemToString": [Function], - "titleText": "", - "type": "default", - }, "propTypes": Object { "aria-label": Object { "type": "string", @@ -3227,15 +3088,6 @@ Map { "contextType": Object { "$$typeof": Symbol(react.context), }, - "defaultProps": Object { - "accept": Array [], - "buttonKind": "primary", - "buttonLabel": "", - "disabled": false, - "filenameStatus": "uploading", - "multiple": false, - "onClick": [Function], - }, "propTypes": Object { "accept": Object { "args": Array [ @@ -3281,7 +3133,6 @@ Map { "type": "oneOf", }, "iconDescription": Object { - "isRequired": true, "type": "string", }, "labelDescription": Object { @@ -3386,13 +3237,6 @@ Map { }, }, "FileUploaderDropContainer" => Object { - "defaultProps": Object { - "accept": Array [], - "labelText": "Add file", - "multiple": false, - "onAddFiles": [Function], - "pattern": ".[0-9a-z]+$", - }, "propTypes": Object { "accept": Object { "args": Array [ @@ -3435,10 +3279,6 @@ Map { }, }, "FileUploaderItem" => Object { - "defaultProps": Object { - "onDelete": [Function], - "status": "uploading", - }, "propTypes": Object { "errorBody": Object { "type": "string", @@ -3491,11 +3331,6 @@ Map { }, }, "Filename" => Object { - "defaultProps": Object { - "iconDescription": "Uploading file", - "status": "uploading", - "tabIndex": "0", - }, "propTypes": Object { "aria-describedby": Object { "type": "string", @@ -3520,36 +3355,12 @@ Map { "type": "oneOf", }, "tabIndex": Object { - "args": Array [ - Array [ - Object { - "type": "number", - }, - Object { - "type": "string", - }, - ], - ], - "type": "oneOfType", + "type": "number", }, }, }, "FilterableMultiSelect" => Object { "$$typeof": Symbol(react.forward_ref), - "defaultProps": Object { - "clearSelectionDescription": "Total items selected: ", - "clearSelectionText": "To clear selection, press Delete or Backspace,", - "compareItems": [Function], - "direction": "bottom", - "disabled": false, - "filterItems": [Function], - "initialSelectedItems": Array [], - "itemToString": [Function], - "locale": "en", - "open": false, - "selectionFeedback": "top-after-reopen", - "sortItems": [Function], - }, "propTypes": Object { "aria-label": [Function], "ariaLabel": [Function], @@ -3560,7 +3371,6 @@ Map { "type": "string", }, "compareItems": Object { - "isRequired": true, "type": "func", }, "direction": Object { @@ -3778,7 +3588,6 @@ Map { "type": "oneOf", }, "sortItems": Object { - "isRequired": true, "type": "func", }, "translateWithId": Object { @@ -3854,11 +3663,6 @@ Map { "Provider": "React.Provider", }, "FormGroup" => Object { - "defaultProps": Object { - "invalid": false, - "message": false, - "messageText": "", - }, "propTypes": Object { "children": Object { "type": "node", @@ -4399,12 +4203,6 @@ Map { }, }, "InlineNotification" => Object { - "defaultProps": Object { - "hideCloseButton": false, - "kind": "error", - "onCloseButtonClick": [Function], - "role": "status", - }, "propTypes": Object { "aria-label": Object { "type": "string", @@ -4814,18 +4612,6 @@ Map { }, "Modal" => Object { "$$typeof": Symbol(react.forward_ref), - "defaultProps": Object { - "hasScrollingContent": false, - "modalHeading": "", - "modalLabel": "", - "onKeyDown": [Function], - "onRequestClose": [Function], - "onRequestSubmit": [Function], - "passiveModal": false, - "preventCloseOnClickOutside": false, - "primaryButtonDisabled": false, - "selectorPrimaryFocus": "[data-modal-primary-focus]", - }, "propTypes": Object { "alert": Object { "type": "bool", @@ -4961,11 +4747,6 @@ Map { }, "ModalFooter" => Object { "$$typeof": Symbol(react.forward_ref), - "defaultProps": Object { - "closeModal": [Function], - "onRequestClose": [Function], - "onRequestSubmit": [Function], - }, "propTypes": Object { "children": Object { "type": "node", @@ -5026,9 +4807,6 @@ Map { }, "ModalHeader" => Object { "$$typeof": Symbol(react.forward_ref), - "defaultProps": Object { - "iconDescription": "Close", - }, "propTypes": Object { "buttonOnClick": Object { "type": "func", @@ -5067,17 +4845,6 @@ Map { "render": [Function], }, "ModalWrapper" => Object { - "defaultProps": Object { - "disabled": false, - "onKeyDown": [Function], - "preventCloseOnClickOutside": false, - "primaryButtonText": "Save", - "secondaryButtonText": "Cancel", - "selectorPrimaryFocus": "[data-modal-primary-focus]", - "shouldCloseAfterSubmit": true, - "triggerButtonIconDescription": "Provide icon description if icon is used", - "triggerButtonKind": "primary", - }, "propTypes": Object { "buttonTriggerClassName": Object { "type": "string", @@ -5176,20 +4943,6 @@ Map { "$$typeof": Symbol(react.forward_ref), "Filterable": Object { "$$typeof": Symbol(react.forward_ref), - "defaultProps": Object { - "clearSelectionDescription": "Total items selected: ", - "clearSelectionText": "To clear selection, press Delete or Backspace,", - "compareItems": [Function], - "direction": "bottom", - "disabled": false, - "filterItems": [Function], - "initialSelectedItems": Array [], - "itemToString": [Function], - "locale": "en", - "open": false, - "selectionFeedback": "top-after-reopen", - "sortItems": [Function], - }, "propTypes": Object { "aria-label": [Function], "ariaLabel": [Function], @@ -5200,7 +4953,6 @@ Map { "type": "string", }, "compareItems": Object { - "isRequired": true, "type": "func", }, "direction": Object { @@ -5418,7 +5170,6 @@ Map { "type": "oneOf", }, "sortItems": Object { - "isRequired": true, "type": "func", }, "translateWithId": Object { @@ -5436,22 +5187,6 @@ Map { }, "render": [Function], }, - "defaultProps": Object { - "clearSelectionDescription": "Total items selected: ", - "clearSelectionText": "To clear selection, press Delete or Backspace,", - "compareItems": [Function], - "direction": "bottom", - "disabled": false, - "initialSelectedItems": Array [], - "itemToString": [Function], - "locale": "en", - "open": false, - "selectedItems": undefined, - "selectionFeedback": "top-after-reopen", - "sortItems": [Function], - "titleText": false, - "type": "default", - }, "propTypes": Object { "className": Object { "type": "string", @@ -5463,7 +5198,6 @@ Map { "type": "string", }, "compareItems": Object { - "isRequired": true, "type": "func", }, "direction": Object { @@ -5554,7 +5288,6 @@ Map { "type": "oneOf", }, "sortItems": Object { - "isRequired": true, "type": "func", }, "titleText": Object { @@ -5601,30 +5334,6 @@ Map { }, }, "NotificationButton" => Object { - "defaultProps": Object { - "aria-label": "close notification", - "notificationType": "toast", - "renderIcon": Object { - "$$typeof": Symbol(react.forward_ref), - "propTypes": Object { - "size": Object { - "args": Array [ - Array [ - Object { - "type": "number", - }, - Object { - "type": "string", - }, - ], - ], - "type": "oneOfType", - }, - }, - "render": [Function], - }, - "type": "button", - }, "propTypes": Object { "aria-label": Object { "type": "string", @@ -6320,9 +6029,6 @@ Map { }, }, "ProgressStep" => Object { - "defaultProps": Object { - "translateWithId": [Function], - }, "propTypes": Object { "className": Object { "type": "string", @@ -6521,10 +6227,6 @@ Map { }, "RadioTile" => Object { "$$typeof": Symbol(react.forward_ref), - "defaultProps": Object { - "onChange": [Function], - "tabIndex": 0, - }, "propTypes": Object { "checked": Object { "type": "bool", @@ -6697,9 +6399,6 @@ Map { "render": [Function], }, "SearchSkeleton" => Object { - "defaultProps": Object { - "small": false, - }, "propTypes": Object { "className": Object { "type": "string", @@ -6730,14 +6429,6 @@ Map { }, "Select" => Object { "$$typeof": Symbol(react.forward_ref), - "defaultProps": Object { - "disabled": false, - "helperText": "", - "inline": false, - "invalid": false, - "invalidText": "", - "labelText": "Select", - }, "propTypes": Object { "children": Object { "type": "node", @@ -6803,12 +6494,6 @@ Map { "render": [Function], }, "SelectItem" => Object { - "defaultProps": Object { - "disabled": false, - "hidden": false, - "text": "", - "value": "", - }, "propTypes": Object { "className": Object { "type": "string", @@ -6830,9 +6515,6 @@ Map { }, }, "SelectItemGroup" => Object { - "defaultProps": Object { - "disabled": false, - }, "propTypes": Object { "children": Object { "type": "node", @@ -6985,13 +6667,9 @@ Map { }, }, "SideNavFooter" => Object { - "defaultProps": Object { - "assistiveText": "Toggle opening or closing the side navigation", - }, "displayName": "SideNavFooter", "propTypes": Object { "assistiveText": Object { - "isRequired": true, "type": "string", }, "className": Object { @@ -7036,9 +6714,6 @@ Map { }, }, "SideNavIcon" => Object { - "defaultProps": Object { - "small": false, - }, "propTypes": Object { "children": Object { "isRequired": true, @@ -7048,7 +6723,6 @@ Map { "type": "string", }, "small": Object { - "isRequired": true, "type": "bool", }, }, @@ -7237,12 +6911,6 @@ Map { }, }, "SkeletonText" => Object { - "defaultProps": Object { - "heading": false, - "lineCount": 3, - "paragraph": false, - "width": "100%", - }, "propTypes": Object { "className": Object { "type": "string", @@ -7464,11 +7132,6 @@ Map { }, "Switch" => Object { "$$typeof": Symbol(react.forward_ref), - "defaultProps": Object { - "onClick": [Function], - "onKeyDown": [Function], - "selected": false, - }, "propTypes": Object { "children": Object { "type": "node", @@ -7699,10 +7362,6 @@ Map { }, }, "Table" => Object { - "defaultProps": Object { - "isSortable": false, - "overflowMenuOnHover": true, - }, "propTypes": Object { "children": Object { "type": "node", @@ -7751,28 +7410,6 @@ Map { }, }, "TableBatchAction" => Object { - "defaultProps": Object { - "iconDescription": "Add", - "renderIcon": Object { - "$$typeof": Symbol(react.forward_ref), - "propTypes": Object { - "size": Object { - "args": Array [ - Array [ - Object { - "type": "number", - }, - Object { - "type": "string", - }, - ], - ], - "type": "oneOfType", - }, - }, - "render": [Function], - }, - }, "propTypes": Object { "hasIconOnly": Object { "type": "bool", @@ -7794,9 +7431,6 @@ Map { }, }, "TableBatchActions" => Object { - "defaultProps": Object { - "translateWithId": [Function], - }, "propTypes": Object { "children": Object { "type": "node", @@ -7833,9 +7467,6 @@ Map { ], }, "TableBody" => Object { - "defaultProps": Object { - "aria-live": "polite", - }, "propTypes": Object { "aria-live": Object { "args": Array [ @@ -7984,11 +7615,6 @@ Map { }, "TableHeader" => Object { "$$typeof": Symbol(react.forward_ref), - "defaultProps": Object { - "isSortable": false, - "scope": "col", - "translateWithId": [Function], - }, "propTypes": Object { "children": Object { "type": "node", @@ -8012,7 +7638,6 @@ Map { "type": "func", }, "scope": Object { - "isRequired": true, "type": "string", }, "sortDirection": Object { @@ -8045,9 +7670,6 @@ Map { }, }, "TableSelectAll" => Object { - "defaultProps": Object { - "ariaLabel": "Select all rows in the table", - }, "propTypes": Object { "ariaLabel": Object { "isRequired": true, @@ -8117,12 +7739,11 @@ Map { }, }, "TableToolbar" => Object { - "defaultProps": Object { - "aria-label": "data table toolbar", - }, "propTypes": Object { - "aria-label": [Function], - "aria-labelledby": [Function], + "aria-label": Object { + "type": "string", + }, + "ariaLabel": [Function], "children": Object { "type": "node", }, @@ -8162,28 +7783,6 @@ Map { }, }, "TableToolbarMenu" => Object { - "defaultProps": Object { - "iconDescription": "Settings", - "renderIcon": Object { - "$$typeof": Symbol(react.forward_ref), - "propTypes": Object { - "size": Object { - "args": Array [ - Array [ - Object { - "type": "number", - }, - Object { - "type": "string", - }, - ], - ], - "type": "oneOfType", - }, - }, - "render": [Function], - }, - }, "propTypes": Object { "children": Object { "isRequired": true, @@ -8193,7 +7792,6 @@ Map { "type": "string", }, "iconDescription": Object { - "isRequired": true, "type": "string", }, "renderIcon": Object { @@ -8212,12 +7810,6 @@ Map { }, }, "TableToolbarSearch" => Object { - "defaultProps": Object { - "onClear": [Function], - "persistent": false, - "tabIndex": "0", - "translateWithId": [Function], - }, "propTypes": Object { "children": Object { "type": "node", @@ -8291,7 +7883,6 @@ Map { "type": "oneOfType", }, "translateWithId": Object { - "isRequired": true, "type": "func", }, }, @@ -8412,20 +8003,6 @@ Map { }, "TextArea" => Object { "$$typeof": Symbol(react.forward_ref), - "defaultProps": Object { - "disabled": false, - "enableCounter": false, - "helperText": "", - "invalid": false, - "invalidText": "", - "maxCount": undefined, - "onChange": [Function], - "onClick": [Function], - "placeholder": "", - "rows": 4, - "warn": false, - "warnText": "", - }, "propTypes": Object { "className": Object { "type": "string", @@ -8526,15 +8103,6 @@ Map { "$$typeof": Symbol(react.forward_ref), "ControlledPasswordInput": Object { "$$typeof": Symbol(react.forward_ref), - "defaultProps": Object { - "disabled": false, - "helperText": "", - "invalid": false, - "invalidText": "", - "onChange": [Function], - "onClick": [Function], - "size": undefined, - }, "propTypes": Object { "className": Object { "type": "string", @@ -9045,13 +8613,6 @@ Map { "render": [Function], }, "ToastNotification" => Object { - "defaultProps": Object { - "hideCloseButton": false, - "kind": "error", - "onCloseButtonClick": [Function], - "role": "status", - "timeout": 0, - }, "propTypes": Object { "aria-label": Object { "type": "string", @@ -9682,11 +9243,6 @@ Map { }, "unstable_OverflowMenuV2" => Object {}, "unstable_PageSelector" => Object { - "defaultProps": Object { - "className": null, - "id": 1, - "labelText": "Current page number", - }, "propTypes": Object { "className": Object { "type": "string", @@ -9718,24 +9274,6 @@ Map { }, }, "unstable_Pagination" => Object { - "defaultProps": Object { - "backwardText": "Previous page", - "children": undefined, - "className": null, - "disabled": false, - "forwardText": "Next page", - "id": 1, - "initialPage": 1, - "itemRangeText": [Function], - "itemText": [Function], - "itemsPerPageText": "Items per page:", - "pageRangeText": [Function], - "pageSize": 10, - "pageSizes": undefined, - "pageText": [Function], - "pagesUnknown": false, - "totalItems": undefined, - }, "propTypes": Object { "backwardText": Object { "type": "string", diff --git a/packages/react/examples/custom-data-table-state-manager/src/components/CustomDataTable.js b/packages/react/examples/custom-data-table-state-manager/src/components/CustomDataTable.js index 35fc592d3ed1..ab553a8ae819 100644 --- a/packages/react/examples/custom-data-table-state-manager/src/components/CustomDataTable.js +++ b/packages/react/examples/custom-data-table-state-manager/src/components/CustomDataTable.js @@ -59,14 +59,14 @@ import { */ const CustomDataTable = ({ id, - collator, + collator = new Intl.Collator(), columns, - hasSelection, - pageSize: propPageSize, + hasSelection = false, + pageSize: propPageSize = 5, rows: propRows, - size, + size = TABLE_SIZE.REGULAR, sortInfo: propSortInfo, - start: propStart, + start: propStart = 0, zebra, }) => { const [rows, setRows] = useState(propRows); @@ -341,12 +341,4 @@ CustomDataTable.propTypes = { zebra: PropTypes.bool, }; -CustomDataTable.defaultProps = { - collator: new Intl.Collator(), - hasSelection: false, - pageSize: 5, - size: TABLE_SIZE.REGULAR, - start: 0, -}; - export default CustomDataTable; diff --git a/packages/react/src/components/Accordion/Accordion.Skeleton.tsx b/packages/react/src/components/Accordion/Accordion.Skeleton.tsx index a3f9a2ebc650..6b00e7c926c6 100644 --- a/packages/react/src/components/Accordion/Accordion.Skeleton.tsx +++ b/packages/react/src/components/Accordion/Accordion.Skeleton.tsx @@ -105,12 +105,6 @@ AccordionSkeleton.propTypes = { open: PropTypes.bool, }; -AccordionSkeleton.defaultProps = { - open: true, - count: 4, - align: 'end', -}; - function AccordionSkeletonItem() { const prefix = usePrefix(); return ( diff --git a/packages/react/src/components/Checkbox/Checkbox.tsx b/packages/react/src/components/Checkbox/Checkbox.tsx index 6bc628332899..ed4991df6651 100644 --- a/packages/react/src/components/Checkbox/Checkbox.tsx +++ b/packages/react/src/components/Checkbox/Checkbox.tsx @@ -12,6 +12,7 @@ import { Text } from '../Text'; import { usePrefix } from '../../internal/usePrefix'; import { WarningFilled, WarningAltFilled } from '@carbon/icons-react'; import setupGetInstanceId from '../../tools/setupGetInstanceId'; +import { noopFn } from '../../internal/noopFn'; const getInstanceId = setupGetInstanceId(); @@ -101,9 +102,9 @@ const Checkbox = React.forwardRef( helperText, id, labelText, - onChange, + onChange = noopFn, onClick, - indeterminate, + indeterminate = false, invalid, invalidText, hideLabel, @@ -296,11 +297,6 @@ Checkbox.propTypes = { warnText: PropTypes.node, }; -Checkbox.defaultProps = { - onChange: () => {}, - indeterminate: false, -}; - Checkbox.displayName = 'Checkbox'; export default Checkbox; diff --git a/packages/react/src/components/CodeSnippet/CodeSnippet.js b/packages/react/src/components/CodeSnippet/CodeSnippet.js index 35691be2823c..8d045cfb54bd 100644 --- a/packages/react/src/components/CodeSnippet/CodeSnippet.js +++ b/packages/react/src/components/CodeSnippet/CodeSnippet.js @@ -27,21 +27,21 @@ const defaultMinExpandedNumberOfRows = 16; function CodeSnippet({ align = 'bottom', className, - type, + type = 'single', children, disabled, feedback, feedbackTimeout, onClick, - ['aria-label']: ariaLabel, + ['aria-label']: ariaLabel = 'Copy to clipboard', ariaLabel: deprecatedAriaLabel, copyText, copyButtonDescription, light, - showMoreText, - showLessText, + showMoreText = 'Show more', + showLessText = 'Show less', hideCopyButton, - wrapText, + wrapText = false, maxCollapsedNumberOfRows = defaultMaxCollapsedNumberOfRows, maxExpandedNumberOfRows = defaultMaxExpandedNumberOfRows, minCollapsedNumberOfRows = defaultMinCollapsedNumberOfRows, @@ -419,12 +419,4 @@ CodeSnippet.propTypes = { wrapText: PropTypes.bool, }; -CodeSnippet.defaultProps = { - ['aria-label']: 'Copy to clipboard', - type: 'single', - showMoreText: 'Show more', - showLessText: 'Show less', - wrapText: false, -}; - export default CodeSnippet; diff --git a/packages/react/src/components/ComboBox/ComboBox.tsx b/packages/react/src/components/ComboBox/ComboBox.tsx index a53c2abea5ff..61914df39043 100644 --- a/packages/react/src/components/ComboBox/ComboBox.tsx +++ b/packages/react/src/components/ComboBox/ComboBox.tsx @@ -38,7 +38,6 @@ import { } from '@carbon/icons-react'; import ListBox, { PropTypes as ListBoxPropTypes, - ListBoxType, ListBoxSize, } from '../ListBox'; import { ListBoxTrigger, ListBoxSelection } from '../ListBox/next'; @@ -286,11 +285,6 @@ export interface ComboBoxProps */ translateWithId?: (id: string) => string; - /** - * Currently supports either the default type, or an inline variant - */ - type?: ListBoxType; - /** * Specify whether the control is currently in warning state */ @@ -311,8 +305,8 @@ const ComboBox = forwardRef( ['aria-label']: ariaLabel = 'Choose an item', ariaLabel: deprecatedAriaLabel, className: containerClassName, - direction, - disabled, + direction = 'bottom', + disabled = false, downshiftProps, helperText, id, @@ -320,7 +314,7 @@ const ComboBox = forwardRef( invalid, invalidText, items, - itemToElement, + itemToElement = null, itemToString = defaultItemToString, light, onChange, @@ -333,7 +327,6 @@ const ComboBox = forwardRef( size, titleText, translateWithId, - type: _type, warn, warnText, ...rest @@ -913,11 +906,6 @@ ComboBox.propTypes = { */ translateWithId: PropTypes.func, - /** - * Currently supports either the default type, or an inline variant - */ - type: ListBoxPropTypes.ListBoxType, - /** * Specify whether the control is currently in warning state */ @@ -929,16 +917,6 @@ ComboBox.propTypes = { warnText: PropTypes.node, }; -ComboBox.defaultProps = { - disabled: false, - itemToString: defaultItemToString, - itemToElement: null, - shouldFilterItem: defaultShouldFilterItem, - type: 'default', - ['aria-label']: 'Choose an item', - direction: 'bottom', -}; - type ComboboxComponentProps = PropsWithoutRef< PropsWithChildren> & RefAttributes >; diff --git a/packages/react/src/components/ComposedModal/ComposedModal.tsx b/packages/react/src/components/ComposedModal/ComposedModal.tsx index ef7555510617..4cfce68b7697 100644 --- a/packages/react/src/components/ComposedModal/ComposedModal.tsx +++ b/packages/react/src/components/ComposedModal/ComposedModal.tsx @@ -197,7 +197,7 @@ const ComposedModal = React.forwardRef( onKeyDown, open, preventCloseOnClickOutside, - selectorPrimaryFocus, + selectorPrimaryFocus = '[data-modal-primary-focus]', selectorsFloatingMenus, size, launcherButtonRef, @@ -468,8 +468,5 @@ ComposedModal.propTypes = { */ size: PropTypes.oneOf(['xs', 'sm', 'md', 'lg']), }; -ComposedModal.defaultProps = { - selectorPrimaryFocus: '[data-modal-primary-focus]', -}; export default ComposedModal; diff --git a/packages/react/src/components/ComposedModal/ModalFooter.tsx b/packages/react/src/components/ComposedModal/ModalFooter.tsx index 95891af0264d..9ee4f68905cb 100644 --- a/packages/react/src/components/ComposedModal/ModalFooter.tsx +++ b/packages/react/src/components/ComposedModal/ModalFooter.tsx @@ -4,6 +4,7 @@ import Button from '../Button'; import ButtonSet from '../ButtonSet'; import cx from 'classnames'; import { usePrefix } from '../../internal/usePrefix'; +import { noopFn } from '../../internal/noopFn'; interface SecondaryButtonProps { buttonText: ReactNode; @@ -163,11 +164,11 @@ export const ModalFooter = React.forwardRef( { children, className: customClassName, - closeModal, + closeModal = noopFn, danger, inputref, - onRequestClose, - onRequestSubmit, + onRequestClose = noopFn, + onRequestSubmit = noopFn, primaryButtonDisabled, primaryButtonText, primaryClassName, @@ -324,10 +325,3 @@ ModalFooter.propTypes = { */ secondaryClassName: PropTypes.string, }; - -const noop = () => {}; -ModalFooter.defaultProps = { - onRequestClose: noop, - onRequestSubmit: noop, - closeModal: noop, -}; diff --git a/packages/react/src/components/ComposedModal/ModalHeader.tsx b/packages/react/src/components/ComposedModal/ModalHeader.tsx index 43d394c4851b..1ddbc044454f 100644 --- a/packages/react/src/components/ComposedModal/ModalHeader.tsx +++ b/packages/react/src/components/ComposedModal/ModalHeader.tsx @@ -84,7 +84,7 @@ export const ModalHeader = React.forwardRef( closeClassName, closeIconClassName, closeModal, - iconDescription, + iconDescription = 'Close', label, labelClassName, title, @@ -198,7 +198,3 @@ ModalHeader.propTypes = { */ titleClassName: PropTypes.string, }; - -ModalHeader.defaultProps = { - iconDescription: 'Close', -}; diff --git a/packages/react/src/components/ContentSwitcher/ContentSwitcher.stories.js b/packages/react/src/components/ContentSwitcher/ContentSwitcher.stories.js index 0072a0dfca3d..87b331e8bdc5 100644 --- a/packages/react/src/components/ContentSwitcher/ContentSwitcher.stories.js +++ b/packages/react/src/components/ContentSwitcher/ContentSwitcher.stories.js @@ -53,7 +53,7 @@ export const _WithLayer = () => ( ); export const IconOnly = (args) => ( - + {}} {...args}> @@ -68,7 +68,7 @@ export const IconOnly = (args) => ( export const IconOnlyWithLayer = (args) => ( - + {}} {...args}> diff --git a/packages/react/src/components/ContentSwitcher/ContentSwitcher.tsx b/packages/react/src/components/ContentSwitcher/ContentSwitcher.tsx index cb3bfeb6c94d..3f3129543476 100644 --- a/packages/react/src/components/ContentSwitcher/ContentSwitcher.tsx +++ b/packages/react/src/components/ContentSwitcher/ContentSwitcher.tsx @@ -13,6 +13,7 @@ import { LayoutConstraint } from '../Layout'; import { composeEventHandlers } from '../../tools/events'; import { getNextIndex, matches, keys } from '../../internal/keyboard'; import { PrefixContext } from '../../internal/usePrefix'; +import { noopFn } from '../../internal/noopFn'; interface SwitchEventHandlersParams { index?: number; @@ -126,13 +127,7 @@ export default class ContentSwitcher extends React.Component< static contextType = PrefixContext; - static defaultProps = { - selectedIndex: 0, - selectionMode: 'automatic', - onChange: () => {}, - }; - - static getDerivedStateFromProps({ selectedIndex }, state) { + static getDerivedStateFromProps({ selectedIndex = 0 }, state) { const { prevSelectedIndex } = state; return prevSelectedIndex === selectedIndex ? null @@ -147,7 +142,7 @@ export default class ContentSwitcher extends React.Component< }; handleChildChange = (data) => { - const { selectionMode } = this.props; + const { selectionMode = 'automatic' } = this.props; // the currently selected child index const { selectedIndex } = this.state; // the newly selected child index @@ -202,10 +197,12 @@ export default class ContentSwitcher extends React.Component< className, light, // eslint-disable-next-line @typescript-eslint/no-unused-vars - selectedIndex, // eslint-disable-line no-unused-vars + selectedIndex = 0, // eslint-disable-next-line @typescript-eslint/no-unused-vars - selectionMode, // eslint-disable-line no-unused-vars + selectionMode = 'automatic', size, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + onChange = noopFn, ...other } = this.props; diff --git a/packages/react/src/components/Copy/Copy.js b/packages/react/src/components/Copy/Copy.js index 298fd87ee57a..10b4976a79f4 100644 --- a/packages/react/src/components/Copy/Copy.js +++ b/packages/react/src/components/Copy/Copy.js @@ -12,15 +12,16 @@ import classnames from 'classnames'; import { composeEventHandlers } from '../../tools/events'; import { usePrefix } from '../../internal/usePrefix'; import { IconButton } from '../IconButton'; +import { noopFn } from '../../internal/noopFn'; export default function Copy({ align = 'bottom', children, className, - feedback, - feedbackTimeout, + feedback = 'Copied!', + feedbackTimeout = 2000, onAnimationEnd, - onClick, + onClick = noopFn, ...other }) { const [animation, setAnimation] = useState(''); @@ -125,9 +126,3 @@ Copy.propTypes = { */ onClick: PropTypes.func, }; - -Copy.defaultProps = { - feedback: 'Copied!', - feedbackTimeout: 2000, - onClick: () => {}, -}; diff --git a/packages/react/src/components/CopyButton/CopyButton.js b/packages/react/src/components/CopyButton/CopyButton.js index 7f217b920ab7..de6ec53ab95a 100644 --- a/packages/react/src/components/CopyButton/CopyButton.js +++ b/packages/react/src/components/CopyButton/CopyButton.js @@ -12,17 +12,23 @@ import { Copy as CopyIcon } from '@carbon/icons-react'; import Copy from '../Copy'; import { LayoutConstraint } from '../Layout'; import { usePrefix } from '../../internal/usePrefix'; - +import { noopFn } from '../../internal/noopFn'; export default function CopyButton({ align = 'bottom', - iconDescription, + feedback = 'Copied!', + feedbackTimeout = 2000, + iconDescription = 'Copy to clipboard', className, + onClick = noopFn, ...other }) { const prefix = usePrefix(); return ( {}, -}; diff --git a/packages/react/src/components/DataTable/DataTable.tsx b/packages/react/src/components/DataTable/DataTable.tsx index 310d7c93af78..e04c3f23167b 100644 --- a/packages/react/src/components/DataTable/DataTable.tsx +++ b/packages/react/src/components/DataTable/DataTable.tsx @@ -15,7 +15,6 @@ import { getCellId } from './tools/cells'; import denormalize from './tools/denormalize'; import { composeEventHandlers } from '../../tools/events'; import { defaultFilterRows } from './tools/filter'; -import { defaultSortRow } from './tools/sorting'; import setupGetInstanceId from './tools/instanceId'; import Table from './Table'; import TableActionList from './TableActionList'; @@ -64,15 +63,6 @@ const defaultTranslations = { const translateWithId = (id) => defaultTranslations[id]; -const dataTableDefaultProps = { - filterRows: defaultFilterRows, - locale: 'en', - overflowMenuOnHover: true, - size: 'lg', - sortRow: defaultSortRow, - translateWithId, -}; - export type DataTableSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl'; export interface DataTableCell { @@ -220,7 +210,7 @@ export interface DataTableProps { ) => React.ReactElement; experimentalAutoAlign?: boolean; filterRows?: (filterRowsArgs: { - cellsById: Record>; + cellsById: Record>; getCellId: (rowId: string, header: string) => string; headers: Array; inputValue: string; @@ -274,12 +264,11 @@ interface DataTableState { * consumer. */ class DataTable extends React.Component< - DataTableProps & typeof dataTableDefaultProps, + DataTableProps, DataTableState > { instanceId: number; - static defaultProps = dataTableDefaultProps; static propTypes = { /** * Experimental property. Allows table to align cell contents to the top if there is text wrapping in the content. Might have performance issues, intended for smaller tables @@ -495,7 +484,7 @@ class DataTable extends React.Component< [key: string]: unknown; } ) => { - const { translateWithId: t } = this.props; + const { translateWithId: t = translateWithId } = this.props; const { isExpandedAll, rowIds, rowsById } = this.state; const isExpanded = isExpandedAll || rowIds.every((id) => rowsById[id].isExpanded); @@ -561,7 +550,7 @@ class DataTable extends React.Component< row: DataTableRow; [key: string]: unknown; }) => { - const { translateWithId: t } = this.props; + const { translateWithId: t = translateWithId } = this.props; const translationKey = row.isExpanded ? translationKeys.collapseRow : translationKeys.expandRow; @@ -617,7 +606,7 @@ class DataTable extends React.Component< [key: string]: unknown; } ) => { - const { translateWithId: t } = this.props; + const { translateWithId: t = translateWithId } = this.props; // If we're given a row, return the selection state values for that row if (row) { @@ -694,11 +683,11 @@ class DataTable extends React.Component< getTableProps = () => { const { useZebraStyles, - size, + size = 'lg', isSortable, useStaticWidth, stickyHeader, - overflowMenuOnHover, + overflowMenuOnHover = true, experimentalAutoAlign, } = this.props; return { @@ -739,9 +728,10 @@ class DataTable extends React.Component< * @returns {Array} the array of rowIds that are currently included through the filter * */ getFilteredRowIds = () => { + const { filterRows = defaultFilterRows } = this.props; const filteredRowIds = typeof this.state.filterInputValue === 'string' - ? this.props.filterRows({ + ? filterRows({ rowIds: this.state.rowIds, headers: this.props.headers, cellsById: this.state.cellsById, @@ -941,8 +931,12 @@ class DataTable extends React.Component< }; render() { - // eslint-disable-next-line react/prop-types - const { children, filterRows, headers, render } = this.props; + const { + children, + filterRows = defaultFilterRows, + headers, + render, + } = this.props; const { filterInputValue, rowIds, rowsById, cellsById } = this.state; const filteredRowIds = typeof filterInputValue === 'string' diff --git a/packages/react/src/components/DataTable/Table.tsx b/packages/react/src/components/DataTable/Table.tsx index 821253bdb069..9e82aaf81856 100644 --- a/packages/react/src/components/DataTable/Table.tsx +++ b/packages/react/src/components/DataTable/Table.tsx @@ -289,9 +289,4 @@ Table.propTypes = { useZebraStyles: PropTypes.bool, }; -Table.defaultProps = { - isSortable: false, - overflowMenuOnHover: true, -}; - export default Table; diff --git a/packages/react/src/components/DataTable/TableBatchAction.js b/packages/react/src/components/DataTable/TableBatchAction.js index 1a0db30d441e..fcaa9e052605 100644 --- a/packages/react/src/components/DataTable/TableBatchAction.js +++ b/packages/react/src/components/DataTable/TableBatchAction.js @@ -10,7 +10,17 @@ import React from 'react'; import { AddFilled as iconAddSolid } from '@carbon/icons-react'; import Button from '../Button'; -const TableBatchAction = (props) => @@ -129,13 +126,7 @@ Filename.propTypes = { /** * Provide a custom tabIndex value for the `` */ - tabIndex: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), -}; - -Filename.defaultProps = { - iconDescription: 'Uploading file', - status: 'uploading', - tabIndex: '0', + tabIndex: PropTypes.number, }; export default Filename; diff --git a/packages/react/src/components/FileUploader/__tests__/FileUploader-test.js b/packages/react/src/components/FileUploader/__tests__/FileUploader-test.js index 7a750b3219fc..72cf8c1ba114 100644 --- a/packages/react/src/components/FileUploader/__tests__/FileUploader-test.js +++ b/packages/react/src/components/FileUploader/__tests__/FileUploader-test.js @@ -14,6 +14,7 @@ import { uploadFiles } from '../test-helpers'; const iconDescription = 'test description'; const requiredProps = { iconDescription, + filenameStatus: 'uploading', labelTitle: 'Upload files', labelDescription: 'Max file size is 500mb. Only .jpg files are supported.', }; diff --git a/packages/react/src/components/FileUploader/__tests__/FileUploaderDropContainer-test.js b/packages/react/src/components/FileUploader/__tests__/FileUploaderDropContainer-test.js index d397a5babd02..9caf4730e7a9 100644 --- a/packages/react/src/components/FileUploader/__tests__/FileUploaderDropContainer-test.js +++ b/packages/react/src/components/FileUploader/__tests__/FileUploaderDropContainer-test.js @@ -12,15 +12,19 @@ import { Simulate } from 'react-dom/test-utils'; import { FileUploaderDropContainer } from '../'; import { uploadFiles } from '../test-helpers'; +const requiredProps = { labelText: 'Add file' }; + describe('FileUploaderDropContainer', () => { it('should not have axe violations', async () => { - const { container } = render(); + const { container } = render( + + ); await expect(container).toHaveNoAxeViolations(); }); it('should support a custom class name on the drop area', () => { const { container } = render( - + ); // eslint-disable-next-line testing-library/no-container, testing-library/no-node-access const dropArea = container.querySelector('button'); @@ -30,8 +34,8 @@ describe('FileUploaderDropContainer', () => { it('should have a unique id each time it is used', () => { const { container } = render( <> - - + + ); // eslint-disable-next-line testing-library/no-container, testing-library/no-node-access @@ -40,14 +44,18 @@ describe('FileUploaderDropContainer', () => { }); it('should render with the default labelText prop', () => { - const { container } = render(); + const { container } = render( + + ); // eslint-disable-next-line testing-library/prefer-screen-queries const label = getByText(container, 'Add file'); expect(label).toBeInstanceOf(HTMLElement); }); it('should render with multiple set to false by default', () => { - const { container } = render(); + const { container } = render( + + ); // eslint-disable-next-line testing-library/no-container, testing-library/no-node-access const input = container.querySelector('input'); expect(input.getAttribute('multiple')).toBeFalsy(); @@ -71,7 +79,7 @@ describe('FileUploaderDropContainer', () => { it('should call `onAddFiles` when a file is selected', () => { const onAddFiles = jest.fn(); const { container } = render( - + ); // eslint-disable-next-line testing-library/no-container, testing-library/no-node-access const input = container.querySelector('input'); @@ -95,7 +103,11 @@ describe('FileUploaderDropContainer', () => { it('should mark invalid files using default pattern', () => { const onAddFiles = jest.fn(); const { container } = render( - + ); // eslint-disable-next-line testing-library/no-container, testing-library/no-node-access const input = container.querySelector('input'); @@ -138,7 +150,11 @@ describe('FileUploaderDropContainer', () => { it('should be case insensitive when marking files invalid', () => { const onAddFiles = jest.fn(); const { container } = render( - + ); // eslint-disable-next-line testing-library/no-container, testing-library/no-node-access const input = container.querySelector('input'); @@ -181,6 +197,7 @@ describe('FileUploaderDropContainer', () => { onAddFiles={onAddFiles} accept={['.txt', '.a_a', '.b-b', '.a-b_c']} pattern=".[0-9a-z-_]+$" + {...requiredProps} /> ); // eslint-disable-next-line testing-library/no-container, testing-library/no-node-access diff --git a/packages/react/src/components/FluidDropdown/__tests__/FluidDropdown-test.js b/packages/react/src/components/FluidDropdown/__tests__/FluidDropdown-test.js index e00cacd50b87..94998f0c8b3d 100644 --- a/packages/react/src/components/FluidDropdown/__tests__/FluidDropdown-test.js +++ b/packages/react/src/components/FluidDropdown/__tests__/FluidDropdown-test.js @@ -29,6 +29,7 @@ describe('FluidDropdown', () => { label: 'input', placeholder: 'Filter...', type: 'default', + titleText: 'Dropdown label', }; }); @@ -104,12 +105,12 @@ describe('FluidDropdown', () => { describe('title', () => { it('renders a title', () => { - render(); + render(); expect(screen.getByText('Email Input')).toBeInTheDocument(); }); it('has the expected classes', () => { - render(); + render(); expect(screen.getByText('Email Input')).toHaveClass(`${prefix}--label`); }); }); diff --git a/packages/react/src/components/FluidSearch/FluidSearch.js b/packages/react/src/components/FluidSearch/FluidSearch.js index 1544d54cbfc5..18c209a5ba8f 100644 --- a/packages/react/src/components/FluidSearch/FluidSearch.js +++ b/packages/react/src/components/FluidSearch/FluidSearch.js @@ -26,13 +26,6 @@ const FluidSearch = React.forwardRef(function FluidSearch( ); }); -FluidSearch.defaultProps = { - autoComplete: 'off', - closeButtonLabelText: 'Clear search input', - role: 'searchbox', - type: 'text', -}; - FluidSearch.propTypes = { /** * Specify an optional value for the `autocomplete` property on the underlying diff --git a/packages/react/src/components/FormGroup/FormGroup.stories.js b/packages/react/src/components/FormGroup/FormGroup.stories.js index fbdda32b29e0..d2e0cfccdbd2 100644 --- a/packages/react/src/components/FormGroup/FormGroup.stories.js +++ b/packages/react/src/components/FormGroup/FormGroup.stories.js @@ -6,7 +6,7 @@ */ import React from 'react'; -import FormGroup from '../FormGroup'; +import { FormGroup } from '../FormGroup'; import TextInput from '../TextInput'; import RadioButtonGroup from '../RadioButtonGroup'; import RadioButton from '../RadioButton'; diff --git a/packages/react/src/components/FormGroup/FormGroup.tsx b/packages/react/src/components/FormGroup/FormGroup.tsx index 7c1b5de322ef..7dd2a8b541bb 100644 --- a/packages/react/src/components/FormGroup/FormGroup.tsx +++ b/packages/react/src/components/FormGroup/FormGroup.tsx @@ -47,11 +47,11 @@ export interface FormGroupProps extends ReactAttr { const FormGroup = ({ legendId, legendText, - invalid, + invalid = false, children, className, - message, - messageText, + message = false, + messageText = '', ...rest }: FormGroupProps) => { const prefix = usePrefix(); @@ -115,10 +115,4 @@ FormGroup.propTypes = { messageText: PropTypes.string, }; -FormGroup.defaultProps = { - invalid: false, - message: false, - messageText: '', -}; - export default FormGroup; diff --git a/packages/react/src/components/ListBox/ListBox.tsx b/packages/react/src/components/ListBox/ListBox.tsx index 80e4a979049f..6e6017bb9ea0 100644 --- a/packages/react/src/components/ListBox/ListBox.tsx +++ b/packages/react/src/components/ListBox/ListBox.tsx @@ -90,8 +90,8 @@ const ListBox: ListBoxComponent = React.forwardRef(function ListBox( { children, className: containerClassName, - disabled, - type, + disabled = false, + type = 'default', size, invalid, invalidText, @@ -156,7 +156,7 @@ ListBox.propTypes = { /** * Specify whether the ListBox is currently disabled */ - disabled: PropTypes.bool.isRequired, + disabled: PropTypes.bool, /** * Specify whether the control is currently invalid @@ -192,7 +192,7 @@ ListBox.propTypes = { * Specify the "type" of the ListBox. Currently supports either `default` or * `inline` as an option. */ - type: ListBoxType.isRequired, + type: ListBoxType, /** * Specify whether the control is currently in warning state @@ -205,9 +205,4 @@ ListBox.propTypes = { warnText: PropTypes.node, }; -ListBox.defaultProps = { - disabled: false, - type: 'default', -}; - export default ListBox; diff --git a/packages/react/src/components/ListBox/ListBoxMenuIcon.tsx b/packages/react/src/components/ListBox/ListBoxMenuIcon.tsx index aa55a958b746..c82921a2137f 100644 --- a/packages/react/src/components/ListBox/ListBoxMenuIcon.tsx +++ b/packages/react/src/components/ListBox/ListBoxMenuIcon.tsx @@ -74,11 +74,7 @@ ListBoxMenuIcon.propTypes = { * icon. This function takes in an id defined in `translationIds` and should * return a string message for that given message id. */ - translateWithId: PropTypes.func.isRequired, -}; - -ListBoxMenuIcon.defaultProps = { - translateWithId: defaultTranslateWithId, + translateWithId: PropTypes.func, }; export default ListBoxMenuIcon; diff --git a/packages/react/src/components/ListBox/ListBoxMenuItem.tsx b/packages/react/src/components/ListBox/ListBoxMenuItem.tsx index 0a0c18d2d72d..b6eb7e41804a 100644 --- a/packages/react/src/components/ListBox/ListBoxMenuItem.tsx +++ b/packages/react/src/components/ListBox/ListBoxMenuItem.tsx @@ -59,7 +59,13 @@ export type ListBoxMenuItemComponent = ForwardRefReturn< */ const ListBoxMenuItem = React.forwardRef( function ListBoxMenuItem( - { children, isActive, isHighlighted, title, ...rest }: ListBoxMenuItemProps, + { + children, + isActive = false, + isHighlighted = false, + title, + ...rest + }: ListBoxMenuItemProps, forwardedRef: ListBoxMenuItemForwardedRef ) { const prefix = usePrefix(); @@ -101,12 +107,12 @@ ListBoxMenuItem.propTypes = { /** * Specify whether the current menu item is "active". */ - isActive: PropTypes.bool.isRequired, + isActive: PropTypes.bool, /** * Specify whether the current menu item is "highlighted". */ - isHighlighted: PropTypes.bool.isRequired, + isHighlighted: PropTypes.bool, /** * Provide an optional tooltip for the ListBoxMenuItem @@ -114,9 +120,4 @@ ListBoxMenuItem.propTypes = { title: PropTypes.string, }; -ListBoxMenuItem.defaultProps = { - isActive: false, - isHighlighted: false, -}; - export default ListBoxMenuItem as ListBoxMenuItemComponent; diff --git a/packages/react/src/components/ListBox/ListBoxSelection.tsx b/packages/react/src/components/ListBox/ListBoxSelection.tsx index e88a88cbdc5a..9ef89b691b45 100644 --- a/packages/react/src/components/ListBox/ListBoxSelection.tsx +++ b/packages/react/src/components/ListBox/ListBoxSelection.tsx @@ -50,11 +50,23 @@ export interface ListBoxSelectionProps { * icon. This function takes in an id defined in `translationIds` and should * return a string message for that given message id. */ - translateWithId(messageId: string, args?: Record): string; + translateWithId?(messageId: string, args?: Record): string; } export type ListBoxSelectionComponent = React.FC; +export const translationIds = { + 'clear.all': 'clear.all', + 'clear.selection': 'clear.selection', +}; + +const defaultTranslations = { + [translationIds['clear.all']]: 'Clear all selected items', + [translationIds['clear.selection']]: 'Clear selected item', +}; + +const defaultTranslateWithId = (id: string) => defaultTranslations[id]; + /** * `ListBoxSelection` is used to provide controls for clearing a selection, in * addition to conditionally rendering a badge if the control has more than one @@ -63,7 +75,7 @@ export type ListBoxSelectionComponent = React.FC; const ListBoxSelection: ListBoxSelectionComponent = ({ clearSelection, selectionCount, - translateWithId: t, + translateWithId: t = defaultTranslateWithId, disabled, onClearSelection, readOnly, @@ -124,16 +136,6 @@ const ListBoxSelection: ListBoxSelectionComponent = ({ ); }; -export const translationIds = { - 'clear.all': 'clear.all', - 'clear.selection': 'clear.selection', -}; - -const defaultTranslations = { - [translationIds['clear.all']]: 'Clear all selected items', - [translationIds['clear.selection']]: 'Clear selected item', -}; - ListBoxSelection.propTypes = { /** * Specify a function to be invoked when a user interacts with the clear @@ -168,11 +170,7 @@ ListBoxSelection.propTypes = { * icon. This function takes in an id defined in `translationIds` and should * return a string message for that given message id. */ - translateWithId: PropTypes.func.isRequired, -}; - -ListBoxSelection.defaultProps = { - translateWithId: (id: string) => defaultTranslations[id], + translateWithId: PropTypes.func, }; export default ListBoxSelection; diff --git a/packages/react/src/components/ListBox/next/ListBoxSelection.js b/packages/react/src/components/ListBox/next/ListBoxSelection.js index d7fbe6c67bd6..1ecc3a5b743b 100644 --- a/packages/react/src/components/ListBox/next/ListBoxSelection.js +++ b/packages/react/src/components/ListBox/next/ListBoxSelection.js @@ -16,10 +16,23 @@ import { usePrefix } from '../../../internal/usePrefix'; * addition to conditionally rendering a badge if the control has more than one * selection. */ + +export const translationIds = { + 'clear.all': 'clear.all', + 'clear.selection': 'clear.selection', +}; + +const defaultTranslations = { + [translationIds['clear.all']]: 'Clear all selected items', + [translationIds['clear.selection']]: 'Clear selected item', +}; + +const defaultTranslateWithId = (id) => defaultTranslations[id]; + function ListBoxSelection({ clearSelection, selectionCount, - translateWithId: t, + translateWithId: t = defaultTranslateWithId, disabled, onClearSelection, ...rest @@ -85,16 +98,6 @@ function ListBoxSelection({ ); } -export const translationIds = { - 'clear.all': 'clear.all', - 'clear.selection': 'clear.selection', -}; - -const defaultTranslations = { - [translationIds['clear.all']]: 'Clear all selected items', - [translationIds['clear.selection']]: 'Clear selected item', -}; - ListBoxSelection.propTypes = { /** * Specify a function to be invoked when a user interacts with the clear @@ -136,11 +139,7 @@ ListBoxSelection.propTypes = { * icon. This function takes in an id defined in `translationIds` and should * return a string message for that given message id. */ - translateWithId: PropTypes.func.isRequired, -}; - -ListBoxSelection.defaultProps = { - translateWithId: (id) => defaultTranslations[id], + translateWithId: PropTypes.func, }; export default ListBoxSelection; diff --git a/packages/react/src/components/ListBox/next/ListBoxTrigger.js b/packages/react/src/components/ListBox/next/ListBoxTrigger.js index fa096abd7e1e..4e5f8e130c6f 100644 --- a/packages/react/src/components/ListBox/next/ListBoxTrigger.js +++ b/packages/react/src/components/ListBox/next/ListBoxTrigger.js @@ -21,11 +21,17 @@ const defaultTranslations = { [translationIds['open.menu']]: 'Open', }; +const defaultTranslateWithId = (id) => defaultTranslations[id]; + /** * `ListBoxTrigger` is used to orient the icon up or down depending on the * state of the menu for a given `ListBox` */ -const ListBoxTrigger = ({ isOpen, translateWithId: t, ...rest }) => { +const ListBoxTrigger = ({ + isOpen, + translateWithId: t = defaultTranslateWithId, + ...rest +}) => { const prefix = usePrefix(); const className = cx({ [`${prefix}--list-box__menu-icon`]: true, @@ -57,11 +63,7 @@ ListBoxTrigger.propTypes = { * icon. This function takes in an id defined in `translationIds` and should * return a string message for that given message id. */ - translateWithId: PropTypes.func.isRequired, -}; - -ListBoxTrigger.defaultProps = { - translateWithId: (id) => defaultTranslations[id], + translateWithId: PropTypes.func, }; export default ListBoxTrigger; diff --git a/packages/react/src/components/Modal/Modal.js b/packages/react/src/components/Modal/Modal.js index 5eca4542e223..8ade026277af 100644 --- a/packages/react/src/components/Modal/Modal.js +++ b/packages/react/src/components/Modal/Modal.js @@ -19,6 +19,7 @@ import wrapFocus, { import setupGetInstanceId from '../../tools/setupGetInstanceId'; import { usePrefix } from '../../internal/usePrefix'; import { keys, match } from '../../internal/keyboard'; +import { noopFn } from '../../internal/noopFn'; import { Text } from '../Text'; const getInstanceId = setupGetInstanceId(); @@ -28,27 +29,27 @@ const Modal = React.forwardRef(function Modal( 'aria-label': ariaLabelProp, children, className, - modalHeading, - modalLabel, + modalHeading = '', + modalLabel = '', modalAriaLabel, - passiveModal, + passiveModal = false, secondaryButtonText, primaryButtonText, open, - onRequestClose, - onRequestSubmit, + onRequestClose = noopFn, + onRequestSubmit = noopFn, onSecondarySubmit, - primaryButtonDisabled, + primaryButtonDisabled = false, danger, alert, secondaryButtons, - selectorPrimaryFocus, // eslint-disable-line - selectorsFloatingMenus, // eslint-disable-line - shouldSubmitOnEnter, // eslint-disable-line + selectorPrimaryFocus = '[data-modal-primary-focus]', + selectorsFloatingMenus, + shouldSubmitOnEnter, size, - hasScrollingContent, + hasScrollingContent = false, closeButtonLabel, - preventCloseOnClickOutside, // eslint-disable-line + preventCloseOnClickOutside = false, isFullWidth, launcherButtonRef, ...rest @@ -515,17 +516,4 @@ Modal.propTypes = { size: PropTypes.oneOf(['xs', 'sm', 'md', 'lg']), }; -Modal.defaultProps = { - onRequestClose: () => {}, - onRequestSubmit: () => {}, - primaryButtonDisabled: false, - onKeyDown: () => {}, - passiveModal: false, - modalHeading: '', - modalLabel: '', - preventCloseOnClickOutside: false, - selectorPrimaryFocus: '[data-modal-primary-focus]', - hasScrollingContent: false, -}; - export default Modal; diff --git a/packages/react/src/components/ModalWrapper/ModalWrapper.js b/packages/react/src/components/ModalWrapper/ModalWrapper.js index f6f23d66c31e..2d144e2b1df9 100644 --- a/packages/react/src/components/ModalWrapper/ModalWrapper.js +++ b/packages/react/src/components/ModalWrapper/ModalWrapper.js @@ -11,6 +11,7 @@ import Modal from '../Modal'; import Button from '../Button'; import { ButtonKinds } from '../../prop-types/types'; import { warning } from '../../internal/warning'; +import { noopFn } from '../../internal/noopFn'; let didWarnAboutDeprecation = false; @@ -52,18 +53,6 @@ export default class ModalWrapper extends React.Component { withHeader: PropTypes.bool, }; - static defaultProps = { - shouldCloseAfterSubmit: true, - primaryButtonText: 'Save', - secondaryButtonText: 'Cancel', - triggerButtonIconDescription: 'Provide icon description if icon is used', - triggerButtonKind: 'primary', - disabled: false, - preventCloseOnClickOutside: false, - selectorPrimaryFocus: '[data-modal-primary-focus]', - onKeyDown: () => {}, - }; - triggerButton = React.createRef(); modal = React.createRef(); @@ -107,17 +96,19 @@ export default class ModalWrapper extends React.Component { render() { const { children, - onKeyDown, + onKeyDown = noopFn, buttonTriggerText, buttonTriggerClassName, renderTriggerButtonIcon, - triggerButtonIconDescription, - triggerButtonKind, - disabled, + primaryButtonText = 'Save', + secondaryButtonText = 'Cancel', + triggerButtonIconDescription = 'Provide icon description if icon is used', + triggerButtonKind = 'primary', + disabled = false, handleSubmit, // eslint-disable-line no-unused-vars - shouldCloseAfterSubmit, // eslint-disable-line no-unused-vars - selectorPrimaryFocus, - preventCloseOnClickOutside, // eslint-disable-line no-unused-vars + shouldCloseAfterSubmit = true, // eslint-disable-line no-unused-vars + selectorPrimaryFocus = '[data-modal-primary-focus]', + preventCloseOnClickOutside = false, // eslint-disable-line no-unused-vars ...other } = this.props; @@ -148,7 +139,11 @@ export default class ModalWrapper extends React.Component { ref={this.triggerButton}> {buttonTriggerText} - + {children} diff --git a/packages/react/src/components/MultiSelect/FilterableMultiSelect.js b/packages/react/src/components/MultiSelect/FilterableMultiSelect.js index bda6384794e6..3e6cbd717a95 100644 --- a/packages/react/src/components/MultiSelect/FilterableMultiSelect.js +++ b/packages/react/src/components/MultiSelect/FilterableMultiSelect.js @@ -28,34 +28,34 @@ import { FormContext } from '../FluidForm'; const FilterableMultiSelect = React.forwardRef(function FilterableMultiSelect( { className: containerClassName, - clearSelectionDescription, - clearSelectionText, - compareItems, - direction, - disabled, + clearSelectionDescription = 'Total items selected: ', + clearSelectionText = 'To clear selection, press Delete or Backspace', + compareItems = defaultCompareItems, + direction = 'bottom', + disabled = false, downshiftProps, - filterItems, + filterItems = defaultFilterItems, helperText, hideLabel, id, - initialSelectedItems, + initialSelectedItems = [], invalid, invalidText, items, itemToElement: ItemToElement, // needs to be capitalized for react to render it correctly - itemToString, + itemToString = defaultItemToString, light, - locale, + locale = 'en', onInputValueChange, - open, + open = false, onChange, onMenuChange, placeholder, titleText, type, - selectionFeedback, + selectionFeedback = 'top-after-reopen', size, - sortItems, + sortItems = defaultSortItems, translateWithId, useTitleInItem, warn, @@ -680,19 +680,4 @@ FilterableMultiSelect.propTypes = { warnText: PropTypes.node, }; -FilterableMultiSelect.defaultProps = { - compareItems: defaultCompareItems, - direction: 'bottom', - disabled: false, - filterItems: defaultFilterItems, - initialSelectedItems: [], - itemToString: defaultItemToString, - locale: 'en', - sortItems: defaultSortItems, - open: false, - selectionFeedback: 'top-after-reopen', - clearSelectionText: 'To clear selection, press Delete or Backspace,', - clearSelectionDescription: 'Total items selected: ', -}; - export default FilterableMultiSelect; diff --git a/packages/react/src/components/MultiSelect/MultiSelect.stories.js b/packages/react/src/components/MultiSelect/MultiSelect.stories.js index 110cd24c44ee..12ab47b32807 100644 --- a/packages/react/src/components/MultiSelect/MultiSelect.stories.js +++ b/packages/react/src/components/MultiSelect/MultiSelect.stories.js @@ -142,7 +142,7 @@ Playground.args = { invalidText: 'whoopsie!', label: 'This is a label', clearSelectionDescription: 'Total items selected: ', - useTitleInItem: 'this is the item title', + useTitleInItem: false, clearSelectionText: 'To clear selection, press Delete or Backspace,', }; diff --git a/packages/react/src/components/MultiSelect/MultiSelect.tsx b/packages/react/src/components/MultiSelect/MultiSelect.tsx index 69b439a64dc3..1dd72c3c72e6 100644 --- a/packages/react/src/components/MultiSelect/MultiSelect.tsx +++ b/packages/react/src/components/MultiSelect/MultiSelect.tsx @@ -33,8 +33,8 @@ import { FormContext } from '../FluidForm'; import { ListBoxProps } from '../ListBox/ListBox'; import { OnChangeData } from '../Dropdown'; import type { InternationalProps } from '../../types/common'; +import { noopFn } from '../../internal/noopFn'; -const noop = () => {}; const getInstanceId = setupGetInstanceId(); const { ItemClick, @@ -98,7 +98,7 @@ interface MultiSelectSortingProps { item1: ItemType, item2: ItemType, options: SharedOptions - ): number; // required but has default value + ): number; /** * Provide a method that sorts all options in the control. Overriding this @@ -123,7 +123,7 @@ interface MultiSelectSortingProps { sortItems?( items: ReadonlyArray, options: SortItemsOptions - ): ItemType[]; // required but has default value + ): ItemType[]; } export interface MultiSelectProps @@ -304,18 +304,18 @@ const MultiSelect = React.forwardRef( items, itemToElement, itemToString = defaultItemToString, - titleText, + titleText = false, hideLabel, helperText, label, - type, + type = 'default', size, - disabled, - initialSelectedItems, - sortItems, - compareItems, - clearSelectionText, - clearSelectionDescription, + disabled = false, + initialSelectedItems = [], + sortItems = defaultSortItems as MultiSelectProps['sortItems'], + compareItems = defaultCompareItems, + clearSelectionText = 'To clear selection, press Delete or Backspace', + clearSelectionDescription = 'Total items selected: ', light, invalid, invalidText, @@ -324,14 +324,14 @@ const MultiSelect = React.forwardRef( useTitleInItem, translateWithId, downshiftProps, - open, - selectionFeedback, + open = false, + selectionFeedback = 'top-after-reopen', onChange, onMenuChange, - direction, + direction = 'bottom', selectedItems: selected, readOnly, - locale, + locale = 'en', }: MultiSelectProps, ref: ForwardedRef ) => { @@ -607,7 +607,9 @@ const MultiSelect = React.forwardRef( {selectedItems.length > 0 && ( Array */ - sortItems: PropTypes.func.isRequired, + sortItems: PropTypes.func, /** * Provide text to be used in a `