Accordion

A stack of sections that expand when tapped, one at a time or several at once.

Installation

npx @blotch/dolan add accordion
import {
  UiAccordion,
  UiAccordionContent,
  UiAccordionItem,
  UiAccordionTrigger,
} from '../components/ui/accordion';

Usage

src/app/app.ts
import { Component } from '@angular/core';
import { LYNX_ELEMENTS } from '@blotch/angular-lynx';
import {
  UiAccordion,
  UiAccordionContent,
  UiAccordionItem,
  UiAccordionTrigger,
} from '../components/ui/accordion';

@Component({
  selector: 'app-root',
  imports: [
    LYNX_ELEMENTS,
    UiAccordion,
    UiAccordionItem,
    UiAccordionTrigger,
    UiAccordionContent,
  ],
  template: `
    <ui-accordion>
      <ui-accordion-item value="shipping">
        <ui-accordion-trigger>
          How long does shipping take?
        </ui-accordion-trigger>
        <ui-accordion-content>
          <text class="text-sm text-muted-foreground">Three to five days.</text>
        </ui-accordion-content>
      </ui-accordion-item>
      <ui-accordion-item value="returns">
        <ui-accordion-trigger>Can I return an item?</ui-accordion-trigger>
        <ui-accordion-content>
          <text class="text-sm text-muted-foreground">
            Yes, within 30 days.
          </text>
        </ui-accordion-content>
      </ui-accordion-item>
    </ui-accordion>
  `,
})
export class App {}
  • Each item needs a unique value. All items start closed.
  • The trigger wraps its content in <text> and adds an arrow, so pass plain text.
  • Content shows only while its item is open. It slides and fades in as the item opens.

Several open at once

<ui-accordion type="multiple">…</ui-accordion>

With the default single, opening an item closes the others.

Control from code

src/app/faq.ts
import { Component, viewChild } from '@angular/core';
import { LYNX_ELEMENTS } from '@blotch/angular-lynx';
import {
  UiAccordion,
  UiAccordionContent,
  UiAccordionItem,
  UiAccordionTrigger,
} from '../components/ui/accordion';

@Component({
  selector: 'app-faq',
  imports: [
    LYNX_ELEMENTS,
    UiAccordion,
    UiAccordionItem,
    UiAccordionTrigger,
    UiAccordionContent,
  ],
  template: `
    <text class="text-sm text-primary" (bindtap)="showReturns()">
      Read the returns policy
    </text>
    <ui-accordion>
      <ui-accordion-item value="returns">
        <ui-accordion-trigger>Can I return an item?</ui-accordion-trigger>
        <ui-accordion-content>
          <text class="text-sm text-muted-foreground">
            Yes, within 30 days.
          </text>
        </ui-accordion-content>
      </ui-accordion-item>
    </ui-accordion>
  `,
})
export class Faq {
  readonly faq = viewChild.required(UiAccordion);

  protected showReturns(): void {
    if (!this.faq().isExpanded('returns')) {
      this.faq().toggle('returns');
    }
  }
}

UiAccordion has two public methods: toggle(value) opens or closes an item, and isExpanded(value) says whether it's open. The open values are in its expandedItems signal, a Set<string>.

API

UiAccordion

InputTypeDefaultDescription
type'single' | 'multiple''single'Whether opening an item closes the others.
classstring''Extra Tailwind classes for the container.

No outputs.

UiAccordionItem

InputTypeDefaultDescription
valuestringRequiredIdentifies the item. Unique per accordion.
classstring''Extra Tailwind classes for the item.

No outputs.

All other sub-components (UiAccordionTrigger, UiAccordionContent) accept class.

  • Collapsible: a single section that opens and closes
  • Tabs: show one panel at a time with a tab bar