kempo-ui 0.0.67 → 0.0.69
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/components/ShadowComponent.js +1 -1
- package/dist/components/Tree.js +10 -16
- package/docs/components/accordion.html +1 -1
- package/docs/components/card.html +1 -1
- package/docs/components/color-picker.html +1 -1
- package/docs/components/content-slider.html +1 -1
- package/docs/components/dialog.html +1 -1
- package/docs/components/dropdown.html +1 -1
- package/docs/components/focus-capture.html +1 -1
- package/docs/components/html-editor.html +1 -1
- package/docs/components/hybrid-component.html +1 -1
- package/docs/components/icon.html +1 -1
- package/docs/components/import.html +1 -1
- package/docs/components/light-component.html +1 -1
- package/docs/components/photo-viewer.html +1 -1
- package/docs/components/resize.html +1 -1
- package/docs/components/shadow-component.html +1 -1
- package/docs/components/show-more.html +1 -1
- package/docs/components/side-menu.html +1 -1
- package/docs/components/side-panel-basic.html +1 -1
- package/docs/components/side-panel-dual.html +1 -1
- package/docs/components/side-panel-menu.html +1 -1
- package/docs/components/side-panel-persistent.html +1 -1
- package/docs/components/side-panel-scroll.html +1 -1
- package/docs/components/side-panel.html +1 -1
- package/docs/components/sortable.html +1 -1
- package/docs/components/spinner.html +1 -1
- package/docs/components/split.html +1 -1
- package/docs/components/table.html +1 -1
- package/docs/components/tableControls.html +1 -1
- package/docs/components/tableCustomFields.html +1 -1
- package/docs/components/tableFetchRecords.html +1 -1
- package/docs/components/tableFieldSortHide.html +1 -1
- package/docs/components/tablePagination.html +1 -1
- package/docs/components/tableRecordEditing.html +1 -1
- package/docs/components/tableRecordFiltering.html +1 -1
- package/docs/components/tableRecordHiding.html +1 -1
- package/docs/components/tableRecordSearching.html +1 -1
- package/docs/components/tableRecordSelection.html +1 -1
- package/docs/components/tableRowControls.html +1 -1
- package/docs/components/tableSorting.html +1 -1
- package/docs/components/tabs.html +1 -1
- package/docs/components/tags.html +1 -1
- package/docs/components/theme-switcher.html +1 -1
- package/docs/components/timestamp.html +1 -1
- package/docs/components/toast.html +1 -1
- package/docs/components/toggle.html +19 -1
- package/docs/components/tree.html +197 -30
- package/docs/index.html +1 -1
- package/docs/src/components/ShadowComponent.js +1 -1
- package/docs/src/components/Tree.js +10 -16
- package/docs/utils/context.html +1 -1
- package/docs/utils/cookie.html +1 -1
- package/docs/utils/debounce.html +1 -1
- package/docs/utils/drag.html +1 -1
- package/docs/utils/formatTimestamp.html +1 -1
- package/docs/utils/object.html +1 -1
- package/docs/utils/propConverters.html +1 -1
- package/docs/utils/string.html +1 -1
- package/docs/utils/theme.html +1 -1
- package/docs/utils/toTitleCase.html +1 -1
- package/docs/utils/type.html +1 -1
- package/docs/utils/wait.html +1 -1
- package/package.json +5 -1
- package/src/components/ShadowComponent.js +1 -1
- package/src/components/Toggle.js +2 -0
- package/src/components/Tree.js +95 -137
- package/tests/components/Toggle.browser-test.js +31 -0
- package/tests/components/Tree.browser-test.js +161 -161
- package/tools/highlight.js +51 -0
package/src/components/Tree.js
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
|
-
import ShadowComponent from './ShadowComponent.js';
|
|
2
|
-
import { html, css
|
|
1
|
+
import ShadowComponent from './ShadowComponent.js';
|
|
2
|
+
import { html, css } from '../lit-all.min.js';
|
|
3
3
|
import { boolExists } from '../utils/propConverters.js';
|
|
4
4
|
import './Icon.js';
|
|
5
5
|
|
|
6
|
+
let nodeTagCounter = 0;
|
|
7
|
+
|
|
6
8
|
export default class Tree extends ShadowComponent {
|
|
7
9
|
/* Properties */
|
|
8
10
|
static properties = {
|
|
9
11
|
data: { type: Object },
|
|
10
12
|
depth: { type: Number, reflect: true },
|
|
11
13
|
editable: { type: Boolean, converter: boolExists, attribute: 'editable', reflect: true }
|
|
12
|
-
}
|
|
14
|
+
};
|
|
13
15
|
|
|
14
16
|
constructor(){
|
|
15
17
|
super();
|
|
@@ -20,129 +22,129 @@ export default class Tree extends ShadowComponent {
|
|
|
20
22
|
|
|
21
23
|
/* Rendering */
|
|
22
24
|
render(){
|
|
23
|
-
if(
|
|
24
|
-
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
if(typeof this.data === 'object' && this.data !== null){
|
|
25
|
+
if(this.data === null || this.data === undefined) return html`<slot></slot>`;
|
|
26
|
+
if(Tree.nodes.find(n => n.detect(this.data))){
|
|
28
27
|
return html`
|
|
29
28
|
<div class="tree-root">
|
|
30
|
-
${
|
|
31
|
-
? this.data.map((v, i) => [i, v])
|
|
32
|
-
: Object.entries(this.data)
|
|
33
|
-
).map(([key, value]) => Tree.renderValue(value, key, 1, this.depth))}
|
|
29
|
+
${Tree.renderValue(this.data, null, 0, this.depth)}
|
|
34
30
|
</div>
|
|
35
31
|
`;
|
|
36
32
|
}
|
|
37
|
-
|
|
33
|
+
const entries = Array.isArray(this.data)
|
|
34
|
+
? this.data.map((v, i) => [i, v])
|
|
35
|
+
: typeof this.data === 'object'
|
|
36
|
+
? Object.entries(this.data)
|
|
37
|
+
: null;
|
|
38
38
|
return html`
|
|
39
39
|
<div class="tree-root">
|
|
40
|
-
${
|
|
40
|
+
${entries
|
|
41
|
+
? entries.map(([key, value]) => Tree.renderValue(value, key, 1, this.depth))
|
|
42
|
+
: Tree.renderValue(this.data, null, 0, this.depth)}
|
|
41
43
|
</div>
|
|
42
44
|
`;
|
|
43
45
|
}
|
|
44
46
|
|
|
45
|
-
/*
|
|
46
|
-
static
|
|
47
|
+
/* Node Registry */
|
|
48
|
+
static nodes = [];
|
|
47
49
|
|
|
48
|
-
static
|
|
49
|
-
|
|
50
|
+
static addNode = (...nodes) => {
|
|
51
|
+
[...nodes].reverse().forEach(node => {
|
|
52
|
+
if(!Object.prototype.hasOwnProperty.call(node, 'nodeTag')){
|
|
53
|
+
node.nodeTag = `k-tree-node-${nodeTagCounter++}`;
|
|
54
|
+
window.customElements.define(node.nodeTag, node);
|
|
55
|
+
}
|
|
56
|
+
Tree.nodes.unshift(node);
|
|
57
|
+
});
|
|
50
58
|
};
|
|
51
59
|
|
|
52
60
|
/* Static Methods */
|
|
53
|
-
static renderValue(value, key = null,
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
keyLabel.className = typeof key === 'number' ? 'tc-muted' : '';
|
|
62
|
-
keyLabel.textContent = `${key}: `;
|
|
63
|
-
wrapper.appendChild(keyLabel);
|
|
64
|
-
}
|
|
65
|
-
const leaf = new LeafClass(value);
|
|
66
|
-
const rendered = leaf.render();
|
|
67
|
-
if(rendered instanceof Node){
|
|
68
|
-
wrapper.appendChild(rendered);
|
|
69
|
-
} else {
|
|
70
|
-
const span = document.createElement('span');
|
|
71
|
-
render(rendered, span);
|
|
72
|
-
wrapper.appendChild(span);
|
|
73
|
-
}
|
|
74
|
-
return wrapper;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
if(typeof value === 'object' && value !== null){
|
|
78
|
-
const branch = new TreeBranch();
|
|
79
|
-
branch.value = value;
|
|
80
|
-
branch.key = key;
|
|
81
|
-
branch.currentDepth = currentDepth;
|
|
82
|
-
branch.maxDepth = maxDepth;
|
|
83
|
-
return branch;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
return html`<span class="d-b primitive">${key !== null ? html`<span class="${typeof key === 'number' ? 'tc-muted' : ''}">${key}: </span>` : ''}${value}</span>`;
|
|
61
|
+
static renderValue(value, key = null, depth = 0, maxDepth = 0){
|
|
62
|
+
const NodeClass = Tree.nodes.find(n => n.detect(value)) ?? TreeNode;
|
|
63
|
+
const el = document.createElement(NodeClass.nodeTag);
|
|
64
|
+
el.value = value;
|
|
65
|
+
el.key = key;
|
|
66
|
+
el.depth = depth;
|
|
67
|
+
el.maxDepth = maxDepth;
|
|
68
|
+
return el;
|
|
87
69
|
}
|
|
88
70
|
}
|
|
89
71
|
|
|
90
72
|
window.customElements.define('k-tree', Tree);
|
|
91
73
|
|
|
92
|
-
export class
|
|
74
|
+
export class TreeNode extends ShadowComponent {
|
|
75
|
+
static nodeTag = 'k-tree-node';
|
|
76
|
+
|
|
93
77
|
/* Properties */
|
|
94
78
|
static properties = {
|
|
95
79
|
value: { type: Object },
|
|
96
|
-
key: {
|
|
97
|
-
|
|
80
|
+
key: { attribute: false },
|
|
81
|
+
depth: { type: Number },
|
|
98
82
|
maxDepth: { type: Number },
|
|
99
|
-
opened: { type: Boolean, converter: boolExists, reflect: true }
|
|
83
|
+
opened: { type: Boolean, converter: boolExists, reflect: true },
|
|
84
|
+
icon: { type: String }
|
|
100
85
|
};
|
|
101
86
|
|
|
102
87
|
constructor(){
|
|
103
88
|
super();
|
|
104
89
|
this.value = null;
|
|
105
90
|
this.key = null;
|
|
106
|
-
this.
|
|
91
|
+
this.depth = 0;
|
|
107
92
|
this.maxDepth = 0;
|
|
108
93
|
this.opened = false;
|
|
94
|
+
this.icon = null;
|
|
109
95
|
}
|
|
110
96
|
|
|
111
97
|
/* Lifecycle */
|
|
112
98
|
connectedCallback(){
|
|
113
99
|
super.connectedCallback();
|
|
114
|
-
if(this.
|
|
115
|
-
this.opened = true;
|
|
116
|
-
}
|
|
100
|
+
if(this.depth <= this.maxDepth) this.opened = true;
|
|
117
101
|
}
|
|
118
102
|
|
|
119
103
|
/* Members */
|
|
120
|
-
get tree(){
|
|
121
|
-
return this.closest('k-tree');
|
|
122
|
-
}
|
|
104
|
+
get tree(){ return this.closest('k-tree'); }
|
|
123
105
|
|
|
124
106
|
/* Event Handlers */
|
|
125
|
-
toggle = () => {
|
|
126
|
-
this.opened = !this.opened;
|
|
127
|
-
};
|
|
107
|
+
toggle = () => { this.opened = !this.opened; };
|
|
128
108
|
|
|
129
109
|
/* Rendering */
|
|
110
|
+
renderLabel(){
|
|
111
|
+
if(typeof this.value === 'object' && this.value !== null){
|
|
112
|
+
return html`${Array.isArray(this.value) ? 'Array' : 'Object'}`;
|
|
113
|
+
}
|
|
114
|
+
return html`${this.value}`;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
getChildren(){
|
|
118
|
+
if(typeof this.value !== 'object' || this.value === null) return null;
|
|
119
|
+
return Array.isArray(this.value)
|
|
120
|
+
? this.value.map((v, i) => [i, v])
|
|
121
|
+
: Object.entries(this.value);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
renderIcon(){
|
|
125
|
+
if(this.icon) return html`<k-icon name="${this.icon}"></k-icon>`;
|
|
126
|
+
return html`<k-icon name="chevron" class="toggle-icon" direction="${this.opened ? 'down' : 'right'}"></k-icon>`;
|
|
127
|
+
}
|
|
128
|
+
|
|
130
129
|
render(){
|
|
131
|
-
const
|
|
132
|
-
const
|
|
130
|
+
const children = this.getChildren();
|
|
131
|
+
const keyLabel = this.key !== null
|
|
132
|
+
? html`<span class="${typeof this.key === 'number' ? 'tc-muted' : ''}">${this.key}: </span>`
|
|
133
|
+
: '';
|
|
134
|
+
|
|
135
|
+
if(!children){
|
|
136
|
+
return html`<span class="d-b">${keyLabel}${this.renderLabel()}</span>`;
|
|
137
|
+
}
|
|
133
138
|
|
|
134
139
|
return html`
|
|
135
140
|
<div>
|
|
136
141
|
<button class="branch-label no-btn" @click=${this.toggle} aria-expanded="${this.opened}">
|
|
137
|
-
|
|
138
|
-
${
|
|
142
|
+
${this.renderIcon()}
|
|
143
|
+
${keyLabel}${this.renderLabel()}
|
|
139
144
|
</button>
|
|
140
145
|
${this.opened ? html`
|
|
141
146
|
<div class="pl">
|
|
142
|
-
${
|
|
143
|
-
? this.value.map((v, i) => [i, v])
|
|
144
|
-
: Object.entries(this.value)
|
|
145
|
-
).map(([key, value]) => Tree.renderValue(value, key, this.currentDepth + 1, this.maxDepth)) : ''}
|
|
147
|
+
${children.map(([k, v]) => Tree.renderValue(v, k, this.depth + 1, this.maxDepth))}
|
|
146
148
|
</div>
|
|
147
149
|
` : ''}
|
|
148
150
|
</div>
|
|
@@ -164,81 +166,37 @@ export class TreeBranch extends ShadowComponent {
|
|
|
164
166
|
.branch-label:focus-visible{
|
|
165
167
|
box-shadow: var(--focus_shadow);
|
|
166
168
|
}
|
|
167
|
-
.toggle-icon{
|
|
168
|
-
transition: transform var(--animation_ms, 200ms);
|
|
169
|
-
}
|
|
170
|
-
.toggle-icon.opened{
|
|
171
|
-
transform: rotate(90deg);
|
|
172
|
-
}
|
|
173
169
|
`;
|
|
174
|
-
}
|
|
175
170
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
export class TreeLeaf {
|
|
179
|
-
constructor(value = null){
|
|
180
|
-
this.value = value;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
/* Rendering */
|
|
184
|
-
render(){
|
|
185
|
-
return html`${this.value}`;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
/* Static Methods */
|
|
189
|
-
static detect = () => {
|
|
190
|
-
return false;
|
|
191
|
-
};
|
|
171
|
+
static detect = () => false;
|
|
192
172
|
}
|
|
193
173
|
|
|
194
|
-
|
|
195
|
-
/* Rendering */
|
|
196
|
-
render(){
|
|
197
|
-
return html`<span class="tc-success">"${this.value}"</span>`;
|
|
198
|
-
}
|
|
174
|
+
window.customElements.define('k-tree-node', TreeNode);
|
|
199
175
|
|
|
200
|
-
|
|
201
|
-
|
|
176
|
+
export class StringNode extends TreeNode {
|
|
177
|
+
renderLabel(){ return html`<span class="tc-success">"${this.value}"</span>`; }
|
|
178
|
+
static detect = v => typeof v === 'string';
|
|
202
179
|
}
|
|
203
180
|
|
|
204
|
-
export class
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
return html`<span class="tc-primary">${this.value}</span>`;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
/* Static Methods */
|
|
211
|
-
static detect = value => typeof value === 'number';
|
|
181
|
+
export class NumberNode extends TreeNode {
|
|
182
|
+
renderLabel(){ return html`<span class="tc-primary">${this.value}</span>`; }
|
|
183
|
+
static detect = v => typeof v === 'number';
|
|
212
184
|
}
|
|
213
185
|
|
|
214
|
-
export class
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
return html`<span class="${this.value ? 'tc-success' : 'tc-danger'}">${this.value}</span>`;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
/* Static Methods */
|
|
221
|
-
static detect = value => typeof value === 'boolean';
|
|
186
|
+
export class BooleanNode extends TreeNode {
|
|
187
|
+
renderLabel(){ return html`<span class="${this.value ? 'tc-success' : 'tc-danger'}">${this.value}</span>`; }
|
|
188
|
+
static detect = v => typeof v === 'boolean';
|
|
222
189
|
}
|
|
223
190
|
|
|
224
|
-
export class
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
return html`<span class="tc-muted">null</span>`;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
/* Static Methods */
|
|
231
|
-
static detect = value => value === null;
|
|
191
|
+
export class NullNode extends TreeNode {
|
|
192
|
+
renderLabel(){ return html`<span class="tc-muted">null</span>`; }
|
|
193
|
+
static detect = v => v === null;
|
|
232
194
|
}
|
|
233
195
|
|
|
234
|
-
export class
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
return html`<span class="tc-muted">undefined</span>`;
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
/* Static Methods */
|
|
241
|
-
static detect = value => value === undefined;
|
|
196
|
+
export class UndefinedNode extends TreeNode {
|
|
197
|
+
renderLabel(){ return html`<span class="tc-muted">undefined</span>`; }
|
|
198
|
+
static detect = v => v === undefined;
|
|
242
199
|
}
|
|
243
200
|
|
|
244
|
-
Tree.
|
|
201
|
+
Tree.addNode(StringNode, NumberNode, BooleanNode, NullNode, UndefinedNode);
|
|
202
|
+
|
|
@@ -512,6 +512,37 @@ export default {
|
|
|
512
512
|
pass('Label content projected');
|
|
513
513
|
},
|
|
514
514
|
|
|
515
|
+
'switch should not shrink in constrained container': async ({pass, fail}) => {
|
|
516
|
+
const { container, toggle } = await createToggle();
|
|
517
|
+
container.style.width = '100px';
|
|
518
|
+
await toggle.updateComplete;
|
|
519
|
+
const switchEl = toggle.shadowRoot.querySelector('#switch');
|
|
520
|
+
const style = window.getComputedStyle(switchEl);
|
|
521
|
+
if(style.flexShrink !== '0'){
|
|
522
|
+
cleanup(container);
|
|
523
|
+
return fail(`Expected switch flex-shrink to be 0, got ${style.flexShrink}`);
|
|
524
|
+
}
|
|
525
|
+
if(style.flexGrow !== '0'){
|
|
526
|
+
cleanup(container);
|
|
527
|
+
return fail(`Expected switch flex-grow to be 0, got ${style.flexGrow}`);
|
|
528
|
+
}
|
|
529
|
+
cleanup(container);
|
|
530
|
+
pass('Switch does not shrink in constrained container');
|
|
531
|
+
},
|
|
532
|
+
|
|
533
|
+
'label should shrink in constrained container': async ({pass, fail}) => {
|
|
534
|
+
const { container, toggle } = await createToggle();
|
|
535
|
+
await toggle.updateComplete;
|
|
536
|
+
const label = toggle.shadowRoot.querySelector('#label');
|
|
537
|
+
const style = window.getComputedStyle(label);
|
|
538
|
+
if(style.flexGrow !== '1'){
|
|
539
|
+
cleanup(container);
|
|
540
|
+
return fail(`Expected label flex-grow to be 1, got ${style.flexGrow}`);
|
|
541
|
+
}
|
|
542
|
+
cleanup(container);
|
|
543
|
+
pass('Label grows to fill remaining space');
|
|
544
|
+
},
|
|
545
|
+
|
|
515
546
|
/*
|
|
516
547
|
Method Chaining
|
|
517
548
|
*/
|