@oneplatformdev/ui 0.1.99-beta.287 → 0.1.99-beta.289
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/.storybook/Wrappers.js.map +1 -1
- package/Accordion/Accordion.js.map +1 -1
- package/Alert/Alert.js.map +1 -1
- package/Alert/alertVariants.js.map +1 -1
- package/AlertDialog/AlertDialog.js.map +1 -1
- package/AlertDialog/AlertDialog.stories.js +4 -2
- package/AlertDialog/AlertDialog.stories.js.map +1 -1
- package/AlertDialog/AlertDialogRoot.js +20 -18
- package/AlertDialog/AlertDialogRoot.js.map +1 -1
- package/AreaChart/AreaChart.js.map +1 -1
- package/Aside/Aside.js.map +1 -1
- package/Aside/AsideSidebar.js.map +1 -1
- package/AspectRatio/AspectRatio.js.map +1 -1
- package/Avatar/Avatar.js.map +1 -1
- package/Badge/Badge.js.map +1 -1
- package/Badge/badgeVariants.js.map +1 -1
- package/Breadcrumb/Breadcrumb.js.map +1 -1
- package/Button/Button.js +11 -10
- package/Button/Button.js.map +1 -1
- package/Button/Button.stories.js.map +1 -1
- package/Button/Button.utils.js.map +1 -1
- package/Button/ButtonCounterBadge.js.map +1 -1
- package/Button/buttonVariants.js.map +1 -1
- package/ButtonIcon/ButtonIcon.js +22 -19
- package/ButtonIcon/ButtonIcon.js.map +1 -1
- package/ButtonIcon/ButtonIcon.stories.js.map +1 -1
- package/ButtonIcon/buttonIconVariants.js.map +1 -1
- package/CHANGELOG.md +3447 -3401
- package/Calendar/Calendar.js +6 -4
- package/Calendar/Calendar.js.map +1 -1
- package/Card/Card.js.map +1 -1
- package/Carousel/Carousel.js +7 -6
- package/Carousel/Carousel.js.map +1 -1
- package/Chart/Chart.js.map +1 -1
- package/Checkbox/Checkbox.js +1 -0
- package/Checkbox/Checkbox.js.map +1 -1
- package/Checkbox/Checkbox.stories.js.map +1 -1
- package/Collapsible/Collapsible.js.map +1 -1
- package/Combobox/Combobox.js +54 -53
- package/Combobox/Combobox.js.map +1 -1
- package/Combobox/Combobox.stories.js.map +1 -1
- package/Combobox/Combobox.types.js.map +1 -1
- package/Combobox/ComboboxOptionItem.js +19 -18
- package/Combobox/ComboboxOptionItem.js.map +1 -1
- package/Combobox/ComboboxRenderContent.js +27 -26
- package/Combobox/ComboboxRenderContent.js.map +1 -1
- package/Combobox/ComboboxRenderOptions.js +5 -5
- package/Combobox/ComboboxRenderOptions.js.map +1 -1
- package/Combobox/ComboboxRenderTrigger.js +20 -18
- package/Combobox/ComboboxRenderTrigger.js.map +1 -1
- package/Command/Command.js +22 -21
- package/Command/Command.js.map +1 -1
- package/ContextPopover/ContextDropdownMenu.js.map +1 -1
- package/ContextPopover/ContextPopover.js.map +1 -1
- package/ContextPopover/useContextPopoverHandler.js.map +1 -1
- package/DataTable/DataTable.js +26 -24
- package/DataTable/DataTable.js.map +1 -1
- package/DataTable/DataTableColumnFilter.js +7 -6
- package/DataTable/DataTableColumnFilter.js.map +1 -1
- package/DataTable/useDataTable.js.map +1 -1
- package/DatePicker/DatePicker.js +2 -1
- package/DatePicker/DatePicker.js.map +1 -1
- package/Dialog/Dialog.js +21 -20
- package/Dialog/Dialog.js.map +1 -1
- package/Dialog/Dialog.stories.js +15 -14
- package/Dialog/Dialog.stories.js.map +1 -1
- package/Dialog/DialogOverlayScope.js.map +1 -1
- package/Dialog/useDialogClosePosition.js.map +1 -1
- package/Drawer/Drawer.js.map +1 -1
- package/DropdownMenu/DropdownMenu.js.map +1 -1
- package/Dropzone/Dropzone.d.ts.map +1 -1
- package/Dropzone/Dropzone.js +155 -144
- package/Dropzone/Dropzone.js.map +1 -1
- package/Dropzone/Dropzone.stories.js.map +1 -1
- package/Dropzone/Dropzone.types.js.map +1 -1
- package/Dropzone/DropzoneFilePreview.js.map +1 -1
- package/Dropzone/DropzoneSinglePickPreview.js +3 -2
- package/Dropzone/DropzoneSinglePickPreview.js.map +1 -1
- package/Dropzone/DropzoneUtils.js.map +1 -1
- package/Form/Form.js +29 -28
- package/Form/Form.js.map +1 -1
- package/Form/FormRenderControl.js +7 -6
- package/Form/FormRenderControl.js.map +1 -1
- package/Form/Form_old.js +5 -4
- package/Form/Form_old.js.map +1 -1
- package/FormCheckbox/FormCheckbox.js +4 -4
- package/FormCheckbox/FormCheckbox.js.map +1 -1
- package/FormCombobox/FormCombobox.js +4 -4
- package/FormCombobox/FormCombobox.js.map +1 -1
- package/FormDatePicker/FormDatePicker.js +4 -4
- package/FormDatePicker/FormDatePicker.js.map +1 -1
- package/FormDropzone/FormDropzone.js +3 -3
- package/FormDropzone/FormDropzone.js.map +1 -1
- package/FormInput/FormInput.js +6 -6
- package/FormInput/FormInput.js.map +1 -1
- package/FormInput/FormInput.stories.js +34 -15
- package/FormInput/FormInput.stories.js.map +1 -1
- package/FormRadio/FormRadio.js.map +1 -1
- package/FormSelect/FormSelect.js +9 -6
- package/FormSelect/FormSelect.js.map +1 -1
- package/FormTextarea/FormTextarea.js +4 -4
- package/FormTextarea/FormTextarea.js.map +1 -1
- package/Header/Header.js.map +1 -1
- package/HoverCard/HoverCard.js.map +1 -1
- package/InfoBlock/InfoBlock.js.map +1 -1
- package/InfoBlock/InfoBlock.stories.js.map +1 -1
- package/InfoBlock/infoBlockVariants.js.map +1 -1
- package/Input/Input.js.map +1 -1
- package/Input/Input.stories.js.map +1 -1
- package/Input/inputVariants.js.map +1 -1
- package/InputOTP/InputOTP.d.ts.map +1 -1
- package/InputOTP/InputOTP.js.map +1 -1
- package/LICENSE +21 -21
- package/Label/Label.js.map +1 -1
- package/Label/labelVariants.js.map +1 -1
- package/LazyLoader/LazyLoader.js +5 -4
- package/LazyLoader/LazyLoader.js.map +1 -1
- package/LoadedIcon/LoadedIcon.js.map +1 -1
- package/LoadingMask/LoadingMask.js.map +1 -1
- package/LoadingMask/RenderLoadingMask.js.map +1 -1
- package/LoadingProgress/LoadingProgress.js.map +1 -1
- package/LoadingProgress/loadingProgressVariants.js.map +1 -1
- package/Menubar/Menubar.js.map +1 -1
- package/NavigationMenu/NavigationMenu.js.map +1 -1
- package/NavigationMenu/navigationMenuVariants.js.map +1 -1
- package/Pagination/Pagination.js +1 -0
- package/Pagination/Pagination.js.map +1 -1
- package/Popover/Popover.js.map +1 -1
- package/Progress/Progress.js.map +1 -1
- package/README.md +7 -7
- package/Radio/Radio.js.map +1 -1
- package/RadioGroup/RadioGroup.js.map +1 -1
- package/Resizable/Resizable.js.map +1 -1
- package/Resizable/Resizable.stories.js.map +1 -1
- package/ScrollArea/ScrollArea.js.map +1 -1
- package/Search/Search.js +9 -9
- package/Search/Search.js.map +1 -1
- package/Search/Search.stories.js.map +1 -1
- package/Select/Select.js +7 -6
- package/Select/Select.js.map +1 -1
- package/Select/Select.stories.js.map +1 -1
- package/Select/SelectRoot.js.map +1 -1
- package/Separator/Separator.js.map +1 -1
- package/Sheet/Sheet.js.map +1 -1
- package/Sidebar/Sidebar.js +21 -20
- package/Sidebar/Sidebar.js.map +1 -1
- package/Skeleton/Skeleton.js.map +1 -1
- package/Slider/Slider.js.map +1 -1
- package/Sonner/Sonner.js.map +1 -1
- package/Switch/Switch.js.map +1 -1
- package/Switch/Switch.stories.js.map +1 -1
- package/Table/Table.js.map +1 -1
- package/TablePagination/TablePagination.js +26 -21
- package/TablePagination/TablePagination.js.map +1 -1
- package/Tabs/Tabs.js.map +1 -1
- package/Tabs/TabsRoot.js.map +1 -1
- package/Textarea/Textarea.js.map +1 -1
- package/Textarea/Textarea.stories.js.map +1 -1
- package/Textarea/useAutosizeTextArea.js.map +1 -1
- package/Theme/ThemeModeToggle.js +4 -3
- package/Theme/ThemeModeToggle.js.map +1 -1
- package/Theme/ThemeProvider.js.map +1 -1
- package/Toast/Toast.js.map +1 -1
- package/Toast/toast.constants.js.map +1 -1
- package/Toast/toastVariants.js.map +1 -1
- package/Toast/useToast.js.map +1 -1
- package/Toaster/Toaster.js.map +1 -1
- package/Toggle/Toggle.js.map +1 -1
- package/ToggleGroup/ToggleGroup.js.map +1 -1
- package/Tooltip/Tooltip.js.map +1 -1
- package/Tooltip/TooltipRoot.js.map +1 -1
- package/Tooltip/tooltipVariants.js.map +1 -1
- package/index.js +288 -288
- package/package.json +4 -4
- package/vite-env.d.ts +7 -7
- package/Dropzone/DropzoneCoverPreview.d.ts +0 -14
- package/Dropzone/DropzoneCoverPreview.d.ts.map +0 -1
- package/Dropzone/DropzoneCoverPreview.js +0 -56
- package/Dropzone/DropzoneCoverPreview.js.map +0 -1
package/Combobox/Combobox.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Combobox.js","sources":["../../src/Combobox/Combobox.tsx"],"sourcesContent":["import {\r\n Dispatch, JSX,\r\n SetStateAction,\r\n useCallback,\r\n useEffect, useImperativeHandle,\r\n useLayoutEffect,\r\n useMemo, useRef,\r\n useState,\r\n} from 'react';\r\nimport { Popover } from '../Popover';\r\nimport { useDebounceCallback } from '@oneplatformdev/hooks';\r\nimport {\r\n ComboboxCallbackStateParams, ComboboxCallbackStateParamsRenderHandler,\r\n ComboboxOption,\r\n ComboboxProps, ComboboxSelectedType,\r\n DEFAULT_COMBOBOX_TYPE, MultiComboboxProps, SingleComboboxProps,\r\n} from './Combobox.types';\r\nimport { ComboboxRenderTrigger } from \"./ComboboxRenderTrigger\";\r\nimport { ComboboxRenderContent } from \"./ComboboxRenderContent\";\r\n\r\nexport function Combobox<Data extends object>(props: SingleComboboxProps<Data>): JSX.Element;\r\nexport function Combobox<Data extends object>(props: MultiComboboxProps<Data>): JSX.Element;\r\n\r\nexport function Combobox<Data extends object = object>(\r\n props: ComboboxProps<Data, 'single'> | ComboboxProps<Data, 'multi'>\r\n): JSX.Element {\r\n const {\r\n value,\r\n options: itemOptions,\r\n placeholder,\r\n disabled,\r\n searchLabel,\r\n emptyLabel,\r\n loadData,\r\n renderTrigger,\r\n commandInputAction,\r\n renderList,\r\n listHeadAction,\r\n listFooterAction,\r\n emptyAction,\r\n slotProps,\r\n defaultNodeOpen,\r\n defaultNodeDisabled,\r\n defaultNodeMatched,\r\n defaultNodeMuted,\r\n defaultNodeInteractive,\r\n forcePointerSelect,\r\n } = props;\r\n\r\n const type: ComboboxSelectedType = props.type ?? DEFAULT_COMBOBOX_TYPE;\r\n type StateSingle = ComboboxCallbackStateParams<Data, 'single'>;\r\n type StateMulti = ComboboxCallbackStateParams<Data, 'multi'>;\r\n type State = StateSingle | StateMulti;\r\n\r\n const [ initialLoading, setInitialLoading ] = useState(false);\r\n const [ loading, setLoading ] = useState(false);\r\n const [loadingMore, setLoadingMore] = useState(false);\r\n\r\n const [ open, setOpen ] = useState(false);\r\n const [ searchTerm, setSearchTerm ] = useState('');\r\n\r\n const [ selectedOptions, setSelectedOptions ] = useState<\r\n Map<ComboboxOption<Data>['value'], ComboboxOption<Data>>\r\n >(new Map());\r\n\r\n const [ options, _setOptions ] = useState<ComboboxOption<Data>[]>([]);\r\n const [ flattenOptions, setFlattenOptions ] = useState<ComboboxOption<Data>[]>([]);\r\n const setOptions: Dispatch<SetStateAction<ComboboxOption<Data>[]>> = useCallback((stater) => {\r\n const flatten = (next: ComboboxOption<Data>[]) => {\r\n const res: ComboboxOption<Data>[] = [];\r\n const walk = (nodes?: ComboboxOption<Data>[]) => {\r\n if (!nodes) return;\r\n for (const node of nodes) {\r\n res.push(node);\r\n if (node.items && node.items.length) walk(node.items);\r\n }\r\n };\r\n walk(next);\r\n setFlattenOptions((prev) => {\r\n const isIncludedInRes = res.find(o => !!value && String(o.value) === String(value));\r\n\r\n if (!isIncludedInRes) {\r\n const selectedOption = selectedOptions.size ? Array.from(selectedOptions.values()) : undefined;\r\n const current = (selectedOption || prev).find(o => !!value && String(o.value) === String(value))\r\n if (current) return [ current, ...res ];\r\n }\r\n\r\n return res;\r\n });\r\n }\r\n _setOptions((prev) => {\r\n const next: ComboboxOption<Data>[] = typeof stater === 'function' ? stater(prev) : stater;\r\n flatten(next);\r\n setSelectedOptions(prevSelections => {\r\n const nextSelections = new Map(prevSelections);\r\n const vls = Array.isArray(value) ? value : [value];\r\n for (const v of vls) {\r\n if(!v) continue;\r\n if(nextSelections.has(v)) continue;\r\n const o = next.find(o => String(o.value).toLowerCase() === String(v).toLowerCase());\r\n if(!o) continue;\r\n nextSelections.set(o.value, o);\r\n }\r\n return nextSelections;\r\n })\r\n return next;\r\n });\r\n }, [ selectedOptions, value ])\r\n\r\n const [total, setTotal] = useState<number>(0);\r\n const [offset, setOffset] = useState<number>(0);\r\n const hasNext = offset < total;\r\n\r\n useEffect(() => {\r\n itemOptions?.length && setOptions(itemOptions);\r\n }, [ itemOptions ]);\r\n\r\n const requestIdRef = useRef(0);\r\n const abortRef = useRef<AbortController>(null);\r\n const beginRequest = useCallback(() => {\r\n requestIdRef.current += 1;\r\n abortRef.current?.abort();\r\n const ac = new AbortController();\r\n abortRef.current = ac;\r\n return { id: requestIdRef.current, signal: ac.signal };\r\n }, []);\r\n useEffect(() => {\r\n return () => abortRef.current?.abort();\r\n }, []);\r\n\r\n const isSearchedEmptyList = useMemo(() => {\r\n return Boolean(searchTerm) && !options.length && !loading;\r\n }, [ loading, options.length, searchTerm ])\r\n\r\n const isEmptyList = useMemo(() => {\r\n return !options.length && !loading;\r\n }, [ loading, options.length, searchTerm ])\r\n\r\n const onChangeOption = useCallback((option: ComboboxOption<Data>) => {\r\n if(props.type === 'single') {\r\n setSelectedOptions(prev => {\r\n const isSelected = prev.has(option.value);\r\n const next = new Map<ComboboxOption<Data>['value'], ComboboxOption<Data>>();\r\n\r\n if(isSelected) props.onChange?.(undefined);\r\n else {\r\n next.set(option.value, option);\r\n props.onChange?.(option.value);\r\n }\r\n\r\n return next;\r\n });\r\n setOpen(false);\r\n }\r\n\r\n if(props.type === 'multi') {\r\n setSelectedOptions(prev => {\r\n const next = new Map(prev);\r\n if(next.has(option.value)) next.delete(option.value);\r\n else next.set(option.value, option);\r\n props.onChange?.(Array.from(next.keys()));\r\n return next;\r\n });\r\n }\r\n }, [props.type, props.onChange]);\r\n\r\n const callbackStateParams = useMemo((): State => {\r\n const base = {\r\n options,\r\n setOptions,\r\n search: searchTerm || '',\r\n setSearch: setSearchTerm,\r\n onChangeOption,\r\n open,\r\n setOpen,\r\n loading,\r\n setLoading,\r\n isEmptyList,\r\n isSearchedEmptyList,\r\n placeholder,\r\n }\r\n\r\n const selectedOptionArray = Array.from(selectedOptions.values());\r\n\r\n if(type === 'multi') {\r\n const selectedOption = selectedOptionArray\r\n const setSelectedOption: Dispatch<SetStateAction<ComboboxOption<Data>[] | undefined>> = (value) => {\r\n setSelectedOptions((prevSet) => {\r\n const prevStateArray = Array.from(prevSet.values());\r\n const nextStateArray = typeof value === 'function'\r\n ? (value as (prev: ComboboxOption<Data>[]) => ComboboxOption<Data>[])(prevStateArray)\r\n : value;\r\n if (!nextStateArray) return new Map();\r\n return new Map(nextStateArray.map(o => [o.value, o]));\r\n });\r\n };\r\n return { ...base, type: 'multi', selectedOption, setSelectedOption } satisfies StateMulti;\r\n }\r\n\r\n if(type === 'single') {\r\n const selectedOption = selectedOptionArray[0]\r\n const setSelectedOption: Dispatch<SetStateAction<ComboboxOption<Data> | undefined>> = (value) => {\r\n setSelectedOptions((prevSet) => {\r\n const [currentSingle] = Array.from(prevSet.values());\r\n const nextValue = typeof value === 'function'\r\n ? (value as (prev: ComboboxOption<Data> | undefined) => ComboboxOption<Data> | undefined)(currentSingle)\r\n : value;\r\n\r\n const nextMap = new Map<ComboboxOption<Data>['value'], ComboboxOption<Data>>();\r\n if (nextValue) nextMap.set(nextValue.value, nextValue);\r\n return nextMap;\r\n });\r\n };\r\n return { ...base, type: 'single', selectedOption, setSelectedOption } satisfies StateSingle;\r\n }\r\n\r\n throw new Error(`Combobox type ${type} is not supported`);\r\n }, [ placeholder, loading, open, options, searchTerm, selectedOptions, isEmptyList, isSearchedEmptyList, setOptions, onChangeOption, props.type ]);\r\n useImperativeHandle(props.imperativeRef, () => callbackStateParams, [callbackStateParams]);\r\n\r\n const fetchData = useCallback(async (\r\n params: Parameters<typeof loadData>[0],\r\n signal: AbortSignal,\r\n ) => {\r\n const fetchedData = await loadData(params, signal, callbackStateParams);\r\n if (!fetchedData) throw new Error('Expected loadData to return data');\r\n return Array.isArray(fetchedData)\r\n ? { data: fetchedData, total: fetchedData.length }\r\n : fetchedData;\r\n }, [loadData, callbackStateParams]);\r\n\r\n const loadFirst = useCallback(async (value: string = '') => {\r\n if (!loadData) return;\r\n const { id, signal } = beginRequest();\r\n try {\r\n setLoading(true);\r\n setLoadingMore(false);\r\n\r\n const result = await fetchData({ search: value }, signal);\r\n if (id !== requestIdRef.current) return;\r\n\r\n setOptions(result.data);\r\n setTotal(result.total);\r\n setOffset(result.data.length);\r\n } catch (error) {\r\n console.error('Unexpected error while get option:', error);\r\n } finally {\r\n if (id === requestIdRef.current) setLoading(false);\r\n }\r\n }, [beginRequest, fetchData, loadData]);\r\n\r\n const loadMore = useCallback(async () => {\r\n if (!loadData) return;\r\n if (!hasNext || loading || loadingMore) return;\r\n const { id, signal } = beginRequest();\r\n try {\r\n setLoadingMore(true);\r\n const result = await fetchData(\r\n { search: searchTerm, offset },\r\n signal\r\n );\r\n setOptions((prev) => [...prev, ...result.data]);\r\n setTotal(result.total);\r\n setOffset((prev) => prev + result.data.length);\r\n } catch (error) {\r\n console.error('Unexpected error while load more option:', error);\r\n } finally {\r\n if (id === requestIdRef.current) setLoadingMore(false);\r\n }\r\n }, [beginRequest, fetchData, hasNext, loadData, loading, loadingMore, offset, searchTerm]);\r\n\r\n const debouncedGetData = useDebounceCallback(loadFirst, 600, {\r\n leading: false,\r\n trailing: true,\r\n });\r\n\r\n const handleSearchChange = useCallback((value: string) => {\r\n setLoading(true);\r\n setSearchTerm(value);\r\n debouncedGetData(value);\r\n }, []);\r\n\r\n const handleClearSelections = useCallback(() => {\r\n props.onChange(undefined);\r\n setSelectedOptions(new Map());\r\n setOpen(false);\r\n }, [props.onChange]);\r\n\r\n const handleReset = useCallback(() => {\r\n abortRef.current?.abort();\r\n requestIdRef.current += 1;\r\n setSearchTerm(\"\");\r\n setLoading(false);\r\n setLoadingMore(false);\r\n }, []);\r\n\r\n const handlePopoverOpen = useCallback(async (next: boolean) => {\r\n setOpen(next);\r\n if(!next) return handleReset();\r\n void loadFirst();\r\n setSearchTerm('');\r\n }, [handleReset, loadFirst]);\r\n\r\n const runOnMount = useCallback(async () => {\r\n if (!props.onMount) return;\r\n setInitialLoading(true);\r\n try {\r\n if (type === 'multi') {\r\n await (props as MultiComboboxProps<Data>).onMount?.(callbackStateParams as StateMulti);\r\n } else {\r\n await (props as SingleComboboxProps<Data>).onMount?.(callbackStateParams as StateSingle);\r\n }\r\n } finally {\r\n setInitialLoading(false);\r\n }\r\n }, [ props.onMount, callbackStateParams ]);\r\n useLayoutEffect(() => {\r\n runOnMount();\r\n }, []);\r\n\r\n return (\r\n <div className=\"w-full\">\r\n <Popover\r\n open={open}\r\n onOpenChange={handlePopoverOpen}\r\n modal={slotProps?.popover?.modal}\r\n >\r\n <ComboboxRenderTrigger\r\n value={value}\r\n type={type}\r\n open={open}\r\n initialLoading={initialLoading}\r\n selectedOptions={selectedOptions}\r\n flattenOptions={flattenOptions}\r\n onSelect={onChangeOption}\r\n onClearSelections={handleClearSelections}\r\n callbackStateParams={callbackStateParams}\r\n renderTrigger={renderTrigger as ComboboxCallbackStateParamsRenderHandler<Data>}\r\n placeholder={placeholder}\r\n disabled={disabled}\r\n />\r\n\r\n <ComboboxRenderContent\r\n open={open}\r\n value={value}\r\n type={type}\r\n options={options}\r\n search={searchTerm}\r\n onSearch={handleSearchChange}\r\n onSelect={onChangeOption}\r\n onLoadMore={loadMore}\r\n hasNext={hasNext}\r\n loading={loading}\r\n loadingMore={loadingMore}\r\n isEmptyList={isEmptyList}\r\n callbackStateParams={callbackStateParams}\r\n commandInputAction={commandInputAction as ComboboxCallbackStateParamsRenderHandler<Data>}\r\n renderList={renderList as ComboboxCallbackStateParamsRenderHandler<Data>}\r\n listHeadAction={listHeadAction as ComboboxCallbackStateParamsRenderHandler<Data>}\r\n listFooterAction={listFooterAction as ComboboxCallbackStateParamsRenderHandler<Data>}\r\n emptyAction={emptyAction as ComboboxCallbackStateParamsRenderHandler<Data>}\r\n slotProps={slotProps}\r\n searchLabel={searchLabel}\r\n emptyLabel={emptyLabel}\r\n defaultNodeOpen={defaultNodeOpen}\r\n defaultNodeDisabled={defaultNodeDisabled}\r\n defaultNodeMatched={defaultNodeMatched}\r\n defaultNodeMuted={defaultNodeMuted}\r\n defaultNodeInteractive={defaultNodeInteractive}\r\n forcePointerSelect={forcePointerSelect}\r\n popoverContainer={slotProps?.popover?.container}\r\n />\r\n </Popover>\r\n </div>\r\n );\r\n}\r\n"],"names":["Combobox","props","value","itemOptions","placeholder","disabled","searchLabel","emptyLabel","loadData","renderTrigger","commandInputAction","renderList","listHeadAction","listFooterAction","emptyAction","slotProps","defaultNodeOpen","defaultNodeDisabled","defaultNodeMatched","defaultNodeMuted","defaultNodeInteractive","forcePointerSelect","type","DEFAULT_COMBOBOX_TYPE","initialLoading","setInitialLoading","useState","loading","setLoading","loadingMore","setLoadingMore","open","setOpen","searchTerm","setSearchTerm","selectedOptions","setSelectedOptions","options","_setOptions","flattenOptions","setFlattenOptions","setOptions","useCallback","stater","flatten","next","res","walk","nodes","node","prev","o","current","prevSelections","nextSelections","vls","v","total","setTotal","offset","setOffset","hasNext","useEffect","requestIdRef","useRef","abortRef","beginRequest","ac","isSearchedEmptyList","useMemo","isEmptyList","onChangeOption","option","isSelected","callbackStateParams","base","selectedOptionArray","prevSet","prevStateArray","nextStateArray","selectedOption","currentSingle","nextValue","nextMap","useImperativeHandle","fetchData","params","signal","fetchedData","loadFirst","id","result","error","loadMore","debouncedGetData","useDebounceCallback","handleSearchChange","handleClearSelections","handleReset","handlePopoverOpen","runOnMount","useLayoutEffect","jsx","jsxs","Popover","ComboboxRenderTrigger","ComboboxRenderContent"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Combobox.js","sources":["../../src/Combobox/Combobox.tsx"],"sourcesContent":["import {\n Dispatch, JSX,\n SetStateAction,\n useCallback,\n useEffect, useImperativeHandle,\n useLayoutEffect,\n useMemo, useRef,\n useState,\n} from 'react';\nimport { Popover } from '../Popover';\nimport { useDebounceCallback } from '@oneplatformdev/hooks';\nimport {\n ComboboxCallbackStateParams, ComboboxCallbackStateParamsRenderHandler,\n ComboboxOption,\n ComboboxProps, ComboboxSelectedType,\n DEFAULT_COMBOBOX_TYPE, MultiComboboxProps, SingleComboboxProps,\n} from './Combobox.types';\nimport { ComboboxRenderTrigger } from \"./ComboboxRenderTrigger\";\nimport { ComboboxRenderContent } from \"./ComboboxRenderContent\";\n\nexport function Combobox<Data extends object>(props: SingleComboboxProps<Data>): JSX.Element;\nexport function Combobox<Data extends object>(props: MultiComboboxProps<Data>): JSX.Element;\n\nexport function Combobox<Data extends object = object>(\n props: ComboboxProps<Data, 'single'> | ComboboxProps<Data, 'multi'>\n): JSX.Element {\n const {\n value,\n options: itemOptions,\n placeholder,\n disabled,\n searchLabel,\n emptyLabel,\n loadData,\n renderTrigger,\n commandInputAction,\n renderList,\n listHeadAction,\n listFooterAction,\n emptyAction,\n slotProps,\n defaultNodeOpen,\n defaultNodeDisabled,\n defaultNodeMatched,\n defaultNodeMuted,\n defaultNodeInteractive,\n forcePointerSelect,\n } = props;\n\n const type: ComboboxSelectedType = props.type ?? DEFAULT_COMBOBOX_TYPE;\n type StateSingle = ComboboxCallbackStateParams<Data, 'single'>;\n type StateMulti = ComboboxCallbackStateParams<Data, 'multi'>;\n type State = StateSingle | StateMulti;\n\n const [ initialLoading, setInitialLoading ] = useState(false);\n const [ loading, setLoading ] = useState(false);\n const [loadingMore, setLoadingMore] = useState(false);\n\n const [ open, setOpen ] = useState(false);\n const [ searchTerm, setSearchTerm ] = useState('');\n\n const [ selectedOptions, setSelectedOptions ] = useState<\n Map<ComboboxOption<Data>['value'], ComboboxOption<Data>>\n >(new Map());\n\n const [ options, _setOptions ] = useState<ComboboxOption<Data>[]>([]);\n const [ flattenOptions, setFlattenOptions ] = useState<ComboboxOption<Data>[]>([]);\n const setOptions: Dispatch<SetStateAction<ComboboxOption<Data>[]>> = useCallback((stater) => {\n const flatten = (next: ComboboxOption<Data>[]) => {\n const res: ComboboxOption<Data>[] = [];\n const walk = (nodes?: ComboboxOption<Data>[]) => {\n if (!nodes) return;\n for (const node of nodes) {\n res.push(node);\n if (node.items && node.items.length) walk(node.items);\n }\n };\n walk(next);\n setFlattenOptions((prev) => {\n const isIncludedInRes = res.find(o => !!value && String(o.value) === String(value));\n\n if (!isIncludedInRes) {\n const selectedOption = selectedOptions.size ? Array.from(selectedOptions.values()) : undefined;\n const current = (selectedOption || prev).find(o => !!value && String(o.value) === String(value))\n if (current) return [ current, ...res ];\n }\n\n return res;\n });\n }\n _setOptions((prev) => {\n const next: ComboboxOption<Data>[] = typeof stater === 'function' ? stater(prev) : stater;\n flatten(next);\n setSelectedOptions(prevSelections => {\n const nextSelections = new Map(prevSelections);\n const vls = Array.isArray(value) ? value : [value];\n for (const v of vls) {\n if(!v) continue;\n if(nextSelections.has(v)) continue;\n const o = next.find(o => String(o.value).toLowerCase() === String(v).toLowerCase());\n if(!o) continue;\n nextSelections.set(o.value, o);\n }\n return nextSelections;\n })\n return next;\n });\n }, [ selectedOptions, value ])\n\n const [total, setTotal] = useState<number>(0);\n const [offset, setOffset] = useState<number>(0);\n const hasNext = offset < total;\n\n useEffect(() => {\n itemOptions?.length && setOptions(itemOptions);\n }, [ itemOptions ]);\n\n const requestIdRef = useRef(0);\n const abortRef = useRef<AbortController>(null);\n const beginRequest = useCallback(() => {\n requestIdRef.current += 1;\n abortRef.current?.abort();\n const ac = new AbortController();\n abortRef.current = ac;\n return { id: requestIdRef.current, signal: ac.signal };\n }, []);\n useEffect(() => {\n return () => abortRef.current?.abort();\n }, []);\n\n const isSearchedEmptyList = useMemo(() => {\n return Boolean(searchTerm) && !options.length && !loading;\n }, [ loading, options.length, searchTerm ])\n\n const isEmptyList = useMemo(() => {\n return !options.length && !loading;\n }, [ loading, options.length, searchTerm ])\n\n const onChangeOption = useCallback((option: ComboboxOption<Data>) => {\n if(props.type === 'single') {\n setSelectedOptions(prev => {\n let next = new Map(prev);\n const isSelected = next.has(option.value);\n\n if(next.has(option.value)) next = new Map();\n else next.set(option.value, option);\n\n if(isSelected) props.onChange?.(undefined);\n else props.onChange?.(option.value);\n\n return next;\n });\n setOpen(false);\n }\n\n if(props.type === 'multi') {\n setSelectedOptions(prev => {\n const next = new Map(prev);\n if(next.has(option.value)) next.delete(option.value);\n else next.set(option.value, option);\n props.onChange?.(Array.from(next.keys()));\n return next;\n });\n }\n }, [props.type, props.onChange]);\n\n const callbackStateParams = useMemo((): State => {\n const base = {\n options,\n setOptions,\n search: searchTerm || '',\n setSearch: setSearchTerm,\n onChangeOption,\n open,\n setOpen,\n loading,\n setLoading,\n isEmptyList,\n isSearchedEmptyList,\n placeholder,\n }\n\n const selectedOptionArray = Array.from(selectedOptions.values());\n\n if(type === 'multi') {\n const selectedOption = selectedOptionArray\n const setSelectedOption: Dispatch<SetStateAction<ComboboxOption<Data>[] | undefined>> = (value) => {\n setSelectedOptions((prevSet) => {\n const prevStateArray = Array.from(prevSet.values());\n const nextStateArray = typeof value === 'function'\n ? (value as (prev: ComboboxOption<Data>[]) => ComboboxOption<Data>[])(prevStateArray)\n : value;\n if (!nextStateArray) return new Map();\n return new Map(nextStateArray.map(o => [o.value, o]));\n });\n };\n return { ...base, type: 'multi', selectedOption, setSelectedOption } satisfies StateMulti;\n }\n\n if(type === 'single') {\n const selectedOption = selectedOptionArray[0]\n const setSelectedOption: Dispatch<SetStateAction<ComboboxOption<Data> | undefined>> = (value) => {\n setSelectedOptions((prevSet) => {\n const [currentSingle] = Array.from(prevSet.values());\n const nextValue = typeof value === 'function'\n ? (value as (prev: ComboboxOption<Data> | undefined) => ComboboxOption<Data> | undefined)(currentSingle)\n : value;\n\n const nextMap = new Map<ComboboxOption<Data>['value'], ComboboxOption<Data>>();\n if (nextValue) nextMap.set(nextValue.value, nextValue);\n return nextMap;\n });\n };\n return { ...base, type: 'single', selectedOption, setSelectedOption } satisfies StateSingle;\n }\n\n throw new Error(`Combobox type ${type} is not supported`);\n }, [ placeholder, loading, open, options, searchTerm, selectedOptions, isEmptyList, isSearchedEmptyList, setOptions, onChangeOption, props.type ]);\n useImperativeHandle(props.imperativeRef, () => callbackStateParams, [callbackStateParams]);\n\n const fetchData = useCallback(async (\n params: Parameters<typeof loadData>[0],\n signal: AbortSignal,\n ) => {\n const fetchedData = await loadData(params, signal, callbackStateParams);\n if (!fetchedData) throw new Error('Expected loadData to return data');\n return Array.isArray(fetchedData)\n ? { data: fetchedData, total: fetchedData.length }\n : fetchedData;\n }, [loadData, callbackStateParams]);\n\n const loadFirst = useCallback(async (value: string = '') => {\n if (!loadData) return;\n const { id, signal } = beginRequest();\n try {\n setLoading(true);\n setLoadingMore(false);\n\n const result = await fetchData({ search: value }, signal);\n if (id !== requestIdRef.current) return;\n\n setOptions(result.data);\n setTotal(result.total);\n setOffset(result.data.length);\n } catch (error) {\n console.error('Unexpected error while get option:', error);\n } finally {\n if (id === requestIdRef.current) setLoading(false);\n }\n }, [beginRequest, fetchData, loadData]);\n\n const loadMore = useCallback(async () => {\n if (!loadData) return;\n if (!hasNext || loading || loadingMore) return;\n const { id, signal } = beginRequest();\n try {\n setLoadingMore(true);\n const result = await fetchData(\n { search: searchTerm, offset },\n signal\n );\n setOptions((prev) => [...prev, ...result.data]);\n setTotal(result.total);\n setOffset((prev) => prev + result.data.length);\n } catch (error) {\n console.error('Unexpected error while load more option:', error);\n } finally {\n if (id === requestIdRef.current) setLoadingMore(false);\n }\n }, [beginRequest, fetchData, hasNext, loadData, loading, loadingMore, offset, searchTerm]);\n\n const debouncedGetData = useDebounceCallback(loadFirst, 600, {\n leading: false,\n trailing: true,\n });\n\n const handleSearchChange = useCallback((value: string) => {\n setLoading(true);\n setSearchTerm(value);\n debouncedGetData(value);\n }, []);\n\n const handleClearSelections = useCallback(() => {\n props.onChange(undefined);\n setSelectedOptions(new Map());\n setOpen(false);\n }, [props.onChange]);\n\n const handleReset = useCallback(() => {\n abortRef.current?.abort();\n requestIdRef.current += 1;\n setSearchTerm(\"\");\n setLoading(false);\n setLoadingMore(false);\n }, []);\n\n const handlePopoverOpen = useCallback(async (next: boolean) => {\n setOpen(next);\n if(!next) return handleReset();\n void loadFirst();\n setSearchTerm('');\n }, [handleReset, loadFirst]);\n\n const runOnMount = useCallback(async () => {\n if (!props.onMount) return;\n setInitialLoading(true);\n try {\n if (type === 'multi') {\n await (props as MultiComboboxProps<Data>).onMount?.(callbackStateParams as StateMulti);\n } else {\n await (props as SingleComboboxProps<Data>).onMount?.(callbackStateParams as StateSingle);\n }\n } finally {\n setInitialLoading(false);\n }\n }, [ props.onMount, callbackStateParams ]);\n useLayoutEffect(() => {\n runOnMount();\n }, []);\n\n return (\n <div className=\"w-full\">\n <Popover\n open={open}\n onOpenChange={handlePopoverOpen}\n modal={slotProps?.popover?.modal}\n >\n <ComboboxRenderTrigger\n value={value}\n type={type}\n open={open}\n initialLoading={initialLoading}\n selectedOptions={selectedOptions}\n flattenOptions={flattenOptions}\n onSelect={onChangeOption}\n onClearSelections={handleClearSelections}\n callbackStateParams={callbackStateParams}\n renderTrigger={renderTrigger as ComboboxCallbackStateParamsRenderHandler<Data>}\n placeholder={placeholder}\n disabled={disabled}\n />\n\n <ComboboxRenderContent\n open={open}\n value={value}\n type={type}\n options={options}\n search={searchTerm}\n onSearch={handleSearchChange}\n onSelect={onChangeOption}\n onLoadMore={loadMore}\n hasNext={hasNext}\n loading={loading}\n loadingMore={loadingMore}\n isEmptyList={isEmptyList}\n callbackStateParams={callbackStateParams}\n commandInputAction={commandInputAction as ComboboxCallbackStateParamsRenderHandler<Data>}\n renderList={renderList as ComboboxCallbackStateParamsRenderHandler<Data>}\n listHeadAction={listHeadAction as ComboboxCallbackStateParamsRenderHandler<Data>}\n listFooterAction={listFooterAction as ComboboxCallbackStateParamsRenderHandler<Data>}\n emptyAction={emptyAction as ComboboxCallbackStateParamsRenderHandler<Data>}\n slotProps={slotProps}\n searchLabel={searchLabel}\n emptyLabel={emptyLabel}\n defaultNodeOpen={defaultNodeOpen}\n defaultNodeDisabled={defaultNodeDisabled}\n defaultNodeMatched={defaultNodeMatched}\n defaultNodeMuted={defaultNodeMuted}\n defaultNodeInteractive={defaultNodeInteractive}\n forcePointerSelect={forcePointerSelect}\n popoverContainer={slotProps?.popover?.container}\n />\n </Popover>\n </div>\n );\n}\n"],"names":["Combobox","props","value","itemOptions","placeholder","disabled","searchLabel","emptyLabel","loadData","renderTrigger","commandInputAction","renderList","listHeadAction","listFooterAction","emptyAction","slotProps","defaultNodeOpen","defaultNodeDisabled","defaultNodeMatched","defaultNodeMuted","defaultNodeInteractive","forcePointerSelect","type","DEFAULT_COMBOBOX_TYPE","initialLoading","setInitialLoading","useState","loading","setLoading","loadingMore","setLoadingMore","open","setOpen","searchTerm","setSearchTerm","selectedOptions","setSelectedOptions","options","_setOptions","flattenOptions","setFlattenOptions","setOptions","useCallback","stater","flatten","next","res","walk","nodes","node","prev","o","current","prevSelections","nextSelections","vls","v","total","setTotal","offset","setOffset","hasNext","useEffect","requestIdRef","useRef","abortRef","beginRequest","ac","isSearchedEmptyList","useMemo","isEmptyList","onChangeOption","option","isSelected","callbackStateParams","base","selectedOptionArray","prevSet","prevStateArray","nextStateArray","selectedOption","currentSingle","nextValue","nextMap","useImperativeHandle","fetchData","params","signal","fetchedData","loadFirst","id","result","error","loadMore","debouncedGetData","useDebounceCallback","handleSearchChange","handleClearSelections","handleReset","handlePopoverOpen","runOnMount","useLayoutEffect","jsx","jsxs","Popover","ComboboxRenderTrigger","ComboboxRenderContent"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Combobox.stories.js","sources":["../../src/Combobox/Combobox.stories.tsx"],"sourcesContent":["import React, { useMemo, useState } from 'react';\r\nimport type { Meta, StoryObj } from '@storybook/react';\r\n\r\nimport { Combobox } from './Combobox';\r\nimport {\r\n ComboboxCallbackStateParams,\r\n ComboboxOption,\r\n ComboboxProps, MultiComboboxProps, SingleComboboxProps,\r\n} from './Combobox.types';\r\n\r\nconst sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));\r\n\r\nconst flatten = (nodes: ComboboxOption[] = []): ComboboxOption[] => {\r\n const res: ComboboxOption[] = [];\r\n const walk = (list?: ComboboxOption[]) => {\r\n if (!list?.length) return;\r\n for (const n of list) {\r\n res.push(n);\r\n if (n.items?.length) walk(n.items);\r\n }\r\n };\r\n walk(nodes);\r\n return res;\r\n};\r\n\r\nconst createFetchOptions =\r\n (all: ComboboxOption[], delayMs = 150): ComboboxProps['loadData'] =>\r\n async ({ search }) => {\r\n await sleep(delayMs);\r\n\r\n const q = (search ?? '').trim().toLowerCase();\r\n if (!q) return all;\r\n\r\n // simple \"contains\" search across flattened options; then return top-level filtered\r\n // (enough for Storybook demos; your real API can do better)\r\n const allFlat = flatten(all);\r\n const matchedValues = new Set(\r\n allFlat\r\n .filter((o) => String(o.label).toLowerCase().includes(q))\r\n .map((o) => String(o.value)),\r\n );\r\n\r\n const filterTree = (list: ComboboxOption[]): ComboboxOption[] => {\r\n return list\r\n .map((n) => {\r\n const items = n.items?.length ? filterTree(n.items) : undefined;\r\n const selfMatch =\r\n matchedValues.has(String(n.value)) ||\r\n String(n.label).toLowerCase().includes(q);\r\n\r\n if (!selfMatch && !items?.length) return null;\r\n return { ...n, items };\r\n })\r\n .filter(Boolean) as ComboboxOption[];\r\n };\r\n\r\n return filterTree(all);\r\n };\r\n\r\n\r\nconst filterTreeBySearch = (\r\n all: ComboboxOption[],\r\n search?: string,\r\n): ComboboxOption[] => {\r\n const q = (search ?? '').trim().toLowerCase();\r\n if (!q) return all;\r\n\r\n const allFlat = flatten(all);\r\n\r\n const matchedValues = new Set(\r\n allFlat\r\n .filter((o) => String(o.label).toLowerCase().includes(q))\r\n .map((o) => String(o.value)),\r\n );\r\n\r\n const filterTree = (list: ComboboxOption[]): ComboboxOption[] => {\r\n return list\r\n .map((n) => {\r\n const items = n.items?.length ? filterTree(n.items) : undefined;\r\n const selfMatch =\r\n matchedValues.has(String(n.value)) ||\r\n String(n.label).toLowerCase().includes(q);\r\n\r\n if (!selfMatch && !items?.length) return null;\r\n return { ...n, items };\r\n })\r\n .filter(Boolean) as ComboboxOption[];\r\n };\r\n\r\n return filterTree(all);\r\n};\r\n\r\nconst createPaginatedFetchOptions =\r\n (\r\n all: ComboboxOption[],\r\n delayMs = 250,\r\n limit = 20,\r\n ): ComboboxProps['loadData'] =>\r\n async ({ search, offset = 0 }) => {\r\n await sleep(delayMs);\r\n\r\n const filteredTree = filterTreeBySearch(all, search);\r\n const filteredFlat = flatten(filteredTree);\r\n\r\n const data = filteredFlat.slice(offset, offset + limit);\r\n\r\n return {\r\n data,\r\n total: filteredFlat.length,\r\n };\r\n };\r\n\r\nconst BASE_OPTIONS: ComboboxOption[] = [\r\n { value: 'ua', label: 'Ukraine' },\r\n { value: 'pl', label: 'Poland' },\r\n { value: 'de', label: 'Germany' },\r\n { value: 'fr', label: 'France' },\r\n { value: 'es', label: 'Spain' },\r\n { value: 'it', label: 'Italy' },\r\n];\r\n\r\nconst MANY_OPTIONS: ComboboxOption[] = Array.from({ length: 120 }).map((_, i) => ({\r\n value: `option-${i + 1}`,\r\n label: `Option ${i + 1}`,\r\n}));\r\n\r\nconst NESTED_OPTIONS: ComboboxOption[] = [\r\n {\r\n value: 'europe',\r\n label: 'Europe',\r\n items: [\r\n {\r\n value: 'fr',\r\n label: 'France',\r\n items: [\r\n {\r\n value: 'paris',\r\n label: 'Paris (Île-de-France)',\r\n items: [\r\n { value: 'paris-1', label: 'Paris 1st arrondissement' },\r\n { value: 'paris-3', label: 'Paris 3rd arrondissement' },\r\n { value: 'paris-10', label: 'Paris 10th arrondissement' },\r\n ],\r\n },\r\n { value: 'marseille', label: 'Marseille (Provence-Alpes-Côte d\\'Azur)' },\r\n {\r\n value: 'lyon',\r\n label: 'Lyon (Auvergne-Rhône-Alpes)',\r\n items: [\r\n { value: 'lyon-presquile', label: 'Presqu\\'île (1st/2nd)' },\r\n { value: 'lyon-vieux', label: 'Vieux Lyon' },\r\n ],\r\n },\r\n { value: 'toulouse', label: 'Toulouse (Occitanie)' },\r\n { value: 'bordeaux', label: 'Bordeaux (Nouvelle-Aquitaine)' },\r\n { value: 'strasbourg', label: 'Strasbourg (Grand Est)' },\r\n {\r\n value: 'rennes',\r\n label: 'Rennes (Brittany)',\r\n items: [\r\n { value: 'rennes-centre', label: 'Rennes Centre' },\r\n { value: 'rennes-beauregard', label: 'Beauregard' },\r\n ],\r\n },\r\n ]\r\n },\r\n { value: 'ua', label: 'Ukraine' },\r\n { value: 'pl', label: 'Poland' },\r\n { value: 'de', label: 'Germany' },\r\n ],\r\n },\r\n {\r\n value: 'north-america',\r\n label: 'North America',\r\n items: [\r\n { value: 'us', label: 'United States' },\r\n { value: 'ca', label: 'Canada' },\r\n { value: 'mx', label: 'Mexico' },\r\n { value: 'north-america-long', label: 'To long option to test wrapping. '.repeat(3) },\r\n {\r\n value: 'north-america-long-single',\r\n label: 'To long option to test wrapping. '.replace(/ /g, '_').repeat(3)\r\n },\r\n ],\r\n },\r\n];\r\nconst getFlattenOptions = (options: ComboboxOption[]) => {\r\n return options.flatMap(option => [\r\n option,\r\n ...(option.items ? getFlattenOptions(option.items) : [])\r\n ]);\r\n};\r\n\r\nconst getAllValues = (options: ComboboxOption[]): string[] => {\r\n return getFlattenOptions(options).map(o => o.value)\r\n};\r\n\r\ntype ControlledProps<T extends ComboboxProps = ComboboxProps> = Omit<T, 'value' | 'onChange'> & {\r\n initialValue?: T['value'];\r\n};\r\n\r\nfunction ControlledCombobox({ initialValue = '', ...args }: ControlledProps<SingleComboboxProps>) {\r\n const [ value, setValue ] = useState<SingleComboboxProps['value']>(initialValue);\r\n const loadData = useMemo(\r\n () => args.loadData,\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n [],\r\n );\r\n\r\n return (\r\n <div className=\"max-w-sm\">\r\n <Combobox type='single' {...args} value={value} onChange={setValue} loadData={loadData}\r\n defaultNodeMatched/>\r\n <div className=\"mt-3 text-xs text-muted-foreground\">\r\n value: <span className=\"font-mono\">{String(value || '')}</span>\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\nfunction ControlledComboboxMulti({\r\n initialValue = [],\r\n ...args\r\n }: ControlledProps<MultiComboboxProps>) {\r\n const [ value, setValue ] = useState<MultiComboboxProps['value'] | undefined>(initialValue);\r\n const loadData = useMemo(() => args.loadData, []);\r\n return (\r\n <div className=\"max-w-sm\">\r\n <Combobox\r\n {...args}\r\n type='multi'\r\n value={value}\r\n onChange={setValue}\r\n loadData={loadData}\r\n />\r\n <div className=\"mt-3 text-xs text-muted-foreground\">\r\n value: <span className=\"font-mono\">{(value || []).join(', ')}</span>\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\nconst meta = {\r\n title: 'Combobox',\r\n component: Combobox,\r\n parameters: {\r\n layout: 'centered',\r\n },\r\n args: {\r\n placeholder: 'Select option...',\r\n searchLabel: 'Type to search...',\r\n emptyLabel: 'No options',\r\n disabled: false,\r\n loadData: createFetchOptions(BASE_OPTIONS, 250),\r\n },\r\n argTypes: {\r\n loadData: { control: false },\r\n onChange: { control: false },\r\n onMount: { control: false },\r\n emptyAction: { control: false },\r\n commandInputAction: { control: false },\r\n listHeadAction: { control: false },\r\n options: { control: false },\r\n value: { control: false },\r\n },\r\n decorators: [\r\n (Story) => (\r\n <div className=\"p-6 w-[420px]\">\r\n <Story/>\r\n </div>\r\n ),\r\n ],\r\n} satisfies Meta<typeof Combobox>;\r\n\r\nexport default meta;\r\n\r\ntype Story = StoryObj<typeof meta>;\r\n\r\n/** 1) Default (async options) */\r\nexport const Default: Story = {\r\n render: (args) => <ControlledCombobox {...args} />,\r\n};\r\n\r\n/** 2) With initial selected value */\r\nexport const WithValueSelected: Story = {\r\n render: (args) => <ControlledCombobox {...args} initialValue=\"pl\"/>,\r\n};\r\n\r\n/** 3) Disabled */\r\nexport const Disabled: Story = {\r\n args: { disabled: true },\r\n render: (args) => <ControlledCombobox {...args} initialValue=\"de\"/>,\r\n};\r\n\r\n/** 4) Static options via `options` prop (no async needed, but loadData still required) */\r\nexport const WithStaticOptionsProp: Story = {\r\n args: {\r\n options: BASE_OPTIONS,\r\n loadData: async () => BASE_OPTIONS,\r\n },\r\n render: (args) => <ControlledCombobox {...args} />,\r\n};\r\n\r\n/** 5) Slow fetch to show loading state on open/search */\r\nexport const SlowFetchLoading: Story = {\r\n args: {\r\n loadData: createFetchOptions(BASE_OPTIONS, 1200),\r\n },\r\n render: (args) => <ControlledCombobox {...args} />,\r\n};\r\n\r\n/** 5.1) Forced loading state (opened on mount) */\r\nexport const Loading: Story = {\r\n args: {\r\n loadData: async () => BASE_OPTIONS,\r\n onMount: async (st: ComboboxCallbackStateParams<object, 'single'>) => {\r\n st.setOpen(true);\r\n st.setOptions([]);\r\n st.setLoading(true);\r\n await sleep(1200);\r\n st.setOptions(BASE_OPTIONS);\r\n st.setLoading(false);\r\n },\r\n },\r\n render: (args) => <ControlledCombobox {...args} />,\r\n};\r\n\r\n/** 6) Empty state with action (search something like \"zzz\") */\r\nexport const EmptyStateWithAction: Story = {\r\n args: {\r\n emptyLabel: 'Nothing found',\r\n emptyAction: (st: ComboboxCallbackStateParams) => {\r\n const canCreate = Boolean(st.search?.trim());\r\n return (\r\n <button\r\n type=\"button\"\r\n className=\"inline-flex items-center justify-center rounded-md border px-3 py-1.5 text-sm\"\r\n disabled={!canCreate}\r\n onClick={() => {\r\n const v = st.search.trim();\r\n const next: ComboboxOption = { value: v, label: `Create \"${v}\"` };\r\n st.setOptions([ next ]);\r\n st.setLoading(false);\r\n }}\r\n >\r\n Create option\r\n </button>\r\n );\r\n },\r\n },\r\n render: (args) => <ControlledCombobox {...args} />,\r\n};\r\n\r\n/** 7) commandInputAction (helper row under input) */\r\nexport const WithCommandInputAction: Story = {\r\n args: {\r\n commandInputAction: (st: ComboboxCallbackStateParams) => (\r\n <div className=\"px-3 py-2 flex items-center justify-between text-xs text-muted-foreground\">\r\n <span>\r\n results: <span className=\"font-mono\">{st.options.length}</span>\r\n </span>\r\n <button\r\n type=\"button\"\r\n className=\"underline\"\r\n onClick={() => {\r\n st.setSearch('');\r\n st.setLoading(false);\r\n }}\r\n >\r\n Clear search\r\n </button>\r\n </div>\r\n ),\r\n },\r\n render: (args) => <ControlledCombobox {...args} />,\r\n};\r\n\r\n/** 8) listHeadAction (top action inside list) */\r\nexport const WithListHeadAction: Story = {\r\n args: {\r\n listHeadAction: (st: ComboboxCallbackStateParams) => (\r\n <button\r\n type=\"button\"\r\n className=\"w-full text-left px-3 py-2 text-sm\"\r\n onClick={() => {\r\n st.setSearch('');\r\n st.setOpen(false);\r\n }}\r\n >\r\n Close list\r\n </button>\r\n ),\r\n },\r\n render: (args) => <ControlledCombobox {...args} />,\r\n};\r\n\r\n/** 9) listHeadAction (footer action outside of list) */\r\nexport const WithListFooterAction: Story = {\r\n args: {\r\n listFooterAction: (st: ComboboxCallbackStateParams) => (\r\n <button\r\n type=\"button\"\r\n className=\"w-full text-left min-h-10 text-sm\"\r\n onClick={() => {\r\n st.setSearch('');\r\n st.setOpen(false);\r\n }}\r\n >\r\n list footer action\r\n </button>\r\n ),\r\n },\r\n render: (args) => <ControlledCombobox {...args} />,\r\n};\r\n\r\n/** 10) Nested options tree */\r\nexport const NestedOptions: Story = {\r\n args: {\r\n loadData: createFetchOptions(NESTED_OPTIONS, 250),\r\n // defaultNodeDisabled: false,\r\n // defaultNodeMatched: false,\r\n // defaultNodeMuted: true,\r\n // defaultNodeInteractive: false,\r\n },\r\n render: (args) => <ControlledCombobox {...args} />,\r\n};\r\n\r\n/** 11) Multi Nested options tree */\r\nexport const NestedOptionsMulti: Story = {\r\n args: {\r\n loadData: createFetchOptions(NESTED_OPTIONS, 250),\r\n onMount: async (st: ComboboxCallbackStateParams<object, 'single'>) => {\r\n await sleep(900);\r\n st.setOptions(getFlattenOptions(NESTED_OPTIONS));\r\n },\r\n },\r\n render: (args) => {\r\n const TEST_FULL = false;\r\n const initialValues = TEST_FULL ? getAllValues(NESTED_OPTIONS) : [ 'fr', 'de' ];\r\n return <ControlledComboboxMulti {...args} initialValue={initialValues}/>\r\n },\r\n};\r\n\r\n/** 12) onMount initial loading (simulate prefetch on mount) */\r\nexport const OnMountPrefetch: Story = {\r\n args: {\r\n loadData: createFetchOptions(BASE_OPTIONS, 250),\r\n onMount: async (st: ComboboxCallbackStateParams<object, 'multi'>) => {\r\n await sleep(900);\r\n st.setOptions(BASE_OPTIONS);\r\n },\r\n },\r\n render: (args) => <ControlledCombobox {...args} />,\r\n};\r\n\r\n/** 13) render custom trigger */\r\nexport const RenderCustomTrigger: Story = {\r\n args: {\r\n renderTrigger: (state) => {\r\n console.log('state', state);\r\n return (\r\n <button\r\n type=\"button\"\r\n className=\"w-full\"\r\n onClick={() => state.setOpen((o) => !o)}\r\n >\r\n {state.selectedOption ? `Selected: ${state.selectedOption.label}` : 'Select option...'}\r\n </button>\r\n )\r\n }\r\n },\r\n render: (args) => <ControlledCombobox {...args} />,\r\n};\r\n\r\n/** 14) Load more with infinite scroll */\r\nexport const InfiniteScrollLoadMore: Story = {\r\n args: {\r\n placeholder: 'Select option...',\r\n searchLabel: 'Type to search...',\r\n emptyLabel: 'No options',\r\n loadData: createPaginatedFetchOptions(MANY_OPTIONS, 500, 20),\r\n },\r\n render: (args) => <ControlledCombobox {...args} />,\r\n};\r\n"],"names":["sleep","ms","r","flatten","nodes","res","walk","list","n","createFetchOptions","all","delayMs","search","q","allFlat","matchedValues","o","filterTree","items","filterTreeBySearch","createPaginatedFetchOptions","limit","offset","filteredTree","filteredFlat","BASE_OPTIONS","MANY_OPTIONS","_","i","NESTED_OPTIONS","getFlattenOptions","options","option","ControlledCombobox","initialValue","args","value","setValue","useState","loadData","useMemo","jsxs","jsx","Combobox","ControlledComboboxMulti","meta","Story","Default","WithValueSelected","Disabled","WithStaticOptionsProp","SlowFetchLoading","Loading","st","EmptyStateWithAction","canCreate","v","next","WithCommandInputAction","WithListHeadAction","WithListFooterAction","NestedOptions","NestedOptionsMulti","OnMountPrefetch","RenderCustomTrigger","state","InfiniteScrollLoadMore"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Combobox.stories.js","sources":["../../src/Combobox/Combobox.stories.tsx"],"sourcesContent":["import React, { useMemo, useState } from 'react';\nimport type { Meta, StoryObj } from '@storybook/react';\n\nimport { Combobox } from './Combobox';\nimport {\n ComboboxCallbackStateParams,\n ComboboxOption,\n ComboboxProps, MultiComboboxProps, SingleComboboxProps,\n} from './Combobox.types';\n\nconst sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));\n\nconst flatten = (nodes: ComboboxOption[] = []): ComboboxOption[] => {\n const res: ComboboxOption[] = [];\n const walk = (list?: ComboboxOption[]) => {\n if (!list?.length) return;\n for (const n of list) {\n res.push(n);\n if (n.items?.length) walk(n.items);\n }\n };\n walk(nodes);\n return res;\n};\n\nconst createFetchOptions =\n (all: ComboboxOption[], delayMs = 150): ComboboxProps['loadData'] =>\n async ({ search }) => {\n await sleep(delayMs);\n\n const q = (search ?? '').trim().toLowerCase();\n if (!q) return all;\n\n // simple \"contains\" search across flattened options; then return top-level filtered\n // (enough for Storybook demos; your real API can do better)\n const allFlat = flatten(all);\n const matchedValues = new Set(\n allFlat\n .filter((o) => String(o.label).toLowerCase().includes(q))\n .map((o) => String(o.value)),\n );\n\n const filterTree = (list: ComboboxOption[]): ComboboxOption[] => {\n return list\n .map((n) => {\n const items = n.items?.length ? filterTree(n.items) : undefined;\n const selfMatch =\n matchedValues.has(String(n.value)) ||\n String(n.label).toLowerCase().includes(q);\n\n if (!selfMatch && !items?.length) return null;\n return { ...n, items };\n })\n .filter(Boolean) as ComboboxOption[];\n };\n\n return filterTree(all);\n };\n\n\nconst filterTreeBySearch = (\n all: ComboboxOption[],\n search?: string,\n): ComboboxOption[] => {\n const q = (search ?? '').trim().toLowerCase();\n if (!q) return all;\n\n const allFlat = flatten(all);\n\n const matchedValues = new Set(\n allFlat\n .filter((o) => String(o.label).toLowerCase().includes(q))\n .map((o) => String(o.value)),\n );\n\n const filterTree = (list: ComboboxOption[]): ComboboxOption[] => {\n return list\n .map((n) => {\n const items = n.items?.length ? filterTree(n.items) : undefined;\n const selfMatch =\n matchedValues.has(String(n.value)) ||\n String(n.label).toLowerCase().includes(q);\n\n if (!selfMatch && !items?.length) return null;\n return { ...n, items };\n })\n .filter(Boolean) as ComboboxOption[];\n };\n\n return filterTree(all);\n};\n\nconst createPaginatedFetchOptions =\n (\n all: ComboboxOption[],\n delayMs = 250,\n limit = 20,\n ): ComboboxProps['loadData'] =>\n async ({ search, offset = 0 }) => {\n await sleep(delayMs);\n\n const filteredTree = filterTreeBySearch(all, search);\n const filteredFlat = flatten(filteredTree);\n\n const data = filteredFlat.slice(offset, offset + limit);\n\n return {\n data,\n total: filteredFlat.length,\n };\n };\n\nconst BASE_OPTIONS: ComboboxOption[] = [\n { value: 'ua', label: 'Ukraine' },\n { value: 'pl', label: 'Poland' },\n { value: 'de', label: 'Germany' },\n { value: 'fr', label: 'France' },\n { value: 'es', label: 'Spain' },\n { value: 'it', label: 'Italy' },\n];\n\nconst MANY_OPTIONS: ComboboxOption[] = Array.from({ length: 120 }).map((_, i) => ({\n value: `option-${i + 1}`,\n label: `Option ${i + 1}`,\n}));\n\nconst NESTED_OPTIONS: ComboboxOption[] = [\n {\n value: 'europe',\n label: 'Europe',\n items: [\n {\n value: 'fr',\n label: 'France',\n items: [\n {\n value: 'paris',\n label: 'Paris (Île-de-France)',\n items: [\n { value: 'paris-1', label: 'Paris 1st arrondissement' },\n { value: 'paris-3', label: 'Paris 3rd arrondissement' },\n { value: 'paris-10', label: 'Paris 10th arrondissement' },\n ],\n },\n { value: 'marseille', label: 'Marseille (Provence-Alpes-Côte d\\'Azur)' },\n {\n value: 'lyon',\n label: 'Lyon (Auvergne-Rhône-Alpes)',\n items: [\n { value: 'lyon-presquile', label: 'Presqu\\'île (1st/2nd)' },\n { value: 'lyon-vieux', label: 'Vieux Lyon' },\n ],\n },\n { value: 'toulouse', label: 'Toulouse (Occitanie)' },\n { value: 'bordeaux', label: 'Bordeaux (Nouvelle-Aquitaine)' },\n { value: 'strasbourg', label: 'Strasbourg (Grand Est)' },\n {\n value: 'rennes',\n label: 'Rennes (Brittany)',\n items: [\n { value: 'rennes-centre', label: 'Rennes Centre' },\n { value: 'rennes-beauregard', label: 'Beauregard' },\n ],\n },\n ]\n },\n { value: 'ua', label: 'Ukraine' },\n { value: 'pl', label: 'Poland' },\n { value: 'de', label: 'Germany' },\n ],\n },\n {\n value: 'north-america',\n label: 'North America',\n items: [\n { value: 'us', label: 'United States' },\n { value: 'ca', label: 'Canada' },\n { value: 'mx', label: 'Mexico' },\n { value: 'north-america-long', label: 'To long option to test wrapping. '.repeat(3) },\n {\n value: 'north-america-long-single',\n label: 'To long option to test wrapping. '.replace(/ /g, '_').repeat(3)\n },\n ],\n },\n];\nconst getFlattenOptions = (options: ComboboxOption[]) => {\n return options.flatMap(option => [\n option,\n ...(option.items ? getFlattenOptions(option.items) : [])\n ]);\n};\n\nconst getAllValues = (options: ComboboxOption[]): string[] => {\n return getFlattenOptions(options).map(o => o.value)\n};\n\ntype ControlledProps<T extends ComboboxProps = ComboboxProps> = Omit<T, 'value' | 'onChange'> & {\n initialValue?: T['value'];\n};\n\nfunction ControlledCombobox({ initialValue = '', ...args }: ControlledProps<SingleComboboxProps>) {\n const [ value, setValue ] = useState<SingleComboboxProps['value']>(initialValue);\n const loadData = useMemo(\n () => args.loadData,\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [],\n );\n\n return (\n <div className=\"max-w-sm\">\n <Combobox type='single' {...args} value={value} onChange={setValue} loadData={loadData}\n defaultNodeMatched/>\n <div className=\"mt-3 text-xs text-muted-foreground\">\n value: <span className=\"font-mono\">{String(value || '')}</span>\n </div>\n </div>\n );\n}\n\nfunction ControlledComboboxMulti({\n initialValue = [],\n ...args\n }: ControlledProps<MultiComboboxProps>) {\n const [ value, setValue ] = useState<MultiComboboxProps['value'] | undefined>(initialValue);\n const loadData = useMemo(() => args.loadData, []);\n return (\n <div className=\"max-w-sm\">\n <Combobox\n {...args}\n type='multi'\n value={value}\n onChange={setValue}\n loadData={loadData}\n />\n <div className=\"mt-3 text-xs text-muted-foreground\">\n value: <span className=\"font-mono\">{(value || []).join(', ')}</span>\n </div>\n </div>\n );\n}\n\nconst meta = {\n title: 'Combobox',\n component: Combobox,\n parameters: {\n layout: 'centered',\n },\n args: {\n placeholder: 'Select option...',\n searchLabel: 'Type to search...',\n emptyLabel: 'No options',\n disabled: false,\n loadData: createFetchOptions(BASE_OPTIONS, 250),\n },\n argTypes: {\n loadData: { control: false },\n onChange: { control: false },\n onMount: { control: false },\n emptyAction: { control: false },\n commandInputAction: { control: false },\n listHeadAction: { control: false },\n options: { control: false },\n value: { control: false },\n },\n decorators: [\n (Story) => (\n <div className=\"p-6 w-[420px]\">\n <Story/>\n </div>\n ),\n ],\n} satisfies Meta<typeof Combobox>;\n\nexport default meta;\n\ntype Story = StoryObj<typeof meta>;\n\n/** 1) Default (async options) */\nexport const Default: Story = {\n render: (args) => <ControlledCombobox {...args} />,\n};\n\n/** 2) With initial selected value */\nexport const WithValueSelected: Story = {\n render: (args) => <ControlledCombobox {...args} initialValue=\"pl\"/>,\n};\n\n/** 3) Disabled */\nexport const Disabled: Story = {\n args: { disabled: true },\n render: (args) => <ControlledCombobox {...args} initialValue=\"de\"/>,\n};\n\n/** 4) Static options via `options` prop (no async needed, but loadData still required) */\nexport const WithStaticOptionsProp: Story = {\n args: {\n options: BASE_OPTIONS,\n loadData: async () => BASE_OPTIONS,\n },\n render: (args) => <ControlledCombobox {...args} />,\n};\n\n/** 5) Slow fetch to show loading state on open/search */\nexport const SlowFetchLoading: Story = {\n args: {\n loadData: createFetchOptions(BASE_OPTIONS, 1200),\n },\n render: (args) => <ControlledCombobox {...args} />,\n};\n\n/** 5.1) Forced loading state (opened on mount) */\nexport const Loading: Story = {\n args: {\n loadData: async () => BASE_OPTIONS,\n onMount: async (st: ComboboxCallbackStateParams<object, 'single'>) => {\n st.setOpen(true);\n st.setOptions([]);\n st.setLoading(true);\n await sleep(1200);\n st.setOptions(BASE_OPTIONS);\n st.setLoading(false);\n },\n },\n render: (args) => <ControlledCombobox {...args} />,\n};\n\n/** 6) Empty state with action (search something like \"zzz\") */\nexport const EmptyStateWithAction: Story = {\n args: {\n emptyLabel: 'Nothing found',\n emptyAction: (st: ComboboxCallbackStateParams) => {\n const canCreate = Boolean(st.search?.trim());\n return (\n <button\n type=\"button\"\n className=\"inline-flex items-center justify-center rounded-md border px-3 py-1.5 text-sm\"\n disabled={!canCreate}\n onClick={() => {\n const v = st.search.trim();\n const next: ComboboxOption = { value: v, label: `Create \"${v}\"` };\n st.setOptions([ next ]);\n st.setLoading(false);\n }}\n >\n Create option\n </button>\n );\n },\n },\n render: (args) => <ControlledCombobox {...args} />,\n};\n\n/** 7) commandInputAction (helper row under input) */\nexport const WithCommandInputAction: Story = {\n args: {\n commandInputAction: (st: ComboboxCallbackStateParams) => (\n <div className=\"px-3 py-2 flex items-center justify-between text-xs text-muted-foreground\">\n <span>\n results: <span className=\"font-mono\">{st.options.length}</span>\n </span>\n <button\n type=\"button\"\n className=\"underline\"\n onClick={() => {\n st.setSearch('');\n st.setLoading(false);\n }}\n >\n Clear search\n </button>\n </div>\n ),\n },\n render: (args) => <ControlledCombobox {...args} />,\n};\n\n/** 8) listHeadAction (top action inside list) */\nexport const WithListHeadAction: Story = {\n args: {\n listHeadAction: (st: ComboboxCallbackStateParams) => (\n <button\n type=\"button\"\n className=\"w-full text-left px-3 py-2 text-sm\"\n onClick={() => {\n st.setSearch('');\n st.setOpen(false);\n }}\n >\n Close list\n </button>\n ),\n },\n render: (args) => <ControlledCombobox {...args} />,\n};\n\n/** 9) listHeadAction (footer action outside of list) */\nexport const WithListFooterAction: Story = {\n args: {\n listFooterAction: (st: ComboboxCallbackStateParams) => (\n <button\n type=\"button\"\n className=\"w-full text-left min-h-10 text-sm\"\n onClick={() => {\n st.setSearch('');\n st.setOpen(false);\n }}\n >\n list footer action\n </button>\n ),\n },\n render: (args) => <ControlledCombobox {...args} />,\n};\n\n/** 10) Nested options tree */\nexport const NestedOptions: Story = {\n args: {\n loadData: createFetchOptions(NESTED_OPTIONS, 250),\n // defaultNodeDisabled: false,\n // defaultNodeMatched: false,\n // defaultNodeMuted: true,\n // defaultNodeInteractive: false,\n },\n render: (args) => <ControlledCombobox {...args} />,\n};\n\n/** 11) Multi Nested options tree */\nexport const NestedOptionsMulti: Story = {\n args: {\n loadData: createFetchOptions(NESTED_OPTIONS, 250),\n onMount: async (st: ComboboxCallbackStateParams<object, 'single'>) => {\n await sleep(900);\n st.setOptions(getFlattenOptions(NESTED_OPTIONS));\n },\n },\n render: (args) => {\n const TEST_FULL = false;\n const initialValues = TEST_FULL ? getAllValues(NESTED_OPTIONS) : [ 'fr', 'de' ];\n return <ControlledComboboxMulti {...args} initialValue={initialValues}/>\n },\n};\n\n/** 12) onMount initial loading (simulate prefetch on mount) */\nexport const OnMountPrefetch: Story = {\n args: {\n loadData: createFetchOptions(BASE_OPTIONS, 250),\n onMount: async (st: ComboboxCallbackStateParams<object, 'multi'>) => {\n await sleep(900);\n st.setOptions(BASE_OPTIONS);\n },\n },\n render: (args) => <ControlledCombobox {...args} />,\n};\n\n/** 13) render custom trigger */\nexport const RenderCustomTrigger: Story = {\n args: {\n renderTrigger: (state) => {\n console.log('state', state);\n return (\n <button\n type=\"button\"\n className=\"w-full\"\n onClick={() => state.setOpen((o) => !o)}\n >\n {state.selectedOption ? `Selected: ${state.selectedOption.label}` : 'Select option...'}\n </button>\n )\n }\n },\n render: (args) => <ControlledCombobox {...args} />,\n};\n\n/** 14) Load more with infinite scroll */\nexport const InfiniteScrollLoadMore: Story = {\n args: {\n placeholder: 'Select option...',\n searchLabel: 'Type to search...',\n emptyLabel: 'No options',\n loadData: createPaginatedFetchOptions(MANY_OPTIONS, 500, 20),\n },\n render: (args) => <ControlledCombobox {...args} />,\n};\n"],"names":["sleep","ms","r","flatten","nodes","res","walk","list","n","createFetchOptions","all","delayMs","search","q","allFlat","matchedValues","o","filterTree","items","filterTreeBySearch","createPaginatedFetchOptions","limit","offset","filteredTree","filteredFlat","BASE_OPTIONS","MANY_OPTIONS","_","i","NESTED_OPTIONS","getFlattenOptions","options","option","ControlledCombobox","initialValue","args","value","setValue","useState","loadData","useMemo","jsxs","jsx","Combobox","ControlledComboboxMulti","meta","Story","Default","WithValueSelected","Disabled","WithStaticOptionsProp","SlowFetchLoading","Loading","st","EmptyStateWithAction","canCreate","v","next","WithCommandInputAction","WithListHeadAction","WithListFooterAction","NestedOptions","NestedOptionsMulti","OnMountPrefetch","RenderCustomTrigger","state","InfiniteScrollLoadMore"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Combobox.types.js","sources":["../../src/Combobox/Combobox.types.ts"],"sourcesContent":["import { Dispatch, HTMLAttributes, ReactNode, Ref, SetStateAction } from 'react';\
|
|
1
|
+
{"version":3,"file":"Combobox.types.js","sources":["../../src/Combobox/Combobox.types.ts"],"sourcesContent":["import { Dispatch, HTMLAttributes, ReactNode, Ref, SetStateAction } from 'react';\n\nexport type ComboboxValueType = string | string[];\nexport type ComboboxSelectedType = 'single' | 'multi';\n\nexport const DEFAULT_COMBOBOX_TYPE: ComboboxSelectedType = 'single';\n\nexport interface ComboboxOption<Data extends object = object> {\n value: string;\n label: string;\n node?: Data;\n // tree only\n items?: ComboboxOption<Data>[];\n path?: string[];\n parent?: string;\n level?: number;\n matched?: boolean;\n}\n\nexport interface ComboboxCallbackStateParams<\n Data extends object = object,\n T extends ComboboxSelectedType = 'single'\n> {\n options: ComboboxOption<Data>[];\n setOptions: Dispatch<SetStateAction<ComboboxOption<Data>[]>>\n search: string;\n setSearch: Dispatch<SetStateAction<string>>\n onChangeOption: (option: ComboboxOption<Data>) => void;\n open: boolean,\n setOpen: Dispatch<SetStateAction<boolean>>;\n loading: boolean;\n setLoading: Dispatch<SetStateAction<boolean>>;\n isEmptyList: boolean;\n isSearchedEmptyList: boolean;\n placeholder?: string;\n\n type: T;\n selectedOption: T extends 'single'\n ? ComboboxOption<Data> | undefined\n : ComboboxOption<Data>[];\n setSelectedOption: T extends 'single'\n ? Dispatch<SetStateAction<ComboboxOption<Data> | undefined>>\n : Dispatch<SetStateAction<ComboboxOption<Data>[] | undefined>>;\n}\n\nexport type ComboboxCallbackStateParamsUnion<Data extends object = object> = ComboboxCallbackStateParams<Data, 'single'> | ComboboxCallbackStateParams<Data, 'multi'>\nexport type ComboboxCallbackStateParamsRenderHandler<Data extends object = object> = (params:ComboboxCallbackStateParamsUnion<Data>) => ReactNode\n\nexport interface IComboboxOptionsNodeHandlersProps<Data extends object = object> {\n defaultNodeOpen?: boolean | ((option: ComboboxOption<Data>, deep: number) => boolean | undefined);\n defaultNodeDisabled?: boolean | ((option: ComboboxOption<Data>, deep: number) => boolean | undefined);\n defaultNodeMatched?: boolean | ((option: ComboboxOption<Data>, deep: number) => boolean | undefined);\n defaultNodeMuted?: boolean | ((option: ComboboxOption<Data>, deep: number) => boolean | undefined);\n defaultNodeInteractive?: boolean | ((option: ComboboxOption<Data>, deep: number) => boolean | undefined);\n /** Use onPointerUp instead of cmdk onSelect. Fixes selection inside modal Dialog. */\n forcePointerSelect?: boolean;\n}\n\nexport interface IComboboxOptionsNodeProps<Data extends object = object>\n extends IComboboxOptionsNodeHandlersProps<Data> {\n type: ComboboxSelectedType,\n search?: string;\n value?: ComboboxValueType;\n option: ComboboxOption<Data>;\n onSelect?: (option: ComboboxOption<Data>) => void;\n deep?: number;\n}\n\nexport interface IComboboxOptionsProps<Data extends object = object>\n extends Omit<IComboboxOptionsNodeProps<Data>, 'option'>, IComboboxOptionsNodeHandlersProps<Data> {\n options?: ComboboxOption<Data>[];\n}\n\ninterface IListActionProps extends HTMLAttributes<HTMLDivElement> {\n bordered?: boolean;\n}\ninterface IPopoverSlotProps {\n /** Set Popover modal mode. Use `true` when Combobox is inside a modal Dialog. */\n modal?: boolean;\n /** Container element for Popover portal. Use to render inside modal Dialog. */\n container?: HTMLElement | null;\n}\n\nexport interface ISlotProps {\n popover?: IPopoverSlotProps;\n listFooterAction?: IListActionProps;\n}\n\ntype ComboboxLoadDataParams = { search?: string; offset?: number; }\ntype ComboboxLoadDataResult<Data extends object = object> = { data: ComboboxOption<Data>[]; total: number; }\ntype ComboboxLoadDataReturn<Data extends object = object> = ComboboxOption<Data>[] | ComboboxLoadDataResult<Data>;\ntype ComboboxLoadData<Data extends object = object> = (\n params: ComboboxLoadDataParams,\n signal: AbortSignal,\n controller: ComboboxCallbackStateParams<Data, 'single'> | ComboboxCallbackStateParams<Data, 'multi'>\n) => Promise<ComboboxLoadDataReturn<Data>>;\n\nexport interface ComboboxBaseProps<\n Data extends object = object,\n T extends ComboboxSelectedType = 'single'\n> extends IComboboxOptionsNodeHandlersProps {\n type?: T;\n imperativeRef?: Ref<\n ComboboxCallbackStateParams<Data, 'single'>\n | ComboboxCallbackStateParams<Data, 'multi'>\n | null\n >;\n placeholder?: string;\n searchLabel?: string;\n disabled?: boolean;\n /** Callback for load data on search debounce */\n loadData: ComboboxLoadData<Data>;\n options?: ComboboxOption<Data>[];\n /** Command Empty list label*/\n emptyLabel?: string;\n /** Command Empty list action */\n emptyAction?: ((params: ComboboxCallbackStateParams<Data, T>) => ReactNode) | ReactNode;\n /** Command Input footer action */\n commandInputAction?: ((params: ComboboxCallbackStateParams<Data, T>) => ReactNode) | ReactNode;\n /** Command List first element action */\n listHeadAction?: ((params: ComboboxCallbackStateParams<Data, T>) => ReactNode) | ReactNode;\n /** Command List footer element action */\n listFooterAction?: ((params: ComboboxCallbackStateParams<Data, T>) => ReactNode) | ReactNode;\n /** Callback for load data on start component */\n onMount?: (params: ComboboxCallbackStateParams<Data, T>) => Promise<void>;\n\n renderTrigger?: (params: ComboboxCallbackStateParams<Data, T>) => ReactNode;\n renderList?: (params: ComboboxCallbackStateParams<Data, T>) => ReactNode;\n\n slotProps?: ISlotProps;\n}\n\nexport interface SingleComboboxProps<Data extends object = object>\n extends ComboboxBaseProps<Data, 'single'> {\n type?: 'single';\n value?: string;\n onChange: (value: string | undefined) => void;\n}\nexport interface MultiComboboxProps<Data extends object = object>\n extends ComboboxBaseProps<Data, 'multi'> {\n type: 'multi';\n value?: string[];\n onChange: (value: string[] | undefined) => void;\n}\n\nexport type ComboboxProps<\n Data extends object = object,\n T extends ComboboxSelectedType = 'single'\n> = T extends 'single'\n ? SingleComboboxProps<Data>\n : MultiComboboxProps<Data>;\n"],"names":["DEFAULT_COMBOBOX_TYPE"],"mappings":"AAKO,MAAMA,IAA8C;"}
|
|
@@ -1,30 +1,31 @@
|
|
|
1
1
|
import { jsxs as b, jsx as a } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { CommandItem as g } from "../Command/Command.js";
|
|
3
|
+
import { DEFAULT_COMBOBOX_TYPE as N } from "./Combobox.types.js";
|
|
4
|
+
import { ChevronRightIcon as x, CheckIcon as D } from "lucide-react";
|
|
4
5
|
import { cn as r } from "@oneplatformdev/utils";
|
|
5
|
-
import {
|
|
6
|
-
import { ButtonIcon as
|
|
7
|
-
import
|
|
8
|
-
const E = 24, P = 8, I = (
|
|
6
|
+
import { Checkbox as k } from "../Checkbox/Checkbox.js";
|
|
7
|
+
import { ButtonIcon as C } from "../ButtonIcon/ButtonIcon.js";
|
|
8
|
+
import "../ButtonIcon/buttonIconVariants.js";
|
|
9
|
+
const E = 24, P = 8, I = (i) => i ? Math.max(i - 1, 0) * E - P : 0, L = (i) => {
|
|
9
10
|
const {
|
|
10
|
-
type: s =
|
|
11
|
+
type: s = N,
|
|
11
12
|
expanded: h,
|
|
12
13
|
option: e,
|
|
13
14
|
onSelect: y,
|
|
14
15
|
value: l = "",
|
|
15
16
|
deep: t = 0,
|
|
16
|
-
onCollapseToggle:
|
|
17
|
+
onCollapseToggle: c,
|
|
17
18
|
defaultNodeDisabled: p,
|
|
18
19
|
defaultNodeMatched: d,
|
|
19
20
|
defaultNodeMuted: f,
|
|
20
21
|
defaultNodeInteractive: o,
|
|
21
22
|
forcePointerSelect: u
|
|
22
|
-
} =
|
|
23
|
-
if (!(typeof o == "function" ? o(e, t) : o ?? !0)) return
|
|
23
|
+
} = i, m = Array.isArray(l) ? l.includes(e.value) : l === e.value, v = () => {
|
|
24
|
+
if (!(typeof o == "function" ? o(e, t) : o ?? !0)) return c?.();
|
|
24
25
|
y?.(e);
|
|
25
26
|
};
|
|
26
27
|
return /* @__PURE__ */ b(
|
|
27
|
-
|
|
28
|
+
g,
|
|
28
29
|
{
|
|
29
30
|
value: e.value,
|
|
30
31
|
"data-matched": e.matched ?? !0,
|
|
@@ -45,10 +46,10 @@ const E = 24, P = 8, I = (c) => c ? Math.max(c - 1, 0) * E - P : 0, F = (c) => {
|
|
|
45
46
|
style: { paddingLeft: "var(--deep-space)" },
|
|
46
47
|
className: "relative box-border min-w-10 h-10",
|
|
47
48
|
onClick: (n) => {
|
|
48
|
-
|
|
49
|
+
c && (n?.preventDefault(), n?.stopPropagation(), c?.());
|
|
49
50
|
},
|
|
50
|
-
children: /* @__PURE__ */ a("div", { className: "w-10 aspect-square shrink-0", children:
|
|
51
|
-
|
|
51
|
+
children: /* @__PURE__ */ a("div", { className: "w-10 aspect-square shrink-0", children: c && /* @__PURE__ */ a(
|
|
52
|
+
C,
|
|
52
53
|
{
|
|
53
54
|
type: "button",
|
|
54
55
|
variant: "ghost",
|
|
@@ -57,7 +58,7 @@ const E = 24, P = 8, I = (c) => c ? Math.max(c - 1, 0) * E - P : 0, F = (c) => {
|
|
|
57
58
|
"bg-transparent hover:bg-transparent active:bg-transparent focus:bg-transparent"
|
|
58
59
|
),
|
|
59
60
|
icon: /* @__PURE__ */ a(
|
|
60
|
-
|
|
61
|
+
x,
|
|
61
62
|
{
|
|
62
63
|
strokeWidth: 2,
|
|
63
64
|
className: r(
|
|
@@ -71,7 +72,7 @@ const E = 24, P = 8, I = (c) => c ? Math.max(c - 1, 0) * E - P : 0, F = (c) => {
|
|
|
71
72
|
) })
|
|
72
73
|
}
|
|
73
74
|
),
|
|
74
|
-
s === "multi" && /* @__PURE__ */ a(
|
|
75
|
+
s === "multi" && /* @__PURE__ */ a(k, { checked: m, className: "mr-2 shrink-0" }),
|
|
75
76
|
/* @__PURE__ */ a(
|
|
76
77
|
"span",
|
|
77
78
|
{
|
|
@@ -85,7 +86,7 @@ const E = 24, P = 8, I = (c) => c ? Math.max(c - 1, 0) * E - P : 0, F = (c) => {
|
|
|
85
86
|
}
|
|
86
87
|
),
|
|
87
88
|
s === "single" && /* @__PURE__ */ a(
|
|
88
|
-
|
|
89
|
+
D,
|
|
89
90
|
{
|
|
90
91
|
className: r(
|
|
91
92
|
"ml-2 shrink-0",
|
|
@@ -99,6 +100,6 @@ const E = 24, P = 8, I = (c) => c ? Math.max(c - 1, 0) * E - P : 0, F = (c) => {
|
|
|
99
100
|
);
|
|
100
101
|
};
|
|
101
102
|
export {
|
|
102
|
-
|
|
103
|
+
L as ComboboxOptionItem
|
|
103
104
|
};
|
|
104
105
|
//# sourceMappingURL=ComboboxOptionItem.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ComboboxOptionItem.js","sources":["../../src/Combobox/ComboboxOptionItem.tsx"],"sourcesContent":["import { CSSProperties, PropsWithChildren } from 'react';\
|
|
1
|
+
{"version":3,"file":"ComboboxOptionItem.js","sources":["../../src/Combobox/ComboboxOptionItem.tsx"],"sourcesContent":["import { CSSProperties, PropsWithChildren } from 'react';\nimport { CommandItem } from '../Command';\nimport { DEFAULT_COMBOBOX_TYPE, IComboboxOptionsNodeProps } from './Combobox.types';\nimport { CheckIcon, ChevronRightIcon } from 'lucide-react';\nimport { cn } from '@oneplatformdev/utils';\nimport { Checkbox } from \"../Checkbox\";\nimport { ButtonIcon } from \"../ButtonIcon\";\n\nconst DEEP_OFFSET = 24;\nconst DEEP_PADDING_DELTA = 8;\nconst calcDeepSpace = (deep: number) => {\n if(!deep) return 0;\n const space = Math.max(deep - 1, 0) * DEEP_OFFSET;\n return space - DEEP_PADDING_DELTA;\n}\n\nexport const ComboboxOptionItem = <Data extends object>(\n props: PropsWithChildren<IComboboxOptionsNodeProps<Data>> & {\n onCollapseToggle?: () => void;\n expanded?: boolean;\n }\n) => {\n const {\n type = DEFAULT_COMBOBOX_TYPE,\n expanded,\n option,\n onSelect,\n value = '',\n deep = 0,\n onCollapseToggle,\n defaultNodeDisabled,\n defaultNodeMatched,\n defaultNodeMuted,\n defaultNodeInteractive,\n forcePointerSelect,\n } = props;\n\n const isSelected = Array.isArray(value)\n ? value.includes(option.value)\n : value === option.value;\n\n const handleSelect = () => {\n const interactive = typeof defaultNodeInteractive === \"function\"\n ? defaultNodeInteractive(option, deep)\n : defaultNodeInteractive ?? true;\n if (!interactive) return onCollapseToggle?.();\n onSelect?.(option);\n };\n\n return (\n <CommandItem\n key={option.value}\n value={option.value}\n data-matched={option.matched ?? true}\n onSelect={forcePointerSelect ? undefined : handleSelect}\n onPointerUp={forcePointerSelect ? handleSelect : undefined}\n onClick={(e) => {\n const interactive = typeof defaultNodeInteractive === \"function\"\n ? defaultNodeInteractive(option, deep)\n : defaultNodeInteractive ?? true\n\n if(!interactive) {\n e?.preventDefault();\n e?.stopPropagation();\n }\n }}\n className={cn('py-0 gap-0', deep && 'pl-0')}\n style={{\n '--deep-space': `${calcDeepSpace(deep)}px`,\n } as CSSProperties}\n disabled={typeof defaultNodeDisabled === \"function\"\n ? defaultNodeDisabled(option, deep)\n : defaultNodeDisabled ?? false}\n >\n {!!deep && (\n <div\n style={{ paddingLeft: 'var(--deep-space)' }}\n className='relative box-border min-w-10 h-10'\n onClick={(e) => {\n if(!onCollapseToggle) return;\n e?.preventDefault();\n e?.stopPropagation();\n onCollapseToggle?.();\n }}\n >\n <div className='w-10 aspect-square shrink-0'>\n {onCollapseToggle && (\n <ButtonIcon\n type=\"button\"\n variant=\"ghost\"\n color='secondary'\n className={cn(\n 'bg-transparent hover:bg-transparent active:bg-transparent focus:bg-transparent'\n )}\n icon={(\n <ChevronRightIcon\n strokeWidth={2}\n className={cn(\n 'text-[#06080D]',\n 'transition-transform duration-200',\n expanded && 'rotate-90',\n )}\n />\n )}\n />\n )}\n </div>\n </div>\n )}\n {type === 'multi' && <Checkbox checked={isSelected} className='mr-2 shrink-0'/>}\n <span\n className={cn(\n 'overflow-hidden whitespace-wrap text-ellipsis line-clamp-2 grow',\n (() => {\n return typeof defaultNodeMatched === \"function\"\n ? defaultNodeMatched(option, deep)\n : defaultNodeMatched ?? false\n })() && 'font-bold',\n (() => {\n return typeof defaultNodeMuted === \"function\"\n ? defaultNodeMuted(option, deep)\n : defaultNodeMuted ?? false\n })() && 'opacity-60',\n (() => {\n const res = typeof defaultNodeInteractive === \"function\"\n ? defaultNodeInteractive(option, deep)\n : defaultNodeInteractive ?? true\n return !res;\n })() && 'pointer-events-none',\n )}\n >\n {option.label}\n </span>\n {type === 'single' && (\n <CheckIcon\n className={cn(\n 'ml-2 shrink-0',\n isSelected ? 'opacity-100' : 'opacity-0'\n )}\n />\n )}\n </CommandItem>\n );\n}\n"],"names":["DEEP_OFFSET","DEEP_PADDING_DELTA","calcDeepSpace","deep","ComboboxOptionItem","props","type","DEFAULT_COMBOBOX_TYPE","expanded","option","onSelect","value","onCollapseToggle","defaultNodeDisabled","defaultNodeMatched","defaultNodeMuted","defaultNodeInteractive","forcePointerSelect","isSelected","handleSelect","jsxs","CommandItem","e","cn","jsx","ButtonIcon","ChevronRightIcon","Checkbox","CheckIcon"],"mappings":"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"}
|
|
@@ -1,29 +1,30 @@
|
|
|
1
1
|
import { jsx as e, jsxs as i, Fragment as w } from "react/jsx-runtime";
|
|
2
|
+
import { LoadingMask as G } from "../LoadingMask/LoadingMask.js";
|
|
3
|
+
import "../LoadingMask/RenderLoadingMask.js";
|
|
4
|
+
import { PopoverContent as H } from "../Popover/Popover.js";
|
|
5
|
+
import { Command as J, CommandInput as T, CommandList as _, CommandGroup as q, CommandEmpty as y, CommandItem as z } from "../Command/Command.js";
|
|
2
6
|
import { cn as s } from "@oneplatformdev/utils";
|
|
3
|
-
import { ComboboxRenderOptions as
|
|
4
|
-
import { useRef as
|
|
5
|
-
import { useInView as
|
|
6
|
-
import { PopoverContent as _ } from "../Popover/Popover.js";
|
|
7
|
-
import { Command as q, CommandInput as z, CommandList as B, CommandGroup as K, CommandEmpty as y, CommandItem as Q } from "../Command/Command.js";
|
|
8
|
-
import { LoadingMask as U } from "../LoadingMask/LoadingMask.js";
|
|
7
|
+
import { ComboboxRenderOptions as B } from "./ComboboxRenderOptions.js";
|
|
8
|
+
import { useRef as K, useEffect as Q } from "react";
|
|
9
|
+
import { useInView as U } from "react-intersection-observer";
|
|
9
10
|
import { Skeleton as W } from "../Skeleton/Skeleton.js";
|
|
10
|
-
const X = (t) => /* @__PURE__ */ e("div", { className: "flex w-full flex-col gap-0", children: Array.from({ length: t.length || 2 }).map((c,
|
|
11
|
+
const X = (t) => /* @__PURE__ */ e("div", { className: "flex w-full flex-col gap-0", children: Array.from({ length: t.length || 2 }).map((c, m) => /* @__PURE__ */ e(
|
|
11
12
|
"div",
|
|
12
13
|
{
|
|
13
14
|
className: "flex items-center min-h-10 w-full px-4",
|
|
14
15
|
children: /* @__PURE__ */ e("div", { className: s("flex items-center w-full", t.className), children: /* @__PURE__ */ e(W, { className: "h-4 w-full" }) })
|
|
15
16
|
},
|
|
16
|
-
|
|
17
|
-
)) }),
|
|
17
|
+
m
|
|
18
|
+
)) }), ie = (t) => {
|
|
18
19
|
const {
|
|
19
20
|
open: c,
|
|
20
|
-
type:
|
|
21
|
+
type: m,
|
|
21
22
|
search: u,
|
|
22
23
|
onSearch: C,
|
|
23
24
|
hasNext: v,
|
|
24
25
|
loading: r,
|
|
25
26
|
loadingMore: A,
|
|
26
|
-
isEmptyList:
|
|
27
|
+
isEmptyList: d,
|
|
27
28
|
onSelect: L,
|
|
28
29
|
options: x = [],
|
|
29
30
|
callbackStateParams: o,
|
|
@@ -43,24 +44,24 @@ const X = (t) => /* @__PURE__ */ e("div", { className: "flex w-full flex-col gap
|
|
|
43
44
|
popoverContainer: E,
|
|
44
45
|
renderList: h,
|
|
45
46
|
onLoadMore: V
|
|
46
|
-
} = t, b =
|
|
47
|
+
} = t, b = K(null), { ref: j, inView: g } = U({
|
|
47
48
|
root: b.current,
|
|
48
49
|
rootMargin: "0px 0px 200px 0px",
|
|
49
50
|
threshold: 0
|
|
50
51
|
});
|
|
51
|
-
return
|
|
52
|
+
return Q(() => {
|
|
52
53
|
c && g && V?.();
|
|
53
54
|
}, [g, c]), /* @__PURE__ */ e(
|
|
54
|
-
|
|
55
|
+
H,
|
|
55
56
|
{
|
|
56
57
|
className: s(
|
|
57
58
|
"w-(--radix-popper-anchor-width) max-w-none p-2"
|
|
58
59
|
),
|
|
59
60
|
align: "start",
|
|
60
61
|
container: E,
|
|
61
|
-
children: /* @__PURE__ */ i(
|
|
62
|
+
children: /* @__PURE__ */ i(J, { shouldFilter: !1, children: [
|
|
62
63
|
/* @__PURE__ */ e(
|
|
63
|
-
|
|
64
|
+
T,
|
|
64
65
|
{
|
|
65
66
|
placeholder: F,
|
|
66
67
|
value: u,
|
|
@@ -68,22 +69,22 @@ const X = (t) => /* @__PURE__ */ e("div", { className: "flex w-full flex-col gap
|
|
|
68
69
|
}
|
|
69
70
|
),
|
|
70
71
|
typeof p == "function" ? p(o) : p,
|
|
71
|
-
/* @__PURE__ */ e(
|
|
72
|
-
|
|
72
|
+
/* @__PURE__ */ e(_, { ref: b, children: /* @__PURE__ */ i(
|
|
73
|
+
q,
|
|
73
74
|
{
|
|
74
75
|
className: s(
|
|
75
76
|
!x.length && "p-0 shadow-none",
|
|
76
77
|
"px-0 py-2"
|
|
77
78
|
),
|
|
78
79
|
children: [
|
|
79
|
-
r && /* @__PURE__ */ e("div", { className: "pt-2 pb-0", children: /* @__PURE__ */ e(
|
|
80
|
-
!r &&
|
|
80
|
+
r && /* @__PURE__ */ e("div", { className: "pt-2 pb-0", children: /* @__PURE__ */ e(G, {}) }),
|
|
81
|
+
!r && d && /* @__PURE__ */ e(w, { children: n ? /* @__PURE__ */ i(y, { className: "flex flex-col gap-3 py-5 px-3 items-center", children: [
|
|
81
82
|
/* @__PURE__ */ e("span", { children: N }),
|
|
82
83
|
typeof n == "function" ? n(o) : n
|
|
83
84
|
] }) : /* @__PURE__ */ e(y, { children: N }) }),
|
|
84
|
-
!r && !
|
|
85
|
+
!r && !d && /* @__PURE__ */ i(w, { children: [
|
|
85
86
|
l && /* @__PURE__ */ e(
|
|
86
|
-
|
|
87
|
+
z,
|
|
87
88
|
{
|
|
88
89
|
asChild: !0,
|
|
89
90
|
className: "w-full",
|
|
@@ -93,9 +94,9 @@ const X = (t) => /* @__PURE__ */ e("div", { className: "flex w-full flex-col gap
|
|
|
93
94
|
),
|
|
94
95
|
h && h(o),
|
|
95
96
|
!h && /* @__PURE__ */ e(
|
|
96
|
-
|
|
97
|
+
B,
|
|
97
98
|
{
|
|
98
|
-
type:
|
|
99
|
+
type: m,
|
|
99
100
|
search: u,
|
|
100
101
|
value: S,
|
|
101
102
|
options: x,
|
|
@@ -113,7 +114,7 @@ const X = (t) => /* @__PURE__ */ e("div", { className: "flex w-full flex-col gap
|
|
|
113
114
|
]
|
|
114
115
|
}
|
|
115
116
|
) }),
|
|
116
|
-
!r && a && !
|
|
117
|
+
!r && a && !d && /* @__PURE__ */ e(
|
|
117
118
|
"div",
|
|
118
119
|
{
|
|
119
120
|
"data-slot": "command-footer-wrapper",
|
|
@@ -137,6 +138,6 @@ const X = (t) => /* @__PURE__ */ e("div", { className: "flex w-full flex-col gap
|
|
|
137
138
|
);
|
|
138
139
|
};
|
|
139
140
|
export {
|
|
140
|
-
|
|
141
|
+
ie as ComboboxRenderContent
|
|
141
142
|
};
|
|
142
143
|
//# sourceMappingURL=ComboboxRenderContent.js.map
|