@vaadin/side-nav 25.0.0-alpha9 → 25.0.0-beta2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vaadin/side-nav",
3
- "version": "25.0.0-alpha9",
3
+ "version": "25.0.0-beta2",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -21,9 +21,6 @@
21
21
  "type": "module",
22
22
  "files": [
23
23
  "src",
24
- "!src/styles/*-base-styles.d.ts",
25
- "!src/styles/*-base-styles.js",
26
- "theme",
27
24
  "vaadin-*.d.ts",
28
25
  "vaadin-*.js",
29
26
  "web-types.json",
@@ -37,22 +34,22 @@
37
34
  ],
38
35
  "dependencies": {
39
36
  "@open-wc/dedupe-mixin": "^1.3.0",
40
- "@vaadin/a11y-base": "25.0.0-alpha9",
41
- "@vaadin/component-base": "25.0.0-alpha9",
42
- "@vaadin/vaadin-lumo-styles": "25.0.0-alpha9",
43
- "@vaadin/vaadin-themable-mixin": "25.0.0-alpha9",
37
+ "@vaadin/a11y-base": "25.0.0-beta2",
38
+ "@vaadin/component-base": "25.0.0-beta2",
39
+ "@vaadin/vaadin-themable-mixin": "25.0.0-beta2",
44
40
  "lit": "^3.0.0"
45
41
  },
46
42
  "devDependencies": {
47
- "@vaadin/chai-plugins": "25.0.0-alpha9",
48
- "@vaadin/test-runner-commands": "25.0.0-alpha9",
43
+ "@vaadin/chai-plugins": "25.0.0-beta2",
44
+ "@vaadin/test-runner-commands": "25.0.0-beta2",
49
45
  "@vaadin/testing-helpers": "^2.0.0",
46
+ "@vaadin/vaadin-lumo-styles": "25.0.0-beta2",
50
47
  "lit": "^3.0.0",
51
- "sinon": "^18.0.0"
48
+ "sinon": "^21.0.0"
52
49
  },
53
50
  "web-types": [
54
51
  "web-types.json",
55
52
  "web-types.lit.json"
56
53
  ],
57
- "gitHead": "bbe4720721e0955ffc87a79b412bee38b1f0eb1e"
54
+ "gitHead": "e078f8371ae266f05c7ca1ec25686cc489c83f24"
58
55
  }
@@ -3,7 +3,7 @@
3
3
  * Copyright (c) 2023 - 2025 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/component-base/src/style-props.js';
6
+ import '@vaadin/component-base/src/styles/style-props.js';
7
7
  import { css } from 'lit';
8
8
  import { sharedStyles } from './vaadin-side-nav-shared-base-styles.js';
9
9
 
@@ -18,25 +18,47 @@ const sideNav = css`
18
18
  display: flex;
19
19
  align-items: center;
20
20
  justify-content: start;
21
- gap: var(--vaadin-side-nav-item-gap, var(--vaadin-gap-container-inline));
21
+ gap: var(--vaadin-side-nav-item-gap, var(--vaadin-gap-s));
22
22
  padding: var(--vaadin-side-nav-item-padding, var(--vaadin-padding-container));
23
- font-size: var(--vaadin-side-nav-label-font-size, 0.875em);
23
+ font-size: var(--vaadin-side-nav-label-font-size, max(11px, 0.875em));
24
24
  font-weight: var(--vaadin-side-nav-label-font-weight, 500);
25
- color: var(--vaadin-side-nav-label-color, var(--vaadin-color-subtle));
25
+ color: var(--vaadin-side-nav-label-color, var(--vaadin-text-color-secondary));
26
26
  line-height: var(--vaadin-side-nav-label-line-height, inherit);
27
27
  border-radius: var(--vaadin-side-nav-item-border-radius, var(--vaadin-radius-m));
28
28
  touch-action: manipulation;
29
+ min-width: 0;
30
+ max-width: 100%;
31
+ }
32
+
33
+ ::slotted([slot='label']) {
34
+ min-width: 0;
35
+ overflow: hidden;
36
+ text-overflow: ellipsis;
37
+ margin: 0;
29
38
  }
30
39
  `;
31
40
 
32
41
  export const sideNavStyles = [sharedStyles, sideNav];
33
42
 
34
43
  export const sideNavSlotStyles = css`
35
- :where(vaadin-side-nav:has(vaadin-icon[slot='prefix'])) {
36
- --_has-prefix-icon: '';
44
+ :where(vaadin-side-nav:has(> vaadin-side-nav-item > vaadin-icon[slot='prefix']))::part(children),
45
+ :where(vaadin-side-nav-item:has(> vaadin-side-nav-item[slot='children'] > vaadin-icon[slot='prefix']))::part(
46
+ children
47
+ ) {
48
+ --_icon-indent: calc(var(--_icon-indent-2, 0) + 1);
49
+ }
50
+
51
+ :where(vaadin-side-nav-item:has(> vaadin-icon[slot='prefix']))::part(content) {
52
+ --_icon-indent: calc(var(--_icon-indent-2) - 1);
53
+ }
54
+
55
+ :where(
56
+ vaadin-side-nav-item:has(> vaadin-icon[slot='prefix']):has(> vaadin-side-nav-item > vaadin-icon[slot='prefix'])
57
+ )::part(children) {
58
+ --_level: var(--_level-2, 0);
37
59
  }
38
60
 
39
- :where(vaadin-side-nav-item:has(> vaadin-icon[slot='prefix']))::part(link) {
40
- --_has-prefix-icon:;
61
+ vaadin-side-nav:not(:has([slot='label']))::part(label) {
62
+ display: none;
41
63
  }
42
64
  `;
@@ -3,20 +3,24 @@
3
3
  * Copyright (c) 2023 - 2025 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/component-base/src/style-props.js';
6
+ import '@vaadin/component-base/src/styles/style-props.js';
7
7
  import { css } from 'lit';
8
+ import { screenReaderOnly } from '@vaadin/a11y-base/src/styles/sr-only-styles.js';
8
9
  import { sharedStyles } from './vaadin-side-nav-shared-base-styles.js';
9
10
 
10
11
  const sideNavItem = css`
11
12
  [part='content'] {
12
13
  display: flex;
13
14
  align-items: center;
15
+ min-width: 0;
16
+ max-width: 100%;
14
17
  padding: var(--vaadin-side-nav-item-padding, var(--vaadin-padding-container));
15
- gap: var(--vaadin-side-nav-item-gap, var(--vaadin-gap-container-inline));
18
+ --_gap: var(--vaadin-side-nav-item-gap, var(--vaadin-gap-s));
19
+ gap: var(--_gap);
16
20
  font-size: var(--vaadin-side-nav-item-font-size, 1em);
17
21
  font-weight: var(--vaadin-side-nav-item-font-weight, 500);
18
22
  line-height: var(--vaadin-side-nav-item-line-height, inherit);
19
- color: var(--vaadin-side-nav-item-color, var(--vaadin-color-subtle));
23
+ color: var(--vaadin-side-nav-item-text-color, var(--vaadin-text-color-secondary));
20
24
  background: var(--vaadin-side-nav-item-background, transparent);
21
25
  background-origin: border-box;
22
26
  border: var(--vaadin-side-nav-item-border-width, 0) solid var(--vaadin-side-nav-item-border-color, transparent);
@@ -27,7 +31,7 @@ const sideNavItem = css`
27
31
 
28
32
  :host([current]) [part='content'] {
29
33
  --vaadin-side-nav-item-background: var(--vaadin-background-container);
30
- --vaadin-side-nav-item-color: var(--vaadin-color);
34
+ --vaadin-side-nav-item-text-color: var(--vaadin-text-color);
31
35
  }
32
36
 
33
37
  :host([disabled]) {
@@ -35,7 +39,7 @@ const sideNavItem = css`
35
39
  }
36
40
 
37
41
  :host([disabled]) [part='content'] {
38
- --vaadin-side-nav-item-color: var(--vaadin-color-disabled);
42
+ --vaadin-side-nav-item-text-color: var(--vaadin-text-color-disabled);
39
43
  }
40
44
 
41
45
  [part='link'] {
@@ -68,14 +72,6 @@ const sideNavItem = css`
68
72
  flex: none;
69
73
  }
70
74
 
71
- /* Reserved space for icon */
72
- slot[name='prefix']::before {
73
- content: var(--_has-prefix-icon);
74
- display: block;
75
- width: var(--vaadin-icon-size, 1lh);
76
- flex: none;
77
- }
78
-
79
75
  [part='content']:not(:has([href])):has([part='toggle-button']:focus-visible),
80
76
  [part='content']:has(:not([part='toggle-button']):focus-visible),
81
77
  [part='content']:has([href]) [part='toggle-button']:focus-visible {
@@ -89,34 +85,40 @@ const sideNavItem = css`
89
85
  /* Hierarchy indentation */
90
86
  [part='content']::before {
91
87
  content: '';
92
- --_hierarchy-indent: calc(var(--_level, 0) * var(--vaadin-side-nav-child-indent, var(--vaadin-icon-size, 1lh)));
93
- --_icon-indent: calc(var(--_level, 0) * var(--vaadin-side-nav-item-gap, var(--vaadin-gap-container-inline)));
94
- width: calc(var(--_hierarchy-indent) + var(--_icon-indent));
88
+ width: calc(
89
+ var(--vaadin-side-nav-child-indent, 1em) * var(--_level, 0) + var(--_icon-indent, 0) *
90
+ (var(--vaadin-icon-size, 1lh) + var(--_gap))
91
+ );
95
92
  flex: none;
96
- margin-inline-start: calc(var(--vaadin-side-nav-item-gap, var(--vaadin-gap-container-inline)) * -1);
93
+ margin-inline-start: calc(var(--_gap) * -1);
97
94
  }
98
95
 
99
- slot[name='children'] {
96
+ [part='children'] {
100
97
  --_level: calc(var(--_level-2, 0) + 1);
101
98
  }
102
99
 
103
- slot[name='children']::slotted(*) {
100
+ [part='children'] ::slotted(*) {
104
101
  --_level-2: var(--_level);
105
102
  }
106
103
 
107
104
  @media (forced-colors: active) {
105
+ [part='content'] {
106
+ border: 1px solid Canvas !important;
107
+ }
108
+
108
109
  :host([current]) [part='content'] {
109
- color: Highlight;
110
+ color: Highlight !important;
111
+ border-color: Highlight !important;
110
112
  }
111
113
 
112
114
  :host([disabled]) [part='content'] {
113
- --vaadin-side-nav-item-color: GrayText;
115
+ --vaadin-side-nav-item-text-color: GrayText !important;
114
116
  }
115
117
 
116
118
  :host([disabled]) [part='toggle-button']::before {
117
- background: GrayText;
119
+ background: GrayText !important;
118
120
  }
119
121
  }
120
122
  `;
121
123
 
122
- export const sideNavItemStyles = [sharedStyles, sideNavItem];
124
+ export const sideNavItemStyles = [sharedStyles, screenReaderOnly, sideNavItem];
@@ -3,14 +3,16 @@
3
3
  * Copyright (c) 2023 - 2025 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/component-base/src/style-props.js';
6
+ import '@vaadin/component-base/src/styles/style-props.js';
7
7
  import { css } from 'lit';
8
8
 
9
9
  export const sharedStyles = css`
10
10
  :host {
11
11
  display: flex;
12
12
  flex-direction: column;
13
- gap: var(--vaadin-side-nav-items-gap, var(--vaadin-gap-container-block));
13
+ min-width: 0;
14
+ max-width: 100%;
15
+ gap: var(--vaadin-side-nav-items-gap, var(--vaadin-gap-s));
14
16
  cursor: default;
15
17
  -webkit-tap-highlight-color: transparent;
16
18
  }
@@ -35,14 +37,14 @@ export const sharedStyles = css`
35
37
 
36
38
  [part='toggle-button'] {
37
39
  border-radius: var(--vaadin-side-nav-item-border-radius, var(--vaadin-radius-s));
38
- color: var(--vaadin-color-subtle);
40
+ color: var(--vaadin-text-color-secondary);
39
41
  }
40
42
 
41
43
  [part='toggle-button']::before {
42
44
  content: '';
43
45
  display: block;
44
46
  background: currentColor;
45
- mask-image: var(--_vaadin-icon-chevron-down);
47
+ mask: var(--_vaadin-icon-chevron-down) 50% / var(--vaadin-icon-visual-size, 100%) no-repeat;
46
48
  width: var(--vaadin-icon-size, 1lh);
47
49
  height: var(--vaadin-icon-size, 1lh);
48
50
  rotate: -90deg;
@@ -76,7 +78,11 @@ export const sharedStyles = css`
76
78
  list-style-type: none;
77
79
  display: flex;
78
80
  flex-direction: column;
79
- gap: var(--vaadin-side-nav-items-gap, var(--vaadin-gap-container-block));
81
+ gap: var(--vaadin-side-nav-items-gap, var(--vaadin-gap-s));
82
+ }
83
+
84
+ [part='children'] slot {
85
+ --_icon-indent-2: var(--_icon-indent);
80
86
  }
81
87
 
82
88
  :focus-visible {
@@ -21,7 +21,7 @@ export declare class SideNavChildrenMixinClass {
21
21
  * just the individual properties you want to change.
22
22
  *
23
23
  * The object has the following structure and default values:
24
- * ```
24
+ * ```js
25
25
  * {
26
26
  * toggle: 'Toggle child items'
27
27
  * }
@@ -65,7 +65,7 @@ export const SideNavChildrenMixin = (superClass) =>
65
65
  * just the individual properties you want to change.
66
66
  *
67
67
  * The object has the following structure and default values:
68
- * ```
68
+ * ```js
69
69
  * {
70
70
  * toggle: 'Toggle child items'
71
71
  * }
@@ -72,6 +72,7 @@ export type SideNavItemEventMap = HTMLElementEventMap & SideNavItemCustomEventMa
72
72
  * `disabled` | Set when the element is disabled.
73
73
  * `expanded` | Set when the element is expanded.
74
74
  * `has-children` | Set when the element has child items.
75
+ * `has-tooltip` | Set when the element has a slotted tooltip.
75
76
  *
76
77
  * See [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.
77
78
  *
@@ -9,11 +9,12 @@ import { DisabledMixin } from '@vaadin/a11y-base/src/disabled-mixin.js';
9
9
  import { defineCustomElement } from '@vaadin/component-base/src/define.js';
10
10
  import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
11
11
  import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
12
+ import { TooltipController } from '@vaadin/component-base/src/tooltip-controller.js';
12
13
  import { matchPaths } from '@vaadin/component-base/src/url-utils.js';
13
14
  import { LumoInjectionMixin } from '@vaadin/vaadin-themable-mixin/lumo-injection-mixin.js';
14
15
  import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
15
16
  import { location } from './location.js';
16
- import { sideNavItemStyles } from './styles/vaadin-side-nav-item-core-styles.js';
17
+ import { sideNavItemStyles } from './styles/vaadin-side-nav-item-base-styles.js';
17
18
  import { SideNavChildrenMixin } from './vaadin-side-nav-children-mixin.js';
18
19
 
19
20
  /**
@@ -69,6 +70,7 @@ import { SideNavChildrenMixin } from './vaadin-side-nav-children-mixin.js';
69
70
  * `disabled` | Set when the element is disabled.
70
71
  * `expanded` | Set when the element is expanded.
71
72
  * `has-children` | Set when the element has child items.
73
+ * `has-tooltip` | Set when the element has a slotted tooltip.
72
74
  *
73
75
  * See [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.
74
76
  *
@@ -174,6 +176,11 @@ class SideNavItem extends SideNavChildrenMixin(
174
176
  type: Boolean,
175
177
  value: false,
176
178
  },
179
+
180
+ /** @private */
181
+ __tooltipText: {
182
+ type: String,
183
+ },
177
184
  };
178
185
  }
179
186
 
@@ -246,7 +253,7 @@ class SideNavItem extends SideNavChildrenMixin(
246
253
  /** @protected */
247
254
  render() {
248
255
  return html`
249
- <div part="content" @click="${this._onContentClick}">
256
+ <div id="content" part="content" @click="${this._onContentClick}">
250
257
  <a
251
258
  id="link"
252
259
  ?disabled="${this.disabled}"
@@ -259,6 +266,7 @@ class SideNavItem extends SideNavChildrenMixin(
259
266
  >
260
267
  <slot name="prefix"></slot>
261
268
  <slot></slot>
269
+ <div class="sr-only">${this.__tooltipText}</div>
262
270
  <slot name="suffix"></slot>
263
271
  </a>
264
272
  <button
@@ -274,9 +282,29 @@ class SideNavItem extends SideNavChildrenMixin(
274
282
  <slot name="children"></slot>
275
283
  </ul>
276
284
  <div hidden id="i18n">${this.__effectiveI18n.toggle}</div>
285
+ <slot name="tooltip"></slot>
277
286
  `;
278
287
  }
279
288
 
289
+ /** @protected */
290
+ ready() {
291
+ super.ready();
292
+
293
+ this._tooltipController = new TooltipController(this);
294
+ this._tooltipController.setTarget(this.$.content);
295
+ this._tooltipController.setAriaTarget(null);
296
+ this._tooltipController.addEventListener('tooltip-changed', (event) => {
297
+ const { node } = event.detail;
298
+ if (node) {
299
+ this.__tooltipText = node.textContent.trim();
300
+ node.setAttribute('aria-hidden', 'true');
301
+ } else {
302
+ this.__tooltipText = '';
303
+ }
304
+ });
305
+ this.addController(this._tooltipController);
306
+ }
307
+
280
308
  /** @private */
281
309
  _onButtonClick(event) {
282
310
  // Prevent the event from being handled
@@ -313,6 +341,11 @@ class SideNavItem extends SideNavChildrenMixin(
313
341
 
314
342
  /** @private */
315
343
  __expandParentItems() {
344
+ const sideNav = this.closest('vaadin-side-nav');
345
+ if (sideNav && sideNav.noAutoExpand) {
346
+ return;
347
+ }
348
+
316
349
  const parentItem = this.__getParentItem();
317
350
  if (parentItem) {
318
351
  parentItem.__expandParentItems();
@@ -127,6 +127,15 @@ declare class SideNav extends SideNavChildrenMixin(FocusMixin(ElementMixin(Thema
127
127
  */
128
128
  location: any;
129
129
 
130
+ /**
131
+ * Whether to expand parent items of the nested matching item after initial
132
+ * rendering or navigation. By default, all the parent items are expanded.
133
+ * Set to true to disable this behavior.
134
+ *
135
+ * @attr {boolean} no-auto-expand
136
+ */
137
+ noAutoExpand: boolean;
138
+
130
139
  addEventListener<K extends keyof SideNavEventMap>(
131
140
  type: K,
132
141
  listener: (this: SideNav, ev: SideNavEventMap[K]) => void,
@@ -13,7 +13,7 @@ import { SlotStylesMixin } from '@vaadin/component-base/src/slot-styles-mixin.js
13
13
  import { generateUniqueId } from '@vaadin/component-base/src/unique-id-utils.js';
14
14
  import { LumoInjectionMixin } from '@vaadin/vaadin-themable-mixin/lumo-injection-mixin.js';
15
15
  import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
16
- import { sideNavSlotStyles, sideNavStyles } from './styles/vaadin-side-nav-core-styles.js';
16
+ import { sideNavSlotStyles, sideNavStyles } from './styles/vaadin-side-nav-base-styles.js';
17
17
  import { SideNavChildrenMixin } from './vaadin-side-nav-children-mixin.js';
18
18
 
19
19
  /**
@@ -150,6 +150,19 @@ class SideNav extends SideNavChildrenMixin(
150
150
  location: {
151
151
  observer: '__locationChanged',
152
152
  },
153
+
154
+ /**
155
+ * Whether to expand parent items of the nested matching item after initial
156
+ * rendering or navigation. By default, all the parent items are expanded.
157
+ * Set to true to disable this behavior.
158
+ *
159
+ * @attr {boolean} no-auto-expand
160
+ */
161
+ noAutoExpand: {
162
+ type: Boolean,
163
+ reflectToAttribute: true,
164
+ value: false,
165
+ },
153
166
  };
154
167
  }
155
168
 
@@ -1,2 +1,2 @@
1
- import './theme/lumo/vaadin-side-nav-item.js';
1
+ import './src/vaadin-side-nav-item.js';
2
2
  export * from './src/vaadin-side-nav-item.js';
@@ -1,2 +1,2 @@
1
- import './theme/lumo/vaadin-side-nav.js';
1
+ import './src/vaadin-side-nav.js';
2
2
  export * from './src/vaadin-side-nav.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": "25.0.0-alpha9",
4
+ "version": "25.0.0-beta2",
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\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`disabled` | Set when the element is disabled.\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.",
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`disabled` | Set when the element is disabled.\n`expanded` | Set when the element is expanded.\n`has-children` | Set when the element has child items.\n`has-tooltip` | Set when the element has a slotted tooltip.\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.",
12
12
  "attributes": [
13
13
  {
14
14
  "name": "disabled",
@@ -97,7 +97,7 @@
97
97
  },
98
98
  {
99
99
  "name": "i18n",
100
- "description": "The object used to localize this component. To change the default\nlocalization, replace this with an object that provides all properties, or\njust the individual properties you want to change.\n\nThe object has the following structure and default values:\n```\n{\n toggle: 'Toggle child items'\n}\n```",
100
+ "description": "The object used to localize this component. To change the default\nlocalization, replace this with an object that provides all properties, or\njust the individual properties you want to change.\n\nThe object has the following structure and default values:\n```js\n{\n toggle: 'Toggle child items'\n}\n```",
101
101
  "value": {
102
102
  "type": [
103
103
  "SideNavI18n"
@@ -212,6 +212,17 @@
212
212
  ]
213
213
  }
214
214
  },
215
+ {
216
+ "name": "no-auto-expand",
217
+ "description": "Whether to expand parent items of the nested matching item after initial\nrendering or navigation. By default, all the parent items are expanded.\nSet to true to disable this behavior.",
218
+ "value": {
219
+ "type": [
220
+ "boolean",
221
+ "null",
222
+ "undefined"
223
+ ]
224
+ }
225
+ },
215
226
  {
216
227
  "name": "theme",
217
228
  "description": "The theme variants to apply to the component.",
@@ -228,7 +239,7 @@
228
239
  "properties": [
229
240
  {
230
241
  "name": "i18n",
231
- "description": "The object used to localize this component. To change the default\nlocalization, replace this with an object that provides all properties, or\njust the individual properties you want to change.\n\nThe object has the following structure and default values:\n```\n{\n toggle: 'Toggle child items'\n}\n```",
242
+ "description": "The object used to localize this component. To change the default\nlocalization, replace this with an object that provides all properties, or\njust the individual properties you want to change.\n\nThe object has the following structure and default values:\n```js\n{\n toggle: 'Toggle child items'\n}\n```",
232
243
  "value": {
233
244
  "type": [
234
245
  "SideNavI18n"
@@ -271,6 +282,17 @@
271
282
  "any"
272
283
  ]
273
284
  }
285
+ },
286
+ {
287
+ "name": "noAutoExpand",
288
+ "description": "Whether to expand parent items of the nested matching item after initial\nrendering or navigation. By default, all the parent items are expanded.\nSet to true to disable this behavior.",
289
+ "value": {
290
+ "type": [
291
+ "boolean",
292
+ "null",
293
+ "undefined"
294
+ ]
295
+ }
274
296
  }
275
297
  ],
276
298
  "events": [
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/web-types",
3
3
  "name": "@vaadin/side-nav",
4
- "version": "25.0.0-alpha9",
4
+ "version": "25.0.0-beta2",
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\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`disabled` | Set when the element is disabled.\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.",
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`disabled` | Set when the element is disabled.\n`expanded` | Set when the element is expanded.\n`has-children` | Set when the element has child items.\n`has-tooltip` | Set when the element has a slotted tooltip.\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.",
20
20
  "extension": true,
21
21
  "attributes": [
22
22
  {
@@ -49,7 +49,7 @@
49
49
  },
50
50
  {
51
51
  "name": ".i18n",
52
- "description": "The object used to localize this component. To change the default\nlocalization, replace this with an object that provides all properties, or\njust the individual properties you want to change.\n\nThe object has the following structure and default values:\n```\n{\n toggle: 'Toggle child items'\n}\n```",
52
+ "description": "The object used to localize this component. To change the default\nlocalization, replace this with an object that provides all properties, or\njust the individual properties you want to change.\n\nThe object has the following structure and default values:\n```js\n{\n toggle: 'Toggle child items'\n}\n```",
53
53
  "value": {
54
54
  "kind": "expression"
55
55
  }
@@ -110,9 +110,16 @@
110
110
  "kind": "expression"
111
111
  }
112
112
  },
113
+ {
114
+ "name": "?noAutoExpand",
115
+ "description": "Whether to expand parent items of the nested matching item after initial\nrendering or navigation. By default, all the parent items are expanded.\nSet to true to disable this behavior.",
116
+ "value": {
117
+ "kind": "expression"
118
+ }
119
+ },
113
120
  {
114
121
  "name": ".i18n",
115
- "description": "The object used to localize this component. To change the default\nlocalization, replace this with an object that provides all properties, or\njust the individual properties you want to change.\n\nThe object has the following structure and default values:\n```\n{\n toggle: 'Toggle child items'\n}\n```",
122
+ "description": "The object used to localize this component. To change the default\nlocalization, replace this with an object that provides all properties, or\njust the individual properties you want to change.\n\nThe object has the following structure and default values:\n```js\n{\n toggle: 'Toggle child items'\n}\n```",
116
123
  "value": {
117
124
  "kind": "expression"
118
125
  }
@@ -1,10 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright (c) 2023 - 2025 Vaadin Ltd.
4
- * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
- */
6
- import type { CSSResult } from 'lit';
7
-
8
- export const sideNavStyles: CSSResult;
9
-
10
- export const sideNavSlotStyles: CSSResult;
@@ -1,39 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright (c) 2023 - 2025 Vaadin Ltd.
4
- * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
- */
6
- import { css } from 'lit';
7
-
8
- export const sideNavStyles = css`
9
- :host {
10
- display: block;
11
- }
12
-
13
- :host([hidden]) {
14
- display: none !important;
15
- }
16
-
17
- button {
18
- display: flex;
19
- align-items: center;
20
- justify-content: inherit;
21
- width: 100%;
22
- margin: 0;
23
- padding: 0;
24
- background-color: initial;
25
- color: inherit;
26
- border: initial;
27
- outline: none;
28
- font: inherit;
29
- text-align: inherit;
30
- }
31
-
32
- [part='children'] {
33
- padding: 0;
34
- margin: 0;
35
- list-style-type: none;
36
- }
37
- `;
38
-
39
- export const sideNavSlotStyles = css``;
@@ -1,8 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright (c) 2023 - 2025 Vaadin Ltd.
4
- * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
- */
6
- import type { CSSResult } from 'lit';
7
-
8
- export const sideNavItemStyles: CSSResult;
@@ -1,70 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright (c) 2023 - 2025 Vaadin Ltd.
4
- * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
- */
6
- import { css } from 'lit';
7
-
8
- export const sideNavItemStyles = css`
9
- :host {
10
- display: block;
11
- }
12
-
13
- :host([hidden]),
14
- [hidden] {
15
- display: none !important;
16
- }
17
-
18
- :host([disabled]) {
19
- pointer-events: none;
20
- }
21
-
22
- [part='content'] {
23
- display: flex;
24
- align-items: center;
25
- }
26
-
27
- [part='link'] {
28
- flex: auto;
29
- min-width: 0;
30
- display: flex;
31
- align-items: center;
32
- text-decoration: none;
33
- color: inherit;
34
- font: inherit;
35
- }
36
-
37
- button {
38
- appearance: none;
39
- flex: none;
40
- position: relative;
41
- margin: 0;
42
- padding: 0;
43
- border: 0;
44
- background: transparent;
45
- }
46
-
47
- [part='children'] {
48
- padding: 0;
49
- margin: 0;
50
- list-style-type: none;
51
- }
52
-
53
- :host(:not([has-children])) button {
54
- display: none !important;
55
- }
56
-
57
- slot[name='prefix'],
58
- slot[name='suffix'] {
59
- flex: none;
60
- }
61
-
62
- slot:not([name]) {
63
- display: block;
64
- flex: auto;
65
- min-width: 0;
66
- overflow: hidden;
67
- text-overflow: ellipsis;
68
- white-space: nowrap;
69
- }
70
- `;
@@ -1,7 +0,0 @@
1
- import '@vaadin/vaadin-lumo-styles/color.js';
2
- import '@vaadin/vaadin-lumo-styles/typography.js';
3
- import '@vaadin/vaadin-lumo-styles/sizing.js';
4
- import '@vaadin/vaadin-lumo-styles/spacing.js';
5
- import '@vaadin/vaadin-lumo-styles/style.js';
6
- import '@vaadin/vaadin-lumo-styles/font-icons.js';
7
- export declare const sideNavItemStyles: import("lit").CSSResult;
@@ -1,123 +0,0 @@
1
- import '@vaadin/vaadin-lumo-styles/color.js';
2
- import '@vaadin/vaadin-lumo-styles/typography.js';
3
- import '@vaadin/vaadin-lumo-styles/sizing.js';
4
- import '@vaadin/vaadin-lumo-styles/spacing.js';
5
- import '@vaadin/vaadin-lumo-styles/style.js';
6
- import '@vaadin/vaadin-lumo-styles/font-icons.js';
7
- import { fieldButton } from '@vaadin/vaadin-lumo-styles/mixins/field-button.js';
8
- import { css, registerStyles } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
9
-
10
- export const sideNavItemStyles = css`
11
- :host {
12
- --_focus-ring-color: var(--vaadin-focus-ring-color, var(--lumo-primary-color-50pct));
13
- --_focus-ring-width: var(--vaadin-focus-ring-width, 2px);
14
- }
15
-
16
- [part='link'] {
17
- width: 100%;
18
- gap: var(--lumo-space-xs);
19
- padding: var(--lumo-space-s);
20
- padding-inline-start: calc(var(--lumo-space-s) + var(--_child-indent, 0px));
21
- border-radius: var(--lumo-border-radius-m);
22
- transition:
23
- background-color 140ms,
24
- color 140ms;
25
- cursor: var(--lumo-clickable-cursor, default);
26
- min-height: var(--lumo-icon-size-m);
27
- }
28
-
29
- [part='link'][href] {
30
- cursor: pointer;
31
- }
32
-
33
- :host([disabled]) [part='link'] {
34
- color: var(--lumo-disabled-text-color);
35
- }
36
-
37
- [part='toggle-button'] {
38
- margin-inline-end: calc(var(--lumo-space-xs) * -1);
39
- width: var(--lumo-size-s);
40
- height: var(--lumo-size-s);
41
- }
42
-
43
- :host([has-children]) [part='content'] {
44
- padding-inline-end: var(--lumo-space-s);
45
- }
46
-
47
- @media (any-hover: hover) {
48
- [part='link']:hover {
49
- color: var(--lumo-header-text-color);
50
- }
51
-
52
- [part='toggle-button']:hover {
53
- color: var(--lumo-body-text-color);
54
- }
55
- }
56
-
57
- [part='link']:active:focus {
58
- background-color: var(--lumo-contrast-5pct);
59
- }
60
-
61
- [part='toggle-button']::before {
62
- content: var(--lumo-icons-dropdown);
63
- transform: rotate(-90deg);
64
- transition: transform 140ms;
65
- }
66
-
67
- :host([dir='rtl']) [part='toggle-button']::before {
68
- transform: rotate(90deg);
69
- }
70
-
71
- :host([expanded]) [part='toggle-button']::before {
72
- transform: none;
73
- }
74
-
75
- [part='link'],
76
- [part='toggle-button'] {
77
- outline: none;
78
- }
79
-
80
- [part='link']:focus-visible,
81
- [part='toggle-button']:focus-visible {
82
- border-radius: var(--lumo-border-radius-m);
83
- box-shadow: 0 0 0 var(--_focus-ring-width) var(--_focus-ring-color);
84
- }
85
-
86
- [part='link']:active {
87
- color: var(--lumo-header-text-color);
88
- }
89
-
90
- slot:not([name]) {
91
- margin: 0 var(--lumo-space-s);
92
- }
93
-
94
- slot[name='prefix']::slotted(:is(vaadin-icon, [class*='icon'])) {
95
- padding: 0.1em;
96
- flex-shrink: 0;
97
- color: var(--lumo-contrast-60pct);
98
- }
99
-
100
- :host([disabled]) slot[name='prefix']::slotted(:is(vaadin-icon, [class*='icon'])) {
101
- color: var(--lumo-disabled-text-color);
102
- }
103
-
104
- :host([current]) slot[name='prefix']::slotted(:is(vaadin-icon, [class*='icon'])) {
105
- color: inherit;
106
- }
107
-
108
- slot[name='children'] {
109
- --_child-indent: calc(var(--_child-indent-2, 0px) + var(--vaadin-side-nav-child-indent, var(--lumo-space-l)));
110
- }
111
-
112
- slot[name='children']::slotted(*) {
113
- --_child-indent-2: var(--_child-indent);
114
- }
115
-
116
- :host([current]) [part='content'] {
117
- background-color: var(--lumo-primary-color-10pct);
118
- color: var(--vaadin-selection-color-text, var(--lumo-primary-text-color));
119
- border-radius: var(--lumo-border-radius-m);
120
- }
121
- `;
122
-
123
- registerStyles('vaadin-side-nav-item', [fieldButton, sideNavItemStyles], { moduleId: 'lumo-side-nav-item' });
@@ -1,7 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright (c) 2023 - 2025 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';
@@ -1,7 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright (c) 2023 - 2025 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';
@@ -1,7 +0,0 @@
1
- import '@vaadin/vaadin-lumo-styles/color.js';
2
- import '@vaadin/vaadin-lumo-styles/typography.js';
3
- import '@vaadin/vaadin-lumo-styles/sizing.js';
4
- import '@vaadin/vaadin-lumo-styles/spacing.js';
5
- import '@vaadin/vaadin-lumo-styles/style.js';
6
- import '@vaadin/vaadin-lumo-styles/font-icons.js';
7
- export declare const sideNavStyles: import("lit").CSSResult;
@@ -1,81 +0,0 @@
1
- import '@vaadin/vaadin-lumo-styles/color.js';
2
- import '@vaadin/vaadin-lumo-styles/typography.js';
3
- import '@vaadin/vaadin-lumo-styles/sizing.js';
4
- import '@vaadin/vaadin-lumo-styles/spacing.js';
5
- import '@vaadin/vaadin-lumo-styles/style.js';
6
- import '@vaadin/vaadin-lumo-styles/font-icons.js';
7
- import { css, registerStyles } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
8
-
9
- export const sideNavStyles = css`
10
- :host {
11
- font-family: var(--lumo-font-family);
12
- font-size: var(--lumo-font-size-m);
13
- font-weight: 500;
14
- line-height: var(--lumo-line-height-xs);
15
- color: var(--lumo-body-text-color);
16
- -webkit-tap-highlight-color: transparent;
17
- --_focus-ring-color: var(--vaadin-focus-ring-color, var(--lumo-primary-color-50pct));
18
- --_focus-ring-width: var(--vaadin-focus-ring-width, 2px);
19
- }
20
-
21
- [part='label'] {
22
- display: flex;
23
- align-items: center;
24
- width: 100%;
25
- outline: none;
26
- box-sizing: border-box;
27
- border-radius: var(--lumo-border-radius-m);
28
- font-family: var(--lumo-font-family);
29
- font-size: var(--lumo-font-size-s);
30
- font-weight: 500;
31
- line-height: var(--lumo-line-height-xs);
32
- }
33
-
34
- [part='label'] ::slotted([slot='label']) {
35
- color: var(--lumo-secondary-text-color);
36
- margin: var(--lumo-space-s);
37
- }
38
-
39
- :host([focus-ring]) [part='label'] {
40
- box-shadow: 0 0 0 var(--_focus-ring-width) var(--_focus-ring-color);
41
- }
42
-
43
- [part='toggle-button'] {
44
- display: inline-flex;
45
- align-items: center;
46
- justify-content: center;
47
- width: var(--lumo-size-s);
48
- height: var(--lumo-size-s);
49
- margin-inline: auto var(--lumo-space-xs);
50
- font-size: var(--lumo-icon-size-m);
51
- line-height: 1;
52
- color: var(--lumo-contrast-60pct);
53
- font-family: 'lumo-icons';
54
- cursor: var(--lumo-clickable-cursor);
55
- }
56
-
57
- [part='toggle-button']::before {
58
- content: var(--lumo-icons-angle-right);
59
- transition: transform 140ms;
60
- }
61
-
62
- :host(:not([collapsible])) [part='toggle-button'] {
63
- display: none !important;
64
- }
65
-
66
- :host(:not([collapsed])) [part='toggle-button']::before {
67
- transform: rotate(90deg);
68
- }
69
-
70
- :host([collapsed][dir='rtl']) [part='toggle-button']::before {
71
- transform: rotate(180deg);
72
- }
73
-
74
- @media (any-hover: hover) {
75
- [part='label']:hover [part='toggle-button'] {
76
- color: var(--lumo-body-text-color);
77
- }
78
- }
79
- `;
80
-
81
- registerStyles('vaadin-side-nav', sideNavStyles, { moduleId: 'lumo-side-nav' });
@@ -1,8 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright (c) 2023 - 2025 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.js';
7
- import './vaadin-side-nav-styles.js';
8
- import '../../src/vaadin-side-nav.js';
@@ -1,8 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright (c) 2023 - 2025 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.js';
7
- import './vaadin-side-nav-styles.js';
8
- import '../../src/vaadin-side-nav.js';