

<Preview className="py-22" name="BasicAccordionExample" />

## Overview [#overview]

The **Accordion** component provides an interactive way to display collapsible content sections. Built on Base UI primitives, it supports single or multiple item expansion with customizable variants and smooth CSS transitions.

## Usage [#usage]

```tsx
import {
  Accordion,
  AccordionHeader,
  AccordionItem,
  AccordionPanel,
  AccordionTrigger,
} from "@tilt-legal/cubitt-components/primitives";
```

```tsx
<Accordion multiple={false}>
  <AccordionItem value="item-1">
    <AccordionHeader>
      <AccordionTrigger>Is it accessible?</AccordionTrigger>
    </AccordionHeader>
    <AccordionPanel>
      Yes. It adheres to the WAI-ARIA design pattern.
    </AccordionPanel>
  </AccordionItem>
</Accordion>
```

<Accordions type="single">
  <Accordion title="URL State Management">
    You can sync the accordion state with the URL by providing a `paramName`:

    ```tsx
    // Synced with ?sections=faq,privacy
    <Accordion paramName="sections" defaultValue={["faq"]}>
      <AccordionItem value="faq">
        <AccordionHeader>
          <AccordionTrigger>FAQ</AccordionTrigger>
        </AccordionHeader>
        <AccordionPanel>
          Frequently asked questions...
        </AccordionPanel>
      </AccordionItem>
      <AccordionItem value="privacy">
        <AccordionHeader>
          <AccordionTrigger>Privacy Policy</AccordionTrigger>
        </AccordionHeader>
        <AccordionPanel>
          Our privacy policy details...
        </AccordionPanel>
      </AccordionItem>
    </Accordion>

    // Advanced options:
    <Accordion
      paramName="docs"
      paramClearOnDefault={true}    // Remove param when no items are open
      paramDebounce={300}           // Debounce URL updates
      onUrlValueChange={(value) => console.log("Active sections:", value)}
    >
      {/* ... */}
    </Accordion>
    ```
  </Accordion>
</Accordions>

## Examples [#examples]

### Solid [#solid]

<Tabs items="['Preview', 'Code']">
  <Tab value="Preview">
    <Preview className="py-22" name="SolidAccordionExample" />
  </Tab>

  <Tab value="Code">
    ```tsx
    import {
      Accordion,
      AccordionHeader,
      AccordionItem,
      AccordionPanel,
      AccordionTrigger,
    } from "@tilt-legal/cubitt-components/primitives";

    <Accordion multiple={false} className="w-full lg:w-[75%]">
      <AccordionItem value="item-1">
        <AccordionHeader>
          <AccordionTrigger>What is Cubitt?</AccordionTrigger>
        </AccordionHeader>
        <AccordionPanel>
          Cubitt is a modern React component library built on top of Base UI primitives.
        </AccordionPanel>
      </AccordionItem>
    </Accordion>
    ```
  </Tab>
</Tabs>

### Outline [#outline]

<Tabs items="['Preview', 'Code']">
  <Tab value="Preview">
    <Preview className="py-22" name="OutlineAccordionExample" />
  </Tab>

  <Tab value="Code">
    ```tsx
    import {
      Accordion,
      AccordionHeader,
      AccordionItem,
      AccordionPanel,
      AccordionTrigger,
    } from "@tilt-legal/cubitt-components/primitives";

    <Accordion multiple={false} className="w-full lg:w-[75%]">
      <AccordionItem value="item-1">
        <AccordionHeader>
          <AccordionTrigger>What is Cubitt?</AccordionTrigger>
        </AccordionHeader>
        <AccordionPanel>
          Cubitt is a modern React component library built on top of Base UI primitives.
        </AccordionPanel>
      </AccordionItem>
    </Accordion>
    ```
  </Tab>
</Tabs>

### Custom Indicators [#custom-indicators]

<Tabs items="['Preview', 'Code']">
  <Tab value="Preview">
    <Preview className="py-22" name="PlusIndicatorAccordionExample" />
  </Tab>

  <Tab value="Code">
    ```tsx
    import {
      Accordion,
      AccordionHeader,
      AccordionItem,
      AccordionPanel,
      AccordionTrigger,
    } from "@tilt-legal/cubitt-components/primitives";

    <Accordion multiple={false} indicator="plus" className="w-full lg:w-[75%]">
      <AccordionItem value="item-1">
        <AccordionHeader>
          <AccordionTrigger>What is Cubitt?</AccordionTrigger>
        </AccordionHeader>
        <AccordionPanel>
          Cubitt is a modern React component library built on top of Base UI primitives.
        </AccordionPanel>
      </AccordionItem>
      <AccordionItem value="item-2">
        <AccordionHeader>
          <AccordionTrigger>Is it accessible?</AccordionTrigger>
        </AccordionHeader>
        <AccordionPanel>
          Yes. It adheres to the WAI-ARIA design pattern.
        </AccordionPanel>
      </AccordionItem>
    </Accordion>
    ```
  </Tab>
</Tabs>

### Multiple Open Items [#multiple-open-items]

<Tabs items="['Preview', 'Code']">
  <Tab value="Preview">
    <Preview className="py-22" name="MultipleAccordionExample" />
  </Tab>

  <Tab value="Code">
    ```tsx
    import {
      Accordion,
      AccordionHeader,
      AccordionItem,
      AccordionPanel,
      AccordionTrigger,
    } from "@tilt-legal/cubitt-components/primitives";

    <Accordion multiple={true} className="w-full lg:w-[75%]">
      <AccordionItem value="item-1">
        <AccordionHeader>
          <AccordionTrigger>What is Cubitt?</AccordionTrigger>
        </AccordionHeader>
        <AccordionPanel>
          Cubitt is a modern React component library.
        </AccordionPanel>
      </AccordionItem>
      <AccordionItem value="item-2">
        <AccordionHeader>
          <AccordionTrigger>Is it accessible?</AccordionTrigger>
        </AccordionHeader>
        <AccordionPanel>
          Yes. It adheres to the WAI-ARIA design pattern.
        </AccordionPanel>
      </AccordionItem>
    </Accordion>
    ```
  </Tab>
</Tabs>

### Nested Accordions [#nested-accordions]

<Tabs items="['Preview', 'Code']">
  <Tab value="Preview">
    <Preview className="py-22" name="NestedAccordionExample" />
  </Tab>

  <Tab value="Code">
    ```tsx
    import {
      Accordion,
      AccordionHeader,
      AccordionItem,
      AccordionPanel,
      AccordionTrigger,
    } from "@tilt-legal/cubitt-components/primitives";

    <Accordion variant="outline" multiple={false} className="w-full lg:w-[75%]">
      <AccordionItem value="item-1">
        <AccordionHeader>
          <AccordionTrigger>Getting Started</AccordionTrigger>
        </AccordionHeader>
        <AccordionPanel>
          Follow these steps to get started:
          <Accordion variant="outline" multiple={false} className="mt-4">
            <AccordionItem value="nested-1">
              <AccordionHeader>
                <AccordionTrigger>Installation</AccordionTrigger>
              </AccordionHeader>
              <AccordionPanel>
                Install Cubitt using npm, yarn, or pnpm.
              </AccordionPanel>
            </AccordionItem>
            <AccordionItem value="nested-2">
              <AccordionHeader>
                <AccordionTrigger>Configuration</AccordionTrigger>
              </AccordionHeader>
              <AccordionPanel>
                Configure your project with the necessary providers.
              </AccordionPanel>
            </AccordionItem>
          </Accordion>
        </AccordionPanel>
      </AccordionItem>
    </Accordion>
    ```
  </Tab>
</Tabs>

### Auto-Play [#auto-play]

<Tabs items="['Preview', 'Code']">
  <Tab value="Preview">
    <Preview className="py-22" name="AutoPlayAccordionExample" />
  </Tab>

  <Tab value="Code">
    ```tsx
    import {
      Accordion,
      AccordionHeader,
      AccordionItem,
      AccordionPanel,
      AccordionProgress,
      AccordionTrigger,
    } from "@tilt-legal/cubitt-components/primitives";

    <Accordion
      autoPlay
      autoPlayInterval={5000}
      items={["features", "accessibility", "customization"]}
      defaultValue={["features"]}
      variant="solid"
      className="w-full lg:w-[75%]"
    >
      <AccordionItem value="features">
        <AccordionHeader>
          <AccordionTrigger>What is Cubitt?</AccordionTrigger>
        </AccordionHeader>
        <AccordionPanel>
          Cubitt is a modern React component library built on top of Base UI primitives.
        </AccordionPanel>
        <AccordionProgress />
      </AccordionItem>
      <AccordionItem value="accessibility">
        <AccordionHeader>
          <AccordionTrigger>Is it accessible?</AccordionTrigger>
        </AccordionHeader>
        <AccordionPanel>
          Yes. It adheres to the WAI-ARIA design pattern.
        </AccordionPanel>
        <AccordionProgress />
      </AccordionItem>
    </Accordion>
    ```
  </Tab>
</Tabs>

### URL State [#url-state]

<Tabs items="['Preview', 'Code']">
  <Tab value="Preview">
    <Preview className="py-22" name="AccordionURLStateExample" />
  </Tab>

  <Tab value="Code">
    ```tsx
    import {
      Accordion,
      AccordionHeader,
      AccordionItem,
      AccordionPanel,
      AccordionTrigger,
    } from "@tilt-legal/cubitt-components/primitives";

    // Multiple open sections synced with ?sections=faq (default faq won't show in URL)

    <Accordion
      paramName="sections"
      defaultValue={["faq"]}
      paramClearOnDefault={true}
      className="w-full lg:w-[75%]"
    >
      <AccordionItem value="faq">
        <AccordionHeader>
          <AccordionTrigger>Frequently Asked Questions</AccordionTrigger>
        </AccordionHeader>
        <AccordionPanel>
          Find answers to the most common questions about our service, billing, and features.
        </AccordionPanel>
      </AccordionItem>
      <AccordionItem value="privacy">
        <AccordionHeader>
          <AccordionTrigger>Privacy Policy</AccordionTrigger>
        </AccordionHeader>
        <AccordionPanel>
          Learn how we collect, use, and protect your personal information and data.
        </AccordionPanel>
      </AccordionItem>
      <AccordionItem value="terms">
        <AccordionHeader>
          <AccordionTrigger>Terms of Service</AccordionTrigger>
        </AccordionHeader>
        <AccordionPanel>
          Review the terms and conditions that govern your use of our platform.
        </AccordionPanel>
      </AccordionItem>
    </Accordion>
    ```
  </Tab>
</Tabs>

## API Reference [#api-reference]

### Accordion [#accordion]

| Prop               | Type                                      | Description                                                                          |
| ------------------ | ----------------------------------------- | ------------------------------------------------------------------------------------ |
| `value`            | `string[]`                                | The controlled value of the accordion (array of open item values).                   |
| `defaultValue`     | `string[]`                                | The default value when uncontrolled.                                                 |
| `onValueChange`    | `(value: string[], eventDetails) => void` | Callback fired when the value changes.                                               |
| `multiple`         | `boolean`                                 | Whether multiple items can be open at once. Defaults to `true`.                      |
| `disabled`         | `boolean`                                 | Whether the accordion is disabled. Defaults to `false`.                              |
| `hiddenUntilFound` | `boolean`                                 | Allows browser's page search to find and expand panel contents. Defaults to `false`. |
| `loop`             | `boolean`                                 | Whether to loop keyboard focus back to the first item. Defaults to `true`.           |
| `orientation`      | `"horizontal" \| "vertical"`              | The visual orientation of the accordion. Defaults to `"vertical"`.                   |
| `keepMounted`      | `boolean`                                 | Whether to keep panels in the DOM while closed. Defaults to `false`.                 |
| `variant`          | `"default" \| "outline" \| "solid"`       | Visual style variant. Defaults to `"default"`.                                       |
| `indicator`        | `"arrow" \| "plus" \| "none"`             | Icon indicator type. Defaults to `"arrow"`.                                          |
| `items`            | `string[]`                                | Ordered list of item values for auto-play cycling. Required when `autoPlay` is true. |
| `autoPlay`         | `boolean`                                 | Whether to automatically advance to the next item. Defaults to `false`.              |
| `autoPlayInterval` | `number`                                  | Duration in milliseconds before auto-advancing. Defaults to `5000`.                  |
| `loop`             | `boolean`                                 | Whether to loop back to the first item after the last. Defaults to `true`.           |
| `className`        | `string`                                  | Additional CSS classes for the accordion.                                            |
| `render`           | `ReactElement \| function`                | Allows replacing the component's HTML element.                                       |

#### URL State Props [#url-state-props]

When provided with a `paramName`, the accordion's state will be reflected in the URL.

| Prop                  | Type                                | Description                                                                                 |
| --------------------- | ----------------------------------- | ------------------------------------------------------------------------------------------- |
| `paramName`           | `string`                            | URL parameter name for syncing state with URL. When provided, enables URL state management. |
| `paramValue`          | `string[]`                          | Controlled value for the URL parameter (syncs with accordion `value`).                      |
| `onUrlValueChange`    | `(value: string[] \| null) => void` | Callback when URL parameter value changes.                                                  |
| `paramClearOnDefault` | `boolean`                           | Remove URL param when value equals default. Defaults to `true`.                             |
| `paramThrottle`       | `number`                            | Throttle URL updates in milliseconds.                                                       |
| `paramDebounce`       | `number`                            | Debounce URL updates in milliseconds.                                                       |

### AccordionItem [#accordionitem]

| Prop        | Type      | Description                                         |
| ----------- | --------- | --------------------------------------------------- |
| `value`     | `string`  | The unique value for this accordion item. Required. |
| `disabled`  | `boolean` | Whether this item is disabled.                      |
| `className` | `string`  | Additional CSS classes for the item.                |

### AccordionHeader [#accordionheader]

| Prop        | Type     | Description                            |
| ----------- | -------- | -------------------------------------- |
| `className` | `string` | Additional CSS classes for the header. |

### AccordionTrigger [#accordiontrigger]

| Prop        | Type     | Description                             |
| ----------- | -------- | --------------------------------------- |
| `className` | `string` | Additional CSS classes for the trigger. |

### AccordionPanel [#accordionpanel]

| Prop          | Type      | Description                                                             |
| ------------- | --------- | ----------------------------------------------------------------------- |
| `className`   | `string`  | Additional CSS classes for the panel.                                   |
| `keepMounted` | `boolean` | Whether to keep the panel in the DOM while closed. Defaults to `false`. |

### AccordionProgress [#accordionprogress]

| Prop        | Type     | Description                                                                                       |
| ----------- | -------- | ------------------------------------------------------------------------------------------------- |
| `className` | `string` | Additional CSS classes for the progress bar. Only renders when `autoPlay` is enabled on the root. |

***

## Design Guidelines [#design-guidelines]

### Layout & Positioning [#layout--positioning]

* Use accordions to organize related information into collapsible sections
* Keep trigger labels concise and descriptive
* Consider the content hierarchy when nesting accordions
* Ensure adequate spacing between items for touch targets

### Visual Hierarchy [#visual-hierarchy]

* Use clear visual states for expanded/collapsed items
* Provide visual feedback for user interactions
* Use indicators to show expandable content
* Maintain consistent styling across all accordion items

### Accessibility [#accessibility]

* Provide meaningful labels for each accordion trigger
* Use proper ARIA attributes for screen readers
* Ensure keyboard navigation works correctly
* Consider focus management when items expand/collapse
