@redvars/peacock 3.3.0 → 3.3.2
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/{IndividualComponent-tDnXrOLV.js → IndividualComponent-Dt5xirYG.js} +2 -2
- package/dist/{IndividualComponent-tDnXrOLV.js.map → IndividualComponent-Dt5xirYG.js.map} +1 -1
- package/dist/array-D5vjT2Xm.js +14 -0
- package/dist/array-D5vjT2Xm.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/{button-BGFJfbT2.js → button-ClzS8JLq.js} +3 -4
- package/dist/{button-BGFJfbT2.js.map → button-ClzS8JLq.js.map} +1 -1
- package/dist/button-group-BMS5WvaF.js +292 -0
- package/dist/button-group-BMS5WvaF.js.map +1 -0
- package/dist/button-group.js +6 -107
- package/dist/button-group.js.map +1 -1
- package/dist/button.js +3 -4
- package/dist/button.js.map +1 -1
- package/dist/card.js +104 -0
- package/dist/card.js.map +1 -0
- package/dist/chart-bar-DbnXQgvS.js +1121 -0
- package/dist/chart-bar-DbnXQgvS.js.map +1 -0
- package/dist/chart-bar.js +259 -0
- package/dist/chart-bar.js.map +1 -0
- package/dist/chart-donut.js +4 -2
- package/dist/chart-donut.js.map +1 -1
- package/dist/chart-doughnut.js +4 -2
- package/dist/chart-doughnut.js.map +1 -1
- package/dist/chart-pie.js +4 -2
- package/dist/chart-pie.js.map +1 -1
- package/dist/chart-stacked-bar.js +401 -0
- package/dist/chart-stacked-bar.js.map +1 -0
- package/dist/{class-map-DpeNtqCn.js → class-map-59YGWLnx.js} +9 -3
- package/dist/class-map-59YGWLnx.js.map +1 -0
- package/dist/clock.js +1 -1
- package/dist/code-editor.js +7 -7
- package/dist/code-editor.js.map +1 -1
- package/dist/code-highlighter.js +7 -25
- package/dist/code-highlighter.js.map +1 -1
- package/dist/custom-elements-jsdocs.json +8824 -5047
- package/dist/custom-elements.json +7468 -4147
- package/dist/index.js +16 -10
- package/dist/index.js.map +1 -1
- package/dist/number-counter.js +2 -2
- package/dist/{observe-theme-change-BISF-Gl5.js → observe-theme-change-pALI5fmV.js} +2 -2
- package/dist/{observe-theme-change-BISF-Gl5.js.map → observe-theme-change-pALI5fmV.js.map} +1 -1
- package/dist/peacock-loader.js +42 -1016
- package/dist/peacock-loader.js.map +1 -1
- package/dist/pie-Dz0IDiPt.js +537 -0
- package/dist/pie-Dz0IDiPt.js.map +1 -0
- package/dist/{slider-Dk9CFWTG.js → snackbar-74YCdMPL.js} +6205 -3206
- package/dist/snackbar-74YCdMPL.js.map +1 -0
- package/dist/src/accordion/accordion-item.d.ts +1 -0
- package/dist/src/breadcrumb/breadcrumb/breadcrumb.d.ts +2 -0
- package/dist/src/breadcrumb/breadcrumb-item/breadcrumb-item.d.ts +1 -0
- package/dist/src/button/button-group/button-group.d.ts +4 -0
- package/dist/src/card/card.d.ts +27 -0
- package/dist/src/card/index.d.ts +1 -0
- package/dist/src/chart-bar/chart-bar.d.ts +53 -0
- package/dist/src/chart-bar/chart-stacked-bar.d.ts +78 -0
- package/dist/src/chart-bar/index.d.ts +2 -0
- package/dist/src/code-editor/code-editor.d.ts +4 -3
- package/dist/src/code-highlighter/code-highlighter.d.ts +4 -7
- package/dist/src/index.d.ts +9 -0
- package/dist/src/menu/index.d.ts +3 -0
- package/dist/src/menu/menu/MenuSurfaceController.d.ts +18 -0
- package/dist/src/menu/menu/menu.d.ts +54 -12
- package/dist/src/menu/menu-item/menu-item.d.ts +12 -5
- package/dist/src/menu/sub-menu/sub-menu.d.ts +36 -0
- package/dist/src/pagination/index.d.ts +1 -0
- package/dist/src/pagination/pagination.d.ts +38 -0
- package/dist/src/popover/PopoverController.d.ts +4 -1
- package/dist/src/snackbar/index.d.ts +1 -0
- package/dist/src/snackbar/snackbar.d.ts +40 -0
- package/dist/src/table/index.d.ts +1 -0
- package/dist/src/table/table.d.ts +110 -0
- package/dist/src/tabs/tab-group.d.ts +5 -1
- package/dist/src/tabs/tab-panel.d.ts +2 -0
- package/dist/src/tabs/tab.d.ts +3 -1
- package/dist/src/tabs/tabs.d.ts +2 -0
- package/dist/src/tooltip/tooltip.d.ts +1 -3
- package/dist/src/tree-view/index.d.ts +2 -0
- package/dist/src/tree-view/tree-node.d.ts +69 -0
- package/dist/src/tree-view/tree-view.d.ts +40 -0
- package/dist/src/tree-view/wc-tree-view.d.ts +6 -0
- package/dist/{style-map-CfNHEkQp.js → style-map-DcB52w-l.js} +2 -2
- package/dist/{style-map-CfNHEkQp.js.map → style-map-DcB52w-l.js.map} +1 -1
- package/dist/test/card.test.d.ts +1 -0
- package/dist/test/chart-bar.test.d.ts +1 -0
- package/dist/test/icon.test.d.ts +1 -1
- package/dist/test/menu.test.d.ts +1 -0
- package/dist/test/snackbar.test.d.ts +1 -0
- package/dist/test/sub-menu.test.d.ts +1 -0
- package/dist/test/tree-view.test.d.ts +1 -0
- package/dist/{transform-DRuHEvar.js → transform-DSwFSqzD.js} +13 -558
- package/dist/transform-DSwFSqzD.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/{unsafe-html-CV6Je6HL.js → unsafe-html-C2r3PyzF.js} +2 -2
- package/dist/{unsafe-html-CV6Je6HL.js.map → unsafe-html-C2r3PyzF.js.map} +1 -1
- package/package.json +1 -1
- package/readme.md +40 -40
- package/src/accordion/accordion-item.ts +2 -1
- package/src/breadcrumb/breadcrumb/breadcrumb.ts +3 -0
- package/src/breadcrumb/breadcrumb-item/breadcrumb-item.ts +1 -0
- package/src/button/button-group/button-group.ts +6 -0
- package/src/card/card.scss +61 -0
- package/src/card/card.ts +38 -0
- package/src/card/index.ts +1 -0
- package/src/chart-bar/chart-bar.scss +58 -0
- package/src/chart-bar/chart-bar.ts +306 -0
- package/src/chart-bar/chart-stacked-bar.ts +402 -0
- package/src/chart-bar/index.ts +2 -0
- package/src/code-editor/code-editor.ts +4 -3
- package/src/code-highlighter/code-highlighter.ts +4 -22
- package/src/divider/divider.scss +2 -2
- package/src/empty-state/empty-state.scss +1 -1
- package/src/empty-state/empty-state.ts +1 -1
- package/src/index.ts +11 -2
- package/src/menu/index.ts +3 -0
- package/src/menu/menu/MenuSurfaceController.ts +61 -0
- package/src/menu/{menu-list/menu-list.scss → menu/menu.scss} +19 -4
- package/src/menu/menu/menu.ts +389 -81
- package/src/menu/menu-item/menu-item.ts +115 -36
- package/src/menu/sub-menu/sub-menu.scss +7 -0
- package/src/menu/sub-menu/sub-menu.ts +243 -0
- package/src/pagination/index.ts +1 -0
- package/src/pagination/pagination.scss +59 -0
- package/src/pagination/pagination.ts +135 -0
- package/src/peacock-loader.ts +39 -11
- package/src/popover/PopoverController.ts +13 -7
- package/src/snackbar/demo/index.html +29 -0
- package/src/snackbar/index.ts +1 -0
- package/src/snackbar/snackbar.scss +73 -0
- package/src/snackbar/snackbar.ts +151 -0
- package/src/table/index.ts +1 -0
- package/src/table/table.scss +174 -0
- package/src/table/table.ts +475 -0
- package/src/tabs/tab-group.ts +63 -28
- package/src/tabs/tab-panel.scss +3 -3
- package/src/tabs/tab-panel.ts +3 -0
- package/src/tabs/tab.scss +76 -2
- package/src/tabs/tab.ts +29 -6
- package/src/tabs/tabs.scss +6 -5
- package/src/tabs/tabs.ts +19 -5
- package/src/text/text.css-component.scss +6 -3
- package/src/tooltip/tooltip.scss +16 -13
- package/src/tooltip/tooltip.ts +7 -9
- package/src/tree-view/demo/index.html +57 -0
- package/src/tree-view/index.ts +2 -0
- package/src/tree-view/tree-node.scss +101 -0
- package/src/tree-view/tree-node.ts +268 -0
- package/src/tree-view/tree-view.scss +12 -0
- package/src/tree-view/tree-view.ts +182 -0
- package/src/tree-view/wc-tree-view.ts +9 -0
- package/dist/class-map-DpeNtqCn.js.map +0 -1
- package/dist/slider-Dk9CFWTG.js.map +0 -1
- package/dist/src/menu/menu-list/menu-list.d.ts +0 -22
- package/dist/state-8v48Exzh.js +0 -10
- package/dist/state-8v48Exzh.js.map +0 -1
- package/dist/transform-DRuHEvar.js.map +0 -1
- package/src/menu/menu-list/menu-list.ts +0 -48
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
import { html, LitElement } from 'lit';
|
|
2
|
+
import { property, query } from 'lit/decorators.js';
|
|
3
|
+
import { classMap } from 'lit/directives/class-map.js';
|
|
4
|
+
import { styleMap } from 'lit/directives/style-map.js';
|
|
5
|
+
import styles from './tree-node.scss';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @label Tree Node
|
|
9
|
+
* @tag wc-tree-node
|
|
10
|
+
* @rawTag tree-node
|
|
11
|
+
* @parentRawTag tree-view
|
|
12
|
+
* @summary A tree node represents a single item in a hierarchical tree structure. It supports nesting, icons, links, and keyboard navigation.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```html
|
|
16
|
+
* <wc-tree-view>
|
|
17
|
+
* <wc-tree-node label="Parent">
|
|
18
|
+
* <wc-tree-node label="Child"></wc-tree-node>
|
|
19
|
+
* </wc-tree-node>
|
|
20
|
+
* </wc-tree-view>
|
|
21
|
+
* ```
|
|
22
|
+
* @tags navigation
|
|
23
|
+
*/
|
|
24
|
+
export class TreeNode extends LitElement {
|
|
25
|
+
static styles = [styles];
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* The value used to identify this node when selected.
|
|
29
|
+
*/
|
|
30
|
+
@property({ type: String, reflect: true })
|
|
31
|
+
value: string = '';
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* The display label for this node.
|
|
35
|
+
*/
|
|
36
|
+
@property({ type: String, reflect: true })
|
|
37
|
+
label: string = '';
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Optional icon name to display before the label.
|
|
41
|
+
*/
|
|
42
|
+
@property({ type: String, reflect: true })
|
|
43
|
+
icon: string = '';
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Optional hyperlink to navigate to on click.
|
|
47
|
+
*/
|
|
48
|
+
@property({ type: String, reflect: true })
|
|
49
|
+
href: string = '';
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Sets or retrieves the window or frame at which to target content.
|
|
53
|
+
*/
|
|
54
|
+
@property({ type: String, reflect: true })
|
|
55
|
+
target: string = '_self';
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* If true, the user cannot interact with the node.
|
|
59
|
+
*/
|
|
60
|
+
@property({ type: Boolean, reflect: true })
|
|
61
|
+
disabled: boolean = false;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Whether the node is currently selected.
|
|
65
|
+
*/
|
|
66
|
+
@property({ type: Boolean, reflect: true })
|
|
67
|
+
selected: boolean = false;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Whether child nodes are visible.
|
|
71
|
+
*/
|
|
72
|
+
@property({ type: Boolean, reflect: true })
|
|
73
|
+
expanded: boolean = false;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* The nesting depth level (set automatically by the parent tree-view).
|
|
77
|
+
*/
|
|
78
|
+
@property({ type: Number, reflect: true })
|
|
79
|
+
level: number = 0;
|
|
80
|
+
|
|
81
|
+
@query('.tree-node-content')
|
|
82
|
+
private readonly _nativeElement!: HTMLElement | null;
|
|
83
|
+
|
|
84
|
+
override focus() {
|
|
85
|
+
this._nativeElement?.focus();
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
override blur() {
|
|
89
|
+
this._nativeElement?.blur();
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
private _getChildNodes(): TreeNode[] {
|
|
93
|
+
return Array.from(this.children).filter(
|
|
94
|
+
el => el.tagName.toLowerCase() === 'wc-tree-node',
|
|
95
|
+
) as TreeNode[];
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
connectedCallback() {
|
|
99
|
+
super.connectedCallback();
|
|
100
|
+
this._updateChildLevels();
|
|
101
|
+
this.setAttribute('role', 'treeitem');
|
|
102
|
+
this._syncHostAria();
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
private _syncHostAria() {
|
|
106
|
+
const hasChildren = this._getChildNodes().length > 0;
|
|
107
|
+
if (hasChildren) {
|
|
108
|
+
this.setAttribute('aria-expanded', String(this.expanded));
|
|
109
|
+
} else {
|
|
110
|
+
this.removeAttribute('aria-expanded');
|
|
111
|
+
}
|
|
112
|
+
this.setAttribute('aria-selected', String(this.selected));
|
|
113
|
+
this.setAttribute('aria-disabled', String(this.disabled));
|
|
114
|
+
this.setAttribute('aria-level', String(this.level + 1));
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
private _updateChildLevels() {
|
|
118
|
+
const children = this._getChildNodes();
|
|
119
|
+
children.forEach(child => {
|
|
120
|
+
// eslint-disable-next-line no-param-reassign
|
|
121
|
+
child.level = this.level + 1;
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
private _handleClick(event: Event) {
|
|
126
|
+
if (this.disabled) {
|
|
127
|
+
event.preventDefault();
|
|
128
|
+
event.stopPropagation();
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const hasChildren = this._getChildNodes().length > 0;
|
|
133
|
+
if (hasChildren) {
|
|
134
|
+
this.expanded = !this.expanded;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
this.dispatchEvent(
|
|
138
|
+
new CustomEvent('tree-node:click', {
|
|
139
|
+
bubbles: true,
|
|
140
|
+
composed: true,
|
|
141
|
+
detail: {
|
|
142
|
+
value: this.value || this.label,
|
|
143
|
+
label: this.label,
|
|
144
|
+
expanded: this.expanded,
|
|
145
|
+
},
|
|
146
|
+
}),
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
private _handleKeyDown(event: KeyboardEvent) {
|
|
151
|
+
if (this.disabled) return;
|
|
152
|
+
|
|
153
|
+
const hasChildren = this._getChildNodes().length > 0;
|
|
154
|
+
|
|
155
|
+
switch (event.key) {
|
|
156
|
+
case ' ':
|
|
157
|
+
case 'Enter':
|
|
158
|
+
event.preventDefault();
|
|
159
|
+
if (hasChildren) {
|
|
160
|
+
this.expanded = !this.expanded;
|
|
161
|
+
}
|
|
162
|
+
this.dispatchEvent(
|
|
163
|
+
new CustomEvent('tree-node:click', {
|
|
164
|
+
bubbles: true,
|
|
165
|
+
composed: true,
|
|
166
|
+
detail: {
|
|
167
|
+
value: this.value || this.label,
|
|
168
|
+
label: this.label,
|
|
169
|
+
expanded: this.expanded,
|
|
170
|
+
},
|
|
171
|
+
}),
|
|
172
|
+
);
|
|
173
|
+
if (this.href) {
|
|
174
|
+
window.open(this.href, this.target);
|
|
175
|
+
}
|
|
176
|
+
break;
|
|
177
|
+
case 'ArrowLeft':
|
|
178
|
+
event.preventDefault();
|
|
179
|
+
if (this.expanded && hasChildren) {
|
|
180
|
+
this.expanded = false;
|
|
181
|
+
}
|
|
182
|
+
break;
|
|
183
|
+
case 'ArrowRight':
|
|
184
|
+
event.preventDefault();
|
|
185
|
+
if (hasChildren) {
|
|
186
|
+
if (!this.expanded) {
|
|
187
|
+
this.expanded = true;
|
|
188
|
+
} else {
|
|
189
|
+
const firstChild = this._getChildNodes()[0];
|
|
190
|
+
firstChild?.focus();
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
break;
|
|
194
|
+
default:
|
|
195
|
+
break;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
updated(changedProps: Map<string, unknown>) {
|
|
200
|
+
super.updated(changedProps);
|
|
201
|
+
if (changedProps.has('level')) {
|
|
202
|
+
this._updateChildLevels();
|
|
203
|
+
}
|
|
204
|
+
this._syncHostAria();
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
private _renderContent(hasChildren: boolean) {
|
|
208
|
+
// 0.125rem offset aligns text visually with the expand/icon space
|
|
209
|
+
const indentStyle = styleMap({
|
|
210
|
+
paddingInlineStart: `calc(${this.level + 1}rem - 0.125rem)`,
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
const contentClasses = classMap({
|
|
214
|
+
'tree-node-content': true,
|
|
215
|
+
selected: this.selected,
|
|
216
|
+
disabled: this.disabled,
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
const innerContent = html`
|
|
220
|
+
${hasChildren
|
|
221
|
+
? html`<wc-icon
|
|
222
|
+
class=${classMap({ 'expand-icon': true, expanded: this.expanded })}
|
|
223
|
+
name="arrow_right"
|
|
224
|
+
></wc-icon>`
|
|
225
|
+
: html`<span class="icon-space"></span>`}
|
|
226
|
+
${this.icon
|
|
227
|
+
? html`<wc-icon class="node-icon" name=${this.icon}></wc-icon>`
|
|
228
|
+
: ''}
|
|
229
|
+
<span class="tree-node-label">${this.label}<slot name="label"></slot></span>
|
|
230
|
+
`;
|
|
231
|
+
|
|
232
|
+
if (this.href) {
|
|
233
|
+
return html`<a
|
|
234
|
+
class=${contentClasses}
|
|
235
|
+
style=${indentStyle}
|
|
236
|
+
href=${this.href}
|
|
237
|
+
target=${this.target}
|
|
238
|
+
tabindex=${this.disabled ? '-1' : '0'}
|
|
239
|
+
@click=${this._handleClick}
|
|
240
|
+
@keydown=${this._handleKeyDown}
|
|
241
|
+
>${innerContent}</a>`;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
return html`<div
|
|
245
|
+
class=${contentClasses}
|
|
246
|
+
style=${indentStyle}
|
|
247
|
+
tabindex=${this.disabled ? '-1' : '0'}
|
|
248
|
+
@click=${this._handleClick}
|
|
249
|
+
@keydown=${this._handleKeyDown}
|
|
250
|
+
>${innerContent}</div>`;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
render() {
|
|
254
|
+
const hasChildren = this._getChildNodes().length > 0;
|
|
255
|
+
|
|
256
|
+
const nodeSlotClasses = classMap({
|
|
257
|
+
'node-children': true,
|
|
258
|
+
expanded: this.expanded,
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
return html`<div class="tree-node">
|
|
262
|
+
${this._renderContent(hasChildren)}
|
|
263
|
+
<div class=${nodeSlotClasses}>
|
|
264
|
+
<slot></slot>
|
|
265
|
+
</div>
|
|
266
|
+
</div>`;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { html, LitElement } from 'lit';
|
|
2
|
+
import { property } from 'lit/decorators.js';
|
|
3
|
+
import styles from './tree-view.scss';
|
|
4
|
+
import { TreeNode } from './tree-node.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @label Tree View
|
|
8
|
+
* @tag wc-tree-view
|
|
9
|
+
* @rawTag tree-view
|
|
10
|
+
* @summary A tree view is a hierarchical structure that provides nested levels of navigation. It supports keyboard navigation, single/multi select, and expandable nodes.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```html
|
|
14
|
+
* <wc-tree-view>
|
|
15
|
+
* <wc-tree-node label="Parent" expanded>
|
|
16
|
+
* <wc-tree-node label="Child 1"></wc-tree-node>
|
|
17
|
+
* <wc-tree-node label="Child 2"></wc-tree-node>
|
|
18
|
+
* </wc-tree-node>
|
|
19
|
+
* </wc-tree-view>
|
|
20
|
+
* ```
|
|
21
|
+
* @tags navigation
|
|
22
|
+
*/
|
|
23
|
+
export class TreeView extends LitElement {
|
|
24
|
+
static styles = [styles];
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* The value of the currently selected node.
|
|
28
|
+
*/
|
|
29
|
+
@property({ type: String, attribute: 'selected-node', reflect: true })
|
|
30
|
+
selectedNode: string = '';
|
|
31
|
+
|
|
32
|
+
connectedCallback() {
|
|
33
|
+
super.connectedCallback();
|
|
34
|
+
this.addEventListener('tree-node:click', this._onNodeClick as EventListener);
|
|
35
|
+
this.addEventListener('keydown', this._onKeyDown);
|
|
36
|
+
this.setAttribute('role', 'tree');
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
updated(changedProps: Map<string, unknown>) {
|
|
40
|
+
super.updated(changedProps);
|
|
41
|
+
|
|
42
|
+
if (changedProps.has('selectedNode')) {
|
|
43
|
+
this._syncSelectedStateFromProperty();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
disconnectedCallback() {
|
|
48
|
+
super.disconnectedCallback();
|
|
49
|
+
this.removeEventListener('tree-node:click', this._onNodeClick as EventListener);
|
|
50
|
+
this.removeEventListener('keydown', this._onKeyDown);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
private _getTopLevelNodes(): TreeNode[] {
|
|
54
|
+
return Array.from(this.children).filter(
|
|
55
|
+
el => el.tagName.toLowerCase() === 'wc-tree-node',
|
|
56
|
+
) as TreeNode[];
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
private _getAllVisibleNodes(): TreeNode[] {
|
|
60
|
+
const result: TreeNode[] = [];
|
|
61
|
+
const collect = (nodes: TreeNode[]) => {
|
|
62
|
+
nodes.forEach(node => {
|
|
63
|
+
result.push(node);
|
|
64
|
+
if (node.expanded) {
|
|
65
|
+
const children = Array.from(node.children).filter(
|
|
66
|
+
el => el.tagName.toLowerCase() === 'wc-tree-node',
|
|
67
|
+
) as TreeNode[];
|
|
68
|
+
collect(children);
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
};
|
|
72
|
+
collect(this._getTopLevelNodes());
|
|
73
|
+
return result;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
private _onNodeClick = (event: CustomEvent) => {
|
|
77
|
+
const target = event.target as TreeNode;
|
|
78
|
+
if (target.disabled) return;
|
|
79
|
+
|
|
80
|
+
const value = event.detail?.value ?? target.value ?? target.label;
|
|
81
|
+
this.selectedNode = value;
|
|
82
|
+
|
|
83
|
+
// Update selected state on all nodes
|
|
84
|
+
this._updateSelectedState(value);
|
|
85
|
+
|
|
86
|
+
this.dispatchEvent(
|
|
87
|
+
new CustomEvent('tree-view:change', {
|
|
88
|
+
bubbles: true,
|
|
89
|
+
composed: true,
|
|
90
|
+
detail: { value, node: target },
|
|
91
|
+
}),
|
|
92
|
+
);
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
private _updateSelectedState(selectedValue: string) {
|
|
96
|
+
const allNodes = this._collectAllNodes(this._getTopLevelNodes());
|
|
97
|
+
allNodes.forEach(node => {
|
|
98
|
+
const nodeValue = node.value || node.label;
|
|
99
|
+
// eslint-disable-next-line no-param-reassign
|
|
100
|
+
node.selected = nodeValue === selectedValue;
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
private _clearSelectedState() {
|
|
105
|
+
const allNodes = this._collectAllNodes(this._getTopLevelNodes());
|
|
106
|
+
allNodes.forEach(node => {
|
|
107
|
+
// eslint-disable-next-line no-param-reassign
|
|
108
|
+
node.selected = false;
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
private _syncSelectedStateFromProperty() {
|
|
113
|
+
if (this.selectedNode) {
|
|
114
|
+
this._updateSelectedState(this.selectedNode);
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
this._clearSelectedState();
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
private _onSlotChange = () => {
|
|
122
|
+
this._syncSelectedStateFromProperty();
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
private _collectAllNodes(nodes: TreeNode[]): TreeNode[] {
|
|
126
|
+
const result: TreeNode[] = [];
|
|
127
|
+
nodes.forEach(node => {
|
|
128
|
+
result.push(node);
|
|
129
|
+
const children = Array.from(node.children).filter(
|
|
130
|
+
el => el.tagName.toLowerCase() === 'wc-tree-node',
|
|
131
|
+
) as TreeNode[];
|
|
132
|
+
result.push(...this._collectAllNodes(children));
|
|
133
|
+
});
|
|
134
|
+
return result;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
private _onKeyDown = (event: KeyboardEvent) => {
|
|
138
|
+
const visibleNodes = this._getAllVisibleNodes().filter(n => !n.disabled);
|
|
139
|
+
if (visibleNodes.length === 0) return;
|
|
140
|
+
|
|
141
|
+
const focusedIndex = visibleNodes.findIndex(node => {
|
|
142
|
+
const root = node.shadowRoot;
|
|
143
|
+
return root?.activeElement !== null && root?.activeElement !== undefined;
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
if (focusedIndex === -1 && event.key !== 'Tab') return;
|
|
147
|
+
|
|
148
|
+
switch (event.key) {
|
|
149
|
+
case 'ArrowDown': {
|
|
150
|
+
event.preventDefault();
|
|
151
|
+
const nextIndex = (focusedIndex + 1) % visibleNodes.length;
|
|
152
|
+
visibleNodes[nextIndex]?.focus();
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
case 'ArrowUp': {
|
|
156
|
+
event.preventDefault();
|
|
157
|
+
const prevIndex =
|
|
158
|
+
(focusedIndex - 1 + visibleNodes.length) % visibleNodes.length;
|
|
159
|
+
visibleNodes[prevIndex]?.focus();
|
|
160
|
+
break;
|
|
161
|
+
}
|
|
162
|
+
case 'Home':
|
|
163
|
+
event.preventDefault();
|
|
164
|
+
visibleNodes[0]?.focus();
|
|
165
|
+
break;
|
|
166
|
+
case 'End':
|
|
167
|
+
event.preventDefault();
|
|
168
|
+
visibleNodes[visibleNodes.length - 1]?.focus();
|
|
169
|
+
break;
|
|
170
|
+
default:
|
|
171
|
+
break;
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
render() {
|
|
176
|
+
return html`<div class="tree-view">
|
|
177
|
+
<slot @slotchange=${this._onSlotChange}></slot>
|
|
178
|
+
</div>`;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
static Node = TreeNode;
|
|
182
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { customElement } from 'lit/decorators.js';
|
|
2
|
+
import { TreeView } from './tree-view.js';
|
|
3
|
+
import { TreeNode } from './tree-node.js';
|
|
4
|
+
|
|
5
|
+
@customElement('wc-tree-node')
|
|
6
|
+
export class WcTreeNode extends TreeNode {}
|
|
7
|
+
|
|
8
|
+
@customElement('wc-tree-view')
|
|
9
|
+
export class WcTreeView extends TreeView {}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"class-map-DpeNtqCn.js","sources":["../node_modules/lit-html/directives/class-map.js"],"sourcesContent":["import{noChange as t}from\"../lit-html.js\";import{directive as s,Directive as i,PartType as r}from\"../directive.js\";\n/**\n * @license\n * Copyright 2018 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */const e=s(class extends i{constructor(t){if(super(t),t.type!==r.ATTRIBUTE||\"class\"!==t.name||t.strings?.length>2)throw Error(\"`classMap()` can only be used in the `class` attribute and must be the only part in the attribute.\")}render(t){return\" \"+Object.keys(t).filter(s=>t[s]).join(\" \")+\" \"}update(s,[i]){if(void 0===this.st){this.st=new Set,void 0!==s.strings&&(this.nt=new Set(s.strings.join(\" \").split(/\\s/).filter(t=>\"\"!==t)));for(const t in i)i[t]&&!this.nt?.has(t)&&this.st.add(t);return this.render(i)}const r=s.element.classList;for(const t of this.st)t in i||(r.remove(t),this.st.delete(t));for(const t in i){const s=!!i[t];s===this.st.has(t)||this.nt?.has(t)||(s?(r.add(t),this.st.add(t)):(r.remove(t),this.st.delete(t)))}return t}});export{e as classMap};\n//# sourceMappingURL=class-map.js.map\n"],"names":["s","t","r"],"mappings":";;;AACA;AACA;AACA;AACA;AACA,GAAQ,MAAC,CAAC,CAACA,GAAC,CAAC,cAAc,CAAC,CAAC,WAAW,CAACC,GAAC,CAAC,CAAC,GAAG,KAAK,CAACA,GAAC,CAAC,CAACA,GAAC,CAAC,IAAI,GAAGC,CAAC,CAAC,SAAS,EAAE,OAAO,GAAGD,GAAC,CAAC,IAAI,EAAEA,GAAC,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,oGAAoG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAM,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC,EAAE,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,MAAM,CAAC,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,OAAOA,CAAC,CAAC,CAAC;;;;","x_google_ignoreList":[0]}
|