@redvars/peacock 3.5.0 → 3.5.1
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/dist/BaseButton-DuASuVth.js +219 -0
- package/dist/BaseButton-DuASuVth.js.map +1 -0
- package/dist/BaseHyperlinkMixin-BNuwbiEf.js +65 -0
- package/dist/BaseHyperlinkMixin-BNuwbiEf.js.map +1 -0
- package/dist/assets/components.css +1 -1
- package/dist/assets/components.css.map +1 -1
- package/dist/assets/styles.css +1 -1
- package/dist/assets/styles.css.map +1 -1
- package/dist/banner.js +12 -27
- package/dist/banner.js.map +1 -1
- package/dist/{button-DMN1dPAg.js → button-DouvOfEU.js} +77 -251
- package/dist/button-DouvOfEU.js.map +1 -0
- package/dist/{button-group-CX9CUUXk.js → button-group-CEdMwvJJ.js} +71 -42
- package/dist/button-group-CEdMwvJJ.js.map +1 -0
- package/dist/button-group.js +5 -5
- package/dist/button.js +3 -3
- package/dist/card.js +18 -73
- package/dist/card.js.map +1 -1
- package/dist/chart-bar.js.map +1 -1
- package/dist/chart-doughnut.js +2 -2
- package/dist/chart-doughnut.js.map +1 -1
- package/dist/chart-pie.js +2 -2
- package/dist/chart-pie.js.map +1 -1
- package/dist/chart-stacked-bar.js.map +1 -1
- package/dist/code-highlighter.js +2 -1
- package/dist/code-highlighter.js.map +1 -1
- package/dist/custom-elements-jsdocs.json +3105 -1494
- package/dist/custom-elements.json +9244 -7829
- package/dist/fab.js +421 -9
- package/dist/fab.js.map +1 -1
- package/dist/index.js +6 -6
- package/dist/{select-4pl4XBj7.js → navigation-rail-Lxetd5-Z.js} +2214 -1090
- package/dist/navigation-rail-Lxetd5-Z.js.map +1 -0
- package/dist/notification.js +3 -2
- package/dist/notification.js.map +1 -1
- package/dist/peacock-loader.js +22 -10
- package/dist/peacock-loader.js.map +1 -1
- package/dist/search.js +4 -0
- package/dist/search.js.map +1 -1
- package/dist/src/__mixins/BaseButtonMixin.d.ts +20 -0
- package/dist/src/__mixins/BaseHyperlinkMixin.d.ts +18 -0
- package/dist/src/__mixins/MixinConstructor.d.ts +1 -0
- package/dist/src/banner/banner.d.ts +0 -4
- package/dist/src/button/BaseButton.d.ts +4 -47
- package/dist/src/button/button/button.d.ts +32 -3
- package/dist/src/button/button-group/button-group.d.ts +2 -2
- package/dist/src/button/icon-button/icon-button.d.ts +33 -8
- package/dist/src/card/card.d.ts +4 -15
- package/dist/src/fab/fab.d.ts +4 -35
- package/dist/src/focus-ring/focus-ring.d.ts +11 -5
- package/dist/src/index.d.ts +3 -1
- package/dist/src/link/link.d.ts +1 -1
- package/dist/src/navigation-rail/index.d.ts +2 -0
- package/dist/src/navigation-rail/navigation-rail-item.d.ts +55 -0
- package/dist/src/navigation-rail/navigation-rail.d.ts +71 -0
- package/dist/src/sidebar-menu/index.d.ts +3 -0
- package/dist/src/sidebar-menu/sidebar-menu-item.d.ts +58 -0
- package/dist/src/sidebar-menu/sidebar-menu.d.ts +38 -0
- package/dist/src/sidebar-menu/sidebar-sub-menu.d.ts +35 -0
- package/dist/src/toolbar/toolbar.d.ts +10 -10
- package/dist/src/tooltip/tooltip.d.ts +3 -0
- package/dist/src/url-field/index.d.ts +1 -0
- package/dist/src/url-field/url-field.d.ts +48 -0
- package/dist/test/sidebar-menu.test.d.ts +1 -0
- package/dist/toolbar.js +10 -10
- package/dist/toolbar.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/readme.md +73 -65
- package/scss/mixin.scss +16 -0
- package/src/__mixins/BaseButtonMixin.ts +83 -0
- package/src/__mixins/BaseHyperlinkMixin.ts +68 -0
- package/src/__mixins/MixinConstructor.ts +1 -0
- package/src/{__base_element → __mixins}/README.md +2 -2
- package/src/banner/banner.scss +18 -22
- package/src/banner/banner.ts +1 -7
- package/src/button/BaseButton.ts +11 -100
- package/src/button/button/button-sizes.scss +4 -2
- package/src/button/button/button.ts +76 -23
- package/src/button/button-group/button-group.ts +2 -2
- package/src/button/icon-button/icon-button.ts +75 -33
- package/src/card/card.ts +11 -71
- package/src/chart-bar/chart-bar.ts +9 -14
- package/src/chart-bar/chart-stacked-bar.ts +12 -18
- package/src/chart-doughnut/chart-doughnut.ts +23 -27
- package/src/chart-pie/chart-pie.ts +19 -23
- package/src/checkbox/checkbox.scss +17 -34
- package/src/checkbox/checkbox.ts +3 -1
- package/src/code-highlighter/code-highlighter.scss +1 -0
- package/src/code-highlighter/code-highlighter.ts +1 -1
- package/src/date-picker/date-picker.ts +1 -1
- package/src/elevation/elevation.scss +5 -5
- package/src/fab/fab.ts +29 -100
- package/src/focus-ring/focus-ring.ts +47 -40
- package/src/index.ts +3 -1
- package/src/input/input.ts +3 -1
- package/src/link/link.ts +2 -2
- package/src/menu/menu-item/menu-item.ts +3 -1
- package/src/navigation-rail/index.ts +2 -0
- package/src/navigation-rail/navigation-rail-item.scss +216 -0
- package/src/navigation-rail/navigation-rail-item.ts +223 -0
- package/src/navigation-rail/navigation-rail.scss +72 -0
- package/src/navigation-rail/navigation-rail.ts +149 -0
- package/src/notification/notification.ts +3 -2
- package/src/number-field/number-field.ts +6 -4
- package/src/pagination/pagination.ts +6 -4
- package/src/peacock-loader.ts +22 -5
- package/src/search/search.ts +4 -0
- package/src/sidebar-menu/demo/index.html +68 -0
- package/src/sidebar-menu/index.ts +3 -0
- package/src/sidebar-menu/sidebar-menu-item.scss +102 -0
- package/src/sidebar-menu/sidebar-menu-item.ts +151 -0
- package/src/{tree-view/tree-view.scss → sidebar-menu/sidebar-menu.scss} +1 -1
- package/src/sidebar-menu/sidebar-menu.ts +182 -0
- package/src/sidebar-menu/sidebar-sub-menu.scss +130 -0
- package/src/sidebar-menu/sidebar-sub-menu.ts +160 -0
- package/src/skeleton/skeleton.scss +18 -24
- package/src/snackbar/snackbar.ts +1 -1
- package/src/tabs/tab.ts +4 -3
- package/src/text/text.css-component.scss +7 -1
- package/src/time-picker/time-picker.ts +1 -1
- package/src/toolbar/toolbar.ts +10 -10
- package/src/tooltip/tooltip.ts +24 -0
- package/src/url-field/index.ts +1 -0
- package/src/url-field/url-field.scss +50 -0
- package/src/url-field/url-field.ts +239 -0
- package/dist/button-DMN1dPAg.js.map +0 -1
- package/dist/button-group-CX9CUUXk.js.map +0 -1
- package/dist/fab-C5Nzxk0E.js +0 -497
- package/dist/fab-C5Nzxk0E.js.map +0 -1
- package/dist/select-4pl4XBj7.js.map +0 -1
- package/dist/spread-B5cgadZl.js +0 -32
- package/dist/spread-B5cgadZl.js.map +0 -1
- package/dist/src/__base_element/BaseHyperlink.d.ts +0 -20
- package/dist/src/tree-view/index.d.ts +0 -2
- package/dist/src/tree-view/tree-node.d.ts +0 -69
- package/dist/src/tree-view/tree-view.d.ts +0 -40
- package/dist/src/tree-view/wc-tree-view.d.ts +0 -6
- package/dist/test/tree-view.test.d.ts +0 -1
- package/dist/throttle-C7ZAPqtu.js +0 -24
- package/dist/throttle-C7ZAPqtu.js.map +0 -1
- package/src/__base_element/BaseHyperlink.ts +0 -42
- package/src/tree-view/demo/index.html +0 -57
- package/src/tree-view/index.ts +0 -2
- package/src/tree-view/tree-node.scss +0 -101
- package/src/tree-view/tree-node.ts +0 -268
- package/src/tree-view/tree-view.ts +0 -182
- package/src/tree-view/wc-tree-view.ts +0 -9
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import { html, LitElement, nothing } from 'lit';
|
|
2
|
+
import { property, query, state } from 'lit/decorators.js';
|
|
3
|
+
import { classMap } from 'lit/directives/class-map.js';
|
|
4
|
+
import { dispatchActivationClick, isActivationClick } from '@/__utils/dispatch-event-utils.js';
|
|
5
|
+
import { observerSlotChangesWithCallback } from '@/__utils/observe-slot-change.js';
|
|
6
|
+
import { throttle } from '@/__utils/throttle.js';
|
|
7
|
+
import styles from './navigation-rail-item.scss';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @label Navigation Rail Item
|
|
11
|
+
* @tag wc-navigation-rail-item
|
|
12
|
+
* @rawTag navigation-rail-item
|
|
13
|
+
* @parentRawTag navigation-rail
|
|
14
|
+
*
|
|
15
|
+
* @summary An individual item within a navigation rail.
|
|
16
|
+
* @overview
|
|
17
|
+
* <p>Navigation rail items display a destination with an icon and optional label.</p>
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```html
|
|
21
|
+
* <wc-navigation-rail-item>
|
|
22
|
+
* <wc-icon slot="icon">home</wc-icon>
|
|
23
|
+
* Home
|
|
24
|
+
* </wc-navigation-rail-item>
|
|
25
|
+
* ```
|
|
26
|
+
* @tags navigation
|
|
27
|
+
*/
|
|
28
|
+
export class NavigationRailItem extends LitElement {
|
|
29
|
+
#id = crypto.randomUUID();
|
|
30
|
+
|
|
31
|
+
static styles = [styles];
|
|
32
|
+
|
|
33
|
+
/** Whether this item is currently active/selected. */
|
|
34
|
+
@property({ type: Boolean, reflect: true }) active = false;
|
|
35
|
+
|
|
36
|
+
/** Whether this item is disabled. */
|
|
37
|
+
@property({ type: Boolean, reflect: true }) disabled = false;
|
|
38
|
+
|
|
39
|
+
/** Whether the parent rail is in collapsed mode (labels hidden). */
|
|
40
|
+
@property({ type: Boolean, reflect: true }) collapsed = false;
|
|
41
|
+
|
|
42
|
+
/** If provided, the item renders as a link. */
|
|
43
|
+
@property({ reflect: true }) href?: string;
|
|
44
|
+
|
|
45
|
+
/** Link target. */
|
|
46
|
+
@property() target: string = '_self';
|
|
47
|
+
|
|
48
|
+
/** Value used for identification when managing active state externally. */
|
|
49
|
+
@property({ reflect: true }) value?: string;
|
|
50
|
+
|
|
51
|
+
/** Reason the item is disabled (shown to screen readers). */
|
|
52
|
+
@property({ attribute: 'disabled-reason' }) disabledReason: string = '';
|
|
53
|
+
|
|
54
|
+
/** Sets the delay for throttle in milliseconds. Defaults to 200 milliseconds. */
|
|
55
|
+
@property({ type: Number }) throttleDelay = 200;
|
|
56
|
+
|
|
57
|
+
@state() private _isPressed = false;
|
|
58
|
+
|
|
59
|
+
@state() private _hasLabel = false;
|
|
60
|
+
|
|
61
|
+
@state() private _hasActiveIcon = false;
|
|
62
|
+
|
|
63
|
+
@query('.item-element') readonly itemElement!: HTMLElement | null;
|
|
64
|
+
|
|
65
|
+
override focus() {
|
|
66
|
+
this.itemElement?.focus();
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
override blur() {
|
|
70
|
+
this.itemElement?.blur();
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
override firstUpdated() {
|
|
74
|
+
this.__dispatchClickWithThrottle = throttle(
|
|
75
|
+
this.__dispatchClick,
|
|
76
|
+
this.throttleDelay,
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
observerSlotChangesWithCallback(
|
|
80
|
+
this.renderRoot.querySelector('slot:not([name])'),
|
|
81
|
+
hasContent => {
|
|
82
|
+
this._hasLabel = hasContent;
|
|
83
|
+
this.requestUpdate();
|
|
84
|
+
},
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
observerSlotChangesWithCallback(
|
|
88
|
+
this.renderRoot.querySelector('slot[name="active-icon"]'),
|
|
89
|
+
hasContent => {
|
|
90
|
+
this._hasActiveIcon = hasContent;
|
|
91
|
+
this.requestUpdate();
|
|
92
|
+
},
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
__dispatchClickWithThrottle: (event: MouseEvent | KeyboardEvent) => void =
|
|
97
|
+
event => {
|
|
98
|
+
this.__dispatchClick(event);
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
__dispatchClick = (event: MouseEvent | KeyboardEvent) => {
|
|
102
|
+
if (this.disabled && this.href) {
|
|
103
|
+
event.stopImmediatePropagation();
|
|
104
|
+
event.preventDefault();
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (!isActivationClick(event) || !this.itemElement) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
this.focus();
|
|
113
|
+
dispatchActivationClick(this.itemElement);
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
__handlePress = (event: KeyboardEvent | MouseEvent) => {
|
|
117
|
+
if (this.disabled) return;
|
|
118
|
+
if (
|
|
119
|
+
event instanceof KeyboardEvent &&
|
|
120
|
+
event.type === 'keydown' &&
|
|
121
|
+
(event.key === 'Enter' || event.key === ' ')
|
|
122
|
+
) {
|
|
123
|
+
this._isPressed = true;
|
|
124
|
+
} else if (event.type === 'mousedown') {
|
|
125
|
+
this._isPressed = true;
|
|
126
|
+
} else {
|
|
127
|
+
this._isPressed = false;
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
__isLink() {
|
|
132
|
+
return !!this.href;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
__getDisabledReasonID() {
|
|
136
|
+
return this.disabled && this.disabledReason
|
|
137
|
+
? `disabled-reason-${this.#id}`
|
|
138
|
+
: nothing;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
__renderDisabledReason() {
|
|
142
|
+
const disabledReasonID = this.__getDisabledReasonID();
|
|
143
|
+
if (disabledReasonID)
|
|
144
|
+
return html`<div
|
|
145
|
+
id="disabled-reason-${this.#id}"
|
|
146
|
+
role="tooltip"
|
|
147
|
+
aria-label=${this.disabledReason}
|
|
148
|
+
class="screen-reader-only"
|
|
149
|
+
>
|
|
150
|
+
${this.disabledReason}
|
|
151
|
+
</div>`;
|
|
152
|
+
return nothing;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
__renderItemContent() {
|
|
156
|
+
return html`
|
|
157
|
+
<wc-focus-ring class="focus-ring" for='item'></wc-focus-ring>
|
|
158
|
+
<div class="state-layer"></div>
|
|
159
|
+
<wc-ripple class="ripple"></wc-ripple>
|
|
160
|
+
|
|
161
|
+
<div class="item-content">
|
|
162
|
+
<div class="indicator">
|
|
163
|
+
<div class="icon-container">
|
|
164
|
+
<slot name="active-icon" class="active-icon-slot"></slot>
|
|
165
|
+
<slot name="icon" class="icon-slot"></slot>
|
|
166
|
+
</div>
|
|
167
|
+
</div>
|
|
168
|
+
${this._hasLabel && !this.collapsed
|
|
169
|
+
? html`<div class="label"><slot></slot></div>`
|
|
170
|
+
: html`<slot class="hidden-slot"></slot>`}
|
|
171
|
+
</div>
|
|
172
|
+
|
|
173
|
+
${this.__renderDisabledReason()}
|
|
174
|
+
`;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
render() {
|
|
178
|
+
const isLink = this.__isLink();
|
|
179
|
+
|
|
180
|
+
const cssClasses = {
|
|
181
|
+
item: true,
|
|
182
|
+
'item-element': true,
|
|
183
|
+
active: this.active,
|
|
184
|
+
disabled: this.disabled,
|
|
185
|
+
pressed: this._isPressed,
|
|
186
|
+
'has-label': this._hasLabel,
|
|
187
|
+
'has-active-icon': this._hasActiveIcon,
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
if (!isLink) {
|
|
191
|
+
return html`<button
|
|
192
|
+
id="item"
|
|
193
|
+
class=${classMap(cssClasses)}
|
|
194
|
+
?disabled=${this.disabled}
|
|
195
|
+
aria-disabled=${`${this.disabled}`}
|
|
196
|
+
aria-current=${this.active ? 'page' : nothing}
|
|
197
|
+
?aria-describedby=${this.__getDisabledReasonID()}
|
|
198
|
+
@click=${this.__dispatchClickWithThrottle}
|
|
199
|
+
@mousedown=${this.__handlePress}
|
|
200
|
+
@keydown=${this.__handlePress}
|
|
201
|
+
@keyup=${this.__handlePress}
|
|
202
|
+
>
|
|
203
|
+
${this.__renderItemContent()}
|
|
204
|
+
</button>`;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
return html`<a
|
|
208
|
+
id="item"
|
|
209
|
+
class=${classMap(cssClasses)}
|
|
210
|
+
href=${this.href}
|
|
211
|
+
target=${this.target}
|
|
212
|
+
aria-current=${this.active ? 'page' : nothing}
|
|
213
|
+
aria-disabled=${`${this.disabled}`}
|
|
214
|
+
?aria-describedby=${this.__getDisabledReasonID()}
|
|
215
|
+
@click=${this.__dispatchClickWithThrottle}
|
|
216
|
+
@mousedown=${this.__handlePress}
|
|
217
|
+
@keydown=${this.__handlePress}
|
|
218
|
+
@keyup=${this.__handlePress}
|
|
219
|
+
>
|
|
220
|
+
${this.__renderItemContent()}
|
|
221
|
+
</a>`;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
@use '../../scss/mixin';
|
|
2
|
+
|
|
3
|
+
@include mixin.base-styles;
|
|
4
|
+
|
|
5
|
+
:host {
|
|
6
|
+
display: block;
|
|
7
|
+
height: 100%;
|
|
8
|
+
width: var(--nav-rail-width, 5rem); /* 80dp */
|
|
9
|
+
overflow: hidden;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.rail {
|
|
13
|
+
display: flex;
|
|
14
|
+
flex-direction: column;
|
|
15
|
+
align-items: center;
|
|
16
|
+
height: 100%;
|
|
17
|
+
width: 100%;
|
|
18
|
+
border-radius: inherit;
|
|
19
|
+
background-color: var(--nav-rail-container-color, var(--color-surface));
|
|
20
|
+
padding-block: var(--nav-rail-padding-block, 0.75rem); /* 12dp */
|
|
21
|
+
box-sizing: border-box;
|
|
22
|
+
|
|
23
|
+
.header {
|
|
24
|
+
display: flex;
|
|
25
|
+
flex-direction: column;
|
|
26
|
+
align-items: center;
|
|
27
|
+
width: 100%;
|
|
28
|
+
flex-shrink: 0;
|
|
29
|
+
|
|
30
|
+
&:empty {
|
|
31
|
+
display: none;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
wc-divider {
|
|
36
|
+
width: calc(100% - 1rem);
|
|
37
|
+
margin-block: 0.5rem;
|
|
38
|
+
flex-shrink: 0;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.items {
|
|
42
|
+
display: flex;
|
|
43
|
+
flex-direction: column;
|
|
44
|
+
align-items: center;
|
|
45
|
+
width: 100%;
|
|
46
|
+
gap: 0.75rem; /* 12dp between items */
|
|
47
|
+
flex: 1;
|
|
48
|
+
|
|
49
|
+
::slotted(wc-navigation-rail-item) {
|
|
50
|
+
width: 100%;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/* Alignment variants */
|
|
55
|
+
&.align-top {
|
|
56
|
+
.items {
|
|
57
|
+
justify-content: flex-start;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
&.align-center {
|
|
62
|
+
.items {
|
|
63
|
+
justify-content: center;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
&.align-bottom {
|
|
68
|
+
.items {
|
|
69
|
+
justify-content: flex-end;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { html, LitElement, PropertyValues } from 'lit';
|
|
2
|
+
import { property } from 'lit/decorators.js';
|
|
3
|
+
import { classMap } from 'lit/directives/class-map.js';
|
|
4
|
+
import styles from './navigation-rail.scss';
|
|
5
|
+
import { NavigationRailItem } from './navigation-rail-item.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @label Navigation Rail
|
|
9
|
+
* @tag wc-navigation-rail
|
|
10
|
+
* @rawTag navigation-rail
|
|
11
|
+
*
|
|
12
|
+
* @summary A vertical side navigation for medium-sized screens, following Material Design 3 specs.
|
|
13
|
+
* @overview
|
|
14
|
+
* <p>Navigation rail provides access to primary destinations in an app using icons—with or without labels—on a vertical rail.</p>
|
|
15
|
+
* <p>Use navigation rail on medium-sized screens (tablets) with 3–7 destinations.</p>
|
|
16
|
+
*
|
|
17
|
+
* @cssprop --nav-rail-width - Width of the rail container. Defaults to 5rem (80dp).
|
|
18
|
+
* @cssprop --nav-rail-container-color - Background color of the rail. Defaults to surface color.
|
|
19
|
+
* @cssprop --nav-rail-indicator-color - Color of the active indicator. Defaults to secondary-container.
|
|
20
|
+
* @cssprop --nav-rail-indicator-shape - Shape (border-radius) of the active indicator. Defaults to full (pill).
|
|
21
|
+
* @cssprop --nav-rail-indicator-width - Width of the active indicator. Defaults to 3.5rem (56dp).
|
|
22
|
+
* @cssprop --nav-rail-indicator-height - Height of the active indicator. Defaults to 2rem (32dp).
|
|
23
|
+
* @cssprop --nav-rail-inactive-icon-color - Color of inactive icons. Defaults to on-surface-variant.
|
|
24
|
+
* @cssprop --nav-rail-active-icon-color - Color of active icons. Defaults to on-secondary-container.
|
|
25
|
+
* @cssprop --nav-rail-inactive-label-color - Color of inactive labels. Defaults to on-surface-variant.
|
|
26
|
+
* @cssprop --nav-rail-active-label-color - Color of active labels. Defaults to on-surface.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```html
|
|
30
|
+
* <wc-navigation-rail>
|
|
31
|
+
* <wc-navigation-rail-item active>
|
|
32
|
+
* <wc-icon slot="icon">home</wc-icon>
|
|
33
|
+
* Home
|
|
34
|
+
* </wc-navigation-rail-item>
|
|
35
|
+
* <wc-navigation-rail-item>
|
|
36
|
+
* <wc-icon slot="icon">search</wc-icon>
|
|
37
|
+
* Search
|
|
38
|
+
* </wc-navigation-rail-item>
|
|
39
|
+
* <wc-navigation-rail-item>
|
|
40
|
+
* <wc-icon slot="icon">settings</wc-icon>
|
|
41
|
+
* Settings
|
|
42
|
+
* </wc-navigation-rail-item>
|
|
43
|
+
* </wc-navigation-rail>
|
|
44
|
+
* ```
|
|
45
|
+
* @tags navigation
|
|
46
|
+
*/
|
|
47
|
+
export class NavigationRail extends LitElement {
|
|
48
|
+
static styles = [styles];
|
|
49
|
+
|
|
50
|
+
static Item = NavigationRailItem;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Vertical alignment of items within the rail.
|
|
54
|
+
* - `"top"`: Items align to the top.
|
|
55
|
+
* - `"center"`: Items are centered (default).
|
|
56
|
+
* - `"bottom"`: Items align to the bottom.
|
|
57
|
+
*/
|
|
58
|
+
@property({ reflect: true }) alignment: 'top' | 'center' | 'bottom' = 'center';
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Display mode of the navigation rail.
|
|
62
|
+
* - `"expanded"`: shows labels.
|
|
63
|
+
* - `"collapsed"`: hides labels.
|
|
64
|
+
*/
|
|
65
|
+
@property({ reflect: true }) mode: 'expanded' | 'collapsed' = 'expanded';
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Whether to show a divider between the header and items sections.
|
|
69
|
+
*/
|
|
70
|
+
@property({ type: Boolean, attribute: 'show-divider' }) showDivider = false;
|
|
71
|
+
|
|
72
|
+
connectedCallback() {
|
|
73
|
+
super.connectedCallback();
|
|
74
|
+
this.addEventListener('click', this._handleItemClick);
|
|
75
|
+
this.setAttribute('role', 'navigation');
|
|
76
|
+
this.setAttribute('aria-label', this.getAttribute('aria-label') ?? 'Main navigation');
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
disconnectedCallback() {
|
|
80
|
+
this.removeEventListener('click', this._handleItemClick);
|
|
81
|
+
super.disconnectedCallback();
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
protected override firstUpdated() {
|
|
85
|
+
this._syncItemMode();
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
protected override updated(changedProperties: PropertyValues<this>) {
|
|
89
|
+
if (changedProperties.has('mode')) {
|
|
90
|
+
this._syncItemMode();
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
private _handleItemClick = (event: Event) => {
|
|
95
|
+
const target = event.target as HTMLElement;
|
|
96
|
+
const item = target.closest('wc-navigation-rail-item') as NavigationRailItem | null;
|
|
97
|
+
|
|
98
|
+
if (!item || item.disabled) return;
|
|
99
|
+
|
|
100
|
+
// Deactivate all items and activate the clicked one
|
|
101
|
+
for (const railItem of this._getItems()) {
|
|
102
|
+
railItem.active = railItem === item;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
this.dispatchEvent(
|
|
106
|
+
new CustomEvent('nav-change', {
|
|
107
|
+
detail: {
|
|
108
|
+
value: item.value,
|
|
109
|
+
item,
|
|
110
|
+
},
|
|
111
|
+
bubbles: true,
|
|
112
|
+
composed: true,
|
|
113
|
+
}),
|
|
114
|
+
);
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
private _getItems(): NavigationRailItem[] {
|
|
118
|
+
return Array.from(
|
|
119
|
+
this.querySelectorAll('wc-navigation-rail-item'),
|
|
120
|
+
) as NavigationRailItem[];
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
private _syncItemMode = () => {
|
|
124
|
+
const isCollapsed = this.mode === 'collapsed';
|
|
125
|
+
for (const railItem of this._getItems()) {
|
|
126
|
+
railItem.collapsed = isCollapsed;
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
render() {
|
|
131
|
+
const cssClasses = {
|
|
132
|
+
rail: true,
|
|
133
|
+
[`align-${this.alignment}`]: true,
|
|
134
|
+
[`mode-${this.mode}`]: true,
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
return html`
|
|
138
|
+
<div class=${classMap(cssClasses)}>
|
|
139
|
+
<div class="header">
|
|
140
|
+
<slot name="header"></slot>
|
|
141
|
+
</div>
|
|
142
|
+
${this.showDivider ? html`<wc-divider></wc-divider>` : ''}
|
|
143
|
+
<nav class="items" role="presentation">
|
|
144
|
+
<slot @slotchange=${this._syncItemMode}></slot>
|
|
145
|
+
</nav>
|
|
146
|
+
</div>
|
|
147
|
+
`;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
@@ -193,11 +193,12 @@ export class Notification extends LitElement {
|
|
|
193
193
|
variant="text"
|
|
194
194
|
size="sm"
|
|
195
195
|
aria-label="Close notification"
|
|
196
|
-
name="close"
|
|
197
196
|
@click=${() => {
|
|
198
197
|
this.hideAndEmitDismiss('dismiss');
|
|
199
198
|
}}
|
|
200
|
-
|
|
199
|
+
>
|
|
200
|
+
<wc-icon name="close"></wc-icon>
|
|
201
|
+
</wc-icon-button>
|
|
201
202
|
</div>`
|
|
202
203
|
: nothing}
|
|
203
204
|
</div>
|
|
@@ -170,11 +170,12 @@ export class NumberField extends BaseInput {
|
|
|
170
170
|
${this.stepper && !this.disabled
|
|
171
171
|
? html`<wc-icon-button
|
|
172
172
|
class="stepper"
|
|
173
|
-
name="remove"
|
|
174
173
|
variant="text"
|
|
175
174
|
slot="field-start"
|
|
176
175
|
@click=${this.stepDown}
|
|
177
|
-
|
|
176
|
+
>
|
|
177
|
+
<wc-icon name="remove"></wc-icon>
|
|
178
|
+
</wc-icon-button>`
|
|
178
179
|
: nothing}
|
|
179
180
|
|
|
180
181
|
<slot name="start" slot="field-start"></slot>
|
|
@@ -206,10 +207,11 @@ export class NumberField extends BaseInput {
|
|
|
206
207
|
? html`<wc-icon-button
|
|
207
208
|
class="stepper"
|
|
208
209
|
variant="text"
|
|
209
|
-
name="add"
|
|
210
210
|
slot="field-end"
|
|
211
211
|
@click=${this.stepUp}
|
|
212
|
-
|
|
212
|
+
>
|
|
213
|
+
<wc-icon name="add"></wc-icon>
|
|
214
|
+
</wc-icon-button>`
|
|
213
215
|
: nothing}
|
|
214
216
|
</wc-field>
|
|
215
217
|
`;
|
|
@@ -166,21 +166,23 @@ export class Pagination extends LitElement {
|
|
|
166
166
|
color="secondary"
|
|
167
167
|
variant="text"
|
|
168
168
|
size="sm"
|
|
169
|
-
name="keyboard_arrow_left"
|
|
170
169
|
title="Previous page"
|
|
171
170
|
?disabled=${isFirstPage}
|
|
172
171
|
@click=${this.handlePreviousPage}
|
|
173
|
-
|
|
172
|
+
>
|
|
173
|
+
<wc-icon name="keyboard_arrow_left"></wc-icon>
|
|
174
|
+
</wc-icon-button>
|
|
174
175
|
<wc-icon-button
|
|
175
176
|
class="nav-button"
|
|
176
177
|
color="secondary"
|
|
177
178
|
variant="text"
|
|
178
179
|
size="sm"
|
|
179
|
-
name="keyboard_arrow_right"
|
|
180
180
|
title="Next page"
|
|
181
181
|
?disabled=${isLastPage}
|
|
182
182
|
@click=${this.handleNextPage}
|
|
183
|
-
|
|
183
|
+
>
|
|
184
|
+
<wc-icon name="keyboard_arrow_right"></wc-icon>
|
|
185
|
+
</wc-icon-button>
|
|
184
186
|
</div>
|
|
185
187
|
</div>
|
|
186
188
|
`;
|
package/src/peacock-loader.ts
CHANGED
|
@@ -15,6 +15,7 @@ import { Fab } from './fab/fab.js';
|
|
|
15
15
|
import { SegmentedButton } from './segmented-button/segmented-button.js';
|
|
16
16
|
import { SegmentedButtonGroup } from './segmented-button/segmented-button-group.js';
|
|
17
17
|
import { Input } from './input/input.js';
|
|
18
|
+
import { UrlField } from './url-field/url-field.js';
|
|
18
19
|
import { Field } from './field/field.js';
|
|
19
20
|
import { NumberField } from './number-field/number-field.js';
|
|
20
21
|
import { DatePicker } from './date-picker/date-picker.js';
|
|
@@ -54,7 +55,9 @@ import { TabPanel } from './tabs/tab-panel.js';
|
|
|
54
55
|
import { Slider } from './slider/slider.js';
|
|
55
56
|
import { Table } from './table/table.js';
|
|
56
57
|
import { Pagination } from './pagination/pagination.js';
|
|
57
|
-
import {
|
|
58
|
+
import { SidebarMenu } from './sidebar-menu/sidebar-menu.js';
|
|
59
|
+
import { SidebarMenuItem } from './sidebar-menu/sidebar-menu-item.js';
|
|
60
|
+
import { SidebarSubMenu } from './sidebar-menu/sidebar-sub-menu.js';
|
|
58
61
|
import { Card } from './card/card.js';
|
|
59
62
|
import { CardContent } from './card/card-content.js';
|
|
60
63
|
import { Banner } from './banner/banner.js';
|
|
@@ -66,6 +69,8 @@ import { Select } from './select/select.js';
|
|
|
66
69
|
import { SelectOptionElement } from './select/option.js';
|
|
67
70
|
import { Search } from './search/search.js';
|
|
68
71
|
import { Toolbar } from './toolbar/toolbar.js';
|
|
72
|
+
import { NavigationRail } from './navigation-rail/navigation-rail.js';
|
|
73
|
+
import { NavigationRailItem } from './navigation-rail/navigation-rail-item.js';
|
|
69
74
|
|
|
70
75
|
const distDirectory = `${import.meta.url}/..`;
|
|
71
76
|
await loadCSS(`${distDirectory}/assets/styles.css`);
|
|
@@ -190,6 +195,9 @@ const loaderConfig: LoaderConfig = {
|
|
|
190
195
|
'wc-input': {
|
|
191
196
|
CustomElementClass: Input,
|
|
192
197
|
},
|
|
198
|
+
'wc-url-field': {
|
|
199
|
+
CustomElementClass: UrlField,
|
|
200
|
+
},
|
|
193
201
|
'wc-number-field': {
|
|
194
202
|
CustomElementClass: NumberField,
|
|
195
203
|
},
|
|
@@ -259,11 +267,14 @@ const loaderConfig: LoaderConfig = {
|
|
|
259
267
|
'wc-pagination': {
|
|
260
268
|
CustomElementClass: Pagination,
|
|
261
269
|
},
|
|
262
|
-
'wc-
|
|
263
|
-
CustomElementClass:
|
|
270
|
+
'wc-sidebar-menu': {
|
|
271
|
+
CustomElementClass: SidebarMenu,
|
|
272
|
+
},
|
|
273
|
+
'wc-sidebar-menu-item': {
|
|
274
|
+
CustomElementClass: SidebarMenuItem,
|
|
264
275
|
},
|
|
265
|
-
'wc-
|
|
266
|
-
CustomElementClass:
|
|
276
|
+
'wc-sidebar-sub-menu': {
|
|
277
|
+
CustomElementClass: SidebarSubMenu,
|
|
267
278
|
},
|
|
268
279
|
'wc-snackbar': {
|
|
269
280
|
CustomElementClass: Snackbar,
|
|
@@ -286,6 +297,12 @@ const loaderConfig: LoaderConfig = {
|
|
|
286
297
|
'wc-toolbar': {
|
|
287
298
|
CustomElementClass: Toolbar,
|
|
288
299
|
},
|
|
300
|
+
'wc-navigation-rail': {
|
|
301
|
+
CustomElementClass: NavigationRail,
|
|
302
|
+
},
|
|
303
|
+
'wc-navigation-rail-item': {
|
|
304
|
+
CustomElementClass: NavigationRailItem,
|
|
305
|
+
},
|
|
289
306
|
'wc-chart-doughnut': {
|
|
290
307
|
importPath: `${distDirectory}/chart-doughnut.js`,
|
|
291
308
|
},
|
package/src/search/search.ts
CHANGED
|
@@ -110,6 +110,8 @@ export class Search extends LitElement {
|
|
|
110
110
|
private __handleInput(event: InputEvent) {
|
|
111
111
|
const input = event.target as HTMLInputElement;
|
|
112
112
|
this.value = input.value;
|
|
113
|
+
// Prevent the native input event from escaping in addition to our API event.
|
|
114
|
+
event.stopPropagation();
|
|
113
115
|
this.dispatchEvent(
|
|
114
116
|
new CustomEvent('input', {
|
|
115
117
|
detail: { value: this.value },
|
|
@@ -122,6 +124,8 @@ export class Search extends LitElement {
|
|
|
122
124
|
private __handleChange(event: Event) {
|
|
123
125
|
const input = event.target as HTMLInputElement;
|
|
124
126
|
this.value = input.value;
|
|
127
|
+
// Prevent the native change event from escaping in addition to our API event.
|
|
128
|
+
event.stopPropagation();
|
|
125
129
|
this.dispatchEvent(
|
|
126
130
|
new CustomEvent('change', {
|
|
127
131
|
detail: { value: this.value },
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang='en-GB'>
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset='utf-8'>
|
|
5
|
+
<meta name='viewport' content='width=device-width, initial-scale=1.0, viewport-fit=cover' />
|
|
6
|
+
<link rel='stylesheet' href='/dist/assets/styles/tokens.css' />
|
|
7
|
+
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+Mono:wght@100..900&family=Noto+Sans:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet">
|
|
8
|
+
|
|
9
|
+
<style>
|
|
10
|
+
body {
|
|
11
|
+
background: #fafafa;
|
|
12
|
+
padding: 2rem;
|
|
13
|
+
font-family: 'Noto Sans', sans-serif;
|
|
14
|
+
}
|
|
15
|
+
h2 {
|
|
16
|
+
margin-top: 2rem;
|
|
17
|
+
margin-bottom: 0.5rem;
|
|
18
|
+
}
|
|
19
|
+
</style>
|
|
20
|
+
</head>
|
|
21
|
+
<body>
|
|
22
|
+
|
|
23
|
+
<h2>Basic Sidebar Menu</h2>
|
|
24
|
+
<wc-sidebar-menu>
|
|
25
|
+
<wc-sidebar-sub-menu label="Documents" icon="folder" expanded>
|
|
26
|
+
<wc-sidebar-sub-menu label="Work" icon="folder" expanded>
|
|
27
|
+
<wc-sidebar-menu-item label="Project A" icon="description"></wc-sidebar-menu-item>
|
|
28
|
+
<wc-sidebar-menu-item label="Project B" icon="description"></wc-sidebar-menu-item>
|
|
29
|
+
</wc-sidebar-sub-menu>
|
|
30
|
+
<wc-sidebar-menu-item label="Personal" icon="folder"></wc-sidebar-menu-item>
|
|
31
|
+
</wc-sidebar-sub-menu>
|
|
32
|
+
<wc-sidebar-sub-menu label="Pictures" icon="image" expanded>
|
|
33
|
+
<wc-sidebar-menu-item label="Vacation 2024" icon="image"></wc-sidebar-menu-item>
|
|
34
|
+
<wc-sidebar-menu-item label="Family" icon="image"></wc-sidebar-menu-item>
|
|
35
|
+
</wc-sidebar-sub-menu>
|
|
36
|
+
</wc-sidebar-menu>
|
|
37
|
+
|
|
38
|
+
<h2>Sidebar Menu without icons</h2>
|
|
39
|
+
<wc-sidebar-menu>
|
|
40
|
+
<wc-sidebar-sub-menu label="Category 1" expanded>
|
|
41
|
+
<wc-sidebar-menu-item label="Subcategory 1.1"></wc-sidebar-menu-item>
|
|
42
|
+
<wc-sidebar-menu-item label="Subcategory 1.2"></wc-sidebar-menu-item>
|
|
43
|
+
</wc-sidebar-sub-menu>
|
|
44
|
+
<wc-sidebar-menu-item label="Category 2"></wc-sidebar-menu-item>
|
|
45
|
+
</wc-sidebar-menu>
|
|
46
|
+
|
|
47
|
+
<h2>Disabled items</h2>
|
|
48
|
+
<wc-sidebar-menu>
|
|
49
|
+
<wc-sidebar-sub-menu label="Enabled" expanded>
|
|
50
|
+
<wc-sidebar-menu-item label="Child 1"></wc-sidebar-menu-item>
|
|
51
|
+
<wc-sidebar-menu-item label="Child 2" disabled></wc-sidebar-menu-item>
|
|
52
|
+
</wc-sidebar-sub-menu>
|
|
53
|
+
<wc-sidebar-menu-item label="Disabled" disabled></wc-sidebar-menu-item>
|
|
54
|
+
</wc-sidebar-menu>
|
|
55
|
+
|
|
56
|
+
<script type='module'>
|
|
57
|
+
import '/dist/index.es2017.js';
|
|
58
|
+
|
|
59
|
+
const menu = document.querySelector('wc-sidebar-menu');
|
|
60
|
+
if (menu) {
|
|
61
|
+
menu.addEventListener('sidebar-menu:change', (e) => {
|
|
62
|
+
console.log('Selected item:', e.detail);
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
</script>
|
|
66
|
+
|
|
67
|
+
</body>
|
|
68
|
+
</html>
|