@fluid-topics/ft-tree-selector 1.3.31 → 1.3.33
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/build/ft-tree-selector.d.ts +7 -2
- package/build/ft-tree-selector.js +96 -60
- package/build/ft-tree-selector.light.js +179 -181
- package/build/ft-tree-selector.min.js +127 -136
- package/build/ft-tree-selector.properties.d.ts +9 -1
- package/build/ft-tree-selector.properties.js +6 -1
- package/build/ft-tree-selector.styles.js +2 -6
- package/build/index.d.ts +1 -0
- package/build/index.js +1 -0
- package/package.json +4 -4
|
@@ -2,6 +2,10 @@ import { PropertyValues } from "lit";
|
|
|
2
2
|
import { ElementDefinitionsMap, FtLitElement } from "@fluid-topics/ft-wc-utils";
|
|
3
3
|
import { FtTree, FtTreeChangedDetail, FtTreeNode } from "./model/FtTree";
|
|
4
4
|
import { FtButton } from "@fluid-topics/ft-button";
|
|
5
|
+
import { FtTreeSelectorModes } from "./ft-tree-selector.properties";
|
|
6
|
+
export declare class FtTreeChangeEvent extends CustomEvent<FtTree> {
|
|
7
|
+
constructor(detail: FtTree);
|
|
8
|
+
}
|
|
5
9
|
export declare class TreeNodeChangeEvent extends CustomEvent<FtTreeChangedDetail> {
|
|
6
10
|
constructor(values: FtTreeChangedDetail);
|
|
7
11
|
}
|
|
@@ -11,6 +15,7 @@ export declare class TreeNodeClearAll extends CustomEvent<void> {
|
|
|
11
15
|
export declare class FtTreeSelector extends FtLitElement {
|
|
12
16
|
static elementDefinitions: ElementDefinitionsMap;
|
|
13
17
|
static styles: import("lit").CSSResult;
|
|
18
|
+
mode: FtTreeSelectorModes;
|
|
14
19
|
data: FtTree;
|
|
15
20
|
userOpenedNodes: Set<string>;
|
|
16
21
|
userClosedNodes: Set<string>;
|
|
@@ -25,10 +30,10 @@ export declare class FtTreeSelector extends FtLitElement {
|
|
|
25
30
|
expandAllLabel: string;
|
|
26
31
|
collapseAllLabel: string;
|
|
27
32
|
clearLabel: string;
|
|
28
|
-
protected
|
|
33
|
+
protected willUpdate(changedProperties: PropertyValues): void;
|
|
29
34
|
protected render(): import("lit-html").TemplateResult<1>;
|
|
35
|
+
protected renderNode(breadcrumb: FtTreeNode[], node: FtTreeNode): unknown;
|
|
30
36
|
private clear;
|
|
31
|
-
protected renderNode(node: FtTreeNode): unknown;
|
|
32
37
|
private toggleNode;
|
|
33
38
|
private renderOpenCloseButton;
|
|
34
39
|
private userChangeNodeExpandStatus;
|
|
@@ -6,26 +6,34 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
6
6
|
};
|
|
7
7
|
import { html, nothing } from "lit";
|
|
8
8
|
import { classMap } from "lit/directives/class-map.js";
|
|
9
|
-
import { flatDeep, FtLitElement, hasChanged, ParametrizedLabelResolver
|
|
9
|
+
import { deepCopy, flatDeep, forEachDeep, FtLitElement, hasChanged, ParametrizedLabelResolver } from "@fluid-topics/ft-wc-utils";
|
|
10
10
|
import { styles } from "./ft-tree-selector.styles";
|
|
11
11
|
import { FtCheckbox } from "@fluid-topics/ft-checkbox";
|
|
12
|
-
import { FtTypography } from "@fluid-topics/ft-typography";
|
|
12
|
+
import { FtTypography, FtTypographyVariants } from "@fluid-topics/ft-typography";
|
|
13
13
|
import { repeat } from "lit/directives/repeat.js";
|
|
14
14
|
import { property, queryAll, state } from "lit/decorators.js";
|
|
15
15
|
import { FtButton } from "@fluid-topics/ft-button";
|
|
16
|
+
import { FtTreeSelectorModes } from "./ft-tree-selector.properties";
|
|
17
|
+
import { when } from "lit/directives/when.js";
|
|
18
|
+
export class FtTreeChangeEvent extends CustomEvent {
|
|
19
|
+
constructor(detail) {
|
|
20
|
+
super("tree-change", { detail: deepCopy(detail) });
|
|
21
|
+
}
|
|
22
|
+
}
|
|
16
23
|
export class TreeNodeChangeEvent extends CustomEvent {
|
|
17
24
|
constructor(values) {
|
|
18
|
-
super("treenode-change", { detail: values
|
|
25
|
+
super("treenode-change", { detail: values });
|
|
19
26
|
}
|
|
20
27
|
}
|
|
21
28
|
export class TreeNodeClearAll extends CustomEvent {
|
|
22
29
|
constructor() {
|
|
23
|
-
super("treenode-clear-all"
|
|
30
|
+
super("treenode-clear-all");
|
|
24
31
|
}
|
|
25
32
|
}
|
|
26
33
|
class FtTreeSelector extends FtLitElement {
|
|
27
34
|
constructor() {
|
|
28
35
|
super(...arguments);
|
|
36
|
+
this.mode = FtTreeSelectorModes.auto;
|
|
29
37
|
this.userOpenedNodes = new Set();
|
|
30
38
|
this.userClosedNodes = new Set();
|
|
31
39
|
this.currentExpandButtonFocusedIndex = 0;
|
|
@@ -38,20 +46,20 @@ class FtTreeSelector extends FtLitElement {
|
|
|
38
46
|
this.collapseAllLabel = "Collapse all";
|
|
39
47
|
this.clearLabel = "Clear";
|
|
40
48
|
}
|
|
41
|
-
|
|
42
|
-
super.
|
|
49
|
+
willUpdate(changedProperties) {
|
|
50
|
+
super.willUpdate(changedProperties);
|
|
43
51
|
if (this.data && this.isTreeSelectorCollapsed == undefined) {
|
|
44
|
-
this.isTreeSelectorCollapsed = this.data.rootNodes.every(entry => !this.isNodeExpanded(entry));
|
|
52
|
+
this.isTreeSelectorCollapsed = this.data.rootNodes.every((entry) => !this.isNodeExpanded(entry));
|
|
45
53
|
}
|
|
46
54
|
}
|
|
47
55
|
render() {
|
|
48
56
|
var _a;
|
|
49
|
-
const atLeastOneRootNodeIsExpandable = this.data.rootNodes.some(rootNode => rootNode.children.length > 0);
|
|
57
|
+
const atLeastOneRootNodeIsExpandable = this.data.rootNodes.some((rootNode) => rootNode.children.length > 0);
|
|
50
58
|
return html `
|
|
51
59
|
<div class="ft-tree-selector ${atLeastOneRootNodeIsExpandable ? "with-expandable" : ""}">
|
|
52
60
|
<div part="header">
|
|
53
61
|
${this.label.length > 0 ? html `
|
|
54
|
-
<ft-typography variant="overline" part="label">
|
|
62
|
+
<ft-typography variant="${FtTypographyVariants.overline}" part="label">
|
|
55
63
|
${this.label}
|
|
56
64
|
</ft-typography>
|
|
57
65
|
` : nothing}
|
|
@@ -59,36 +67,28 @@ class FtTreeSelector extends FtLitElement {
|
|
|
59
67
|
<ft-button dense
|
|
60
68
|
tooltipposition="bottom"
|
|
61
69
|
part="expand-button"
|
|
62
|
-
icon
|
|
70
|
+
icon="${this.isTreeSelectorCollapsed ? "ICON_EXPAND" : "ICON_COLLAPSE"}"
|
|
63
71
|
label="${this.isTreeSelectorCollapsed ? this.expandAllLabel : this.collapseAllLabel}"
|
|
64
72
|
aria-expanded="${this.isTreeSelectorCollapsed}"
|
|
65
|
-
@click
|
|
73
|
+
@click=${() => this.toggleExpandAll()}>
|
|
66
74
|
</ft-button>
|
|
67
75
|
` : nothing}
|
|
68
76
|
|
|
69
|
-
${((_a = this.data) === null || _a === void 0 ? void 0 : _a.rootNodes.some(node => node.selected || node.indeterminate))
|
|
70
|
-
html `
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
77
|
+
${((_a = this.data) === null || _a === void 0 ? void 0 : _a.rootNodes.some((node) => node.selected || node.indeterminate))
|
|
78
|
+
? html `
|
|
79
|
+
<ft-button icon="close" dense @click=${() => this.clear()} part="clear-button">
|
|
80
|
+
${this.clearLabel}
|
|
81
|
+
</ft-button>
|
|
82
|
+
` : nothing}
|
|
75
83
|
</div>
|
|
76
84
|
${repeat(this.data.rootNodes, (node) => node.value, (node) => {
|
|
77
|
-
return this.renderNode(node);
|
|
85
|
+
return this.renderNode([], node);
|
|
78
86
|
})}
|
|
79
87
|
</div>
|
|
80
88
|
</div>
|
|
81
89
|
`;
|
|
82
90
|
}
|
|
83
|
-
|
|
84
|
-
flatDeep(this.data.rootNodes, n => n.children).forEach(n => {
|
|
85
|
-
n.selected = false;
|
|
86
|
-
n.indeterminate = false;
|
|
87
|
-
});
|
|
88
|
-
this.requestUpdate();
|
|
89
|
-
this.dispatchEvent(new TreeNodeClearAll());
|
|
90
|
-
}
|
|
91
|
-
renderNode(node) {
|
|
91
|
+
renderNode(breadcrumb, node) {
|
|
92
92
|
const isNodeExpanded = this.isNodeExpanded(node);
|
|
93
93
|
const childrenClasses = {
|
|
94
94
|
"expanded": isNodeExpanded,
|
|
@@ -102,31 +102,67 @@ class FtTreeSelector extends FtLitElement {
|
|
|
102
102
|
${this.renderOpenCloseButton(node)}
|
|
103
103
|
<ft-checkbox part="checkbox"
|
|
104
104
|
name="${node.label}"
|
|
105
|
-
?checked
|
|
106
|
-
?indeterminate
|
|
107
|
-
@change=${(e) => this.toggleNode(node, e)}>
|
|
105
|
+
?checked=${node.selected}
|
|
106
|
+
?indeterminate=${node.indeterminate}
|
|
107
|
+
@change=${(e) => this.toggleNode(breadcrumb, node, e)}>
|
|
108
108
|
${node.label}
|
|
109
109
|
</ft-checkbox>
|
|
110
110
|
</div>
|
|
111
111
|
${node.children.length != 0 && this.isNodeExpanded(node)
|
|
112
112
|
? html `
|
|
113
|
-
<div part="children" class
|
|
114
|
-
${isNodeExpanded
|
|
115
|
-
? html `${repeat(node.children, (c) => c.value, (c) => this.renderNode(c))}`
|
|
116
|
-
: nothing}
|
|
113
|
+
<div part="children" class="${classMap(childrenClasses)}" id="${this.getAriaControlId(node)}">
|
|
114
|
+
${when(isNodeExpanded, () => repeat(node.children, (c) => c.value, (c) => this.renderNode([...breadcrumb, node], c)))}
|
|
117
115
|
</div>`
|
|
118
116
|
: nothing}
|
|
119
117
|
</div>
|
|
120
118
|
`;
|
|
121
119
|
}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
120
|
+
clear() {
|
|
121
|
+
flatDeep(this.data.rootNodes, (n) => n.children).forEach((n) => {
|
|
122
|
+
n.selected = false;
|
|
123
|
+
n.indeterminate = false;
|
|
124
|
+
});
|
|
125
125
|
this.requestUpdate();
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
126
|
+
switch (this.mode) {
|
|
127
|
+
case FtTreeSelectorModes.auto:
|
|
128
|
+
case FtTreeSelectorModes.downward:
|
|
129
|
+
this.dispatchEvent(new FtTreeChangeEvent(this.data));
|
|
130
|
+
break;
|
|
131
|
+
default:
|
|
132
|
+
this.dispatchEvent(new TreeNodeClearAll());
|
|
133
|
+
break;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
toggleNode(breadcrumb, node, e) {
|
|
137
|
+
const update = (n) => {
|
|
138
|
+
n.selected = e.detail;
|
|
139
|
+
n.indeterminate = false;
|
|
140
|
+
};
|
|
141
|
+
update(node);
|
|
142
|
+
const parents = [...breadcrumb].reverse();
|
|
143
|
+
switch (this.mode) {
|
|
144
|
+
case FtTreeSelectorModes.auto:
|
|
145
|
+
forEachDeep(node.children, (n) => n.children, update);
|
|
146
|
+
parents.forEach((n) => {
|
|
147
|
+
n.selected = n.children.every((c) => c.selected);
|
|
148
|
+
n.indeterminate = !n.selected && n.children.some((c) => c.selected || c.indeterminate);
|
|
149
|
+
});
|
|
150
|
+
this.requestUpdate();
|
|
151
|
+
this.dispatchEvent(new FtTreeChangeEvent(this.data));
|
|
152
|
+
break;
|
|
153
|
+
case FtTreeSelectorModes.downward:
|
|
154
|
+
forEachDeep(node.children, (n) => n.children, update);
|
|
155
|
+
this.requestUpdate();
|
|
156
|
+
this.dispatchEvent(new FtTreeChangeEvent(this.data));
|
|
157
|
+
break;
|
|
158
|
+
default:
|
|
159
|
+
this.requestUpdate();
|
|
160
|
+
this.dispatchEvent(new TreeNodeChangeEvent({
|
|
161
|
+
value: node.value,
|
|
162
|
+
selected: e.detail,
|
|
163
|
+
}));
|
|
164
|
+
break;
|
|
165
|
+
}
|
|
130
166
|
}
|
|
131
167
|
renderOpenCloseButton(node) {
|
|
132
168
|
if (node.children.length === 0) {
|
|
@@ -134,18 +170,18 @@ class FtTreeSelector extends FtLitElement {
|
|
|
134
170
|
<div part="expand"></div>
|
|
135
171
|
`;
|
|
136
172
|
}
|
|
137
|
-
|
|
173
|
+
const isNodeExpanded = this.isNodeExpanded(node);
|
|
138
174
|
return html `
|
|
139
175
|
<ft-button dense part="expand" tooltipposition="bottom"
|
|
140
|
-
icon
|
|
176
|
+
icon="${isNodeExpanded ? "TRIANGLE_BOTTOM" : "TRIANGLE_RIGHT"}"
|
|
141
177
|
label="${isNodeExpanded ? this.collapseLabel : this.expandLabel}"
|
|
142
178
|
aria-label="${ParametrizedLabelResolver.replaceParameters(isNodeExpanded
|
|
143
179
|
? this.collapseParametrizedLabel
|
|
144
180
|
: this.expandParametrizedLabel, node.label)}"
|
|
145
181
|
aria-expanded="${isNodeExpanded}"
|
|
146
|
-
aria-
|
|
147
|
-
@keydown
|
|
148
|
-
@click
|
|
182
|
+
aria-controls="${this.getAriaControlId(node)}"
|
|
183
|
+
@keydown=${(e) => this.onKeydown(e, node)}
|
|
184
|
+
@click=${() => this.userChangeNodeExpandStatus(!isNodeExpanded, node.value)}>
|
|
149
185
|
</ft-button>
|
|
150
186
|
`;
|
|
151
187
|
}
|
|
@@ -198,19 +234,19 @@ class FtTreeSelector extends FtLitElement {
|
|
|
198
234
|
}
|
|
199
235
|
}
|
|
200
236
|
focusPreviousButton(currentButton) {
|
|
201
|
-
|
|
237
|
+
const currentIndex = this.currentLevelExpandButtons.indexOf(currentButton);
|
|
202
238
|
this.currentLevelExpandButtons[currentIndex == 0 ? this.currentLevelExpandButtons.length - 1 : currentIndex - 1].focus();
|
|
203
239
|
}
|
|
204
240
|
focusNextButton(currentButton) {
|
|
205
|
-
|
|
206
|
-
|
|
241
|
+
const ftButtons = [...this.currentLevelExpandButtons];
|
|
242
|
+
const currentIndex = ftButtons.indexOf(currentButton);
|
|
207
243
|
ftButtons[currentIndex == ftButtons.length - 1 ? 0 : currentIndex + 1].focus();
|
|
208
244
|
}
|
|
209
245
|
isNodeExpanded(node) {
|
|
210
246
|
return !this.userClosedNodes.has(node.value) && (node.expanded || this.userOpenedNodes.has(node.value));
|
|
211
247
|
}
|
|
212
248
|
hasExpandableChildren(node) {
|
|
213
|
-
return node.children.some(child => child.children.length > 0);
|
|
249
|
+
return node.children.some((child) => child.children.length > 0);
|
|
214
250
|
}
|
|
215
251
|
toggleExpandAll() {
|
|
216
252
|
if (this.isTreeSelectorCollapsed) {
|
|
@@ -222,20 +258,17 @@ class FtTreeSelector extends FtLitElement {
|
|
|
222
258
|
}
|
|
223
259
|
expandAll() {
|
|
224
260
|
this.userClosedNodes = new Set();
|
|
225
|
-
this.userOpenedNodes = new Set(this.
|
|
261
|
+
this.userOpenedNodes = new Set(this.getAllClosedNodes());
|
|
226
262
|
this.isTreeSelectorCollapsed = false;
|
|
227
263
|
}
|
|
228
|
-
getAllClosedNodes(
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
else {
|
|
233
|
-
return [];
|
|
234
|
-
}
|
|
264
|
+
getAllClosedNodes() {
|
|
265
|
+
return flatDeep(this.data.rootNodes, (n) => n.children)
|
|
266
|
+
.filter((n) => !n.expanded)
|
|
267
|
+
.map((n) => n.value);
|
|
235
268
|
}
|
|
236
269
|
collapseAll() {
|
|
237
270
|
this.userOpenedNodes = new Set();
|
|
238
|
-
this.userClosedNodes = new Set(this.data.rootNodes.filter((n) => n.expanded).map(n => n.value));
|
|
271
|
+
this.userClosedNodes = new Set(this.data.rootNodes.filter((n) => n.expanded).map((n) => n.value));
|
|
239
272
|
this.isTreeSelectorCollapsed = true;
|
|
240
273
|
}
|
|
241
274
|
getAriaControlId(node) {
|
|
@@ -245,9 +278,12 @@ class FtTreeSelector extends FtLitElement {
|
|
|
245
278
|
FtTreeSelector.elementDefinitions = {
|
|
246
279
|
"ft-checkbox": FtCheckbox,
|
|
247
280
|
"ft-typography": FtTypography,
|
|
248
|
-
"ft-button": FtButton
|
|
281
|
+
"ft-button": FtButton,
|
|
249
282
|
};
|
|
250
283
|
FtTreeSelector.styles = styles;
|
|
284
|
+
__decorate([
|
|
285
|
+
property()
|
|
286
|
+
], FtTreeSelector.prototype, "mode", void 0);
|
|
251
287
|
__decorate([
|
|
252
288
|
property()
|
|
253
289
|
], FtTreeSelector.prototype, "data", void 0);
|