Skip to main content

Overview

The Accordion component provides a vertically stacked set of expandable/collapsible panels. It supports single or multiple panel expansion and includes smooth animations.

Component Selector

<magary-accordion />
The Accordion must be used with <magary-accordion-tab> child components.

Basic Usage

import { Component } from '@angular/core';
import { MagaryAccordion, MagaryAccordionTab } from 'ng-magary';

@Component({
  selector: 'app-demo',
  standalone: true,
  imports: [MagaryAccordion, MagaryAccordionTab],
  template: `
    <magary-accordion>
      <magary-accordion-tab header="Section 1">
        <p>Content for section 1</p>
      </magary-accordion-tab>
      <magary-accordion-tab header="Section 2">
        <p>Content for section 2</p>
      </magary-accordion-tab>
      <magary-accordion-tab header="Section 3">
        <p>Content for section 3</p>
      </magary-accordion-tab>
    </magary-accordion>
  `
})
export class DemoComponent {}

Multiple Panels Open

<magary-accordion [multiple]="true">
  <magary-accordion-tab header="Panel 1">
    <p>Content 1</p>
  </magary-accordion-tab>
  <magary-accordion-tab header="Panel 2">
    <p>Content 2</p>
  </magary-accordion-tab>
  <magary-accordion-tab header="Panel 3">
    <p>Content 3</p>
  </magary-accordion-tab>
</magary-accordion>

Pre-selected Panels

<magary-accordion>
  <magary-accordion-tab header="Panel 1" [(selected)]="true">
    <p>This panel is open by default</p>
  </magary-accordion-tab>
  <magary-accordion-tab header="Panel 2">
    <p>Content 2</p>
  </magary-accordion-tab>
</magary-accordion>

Disabled Panel

<magary-accordion>
  <magary-accordion-tab header="Enabled Panel">
    <p>You can toggle this panel</p>
  </magary-accordion-tab>
  <magary-accordion-tab header="Disabled Panel" [disabled]="true">
    <p>This panel cannot be toggled</p>
  </magary-accordion-tab>
</magary-accordion>

Properties

Accordion (Container)

multiple
boolean
default:"false"
When true, multiple panels can be expanded at the same time. When false, only one panel can be open (opening a new panel closes the previously open one)

AccordionTab (Child Component)

header
string
The header text displayed in the panel’s toggle button
selected
boolean
default:"false"
Whether the panel is expanded. Supports two-way binding with [(selected)]
disabled
boolean
default:"false"
When true, prevents the panel from being toggled

Events

Accordion Events

onOpen
output<MagaryAccordionTabChangeEvent>
Emitted when a panel is expanded. Event contains:
  • originalEvent: The DOM event (or null)
  • index: Index of the opened panel
onClose
output<MagaryAccordionTabChangeEvent>
Emitted when a panel is collapsed. Event contains:
  • originalEvent: The DOM event (or null)
  • index: Index of the closed panel

Two-Way Binding

You can control panel state programmatically using two-way binding:
import { Component } from '@angular/core';

@Component({
  template: `
    <magary-accordion>
      <magary-accordion-tab
        header="Controlled Panel"
        [(selected)]="isOpen"
      >
        <p>Panel content</p>
      </magary-accordion-tab>
    </magary-accordion>
    
    <button (click)="isOpen = !isOpen">
      {{ isOpen ? 'Close' : 'Open' }} Panel
    </button>
  `
})
export class DemoComponent {
  isOpen = false;
}

Animations

The Accordion features smooth expand/collapse animations using Angular animations:
  • Height transition from 0 to auto
  • Opacity fade in/out
  • Cubic bezier easing for natural motion

Accessibility Features

  • ARIA accordion pattern with proper roles
  • Keyboard support for toggling panels
  • aria-expanded state on headers
  • aria-controls association between headers and content
  • aria-labelledby on content panels
  • Disabled state handling
  • Focus management

Keyboard Navigation

KeyAction
Enter / SpaceToggle the focused panel
TabMove focus to next focusable element
Shift + TabMove focus to previous element

Styling

The Accordion uses the following CSS classes:
  • .magary-accordion: Main container
  • .magary-accordion-tab: Individual accordion panel
  • .magary-accordion-header: Panel header/toggle button
  • .magary-accordion-content: Panel content area
  • .selected: Applied to expanded panels
  • .disabled: Applied to disabled panels

Complete Example

import { Component, signal } from '@angular/core';
import { MagaryAccordion, MagaryAccordionTab } from 'ng-magary';
import { CommonModule } from '@angular/common';

interface FAQItem {
  question: string;
  answer: string;
  expanded?: boolean;
}

@Component({
  selector: 'app-accordion-demo',
  standalone: true,
  imports: [MagaryAccordion, MagaryAccordionTab, CommonModule],
  template: `
    <div class="demo-container">
      <h3>Single Panel (Default)</h3>
      <magary-accordion (onOpen)="onPanelOpen($event)">
        <magary-accordion-tab header="What is Angular?">
          <p>
            Angular is a platform and framework for building single-page
            client applications using HTML and TypeScript.
          </p>
        </magary-accordion-tab>
        <magary-accordion-tab header="What is TypeScript?">
          <p>
            TypeScript is a strongly typed programming language that builds
            on JavaScript, giving you better tooling at any scale.
          </p>
        </magary-accordion-tab>
        <magary-accordion-tab header="What are Components?">
          <p>
            Components are the fundamental building blocks of Angular
            applications. They control a portion of the screen called a view.
          </p>
        </magary-accordion-tab>
      </magary-accordion>

      <h3>Multiple Panels Open</h3>
      <magary-accordion [multiple]="true">
        <magary-accordion-tab header="Features" [(selected)]="true">
          <ul>
            <li>Component-based architecture</li>
            <li>TypeScript support</li>
            <li>Dependency injection</li>
            <li>Reactive forms</li>
          </ul>
        </magary-accordion-tab>
        <magary-accordion-tab header="Benefits">
          <ul>
            <li>High performance</li>
            <li>Strong typing</li>
            <li>Great tooling</li>
            <li>Large ecosystem</li>
          </ul>
        </magary-accordion-tab>
        <magary-accordion-tab header="Getting Started">
          <p>Install Angular CLI: <code>npm install -g @angular/cli</code></p>
          <p>Create new app: <code>ng new my-app</code></p>
        </magary-accordion-tab>
      </magary-accordion>

      <h3>With Disabled Panels</h3>
      <magary-accordion>
        <magary-accordion-tab header="Available Panel">
          <p>This panel can be toggled.</p>
        </magary-accordion-tab>
        <magary-accordion-tab header="Coming Soon" [disabled]="true">
          <p>This content is not yet available.</p>
        </magary-accordion-tab>
        <magary-accordion-tab header="Another Panel">
          <p>This panel is also available.</p>
        </magary-accordion-tab>
      </magary-accordion>

      <h3>Programmatic Control</h3>
      <button (click)="togglePanel()">Toggle First Panel</button>
      <magary-accordion>
        <magary-accordion-tab
          header="Controlled Panel"
          [(selected)]="panelOpen"
        >
          <p>This panel is controlled programmatically.</p>
          <p>Current state: {{ panelOpen ? 'Open' : 'Closed' }}</p>
        </magary-accordion-tab>
        <magary-accordion-tab header="Regular Panel">
          <p>This panel works normally.</p>
        </magary-accordion-tab>
      </magary-accordion>

      <h3>Dynamic Content</h3>
      <magary-accordion>
        <magary-accordion-tab
          *ngFor="let item of faqItems; let i = index"
          [header]="item.question"
          [(selected)]="item.expanded"
        >
          <p>{{ item.answer }}</p>
        </magary-accordion-tab>
      </magary-accordion>
    </div>
  `
})
export class AccordionDemoComponent {
  panelOpen = signal(false);
  
  faqItems: FAQItem[] = [
    {
      question: 'How do I install Magary?',
      answer: 'Install using npm: npm install ng-magary',
      expanded: false
    },
    {
      question: 'Is Magary free to use?',
      answer: 'Yes, Magary is open source and free to use.',
      expanded: false
    },
    {
      question: 'Does it work with standalone components?',
      answer: 'Yes, all Magary components are standalone.',
      expanded: false
    }
  ];

  togglePanel() {
    this.panelOpen.update(v => !v);
  }

  onPanelOpen(event: { index: number }) {
    console.log('Panel opened:', event.index);
  }
}

Type Definitions

interface MagaryAccordionTabChangeEvent {
  originalEvent: Event | null;
  index: number;
}

Build docs developers (and LLMs) love