import { CollectionItem, ListCollection, GridCollection, SelectionMode, Selection } from '@zag-js/collection'; import { Machine, EventObject, Service } from '@zag-js/core'; import { TypeaheadState } from '@zag-js/dom-query'; import { PropTypes, RequiredBy, DirectionProperty, CommonProperties } from '@zag-js/types'; interface ValueChangeDetails { value: string[]; items: T[]; } interface HighlightChangeDetails { highlightedValue: string | null; highlightedItem: T | null; highlightedIndex: number; } interface ScrollToIndexDetails { index: number; immediate?: boolean | undefined; getElement: () => HTMLElement | null; } interface SelectionDetails { value: string; } type ElementIds = Partial<{ root: string; content: string; label: string; item: (id: string | number) => string; itemGroup: (id: string | number) => string; itemGroupLabel: (id: string | number) => string; }>; interface ListboxProps extends DirectionProperty, CommonProperties { /** * The orientation of the listbox. * @default "vertical" */ orientation?: "horizontal" | "vertical" | undefined; /** * The item collection */ collection: ListCollection | GridCollection; /** * The ids of the elements in the listbox. Useful for composition. */ ids?: ElementIds | undefined; /** * Whether the listbox is disabled */ disabled?: boolean | undefined; /** * Whether to disallow selecting all items when `meta+a` is pressed */ disallowSelectAll?: boolean | undefined; /** * The callback fired when the highlighted item changes. */ onHighlightChange?: ((details: HighlightChangeDetails) => void) | undefined; /** * The callback fired when the selected item changes. */ onValueChange?: ((details: ValueChangeDetails) => void) | undefined; /** * The controlled keys of the selected items */ value?: string[] | undefined; /** * The initial default value of the listbox when rendered. * Use when you don't need to control the value of the listbox. * * @default [] */ defaultValue?: string[] | undefined; /** * The controlled key of the highlighted item */ highlightedValue?: string | null | undefined; /** * The initial value of the highlighted item when opened. * Use when you don't need to control the highlighted value of the listbox. */ defaultHighlightedValue?: string | null | undefined; /** * Whether to loop the keyboard navigation through the options * @default false */ loopFocus?: boolean | undefined; /** * How multiple selection should behave in the listbox. * * - `single`: The user can select a single item. * - `multiple`: The user can select multiple items without using modifier keys. * - `extended`: The user can select multiple items by using modifier keys. * * @default "single" */ selectionMode?: SelectionMode | undefined; /** * Function to scroll to a specific index */ scrollToIndexFn?: ((details: ScrollToIndexDetails) => void) | undefined; /** * Whether to select the item when it is highlighted */ selectOnHighlight?: boolean | undefined; /** * Whether to disallow empty selection */ deselectable?: boolean | undefined; /** * Whether to enable typeahead on the listbox */ typeahead?: boolean | undefined; /** * Function called when an item is selected */ onSelect?: ((details: SelectionDetails) => void) | undefined; } type PropsWithDefault = "collection" | "selectionMode"; interface ListboxSchema { state: "idle"; props: RequiredBy, PropsWithDefault>; context: { value: string[]; highlightedValue: string | null; highlightedItem: T | null; selectedItemMap: Map; focused: boolean; }; computed: { hasSelectedItems: boolean; isTypingAhead: boolean; isInteractive: boolean; selection: Selection; multiple: boolean; selectedItems: T[]; valueAsString: string; }; refs: { typeahead: TypeaheadState; focusVisible: boolean; inputState: { autoHighlight: boolean; focused: boolean; }; }; action: string; guard: string; effect: string; event: EventObject; } type ListboxService = Service>; type ListboxMachine = Machine>; interface ItemProps { /** * The item to render */ item: T; /** * Whether to highlight the item on hover */ highlightOnHover?: boolean | undefined; } interface ItemState { /** * The underlying value of the item */ value: string; /** * Whether the item is disabled */ disabled: boolean; /** * Whether the item is selected */ selected: boolean; /** * Whether the item is highlighted * @deprecated Use `focused` and `focusVisible` instead */ highlighted: boolean; /** * Whether the item is focused */ focused: boolean; /** * Whether the item is focus visible */ focusVisible: boolean; } interface ItemGroupProps { id: string; } interface ItemGroupLabelProps { htmlFor: string; } interface InputProps { /** * Whether to automatically highlight the item when typing * @default false */ autoHighlight?: boolean | undefined; /** * Determines how keyboard conflicts in the input are resolved. * - "caret": keep native text-editing behavior * - "navigate": forward supported keys to listbox navigation * @default "caret" */ keyboardPriority?: "caret" | "navigate" | undefined; } interface ListboxApi { /** * Whether the select value is empty */ empty: boolean; /** * The value of the highlighted item */ highlightedValue: string | null; /** * The highlighted item */ highlightedItem: V | null; /** * Function to highlight a value */ highlightValue: (value: string) => void; /** * Function to highlight the first value */ highlightFirst: VoidFunction; /** * Function to highlight the last value */ highlightLast: VoidFunction; /** * Function to highlight the next value */ highlightNext: VoidFunction; /** * Function to highlight the previous value */ highlightPrevious: VoidFunction; /** * Function to clear the highlighted value */ clearHighlightedValue: VoidFunction; /** * The selected items */ selectedItems: V[]; /** * Whether there's a selected option */ hasSelectedItems: boolean; /** * The selected item keys */ value: string[]; /** * The string representation of the selected items */ valueAsString: string; /** * Function to select a value */ selectValue: (value: string) => void; /** * Function to select all values. * * **Note**: This should only be called when the selectionMode is `multiple` or `extended`. * Otherwise, an exception will be thrown. */ selectAll: VoidFunction; /** * Function to set the value of the select */ setValue: (value: string[]) => void; /** * Function to clear the value of the select. * If a value is provided, it will only clear that value, otherwise, it will clear all values. */ clearValue: (value?: string) => void; /** * Returns the state of a select item */ getItemState: (props: ItemProps) => ItemState; /** * Function to toggle the select */ collection: ListCollection; /** * Whether the select is disabled */ disabled: boolean; getInputProps: (props?: InputProps) => T["input"]; getRootProps: () => T["element"]; getLabelProps: () => T["label"]; getValueTextProps: () => T["element"]; getContentProps: () => T["element"]; getItemProps: (props: ItemProps) => T["element"]; getItemTextProps: (props: ItemProps) => T["element"]; getItemIndicatorProps: (props: ItemProps) => T["element"]; getItemGroupProps: (props: ItemGroupProps) => T["element"]; getItemGroupLabelProps: (props: ItemGroupLabelProps) => T["element"]; } export type { ElementIds, HighlightChangeDetails, InputProps, ItemGroupLabelProps, ItemGroupProps, ItemProps, ItemState, ListboxApi, ListboxMachine, ListboxProps, ListboxSchema, ListboxService, ScrollToIndexDetails, SelectionDetails, ValueChangeDetails };