import { onCleanup, untrack } from "solid-js"; import { useBaseUiId } from "../base-ui-id"; import { useLabelableContext } from "./labelable-context"; export interface UseLabelableIdParameters { /** * Explicit id for the control. When omitted, {@link useBaseUiId} generates * one. Read once during setup — later changes to `params.id` are ignored * to match `useBaseUiId`'s stable-id semantics. */ id?: string | undefined; } export interface UseLabelableIdReturnValue { /** * The id to render on the control element. Stable for the component's * lifetime; the context's `controlId()` accessor will reflect this id * while the control is mounted. */ id: string; } /** * Register a labelable control's id with the surrounding * ``. Labels rendered inside that provider can then read * `context.controlId()` to wire `htmlFor` / click-to-focus behavior. * * ### Lifecycle * * - On setup, resolves the id (override or generated) and registers it under * a per-call `Symbol()` source key. Registration is synchronous so the * context is populated before the first render of descendants reads it. * - On cleanup, unregisters the id. The provider falls back to its seeded * default control id when no registrations remain (matching React). * * ### Relationship to React's `useLabelableId` * * React's version has an `implicit` branch that checks whether the control * is wrapped in a native `