import { type Accessor } from "solid-js"; import type { BaseUIChangeEventDetails, REASONS } from "../internals/change-event-details.js"; import type { FloatingRootStore } from "../internals/floating-ui/components/floating-root-store.js"; import type { UseInteractionsReturn } from "../internals/floating-ui/hooks/use-interactions.js"; import type { MutableRef } from "../internals/floating-ui/types.js"; import type { InteractionType } from "../internals/popups/use-open-interaction-type.js"; import type { TransitionStatus } from "../internals/use-transition-status/use-transition-status.js"; import type { ItemsInput } from "./utils/resolve-value-label.js"; /** * Selection guard mirroring React's `selectionRef`. React uses it to gate * an accidental mousedown-drag-commit on items: after a mousedown on the * trigger, an unselected item's mouseup is blocked for 200ms, and a * currently-selected item's mouseup is blocked for 400ms. */ export interface SelectSelectionGuard { allowSelectedMouseUp: boolean; allowUnselectedMouseUp: boolean; } /** * Change-reason union for `Select.Root`. Mirrors Base UI React 1:1 — * every reason emitted from `setOpen` / `setValue` in the ported paths. */ export type SelectRootChangeEventReason = typeof REASONS.triggerPress | typeof REASONS.outsidePress | typeof REASONS.escapeKey | typeof REASONS.windowResize | typeof REASONS.itemPress | typeof REASONS.focusOut | typeof REASONS.listNavigation | typeof REASONS.cancelOpen | typeof REASONS.none; export type SelectRootChangeEventDetails = BaseUIChangeEventDetails; export type SelectValue = unknown; /** * Shared state / handles surfaced through the Select root context. Every * reactive field is exposed as an `Accessor` so consumers don't need to * wrap reads in `untrack` / `createMemo`. */ export interface SelectRootContextValue { /** Reactive open state. */ open: Accessor; /** Whether the popup subtree is currently mounted (open OR animating out). */ mounted: Accessor; /** Enter/exit transition phase, or undefined when settled. */ transitionStatus: Accessor; /** Whether the open popup should trap focus + scroll-lock + backdrop-cutout. */ modal: Accessor; /** Whether the select allows multiple values. */ multiple: Accessor; /** Whether the select is disabled (field or own prop). */ disabled: Accessor; /** Whether the select is read-only. */ readOnly: Accessor; /** Whether the select requires a value for submission. */ required: Accessor; /** Field name (own `name` or inherited from ``). */ name: Accessor; /** Autogenerated or explicit root id. */ id: Accessor; /** Field-level label id (wired via LabelableProvider). */ labelId: Accessor; setLabelId: (id: string | undefined) => void; /** The current selection value — scalar or array-of-values for `multiple`. */ value: Accessor; /** The highlighted item index (used for listbox navigation). */ activeIndex: Accessor; setActiveIndex: (index: number | null) => void; /** The currently-selected item index (distinct from activeIndex). */ selectedIndex: Accessor; setSelectedIndex: (index: number | null) => void; /** Whether mouse hovers highlight list items. */ highlightItemOnHover: Accessor; /** Custom value comparer (defaults to `Object.is`). */ isItemEqualToValue: Accessor<(a: SelectValue, b: SelectValue) => boolean>; /** Trigger-to-label formatter for object values. */ itemToStringLabel: Accessor<((value: SelectValue) => string) | undefined>; /** Trigger-to-form-value formatter for object values. */ itemToStringValue: Accessor<((value: SelectValue) => string) | undefined>; /** Optional items registry for trigger label resolution / group support. */ items: Accessor>; /** * Imperative setOpen. Respects `details.cancel()` for uncontrolled open. */ setOpen: (next: boolean, details: SelectRootChangeEventDetails) => void; /** * Imperative setValue. Respects `details.cancel()` and forwards * `onValueChange` before the internal write. */ setValue: (next: SelectValue, details: SelectRootChangeEventDetails) => void; /** Floating-UI root context for interaction hooks and positioning. */ floatingRootContext: FloatingRootStore; /** Interaction prop-getter bundle (click + dismiss + listnav + typeahead). */ interactions: UseInteractionsReturn; /** Trigger element slot (positioner reads this for anchor). */ triggerElement: Accessor; setTriggerElement: (element: HTMLElement | null) => void; /** Popup element ref (filled by ``). */ popupRef: MutableRef; /** List element ref — set by `` when used. */ listElement: Accessor; setListElement: (element: HTMLElement | null) => void; /** Value element ref (trigger's ``). */ valueRef: MutableRef; /** The text ref of the selected item (used for popup alignment math). */ selectedItemTextRef: MutableRef; /** Parallel listRef + labelsRef + valuesRef used by listnav / typeahead / equality. */ listRef: MutableRef>; labelsRef: MutableRef>; valuesRef: MutableRef>; /** Whether typeahead is currently active (suppresses space → click). */ typingRef: MutableRef; /** Consumer callback — called after open/close transitions settle. */ onOpenChangeComplete?: ((open: boolean) => void) | undefined; /** Read by positioner's composite-list reconciliation. */ initialValueRef: MutableRef; /** * Interaction type that opened the popup (`'mouse' | 'keyboard' | 'touch' | * 'pen' | ''`) — used by popup geometry and scroll arrows to differentiate * touch opens from pointer/keyboard opens. `null` while closed. */ openMethod: Accessor; /** Whether the popup's up-scroll arrow should render (trigger-aligned only). */ scrollUpArrowVisible: Accessor; setScrollUpArrowVisible: (next: boolean) => void; /** Whether the popup's down-scroll arrow should render (trigger-aligned only). */ scrollDownArrowVisible: Accessor; setScrollDownArrowVisible: (next: boolean) => void; /** Count of mounted scroll arrows. When any arrow is mounted we skip the * bottom popup/list padding used by React's `scroll-arrow` layout. */ scrollArrowsMountedCountRef: MutableRef; /** * Imperative "recompute scroll arrow visibility now" — filled by the * popup when its geometry effect binds; called from items / positioner / * scroll arrows. Always safe to invoke; delegates through an internal * ref so the popup can swap its callback. */ handleScrollArrowVisibility: () => void; /** * Backing ref for {@link handleScrollArrowVisibility}. The popup writes * its geometry callback here during ``'s setup phase. */ handleScrollArrowVisibilityRef: MutableRef<() => void>; /** * Live callback-invoked variant of the popup's scroll handler — * overwritten by the popup's trigger-aligned geometry effect when the * popup measures initial placement. A no-op otherwise. */ scrollHandlerRef: MutableRef<(scroller: HTMLElement) => void>; /** Tracks whether the most recent interaction was keyboard-driven. */ keyboardActiveRef: MutableRef; /** Selection-window guard — see {@link SelectSelectionGuard}. */ selectionRef: MutableRef; } export declare const SelectRootContext: import("solid-js").Context; export declare function useSelectRootContext(): SelectRootContextValue; export declare function useSelectRootContext(optional: true): SelectRootContextValue | null; //# sourceMappingURL=select-root-context.d.ts.map