{"slug":"accordion","title":"Accordion","description":"Using the accordion machine in your project.","contentType":"component","framework":"svelte","content":"An accordion is a vertically stacked set of interactive headings containing a\ntitle, content snippet, or thumbnail representing a section of content.\n\n## Resources\n\n\n[Latest version: v1.39.1](https://www.npmjs.com/package/@zag-js/accordion)\n[Logic Visualizer](https://zag-visualizer.vercel.app/accordion)\n[Source Code](https://github.com/chakra-ui/zag/tree/main/packages/machines/accordion)\n\n\n\n**Features**\n\n- Full keyboard navigation\n- Supports single and multiple expanded items\n- Supports collapsible items\n- Supports horizontal and vertical orientation\n\n## Installation\n\nInstall the accordion package:\n\n```bash\nnpm install @zag-js/accordion @zag-js/svelte\n# or\nyarn add @zag-js/accordion @zag-js/svelte\n```\n\n## Anatomy\n\nCheck the accordion anatomy and part names.\n\n> Each part includes a `data-part` attribute to help identify them in the DOM.\n\n\n\n## Usage\n\nImport the accordion package:\n\n```tsx\nimport * as accordion from \"@zag-js/accordion\"\n```\n\nThe accordion package exports two key functions:\n\n- `machine` - State machine logic.\n- `connect` - Maps machine state to JSX props and event handlers.\n\n> Pass a unique `id` to `useMachine` so generated element ids stay predictable.\n\nThen use the framework integration helpers:\n\n```svelte\n<script lang=\"ts\">\n  import * as accordion from \"@zag-js/accordion\"\n  import { useMachine, normalizeProps } from \"@zag-js/svelte\"\n\n  const data = [\n    { title: \"Watercraft\", content: \"Sample accordion content\" },\n    { title: \"Automobiles\", content: \"Sample accordion content\" },\n    { title: \"Aircraft\", content: \"Sample accordion content\" },\n  ]\n\n  const id = $props.id()\n  const service = useMachine(accordion.machine, ({ id }))\n  const api = $derived(accordion.connect(service, normalizeProps))\n</script>\n\n<div {...api.getRootProps()}>\n  {#each data as item}\n    <div {...api.getItemProps({ value: item.title })}>\n      <h3>\n        <button {...api.getItemTriggerProps({ value: item.title })}>\n          {item.title}\n        </button>\n      </h3>\n      <div {...api.getItemContentProps({ value: item.title })}>\n        {item.content}\n      </div>\n    </div>\n  {/each}\n</div>\n```\n\nYou may have noticed we wrapped each accordion trigger within an `h3`. This is\nrecommended by the\n[WAI-ARIA](https://www.w3.org/TR/wai-aria-practices-1.1/#wai-aria-roles-states-and-properties)\ndesign pattern to ensure the accordion has the appropriate hierarchy on the\npage.\n\n### Opening multiple items\n\nSet `multiple` to `true` to allow more than one expanded item at a time.\n\n```tsx {2}\nconst service = useMachine(accordion.machine, {\n  multiple: true,\n})\n```\n\n### Setting the initial value\n\nSet `defaultValue` to define expanded items on first render.\n\n```tsx\n// multiple mode\nconst service = useMachine(accordion.machine, {\n  multiple: true,\n  defaultValue: [\"home\", \"about\"],\n})\n\n// single mode\nconst service = useMachine(accordion.machine, {\n  defaultValue: [\"home\"],\n})\n```\n\n### Controlled accordions\n\nUse `value` and `onValueChange` to control expanded items externally.\n\n```svelte\n<script lang=\"ts\">\n  let value = $state([\"home\"])\n\n  const service = useMachine(accordion.machine, {\n    get value() {\n      return value\n    },\n    onValueChange(details) {\n      value = details.value\n    },\n  })\n</script>\n```\n\n### Making items collapsible\n\nSet `collapsible` to `true` to allow closing an expanded item by clicking it\nagain.\n\n> Note: If `multiple` is `true`, we internally set `collapsible` to be `true`.\n\n```tsx {2}\nconst service = useMachine(accordion.machine, {\n  collapsible: true,\n})\n```\n\n### Listening for value changes\n\nWhen the accordion value changes, the `onValueChange` callback is invoked.\n\n```tsx {2-5}\nconst service = useMachine(accordion.machine, {\n  onValueChange(details) {\n    // details => { value: string[] }\n    console.log(\"selected accordion:\", details.value)\n  },\n})\n```\n\n### Listening for focus changes\n\nUse `onFocusChange` to react when keyboard focus moves between item triggers.\n\n```tsx\nconst service = useMachine(accordion.machine, {\n  onFocusChange(details) {\n    // details => { value: string | null }\n    console.log(\"focused item:\", details.value)\n  },\n})\n```\n\n### Horizontal orientation\n\nSet `orientation` to `horizontal` when rendering items side by side.\n\n```tsx {2}\nconst service = useMachine(accordion.machine, {\n  orientation: \"horizontal\",\n})\n```\n\n### Disabling an accordion item\n\nTo disable a specific accordion item, pass the `disabled: true` property to the\n`getItemProps`, `getItemTriggerProps` and `getItemContentProps`.\n\nWhen an accordion item is disabled, it is skipped from keyboard navigation and\ncan't be interacted with.\n\n```tsx\n//...\n<div {...api.getItemProps({ value: \"item\", disabled: true })}>\n  <h3>\n    <button {...api.getItemTriggerProps({ value: \"item\", disabled: true })}>\n      Trigger\n    </button>\n  </h3>\n  <div {...api.getItemContentProps({ value: \"item\", disabled: true })}>\n    Content\n  </div>\n</div>\n//...\n```\n\nYou can also disable the entire accordion by setting `disabled` on the machine.\n\n```tsx {2}\nconst service = useMachine(accordion.machine, {\n  disabled: true,\n})\n```\n\n## Styling guide\n\nEach part includes a `data-part` attribute you can target in CSS.\n\n### Open and closed state\n\nWhen an accordion item expands or collapses, `data-state` is set to `open` or\n`closed` on the item, trigger, and content elements.\n\n```css\n[data-part=\"item\"][data-state=\"open|closed\"] {\n  /* styles for the item is open or closed state */\n}\n\n[data-part=\"item-trigger\"][data-state=\"open|closed\"] {\n  /* styles for the item is open or closed state */\n}\n\n[data-part=\"item-content\"][data-state=\"open|closed\"] {\n  /* styles for the item is open or closed state */\n}\n```\n\n### Focused state\n\nWhen an accordion item's trigger is focused, a `data-focus` attribute is set on\nthe item and content.\n\n```css\n[data-part=\"item\"][data-focus] {\n  /* styles for the item's focus state */\n}\n\n[data-part=\"item-trigger\"]:focus {\n  /* styles for the trigger's focus state */\n}\n\n[data-part=\"item-content\"][data-focus] {\n  /* styles for the content's focus state */\n}\n```\n\n## Creating a component\n\nCreate your accordion component by abstracting the machine into your own\ncomponent.\n\n### Usage\n\n\n\n### Implementation\n\nUse the `splitProps` utility to separate the machine's props from the\ncomponent's props.\n\n\n\n## Methods and Properties\n\nThe accordion's `api` exposes the following methods and properties:\n\n### Machine Context\n\nThe accordion machine exposes the following context properties:\n\n**`ids`**\nType: `Partial<{ root: string; item: (value: string) => string; itemContent: (value: string) => string; itemTrigger: (value: string) => string; }>`\nDescription: The ids of the elements in the accordion. Useful for composition.\n\n**`multiple`**\nType: `boolean`\nDescription: Whether multiple accordion items can be expanded at the same time.\n\n**`collapsible`**\nType: `boolean`\nDescription: Whether an accordion item can be closed after it has been expanded.\n\n**`value`**\nType: `string[]`\nDescription: The controlled value of the expanded accordion items.\n\n**`defaultValue`**\nType: `string[]`\nDescription: The initial value of the expanded accordion items.\nUse when you don't need to control the value of the accordion.\n\n**`disabled`**\nType: `boolean`\nDescription: Whether the accordion items are disabled\n\n**`onValueChange`**\nType: `(details: ValueChangeDetails) => void`\nDescription: The callback fired when the state of expanded/collapsed accordion items changes.\n\n**`onFocusChange`**\nType: `(details: FocusChangeDetails) => void`\nDescription: The callback fired when the focused accordion item changes.\n\n**`orientation`**\nType: `\"horizontal\" | \"vertical\"`\nDescription: The orientation of the accordion items.\n\n**`dir`**\nType: `\"ltr\" | \"rtl\"`\nDescription: The document's text/writing direction.\n\n**`id`**\nType: `string`\nDescription: The unique identifier of the machine.\n\n**`getRootNode`**\nType: `() => ShadowRoot | Node | Document`\nDescription: A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron.\n\n### Machine API\n\nThe accordion `api` exposes the following methods:\n\n**`focusedValue`**\nType: `string`\nDescription: The value of the focused accordion item.\n\n**`value`**\nType: `string[]`\nDescription: The value of the accordion\n\n**`setValue`**\nType: `(value: string[]) => void`\nDescription: Sets the value of the accordion\n\n**`getItemState`**\nType: `(props: ItemProps) => ItemState`\nDescription: Returns the state of an accordion item.\n\n### Data Attributes\n\n**`Root`**\n\n**`data-scope`**: accordion\n**`data-part`**: root\n**`data-orientation`**: The orientation of the accordion\n\n**`Item`**\n\n**`data-scope`**: accordion\n**`data-part`**: item\n**`data-state`**: \"open\" | \"closed\"\n**`data-focus`**: Present when focused\n**`data-disabled`**: Present when disabled\n**`data-orientation`**: The orientation of the item\n\n**`ItemContent`**\n\n**`data-scope`**: accordion\n**`data-part`**: item-content\n**`data-state`**: \"open\" | \"closed\"\n**`data-disabled`**: Present when disabled\n**`data-focus`**: Present when focused\n**`data-orientation`**: The orientation of the item\n\n**`ItemIndicator`**\n\n**`data-scope`**: accordion\n**`data-part`**: item-indicator\n**`data-state`**: \"open\" | \"closed\"\n**`data-disabled`**: Present when disabled\n**`data-focus`**: Present when focused\n**`data-orientation`**: The orientation of the item\n\n**`ItemTrigger`**\n\n**`data-scope`**: accordion\n**`data-part`**: item-trigger\n**`data-controls`**: \n**`data-orientation`**: The orientation of the item\n**`data-state`**: \"open\" | \"closed\"\n\n## Accessibility\n\n### Keyboard Interactions\n\n**`Space`**\nDescription: When focus is on an trigger of a collapsed item, the item is expanded\n\n**`Enter`**\nDescription: When focus is on an trigger of a collapsed section, expands the section.\n\n**`Tab`**\nDescription: Moves focus to the next focusable element\n\n**`Shift + Tab`**\nDescription: Moves focus to the previous focusable element\n\n**`ArrowDown`**\nDescription: Moves focus to the next trigger\n\n**`ArrowUp`**\nDescription: Moves focus to the previous trigger.\n\n**`Home`**\nDescription: When focus is on an trigger, moves focus to the first trigger.\n\n**`End`**\nDescription: When focus is on an trigger, moves focus to the last trigger.","package":"@zag-js/accordion","editUrl":"https://github.com/chakra-ui/zag/edit/main/website/data/components/accordion.mdx"}