OTTODesign System

Code

Accordion

Storybook group: Components · Sidebar path: Components/Accordion · Extracted 28.09.2026

Version Tag Status API
v1 <oc-accordion-v1> Stable, allowed for generation AccordionV1

Overview (v1)

Source: ./src/components/accordion/v1/Overview.mdx

Accordion

The accordion component offers a range of customization options, including settings for the main text, controlling the expansion state, and managing the visibility of the top divider. It also supports specific events for opening and closing actions, along with a designated area for adding long content within the expanded section that can be toggled on and off.

Default variation

Story Default:

<oc-accordion-v1 title="Label">
  <div><oc-placeholder-v1 variant="text" class="oc-headline-100">PLACEHOLDER</oc-placeholder-v1></div>
</oc-accordion-v1>

Configuration

This component is configurable, allowing you to tailor its features and appearance to your specific needs. To explore all the available options and adjust the component, use the component configurator and see the changes affect the component in real-time.

Usage guidelines

Before integrating the accordion component into your project, make sure you have correctly installed the OTTO components package. Look through the variations page for examples of possible component variations. Here, you can discover both common and specific variations that address different use cases.

Info

See the Accordion UX documentation for detailed user experience guidelines.

Accessibility

The accordion component comes with a set of built-in accessibility features to ensure a seamless experience for all users.

Behavior

The trigger that shows and hides the content has role button. When the content is visible, the trigger with role button has aria-expanded set to true. When the content area is hidden, it is set to false. The content itself is a role="region". It is hidden when not expanded. We cannot use aria-hidden in this instance because the content might contain interactive elements which may not be place in an aria-hidden container. These attributes care so the users are not interrupted by a large content block they may not be interested in. The aria-expanded attribute then helps the screen reader to identify this region properly, so that a user can actively decide whether the content should be able to be parsed or not.

Keyboard navigation

The accordion component supports keyboard navigation for accessibility purposes. The following table lists the keyboard shortcuts available for this component:

Shortcut Description
Tab Focuses the trigger.
Space / Enter While focused, toggles the trigger to open or close the accordion.
Further reading

Configuration (v1)

Source: ./src/components/accordion/v1/Configuration.mdx

Accordion configuration

Configure the accordion component with the controls below and see the changes live in the preview canvas. Click the Show code button within the preview canvas to see the source code for the current component configuration.

Story Default:

<oc-accordion-v1 title="Label">
  <div><oc-placeholder-v1 variant="text" class="oc-headline-100">PLACEHOLDER</oc-placeholder-v1></div>
</oc-accordion-v1>

Interactive configurator (Storybook controls); every option is listed in the API section of this file.

API v1

Source: ./src/components/accordion/v1/AccordionV1.API.g.mdx

Accordion v1 API

API: <oc-accordion-v1> (AccordionV1)

The accordion component offers a range of customization options, including settings for the main text, controlling the expansion state, and managing the visibility of the top divider. It also supports specific events for opening and closing actions, along with a designated area for adding long content within the expanded section that can be toggled on and off.

Attributes / properties
Attribute Type Default Required Description
title string "" yes Sets the main text content of the accordion.
expanded boolean false no Indicates whether the accordion is expanded.
hide-divider boolean false no Indicates whether the top divider is hidden.
Slots
Slot Required Description
title yes Sets the content that appears in the title area.
default yes Sets the content that appears in the expanded area.
Events
Event Detail type Description
oc-accordion-open CustomEvent<null> Opening an accordion triggers the oc-open event.
oc-accordion-close CustomEvent<null> Closing an accordion triggers the oc-close event.
oc-open CustomEvent<null> Opening an accordion triggers the oc-open event.
oc-close CustomEvent<null> Closing an accordion triggers the oc-close event.
oc-property-change OcAccordionV1Events["oc-property-change"] Whenever a property value changes, this event triggers. Use this event to track all property changes within the component.

Refer to the Events documentation for more information.
oc-mount { component: string; } Fired when the component is mounted to the DOM. The event is fired when the onMount hook of the component is called by the runtime.
oc-unmount { component: string; } Fired when the component is unmounted from the DOM. The event is fired when the function returned by the onMount hook of the component is called by the runtime.

Variations (v1)

Source: ./src/components/accordion/v1/Variations.mdx

Variations

Listed below are the most common variations of the accordion component as well as specific component variations for different use cases.

You can explore all available options using the component configurator, adjust the component to your needs, and see the changes live in a preview canvas.

Default

Story: components-accordion-variations--default · tags:

The default configuration is in a collapsed expansion state with a placeholder component in the default slot.

Args: defaultSlot=<div><oc-placeholder-v1 variant="text" class="oc-headline-100">PLACEHOLDER</oc-placeholder-v1></div>

<oc-accordion-v1 title="Label">
  <div><oc-placeholder-v1 variant="text" class="oc-headline-100">PLACEHOLDER</oc-placeholder-v1></div>
</oc-accordion-v1>

Demo: custom title and expanded

Story: components-accordion-variations--demo-custom-title-and-expanded · tags:

A demo showcasing the accordion with a custom title and the expanded state.

Args: title=Custom Title, expanded=true, defaultSlot=(see snippet)

<oc-accordion-v1 title="Custom Title" expanded>
  <p class="oc-copy-100">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse ac dignissim massa.
      Suspendisse potenti. Vestibulum vitae nunc vel est ultricies condimentum non eget orci.
      Quisque nec arcu rutrum, sollicitudin ligula non, vulputate leo. In ipsum magna, vehicula at
      hendrerit ut, aliquet in lorem. Vivamus id porttitor orci. Praesent ac nunc sit amet est
      cursus sollicitudin. Sed rhoncus aliquam mi. Quisque gravida vestibulum nunc non posuere.
      Aliquam at congue mauris. Vivamus porttitor mauris eu felis pellentesque, pharetra faucibus
      lorem vehicula. Donec quis consectetur sapien, a ullamcorper risus. Praesent id arcu velit.
      Quisque sapien nibh, porta id orci nec, mattis pellentesque nisl. Phasellus at dapibus neque,
      a volutpat elit. Sed eu orci sollicitudin, fringilla arcu vel, rhoncus ipsum. Aenean vel
      efficitur sem. Nam ante velit, elementum in tortor et, maximus consectetur nibh. Morbi et
      ligula vitae metus pellentesque feugiat. Phasellus et nisl nisi. Phasellus condimentum vitae
      arcu vitae congue. Morbi et libero in urna efficitur lobortis in eget nunc. Etiam ligula
      augue, pulvinar eu gravida at, molestie ut enim. Vivamus sed leo gravida, dictum ex in,
      vehicula turpis. Praesent sollicitudin posuere suscipit. Proin eleifend suscipit risus.
      Aliquam at nibh libero. Donec bibendum, nisi a fringilla hendrerit, risus risus fringilla
      turpis, ut vulputate felis lectus a ligula. Sed libero diam, accumsan ut orci et, lobortis
      pretium dui. Donec elementum, felis id ultricies cursus, odio nunc congue erat, eu venenatis
      eros ligula id nisl. Nunc auctor vel metus et hendrerit. Aliquam cursus tristique purus ut
      interdum. Ut rhoncus ultricies ultrices. Ut eget volutpat augue. Ut fermentum sit amet elit ut
      volutpat. In hac habitasse platea dictumst. Integer ut mauris ut arcu efficitur convallis
      vitae sit amet lacus. Duis convallis pharetra diam et viverra. Mauris consequat dignissim
      hendrerit. Aliquam sit amet metus porttitor ligula aliquet volutpat vitae sit amet nulla.
      Curabitur mattis, neque nec condimentum rutrum, orci nulla accumsan orci, ut pellentesque elit
      quam vel purus. Phasellus a dictum velit, sit amet mattis lectus. Cras diam libero, ultricies
      id consectetur sed, elementum in magna. Pellentesque at felis accumsan, luctus enim in,
      lacinia enim. Ut tortor nibh, volutpat eget vestibulum condimentum, scelerisque finibus
      sapien. Aliquam id ipsum sed ex auctor varius. Vivamus molestie risus euismod purus sodales
      laoreet. Aliquam condimentum dapibus sapien, eget congue risus consectetur vitae. Proin in
      porttitor mauris. Quisque id libero hendrerit sem lacinia gravida.</p>
</oc-accordion-v1>

Demo: custom title with markup

Story: components-accordion-variations--demo-title-with-markup · tags:

A demo showcasing the accordion with a custom markup in title slot

Args: titleSlot=(see snippet), defaultSlot=<p class="oc-copy-100">Lorem ipsum dolor sit amet</p>

<oc-accordion-v1 title="Label">
  <div  style="display: flex; align-items: center" slot="title"><oc-icon-v1 type="chat"></oc-icon-v1><span style="margin-left:10px">Custom Title</span></div>
  <p class="oc-copy-100">Lorem ipsum dolor sit amet</p>
</oc-accordion-v1>
Story source (TypeScript, verbatim from Storybook)
{
  name: "Demo: custom title with markup",
  args: {
    titleSlot: `<div  style="display: flex; align-items: center" slot="title"><oc-icon-v1 type="chat"></oc-icon-v1><span style="margin-left:10px">Custom Title</span></div>`,
    defaultSlot: `<p class="oc-copy-100">Lorem ipsum dolor sit amet</p>`
  }
}

Demo: payment plans accordion

Story: components-accordion-variations--demo-payment-plans-accordion · tags:

A demo showcasing the accordion used for payment plans with a custom markup in title slot

Args: titleSlot=(see snippet), defaultSlot=<p class="oc-copy-100">Lorem ipsum dolor sit amet</p>

<style>
  .accordion_header-split *:nth-child(2) {
    margin-right: 14px;
  }

  .accordion_header-split {
    display: flex;
    justify-content: space-between;
  }

  .accordion_header-subtitle {
    font-weight: normal;
  }

  .pay_color-text-secondary {
    color: var(--oc-semantic-color-text-secondary);
  }
</style>
<oc-accordion-v1 title="Label"
  ><div slot="title">
        <div class="accordion_header-split pay_payment-plan-detail">
          <span> Du zahlst monatlich </span>
          <span>36,69 €</span>
        </div>

        <div
          class="accordion_header-split accordion_header-subtitle oc-copy-100 pay_color-text-secondary pay_payment-plan-detail"
        >
          <span>Letzte Monatsrate abweichend:</span>
          <span>36,69 €</span>
        </div>
      </div> <p class="oc-copy-100">Lorem ipsum dolor sit amet</p>
</oc-accordion-v1>
Story source (TypeScript, verbatim from Storybook)
{
  name: "Demo: payment plans accordion",
  parameters: {
    controls: {
      disabled: true
    }
  },
  argTypes: hideControlsBadge(Metadata),
  args: {
    titleSlot: `<div slot="title">
        <div class="accordion_header-split pay_payment-plan-detail">
          <span> Du zahlst monatlich </span>
          <span>36,69 €</span>
        </div>

        <div
          class="accordion_header-split accordion_header-subtitle oc-copy-100 pay_color-text-secondary pay_payment-plan-detail"
        >
          <span>Letzte Monatsrate abweichend:</span>
          <span>36,69 €</span>
        </div>
      </div>`,
    defaultSlot: `<p class="oc-copy-100">Lorem ipsum dolor sit amet</p>`
  },
  render(args) {
    const {
      titleSlot,
      defaultSlot,
      ...props
    } = args;
    return html`
      <style>
        .accordion_header-split *:nth-child(2) {
          margin-right: 14px;
        }

        .accordion_header-split {
          display: flex;
          justify-content: space-between;
        }

        .accordion_header-subtitle {
          font-weight: normal;
        }

        .pay_color-text-secondary {
          color: var(--oc-semantic-color-text-secondary);
        }
      </style>
      <oc-accordion-v1 ${spread(props)}
        >${unsafeHTML(titleSlot)} ${unsafeHTML(defaultSlot)}
      </oc-accordion-v1>
    `;
  }
}

Interaction tests (AccordionV1.interactions.stories.ts)

Interaction test stories (automated tests, not usage patterns).

Expand On Click

Story: components-accordion-interaction-tests--expand-on-click · tags: play-fn

Collapse On Click

Story: components-accordion-interaction-tests--collapse-on-click · tags: play-fn