{"version":3,"names":["createContext","createMemo","runWithOwner","untrack","useContext","readOption","SNAPSHOT_KEYS","snapshotKeys","defaultItemEquality","stringifyAsLabel","isGroupedItems","items","Array","isArray","length","first","SelectCtx","useSelect","ctx","Error","createSelect","options","isMultiple","multiple","disabled","Boolean","name","readOnly","required","itemToStringLabel","isItemEqualToValue","value","raw","open","isGrouped","its","isItemSelected","item","sv","comparer","some","v","valueLabel","map","join","setValue","next","reason","onValueChange","setOpen","onOpenChange","api","Provider","props","children","SELECT_SNAPSHOT_KEYS"],"sources":["create-select.tsx"],"sourcesContent":["import type { JSX } from \"@solidjs/web\";\nimport {\n\ttype Accessor,\n\tcreateContext,\n\tcreateMemo,\n\trunWithOwner,\n\tuntrack,\n\tuseContext,\n} from \"solid-js\";\nimport { type MaybeAccessor, readOption } from \"../internals/maybe-accessor\";\nimport {\n\tSNAPSHOT_KEYS,\n\ttype Snapshottable,\n\tsnapshotKeys,\n} from \"../internals/observability/snapshot\";\nimport { defaultItemEquality } from \"./utils/item-equality\";\n\ntype ItemEqualityComparer<A, B> = (item: A, value: B) => boolean;\n\nimport { type ItemsInput, stringifyAsLabel } from \"./utils/resolve-value-label\";\n\n/** Detect grouped items (has at least one entry with an `items` key). */\nfunction isGroupedItems(items: unknown): boolean {\n\tif (!Array.isArray(items) || items.length === 0) return false;\n\tconst first = items[0];\n\treturn (\n\t\ttypeof first === \"object\" &&\n\t\tfirst !== null &&\n\t\t\"items\" in first &&\n\t\t!(\"value\" in first)\n\t);\n}\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport type SelectChangeReason =\n\t| \"item-press\"\n\t| \"escape-key\"\n\t| \"outside-press\"\n\t| \"imperative\";\n\nimport type { SelectValue } from \"./select-root-context\";\n\nexport type { SelectValue };\n\nexport interface CreateSelectOptions<\n\tValue = SelectValue,\n\tMultiple extends boolean | undefined = false,\n> {\n\t/**\n\t * Current selected value. Consumer-owned signal. Writes happen via\n\t * `onValueChange` — the primitive does NOT keep an internal copy.\n\t * Pass an array when `multiple: true`.\n\t */\n\tvalue: MaybeAccessor<SelectValueType<Value, Multiple> | null | undefined>;\n\tonValueChange?: (\n\t\tvalue: SelectValueType<Value, Multiple> | null,\n\t\treason: SelectChangeReason,\n\t) => void;\n\n\t/** Open state. Consumer-owned signal. */\n\topen: MaybeAccessor<boolean>;\n\tonOpenChange?: (open: boolean, reason: SelectChangeReason) => void;\n\n\t/** Whether multiple items may be selected. */\n\tmultiple?: Multiple;\n\n\tdisabled?: MaybeAccessor<boolean | undefined>;\n\treadOnly?: MaybeAccessor<boolean | undefined>;\n\trequired?: MaybeAccessor<boolean | undefined>;\n\n\t/** Items registry — drives trigger label resolution for object values. */\n\titems?: MaybeAccessor<ItemsInput<Value> | undefined>;\n\t/** Formatter for object values (trigger display). */\n\titemToStringLabel?: MaybeAccessor<((value: Value) => string) | undefined>;\n\t/** Formatter for object values (form submission). */\n\titemToStringValue?: MaybeAccessor<((value: Value) => string) | undefined>;\n\t/** Custom equality comparer. Defaults to `Object.is`. */\n\tisItemEqualToValue?: MaybeAccessor<\n\t\t((itemValue: Value, value: Value) => boolean) | undefined\n\t>;\n}\n\ntype SelectValueType<\n\tValue,\n\tMultiple extends boolean | undefined,\n> = Multiple extends true ? Value[] : Value;\n\nexport interface SelectApi<\n\tValue = SelectValue,\n\tMultiple extends boolean | undefined = false,\n> {\n\t/** Reactive accessor for the current selected value. */\n\tvalue: Accessor<SelectValueType<Value, Multiple> | null>;\n\t/** Reactive accessor for the open state. */\n\topen: Accessor<boolean>;\n\n\tmultiple: boolean;\n\tdisabled: Accessor<boolean>;\n\treadOnly: Accessor<boolean>;\n\trequired: Accessor<boolean>;\n\n\t/** Items registry (for label resolution / group support). */\n\titems: Accessor<ItemsInput<Value> | undefined>;\n\t/** Whether the items list is grouped. */\n\tisGrouped: Accessor<boolean>;\n\n\t/** Check whether a given item value is currently selected. */\n\tisItemSelected: (item: Value) => boolean;\n\n\t/** Display label for the current value. Empty string when nothing is selected. */\n\tvalueLabel: Accessor<string>;\n\n\t/** Pure event-emitter — fire `onValueChange`. Consumer owns the signal write. */\n\tsetValue: (\n\t\tnext: SelectValueType<Value, Multiple> | null,\n\t\treason?: SelectChangeReason,\n\t) => void;\n\t/** Pure event-emitter — fire `onOpenChange`. */\n\tsetOpen: (next: boolean, reason?: SelectChangeReason) => void;\n\n\t/**\n\t * Context provider. Wrap a subtree to make the api discoverable via\n\t * `useSelect()` without prop-drilling.\n\t */\n\tProvider: (props: { children: JSX.Element }) => JSX.Element;\n}\n\n// ---------------------------------------------------------------------------\n// Context\n// ---------------------------------------------------------------------------\n\nconst SelectCtx = createContext<SelectApi<unknown, boolean | undefined> | null>(\n\tnull,\n);\n\nexport function useSelect<\n\tValue = SelectValue,\n\tMultiple extends boolean | undefined = false,\n>(): SelectApi<Value, Multiple> {\n\tconst ctx = useContext(SelectCtx);\n\tif (ctx == null) {\n\t\tthrow new Error(\n\t\t\t\"Base UI: useSelect() must be called inside a <c.Provider>.\",\n\t\t);\n\t}\n\treturn ctx as SelectApi<Value, Multiple>;\n}\n\n// ---------------------------------------------------------------------------\n// Primitive\n// ---------------------------------------------------------------------------\n\n/**\n * Solid 2-native headless primitive for the select selection logic. Owns:\n * value / open state, isItemSelected derivation, and valueLabel. No filter\n * input (Select has no text input). DOM concerns (floating-ui positioning,\n * keyboard nav, portal, hidden form input) live in the structural\n * `<Select.Root>` wrapper that composes this primitive.\n */\nexport function createSelect<\n\tValue = SelectValue,\n\tMultiple extends boolean | undefined = false,\n>(options: CreateSelectOptions<Value, Multiple>): SelectApi<Value, Multiple> {\n\t// Freeze multi-select at init — the scalar vs. array value shape cannot\n\t// flip after mount.\n\tconst isMultiple = untrack(() => options.multiple === true);\n\n\tconst disabled = createMemo<boolean>(\n\t\t() => Boolean(readOption(options.disabled)),\n\t\t{ name: \"select.disabled\" },\n\t);\n\n\tconst readOnly = createMemo<boolean>(\n\t\t() => Boolean(readOption(options.readOnly)),\n\t\t{ name: \"select.readOnly\" },\n\t);\n\n\tconst required = createMemo<boolean>(\n\t\t() => Boolean(readOption(options.required)),\n\t\t{ name: \"select.required\" },\n\t);\n\n\tconst itemToStringLabel = createMemo<((value: Value) => string) | undefined>(\n\t\t() => readOption(options.itemToStringLabel),\n\t\t{ name: \"select.itemToStringLabel\" },\n\t);\n\n\tconst isItemEqualToValue = createMemo<ItemEqualityComparer<Value, Value>>(\n\t\t() =>\n\t\t\t(readOption(options.isItemEqualToValue) as\n\t\t\t\t| ItemEqualityComparer<Value, Value>\n\t\t\t\t| undefined) ??\n\t\t\t(defaultItemEquality as ItemEqualityComparer<Value, Value>),\n\t\t{ name: \"select.isItemEqualToValue\" },\n\t);\n\n\t// Value — reads through the consumer's accessor.\n\tconst value = createMemo<SelectValueType<Value, Multiple> | null>(\n\t\t() => {\n\t\t\tconst raw = readOption(options.value) as\n\t\t\t\t| SelectValueType<Value, Multiple>\n\t\t\t\t| null\n\t\t\t\t| undefined;\n\t\t\tif (isMultiple) {\n\t\t\t\treturn (\n\t\t\t\t\tArray.isArray(raw) ? raw : raw == null ? [] : raw\n\t\t\t\t) as SelectValueType<Value, Multiple>;\n\t\t\t}\n\t\t\treturn (raw ?? null) as SelectValueType<Value, Multiple> | null;\n\t\t},\n\t\t{ name: \"select.value\" },\n\t);\n\n\t// Open — reads through the consumer's accessor.\n\tconst open = createMemo<boolean>(() => Boolean(readOption(options.open)), {\n\t\tname: \"select.open\",\n\t});\n\n\t// Items registry\n\tconst items = createMemo<ItemsInput<Value> | undefined>(\n\t\t() => readOption(options.items) as ItemsInput<Value> | undefined,\n\t\t{ name: \"select.items\" },\n\t);\n\n\tconst isGrouped = createMemo<boolean>(\n\t\t() => {\n\t\t\tconst its = items();\n\t\t\tif (!its) return false;\n\t\t\treturn isGroupedItems(its as unknown[]);\n\t\t},\n\t\t{ name: \"select.isGrouped\" },\n\t);\n\n\t// isItemSelected — pure derivation.\n\tconst isItemSelected = (item: Value): boolean => {\n\t\tconst sv = value();\n\t\tif (sv == null) return false;\n\t\tconst comparer = isItemEqualToValue();\n\t\tif (isMultiple && Array.isArray(sv)) {\n\t\t\treturn (sv as Value[]).some((v) => comparer(item, v));\n\t\t}\n\t\treturn comparer(item, sv as Value);\n\t};\n\n\t// Display label for the trigger — derived from value + itemToStringLabel.\n\tconst valueLabel = createMemo<string>(\n\t\t() => {\n\t\t\tconst sv = value();\n\t\t\tif (sv == null) return \"\";\n\t\t\tif (isMultiple && Array.isArray(sv)) {\n\t\t\t\treturn (sv as Value[])\n\t\t\t\t\t.map((v) =>\n\t\t\t\t\t\tstringifyAsLabel(\n\t\t\t\t\t\t\tv,\n\t\t\t\t\t\t\titemToStringLabel() as ((item: unknown) => string) | undefined,\n\t\t\t\t\t\t),\n\t\t\t\t\t)\n\t\t\t\t\t.join(\", \");\n\t\t\t}\n\t\t\treturn stringifyAsLabel(\n\t\t\t\tsv,\n\t\t\t\titemToStringLabel() as ((item: unknown) => string) | undefined,\n\t\t\t);\n\t\t},\n\t\t{ name: \"select.valueLabel\" },\n\t);\n\n\t// Pure event-emitters — runWithOwner(null, ...) escapes the reactive owner\n\t// so signal writes inside the callback don't trigger SIGNAL_WRITE_IN_OWNED_SCOPE.\n\tconst setValue = (\n\t\tnext: SelectValueType<Value, Multiple> | null,\n\t\treason: SelectChangeReason = \"imperative\",\n\t): void => {\n\t\trunWithOwner(null, () => options.onValueChange?.(next, reason));\n\t};\n\n\tconst setOpen = (\n\t\tnext: boolean,\n\t\treason: SelectChangeReason = \"imperative\",\n\t): void => {\n\t\trunWithOwner(null, () => options.onOpenChange?.(next, reason));\n\t};\n\n\tconst api: SelectApi<Value, Multiple> = {\n\t\tvalue,\n\t\topen,\n\t\tmultiple: isMultiple,\n\t\tdisabled,\n\t\treadOnly,\n\t\trequired,\n\t\titems,\n\t\tisGrouped,\n\t\tisItemSelected,\n\t\tvalueLabel,\n\t\tsetValue,\n\t\tsetOpen,\n\t\tProvider: (props) => (\n\t\t\t<SelectCtx value={api as SelectApi<unknown, boolean | undefined>}>\n\t\t\t\t{props.children}\n\t\t\t</SelectCtx>\n\t\t),\n\t};\n\n\t(api as SelectApi<Value, Multiple> & Snapshottable)[SNAPSHOT_KEYS] =\n\t\tSELECT_SNAPSHOT_KEYS;\n\n\treturn api;\n}\n\nconst SELECT_SNAPSHOT_KEYS = snapshotKeys<SelectApi>(\n\t\"value\",\n\t\"open\",\n\t\"disabled\",\n\t\"readOnly\",\n\t\"required\",\n\t\"valueLabel\",\n);\n"],"mappings":"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","ignoreList":[]}