Skip to content

Commit f677eb5

Browse files
authored
Merge branch 'main' into SWC-370
2 parents 6416156 + b839f70 commit f677eb5

File tree

3 files changed

+495
-58
lines changed

3 files changed

+495
-58
lines changed

packages/sidenav/README.md

Lines changed: 153 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
## Description
1+
## Overview
22

33
Side navigation allows users to locate information and features within the UI.
44
It can be used for either hierarchical or flat navigation, and gives the ability
@@ -7,37 +7,67 @@ prioritize content or features based on your users’ needs in a way that
77
maintains clear, persistent visibility. Use side navigation within the context
88
of larger elements and mechanisms within the app frame.
99

10-
`<sp-sidenav>` elements accept both `<sp-sidenav-item>` and `<sp-sidenav-heading>` elements as children in order to construct a hierarchy of navigation elements. [`<sp-sidenav-item>`](./components/sidenav-item) elements will place themselves as a togglable child of their `<sp-sidenav>` element parent. `<sp-sidenav-heading>` elements will create visible structure by grouping their child `<sp-sidenav-item>` children under a non-interactive heading.
10+
`<sp-sidenav>` elements accept both `<sp-sidenav-item>` and `<sp-sidenav-heading>` elements as children in order to construct a hierarchy of navigation elements. [`<sp-sidenav-item>`](/components/sidenav-item/) elements will place themselves as a togglable child of their `<sp-sidenav>` element parent. [`<sp-sidenav-heading>`](/components/sidenav-heading/) elements will create visible structure by grouping their `<sp-sidenav-item>` children under a non-interactive heading.
11+
12+
[View the design documentation for this component.](https://spectrum.adobe.com/page/side-navigation/)
1113

1214
### Usage
1315

1416
[![See it on NPM!](https://img.shields.io/npm/v/@spectrum-web-components/sidenav?style=for-the-badge)](https://www.npmjs.com/package/@spectrum-web-components/sidenav)
1517
[![How big is this package in your project?](https://img.shields.io/bundlephobia/minzip/@spectrum-web-components/sidenav?style=for-the-badge)](https://bundlephobia.com/result?p=@spectrum-web-components/sidenav)
1618
[![Try it on Stackblitz](https://img.shields.io/badge/Try%20it%20on-Stackblitz-blue?style=for-the-badge)](https://stackblitz.com/edit/vitejs-vite-q3w6kjxv)
1719

18-
```
20+
```bash
1921
yarn add @spectrum-web-components/sidenav
2022
```
2123

2224
Import the side effectful registration of `<sp-sidenav>`, `<sp-sidenav-heading>`, or `<sp-sidenav-item>` via:
2325

24-
```
26+
```js
2527
import '@spectrum-web-components/sidenav/sp-sidenav.js';
2628
import '@spectrum-web-components/sidenav/sp-sidenav-heading.js';
2729
import '@spectrum-web-components/sidenav/sp-sidenav-item.js';
2830
```
2931

3032
When looking to leverage the `Sidenav`, `SidenavHeading`, or `SidenavItem` base classes as a type and/or for extension purposes, do so via:
3133

32-
```
34+
```js
3335
import {
3436
Sidenav,
3537
SidenavHeading,
36-
SidenavItem
38+
SidenavItem,
3739
} from '@spectrum-web-components/sidenav';
3840
```
3941

40-
## Example
42+
### Anatomy
43+
44+
The side navigation consists of several key parts:
45+
46+
- A container element that manages the side navigation behavior
47+
- Individual side navigation items that may or may not be expandable
48+
- Children side navigation items that are revealed when a parent item is expanded
49+
- Optional heading with a label
50+
51+
```html live-demo
52+
<sp-sidenav>
53+
<sp-sidenav-heading label="Piano"></sp-sidenav-heading>
54+
<sp-sidenav-item label="Treble"></sp-sidenav-item>
55+
<sp-sidenav-item label="Bass"></sp-sidenav-item>
56+
<sp-sidenav-item disabled label="Grand staff"></sp-sidenav-item>
57+
</sp-sidenav>
58+
```
59+
60+
### Options
61+
62+
<sp-tabs selected="default" auto label="Side navigation options">
63+
<sp-tab value="default">Default (single-level)</sp-tab>
64+
<sp-tab-panel value="default">
65+
66+
Make sure to use the right option for the context and user needs. Don’t mix behavior, styles, or variations together in a single navigation menu. Follow these guidelines:
67+
68+
- When navigation is simple, use the single level side navigation.
69+
- When navigation is simple but categorical, use the single level side navigation with headers.
70+
- When navigation is expansive, hierarchical, and/or you need progressive disclosure in the menu behavior, use the multi-level side navigation. Up to three levels of navigation are supported.
4171

4272
```html
4373
<sp-sidenav defaultValue="Docs">
@@ -49,7 +79,7 @@ import {
4979
></sp-sidenav-item>
5080
<sp-sidenav-item
5181
value="Guides"
52-
href="/guides/getting_started"
82+
href="/guides"
5383
label="Guides"
5484
></sp-sidenav-item>
5585
<sp-sidenav-item
@@ -65,71 +95,50 @@ import {
6595
></sp-sidenav-item>
6696
<sp-sidenav-item
6797
value="Releases"
68-
href="http://git.corp.adobe.com/React/react-spectrum/releases"
98+
href="/releases"
6999
target="_blank"
70100
label="Releases"
71101
disabled
72102
></sp-sidenav-item>
73103
<sp-sidenav-item
74104
value="GitHub"
75-
href="http://git.corp.adobe.com/React/react-spectrum"
105+
href="/github"
76106
target="_blank"
77107
label="Github"
78108
></sp-sidenav-item>
79109
</sp-sidenav>
80110
```
81111

82-
## Multi-level
83-
84-
Use this variation when you have multiple layers of hierarchical navigation. The
85-
headers are styled differently and possess the same interactive behavior as a
86-
treeview; clicking the header opens and collapses the children navigation items.
87-
In the instances where a top-level navigation item has no children, clicking
88-
will send the user to the location of the item.
89-
90-
```html
91-
<sp-sidenav variant="multilevel" defaultValue="Layout">
92-
<sp-sidenav-item value="Guidelines" label="Guidelines">
93-
</sp-sidenav-item>
94-
<sp-sidenav-item value="Styles" label="Styles" expanded>
95-
<sp-sidenav-item value="Color" label="Color">
96-
</sp-sidenav-item>
97-
<sp-sidenav-item value="Grid" label="Grid" expanded>
98-
<sp-sidenav-item value="Layout" label="Layout">
99-
</sp-sidenav-item>
100-
<sp-sidenav-item value="Responsive" label="Responsive">
101-
</sp-sidenav-item>
102-
</sp-sidenav-item>
103-
<sp-sidenav-item value="Typography" label="Typography">
104-
</sp-sidenav-item>
105-
</sp-sidenav-item>
106-
<sp-sidenav-item value="Elements" label="Elements">
107-
</sp-sidenav-item>
108-
<sp-sidenav-item value="Patterns" label="Patterns">
109-
</sp-sidenav-item>
110-
</sp-sidenav-itm>
111-
```
112+
</sp-tab-panel>
113+
<sp-tab value="icon-single">Single-level with icons</sp-tab>
114+
<sp-tab-panel value="icon-single">
112115

113-
## Icon
116+
In single-level side navigation, do not mix icon usage between side nav items. Either all side nav items have icons, or no items have icons. In cases where the navigation content might be user-generated, stick to text-only navigation items.
114117

115118
```html
116119
<sp-sidenav>
117120
<sp-sidenav-item value="Section Title 1" label="Section Title 1">
118121
<sp-icon-star slot="icon"></sp-icon-star>
119122
</sp-sidenav-item>
120-
<sp-sidenav-item value="Section Title 2" label="Section Title 2">
123+
<sp-sidenav-item value="Section Title 2" label="Section Title 2" expanded>
121124
<sp-icon-star slot="icon"></sp-icon-star>
122125
</sp-sidenav-item>
123-
<sp-sidenav-item value="Section Title 3" label="Section Title 3">
126+
<sp-sidenav-item value="Section Title 3" label="Section Title 3" expanded>
124127
<sp-icon-star slot="icon"></sp-icon-star>
125128
</sp-sidenav-item>
126129
</sp-sidenav>
127130
```
128131

129-
## Heading
132+
</sp-tab-panel>
133+
<sp-tab value="headings">With headings</sp-tab>
134+
<sp-tab-panel value="headings">
135+
136+
Use headings in single level side navigation when it's beneficial to group navigation items into categories. The headings are not interactive. If items don’t fall into a category, place them at the top. When using the heading variation, an entire category should either all have icons or all be text-only.
137+
138+
Although headings can be used in multi-level side navigation, they can only be used as first-level items, and are not to be nested.
130139

131140
```html
132-
<sp-sidenav variant="multilevel">
141+
<sp-sidenav>
133142
<sp-sidenav-item value="Section 1" label="Section 1"></sp-sidenav-item>
134143
<sp-sidenav-item value="Section 2" label="Section 2"></sp-sidenav-item>
135144
<sp-sidenav-heading label="Category 1">
@@ -143,6 +152,103 @@ will send the user to the location of the item.
143152
</sp-sidenav>
144153
```
145154

146-
## Accessibility
155+
</sp-tab-panel>
156+
<sp-tab value="multilevel">Multi-level</sp-tab>
157+
<sp-tab-panel value="multilevel">
158+
159+
Use `variant="multilevel"` when you have multiple layers of hierarchical navigation.
160+
In the instances where a top-level navigation item has no children, clicking
161+
will send the user to the location of the item. Additionally, headings can be used
162+
in multi-level side navigation, but they can only be used as first-level items, and are not to be nested.
163+
164+
Up to three levels of navigation are supported.
165+
166+
```html
167+
<sp-sidenav variant="multilevel" defaultValue="Layout">
168+
<sp-sidenav-item value="Guidelines" label="Guidelines"></sp-sidenav-item>
169+
<sp-sidenav-heading value="Styles" label="Styles">
170+
<sp-sidenav-item value="Color" label="Color"></sp-sidenav-item>
171+
<sp-sidenav-item value="Grid" label="Grid" expanded>
172+
<sp-sidenav-item value="Layout" label="Layout"></sp-sidenav-item>
173+
<sp-sidenav-item
174+
value="Responsive"
175+
label="Responsive"
176+
></sp-sidenav-item>
177+
</sp-sidenav-item>
178+
<sp-sidenav-item
179+
value="Typography"
180+
label="Typography"
181+
></sp-sidenav-item>
182+
</sp-sidenav-heading>
183+
<sp-sidenav-item value="Elements" label="Elements"></sp-sidenav-item>
184+
<sp-sidenav-item value="Patterns" label="Patterns"></sp-sidenav-item>
185+
</sp-sidenav>
186+
```
187+
188+
</sp-tab-panel>
189+
<sp-tab value="icon-multi">Multi-level with icons</sp-tab>
190+
<sp-tab-panel value="icon-multi">
191+
192+
In multi-level side navigation, icon and text-only navigation items can be used in combination, but only the first-level items can have icons to maintain visual clarity and hierarchy. Icons only appear on first-level items, and sublevels (second and third) should not include icons. In cases where the navigation content might be user-generated, stick to text-only navigation items.
193+
194+
#### Multi-level side navigation icon usage
195+
196+
- All icons: all items have icons
197+
- No icons: no items have icons
198+
- Mixed icons: only first-level items have icons; second and third-level items do not
199+
200+
```html
201+
<sp-sidenav>
202+
<sp-sidenav-item value="Section Title 1" label="Section Title 1">
203+
<sp-icon-star slot="icon"></sp-icon-star>
204+
<sp-sidenav-item
205+
value="Typography"
206+
label="Typography"
207+
></sp-sidenav-item>
208+
</sp-sidenav-item>
209+
<sp-sidenav-item value="Section Title 2" label="Section Title 2" expanded>
210+
<sp-icon-star slot="icon"></sp-icon-star>
211+
<sp-sidenav-item
212+
value="Iconography"
213+
label="Iconography"
214+
></sp-sidenav-item>
215+
</sp-sidenav-item>
216+
<sp-sidenav-item value="Section Title 3" label="Section Title 3" expanded>
217+
<sp-icon-star slot="icon"></sp-icon-star>
218+
<sp-sidenav-item value="Patterns" label="Patterns" expanded>
219+
<sp-sidenav-item value="Forms" label="Forms"></sp-sidenav-item>
220+
<sp-sidenav-item value="Cards" label="Cards"></sp-sidenav-item>
221+
</sp-sidenav-item>
222+
</sp-sidenav-item>
223+
</sp-sidenav>
224+
```
225+
226+
</sp-tab-panel>
227+
</sp-tabs>
228+
229+
### Behaviors
230+
231+
When an side navigation item is programmatically selected in `variant="multilevel"`, all of its parent items automatically expand to reveal the selection path.
232+
233+
### Accessibility
234+
235+
When the `manage-tab-index` attribute is set on an `<sp-sidenav>` element, it will present its `<sp-sidenav-item>` children with a single tab-stop. This will leave items beyond the selected item (or when there is no focusable selected item), accessible via the up and down arrow keys. Items with expanded children that aren't selected lose focus when `manage-tab-index` is active.
236+
237+
#### Roles and ARIA attributes
238+
239+
- `<sp-sidenav>` renders a `<nav>` tag and implicitly sets `role="navigation"`
240+
- Optional `aria-label` is available for further identification
241+
- Individual items use `role="listitem"` automatically
242+
- Nested list containers (i.e. `<div>` tags) use `role="list"`
243+
- Nested item containers use `aria-labelledby` referencing their parent item's `id`
244+
- `aria-expanded="true/false"` indicates expand/collapse state for parent items
245+
- `aria-controls` on parent items is set to the `id` of their child `role="list"` containers when expanded
246+
- `aria-current="page"` indicates the currently selected item when it has an `href`
247+
- When the `<sp-sidenav>` includes the `disabled` property, the entire component receives `tabindex="-1"`
248+
- `aria-hidden="true"` is applied to all decorative icons
249+
250+
#### Keyboard interaction
147251

148-
When the `manage-tab-index` attribute is set on an `sp-sidenav` element then it will presents its child `sp-sidenav-item` children with a single tab-stop. This will leave items beyond the selected item, or first when there is no focusable selected item, will be accessibile via the up and down arrow keys.
252+
- `Tab` and `Shift + Tab` moves focus into or out of the side nav
253+
- If `manage-tab-index` is enabled, the up and down arrow keys will shift focus between all visible sidenav items
254+
- `Enter` selects a side nav item or toggles expansion for parent items
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
## Overview
2+
3+
`<sp-sidenav-heading>` elements will create visible structure by grouping their child `<sp-sidenav-item>` children under a non-interactive heading. Headings are used at the first level of navigation, and should not be used in any subsequent navigation level.
4+
5+
### Usage
6+
7+
[![See it on NPM!](https://img.shields.io/npm/v/@spectrum-web-components/sidenav?style=for-the-badge)](https://www.npmjs.com/package/@spectrum-web-components/sidenav)
8+
[![How big is this package in your project?](https://img.shields.io/bundlephobia/minzip/@spectrum-web-components/sidenav?style=for-the-badge)](https://bundlephobia.com/result?p=@spectrum-web-components/sidenav)
9+
10+
```bash
11+
yarn add @spectrum-web-components/sidenav
12+
```
13+
14+
Import the side effectful registration of `<sp-sidenav-heading>` via:
15+
16+
```js
17+
import '@spectrum-web-components/sidenav/sp-sidenav-heading.js';
18+
```
19+
20+
When looking to leverage the `SidenavHeading` base classes as a type and/or for extension purposes, do so via:
21+
22+
```js
23+
import { SidenavHeading } from '@spectrum-web-components/sidenav';
24+
```
25+
26+
### Anatomy
27+
28+
- **Label**: text content of the heading
29+
- **Default slot**: children `<sp-sidenav-item>` elements will be categorized under the heading element
30+
31+
### Options
32+
33+
<sp-tabs selected="single-level" auto label="Side nav heading options">
34+
<sp-tab value="single-level">Single-level with headings</sp-tab>
35+
<sp-tab-panel value="single-level">
36+
37+
Use a single level side navigation with headings when needing to group navigation items into categories. Headings are not interactive.
38+
39+
```html
40+
<sp-sidenav>
41+
<sp-sidenav-heading label="Docs heading">
42+
<sp-sidenav-item
43+
value="new-docs"
44+
label="New docs"
45+
href="/components/sidenav"
46+
></sp-sidenav-item>
47+
<sp-sidenav-item
48+
value="old-docs"
49+
label="Old docs"
50+
href="/components/sidenav"
51+
></sp-sidenav-item>
52+
</sp-sidenav-heading>
53+
</sp-sidenav>
54+
```
55+
56+
</sp-tab-panel>
57+
<sp-tab value="multi-level">Multi-level with headings</sp-tab>
58+
<sp-tab-panel value="multi-level">
59+
60+
In multi-level side navigation, headings can only be used at the first level of navigation. Do not nest headings within second or third level side nav items.
61+
62+
```html
63+
<sp-sidenav variant="multilevel">
64+
<sp-sidenav-heading label="Styles">
65+
<sp-sidenav-item value="Color" label="Color"></sp-sidenav-item>
66+
<sp-sidenav-item value="Grid" label="Grid"></sp-sidenav-item>
67+
<sp-sidenav-heading label="Heading styles">
68+
<sp-sidenav-item value="Typography" label="Typography" expanded>
69+
<sp-sidenav-item
70+
value="Display"
71+
label="Display headings"
72+
></sp-sidenav-item>
73+
<sp-sidenav-item value="H1" label="H1"></sp-sidenav-item>
74+
<sp-sidenav-item value="H2" label="H2"></sp-sidenav-item>
75+
</sp-sidenav-item>
76+
</sp-sidenav-heading>
77+
78+
<sp-sidenav-heading label="Font styles">
79+
<sp-sidenav-item value="Body" label="Body copy"></sp-sidenav-item>
80+
<sp-sidenav-item value="Details" label="Details"></sp-sidenav-item>
81+
<sp-sidenav-item value="Code" label="Code"></sp-sidenav-item>
82+
</sp-sidenav-heading>
83+
</sp-sidenav-heading>
84+
</sp-sidenav>
85+
```
86+
87+
</sp-tab-panel>
88+
</sp-tabs>
89+
90+
### Accessibility
91+
92+
Although `<sp-sidenav-heading>` elements are non-interactive, they do offer accessibility features:
93+
94+
- Uses `<h2>` elements for heading text to provide proper document outline
95+
- Automatically sets `role="listitem"` on the heading component itself
96+
- Creates a nested `role="list"` container for grouped navigation items
97+
- `aria-labelledby` is set to the `id` of rendered `<h2>` tag on nested list items to associate the list with the heading

0 commit comments

Comments
 (0)