Skip to content

Commit 30c7274

Browse files
committed
feat(@angular/cli): add examples for @angular/aria
Adds a comprehensive set of nine new examples for the `@angular/aria` package. These examples demonstrate the usage of directives for common accessibility patterns, including accordions, comboboxes, menus, tabs, toolbars, and trees.
1 parent 52ace04 commit 30c7274

File tree

9 files changed

+1741
-0
lines changed

9 files changed

+1741
-0
lines changed
Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
---
2+
title: Accordion
3+
summary: Demonstrates how to create an accessible accordion component using @angular/aria directives.
4+
keywords:
5+
- Accordion
6+
- AccordionGroup
7+
- AccordionTrigger
8+
- AccordionPanel
9+
- AccordionContent
10+
- ngAccordionGroup
11+
- ngAccordionTrigger
12+
- ngAccordionPanel
13+
- ngAccordionContent
14+
required_packages:
15+
- '@angular/aria/accordion'
16+
related_concepts:
17+
- 'Accessibility'
18+
- 'A11y'
19+
- 'UI Patterns'
20+
- 'Aria'
21+
experimental: true
22+
---
23+
24+
## Purpose
25+
26+
The `@angular/aria/accordion` accordion directives provide the foundational logic and accessibility features for creating accordion-style UI elements. Accordion are used to organize related content into expandable and collapsible sections with a trigger button and a content panel.
27+
28+
## When to Use
29+
30+
Use the Angular Aria accordion directives when you need to display a list of headers that can show or hide associated content panels. This pattern is ideal for FAQs, long-form content segmentation, or progressively disclosing information to reduce page scrolling. Avoid using accordions for general navigation menus, tabbed interfaces, or whenever multiple sections of content must be simultaneously visible.
31+
32+
## Key Concepts
33+
34+
- **AccordionGroup**: A directive that acts as the container for a set of accordion items. It manages the overall state and interactions of the accordion, such as keyboard navigation and expansion mode.
35+
- **AccordionTrigger**: A directive that represents the trigger button for an accordion item. It controls the expansion state of an associated `ngAccordionPanel`.
36+
- **AccordionPanel**: A directive that represents the content panel of an accordion item. It is controlled by an associated `ngAccordionTrigger`.
37+
- **AccordionContent**: A structural directive that marks the `ng-template` to be used as the content for an `ngAccordionPanel`. This content can be lazily loaded.
38+
39+
## Example Files
40+
41+
This example demonstrates a basic, accessible accordion with two items that allows only one panel to be open at a time.
42+
43+
### accordion-example.ts
44+
45+
This file defines the accordion component, imports the necessary `@angular/aria/accordion` directives, and provides the data for the accordion items.
46+
47+
```typescript
48+
import { ChangeDetectionStrategy, Component } from '@angular/core';
49+
import {
50+
AccordionGroup,
51+
AccordionTrigger,
52+
AccordionPanel,
53+
AccordionContent,
54+
} from '@angular/aria/accordion';
55+
56+
@Component({
57+
selector: 'accordion-example',
58+
templateUrl: 'accordion-example.html',
59+
styleUrls: ['accordion-example.css'],
60+
imports: [AccordionGroup, AccordionTrigger, AccordionPanel, AccordionContent],
61+
changeDetection: ChangeDetectionStrategy.OnPush,
62+
})
63+
export class AccordionExample {}
64+
```
65+
66+
### accordion-example.html
67+
68+
This template structures the accordion using the `ngAccordionGroup`, `ngAccordionTrigger`, `ngAccordionPanel`, and `ngAccordionContent` directives, binding the necessary ARIA attributes for accessibility.
69+
70+
```html
71+
<h1>Accordion Examples</h1>
72+
73+
<div ngAccordionGroup [multiExpandable]="false">
74+
<h3>
75+
<span ngAccordionTrigger panelId="item-1" #trigger1="ngAccordionTrigger">
76+
Accordion Heading 1
77+
<span
78+
aria-hidden="true"
79+
class="expand-icon"
80+
[class.expand-icon__expanded]="trigger1.expanded()"
81+
></span>
82+
</span>
83+
</h3>
84+
<div ngAccordionPanel panelId="item-1">
85+
<ng-template ngAccordionContent>
86+
<p>Accordion Content Here</p>
87+
</ng-template>
88+
</div>
89+
90+
<h3>
91+
<span ngAccordionTrigger panelId="item-2" #trigger2="ngAccordionTrigger">
92+
Accordion Heading 2
93+
<span
94+
aria-hidden="true"
95+
class="expand-icon"
96+
[class.expand-icon__expanded]="trigger2.expanded()"
97+
></span>
98+
</span>
99+
</h3>
100+
<div ngAccordionPanel panelId="item-2">
101+
<ng-template ngAccordionContent>
102+
<p>More Accordion Content Here</p>
103+
</ng-template>
104+
</div>
105+
</div>
106+
```
107+
108+
### accordion-example.css
109+
110+
This file provides basic styling to make the component visually function like an accordion, including focus indicators, icons, and transitions. Note that there are no disabled styles.
111+
112+
```css
113+
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
114+
115+
[ngAccordionGroup] {
116+
width: 300px;
117+
}
118+
119+
[ngAccordionTrigger] {
120+
display: flex;
121+
align-items: center;
122+
justify-content: space-between;
123+
width: 100%;
124+
margin: 0;
125+
padding: 12px 16px;
126+
}
127+
128+
h3 {
129+
margin: 0;
130+
position: relative;
131+
}
132+
133+
h3:focus-within::before,
134+
h3:hover::before {
135+
content: '';
136+
position: absolute;
137+
height: 100%;
138+
width: 2px;
139+
background-color: blue;
140+
top: 0;
141+
left: 0;
142+
}
143+
144+
h3:not(:first-of-type) {
145+
border-block-start: 1px solid lightgrey;
146+
}
147+
148+
p {
149+
padding: 1rem 2rem;
150+
}
151+
152+
[ngAccordionTrigger] svg {
153+
width: 24px;
154+
height: 24px;
155+
transition: transform 0.2s ease-in-out;
156+
transform: rotate(90deg);
157+
pointer-events: none;
158+
}
159+
160+
[ngAccordionTrigger][aria-expanded='true'] svg {
161+
transform: rotate(-90deg);
162+
}
163+
164+
.expand-icon {
165+
position: relative;
166+
width: 1rem;
167+
height: 1rem;
168+
flex-shrink: 0;
169+
margin-left: 1rem;
170+
}
171+
172+
.expand-icon::before,
173+
.expand-icon::after {
174+
content: '';
175+
position: absolute;
176+
width: 100%;
177+
height: 2px;
178+
top: 50%;
179+
background-color: black;
180+
transition: 0.3s ease-out;
181+
}
182+
183+
.expand-icon::after {
184+
transform: rotate(90deg);
185+
}
186+
.expand-icon__expanded::before {
187+
transform: translateY(-50%) rotate(-90deg);
188+
opacity: 0;
189+
}
190+
.expand-icon__expanded::after {
191+
transform: translateY(-50%) rotate(0);
192+
}
193+
```
194+
195+
## Usage Notes
196+
197+
- The core link between the header and the content is established by ensuring the `[ngAccordionTrigger]` panelId and the `[ngAccordionPanel]` panelId are identical (e.g., item-id).
198+
- The `[ngAccordionContent]` directive is applied to an `ng-template` to enable deferred rendering for performance optimization.
199+
- Disable triggers using the `disabled` input.

0 commit comments

Comments
 (0)