@vaadin/side-nav 24.2.0-alpha1 → 24.2.0-alpha10
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 -7
- 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 +56 -59
- package/src/vaadin-side-nav.d.ts +14 -1
- package/src/vaadin-side-nav.js +32 -2
- 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/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-alpha10",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -35,15 +35,15 @@
|
|
|
35
35
|
"web-component"
|
|
36
36
|
],
|
|
37
37
|
"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-
|
|
38
|
+
"@vaadin/component-base": "24.2.0-alpha10",
|
|
39
|
+
"@vaadin/vaadin-lumo-styles": "24.2.0-alpha10",
|
|
40
|
+
"@vaadin/vaadin-material-styles": "24.2.0-alpha10",
|
|
41
|
+
"@vaadin/vaadin-themable-mixin": "24.2.0-alpha10",
|
|
42
42
|
"lit": "^2.0.0"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"@esm-bundle/chai": "^4.3.4",
|
|
46
|
-
"@vaadin/testing-helpers": "^0.
|
|
46
|
+
"@vaadin/testing-helpers": "^0.5.0",
|
|
47
47
|
"lit": "^2.0.0",
|
|
48
48
|
"sinon": "^13.0.2"
|
|
49
49
|
},
|
|
@@ -51,5 +51,5 @@
|
|
|
51
51
|
"web-types.json",
|
|
52
52
|
"web-types.lit.json"
|
|
53
53
|
],
|
|
54
|
-
"gitHead": "
|
|
54
|
+
"gitHead": "ca16b5f88b00ae05fb6d7c7e9874525048e389f0"
|
|
55
55
|
}
|
|
@@ -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,42 +5,19 @@
|
|
|
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';
|
|
15
|
+
import { SideNavChildrenMixin } from './vaadin-side-nav-children-mixin.js';
|
|
14
16
|
|
|
15
17
|
function isEnabled() {
|
|
16
18
|
return window.Vaadin && window.Vaadin.featureFlags && !!window.Vaadin.featureFlags.sideNavComponent;
|
|
17
19
|
}
|
|
18
20
|
|
|
19
|
-
/**
|
|
20
|
-
* A controller to manage the item content children slot.
|
|
21
|
-
*/
|
|
22
|
-
class ChildrenController extends SlotController {
|
|
23
|
-
constructor(host) {
|
|
24
|
-
super(host, 'children', null, { observe: true, multiple: true });
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* @protected
|
|
29
|
-
* @override
|
|
30
|
-
*/
|
|
31
|
-
initAddedNode() {
|
|
32
|
-
this.host.requestUpdate();
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* @protected
|
|
37
|
-
* @override
|
|
38
|
-
*/
|
|
39
|
-
teardownNode() {
|
|
40
|
-
this.host.requestUpdate();
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
21
|
/**
|
|
45
22
|
* A navigation item to be used within `<vaadin-side-nav>`. Represents a navigation target.
|
|
46
23
|
* Not intended to be used separately.
|
|
@@ -78,6 +55,8 @@ class ChildrenController extends SlotController {
|
|
|
78
55
|
*
|
|
79
56
|
* ### Styling
|
|
80
57
|
*
|
|
58
|
+
* The following shadow DOM parts are available for styling:
|
|
59
|
+
*
|
|
81
60
|
* Part name | Description
|
|
82
61
|
* ----------------|----------------
|
|
83
62
|
* `content` | The element that wraps link and toggle button
|
|
@@ -85,6 +64,14 @@ class ChildrenController extends SlotController {
|
|
|
85
64
|
* `link` | The clickable anchor used for navigation
|
|
86
65
|
* `toggle-button` | The toggle button
|
|
87
66
|
*
|
|
67
|
+
* The following state attributes are available for styling:
|
|
68
|
+
*
|
|
69
|
+
* Attribute | Description
|
|
70
|
+
* ---------------|-------------
|
|
71
|
+
* `disabled` | Set when the element is disabled.
|
|
72
|
+
* `expanded` | Set when the element is expanded.
|
|
73
|
+
* `has-children` | Set when the element has child items.
|
|
74
|
+
*
|
|
88
75
|
* See [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.
|
|
89
76
|
*
|
|
90
77
|
* @fires {CustomEvent} expanded-changed - Fired when the `expanded` property changes.
|
|
@@ -92,9 +79,11 @@ class ChildrenController extends SlotController {
|
|
|
92
79
|
* @extends LitElement
|
|
93
80
|
* @mixes PolylitMixin
|
|
94
81
|
* @mixes ThemableMixin
|
|
82
|
+
* @mixes DisabledMixin
|
|
95
83
|
* @mixes ElementMixin
|
|
84
|
+
* @mixes SideNavChildrenMixin
|
|
96
85
|
*/
|
|
97
|
-
class SideNavItem extends ElementMixin(ThemableMixin(PolylitMixin(LitElement))) {
|
|
86
|
+
class SideNavItem extends SideNavChildrenMixin(DisabledMixin(ElementMixin(ThemableMixin(PolylitMixin(LitElement))))) {
|
|
98
87
|
static get is() {
|
|
99
88
|
return 'vaadin-side-nav-item';
|
|
100
89
|
}
|
|
@@ -107,11 +96,14 @@ class SideNavItem extends ElementMixin(ThemableMixin(PolylitMixin(LitElement)))
|
|
|
107
96
|
path: String,
|
|
108
97
|
|
|
109
98
|
/**
|
|
110
|
-
*
|
|
99
|
+
* The list of alternative paths matching this item
|
|
111
100
|
*
|
|
112
|
-
* @
|
|
101
|
+
* @type {!Array<string>}
|
|
113
102
|
*/
|
|
114
|
-
pathAliases:
|
|
103
|
+
pathAliases: {
|
|
104
|
+
type: Array,
|
|
105
|
+
value: () => [],
|
|
106
|
+
},
|
|
115
107
|
|
|
116
108
|
/**
|
|
117
109
|
* Whether to show the child items or not
|
|
@@ -132,7 +124,7 @@ class SideNavItem extends ElementMixin(ThemableMixin(PolylitMixin(LitElement)))
|
|
|
132
124
|
*
|
|
133
125
|
* @type {boolean}
|
|
134
126
|
*/
|
|
135
|
-
|
|
127
|
+
current: {
|
|
136
128
|
type: Boolean,
|
|
137
129
|
value: false,
|
|
138
130
|
readOnly: true,
|
|
@@ -142,13 +134,13 @@ class SideNavItem extends ElementMixin(ThemableMixin(PolylitMixin(LitElement)))
|
|
|
142
134
|
}
|
|
143
135
|
|
|
144
136
|
static get styles() {
|
|
145
|
-
return sideNavItemBaseStyles;
|
|
137
|
+
return [screenReaderOnly, sideNavItemBaseStyles];
|
|
146
138
|
}
|
|
147
139
|
|
|
148
140
|
constructor() {
|
|
149
141
|
super();
|
|
150
142
|
|
|
151
|
-
this.
|
|
143
|
+
this.__boundUpdateCurrent = this.__updateCurrent.bind(this);
|
|
152
144
|
}
|
|
153
145
|
|
|
154
146
|
/** @protected */
|
|
@@ -161,8 +153,7 @@ class SideNavItem extends ElementMixin(ThemableMixin(PolylitMixin(LitElement)))
|
|
|
161
153
|
* @override
|
|
162
154
|
*/
|
|
163
155
|
firstUpdated() {
|
|
164
|
-
|
|
165
|
-
this.addController(this._childrenController);
|
|
156
|
+
super.firstUpdated();
|
|
166
157
|
|
|
167
158
|
// By default, if the user hasn't provided a custom role,
|
|
168
159
|
// the role attribute is set to "listitem".
|
|
@@ -179,46 +170,60 @@ class SideNavItem extends ElementMixin(ThemableMixin(PolylitMixin(LitElement)))
|
|
|
179
170
|
super.updated(props);
|
|
180
171
|
|
|
181
172
|
if (props.has('path') || props.has('pathAliases')) {
|
|
182
|
-
this.
|
|
173
|
+
this.__updateCurrent();
|
|
183
174
|
}
|
|
184
175
|
|
|
185
|
-
|
|
176
|
+
// Ensure all the child items are disabled
|
|
177
|
+
if (props.has('disabled') || props.has('_itemsCount')) {
|
|
178
|
+
this._items.forEach((item) => {
|
|
179
|
+
item.disabled = this.disabled;
|
|
180
|
+
});
|
|
181
|
+
}
|
|
186
182
|
}
|
|
187
183
|
|
|
188
184
|
/** @protected */
|
|
189
185
|
connectedCallback() {
|
|
190
186
|
super.connectedCallback();
|
|
191
|
-
this.
|
|
192
|
-
|
|
193
|
-
window.addEventListener('popstate', this.
|
|
187
|
+
this.__updateCurrent();
|
|
188
|
+
|
|
189
|
+
window.addEventListener('popstate', this.__boundUpdateCurrent);
|
|
194
190
|
}
|
|
195
191
|
|
|
196
192
|
/** @protected */
|
|
197
193
|
disconnectedCallback() {
|
|
198
194
|
super.disconnectedCallback();
|
|
199
|
-
window.removeEventListener('popstate', this.
|
|
195
|
+
window.removeEventListener('popstate', this.__boundUpdateCurrent);
|
|
200
196
|
}
|
|
201
197
|
|
|
202
198
|
/** @protected */
|
|
203
199
|
render() {
|
|
204
200
|
return html`
|
|
205
201
|
<div part="content" @click="${this._onContentClick}">
|
|
206
|
-
<a
|
|
202
|
+
<a
|
|
203
|
+
id="link"
|
|
204
|
+
?disabled="${this.disabled}"
|
|
205
|
+
tabindex="${this.disabled || !this.path ? '-1' : '0'}"
|
|
206
|
+
href="${ifDefined(this.disabled ? null : this.path)}"
|
|
207
|
+
part="link"
|
|
208
|
+
aria-current="${this.current ? 'page' : 'false'}"
|
|
209
|
+
>
|
|
207
210
|
<slot name="prefix"></slot>
|
|
208
211
|
<slot></slot>
|
|
209
212
|
<slot name="suffix"></slot>
|
|
210
213
|
</a>
|
|
211
214
|
<button
|
|
212
215
|
part="toggle-button"
|
|
216
|
+
?disabled="${this.disabled}"
|
|
213
217
|
@click="${this._onButtonClick}"
|
|
214
218
|
aria-controls="children"
|
|
215
219
|
aria-expanded="${this.expanded}"
|
|
216
|
-
aria-
|
|
220
|
+
aria-labelledby="link i18n"
|
|
217
221
|
></button>
|
|
218
222
|
</div>
|
|
219
|
-
<ul part="children" ?hidden="${!this.expanded}">
|
|
223
|
+
<ul part="children" role="list" ?hidden="${!this.expanded}" aria-hidden="${this.expanded ? 'false' : 'true'}">
|
|
220
224
|
<slot name="children"></slot>
|
|
221
225
|
</ul>
|
|
226
|
+
<div class="sr-only" id="i18n">${this.i18n.toggle}</div>
|
|
222
227
|
`;
|
|
223
228
|
}
|
|
224
229
|
|
|
@@ -244,29 +249,21 @@ class SideNavItem extends ElementMixin(ThemableMixin(PolylitMixin(LitElement)))
|
|
|
244
249
|
}
|
|
245
250
|
|
|
246
251
|
/** @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;
|
|
252
|
+
__updateCurrent() {
|
|
253
|
+
this._setCurrent(this.__isCurrent());
|
|
254
|
+
if (this.current) {
|
|
255
|
+
this.expanded = this._items.length > 0;
|
|
256
256
|
}
|
|
257
257
|
}
|
|
258
258
|
|
|
259
259
|
/** @private */
|
|
260
|
-
|
|
260
|
+
__isCurrent() {
|
|
261
261
|
if (this.path == null) {
|
|
262
262
|
return false;
|
|
263
263
|
}
|
|
264
|
-
if (matchPaths(document.location.pathname, this.path)) {
|
|
265
|
-
return true;
|
|
266
|
-
}
|
|
267
264
|
return (
|
|
268
|
-
this.
|
|
269
|
-
this.pathAliases.
|
|
265
|
+
matchPaths(document.location.pathname, this.path) ||
|
|
266
|
+
this.pathAliases.some((alias) => matchPaths(document.location.pathname, alias))
|
|
270
267
|
);
|
|
271
268
|
}
|
|
272
269
|
}
|
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,6 +11,7 @@ import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
|
|
|
11
11
|
import { generateUniqueId } from '@vaadin/component-base/src/unique-id-utils.js';
|
|
12
12
|
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
13
13
|
import { sideNavBaseStyles } from './vaadin-side-nav-base-styles.js';
|
|
14
|
+
import { SideNavChildrenMixin } from './vaadin-side-nav-children-mixin.js';
|
|
14
15
|
|
|
15
16
|
function isEnabled() {
|
|
16
17
|
return window.Vaadin && window.Vaadin.featureFlags && !!window.Vaadin.featureFlags.sideNavComponent;
|
|
@@ -47,12 +48,22 @@ function isEnabled() {
|
|
|
47
48
|
*
|
|
48
49
|
* ### Styling
|
|
49
50
|
*
|
|
51
|
+
* The following shadow DOM parts are available for styling:
|
|
52
|
+
*
|
|
50
53
|
* Part name | Description
|
|
51
54
|
* ----------------|----------------
|
|
52
55
|
* `label` | The label element
|
|
53
56
|
* `children` | The element that wraps child items
|
|
54
57
|
* `toggle-button` | The toggle button
|
|
55
58
|
*
|
|
59
|
+
* The following state attributes are available for styling:
|
|
60
|
+
*
|
|
61
|
+
* Attribute | Description
|
|
62
|
+
* -------------|-------------
|
|
63
|
+
* `collapsed` | Set when the element is collapsed.
|
|
64
|
+
* `focus-ring` | Set when the label is focused using the keyboard.
|
|
65
|
+
* `focused` | Set when the label is focused.
|
|
66
|
+
*
|
|
56
67
|
* See [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.
|
|
57
68
|
*
|
|
58
69
|
* @fires {CustomEvent} collapsed-changed - Fired when the `collapsed` property changes.
|
|
@@ -61,8 +72,9 @@ function isEnabled() {
|
|
|
61
72
|
* @mixes PolylitMixin
|
|
62
73
|
* @mixes ThemableMixin
|
|
63
74
|
* @mixes ElementMixin
|
|
75
|
+
* @mixes SideNavChildrenMixin
|
|
64
76
|
*/
|
|
65
|
-
class SideNav extends FocusMixin(ElementMixin(ThemableMixin(PolylitMixin(LitElement)))) {
|
|
77
|
+
class SideNav extends SideNavChildrenMixin(FocusMixin(ElementMixin(ThemableMixin(PolylitMixin(LitElement))))) {
|
|
66
78
|
static get is() {
|
|
67
79
|
return 'vaadin-side-nav';
|
|
68
80
|
}
|
|
@@ -108,6 +120,15 @@ class SideNav extends FocusMixin(ElementMixin(ThemableMixin(PolylitMixin(LitElem
|
|
|
108
120
|
this._labelId = `side-nav-label-${generateUniqueId()}`;
|
|
109
121
|
}
|
|
110
122
|
|
|
123
|
+
/**
|
|
124
|
+
* Name of the slot to be used for children.
|
|
125
|
+
* @protected
|
|
126
|
+
* @override
|
|
127
|
+
*/
|
|
128
|
+
get _itemsSlotName() {
|
|
129
|
+
return '';
|
|
130
|
+
}
|
|
131
|
+
|
|
111
132
|
/** @protected */
|
|
112
133
|
get focusElement() {
|
|
113
134
|
return this.shadowRoot.querySelector('button');
|
|
@@ -115,6 +136,8 @@ class SideNav extends FocusMixin(ElementMixin(ThemableMixin(PolylitMixin(LitElem
|
|
|
115
136
|
|
|
116
137
|
/** @protected */
|
|
117
138
|
firstUpdated() {
|
|
139
|
+
super.firstUpdated();
|
|
140
|
+
|
|
118
141
|
// By default, if the user hasn't provided a custom role,
|
|
119
142
|
// the role attribute is set to "navigation".
|
|
120
143
|
if (!this.hasAttribute('role')) {
|
|
@@ -129,12 +152,19 @@ class SideNav extends FocusMixin(ElementMixin(ThemableMixin(PolylitMixin(LitElem
|
|
|
129
152
|
part="label"
|
|
130
153
|
@click="${this._onLabelClick}"
|
|
131
154
|
aria-expanded="${ifDefined(this.collapsible ? !this.collapsed : null)}"
|
|
155
|
+
aria-hidden="${ifDefined(this.collapsible === false ? true : null)}"
|
|
132
156
|
aria-controls="children"
|
|
133
157
|
>
|
|
134
158
|
<slot name="label" @slotchange="${this._onLabelSlotChange}"></slot>
|
|
135
159
|
<span part="toggle-button" aria-hidden="true"></span>
|
|
136
160
|
</button>
|
|
137
|
-
<ul
|
|
161
|
+
<ul
|
|
162
|
+
id="children"
|
|
163
|
+
role="list"
|
|
164
|
+
part="children"
|
|
165
|
+
?hidden="${this.collapsed}"
|
|
166
|
+
aria-hidden="${this.collapsed ? 'true' : 'false'}"
|
|
167
|
+
>
|
|
138
168
|
<slot></slot>
|
|
139
169
|
</ul>
|
|
140
170
|
`;
|
|
@@ -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-alpha10",
|
|
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-alpha10",
|
|
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.",
|