import { type Accessor, createContext, useContext } from "solid-js"; import type { TransitionStatus } from "../internals/use-transition-status/use-transition-status"; import type { AccordionRootState } from "./accordion-root-context.ts"; /** * Per-item state. Inherits the root's `{ value, disabled, orientation }` * projection plus item-level fields — `index` and `open` map directly to * `data-index` / `data-open`. */ export interface AccordionItemState extends AccordionRootState { /** Item's index within the accordion (DOM order). */ index: number; /** Whether the item is currently expanded. */ open: boolean; /** Enter/exit transition phase (threaded through to panel). */ transitionStatus: TransitionStatus; } /** * Context carried by ``. The trigger uses `triggerId` for its * own `id` (so the panel's `aria-labelledby` can point to it); the panel uses * it for `aria-labelledby`. `setTriggerId` is how the trigger registers a * consumer-provided id upstream. */ export interface AccordionItemContextValue { /** Live accessor for this item's open state. */ open: Accessor; /** Live accessor for this item's projected state. */ state: Accessor; /** Consumer-provided (or generated) id of the item's trigger. */ triggerId: Accessor; /** Called by the trigger to register its id for `aria-labelledby`. */ setTriggerId: (id: string | undefined) => void; } /** * `createContext(null)` + `== null` sentinel — * Solid 2's `useContext` throws `ContextNotFoundError` when the default is * `undefined`, which would shadow the intended Base UI error message below. */ export const AccordionItemContext = createContext(null); export function useAccordionItemContext(): AccordionItemContextValue { const context = useContext(AccordionItemContext); if (context == null) { throw new Error( "Base UI: AccordionItemContext is missing. Accordion parts must be placed within .", ); } return context; }