From 71c95963365d1cf29ddd63b526999166ed590dcd Mon Sep 17 00:00:00 2001 From: Nikhil Tomar <63502271+2nikhiltom@users.noreply.github.com> Date: Sat, 7 Sep 2024 22:20:01 +0530 Subject: [PATCH] fix(ts): adds types to next/ListBoxTrigger next/ListBoxSelection tsx (#17325) * fix(17292): rename .js to .tsx * fix(17292): convert ListBoxTigger and Selection to TS --- .../src/components/ComboBox/ComboBox.tsx | 1 - ...stBoxSelection.js => ListBoxSelection.tsx} | 78 ++++++++++++++-- .../components/ListBox/next/ListBoxTrigger.js | 70 --------------- .../ListBox/next/ListBoxTrigger.tsx | 90 +++++++++++++++++++ .../src/components/ListBox/next/index.js | 9 -- .../src/components/ListBox/next/index.ts | 15 ++++ .../MultiSelect/FilterableMultiSelect.tsx | 8 +- 7 files changed, 178 insertions(+), 93 deletions(-) rename packages/react/src/components/ListBox/next/{ListBoxSelection.js => ListBoxSelection.tsx} (58%) delete mode 100644 packages/react/src/components/ListBox/next/ListBoxTrigger.js create mode 100644 packages/react/src/components/ListBox/next/ListBoxTrigger.tsx delete mode 100644 packages/react/src/components/ListBox/next/index.js create mode 100644 packages/react/src/components/ListBox/next/index.ts diff --git a/packages/react/src/components/ComboBox/ComboBox.tsx b/packages/react/src/components/ComboBox/ComboBox.tsx index 8266ad21dbd8..eb26d126bbfe 100644 --- a/packages/react/src/components/ComboBox/ComboBox.tsx +++ b/packages/react/src/components/ComboBox/ComboBox.tsx @@ -887,7 +887,6 @@ const ComboBox = forwardRef( )} diff --git a/packages/react/src/components/ListBox/next/ListBoxSelection.js b/packages/react/src/components/ListBox/next/ListBoxSelection.tsx similarity index 58% rename from packages/react/src/components/ListBox/next/ListBoxSelection.js rename to packages/react/src/components/ListBox/next/ListBoxSelection.tsx index 1ecc3a5b743b..726c84810d8a 100644 --- a/packages/react/src/components/ListBox/next/ListBoxSelection.js +++ b/packages/react/src/components/ListBox/next/ListBoxSelection.tsx @@ -1,5 +1,5 @@ /** - * Copyright IBM Corp. 2016, 2023 + * Copyright IBM Corp. 2016, 2024 * * This source code is licensed under the Apache-2.0 license found in the * LICENSE file in the root directory of this source tree. @@ -20,14 +20,66 @@ import { usePrefix } from '../../../internal/usePrefix'; export const translationIds = { 'clear.all': 'clear.all', 'clear.selection': 'clear.selection', -}; +} as const; + +export type TranslationKey = keyof typeof translationIds; -const defaultTranslations = { - [translationIds['clear.all']]: 'Clear all selected items', - [translationIds['clear.selection']]: 'Clear selected item', +const defaultTranslations: Record = { + 'clear.all': 'Clear all selected items', + 'clear.selection': 'Clear selected item', }; -const defaultTranslateWithId = (id) => defaultTranslations[id]; +function defaultTranslateWithId(id: TranslationKey): string { + return defaultTranslations[id]; +} +export interface ListBoxSelectionProps { + /** + * Specify a function to be invoked when a user interacts with the clear + * selection element. + */ + clearSelection: ( + event: + | React.MouseEvent + | React.KeyboardEvent + ) => void; + /** + * Specify an optional `selectionCount` value that will be used to determine + * whether the selection should display a badge or a single clear icon. + */ + selectionCount?: number; + /** + * i18n hook used to provide the appropriate description for the given menu + * icon. This function takes in an id defined in `translationIds` and should + * return a string message for that given message id. + */ + translateWithId?: (id: TranslationKey) => string; + /** + * Specify whether or not the clear selection element should be disabled + */ + disabled?: boolean; + /** + * Specify an optional `onClearSelection` handler that is called when the underlying + * element is cleared + */ + onClearSelection?: (event: React.MouseEvent) => void; + /** + * Specify an optional `onClick` handler that is called when the underlying + * clear selection element is clicked + */ + onClick?: React.MouseEventHandler; + + /** + * Specify an optional `onKeyDown` handler that is called when the underlying + * clear selection element fires a keydown event + */ + onKeyDown?: React.KeyboardEventHandler; + + /** + * Specify an optional `onMouseUp` handler that is called when the underlying + * clear selection element fires a mouseup event + */ + onMouseUp?: React.MouseEventHandler; +} function ListBoxSelection({ clearSelection, @@ -36,7 +88,7 @@ function ListBoxSelection({ disabled, onClearSelection, ...rest -}) { +}: ListBoxSelectionProps) { const prefix = usePrefix(); const className = cx(`${prefix}--list-box__selection`, { [`${prefix}--tag--filter`]: selectionCount, @@ -52,7 +104,7 @@ function ListBoxSelection({ } ); - function onClick(event) { + function onClick(event: React.MouseEvent) { event.stopPropagation(); if (disabled) { return; @@ -66,7 +118,9 @@ function ListBoxSelection({ if (selectionCount) { return (
- + {selectionCount} - ); -}); - -ListBoxTrigger.propTypes = { - /** - * Specify whether the menu is currently open, which will influence the - * direction of the menu icon - */ - isOpen: PropTypes.bool.isRequired, - - /** - * i18n hook used to provide the appropriate description for the given menu - * icon. This function takes in an id defined in `translationIds` and should - * return a string message for that given message id. - */ - translateWithId: PropTypes.func, -}; - -export default ListBoxTrigger; diff --git a/packages/react/src/components/ListBox/next/ListBoxTrigger.tsx b/packages/react/src/components/ListBox/next/ListBoxTrigger.tsx new file mode 100644 index 000000000000..4e898168f486 --- /dev/null +++ b/packages/react/src/components/ListBox/next/ListBoxTrigger.tsx @@ -0,0 +1,90 @@ +/** + * Copyright IBM Corp. 2016, 2024 + * + * 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 cx from 'classnames'; +import React from 'react'; +import PropTypes from 'prop-types'; +import { ChevronDown } from '@carbon/icons-react'; +import { usePrefix } from '../../../internal/usePrefix'; + +export const translationIds = { + 'close.menu': 'close.menu', + 'open.menu': 'open.menu', +} as const; + +export type TranslationKey = keyof typeof translationIds; + +const defaultTranslations: Record = { + [translationIds['close.menu']]: 'Close', + [translationIds['open.menu']]: 'Open', +}; + +const defaultTranslateWithId = (id: TranslationKey): string => + defaultTranslations[id]; + +export interface ListBoxTriggerProps + extends React.ButtonHTMLAttributes { + /** + * Specify whether the menu is currently open, which will influence the + * direction of the menu icon + */ + isOpen: boolean; + /** + * i18n hook used to provide the appropriate description for the given menu + * icon. This function takes in an id defined in `translationIds` and should + * return a string message for that given message id. + */ + translateWithId?: (id: TranslationKey) => string; +} + +/** + * `ListBoxTrigger` is used to orient the icon up or down depending on the + * state of the menu for a given `ListBox` + */ + +const ListBoxTrigger = React.forwardRef( + function ListBoxTrigger( + { isOpen, translateWithId: t = defaultTranslateWithId, ...rest }, + ref + ) { + const prefix = usePrefix(); + const className = cx({ + [`${prefix}--list-box__menu-icon`]: true, + [`${prefix}--list-box__menu-icon--open`]: isOpen, + }); + const description = isOpen ? t('close.menu') : t('open.menu'); + return ( + + ); + } +); + +ListBoxTrigger.propTypes = { + /** + * Specify whether the menu is currently open, which will influence the + * direction of the menu icon + */ + isOpen: PropTypes.bool.isRequired, + + /** + * i18n hook used to provide the appropriate description for the given menu + * icon. This function takes in an id defined in `translationIds` and should + * return a string message for that given message id. + */ + translateWithId: PropTypes.func, +}; + +export default ListBoxTrigger; diff --git a/packages/react/src/components/ListBox/next/index.js b/packages/react/src/components/ListBox/next/index.js deleted file mode 100644 index 5dce83f7c589..000000000000 --- a/packages/react/src/components/ListBox/next/index.js +++ /dev/null @@ -1,9 +0,0 @@ -/** - * 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. - */ - -export { default as ListBoxSelection } from './ListBoxSelection'; -export { default as ListBoxTrigger } from './ListBoxTrigger'; diff --git a/packages/react/src/components/ListBox/next/index.ts b/packages/react/src/components/ListBox/next/index.ts new file mode 100644 index 000000000000..24b26e8e29de --- /dev/null +++ b/packages/react/src/components/ListBox/next/index.ts @@ -0,0 +1,15 @@ +/** + * Copyright IBM Corp. 2016, 2024 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +export { + default as ListBoxSelection, + type ListBoxSelectionProps, +} from './ListBoxSelection'; +export { + default as ListBoxTrigger, + type ListBoxTriggerProps, +} from './ListBoxTrigger'; diff --git a/packages/react/src/components/MultiSelect/FilterableMultiSelect.tsx b/packages/react/src/components/MultiSelect/FilterableMultiSelect.tsx index 93dbfd775561..e0a9a2def1f3 100644 --- a/packages/react/src/components/MultiSelect/FilterableMultiSelect.tsx +++ b/packages/react/src/components/MultiSelect/FilterableMultiSelect.tsx @@ -28,6 +28,7 @@ import React, { ForwardedRef, type FocusEvent, type KeyboardEvent, + type MouseEvent, ReactElement, useLayoutEffect, useMemo, @@ -650,7 +651,9 @@ const FilterableMultiSelect = React.forwardRef(function FilterableMultiSelect< } }); - function clearInputValue(event?: KeyboardEvent | undefined) { + function clearInputValue( + event?: KeyboardEvent | MouseEvent + ) { const value = textInput.current?.value; if (value?.length === 1 || (event && match(event, keys.Escape))) { setInputValue(''); @@ -832,7 +835,6 @@ const FilterableMultiSelect = React.forwardRef(function FilterableMultiSelect< className={`${prefix}--list-box__field`} ref={autoAlign ? refs.setReference : null}> {controlledSelectedItems.length > 0 && ( - // @ts-expect-error: It is expecting a non-required prop called: "onClearSelection" { clearSelection(); @@ -859,7 +861,6 @@ const FilterableMultiSelect = React.forwardRef(function FilterableMultiSelect< /> )} {inputValue && ( - // @ts-expect-error: It is expecting two non-required prop called: "onClearSelection" & "selectionCount"