@rio-cloud/rio-uikit 2.4.2 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CountedInput.d.ts +2 -0
- package/CountedInput.js +5 -0
- package/CountedInput.js.map +1 -0
- package/TabbedPanel.d.ts +2 -0
- package/TabbedPanel.js +5 -0
- package/TabbedPanel.js.map +1 -0
- package/components/applicationHeader/NavItems.js +58 -46
- package/components/applicationHeader/NavItems.js.map +1 -1
- package/components/applicationLayout/ApplicationLayoutBody.d.ts +1 -1
- package/components/applicationLayout/ApplicationLayoutBody.js +29 -29
- package/components/applicationLayout/ApplicationLayoutBody.js.map +1 -1
- package/components/applicationLayout/ApplicationLayoutHeader.js +22 -7
- package/components/applicationLayout/ApplicationLayoutHeader.js.map +1 -1
- package/components/assetTree/useTreeHeight.js.map +1 -1
- package/components/button/Button.d.ts +11 -3
- package/components/button/Button.js.map +1 -1
- package/components/clearableInput/ClearableInput.d.ts +4 -0
- package/components/clearableInput/ClearableInput.js.map +1 -1
- package/components/countedInput/CountedInput.d.ts +91 -0
- package/components/countedInput/CountedInput.js +65 -0
- package/components/countedInput/CountedInput.js.map +1 -0
- package/components/datepicker/DayPicker.js +3 -2
- package/components/datepicker/DayPicker.js.map +1 -1
- package/components/datepicker/DayPickerInput.d.ts +1 -1
- package/components/datepicker/DayPickerInput.js.map +1 -1
- package/components/datepicker/dayPickerTypes.d.ts +3 -2
- package/components/datepicker/dayPickerTypes.js.map +1 -1
- package/components/datepicker/dayPickerUtils.d.ts +1 -1
- package/components/datepicker/dayPickerUtils.js +45 -22
- package/components/datepicker/dayPickerUtils.js.map +1 -1
- package/components/datepicker/useDayPickerInputState.d.ts +1 -1
- package/components/dialog/ConfirmationDialog.d.ts +17 -0
- package/components/dialog/ConfirmationDialog.js +43 -19
- package/components/dialog/ConfirmationDialog.js.map +1 -1
- package/components/dialog/DialogHeader.js +20 -19
- package/components/dialog/DialogHeader.js.map +1 -1
- package/components/dropdown/ButtonDropdown.d.ts +5 -0
- package/components/dropdown/ButtonDropdown.js +63 -61
- package/components/dropdown/ButtonDropdown.js.map +1 -1
- package/components/dropdown/DropdownToggleButton.d.ts +2 -0
- package/components/dropdown/DropdownToggleButton.js +39 -35
- package/components/dropdown/DropdownToggleButton.js.map +1 -1
- package/components/map/components/features/settings/builtinSettings/MapTypeSettings.js +103 -105
- package/components/map/components/features/settings/builtinSettings/MapTypeSettings.js.map +1 -1
- package/components/map/utils/eventHandling.js.map +1 -1
- package/components/map/utils/mapTypes.d.ts +7 -0
- package/components/map/utils/mapTypes.js.map +1 -1
- package/components/map/utils/rendering.js +5 -5
- package/components/numberControl/NumberControl.js.map +1 -1
- package/components/page/Page.d.ts +2 -0
- package/components/page/Page.js.map +1 -1
- package/components/rioglyph/Rioglyph.d.ts +8 -2
- package/components/rioglyph/Rioglyph.js.map +1 -1
- package/components/rioglyph/RioglyphIconType.d.ts +1 -1
- package/components/selects/BaseSelectDropdown.d.ts +8 -0
- package/components/selects/BaseSelectDropdown.js +76 -60
- package/components/selects/BaseSelectDropdown.js.map +1 -1
- package/components/selects/Multiselect.d.ts +5 -0
- package/components/selects/Multiselect.js +60 -58
- package/components/selects/Multiselect.js.map +1 -1
- package/components/selects/Select.d.ts +5 -0
- package/components/selects/Select.js +60 -58
- package/components/selects/Select.js.map +1 -1
- package/components/sidebars/Sidebar.js +40 -40
- package/components/sidebars/Sidebar.js.map +1 -1
- package/components/sidebars/SidebarCloseButton.d.ts +3 -1
- package/components/sidebars/SidebarCloseButton.js +19 -5
- package/components/sidebars/SidebarCloseButton.js.map +1 -1
- package/components/states/CustomState.d.ts +7 -1
- package/components/states/CustomState.js.map +1 -1
- package/components/states/StateButton.d.ts +11 -1
- package/components/states/StateButton.js +46 -10
- package/components/states/StateButton.js.map +1 -1
- package/components/statsWidget/StatsWidgetNumber.d.ts +16 -1
- package/components/statsWidget/StatsWidgetNumber.js +29 -12
- package/components/statsWidget/StatsWidgetNumber.js.map +1 -1
- package/components/tabbedPanel/TabbedPanel.d.ts +99 -0
- package/components/tabbedPanel/TabbedPanel.js +119 -0
- package/components/tabbedPanel/TabbedPanel.js.map +1 -0
- package/components/table/Table.types.d.ts +9 -1
- package/components/table/TableColumn.js +20 -19
- package/components/table/TableColumn.js.map +1 -1
- package/components/table/TableHeaderColumn.d.ts +4 -0
- package/components/table/TableHeaderColumn.js +50 -53
- package/components/table/TableHeaderColumn.js.map +1 -1
- package/components/table/TableToolbar.d.ts +4 -0
- package/components/table/TableToolbar.js.map +1 -1
- package/components/table/TableToolbarColumn.d.ts +3 -0
- package/components/table/TableToolbarColumn.js.map +1 -1
- package/components/table/render/header/resolveHeaderCellStyle.d.ts +87 -55
- package/components/timepicker/TimePicker.d.ts +6 -0
- package/components/timepicker/TimePicker.js +57 -56
- package/components/timepicker/TimePicker.js.map +1 -1
- package/hooks/useClickOutside.js +3 -3
- package/hooks/useClipboard.js.map +1 -1
- package/hooks/useScrollPosition.js.map +1 -1
- package/package.json +4 -4
- package/themes/Volkswagen/components/applicationHeader/VolkswagenApplicationHeader.js +23 -22
- package/themes/Volkswagen/components/applicationHeader/VolkswagenApplicationHeader.js.map +1 -1
- package/utils/analytics/getTrackingLabelFromNode.d.ts +2 -0
- package/utils/analytics/getTrackingLabelFromNode.js +24 -0
- package/utils/analytics/getTrackingLabelFromNode.js.map +1 -0
- package/utils/analytics/googleAnalyticsUtils.js +21 -28
- package/utils/analytics/googleAnalyticsUtils.js.map +1 -1
- package/utils/getNodeTextContent.d.ts +2 -0
- package/utils/getNodeTextContent.js +22 -0
- package/utils/getNodeTextContent.js.map +1 -0
- package/utils/init/initCSS.js +5 -5
- package/utils/init/initCSS.js.map +1 -1
- package/utils/init/initConfig.js +4 -7
- package/utils/init/initConfig.js.map +1 -1
- package/utils/init/initDocumentBootstrapping.js +14 -14
- package/utils/init/initDocumentBootstrapping.js.map +1 -1
- package/version.d.ts +1 -1
- package/version.js +1 -1
- package/version.js.map +1 -1
- package/DayPickerPrototype.d.ts +0 -2
- package/DayPickerPrototype.js +0 -5
- package/DayPickerPrototype.js.map +0 -1
- package/TableNext.d.ts +0 -2
- package/TableNext.js +0 -25
- package/TableNext.js.map +0 -1
- package/components/datepicker/DayPickerPrototype.d.ts +0 -53
- package/components/datepicker/DayPickerPrototype.js +0 -285
- package/components/datepicker/DayPickerPrototype.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseSelectDropdown.js","sources":["../../../src/components/selects/BaseSelectDropdown.tsx"],"sourcesContent":["import type React from 'react';\nimport { useEffect, useLayoutEffect, useRef, useState } from 'react';\nimport { isEmpty } from 'es-toolkit/compat';\nimport { noop } from 'es-toolkit/function';\n\nimport classNames from '../../utils/classNames';\nimport { useDropDirection } from '../../utils/useDropDirection';\nimport { DOWN, scrollItemIntoView, UP } from '../../utils/scrollItemIntoView';\nimport useKey from '../../useKey';\nimport DropdownHeader from './DropdownHeader';\nimport NoItemMessage from './NoItemMessage';\nimport Spinner from '../spinner/Spinner';\n\nconst DATA_ATTRIBUTE_ID = 'data-item-id';\nconst DEFAULT_FOCUSED_ITEM_INDEX = 0;\nconst HIGHLIGHT_CLASS = 'focus';\nconst DEFAULT_SCROLL_DIRECTION = DOWN;\n\nexport type OptionDOMValue = {\n id: string;\n text: string;\n};\n\nexport type SelectOption = {\n /**\n * Used to identify an option.\n */\n id: string;\n\n /**\n * The option item text.\n */\n label: string | React.ReactNode;\n\n /**\n * Icon to be displayed in front of the label.\n */\n icon?: React.ReactNode;\n\n /**\n * Defines whether the menu item is selected.\n *\n * @default false\n */\n selected?: boolean;\n\n /**\n * Setting \"disabled\" to true will disable the respective item.\n *\n * @default false\n */\n disabled?: boolean;\n\n /**\n * Will treat the given value as a menu header\n */\n header?: boolean;\n};\n\nexport type BaseSelectDropdownProps<T extends SelectOption> = {\n options?: T[];\n isOpen?: boolean;\n isLoading?: boolean;\n updateDOMValues?: (values: OptionDOMValue[] | undefined) => void;\n onOpen?: (hasDropup: boolean) => void;\n onSelect?: (selectedItem: T | undefined) => void;\n onClose?: () => void;\n placeholder?: string | React.ReactNode;\n dropup?: boolean;\n pullRight?: boolean;\n autoDropDirection?: boolean;\n noItemMessage?: string | React.ReactNode;\n focusedItemIndex?: number;\n dropdownClassName?: string;\n keyboardUsed?: boolean;\n useActiveClass?: boolean;\n};\n\nconst BaseSelectDropdown = <T extends SelectOption>(props: BaseSelectDropdownProps<T>) => {\n const {\n isOpen = false,\n isLoading = false,\n updateDOMValues = noop,\n onOpen = noop,\n onSelect = noop,\n onClose = noop,\n options = [],\n autoDropDirection = true,\n dropup = false,\n pullRight = false,\n useActiveClass = false,\n focusedItemIndex: externalFocusedItemIndex,\n keyboardUsed: externalKeyboardUsed,\n noItemMessage,\n dropdownClassName,\n } = props;\n\n const [focusedItemIndex, setFocusedItemIndex] = useState(externalFocusedItemIndex || DEFAULT_FOCUSED_ITEM_INDEX);\n const [keyboardUsed, setKeyboardUsed] = useState(externalKeyboardUsed);\n const lastScrollDirectionRef = useRef<typeof UP | typeof DOWN>(DEFAULT_SCROLL_DIRECTION);\n\n const dropdownMenuRef = useRef<HTMLUListElement>(null);\n\n // Reset scroll position whenever the menu opens to avoid retaining old scroll offsets\n useEffect(() => {\n if (isOpen && dropdownMenuRef.current) {\n dropdownMenuRef.current.scrollTop = 0;\n }\n }, [isOpen]);\n\n // Keep internal focus state in sync when the dropdown opens/closes or when parent-controlled values change\n useEffect(() => {\n if (typeof externalFocusedItemIndex === 'number') {\n setFocusedItemIndex(externalFocusedItemIndex);\n }\n\n if (typeof externalKeyboardUsed === 'boolean') {\n setKeyboardUsed(externalKeyboardUsed);\n }\n\n if (!isOpen) {\n lastScrollDirectionRef.current = DEFAULT_SCROLL_DIRECTION;\n }\n }, [externalFocusedItemIndex, externalKeyboardUsed, isOpen]);\n\n // Overwrite position of dropdown menu in case auto drop is enabled\n const dropDirection = useDropDirection({ pullRight, dropup, autoDropDirection, dropdownMenuRef }, [isOpen]);\n\n // Add or remove the \"dropup\" class from the parent Select/Multiselect component to position\n // the dropdown element accordingly via CSS\n useLayoutEffect(() => {\n if (dropdownMenuRef.current) {\n const parent = dropdownMenuRef.current.parentElement;\n if (dropDirection.dropup) {\n parent?.classList.add('dropup');\n } else {\n parent?.classList.remove('dropup');\n }\n }\n }, [dropDirection, dropdownMenuRef]);\n\n useEffect(() => {\n // all available items need to be rendered in order to know their DOM value\n // which will be used for filtering in the parent component\n updateDOMValues(updateItemDOMValues());\n }, [options]);\n\n // Scroll the focused item into view whenever focus changes\n useEffect(() => {\n if (!isOpen) {\n return;\n }\n\n scrollItemIntoView(\n lastScrollDirectionRef.current || DEFAULT_SCROLL_DIRECTION,\n dropdownMenuRef.current,\n getFocusedOptionNode()\n );\n }, [focusedItemIndex, isOpen]);\n\n // update internal state for isOpen\n const [previousIsOpen, setPreviousIsOpen] = useState(isOpen);\n if (isOpen && !previousIsOpen) {\n onOpen(dropDirection.dropup);\n setPreviousIsOpen(isOpen);\n } else if (!isOpen && previousIsOpen) {\n onClose();\n setPreviousIsOpen(isOpen);\n }\n\n useKey(event => {\n if (isOpen) {\n switch (event.key) {\n case 'Escape': {\n // close dropdown on esc\n onClose();\n break;\n }\n case 'Tab': {\n // close dropdown on tab\n onClose();\n break;\n }\n case 'Enter': {\n // select item on enter\n selectOptionOnEnter(event);\n break;\n }\n case 'ArrowUp': {\n // prevent scrolling the page when dropdown menu is open\n event.preventDefault();\n\n // select item above on arrow up key\n focusOption(UP);\n scrollItemIntoView(UP, dropdownMenuRef.current, getFocusedOptionNode());\n break;\n }\n case 'ArrowDown': {\n // prevent scrolling the page when dropdown menu is open\n event.preventDefault();\n\n // select item below on arrow down key\n focusOption(DOWN);\n scrollItemIntoView(DOWN, dropdownMenuRef.current, getFocusedOptionNode());\n break;\n }\n default:\n break;\n }\n }\n });\n\n const focusOption = (direction: typeof UP | typeof DOWN) => {\n let nextFocusedItem = 0;\n\n switch (direction) {\n case UP: {\n nextFocusedItem = focusedItemIndex <= 0 ? focusedItemIndex : focusedItemIndex - 1;\n break;\n }\n case DOWN: {\n nextFocusedItem = focusedItemIndex === options.length - 1 ? focusedItemIndex : focusedItemIndex + 1;\n break;\n }\n default:\n break;\n }\n\n lastScrollDirectionRef.current = direction;\n\n // In case the next item index is negative, means outside the bounds of the items,\n // reset it depending on the current direction\n const indexLimit = direction === UP ? options.length - 1 : 0;\n\n setFocusedItemIndex(nextFocusedItem < 0 ? indexLimit : nextFocusedItem);\n setKeyboardUsed(true);\n };\n\n const getOptionNodes = () => {\n const node = dropdownMenuRef.current;\n return node?.getElementsByTagName('a') || [];\n };\n\n const updateItemDOMValues = () => {\n if (dropdownMenuRef.current) {\n const optionNodes = getOptionNodes();\n return [...optionNodes].map(\n item =>\n ({\n id: item.getAttribute(DATA_ATTRIBUTE_ID),\n text: item.textContent,\n }) as OptionDOMValue\n );\n }\n };\n\n const getFocusedOptionNode = () => {\n const optionNodes = getOptionNodes();\n return [...optionNodes].find(item => item.className.includes(HIGHLIGHT_CLASS));\n };\n\n const selectOptionOnEnter = (event: KeyboardEvent) => {\n event.preventDefault();\n\n // When no filter result was found, avoid selecting anything\n if (isEmpty(options)) {\n return;\n }\n\n const match = getFocusedOptionNode();\n\n if (match) {\n const selectedItem = options.find(option => option.id === match.getAttribute(DATA_ATTRIBUTE_ID));\n onSelect(selectedItem);\n }\n };\n\n const handleOptionChange = (event: React.MouseEvent<HTMLAnchorElement>) => {\n event.preventDefault();\n\n const optionId = event.currentTarget.getElementsByTagName('input')[0].value;\n const selectedItem = options.find(option => option.id === optionId);\n\n onSelect(selectedItem);\n };\n\n const dropdownMenuClasses = classNames('dropdown-menu', dropDirection.pullRight && 'pull-right', dropdownClassName);\n\n // Don't show the dropdown, when no match are found when filtering unless there is a not found message\n if (isEmpty(options)) {\n return <NoItemMessage noItemMessage={noItemMessage} className={dropdownMenuClasses} />;\n }\n\n return (\n <ul className={dropdownMenuClasses} ref={dropdownMenuRef} role='menu'>\n {isLoading && (\n <div className='display-flex justify-content-center padding-10'>\n <Spinner />\n </div>\n )}\n {!isLoading &&\n options.map((option, index) => {\n if (option.header) {\n return <DropdownHeader key={option.id} icon={option.icon} label={option.label} />;\n }\n\n // Show focused style only when keyboard is in use\n const anchorClassNames = classNames(\n keyboardUsed && focusedItemIndex === index ? HIGHLIGHT_CLASS : '',\n option.disabled && 'pointer-events-none',\n 'display-flex align-items-center gap-3'\n );\n\n const wrapperClassNames = classNames(\n option.disabled && 'disabled',\n useActiveClass && option.selected && 'active'\n );\n\n return (\n <li key={option.id} className={wrapperClassNames} role='listitem'>\n <a\n role='menuitem'\n className={anchorClassNames}\n data-item-id={option.id}\n data-item-index={index}\n // Note, we need to assign the click callback only when it's not disabled\n // otherwise the functions is still triggered\n onClick={option.disabled ? undefined : handleOptionChange}\n >\n <span className='selected-option-dropdown-item'>\n {option.icon && <>{option.icon}</>}\n {option.label}\n </span>\n <input type='hidden' value={option.id} />\n </a>\n </li>\n );\n })}\n </ul>\n );\n};\n\nexport const filterOptions = <T extends SelectOption>(\n itemDOMValues: OptionDOMValue[],\n filterValue: string,\n options: T[]\n) => {\n const filteredDOMValues = itemDOMValues.filter(item => item.text.toLowerCase().includes(filterValue.toLowerCase()));\n\n // Filter the options according to the filtered DOM values and map the IDs since the filter cannot be done\n // on the options itself as they might contain arbitrary components\n return options.filter(option => filteredDOMValues.find(domValue => domValue.id === option.id));\n};\n\nexport default BaseSelectDropdown;\n"],"names":["DATA_ATTRIBUTE_ID","DEFAULT_FOCUSED_ITEM_INDEX","HIGHLIGHT_CLASS","DEFAULT_SCROLL_DIRECTION","DOWN","BaseSelectDropdown","props","isOpen","isLoading","updateDOMValues","noop","onOpen","onSelect","onClose","options","autoDropDirection","dropup","pullRight","useActiveClass","externalFocusedItemIndex","externalKeyboardUsed","noItemMessage","dropdownClassName","focusedItemIndex","setFocusedItemIndex","useState","keyboardUsed","setKeyboardUsed","lastScrollDirectionRef","useRef","dropdownMenuRef","useEffect","dropDirection","useDropDirection","useLayoutEffect","parent","updateItemDOMValues","scrollItemIntoView","getFocusedOptionNode","previousIsOpen","setPreviousIsOpen","useKey","event","selectOptionOnEnter","focusOption","UP","direction","nextFocusedItem","indexLimit","getOptionNodes","item","isEmpty","match","selectedItem","option","handleOptionChange","optionId","dropdownMenuClasses","classNames","jsx","NoItemMessage","Spinner","index","DropdownHeader","anchorClassNames","wrapperClassNames","jsxs","Fragment","filterOptions","itemDOMValues","filterValue","filteredDOMValues","domValue"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"BaseSelectDropdown.js","sources":["../../../src/components/selects/BaseSelectDropdown.tsx"],"sourcesContent":["import type React from 'react';\nimport { useEffect, useLayoutEffect, useRef, useState } from 'react';\nimport { isEmpty } from 'es-toolkit/compat';\nimport { noop } from 'es-toolkit/function';\n\nimport classNames from '../../utils/classNames';\nimport { useDropDirection } from '../../utils/useDropDirection';\nimport { DOWN, scrollItemIntoView, UP } from '../../utils/scrollItemIntoView';\nimport useKey from '../../useKey';\nimport DropdownHeader from './DropdownHeader';\nimport NoItemMessage from './NoItemMessage';\nimport Spinner from '../spinner/Spinner';\n\nconst DATA_ATTRIBUTE_ID = 'data-item-id';\nconst DEFAULT_FOCUSED_ITEM_INDEX = 0;\nconst HIGHLIGHT_CLASS = 'focus';\nconst DEFAULT_SCROLL_DIRECTION = DOWN;\n\nexport type OptionDOMValue = {\n id: string;\n text: string;\n};\n\nexport type SelectOption = {\n /**\n * Used to identify an option.\n */\n id: string;\n\n /**\n * The option item text.\n */\n label: string | React.ReactNode;\n\n /**\n * Optional description shown below the option item text.\n */\n description?: string | React.ReactNode;\n\n /**\n * Additional classes to be set on the dropdown menu item.\n */\n dropdownItemClassName?: string;\n\n /**\n * Icon to be displayed in front of the label.\n */\n icon?: React.ReactNode;\n\n /**\n * Defines whether the menu item is selected.\n *\n * @default false\n */\n selected?: boolean;\n\n /**\n * Setting \"disabled\" to true will disable the respective item.\n *\n * @default false\n */\n disabled?: boolean;\n\n /**\n * Will treat the given value as a menu header\n */\n header?: boolean;\n};\n\nexport type BaseSelectDropdownProps<T extends SelectOption> = {\n options?: T[];\n isOpen?: boolean;\n isLoading?: boolean;\n updateDOMValues?: (values: OptionDOMValue[] | undefined) => void;\n onOpen?: (hasDropup: boolean) => void;\n onSelect?: (selectedItem: T | undefined) => void;\n onClose?: () => void;\n placeholder?: string | React.ReactNode;\n dropup?: boolean;\n pullRight?: boolean;\n autoDropDirection?: boolean;\n noItemMessage?: string | React.ReactNode;\n focusedItemIndex?: number;\n dropdownClassName?: string;\n keyboardUsed?: boolean;\n useActiveClass?: boolean;\n};\n\nconst BaseSelectDropdown = <T extends SelectOption>(props: BaseSelectDropdownProps<T>) => {\n const {\n isOpen = false,\n isLoading = false,\n updateDOMValues = noop,\n onOpen = noop,\n onSelect = noop,\n onClose = noop,\n options = [],\n autoDropDirection = true,\n dropup = false,\n pullRight = false,\n useActiveClass = false,\n focusedItemIndex: externalFocusedItemIndex,\n keyboardUsed: externalKeyboardUsed,\n noItemMessage,\n dropdownClassName,\n } = props;\n\n const [focusedItemIndex, setFocusedItemIndex] = useState(externalFocusedItemIndex || DEFAULT_FOCUSED_ITEM_INDEX);\n const [keyboardUsed, setKeyboardUsed] = useState(externalKeyboardUsed);\n const lastScrollDirectionRef = useRef<typeof UP | typeof DOWN>(DEFAULT_SCROLL_DIRECTION);\n\n const dropdownMenuRef = useRef<HTMLUListElement>(null);\n\n // Reset scroll position whenever the menu opens to avoid retaining old scroll offsets\n useEffect(() => {\n if (isOpen && dropdownMenuRef.current) {\n dropdownMenuRef.current.scrollTop = 0;\n }\n }, [isOpen]);\n\n // Keep internal focus state in sync when the dropdown opens/closes or when parent-controlled values change\n useEffect(() => {\n if (typeof externalFocusedItemIndex === 'number') {\n setFocusedItemIndex(externalFocusedItemIndex);\n }\n\n if (typeof externalKeyboardUsed === 'boolean') {\n setKeyboardUsed(externalKeyboardUsed);\n }\n\n if (!isOpen) {\n lastScrollDirectionRef.current = DEFAULT_SCROLL_DIRECTION;\n }\n }, [externalFocusedItemIndex, externalKeyboardUsed, isOpen]);\n\n // Overwrite position of dropdown menu in case auto drop is enabled\n const dropDirection = useDropDirection({ pullRight, dropup, autoDropDirection, dropdownMenuRef }, [isOpen]);\n\n // Add or remove the \"dropup\" class from the parent Select/Multiselect component to position\n // the dropdown element accordingly via CSS\n useLayoutEffect(() => {\n if (dropdownMenuRef.current) {\n const parent = dropdownMenuRef.current.parentElement;\n if (dropDirection.dropup) {\n parent?.classList.add('dropup');\n } else {\n parent?.classList.remove('dropup');\n }\n }\n }, [dropDirection, dropdownMenuRef]);\n\n useEffect(() => {\n // all available items need to be rendered in order to know their DOM value\n // which will be used for filtering in the parent component\n updateDOMValues(updateItemDOMValues());\n }, [options]);\n\n // Scroll the focused item into view whenever focus changes\n useEffect(() => {\n if (!isOpen) {\n return;\n }\n\n scrollItemIntoView(\n lastScrollDirectionRef.current || DEFAULT_SCROLL_DIRECTION,\n dropdownMenuRef.current,\n getFocusedOptionNode()\n );\n }, [focusedItemIndex, isOpen]);\n\n // update internal state for isOpen\n const [previousIsOpen, setPreviousIsOpen] = useState(isOpen);\n if (isOpen && !previousIsOpen) {\n onOpen(dropDirection.dropup);\n setPreviousIsOpen(isOpen);\n } else if (!isOpen && previousIsOpen) {\n onClose();\n setPreviousIsOpen(isOpen);\n }\n\n useKey(event => {\n if (isOpen) {\n switch (event.key) {\n case 'Escape': {\n // close dropdown on esc\n onClose();\n break;\n }\n case 'Tab': {\n // close dropdown on tab\n onClose();\n break;\n }\n case 'Enter': {\n // select item on enter\n selectOptionOnEnter(event);\n break;\n }\n case 'ArrowUp': {\n // prevent scrolling the page when dropdown menu is open\n event.preventDefault();\n\n // select item above on arrow up key\n focusOption(UP);\n scrollItemIntoView(UP, dropdownMenuRef.current, getFocusedOptionNode());\n break;\n }\n case 'ArrowDown': {\n // prevent scrolling the page when dropdown menu is open\n event.preventDefault();\n\n // select item below on arrow down key\n focusOption(DOWN);\n scrollItemIntoView(DOWN, dropdownMenuRef.current, getFocusedOptionNode());\n break;\n }\n default:\n break;\n }\n }\n });\n\n const focusOption = (direction: typeof UP | typeof DOWN) => {\n let nextFocusedItem = 0;\n\n switch (direction) {\n case UP: {\n nextFocusedItem = focusedItemIndex <= 0 ? focusedItemIndex : focusedItemIndex - 1;\n break;\n }\n case DOWN: {\n nextFocusedItem = focusedItemIndex === options.length - 1 ? focusedItemIndex : focusedItemIndex + 1;\n break;\n }\n default:\n break;\n }\n\n lastScrollDirectionRef.current = direction;\n\n // In case the next item index is negative, means outside the bounds of the items,\n // reset it depending on the current direction\n const indexLimit = direction === UP ? options.length - 1 : 0;\n\n setFocusedItemIndex(nextFocusedItem < 0 ? indexLimit : nextFocusedItem);\n setKeyboardUsed(true);\n };\n\n const getOptionNodes = () => {\n const node = dropdownMenuRef.current;\n return node?.getElementsByTagName('a') || [];\n };\n\n const updateItemDOMValues = () => {\n if (dropdownMenuRef.current) {\n const optionNodes = getOptionNodes();\n return [...optionNodes].map(\n item =>\n ({\n id: item.getAttribute(DATA_ATTRIBUTE_ID),\n text: item.textContent,\n }) as OptionDOMValue\n );\n }\n };\n\n const getFocusedOptionNode = () => {\n const optionNodes = getOptionNodes();\n return [...optionNodes].find(item => item.className.includes(HIGHLIGHT_CLASS));\n };\n\n const selectOptionOnEnter = (event: KeyboardEvent) => {\n event.preventDefault();\n\n // When no filter result was found, avoid selecting anything\n if (isEmpty(options)) {\n return;\n }\n\n const match = getFocusedOptionNode();\n\n if (match) {\n const selectedItem = options.find(option => option.id === match.getAttribute(DATA_ATTRIBUTE_ID));\n onSelect(selectedItem);\n }\n };\n\n const handleOptionChange = (event: React.MouseEvent<HTMLAnchorElement>) => {\n event.preventDefault();\n\n const optionId = event.currentTarget.getElementsByTagName('input')[0].value;\n const selectedItem = options.find(option => option.id === optionId);\n\n onSelect(selectedItem);\n };\n\n const dropdownMenuClasses = classNames('dropdown-menu', dropDirection.pullRight && 'pull-right', dropdownClassName);\n\n // Don't show the dropdown, when no match are found when filtering unless there is a not found message\n if (isEmpty(options)) {\n return <NoItemMessage noItemMessage={noItemMessage} className={dropdownMenuClasses} />;\n }\n\n return (\n <ul className={dropdownMenuClasses} ref={dropdownMenuRef} role='menu'>\n {isLoading && (\n <div className='display-flex justify-content-center padding-10'>\n <Spinner />\n </div>\n )}\n {!isLoading &&\n options.map((option, index) => {\n if (option.header) {\n return <DropdownHeader key={option.id} icon={option.icon} label={option.label} />;\n }\n\n // Show focused style only when keyboard is in use\n const anchorClassNames = classNames(\n keyboardUsed && focusedItemIndex === index ? HIGHLIGHT_CLASS : '',\n option.disabled && 'pointer-events-none',\n 'display-flex align-items-center gap-3',\n option.dropdownItemClassName\n );\n\n const wrapperClassNames = classNames(\n option.disabled && 'disabled',\n useActiveClass && option.selected && 'active'\n );\n\n return (\n <li key={option.id} className={wrapperClassNames} role='listitem'>\n <a\n role='menuitem'\n className={anchorClassNames}\n data-item-id={option.id}\n data-item-index={index}\n // Note, we need to assign the click callback only when it's not disabled\n // otherwise the functions is still triggered\n onClick={option.disabled ? undefined : handleOptionChange}\n >\n <span\n className={classNames(\n 'selected-option-dropdown-item',\n option.description && 'selected-option-dropdown-item-with-description'\n )}\n >\n {option.icon && <>{option.icon}</>}\n {option.description ? (\n <span className='selected-option-dropdown-text'>\n <span className='selected-option-dropdown-label'>{option.label}</span>\n <span className='selected-option-dropdown-description'>\n {' '}\n {option.description}\n </span>\n </span>\n ) : (\n option.label\n )}\n </span>\n <input type='hidden' value={option.id} />\n </a>\n </li>\n );\n })}\n </ul>\n );\n};\n\nexport const filterOptions = <T extends SelectOption>(\n itemDOMValues: OptionDOMValue[],\n filterValue: string,\n options: T[]\n) => {\n const filteredDOMValues = itemDOMValues.filter(item => item.text.toLowerCase().includes(filterValue.toLowerCase()));\n\n // Filter the options according to the filtered DOM values and map the IDs since the filter cannot be done\n // on the options itself as they might contain arbitrary components\n return options.filter(option => filteredDOMValues.find(domValue => domValue.id === option.id));\n};\n\nexport default BaseSelectDropdown;\n"],"names":["DATA_ATTRIBUTE_ID","DEFAULT_FOCUSED_ITEM_INDEX","HIGHLIGHT_CLASS","DEFAULT_SCROLL_DIRECTION","DOWN","BaseSelectDropdown","props","isOpen","isLoading","updateDOMValues","noop","onOpen","onSelect","onClose","options","autoDropDirection","dropup","pullRight","useActiveClass","externalFocusedItemIndex","externalKeyboardUsed","noItemMessage","dropdownClassName","focusedItemIndex","setFocusedItemIndex","useState","keyboardUsed","setKeyboardUsed","lastScrollDirectionRef","useRef","dropdownMenuRef","useEffect","dropDirection","useDropDirection","useLayoutEffect","parent","updateItemDOMValues","scrollItemIntoView","getFocusedOptionNode","previousIsOpen","setPreviousIsOpen","useKey","event","selectOptionOnEnter","focusOption","UP","direction","nextFocusedItem","indexLimit","getOptionNodes","item","isEmpty","match","selectedItem","option","handleOptionChange","optionId","dropdownMenuClasses","classNames","jsx","NoItemMessage","Spinner","index","DropdownHeader","anchorClassNames","wrapperClassNames","jsxs","Fragment","filterOptions","itemDOMValues","filterValue","filteredDOMValues","domValue"],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
2
|
import { SelectOption } from './BaseSelectDropdown';
|
|
3
|
+
import { TrackingAttributes } from '../../utils/analytics/googleAnalyticsUtils';
|
|
3
4
|
import { WithFeedbackAndAddonProps } from './WithFeedbackAndAddon';
|
|
4
5
|
export type MultiselectCounterMessage = {
|
|
5
6
|
/**
|
|
@@ -170,6 +171,10 @@ export type MultiselectProps<T extends MultiselectOption> = Omit<WithFeedbackAnd
|
|
|
170
171
|
* Additional classes to be set to the select wrapper
|
|
171
172
|
*/
|
|
172
173
|
className?: string;
|
|
174
|
+
/**
|
|
175
|
+
* Optional tracking attributes added to the toggle button.
|
|
176
|
+
*/
|
|
177
|
+
trackingAttributes?: TrackingAttributes;
|
|
173
178
|
};
|
|
174
179
|
declare const Multiselect: (props: MultiselectProps<MultiselectOption>) => import("react/jsx-runtime").JSX.Element;
|
|
175
180
|
export default Multiselect;
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
import { jsxs as N, jsx as a } from "react/jsx-runtime";
|
|
2
2
|
import { useState as n, useRef as T } from "react";
|
|
3
|
-
import { isEqual as
|
|
4
|
-
import { isEmpty as
|
|
3
|
+
import { isEqual as k } from "es-toolkit/predicate";
|
|
4
|
+
import { isEmpty as ke } from "es-toolkit/compat";
|
|
5
5
|
import { noop as ye } from "es-toolkit/function";
|
|
6
6
|
import G from "../../utils/classNames.js";
|
|
7
|
-
import Re, { filterOptions as
|
|
8
|
-
import
|
|
9
|
-
import
|
|
10
|
-
import
|
|
11
|
-
import
|
|
12
|
-
import
|
|
13
|
-
import
|
|
14
|
-
import
|
|
15
|
-
import
|
|
16
|
-
const I = -1,
|
|
7
|
+
import Re, { filterOptions as Ee } from "./BaseSelectDropdown.js";
|
|
8
|
+
import Pe from "./ClearButton.js";
|
|
9
|
+
import _e from "./MultiselectToggleCounter.js";
|
|
10
|
+
import Ke from "./MultiselectToggleSelection.js";
|
|
11
|
+
import Ue from "./MultiselectToggleFilter.js";
|
|
12
|
+
import Be from "./MultiselectTogglePlaceholder.js";
|
|
13
|
+
import Ve from "../../hooks/useClickOutside.js";
|
|
14
|
+
import We from "../../hooks/useMergeRefs.js";
|
|
15
|
+
import je from "./WithFeedbackAndAddon.js";
|
|
16
|
+
const I = -1, nt = (H) => {
|
|
17
17
|
const {
|
|
18
|
-
name:
|
|
19
|
-
id: J =
|
|
18
|
+
name: y,
|
|
19
|
+
id: J = y,
|
|
20
20
|
options: o = [],
|
|
21
21
|
value: i,
|
|
22
22
|
onChange: S = ye,
|
|
@@ -27,7 +27,7 @@ const I = -1, ot = (H) => {
|
|
|
27
27
|
autoDropDirection: ee = !0,
|
|
28
28
|
bsSize: w = "md",
|
|
29
29
|
variant: te = "default",
|
|
30
|
-
disabled:
|
|
30
|
+
disabled: R = !1,
|
|
31
31
|
tabIndex: se = 0,
|
|
32
32
|
hasError: oe = !1,
|
|
33
33
|
useFilter: E = !1,
|
|
@@ -45,10 +45,11 @@ const I = -1, ot = (H) => {
|
|
|
45
45
|
messageWhiteSpace: ae = "normal",
|
|
46
46
|
btnClassName: B,
|
|
47
47
|
dropdownClassName: ie,
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
trackingAttributes: ce,
|
|
49
|
+
...de
|
|
50
|
+
} = H, [l, M] = n(!1), [r, u] = n(i || []), [v, f] = n(!1), [O, p] = n(""), [ue, d] = n(o), [V, fe] = n([]), [pe, h] = n(I), [me, m] = n(!1), W = T(null), x = T(null), ge = Ve((e) => {
|
|
50
51
|
x.current && !x.current.contains(e.target) && z();
|
|
51
|
-
}),
|
|
52
|
+
}), he = We(x, ge), D = (e, t) => {
|
|
52
53
|
if (t)
|
|
53
54
|
u(t);
|
|
54
55
|
else if (e) {
|
|
@@ -57,43 +58,43 @@ const I = -1, ot = (H) => {
|
|
|
57
58
|
}
|
|
58
59
|
}, j = T(!0);
|
|
59
60
|
j.current && (D(o, i), j.current = !1);
|
|
60
|
-
const [
|
|
61
|
-
|
|
62
|
-
const [
|
|
63
|
-
|
|
64
|
-
const
|
|
65
|
-
!e.length || (v || O) && V.length > 0 ||
|
|
66
|
-
(s) =>
|
|
61
|
+
const [Ie, Se] = n(i);
|
|
62
|
+
k(i, Ie) || (D(o, i), Se(i));
|
|
63
|
+
const [we, Ce] = n(o);
|
|
64
|
+
k(o, we) || (D(o, i), d(o), Ce(o));
|
|
65
|
+
const Fe = (e = []) => {
|
|
66
|
+
!e.length || (v || O) && V.length > 0 || fe(
|
|
67
|
+
(s) => k(s, e) ? s : e
|
|
67
68
|
);
|
|
68
69
|
}, L = () => /* @__PURE__ */ a(
|
|
69
|
-
|
|
70
|
+
Ue,
|
|
70
71
|
{
|
|
71
72
|
isActive: v || !!O,
|
|
72
73
|
selectedItemIds: r,
|
|
73
74
|
filterValue: O,
|
|
74
|
-
onFilterChange:
|
|
75
|
+
onFilterChange: Oe
|
|
75
76
|
}
|
|
76
|
-
),
|
|
77
|
-
|
|
77
|
+
), be = () => C || F ? /* @__PURE__ */ a(
|
|
78
|
+
_e,
|
|
78
79
|
{
|
|
79
80
|
selectedAmount: r.length,
|
|
80
81
|
counterMessage: C,
|
|
81
82
|
customRenderer: F
|
|
82
83
|
}
|
|
83
84
|
) : /* @__PURE__ */ a(
|
|
84
|
-
|
|
85
|
+
Ke,
|
|
85
86
|
{
|
|
86
87
|
options: o,
|
|
87
88
|
selectedItemIds: r,
|
|
88
89
|
showSelectedItemIcon: le,
|
|
89
90
|
showUnselectedItemIcons: P,
|
|
90
|
-
onRemoveItem:
|
|
91
|
+
onRemoveItem: De,
|
|
91
92
|
multiline: g,
|
|
92
93
|
hasInputAddon: !!b,
|
|
93
94
|
hasFilter: E,
|
|
94
95
|
children: g && L()
|
|
95
96
|
}
|
|
96
|
-
),
|
|
97
|
+
), Me = () => {
|
|
97
98
|
const e = G(
|
|
98
99
|
"dropdown-toggle",
|
|
99
100
|
"form-control",
|
|
@@ -102,31 +103,32 @@ const I = -1, ot = (H) => {
|
|
|
102
103
|
w === "sm" && "input-sm",
|
|
103
104
|
w === "lg" && "input-lg",
|
|
104
105
|
g && "height-auto",
|
|
105
|
-
|
|
106
|
-
), t =
|
|
106
|
+
R && "disabled"
|
|
107
|
+
), t = ke(r) && !P, s = E && l && !C && !F, c = r.length > 0 ? { id: "__multiselect-clear__", label: "" } : null, X = /* @__PURE__ */ N(
|
|
107
108
|
"button",
|
|
108
109
|
{
|
|
109
110
|
type: "button",
|
|
110
111
|
id: J,
|
|
111
|
-
name:
|
|
112
|
+
name: y,
|
|
112
113
|
className: e,
|
|
114
|
+
...ce,
|
|
113
115
|
"data-toggle": "dropdown",
|
|
114
116
|
tabIndex: se,
|
|
115
117
|
"aria-haspopup": "true",
|
|
116
118
|
"aria-expanded": l,
|
|
117
119
|
onClick: A,
|
|
118
|
-
onKeyDown:
|
|
120
|
+
onKeyDown: Ne,
|
|
119
121
|
ref: W,
|
|
120
122
|
children: [
|
|
121
|
-
t ? /* @__PURE__ */ a(
|
|
123
|
+
t ? /* @__PURE__ */ a(Be, { placeholder: Q }) : be(),
|
|
122
124
|
s && !g && L(),
|
|
123
125
|
/* @__PURE__ */ N("span", { className: "select-toggle-actions", children: [
|
|
124
126
|
/* @__PURE__ */ a(
|
|
125
|
-
|
|
127
|
+
Pe,
|
|
126
128
|
{
|
|
127
129
|
showClear: ne,
|
|
128
130
|
selectedItem: c,
|
|
129
|
-
onClear:
|
|
131
|
+
onClear: Ae
|
|
130
132
|
}
|
|
131
133
|
),
|
|
132
134
|
/* @__PURE__ */ a("span", { className: "caret" })
|
|
@@ -135,7 +137,7 @@ const I = -1, ot = (H) => {
|
|
|
135
137
|
}
|
|
136
138
|
);
|
|
137
139
|
return !b && !K && !U ? X : /* @__PURE__ */ a(
|
|
138
|
-
|
|
140
|
+
je,
|
|
139
141
|
{
|
|
140
142
|
bsSize: w,
|
|
141
143
|
inputAddon: b,
|
|
@@ -145,18 +147,18 @@ const I = -1, ot = (H) => {
|
|
|
145
147
|
children: X
|
|
146
148
|
}
|
|
147
149
|
);
|
|
148
|
-
},
|
|
149
|
-
const e =
|
|
150
|
+
}, ve = () => {
|
|
151
|
+
const e = ue.map((t) => (t.selected = r.indexOf(t.id) !== -1, t));
|
|
150
152
|
return /* @__PURE__ */ a(
|
|
151
153
|
Re,
|
|
152
154
|
{
|
|
153
155
|
isOpen: l,
|
|
154
156
|
isLoading: Y,
|
|
155
157
|
options: e,
|
|
156
|
-
focusedItemIndex:
|
|
157
|
-
keyboardUsed:
|
|
158
|
-
updateDOMValues:
|
|
159
|
-
onSelect:
|
|
158
|
+
focusedItemIndex: pe,
|
|
159
|
+
keyboardUsed: me,
|
|
160
|
+
updateDOMValues: Fe,
|
|
161
|
+
onSelect: xe,
|
|
160
162
|
onClose: z,
|
|
161
163
|
noItemMessage: re,
|
|
162
164
|
pullRight: $,
|
|
@@ -166,18 +168,18 @@ const I = -1, ot = (H) => {
|
|
|
166
168
|
dropdownClassName: ie
|
|
167
169
|
}
|
|
168
170
|
);
|
|
169
|
-
},
|
|
171
|
+
}, Oe = (e) => {
|
|
170
172
|
e.preventDefault();
|
|
171
173
|
const t = e.currentTarget.value;
|
|
172
174
|
if (t === "") {
|
|
173
175
|
f(!1), p(""), d(o), m(!1), h(I);
|
|
174
176
|
return;
|
|
175
177
|
}
|
|
176
|
-
const s =
|
|
178
|
+
const s = Ee(V, t, o);
|
|
177
179
|
l || M(!0);
|
|
178
180
|
const c = s.length > 0 ? 0 : -1;
|
|
179
181
|
f(!0), p(t), d(s), s.length > 0 && m(!0), h(c);
|
|
180
|
-
},
|
|
182
|
+
}, xe = (e) => {
|
|
181
183
|
if (e?.disabled)
|
|
182
184
|
return;
|
|
183
185
|
const t = e ? q(e.id) : r;
|
|
@@ -185,13 +187,13 @@ const I = -1, ot = (H) => {
|
|
|
185
187
|
}, q = (e) => {
|
|
186
188
|
const t = [...r], s = r.indexOf(e);
|
|
187
189
|
return s !== -1 ? t.splice(s, 1) : t.push(e), t;
|
|
188
|
-
},
|
|
190
|
+
}, De = (e, t) => {
|
|
189
191
|
e.stopPropagation();
|
|
190
192
|
const s = q(t);
|
|
191
193
|
u(s), S(s);
|
|
192
|
-
},
|
|
194
|
+
}, Ae = () => {
|
|
193
195
|
u([]), f(!1), p(""), d(o), m(!1), h(I), S([]);
|
|
194
|
-
},
|
|
196
|
+
}, Ne = (e) => {
|
|
195
197
|
switch (e.key) {
|
|
196
198
|
case "Space":
|
|
197
199
|
l || (e.preventDefault(), A(e));
|
|
@@ -201,13 +203,13 @@ const I = -1, ot = (H) => {
|
|
|
201
203
|
break;
|
|
202
204
|
}
|
|
203
205
|
}, A = (e) => {
|
|
204
|
-
if (
|
|
206
|
+
if (R || v)
|
|
205
207
|
return;
|
|
206
208
|
const t = e.detail === 0;
|
|
207
209
|
M((s) => !s), m(t);
|
|
208
210
|
}, z = () => {
|
|
209
211
|
l && (M(!1), f(!1), p(""), d(o), h(I), m(!1), W?.current?.focus());
|
|
210
|
-
},
|
|
212
|
+
}, Te = G(
|
|
211
213
|
"select",
|
|
212
214
|
"multiselect",
|
|
213
215
|
"dropdown",
|
|
@@ -216,12 +218,12 @@ const I = -1, ot = (H) => {
|
|
|
216
218
|
te === "blank" && "select-blank",
|
|
217
219
|
_ && _
|
|
218
220
|
);
|
|
219
|
-
return /* @__PURE__ */ N("div", { ...
|
|
220
|
-
|
|
221
|
-
|
|
221
|
+
return /* @__PURE__ */ N("div", { ...de, className: Te, ref: he, children: [
|
|
222
|
+
Me(),
|
|
223
|
+
ve()
|
|
222
224
|
] });
|
|
223
225
|
};
|
|
224
226
|
export {
|
|
225
|
-
|
|
227
|
+
nt as default
|
|
226
228
|
};
|
|
227
229
|
//# sourceMappingURL=Multiselect.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Multiselect.js","sources":["../../../src/components/selects/Multiselect.tsx"],"sourcesContent":["import type React from 'react';\nimport { useRef, useState } from 'react';\nimport { isEqual } from 'es-toolkit/predicate';\nimport { isEmpty } from 'es-toolkit/compat';\nimport { noop } from 'es-toolkit/function';\n\nimport classNames from '../../utils/classNames';\nimport BaseSelectDropdown, { filterOptions, type OptionDOMValue, type SelectOption } from './BaseSelectDropdown';\nimport ClearButton from './ClearButton';\nimport MultiselectToggleCounter from './MultiselectToggleCounter';\nimport MultiselectToggleSelection from './MultiselectToggleSelection';\nimport MultiselectToggleFilter from './MultiselectToggleFilter';\nimport MultiselectTogglePlaceholder from './MultiselectTogglePlaceholder';\nimport useClickOutside from '../../useClickOutside';\nimport useMergeRefs from '../../hooks/useMergeRefs';\nimport WithFeedbackAndAddon, { type WithFeedbackAndAddonProps } from './WithFeedbackAndAddon';\n\nconst DEFAULT_FOCUSED_ITEM_INDEX = -1;\n\nexport type MultiselectCounterMessage = {\n /**\n * Text that will be used when a single item is selected.\n */\n one: string | React.ReactNode;\n\n /**\n * Text that will be used when multiple item are selected.\n */\n many: string | React.ReactNode;\n};\n\nexport type MultiselectOption = SelectOption & {};\n\nexport type MultiselectProps<T extends MultiselectOption> = Omit<WithFeedbackAndAddonProps, 'bsSize'> & {\n /**\n * Passed through as HTML attribute to the toggle button.\n */\n name?: string;\n\n /**\n * Passed as HTML attribute to the toggle button.\n *\n * @default Uses the value given to `name` if not provided explicitly.\n */\n id?: string;\n\n /**\n * Items to display in the dropdown menu.\n *\n * @default []\n */\n options?: T[];\n\n /**\n * Sets the ids of the selected options when the component is already mounted.\n */\n value?: string[];\n\n /**\n * Callback function triggered when an item is selected.\n *\n * @param selectedItemIds Array containing all the IDs that have been selected.\n *\n * @default () => {}\n */\n onChange?: (selectedItemIds: string[]) => void;\n\n /**\n * Text to display when nothing is selected.\n */\n placeholder?: string | React.ReactNode;\n\n /**\n * Defines whether the dropdown opens upwards.\n *\n * Set to `true` additionally disables autoDrop feature.\n *\n * @default false\n */\n dropup?: boolean;\n\n /**\n * Defines whether the dropdown opens right aligned to the dropdown toggle.\n *\n * Set to 'true' additionally disables autoDrop feature.\n *\n * @default false\n */\n pullRight?: boolean;\n\n /**\n * Enables or disables the autoDrop positioning feature.\n *\n * When enabled, the option list opens below or above the input depending on the surrounding space.\n *\n * @default true\n */\n autoDropDirection?: boolean;\n\n /**\n * Shows a loading spinner instead of the menu items if set to true.\n * @default false\n */\n isLoading?: boolean;\n\n /**\n * Defines the size of the select to be rendered.\n *\n * @default 'md'\n */\n bsSize?: 'sm' | 'md' | 'lg';\n\n /**\n * Defines the visual variant of the select.\n *\n * @default 'default'\n */\n variant?: 'default' | 'blank';\n\n /**\n * Option to disable the opening of the option list.\n *\n * @default false\n */\n disabled?: boolean;\n\n /**\n * Sets the input's tabindex attribute.\n *\n * The tabindex attribute allows developers to make HTML elements focusable, allow or prevent them from being\n * sequentially focusable (usually with the Tab key, hence the name) and determine their relative ordering for\n * sequential focus navigation.\n *\n * @default 0\n */\n tabIndex?: number;\n\n /**\n * Defines whether the Bootstrap error classes shall be added to the toggle element.\n *\n * @default false\n */\n hasError?: boolean;\n\n /**\n * Defines whether the selected items wrap around within the dropdown toggle.\n *\n * @default false\n */\n multiline?: boolean;\n\n /**\n * Defines whether the component should be filterable.\n *\n * @default false\n */\n useFilter?: boolean;\n\n /**\n * Set to show a clear button.\n *\n * @default false\n */\n useClear?: boolean;\n\n /**\n * Text that shall be shown when not match was found when filtering.\n */\n noItemMessage?: string | React.ReactNode;\n\n /**\n * Object that will render the number of selected items instead of individual items.\n *\n * Using this prop will disable the filter functionality.\n */\n counterMessage?: MultiselectCounterMessage;\n\n /**\n * Optional render function that is used to render the message how many items have been selected.\n *\n * Using this prop will disable the filter functionality.\n *\n * @param selectedAmount The total amount of selected items.\n */\n renderCounterMessage?: (selectedAmount: number) => React.ReactNode;\n\n /**\n * Set to show only the icon and not the label of selected item.\n *\n * @default false\n */\n showSelectedItemIcon?: boolean;\n\n /**\n * Set to show all item icons within the toggle element.\n *\n * Selected items are highlighted and unselected items are shown as inactive.\n *\n * @default false\n */\n showUnselectedItemIcons?: boolean;\n\n /**\n * Additional classes to be set to the dropdown.\n */\n dropdownClassName?: string;\n\n /**\n * Additional classes to be set to the select/input.\n */\n btnClassName?: string;\n\n /**\n * Additional classes to be set to the select wrapper\n */\n className?: string;\n};\n\nconst Multiselect = (props: MultiselectProps<MultiselectOption>) => {\n const {\n name,\n id = name,\n options = [],\n value,\n onChange = noop,\n placeholder,\n isLoading = false,\n dropup = false,\n pullRight = false,\n autoDropDirection = true,\n bsSize = 'md',\n variant = 'default',\n disabled = false,\n tabIndex = 0,\n hasError = false,\n useFilter = false,\n useClear = false,\n multiline = false,\n noItemMessage,\n counterMessage,\n renderCounterMessage,\n showSelectedItemIcon = false,\n showUnselectedItemIcons = false,\n className,\n inputAddon,\n errorMessage,\n warningMessage,\n messageWhiteSpace = 'normal',\n btnClassName,\n dropdownClassName,\n ...remainingProps\n } = props;\n\n const [isOpen, setIsOpen] = useState(false);\n const [selectedItemIds, setSelectedItemIds] = useState<string[]>(value || []);\n const [isFilterActive, setIsFilterActive] = useState(false);\n const [filterValue, setFilterValue] = useState('');\n const [filteredOptions, setFilteredOptions] = useState<MultiselectOption[]>(options);\n const [itemDOMValues, setItemDOMValues] = useState<OptionDOMValue[]>([]);\n const [focusedItemIndex, setFocusedItemIndex] = useState(DEFAULT_FOCUSED_ITEM_INDEX);\n const [keyboardUsed, setKeyboardUsed] = useState(false);\n\n const refToggle = useRef<HTMLButtonElement>(null);\n const refMultiSelectWrapper = useRef<HTMLDivElement>(null);\n\n const ref = useClickOutside(event => {\n // Check if the click is truly outside the multiselect wrapper\n if (refMultiSelectWrapper.current && !refMultiSelectWrapper.current.contains(event.target as Node)) {\n closeMenu();\n }\n });\n\n const mergedSelectRefs = useMergeRefs(refMultiSelectWrapper, ref);\n\n const updateSelectedItems = (optionsToCheck: MultiselectOption[], selectedItem: string[] | undefined) => {\n if (selectedItem) {\n setSelectedItemIds(selectedItem);\n } else if (optionsToCheck) {\n const filteredBySelection = optionsToCheck.filter(item => item.selected);\n setSelectedItemIds(filteredBySelection.map(option => option.id));\n }\n };\n\n // Update the selectedItems on first render.\n // Note, we use a ref instead of an effect as the effect is triggered too late\n const firstRenderRef = useRef<boolean>(true);\n if (firstRenderRef.current) {\n updateSelectedItems(options, value);\n firstRenderRef.current = false;\n }\n\n // Update selection based on changed value prop\n const [previousValue, setPreviousValue] = useState(value);\n if (!isEqual(value, previousValue)) {\n updateSelectedItems(options, value);\n setPreviousValue(value);\n }\n\n // Update options when they have changed from the outside\n const [previousOptions, setPreviousOptions] = useState(options);\n if (!isEqual(options, previousOptions)) {\n updateSelectedItems(options, value);\n setFilteredOptions(options);\n setPreviousOptions(options);\n }\n\n const updateDOMValues = (updatedItemDOMValues: OptionDOMValue[] = []) => {\n if (!updatedItemDOMValues.length) {\n return;\n }\n\n const shouldKeepPreviousSnapshot = (isFilterActive || filterValue) && itemDOMValues.length > 0;\n if (shouldKeepPreviousSnapshot) {\n return;\n }\n\n setItemDOMValues(currentItemDOMValues =>\n isEqual(currentItemDOMValues, updatedItemDOMValues) ? currentItemDOMValues : updatedItemDOMValues\n );\n };\n\n const renderFilter = () => (\n <MultiselectToggleFilter\n isActive={isFilterActive || !!filterValue}\n selectedItemIds={selectedItemIds}\n filterValue={filterValue}\n onFilterChange={handleFilterChange}\n />\n );\n\n const renderSelection = () => {\n if (counterMessage || renderCounterMessage) {\n return (\n <MultiselectToggleCounter\n selectedAmount={selectedItemIds.length}\n counterMessage={counterMessage}\n customRenderer={renderCounterMessage}\n />\n );\n }\n\n return (\n <MultiselectToggleSelection\n options={options}\n selectedItemIds={selectedItemIds}\n showSelectedItemIcon={showSelectedItemIcon}\n showUnselectedItemIcons={showUnselectedItemIcons}\n onRemoveItem={handleRemoveSelectedItem}\n multiline={multiline}\n hasInputAddon={!!inputAddon}\n hasFilter={useFilter}\n >\n {multiline && renderFilter()}\n </MultiselectToggleSelection>\n );\n };\n\n const renderToggle = () => {\n const wrapperClassNames = classNames(\n 'dropdown-toggle',\n 'form-control',\n 'text-left',\n btnClassName && btnClassName,\n bsSize === 'sm' && 'input-sm',\n bsSize === 'lg' && 'input-lg',\n multiline && 'height-auto',\n disabled && 'disabled'\n );\n\n const showPlaceholder = isEmpty(selectedItemIds) && !showUnselectedItemIcons;\n const showFilter = useFilter && isOpen && !counterMessage && !renderCounterMessage;\n const selectedItemForClearButton =\n selectedItemIds.length > 0 ? ({ id: '__multiselect-clear__', label: '' } as SelectOption) : null;\n\n const toggleButton = (\n <button\n type='button'\n id={id}\n name={name}\n className={wrapperClassNames}\n data-toggle='dropdown'\n tabIndex={tabIndex}\n aria-haspopup='true'\n aria-expanded={isOpen}\n onClick={onToggle}\n onKeyDown={handleToggleKeyDown}\n ref={refToggle}\n >\n {showPlaceholder ? <MultiselectTogglePlaceholder placeholder={placeholder} /> : renderSelection()}\n {showFilter && !multiline && renderFilter()}\n <span className='select-toggle-actions'>\n <ClearButton\n showClear={useClear}\n selectedItem={selectedItemForClearButton}\n onClear={handleClearSelectedItems}\n />\n <span className='caret' />\n </span>\n </button>\n );\n\n if (!inputAddon && !errorMessage && !warningMessage) {\n return toggleButton;\n }\n\n return (\n <WithFeedbackAndAddon\n bsSize={bsSize}\n inputAddon={inputAddon}\n errorMessage={errorMessage}\n warningMessage={warningMessage}\n messageWhiteSpace={messageWhiteSpace}\n >\n {toggleButton}\n </WithFeedbackAndAddon>\n );\n };\n\n const renderDropdownMenu = () => {\n const nonSelectedOptions = filteredOptions.map(option => {\n option.selected = selectedItemIds.indexOf(option.id) !== -1;\n return option;\n });\n\n return (\n <BaseSelectDropdown\n isOpen={isOpen}\n isLoading={isLoading}\n options={nonSelectedOptions}\n focusedItemIndex={focusedItemIndex}\n keyboardUsed={keyboardUsed}\n updateDOMValues={updateDOMValues}\n onSelect={onOptionChange}\n onClose={closeMenu}\n noItemMessage={noItemMessage}\n pullRight={pullRight}\n useActiveClass\n dropup={dropup}\n autoDropDirection={autoDropDirection}\n dropdownClassName={dropdownClassName}\n />\n );\n };\n\n const handleFilterChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n event.preventDefault();\n\n const targetFilterValue = event.currentTarget.value;\n\n if (targetFilterValue === '') {\n setIsFilterActive(false);\n setFilterValue('');\n setFilteredOptions(options);\n setKeyboardUsed(false);\n setFocusedItemIndex(DEFAULT_FOCUSED_ITEM_INDEX);\n return;\n }\n\n const optionsFiltered = filterOptions(itemDOMValues, targetFilterValue, options);\n\n if (!isOpen) {\n // Ensure dropdown stays open when filtering\n setIsOpen(true);\n }\n\n const newFocusedItemIndex = optionsFiltered.length > 0 ? 0 : -1;\n\n setIsFilterActive(true);\n setFilterValue(targetFilterValue);\n setFilteredOptions(optionsFiltered);\n\n if (optionsFiltered.length > 0) {\n // Only set keyboard used if there are filtered options\n setKeyboardUsed(true);\n }\n\n setFocusedItemIndex(newFocusedItemIndex);\n };\n\n const onOptionChange = (currentSelectedItem: MultiselectOption | undefined) => {\n // prevent selecting disabled Items via keyboard\n if (currentSelectedItem?.disabled) {\n return;\n }\n\n const updatedSelectedItems = currentSelectedItem ? updateSelection(currentSelectedItem.id) : selectedItemIds;\n\n // Reset everything after an option was selected. Remove the filter again.\n setSelectedItemIds(updatedSelectedItems);\n setIsFilterActive(false);\n setFilterValue('');\n setFilteredOptions(options);\n\n onChange(updatedSelectedItems);\n };\n\n const updateSelection = (selectedItemId: string) => {\n const newSelectedItems = [...selectedItemIds];\n const itemIndex = selectedItemIds.indexOf(selectedItemId);\n\n if (itemIndex !== -1) {\n newSelectedItems.splice(itemIndex, 1);\n } else {\n newSelectedItems.push(selectedItemId);\n }\n\n return newSelectedItems;\n };\n\n const handleRemoveSelectedItem = (event: React.MouseEvent<HTMLSpanElement>, itemId: string) => {\n event.stopPropagation();\n\n const newSelectedItems = updateSelection(itemId);\n setSelectedItemIds(newSelectedItems);\n\n onChange(newSelectedItems);\n };\n\n const handleClearSelectedItems = () => {\n setSelectedItemIds([]);\n setIsFilterActive(false);\n setFilterValue('');\n setFilteredOptions(options);\n setKeyboardUsed(false);\n setFocusedItemIndex(DEFAULT_FOCUSED_ITEM_INDEX);\n\n onChange([]);\n };\n\n const handleToggleKeyDown = (event: React.KeyboardEvent<HTMLButtonElement>) => {\n switch (event.key) {\n case 'Space':\n if (!isOpen) {\n // open on space\n event.preventDefault();\n onToggle(event);\n }\n break;\n case 'Enter':\n if (!isOpen) {\n // open on enter\n event.preventDefault();\n onToggle(event);\n }\n break;\n default:\n break;\n }\n };\n\n const onToggle = (event: React.MouseEvent<HTMLButtonElement> | React.KeyboardEvent<HTMLButtonElement>) => {\n // Don't toggle when component is disabled or an item in the toggle was clicked in order to remove from\n // selection neither close when filter is active, means entering some filter value\n // in order to avoid closing menu on space but allow to use it for filtering\n if (disabled || isFilterActive) {\n return;\n }\n\n // using the enter key on the toggle button will trigger a synthetic click event as all buttons are of\n // type submit by default in HTML. In order to differentiate between real click and a synthetic event\n // caused by they keyboard, use the event details. A synthetic event is always 0.\n const isKeyboardUsed = event.detail === 0;\n\n setIsOpen(prevValue => !prevValue);\n setKeyboardUsed(isKeyboardUsed);\n };\n\n const closeMenu = () => {\n if (isOpen) {\n setIsOpen(false);\n setIsFilterActive(false);\n setFilterValue('');\n setFilteredOptions(options);\n setFocusedItemIndex(DEFAULT_FOCUSED_ITEM_INDEX);\n setKeyboardUsed(false);\n\n refToggle?.current?.focus();\n }\n };\n\n const wrapperClasses = classNames(\n 'select',\n 'multiselect',\n 'dropdown',\n isOpen && 'open',\n hasError && 'has-error',\n variant === 'blank' && 'select-blank',\n className && className\n );\n\n return (\n <div {...remainingProps} className={wrapperClasses} ref={mergedSelectRefs}>\n {renderToggle()}\n {renderDropdownMenu()}\n </div>\n );\n};\n\nexport default Multiselect;\n"],"names":["DEFAULT_FOCUSED_ITEM_INDEX","Multiselect","props","name","id","options","value","onChange","noop","placeholder","isLoading","dropup","pullRight","autoDropDirection","bsSize","variant","disabled","tabIndex","hasError","useFilter","useClear","multiline","noItemMessage","counterMessage","renderCounterMessage","showSelectedItemIcon","showUnselectedItemIcons","className","inputAddon","errorMessage","warningMessage","messageWhiteSpace","btnClassName","dropdownClassName","remainingProps","isOpen","setIsOpen","useState","selectedItemIds","setSelectedItemIds","isFilterActive","setIsFilterActive","filterValue","setFilterValue","filteredOptions","setFilteredOptions","itemDOMValues","setItemDOMValues","focusedItemIndex","setFocusedItemIndex","keyboardUsed","setKeyboardUsed","refToggle","useRef","refMultiSelectWrapper","ref","useClickOutside","event","closeMenu","mergedSelectRefs","useMergeRefs","updateSelectedItems","optionsToCheck","selectedItem","filteredBySelection","item","option","firstRenderRef","previousValue","setPreviousValue","isEqual","previousOptions","setPreviousOptions","updateDOMValues","updatedItemDOMValues","currentItemDOMValues","renderFilter","jsx","MultiselectToggleFilter","handleFilterChange","renderSelection","MultiselectToggleCounter","MultiselectToggleSelection","handleRemoveSelectedItem","renderToggle","wrapperClassNames","classNames","showPlaceholder","isEmpty","showFilter","selectedItemForClearButton","toggleButton","jsxs","onToggle","handleToggleKeyDown","MultiselectTogglePlaceholder","ClearButton","handleClearSelectedItems","WithFeedbackAndAddon","renderDropdownMenu","nonSelectedOptions","BaseSelectDropdown","onOptionChange","targetFilterValue","optionsFiltered","filterOptions","newFocusedItemIndex","currentSelectedItem","updatedSelectedItems","updateSelection","selectedItemId","newSelectedItems","itemIndex","itemId","isKeyboardUsed","prevValue","wrapperClasses"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Multiselect.js","sources":["../../../src/components/selects/Multiselect.tsx"],"sourcesContent":["import type React from 'react';\nimport { useRef, useState } from 'react';\nimport { isEqual } from 'es-toolkit/predicate';\nimport { isEmpty } from 'es-toolkit/compat';\nimport { noop } from 'es-toolkit/function';\n\nimport classNames from '../../utils/classNames';\nimport BaseSelectDropdown, { filterOptions, type OptionDOMValue, type SelectOption } from './BaseSelectDropdown';\nimport ClearButton from './ClearButton';\nimport MultiselectToggleCounter from './MultiselectToggleCounter';\nimport MultiselectToggleSelection from './MultiselectToggleSelection';\nimport MultiselectToggleFilter from './MultiselectToggleFilter';\nimport MultiselectTogglePlaceholder from './MultiselectTogglePlaceholder';\nimport useClickOutside from '../../useClickOutside';\nimport useMergeRefs from '../../hooks/useMergeRefs';\nimport type { TrackingAttributes } from '../../utils/analytics/googleAnalyticsUtils';\nimport WithFeedbackAndAddon, { type WithFeedbackAndAddonProps } from './WithFeedbackAndAddon';\n\nconst DEFAULT_FOCUSED_ITEM_INDEX = -1;\n\nexport type MultiselectCounterMessage = {\n /**\n * Text that will be used when a single item is selected.\n */\n one: string | React.ReactNode;\n\n /**\n * Text that will be used when multiple item are selected.\n */\n many: string | React.ReactNode;\n};\n\nexport type MultiselectOption = SelectOption & {};\n\nexport type MultiselectProps<T extends MultiselectOption> = Omit<WithFeedbackAndAddonProps, 'bsSize'> & {\n /**\n * Passed through as HTML attribute to the toggle button.\n */\n name?: string;\n\n /**\n * Passed as HTML attribute to the toggle button.\n *\n * @default Uses the value given to `name` if not provided explicitly.\n */\n id?: string;\n\n /**\n * Items to display in the dropdown menu.\n *\n * @default []\n */\n options?: T[];\n\n /**\n * Sets the ids of the selected options when the component is already mounted.\n */\n value?: string[];\n\n /**\n * Callback function triggered when an item is selected.\n *\n * @param selectedItemIds Array containing all the IDs that have been selected.\n *\n * @default () => {}\n */\n onChange?: (selectedItemIds: string[]) => void;\n\n /**\n * Text to display when nothing is selected.\n */\n placeholder?: string | React.ReactNode;\n\n /**\n * Defines whether the dropdown opens upwards.\n *\n * Set to `true` additionally disables autoDrop feature.\n *\n * @default false\n */\n dropup?: boolean;\n\n /**\n * Defines whether the dropdown opens right aligned to the dropdown toggle.\n *\n * Set to 'true' additionally disables autoDrop feature.\n *\n * @default false\n */\n pullRight?: boolean;\n\n /**\n * Enables or disables the autoDrop positioning feature.\n *\n * When enabled, the option list opens below or above the input depending on the surrounding space.\n *\n * @default true\n */\n autoDropDirection?: boolean;\n\n /**\n * Shows a loading spinner instead of the menu items if set to true.\n * @default false\n */\n isLoading?: boolean;\n\n /**\n * Defines the size of the select to be rendered.\n *\n * @default 'md'\n */\n bsSize?: 'sm' | 'md' | 'lg';\n\n /**\n * Defines the visual variant of the select.\n *\n * @default 'default'\n */\n variant?: 'default' | 'blank';\n\n /**\n * Option to disable the opening of the option list.\n *\n * @default false\n */\n disabled?: boolean;\n\n /**\n * Sets the input's tabindex attribute.\n *\n * The tabindex attribute allows developers to make HTML elements focusable, allow or prevent them from being\n * sequentially focusable (usually with the Tab key, hence the name) and determine their relative ordering for\n * sequential focus navigation.\n *\n * @default 0\n */\n tabIndex?: number;\n\n /**\n * Defines whether the Bootstrap error classes shall be added to the toggle element.\n *\n * @default false\n */\n hasError?: boolean;\n\n /**\n * Defines whether the selected items wrap around within the dropdown toggle.\n *\n * @default false\n */\n multiline?: boolean;\n\n /**\n * Defines whether the component should be filterable.\n *\n * @default false\n */\n useFilter?: boolean;\n\n /**\n * Set to show a clear button.\n *\n * @default false\n */\n useClear?: boolean;\n\n /**\n * Text that shall be shown when not match was found when filtering.\n */\n noItemMessage?: string | React.ReactNode;\n\n /**\n * Object that will render the number of selected items instead of individual items.\n *\n * Using this prop will disable the filter functionality.\n */\n counterMessage?: MultiselectCounterMessage;\n\n /**\n * Optional render function that is used to render the message how many items have been selected.\n *\n * Using this prop will disable the filter functionality.\n *\n * @param selectedAmount The total amount of selected items.\n */\n renderCounterMessage?: (selectedAmount: number) => React.ReactNode;\n\n /**\n * Set to show only the icon and not the label of selected item.\n *\n * @default false\n */\n showSelectedItemIcon?: boolean;\n\n /**\n * Set to show all item icons within the toggle element.\n *\n * Selected items are highlighted and unselected items are shown as inactive.\n *\n * @default false\n */\n showUnselectedItemIcons?: boolean;\n\n /**\n * Additional classes to be set to the dropdown.\n */\n dropdownClassName?: string;\n\n /**\n * Additional classes to be set to the select/input.\n */\n btnClassName?: string;\n\n /**\n * Additional classes to be set to the select wrapper\n */\n className?: string;\n\n /**\n * Optional tracking attributes added to the toggle button.\n */\n trackingAttributes?: TrackingAttributes;\n};\n\nconst Multiselect = (props: MultiselectProps<MultiselectOption>) => {\n const {\n name,\n id = name,\n options = [],\n value,\n onChange = noop,\n placeholder,\n isLoading = false,\n dropup = false,\n pullRight = false,\n autoDropDirection = true,\n bsSize = 'md',\n variant = 'default',\n disabled = false,\n tabIndex = 0,\n hasError = false,\n useFilter = false,\n useClear = false,\n multiline = false,\n noItemMessage,\n counterMessage,\n renderCounterMessage,\n showSelectedItemIcon = false,\n showUnselectedItemIcons = false,\n className,\n inputAddon,\n errorMessage,\n warningMessage,\n messageWhiteSpace = 'normal',\n btnClassName,\n dropdownClassName,\n trackingAttributes,\n ...remainingProps\n } = props;\n\n const [isOpen, setIsOpen] = useState(false);\n const [selectedItemIds, setSelectedItemIds] = useState<string[]>(value || []);\n const [isFilterActive, setIsFilterActive] = useState(false);\n const [filterValue, setFilterValue] = useState('');\n const [filteredOptions, setFilteredOptions] = useState<MultiselectOption[]>(options);\n const [itemDOMValues, setItemDOMValues] = useState<OptionDOMValue[]>([]);\n const [focusedItemIndex, setFocusedItemIndex] = useState(DEFAULT_FOCUSED_ITEM_INDEX);\n const [keyboardUsed, setKeyboardUsed] = useState(false);\n\n const refToggle = useRef<HTMLButtonElement>(null);\n const refMultiSelectWrapper = useRef<HTMLDivElement>(null);\n\n const ref = useClickOutside(event => {\n // Check if the click is truly outside the multiselect wrapper\n if (refMultiSelectWrapper.current && !refMultiSelectWrapper.current.contains(event.target as Node)) {\n closeMenu();\n }\n });\n\n const mergedSelectRefs = useMergeRefs(refMultiSelectWrapper, ref);\n\n const updateSelectedItems = (optionsToCheck: MultiselectOption[], selectedItem: string[] | undefined) => {\n if (selectedItem) {\n setSelectedItemIds(selectedItem);\n } else if (optionsToCheck) {\n const filteredBySelection = optionsToCheck.filter(item => item.selected);\n setSelectedItemIds(filteredBySelection.map(option => option.id));\n }\n };\n\n // Update the selectedItems on first render.\n // Note, we use a ref instead of an effect as the effect is triggered too late\n const firstRenderRef = useRef<boolean>(true);\n if (firstRenderRef.current) {\n updateSelectedItems(options, value);\n firstRenderRef.current = false;\n }\n\n // Update selection based on changed value prop\n const [previousValue, setPreviousValue] = useState(value);\n if (!isEqual(value, previousValue)) {\n updateSelectedItems(options, value);\n setPreviousValue(value);\n }\n\n // Update options when they have changed from the outside\n const [previousOptions, setPreviousOptions] = useState(options);\n if (!isEqual(options, previousOptions)) {\n updateSelectedItems(options, value);\n setFilteredOptions(options);\n setPreviousOptions(options);\n }\n\n const updateDOMValues = (updatedItemDOMValues: OptionDOMValue[] = []) => {\n if (!updatedItemDOMValues.length) {\n return;\n }\n\n const shouldKeepPreviousSnapshot = (isFilterActive || filterValue) && itemDOMValues.length > 0;\n if (shouldKeepPreviousSnapshot) {\n return;\n }\n\n setItemDOMValues(currentItemDOMValues =>\n isEqual(currentItemDOMValues, updatedItemDOMValues) ? currentItemDOMValues : updatedItemDOMValues\n );\n };\n\n const renderFilter = () => (\n <MultiselectToggleFilter\n isActive={isFilterActive || !!filterValue}\n selectedItemIds={selectedItemIds}\n filterValue={filterValue}\n onFilterChange={handleFilterChange}\n />\n );\n\n const renderSelection = () => {\n if (counterMessage || renderCounterMessage) {\n return (\n <MultiselectToggleCounter\n selectedAmount={selectedItemIds.length}\n counterMessage={counterMessage}\n customRenderer={renderCounterMessage}\n />\n );\n }\n\n return (\n <MultiselectToggleSelection\n options={options}\n selectedItemIds={selectedItemIds}\n showSelectedItemIcon={showSelectedItemIcon}\n showUnselectedItemIcons={showUnselectedItemIcons}\n onRemoveItem={handleRemoveSelectedItem}\n multiline={multiline}\n hasInputAddon={!!inputAddon}\n hasFilter={useFilter}\n >\n {multiline && renderFilter()}\n </MultiselectToggleSelection>\n );\n };\n\n const renderToggle = () => {\n const wrapperClassNames = classNames(\n 'dropdown-toggle',\n 'form-control',\n 'text-left',\n btnClassName && btnClassName,\n bsSize === 'sm' && 'input-sm',\n bsSize === 'lg' && 'input-lg',\n multiline && 'height-auto',\n disabled && 'disabled'\n );\n\n const showPlaceholder = isEmpty(selectedItemIds) && !showUnselectedItemIcons;\n const showFilter = useFilter && isOpen && !counterMessage && !renderCounterMessage;\n const selectedItemForClearButton =\n selectedItemIds.length > 0 ? ({ id: '__multiselect-clear__', label: '' } as SelectOption) : null;\n\n const toggleButton = (\n <button\n type='button'\n id={id}\n name={name}\n className={wrapperClassNames}\n {...trackingAttributes}\n data-toggle='dropdown'\n tabIndex={tabIndex}\n aria-haspopup='true'\n aria-expanded={isOpen}\n onClick={onToggle}\n onKeyDown={handleToggleKeyDown}\n ref={refToggle}\n >\n {showPlaceholder ? <MultiselectTogglePlaceholder placeholder={placeholder} /> : renderSelection()}\n {showFilter && !multiline && renderFilter()}\n <span className='select-toggle-actions'>\n <ClearButton\n showClear={useClear}\n selectedItem={selectedItemForClearButton}\n onClear={handleClearSelectedItems}\n />\n <span className='caret' />\n </span>\n </button>\n );\n\n if (!inputAddon && !errorMessage && !warningMessage) {\n return toggleButton;\n }\n\n return (\n <WithFeedbackAndAddon\n bsSize={bsSize}\n inputAddon={inputAddon}\n errorMessage={errorMessage}\n warningMessage={warningMessage}\n messageWhiteSpace={messageWhiteSpace}\n >\n {toggleButton}\n </WithFeedbackAndAddon>\n );\n };\n\n const renderDropdownMenu = () => {\n const nonSelectedOptions = filteredOptions.map(option => {\n option.selected = selectedItemIds.indexOf(option.id) !== -1;\n return option;\n });\n\n return (\n <BaseSelectDropdown\n isOpen={isOpen}\n isLoading={isLoading}\n options={nonSelectedOptions}\n focusedItemIndex={focusedItemIndex}\n keyboardUsed={keyboardUsed}\n updateDOMValues={updateDOMValues}\n onSelect={onOptionChange}\n onClose={closeMenu}\n noItemMessage={noItemMessage}\n pullRight={pullRight}\n useActiveClass\n dropup={dropup}\n autoDropDirection={autoDropDirection}\n dropdownClassName={dropdownClassName}\n />\n );\n };\n\n const handleFilterChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n event.preventDefault();\n\n const targetFilterValue = event.currentTarget.value;\n\n if (targetFilterValue === '') {\n setIsFilterActive(false);\n setFilterValue('');\n setFilteredOptions(options);\n setKeyboardUsed(false);\n setFocusedItemIndex(DEFAULT_FOCUSED_ITEM_INDEX);\n return;\n }\n\n const optionsFiltered = filterOptions(itemDOMValues, targetFilterValue, options);\n\n if (!isOpen) {\n // Ensure dropdown stays open when filtering\n setIsOpen(true);\n }\n\n const newFocusedItemIndex = optionsFiltered.length > 0 ? 0 : -1;\n\n setIsFilterActive(true);\n setFilterValue(targetFilterValue);\n setFilteredOptions(optionsFiltered);\n\n if (optionsFiltered.length > 0) {\n // Only set keyboard used if there are filtered options\n setKeyboardUsed(true);\n }\n\n setFocusedItemIndex(newFocusedItemIndex);\n };\n\n const onOptionChange = (currentSelectedItem: MultiselectOption | undefined) => {\n // prevent selecting disabled Items via keyboard\n if (currentSelectedItem?.disabled) {\n return;\n }\n\n const updatedSelectedItems = currentSelectedItem ? updateSelection(currentSelectedItem.id) : selectedItemIds;\n\n // Reset everything after an option was selected. Remove the filter again.\n setSelectedItemIds(updatedSelectedItems);\n setIsFilterActive(false);\n setFilterValue('');\n setFilteredOptions(options);\n\n onChange(updatedSelectedItems);\n };\n\n const updateSelection = (selectedItemId: string) => {\n const newSelectedItems = [...selectedItemIds];\n const itemIndex = selectedItemIds.indexOf(selectedItemId);\n\n if (itemIndex !== -1) {\n newSelectedItems.splice(itemIndex, 1);\n } else {\n newSelectedItems.push(selectedItemId);\n }\n\n return newSelectedItems;\n };\n\n const handleRemoveSelectedItem = (event: React.MouseEvent<HTMLSpanElement>, itemId: string) => {\n event.stopPropagation();\n\n const newSelectedItems = updateSelection(itemId);\n setSelectedItemIds(newSelectedItems);\n\n onChange(newSelectedItems);\n };\n\n const handleClearSelectedItems = () => {\n setSelectedItemIds([]);\n setIsFilterActive(false);\n setFilterValue('');\n setFilteredOptions(options);\n setKeyboardUsed(false);\n setFocusedItemIndex(DEFAULT_FOCUSED_ITEM_INDEX);\n\n onChange([]);\n };\n\n const handleToggleKeyDown = (event: React.KeyboardEvent<HTMLButtonElement>) => {\n switch (event.key) {\n case 'Space':\n if (!isOpen) {\n // open on space\n event.preventDefault();\n onToggle(event);\n }\n break;\n case 'Enter':\n if (!isOpen) {\n // open on enter\n event.preventDefault();\n onToggle(event);\n }\n break;\n default:\n break;\n }\n };\n\n const onToggle = (event: React.MouseEvent<HTMLButtonElement> | React.KeyboardEvent<HTMLButtonElement>) => {\n // Don't toggle when component is disabled or an item in the toggle was clicked in order to remove from\n // selection neither close when filter is active, means entering some filter value\n // in order to avoid closing menu on space but allow to use it for filtering\n if (disabled || isFilterActive) {\n return;\n }\n\n // using the enter key on the toggle button will trigger a synthetic click event as all buttons are of\n // type submit by default in HTML. In order to differentiate between real click and a synthetic event\n // caused by they keyboard, use the event details. A synthetic event is always 0.\n const isKeyboardUsed = event.detail === 0;\n\n setIsOpen(prevValue => !prevValue);\n setKeyboardUsed(isKeyboardUsed);\n };\n\n const closeMenu = () => {\n if (isOpen) {\n setIsOpen(false);\n setIsFilterActive(false);\n setFilterValue('');\n setFilteredOptions(options);\n setFocusedItemIndex(DEFAULT_FOCUSED_ITEM_INDEX);\n setKeyboardUsed(false);\n\n refToggle?.current?.focus();\n }\n };\n\n const wrapperClasses = classNames(\n 'select',\n 'multiselect',\n 'dropdown',\n isOpen && 'open',\n hasError && 'has-error',\n variant === 'blank' && 'select-blank',\n className && className\n );\n\n return (\n <div {...remainingProps} className={wrapperClasses} ref={mergedSelectRefs}>\n {renderToggle()}\n {renderDropdownMenu()}\n </div>\n );\n};\n\nexport default Multiselect;\n"],"names":["DEFAULT_FOCUSED_ITEM_INDEX","Multiselect","props","name","id","options","value","onChange","noop","placeholder","isLoading","dropup","pullRight","autoDropDirection","bsSize","variant","disabled","tabIndex","hasError","useFilter","useClear","multiline","noItemMessage","counterMessage","renderCounterMessage","showSelectedItemIcon","showUnselectedItemIcons","className","inputAddon","errorMessage","warningMessage","messageWhiteSpace","btnClassName","dropdownClassName","trackingAttributes","remainingProps","isOpen","setIsOpen","useState","selectedItemIds","setSelectedItemIds","isFilterActive","setIsFilterActive","filterValue","setFilterValue","filteredOptions","setFilteredOptions","itemDOMValues","setItemDOMValues","focusedItemIndex","setFocusedItemIndex","keyboardUsed","setKeyboardUsed","refToggle","useRef","refMultiSelectWrapper","ref","useClickOutside","event","closeMenu","mergedSelectRefs","useMergeRefs","updateSelectedItems","optionsToCheck","selectedItem","filteredBySelection","item","option","firstRenderRef","previousValue","setPreviousValue","isEqual","previousOptions","setPreviousOptions","updateDOMValues","updatedItemDOMValues","currentItemDOMValues","renderFilter","jsx","MultiselectToggleFilter","handleFilterChange","renderSelection","MultiselectToggleCounter","MultiselectToggleSelection","handleRemoveSelectedItem","renderToggle","wrapperClassNames","classNames","showPlaceholder","isEmpty","showFilter","selectedItemForClearButton","toggleButton","jsxs","onToggle","handleToggleKeyDown","MultiselectTogglePlaceholder","ClearButton","handleClearSelectedItems","WithFeedbackAndAddon","renderDropdownMenu","nonSelectedOptions","BaseSelectDropdown","onOptionChange","targetFilterValue","optionsFiltered","filterOptions","newFocusedItemIndex","currentSelectedItem","updatedSelectedItems","updateSelection","selectedItemId","newSelectedItems","itemIndex","itemId","isKeyboardUsed","prevValue","wrapperClasses"],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
2
|
import { SelectOption } from './BaseSelectDropdown';
|
|
3
|
+
import { TrackingAttributes } from '../../utils/analytics/googleAnalyticsUtils';
|
|
3
4
|
import { WithFeedbackAndAddonProps } from './WithFeedbackAndAddon';
|
|
4
5
|
export type { SelectOption } from './BaseSelectDropdown';
|
|
5
6
|
/**
|
|
@@ -153,6 +154,10 @@ export type SelectProps<T extends SelectOption> = Omit<WithFeedbackAndAddonProps
|
|
|
153
154
|
* Additional classes to be set to the select wrapper.
|
|
154
155
|
*/
|
|
155
156
|
className?: string;
|
|
157
|
+
/**
|
|
158
|
+
* Optional tracking attributes added to the toggle button.
|
|
159
|
+
*/
|
|
160
|
+
trackingAttributes?: TrackingAttributes;
|
|
156
161
|
};
|
|
157
162
|
declare const Select: <T extends SelectOption>(props: SelectProps<T>) => import("react/jsx-runtime").JSX.Element;
|
|
158
163
|
export default Select;
|