{"version":3,"names":["createSignal","useBaseUiId","LabelableContext","LabelableProvider","props","defaultId","controlRegistrations","Map","labelRegistrations","initialControlId","controlId","undefined","controlIdSignal","setControlIdSignal","ownedWrite","labelIdsSignal","setLabelIdsSignal","Object","freeze","equals","recomputeControlId","prev","size","first","id","values","registerControlId","source","has","delete","existing","get","set","registerLabelId","Array","from","contextValue","getLabelIds","present","children"],"sources":["labelable-provider.tsx"],"sourcesContent":["import type { JSX } from \"@solidjs/web\";\nimport { createSignal } from \"solid-js\";\nimport { useBaseUiId } from \"../base-ui-id\";\nimport {\n\tLabelableContext,\n\ttype LabelableContextValue,\n} from \"./labelable-context\";\n\nexport interface LabelableProviderProps {\n\t/**\n\t * Explicit control id to seed the provider with. When omitted, the provider\n\t * generates one lazily (only used if a labelable control registers without\n\t * supplying its own id).\n\t */\n\tcontrolId?: string | null | undefined;\n\tchildren?: JSX.Element | undefined;\n}\n\n/**\n * Provides a {@link LabelableContext} to descendants so label components and\n * the control they label can discover each other.\n *\n * Design notes (differences from Base UI React's `LabelableProvider`):\n *\n * - Control-id and label-id registries are kept in separate `Map<symbol, ...>`\n *   registries, each paired with a signal that holds the current computed\n *   view. When a registration changes, we recompute the view once and push\n *   the new value through the signal — no `tick` indirection.\n * - Registrations arrive from `useLabel` / `useLabelableId` during owned\n *   setup. Both registry signals opt into `ownedWrite` so those writes don't\n *   trip the Solid 2 `SIGNAL_WRITE_IN_OWNED_SCOPE` check (RFC 01). The writes\n *   are pure internal plumbing — no app-visible state depends on their\n *   timing within the owned scope.\n * - `getLabelIds` returns a fresh frozen array on each change so consumers\n *   that memoize off its reference (e.g. `useAriaLabelledBy` joining with\n *   spaces) see a stable identity between registrations.\n * - The `controlId` accessor reports the first still-registered control id\n *   (matching React's \"first wins, ignore stale\" logic). `null` means\n *   \"implicit label\", `undefined` means \"nothing registered yet\".\n */\nexport function LabelableProvider(props: LabelableProviderProps): JSX.Element {\n\t// Default id is generated lazily via `useBaseUiId` so the id slot is only\n\t// burned if the consumer actually wants one.\n\tconst defaultId = useBaseUiId();\n\n\tconst controlRegistrations = new Map<symbol, string | null>();\n\tconst labelRegistrations = new Map<symbol, string>();\n\n\t// Seed the control id from props. `null` (explicit implicit) and string\n\t// values are kept as-is; `undefined` falls back to the generated default.\n\t//\n\t// We intentionally read `props.controlId` only once during setup. React's\n\t// `LabelableProvider` uses `useState(initialControlId)` which snapshots the\n\t// initial value and then lets `registerControlId` drive subsequent updates\n\t// — we match that.\n\tconst initialControlId =\n\t\tprops.controlId === undefined ? defaultId : props.controlId;\n\n\tconst [controlIdSignal, setControlIdSignal] = createSignal<\n\t\tstring | null | undefined\n\t>(initialControlId, { ownedWrite: true });\n\n\tconst [labelIdsSignal, setLabelIdsSignal] = createSignal<readonly string[]>(\n\t\tObject.freeze([] as string[]),\n\t\t// `equals: false` — we always push a fresh frozen array on change,\n\t\t// and we want consumers to re-run even when array contents happen to\n\t\t// match (e.g. a label swap that preserves length + order).\n\t\t{ ownedWrite: true, equals: false },\n\t);\n\n\tfunction recomputeControlId(prev: string | null | undefined) {\n\t\t// Mirror React: when nothing is registered, fall back to the seeded\n\t\t// initial id (generated default or explicit prop). Otherwise, reuse\n\t\t// `prev` if it's still registered (stable output), else pick the first\n\t\t// registered id in insertion order.\n\t\tif (controlRegistrations.size === 0) {\n\t\t\treturn initialControlId;\n\t\t}\n\t\tlet first: string | null | undefined;\n\t\tfor (const id of controlRegistrations.values()) {\n\t\t\tif (prev !== undefined && id === prev) {\n\t\t\t\treturn prev;\n\t\t\t}\n\t\t\tif (first === undefined) {\n\t\t\t\tfirst = id;\n\t\t\t}\n\t\t}\n\t\treturn first;\n\t}\n\n\tfunction registerControlId(\n\t\tsource: symbol,\n\t\tid: string | null | undefined,\n\t): void {\n\t\tif (id === undefined) {\n\t\t\tif (!controlRegistrations.has(source)) return;\n\t\t\tcontrolRegistrations.delete(source);\n\t\t} else {\n\t\t\tconst existing = controlRegistrations.get(source);\n\t\t\tif (existing === id && controlRegistrations.has(source)) return;\n\t\t\tcontrolRegistrations.set(source, id);\n\t\t}\n\t\t// `ownedWrite` lets this run during owned setup/cleanup.\n\t\tsetControlIdSignal((prev) => recomputeControlId(prev));\n\t}\n\n\tfunction registerLabelId(source: symbol, id: string | undefined): void {\n\t\tif (id === undefined) {\n\t\t\tif (!labelRegistrations.has(source)) return;\n\t\t\tlabelRegistrations.delete(source);\n\t\t} else {\n\t\t\tconst existing = labelRegistrations.get(source);\n\t\t\tif (existing === id) return;\n\t\t\tlabelRegistrations.set(source, id);\n\t\t}\n\t\t// Snapshot the Map's insertion-order values into a fresh frozen array.\n\t\t// `isEqual: false` on the signal means every set fires subscribers — we\n\t\t// want that, because the array identity changes every time a label is\n\t\t// added or removed.\n\t\tsetLabelIdsSignal(Object.freeze(Array.from(labelRegistrations.values())));\n\t}\n\n\t// Signals are already accessors — wrapping them in a `createMemo(() => sig())`\n\t// just adds a dependency layer that re-emits the same value. Expose the\n\t// signal accessors directly.\n\tconst contextValue: LabelableContextValue = {\n\t\tcontrolId: controlIdSignal,\n\t\tregisterControlId,\n\t\tregisterLabelId,\n\t\tgetLabelIds: labelIdsSignal,\n\t\tpresent: true,\n\t};\n\n\treturn (\n\t\t<LabelableContext value={contextValue}>{props.children}</LabelableContext>\n\t);\n}\n"],"mappings":"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","ignoreList":[]}