@fluid-topics/ft-tree-list 1.3.21 → 1.3.23
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-list.light.js +372 -288
- package/build/ft-tree-list.min.js +325 -241
- package/build/ftds-tree-list.d.ts +6 -0
- package/build/ftds-tree-list.js +98 -20
- package/build/ftds-tree-list.properties.d.ts +4 -1
- package/build/ftds-tree-list.styles.js +46 -9
- package/package.json +6 -6
|
@@ -21,6 +21,7 @@ export declare class FtdsTreeList extends FtLitElement implements FtdsTreeListPr
|
|
|
21
21
|
expandAllLabel: string;
|
|
22
22
|
collapseAllLabel: string;
|
|
23
23
|
emptyState?: EmptyStateConfiguration;
|
|
24
|
+
loading: boolean;
|
|
24
25
|
nodeToFocus?: FtTreeNode;
|
|
25
26
|
isTreeSelectorCollapsed?: boolean;
|
|
26
27
|
childrenCounts: Map<string, number>;
|
|
@@ -33,6 +34,9 @@ export declare class FtdsTreeList extends FtLitElement implements FtdsTreeListPr
|
|
|
33
34
|
setFocusToTreeItem(item: FtTreeNode): void;
|
|
34
35
|
selectNodeByBreadcrumb(breadcrumb: string[]): Promise<void>;
|
|
35
36
|
protected render(): TemplateResult<1>;
|
|
37
|
+
protected renderBody(): TemplateResult;
|
|
38
|
+
protected renderLoadingState(): TemplateResult;
|
|
39
|
+
protected renderLeftHeader(): TemplateResult;
|
|
36
40
|
protected renderNode(node: FtTreeNode): unknown;
|
|
37
41
|
protected renderChildNodes(isNodeExpanded: boolean, visibleChildren: FtTreeNode[], node: FtTreeNode, childrenClasses: {
|
|
38
42
|
expanded: boolean;
|
|
@@ -47,6 +51,8 @@ export declare class FtdsTreeList extends FtLitElement implements FtdsTreeListPr
|
|
|
47
51
|
"with-children": boolean;
|
|
48
52
|
}): TemplateResult<1>;
|
|
49
53
|
protected renderEmptyState(): TemplateResult<1>;
|
|
54
|
+
protected renderEmptyStateTitle(): TemplateResult | symbol;
|
|
55
|
+
protected renderEmptyStateDescription(): TemplateResult | symbol;
|
|
50
56
|
protected willUpdate(props: PropertyValues): void;
|
|
51
57
|
protected updated(props: PropertyValues): void;
|
|
52
58
|
protected onKeydown(event: KeyboardEvent, currentNode: FtTreeNode, isLoadMore: boolean, parentNode?: FtTreeNode): void;
|
package/build/ftds-tree-list.js
CHANGED
|
@@ -17,6 +17,7 @@ import { FtdsButton } from "@fluid-topics/ft-button";
|
|
|
17
17
|
import { styles } from "./ftds-tree-list.styles";
|
|
18
18
|
import { createLoadMoreNode, getPathToNode, TraversalInstruction, traverseVisibleTree } from "./model/FtTreeListData";
|
|
19
19
|
import { cactusSvg } from "@fluid-topics/ft-assets";
|
|
20
|
+
import { FtSkeleton } from "@fluid-topics/ft-skeleton";
|
|
20
21
|
export class NodeSelectedEvent extends CustomEvent {
|
|
21
22
|
constructor(node) {
|
|
22
23
|
super("node-selected", { detail: node });
|
|
@@ -34,6 +35,7 @@ class FtdsTreeList extends FtLitElement {
|
|
|
34
35
|
this.collapseParametrizedLabel = "Collapse {0}";
|
|
35
36
|
this.expandAllLabel = "Expand all";
|
|
36
37
|
this.collapseAllLabel = "Collapse all";
|
|
38
|
+
this.loading = false;
|
|
37
39
|
this.childrenCounts = new Map();
|
|
38
40
|
this.userOpenedNodes = new Set();
|
|
39
41
|
this.userClosedNodes = new Set();
|
|
@@ -72,20 +74,12 @@ class FtdsTreeList extends FtLitElement {
|
|
|
72
74
|
this.selectNode(currentNode);
|
|
73
75
|
}
|
|
74
76
|
render() {
|
|
75
|
-
var _a;
|
|
76
77
|
const atLeastOneRootNodeIsExpandable = this.data && this.data.rootNodes && this.data.rootNodes.length > 0
|
|
77
78
|
? this.data.rootNodes.some((rootNode) => rootNode.children.length > 0)
|
|
78
79
|
: false;
|
|
79
80
|
return html `
|
|
80
81
|
<div part="header">
|
|
81
|
-
${when(this.label.length > 0, () =>
|
|
82
|
-
<ft-typography class="header-label" variant="${FtTypographyVariants.body1semibold}">
|
|
83
|
-
${this.label}
|
|
84
|
-
<ft-typography variant="${FtTypographyVariants.body2medium}" class="node-children-count">
|
|
85
|
-
(${this.getEntriesCount()})
|
|
86
|
-
</ft-typography>
|
|
87
|
-
</ft-typography>
|
|
88
|
-
`)}
|
|
82
|
+
${when(this.label.length > 0, () => this.renderLeftHeader())}
|
|
89
83
|
${when(atLeastOneRootNodeIsExpandable, () => html `
|
|
90
84
|
<ftds-button
|
|
91
85
|
dense
|
|
@@ -100,12 +94,59 @@ class FtdsTreeList extends FtLitElement {
|
|
|
100
94
|
</ftds-button>
|
|
101
95
|
`)}
|
|
102
96
|
</div>
|
|
103
|
-
${
|
|
97
|
+
${this.renderBody()}
|
|
98
|
+
`;
|
|
99
|
+
}
|
|
100
|
+
renderBody() {
|
|
101
|
+
var _a;
|
|
102
|
+
if (this.loading) {
|
|
103
|
+
return this.renderLoadingState();
|
|
104
|
+
}
|
|
105
|
+
else if (!((_a = this.data) === null || _a === void 0 ? void 0 : _a.rootNodes) || this.data.rootNodes.length <= 0) {
|
|
106
|
+
return this.renderEmptyState();
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
return html `
|
|
104
110
|
<ul role="tree" class="ft-tree-list" aria-labelledby="${this.label}">
|
|
105
111
|
${repeat(this.data.rootNodes, (node) => node.value, (node) => this.renderNode(node))}
|
|
106
|
-
</ul
|
|
107
|
-
|
|
112
|
+
</ul>`;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
renderLoadingState() {
|
|
116
|
+
const skeletons = [
|
|
117
|
+
50, 45, 30, 35, 25,
|
|
118
|
+
44, 35, 27, 42, 25,
|
|
119
|
+
47, 30, 29, 45, 49,
|
|
120
|
+
].map(width => html `
|
|
121
|
+
<li>
|
|
122
|
+
<div class="ft-tree-list--item">
|
|
123
|
+
<ft-skeleton style="--ft-skeleton--width: ${width}%"></ft-skeleton>
|
|
124
|
+
</div>
|
|
125
|
+
</li>`);
|
|
126
|
+
return html `
|
|
127
|
+
<ul class="ft-tree-list loading-state">${skeletons}</ul>`;
|
|
128
|
+
}
|
|
129
|
+
renderLeftHeader() {
|
|
130
|
+
if (this.loading) {
|
|
131
|
+
return html `
|
|
132
|
+
<div class="header-left">
|
|
133
|
+
<ft-typography class="header-label" variant="${FtTypographyVariants.body1semibold}">
|
|
134
|
+
${this.label}
|
|
135
|
+
</ft-typography>
|
|
136
|
+
<ft-skeleton class="node-count-loader"></ft-skeleton>
|
|
137
|
+
</div>
|
|
108
138
|
`;
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
return html `
|
|
142
|
+
<ft-typography class="header-label" variant="${FtTypographyVariants.body1semibold}">
|
|
143
|
+
${this.label}
|
|
144
|
+
<ft-typography variant="${FtTypographyVariants.body2medium}" class="node-children-count">
|
|
145
|
+
(${this.getEntriesCount()})
|
|
146
|
+
</ft-typography>
|
|
147
|
+
</ft-typography>
|
|
148
|
+
`;
|
|
149
|
+
}
|
|
109
150
|
}
|
|
110
151
|
renderNode(node) {
|
|
111
152
|
var _a;
|
|
@@ -128,7 +169,7 @@ class FtdsTreeList extends FtLitElement {
|
|
|
128
169
|
role="treeitem"
|
|
129
170
|
data-value="${node.value}"
|
|
130
171
|
aria-expanded="${ifDefined(isNodeExpanded)}"
|
|
131
|
-
class="${classMap(childrenClasses)}"
|
|
172
|
+
class="ft-tree-list--item ${classMap(childrenClasses)}"
|
|
132
173
|
tabindex="-1"
|
|
133
174
|
@keydown="${(e) => this.onKeydown(e, node, false)}"
|
|
134
175
|
>
|
|
@@ -176,7 +217,7 @@ class FtdsTreeList extends FtLitElement {
|
|
|
176
217
|
icon="${FtIcons.ARROW_DOWN}"
|
|
177
218
|
tabindex="-1"
|
|
178
219
|
aria-expanded="false"
|
|
179
|
-
class="${classMap(childrenClasses)}"
|
|
220
|
+
class="ft-tree-list--item ${classMap(childrenClasses)}"
|
|
180
221
|
@click="${() => this.loadMore(node)}"
|
|
181
222
|
@keydown="${(e) => this.onKeydown(e, createLoadMoreNode(node), true, node)}">
|
|
182
223
|
<ft-icon value=${FtIcons.ARROW_DOWN}></ft-icon>
|
|
@@ -191,16 +232,49 @@ class FtdsTreeList extends FtLitElement {
|
|
|
191
232
|
`;
|
|
192
233
|
}
|
|
193
234
|
renderEmptyState() {
|
|
194
|
-
var _a
|
|
235
|
+
var _a;
|
|
195
236
|
return html `
|
|
196
237
|
<div class="empty-state">
|
|
197
238
|
${((_a = this.emptyState) === null || _a === void 0 ? void 0 : _a.noImage) ? nothing : cactusSvg}
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
</ft-typography>
|
|
239
|
+
${this.renderEmptyStateTitle()}
|
|
240
|
+
${this.renderEmptyStateDescription()}
|
|
201
241
|
</div>
|
|
202
242
|
`;
|
|
203
243
|
}
|
|
244
|
+
renderEmptyStateTitle() {
|
|
245
|
+
if (!this.emptyState) {
|
|
246
|
+
return nothing;
|
|
247
|
+
}
|
|
248
|
+
if (typeof this.emptyState.title === "string") {
|
|
249
|
+
return html `
|
|
250
|
+
<ft-typography class="empty-state--title" variant="${FtTypographyVariants.body1medium}">
|
|
251
|
+
${this.emptyState.title}
|
|
252
|
+
</ft-typography>`;
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
return this.emptyState.title;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
renderEmptyStateDescription() {
|
|
259
|
+
var _a;
|
|
260
|
+
if (!((_a = this.emptyState) === null || _a === void 0 ? void 0 : _a.description)) {
|
|
261
|
+
return nothing;
|
|
262
|
+
}
|
|
263
|
+
if (typeof this.emptyState.description === "string") {
|
|
264
|
+
this.emptyState.description = [this.emptyState.description];
|
|
265
|
+
}
|
|
266
|
+
if (this.emptyState.description instanceof Array) {
|
|
267
|
+
const labels = this.emptyState.description.map(label => html `
|
|
268
|
+
<ft-typography variant="${FtTypographyVariants.body1medium}">
|
|
269
|
+
${label}
|
|
270
|
+
</ft-typography>`);
|
|
271
|
+
return html `
|
|
272
|
+
<div class="empty-state--description">${labels}</div>`;
|
|
273
|
+
}
|
|
274
|
+
else {
|
|
275
|
+
return this.emptyState.description;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
204
278
|
willUpdate(props) {
|
|
205
279
|
var _a, _b;
|
|
206
280
|
super.willUpdate(props);
|
|
@@ -444,7 +518,8 @@ class FtdsTreeList extends FtLitElement {
|
|
|
444
518
|
FtdsTreeList.elementDefinitions = {
|
|
445
519
|
"ft-typography": FtTypography,
|
|
446
520
|
"ftds-button": FtdsButton,
|
|
447
|
-
"ft-icon": FtIcon
|
|
521
|
+
"ft-icon": FtIcon,
|
|
522
|
+
"ft-skeleton": FtSkeleton,
|
|
448
523
|
};
|
|
449
524
|
FtdsTreeList.styles = styles;
|
|
450
525
|
__decorate([
|
|
@@ -481,8 +556,11 @@ __decorate([
|
|
|
481
556
|
property()
|
|
482
557
|
], FtdsTreeList.prototype, "collapseAllLabel", void 0);
|
|
483
558
|
__decorate([
|
|
484
|
-
jsonProperty(
|
|
559
|
+
jsonProperty(undefined)
|
|
485
560
|
], FtdsTreeList.prototype, "emptyState", void 0);
|
|
561
|
+
__decorate([
|
|
562
|
+
property({ type: Boolean })
|
|
563
|
+
], FtdsTreeList.prototype, "loading", void 0);
|
|
486
564
|
__decorate([
|
|
487
565
|
state()
|
|
488
566
|
], FtdsTreeList.prototype, "nodeToFocus", void 0);
|
|
@@ -11,8 +11,11 @@ export interface FtdsTreeListProperties {
|
|
|
11
11
|
collapseParametrizedLabel: string;
|
|
12
12
|
expandAllLabel: string;
|
|
13
13
|
collapseAllLabel: string;
|
|
14
|
+
emptyState?: EmptyStateConfiguration;
|
|
15
|
+
loading?: boolean;
|
|
14
16
|
}
|
|
15
17
|
export interface EmptyStateConfiguration {
|
|
16
18
|
noImage: boolean;
|
|
17
|
-
|
|
19
|
+
title: string | TemplateResult;
|
|
20
|
+
description?: string | string[] | TemplateResult;
|
|
18
21
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { css } from "lit";
|
|
2
|
-
import { setVariable } from "@fluid-topics/ft-wc-utils";
|
|
2
|
+
import { foundation, setVariable } from "@fluid-topics/ft-wc-utils";
|
|
3
3
|
import { FtTypographyCssVariables, FtTypographyVariants } from "@fluid-topics/ft-typography";
|
|
4
4
|
import { treeList } from "@fluid-topics/design-system-variables";
|
|
5
5
|
import { FtIconCssVariables } from "@fluid-topics/ft-icon";
|
|
@@ -24,38 +24,54 @@ export const styles = css `
|
|
|
24
24
|
align-items: baseline;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
.header-left {
|
|
28
|
+
display: flex;
|
|
29
|
+
flex-direction: row;
|
|
30
|
+
align-items: center;
|
|
31
|
+
gap: 8px;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.node-count-loader {
|
|
35
|
+
width: 30px;
|
|
36
|
+
}
|
|
37
|
+
|
|
27
38
|
/* Tree */
|
|
28
|
-
ul
|
|
39
|
+
ul.ft-tree-list {
|
|
29
40
|
padding: 0;
|
|
30
41
|
margin: 0;
|
|
31
42
|
position: relative;
|
|
32
43
|
overflow-x: clip;
|
|
33
44
|
}
|
|
34
45
|
|
|
35
|
-
ul
|
|
46
|
+
ul.ft-tree-list:before {
|
|
36
47
|
border-width: 0 ${treeList.listContainerBorderWidth};
|
|
37
48
|
border-style: solid;
|
|
38
49
|
border-color: ${treeList.listContainerBorderColor};
|
|
39
50
|
background-color: ${treeList.listContainerBackgroundColor};
|
|
40
51
|
}
|
|
41
52
|
|
|
42
|
-
ul
|
|
43
|
-
ul
|
|
53
|
+
ul.ft-tree-list,
|
|
54
|
+
ul.ft-tree-list li {
|
|
44
55
|
list-style: none;
|
|
45
56
|
width: max-content;
|
|
46
57
|
min-width: 100%;
|
|
47
58
|
}
|
|
48
59
|
|
|
49
|
-
ul
|
|
60
|
+
ul.ft-tree-list > li {
|
|
50
61
|
padding-left: ${treeList.nodeRootPaddingLeft};
|
|
51
62
|
}
|
|
52
63
|
|
|
53
|
-
ul
|
|
64
|
+
ul.ft-tree-list .ft-tree-list--item {
|
|
54
65
|
height: ${treeList.nodeHeight};
|
|
55
66
|
line-height: ${treeList.nodeHeight};
|
|
56
67
|
width: calc(100% - ${treeList.nodeRootPaddingLeft});
|
|
57
68
|
}
|
|
58
69
|
|
|
70
|
+
ul.loading-state .ft-tree-list--item {
|
|
71
|
+
display: flex;
|
|
72
|
+
align-items: center;
|
|
73
|
+
}
|
|
74
|
+
|
|
59
75
|
li a[role="treeitem"] {
|
|
60
76
|
display: inline-flex;
|
|
61
77
|
align-items: baseline;
|
|
@@ -71,7 +87,7 @@ export const styles = css `
|
|
|
71
87
|
padding-left: ${treeList.nodeChildPaddingLeft};
|
|
72
88
|
}
|
|
73
89
|
|
|
74
|
-
li
|
|
90
|
+
li .ft-tree-list--item:before {
|
|
75
91
|
content: '';
|
|
76
92
|
position: absolute;
|
|
77
93
|
left: 0;
|
|
@@ -83,7 +99,7 @@ export const styles = css `
|
|
|
83
99
|
border-color: ${treeList.nodeUnselectedDefaultBorderColor};
|
|
84
100
|
}
|
|
85
101
|
|
|
86
|
-
ul
|
|
102
|
+
ul.ft-tree-list > li:first-of-type .ft-tree-list--item:before {
|
|
87
103
|
border-top-width: ${treeList.nodeBorderWidth};
|
|
88
104
|
}
|
|
89
105
|
|
|
@@ -214,5 +230,26 @@ export const styles = css `
|
|
|
214
230
|
display: flex;
|
|
215
231
|
flex-direction: column;
|
|
216
232
|
align-items: center;
|
|
233
|
+
padding-top: ${treeList.emptyStateContainerPaddingTop};
|
|
234
|
+
padding-bottom: ${treeList.emptyStateContainerPaddingBottom};
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
.empty-state--title {
|
|
238
|
+
margin-bottom: ${treeList.emptyStateTitleMarginBottom};
|
|
239
|
+
color: ${treeList.emptyStateTitleLabelColor};
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
.empty-state--description {
|
|
243
|
+
display: flex;
|
|
244
|
+
flex-direction: column;
|
|
245
|
+
align-items: center;
|
|
246
|
+
gap: ${foundation.spacing2};
|
|
247
|
+
color: ${treeList.emptyStateDescriptionLabelColor};
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
.empty-state svg {
|
|
251
|
+
height: ${treeList.emptyStateIllustrationHeight};
|
|
252
|
+
width: ${treeList.emptyStateIllustrationWidth};
|
|
253
|
+
margin-bottom: ${treeList.emptyStateIllustrationMarginBottom};
|
|
217
254
|
}
|
|
218
255
|
`;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluid-topics/ft-tree-list",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.23",
|
|
4
4
|
"description": "A tree list component",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Lit"
|
|
@@ -19,13 +19,13 @@
|
|
|
19
19
|
"url": "ssh://git@scm.mrs.antidot.net:2222/fluidtopics/ft-web-components.git"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@fluid-topics/design-system-variables": "2.
|
|
23
|
-
"@fluid-topics/ft-assets": "1.3.
|
|
24
|
-
"@fluid-topics/ft-wc-utils": "1.3.
|
|
22
|
+
"@fluid-topics/design-system-variables": "2.53.0",
|
|
23
|
+
"@fluid-topics/ft-assets": "1.3.23",
|
|
24
|
+
"@fluid-topics/ft-wc-utils": "1.3.23",
|
|
25
25
|
"lit": "3.1.0"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
|
-
"@fluid-topics/ft-wc-test-utils": "1.3.
|
|
28
|
+
"@fluid-topics/ft-wc-test-utils": "1.3.23"
|
|
29
29
|
},
|
|
30
|
-
"gitHead": "
|
|
30
|
+
"gitHead": "1449ae5b73dbdbe40583d414fc5d8e5395694146"
|
|
31
31
|
}
|