import { createContext, useContext } from "solid-js";

/**
 * The value handed down by `<LabelableProvider>` to its descendants.
 *
 * Solid 2 adaptations from Base UI React's `LabelableContext`:
 *
 * - All reactive values are exposed as `Accessor<T>` so callers pull on demand
 *   and don't trip the top-level reactive read rule (RFC 01).
 * - The single `labelId` from React is generalized to a registry keyed by a
 *   per-consumer source `symbol`. Multiple labels can register into the same
 *   provider — `getLabelIds()` returns them in registration order, which
 *   `useAriaLabelledBy` joins with spaces. This is the multi-label superset of
 *   `use-registered-label-id.ts` (which progress/meter still use for their
 *   simpler single-id case).
 * - Setters are plain functions that may be called from owned scope on setup
 *   or from cleanup. The underlying signals opt into `ownedWrite` where
 *   appropriate so those writes don't trip `SIGNAL_WRITE_IN_OWNED_SCOPE`.
 * - `controlId` follows React's semantics: explicit `null` means "no
 *   association" (implicit label), `undefined` means "no registration yet",
 *   any string is the resolved control id.
 */

const NOOP = () => {};
const EMPTY_IDS = Object.freeze([]);

/**
 * The noop context used when no `<LabelableProvider>` is an ancestor. All
 * accessors return "nothing" and setters are no-ops, so consumers don't need
 * to branch on presence for correctness — they can just call through.
 */
export const NOOP_LABELABLE_CONTEXT = {
  controlId: () => undefined,
  registerControlId: NOOP,
  registerLabelId: NOOP,
  getLabelIds: () => EMPTY_IDS,
  present: false
};

/**
 * Context for [labelable elements](https://html.spec.whatwg.org/multipage/forms.html#category-label)
 * — provides a two-way channel between label components and the control they
 * label, so each side can discover the other's id without the consumer having
 * to thread them manually.
 *
 * Provide with `<LabelableContext value={...}>` (Solid 2 context-as-provider
 * pattern — RFC 02). In practice, use `<LabelableProvider>` which constructs
 * the context internally.
 */
export const LabelableContext = createContext(NOOP_LABELABLE_CONTEXT);

/**
 * Read the nearest `<LabelableProvider>` context. Returns the noop context
 * when no provider is an ancestor; callers can branch on `.present` if they
 * need to detect that case, or just call through (setters are no-ops, the
 * id accessor returns `undefined`).
 */
export function useLabelableContext() {
  return useContext(LabelableContext);
}
//# sourceMappingURL=labelable-context.jsx.map
