From ff2a05867113605705b87e0caf3d4678b1341a97 Mon Sep 17 00:00:00 2001 From: mila2999 Date: Mon, 19 Feb 2024 19:34:16 +0200 Subject: [PATCH 01/18] chore: migrated Dropdown component mondaycom#1622 --- packages/core/package.json | 3 +- .../Dropdown/{Dropdown.jsx => Dropdown.tsx} | 546 +++++++++--------- 2 files changed, 265 insertions(+), 284 deletions(-) rename packages/core/src/components/Dropdown/{Dropdown.jsx => Dropdown.tsx} (78%) diff --git a/packages/core/package.json b/packages/core/package.json index c7d46a0ec9..e4d20a7440 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -118,7 +118,7 @@ "react-transition-group": "^4.4.5", "react-virtualized-auto-sizer": "^1.0.7", "react-window": "^1.8.7", - "react-windowed-select": "^2.0.4", + "react-windowed-select": "3.1.2", "style-inject": "^0.3.0", "vibe-storybook-components": "0.18.4" }, @@ -180,6 +180,7 @@ "@types/react-dates": "^21.8.3", "@types/react-is": "^16.7.5", "@types/react-resizable": "^3.0.7", + "@types/react-select": "^3.1.2", "@types/react-test-renderer": "^16.9.0", "@types/react-transition-group": "^4.4.5", "@types/react-virtualized-auto-sizer": "^1.0.1", diff --git a/packages/core/src/components/Dropdown/Dropdown.jsx b/packages/core/src/components/Dropdown/Dropdown.tsx similarity index 78% rename from packages/core/src/components/Dropdown/Dropdown.jsx rename to packages/core/src/components/Dropdown/Dropdown.tsx index 99ba6d3ba2..e1b5eb7528 100644 --- a/packages/core/src/components/Dropdown/Dropdown.jsx +++ b/packages/core/src/components/Dropdown/Dropdown.tsx @@ -28,8 +28,245 @@ import generateBaseStyles, { customTheme } from "./Dropdown.styles"; import Control from "./components/Control/Control"; import menuStyles from "./components/menu/menu.module.scss"; import styles from "./Dropdown.module.scss"; +import { VibeComponent, VibeComponentProps } from "src/types"; +import { IComboboxOption } from "../Combobox/components/ComboboxConstants"; -const Dropdown = forwardRef( +export interface DropdownComponentProps extends VibeComponentProps { + /** + * Custom style + */ + className?: string; + /** ClassName to be added to dropdown option wrapper (dropdown-wrapper__option--reset) */ + optionWrapperClassName?: string; + /** ClassName to be added to dropdown single value wrapper (dropdown-wrapper__single-value--reset) */ + singleValueWrapperClassName?: string; + /** ClassName to be added to dropdown menu wrapper (dropdown-menu-wrapper) */ + dropdownMenuWrapperClassName?: string; + /** + * Placeholder to show when no value was selected + */ + placeholder?: string; + /** + * If set to true, dropdown will be disabled + */ + disabled?: boolean; + /** + * If set to true, dropdown won't be editable + */ + readOnly?: boolean; + /** + * Called when menu is opened + */ + onMenuOpen?: () => void; + /** + * Called when menu is closed + */ + onMenuClose?: () => void; + /** + * Called when key is pressed in the dropdown + */ + onKeyDown?: (...args: unknown[]) => unknown; + /** + * Called when focused + */ + onFocus?: (...args: unknown[]) => unknown; + /** + * Called when blurred + */ + onBlur?: (...args: unknown[]) => unknown; + /** + * Called when selected value has changed + */ + onChange?: (...args: unknown[]) => unknown; + /** + * Called when the dropdown's input changes. + */ + onInputChange?: (...args: unknown[]) => unknown; + /** + * If true, search in options will be enabled + */ + searchable?: boolean; + /** + * The dropdown options + */ + options?: Record[]; + /** + * Text to display when there are no options + */ + noOptionsMessage: ((obj: { inputValue: string }) => React.ReactNode) | ((obj: { inputValue: string }) => void); + /** + * If set to true, the menu will open when focused + */ + openMenuOnFocus?: boolean; + /** + * If set to true, the menu will open when clicked + */ + openMenuOnClick?: boolean; + /** + * If set to true, clear button will be added + */ + clearable?: boolean; + /** + * custom option render function + */ + optionRenderer?: (option: IComboboxOption) => JSX.Element; + /** + * custom value render function + */ + valueRenderer?: (...args: unknown[]) => unknown; + ValueRenderer?: (...args: unknown[]) => unknown; + /** + * custom menu render function + */ + menuRenderer?: (...args: unknown[]) => unknown; + /** + * Default placement of the Dropdown menu in relation to its control. Use "auto" to flip the menu when there isn't enough space below the control. + */ + menuPlacement: any; + + // enum() PropTypes.oneOf(Object.values(DROPDOWN_MENU_PLACEMENT)), + /** + * The CSS position value of the menu, when "fixed" extra layout management might be required + * Fixed position can be used to solve the issue of positioning Dropdown inside overflow container like Modal or Dialog + */ + menuPosition: any; + /** + * If set to true, the dropdown will be in Right to Left mode + */ + rtl: boolean; + /** + * Set default selected value + */ + defaultValue: any; + /** + * The component's value. + * When passed, makes this a [controlled](https://reactjs.org/docs/forms.html#controlled-components) component. + */ + value: any; + /** + * Select menu size from `Dropdown.size` - Dropdown.sizes.LARGE | Dropdown.sizes.MEDIUM | Dropdown.sizes.SMALL + */ + size?: any; + /** + * If provided Dropdown will work in async mode. Can be either promise or callback + */ + asyncOptions: any; + /** + * If set to true, fetched async options will be cached + */ + cacheOptions: boolean; + /** + * If set, `asyncOptions` will be invoked with its value on mount and the resolved results will be loaded + */ + defaultOptions: boolean | Record[]; + /** + * If set to true, the menu will use virtualization. Virtualized async works only with + */ + isVirtualized: boolean; + /** + * Whether the menu should use a portal, and where it should attach + */ + menuPortalTarget: HTMLElement; + /** + * Custom function to override existing styles (similar to `react-select`'s `style` prop), for example: `base => ({...base, color: 'red'})`, where `base` is the component's default styles + */ + extraStyles: (...args: unknown[]) => unknown; + /** + * Maximum height of the menu before scrolling + */ + maxMenuHeight: number; + /** + * Tab index for keyboard navigation purposes + */ + tabIndex: number; + /** + * ID for the select container + */ + id: any; + /** + * focusAuto when component mount + */ + autoFocus: boolean; + /** + * If set to true, the dropdown will be in multi-select mode. + * When in multi-select mode, the selected value will be an array, + * and it will be displayed as our [``](/?path=/docs/components-chips--sandbox) component. + */ + multi: boolean; + /** + * If set to true together with `multi`, it will make the dropdown expand to multiple lines when new values are selected. + */ + multiline: boolean; + /** + Pass closeMenuOnSelect to close the multi choose any time an options is chosen. + */ + closeMenuOnSelect: boolean; + // Won't be needed once we upgrade to react-select ^5.5 https://github.com/JedWatson/react-select/issues/4088#issuecomment-1276835389 + /** + * If menu should be closed on scroll - helpful for some tricky use cases + * @default false, but true when insideOverflowContainer or insideOverflowWithTransformContainer are true + */ + closeMenuOnScroll: ((event: React.FocusEvent) => boolean) | boolean; + /** + * callback to be called when `multiline` is `true` and the option is removed + */ + onOptionRemove: (...args: unknown[]) => unknown; + /** + Pass Ref for reference of the actual dropdown component + */ + ref: React.ForwardedRef; + /** + The options set by default will be set as mandatory and the user will not be able to cancel their selection + */ + withMandatoryDefaultOptions: boolean; + /** + * Override the built-in logic to detect whether an option is selected. + */ + isOptionSelected: (option: unknown, selectValue: any) => boolean; + /** + * For display the drop down menu in overflow hidden/scroll container. + */ + insideOverflowContainer: boolean; + /** + * For display the drop down menu in overflow hidden/scroll container which contains transform css function usage. + */ + insideOverflowWithTransformContainer: boolean; + /** + * When content is passed, the dropdown will include a tooltip on the dropdown's value. + */ + tooltipContent: string; + /** + * Display the drop down with loading state. + */ + isLoading: boolean; + /** + * Overrides the built-in logic of loading message design + */ + loadingMessage: (obj: { inputValue: string }) => React.ReactNode; + /** + * aria-label attribute for dropdown + */ + ariaLabel: string; + /** + * Overrides the built-in logic of tab selecting value (default: true) + */ + tabSelectsValue: boolean; + /** + * Overrides the build-in search filter logic - https://react-select.com/advanced#custom-filter-logic + * createFilter function is available at Dropdown.createFilter + */ + filterOption: (option: any, inputValue: string) => boolean; + + withReadOnlyStyle?: boolean; + OptionRenderer?: (option: IComboboxOption) => JSX.Element; + menuIsOpen?: boolean; + onOptionSelect: (...args: unknown[]) => void; + onClear: (...args: unknown[]) => void; + popupsContainerSelector: string; + selectProps: Record; +} + +const Dropdown: VibeComponent = forwardRef( ( { className, @@ -136,7 +373,7 @@ const Dropdown = forwardRef( const inlineStyles = useMemo(() => { // We first want to get the default stylized groups (e.g. "container", "menu"). - const baseStyles = generateBaseStyles({ + const baseStyles: any = generateBaseStyles({ size, rtl, insideOverflowContainer, @@ -151,19 +388,19 @@ const Dropdown = forwardRef( const mergedStyles = Object.entries(customStyles).reduce((accumulator, [stylesGroup, stylesFn]) => { return { ...accumulator, - [stylesGroup]: (defaultStyles, state) => { + [stylesGroup]: (defaultStyles: any, state: any) => { const provided = baseStyles[stylesGroup] ? baseStyles[stylesGroup](defaultStyles, state) : defaultStyles; return stylesFn(provided, state); } }; - }, {}); + }, {} as any); if (multi) { if (multiline) { ADD_AUTO_HEIGHT_COMPONENTS.forEach(component => { const original = mergedStyles[component]; - mergedStyles[component] = (provided, state) => ({ + mergedStyles[component] = (provided: any, state: any) => ({ ...original(provided, state), height: "auto" }); @@ -171,7 +408,7 @@ const Dropdown = forwardRef( } const originalValueContainer = mergedStyles.valueContainer; - mergedStyles.valueContainer = (provided, state) => ({ + mergedStyles.valueContainer = (provided: any, state: any) => ({ ...originalValueContainer(provided, state), paddingLeft: 6 }); @@ -181,7 +418,7 @@ const Dropdown = forwardRef( }, [size, rtl, insideOverflowContainer, insideOverflowWithTransformContainer, extraStyles, multi, multiline]); const Menu = useCallback( - props => ( + (props: any) => ( , [size]); + const DropdownIndicator = useCallback( + (props: any) => , + [size] + ); const Option = useCallback( - props => ( + (props: any) => ( ), [finalOptionRenderer, optionWrapperClassName] ); const Input = useCallback( - props => , + (props: any) => , [menuId] ); const SingleValue = useCallback( - props => ( + (props: any) => ( , [size]); + const ClearIndicator = useCallback((props: any) => , [size]); const onOptionRemove = useMemo(() => { - return function (optionValue, e) { + return function (optionValue: any, e: any) { if (customOnOptionRemove) { customOnOptionRemove(selectedOptionsMap[optionValue]); } - const newSelectedOptions = selectedOptions.filter(option => option.value !== optionValue); + const newSelectedOptions = selectedOptions.filter((option: any) => option.value !== optionValue); if (customOnChange) { customOnChange(newSelectedOptions, e); } @@ -256,7 +496,7 @@ const Dropdown = forwardRef( popupsContainerSelector ] ); - const onChange = (option, event) => { + const onChange = (option: any, event: any) => { if (customOnChange) { customOnChange(option, event); } @@ -306,7 +546,7 @@ const Dropdown = forwardRef( }; const closeMenuOnScroll = useCallback( - event => { + (event: any) => { const scrolledElement = event.target; if (scrolledElement?.parentElement?.classList.contains(menuStyles.dropdownMenuWrapper)) { return false; @@ -329,15 +569,15 @@ const Dropdown = forwardRef( Control, SingleValue, ...(multi && { - MultiValue: NOOP, // We need it for react-select to behave nice with "multi" + MultiValue: NOOP as any, // We need it for react-select to behave nice with "multi" ValueContainer: MultiValueContainer }), ...(isVirtualized && { MenuList: WindowedMenuList }) }} // When inside scroll we set the menu position by js and we can't follow the drop down location while use scrolling - closeMenuOnScroll={closeMenuOnScroll} + closeMenuOnScroll={closeMenuOnScroll as any} size={size} - noOptionsMessage={noOptionsMessage} + noOptionsMessage={noOptionsMessage as any} placeholder={placeholder} isDisabled={disabled} isClearable={!readOnly && clearable} @@ -375,7 +615,7 @@ const Dropdown = forwardRef( data-testid={dataTestId || getTestId(ComponentDefaultTestId.DROPDOWN, id)} autoFocus={autoFocus} closeMenuOnSelect={closeMenuOnSelect} - ref={ref} + ref={ref as any} withMandatoryDefaultOptions={withMandatoryDefaultOptions} isOptionSelected={isOptionSelected} isLoading={isLoading} @@ -414,13 +654,13 @@ Dropdown.defaultProps = { onInputChange: NOOP, searchable: true, options: [], - menuPlacement: Dropdown.menuPlacements.BOTTOM, - menuPosition: Dropdown.menuPositions.ABSOLUTE, + menuPlacement: DROPDOWN_MENU_PLACEMENT.BOTTOM, + menuPosition: DROPDOWN_MENU_POSITION.ABSOLUTE, noOptionsMessage: NOOP, clearable: true, size: SIZES.MEDIUM, extraStyles: defaultCustomStyles, - tabIndex: "0", + tabIndex: 0, onOptionRemove: undefined, id: DROPDOWN_ID, menuId: DROPDOWN_MENU_ID, @@ -441,264 +681,4 @@ Dropdown.defaultProps = { filterOption: undefined }; -Dropdown.propTypes = { - /** - * Custom style - */ - className: PropTypes.string, - /** ClassName to be added to dropdown option wrapper (dropdown-wrapper__option--reset) */ - optionWrapperClassName: PropTypes.string, - /** ClassName to be added to dropdown single value wrapper (dropdown-wrapper__single-value--reset) */ - singleValueWrapperClassName: PropTypes.string, - /** ClassName to be added to dropdown menu wrapper (dropdown-menu-wrapper) */ - dropdownMenuWrapperClassName: PropTypes.string, - /** - * Placeholder to show when no value was selected - */ - placeholder: PropTypes.string, - /** - * If set to true, dropdown will be disabled - */ - disabled: PropTypes.bool, - /** - * If set to true, dropdown won't be editable - */ - readOnly: PropTypes.bool, - /** - * Called when menu is opened - */ - onMenuOpen: PropTypes.func, - /** - * Called when menu is closed - */ - onMenuClose: PropTypes.func, - /** - * Called when key is pressed in the dropdown - */ - onKeyDown: PropTypes.func, - /** - * Called when focused - */ - onFocus: PropTypes.func, - /** - * Called when blurred - */ - onBlur: PropTypes.func, - /** - * Called when selected value has changed - */ - onChange: PropTypes.func, - /** - * Called when the dropdown's input changes. - */ - onInputChange: PropTypes.func, - /** - * If true, search in options will be enabled - */ - searchable: PropTypes.bool, - /** - * The dropdown options - */ - options: PropTypes.arrayOf(PropTypes.object), - /** - * Text to display when there are no options - */ - noOptionsMessage: PropTypes.func, - /** - * If set to true, the menu will open when focused - */ - openMenuOnFocus: PropTypes.bool, - /** - * If set to true, the menu will open when clicked - */ - openMenuOnClick: PropTypes.bool, - /** - * If set to true, clear button will be added - */ - clearable: PropTypes.bool, - /** - * custom option render function - */ - optionRenderer: PropTypes.oneOfType([PropTypes.func, PropTypes.object]), - /** - * custom value render function - */ - valueRenderer: PropTypes.func, - /** - * custom menu render function - */ - menuRenderer: PropTypes.func, - /** - * Default placement of the Dropdown menu in relation to its control. Use "auto" to flip the menu when there isn't enough space below the control. - */ - menuPlacement: PropTypes.oneOf(Object.values(DROPDOWN_MENU_PLACEMENT)), - /** - * The CSS position value of the menu, when "fixed" extra layout management might be required - * Fixed position can be used to solve the issue of positioning Dropdown inside overflow container like Modal or Dialog - */ - menuPosition: PropTypes.oneOf(Object.values(DROPDOWN_MENU_POSITION)), - /** - * If set to true, the dropdown will be in Right to Left mode - */ - rtl: PropTypes.bool, - /** - * Set default selected value - */ - defaultValue: PropTypes.oneOfType([ - PropTypes.arrayOf( - PropTypes.shape({ - label: PropTypes.string.isRequired, - value: PropTypes.string.isRequired - }) - ), - PropTypes.shape({ - label: PropTypes.string.isRequired, - value: PropTypes.string.isRequired - }) - ]), - /** - * The component's value. - * When passed, makes this a [controlled](https://reactjs.org/docs/forms.html#controlled-components) component. - */ - value: PropTypes.oneOfType([ - PropTypes.arrayOf( - PropTypes.shape({ - label: PropTypes.string.isRequired, - value: PropTypes.string.isRequired - }) - ), - PropTypes.shape({ - label: PropTypes.string.isRequired, - value: PropTypes.string.isRequired - }) - ]), - /** - * Select menu size from `Dropdown.size` - Dropdown.sizes.LARGE | Dropdown.sizes.MEDIUM | Dropdown.sizes.SMALL - */ - size: PropTypes.string, - /** - * If provided Dropdown will work in async mode. Can be either promise or callback - */ - asyncOptions: PropTypes.oneOfType([ - PropTypes.func, // callback - PropTypes.shape({ - then: PropTypes.func.isRequired, - catch: PropTypes.func.isRequired - }) // Promise - ]), - /** - * If set to true, fetched async options will be cached - */ - cacheOptions: PropTypes.bool, - /** - * If set, `asyncOptions` will be invoked with its value on mount and the resolved results will be loaded - */ - defaultOptions: PropTypes.oneOfType([PropTypes.bool, PropTypes.arrayOf(PropTypes.object)]), - /** - * If set to true, the menu will use virtualization. Virtualized async works only with - */ - isVirtualized: PropTypes.bool, - /** - * Whether the menu should use a portal, and where it should attach - */ - menuPortalTarget: PropTypes.oneOfType([PropTypes.element, PropTypes.object]), - /** - * Custom function to override existing styles (similar to `react-select`'s `style` prop), for example: `base => ({...base, color: 'red'})`, where `base` is the component's default styles - */ - extraStyles: PropTypes.func, - /** - * Maximum height of the menu before scrolling - */ - maxMenuHeight: PropTypes.number, - /** - * Tab index for keyboard navigation purposes - */ - tabIndex: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), - /** - * ID for the select container - */ - id: PropTypes.string, - /** - * ID for the menu container - */ - menuId: PropTypes.string, - /** - * aria-label attribute for the menu container - */ - menuAriaLabel: PropTypes.string, - /** - * focusAuto when component mount - */ - autoFocus: PropTypes.bool, - /** - * If set to true, the dropdown will be in multi-select mode. - * When in multi-select mode, the selected value will be an array, - * and it will be displayed as our [``](/?path=/docs/components-chips--sandbox) component. - */ - multi: PropTypes.bool, - /** - * If set to true together with `multi`, it will make the dropdown expand to multiple lines when new values are selected. - */ - multiline: PropTypes.bool, - /** - Pass closeMenuOnSelect to close the multi choose any time an options is chosen. - */ - closeMenuOnSelect: PropTypes.bool, - // Won't be needed once we upgrade to react-select ^5.5 https://github.com/JedWatson/react-select/issues/4088#issuecomment-1276835389 - /** - * If menu should be closed on scroll - helpful for some tricky use cases - * @default false, but true when insideOverflowContainer or insideOverflowWithTransformContainer are true - */ - closeMenuOnScroll: PropTypes.bool, - /** - * callback to be called when `multiline` is `true` and the option is removed - */ - onOptionRemove: PropTypes.func, - /** - Pass Ref for reference of the actual dropdown component - */ - ref: PropTypes.func, - /** - The options set by default will be set as mandatory and the user will not be able to cancel their selection - */ - withMandatoryDefaultOptions: PropTypes.bool, - /** - * Override the built-in logic to detect whether an option is selected. - */ - isOptionSelected: PropTypes.func, - /** - * Allows the dropdown menu to overflow its container. - */ - insideOverflowContainer: PropTypes.bool, - /** - * Allows the dropdown menu to overflow its container, including CSS transformations. - */ - insideOverflowWithTransformContainer: PropTypes.bool, - /** - * When content is passed, the dropdown will include a tooltip on the dropdown's value. - */ - tooltipContent: PropTypes.string, - /** - * Display the drop down with loading state. - */ - isLoading: PropTypes.bool, - /** - * Overrides the built-in logic of loading message design - */ - loadingMessage: PropTypes.func, - /** - * aria-label attribute for dropdown - */ - ariaLabel: PropTypes.string, - /** - * Overrides the built-in logic of tab selecting value (default: true) - */ - tabSelectsValue: PropTypes.bool, - /** - * Overrides the build-in search filter logic - https://react-select.com/advanced#custom-filter-logic - * createFilter function is available at Dropdown.createFilter - */ - filterOption: PropTypes.oneOfType([PropTypes.func, PropTypes.object]) -}; - export default Dropdown; From e4e07d97618e53a10ec25b6a21bf76123523f441 Mon Sep 17 00:00:00 2001 From: mila2999 Date: Mon, 19 Feb 2024 20:40:09 +0200 Subject: [PATCH 02/18] chore: fixing options types for tests --- packages/core/src/components/Dropdown/Dropdown.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/components/Dropdown/Dropdown.tsx b/packages/core/src/components/Dropdown/Dropdown.tsx index e1b5eb7528..afb73934ae 100644 --- a/packages/core/src/components/Dropdown/Dropdown.tsx +++ b/packages/core/src/components/Dropdown/Dropdown.tsx @@ -89,7 +89,7 @@ export interface DropdownComponentProps extends VibeComponentProps { /** * The dropdown options */ - options?: Record[]; + options?: any; /** * Text to display when there are no options */ From 42c3ca607213e701f82e1f0507306d0c114fc6e0 Mon Sep 17 00:00:00 2001 From: mila2999 Date: Mon, 19 Feb 2024 21:19:39 +0200 Subject: [PATCH 03/18] chore: fixing build issues --- .../core/src/components/Dropdown/Dropdown.tsx | 74 +++++++++---------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/packages/core/src/components/Dropdown/Dropdown.tsx b/packages/core/src/components/Dropdown/Dropdown.tsx index afb73934ae..d5143790a6 100644 --- a/packages/core/src/components/Dropdown/Dropdown.tsx +++ b/packages/core/src/components/Dropdown/Dropdown.tsx @@ -93,7 +93,7 @@ export interface DropdownComponentProps extends VibeComponentProps { /** * Text to display when there are no options */ - noOptionsMessage: ((obj: { inputValue: string }) => React.ReactNode) | ((obj: { inputValue: string }) => void); + noOptionsMessage?: any; /** * If set to true, the menu will open when focused */ @@ -122,27 +122,27 @@ export interface DropdownComponentProps extends VibeComponentProps { /** * Default placement of the Dropdown menu in relation to its control. Use "auto" to flip the menu when there isn't enough space below the control. */ - menuPlacement: any; + menuPlacement?: any; // enum() PropTypes.oneOf(Object.values(DROPDOWN_MENU_PLACEMENT)), /** * The CSS position value of the menu, when "fixed" extra layout management might be required * Fixed position can be used to solve the issue of positioning Dropdown inside overflow container like Modal or Dialog */ - menuPosition: any; + menuPosition?: any; /** * If set to true, the dropdown will be in Right to Left mode */ - rtl: boolean; + rtl?: boolean; /** * Set default selected value */ - defaultValue: any; + defaultValue?: any; /** * The component's value. * When passed, makes this a [controlled](https://reactjs.org/docs/forms.html#controlled-components) component. */ - value: any; + value?: any; /** * Select menu size from `Dropdown.size` - Dropdown.sizes.LARGE | Dropdown.sizes.MEDIUM | Dropdown.sizes.SMALL */ @@ -150,120 +150,120 @@ export interface DropdownComponentProps extends VibeComponentProps { /** * If provided Dropdown will work in async mode. Can be either promise or callback */ - asyncOptions: any; + asyncOptions?: any; /** * If set to true, fetched async options will be cached */ - cacheOptions: boolean; + cacheOptions?: boolean; /** * If set, `asyncOptions` will be invoked with its value on mount and the resolved results will be loaded */ - defaultOptions: boolean | Record[]; + defaultOptions?: boolean | Record[]; /** * If set to true, the menu will use virtualization. Virtualized async works only with */ - isVirtualized: boolean; + isVirtualized?: boolean; /** * Whether the menu should use a portal, and where it should attach */ - menuPortalTarget: HTMLElement; + menuPortalTarget?: HTMLElement; /** * Custom function to override existing styles (similar to `react-select`'s `style` prop), for example: `base => ({...base, color: 'red'})`, where `base` is the component's default styles */ - extraStyles: (...args: unknown[]) => unknown; + extraStyles?: (...args: unknown[]) => unknown; /** * Maximum height of the menu before scrolling */ - maxMenuHeight: number; + maxMenuHeight?: number; /** * Tab index for keyboard navigation purposes */ - tabIndex: number; + tabIndex?: number; /** * ID for the select container */ - id: any; + id?: any; /** * focusAuto when component mount */ - autoFocus: boolean; + autoFocus?: boolean; /** * If set to true, the dropdown will be in multi-select mode. * When in multi-select mode, the selected value will be an array, * and it will be displayed as our [``](/?path=/docs/components-chips--sandbox) component. */ - multi: boolean; + multi?: boolean; /** * If set to true together with `multi`, it will make the dropdown expand to multiple lines when new values are selected. */ - multiline: boolean; + multiline?: boolean; /** Pass closeMenuOnSelect to close the multi choose any time an options is chosen. */ - closeMenuOnSelect: boolean; + closeMenuOnSelect?: boolean; // Won't be needed once we upgrade to react-select ^5.5 https://github.com/JedWatson/react-select/issues/4088#issuecomment-1276835389 /** * If menu should be closed on scroll - helpful for some tricky use cases * @default false, but true when insideOverflowContainer or insideOverflowWithTransformContainer are true */ - closeMenuOnScroll: ((event: React.FocusEvent) => boolean) | boolean; + closeMenuOnScroll?: ((event: React.FocusEvent) => boolean) | boolean; /** * callback to be called when `multiline` is `true` and the option is removed */ - onOptionRemove: (...args: unknown[]) => unknown; + onOptionRemove?: (...args: unknown[]) => unknown; /** Pass Ref for reference of the actual dropdown component */ - ref: React.ForwardedRef; + ref?: React.ForwardedRef; /** The options set by default will be set as mandatory and the user will not be able to cancel their selection */ - withMandatoryDefaultOptions: boolean; + withMandatoryDefaultOptions?: boolean; /** * Override the built-in logic to detect whether an option is selected. */ - isOptionSelected: (option: unknown, selectValue: any) => boolean; + isOptionSelected?: (option: unknown, selectValue: any) => boolean; /** * For display the drop down menu in overflow hidden/scroll container. */ - insideOverflowContainer: boolean; + insideOverflowContainer?: boolean; /** * For display the drop down menu in overflow hidden/scroll container which contains transform css function usage. */ - insideOverflowWithTransformContainer: boolean; + insideOverflowWithTransformContainer?: boolean; /** * When content is passed, the dropdown will include a tooltip on the dropdown's value. */ - tooltipContent: string; + tooltipContent?: string; /** * Display the drop down with loading state. */ - isLoading: boolean; + isLoading?: boolean; /** * Overrides the built-in logic of loading message design */ - loadingMessage: (obj: { inputValue: string }) => React.ReactNode; + loadingMessage?: (obj: { inputValue: string }) => React.ReactNode; /** * aria-label attribute for dropdown */ - ariaLabel: string; + ariaLabel?: string; /** * Overrides the built-in logic of tab selecting value (default: true) */ - tabSelectsValue: boolean; + tabSelectsValue?: boolean; /** * Overrides the build-in search filter logic - https://react-select.com/advanced#custom-filter-logic * createFilter function is available at Dropdown.createFilter */ - filterOption: (option: any, inputValue: string) => boolean; + filterOption?: (option: any, inputValue: string) => boolean; withReadOnlyStyle?: boolean; OptionRenderer?: (option: IComboboxOption) => JSX.Element; menuIsOpen?: boolean; - onOptionSelect: (...args: unknown[]) => void; - onClear: (...args: unknown[]) => void; - popupsContainerSelector: string; - selectProps: Record; + onOptionSelect?: (...args: unknown[]) => void; + onClear?: (...args: unknown[]) => void; + popupsContainerSelector?: string; + selectProps?: Record; } const Dropdown: VibeComponent = forwardRef( @@ -528,7 +528,7 @@ const Dropdown: VibeComponent = forwardR } }; - const DropDownComponent = asyncOptions ? AsyncSelect : Select; + const DropDownComponent: any = asyncOptions ? AsyncSelect : Select; const asyncAdditions = { ...(asyncOptions && { From 6bf1b730971c40b78010c05b3743fa624fdfe713 Mon Sep 17 00:00:00 2001 From: mila2999 Date: Wed, 21 Feb 2024 20:05:04 +0200 Subject: [PATCH 04/18] chore:working on types --- .../core/src/components/Dropdown/Dropdown.tsx | 15 ++++---- .../components/Dropdown/DropdownConstants.tsx | 35 +++++++++++++++++++ 2 files changed, 43 insertions(+), 7 deletions(-) create mode 100644 packages/core/src/components/Dropdown/DropdownConstants.tsx diff --git a/packages/core/src/components/Dropdown/Dropdown.tsx b/packages/core/src/components/Dropdown/Dropdown.tsx index d5143790a6..7ff99c37b2 100644 --- a/packages/core/src/components/Dropdown/Dropdown.tsx +++ b/packages/core/src/components/Dropdown/Dropdown.tsx @@ -18,11 +18,12 @@ import { ADD_AUTO_HEIGHT_COMPONENTS, defaultCustomStyles, DROPDOWN_CHIP_COLORS, - DROPDOWN_ID, + DROPDOWN_MENU, DROPDOWN_MENU_ID, DROPDOWN_MENU_ARIA_LABEL, DROPDOWN_MENU_PLACEMENT, - DROPDOWN_MENU_POSITION + DROPDOWN_MENU_POSITION, + DropdownDefaultValue } from "./DropdownConstants"; import generateBaseStyles, { customTheme } from "./Dropdown.styles"; import Control from "./components/Control/Control"; @@ -89,11 +90,11 @@ export interface DropdownComponentProps extends VibeComponentProps { /** * The dropdown options */ - options?: any; + options?: DropdownDefaultValue[]; /** * Text to display when there are no options */ - noOptionsMessage?: any; + noOptionsMessage?: (() => string) | typeof NOOP; /** * If set to true, the menu will open when focused */ @@ -122,7 +123,7 @@ export interface DropdownComponentProps extends VibeComponentProps { /** * Default placement of the Dropdown menu in relation to its control. Use "auto" to flip the menu when there isn't enough space below the control. */ - menuPlacement?: any; + menuPlacement?: DROPDOWN_MENU_PLACEMENT; // enum() PropTypes.oneOf(Object.values(DROPDOWN_MENU_PLACEMENT)), /** @@ -398,7 +399,7 @@ const Dropdown: VibeComponent = forwardR if (multi) { if (multiline) { - ADD_AUTO_HEIGHT_COMPONENTS.forEach(component => { + Object.values(ADD_AUTO_HEIGHT_COMPONENTS).forEach(component => { const original = mergedStyles[component]; mergedStyles[component] = (provided: any, state: any) => ({ ...original(provided, state), @@ -662,7 +663,7 @@ Dropdown.defaultProps = { extraStyles: defaultCustomStyles, tabIndex: 0, onOptionRemove: undefined, - id: DROPDOWN_ID, + id: DROPDOWN_MENU.ID, menuId: DROPDOWN_MENU_ID, menuAriaLabel: DROPDOWN_MENU_ARIA_LABEL, autoFocus: false, diff --git a/packages/core/src/components/Dropdown/DropdownConstants.tsx b/packages/core/src/components/Dropdown/DropdownConstants.tsx new file mode 100644 index 0000000000..4ac27c1bc6 --- /dev/null +++ b/packages/core/src/components/Dropdown/DropdownConstants.tsx @@ -0,0 +1,35 @@ +import { Theme } from "../ThemeProvider/ThemeProviderConstants"; + +export const defaultCustomStyles = (baseStyles: string) => baseStyles; + +export enum ADD_AUTO_HEIGHT_COMPONENTS { + CONTAINER = "container", + CONTROL = "control", + VALUE_CONTAINER = "valueContainer" +} + +export enum DROPDOWN_MENU { + ID = "dropdown-menu-id" +} + +export enum DROPDOWN_CHIP_COLORS { + PRIMARY = "PRIMARY", + NEGATIVE = "NEGATIVE", + POSITIVE = "POSITIVE" +} + +export enum DROPDOWN_MENU_POSITION { + ABSOLUTE = "absolute", + FIXED = "fixed" +} + +export enum DROPDOWN_MENU_PLACEMENT { + TOP = "top", + BOTTOM = "bottom", + AUTO = "auto" +} + +export type DropdownDefaultValue = { + label: string; + value: string | number | Theme; +}; From bcbee2fb7c4e1c4a2e3868f47893668774bbcbbf Mon Sep 17 00:00:00 2001 From: mila2999 Date: Wed, 21 Feb 2024 20:39:32 +0200 Subject: [PATCH 05/18] chore: working on types --- .../core/src/components/Dropdown/Dropdown.tsx | 35 +++++++++++-------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/packages/core/src/components/Dropdown/Dropdown.tsx b/packages/core/src/components/Dropdown/Dropdown.tsx index 7ff99c37b2..2134159b28 100644 --- a/packages/core/src/components/Dropdown/Dropdown.tsx +++ b/packages/core/src/components/Dropdown/Dropdown.tsx @@ -1,7 +1,7 @@ /* eslint-disable react/require-default-props,react/forbid-prop-types */ import { ComponentDefaultTestId, getTestId } from "../../tests/test-ids-utils"; import cx from "classnames"; -import { SIZES } from "../../constants/sizes"; +import { BaseSizes, SIZES } from "../../constants/sizes"; import { forwardRef, useCallback, useMemo, useRef, useState } from "react"; import Select, { components, createFilter } from "react-select"; import AsyncSelect from "react-select/async"; @@ -130,7 +130,7 @@ export interface DropdownComponentProps extends VibeComponentProps { * The CSS position value of the menu, when "fixed" extra layout management might be required * Fixed position can be used to solve the issue of positioning Dropdown inside overflow container like Modal or Dialog */ - menuPosition?: any; + menuPosition?: DROPDOWN_MENU_POSITION; /** * If set to true, the dropdown will be in Right to Left mode */ @@ -138,20 +138,20 @@ export interface DropdownComponentProps extends VibeComponentProps { /** * Set default selected value */ - defaultValue?: any; + defaultValue?: DropdownDefaultValue[]; /** * The component's value. * When passed, makes this a [controlled](https://reactjs.org/docs/forms.html#controlled-components) component. */ - value?: any; + value?: DropdownDefaultValue[]; /** * Select menu size from `Dropdown.size` - Dropdown.sizes.LARGE | Dropdown.sizes.MEDIUM | Dropdown.sizes.SMALL */ - size?: any; + size?: BaseSizes; /** * If provided Dropdown will work in async mode. Can be either promise or callback */ - asyncOptions?: any; + asyncOptions?: (inputValue: string) => Promise; /** * If set to true, fetched async options will be cached */ @@ -183,7 +183,7 @@ export interface DropdownComponentProps extends VibeComponentProps { /** * ID for the select container */ - id?: any; + id?: DROPDOWN_MENU.ID; /** * focusAuto when component mount */ @@ -256,7 +256,7 @@ export interface DropdownComponentProps extends VibeComponentProps { * Overrides the build-in search filter logic - https://react-select.com/advanced#custom-filter-logic * createFilter function is available at Dropdown.createFilter */ - filterOption?: (option: any, inputValue: string) => boolean; + filterOption?: (option: unknown, inputValue: string) => boolean; withReadOnlyStyle?: boolean; OptionRenderer?: (option: IComboboxOption) => JSX.Element; @@ -344,7 +344,7 @@ const Dropdown: VibeComponent = forwardR if (defaultValue) { return Array.isArray(defaultValue) ? defaultValue.map(df => ({ ...df, isMandatory: true })) - : { ...defaultValue, isMandatory: true }; + : { ...(defaultValue as DropdownDefaultValue), isMandatory: true }; } return defaultValue; @@ -357,7 +357,10 @@ const Dropdown: VibeComponent = forwardR const selectedOptions = customValue ?? selected; const selectedOptionsMap = useMemo(() => { if (Array.isArray(selectedOptions)) { - return selectedOptions.reduce((acc, option) => ({ ...acc, [option.value]: option }), {}); + return selectedOptions.reduce( + (acc, option) => ({ ...acc, [option.value as DropdownDefaultValue["label"]]: option }), + {} + ); } return {}; }, [selectedOptions]); @@ -454,7 +457,7 @@ const Dropdown: VibeComponent = forwardR {...props} readOnly={readOnly} Renderer={finalValueRenderer} - selectedOption={selectedOptions[0]} + selectedOption={(selectedOptions as DropdownDefaultValue[])[0]} singleValueWrapperClassName={singleValueWrapperClassName} /> ), @@ -466,9 +469,11 @@ const Dropdown: VibeComponent = forwardR const onOptionRemove = useMemo(() => { return function (optionValue: any, e: any) { if (customOnOptionRemove) { - customOnOptionRemove(selectedOptionsMap[optionValue]); + customOnOptionRemove((selectedOptionsMap as DropdownDefaultValue[])[optionValue]); } - const newSelectedOptions = selectedOptions.filter((option: any) => option.value !== optionValue); + const newSelectedOptions = (selectedOptions as DropdownDefaultValue[]).filter( + option => option.value !== optionValue + ); if (customOnChange) { customOnChange(newSelectedOptions, e); } @@ -511,7 +516,7 @@ const Dropdown: VibeComponent = forwardR } if (!isControlled) { - setSelected([...selectedOptions, selectedOption]); + setSelected([...(selectedOptions as DropdownDefaultValue[]), selectedOption]); } break; } @@ -659,7 +664,7 @@ Dropdown.defaultProps = { menuPosition: DROPDOWN_MENU_POSITION.ABSOLUTE, noOptionsMessage: NOOP, clearable: true, - size: SIZES.MEDIUM, + size: BaseSizes.MEDIUM, extraStyles: defaultCustomStyles, tabIndex: 0, onOptionRemove: undefined, From 2b243ce7db053d0500331b438190be00801ad98f Mon Sep 17 00:00:00 2001 From: mila2999 Date: Wed, 21 Feb 2024 21:17:22 +0200 Subject: [PATCH 06/18] Working on fixing types --- packages/core/src/components/Dropdown/Dropdown.tsx | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/packages/core/src/components/Dropdown/Dropdown.tsx b/packages/core/src/components/Dropdown/Dropdown.tsx index 2134159b28..c44166db6f 100644 --- a/packages/core/src/components/Dropdown/Dropdown.tsx +++ b/packages/core/src/components/Dropdown/Dropdown.tsx @@ -3,7 +3,7 @@ import { ComponentDefaultTestId, getTestId } from "../../tests/test-ids-utils"; import cx from "classnames"; import { BaseSizes, SIZES } from "../../constants/sizes"; import { forwardRef, useCallback, useMemo, useRef, useState } from "react"; -import Select, { components, createFilter } from "react-select"; +import Select, { MenuProps, OptionsType, components, createFilter } from "react-select"; import AsyncSelect from "react-select/async"; import { noop as NOOP } from "lodash-es"; import { WindowedMenuList } from "react-windowed-select"; @@ -31,6 +31,12 @@ import menuStyles from "./components/menu/menu.module.scss"; import styles from "./Dropdown.module.scss"; import { VibeComponent, VibeComponentProps } from "src/types"; import { IComboboxOption } from "../Combobox/components/ComboboxConstants"; +import { Option } from "react-select/src/filters"; + +interface CustomMenuProps extends MenuProps { + Renderer: React.ComponentType; + dropdownMenuWrapperClassName: string; +} export interface DropdownComponentProps extends VibeComponentProps { /** @@ -422,7 +428,7 @@ const Dropdown: VibeComponent = forwardR }, [size, rtl, insideOverflowContainer, insideOverflowWithTransformContainer, extraStyles, multi, multiline]); const Menu = useCallback( - (props: any) => ( + (props: CustomMenuProps) => ( = forwardR ); const DropdownIndicator = useCallback( - (props: any) => , + (props: { size: string }) => , [size] ); From e5d5fa66520470f72b12d047925fb700f1fd70e8 Mon Sep 17 00:00:00 2001 From: mila2999 Date: Thu, 22 Feb 2024 00:17:20 +0200 Subject: [PATCH 07/18] Working on fixing types --- .../core/src/components/Dropdown/Dropdown.tsx | 94 +++++++++++++------ .../components/Dropdown/DropdownConstants.tsx | 1 + 2 files changed, 65 insertions(+), 30 deletions(-) diff --git a/packages/core/src/components/Dropdown/Dropdown.tsx b/packages/core/src/components/Dropdown/Dropdown.tsx index c44166db6f..d8856e3d05 100644 --- a/packages/core/src/components/Dropdown/Dropdown.tsx +++ b/packages/core/src/components/Dropdown/Dropdown.tsx @@ -1,13 +1,12 @@ /* eslint-disable react/require-default-props,react/forbid-prop-types */ import { ComponentDefaultTestId, getTestId } from "../../tests/test-ids-utils"; import cx from "classnames"; -import { BaseSizes, SIZES } from "../../constants/sizes"; -import { forwardRef, useCallback, useMemo, useRef, useState } from "react"; -import Select, { MenuProps, OptionsType, components, createFilter } from "react-select"; +import { BaseSizes, SIZES, SIZES_VALUES } from "../../constants/sizes"; +import React, { forwardRef, useCallback, useMemo, useRef, useState } from "react"; +import Select, { InputProps, MenuProps, OptionProps, SingleValueProps, components, createFilter } from "react-select"; import AsyncSelect from "react-select/async"; import { noop as NOOP } from "lodash-es"; import { WindowedMenuList } from "react-windowed-select"; -import PropTypes from "prop-types"; import MenuComponent from "./components/menu/menu"; import DropdownIndicatorComponent from "./components/DropdownIndicator/DropdownIndicator"; import OptionComponent from "./components/option/option"; @@ -32,12 +31,36 @@ import styles from "./Dropdown.module.scss"; import { VibeComponent, VibeComponentProps } from "src/types"; import { IComboboxOption } from "../Combobox/components/ComboboxConstants"; import { Option } from "react-select/src/filters"; +import { HtmlAttributes } from "csstype"; +import { RefObject } from "preact"; + +interface CustomSingleValueProps extends SingleValueProps { + Renderer: React.ComponentType; + readOnly: boolean; + selectedOption: DropdownDefaultValue; + singleVueWrapperClassName?: string; +} interface CustomMenuProps extends MenuProps { Renderer: React.ComponentType; dropdownMenuWrapperClassName: string; } +interface CustomOptionProps extends OptionProps { + Renderer: React.ComponentType; + optionWrapperClassName?: string; +} + +type SelectEvent = { + action: "select-option" | "clear"; + option?: DropdownDefaultValue; +}; + +type DropdownState = { + isDisabled: boolean; + selectProps: { withReadOnlyStyle: boolean; readOnly: boolean }; +}; + export interface DropdownComponentProps extends VibeComponentProps { /** * Custom style @@ -229,7 +252,7 @@ export interface DropdownComponentProps extends VibeComponentProps { /** * Override the built-in logic to detect whether an option is selected. */ - isOptionSelected?: (option: unknown, selectValue: any) => boolean; + isOptionSelected?: (option: DropdownDefaultValue, selectValue: DropdownDefaultValue["value"]) => boolean; /** * For display the drop down menu in overflow hidden/scroll container. */ @@ -365,10 +388,10 @@ const Dropdown: VibeComponent = forwardR if (Array.isArray(selectedOptions)) { return selectedOptions.reduce( (acc, option) => ({ ...acc, [option.value as DropdownDefaultValue["label"]]: option }), - {} + {} as DropdownDefaultValue ); } - return {}; + return {} as DropdownDefaultValue; }, [selectedOptions]); const overrideAriaLabel = useMemo(() => { @@ -383,7 +406,7 @@ const Dropdown: VibeComponent = forwardR const inlineStyles = useMemo(() => { // We first want to get the default stylized groups (e.g. "container", "menu"). - const baseStyles: any = generateBaseStyles({ + const baseStyles = generateBaseStyles({ size, rtl, insideOverflowContainer, @@ -391,6 +414,8 @@ const Dropdown: VibeComponent = forwardR insideOverflowWithTransformContainer }); + type BaseStyles = typeof baseStyles; + // Then we want to run the consumer's root-level custom styles with our "base" override groups. const customStyles = extraStyles(baseStyles); @@ -398,19 +423,20 @@ const Dropdown: VibeComponent = forwardR const mergedStyles = Object.entries(customStyles).reduce((accumulator, [stylesGroup, stylesFn]) => { return { ...accumulator, - [stylesGroup]: (defaultStyles: any, state: any) => { - const provided = baseStyles[stylesGroup] ? baseStyles[stylesGroup](defaultStyles, state) : defaultStyles; + [stylesGroup]: (defaultStyles: BaseStyles, state: DropdownState) => { + const providedFn = baseStyles[stylesGroup as keyof BaseStyles]; + const provided = providedFn ? providedFn(defaultStyles, state) : defaultStyles; return stylesFn(provided, state); } }; - }, {} as any); + }, {} as BaseStyles); if (multi) { if (multiline) { Object.values(ADD_AUTO_HEIGHT_COMPONENTS).forEach(component => { const original = mergedStyles[component]; - mergedStyles[component] = (provided: any, state: any) => ({ + mergedStyles[component] = (provided: BaseStyles, state: DropdownState) => ({ ...original(provided, state), height: "auto" }); @@ -418,7 +444,7 @@ const Dropdown: VibeComponent = forwardR } const originalValueContainer = mergedStyles.valueContainer; - mergedStyles.valueContainer = (provided: any, state: any) => ({ + mergedStyles.valueContainer = (provided: BaseStyles, state: DropdownState) => ({ ...originalValueContainer(provided, state), paddingLeft: 6 }); @@ -441,24 +467,26 @@ const Dropdown: VibeComponent = forwardR ); const DropdownIndicator = useCallback( - (props: { size: string }) => , + (props: React.HTMLAttributes & { size?: SIZES_VALUES }) => ( + + ), [size] ); const Option = useCallback( - (props: any) => ( + (props: CustomOptionProps) => ( ), [finalOptionRenderer, optionWrapperClassName] ); const Input = useCallback( - (props: any) => , + (props: InputProps) => , [menuId] ); const SingleValue = useCallback( - (props: any) => ( + (props: CustomSingleValueProps) => ( = forwardR [finalValueRenderer, readOnly, selectedOptions, singleValueWrapperClassName] ); - const ClearIndicator = useCallback((props: any) => , [size]); + const ClearIndicator = useCallback( + (props: React.HTMLAttributes & { size?: SIZES_VALUES }) => ( + + ), + [size] + ); const onOptionRemove = useMemo(() => { - return function (optionValue: any, e: any) { + return function (optionValue: number, e: React.MouseEvent | React.KeyboardEvent) { if (customOnOptionRemove) { - customOnOptionRemove((selectedOptionsMap as DropdownDefaultValue[])[optionValue]); + customOnOptionRemove((selectedOptionsMap as unknown as DropdownDefaultValue[])[optionValue]); } - const newSelectedOptions = (selectedOptions as DropdownDefaultValue[]).filter( - option => option.value !== optionValue - ); + const newSelectedOptions = Array.isArray(selectedOptions) + ? selectedOptions.filter(option => option.value !== optionValue) + : selectedOptions; + if (customOnChange) { customOnChange(newSelectedOptions, e); } @@ -508,7 +542,7 @@ const Dropdown: VibeComponent = forwardR popupsContainerSelector ] ); - const onChange = (option: any, event: any) => { + const onChange = (option: DropdownDefaultValue, event: SelectEvent) => { if (customOnChange) { customOnChange(option, event); } @@ -540,7 +574,7 @@ const Dropdown: VibeComponent = forwardR } }; - const DropDownComponent: any = asyncOptions ? AsyncSelect : Select; + const DropDownComponent: React.ElementType = asyncOptions ? AsyncSelect : Select; const asyncAdditions = { ...(asyncOptions && { @@ -558,7 +592,7 @@ const Dropdown: VibeComponent = forwardR }; const closeMenuOnScroll = useCallback( - (event: any) => { + (event: React.FocusEvent) => { const scrolledElement = event.target; if (scrolledElement?.parentElement?.classList.contains(menuStyles.dropdownMenuWrapper)) { return false; @@ -581,15 +615,15 @@ const Dropdown: VibeComponent = forwardR Control, SingleValue, ...(multi && { - MultiValue: NOOP as any, // We need it for react-select to behave nice with "multi" + MultiValue: NOOP, // We need it for react-select to behave nice with "multi" ValueContainer: MultiValueContainer }), ...(isVirtualized && { MenuList: WindowedMenuList }) }} // When inside scroll we set the menu position by js and we can't follow the drop down location while use scrolling - closeMenuOnScroll={closeMenuOnScroll as any} + closeMenuOnScroll={closeMenuOnScroll} size={size} - noOptionsMessage={noOptionsMessage as any} + noOptionsMessage={noOptionsMessage} placeholder={placeholder} isDisabled={disabled} isClearable={!readOnly && clearable} @@ -627,7 +661,7 @@ const Dropdown: VibeComponent = forwardR data-testid={dataTestId || getTestId(ComponentDefaultTestId.DROPDOWN, id)} autoFocus={autoFocus} closeMenuOnSelect={closeMenuOnSelect} - ref={ref as any} + ref={ref as React.RefObject} withMandatoryDefaultOptions={withMandatoryDefaultOptions} isOptionSelected={isOptionSelected} isLoading={isLoading} diff --git a/packages/core/src/components/Dropdown/DropdownConstants.tsx b/packages/core/src/components/Dropdown/DropdownConstants.tsx index 4ac27c1bc6..21066811a6 100644 --- a/packages/core/src/components/Dropdown/DropdownConstants.tsx +++ b/packages/core/src/components/Dropdown/DropdownConstants.tsx @@ -32,4 +32,5 @@ export enum DROPDOWN_MENU_PLACEMENT { export type DropdownDefaultValue = { label: string; value: string | number | Theme; + isMandatory?: boolean; }; From 8b9115635941f1638027d72f1915eafe30ea107f Mon Sep 17 00:00:00 2001 From: mila2999 Date: Fri, 5 Apr 2024 09:05:47 +0300 Subject: [PATCH 08/18] Code Review changes 1 --- .DS_Store | Bin 0 -> 6148 bytes packages/.DS_Store | Bin 0 -> 6148 bytes packages/core/.DS_Store | Bin 0 -> 6148 bytes .../core/src/components/Dropdown/Dropdown.tsx | 41 ++++++++---------- .../components/Dropdown/DropdownConstants.tsx | 4 +- 5 files changed, 20 insertions(+), 25 deletions(-) create mode 100644 .DS_Store create mode 100644 packages/.DS_Store create mode 100644 packages/core/.DS_Store diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..a5f014d851e3cc8a1d48284e6ef4e2b258f5a7cd GIT binary patch literal 6148 zcmeHLJ!>055Pj>Mv9JYE5o4EEIFKqqMcU*dPGE4UHdu-zBZWvlp^w6Zz(Kkc{sT#2 zH3t6zHwLSSaGNSWAU`36%8;4eO*E&|iBv{}9oT()J2Sga?{qg>0Z^q;vj`LbZp^zELW+{_Kl3MySi(f#S<_gyc}ZJHx@P=CH6% zH<~laj*@(U3G?yLBozip9k6*blRnAe(X%hA-?uv0T)F!)e`4RqHQqOmQ$)1)399Jo z(Fh&78c0Q+jCZT6VkNKf=h=B^?oa00lIOp~OWw~vT`=z)dU%5d-cjFLzx8l0jI!U1^E5oQ)3J)#s>APgF1Z#AoOTj8;$ua!8yLgz+!BW zJY>qG5}H(Hj~L3N)4Xrv0*kRhlMZDMAIk2m> z|I69u|74Q8atb&F{woEP7goX&eI#33Qy-3Ntxv5+jg8}CgF1yeTaNXBOELeippAS! Y4+sN`u|b+4b3X*M46btu+^Yh=0j_P=TmS$7 literal 0 HcmV?d00001 diff --git a/packages/.DS_Store b/packages/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..db97e137e8d8a12b01ccc001a780b51b633040aa GIT binary patch literal 6148 zcmeHKy-EW?5T4N!4irpjx%dWogEO3#Hfb$1i5T$01^+;7uD0?Ktb7iIq(!eM?^WAAj_abMBQmxGiNcftWllyhvRxS?^xuw zs$}mOjj5&!I&JTN>*4;bZJX6)IjZUrbouh|>A74i_fq@hTl;*v;%58&5uvm}mvlw9 zRHd2eVD}`owsSA0cSo-;F?TC|R&VodIVcWnf*WJ-Pq)@ym1;`DuvHoB?Oxk1@bmIV=bG zD7#y~e4gC30qqz~MEn{VKrl`o0hq`+vJ;JJ4>E>dVc00jDx#0!Kz|5CLcDVZet>~@ DPT@@U literal 0 HcmV?d00001 diff --git a/packages/core/.DS_Store b/packages/core/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..bd10f3a3d58f4cb9f5aa7189cd1d9dd6cd3e9bb9 GIT binary patch literal 6148 zcmeHKy-EW?5S~p^M3W+gh2;tgmgWu4aCUaF6qF>Q!krh4=}&wM3-JL&d;fHLrt44`MT)EgdkR0fm* zWnjtxe;+KAF%rx@x=#lNcLe~}V0MCeizh%U7zySc;ei;R3iPQ)t{BFr!)_%m63jjN zbTV@JFmkey8;WtKV}I+y$wVG?R0foRA_G;wY;phJnScK;Ch1BUPzL@L1Ev;t;|?B4 ydTZ(7xYt_fA(VyVa*xv#Ok68QEVtrSs1w*NPk@nN?hzJ<{t<9A=%5VzDg&QcwQ&mo literal 0 HcmV?d00001 diff --git a/packages/core/src/components/Dropdown/Dropdown.tsx b/packages/core/src/components/Dropdown/Dropdown.tsx index d8856e3d05..219fbec4fb 100644 --- a/packages/core/src/components/Dropdown/Dropdown.tsx +++ b/packages/core/src/components/Dropdown/Dropdown.tsx @@ -22,38 +22,33 @@ import { DROPDOWN_MENU_ARIA_LABEL, DROPDOWN_MENU_PLACEMENT, DROPDOWN_MENU_POSITION, - DropdownDefaultValue + DropdownOption } from "./DropdownConstants"; import generateBaseStyles, { customTheme } from "./Dropdown.styles"; import Control from "./components/Control/Control"; import menuStyles from "./components/menu/menu.module.scss"; import styles from "./Dropdown.module.scss"; -import { VibeComponent, VibeComponentProps } from "src/types"; +import { VibeComponent, VibeComponentProps } from "../../types"; import { IComboboxOption } from "../Combobox/components/ComboboxConstants"; import { Option } from "react-select/src/filters"; -import { HtmlAttributes } from "csstype"; -import { RefObject } from "preact"; -interface CustomSingleValueProps extends SingleValueProps { +interface CustomSingleValueProps extends SingleValueProps { Renderer: React.ComponentType; readOnly: boolean; - selectedOption: DropdownDefaultValue; - singleVueWrapperClassName?: string; + selectedOption: DropdownOption; } interface CustomMenuProps extends MenuProps { - Renderer: React.ComponentType; dropdownMenuWrapperClassName: string; } interface CustomOptionProps extends OptionProps { - Renderer: React.ComponentType; optionWrapperClassName?: string; } type SelectEvent = { action: "select-option" | "clear"; - option?: DropdownDefaultValue; + option?: DropdownOption; }; type DropdownState = { @@ -119,7 +114,7 @@ export interface DropdownComponentProps extends VibeComponentProps { /** * The dropdown options */ - options?: DropdownDefaultValue[]; + options?: DropdownOption[]; /** * Text to display when there are no options */ @@ -167,12 +162,12 @@ export interface DropdownComponentProps extends VibeComponentProps { /** * Set default selected value */ - defaultValue?: DropdownDefaultValue[]; + defaultValue?: DropdownOption[]; /** * The component's value. * When passed, makes this a [controlled](https://reactjs.org/docs/forms.html#controlled-components) component. */ - value?: DropdownDefaultValue[]; + value?: DropdownOption[]; /** * Select menu size from `Dropdown.size` - Dropdown.sizes.LARGE | Dropdown.sizes.MEDIUM | Dropdown.sizes.SMALL */ @@ -180,7 +175,7 @@ export interface DropdownComponentProps extends VibeComponentProps { /** * If provided Dropdown will work in async mode. Can be either promise or callback */ - asyncOptions?: (inputValue: string) => Promise; + asyncOptions?: (inputValue: string) => Promise; /** * If set to true, fetched async options will be cached */ @@ -252,7 +247,7 @@ export interface DropdownComponentProps extends VibeComponentProps { /** * Override the built-in logic to detect whether an option is selected. */ - isOptionSelected?: (option: DropdownDefaultValue, selectValue: DropdownDefaultValue["value"]) => boolean; + isOptionSelected?: (option: DropdownOption, selectValue: DropdownOption["value"]) => boolean; /** * For display the drop down menu in overflow hidden/scroll container. */ @@ -373,7 +368,7 @@ const Dropdown: VibeComponent = forwardR if (defaultValue) { return Array.isArray(defaultValue) ? defaultValue.map(df => ({ ...df, isMandatory: true })) - : { ...(defaultValue as DropdownDefaultValue), isMandatory: true }; + : { ...(defaultValue as DropdownOption), isMandatory: true }; } return defaultValue; @@ -387,11 +382,11 @@ const Dropdown: VibeComponent = forwardR const selectedOptionsMap = useMemo(() => { if (Array.isArray(selectedOptions)) { return selectedOptions.reduce( - (acc, option) => ({ ...acc, [option.value as DropdownDefaultValue["label"]]: option }), - {} as DropdownDefaultValue + (acc, option) => ({ ...acc, [option.value as DropdownOption["label"]]: option }), + {} as DropdownOption ); } - return {} as DropdownDefaultValue; + return {} as DropdownOption; }, [selectedOptions]); const overrideAriaLabel = useMemo(() => { @@ -491,7 +486,7 @@ const Dropdown: VibeComponent = forwardR {...props} readOnly={readOnly} Renderer={finalValueRenderer} - selectedOption={(selectedOptions as DropdownDefaultValue[])[0]} + selectedOption={(selectedOptions as DropdownOption[])[0]} singleValueWrapperClassName={singleValueWrapperClassName} /> ), @@ -508,7 +503,7 @@ const Dropdown: VibeComponent = forwardR const onOptionRemove = useMemo(() => { return function (optionValue: number, e: React.MouseEvent | React.KeyboardEvent) { if (customOnOptionRemove) { - customOnOptionRemove((selectedOptionsMap as unknown as DropdownDefaultValue[])[optionValue]); + customOnOptionRemove((selectedOptionsMap as unknown as DropdownOption[])[optionValue]); } const newSelectedOptions = Array.isArray(selectedOptions) ? selectedOptions.filter(option => option.value !== optionValue) @@ -542,7 +537,7 @@ const Dropdown: VibeComponent = forwardR popupsContainerSelector ] ); - const onChange = (option: DropdownDefaultValue, event: SelectEvent) => { + const onChange = (option: DropdownOption, event: SelectEvent) => { if (customOnChange) { customOnChange(option, event); } @@ -556,7 +551,7 @@ const Dropdown: VibeComponent = forwardR } if (!isControlled) { - setSelected([...(selectedOptions as DropdownDefaultValue[]), selectedOption]); + setSelected([...(selectedOptions as DropdownOption[]), selectedOption]); } break; } diff --git a/packages/core/src/components/Dropdown/DropdownConstants.tsx b/packages/core/src/components/Dropdown/DropdownConstants.tsx index 21066811a6..120a81c6ee 100644 --- a/packages/core/src/components/Dropdown/DropdownConstants.tsx +++ b/packages/core/src/components/Dropdown/DropdownConstants.tsx @@ -29,8 +29,8 @@ export enum DROPDOWN_MENU_PLACEMENT { AUTO = "auto" } -export type DropdownDefaultValue = { +export type DropdownOption = { label: string; - value: string | number | Theme; + value: string | number; isMandatory?: boolean; }; From 74818cc57818b5eae1e1f7599b5e42f3516a3961 Mon Sep 17 00:00:00 2001 From: mila2999 Date: Fri, 5 Apr 2024 09:46:08 +0300 Subject: [PATCH 09/18] Code review changes 2 --- packages/core/src/components/Dropdown/Dropdown.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/core/src/components/Dropdown/Dropdown.tsx b/packages/core/src/components/Dropdown/Dropdown.tsx index 219fbec4fb..1de680a2a7 100644 --- a/packages/core/src/components/Dropdown/Dropdown.tsx +++ b/packages/core/src/components/Dropdown/Dropdown.tsx @@ -167,7 +167,7 @@ export interface DropdownComponentProps extends VibeComponentProps { * The component's value. * When passed, makes this a [controlled](https://reactjs.org/docs/forms.html#controlled-components) component. */ - value?: DropdownOption[]; + value?: DropdownOption[] | DropdownOption; /** * Select menu size from `Dropdown.size` - Dropdown.sizes.LARGE | Dropdown.sizes.MEDIUM | Dropdown.sizes.SMALL */ @@ -231,7 +231,7 @@ export interface DropdownComponentProps extends VibeComponentProps { * If menu should be closed on scroll - helpful for some tricky use cases * @default false, but true when insideOverflowContainer or insideOverflowWithTransformContainer are true */ - closeMenuOnScroll?: ((event: React.FocusEvent) => boolean) | boolean; + closeMenuOnScroll?: boolean; /** * callback to be called when `multiline` is `true` and the option is removed */ @@ -364,7 +364,7 @@ const Dropdown: VibeComponent = forwardR const controlRef = useRef(); const overrideMenuPortalTarget = menuPortalTarget || (popupsContainerSelector && document.querySelector(popupsContainerSelector)); - const overrideDefaultValue = useMemo(() => { + const overrideDefaultValue: DropdownOption | DropdownOption[] = useMemo(() => { if (defaultValue) { return Array.isArray(defaultValue) ? defaultValue.map(df => ({ ...df, isMandatory: true })) From 98d384b9530c3fc21a230416da106ad4a515e9fc Mon Sep 17 00:00:00 2001 From: mila2999 Date: Fri, 5 Apr 2024 10:36:28 +0300 Subject: [PATCH 10/18] Code Review finish before rebase --- .../core/src/components/Dropdown/Dropdown.tsx | 39 ++++++++++++------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/packages/core/src/components/Dropdown/Dropdown.tsx b/packages/core/src/components/Dropdown/Dropdown.tsx index 1de680a2a7..c8427cf940 100644 --- a/packages/core/src/components/Dropdown/Dropdown.tsx +++ b/packages/core/src/components/Dropdown/Dropdown.tsx @@ -3,7 +3,15 @@ import { ComponentDefaultTestId, getTestId } from "../../tests/test-ids-utils"; import cx from "classnames"; import { BaseSizes, SIZES, SIZES_VALUES } from "../../constants/sizes"; import React, { forwardRef, useCallback, useMemo, useRef, useState } from "react"; -import Select, { InputProps, MenuProps, OptionProps, SingleValueProps, components, createFilter } from "react-select"; +import Select, { + InputProps, + MenuProps, + OptionProps, + SingleValueProps, + components, + createFilter, + OptionTypeBase +} from "react-select"; import AsyncSelect from "react-select/async"; import { noop as NOOP } from "lodash-es"; import { WindowedMenuList } from "react-windowed-select"; @@ -29,8 +37,6 @@ import Control from "./components/Control/Control"; import menuStyles from "./components/menu/menu.module.scss"; import styles from "./Dropdown.module.scss"; import { VibeComponent, VibeComponentProps } from "../../types"; -import { IComboboxOption } from "../Combobox/components/ComboboxConstants"; -import { Option } from "react-select/src/filters"; interface CustomSingleValueProps extends SingleValueProps { Renderer: React.ComponentType; @@ -38,11 +44,11 @@ interface CustomSingleValueProps extends SingleValueProps { selectedOption: DropdownOption; } -interface CustomMenuProps extends MenuProps { +interface CustomMenuProps extends MenuProps { dropdownMenuWrapperClassName: string; } -interface CustomOptionProps extends OptionProps { +interface CustomOptionProps extends OptionProps { optionWrapperClassName?: string; } @@ -82,31 +88,34 @@ export interface DropdownComponentProps extends VibeComponentProps { /** * Called when menu is opened */ - onMenuOpen?: () => void; + onMenuOpen?: (event: React.MouseEvent) => void; /** * Called when menu is closed */ - onMenuClose?: () => void; + onMenuClose?: (event: React.MouseEvent) => void; /** * Called when key is pressed in the dropdown */ - onKeyDown?: (...args: unknown[]) => unknown; + onKeyDown?: (event: React.MouseEvent) => void; /** * Called when focused */ - onFocus?: (...args: unknown[]) => unknown; + onFocus?: (event: React.MouseEvent) => void; /** * Called when blurred */ - onBlur?: (...args: unknown[]) => unknown; + onBlur?: (event: React.MouseEvent) => void; /** * Called when selected value has changed */ - onChange?: (...args: unknown[]) => unknown; + onChange?: ( + option: DropdownOption | DropdownOption[], + event: SelectEvent | React.MouseEvent | React.KeyboardEvent + ) => void; /** * Called when the dropdown's input changes. */ - onInputChange?: (...args: unknown[]) => unknown; + onInputChange?: (event: React.KeyboardEvent) => void; /** * If true, search in options will be enabled */ @@ -134,7 +143,7 @@ export interface DropdownComponentProps extends VibeComponentProps { /** * custom option render function */ - optionRenderer?: (option: IComboboxOption) => JSX.Element; + optionRenderer?: (option: DropdownOption) => JSX.Element; /** * custom value render function */ @@ -203,7 +212,7 @@ export interface DropdownComponentProps extends VibeComponentProps { /** * Tab index for keyboard navigation purposes */ - tabIndex?: number; + tabIndex?: number | string; /** * ID for the select container */ @@ -283,7 +292,7 @@ export interface DropdownComponentProps extends VibeComponentProps { filterOption?: (option: unknown, inputValue: string) => boolean; withReadOnlyStyle?: boolean; - OptionRenderer?: (option: IComboboxOption) => JSX.Element; + OptionRenderer?: (option: DropdownOption) => JSX.Element; menuIsOpen?: boolean; onOptionSelect?: (...args: unknown[]) => void; onClear?: (...args: unknown[]) => void; From 661a915dee600a4e2c6939359c19b3befb1960aa Mon Sep 17 00:00:00 2001 From: mila2999 Date: Fri, 5 Apr 2024 11:12:56 +0300 Subject: [PATCH 11/18] changed DROPDOWN_ID to type --- packages/core/src/components/Dropdown/Dropdown.tsx | 4 ++-- packages/core/src/components/Dropdown/DropdownConstants.tsx | 4 +--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/core/src/components/Dropdown/Dropdown.tsx b/packages/core/src/components/Dropdown/Dropdown.tsx index c8427cf940..4e4786aa66 100644 --- a/packages/core/src/components/Dropdown/Dropdown.tsx +++ b/packages/core/src/components/Dropdown/Dropdown.tsx @@ -25,7 +25,7 @@ import { ADD_AUTO_HEIGHT_COMPONENTS, defaultCustomStyles, DROPDOWN_CHIP_COLORS, - DROPDOWN_MENU, + DROPDOWN_ID, DROPDOWN_MENU_ID, DROPDOWN_MENU_ARIA_LABEL, DROPDOWN_MENU_PLACEMENT, @@ -216,7 +216,7 @@ export interface DropdownComponentProps extends VibeComponentProps { /** * ID for the select container */ - id?: DROPDOWN_MENU.ID; + id?: DROPDOWN_ID; /** * focusAuto when component mount */ diff --git a/packages/core/src/components/Dropdown/DropdownConstants.tsx b/packages/core/src/components/Dropdown/DropdownConstants.tsx index 120a81c6ee..a87a9b0691 100644 --- a/packages/core/src/components/Dropdown/DropdownConstants.tsx +++ b/packages/core/src/components/Dropdown/DropdownConstants.tsx @@ -8,9 +8,7 @@ export enum ADD_AUTO_HEIGHT_COMPONENTS { VALUE_CONTAINER = "valueContainer" } -export enum DROPDOWN_MENU { - ID = "dropdown-menu-id" -} +export type DROPDOWN_ID = "dropdown-menu-id"; export enum DROPDOWN_CHIP_COLORS { PRIMARY = "PRIMARY", From 2aa8b909c39b29ca3c6d684f13c2b1e4599821fe Mon Sep 17 00:00:00 2001 From: mila2999 Date: Fri, 5 Apr 2024 11:27:38 +0300 Subject: [PATCH 12/18] fixed typing issue --- packages/core/src/components/Dropdown/Dropdown.tsx | 4 ++-- packages/core/src/components/Dropdown/DropdownConstants.tsx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/core/src/components/Dropdown/Dropdown.tsx b/packages/core/src/components/Dropdown/Dropdown.tsx index 4e4786aa66..42bf7bf842 100644 --- a/packages/core/src/components/Dropdown/Dropdown.tsx +++ b/packages/core/src/components/Dropdown/Dropdown.tsx @@ -216,7 +216,7 @@ export interface DropdownComponentProps extends VibeComponentProps { /** * ID for the select container */ - id?: DROPDOWN_ID; + id?: typeof DROPDOWN_ID; /** * focusAuto when component mount */ @@ -712,7 +712,7 @@ Dropdown.defaultProps = { extraStyles: defaultCustomStyles, tabIndex: 0, onOptionRemove: undefined, - id: DROPDOWN_MENU.ID, + id: DROPDOWN_ID, menuId: DROPDOWN_MENU_ID, menuAriaLabel: DROPDOWN_MENU_ARIA_LABEL, autoFocus: false, diff --git a/packages/core/src/components/Dropdown/DropdownConstants.tsx b/packages/core/src/components/Dropdown/DropdownConstants.tsx index a87a9b0691..79212bcdd6 100644 --- a/packages/core/src/components/Dropdown/DropdownConstants.tsx +++ b/packages/core/src/components/Dropdown/DropdownConstants.tsx @@ -8,7 +8,7 @@ export enum ADD_AUTO_HEIGHT_COMPONENTS { VALUE_CONTAINER = "valueContainer" } -export type DROPDOWN_ID = "dropdown-menu-id"; +export const DROPDOWN_ID = "dropdown-menu-id"; export enum DROPDOWN_CHIP_COLORS { PRIMARY = "PRIMARY", From b965e41e3061f9d68118cd5946b6c846c5a26726 Mon Sep 17 00:00:00 2001 From: mila2999 Date: Fri, 5 Apr 2024 11:59:42 +0300 Subject: [PATCH 13/18] reverted Theme dropdown option value --- packages/core/src/components/Dropdown/DropdownConstants.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/components/Dropdown/DropdownConstants.tsx b/packages/core/src/components/Dropdown/DropdownConstants.tsx index 79212bcdd6..05887a2c29 100644 --- a/packages/core/src/components/Dropdown/DropdownConstants.tsx +++ b/packages/core/src/components/Dropdown/DropdownConstants.tsx @@ -29,6 +29,6 @@ export enum DROPDOWN_MENU_PLACEMENT { export type DropdownOption = { label: string; - value: string | number; + value: string | number | Theme; isMandatory?: boolean; }; From d5a7910623e4669049ebaa0e82025686a34ee931 Mon Sep 17 00:00:00 2001 From: mila2999 Date: Fri, 5 Apr 2024 12:39:56 +0300 Subject: [PATCH 14/18] ref change after rebase --- packages/core/src/components/Dropdown/Dropdown.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/components/Dropdown/Dropdown.tsx b/packages/core/src/components/Dropdown/Dropdown.tsx index 42bf7bf842..f42bee20be 100644 --- a/packages/core/src/components/Dropdown/Dropdown.tsx +++ b/packages/core/src/components/Dropdown/Dropdown.tsx @@ -248,7 +248,7 @@ export interface DropdownComponentProps extends VibeComponentProps { /** Pass Ref for reference of the actual dropdown component */ - ref?: React.ForwardedRef; + ref?: React.ForwardedRef | string; /** The options set by default will be set as mandatory and the user will not be able to cancel their selection */ From 1c718903140c9f47d6c1711d06eda40cebb7402e Mon Sep 17 00:00:00 2001 From: mila2999 Date: Wed, 10 Apr 2024 15:00:59 +0300 Subject: [PATCH 15/18] reverted react-windowed-select commit and added packages.d.ts with declare module --- packages/core/package.json | 2 +- packages/core/types/packages.d.ts | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 packages/core/types/packages.d.ts diff --git a/packages/core/package.json b/packages/core/package.json index e4d20a7440..841228a783 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -118,7 +118,7 @@ "react-transition-group": "^4.4.5", "react-virtualized-auto-sizer": "^1.0.7", "react-window": "^1.8.7", - "react-windowed-select": "3.1.2", + "react-windowed-select": "^2.0.4", "style-inject": "^0.3.0", "vibe-storybook-components": "0.18.4" }, diff --git a/packages/core/types/packages.d.ts b/packages/core/types/packages.d.ts new file mode 100644 index 0000000000..2ff5cdb473 --- /dev/null +++ b/packages/core/types/packages.d.ts @@ -0,0 +1,2 @@ +// Packages +declare module "react-windowed-select"; From 3e8fc613fd9e1b29577d4c8b2727b56de42cfe30 Mon Sep 17 00:00:00 2001 From: mila2999 Date: Wed, 10 Apr 2024 15:06:42 +0300 Subject: [PATCH 16/18] fix yarn.lock --- yarn.lock | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/yarn.lock b/yarn.lock index 82d55dc67d..1936026ad0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4958,6 +4958,13 @@ "@types/react-outside-click-handler" "*" moment "^2.26.0" +"@types/react-dom@*": + version "18.2.24" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.24.tgz#8dda8f449ae436a7a6e91efed8035d4ab03ff759" + integrity sha512-cN6upcKd8zkGy4HU9F1+/s98Hrp6D4MOcippK4PoE8OZRngohHZpbJn1GsaDLz87MqvHNoT13nHvNqM9ocRHZg== + dependencies: + "@types/react" "*" + "@types/react-dom@<18.0.0": version "17.0.25" resolved "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.25.tgz#e0e5b3571e1069625b3a3da2b279379aa33a0cb5" @@ -4993,6 +5000,15 @@ dependencies: "@types/react" "*" +"@types/react-select@^3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@types/react-select/-/react-select-3.1.2.tgz#38627df4b49be9b28f800ed72b35d830369a624b" + integrity sha512-ygvR/2FL87R2OLObEWFootYzkvm67LRA+URYEAcBuvKk7IXmdsnIwSGm60cVXGaqkJQHozb2Cy1t94tCYb6rJA== + dependencies: + "@types/react" "*" + "@types/react-dom" "*" + "@types/react-transition-group" "*" + "@types/react-test-renderer@>=16.9.0": version "18.0.7" resolved "https://registry.npmjs.org/@types/react-test-renderer/-/react-test-renderer-18.0.7.tgz#2cfe657adb3688cdf543995eceb2e062b5a68728" @@ -5007,7 +5023,7 @@ dependencies: "@types/react" "^16" -"@types/react-transition-group@^4.4.5": +"@types/react-transition-group@*", "@types/react-transition-group@^4.4.5": version "4.4.10" resolved "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.10.tgz#6ee71127bdab1f18f11ad8fb3322c6da27c327ac" integrity sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q== From ff76bede332d2d590b2e602b4f37678908498e8e Mon Sep 17 00:00:00 2001 From: mila2999 Date: Wed, 10 Apr 2024 15:47:17 +0300 Subject: [PATCH 17/18] remove ds_store files --- .DS_Store | Bin 6148 -> 0 bytes packages/.DS_Store | Bin 6148 -> 0 bytes packages/core/.DS_Store | Bin 6148 -> 0 bytes 3 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 .DS_Store delete mode 100644 packages/.DS_Store delete mode 100644 packages/core/.DS_Store diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index a5f014d851e3cc8a1d48284e6ef4e2b258f5a7cd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHLJ!>055Pj>Mv9JYE5o4EEIFKqqMcU*dPGE4UHdu-zBZWvlp^w6Zz(Kkc{sT#2 zH3t6zHwLSSaGNSWAU`36%8;4eO*E&|iBv{}9oT()J2Sga?{qg>0Z^q;vj`LbZp^zELW+{_Kl3MySi(f#S<_gyc}ZJHx@P=CH6% zH<~laj*@(U3G?yLBozip9k6*blRnAe(X%hA-?uv0T)F!)e`4RqHQqOmQ$)1)399Jo z(Fh&78c0Q+jCZT6VkNKf=h=B^?oa00lIOp~OWw~vT`=z)dU%5d-cjFLzx8l0jI!U1^E5oQ)3J)#s>APgF1Z#AoOTj8;$ua!8yLgz+!BW zJY>qG5}H(Hj~L3N)4Xrv0*kRhlMZDMAIk2m> z|I69u|74Q8atb&F{woEP7goX&eI#33Qy-3Ntxv5+jg8}CgF1yeTaNXBOELeippAS! Y4+sN`u|b+4b3X*M46btu+^Yh=0j_P=TmS$7 diff --git a/packages/.DS_Store b/packages/.DS_Store deleted file mode 100644 index db97e137e8d8a12b01ccc001a780b51b633040aa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHKy-EW?5T4N!4irpjx%dWogEO3#Hfb$1i5T$01^+;7uD0?Ktb7iIq(!eM?^WAAj_abMBQmxGiNcftWllyhvRxS?^xuw zs$}mOjj5&!I&JTN>*4;bZJX6)IjZUrbouh|>A74i_fq@hTl;*v;%58&5uvm}mvlw9 zRHd2eVD}`owsSA0cSo-;F?TC|R&VodIVcWnf*WJ-Pq)@ym1;`DuvHoB?Oxk1@bmIV=bG zD7#y~e4gC30qqz~MEn{VKrl`o0hq`+vJ;JJ4>E>dVc00jDx#0!Kz|5CLcDVZet>~@ DPT@@U diff --git a/packages/core/.DS_Store b/packages/core/.DS_Store deleted file mode 100644 index bd10f3a3d58f4cb9f5aa7189cd1d9dd6cd3e9bb9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHKy-EW?5S~p^M3W+gh2;tgmgWu4aCUaF6qF>Q!krh4=}&wM3-JL&d;fHLrt44`MT)EgdkR0fm* zWnjtxe;+KAF%rx@x=#lNcLe~}V0MCeizh%U7zySc;ei;R3iPQ)t{BFr!)_%m63jjN zbTV@JFmkey8;WtKV}I+y$wVG?R0foRA_G;wY;phJnScK;Ch1BUPzL@L1Ev;t;|?B4 ydTZ(7xYt_fA(VyVa*xv#Ok68QEVtrSs1w*NPk@nN?hzJ<{t<9A=%5VzDg&QcwQ&mo From 4506446878e93b415e94705b6b9b66f81afe0be6 Mon Sep 17 00:00:00 2001 From: Mila2999 Date: Sun, 19 May 2024 09:46:19 +0900 Subject: [PATCH 18/18] rebase merge fixes --- packages/core/src/components/Dropdown/Dropdown.tsx | 5 +++++ packages/core/src/components/Dropdown/DropdownConstants.tsx | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/packages/core/src/components/Dropdown/Dropdown.tsx b/packages/core/src/components/Dropdown/Dropdown.tsx index f42bee20be..1f427a51cc 100644 --- a/packages/core/src/components/Dropdown/Dropdown.tsx +++ b/packages/core/src/components/Dropdown/Dropdown.tsx @@ -217,9 +217,14 @@ export interface DropdownComponentProps extends VibeComponentProps { * ID for the select container */ id?: typeof DROPDOWN_ID; + /** + * ID for the menu component + */ + menuId?: typeof DROPDOWN_MENU_ID; /** * focusAuto when component mount */ + menuAriaLabel?: typeof DROPDOWN_MENU_ARIA_LABEL, autoFocus?: boolean; /** * If set to true, the dropdown will be in multi-select mode. diff --git a/packages/core/src/components/Dropdown/DropdownConstants.tsx b/packages/core/src/components/Dropdown/DropdownConstants.tsx index 05887a2c29..996941c8d3 100644 --- a/packages/core/src/components/Dropdown/DropdownConstants.tsx +++ b/packages/core/src/components/Dropdown/DropdownConstants.tsx @@ -8,6 +8,10 @@ export enum ADD_AUTO_HEIGHT_COMPONENTS { VALUE_CONTAINER = "valueContainer" } +export const DROPDOWN_MENU_ARIA_LABEL = "Dropdown menu"; + +export const DROPDOWN_MENU_ID = "dropdown-menu-list-id"; + export const DROPDOWN_ID = "dropdown-menu-id"; export enum DROPDOWN_CHIP_COLORS {