@spectrum-web-components/sidenav 1.7.0 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +153 -47
- package/package.json +4 -4
- package/sp-sidenav-heading.d.ts +11 -0
- package/sp-sidenav-heading.dev.js.map +1 -1
- package/sp-sidenav-heading.js.map +1 -1
- package/sp-sidenav-item.d.ts +11 -0
- package/sp-sidenav-item.dev.js.map +1 -1
- package/sp-sidenav-item.js.map +1 -1
- package/sp-sidenav.d.ts +11 -0
- package/sp-sidenav.dev.js.map +1 -1
- package/sp-sidenav.js.map +1 -1
- package/src/Sidenav.d.ts +11 -0
- package/src/Sidenav.dev.js.map +1 -1
- package/src/Sidenav.js.map +1 -1
- package/src/SidenavHeading.d.ts +11 -0
- package/src/SidenavHeading.dev.js.map +1 -1
- package/src/SidenavHeading.js.map +1 -1
- package/src/SidenavItem.d.ts +11 -0
- package/src/SidenavItem.dev.js.map +1 -1
- package/src/SidenavItem.js.map +1 -1
- package/src/index.d.ts +11 -0
- package/src/index.dev.js.map +1 -1
- package/src/index.js.map +1 -1
- package/src/sidenav-heading-overrides.css.dev.js.map +1 -1
- package/src/sidenav-heading-overrides.css.js.map +1 -1
- package/src/sidenav-heading.css.dev.js.map +1 -1
- package/src/sidenav-heading.css.js.map +1 -1
- package/src/sidenav-item-overrides.css.dev.js.map +1 -1
- package/src/sidenav-item-overrides.css.js.map +1 -1
- package/src/sidenav-item.css.dev.js.map +1 -1
- package/src/sidenav-item.css.js.map +1 -1
- package/src/sidenav-overrides.css.dev.js.map +1 -1
- package/src/sidenav-overrides.css.js.map +1 -1
- package/src/sidenav.css.dev.js.map +1 -1
- package/src/sidenav.css.js.map +1 -1
- package/src/spectrum-sidenav-heading.css.dev.js.map +1 -1
- package/src/spectrum-sidenav-heading.css.js.map +1 -1
- package/src/spectrum-sidenav-item.css.dev.js.map +1 -1
- package/src/spectrum-sidenav-item.css.js.map +1 -1
- package/src/spectrum-sidenav.css.dev.js.map +1 -1
- package/src/spectrum-sidenav.css.js.map +1 -1
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
##
|
|
1
|
+
## Overview
|
|
2
2
|
|
|
3
3
|
Side navigation allows users to locate information and features within the UI.
|
|
4
4
|
It can be used for either hierarchical or flat navigation, and gives the ability
|
|
@@ -7,7 +7,9 @@ prioritize content or features based on your users’ needs in a way that
|
|
|
7
7
|
maintains clear, persistent visibility. Use side navigation within the context
|
|
8
8
|
of larger elements and mechanisms within the app frame.
|
|
9
9
|
|
|
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>`](
|
|
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/)
|
|
11
13
|
|
|
12
14
|
### Usage
|
|
13
15
|
|
|
@@ -15,13 +17,13 @@ of larger elements and mechanisms within the app frame.
|
|
|
15
17
|
[](https://bundlephobia.com/result?p=@spectrum-web-components/sidenav)
|
|
16
18
|
[](https://stackblitz.com/edit/vitejs-vite-q3w6kjxv)
|
|
17
19
|
|
|
18
|
-
```
|
|
20
|
+
```bash
|
|
19
21
|
yarn add @spectrum-web-components/sidenav
|
|
20
22
|
```
|
|
21
23
|
|
|
22
24
|
Import the side effectful registration of `<sp-sidenav>`, `<sp-sidenav-heading>`, or `<sp-sidenav-item>` via:
|
|
23
25
|
|
|
24
|
-
```
|
|
26
|
+
```js
|
|
25
27
|
import '@spectrum-web-components/sidenav/sp-sidenav.js';
|
|
26
28
|
import '@spectrum-web-components/sidenav/sp-sidenav-heading.js';
|
|
27
29
|
import '@spectrum-web-components/sidenav/sp-sidenav-item.js';
|
|
@@ -29,15 +31,43 @@ import '@spectrum-web-components/sidenav/sp-sidenav-item.js';
|
|
|
29
31
|
|
|
30
32
|
When looking to leverage the `Sidenav`, `SidenavHeading`, or `SidenavItem` base classes as a type and/or for extension purposes, do so via:
|
|
31
33
|
|
|
32
|
-
```
|
|
34
|
+
```js
|
|
33
35
|
import {
|
|
34
36
|
Sidenav,
|
|
35
37
|
SidenavHeading,
|
|
36
|
-
SidenavItem
|
|
38
|
+
SidenavItem,
|
|
37
39
|
} from '@spectrum-web-components/sidenav';
|
|
38
40
|
```
|
|
39
41
|
|
|
40
|
-
|
|
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.
|
|
41
71
|
|
|
42
72
|
```html
|
|
43
73
|
<sp-sidenav defaultValue="Docs">
|
|
@@ -49,7 +79,7 @@ import {
|
|
|
49
79
|
></sp-sidenav-item>
|
|
50
80
|
<sp-sidenav-item
|
|
51
81
|
value="Guides"
|
|
52
|
-
href="/guides
|
|
82
|
+
href="/guides"
|
|
53
83
|
label="Guides"
|
|
54
84
|
></sp-sidenav-item>
|
|
55
85
|
<sp-sidenav-item
|
|
@@ -65,71 +95,50 @@ import {
|
|
|
65
95
|
></sp-sidenav-item>
|
|
66
96
|
<sp-sidenav-item
|
|
67
97
|
value="Releases"
|
|
68
|
-
href="
|
|
98
|
+
href="/releases"
|
|
69
99
|
target="_blank"
|
|
70
100
|
label="Releases"
|
|
71
101
|
disabled
|
|
72
102
|
></sp-sidenav-item>
|
|
73
103
|
<sp-sidenav-item
|
|
74
104
|
value="GitHub"
|
|
75
|
-
href="
|
|
105
|
+
href="/github"
|
|
76
106
|
target="_blank"
|
|
77
107
|
label="Github"
|
|
78
108
|
></sp-sidenav-item>
|
|
79
109
|
</sp-sidenav>
|
|
80
110
|
```
|
|
81
111
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
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">
|
|
112
115
|
|
|
113
|
-
|
|
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.
|
|
114
117
|
|
|
115
118
|
```html
|
|
116
119
|
<sp-sidenav>
|
|
117
120
|
<sp-sidenav-item value="Section Title 1" label="Section Title 1">
|
|
118
121
|
<sp-icon-star slot="icon"></sp-icon-star>
|
|
119
122
|
</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>
|
|
121
124
|
<sp-icon-star slot="icon"></sp-icon-star>
|
|
122
125
|
</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>
|
|
124
127
|
<sp-icon-star slot="icon"></sp-icon-star>
|
|
125
128
|
</sp-sidenav-item>
|
|
126
129
|
</sp-sidenav>
|
|
127
130
|
```
|
|
128
131
|
|
|
129
|
-
|
|
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.
|
|
130
139
|
|
|
131
140
|
```html
|
|
132
|
-
<sp-sidenav
|
|
141
|
+
<sp-sidenav>
|
|
133
142
|
<sp-sidenav-item value="Section 1" label="Section 1"></sp-sidenav-item>
|
|
134
143
|
<sp-sidenav-item value="Section 2" label="Section 2"></sp-sidenav-item>
|
|
135
144
|
<sp-sidenav-heading label="Category 1">
|
|
@@ -143,6 +152,103 @@ will send the user to the location of the item.
|
|
|
143
152
|
</sp-sidenav>
|
|
144
153
|
```
|
|
145
154
|
|
|
146
|
-
|
|
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
|
|
147
251
|
|
|
148
|
-
|
|
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
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spectrum-web-components/sidenav",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -84,9 +84,9 @@
|
|
|
84
84
|
"css"
|
|
85
85
|
],
|
|
86
86
|
"dependencies": {
|
|
87
|
-
"@spectrum-web-components/base": "1.
|
|
88
|
-
"@spectrum-web-components/reactive-controllers": "1.
|
|
89
|
-
"@spectrum-web-components/shared": "1.
|
|
87
|
+
"@spectrum-web-components/base": "1.8.0",
|
|
88
|
+
"@spectrum-web-components/reactive-controllers": "1.8.0",
|
|
89
|
+
"@spectrum-web-components/shared": "1.8.0"
|
|
90
90
|
},
|
|
91
91
|
"types": "./src/index.d.ts",
|
|
92
92
|
"customElements": "custom-elements.json",
|
package/sp-sidenav-heading.d.ts
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2025 Adobe. All rights reserved.
|
|
3
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
*
|
|
7
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
+
* governing permissions and limitations under the License.
|
|
11
|
+
*/
|
|
1
12
|
import { SideNavHeading } from './src/SidenavHeading.js';
|
|
2
13
|
declare global {
|
|
3
14
|
interface HTMLElementTagNameMap {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["sp-sidenav-heading.ts"],
|
|
4
|
-
"sourcesContent": ["
|
|
4
|
+
"sourcesContent": ["/**\n * Copyright 2025 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\nimport { SideNavHeading } from './src/SidenavHeading.dev.js'\nimport { defineElement } from '@spectrum-web-components/base/src/define-element.js';\n\ndefineElement('sp-sidenav-heading', SideNavHeading);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'sp-sidenav-heading': SideNavHeading;\n }\n}\n"],
|
|
5
5
|
"mappings": ";AAWA,SAAS,sBAAsB;AAC/B,SAAS,qBAAqB;AAE9B,cAAc,sBAAsB,cAAc;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["sp-sidenav-heading.ts"],
|
|
4
|
-
"sourcesContent": ["
|
|
4
|
+
"sourcesContent": ["/**\n * Copyright 2025 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\nimport { SideNavHeading } from './src/SidenavHeading.js';\nimport { defineElement } from '@spectrum-web-components/base/src/define-element.js';\n\ndefineElement('sp-sidenav-heading', SideNavHeading);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'sp-sidenav-heading': SideNavHeading;\n }\n}\n"],
|
|
5
5
|
"mappings": "aAWA,OAAS,kBAAAA,MAAsB,0BAC/B,OAAS,iBAAAC,MAAqB,sDAE9BA,EAAc,qBAAsBD,CAAc",
|
|
6
6
|
"names": ["SideNavHeading", "defineElement"]
|
|
7
7
|
}
|
package/sp-sidenav-item.d.ts
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2025 Adobe. All rights reserved.
|
|
3
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
*
|
|
7
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
+
* governing permissions and limitations under the License.
|
|
11
|
+
*/
|
|
1
12
|
import { SideNavItem } from './src/SidenavItem.js';
|
|
2
13
|
declare global {
|
|
3
14
|
interface HTMLElementTagNameMap {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["sp-sidenav-item.ts"],
|
|
4
|
-
"sourcesContent": ["
|
|
4
|
+
"sourcesContent": ["/**\n * Copyright 2025 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\nimport { SideNavItem } from './src/SidenavItem.dev.js'\nimport { defineElement } from '@spectrum-web-components/base/src/define-element.js';\n\ndefineElement('sp-sidenav-item', SideNavItem);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'sp-sidenav-item': SideNavItem;\n }\n}\n"],
|
|
5
5
|
"mappings": ";AAWA,SAAS,mBAAmB;AAC5B,SAAS,qBAAqB;AAE9B,cAAc,mBAAmB,WAAW;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/sp-sidenav-item.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["sp-sidenav-item.ts"],
|
|
4
|
-
"sourcesContent": ["
|
|
4
|
+
"sourcesContent": ["/**\n * Copyright 2025 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\nimport { SideNavItem } from './src/SidenavItem.js';\nimport { defineElement } from '@spectrum-web-components/base/src/define-element.js';\n\ndefineElement('sp-sidenav-item', SideNavItem);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'sp-sidenav-item': SideNavItem;\n }\n}\n"],
|
|
5
5
|
"mappings": "aAWA,OAAS,eAAAA,MAAmB,uBAC5B,OAAS,iBAAAC,MAAqB,sDAE9BA,EAAc,kBAAmBD,CAAW",
|
|
6
6
|
"names": ["SideNavItem", "defineElement"]
|
|
7
7
|
}
|
package/sp-sidenav.d.ts
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2025 Adobe. All rights reserved.
|
|
3
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
*
|
|
7
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
+
* governing permissions and limitations under the License.
|
|
11
|
+
*/
|
|
1
12
|
import { SideNav } from './src/Sidenav.js';
|
|
2
13
|
declare global {
|
|
3
14
|
interface HTMLElementTagNameMap {
|
package/sp-sidenav.dev.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["sp-sidenav.ts"],
|
|
4
|
-
"sourcesContent": ["
|
|
4
|
+
"sourcesContent": ["/**\n * Copyright 2025 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\nimport { SideNav } from './src/Sidenav.dev.js'\nimport { defineElement } from '@spectrum-web-components/base/src/define-element.js';\n\ndefineElement('sp-sidenav', SideNav);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'sp-sidenav': SideNav;\n }\n}\n"],
|
|
5
5
|
"mappings": ";AAWA,SAAS,eAAe;AACxB,SAAS,qBAAqB;AAE9B,cAAc,cAAc,OAAO;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/sp-sidenav.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["sp-sidenav.ts"],
|
|
4
|
-
"sourcesContent": ["
|
|
4
|
+
"sourcesContent": ["/**\n * Copyright 2025 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\nimport { SideNav } from './src/Sidenav.js';\nimport { defineElement } from '@spectrum-web-components/base/src/define-element.js';\n\ndefineElement('sp-sidenav', SideNav);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'sp-sidenav': SideNav;\n }\n}\n"],
|
|
5
5
|
"mappings": "aAWA,OAAS,WAAAA,MAAe,mBACxB,OAAS,iBAAAC,MAAqB,sDAE9BA,EAAc,aAAcD,CAAO",
|
|
6
6
|
"names": ["SideNav", "defineElement"]
|
|
7
7
|
}
|
package/src/Sidenav.d.ts
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2025 Adobe. All rights reserved.
|
|
3
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
*
|
|
7
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
+
* governing permissions and limitations under the License.
|
|
11
|
+
*/
|
|
1
12
|
import { CSSResultArray, PropertyValues, TemplateResult } from '@spectrum-web-components/base';
|
|
2
13
|
import { RovingTabindexController } from '@spectrum-web-components/reactive-controllers/src/RovingTabindex.js';
|
|
3
14
|
import { Focusable } from '@spectrum-web-components/shared';
|
package/src/Sidenav.dev.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["Sidenav.ts"],
|
|
4
|
-
"sourcesContent": ["
|
|
4
|
+
"sourcesContent": ["/**\n * Copyright 2025 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {\n CSSResultArray,\n html,\n PropertyValues,\n TemplateResult,\n} from '@spectrum-web-components/base';\nimport { property } from '@spectrum-web-components/base/src/decorators.js';\nimport { RovingTabindexController } from '@spectrum-web-components/reactive-controllers/src/RovingTabindex.js';\n\nimport sidenavStyles from './sidenav.css.js';\nimport { Focusable } from '@spectrum-web-components/shared';\nimport { SideNavItem } from './SidenavItem.dev.js'\nimport { SideNavHeading } from './SidenavHeading.dev.js'\nimport { ifDefined } from '@spectrum-web-components/base/src/directives.js';\n\nexport interface SidenavSelectDetail {\n value: string;\n}\n\n/**\n * @element sp-sidenav\n *\n * @slot - the Sidenav Items to display\n * @fires change - Announces a change in the `value` property of the navigation element.\n * This change can be \"canceled\" via `event.preventDefault()`.\n */\nexport class SideNav extends Focusable {\n public static override get styles(): CSSResultArray {\n return [sidenavStyles];\n }\n\n private items = new Set<SideNavItem>();\n\n public startTrackingSelectionForItem(item: SideNavItem): void {\n this.items.add(item);\n this.rovingTabindexController.clearElementCache();\n }\n\n public stopTrackingSelectionForItem(item: SideNavItem): void {\n this.items.delete(item);\n this.rovingTabindexController.clearElementCache();\n }\n\n rovingTabindexController = new RovingTabindexController<SideNavItem>(this, {\n focusInIndex: (elements: SideNavItem[]) => {\n let parentSideNavItem: SideNavItem | undefined;\n let index = elements.findIndex((el) => {\n // If the selected item's parent is collapsed, save it for later.\n if (el.value === this.value && this.isDisabledChild(el)) {\n parentSideNavItem = el.closest(\n 'sp-sidenav-item:not([expanded])'\n ) as SideNavItem;\n }\n return this.value\n ? !el.disabled &&\n !this.isDisabledChild(el) &&\n el.value === this.value\n : !el.disabled && !this.isDisabledChild(el);\n });\n // If the selected item's parent is collapsed, focus the collapsed parent.\n if (index === -1 && parentSideNavItem) {\n index = elements.findIndex((el) => el === parentSideNavItem);\n }\n return index;\n },\n direction: 'vertical',\n elements: () =>\n [...this.querySelectorAll('sp-sidenav-item')] as SideNavItem[],\n isFocusableElement: (el: SideNavItem) =>\n !el.disabled && !this.isDisabledChild(el),\n });\n\n @property({ type: Boolean, reflect: true, attribute: 'manage-tab-index' })\n public manageTabIndex = false;\n\n @property({ reflect: true })\n public value: string | undefined = undefined;\n\n /**\n * The multilevel variant will have multiple layers of hierarchical navigation items.\n */\n @property({ reflect: true })\n public variant?: 'multilevel' = undefined;\n\n /**\n * An accessible label that describes the component,\n * so that the side navigation can be distinguished\n * from other navigation by screen reader users.\n * It will be applied to aria-label, but not visually rendered.\n */\n @property({ reflect: true })\n public label?: string | undefined = undefined;\n\n private handleSelect(\n event: CustomEvent<SidenavSelectDetail> & { target: SideNavItem }\n ): void {\n event.stopPropagation();\n if (this.value === event.detail.value) {\n return;\n }\n const oldValue = this.value;\n this.value = event.detail.value;\n const applyDefault = this.dispatchEvent(\n new Event('change', {\n bubbles: true,\n composed: true,\n cancelable: true,\n })\n );\n if (!applyDefault) {\n this.value = oldValue;\n event.target.selected = false;\n event.preventDefault();\n } else {\n this.items.forEach((item) => item.handleSideNavSelect(event));\n }\n }\n\n public override focus(): void {\n this.rovingTabindexController.focus();\n }\n\n public override blur(): void {\n if (this.focusElement === this) {\n return;\n }\n\n super.blur();\n }\n\n public override click(): void {\n if (this.focusElement === this) {\n return;\n }\n\n super.click();\n }\n\n public override get focusElement(): SideNavItem | SideNav {\n return this.rovingTabindexController.focusInElement || this;\n }\n\n private isDisabledChild(child: SideNavItem): boolean {\n if (child.disabled) {\n return true;\n }\n let parent = child.parentElement as\n | SideNavItem\n | SideNav\n | SideNavHeading;\n while (\n parent instanceof SideNavHeading ||\n (!(parent as SideNavItem).disabled &&\n parent instanceof SideNavItem &&\n parent.expanded)\n ) {\n parent = parent.parentElement as\n | SideNavItem\n | SideNav\n | SideNavHeading;\n }\n return parent !== this;\n }\n\n private handleSlotchange(): void {\n if (this.manageTabIndex) {\n this.rovingTabindexController.manage();\n } else {\n this.rovingTabindexController.unmanage();\n }\n }\n\n protected override render(): TemplateResult {\n return html`\n <nav\n @sidenav-select=${this.handleSelect}\n aria-label=${ifDefined(this.label)}\n >\n <div role=\"list\">\n <slot\n name=\"descendant\"\n @slotchange=${this.handleSlotchange}\n ></slot>\n </div>\n </nav>\n `;\n }\n\n protected override willUpdate(): void {\n if (!this.hasUpdated) {\n const selectedChild = this.querySelector(\n '[selected]'\n ) as SideNavItem;\n if (selectedChild) {\n this.value = selectedChild.value;\n }\n }\n }\n\n protected override updated(changes: PropertyValues): void {\n super.updated(changes);\n if (changes.has('manageTabIndex')) {\n if (this.manageTabIndex) {\n this.rovingTabindexController.manage();\n } else {\n this.rovingTabindexController.unmanage();\n }\n }\n }\n}\n\ndeclare global {\n interface GlobalEventHandlersEventMap {\n 'sp-sidenav:select': CustomEvent<SidenavSelectDetail>;\n }\n}\n"],
|
|
5
5
|
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/src/Sidenav.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["Sidenav.ts"],
|
|
4
|
-
"sourcesContent": ["
|
|
4
|
+
"sourcesContent": ["/**\n * Copyright 2025 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {\n CSSResultArray,\n html,\n PropertyValues,\n TemplateResult,\n} from '@spectrum-web-components/base';\nimport { property } from '@spectrum-web-components/base/src/decorators.js';\nimport { RovingTabindexController } from '@spectrum-web-components/reactive-controllers/src/RovingTabindex.js';\n\nimport sidenavStyles from './sidenav.css.js';\nimport { Focusable } from '@spectrum-web-components/shared';\nimport { SideNavItem } from './SidenavItem.js';\nimport { SideNavHeading } from './SidenavHeading.js';\nimport { ifDefined } from '@spectrum-web-components/base/src/directives.js';\n\nexport interface SidenavSelectDetail {\n value: string;\n}\n\n/**\n * @element sp-sidenav\n *\n * @slot - the Sidenav Items to display\n * @fires change - Announces a change in the `value` property of the navigation element.\n * This change can be \"canceled\" via `event.preventDefault()`.\n */\nexport class SideNav extends Focusable {\n public static override get styles(): CSSResultArray {\n return [sidenavStyles];\n }\n\n private items = new Set<SideNavItem>();\n\n public startTrackingSelectionForItem(item: SideNavItem): void {\n this.items.add(item);\n this.rovingTabindexController.clearElementCache();\n }\n\n public stopTrackingSelectionForItem(item: SideNavItem): void {\n this.items.delete(item);\n this.rovingTabindexController.clearElementCache();\n }\n\n rovingTabindexController = new RovingTabindexController<SideNavItem>(this, {\n focusInIndex: (elements: SideNavItem[]) => {\n let parentSideNavItem: SideNavItem | undefined;\n let index = elements.findIndex((el) => {\n // If the selected item's parent is collapsed, save it for later.\n if (el.value === this.value && this.isDisabledChild(el)) {\n parentSideNavItem = el.closest(\n 'sp-sidenav-item:not([expanded])'\n ) as SideNavItem;\n }\n return this.value\n ? !el.disabled &&\n !this.isDisabledChild(el) &&\n el.value === this.value\n : !el.disabled && !this.isDisabledChild(el);\n });\n // If the selected item's parent is collapsed, focus the collapsed parent.\n if (index === -1 && parentSideNavItem) {\n index = elements.findIndex((el) => el === parentSideNavItem);\n }\n return index;\n },\n direction: 'vertical',\n elements: () =>\n [...this.querySelectorAll('sp-sidenav-item')] as SideNavItem[],\n isFocusableElement: (el: SideNavItem) =>\n !el.disabled && !this.isDisabledChild(el),\n });\n\n @property({ type: Boolean, reflect: true, attribute: 'manage-tab-index' })\n public manageTabIndex = false;\n\n @property({ reflect: true })\n public value: string | undefined = undefined;\n\n /**\n * The multilevel variant will have multiple layers of hierarchical navigation items.\n */\n @property({ reflect: true })\n public variant?: 'multilevel' = undefined;\n\n /**\n * An accessible label that describes the component,\n * so that the side navigation can be distinguished\n * from other navigation by screen reader users.\n * It will be applied to aria-label, but not visually rendered.\n */\n @property({ reflect: true })\n public label?: string | undefined = undefined;\n\n private handleSelect(\n event: CustomEvent<SidenavSelectDetail> & { target: SideNavItem }\n ): void {\n event.stopPropagation();\n if (this.value === event.detail.value) {\n return;\n }\n const oldValue = this.value;\n this.value = event.detail.value;\n const applyDefault = this.dispatchEvent(\n new Event('change', {\n bubbles: true,\n composed: true,\n cancelable: true,\n })\n );\n if (!applyDefault) {\n this.value = oldValue;\n event.target.selected = false;\n event.preventDefault();\n } else {\n this.items.forEach((item) => item.handleSideNavSelect(event));\n }\n }\n\n public override focus(): void {\n this.rovingTabindexController.focus();\n }\n\n public override blur(): void {\n if (this.focusElement === this) {\n return;\n }\n\n super.blur();\n }\n\n public override click(): void {\n if (this.focusElement === this) {\n return;\n }\n\n super.click();\n }\n\n public override get focusElement(): SideNavItem | SideNav {\n return this.rovingTabindexController.focusInElement || this;\n }\n\n private isDisabledChild(child: SideNavItem): boolean {\n if (child.disabled) {\n return true;\n }\n let parent = child.parentElement as\n | SideNavItem\n | SideNav\n | SideNavHeading;\n while (\n parent instanceof SideNavHeading ||\n (!(parent as SideNavItem).disabled &&\n parent instanceof SideNavItem &&\n parent.expanded)\n ) {\n parent = parent.parentElement as\n | SideNavItem\n | SideNav\n | SideNavHeading;\n }\n return parent !== this;\n }\n\n private handleSlotchange(): void {\n if (this.manageTabIndex) {\n this.rovingTabindexController.manage();\n } else {\n this.rovingTabindexController.unmanage();\n }\n }\n\n protected override render(): TemplateResult {\n return html`\n <nav\n @sidenav-select=${this.handleSelect}\n aria-label=${ifDefined(this.label)}\n >\n <div role=\"list\">\n <slot\n name=\"descendant\"\n @slotchange=${this.handleSlotchange}\n ></slot>\n </div>\n </nav>\n `;\n }\n\n protected override willUpdate(): void {\n if (!this.hasUpdated) {\n const selectedChild = this.querySelector(\n '[selected]'\n ) as SideNavItem;\n if (selectedChild) {\n this.value = selectedChild.value;\n }\n }\n }\n\n protected override updated(changes: PropertyValues): void {\n super.updated(changes);\n if (changes.has('manageTabIndex')) {\n if (this.manageTabIndex) {\n this.rovingTabindexController.manage();\n } else {\n this.rovingTabindexController.unmanage();\n }\n }\n }\n}\n\ndeclare global {\n interface GlobalEventHandlersEventMap {\n 'sp-sidenav:select': CustomEvent<SidenavSelectDetail>;\n }\n}\n"],
|
|
5
5
|
"mappings": "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",
|
|
6
6
|
"names": ["html", "property", "RovingTabindexController", "sidenavStyles", "Focusable", "SideNavItem", "SideNavHeading", "ifDefined", "elements", "parentSideNavItem", "index", "el", "item", "event", "oldValue", "child", "parent", "selectedChild", "changes", "__decorateClass"]
|
|
7
7
|
}
|
package/src/SidenavHeading.d.ts
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2025 Adobe. All rights reserved.
|
|
3
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
*
|
|
7
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
+
* governing permissions and limitations under the License.
|
|
11
|
+
*/
|
|
1
12
|
import { CSSResultArray, PropertyValues, SpectrumElement, TemplateResult } from '@spectrum-web-components/base';
|
|
2
13
|
/**
|
|
3
14
|
* @element sp-sidenav-heading
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["SidenavHeading.ts"],
|
|
4
|
-
"sourcesContent": ["
|
|
4
|
+
"sourcesContent": ["/**\n * Copyright 2025 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {\n CSSResultArray,\n html,\n PropertyValues,\n SpectrumElement,\n TemplateResult,\n} from '@spectrum-web-components/base';\nimport { property } from '@spectrum-web-components/base/src/decorators.js';\n\nimport sidenavItemStyles from './sidenav-item.css.js';\nimport sidenavHeadingStyles from './sidenav-heading.css.js';\n\n/**\n * @element sp-sidenav-heading\n *\n * @slot - the Sidenav Items to display in association with the heading\n */\nexport class SideNavHeading extends SpectrumElement {\n @property({ reflect: true })\n public label = '';\n\n public static override get styles(): CSSResultArray {\n return [sidenavItemStyles, sidenavHeadingStyles];\n }\n\n protected override update(changes: PropertyValues): void {\n if (!this.hasAttribute('slot')) {\n this.slot = 'descendant';\n }\n super.update(changes);\n }\n\n protected override render(): TemplateResult {\n return html`\n <h2 id=\"heading\">${this.label}</h2>\n <div id=\"list\" aria-labelledby=\"heading\" role=\"list\">\n <slot name=\"descendant\"></slot>\n </div>\n `;\n }\n\n protected override firstUpdated(changed: PropertyValues<this>): void {\n super.firstUpdated(changed);\n this.setAttribute('role', 'listitem');\n }\n}\n"],
|
|
5
5
|
"mappings": ";;;;;;;;;;;AAYA;AAAA,EAEI;AAAA,EAEA;AAAA,OAEG;AACP,SAAS,gBAAgB;AAEzB,OAAO,uBAAuB;AAC9B,OAAO,0BAA0B;AAO1B,aAAM,uBAAuB,gBAAgB;AAAA,EAA7C;AAAA;AAEH,SAAO,QAAQ;AAAA;AAAA,EAEf,WAA2B,SAAyB;AAChD,WAAO,CAAC,mBAAmB,oBAAoB;AAAA,EACnD;AAAA,EAEmB,OAAO,SAA+B;AACrD,QAAI,CAAC,KAAK,aAAa,MAAM,GAAG;AAC5B,WAAK,OAAO;AAAA,IAChB;AACA,UAAM,OAAO,OAAO;AAAA,EACxB;AAAA,EAEmB,SAAyB;AACxC,WAAO;AAAA,+BACgB,KAAK,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA,EAKrC;AAAA,EAEmB,aAAa,SAAqC;AACjE,UAAM,aAAa,OAAO;AAC1B,SAAK,aAAa,QAAQ,UAAU;AAAA,EACxC;AACJ;AA1BW;AAAA,EADN,SAAS,EAAE,SAAS,KAAK,CAAC;AAAA,GADlB,eAEF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["SidenavHeading.ts"],
|
|
4
|
-
"sourcesContent": ["
|
|
4
|
+
"sourcesContent": ["/**\n * Copyright 2025 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {\n CSSResultArray,\n html,\n PropertyValues,\n SpectrumElement,\n TemplateResult,\n} from '@spectrum-web-components/base';\nimport { property } from '@spectrum-web-components/base/src/decorators.js';\n\nimport sidenavItemStyles from './sidenav-item.css.js';\nimport sidenavHeadingStyles from './sidenav-heading.css.js';\n\n/**\n * @element sp-sidenav-heading\n *\n * @slot - the Sidenav Items to display in association with the heading\n */\nexport class SideNavHeading extends SpectrumElement {\n @property({ reflect: true })\n public label = '';\n\n public static override get styles(): CSSResultArray {\n return [sidenavItemStyles, sidenavHeadingStyles];\n }\n\n protected override update(changes: PropertyValues): void {\n if (!this.hasAttribute('slot')) {\n this.slot = 'descendant';\n }\n super.update(changes);\n }\n\n protected override render(): TemplateResult {\n return html`\n <h2 id=\"heading\">${this.label}</h2>\n <div id=\"list\" aria-labelledby=\"heading\" role=\"list\">\n <slot name=\"descendant\"></slot>\n </div>\n `;\n }\n\n protected override firstUpdated(changed: PropertyValues<this>): void {\n super.firstUpdated(changed);\n this.setAttribute('role', 'listitem');\n }\n}\n"],
|
|
5
5
|
"mappings": "qNAYA,OAEI,QAAAA,EAEA,mBAAAC,MAEG,gCACP,OAAS,YAAAC,MAAgB,kDAEzB,OAAOC,MAAuB,wBAC9B,OAAOC,MAA0B,2BAO1B,aAAM,uBAAuBH,CAAgB,CAA7C,kCAEH,KAAO,MAAQ,GAEf,WAA2B,QAAyB,CAChD,MAAO,CAACE,EAAmBC,CAAoB,CACnD,CAEmB,OAAOC,EAA+B,CAChD,KAAK,aAAa,MAAM,IACzB,KAAK,KAAO,cAEhB,MAAM,OAAOA,CAAO,CACxB,CAEmB,QAAyB,CACxC,OAAOL;AAAA,+BACgB,KAAK,KAAK;AAAA;AAAA;AAAA;AAAA,SAKrC,CAEmB,aAAaM,EAAqC,CACjE,MAAM,aAAaA,CAAO,EAC1B,KAAK,aAAa,OAAQ,UAAU,CACxC,CACJ,CA1BWC,EAAA,CADNL,EAAS,CAAE,QAAS,EAAK,CAAC,GADlB,eAEF",
|
|
6
6
|
"names": ["html", "SpectrumElement", "property", "sidenavItemStyles", "sidenavHeadingStyles", "changes", "changed", "__decorateClass"]
|
|
7
7
|
}
|