import * as React from 'react'; /** Enabled options selector, duplicated rather than imported across Combobox/Listbox/Transfer since each component folder is its own bundle. */ export declare const OPTION_SELECTOR = "[role=\"option\"]:not([data-disabled])"; /** @internal What one registered option contributes to a {@link useOptionCollection} collection. */ export interface OptionEntry { /** Identifier committed to the owning root's value when this option is chosen. */ value: string; /** The option's `textValue`, or its rendered text — matched by `filter` and written back into the input. */ text: string; } /** @internal Parameters for {@link useOptionCollection}. */ export interface UseOptionCollectionOptions { /** Whether the popup listing the options is currently open. */ open: boolean; /** Opens/closes that popup — used by {@link OptionCollection.openWithHighlight}. */ setOpen: (open: boolean) => void; /** The popup element the options are rendered inside; read directly for highlight moves. */ contentRef: React.RefObject; /** * Whether {@link OptionCollection.moveActive} wraps around the ends of the list instead of clamping at them. * @default false */ loop?: boolean | undefined; /** * Scores a registered entry for ranking: return a number to rank it, `null` to leave it unscored, or omit entirely for a family with no ranking filter. * @default undefined — no ranking. */ scoreItem?: ((entry: OptionEntry) => number | null) | undefined; } /** @internal What {@link useOptionCollection} hands back to a root's context. */ export interface OptionCollection { /** Element id of the virtually-focused option, mirrored into the input's `aria-activedescendant`. */ activeId: string | null; /** Rank (`0` = first) each currently-visible option traverses and renders in when `scoreItem` also scores it, descending by score; `null` when nothing scored numerically. */ itemOrder: ReadonlyMap | null; /** Moves the virtual focus, or clears it with `null`. */ setActiveId: (id: string | null) => void; /** How many options are currently registered (i.e. rendered and surviving the filter). */ itemCount: number; /** Adds an option to the collection under its element id. */ registerItem: (id: string, entry: OptionEntry) => void; /** Removes an option from the collection. */ unregisterItem: (id: string) => void; /** The registered entry behind an option id, for committing the virtually-focused option. */ getItem: (id: string) => OptionEntry | undefined; /** Opens the popup and, once its options are mounted, highlights the first (or last) one. */ openWithHighlight: (edge: 'first' | 'last') => void; /** * Moves the highlight one option forward (`1`) or back (`-1`), wrapping around the ends when `loop` is set, clamped otherwise, and scrolls it into view. * @returns the element id now highlighted, or `null` when there was nothing to move to. */ moveActive: (direction: 1 | -1) => string | null; /** * Moves the highlight to the first or last option and scrolls it into view, for Home/End while the popup is open. * @returns the element id now highlighted, or `null` when the list is empty. */ moveActiveToEdge: (edge: 'first' | 'last') => string | null; } export declare function useOptionCollection({ open, setOpen, contentRef, loop, scoreItem, }: UseOptionCollectionOptions): OptionCollection; /** @internal Parameters for {@link useOptionEntry}. */ export interface UseOptionEntryOptions { /** This option's element id — the value the input's `aria-activedescendant` carries while it is highlighted. */ id: string; /** The value committed to the root when this option is chosen. */ value: string; /** Explicit text for matching, when the option renders more than its label. */ textValue: string | undefined; /** The element rendering this option, measured for its text when `textValue` is absent. */ itemRef: React.RefObject; /** Whether an option with this text survives the root's current filter and draft text. */ matchesFilter: (text: string) => boolean; /** The root's collection registration, from {@link useOptionCollection}. */ registerItem: (id: string, entry: OptionEntry) => void; /** The root's collection de-registration, from {@link useOptionCollection}. */ unregisterItem: (id: string) => void; } /** * @internal The measure-then-filter-then-register cycle every `*Item` part runs; an unmeasured option always renders, and a rejected one renders nothing at all rather than hiding, since a hidden option would still be reachable via `aria-activedescendant`. * @returns The option's measured text (or `null` before the first measurement) and whether it should render. */ export declare function useOptionEntry({ id, value, textValue, itemRef, matchesFilter, registerItem, unregisterItem, }: UseOptionEntryOptions): { text: string | null; visible: boolean; };