@vaadin/side-nav 24.2.0-alpha1 → 24.2.0-alpha11
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 +6 -1
- package/package.json +7 -8
- package/src/vaadin-side-nav-base-styles.js +15 -13
- package/src/vaadin-side-nav-children-mixin.d.ts +46 -0
- package/src/vaadin-side-nav-children-mixin.js +134 -0
- package/src/vaadin-side-nav-item.d.ts +18 -6
- package/src/vaadin-side-nav-item.js +57 -66
- package/src/vaadin-side-nav.d.ts +14 -1
- package/src/vaadin-side-nav.js +33 -13
- package/theme/lumo/vaadin-side-nav-item-styles.js +21 -21
- package/theme/lumo/vaadin-side-nav-styles.js +6 -1
- package/theme/material/vaadin-side-nav-item-styles.js +142 -0
- package/theme/material/vaadin-side-nav-item.js +7 -0
- package/theme/material/vaadin-side-nav-styles.js +69 -0
- package/theme/material/vaadin-side-nav.js +2 -1
- package/web-types.json +39 -12
- package/web-types.lit.json +25 -4
- package/enable.js +0 -3
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-
|
|
3
|
+
"version": "24.2.0-alpha11",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -20,7 +20,6 @@
|
|
|
20
20
|
"module": "vaadin-side-nav.js",
|
|
21
21
|
"type": "module",
|
|
22
22
|
"files": [
|
|
23
|
-
"enable.js",
|
|
24
23
|
"src",
|
|
25
24
|
"theme",
|
|
26
25
|
"vaadin-*.d.ts",
|
|
@@ -35,15 +34,15 @@
|
|
|
35
34
|
"web-component"
|
|
36
35
|
],
|
|
37
36
|
"dependencies": {
|
|
38
|
-
"@vaadin/component-base": "24.2.0-
|
|
39
|
-
"@vaadin/vaadin-lumo-styles": "24.2.0-
|
|
40
|
-
"@vaadin/vaadin-material-styles": "24.2.0-
|
|
41
|
-
"@vaadin/vaadin-themable-mixin": "24.2.0-
|
|
37
|
+
"@vaadin/component-base": "24.2.0-alpha11",
|
|
38
|
+
"@vaadin/vaadin-lumo-styles": "24.2.0-alpha11",
|
|
39
|
+
"@vaadin/vaadin-material-styles": "24.2.0-alpha11",
|
|
40
|
+
"@vaadin/vaadin-themable-mixin": "24.2.0-alpha11",
|
|
42
41
|
"lit": "^2.0.0"
|
|
43
42
|
},
|
|
44
43
|
"devDependencies": {
|
|
45
44
|
"@esm-bundle/chai": "^4.3.4",
|
|
46
|
-
"@vaadin/testing-helpers": "^0.
|
|
45
|
+
"@vaadin/testing-helpers": "^0.5.0",
|
|
47
46
|
"lit": "^2.0.0",
|
|
48
47
|
"sinon": "^13.0.2"
|
|
49
48
|
},
|
|
@@ -51,5 +50,5 @@
|
|
|
51
50
|
"web-types.json",
|
|
52
51
|
"web-types.lit.json"
|
|
53
52
|
],
|
|
54
|
-
"gitHead": "
|
|
53
|
+
"gitHead": "a958207d5f6a09ca0e2dcf9f62194b3f92c8766a"
|
|
55
54
|
}
|
|
@@ -10,10 +10,20 @@ 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
|
+
:host([disabled]) {
|
|
19
|
+
pointer-events: none;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
[part='content'] {
|
|
23
|
+
display: flex;
|
|
24
|
+
align-items: center;
|
|
25
|
+
}
|
|
26
|
+
|
|
17
27
|
[part='link'] {
|
|
18
28
|
flex: auto;
|
|
19
29
|
min-width: 0;
|
|
@@ -28,6 +38,11 @@ export const sideNavItemBaseStyles = css`
|
|
|
28
38
|
-webkit-appearance: none;
|
|
29
39
|
appearance: none;
|
|
30
40
|
flex: none;
|
|
41
|
+
position: relative;
|
|
42
|
+
margin: 0;
|
|
43
|
+
padding: 0;
|
|
44
|
+
border: 0;
|
|
45
|
+
background: transparent;
|
|
31
46
|
}
|
|
32
47
|
|
|
33
48
|
[part='children'] {
|
|
@@ -40,19 +55,6 @@ export const sideNavItemBaseStyles = css`
|
|
|
40
55
|
display: none !important;
|
|
41
56
|
}
|
|
42
57
|
|
|
43
|
-
:host(:not([path])) a {
|
|
44
|
-
position: relative;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
:host(:not([path])) button::after {
|
|
48
|
-
content: '';
|
|
49
|
-
position: absolute;
|
|
50
|
-
top: 0;
|
|
51
|
-
right: 0;
|
|
52
|
-
bottom: 0;
|
|
53
|
-
left: 0;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
58
|
slot[name='prefix'],
|
|
57
59
|
slot[name='suffix'] {
|
|
58
60
|
flex: none;
|
|
@@ -0,0 +1,46 @@
|
|
|
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
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Count of child items.
|
|
44
|
+
*/
|
|
45
|
+
protected _itemsCount: number;
|
|
46
|
+
}
|
|
@@ -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
|
+
* @protected
|
|
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
|
+
};
|
|
@@ -4,9 +4,11 @@
|
|
|
4
4
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
5
|
*/
|
|
6
6
|
import { LitElement } from 'lit';
|
|
7
|
+
import { DisabledMixin } from '@vaadin/a11y-base/src/disabled-mixin.js';
|
|
7
8
|
import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
|
|
8
9
|
import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
|
|
9
10
|
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
11
|
+
import { SideNavChildrenMixin } from './vaadin-side-nav-children-mixin.js';
|
|
10
12
|
|
|
11
13
|
/**
|
|
12
14
|
* Fired when the `expanded` property changes.
|
|
@@ -56,6 +58,8 @@ export type SideNavItemEventMap = HTMLElementEventMap & SideNavItemCustomEventMa
|
|
|
56
58
|
*
|
|
57
59
|
* ### Styling
|
|
58
60
|
*
|
|
61
|
+
* The following shadow DOM parts are available for styling:
|
|
62
|
+
*
|
|
59
63
|
* Part name | Description
|
|
60
64
|
* ----------------|----------------
|
|
61
65
|
* `content` | The element that wraps link and toggle button
|
|
@@ -63,22 +67,30 @@ export type SideNavItemEventMap = HTMLElementEventMap & SideNavItemCustomEventMa
|
|
|
63
67
|
* `link` | The clickable anchor used for navigation
|
|
64
68
|
* `toggle-button` | The toggle button
|
|
65
69
|
*
|
|
70
|
+
* The following state attributes are available for styling:
|
|
71
|
+
*
|
|
72
|
+
* Attribute | Description
|
|
73
|
+
* ---------------|-------------
|
|
74
|
+
* `disabled` | Set when the element is disabled.
|
|
75
|
+
* `expanded` | Set when the element is expanded.
|
|
76
|
+
* `has-children` | Set when the element has child items.
|
|
77
|
+
*
|
|
66
78
|
* See [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.
|
|
67
79
|
*
|
|
68
80
|
* @fires {CustomEvent} expanded-changed - Fired when the `expanded` property changes.
|
|
69
81
|
*/
|
|
70
|
-
declare class SideNavItem extends
|
|
82
|
+
declare class SideNavItem extends SideNavChildrenMixin(
|
|
83
|
+
DisabledMixin(ElementMixin(ThemableMixin(PolylitMixin(LitElement)))),
|
|
84
|
+
) {
|
|
71
85
|
/**
|
|
72
86
|
* The path to navigate to
|
|
73
87
|
*/
|
|
74
88
|
path: string | null | undefined;
|
|
75
89
|
|
|
76
90
|
/**
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
* @attr {string} path-aliases
|
|
91
|
+
* The list of alternative paths matching this item
|
|
80
92
|
*/
|
|
81
|
-
pathAliases: string
|
|
93
|
+
pathAliases: string[];
|
|
82
94
|
|
|
83
95
|
/**
|
|
84
96
|
* Whether to show the child items or not
|
|
@@ -90,7 +102,7 @@ declare class SideNavItem extends ElementMixin(ThemableMixin(PolylitMixin(LitEle
|
|
|
90
102
|
* Set when the item is appended to DOM or when navigated back
|
|
91
103
|
* to the page that contains this item using the browser.
|
|
92
104
|
*/
|
|
93
|
-
readonly
|
|
105
|
+
readonly current: boolean;
|
|
94
106
|
|
|
95
107
|
addEventListener<K extends keyof SideNavItemEventMap>(
|
|
96
108
|
type: K,
|
|
@@ -5,41 +5,14 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { html, LitElement } from 'lit';
|
|
7
7
|
import { ifDefined } from 'lit/directives/if-defined.js';
|
|
8
|
+
import { DisabledMixin } from '@vaadin/a11y-base/src/disabled-mixin.js';
|
|
9
|
+
import { screenReaderOnly } from '@vaadin/a11y-base/src/styles/sr-only-styles.js';
|
|
8
10
|
import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
|
|
9
11
|
import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
|
|
10
|
-
import { SlotController } from '@vaadin/component-base/src/slot-controller.js';
|
|
11
12
|
import { matchPaths } from '@vaadin/component-base/src/url-utils.js';
|
|
12
13
|
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
13
14
|
import { sideNavItemBaseStyles } from './vaadin-side-nav-base-styles.js';
|
|
14
|
-
|
|
15
|
-
function isEnabled() {
|
|
16
|
-
return window.Vaadin && window.Vaadin.featureFlags && !!window.Vaadin.featureFlags.sideNavComponent;
|
|
17
|
-
}
|
|
18
|
-
|
|
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
|
-
}
|
|
15
|
+
import { SideNavChildrenMixin } from './vaadin-side-nav-children-mixin.js';
|
|
43
16
|
|
|
44
17
|
/**
|
|
45
18
|
* A navigation item to be used within `<vaadin-side-nav>`. Represents a navigation target.
|
|
@@ -78,6 +51,8 @@ class ChildrenController extends SlotController {
|
|
|
78
51
|
*
|
|
79
52
|
* ### Styling
|
|
80
53
|
*
|
|
54
|
+
* The following shadow DOM parts are available for styling:
|
|
55
|
+
*
|
|
81
56
|
* Part name | Description
|
|
82
57
|
* ----------------|----------------
|
|
83
58
|
* `content` | The element that wraps link and toggle button
|
|
@@ -85,6 +60,14 @@ class ChildrenController extends SlotController {
|
|
|
85
60
|
* `link` | The clickable anchor used for navigation
|
|
86
61
|
* `toggle-button` | The toggle button
|
|
87
62
|
*
|
|
63
|
+
* The following state attributes are available for styling:
|
|
64
|
+
*
|
|
65
|
+
* Attribute | Description
|
|
66
|
+
* ---------------|-------------
|
|
67
|
+
* `disabled` | Set when the element is disabled.
|
|
68
|
+
* `expanded` | Set when the element is expanded.
|
|
69
|
+
* `has-children` | Set when the element has child items.
|
|
70
|
+
*
|
|
88
71
|
* See [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.
|
|
89
72
|
*
|
|
90
73
|
* @fires {CustomEvent} expanded-changed - Fired when the `expanded` property changes.
|
|
@@ -92,9 +75,11 @@ class ChildrenController extends SlotController {
|
|
|
92
75
|
* @extends LitElement
|
|
93
76
|
* @mixes PolylitMixin
|
|
94
77
|
* @mixes ThemableMixin
|
|
78
|
+
* @mixes DisabledMixin
|
|
95
79
|
* @mixes ElementMixin
|
|
80
|
+
* @mixes SideNavChildrenMixin
|
|
96
81
|
*/
|
|
97
|
-
class SideNavItem extends ElementMixin(ThemableMixin(PolylitMixin(LitElement))) {
|
|
82
|
+
class SideNavItem extends SideNavChildrenMixin(DisabledMixin(ElementMixin(ThemableMixin(PolylitMixin(LitElement))))) {
|
|
98
83
|
static get is() {
|
|
99
84
|
return 'vaadin-side-nav-item';
|
|
100
85
|
}
|
|
@@ -107,11 +92,14 @@ class SideNavItem extends ElementMixin(ThemableMixin(PolylitMixin(LitElement)))
|
|
|
107
92
|
path: String,
|
|
108
93
|
|
|
109
94
|
/**
|
|
110
|
-
*
|
|
95
|
+
* The list of alternative paths matching this item
|
|
111
96
|
*
|
|
112
|
-
* @
|
|
97
|
+
* @type {!Array<string>}
|
|
113
98
|
*/
|
|
114
|
-
pathAliases:
|
|
99
|
+
pathAliases: {
|
|
100
|
+
type: Array,
|
|
101
|
+
value: () => [],
|
|
102
|
+
},
|
|
115
103
|
|
|
116
104
|
/**
|
|
117
105
|
* Whether to show the child items or not
|
|
@@ -132,7 +120,7 @@ class SideNavItem extends ElementMixin(ThemableMixin(PolylitMixin(LitElement)))
|
|
|
132
120
|
*
|
|
133
121
|
* @type {boolean}
|
|
134
122
|
*/
|
|
135
|
-
|
|
123
|
+
current: {
|
|
136
124
|
type: Boolean,
|
|
137
125
|
value: false,
|
|
138
126
|
readOnly: true,
|
|
@@ -142,13 +130,13 @@ class SideNavItem extends ElementMixin(ThemableMixin(PolylitMixin(LitElement)))
|
|
|
142
130
|
}
|
|
143
131
|
|
|
144
132
|
static get styles() {
|
|
145
|
-
return sideNavItemBaseStyles;
|
|
133
|
+
return [screenReaderOnly, sideNavItemBaseStyles];
|
|
146
134
|
}
|
|
147
135
|
|
|
148
136
|
constructor() {
|
|
149
137
|
super();
|
|
150
138
|
|
|
151
|
-
this.
|
|
139
|
+
this.__boundUpdateCurrent = this.__updateCurrent.bind(this);
|
|
152
140
|
}
|
|
153
141
|
|
|
154
142
|
/** @protected */
|
|
@@ -161,8 +149,7 @@ class SideNavItem extends ElementMixin(ThemableMixin(PolylitMixin(LitElement)))
|
|
|
161
149
|
* @override
|
|
162
150
|
*/
|
|
163
151
|
firstUpdated() {
|
|
164
|
-
|
|
165
|
-
this.addController(this._childrenController);
|
|
152
|
+
super.firstUpdated();
|
|
166
153
|
|
|
167
154
|
// By default, if the user hasn't provided a custom role,
|
|
168
155
|
// the role attribute is set to "listitem".
|
|
@@ -179,46 +166,60 @@ class SideNavItem extends ElementMixin(ThemableMixin(PolylitMixin(LitElement)))
|
|
|
179
166
|
super.updated(props);
|
|
180
167
|
|
|
181
168
|
if (props.has('path') || props.has('pathAliases')) {
|
|
182
|
-
this.
|
|
169
|
+
this.__updateCurrent();
|
|
183
170
|
}
|
|
184
171
|
|
|
185
|
-
|
|
172
|
+
// Ensure all the child items are disabled
|
|
173
|
+
if (props.has('disabled') || props.has('_itemsCount')) {
|
|
174
|
+
this._items.forEach((item) => {
|
|
175
|
+
item.disabled = this.disabled;
|
|
176
|
+
});
|
|
177
|
+
}
|
|
186
178
|
}
|
|
187
179
|
|
|
188
180
|
/** @protected */
|
|
189
181
|
connectedCallback() {
|
|
190
182
|
super.connectedCallback();
|
|
191
|
-
this.
|
|
192
|
-
|
|
193
|
-
window.addEventListener('popstate', this.
|
|
183
|
+
this.__updateCurrent();
|
|
184
|
+
|
|
185
|
+
window.addEventListener('popstate', this.__boundUpdateCurrent);
|
|
194
186
|
}
|
|
195
187
|
|
|
196
188
|
/** @protected */
|
|
197
189
|
disconnectedCallback() {
|
|
198
190
|
super.disconnectedCallback();
|
|
199
|
-
window.removeEventListener('popstate', this.
|
|
191
|
+
window.removeEventListener('popstate', this.__boundUpdateCurrent);
|
|
200
192
|
}
|
|
201
193
|
|
|
202
194
|
/** @protected */
|
|
203
195
|
render() {
|
|
204
196
|
return html`
|
|
205
197
|
<div part="content" @click="${this._onContentClick}">
|
|
206
|
-
<a
|
|
198
|
+
<a
|
|
199
|
+
id="link"
|
|
200
|
+
?disabled="${this.disabled}"
|
|
201
|
+
tabindex="${this.disabled || !this.path ? '-1' : '0'}"
|
|
202
|
+
href="${ifDefined(this.disabled ? null : this.path)}"
|
|
203
|
+
part="link"
|
|
204
|
+
aria-current="${this.current ? 'page' : 'false'}"
|
|
205
|
+
>
|
|
207
206
|
<slot name="prefix"></slot>
|
|
208
207
|
<slot></slot>
|
|
209
208
|
<slot name="suffix"></slot>
|
|
210
209
|
</a>
|
|
211
210
|
<button
|
|
212
211
|
part="toggle-button"
|
|
212
|
+
?disabled="${this.disabled}"
|
|
213
213
|
@click="${this._onButtonClick}"
|
|
214
214
|
aria-controls="children"
|
|
215
215
|
aria-expanded="${this.expanded}"
|
|
216
|
-
aria-
|
|
216
|
+
aria-labelledby="link i18n"
|
|
217
217
|
></button>
|
|
218
218
|
</div>
|
|
219
|
-
<ul part="children" ?hidden="${!this.expanded}">
|
|
219
|
+
<ul part="children" role="list" ?hidden="${!this.expanded}" aria-hidden="${this.expanded ? 'false' : 'true'}">
|
|
220
220
|
<slot name="children"></slot>
|
|
221
221
|
</ul>
|
|
222
|
+
<div class="sr-only" id="i18n">${this.i18n.toggle}</div>
|
|
222
223
|
`;
|
|
223
224
|
}
|
|
224
225
|
|
|
@@ -244,35 +245,25 @@ class SideNavItem extends ElementMixin(ThemableMixin(PolylitMixin(LitElement)))
|
|
|
244
245
|
}
|
|
245
246
|
|
|
246
247
|
/** @private */
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
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;
|
|
248
|
+
__updateCurrent() {
|
|
249
|
+
this._setCurrent(this.__isCurrent());
|
|
250
|
+
if (this.current) {
|
|
251
|
+
this.expanded = this._items.length > 0;
|
|
256
252
|
}
|
|
257
253
|
}
|
|
258
254
|
|
|
259
255
|
/** @private */
|
|
260
|
-
|
|
256
|
+
__isCurrent() {
|
|
261
257
|
if (this.path == null) {
|
|
262
258
|
return false;
|
|
263
259
|
}
|
|
264
|
-
if (matchPaths(document.location.pathname, this.path)) {
|
|
265
|
-
return true;
|
|
266
|
-
}
|
|
267
260
|
return (
|
|
268
|
-
this.
|
|
269
|
-
this.pathAliases.
|
|
261
|
+
matchPaths(document.location.pathname, this.path) ||
|
|
262
|
+
this.pathAliases.some((alias) => matchPaths(document.location.pathname, alias))
|
|
270
263
|
);
|
|
271
264
|
}
|
|
272
265
|
}
|
|
273
266
|
|
|
274
|
-
|
|
275
|
-
customElements.define(SideNavItem.is, SideNavItem);
|
|
276
|
-
}
|
|
267
|
+
customElements.define(SideNavItem.is, SideNavItem);
|
|
277
268
|
|
|
278
269
|
export { SideNavItem };
|
package/src/vaadin-side-nav.d.ts
CHANGED
|
@@ -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
|
*/
|
package/src/vaadin-side-nav.js
CHANGED
|
@@ -11,10 +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
|
-
|
|
15
|
-
function isEnabled() {
|
|
16
|
-
return window.Vaadin && window.Vaadin.featureFlags && !!window.Vaadin.featureFlags.sideNavComponent;
|
|
17
|
-
}
|
|
14
|
+
import { SideNavChildrenMixin } from './vaadin-side-nav-children-mixin.js';
|
|
18
15
|
|
|
19
16
|
/**
|
|
20
17
|
* `<vaadin-side-nav>` is a Web Component for navigation menus.
|
|
@@ -47,12 +44,22 @@ function isEnabled() {
|
|
|
47
44
|
*
|
|
48
45
|
* ### Styling
|
|
49
46
|
*
|
|
47
|
+
* The following shadow DOM parts are available for styling:
|
|
48
|
+
*
|
|
50
49
|
* Part name | Description
|
|
51
50
|
* ----------------|----------------
|
|
52
51
|
* `label` | The label element
|
|
53
52
|
* `children` | The element that wraps child items
|
|
54
53
|
* `toggle-button` | The toggle button
|
|
55
54
|
*
|
|
55
|
+
* The following state attributes are available for styling:
|
|
56
|
+
*
|
|
57
|
+
* Attribute | Description
|
|
58
|
+
* -------------|-------------
|
|
59
|
+
* `collapsed` | Set when the element is collapsed.
|
|
60
|
+
* `focus-ring` | Set when the label is focused using the keyboard.
|
|
61
|
+
* `focused` | Set when the label is focused.
|
|
62
|
+
*
|
|
56
63
|
* See [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.
|
|
57
64
|
*
|
|
58
65
|
* @fires {CustomEvent} collapsed-changed - Fired when the `collapsed` property changes.
|
|
@@ -61,8 +68,9 @@ function isEnabled() {
|
|
|
61
68
|
* @mixes PolylitMixin
|
|
62
69
|
* @mixes ThemableMixin
|
|
63
70
|
* @mixes ElementMixin
|
|
71
|
+
* @mixes SideNavChildrenMixin
|
|
64
72
|
*/
|
|
65
|
-
class SideNav extends FocusMixin(ElementMixin(ThemableMixin(PolylitMixin(LitElement)))) {
|
|
73
|
+
class SideNav extends SideNavChildrenMixin(FocusMixin(ElementMixin(ThemableMixin(PolylitMixin(LitElement))))) {
|
|
66
74
|
static get is() {
|
|
67
75
|
return 'vaadin-side-nav';
|
|
68
76
|
}
|
|
@@ -108,6 +116,15 @@ class SideNav extends FocusMixin(ElementMixin(ThemableMixin(PolylitMixin(LitElem
|
|
|
108
116
|
this._labelId = `side-nav-label-${generateUniqueId()}`;
|
|
109
117
|
}
|
|
110
118
|
|
|
119
|
+
/**
|
|
120
|
+
* Name of the slot to be used for children.
|
|
121
|
+
* @protected
|
|
122
|
+
* @override
|
|
123
|
+
*/
|
|
124
|
+
get _itemsSlotName() {
|
|
125
|
+
return '';
|
|
126
|
+
}
|
|
127
|
+
|
|
111
128
|
/** @protected */
|
|
112
129
|
get focusElement() {
|
|
113
130
|
return this.shadowRoot.querySelector('button');
|
|
@@ -115,6 +132,8 @@ class SideNav extends FocusMixin(ElementMixin(ThemableMixin(PolylitMixin(LitElem
|
|
|
115
132
|
|
|
116
133
|
/** @protected */
|
|
117
134
|
firstUpdated() {
|
|
135
|
+
super.firstUpdated();
|
|
136
|
+
|
|
118
137
|
// By default, if the user hasn't provided a custom role,
|
|
119
138
|
// the role attribute is set to "navigation".
|
|
120
139
|
if (!this.hasAttribute('role')) {
|
|
@@ -129,12 +148,19 @@ class SideNav extends FocusMixin(ElementMixin(ThemableMixin(PolylitMixin(LitElem
|
|
|
129
148
|
part="label"
|
|
130
149
|
@click="${this._onLabelClick}"
|
|
131
150
|
aria-expanded="${ifDefined(this.collapsible ? !this.collapsed : null)}"
|
|
151
|
+
aria-hidden="${ifDefined(this.collapsible === false ? true : null)}"
|
|
132
152
|
aria-controls="children"
|
|
133
153
|
>
|
|
134
154
|
<slot name="label" @slotchange="${this._onLabelSlotChange}"></slot>
|
|
135
155
|
<span part="toggle-button" aria-hidden="true"></span>
|
|
136
156
|
</button>
|
|
137
|
-
<ul
|
|
157
|
+
<ul
|
|
158
|
+
id="children"
|
|
159
|
+
role="list"
|
|
160
|
+
part="children"
|
|
161
|
+
?hidden="${this.collapsed}"
|
|
162
|
+
aria-hidden="${this.collapsed ? 'true' : 'false'}"
|
|
163
|
+
>
|
|
138
164
|
<slot></slot>
|
|
139
165
|
</ul>
|
|
140
166
|
`;
|
|
@@ -176,12 +202,6 @@ class SideNav extends FocusMixin(ElementMixin(ThemableMixin(PolylitMixin(LitElem
|
|
|
176
202
|
}
|
|
177
203
|
}
|
|
178
204
|
|
|
179
|
-
|
|
180
|
-
customElements.define(SideNav.is, SideNav);
|
|
181
|
-
} else {
|
|
182
|
-
console.warn(
|
|
183
|
-
'WARNING: The side-nav component is currently an experimental feature and needs to be explicitly enabled. To enable the component, `import "@vaadin/side-nav/enable.js"` *before* importing the side-nav module itself.',
|
|
184
|
-
);
|
|
185
|
-
}
|
|
205
|
+
customElements.define(SideNav.is, SideNav);
|
|
186
206
|
|
|
187
207
|
export { SideNav };
|
|
@@ -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,18 @@ 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
|
+
:host([disabled]) [part='link'] {
|
|
27
|
+
color: var(--lumo-disabled-text-color);
|
|
28
|
+
}
|
|
29
|
+
|
|
26
30
|
[part='toggle-button'] {
|
|
27
|
-
position: relative;
|
|
28
|
-
border: 0;
|
|
29
|
-
margin: calc((var(--lumo-icon-size-m) - var(--lumo-size-s)) / 2) 0;
|
|
30
31
|
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
32
|
width: var(--lumo-size-s);
|
|
36
33
|
height: var(--lumo-size-s);
|
|
37
|
-
cursor: var(--lumo-clickable-cursor, default);
|
|
38
|
-
transition: color 140ms;
|
|
39
34
|
}
|
|
40
35
|
|
|
41
36
|
:host([has-children]) [part='content'] {
|
|
@@ -57,15 +52,15 @@ export const sideNavItemStyles = css`
|
|
|
57
52
|
}
|
|
58
53
|
|
|
59
54
|
[part='toggle-button']::before {
|
|
60
|
-
font-family: lumo-icons;
|
|
61
55
|
content: var(--lumo-icons-dropdown);
|
|
62
|
-
font-size: 1.5em;
|
|
63
|
-
line-height: var(--lumo-size-s);
|
|
64
|
-
display: inline-block;
|
|
65
56
|
transform: rotate(-90deg);
|
|
66
57
|
transition: transform 140ms;
|
|
67
58
|
}
|
|
68
59
|
|
|
60
|
+
:host([dir='rtl']) [part='toggle-button']::before {
|
|
61
|
+
transform: rotate(90deg);
|
|
62
|
+
}
|
|
63
|
+
|
|
69
64
|
:host([expanded]) [part='toggle-button']::before {
|
|
70
65
|
transform: none;
|
|
71
66
|
}
|
|
@@ -93,10 +88,15 @@ export const sideNavItemStyles = css`
|
|
|
93
88
|
|
|
94
89
|
slot[name='prefix']::slotted(:is(vaadin-icon, [class*='icon'])) {
|
|
95
90
|
padding: 0.1em;
|
|
91
|
+
flex-shrink: 0;
|
|
96
92
|
color: var(--lumo-contrast-60pct);
|
|
97
93
|
}
|
|
98
94
|
|
|
99
|
-
:host([
|
|
95
|
+
:host([disabled]) slot[name='prefix']::slotted(:is(vaadin-icon, [class*='icon'])) {
|
|
96
|
+
color: var(--lumo-disabled-text-color);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
:host([current]) slot[name='prefix']::slotted(:is(vaadin-icon, [class*='icon'])) {
|
|
100
100
|
color: inherit;
|
|
101
101
|
}
|
|
102
102
|
|
|
@@ -108,10 +108,10 @@ export const sideNavItemStyles = css`
|
|
|
108
108
|
--_child-indent-2: var(--_child-indent);
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
-
:host([
|
|
111
|
+
:host([current]) [part='link'] {
|
|
112
112
|
color: var(--lumo-primary-text-color);
|
|
113
113
|
background-color: var(--lumo-primary-color-10pct);
|
|
114
114
|
}
|
|
115
115
|
`;
|
|
116
116
|
|
|
117
|
-
registerStyles('vaadin-side-nav-item', sideNavItemStyles, { moduleId: 'lumo-side-nav-item' });
|
|
117
|
+
registerStyles('vaadin-side-nav-item', [fieldButton, sideNavItemStyles], { moduleId: 'lumo-side-nav-item' });
|
|
@@ -55,16 +55,21 @@ export const sideNavStyles = css`
|
|
|
55
55
|
|
|
56
56
|
[part='toggle-button']::before {
|
|
57
57
|
content: var(--lumo-icons-angle-right);
|
|
58
|
+
transition: transform 140ms;
|
|
58
59
|
}
|
|
59
60
|
|
|
60
61
|
:host(:not([collapsible])) [part='toggle-button'] {
|
|
61
62
|
display: none !important;
|
|
62
63
|
}
|
|
63
64
|
|
|
64
|
-
:host(:not([collapsed])) [part='toggle-button'] {
|
|
65
|
+
:host(:not([collapsed])) [part='toggle-button']::before {
|
|
65
66
|
transform: rotate(90deg);
|
|
66
67
|
}
|
|
67
68
|
|
|
69
|
+
:host([collapsed][dir='rtl']) [part='toggle-button']::before {
|
|
70
|
+
transform: rotate(180deg);
|
|
71
|
+
}
|
|
72
|
+
|
|
68
73
|
@media (any-hover: hover) {
|
|
69
74
|
[part='label']:hover [part='toggle-button'] {
|
|
70
75
|
color: var(--lumo-body-text-color);
|
|
@@ -0,0 +1,142 @@
|
|
|
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([disabled]) [part='link'] {
|
|
35
|
+
color: var(--material-disabled-text-color);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
:host([current]) [part='link']::before {
|
|
39
|
+
position: absolute;
|
|
40
|
+
content: '';
|
|
41
|
+
inset: 0;
|
|
42
|
+
background-color: var(--material-primary-color);
|
|
43
|
+
opacity: 0.12;
|
|
44
|
+
border-radius: 4px;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
[part='toggle-button'] {
|
|
48
|
+
width: 32px;
|
|
49
|
+
height: 32px;
|
|
50
|
+
margin-inline-end: -4px;
|
|
51
|
+
transform: rotate(90deg);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
[part='toggle-button']::before {
|
|
55
|
+
font-family: 'material-icons';
|
|
56
|
+
font-size: 24px;
|
|
57
|
+
width: 24px;
|
|
58
|
+
display: inline-block;
|
|
59
|
+
content: var(--material-icons-chevron-right);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
[part='toggle-button']::after {
|
|
63
|
+
display: inline-block;
|
|
64
|
+
content: '';
|
|
65
|
+
position: absolute;
|
|
66
|
+
top: 0;
|
|
67
|
+
left: 0;
|
|
68
|
+
width: 100%;
|
|
69
|
+
height: 100%;
|
|
70
|
+
border-radius: 50%;
|
|
71
|
+
background-color: var(--material-disabled-text-color);
|
|
72
|
+
transform: scale(0);
|
|
73
|
+
opacity: 0;
|
|
74
|
+
transition: transform 0s 0.8s, opacity 0.8s;
|
|
75
|
+
will-change: transform, opacity;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
[part='toggle-button']:focus-visible::after {
|
|
79
|
+
transition-duration: 0.08s, 0.01s;
|
|
80
|
+
transition-delay: 0s, 0s;
|
|
81
|
+
transform: scale(1.25);
|
|
82
|
+
opacity: 0.16;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
:host([expanded]) [part='toggle-button'] {
|
|
86
|
+
transform: rotate(270deg);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
:host([has-children]) [part='content'] {
|
|
90
|
+
padding-inline-end: 8px;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
@media (any-hover: hover) {
|
|
94
|
+
:host(:not([current])) [part='link'][href]:hover {
|
|
95
|
+
background-color: var(--material-secondary-background-color);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
[part='toggle-button']:hover {
|
|
99
|
+
color: var(--material-body-text-color);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
@supports selector(:focus-visible) {
|
|
104
|
+
[part='link'],
|
|
105
|
+
[part='toggle-button'] {
|
|
106
|
+
outline: none;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
:host(:not([current])) [part='link']:focus-visible {
|
|
110
|
+
background-color: var(--material-divider-color);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
:host([current]) [part='link']:focus-visible::before {
|
|
114
|
+
opacity: 0.24;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
slot[name='prefix']::slotted(:is(vaadin-icon, [class*='icon'])) {
|
|
119
|
+
padding: 0.1em;
|
|
120
|
+
flex-shrink: 0;
|
|
121
|
+
margin-inline-end: 24px;
|
|
122
|
+
color: var(--material-secondary-text-color);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
:host([disabled]) slot[name='prefix']::slotted(:is(vaadin-icon, [class*='icon'])) {
|
|
126
|
+
color: var(--material-disabled-text-color);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
:host([current]) slot[name='prefix']::slotted(:is(vaadin-icon, [class*='icon'])) {
|
|
130
|
+
color: inherit;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
slot[name='children'] {
|
|
134
|
+
--_child-indent: calc(var(--_child-indent-2, 0px) + var(--vaadin-side-nav-child-indent, 24px));
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
slot[name='children']::slotted(*) {
|
|
138
|
+
--_child-indent-2: var(--_child-indent);
|
|
139
|
+
}
|
|
140
|
+
`;
|
|
141
|
+
|
|
142
|
+
registerStyles('vaadin-side-nav-item', [fieldButton, sideNavItemStyles], { moduleId: 'material-side-nav-item' });
|
|
@@ -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,29 +1,29 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/web-types",
|
|
3
3
|
"name": "@vaadin/side-nav",
|
|
4
|
-
"version": "24.2.0-
|
|
4
|
+
"version": "24.2.0-alpha11",
|
|
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`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.",
|
|
12
12
|
"attributes": [
|
|
13
13
|
{
|
|
14
|
-
"name": "
|
|
15
|
-
"description": "
|
|
14
|
+
"name": "disabled",
|
|
15
|
+
"description": "If true, the user cannot interact with this element.",
|
|
16
16
|
"value": {
|
|
17
17
|
"type": [
|
|
18
|
-
"
|
|
18
|
+
"boolean",
|
|
19
19
|
"null",
|
|
20
20
|
"undefined"
|
|
21
21
|
]
|
|
22
22
|
}
|
|
23
23
|
},
|
|
24
24
|
{
|
|
25
|
-
"name": "path
|
|
26
|
-
"description": "
|
|
25
|
+
"name": "path",
|
|
26
|
+
"description": "The path to navigate to",
|
|
27
27
|
"value": {
|
|
28
28
|
"type": [
|
|
29
29
|
"string",
|
|
@@ -55,6 +55,26 @@
|
|
|
55
55
|
],
|
|
56
56
|
"js": {
|
|
57
57
|
"properties": [
|
|
58
|
+
{
|
|
59
|
+
"name": "disabled",
|
|
60
|
+
"description": "If true, the user cannot interact with this element.",
|
|
61
|
+
"value": {
|
|
62
|
+
"type": [
|
|
63
|
+
"boolean",
|
|
64
|
+
"null",
|
|
65
|
+
"undefined"
|
|
66
|
+
]
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"name": "i18n",
|
|
71
|
+
"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```",
|
|
72
|
+
"value": {
|
|
73
|
+
"type": [
|
|
74
|
+
"SideNavI18n"
|
|
75
|
+
]
|
|
76
|
+
}
|
|
77
|
+
},
|
|
58
78
|
{
|
|
59
79
|
"name": "path",
|
|
60
80
|
"description": "The path to navigate to",
|
|
@@ -68,12 +88,10 @@
|
|
|
68
88
|
},
|
|
69
89
|
{
|
|
70
90
|
"name": "pathAliases",
|
|
71
|
-
"description": "
|
|
91
|
+
"description": "The list of alternative paths matching this item",
|
|
72
92
|
"value": {
|
|
73
93
|
"type": [
|
|
74
|
-
"string"
|
|
75
|
-
"null",
|
|
76
|
-
"undefined"
|
|
94
|
+
"Array.<string>"
|
|
77
95
|
]
|
|
78
96
|
}
|
|
79
97
|
},
|
|
@@ -97,7 +115,7 @@
|
|
|
97
115
|
},
|
|
98
116
|
{
|
|
99
117
|
"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.",
|
|
118
|
+
"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
119
|
"attributes": [
|
|
102
120
|
{
|
|
103
121
|
"name": "collapsible",
|
|
@@ -131,6 +149,15 @@
|
|
|
131
149
|
],
|
|
132
150
|
"js": {
|
|
133
151
|
"properties": [
|
|
152
|
+
{
|
|
153
|
+
"name": "i18n",
|
|
154
|
+
"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```",
|
|
155
|
+
"value": {
|
|
156
|
+
"type": [
|
|
157
|
+
"SideNavI18n"
|
|
158
|
+
]
|
|
159
|
+
}
|
|
160
|
+
},
|
|
134
161
|
{
|
|
135
162
|
"name": "collapsible",
|
|
136
163
|
"description": "Whether the side nav is collapsible. When enabled, the toggle icon is shown.",
|
package/web-types.lit.json
CHANGED
|
@@ -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-
|
|
4
|
+
"version": "24.2.0-alpha11",
|
|
5
5
|
"description-markup": "markdown",
|
|
6
6
|
"framework": "lit",
|
|
7
7
|
"framework-config": {
|
|
@@ -16,9 +16,16 @@
|
|
|
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`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.",
|
|
20
20
|
"extension": true,
|
|
21
21
|
"attributes": [
|
|
22
|
+
{
|
|
23
|
+
"name": "?disabled",
|
|
24
|
+
"description": "If true, the user cannot interact with this element.",
|
|
25
|
+
"value": {
|
|
26
|
+
"kind": "expression"
|
|
27
|
+
}
|
|
28
|
+
},
|
|
22
29
|
{
|
|
23
30
|
"name": "?expanded",
|
|
24
31
|
"description": "Whether to show the child items or not",
|
|
@@ -26,6 +33,13 @@
|
|
|
26
33
|
"kind": "expression"
|
|
27
34
|
}
|
|
28
35
|
},
|
|
36
|
+
{
|
|
37
|
+
"name": ".i18n",
|
|
38
|
+
"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```",
|
|
39
|
+
"value": {
|
|
40
|
+
"kind": "expression"
|
|
41
|
+
}
|
|
42
|
+
},
|
|
29
43
|
{
|
|
30
44
|
"name": ".path",
|
|
31
45
|
"description": "The path to navigate to",
|
|
@@ -35,7 +49,7 @@
|
|
|
35
49
|
},
|
|
36
50
|
{
|
|
37
51
|
"name": ".pathAliases",
|
|
38
|
-
"description": "
|
|
52
|
+
"description": "The list of alternative paths matching this item",
|
|
39
53
|
"value": {
|
|
40
54
|
"kind": "expression"
|
|
41
55
|
}
|
|
@@ -51,7 +65,7 @@
|
|
|
51
65
|
},
|
|
52
66
|
{
|
|
53
67
|
"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.",
|
|
68
|
+
"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
69
|
"extension": true,
|
|
56
70
|
"attributes": [
|
|
57
71
|
{
|
|
@@ -68,6 +82,13 @@
|
|
|
68
82
|
"kind": "expression"
|
|
69
83
|
}
|
|
70
84
|
},
|
|
85
|
+
{
|
|
86
|
+
"name": ".i18n",
|
|
87
|
+
"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```",
|
|
88
|
+
"value": {
|
|
89
|
+
"kind": "expression"
|
|
90
|
+
}
|
|
91
|
+
},
|
|
71
92
|
{
|
|
72
93
|
"name": "@collapsed-changed",
|
|
73
94
|
"description": "Fired when the `collapsed` property changes.",
|
package/enable.js
DELETED