@fluid-topics/ft-tree-list 1.2.67

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.
@@ -0,0 +1,211 @@
1
+ import { css } from "lit";
2
+ import { setVariable, } from "@fluid-topics/ft-wc-utils";
3
+ import { FtTypographyCssVariables, FtTypographyVariants } from "@fluid-topics/ft-typography";
4
+ import { treeList } from "@fluid-topics/design-system-variables";
5
+ export { treeList as FtdsTreeListCssVariables } from "@fluid-topics/design-system-variables";
6
+ // language=CSS
7
+ export const styles = css `
8
+ /* Header */
9
+ [part="header"] {
10
+ display: flex;
11
+ flex-wrap: wrap;
12
+ justify-content: space-between;
13
+ align-items: baseline;
14
+ margin-bottom: ${treeList.headerSectionMarginBottom};
15
+ padding-left: ${treeList.headerSectionPaddingLeft};
16
+ padding-right: ${treeList.headerSectionPaddingRight};
17
+ color: ${treeList.headerSectionColor};
18
+ }
19
+
20
+ .header-label {
21
+ display: flex;
22
+ gap: ${treeList.headerSectionHorizontalGap};
23
+ align-items: baseline;
24
+ }
25
+
26
+ /* Tree */
27
+ ul[role="tree"] {
28
+ padding: 0;
29
+ margin: 0;
30
+ position: relative;
31
+ overflow-x: clip;
32
+ }
33
+
34
+ ul[role="tree"]:before {
35
+ border-width: 0 ${treeList.listContainerBorderWidth};
36
+ border-style: solid;
37
+ border-color: ${treeList.listContainerBorderColor};
38
+ background-color: ${treeList.listContainerBackgroundColor};
39
+ }
40
+
41
+ ul[role="tree"],
42
+ ul[role="tree"] li {
43
+ list-style: none;
44
+ width: max-content;
45
+ min-width: 100%;
46
+ }
47
+
48
+ ul[role="tree"] > li {
49
+ padding-left: ${treeList.nodeRootPaddingLeft};
50
+ }
51
+
52
+ ul[role="tree"] a[role="treeitem"] {
53
+ height: ${treeList.nodeHeight};
54
+ line-height: ${treeList.nodeHeight};
55
+ width: calc(100% - ${treeList.nodeRootPaddingLeft});
56
+ }
57
+
58
+ li a[role="treeitem"] {
59
+ display: inline-flex;
60
+ align-items: baseline;
61
+ padding-right: ${treeList.nodeParentLabelMarginRight};
62
+ cursor: pointer;
63
+ }
64
+
65
+ li a[role="treeitem"]:not(.with-children):not([part="load-more"]) {
66
+ padding-left: ${treeList.nodeLeafPaddingLeft};
67
+ }
68
+
69
+ li a[role="treeitem"] + ul {
70
+ padding-left: ${treeList.nodeChildPaddingLeft};
71
+ }
72
+
73
+ li a[role="treeitem"]:before {
74
+ content: '';
75
+ position: absolute;
76
+ left: 0;
77
+ width: 100%;
78
+ height: ${treeList.nodeHeight};
79
+ pointer-events: none;
80
+ border-width: 0 ${treeList.nodeBorderWidth} ${treeList.nodeBorderWidth} ${treeList.nodeBorderWidth};
81
+ border-style: solid;
82
+ border-color: ${treeList.nodeUnselectedDefaultBorderColor};
83
+ }
84
+
85
+ ul[role="tree"] > li:first-of-type a[role="treeitem"]:before {
86
+ border-top-width: ${treeList.nodeBorderWidth};
87
+ }
88
+
89
+ li a[role="treeitem"]:hover:before, li a[role="treeitem"]:focus-visible:before {
90
+ left: 1px;
91
+ width: calc(100% - 4px); /* 4px to not clip the border when no horizontal scroll */
92
+ border-style: solid;
93
+ }
94
+
95
+ /* Hover node */
96
+ li a[role="treeitem"]:hover:before {
97
+ border-color: ${treeList.nodeHoverBorderColor} !important;
98
+ border-width: ${treeList.nodeBorderWidth};
99
+ }
100
+
101
+ /* Focus node */
102
+ li a[role="treeitem"]:focus-visible {
103
+ outline: none;
104
+ }
105
+
106
+ li a[role="treeitem"]:focus-visible:before, ul[role="tree"] > li:first-of-type a[role="treeitem"]:focus-visible:before {
107
+ border-color: ${treeList.nodeFocusFocusRingColor} !important;
108
+ border-width: ${treeList.nodeFocusOutlineWidth};
109
+ }
110
+
111
+ /* Selected Node */
112
+ li > a[role="treeitem"][aria-selected=true] ft-typography[part="node-label"] {
113
+ color: ${treeList.nodeSelectedLabelColor};
114
+ }
115
+
116
+ li > a[role="treeitem"][aria-selected=true] [part="node-expand"] {
117
+ color: ${treeList.nodeSelectedIconColor};
118
+ }
119
+
120
+ li > a[role="treeitem"][aria-selected=true]:before {
121
+ background-color: ${treeList.nodeSelectedBackgroundColor};
122
+ border-color: ${treeList.nodeSelectedDefaultBorderColor};
123
+ }
124
+
125
+ /* Descendent of selected Node */
126
+ li > a[role="treeitem"][aria-selected=true] + ul a ft-typography[part="node-label"] {
127
+ color: ${treeList.nodeDescendantOfSelectedLabelColor};
128
+ }
129
+
130
+ li > a[role="treeitem"][aria-selected=true] + ul a [part="node-expand"] {
131
+ color: ${treeList.nodeDescendantOfSelectedIconColor};
132
+ }
133
+
134
+ li > a[role="treeitem"][aria-selected=true] + ul a:before {
135
+ background-color: ${treeList.nodeDescendantOfSelectedBackgroundColor};
136
+ border-color: ${treeList.nodeDescendantOfSelectedDefaultBorderColor};
137
+ }
138
+
139
+ /* Buttons */
140
+ [part="node-expand"] {
141
+ --ft-icon-font-size: 16px;
142
+ color: ${treeList.nodeUnselectedIconColor};
143
+ }
144
+
145
+ /* Load more node */
146
+ [part="load-more"] [part="node-label"],
147
+ li > a[role="treeitem"][aria-selected=true] + ul a[part="load-more"] ft-typography[part="node-label"] {
148
+ color: ${treeList.loadMoreLabelColor};
149
+ }
150
+
151
+ [part="load-more"] ft-icon {
152
+ color: ${treeList.loadMoreIconColor};
153
+ }
154
+
155
+ li a[role="treeitem"][part="load-more"]:before {
156
+ border-color: ${treeList.loadMoreUnselectedDefaultBorderColor};
157
+ }
158
+
159
+ li > a[role="treeitem"][aria-selected=true] + ul a[part="load-more"]:not(:hover, :focus-visible, :active):before {
160
+ background-color: ${treeList.loadMoreDescendantOfSelectedDefaultBackgroundColor};
161
+ border-color: ${treeList.loadMoreDescendantOfSelectedDefaultBorderColor};
162
+ }
163
+
164
+ li a[role="treeitem"][part="load-more"]:hover:before {
165
+ background-color: ${treeList.loadMoreHoverBackgroundColor};
166
+ border-color: ${treeList.loadMoreHoverBorderColor} !important;
167
+ }
168
+
169
+ li a[role="treeitem"][part="load-more"]:focus-visible:before {
170
+ background-color: ${treeList.loadMoreFocusBackgroundColor};
171
+ }
172
+
173
+ li a[role="treeitem"][part="load-more"]:active:before {
174
+ background-color: ${treeList.loadMoreActiveBackgroundColor};
175
+ border-color: ${treeList.loadMoreActiveBorderColor} !important;
176
+ }
177
+
178
+ /* Labels */
179
+ .node-label-container {
180
+ display: flex;
181
+ width: 100%;
182
+ align-items: baseline;
183
+ }
184
+
185
+ ft-typography[part="node-label"] {
186
+ height: 100%;
187
+ white-space: nowrap;
188
+ color: ${treeList.nodeUnselectedLabelColor};
189
+ margin-right: ${treeList.nodeParentLabelMarginRight};
190
+ }
191
+
192
+ li a[role="treeitem"].with-children > .node-label-container > ft-typography[part="node-label"] {
193
+ margin-left: ${treeList.nodeParentLabelMarginLeft};
194
+ }
195
+
196
+ li > a[aria-selected=true] > ft-typography[part="node-label"] {
197
+ ${setVariable(FtTypographyCssVariables.fontFamily, FtTypographyVariants.body2semibold)};
198
+ ${setVariable(FtTypographyCssVariables.fontWeight, "bold")};
199
+ }
200
+
201
+ .node-children-count {
202
+ color: ${treeList.nodeUnselectedCounterColor};
203
+ }
204
+
205
+ /* Empty State */
206
+ .empty-state {
207
+ display: flex;
208
+ flex-direction: column;
209
+ align-items: center;
210
+ }
211
+ `;
@@ -0,0 +1,3 @@
1
+ export * from "./ftds-tree-list.styles";
2
+ export * from "./ftds-tree-list.properties";
3
+ export * from "./ftds-tree-list";
package/build/index.js ADDED
@@ -0,0 +1,6 @@
1
+ import { customElement } from "@fluid-topics/ft-wc-utils";
2
+ import { FtdsTreeList } from "./ftds-tree-list";
3
+ export * from "./ftds-tree-list.styles";
4
+ export * from "./ftds-tree-list.properties";
5
+ export * from "./ftds-tree-list";
6
+ customElement("ftds-tree-list")(FtdsTreeList);
@@ -0,0 +1,18 @@
1
+ export interface FtTreeNode {
2
+ value: string;
3
+ label: string;
4
+ expanded?: boolean;
5
+ children: FtTreeNode[];
6
+ loadedCount?: number;
7
+ }
8
+ export interface FtTreeListData {
9
+ rootNodes: FtTreeNode[];
10
+ }
11
+ export declare class TraversalInstruction {
12
+ readonly finished: boolean;
13
+ readonly skipChild: boolean;
14
+ constructor(finished: boolean, skipChild: boolean);
15
+ }
16
+ export declare function createLoadMoreNode(node: FtTreeNode): FtTreeNode;
17
+ export declare function traverseVisibleTree(nodes: FtTreeNode[], callback: (node: FtTreeNode, depth: number, parent: FtTreeNode | null) => TraversalInstruction | void, parent?: FtTreeNode | null, depth?: number): boolean;
18
+ export declare function getPathToNode(root: FtTreeNode | FtTreeNode[], targetValue: string, path?: FtTreeNode[]): FtTreeNode[] | null;
@@ -0,0 +1,50 @@
1
+ export class TraversalInstruction {
2
+ constructor(finished, skipChild) {
3
+ this.finished = finished;
4
+ this.skipChild = skipChild;
5
+ }
6
+ }
7
+ export function createLoadMoreNode(node) {
8
+ return {
9
+ value: `load-more-${node.value}`,
10
+ label: "Load more",
11
+ children: []
12
+ };
13
+ }
14
+ export function traverseVisibleTree(nodes, callback, parent = null, depth = 0) {
15
+ var _a;
16
+ for (const node of nodes) {
17
+ const instruction = callback(node, depth, parent);
18
+ if (instruction === null || instruction === void 0 ? void 0 : instruction.finished) {
19
+ return true;
20
+ }
21
+ if (!(instruction === null || instruction === void 0 ? void 0 : instruction.skipChild) && ((_a = node.children) === null || _a === void 0 ? void 0 : _a.length)) {
22
+ const finished = traverseVisibleTree(node.children.slice(0, node.loadedCount), callback, node, depth + 1);
23
+ if (finished) {
24
+ return true;
25
+ }
26
+ if (node.loadedCount && (node.loadedCount < node.children.length)) {
27
+ let loadMoreNode = createLoadMoreNode(node);
28
+ callback(loadMoreNode, depth + 1, parent);
29
+ }
30
+ }
31
+ }
32
+ return false;
33
+ }
34
+ export function getPathToNode(root, targetValue, path = []) {
35
+ var _a;
36
+ const nodes = Array.isArray(root) ? root : [root];
37
+ for (const node of nodes) {
38
+ const newPath = [...path, node];
39
+ if (node.value === targetValue) {
40
+ return newPath;
41
+ }
42
+ if ((_a = node.children) === null || _a === void 0 ? void 0 : _a.length) {
43
+ const result = getPathToNode(node.children, targetValue, newPath);
44
+ if (result) {
45
+ return result;
46
+ }
47
+ }
48
+ }
49
+ return null;
50
+ }
package/package.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "@fluid-topics/ft-tree-list",
3
+ "version": "1.2.67",
4
+ "description": "A tree list component",
5
+ "keywords": [
6
+ "Lit"
7
+ ],
8
+ "author": "Fluid Topics <devtopics@antidot.net>",
9
+ "license": "ISC",
10
+ "main": "build/index.js",
11
+ "web": "build/ft-tree-list.min.js",
12
+ "typings": "build/index",
13
+ "files": [
14
+ "build/**/*.js",
15
+ "build/**/*.ts"
16
+ ],
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "ssh://git@scm.mrs.antidot.net:2222/fluidtopics/ft-web-components.git"
20
+ },
21
+ "dependencies": {
22
+ "@fluid-topics/design-system-variables": "0.1.99",
23
+ "@fluid-topics/ft-assets": "1.2.67",
24
+ "@fluid-topics/ft-wc-utils": "1.2.67",
25
+ "lit": "3.1.0"
26
+ },
27
+ "devDependencies": {
28
+ "@fluid-topics/ft-wc-test-utils": "1.2.67"
29
+ },
30
+ "gitHead": "883c4eaa2ce2d80befa30df7781a2cc5f547260f"
31
+ }