import type { ReactNode } from "react";
export type AccordionHeadingLevel = 2 | 3 | 4 | 5 | 6;
export type AccordionItem = {
content: ReactNode;
isDisabled?: boolean;
key: string;
label: ReactNode;
};
export type AccordionProps = {
className?: string;
/** **Initial** only. Charcuterie owns it from then on. */
expandedKeys?: string[];
/**
* The heading level the triggers sit at. An accordion inside a
* `Card` that already has an `
` needs `3`, and getting this
* wrong is a document-outline break that no gate here can see —
* it depends entirely on the page.
*/
headingLevel?: AccordionHeadingLevel;
/**
* Several sections open at once. The default is **exclusive**,
* because that is what every one of the fleet's disclosure groups
* does today.
*/
isMultiple?: boolean;
items: AccordionItem[];
onChange?: (expandedKeys: string[]) => void;
};
/**
* Eleven sites in the fleet, and the plan called it "nearly free
* once `Tabs` exists". It is — the exclusive mode is
* `VisibilityGroup` and nothing else — but the reason it is worth
* shipping is not the saving.
*
* ### The two-owners bug, live, in the app this milestone migrates
*
* mux-magic's `JobStepsDisclosure` is built on ``, and
* `` **owns `open`**. It also wants the state in a Jotai
* atom so a job can be expanded from elsewhere. Reconciling the two
* takes three separate mechanisms:
*
* ```tsx
* const detailsRef = useRef(null)
* const skipNextToggleRef = useRef(isOpen)
*
* useEffect(() => {
* if (detailsRef.current) detailsRef.current.open = isOpen
* }, [isOpen])
*
* const handleToggle = (event) => {
* if (skipNextToggleRef.current) {
* skipNextToggleRef.current = false
* return // ← swallow the toggle our own write just fired
* }
* setStepsOpen(…)
* }
* ```
*
* That is the Radix argument from `Popover` pointed at the platform:
* a ref to reach past React, an effect to push state into the DOM,
* and a guard to stop the DOM's echo coming back. Every one of the
* three exists only because two things hold one fact.
*
* So this is a `