-
Notifications
You must be signed in to change notification settings - Fork 2
/
cosmoz-treenode.js
156 lines (146 loc) · 3.33 KB
/
cosmoz-treenode.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
import { component, html } from '@pionjs/pion';
export const computePathToRender = (path, hideFromRoot, showMaxNodes) => {
if (!path) {
return;
}
let pathToRender = path;
if (hideFromRoot > 0 && path.length > hideFromRoot) {
pathToRender = path.slice(hideFromRoot);
}
if (showMaxNodes > 0 && pathToRender.length > showMaxNodes) {
pathToRender = path.slice(-showMaxNodes);
}
return pathToRender;
},
/**
* Walks the path array from the end until an undefined part is found
* to make sure no unknown parts are present.
* @param {Array} inputPath Array of path parts
* @returns {Array} Array with defined parts
*/
getKnownPath = (inputPath) => {
let path = inputPath;
if (!Array.isArray(path) || path.length === 0) {
return path;
}
for (let i = path.length - 1; i >= 0; i--) {
if (path[i] === undefined) {
path.splice(0, i + 1);
if (path.length === 0) {
path = null;
}
break;
}
}
return path;
},
computePath = (ownerTree, keyProperty, keyValue) => {
// HACK(pasleq): Cosmoz.Tree API needs to be fixed to avoid such code in components
let path = null;
if (!ownerTree || keyProperty == null || keyValue === undefined) {
return;
}
if (keyProperty === 'pathLocator') {
path = ownerTree.getPathNodes(keyValue);
} else {
const node = ownerTree.getNodeByProperty(keyValue, keyProperty);
if (node && node.pathLocator) {
path = ownerTree.getPathNodes(node.pathLocator);
}
}
return getKnownPath(path);
},
computePathText = ({
ownerTree,
ellipsis,
pathToRender,
path,
valueProperty,
pathSeparator,
}) => {
if (!pathToRender) {
return '';
}
const stringParts = pathToRender.map((node) =>
ownerTree.getProperty(node, valueProperty)
);
let text = stringParts.join(pathSeparator);
if (pathToRender.length < path.length) {
text = ellipsis + text;
}
return text;
},
render = ({ title, text }) => html`
<style>
:host {
display: block;
}
:host([no-wrap]) {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
direction: rtl;
}
/* Safari only css fix */
@media not all and (min-resolution: 0.001dpcm) {
@supports (-webkit-appearance: none) {
:host span {
display: inline-block;
}
}
}
</style>
<span title=${title}>‎${text}</span>
`,
Treenode = ({
valueProperty = 'name',
pathSeparator = ' / ',
hideFromRoot = 0,
showMaxNodes = 0,
keyProperty,
keyValue,
ownerTree,
ellipsis = '… / ',
fallback,
}) => {
const path = computePath(ownerTree, keyProperty, keyValue);
if (!path) return render({ text: fallback, title: fallback });
const pathToRender = computePathToRender(path, hideFromRoot, showMaxNodes),
opts = {
ownerTree,
ellipsis,
path,
valueProperty,
pathSeparator,
};
return render({
text: computePathText({
...opts,
pathToRender,
}),
title: computePathText({
...opts,
pathToRender: path,
}),
});
};
/**
* `cosmoz-treenode` is a component to display a node in a `cosmoz-tree` data structure
* @polymer
* @customElement
* @demo demo/index.html
*/
customElements.define(
'cosmoz-treenode',
component(Treenode, {
observedAttributes: [
'key-property',
'key-value',
'value-property',
'path-separator',
'hide-from-root',
'show-max-nodes',
'fallback',
],
})
);