@vaadin/side-nav 24.2.0-alpha1 → 24.2.0-alpha2

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 CHANGED
@@ -49,9 +49,14 @@ import '@vaadin/side-nav';
49
49
  ## Themes
50
50
 
51
51
  Vaadin components come with two built-in [themes](https://vaadin.com/docs/latest/styling), Lumo and Material.
52
- This component currently does not support Material theme.
53
52
  The [main entrypoint](https://github.com/vaadin/web-components/blob/main/packages/side-nav/vaadin-side-nav.js) of the package uses the Lumo theme.
54
53
 
54
+ To use the Material theme, import the component from the `theme/material` folder:
55
+
56
+ ```js
57
+ import '@vaadin/side-nav/theme/material/vaadin-side-nav.js';
58
+ ```
59
+
55
60
  You can also import the Lumo version of the component explicitly:
56
61
 
57
62
  ```js
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vaadin/side-nav",
3
- "version": "24.2.0-alpha1",
3
+ "version": "24.2.0-alpha2",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -35,10 +35,10 @@
35
35
  "web-component"
36
36
  ],
37
37
  "dependencies": {
38
- "@vaadin/component-base": "24.2.0-alpha1",
39
- "@vaadin/vaadin-lumo-styles": "24.2.0-alpha1",
40
- "@vaadin/vaadin-material-styles": "24.2.0-alpha1",
41
- "@vaadin/vaadin-themable-mixin": "24.2.0-alpha1",
38
+ "@vaadin/component-base": "24.2.0-alpha2",
39
+ "@vaadin/vaadin-lumo-styles": "24.2.0-alpha2",
40
+ "@vaadin/vaadin-material-styles": "24.2.0-alpha2",
41
+ "@vaadin/vaadin-themable-mixin": "24.2.0-alpha2",
42
42
  "lit": "^2.0.0"
43
43
  },
44
44
  "devDependencies": {
@@ -51,5 +51,5 @@
51
51
  "web-types.json",
52
52
  "web-types.lit.json"
53
53
  ],
54
- "gitHead": "0dbb118320203ab6c0c07450a3e718815367589f"
54
+ "gitHead": "b8378bd2267728e172012bcb2ea45c3e5a6e590a"
55
55
  }
@@ -10,10 +10,16 @@ export const sideNavItemBaseStyles = css`
10
10
  display: block;
11
11
  }
12
12
 
13
+ :host([hidden]),
13
14
  [hidden] {
14
15
  display: none !important;
15
16
  }
16
17
 
18
+ [part='content'] {
19
+ display: flex;
20
+ align-items: center;
21
+ }
22
+
17
23
  [part='link'] {
18
24
  flex: auto;
19
25
  min-width: 0;
@@ -28,6 +34,11 @@ export const sideNavItemBaseStyles = css`
28
34
  -webkit-appearance: none;
29
35
  appearance: none;
30
36
  flex: none;
37
+ position: relative;
38
+ margin: 0;
39
+ padding: 0;
40
+ border: 0;
41
+ background: transparent;
31
42
  }
32
43
 
33
44
  [part='children'] {
@@ -40,10 +51,6 @@ export const sideNavItemBaseStyles = css`
40
51
  display: none !important;
41
52
  }
42
53
 
43
- :host(:not([path])) a {
44
- position: relative;
45
- }
46
-
47
54
  :host(:not([path])) button::after {
48
55
  content: '';
49
56
  position: absolute;
@@ -0,0 +1,41 @@
1
+ /**
2
+ * @license
3
+ * Copyright (c) 2023 Vaadin Ltd.
4
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
+ */
6
+ import type { Constructor } from '@open-wc/dedupe-mixin';
7
+
8
+ export interface SideNavI18n {
9
+ toggle: string;
10
+ }
11
+
12
+ export declare function SideNavChildrenMixin<T extends Constructor<HTMLElement>>(
13
+ base: T,
14
+ ): Constructor<SideNavChildrenMixinClass> & T;
15
+
16
+ export declare class SideNavChildrenMixinClass {
17
+ /**
18
+ * The object used to localize this component.
19
+ *
20
+ * To change the default localization, replace the entire
21
+ * `i18n` object with a custom one.
22
+ *
23
+ * The object has the following structure and default values:
24
+ * ```
25
+ * {
26
+ * toggle: 'Toggle child items'
27
+ * }
28
+ * ```
29
+ */
30
+ i18n: SideNavI18n;
31
+
32
+ /**
33
+ * List of child items of this component.
34
+ */
35
+ protected readonly _items: HTMLElement[];
36
+
37
+ /**
38
+ * Name of the slot to be used for children.
39
+ */
40
+ protected readonly _itemsSlotName: string;
41
+ }
@@ -0,0 +1,134 @@
1
+ /**
2
+ * @license
3
+ * Copyright (c) 2023 Vaadin Ltd.
4
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
+ */
6
+ import { SlotController } from '@vaadin/component-base/src/slot-controller.js';
7
+
8
+ /**
9
+ * A controller that manages the item content children slot.
10
+ */
11
+ class ChildrenController extends SlotController {
12
+ constructor(host, slotName) {
13
+ super(host, slotName, null, { observe: true, multiple: true });
14
+ }
15
+
16
+ /**
17
+ * @protected
18
+ * @override
19
+ */
20
+ initAddedNode() {
21
+ this.host.requestUpdate();
22
+ }
23
+
24
+ /**
25
+ * @protected
26
+ * @override
27
+ */
28
+ teardownNode() {
29
+ this.host.requestUpdate();
30
+ }
31
+ }
32
+
33
+ /**
34
+ * @polymerMixin
35
+ */
36
+ export const SideNavChildrenMixin = (superClass) =>
37
+ class SideNavChildrenMixin extends superClass {
38
+ static get properties() {
39
+ return {
40
+ /**
41
+ * The object used to localize this component.
42
+ *
43
+ * To change the default localization, replace the entire
44
+ * `i18n` object with a custom one.
45
+ *
46
+ * The object has the following structure and default values:
47
+ * ```
48
+ * {
49
+ * toggle: 'Toggle child items'
50
+ * }
51
+ * ```
52
+ *
53
+ * @type {SideNavI18n}
54
+ * @default {English/US}
55
+ */
56
+ i18n: {
57
+ type: Object,
58
+ value: () => {
59
+ return {
60
+ toggle: 'Toggle child items',
61
+ };
62
+ },
63
+ },
64
+
65
+ /**
66
+ * Count of child items.
67
+ * @private
68
+ */
69
+ _itemsCount: {
70
+ type: Number,
71
+ value: 0,
72
+ },
73
+ };
74
+ }
75
+
76
+ constructor() {
77
+ super();
78
+
79
+ this._childrenController = new ChildrenController(this, this._itemsSlotName);
80
+ }
81
+
82
+ /**
83
+ * List of child items of this component.
84
+ * @protected
85
+ */
86
+ get _items() {
87
+ return this._childrenController.nodes;
88
+ }
89
+
90
+ /**
91
+ * Name of the slot to be used for children.
92
+ * @protected
93
+ */
94
+ get _itemsSlotName() {
95
+ return 'children';
96
+ }
97
+
98
+ /** @protected */
99
+ firstUpdated() {
100
+ super.firstUpdated();
101
+
102
+ // Controller that detects changes to the side-nav items.
103
+ this.addController(this._childrenController);
104
+ }
105
+
106
+ /**
107
+ * @protected
108
+ * @override
109
+ */
110
+ willUpdate(props) {
111
+ super.willUpdate(props);
112
+
113
+ this._itemsCount = this._items.length;
114
+ }
115
+
116
+ /**
117
+ * @protected
118
+ * @override
119
+ */
120
+ updated(props) {
121
+ super.updated(props);
122
+
123
+ if (props.has('_itemsCount')) {
124
+ this.toggleAttribute('has-children', this._itemsCount > 0);
125
+ }
126
+
127
+ // Propagate i18n object to all the child items
128
+ if (props.has('_itemsCount') || props.has('i18n')) {
129
+ this._items.forEach((item) => {
130
+ item.i18n = this.i18n;
131
+ });
132
+ }
133
+ }
134
+ };
@@ -7,6 +7,7 @@ import { LitElement } from 'lit';
7
7
  import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
8
8
  import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
9
9
  import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
10
+ import { SideNavChildrenMixin } from './vaadin-side-nav-children-mixin.js';
10
11
 
11
12
  /**
12
13
  * Fired when the `expanded` property changes.
@@ -56,6 +57,8 @@ export type SideNavItemEventMap = HTMLElementEventMap & SideNavItemCustomEventMa
56
57
  *
57
58
  * ### Styling
58
59
  *
60
+ * The following shadow DOM parts are available for styling:
61
+ *
59
62
  * Part name | Description
60
63
  * ----------------|----------------
61
64
  * `content` | The element that wraps link and toggle button
@@ -63,22 +66,27 @@ export type SideNavItemEventMap = HTMLElementEventMap & SideNavItemCustomEventMa
63
66
  * `link` | The clickable anchor used for navigation
64
67
  * `toggle-button` | The toggle button
65
68
  *
69
+ * The following state attributes are available for styling:
70
+ *
71
+ * Attribute | Description
72
+ * ---------------|-------------
73
+ * `expanded` | Set when the element is expanded.
74
+ * `has-children` | Set when the element has child items.
75
+ *
66
76
  * See [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.
67
77
  *
68
78
  * @fires {CustomEvent} expanded-changed - Fired when the `expanded` property changes.
69
79
  */
70
- declare class SideNavItem extends ElementMixin(ThemableMixin(PolylitMixin(LitElement))) {
80
+ declare class SideNavItem extends SideNavChildrenMixin(ElementMixin(ThemableMixin(PolylitMixin(LitElement)))) {
71
81
  /**
72
82
  * The path to navigate to
73
83
  */
74
84
  path: string | null | undefined;
75
85
 
76
86
  /**
77
- * A comma-separated list of alternative paths matching this item.
78
- *
79
- * @attr {string} path-aliases
87
+ * The list of alternative paths matching this item
80
88
  */
81
- pathAliases: string | null | undefined;
89
+ pathAliases: string[];
82
90
 
83
91
  /**
84
92
  * Whether to show the child items or not
@@ -90,7 +98,7 @@ declare class SideNavItem extends ElementMixin(ThemableMixin(PolylitMixin(LitEle
90
98
  * Set when the item is appended to DOM or when navigated back
91
99
  * to the page that contains this item using the browser.
92
100
  */
93
- readonly active: boolean;
101
+ readonly current: boolean;
94
102
 
95
103
  addEventListener<K extends keyof SideNavItemEventMap>(
96
104
  type: K,
@@ -5,42 +5,18 @@
5
5
  */
6
6
  import { html, LitElement } from 'lit';
7
7
  import { ifDefined } from 'lit/directives/if-defined.js';
8
+ import { screenReaderOnly } from '@vaadin/a11y-base/src/styles/sr-only-styles.js';
8
9
  import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
9
10
  import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
10
- import { SlotController } from '@vaadin/component-base/src/slot-controller.js';
11
11
  import { matchPaths } from '@vaadin/component-base/src/url-utils.js';
12
12
  import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
13
13
  import { sideNavItemBaseStyles } from './vaadin-side-nav-base-styles.js';
14
+ import { SideNavChildrenMixin } from './vaadin-side-nav-children-mixin.js';
14
15
 
15
16
  function isEnabled() {
16
17
  return window.Vaadin && window.Vaadin.featureFlags && !!window.Vaadin.featureFlags.sideNavComponent;
17
18
  }
18
19
 
19
- /**
20
- * A controller to manage the item content children slot.
21
- */
22
- class ChildrenController extends SlotController {
23
- constructor(host) {
24
- super(host, 'children', null, { observe: true, multiple: true });
25
- }
26
-
27
- /**
28
- * @protected
29
- * @override
30
- */
31
- initAddedNode() {
32
- this.host.requestUpdate();
33
- }
34
-
35
- /**
36
- * @protected
37
- * @override
38
- */
39
- teardownNode() {
40
- this.host.requestUpdate();
41
- }
42
- }
43
-
44
20
  /**
45
21
  * A navigation item to be used within `<vaadin-side-nav>`. Represents a navigation target.
46
22
  * Not intended to be used separately.
@@ -78,6 +54,8 @@ class ChildrenController extends SlotController {
78
54
  *
79
55
  * ### Styling
80
56
  *
57
+ * The following shadow DOM parts are available for styling:
58
+ *
81
59
  * Part name | Description
82
60
  * ----------------|----------------
83
61
  * `content` | The element that wraps link and toggle button
@@ -85,6 +63,13 @@ class ChildrenController extends SlotController {
85
63
  * `link` | The clickable anchor used for navigation
86
64
  * `toggle-button` | The toggle button
87
65
  *
66
+ * The following state attributes are available for styling:
67
+ *
68
+ * Attribute | Description
69
+ * ---------------|-------------
70
+ * `expanded` | Set when the element is expanded.
71
+ * `has-children` | Set when the element has child items.
72
+ *
88
73
  * See [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.
89
74
  *
90
75
  * @fires {CustomEvent} expanded-changed - Fired when the `expanded` property changes.
@@ -93,8 +78,9 @@ class ChildrenController extends SlotController {
93
78
  * @mixes PolylitMixin
94
79
  * @mixes ThemableMixin
95
80
  * @mixes ElementMixin
81
+ * @mixes SideNavChildrenMixin
96
82
  */
97
- class SideNavItem extends ElementMixin(ThemableMixin(PolylitMixin(LitElement))) {
83
+ class SideNavItem extends SideNavChildrenMixin(ElementMixin(ThemableMixin(PolylitMixin(LitElement)))) {
98
84
  static get is() {
99
85
  return 'vaadin-side-nav-item';
100
86
  }
@@ -107,11 +93,14 @@ class SideNavItem extends ElementMixin(ThemableMixin(PolylitMixin(LitElement)))
107
93
  path: String,
108
94
 
109
95
  /**
110
- * A comma-separated list of alternative paths matching this item.
96
+ * The list of alternative paths matching this item
111
97
  *
112
- * @attr {string} path-aliases
98
+ * @type {!Array<string>}
113
99
  */
114
- pathAliases: String,
100
+ pathAliases: {
101
+ type: Array,
102
+ value: () => [],
103
+ },
115
104
 
116
105
  /**
117
106
  * Whether to show the child items or not
@@ -132,7 +121,7 @@ class SideNavItem extends ElementMixin(ThemableMixin(PolylitMixin(LitElement)))
132
121
  *
133
122
  * @type {boolean}
134
123
  */
135
- active: {
124
+ current: {
136
125
  type: Boolean,
137
126
  value: false,
138
127
  readOnly: true,
@@ -142,13 +131,13 @@ class SideNavItem extends ElementMixin(ThemableMixin(PolylitMixin(LitElement)))
142
131
  }
143
132
 
144
133
  static get styles() {
145
- return sideNavItemBaseStyles;
134
+ return [screenReaderOnly, sideNavItemBaseStyles];
146
135
  }
147
136
 
148
137
  constructor() {
149
138
  super();
150
139
 
151
- this._childrenController = new ChildrenController(this);
140
+ this.__boundUpdateCurrent = this.__updateCurrent.bind(this);
152
141
  }
153
142
 
154
143
  /** @protected */
@@ -161,8 +150,7 @@ class SideNavItem extends ElementMixin(ThemableMixin(PolylitMixin(LitElement)))
161
150
  * @override
162
151
  */
163
152
  firstUpdated() {
164
- // Controller to detect whether the item has child items.
165
- this.addController(this._childrenController);
153
+ super.firstUpdated();
166
154
 
167
155
  // By default, if the user hasn't provided a custom role,
168
156
  // the role attribute is set to "listitem".
@@ -179,31 +167,29 @@ class SideNavItem extends ElementMixin(ThemableMixin(PolylitMixin(LitElement)))
179
167
  super.updated(props);
180
168
 
181
169
  if (props.has('path') || props.has('pathAliases')) {
182
- this.__updateActive();
170
+ this.__updateCurrent();
183
171
  }
184
-
185
- this.toggleAttribute('has-children', this._childrenController.nodes.length > 0);
186
172
  }
187
173
 
188
174
  /** @protected */
189
175
  connectedCallback() {
190
176
  super.connectedCallback();
191
- this.__updateActive();
192
- this.__boundUpdateActive = this.__updateActive.bind(this);
193
- window.addEventListener('popstate', this.__boundUpdateActive);
177
+ this.__updateCurrent();
178
+
179
+ window.addEventListener('popstate', this.__boundUpdateCurrent);
194
180
  }
195
181
 
196
182
  /** @protected */
197
183
  disconnectedCallback() {
198
184
  super.disconnectedCallback();
199
- window.removeEventListener('popstate', this.__boundUpdateActive);
185
+ window.removeEventListener('popstate', this.__boundUpdateCurrent);
200
186
  }
201
187
 
202
188
  /** @protected */
203
189
  render() {
204
190
  return html`
205
191
  <div part="content" @click="${this._onContentClick}">
206
- <a href="${ifDefined(this.path)}" part="link" aria-current="${this.active ? 'page' : 'false'}">
192
+ <a id="link" href="${ifDefined(this.path)}" part="link" aria-current="${this.current ? 'page' : 'false'}">
207
193
  <slot name="prefix"></slot>
208
194
  <slot></slot>
209
195
  <slot name="suffix"></slot>
@@ -213,12 +199,13 @@ class SideNavItem extends ElementMixin(ThemableMixin(PolylitMixin(LitElement)))
213
199
  @click="${this._onButtonClick}"
214
200
  aria-controls="children"
215
201
  aria-expanded="${this.expanded}"
216
- aria-label="Toggle child items"
202
+ aria-labelledby="link i18n"
217
203
  ></button>
218
204
  </div>
219
205
  <ul part="children" ?hidden="${!this.expanded}">
220
206
  <slot name="children"></slot>
221
207
  </ul>
208
+ <div class="sr-only" id="i18n">${this.i18n.toggle}</div>
222
209
  `;
223
210
  }
224
211
 
@@ -244,29 +231,21 @@ class SideNavItem extends ElementMixin(ThemableMixin(PolylitMixin(LitElement)))
244
231
  }
245
232
 
246
233
  /** @private */
247
- __updateActive() {
248
- if (!this.path && this.path !== '') {
249
- this._setActive(false);
250
- return;
251
- }
252
- this._setActive(this.__calculateActive());
253
- this.toggleAttribute('child-active', document.location.pathname.startsWith(this.path));
254
- if (this.active) {
255
- this.expanded = true;
234
+ __updateCurrent() {
235
+ this._setCurrent(this.__isCurrent());
236
+ if (this.current) {
237
+ this.expanded = this._items.length > 0;
256
238
  }
257
239
  }
258
240
 
259
241
  /** @private */
260
- __calculateActive() {
242
+ __isCurrent() {
261
243
  if (this.path == null) {
262
244
  return false;
263
245
  }
264
- if (matchPaths(document.location.pathname, this.path)) {
265
- return true;
266
- }
267
246
  return (
268
- this.pathAliases != null &&
269
- this.pathAliases.split(',').some((alias) => matchPaths(document.location.pathname, alias))
247
+ matchPaths(document.location.pathname, this.path) ||
248
+ this.pathAliases.some((alias) => matchPaths(document.location.pathname, alias))
270
249
  );
271
250
  }
272
251
  }
@@ -8,6 +8,9 @@ import { FocusMixin } from '@vaadin/a11y-base/src/focus-mixin.js';
8
8
  import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
9
9
  import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
10
10
  import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
11
+ import { SideNavChildrenMixin, type SideNavI18n } from './vaadin-side-nav-children-mixin.js';
12
+
13
+ export type { SideNavI18n };
11
14
 
12
15
  /**
13
16
  * Fired when the `collapsed` property changes.
@@ -51,17 +54,27 @@ export type SideNavEventMap = HTMLElementEventMap & SideNavCustomEventMap;
51
54
  *
52
55
  * ### Styling
53
56
  *
57
+ * The following shadow DOM parts are available for styling:
58
+ *
54
59
  * Part name | Description
55
60
  * ----------------|----------------
56
61
  * `label` | The label element
57
62
  * `children` | The element that wraps child items
58
63
  * `toggle-button` | The toggle button
59
64
  *
65
+ * The following state attributes are available for styling:
66
+ *
67
+ * Attribute | Description
68
+ * -------------|-------------
69
+ * `collapsed` | Set when the element is collapsed.
70
+ * `focus-ring` | Set when the label is focused using the keyboard.
71
+ * `focused` | Set when the label is focused.
72
+ *
60
73
  * See [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.
61
74
  *
62
75
  * @fires {CustomEvent} collapsed-changed - Fired when the `collapsed` property changes.
63
76
  */
64
- declare class SideNav extends FocusMixin(ElementMixin(ThemableMixin(PolylitMixin(LitElement)))) {
77
+ declare class SideNav extends SideNavChildrenMixin(FocusMixin(ElementMixin(ThemableMixin(PolylitMixin(LitElement))))) {
65
78
  /**
66
79
  * Whether the side nav is collapsible. When enabled, the toggle icon is shown.
67
80
  */
@@ -11,6 +11,7 @@ import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
11
11
  import { generateUniqueId } from '@vaadin/component-base/src/unique-id-utils.js';
12
12
  import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
13
13
  import { sideNavBaseStyles } from './vaadin-side-nav-base-styles.js';
14
+ import { SideNavChildrenMixin } from './vaadin-side-nav-children-mixin.js';
14
15
 
15
16
  function isEnabled() {
16
17
  return window.Vaadin && window.Vaadin.featureFlags && !!window.Vaadin.featureFlags.sideNavComponent;
@@ -47,12 +48,22 @@ function isEnabled() {
47
48
  *
48
49
  * ### Styling
49
50
  *
51
+ * The following shadow DOM parts are available for styling:
52
+ *
50
53
  * Part name | Description
51
54
  * ----------------|----------------
52
55
  * `label` | The label element
53
56
  * `children` | The element that wraps child items
54
57
  * `toggle-button` | The toggle button
55
58
  *
59
+ * The following state attributes are available for styling:
60
+ *
61
+ * Attribute | Description
62
+ * -------------|-------------
63
+ * `collapsed` | Set when the element is collapsed.
64
+ * `focus-ring` | Set when the label is focused using the keyboard.
65
+ * `focused` | Set when the label is focused.
66
+ *
56
67
  * See [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.
57
68
  *
58
69
  * @fires {CustomEvent} collapsed-changed - Fired when the `collapsed` property changes.
@@ -61,8 +72,9 @@ function isEnabled() {
61
72
  * @mixes PolylitMixin
62
73
  * @mixes ThemableMixin
63
74
  * @mixes ElementMixin
75
+ * @mixes SideNavChildrenMixin
64
76
  */
65
- class SideNav extends FocusMixin(ElementMixin(ThemableMixin(PolylitMixin(LitElement)))) {
77
+ class SideNav extends SideNavChildrenMixin(FocusMixin(ElementMixin(ThemableMixin(PolylitMixin(LitElement))))) {
66
78
  static get is() {
67
79
  return 'vaadin-side-nav';
68
80
  }
@@ -108,6 +120,15 @@ class SideNav extends FocusMixin(ElementMixin(ThemableMixin(PolylitMixin(LitElem
108
120
  this._labelId = `side-nav-label-${generateUniqueId()}`;
109
121
  }
110
122
 
123
+ /**
124
+ * Name of the slot to be used for children.
125
+ * @protected
126
+ * @override
127
+ */
128
+ get _itemsSlotName() {
129
+ return '';
130
+ }
131
+
111
132
  /** @protected */
112
133
  get focusElement() {
113
134
  return this.shadowRoot.querySelector('button');
@@ -115,6 +136,8 @@ class SideNav extends FocusMixin(ElementMixin(ThemableMixin(PolylitMixin(LitElem
115
136
 
116
137
  /** @protected */
117
138
  firstUpdated() {
139
+ super.firstUpdated();
140
+
118
141
  // By default, if the user hasn't provided a custom role,
119
142
  // the role attribute is set to "navigation".
120
143
  if (!this.hasAttribute('role')) {
@@ -4,14 +4,10 @@ import '@vaadin/vaadin-lumo-styles/sizing.js';
4
4
  import '@vaadin/vaadin-lumo-styles/spacing.js';
5
5
  import '@vaadin/vaadin-lumo-styles/style.js';
6
6
  import '@vaadin/vaadin-lumo-styles/font-icons.js';
7
+ import { fieldButton } from '@vaadin/vaadin-lumo-styles/mixins/field-button.js';
7
8
  import { css, registerStyles } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
8
9
 
9
10
  export const sideNavItemStyles = css`
10
- [part='content'] {
11
- display: flex;
12
- align-items: center;
13
- }
14
-
15
11
  [part='link'] {
16
12
  width: 100%;
17
13
  gap: var(--lumo-space-xs);
@@ -23,19 +19,14 @@ export const sideNavItemStyles = css`
23
19
  min-height: var(--lumo-icon-size-m);
24
20
  }
25
21
 
22
+ [part='link'][href] {
23
+ cursor: pointer;
24
+ }
25
+
26
26
  [part='toggle-button'] {
27
- position: relative;
28
- border: 0;
29
- margin: calc((var(--lumo-icon-size-m) - var(--lumo-size-s)) / 2) 0;
30
27
  margin-inline-end: calc(var(--lumo-space-xs) * -1);
31
- padding: 0;
32
- background: transparent;
33
- font: inherit;
34
- color: var(--lumo-tertiary-text-color);
35
28
  width: var(--lumo-size-s);
36
29
  height: var(--lumo-size-s);
37
- cursor: var(--lumo-clickable-cursor, default);
38
- transition: color 140ms;
39
30
  }
40
31
 
41
32
  :host([has-children]) [part='content'] {
@@ -57,11 +48,7 @@ export const sideNavItemStyles = css`
57
48
  }
58
49
 
59
50
  [part='toggle-button']::before {
60
- font-family: lumo-icons;
61
51
  content: var(--lumo-icons-dropdown);
62
- font-size: 1.5em;
63
- line-height: var(--lumo-size-s);
64
- display: inline-block;
65
52
  transform: rotate(-90deg);
66
53
  transition: transform 140ms;
67
54
  }
@@ -93,10 +80,11 @@ export const sideNavItemStyles = css`
93
80
 
94
81
  slot[name='prefix']::slotted(:is(vaadin-icon, [class*='icon'])) {
95
82
  padding: 0.1em;
83
+ flex-shrink: 0;
96
84
  color: var(--lumo-contrast-60pct);
97
85
  }
98
86
 
99
- :host([active]) slot[name='prefix']::slotted(:is(vaadin-icon, [class*='icon'])) {
87
+ :host([current]) slot[name='prefix']::slotted(:is(vaadin-icon, [class*='icon'])) {
100
88
  color: inherit;
101
89
  }
102
90
 
@@ -108,10 +96,10 @@ export const sideNavItemStyles = css`
108
96
  --_child-indent-2: var(--_child-indent);
109
97
  }
110
98
 
111
- :host([active]) [part='link'] {
99
+ :host([current]) [part='link'] {
112
100
  color: var(--lumo-primary-text-color);
113
101
  background-color: var(--lumo-primary-color-10pct);
114
102
  }
115
103
  `;
116
104
 
117
- registerStyles('vaadin-side-nav-item', sideNavItemStyles, { moduleId: 'lumo-side-nav-item' });
105
+ registerStyles('vaadin-side-nav-item', [fieldButton, sideNavItemStyles], { moduleId: 'lumo-side-nav-item' });
@@ -0,0 +1,134 @@
1
+ import '@vaadin/vaadin-material-styles/color.js';
2
+ import '@vaadin/vaadin-material-styles/font-icons.js';
3
+ import '@vaadin/vaadin-material-styles/typography.js';
4
+ import { fieldButton } from '@vaadin/vaadin-material-styles/mixins/field-button.js';
5
+ import { css, registerStyles } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
6
+
7
+ export const sideNavItemStyles = css`
8
+ [part='link'] {
9
+ position: relative;
10
+ width: 100%;
11
+ min-height: 32px;
12
+ margin: 4px 0;
13
+ gap: 8px;
14
+ padding: 4px 8px;
15
+ padding-inline-start: calc(8px + var(--_child-indent, 0px));
16
+ font-family: var(--material-font-family);
17
+ font-size: var(--material-small-font-size);
18
+ line-height: 1;
19
+ font-weight: 500;
20
+ color: var(--material-body-text-color);
21
+ transition: background-color 140ms, color 140ms;
22
+ border-radius: 4px;
23
+ cursor: default;
24
+ }
25
+
26
+ [part='link'][href] {
27
+ cursor: pointer;
28
+ }
29
+
30
+ :host([current]) [part='link'] {
31
+ color: var(--material-primary-text-color);
32
+ }
33
+
34
+ :host([current]) [part='link']::before {
35
+ position: absolute;
36
+ content: '';
37
+ inset: 0;
38
+ background-color: var(--material-primary-color);
39
+ opacity: 0.12;
40
+ border-radius: 4px;
41
+ }
42
+
43
+ [part='toggle-button'] {
44
+ width: 32px;
45
+ height: 32px;
46
+ margin-inline-end: -4px;
47
+ transform: rotate(90deg);
48
+ }
49
+
50
+ [part='toggle-button']::before {
51
+ font-family: 'material-icons';
52
+ font-size: 24px;
53
+ width: 24px;
54
+ display: inline-block;
55
+ content: var(--material-icons-chevron-right);
56
+ }
57
+
58
+ [part='toggle-button']::after {
59
+ display: inline-block;
60
+ content: '';
61
+ position: absolute;
62
+ top: 0;
63
+ left: 0;
64
+ width: 100%;
65
+ height: 100%;
66
+ border-radius: 50%;
67
+ background-color: var(--material-disabled-text-color);
68
+ transform: scale(0);
69
+ opacity: 0;
70
+ transition: transform 0s 0.8s, opacity 0.8s;
71
+ will-change: transform, opacity;
72
+ }
73
+
74
+ [part='toggle-button']:focus-visible::after {
75
+ transition-duration: 0.08s, 0.01s;
76
+ transition-delay: 0s, 0s;
77
+ transform: scale(1.25);
78
+ opacity: 0.16;
79
+ }
80
+
81
+ :host([expanded]) [part='toggle-button'] {
82
+ transform: rotate(270deg);
83
+ }
84
+
85
+ :host([has-children]) [part='content'] {
86
+ padding-inline-end: 8px;
87
+ }
88
+
89
+ @media (any-hover: hover) {
90
+ :host(:not([current])) [part='link'][href]:hover {
91
+ background-color: var(--material-secondary-background-color);
92
+ }
93
+
94
+ [part='toggle-button']:hover {
95
+ color: var(--material-body-text-color);
96
+ }
97
+ }
98
+
99
+ @supports selector(:focus-visible) {
100
+ [part='link'],
101
+ [part='toggle-button'] {
102
+ outline: none;
103
+ }
104
+
105
+ :host(:not([current])) [part='link']:focus-visible {
106
+ background-color: var(--material-divider-color);
107
+ }
108
+
109
+ :host([current]) [part='link']:focus-visible::before {
110
+ opacity: 0.24;
111
+ }
112
+ }
113
+
114
+ slot[name='prefix']::slotted(:is(vaadin-icon, [class*='icon'])) {
115
+ padding: 0.1em;
116
+ flex-shrink: 0;
117
+ margin-inline-end: 24px;
118
+ color: var(--material-secondary-text-color);
119
+ }
120
+
121
+ :host([current]) slot[name='prefix']::slotted(:is(vaadin-icon, [class*='icon'])) {
122
+ color: inherit;
123
+ }
124
+
125
+ slot[name='children'] {
126
+ --_child-indent: calc(var(--_child-indent-2, 0px) + var(--vaadin-side-nav-child-indent, 24px));
127
+ }
128
+
129
+ slot[name='children']::slotted(*) {
130
+ --_child-indent-2: var(--_child-indent);
131
+ }
132
+ `;
133
+
134
+ registerStyles('vaadin-side-nav-item', [fieldButton, sideNavItemStyles], { moduleId: 'material-side-nav-item' });
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @license
3
+ * Copyright (c) 2023 Vaadin Ltd.
4
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
+ */
6
+ import './vaadin-side-nav-item-styles.js';
7
+ import '../../src/vaadin-side-nav-item.js';
@@ -0,0 +1,69 @@
1
+ import '@vaadin/vaadin-material-styles/color.js';
2
+ import '@vaadin/vaadin-material-styles/font-icons.js';
3
+ import '@vaadin/vaadin-material-styles/typography.js';
4
+ import { css, registerStyles } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
5
+
6
+ export const sideNavStyles = css`
7
+ :host {
8
+ -webkit-tap-highlight-color: transparent;
9
+ outline: none;
10
+ }
11
+
12
+ [part='label'] {
13
+ display: flex;
14
+ align-items: center;
15
+ width: 100%;
16
+ min-height: 40px;
17
+ margin: 4px 0;
18
+ padding: 4px 8px;
19
+ outline: none;
20
+ box-sizing: border-box;
21
+ font-family: var(--material-font-family);
22
+ font-size: var(--material-small-font-size);
23
+ color: var(--material-secondary-text-color);
24
+ line-height: 1;
25
+ font-weight: 500;
26
+ border-radius: 4px;
27
+ }
28
+
29
+ :host([focus-ring]) [part='label'] {
30
+ background-color: var(--material-divider-color);
31
+ }
32
+
33
+ [part='toggle-button'] {
34
+ display: inline-flex;
35
+ align-items: center;
36
+ justify-content: center;
37
+ width: 24px;
38
+ height: 24px;
39
+ padding: 4px;
40
+ margin-inline-start: auto;
41
+ margin-inline-end: -4px;
42
+ font-size: var(--material-icon-font-size);
43
+ line-height: 1;
44
+ color: var(--material-secondary-text-color);
45
+ font-family: 'material-icons';
46
+ transform: rotate(90deg);
47
+ }
48
+
49
+ [part='toggle-button']::before {
50
+ content: var(--material-icons-chevron-right);
51
+ font-size: 24px;
52
+ }
53
+
54
+ :host(:not([collapsible])) [part='toggle-button'] {
55
+ display: none !important;
56
+ }
57
+
58
+ :host(:not([collapsed])) [part='toggle-button'] {
59
+ transform: rotate(270deg);
60
+ }
61
+
62
+ @media (any-hover: hover) {
63
+ [part='label']:hover [part='toggle-button'] {
64
+ color: var(--material-body-text-color);
65
+ }
66
+ }
67
+ `;
68
+
69
+ registerStyles('vaadin-side-nav', sideNavStyles, { moduleId: 'material-side-nav' });
@@ -3,5 +3,6 @@
3
3
  * Copyright (c) 2023 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
+ import './vaadin-side-nav-item.js';
7
+ import './vaadin-side-nav-styles.js';
6
8
  import '../../src/vaadin-side-nav.js';
7
- import '../../src/vaadin-side-nav-item.js';
package/web-types.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/web-types",
3
3
  "name": "@vaadin/side-nav",
4
- "version": "24.2.0-alpha1",
4
+ "version": "24.2.0-alpha2",
5
5
  "description-markup": "markdown",
6
6
  "contributions": {
7
7
  "html": {
8
8
  "elements": [
9
9
  {
10
10
  "name": "vaadin-side-nav-item",
11
- "description": "A navigation item to be used within `<vaadin-side-nav>`. Represents a navigation target.\nNot intended to be used separately.\n\n```html\n<vaadin-side-nav-item>\n Item 1\n <vaadin-side-nav-item path=\"/path1\" slot=\"children\">\n Child item 1\n </vaadin-side-nav-item>\n <vaadin-side-nav-item path=\"/path2\" slot=\"children\">\n Child item 2\n </vaadin-side-nav-item>\n</vaadin-side-nav-item>\n```\n\n### Customization\n\nYou can configure the item by using `slot` names.\n\nSlot name | Description\n----------|-------------\n`prefix` | A slot for content before the label (e.g. an icon).\n`suffix` | A slot for content after the label (e.g. an icon).\n\n#### Example\n\n```html\n<vaadin-side-nav-item>\n <vaadin-icon icon=\"vaadin:chart\" slot=\"prefix\"></vaadin-icon>\n Item\n <span theme=\"badge primary\" slot=\"suffix\">Suffix</span>\n</vaadin-side-nav-item>\n```\n\n### Styling\n\nPart name | Description\n----------------|----------------\n`content` | The element that wraps link and toggle button\n`children` | The element that wraps child items\n`link` | The clickable anchor used for navigation\n`toggle-button` | The toggle button\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.",
11
+ "description": "A navigation item to be used within `<vaadin-side-nav>`. Represents a navigation target.\nNot intended to be used separately.\n\n```html\n<vaadin-side-nav-item>\n Item 1\n <vaadin-side-nav-item path=\"/path1\" slot=\"children\">\n Child item 1\n </vaadin-side-nav-item>\n <vaadin-side-nav-item path=\"/path2\" slot=\"children\">\n Child item 2\n </vaadin-side-nav-item>\n</vaadin-side-nav-item>\n```\n\n### Customization\n\nYou can configure the item by using `slot` names.\n\nSlot name | Description\n----------|-------------\n`prefix` | A slot for content before the label (e.g. an icon).\n`suffix` | A slot for content after the label (e.g. an icon).\n\n#### Example\n\n```html\n<vaadin-side-nav-item>\n <vaadin-icon icon=\"vaadin:chart\" slot=\"prefix\"></vaadin-icon>\n Item\n <span theme=\"badge primary\" slot=\"suffix\">Suffix</span>\n</vaadin-side-nav-item>\n```\n\n### Styling\n\nThe following shadow DOM parts are available for styling:\n\nPart name | Description\n----------------|----------------\n`content` | The element that wraps link and toggle button\n`children` | The element that wraps child items\n`link` | The clickable anchor used for navigation\n`toggle-button` | The toggle button\n\nThe following state attributes are available for styling:\n\nAttribute | Description\n---------------|-------------\n`expanded` | Set when the element is expanded.\n`has-children` | Set when the element has child items.\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.",
12
12
  "attributes": [
13
13
  {
14
14
  "name": "path",
@@ -21,17 +21,6 @@
21
21
  ]
22
22
  }
23
23
  },
24
- {
25
- "name": "path-aliases",
26
- "description": "A comma-separated list of alternative paths matching this item.",
27
- "value": {
28
- "type": [
29
- "string",
30
- "null",
31
- "undefined"
32
- ]
33
- }
34
- },
35
24
  {
36
25
  "name": "expanded",
37
26
  "description": "Whether to show the child items or not",
@@ -55,6 +44,15 @@
55
44
  ],
56
45
  "js": {
57
46
  "properties": [
47
+ {
48
+ "name": "i18n",
49
+ "description": "The object used to localize this component.\n\nTo change the default localization, replace the entire\n`i18n` object with a custom one.\n\nThe object has the following structure and default values:\n```\n{\n toggle: 'Toggle child items'\n}\n```",
50
+ "value": {
51
+ "type": [
52
+ "SideNavI18n"
53
+ ]
54
+ }
55
+ },
58
56
  {
59
57
  "name": "path",
60
58
  "description": "The path to navigate to",
@@ -68,12 +66,10 @@
68
66
  },
69
67
  {
70
68
  "name": "pathAliases",
71
- "description": "A comma-separated list of alternative paths matching this item.",
69
+ "description": "The list of alternative paths matching this item",
72
70
  "value": {
73
71
  "type": [
74
- "string",
75
- "null",
76
- "undefined"
72
+ "Array.<string>"
77
73
  ]
78
74
  }
79
75
  },
@@ -97,7 +93,7 @@
97
93
  },
98
94
  {
99
95
  "name": "vaadin-side-nav",
100
- "description": "`<vaadin-side-nav>` is a Web Component for navigation menus.\n\n```html\n<vaadin-side-nav>\n <vaadin-side-nav-item>Item 1</vaadin-side-nav-item>\n <vaadin-side-nav-item>Item 2</vaadin-side-nav-item>\n <vaadin-side-nav-item>Item 3</vaadin-side-nav-item>\n <vaadin-side-nav-item>Item 4</vaadin-side-nav-item>\n</vaadin-side-nav>\n```\n\n### Customization\n\nYou can configure the component by using `slot` names.\n\nSlot name | Description\n----------|-------------\n`label` | The label (text) inside the side nav.\n\n#### Example\n\n```html\n<vaadin-side-nav>\n <span slot=\"label\">Main menu</span>\n <vaadin-side-nav-item>Item</vaadin-side-nav-item>\n</vaadin-side-nav>\n```\n\n### Styling\n\nPart name | Description\n----------------|----------------\n`label` | The label element\n`children` | The element that wraps child items\n`toggle-button` | The toggle button\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.",
96
+ "description": "`<vaadin-side-nav>` is a Web Component for navigation menus.\n\n```html\n<vaadin-side-nav>\n <vaadin-side-nav-item>Item 1</vaadin-side-nav-item>\n <vaadin-side-nav-item>Item 2</vaadin-side-nav-item>\n <vaadin-side-nav-item>Item 3</vaadin-side-nav-item>\n <vaadin-side-nav-item>Item 4</vaadin-side-nav-item>\n</vaadin-side-nav>\n```\n\n### Customization\n\nYou can configure the component by using `slot` names.\n\nSlot name | Description\n----------|-------------\n`label` | The label (text) inside the side nav.\n\n#### Example\n\n```html\n<vaadin-side-nav>\n <span slot=\"label\">Main menu</span>\n <vaadin-side-nav-item>Item</vaadin-side-nav-item>\n</vaadin-side-nav>\n```\n\n### Styling\n\nThe following shadow DOM parts are available for styling:\n\nPart name | Description\n----------------|----------------\n`label` | The label element\n`children` | The element that wraps child items\n`toggle-button` | The toggle button\n\nThe following state attributes are available for styling:\n\nAttribute | Description\n-------------|-------------\n`collapsed` | Set when the element is collapsed.\n`focus-ring` | Set when the label is focused using the keyboard.\n`focused` | Set when the label is focused.\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.",
101
97
  "attributes": [
102
98
  {
103
99
  "name": "collapsible",
@@ -131,6 +127,15 @@
131
127
  ],
132
128
  "js": {
133
129
  "properties": [
130
+ {
131
+ "name": "i18n",
132
+ "description": "The object used to localize this component.\n\nTo change the default localization, replace the entire\n`i18n` object with a custom one.\n\nThe object has the following structure and default values:\n```\n{\n toggle: 'Toggle child items'\n}\n```",
133
+ "value": {
134
+ "type": [
135
+ "SideNavI18n"
136
+ ]
137
+ }
138
+ },
134
139
  {
135
140
  "name": "collapsible",
136
141
  "description": "Whether the side nav is collapsible. When enabled, the toggle icon is shown.",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/web-types",
3
3
  "name": "@vaadin/side-nav",
4
- "version": "24.2.0-alpha1",
4
+ "version": "24.2.0-alpha2",
5
5
  "description-markup": "markdown",
6
6
  "framework": "lit",
7
7
  "framework-config": {
@@ -16,7 +16,7 @@
16
16
  "elements": [
17
17
  {
18
18
  "name": "vaadin-side-nav-item",
19
- "description": "A navigation item to be used within `<vaadin-side-nav>`. Represents a navigation target.\nNot intended to be used separately.\n\n```html\n<vaadin-side-nav-item>\n Item 1\n <vaadin-side-nav-item path=\"/path1\" slot=\"children\">\n Child item 1\n </vaadin-side-nav-item>\n <vaadin-side-nav-item path=\"/path2\" slot=\"children\">\n Child item 2\n </vaadin-side-nav-item>\n</vaadin-side-nav-item>\n```\n\n### Customization\n\nYou can configure the item by using `slot` names.\n\nSlot name | Description\n----------|-------------\n`prefix` | A slot for content before the label (e.g. an icon).\n`suffix` | A slot for content after the label (e.g. an icon).\n\n#### Example\n\n```html\n<vaadin-side-nav-item>\n <vaadin-icon icon=\"vaadin:chart\" slot=\"prefix\"></vaadin-icon>\n Item\n <span theme=\"badge primary\" slot=\"suffix\">Suffix</span>\n</vaadin-side-nav-item>\n```\n\n### Styling\n\nPart name | Description\n----------------|----------------\n`content` | The element that wraps link and toggle button\n`children` | The element that wraps child items\n`link` | The clickable anchor used for navigation\n`toggle-button` | The toggle button\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.",
19
+ "description": "A navigation item to be used within `<vaadin-side-nav>`. Represents a navigation target.\nNot intended to be used separately.\n\n```html\n<vaadin-side-nav-item>\n Item 1\n <vaadin-side-nav-item path=\"/path1\" slot=\"children\">\n Child item 1\n </vaadin-side-nav-item>\n <vaadin-side-nav-item path=\"/path2\" slot=\"children\">\n Child item 2\n </vaadin-side-nav-item>\n</vaadin-side-nav-item>\n```\n\n### Customization\n\nYou can configure the item by using `slot` names.\n\nSlot name | Description\n----------|-------------\n`prefix` | A slot for content before the label (e.g. an icon).\n`suffix` | A slot for content after the label (e.g. an icon).\n\n#### Example\n\n```html\n<vaadin-side-nav-item>\n <vaadin-icon icon=\"vaadin:chart\" slot=\"prefix\"></vaadin-icon>\n Item\n <span theme=\"badge primary\" slot=\"suffix\">Suffix</span>\n</vaadin-side-nav-item>\n```\n\n### Styling\n\nThe following shadow DOM parts are available for styling:\n\nPart name | Description\n----------------|----------------\n`content` | The element that wraps link and toggle button\n`children` | The element that wraps child items\n`link` | The clickable anchor used for navigation\n`toggle-button` | The toggle button\n\nThe following state attributes are available for styling:\n\nAttribute | Description\n---------------|-------------\n`expanded` | Set when the element is expanded.\n`has-children` | Set when the element has child items.\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.",
20
20
  "extension": true,
21
21
  "attributes": [
22
22
  {
@@ -26,6 +26,13 @@
26
26
  "kind": "expression"
27
27
  }
28
28
  },
29
+ {
30
+ "name": ".i18n",
31
+ "description": "The object used to localize this component.\n\nTo change the default localization, replace the entire\n`i18n` object with a custom one.\n\nThe object has the following structure and default values:\n```\n{\n toggle: 'Toggle child items'\n}\n```",
32
+ "value": {
33
+ "kind": "expression"
34
+ }
35
+ },
29
36
  {
30
37
  "name": ".path",
31
38
  "description": "The path to navigate to",
@@ -35,7 +42,7 @@
35
42
  },
36
43
  {
37
44
  "name": ".pathAliases",
38
- "description": "A comma-separated list of alternative paths matching this item.",
45
+ "description": "The list of alternative paths matching this item",
39
46
  "value": {
40
47
  "kind": "expression"
41
48
  }
@@ -51,7 +58,7 @@
51
58
  },
52
59
  {
53
60
  "name": "vaadin-side-nav",
54
- "description": "`<vaadin-side-nav>` is a Web Component for navigation menus.\n\n```html\n<vaadin-side-nav>\n <vaadin-side-nav-item>Item 1</vaadin-side-nav-item>\n <vaadin-side-nav-item>Item 2</vaadin-side-nav-item>\n <vaadin-side-nav-item>Item 3</vaadin-side-nav-item>\n <vaadin-side-nav-item>Item 4</vaadin-side-nav-item>\n</vaadin-side-nav>\n```\n\n### Customization\n\nYou can configure the component by using `slot` names.\n\nSlot name | Description\n----------|-------------\n`label` | The label (text) inside the side nav.\n\n#### Example\n\n```html\n<vaadin-side-nav>\n <span slot=\"label\">Main menu</span>\n <vaadin-side-nav-item>Item</vaadin-side-nav-item>\n</vaadin-side-nav>\n```\n\n### Styling\n\nPart name | Description\n----------------|----------------\n`label` | The label element\n`children` | The element that wraps child items\n`toggle-button` | The toggle button\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.",
61
+ "description": "`<vaadin-side-nav>` is a Web Component for navigation menus.\n\n```html\n<vaadin-side-nav>\n <vaadin-side-nav-item>Item 1</vaadin-side-nav-item>\n <vaadin-side-nav-item>Item 2</vaadin-side-nav-item>\n <vaadin-side-nav-item>Item 3</vaadin-side-nav-item>\n <vaadin-side-nav-item>Item 4</vaadin-side-nav-item>\n</vaadin-side-nav>\n```\n\n### Customization\n\nYou can configure the component by using `slot` names.\n\nSlot name | Description\n----------|-------------\n`label` | The label (text) inside the side nav.\n\n#### Example\n\n```html\n<vaadin-side-nav>\n <span slot=\"label\">Main menu</span>\n <vaadin-side-nav-item>Item</vaadin-side-nav-item>\n</vaadin-side-nav>\n```\n\n### Styling\n\nThe following shadow DOM parts are available for styling:\n\nPart name | Description\n----------------|----------------\n`label` | The label element\n`children` | The element that wraps child items\n`toggle-button` | The toggle button\n\nThe following state attributes are available for styling:\n\nAttribute | Description\n-------------|-------------\n`collapsed` | Set when the element is collapsed.\n`focus-ring` | Set when the label is focused using the keyboard.\n`focused` | Set when the label is focused.\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.",
55
62
  "extension": true,
56
63
  "attributes": [
57
64
  {
@@ -68,6 +75,13 @@
68
75
  "kind": "expression"
69
76
  }
70
77
  },
78
+ {
79
+ "name": ".i18n",
80
+ "description": "The object used to localize this component.\n\nTo change the default localization, replace the entire\n`i18n` object with a custom one.\n\nThe object has the following structure and default values:\n```\n{\n toggle: 'Toggle child items'\n}\n```",
81
+ "value": {
82
+ "kind": "expression"
83
+ }
84
+ },
71
85
  {
72
86
  "name": "@collapsed-changed",
73
87
  "description": "Fired when the `collapsed` property changes.",