import { UseComboboxProps as UseDownshiftComboboxProps, UseMultipleSelectionProps as UseDownshiftMultipleSelectionProps, UseComboboxReturnValue as UseDownshiftComboboxReturnValue, UseComboboxState as UseDownshiftComboboxState, UseMultipleSelectionState as UseDownshiftMultipleSelectionState, UseSelectProps as UseDownshiftSelectProps, UseSelectReturnValue as UseDownshiftSelectReturnValue, UseSelectState as UseDownshiftSelectState, UseMultipleSelectionReturnValue as UseDownshiftMultipleSelectionReturnValue } from 'downshift'; import { DataTrackingId, DistributiveOmit, LayoutUtilProps } from '../../types'; import { CSSProperties, ComponentPropsWithoutRef, Dispatch, MutableRefObject, ReactNode, SetStateAction } from 'react'; import { ComboboxGroupByValue } from './internal/ComboboxGroupContext'; import { MatchSorterOptions } from 'match-sorter'; import { ComboboxContentOptionsProps } from './ComboboxContent'; import { LabelProps } from '../../internal/components/Label/Label'; import { ChipProps } from '../Chip'; import { IconProps } from '../Icon'; import { AvatarProps } from '../Avatar'; import { FlexProps } from '../Flex'; import { TextFieldProps } from '../TextField/internal/TextField'; /** * Props for the useInfiniteCombobox hook */ export type UseInfiniteComboboxProps = { /** Function to fetch items for the current page */ query: (params: { page: number; inputValue: string; selectedItem: Item | null; selectedItems: Item[]; }) => Promise; /** Initial page number to start from */ initialPage?: number; /** Initial loading state */ initialLoading?: boolean; /** Initial input value */ initialInputValue?: ComboboxProps["initialInputValue"]; /** Default input value */ defaultInputValue?: ComboboxProps["defaultInputValue"]; /** Initial selected item */ initialSelectedItem?: ComboboxProps["initialSelectedItem"]; /** Default selected item */ defaultSelectedItem?: ComboboxProps["defaultSelectedItem"]; /** Initial selected items for multiple selection */ initialSelectedItems?: UseDownshiftMultipleSelectionProps["initialSelectedItems"]; /** Default selected items for multiple selection */ defaultSelectedItems?: UseDownshiftMultipleSelectionProps["defaultSelectedItems"]; /** Whether to trigger query on input value change */ updateOnInputValueChange?: boolean; /** Whether to trigger query on selected item change */ updateOnSelectedItemChange?: boolean; /** Whether to trigger query on selected items change */ updateOnSelectedItemsChange?: boolean; /** Whether to trigger query on first render */ queryOnFirstRender?: boolean; /** Custom function to determine when to trigger query */ shouldTriggerQuery?: (element: EventTarget & HTMLElement) => boolean; } & ({ queryInitialItems?: never; /** Initial items array (mutually exclusive with queryInitialItems) */ initialItems?: Item[]; } | { /** Function to get initial items (mutually exclusive with initialItems) */ queryInitialItems?: () => Item[]; initialItems?: never; }); /** * Props for the ComboboxContext component * @extends Required | UseDownshiftSelectProps, "items" | "itemToString" | "itemToKey" | "selectedItem">> * @extends Pick | UseDownshiftSelectReturnValue, "getToggleButtonProps" | "getItemProps" | "getLabelProps" | "getMenuProps" | "closeMenu" | "selectItem" | "highlightedIndex" | "isOpen" | "inputValue"> * @extends Partial, "getInputProps">> * @extends Partial, "getSelectedItemProps" | "getDropdownProps" | "addSelectedItem" | "removeSelectedItem" | "setSelectedItems" | "reset">> * @extends Partial | UseDownshiftSelectReturnValue, "reset">> * @extends LayoutUtilProps */ export type ComboboxContextProps = Required | UseDownshiftSelectProps, "items" | "itemToString" | "itemToKey" | "selectedItem">> & Pick | UseDownshiftSelectReturnValue, "getToggleButtonProps" | "getItemProps" | "getLabelProps" | "getMenuProps" | "closeMenu" | "selectItem" | "highlightedIndex" | "isOpen" | "inputValue"> & Partial, "getInputProps">> & Partial, "getSelectedItemProps" | "getDropdownProps" | "addSelectedItem" | "removeSelectedItem" | "setSelectedItems" | "reset">> & Partial | UseDownshiftSelectReturnValue, "reset">> & LayoutUtilProps & { disableClearSelection?: boolean; isReadOnly?: boolean; isDisabled?: boolean; /** @deprecated to be removed on next major - this is replaced by Combobox's disabled and readOnly props */ setIsReadOnly: Dispatch>; /** @deprecated to be removed on next major - this is replaced by Combobox's disabled and readOnly props */ setIsDisabled: Dispatch>; hasDisabledPopover: boolean; setHasDisabledPopover: Dispatch>; hasEmpty: boolean; setHasEmpty: Dispatch>; multiple: boolean; select: boolean; selectedItems: Item[]; disabledItems: Item[]; setDisabledItems: Dispatch>; setForceCloseOnSelectItems: Dispatch>; setForceClearInputValueOnSelectItems: Dispatch>; loading: boolean; referenceRef: MutableRefObject; contentRef: MutableRefObject; listRef: MutableRefObject; hasAddNew?: boolean; setHasAddNew?: Dispatch>; onSelectItemAddNew?: (inputValue: UseDownshiftComboboxReturnValue["inputValue"]) => void; setOnSelectItemAddNew?: Dispatch["inputValue"]) => void) | undefined>>; hasExactMatch?: boolean; setHasExactMatch?: Dispatch>; groupBy?: string; groupToString?: (groupByValue: ComboboxGroupByValue) => string | null; groups: { key: ComboboxGroupByValue; label: string | null; items: Item[]; }[]; selectAll?: SelectAllConfig; }; /** * Props for shared functionality across all combobox variants * @extends LayoutUtilProps * @extends Pick, "className" | "style"> */ type SharedProps = LayoutUtilProps & Pick, "className" | "style"> & { children?: ReactNode; /** * @default false */ disabled?: boolean; /** * @default false */ readOnly?: boolean; /** * @default false */ loading?: boolean; /** * @default false */ disableCloseOnClickOutside?: boolean; /** * @default false */ disableMatchReferenceWidth?: boolean; /** * @deprecated to be removed on next major * This is not needed anymore as the Popover API is used. * Popover API uses top-layer for its popover content. */ root?: HTMLElement | React.MutableRefObject | null; /** * @default false */ open?: boolean; /** * @default false */ disableCloseOnSelectItem?: boolean; onStateChange?: (changes: { type: string; } & Partial> & Partial> & Partial>) => void; minPopoverHeight?: string | number; groupBy?: string; groupToString?: (groupByValue: ComboboxGroupByValue) => string | null; /** Accepts groupBy values `a` and `b` -- must return a negative if `a` before `b` and a positive if `b` before `a`. * @default {func} (a, b) => `${a}`.localeCompare(`${b}`) */ groupSorter?: (a: ComboboxGroupByValue, b: ComboboxGroupByValue) => number; }; /** * Props for combobox-specific functionality * @extends Omit, "onStateChange" | "onInputValueChange"> */ type SharedComboboxProps = Omit, "onStateChange" | "onInputValueChange"> & { filterOptions?: MatchSorterOptions; disableFilter?: boolean; /** * @deprecated Please use `Combobox.SearchField`'s `onChange` method instead */ onInputValueChange?: UseDownshiftComboboxProps["onInputValueChange"]; }; /** * Props for select-specific functionality * @extends Omit, "onStateChange" | "onInputValueChange"> */ type SharedSelectProps = Omit, "onStateChange" | "onInputValueChange">; /** * Props for single selection functionality */ type SharedSingleProps = { multiple?: never; onChange?: Dispatch> | ((arg: Item | null) => void); }; export type SelectAllConfig = { label?: string; onSelection: () => void; isChecked: boolean; }; /** * Props for multiple selection functionality * @extends Partial, "onSelectedItemsChange" | "initialSelectedItems" | "initialActiveIndex" | "defaultSelectedItems" | "defaultActiveIndex" | "activeIndex" | "selectedItems">> */ type SharedMultipleProps = { selectAll?: SelectAllConfig; multiple: true; onChange?: Dispatch> | ((arg: Item[] | null) => void); } & Partial, "onSelectedItemsChange" | "initialSelectedItems" | "initialActiveIndex" | "defaultSelectedItems" | "defaultActiveIndex" | "activeIndex" | "selectedItems">>; /** * Props for single select functionality * @extends SharedProps * @extends SharedSelectProps * @extends SharedSingleProps */ export type SelectSingleProps = SharedProps & SharedSelectProps & SharedSingleProps & { disableClearSelection?: boolean; }; /** * Props for multiple select functionality * @extends SharedProps * @extends SharedSelectProps * @extends SharedMultipleProps */ export type SelectMultipleProps = SharedProps & SharedSelectProps & SharedMultipleProps; /** * Props for single combobox functionality * @extends SharedProps * @extends SharedComboboxProps * @extends SharedSingleProps */ export type ComboboxSingleProps = SharedProps & SharedComboboxProps & SharedSingleProps; /** * Props for multiple combobox functionality * @extends Omit, "open" | "disableCloseOnSelectItem"> * @extends SharedComboboxProps * @extends SharedMultipleProps */ export type ComboboxMultipleProps = Omit, "open" | "disableCloseOnSelectItem"> & SharedComboboxProps & SharedMultipleProps & ({ disableClearInputValueOnSelectItem: true; disableCloseOnSelectItem: true; open?: boolean; } | { disableClearInputValueOnSelectItem: true; open: true; disableCloseOnSelectItem?: boolean; } | { disableClearInputValueOnSelectItem?: never; disableCloseOnSelectItem?: boolean; open?: boolean; }); /** * Props for the Combobox component * @property {Item[]} items - Array of items to display in the combobox * @property {(item: Item | null) => string} itemToString - Function to convert item to string * @property {(item: Item) => string | number} itemToKey - Function to get unique key for item * @property {Item | null} [selectedItem] - Currently selected item * @property {Item[] | null} [selectedItems] - Currently selected items for multiple selection * @property {boolean} [multiple] - Enable multiple selection mode * @property {boolean} [loading] - Show loading state * @property {Object} [filterOptions] - Options for filtering items * @property {boolean} [disableFilter] - Disable automatic filtering * @property {string} [groupBy] - Property to group items by * @property {(groupValue: any) => string | null} [groupToString] - Function to convert group value to string * @property {(a: any, b: any) => number} [groupSorter] - Function to sort groups * @extends DataTrackingId */ export type ComboboxProps = ComboboxSingleProps | ComboboxMultipleProps; type SelectProps = SelectSingleProps | SelectMultipleProps; /** * Props for the ComboboxSelect component * @property {Item[]} items - Array of items to display in the select * @property {(item: Item | null) => string} itemToString - Function to convert item to string * @property {(item: Item) => string | number} itemToKey - Function to get unique key for item * @property {Item | null} [selectedItem] - Currently selected item * @property {Item[] | null} [selectedItems] - Currently selected items for multiple selection * @property {boolean} [multiple] - Enable multiple selection mode * @property {boolean} [loading] - Show loading state * @property {string} [groupBy] - Property to group items by * @property {(groupValue: any) => string | null} [groupToString] - Function to convert group value to string * @extends DataTrackingId */ export type ComboboxSelectProps = SelectProps; /** * Props for the ComboboxContent component * @property {({ items: Item[], inputValue: string }) => ReactNode} children - Function that receives items and input value and renders content * @property {boolean} [disablePopover] - Whether to disable popover behavior and render inline */ export type ComboboxContentProps = Omit, "children"> & { /** Render function that receives combobox state and returns content */ children?: ({ items, inputValue, selectedItem, getMenuProps, getItemProps, }: Pick | UseDownshiftSelectProps, "items"> & Pick | UseDownshiftSelectReturnValue, "getMenuProps" | "getItemProps" | "inputValue" | "selectedItem"> & { listProps: ReturnType["getMenuProps"] | UseDownshiftSelectReturnValue["getMenuProps"]> & { style: CSSProperties; }; options: ComboboxContentOptionsProps[]; }) => ReactNode; /** Whether to disable popover behavior and render inline */ disablePopover?: boolean; }; /** * Props for the ComboboxTrigger component * @template Item - The type of items in the combobox */ export type ComboboxTriggerProps = Omit & Pick & LayoutUtilProps & { /** * Should be a positive integer. */ maxRows?: number; /** Allows Combobox/Select to display custom-colored Chips */ selectedItemProps?: (item: Item) => Partial; /** * Called when the clear (close) button is clicked. * @remarks This prop completely replaces the default clear behavior (reset/selectItem). * Only use this when you need complete control over the combobox state, such as in * FilterSelect components where the implementor manages all item filtering and selection. * This should only be used with the disableFilter prop. */ onClear?: () => void; } & { /** @deprecated use disabled in */ disabled?: boolean; /** @deprecated use readOnly in */ readOnly?: boolean; }; /** * Props for the ComboboxSearchField component * @property {string} label - Label for the search field * @property {string} [placeholder] - Placeholder text * @property {string} [description] - Helper text description * @property {string} [moreInfo] - Additional information text * @property {boolean} [required] - Mark field as required * @property {string | { icon: IconProps } | { avatar: AvatarProps }} [prefix] - Prefix content (string, icon, or avatar) * @property {(item: Item) => Partial} [selectedItemProps] - Allows Combobox to display custom-colored Chips * @extends DataTrackingId */ export type ComboboxSearchFieldProps = DistributiveOmit & DataTrackingId & { prefix?: string | { icon: DistributiveOmit; } | { avatar: DistributiveOmit; }; }; /** * Props for the ComboboxSelectTrigger component * @property {string} label - Label for the select trigger * @property {string} [placeholder] - Placeholder text * @property {string} [description] - Helper text description * @property {string} [moreInfo] - Additional information text * @property {boolean} [required] - Mark field as required * @property {string | { icon: IconProps } | { avatar: AvatarProps }} [prefix] - Prefix content (string, icon, or avatar) * @property {(item: Item) => Partial} [selectedItemProps] - Allows Combobox to display custom-colored Chips * @extends DataTrackingId */ export type ComboboxSelectTriggerProps = DistributiveOmit & DataTrackingId & { prefix?: string | { icon: DistributiveOmit; } | { avatar: DistributiveOmit; }; }; /** * Props for the ComboboxList component * @property {ReactNode} children - List items to render */ export type ComboboxListProps = ComponentPropsWithoutRef<"ul" | "div"> & { children?: ReactNode; }; type ComboboxItemSharedProps = ComponentPropsWithoutRef<"li" | "div"> & { children?: ReactNode; disabled?: boolean; alignItems?: FlexProps["alignItems"]; justifyItems?: FlexProps["justifyItems"]; alignContent?: FlexProps["alignContent"]; justifyContent?: FlexProps["justifyContent"]; placeItems?: FlexProps["placeItems"]; placeContent?: FlexProps["placeContent"]; gap?: FlexProps["gap"]; rowGap?: FlexProps["rowGap"]; columnGap?: FlexProps["columnGap"]; }; /** * Props for the ComboboxItem component * @property {Item} item - The item to render * @property {number} index - Index of the item in the list * @property {ReactNode} children - Content to render for the item * @property {boolean} [disabled] - Disable the item * @extends DataTrackingId */ export type ComboboxItemProps = ComboboxItemSharedProps & { /** The item to render */ item: Item; /** The index of the item in the list */ index: number; hideCheckbox?: boolean; forceCloseOnSelect?: boolean; forceClearInputValueOnSelect?: boolean; } & DataTrackingId; /** * Props for the ComboboxItemAddNew component * @property {(inputValue: string) => void} onSelection - Callback when "Add New" is selected * @property {ReactNode} children - Content to render for the "Add New" item * @property {boolean} [disabled] - Disable the "Add New" item * @extends DataTrackingId */ export type ComboboxItemAddNewProps = ComboboxItemSharedProps & { /** Callback when the "Add New" item is selected */ onSelection?: (inputValue: UseDownshiftComboboxReturnValue["inputValue"]) => void; } & DataTrackingId; export {};