@vaadin/side-nav 24.1.5 → 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.
@@ -4,9 +4,13 @@
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 { FocusMixin } from '@vaadin/a11y-base/src/focus-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, type SideNavI18n } from './vaadin-side-nav-children-mixin.js';
12
+
13
+ export type { SideNavI18n };
10
14
 
11
15
  /**
12
16
  * Fired when the `collapsed` property changes.
@@ -48,9 +52,29 @@ export type SideNavEventMap = HTMLElementEventMap & SideNavCustomEventMap;
48
52
  * </vaadin-side-nav>
49
53
  * ```
50
54
  *
55
+ * ### Styling
56
+ *
57
+ * The following shadow DOM parts are available for styling:
58
+ *
59
+ * Part name | Description
60
+ * ----------------|----------------
61
+ * `label` | The label element
62
+ * `children` | The element that wraps child items
63
+ * `toggle-button` | The toggle button
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
+ *
73
+ * See [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.
74
+ *
51
75
  * @fires {CustomEvent} collapsed-changed - Fired when the `collapsed` property changes.
52
76
  */
53
- declare class SideNav extends ElementMixin(ThemableMixin(PolylitMixin(LitElement))) {
77
+ declare class SideNav extends SideNavChildrenMixin(FocusMixin(ElementMixin(ThemableMixin(PolylitMixin(LitElement))))) {
54
78
  /**
55
79
  * Whether the side nav is collapsible. When enabled, the toggle icon is shown.
56
80
  */
@@ -4,11 +4,14 @@
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  import { html, LitElement } from 'lit';
7
+ import { ifDefined } from 'lit/directives/if-defined.js';
8
+ import { FocusMixin } from '@vaadin/a11y-base/src/focus-mixin.js';
7
9
  import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
8
10
  import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
9
11
  import { generateUniqueId } from '@vaadin/component-base/src/unique-id-utils.js';
10
12
  import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
11
13
  import { sideNavBaseStyles } from './vaadin-side-nav-base-styles.js';
14
+ import { SideNavChildrenMixin } from './vaadin-side-nav-children-mixin.js';
12
15
 
13
16
  function isEnabled() {
14
17
  return window.Vaadin && window.Vaadin.featureFlags && !!window.Vaadin.featureFlags.sideNavComponent;
@@ -43,18 +46,43 @@ function isEnabled() {
43
46
  * </vaadin-side-nav>
44
47
  * ```
45
48
  *
49
+ * ### Styling
50
+ *
51
+ * The following shadow DOM parts are available for styling:
52
+ *
53
+ * Part name | Description
54
+ * ----------------|----------------
55
+ * `label` | The label element
56
+ * `children` | The element that wraps child items
57
+ * `toggle-button` | The toggle button
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
+ *
67
+ * See [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.
68
+ *
46
69
  * @fires {CustomEvent} collapsed-changed - Fired when the `collapsed` property changes.
47
70
  *
48
71
  * @extends LitElement
49
72
  * @mixes PolylitMixin
50
73
  * @mixes ThemableMixin
51
74
  * @mixes ElementMixin
75
+ * @mixes SideNavChildrenMixin
52
76
  */
53
- class SideNav extends ElementMixin(ThemableMixin(PolylitMixin(LitElement))) {
77
+ class SideNav extends SideNavChildrenMixin(FocusMixin(ElementMixin(ThemableMixin(PolylitMixin(LitElement))))) {
54
78
  static get is() {
55
79
  return 'vaadin-side-nav';
56
80
  }
57
81
 
82
+ static get shadowRootOptions() {
83
+ return { ...LitElement.shadowRootOptions, delegatesFocus: true };
84
+ }
85
+
58
86
  static get properties() {
59
87
  return {
60
88
  /**
@@ -86,8 +114,30 @@ class SideNav extends ElementMixin(ThemableMixin(PolylitMixin(LitElement))) {
86
114
  return sideNavBaseStyles;
87
115
  }
88
116
 
117
+ constructor() {
118
+ super();
119
+
120
+ this._labelId = `side-nav-label-${generateUniqueId()}`;
121
+ }
122
+
123
+ /**
124
+ * Name of the slot to be used for children.
125
+ * @protected
126
+ * @override
127
+ */
128
+ get _itemsSlotName() {
129
+ return '';
130
+ }
131
+
132
+ /** @protected */
133
+ get focusElement() {
134
+ return this.shadowRoot.querySelector('button');
135
+ }
136
+
89
137
  /** @protected */
90
138
  firstUpdated() {
139
+ super.firstUpdated();
140
+
91
141
  // By default, if the user hasn't provided a custom role,
92
142
  // the role attribute is set to "navigation".
93
143
  if (!this.hasAttribute('role')) {
@@ -97,34 +147,62 @@ class SideNav extends ElementMixin(ThemableMixin(PolylitMixin(LitElement))) {
97
147
 
98
148
  /** @protected */
99
149
  render() {
100
- const label = this.querySelector('[slot="label"]');
101
- if (label && this.collapsible) {
102
- return html`
103
- <details ?open="${!this.collapsed}" @toggle="${this.__toggleCollapsed}">${this.__renderBody(label)}</details>
104
- `;
150
+ return html`
151
+ <button
152
+ part="label"
153
+ @click="${this._onLabelClick}"
154
+ aria-expanded="${ifDefined(this.collapsible ? !this.collapsed : null)}"
155
+ aria-hidden="${ifDefined(this.collapsible === false ? true : null)}"
156
+ aria-controls="children"
157
+ >
158
+ <slot name="label" @slotchange="${this._onLabelSlotChange}"></slot>
159
+ <span part="toggle-button" aria-hidden="true"></span>
160
+ </button>
161
+ <ul
162
+ id="children"
163
+ role="list"
164
+ part="children"
165
+ ?hidden="${this.collapsed}"
166
+ aria-hidden="${this.collapsed ? 'true' : 'false'}"
167
+ >
168
+ <slot></slot>
169
+ </ul>
170
+ `;
171
+ }
172
+
173
+ /**
174
+ * @param {Event} event
175
+ * @return {boolean}
176
+ * @protected
177
+ * @override
178
+ */
179
+ _shouldSetFocus(event) {
180
+ return event.composedPath()[0] === this.focusElement;
181
+ }
182
+
183
+ /** @private */
184
+ _onLabelClick() {
185
+ if (this.collapsible) {
186
+ this.__toggleCollapsed();
105
187
  }
106
- return this.__renderBody(label);
107
188
  }
108
189
 
109
190
  /** @private */
110
- __renderBody(label) {
191
+ _onLabelSlotChange() {
192
+ const label = this.querySelector('[slot="label"]');
111
193
  if (label) {
112
- if (!label.id) label.id = `side-nav-label-${generateUniqueId()}`;
194
+ if (!label.id) {
195
+ label.id = this._labelId;
196
+ }
113
197
  this.setAttribute('aria-labelledby', label.id);
114
198
  } else {
115
199
  this.removeAttribute('aria-labelledby');
116
200
  }
117
- return html`
118
- <summary part="label" ?hidden="${label == null}">
119
- <slot name="label" @slotchange="${() => this.requestUpdate()}"></slot>
120
- </summary>
121
- <slot role="list"></slot>
122
- `;
123
201
  }
124
202
 
125
203
  /** @private */
126
- __toggleCollapsed(e) {
127
- this.collapsed = !e.target.open;
204
+ __toggleCollapsed() {
205
+ this.collapsed = !this.collapsed;
128
206
  }
129
207
  }
130
208
 
@@ -4,10 +4,12 @@ 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
- a {
11
+ [part='link'] {
12
+ width: 100%;
11
13
  gap: var(--lumo-space-xs);
12
14
  padding: var(--lumo-space-s);
13
15
  padding-inline-start: calc(var(--lumo-space-s) + var(--_child-indent, 0px));
@@ -17,74 +19,84 @@ export const sideNavItemStyles = css`
17
19
  min-height: var(--lumo-icon-size-m);
18
20
  }
19
21
 
20
- button {
21
- border: 0;
22
- margin: calc((var(--lumo-icon-size-m) - var(--lumo-size-s)) / 2) 0;
22
+ [part='link'][href] {
23
+ cursor: pointer;
24
+ }
25
+
26
+ :host([disabled]) [part='link'] {
27
+ color: var(--lumo-disabled-text-color);
28
+ }
29
+
30
+ [part='toggle-button'] {
23
31
  margin-inline-end: calc(var(--lumo-space-xs) * -1);
24
- padding: 0;
25
- background: transparent;
26
- font: inherit;
27
- color: var(--lumo-tertiary-text-color);
28
32
  width: var(--lumo-size-s);
29
33
  height: var(--lumo-size-s);
30
- cursor: var(--lumo-clickable-cursor, default);
31
- transition: color 140ms;
34
+ }
35
+
36
+ :host([has-children]) [part='content'] {
37
+ padding-inline-end: var(--lumo-space-s);
32
38
  }
33
39
 
34
40
  @media (any-hover: hover) {
35
- a:hover {
41
+ [part='link']:hover {
36
42
  color: var(--lumo-header-text-color);
37
43
  }
38
44
 
39
- button:hover {
45
+ [part='toggle-button']:hover {
40
46
  color: var(--lumo-body-text-color);
41
47
  }
42
48
  }
43
49
 
44
- a:active:focus {
50
+ [part='link']:active:focus {
45
51
  background-color: var(--lumo-contrast-5pct);
46
52
  }
47
53
 
48
- button::before {
49
- font-family: lumo-icons;
54
+ [part='toggle-button']::before {
50
55
  content: var(--lumo-icons-dropdown);
51
- font-size: 1.5em;
52
- line-height: var(--lumo-size-s);
53
- display: inline-block;
54
56
  transform: rotate(-90deg);
55
57
  transition: transform 140ms;
56
58
  }
57
59
 
58
- :host([expanded]) button::before {
60
+ :host([dir='rtl']) [part='toggle-button']::before {
61
+ transform: rotate(90deg);
62
+ }
63
+
64
+ :host([expanded]) [part='toggle-button']::before {
59
65
  transform: none;
60
66
  }
61
67
 
62
68
  @supports selector(:focus-visible) {
63
- a,
64
- button {
69
+ [part='link'],
70
+ [part='toggle-button'] {
65
71
  outline: none;
66
72
  }
67
73
 
68
- a:focus-visible,
69
- button:focus-visible {
74
+ [part='link']:focus-visible,
75
+ [part='toggle-button']:focus-visible {
70
76
  border-radius: var(--lumo-border-radius-m);
71
77
  box-shadow: 0 0 0 2px var(--lumo-primary-color-50pct);
72
78
  }
73
79
  }
74
80
 
75
- a:active {
81
+ [part='link']:active {
76
82
  color: var(--lumo-header-text-color);
77
83
  }
78
84
 
79
85
  slot:not([name]) {
80
- margin: 0 var(--lumo-space-xs);
86
+ margin: 0 var(--lumo-space-s);
81
87
  }
82
88
 
83
89
  slot[name='prefix']::slotted(:is(vaadin-icon, [class*='icon'])) {
90
+ padding: 0.1em;
91
+ flex-shrink: 0;
84
92
  color: var(--lumo-contrast-60pct);
85
93
  }
86
94
 
87
- :host([active]) slot[name='prefix']::slotted(:is(vaadin-icon, [class*='icon'])) {
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'])) {
88
100
  color: inherit;
89
101
  }
90
102
 
@@ -96,10 +108,10 @@ export const sideNavItemStyles = css`
96
108
  --_child-indent-2: var(--_child-indent);
97
109
  }
98
110
 
99
- :host([active]) a {
111
+ :host([current]) [part='link'] {
100
112
  color: var(--lumo-primary-text-color);
101
113
  background-color: var(--lumo-primary-color-10pct);
102
114
  }
103
115
  `;
104
116
 
105
- registerStyles('vaadin-side-nav-item', sideNavItemStyles, { moduleId: 'lumo-side-nav-item' });
117
+ registerStyles('vaadin-side-nav-item', [fieldButton, sideNavItemStyles], { moduleId: 'lumo-side-nav-item' });
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2017 - 2023 Vaadin Ltd.
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
6
  import './vaadin-side-nav-item-styles.js';
@@ -16,49 +16,63 @@ export const sideNavStyles = css`
16
16
  -webkit-tap-highlight-color: transparent;
17
17
  }
18
18
 
19
- summary {
20
- cursor: var(--lumo-clickable-cursor, default);
19
+ [part='label'] {
20
+ display: flex;
21
+ align-items: center;
22
+ width: 100%;
23
+ outline: none;
24
+ box-sizing: border-box;
21
25
  border-radius: var(--lumo-border-radius-m);
26
+ font-family: var(--lumo-font-family);
27
+ font-size: var(--lumo-font-size-s);
28
+ font-weight: 500;
29
+ line-height: var(--lumo-line-height-xs);
22
30
  }
23
31
 
24
- summary ::slotted([slot='label']) {
25
- font-size: var(--lumo-font-size-s);
32
+ [part='label'] ::slotted([slot='label']) {
26
33
  color: var(--lumo-secondary-text-color);
27
34
  margin: var(--lumo-space-s);
28
- border-radius: inherit;
29
35
  }
30
36
 
31
- summary::after {
32
- font-family: lumo-icons;
33
- color: var(--lumo-tertiary-text-color);
34
- font-size: var(--lumo-icon-size-m);
37
+ :host([focus-ring]) [part='label'] {
38
+ box-shadow: 0 0 0 2px var(--lumo-primary-color-50pct);
39
+ }
40
+
41
+ [part='toggle-button'] {
42
+ display: inline-flex;
43
+ align-items: center;
44
+ justify-content: center;
35
45
  width: var(--lumo-size-s);
36
46
  height: var(--lumo-size-s);
37
- transition: transform 140ms;
38
- margin: 0 var(--lumo-space-xs);
47
+ margin-inline-start: auto;
48
+ margin-inline-end: var(--lumo-space-xs);
49
+ font-size: var(--lumo-icon-size-m);
50
+ line-height: 1;
51
+ color: var(--lumo-contrast-60pct);
52
+ font-family: 'lumo-icons';
53
+ cursor: var(--lumo-clickable-cursor);
39
54
  }
40
55
 
41
- :host([collapsible]) summary::after {
42
- content: var(--lumo-icons-dropdown);
56
+ [part='toggle-button']::before {
57
+ content: var(--lumo-icons-angle-right);
58
+ transition: transform 140ms;
43
59
  }
44
60
 
45
- @media (any-hover: hover) {
46
- summary:hover::after {
47
- color: var(--lumo-body-text-color);
48
- }
61
+ :host(:not([collapsible])) [part='toggle-button'] {
62
+ display: none !important;
49
63
  }
50
64
 
51
- :host([collapsed]) summary::after {
52
- transform: rotate(-90deg);
65
+ :host(:not([collapsed])) [part='toggle-button']::before {
66
+ transform: rotate(90deg);
53
67
  }
54
68
 
55
- @supports selector(:focus-visible) {
56
- summary {
57
- outline: none;
58
- }
69
+ :host([collapsed][dir='rtl']) [part='toggle-button']::before {
70
+ transform: rotate(180deg);
71
+ }
59
72
 
60
- summary:focus-visible {
61
- box-shadow: 0 0 0 2px var(--lumo-primary-color-50pct);
73
+ @media (any-hover: hover) {
74
+ [part='label']:hover [part='toggle-button'] {
75
+ color: var(--lumo-body-text-color);
62
76
  }
63
77
  }
64
78
  `;
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2017 - 2023 Vaadin Ltd.
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
6
  import './vaadin-side-nav-item.js';
@@ -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,7 @@
1
+ /**
2
+ * @license
3
+ * Copyright (c) 2023 Vaadin Ltd.
4
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
+ */
6
+ import './vaadin-side-nav-item-styles.js';
7
+ import '../../src/vaadin-side-nav-item.js';
@@ -0,0 +1,69 @@
1
+ import '@vaadin/vaadin-material-styles/color.js';
2
+ import '@vaadin/vaadin-material-styles/font-icons.js';
3
+ import '@vaadin/vaadin-material-styles/typography.js';
4
+ import { css, registerStyles } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
5
+
6
+ export const sideNavStyles = css`
7
+ :host {
8
+ -webkit-tap-highlight-color: transparent;
9
+ outline: none;
10
+ }
11
+
12
+ [part='label'] {
13
+ display: flex;
14
+ align-items: center;
15
+ width: 100%;
16
+ min-height: 40px;
17
+ margin: 4px 0;
18
+ padding: 4px 8px;
19
+ outline: none;
20
+ box-sizing: border-box;
21
+ font-family: var(--material-font-family);
22
+ font-size: var(--material-small-font-size);
23
+ color: var(--material-secondary-text-color);
24
+ line-height: 1;
25
+ font-weight: 500;
26
+ border-radius: 4px;
27
+ }
28
+
29
+ :host([focus-ring]) [part='label'] {
30
+ background-color: var(--material-divider-color);
31
+ }
32
+
33
+ [part='toggle-button'] {
34
+ display: inline-flex;
35
+ align-items: center;
36
+ justify-content: center;
37
+ width: 24px;
38
+ height: 24px;
39
+ padding: 4px;
40
+ margin-inline-start: auto;
41
+ margin-inline-end: -4px;
42
+ font-size: var(--material-icon-font-size);
43
+ line-height: 1;
44
+ color: var(--material-secondary-text-color);
45
+ font-family: 'material-icons';
46
+ transform: rotate(90deg);
47
+ }
48
+
49
+ [part='toggle-button']::before {
50
+ content: var(--material-icons-chevron-right);
51
+ font-size: 24px;
52
+ }
53
+
54
+ :host(:not([collapsible])) [part='toggle-button'] {
55
+ display: none !important;
56
+ }
57
+
58
+ :host(:not([collapsed])) [part='toggle-button'] {
59
+ transform: rotate(270deg);
60
+ }
61
+
62
+ @media (any-hover: hover) {
63
+ [part='label']:hover [part='toggle-button'] {
64
+ color: var(--material-body-text-color);
65
+ }
66
+ }
67
+ `;
68
+
69
+ registerStyles('vaadin-side-nav', sideNavStyles, { moduleId: 'material-side-nav' });
@@ -1,7 +1,8 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2017 - 2023 Vaadin Ltd.
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';