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.
Files changed (70) hide show
  1. package/dist/components/ShadowComponent.js +1 -1
  2. package/dist/components/Tree.js +10 -16
  3. package/docs/components/accordion.html +1 -1
  4. package/docs/components/card.html +1 -1
  5. package/docs/components/color-picker.html +1 -1
  6. package/docs/components/content-slider.html +1 -1
  7. package/docs/components/dialog.html +1 -1
  8. package/docs/components/dropdown.html +1 -1
  9. package/docs/components/focus-capture.html +1 -1
  10. package/docs/components/html-editor.html +1 -1
  11. package/docs/components/hybrid-component.html +1 -1
  12. package/docs/components/icon.html +1 -1
  13. package/docs/components/import.html +1 -1
  14. package/docs/components/light-component.html +1 -1
  15. package/docs/components/photo-viewer.html +1 -1
  16. package/docs/components/resize.html +1 -1
  17. package/docs/components/shadow-component.html +1 -1
  18. package/docs/components/show-more.html +1 -1
  19. package/docs/components/side-menu.html +1 -1
  20. package/docs/components/side-panel-basic.html +1 -1
  21. package/docs/components/side-panel-dual.html +1 -1
  22. package/docs/components/side-panel-menu.html +1 -1
  23. package/docs/components/side-panel-persistent.html +1 -1
  24. package/docs/components/side-panel-scroll.html +1 -1
  25. package/docs/components/side-panel.html +1 -1
  26. package/docs/components/sortable.html +1 -1
  27. package/docs/components/spinner.html +1 -1
  28. package/docs/components/split.html +1 -1
  29. package/docs/components/table.html +1 -1
  30. package/docs/components/tableControls.html +1 -1
  31. package/docs/components/tableCustomFields.html +1 -1
  32. package/docs/components/tableFetchRecords.html +1 -1
  33. package/docs/components/tableFieldSortHide.html +1 -1
  34. package/docs/components/tablePagination.html +1 -1
  35. package/docs/components/tableRecordEditing.html +1 -1
  36. package/docs/components/tableRecordFiltering.html +1 -1
  37. package/docs/components/tableRecordHiding.html +1 -1
  38. package/docs/components/tableRecordSearching.html +1 -1
  39. package/docs/components/tableRecordSelection.html +1 -1
  40. package/docs/components/tableRowControls.html +1 -1
  41. package/docs/components/tableSorting.html +1 -1
  42. package/docs/components/tabs.html +1 -1
  43. package/docs/components/tags.html +1 -1
  44. package/docs/components/theme-switcher.html +1 -1
  45. package/docs/components/timestamp.html +1 -1
  46. package/docs/components/toast.html +1 -1
  47. package/docs/components/toggle.html +19 -1
  48. package/docs/components/tree.html +197 -30
  49. package/docs/index.html +1 -1
  50. package/docs/src/components/ShadowComponent.js +1 -1
  51. package/docs/src/components/Tree.js +10 -16
  52. package/docs/utils/context.html +1 -1
  53. package/docs/utils/cookie.html +1 -1
  54. package/docs/utils/debounce.html +1 -1
  55. package/docs/utils/drag.html +1 -1
  56. package/docs/utils/formatTimestamp.html +1 -1
  57. package/docs/utils/object.html +1 -1
  58. package/docs/utils/propConverters.html +1 -1
  59. package/docs/utils/string.html +1 -1
  60. package/docs/utils/theme.html +1 -1
  61. package/docs/utils/toTitleCase.html +1 -1
  62. package/docs/utils/type.html +1 -1
  63. package/docs/utils/wait.html +1 -1
  64. package/package.json +5 -1
  65. package/src/components/ShadowComponent.js +1 -1
  66. package/src/components/Toggle.js +2 -0
  67. package/src/components/Tree.js +95 -137
  68. package/tests/components/Toggle.browser-test.js +31 -0
  69. package/tests/components/Tree.browser-test.js +161 -161
  70. package/tools/highlight.js +51 -0
@@ -1,4 +1,4 @@
1
- import Tree, { TreeBranch, TreeLeaf, StringLeaf, NumberLeaf, BooleanLeaf, NullLeaf, UndefinedLeaf } from '../../src/components/Tree.js';
1
+ import Tree, { TreeNode, StringNode, NumberNode, BooleanNode, NullNode, UndefinedNode } from '../../src/components/Tree.js';
2
2
 
3
3
  const createTree = async (options = {}) => {
4
4
  const container = document.createElement('div');
@@ -158,7 +158,7 @@ export default {
158
158
  const data = { outer: { inner: 'value' } };
159
159
  const { container, tree } = await createTree({ data });
160
160
  await tree.updateComplete;
161
- const branches = tree.shadowRoot.querySelectorAll('k-tree-branch');
161
+ const branches = tree.shadowRoot.querySelectorAll('k-tree-node');
162
162
  if(branches.length < 1){
163
163
  cleanup(container);
164
164
  return fail('Nested objects should create tree branches');
@@ -177,40 +177,40 @@ export default {
177
177
  pass('Tree has static renderValue method');
178
178
  },
179
179
 
180
- 'should have static addLeaf method': async ({pass, fail}) => {
181
- if(typeof Tree.addLeaf !== 'function'){
182
- return fail('Tree should have static addLeaf method');
180
+ 'should have static addNode method': async ({pass, fail}) => {
181
+ if(typeof Tree.addNode !== 'function'){
182
+ return fail('Tree should have static addNode method');
183
183
  }
184
- pass('Tree has static addLeaf method');
184
+ pass('Tree has static addNode method');
185
185
  },
186
186
 
187
187
  'should have leafs array': async ({pass, fail}) => {
188
- if(!Array.isArray(Tree.leafs)){
188
+ if(!Array.isArray(Tree.nodes)){
189
189
  return fail('Tree should have leafs array');
190
190
  }
191
191
  pass('Tree has leafs array');
192
192
  },
193
193
 
194
194
  /*
195
- TreeBranch Tests
195
+ TreeNode Tests
196
196
  */
197
- 'TreeBranch should be exported': async ({pass, fail}) => {
198
- if(typeof TreeBranch !== 'function'){
199
- return fail('TreeBranch should be exported');
197
+ 'TreeNode should be exported': async ({pass, fail}) => {
198
+ if(typeof TreeNode !== 'function'){
199
+ return fail('TreeNode should be exported');
200
200
  }
201
- pass('TreeBranch is exported');
201
+ pass('TreeNode is exported');
202
202
  },
203
203
 
204
- 'TreeBranch should have default properties': async ({pass, fail}) => {
205
- const branch = new TreeBranch();
204
+ 'TreeNode should have default properties': async ({pass, fail}) => {
205
+ const branch = new TreeNode();
206
206
  if(branch.value !== null){
207
207
  return fail(`Expected value to be null, got ${branch.value}`);
208
208
  }
209
209
  if(branch.key !== null){
210
210
  return fail(`Expected key to be null, got ${branch.key}`);
211
211
  }
212
- if(branch.currentDepth !== 0){
213
- return fail(`Expected currentDepth to be 0, got ${branch.currentDepth}`);
212
+ if(branch.depth !== 0){
213
+ return fail(`Expected depth to be 0, got ${branch.depth}`);
214
214
  }
215
215
  if(branch.maxDepth !== 0){
216
216
  return fail(`Expected maxDepth to be 0, got ${branch.maxDepth}`);
@@ -218,22 +218,22 @@ export default {
218
218
  if(branch.opened !== false){
219
219
  return fail(`Expected opened to be false, got ${branch.opened}`);
220
220
  }
221
- pass('TreeBranch has default properties');
221
+ pass('TreeNode has default properties');
222
222
  },
223
223
 
224
- 'TreeBranch should have toggle method': async ({pass, fail}) => {
225
- const branch = new TreeBranch();
224
+ 'TreeNode should have toggle method': async ({pass, fail}) => {
225
+ const branch = new TreeNode();
226
226
  if(typeof branch.toggle !== 'function'){
227
- return fail('TreeBranch should have toggle method');
227
+ return fail('TreeNode should have toggle method');
228
228
  }
229
- pass('TreeBranch has toggle method');
229
+ pass('TreeNode has toggle method');
230
230
  },
231
231
 
232
- 'TreeBranch toggle should change opened state': async ({pass, fail}) => {
232
+ 'TreeNode toggle should change opened state': async ({pass, fail}) => {
233
233
  const data = { nested: { value: 1 } };
234
234
  const { container, tree } = await createTree({ data });
235
235
  await tree.updateComplete;
236
- const branch = tree.shadowRoot.querySelector('k-tree-branch');
236
+ const branch = tree.shadowRoot.querySelector('k-tree-node');
237
237
  if(!branch){
238
238
  cleanup(container);
239
239
  return fail('Branch should exist');
@@ -246,14 +246,14 @@ export default {
246
246
  return fail('toggle should change opened state');
247
247
  }
248
248
  cleanup(container);
249
- pass('TreeBranch toggle changes opened state');
249
+ pass('TreeNode toggle changes opened state');
250
250
  },
251
251
 
252
- 'TreeBranch should auto-open when depth allows': async ({pass, fail}) => {
252
+ 'TreeNode should auto-open when depth allows': async ({pass, fail}) => {
253
253
  const data = { nested: { value: 1 } };
254
254
  const { container, tree } = await createTree({ data, depth: 1 });
255
255
  await tree.updateComplete;
256
- const branch = tree.shadowRoot.querySelector('k-tree-branch');
256
+ const branch = tree.shadowRoot.querySelector('k-tree-node');
257
257
  if(!branch){
258
258
  cleanup(container);
259
259
  return fail('Branch should exist');
@@ -264,33 +264,33 @@ export default {
264
264
  return fail('Branch should be auto-opened when depth allows');
265
265
  }
266
266
  cleanup(container);
267
- pass('TreeBranch auto-opens when depth allows');
267
+ pass('TreeNode auto-opens when depth allows');
268
268
  },
269
269
 
270
- 'TreeBranch should respect depth for nested branches': async ({pass, fail}) => {
270
+ 'TreeNode should respect depth for nested branches': async ({pass, fail}) => {
271
271
  const data = { level1: { level2: { level3: 'value' } } };
272
272
  const { container, tree } = await createTree({ data, depth: 1 });
273
273
  await tree.updateComplete;
274
- const branch = tree.shadowRoot.querySelector('k-tree-branch');
274
+ const branch = tree.shadowRoot.querySelector('k-tree-node');
275
275
  if(!branch){
276
276
  cleanup(container);
277
277
  return fail('Branch should exist');
278
278
  }
279
279
  await branch.updateComplete;
280
- // First level branch should be open (currentDepth 1 <= maxDepth 1)
280
+ // First level branch should be open (depth 1 <= maxDepth 1)
281
281
  if(branch.opened !== true){
282
282
  cleanup(container);
283
283
  return fail('First level branch should be open at depth 1');
284
284
  }
285
285
  cleanup(container);
286
- pass('TreeBranch respects depth settings');
286
+ pass('TreeNode respects depth settings');
287
287
  },
288
288
 
289
- 'TreeBranch should render toggle icon': async ({pass, fail}) => {
289
+ 'TreeNode should render toggle icon': async ({pass, fail}) => {
290
290
  const data = { nested: { value: 1 } };
291
291
  const { container, tree } = await createTree({ data, depth: 1 });
292
292
  await tree.updateComplete;
293
- const branch = tree.shadowRoot.querySelector('k-tree-branch');
293
+ const branch = tree.shadowRoot.querySelector('k-tree-node');
294
294
  if(!branch){
295
295
  cleanup(container);
296
296
  return fail('Branch should exist');
@@ -302,14 +302,14 @@ export default {
302
302
  return fail('Branch should render toggle icon');
303
303
  }
304
304
  cleanup(container);
305
- pass('TreeBranch renders toggle icon');
305
+ pass('TreeNode renders toggle icon');
306
306
  },
307
307
 
308
- 'TreeBranch should render branch label button': async ({pass, fail}) => {
308
+ 'TreeNode should render branch label button': async ({pass, fail}) => {
309
309
  const data = { nested: { value: 1 } };
310
310
  const { container, tree } = await createTree({ data, depth: 1 });
311
311
  await tree.updateComplete;
312
- const branch = tree.shadowRoot.querySelector('k-tree-branch');
312
+ const branch = tree.shadowRoot.querySelector('k-tree-node');
313
313
  if(!branch){
314
314
  cleanup(container);
315
315
  return fail('Branch should exist');
@@ -321,14 +321,14 @@ export default {
321
321
  return fail('Branch should render label button');
322
322
  }
323
323
  cleanup(container);
324
- pass('TreeBranch renders branch label button');
324
+ pass('TreeNode renders branch label button');
325
325
  },
326
326
 
327
- 'TreeBranch button click should toggle': async ({pass, fail}) => {
327
+ 'TreeNode button click should toggle': async ({pass, fail}) => {
328
328
  const data = { nested: { value: 1 } };
329
329
  const { container, tree } = await createTree({ data, depth: 0 });
330
330
  await tree.updateComplete;
331
- const branch = tree.shadowRoot.querySelector('k-tree-branch');
331
+ const branch = tree.shadowRoot.querySelector('k-tree-node');
332
332
  if(!branch){
333
333
  cleanup(container);
334
334
  return fail('Branch should exist');
@@ -343,192 +343,192 @@ export default {
343
343
  return fail('Button click should toggle opened');
344
344
  }
345
345
  cleanup(container);
346
- pass('TreeBranch button click toggles');
346
+ pass('TreeNode button click toggles');
347
347
  },
348
348
 
349
349
  /*
350
- TreeLeaf Tests
350
+ TreeNode Tests
351
351
  */
352
- 'TreeLeaf should be exported': async ({pass, fail}) => {
353
- if(typeof TreeLeaf !== 'function'){
354
- return fail('TreeLeaf should be exported');
352
+ 'TreeNode should be exported': async ({pass, fail}) => {
353
+ if(typeof TreeNode !== 'function'){
354
+ return fail('TreeNode should be exported');
355
355
  }
356
- pass('TreeLeaf is exported');
356
+ pass('TreeNode is exported');
357
357
  },
358
358
 
359
- 'TreeLeaf should store value': async ({pass, fail}) => {
360
- const leaf = new TreeLeaf('test');
359
+ 'TreeNode should store value': async ({pass, fail}) => {
360
+ const leaf = new TreeNode('test');
361
361
  if(leaf.value !== 'test'){
362
362
  return fail(`Expected value to be 'test', got ${leaf.value}`);
363
363
  }
364
- pass('TreeLeaf stores value');
364
+ pass('TreeNode stores value');
365
365
  },
366
366
 
367
- 'TreeLeaf should have render method': async ({pass, fail}) => {
368
- const leaf = new TreeLeaf('test');
367
+ 'TreeNode should have render method': async ({pass, fail}) => {
368
+ const leaf = new TreeNode('test');
369
369
  if(typeof leaf.render !== 'function'){
370
- return fail('TreeLeaf should have render method');
370
+ return fail('TreeNode should have render method');
371
371
  }
372
- pass('TreeLeaf has render method');
372
+ pass('TreeNode has render method');
373
373
  },
374
374
 
375
- 'TreeLeaf detect should return false': async ({pass, fail}) => {
376
- if(TreeLeaf.detect('any') !== false){
377
- return fail('TreeLeaf.detect should return false');
375
+ 'TreeNode detect should return false': async ({pass, fail}) => {
376
+ if(TreeNode.detect('any') !== false){
377
+ return fail('TreeNode.detect should return false');
378
378
  }
379
- pass('TreeLeaf.detect returns false');
379
+ pass('TreeNode.detect returns false');
380
380
  },
381
381
 
382
382
  /*
383
- StringLeaf Tests
383
+ StringNode Tests
384
384
  */
385
- 'StringLeaf should be exported': async ({pass, fail}) => {
386
- if(typeof StringLeaf !== 'function'){
387
- return fail('StringLeaf should be exported');
385
+ 'StringNode should be exported': async ({pass, fail}) => {
386
+ if(typeof StringNode !== 'function'){
387
+ return fail('StringNode should be exported');
388
388
  }
389
- pass('StringLeaf is exported');
389
+ pass('StringNode is exported');
390
390
  },
391
391
 
392
- 'StringLeaf should detect strings': async ({pass, fail}) => {
393
- if(StringLeaf.detect('hello') !== true){
394
- return fail('StringLeaf should detect strings');
392
+ 'StringNode should detect strings': async ({pass, fail}) => {
393
+ if(StringNode.detect('hello') !== true){
394
+ return fail('StringNode should detect strings');
395
395
  }
396
- if(StringLeaf.detect(123) !== false){
397
- return fail('StringLeaf should not detect non-strings');
396
+ if(StringNode.detect(123) !== false){
397
+ return fail('StringNode should not detect non-strings');
398
398
  }
399
- pass('StringLeaf detects strings correctly');
399
+ pass('StringNode detects strings correctly');
400
400
  },
401
401
 
402
- 'StringLeaf should render with quotes': async ({pass, fail}) => {
403
- const leaf = new StringLeaf('test');
402
+ 'StringNode should render with quotes': async ({pass, fail}) => {
403
+ const leaf = new StringNode('test');
404
404
  const rendered = leaf.render();
405
405
  // TemplateResult, check string representation
406
406
  if(!rendered || !rendered.strings){
407
- return fail('StringLeaf should return template result');
407
+ return fail('StringNode should return template result');
408
408
  }
409
- pass('StringLeaf renders correctly');
409
+ pass('StringNode renders correctly');
410
410
  },
411
411
 
412
412
  /*
413
- NumberLeaf Tests
413
+ NumberNode Tests
414
414
  */
415
- 'NumberLeaf should be exported': async ({pass, fail}) => {
416
- if(typeof NumberLeaf !== 'function'){
417
- return fail('NumberLeaf should be exported');
415
+ 'NumberNode should be exported': async ({pass, fail}) => {
416
+ if(typeof NumberNode !== 'function'){
417
+ return fail('NumberNode should be exported');
418
418
  }
419
- pass('NumberLeaf is exported');
419
+ pass('NumberNode is exported');
420
420
  },
421
421
 
422
- 'NumberLeaf should detect numbers': async ({pass, fail}) => {
423
- if(NumberLeaf.detect(42) !== true){
424
- return fail('NumberLeaf should detect numbers');
422
+ 'NumberNode should detect numbers': async ({pass, fail}) => {
423
+ if(NumberNode.detect(42) !== true){
424
+ return fail('NumberNode should detect numbers');
425
425
  }
426
- if(NumberLeaf.detect('42') !== false){
427
- return fail('NumberLeaf should not detect non-numbers');
426
+ if(NumberNode.detect('42') !== false){
427
+ return fail('NumberNode should not detect non-numbers');
428
428
  }
429
- pass('NumberLeaf detects numbers correctly');
429
+ pass('NumberNode detects numbers correctly');
430
430
  },
431
431
 
432
- 'NumberLeaf should render number value': async ({pass, fail}) => {
433
- const leaf = new NumberLeaf(42);
432
+ 'NumberNode should render number value': async ({pass, fail}) => {
433
+ const leaf = new NumberNode(42);
434
434
  const rendered = leaf.render();
435
435
  if(!rendered || !rendered.strings){
436
- return fail('NumberLeaf should return template result');
436
+ return fail('NumberNode should return template result');
437
437
  }
438
- pass('NumberLeaf renders correctly');
438
+ pass('NumberNode renders correctly');
439
439
  },
440
440
 
441
441
  /*
442
- BooleanLeaf Tests
442
+ BooleanNode Tests
443
443
  */
444
- 'BooleanLeaf should be exported': async ({pass, fail}) => {
445
- if(typeof BooleanLeaf !== 'function'){
446
- return fail('BooleanLeaf should be exported');
444
+ 'BooleanNode should be exported': async ({pass, fail}) => {
445
+ if(typeof BooleanNode !== 'function'){
446
+ return fail('BooleanNode should be exported');
447
447
  }
448
- pass('BooleanLeaf is exported');
448
+ pass('BooleanNode is exported');
449
449
  },
450
450
 
451
- 'BooleanLeaf should detect booleans': async ({pass, fail}) => {
452
- if(BooleanLeaf.detect(true) !== true){
453
- return fail('BooleanLeaf should detect true');
451
+ 'BooleanNode should detect booleans': async ({pass, fail}) => {
452
+ if(BooleanNode.detect(true) !== true){
453
+ return fail('BooleanNode should detect true');
454
454
  }
455
- if(BooleanLeaf.detect(false) !== true){
456
- return fail('BooleanLeaf should detect false');
455
+ if(BooleanNode.detect(false) !== true){
456
+ return fail('BooleanNode should detect false');
457
457
  }
458
- if(BooleanLeaf.detect('true') !== false){
459
- return fail('BooleanLeaf should not detect non-booleans');
458
+ if(BooleanNode.detect('true') !== false){
459
+ return fail('BooleanNode should not detect non-booleans');
460
460
  }
461
- pass('BooleanLeaf detects booleans correctly');
461
+ pass('BooleanNode detects booleans correctly');
462
462
  },
463
463
 
464
- 'BooleanLeaf should render boolean value': async ({pass, fail}) => {
465
- const leafTrue = new BooleanLeaf(true);
466
- const leafFalse = new BooleanLeaf(false);
464
+ 'BooleanNode should render boolean value': async ({pass, fail}) => {
465
+ const leafTrue = new BooleanNode(true);
466
+ const leafFalse = new BooleanNode(false);
467
467
  if(!leafTrue.render() || !leafFalse.render()){
468
- return fail('BooleanLeaf should return template result');
468
+ return fail('BooleanNode should return template result');
469
469
  }
470
- pass('BooleanLeaf renders correctly');
470
+ pass('BooleanNode renders correctly');
471
471
  },
472
472
 
473
473
  /*
474
- NullLeaf Tests
474
+ NullNode Tests
475
475
  */
476
- 'NullLeaf should be exported': async ({pass, fail}) => {
477
- if(typeof NullLeaf !== 'function'){
478
- return fail('NullLeaf should be exported');
476
+ 'NullNode should be exported': async ({pass, fail}) => {
477
+ if(typeof NullNode !== 'function'){
478
+ return fail('NullNode should be exported');
479
479
  }
480
- pass('NullLeaf is exported');
480
+ pass('NullNode is exported');
481
481
  },
482
482
 
483
- 'NullLeaf should detect null': async ({pass, fail}) => {
484
- if(NullLeaf.detect(null) !== true){
485
- return fail('NullLeaf should detect null');
483
+ 'NullNode should detect null': async ({pass, fail}) => {
484
+ if(NullNode.detect(null) !== true){
485
+ return fail('NullNode should detect null');
486
486
  }
487
- if(NullLeaf.detect(undefined) !== false){
488
- return fail('NullLeaf should not detect undefined');
487
+ if(NullNode.detect(undefined) !== false){
488
+ return fail('NullNode should not detect undefined');
489
489
  }
490
- if(NullLeaf.detect('null') !== false){
491
- return fail('NullLeaf should not detect strings');
490
+ if(NullNode.detect('null') !== false){
491
+ return fail('NullNode should not detect strings');
492
492
  }
493
- pass('NullLeaf detects null correctly');
493
+ pass('NullNode detects null correctly');
494
494
  },
495
495
 
496
- 'NullLeaf should render null text': async ({pass, fail}) => {
497
- const leaf = new NullLeaf(null);
496
+ 'NullNode should render null text': async ({pass, fail}) => {
497
+ const leaf = new NullNode(null);
498
498
  const rendered = leaf.render();
499
499
  if(!rendered || !rendered.strings){
500
- return fail('NullLeaf should return template result');
500
+ return fail('NullNode should return template result');
501
501
  }
502
- pass('NullLeaf renders correctly');
502
+ pass('NullNode renders correctly');
503
503
  },
504
504
 
505
505
  /*
506
- UndefinedLeaf Tests
506
+ UndefinedNode Tests
507
507
  */
508
- 'UndefinedLeaf should be exported': async ({pass, fail}) => {
509
- if(typeof UndefinedLeaf !== 'function'){
510
- return fail('UndefinedLeaf should be exported');
508
+ 'UndefinedNode should be exported': async ({pass, fail}) => {
509
+ if(typeof UndefinedNode !== 'function'){
510
+ return fail('UndefinedNode should be exported');
511
511
  }
512
- pass('UndefinedLeaf is exported');
512
+ pass('UndefinedNode is exported');
513
513
  },
514
514
 
515
- 'UndefinedLeaf should detect undefined': async ({pass, fail}) => {
516
- if(UndefinedLeaf.detect(undefined) !== true){
517
- return fail('UndefinedLeaf should detect undefined');
515
+ 'UndefinedNode should detect undefined': async ({pass, fail}) => {
516
+ if(UndefinedNode.detect(undefined) !== true){
517
+ return fail('UndefinedNode should detect undefined');
518
518
  }
519
- if(UndefinedLeaf.detect(null) !== false){
520
- return fail('UndefinedLeaf should not detect null');
519
+ if(UndefinedNode.detect(null) !== false){
520
+ return fail('UndefinedNode should not detect null');
521
521
  }
522
- pass('UndefinedLeaf detects undefined correctly');
522
+ pass('UndefinedNode detects undefined correctly');
523
523
  },
524
524
 
525
- 'UndefinedLeaf should render undefined text': async ({pass, fail}) => {
526
- const leaf = new UndefinedLeaf(undefined);
525
+ 'UndefinedNode should render undefined text': async ({pass, fail}) => {
526
+ const leaf = new UndefinedNode(undefined);
527
527
  const rendered = leaf.render();
528
528
  if(!rendered || !rendered.strings){
529
- return fail('UndefinedLeaf should return template result');
529
+ return fail('UndefinedNode should return template result');
530
530
  }
531
- pass('UndefinedLeaf renders correctly');
531
+ pass('UndefinedNode renders correctly');
532
532
  },
533
533
 
534
534
  /*
@@ -590,32 +590,32 @@ export default {
590
590
  Custom Leaf Registration
591
591
  */
592
592
  'should support custom leaf registration': async ({pass, fail}) => {
593
- const originalLength = Tree.leafs.length;
594
- class CustomLeaf extends TreeLeaf {
593
+ const originalLength = Tree.nodes.length;
594
+ class CustomLeaf extends TreeNode {
595
595
  static detect = () => false;
596
596
  }
597
- Tree.addLeaf(CustomLeaf);
598
- if(Tree.leafs.length !== originalLength + 1){
597
+ Tree.addNode(CustomLeaf);
598
+ if(Tree.nodes.length !== originalLength + 1){
599
599
  return fail('Custom leaf should be added to leafs array');
600
600
  }
601
601
  // Remove the custom leaf to not affect other tests
602
- Tree.leafs.shift();
602
+ Tree.nodes.shift();
603
603
  pass('Custom leaf registration works');
604
604
  },
605
605
 
606
- 'addLeaf should add to beginning of array': async ({pass, fail}) => {
607
- const originalFirst = Tree.leafs[0];
608
- class CustomLeaf extends TreeLeaf {
606
+ 'addNode should add to beginning of array': async ({pass, fail}) => {
607
+ const originalFirst = Tree.nodes[0];
608
+ class CustomLeaf extends TreeNode {
609
609
  static detect = () => false;
610
610
  }
611
- Tree.addLeaf(CustomLeaf);
612
- if(Tree.leafs[0] !== CustomLeaf){
613
- Tree.leafs.shift();
611
+ Tree.addNode(CustomLeaf);
612
+ if(Tree.nodes[0] !== CustomLeaf){
613
+ Tree.nodes.shift();
614
614
  return fail('Custom leaf should be added at beginning');
615
615
  }
616
616
  // Remove the custom leaf
617
- Tree.leafs.shift();
618
- pass('addLeaf adds to beginning of array');
617
+ Tree.nodes.shift();
618
+ pass('addNode adds to beginning of array');
619
619
  },
620
620
 
621
621
  /*
@@ -635,7 +635,7 @@ export default {
635
635
  await tree.updateComplete;
636
636
  // Need to wait for nested branches to render and open
637
637
  await new Promise(r => setTimeout(r, 100));
638
- const branches = tree.shadowRoot.querySelectorAll('k-tree-branch');
638
+ const branches = tree.shadowRoot.querySelectorAll('k-tree-node');
639
639
  // Check that branches exist
640
640
  if(branches.length < 1){
641
641
  cleanup(container);
@@ -655,7 +655,7 @@ export default {
655
655
  const { container, tree } = await createTree({ data, depth: 3 });
656
656
  await tree.updateComplete;
657
657
  // Check that tree structure is created
658
- const branches = tree.shadowRoot.querySelectorAll('k-tree-branch');
658
+ const branches = tree.shadowRoot.querySelectorAll('k-tree-node');
659
659
  if(branches.length < 1){
660
660
  cleanup(container);
661
661
  return fail('Mixed arrays and objects should create branches');
@@ -668,7 +668,7 @@ export default {
668
668
  const data = { empty: {} };
669
669
  const { container, tree } = await createTree({ data, depth: 1 });
670
670
  await tree.updateComplete;
671
- const branches = tree.shadowRoot.querySelectorAll('k-tree-branch');
671
+ const branches = tree.shadowRoot.querySelectorAll('k-tree-node');
672
672
  if(branches.length < 1){
673
673
  cleanup(container);
674
674
  return fail('Empty object should create branch');
@@ -681,7 +681,7 @@ export default {
681
681
  const data = { items: [] };
682
682
  const { container, tree } = await createTree({ data, depth: 1 });
683
683
  await tree.updateComplete;
684
- const branches = tree.shadowRoot.querySelectorAll('k-tree-branch');
684
+ const branches = tree.shadowRoot.querySelectorAll('k-tree-node');
685
685
  if(branches.length < 1){
686
686
  cleanup(container);
687
687
  return fail('Empty array should create branch');
@@ -724,11 +724,11 @@ export default {
724
724
  /*
725
725
  Accessibility
726
726
  */
727
- 'TreeBranch button should have aria-expanded': async ({pass, fail}) => {
727
+ 'TreeNode button should have aria-expanded': async ({pass, fail}) => {
728
728
  const data = { nested: { value: 1 } };
729
729
  const { container, tree } = await createTree({ data, depth: 1 });
730
730
  await tree.updateComplete;
731
- const branch = tree.shadowRoot.querySelector('k-tree-branch');
731
+ const branch = tree.shadowRoot.querySelector('k-tree-node');
732
732
  if(!branch){
733
733
  cleanup(container);
734
734
  return fail('Branch should exist');
@@ -740,14 +740,14 @@ export default {
740
740
  return fail('Branch button should have aria-expanded');
741
741
  }
742
742
  cleanup(container);
743
- pass('TreeBranch button has aria-expanded');
743
+ pass('TreeNode button has aria-expanded');
744
744
  },
745
745
 
746
746
  'aria-expanded should reflect opened state': async ({pass, fail}) => {
747
747
  const data = { nested: { value: 1 } };
748
748
  const { container, tree } = await createTree({ data, depth: 1 });
749
749
  await tree.updateComplete;
750
- const branch = tree.shadowRoot.querySelector('k-tree-branch');
750
+ const branch = tree.shadowRoot.querySelector('k-tree-node');
751
751
  if(!branch){
752
752
  cleanup(container);
753
753
  return fail('Branch should exist');
@@ -766,11 +766,11 @@ export default {
766
766
  /*
767
767
  Tree getter
768
768
  */
769
- 'TreeBranch should have tree getter': async ({pass, fail}) => {
769
+ 'TreeNode should have tree getter': async ({pass, fail}) => {
770
770
  const data = { nested: { value: 1 } };
771
771
  const { container, tree } = await createTree({ data, depth: 1 });
772
772
  await tree.updateComplete;
773
- const branch = tree.shadowRoot.querySelector('k-tree-branch');
773
+ const branch = tree.shadowRoot.querySelector('k-tree-node');
774
774
  if(!branch){
775
775
  cleanup(container);
776
776
  return fail('Branch should exist');
@@ -781,10 +781,10 @@ export default {
781
781
  // In shadow DOM, closest won't find the tree, so branch.tree will be null
782
782
  // This is expected behavior since the branch is inside shadow DOM
783
783
  cleanup(container);
784
- pass('TreeBranch tree getter works (returns null in shadow DOM as expected)');
784
+ pass('TreeNode tree getter works (returns null in shadow DOM as expected)');
785
785
  return;
786
786
  }
787
787
  cleanup(container);
788
- pass('TreeBranch tree getter exists');
788
+ pass('TreeNode tree getter exists');
789
789
  }
790
790
  };
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Highlight Tool
3
+ * Highlights code using Highlight.js and returns a <pre><code> HTML block.
4
+ *
5
+ * CLI Usage:
6
+ * echo '<div>hello</div>' | node tools/highlight.js --lang html
7
+ * node tools/highlight.js --lang javascript --file path/to/code.js
8
+ *
9
+ * Options:
10
+ * --lang <language> Language for syntax highlighting (required for CLI)
11
+ * --file <path> Read code from a file instead of stdin
12
+ *
13
+ * Module Usage:
14
+ * import { highlight } from './tools/highlight.js';
15
+ * const html = highlight(code, 'javascript');
16
+ */
17
+
18
+ import hljs from 'highlight.js';
19
+ import { readFileSync } from 'fs';
20
+ import { fileURLToPath } from 'url';
21
+ import path from 'path';
22
+
23
+ export const highlight = (code, lang) => {
24
+ const result = hljs.highlight(code, { language: lang });
25
+ return `<pre><code class="hljs ${lang}">${result.value}</code></pre>`;
26
+ };
27
+
28
+ const isMain = path.resolve(process.argv[1]) === path.resolve(fileURLToPath(import.meta.url));
29
+
30
+ if(isMain){
31
+ const args = process.argv.slice(2);
32
+ const getArg = name => {
33
+ const idx = args.indexOf(name);
34
+ return idx !== -1 ? args[idx + 1] : null;
35
+ };
36
+
37
+ const lang = getArg('--lang');
38
+ const filePath = getArg('--file');
39
+
40
+ if(!lang){
41
+ console.error('Error: --lang <language> is required');
42
+ console.error('Example: echo "const x = 1;" | node tools/highlight.js --lang javascript');
43
+ process.exit(1);
44
+ }
45
+
46
+ const code = filePath
47
+ ? readFileSync(filePath, 'utf8')
48
+ : readFileSync(0, 'utf8');
49
+
50
+ process.stdout.write(highlight(code, lang) + '\n');
51
+ }