UNPKG

@kobalte/core

Version:

Unstyled components and primitives for building accessible web apps and design systems with SolidJS.

177 lines (170 loc) 5.95 kB
import { ComboboxContent, ComboboxControl, ComboboxHiddenSelect, ComboboxIcon, ComboboxInput, ComboboxListbox, ComboboxPortal, ComboboxBase } from '../chunk/DYCE77BF.js'; export { ComboboxContent as Content, ComboboxControl as Control, ComboboxHiddenSelect as HiddenSelect, ComboboxIcon as Icon, ComboboxInput as Input, ComboboxListbox as Listbox, ComboboxPortal as Portal } from '../chunk/DYCE77BF.js'; import { ListboxItem, ListboxItemDescription, ListboxItemLabel, ListboxSection } from '../chunk/MJSKFKQK.js'; export { ListboxItem as Item, ListboxItemDescription as ItemDescription, ListboxItemLabel as ItemLabel, ListboxSection as Section } from '../chunk/MJSKFKQK.js'; import { PopperArrow } from '../chunk/LMWVDFW6.js'; export { PopperArrow as Arrow } from '../chunk/LMWVDFW6.js'; import { FormControlLabel } from '../chunk/7ZHN3PYD.js'; export { FormControlLabel as Label } from '../chunk/7ZHN3PYD.js'; import { FormControlDescription } from '../chunk/YKGT7A57.js'; export { FormControlDescription as Description } from '../chunk/YKGT7A57.js'; import { Polymorphic } from '../chunk/6Y7B2NEO.js'; import { createComponent, mergeProps } from 'solid-js/web'; import { createContext, useContext, splitProps, Show, createSignal, createEffect, createMemo } from 'solid-js'; var SearchContext = createContext(); function useSearchContext() { const context = useContext(SearchContext); if (context === void 0) { throw new Error("[kobalte]: `useSearchContext` must be used within a `Search` component"); } return context; } // src/search/search-indicator.tsx function SearchIndicator(props) { const [local, other] = splitProps(props, ["loadingComponent"]); const context = useSearchContext(); return createComponent(Polymorphic, mergeProps({ as: "span", "aria-hidden": "true" }, other, { get children() { return createComponent(Show, { get when() { return context.isLoadingSuggestions() === false || !local.loadingComponent; }, get fallback() { return local.loadingComponent; }, get children() { return props.children; } }); } })); } function SearchNoResult(props) { const context = useSearchContext(); return createComponent(Show, { get when() { return context.noResult(); }, get children() { return createComponent(Polymorphic, mergeProps({ as: "div" }, props)); } }); } // src/search/utils.ts var DebouncerTimeout = () => { let _debounceMillisecond = 0; let lastCallbackTime = 0; let timeout; return { debounce: (callback) => { if (lastCallbackTime > Date.now() - _debounceMillisecond) clearTimeout(timeout); timeout = setTimeout(callback, _debounceMillisecond); lastCallbackTime = Date.now(); return timeout; }, setDebounceMillisecond: (debounceMillisecond = 0) => { _debounceMillisecond = debounceMillisecond; } }; }; // src/search/search-root.tsx function SearchRoot(props) { const [local, omit, others] = splitProps( props, ["options", "value", "defaultValue", "onChange", "multiple", "onInputChange", "debounceOptionsMillisecond"], // @ts-expect-error filter is handled externally, so it's omitted ["defaultFilter"] ); const [isLoadingSuggestions, setIsLoadingSuggestions] = createSignal(false); const [suggestionTimeout, setSuggestionTimeout] = createSignal(); const inputChangeDebouncer = DebouncerTimeout(); createEffect(() => inputChangeDebouncer.setDebounceMillisecond(local.debounceOptionsMillisecond)); const onInputChange = (value2) => { if (local.onInputChange === void 0) return; setIsLoadingSuggestions(true); const timeout = inputChangeDebouncer.debounce(async () => { await local.onInputChange(value2); setIsLoadingSuggestions(false); }); setSuggestionTimeout(timeout); }; const value = createMemo(() => { if (local.value != null) { return local.multiple ? local.value : [local.value]; } return local.value; }); const defaultValue = createMemo(() => { if (local.defaultValue != null) { return local.multiple ? local.defaultValue : [local.defaultValue]; } return local.defaultValue; }); const onChange = (value2) => { clearTimeout(suggestionTimeout()); setIsLoadingSuggestions(false); if (local.multiple) { local.onChange?.(value2 ?? []); } else { local.onChange?.(value2[0] ?? null); } }; const noResult = () => local.options.length === 0; const context = { noResult, isLoadingSuggestions }; return createComponent(SearchContext.Provider, { value: context, get children() { return createComponent(ComboboxBase, mergeProps({ closeOnSelection: true, shouldFocusWrap: true, noResetInputOnBlur: true, allowsEmptyCollection: true, get options() { return local.options; }, get value() { return value(); }, get defaultValue() { return defaultValue(); }, onInputChange, defaultFilter: () => true, onChange, get selectionMode() { return local.multiple ? "multiple" : "single"; } }, others)); } }); } // src/search/index.tsx var Search = Object.assign(SearchRoot, { Arrow: PopperArrow, Content: ComboboxContent, Control: ComboboxControl, Description: FormControlDescription, HiddenSelect: ComboboxHiddenSelect, Icon: ComboboxIcon, Input: ComboboxInput, Item: ListboxItem, ItemDescription: ListboxItemDescription, ItemLabel: ListboxItemLabel, Label: FormControlLabel, Listbox: ComboboxListbox, Portal: ComboboxPortal, Section: ListboxSection, NoResult: SearchNoResult, Indicator: SearchIndicator }); export { SearchIndicator as Indicator, SearchNoResult as NoResult, SearchRoot as Root, Search, useSearchContext };