|
| 1 | +<docs-decorative-header title="Accordion"> |
| 2 | +</docs-decorative-header> |
| 3 | + |
| 4 | +<docs-pill-row> |
| 5 | + <docs-pill href="https://www.w3.org/WAI/ARIA/apg/patterns/accordion/" title="Accordion ARIA pattern"/> |
| 6 | + <docs-pill href="/api?query=accordion#angular_aria_accordion" title="Accordion API Reference"/> |
| 7 | +</docs-pill-row> |
| 8 | + |
| 9 | +## Overview |
| 10 | + |
| 11 | +An accordion organizes related content into expandable and collapsible sections, reducing page scrolling and helping users focus on relevant information. Each section has a trigger button and a content panel. Clicking a trigger toggles the visibility of its associated panel. |
| 12 | + |
| 13 | +<docs-code-multifile preview hideCode path="adev/src/content/examples/aria/accordion/src/single-expansion/basic/app/app.component.ts"> |
| 14 | + <docs-code header="TS" path="adev/src/content/examples/aria/accordion/src/single-expansion/basic/app/app.component.ts"/> |
| 15 | + <docs-code header="HTML" path="adev/src/content/examples/aria/accordion/src/single-expansion/basic/app/app.component.html"/> |
| 16 | + <docs-code header="CSS" path="adev/src/content/examples/aria/accordion/src/single-expansion/basic/app/app.component.css"/> |
| 17 | +</docs-code-multifile> |
| 18 | + |
| 19 | +## Usage |
| 20 | + |
| 21 | +Accordions work well for organizing content into logical groups where users typically need to view one section at a time. |
| 22 | + |
| 23 | +**Use accordions when:** |
| 24 | + |
| 25 | +- Displaying FAQs with multiple questions and answers |
| 26 | +- Organizing long forms into manageable sections |
| 27 | +- Reducing scrolling on content-heavy pages |
| 28 | +- Progressively disclosing related information |
| 29 | + |
| 30 | +**Avoid accordions when:** |
| 31 | + |
| 32 | +- Building navigation menus (use the [Menu](guide/aria/menu) component instead) |
| 33 | +- Creating tabbed interfaces (use the [Tabs](guide/aria/tabs) component instead) |
| 34 | +- Showing a single collapsible section (use a disclosure pattern instead) |
| 35 | +- Users need to see multiple sections simultaneously (consider a different layout) |
| 36 | + |
| 37 | +## Features |
| 38 | + |
| 39 | +- **Expansion modes** - Control whether one or multiple panels can be open at the same time |
| 40 | +- **Keyboard navigation** - Navigate between triggers using arrow keys, Home, and End |
| 41 | +- **Lazy rendering** - Content is only created when a panel first expands, improving initial load performance |
| 42 | +- **Disabled states** - Disable the entire group or individual triggers |
| 43 | +- **Focus management** - Control whether disabled items can receive keyboard focus |
| 44 | +- **Programmatic control** - Expand, collapse, or toggle panels from your component code |
| 45 | +- **RTL support** - Automatic support for right-to-left languages |
| 46 | + |
| 47 | +## Examples |
| 48 | + |
| 49 | +### Single expansion mode |
| 50 | + |
| 51 | +Set `[multiExpandable]="false"` to allow only one panel to be open at a time. Opening a new panel automatically closes any previously open panel. |
| 52 | + |
| 53 | +<docs-tab-group> |
| 54 | + <docs-tab label="Basic"> |
| 55 | + <docs-code-multifile preview hideCode path="adev/src/content/examples/aria/accordion/src/single-expansion/basic/app/app.component.ts"> |
| 56 | + <docs-code header="TS" path="adev/src/content/examples/aria/accordion/src/single-expansion/basic/app/app.component.ts"/> |
| 57 | + <docs-code header="HTML" path="adev/src/content/examples/aria/accordion/src/single-expansion/basic/app/app.component.html"/> |
| 58 | + <docs-code header="CSS" path="adev/src/content/examples/aria/accordion/src/single-expansion/basic/app/app.component.css"/> |
| 59 | + </docs-code-multifile> |
| 60 | + </docs-tab> |
| 61 | + <docs-tab label="Material"> |
| 62 | + <docs-code-multifile preview hideCode path="adev/src/content/examples/aria/accordion/src/single-expansion/material/app/app.component.ts"> |
| 63 | + <docs-code header="TS" path="adev/src/content/examples/aria/accordion/src/single-expansion/material/app/app.component.ts"/> |
| 64 | + <docs-code header="HTML" path="adev/src/content/examples/aria/accordion/src/single-expansion/material/app/app.component.html"/> |
| 65 | + <docs-code header="CSS" path="adev/src/content/examples/aria/accordion/src/single-expansion/material/app/app.component.css"/> |
| 66 | + </docs-code-multifile> |
| 67 | + </docs-tab> |
| 68 | + <docs-tab label="Retro"> |
| 69 | + <docs-code-multifile preview hideCode path="adev/src/content/examples/aria/accordion/src/single-expansion/retro/app/app.component.ts"> |
| 70 | + <docs-code header="TS" path="adev/src/content/examples/aria/accordion/src/single-expansion/retro/app/app.component.ts"/> |
| 71 | + <docs-code header="HTML" path="adev/src/content/examples/aria/accordion/src/single-expansion/retro/app/app.component.html"/> |
| 72 | + <docs-code header="CSS" path="adev/src/content/examples/aria/accordion/src/single-expansion/retro/app/app.component.css"/> |
| 73 | + </docs-code-multifile> |
| 74 | + </docs-tab> |
| 75 | +</docs-tab-group> |
| 76 | + |
| 77 | +This mode works well for FAQs or situations where you want users to focus on one answer at a time. |
| 78 | + |
| 79 | +### Multiple expansion mode |
| 80 | + |
| 81 | +Set `[multiExpandable]="true"` to allow multiple panels to be open simultaneously. Users can expand as many panels as needed without closing others. |
| 82 | + |
| 83 | +<docs-tab-group> |
| 84 | + <docs-tab label="Basic"> |
| 85 | + <docs-code-multifile preview hideCode path="adev/src/content/examples/aria/accordion/src/multi-expansion/basic/app/app.component.ts"> |
| 86 | + <docs-code header="TS" path="adev/src/content/examples/aria/accordion/src/multi-expansion/basic/app/app.component.ts"/> |
| 87 | + <docs-code header="HTML" path="adev/src/content/examples/aria/accordion/src/multi-expansion/basic/app/app.component.html"/> |
| 88 | + <docs-code header="CSS" path="adev/src/content/examples/aria/accordion/src/multi-expansion/basic/app/app.component.css"/> |
| 89 | + </docs-code-multifile> |
| 90 | + </docs-tab> |
| 91 | + <docs-tab label="Material"> |
| 92 | + <docs-code-multifile preview hideCode path="adev/src/content/examples/aria/accordion/src/multi-expansion/material/app/app.component.ts"> |
| 93 | + <docs-code header="TS" path="adev/src/content/examples/aria/accordion/src/multi-expansion/material/app/app.component.ts"/> |
| 94 | + <docs-code header="HTML" path="adev/src/content/examples/aria/accordion/src/multi-expansion/material/app/app.component.html"/> |
| 95 | + <docs-code header="CSS" path="adev/src/content/examples/aria/accordion/src/multi-expansion/material/app/app.component.css"/> |
| 96 | + </docs-code-multifile> |
| 97 | + </docs-tab> |
| 98 | + <docs-tab label="Retro"> |
| 99 | + <docs-code-multifile preview hideCode path="adev/src/content/examples/aria/accordion/src/multi-expansion/retro/app/app.component.ts"> |
| 100 | + <docs-code header="TS" path="adev/src/content/examples/aria/accordion/src/multi-expansion/retro/app/app.component.ts"/> |
| 101 | + <docs-code header="HTML" path="adev/src/content/examples/aria/accordion/src/multi-expansion/retro/app/app.component.html"/> |
| 102 | + <docs-code header="CSS" path="adev/src/content/examples/aria/accordion/src/multi-expansion/retro/app/app.component.css"/> |
| 103 | + </docs-code-multifile> |
| 104 | + </docs-tab> |
| 105 | +</docs-tab-group> |
| 106 | + |
| 107 | +This mode is useful for form sections or when users need to compare content across multiple panels. |
| 108 | + |
| 109 | +NOTE: The `multiExpandable` input defaults to `true`. Set it to `false` explicitly if you want single expansion behavior. |
| 110 | + |
| 111 | +### Disabled accordion items |
| 112 | + |
| 113 | +Disable specific triggers using the `disabled` input. Control how disabled items behave during keyboard navigation using the `softDisabled` input on the accordion group. |
| 114 | + |
| 115 | +<docs-tab-group> |
| 116 | + <docs-tab label="Basic"> |
| 117 | + <docs-code-multifile preview hideCode path="adev/src/content/examples/aria/accordion/src/disabled-focusable/basic/app/app.component.ts"> |
| 118 | + <docs-code header="TS" path="adev/src/content/examples/aria/accordion/src/disabled-focusable/basic/app/app.component.ts"/> |
| 119 | + <docs-code header="HTML" path="adev/src/content/examples/aria/accordion/src/disabled-focusable/basic/app/app.component.html"/> |
| 120 | + <docs-code header="CSS" path="adev/src/content/examples/aria/accordion/src/disabled-focusable/basic/app/app.component.css"/> |
| 121 | + </docs-code-multifile> |
| 122 | + </docs-tab> |
| 123 | + <docs-tab label="Material"> |
| 124 | + <docs-code-multifile preview hideCode path="adev/src/content/examples/aria/accordion/src/disabled-focusable/material/app/app.component.ts"> |
| 125 | + <docs-code header="TS" path="adev/src/content/examples/aria/accordion/src/disabled-focusable/material/app/app.component.ts"/> |
| 126 | + <docs-code header="HTML" path="adev/src/content/examples/aria/accordion/src/disabled-focusable/material/app/app.component.html"/> |
| 127 | + <docs-code header="CSS" path="adev/src/content/examples/aria/accordion/src/disabled-focusable/material/app/app.component.css"/> |
| 128 | + </docs-code-multifile> |
| 129 | + </docs-tab> |
| 130 | + <docs-tab label="Retro"> |
| 131 | + <docs-code-multifile preview hideCode path="adev/src/content/examples/aria/accordion/src/disabled-focusable/retro/app/app.component.ts"> |
| 132 | + <docs-code header="TS" path="adev/src/content/examples/aria/accordion/src/disabled-focusable/retro/app/app.component.ts"/> |
| 133 | + <docs-code header="HTML" path="adev/src/content/examples/aria/accordion/src/disabled-focusable/retro/app/app.component.html"/> |
| 134 | + <docs-code header="CSS" path="adev/src/content/examples/aria/accordion/src/disabled-focusable/retro/app/app.component.css"/> |
| 135 | + </docs-code-multifile> |
| 136 | + </docs-tab> |
| 137 | +</docs-tab-group> |
| 138 | + |
| 139 | +When `[softDisabled]="true"` (the default), disabled items can receive focus but cannot be activated. When `[softDisabled]="false"`, disabled items are skipped entirely during keyboard navigation. |
| 140 | + |
| 141 | +### Lazy content rendering |
| 142 | + |
| 143 | +Use the `ngAccordionContent` directive on an `ng-template` to defer rendering content until the panel first expands. This improves performance for accordions with heavy content like images, charts, or complex components. |
| 144 | + |
| 145 | +```angular-html |
| 146 | +<div ngAccordionGroup> |
| 147 | + <div> |
| 148 | + <button ngAccordionTrigger panelId="item-1"> |
| 149 | + Trigger Text |
| 150 | + </button> |
| 151 | + <div ngAccordionPanel panelId="item-1"> |
| 152 | + <ng-template ngAccordionContent> |
| 153 | + <!-- This content only renders when the panel first opens --> |
| 154 | + <img src="large-image.jpg" alt="Description"> |
| 155 | + <app-expensive-component /> |
| 156 | + </ng-template> |
| 157 | + </div> |
| 158 | + </div> |
| 159 | +</div> |
| 160 | +``` |
| 161 | + |
| 162 | +By default, content remains in the DOM after the panel collapses. Set `[preserveContent]="false"` to remove the content from the DOM when the panel closes. |
| 163 | + |
| 164 | +## APIs |
| 165 | + |
| 166 | +### AccordionGroup |
| 167 | + |
| 168 | +The container directive that manages keyboard navigation and expansion behavior for a group of accordion items. |
| 169 | + |
| 170 | +#### Inputs |
| 171 | + |
| 172 | +| Property | Type | Default | Description | |
| 173 | +| ----------------- | --------- | ------- | ------------------------------------------------------------------------- | |
| 174 | +| `disabled` | `boolean` | `false` | Disables all triggers in the group | |
| 175 | +| `multiExpandable` | `boolean` | `true` | Whether multiple panels can be expanded simultaneously | |
| 176 | +| `softDisabled` | `boolean` | `true` | When `true`, disabled items are focusable. When `false`, they are skipped | |
| 177 | +| `wrap` | `boolean` | `false` | Whether keyboard navigation wraps from last to first item and vice versa | |
| 178 | + |
| 179 | +#### Methods |
| 180 | + |
| 181 | +| Method | Parameters | Description | |
| 182 | +| ------------- | ---------- | ---------------------------------------------------------------- | |
| 183 | +| `expandAll` | none | Expands all panels (only works when `multiExpandable` is `true`) | |
| 184 | +| `collapseAll` | none | Collapses all panels | |
| 185 | + |
| 186 | +### AccordionTrigger |
| 187 | + |
| 188 | +The directive applied to the button element that toggles panel visibility. |
| 189 | + |
| 190 | +#### Inputs |
| 191 | + |
| 192 | +| Property | Type | Default | Description | |
| 193 | +| ---------- | --------- | ------- | -------------------------------------------------------------- | |
| 194 | +| `id` | `string` | auto | Unique identifier for the trigger | |
| 195 | +| `panelId` | `string` | — | **Required.** Must match the `panelId` of the associated panel | |
| 196 | +| `disabled` | `boolean` | `false` | Disables this trigger | |
| 197 | +| `expanded` | `boolean` | `false` | Whether the panel is expanded (supports two-way binding) | |
| 198 | + |
| 199 | +#### Signals |
| 200 | + |
| 201 | +| Property | Type | Description | |
| 202 | +| -------- | ----------------- | --------------------------------------- | |
| 203 | +| `active` | `Signal<boolean>` | Whether the trigger currently has focus | |
| 204 | + |
| 205 | +#### Methods |
| 206 | + |
| 207 | +| Method | Parameters | Description | |
| 208 | +| ---------- | ---------- | --------------------------------- | |
| 209 | +| `expand` | none | Expands the associated panel | |
| 210 | +| `collapse` | none | Collapses the associated panel | |
| 211 | +| `toggle` | none | Toggles the panel expansion state | |
| 212 | + |
| 213 | +### AccordionPanel |
| 214 | + |
| 215 | +The directive applied to the element containing the collapsible content. |
| 216 | + |
| 217 | +#### Inputs |
| 218 | + |
| 219 | +| Property | Type | Default | Description | |
| 220 | +| ----------------- | --------- | ------- | ---------------------------------------------------------------- | |
| 221 | +| `id` | `string` | auto | Unique identifier for the panel | |
| 222 | +| `panelId` | `string` | — | **Required.** Must match the `panelId` of the associated trigger | |
| 223 | +| `preserveContent` | `boolean` | `true` | Whether to keep content in DOM after panel collapses | |
| 224 | + |
| 225 | +#### Signals |
| 226 | + |
| 227 | +| Property | Type | Description | |
| 228 | +| --------- | ----------------- | --------------------------------------- | |
| 229 | +| `visible` | `Signal<boolean>` | Whether the panel is currently expanded | |
| 230 | + |
| 231 | +#### Methods |
| 232 | + |
| 233 | +| Method | Parameters | Description | |
| 234 | +| ---------- | ---------- | --------------------------- | |
| 235 | +| `expand` | none | Expands this panel | |
| 236 | +| `collapse` | none | Collapses this panel | |
| 237 | +| `toggle` | none | Toggles the expansion state | |
| 238 | + |
| 239 | +### AccordionContent |
| 240 | + |
| 241 | +The structural directive applied to an `ng-template` inside an accordion panel to enable lazy rendering. |
| 242 | + |
| 243 | +This directive has no inputs, outputs, or methods. Apply it to an `ng-template` element: |
| 244 | + |
| 245 | +```angular-html |
| 246 | +<div ngAccordionPanel panelId="item-1"> |
| 247 | + <ng-template ngAccordionContent> |
| 248 | + <!-- Content here is lazily rendered --> |
| 249 | + </ng-template> |
| 250 | +</div> |
| 251 | +``` |
0 commit comments