lexgui 8.1.1 → 8.2.0

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 (52) hide show
  1. package/build/components/Avatar.d.ts +15 -0
  2. package/build/components/NodeTree.d.ts +51 -26
  3. package/build/components/Vector.d.ts +10 -9
  4. package/build/core/Event.d.ts +6 -26
  5. package/build/core/Namespace.js +1 -1
  6. package/build/core/Namespace.js.map +1 -1
  7. package/build/core/Panel.d.ts +538 -538
  8. package/build/extensions/AssetView.d.ts +7 -6
  9. package/build/extensions/AssetView.js +194 -155
  10. package/build/extensions/AssetView.js.map +1 -1
  11. package/build/extensions/Audio.js.map +1 -1
  12. package/build/extensions/CodeEditor.d.ts +358 -350
  13. package/build/extensions/CodeEditor.js +5054 -5022
  14. package/build/extensions/CodeEditor.js.map +1 -1
  15. package/build/extensions/DocMaker.js +330 -327
  16. package/build/extensions/DocMaker.js.map +1 -1
  17. package/build/extensions/GraphEditor.js +2754 -2760
  18. package/build/extensions/GraphEditor.js.map +1 -1
  19. package/build/extensions/Timeline.d.ts +668 -670
  20. package/build/extensions/Timeline.js +3948 -3955
  21. package/build/extensions/Timeline.js.map +1 -1
  22. package/build/extensions/VideoEditor.d.ts +128 -128
  23. package/build/extensions/VideoEditor.js +893 -898
  24. package/build/extensions/VideoEditor.js.map +1 -1
  25. package/build/index.css.d.ts +3 -4
  26. package/build/index.d.ts +57 -56
  27. package/build/lexgui.all.js +1587 -1369
  28. package/build/lexgui.all.js.map +1 -1
  29. package/build/lexgui.all.min.js +1 -1
  30. package/build/lexgui.all.module.js +1584 -1364
  31. package/build/lexgui.all.module.js.map +1 -1
  32. package/build/lexgui.all.module.min.js +1 -1
  33. package/build/lexgui.css +6157 -5583
  34. package/build/lexgui.js +977 -815
  35. package/build/lexgui.js.map +1 -1
  36. package/build/lexgui.min.css +2 -3
  37. package/build/lexgui.min.js +1 -1
  38. package/build/lexgui.module.js +975 -811
  39. package/build/lexgui.module.js.map +1 -1
  40. package/build/lexgui.module.min.js +1 -1
  41. package/changelog.md +52 -1
  42. package/demo.js +167 -65
  43. package/examples/all-components.html +38 -52
  44. package/examples/asset-view.html +27 -0
  45. package/examples/code-editor.html +1 -1
  46. package/examples/editor.html +10 -95
  47. package/examples/index.html +2 -2
  48. package/examples/side-bar.html +1 -1
  49. package/examples/timeline.html +2 -2
  50. package/examples/video-editor.html +1 -1
  51. package/examples/video-editor2.html +2 -2
  52. package/package.json +7 -4
package/build/lexgui.js CHANGED
@@ -1,9 +1,9 @@
1
1
  // This is a generated file. Do not edit.
2
2
  (function (global, factory) {
3
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
4
- typeof define === 'function' && define.amd ? define(['exports'], factory) :
5
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.lexgui = {}));
6
- })(this, (function (exports) { 'use strict';
3
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('https://cdn.jsdelivr.net/npm/tailwind-merge@3.4.0/+esm')) :
4
+ typeof define === 'function' && define.amd ? define(['exports', 'https://cdn.jsdelivr.net/npm/tailwind-merge@3.4.0/+esm'], factory) :
5
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.lexgui = {}, global.twMerge));
6
+ })(this, (function (exports, _esm) { 'use strict';
7
7
 
8
8
  // Namespace.ts @jxarco
9
9
  /**
@@ -16,7 +16,7 @@
16
16
  exports.LX = g.LX;
17
17
  if (!exports.LX) {
18
18
  exports.LX = {
19
- version: '8.1.1',
19
+ version: '8.2',
20
20
  ready: false,
21
21
  extensions: [], // Store extensions used
22
22
  extraCommandbarEntries: [], // User specific entries for command bar
@@ -127,8 +127,7 @@
127
127
  'M432 48L208 48c-17.7 0-32 14.3-32 32l0 16-48 0 0-16c0-44.2 35.8-80 80-80L432 0c44.2 0 80 35.8 80 80l0 224c0 44.2-35.8 80-80 80l-16 0 0-48 16 0c17.7 0 32-14.3 32-32l0-224c0-17.7-14.3-32-32-32zM48 448c0 8.8 7.2 16 16 16l256 0c8.8 0 16-7.2 16-16l0-192L48 256l0 192zM64 128l256 0c35.3 0 64 28.7 64 64l0 256c0 35.3-28.7 64-64 64L64 512c-35.3 0-64-28.7-64-64L0 192c0-35.3 28.7-64 64-64z'],
128
128
  'WindowMaximize': [512, 512, [], 'solid',
129
129
  'M.3 89.5C.1 91.6 0 93.8 0 96L0 224 0 416c0 35.3 28.7 64 64 64l384 0c35.3 0 64-28.7 64-64l0-192 0-128c0-35.3-28.7-64-64-64L64 32c-2.2 0-4.4 .1-6.5 .3c-9.2 .9-17.8 3.8-25.5 8.2C21.8 46.5 13.4 55.1 7.7 65.5c-3.9 7.3-6.5 15.4-7.4 24zM48 224l416 0 0 192c0 8.8-7.2 16-16 16L64 432c-8.8 0-16-7.2-16-16l0-192z'],
130
- 'WindowMinimize': [512, 512, [], 'solid',
131
- 'M24 432c-13.3 0-24 10.7-24 24s10.7 24 24 24l464 0c13.3 0 24-10.7 24-24s-10.7-24-24-24L24 432z'],
130
+ 'WindowMinimize': [512, 512, [], 'solid', 'M24 432c-13.3 0-24 10.7-24 24s10.7 24 24 24l464 0c13.3 0 24-10.7 24-24s-10.7-24-24-24L24 432z'],
132
131
  'VrCardboard': [640, 512, ['VR'], 'solid',
133
132
  'M576 64L64 64C28.7 64 0 92.7 0 128L0 384c0 35.3 28.7 64 64 64l120.4 0c24.2 0 46.4-13.7 57.2-35.4l32-64c8.8-17.5 26.7-28.6 46.3-28.6s37.5 11.1 46.3 28.6l32 64c10.8 21.7 33 35.4 57.2 35.4L576 448c35.3 0 64-28.7 64-64l0-256c0-35.3-28.7-64-64-64zM96 240a64 64 0 1 1 128 0A64 64 0 1 1 96 240zm384-64a64 64 0 1 1 0 128 64 64 0 1 1 0-128z'],
134
133
  'C': [32, 32, [], 'solid',
@@ -174,8 +173,7 @@
174
173
  'M0 256C0 114.6 114.6 0 256 0S512 114.6 512 256s-114.6 256-256 256L37.1 512c-13.7 0-20.5-16.5-10.9-26.2L75 437C28.7 390.7 0 326.7 0 256zM349.6 153.6c23.6 0 42.7-19.1 42.7-42.7s-19.1-42.7-42.7-42.7c-20.6 0-37.8 14.6-41.8 34c-34.5 3.7-61.4 33-61.4 68.4l0 .2c-37.5 1.6-71.8 12.3-99 29.1c-10.1-7.8-22.8-12.5-36.5-12.5c-33 0-59.8 26.8-59.8 59.8c0 24 14.1 44.6 34.4 54.1c2 69.4 77.6 125.2 170.6 125.2s168.7-55.9 170.6-125.3c20.2-9.6 34.1-30.2 34.1-54c0-33-26.8-59.8-59.8-59.8c-13.7 0-26.3 4.6-36.4 12.4c-27.4-17-62.1-27.7-100-29.1l0-.2c0-25.4 18.9-46.5 43.4-49.9l0 0c4.4 18.8 21.3 32.8 41.5 32.8zM177.1 246.9c16.7 0 29.5 17.6 28.5 39.3s-13.5 29.6-30.3 29.6s-31.4-8.8-30.4-30.5s15.4-38.3 32.1-38.3zm190.1 38.3c1 21.7-13.7 30.5-30.4 30.5s-29.3-7.9-30.3-29.6c-1-21.7 11.8-39.3 28.5-39.3s31.2 16.6 32.1 38.3zm-48.1 56.7c-10.3 24.6-34.6 41.9-63 41.9s-52.7-17.3-63-41.9c-1.2-2.9 .8-6.2 3.9-6.5c18.4-1.9 38.3-2.9 59.1-2.9s40.7 1 59.1 2.9c3.1 .3 5.1 3.6 3.9 6.5z'],
175
174
  'Rust': [512, 512, [], 'solid',
176
175
  'M508.52,249.75,486.7,236.24c-.17-2-.34-3.93-.55-5.88l18.72-17.5a7.35,7.35,0,0,0-2.44-12.25l-24-9c-.54-1.88-1.08-3.78-1.67-5.64l15-20.83a7.35,7.35,0,0,0-4.79-11.54l-25.42-4.15c-.9-1.73-1.79-3.45-2.73-5.15l10.68-23.42a7.35,7.35,0,0,0-6.95-10.39l-25.82.91q-1.79-2.22-3.61-4.4L439,81.84A7.36,7.36,0,0,0,430.16,73L405,78.93q-2.17-1.83-4.4-3.61l.91-25.82a7.35,7.35,0,0,0-10.39-7L367.7,53.23c-1.7-.94-3.43-1.84-5.15-2.73L358.4,25.08a7.35,7.35,0,0,0-11.54-4.79L326,35.26c-1.86-.59-3.75-1.13-5.64-1.67l-9-24a7.35,7.35,0,0,0-12.25-2.44l-17.5,18.72c-1.95-.21-3.91-.38-5.88-.55L262.25,3.48a7.35,7.35,0,0,0-12.5,0L236.24,25.3c-2,.17-3.93.34-5.88.55L212.86,7.13a7.35,7.35,0,0,0-12.25,2.44l-9,24c-1.89.55-3.79,1.08-5.66,1.68l-20.82-15a7.35,7.35,0,0,0-11.54,4.79l-4.15,25.41c-1.73.9-3.45,1.79-5.16,2.73L120.88,42.55a7.35,7.35,0,0,0-10.39,7l.92,25.81c-1.49,1.19-3,2.39-4.42,3.61L81.84,73A7.36,7.36,0,0,0,73,81.84L78.93,107c-1.23,1.45-2.43,2.93-3.62,4.41l-25.81-.91a7.42,7.42,0,0,0-6.37,3.26,7.35,7.35,0,0,0-.57,7.13l10.66,23.41c-.94,1.7-1.83,3.43-2.73,5.16L25.08,153.6a7.35,7.35,0,0,0-4.79,11.54l15,20.82c-.59,1.87-1.13,3.77-1.68,5.66l-24,9a7.35,7.35,0,0,0-2.44,12.25l18.72,17.5c-.21,1.95-.38,3.91-.55,5.88L3.48,249.75a7.35,7.35,0,0,0,0,12.5L25.3,275.76c.17,2,.34,3.92.55,5.87L7.13,299.13a7.35,7.35,0,0,0,2.44,12.25l24,9c.55,1.89,1.08,3.78,1.68,5.65l-15,20.83a7.35,7.35,0,0,0,4.79,11.54l25.42,4.15c.9,1.72,1.79,3.45,2.73,5.14L42.56,391.12a7.35,7.35,0,0,0,.57,7.13,7.13,7.13,0,0,0,6.37,3.26l25.83-.91q1.77,2.22,3.6,4.4L73,430.16A7.36,7.36,0,0,0,81.84,439L107,433.07q2.18,1.83,4.41,3.61l-.92,25.82a7.35,7.35,0,0,0,10.39,6.95l23.43-10.68c1.69.94,3.42,1.83,5.14,2.73l4.15,25.42a7.34,7.34,0,0,0,11.54,4.78l20.83-15c1.86.6,3.76,1.13,5.65,1.68l9,24a7.36,7.36,0,0,0,12.25,2.44l17.5-18.72c1.95.21,3.92.38,5.88.55l13.51,21.82a7.35,7.35,0,0,0,12.5,0l13.51-21.82c2-.17,3.93-.34,5.88-.56l17.5,18.73a7.36,7.36,0,0,0,12.25-2.44l9-24c1.89-.55,3.78-1.08,5.65-1.68l20.82,15a7.34,7.34,0,0,0,11.54-4.78l4.15-25.42c1.72-.9,3.45-1.79,5.15-2.73l23.42,10.68a7.35,7.35,0,0,0,10.39-6.95l-.91-25.82q2.22-1.79,4.4-3.61L430.16,439a7.36,7.36,0,0,0,8.84-8.84L433.07,405q1.83-2.17,3.61-4.4l25.82.91a7.23,7.23,0,0,0,6.37-3.26,7.35,7.35,0,0,0,.58-7.13L458.77,367.7c.94-1.7,1.83-3.43,2.73-5.15l25.42-4.15a7.35,7.35,0,0,0,4.79-11.54l-15-20.83c.59-1.87,1.13-3.76,1.67-5.65l24-9a7.35,7.35,0,0,0,2.44-12.25l-18.72-17.5c.21-1.95.38-3.91.55-5.87l21.82-13.51a7.35,7.35,0,0,0,0-12.5Zm-151,129.08A13.91,13.91,0,0,0,341,389.51l-7.64,35.67A187.51,187.51,0,0,1,177,424.44l-7.64-35.66a13.87,13.87,0,0,0-16.46-10.68l-31.51,6.76a187.38,187.38,0,0,1-16.26-19.21H258.3c1.72,0,2.89-.29,2.89-1.91V309.55c0-1.57-1.17-1.91-2.89-1.91H213.47l.05-34.35H262c4.41,0,23.66,1.28,29.79,25.87,1.91,7.55,6.17,32.14,9.06,40,2.89,8.82,14.6,26.46,27.1,26.46H407a187.3,187.3,0,0,1-17.34,20.09Zm25.77,34.49A15.24,15.24,0,1,1,368,398.08h.44A15.23,15.23,0,0,1,383.24,413.32Zm-225.62-.68a15.24,15.24,0,1,1-15.25-15.25h.45A15.25,15.25,0,0,1,157.62,412.64ZM69.57,234.15l32.83-14.6a13.88,13.88,0,0,0,7.06-18.33L102.69,186h26.56V305.73H75.65A187.65,187.65,0,0,1,69.57,234.15ZM58.31,198.09a15.24,15.24,0,0,1,15.23-15.25H74a15.24,15.24,0,1,1-15.67,15.24Zm155.16,24.49.05-35.32h63.26c3.28,0,23.07,3.77,23.07,18.62,0,12.29-15.19,16.7-27.68,16.7ZM399,306.71c-9.8,1.13-20.63-4.12-22-10.09-5.78-32.49-15.39-39.4-30.57-51.4,18.86-11.95,38.46-29.64,38.46-53.26,0-25.52-17.49-41.59-29.4-49.48-16.76-11-35.28-13.23-40.27-13.23H116.32A187.49,187.49,0,0,1,221.21,70.06l23.47,24.6a13.82,13.82,0,0,0,19.6.44l26.26-25a187.51,187.51,0,0,1,128.37,91.43l-18,40.57A14,14,0,0,0,408,220.43l34.59,15.33a187.12,187.12,0,0,1,.4,32.54H423.71c-1.91,0-2.69,1.27-2.69,3.13v8.82C421,301,409.31,305.58,399,306.71ZM240,60.21A15.24,15.24,0,0,1,255.21,45h.45A15.24,15.24,0,1,1,240,60.21ZM436.84,214a15.24,15.24,0,1,1,0-30.48h.44a15.24,15.24,0,0,1-.44,30.48Z'],
177
- 'Unity': [16, 16, [], 'solid',
178
- 'M8 6.5L5 5l2-1V2L2 5v5l2-1V6.5L7 8v4.5L4 11l-2 1l6 3l6-3l-2-1l-3 1.5V8l3-1.5V9l2 1V5L9 2v2l2 1Z'],
176
+ 'Unity': [16, 16, [], 'solid', 'M8 6.5L5 5l2-1V2L2 5v5l2-1V6.5L7 8v4.5L4 11l-2 1l6 3l6-3l-2-1l-3 1.5V8l3-1.5V9l2 1V5L9 2v2l2 1Z'],
179
177
  'UnrealEngine': [24, 24, [], 'regular',
180
178
  'M12 0a12 12 0 1 0 12 12A12 12 0 0 0 12 0m0 23.52A11.52 11.52 0 1 1 23.52 12A11.52 11.52 0 0 1 12 23.52m7.13-9.791c-.206.997-1.126 3.557-4.06 4.942l-1.179-1.325l-1.988 2a7.34 7.34 0 0 1-5.804-2.978a3 3 0 0 0 .65.123c.326.006.678-.114.678-.66v-5.394a.89.89 0 0 0-1.116-.89c-.92.212-1.656 2.509-1.656 2.509a7.3 7.3 0 0 1 2.528-5.597a7.4 7.4 0 0 1 3.73-1.721c-1.006.573-1.57 1.507-1.57 2.29c0 1.262.76 1.109.984.923v7.28a1.2 1.2 0 0 0 .148.256a1.08 1.08 0 0 0 .88.445c.76 0 1.747-.868 1.747-.868V9.172c0-.6-.452-1.324-.905-1.572c0 0 .838-.149 1.484.346a6 6 0 0 1 .387-.425c1.508-1.48 2.929-1.902 4.112-2.112c0 0-2.151 1.69-2.151 3.96c0 1.687.043 5.801.043 5.801c.799.771 1.986-.342 3.059-1.441Z'],
181
179
  'UnrealEngine@solid': [24, 24, [], 'solid',
@@ -262,8 +260,7 @@
262
260
  'M448 480L64 480c-35.3 0-64-28.7-64-64L0 192l512 0 0 224c0 35.3-28.7 64-64 64zm64-320L0 160 0 96C0 60.7 28.7 32 64 32l128 0c20.1 0 39.1 9.5 51.2 25.6l19.2 25.6c6 8.1 15.5 12.8 25.6 12.8l160 0c35.3 0 64 28.7 64 64z'],
263
261
  'Function': [384, 512, [], 'solid',
264
262
  'M314.7 32c-38.8 0-73.7 23.3-88.6 59.1L170.7 224 64 224c-17.7 0-32 14.3-32 32s14.3 32 32 32l80 0L98.9 396.3c-5 11.9-16.6 19.7-29.5 19.7L32 416c-17.7 0-32 14.3-32 32s14.3 32 32 32l37.3 0c38.8 0 73.7-23.3 88.6-59.1L213.3 288 320 288c17.7 0 32-14.3 32-32s-14.3-32-32-32l-80 0 45.1-108.3c5-11.9 16.6-19.7 29.5-19.7L352 96c17.7 0 32-14.3 32-32s-14.3-32-32-32l-37.3 0z'],
265
- 'Stop': [384, 512, [], 'solid',
266
- 'M0 128C0 92.7 28.7 64 64 64H320c35.3 0 64 28.7 64 64V384c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V128z'],
263
+ 'Stop': [384, 512, [], 'solid', 'M0 128C0 92.7 28.7 64 64 64H320c35.3 0 64 28.7 64 64V384c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V128z'],
267
264
  'Image': [512, 512, [], 'solid',
268
265
  'M448 80c8.8 0 16 7.2 16 16l0 319.8-5-6.5-136-176c-4.5-5.9-11.6-9.3-19-9.3s-14.4 3.4-19 9.3L202 340.7l-30.5-42.7C167 291.7 159.8 288 152 288s-15 3.7-19.5 10.1l-80 112L48 416.3l0-.3L48 96c0-8.8 7.2-16 16-16l384 0zM64 32C28.7 32 0 60.7 0 96L0 416c0 35.3 28.7 64 64 64l384 0c35.3 0 64-28.7 64-64l0-320c0-35.3-28.7-64-64-64L64 32zm80 192a48 48 0 1 0 0-96 48 48 0 1 0 0 96z'],
269
266
  'Images': [576, 512, [], 'solid',
@@ -394,52 +391,6 @@
394
391
  }
395
392
  }
396
393
  exports.LX.IEvent = IEvent;
397
- class TreeEvent {
398
- static NONE = 0;
399
- static NODE_SELECTED = 1;
400
- static NODE_DELETED = 2;
401
- static NODE_DBLCLICKED = 3;
402
- static NODE_CONTEXTMENU = 4;
403
- static NODE_DRAGGED = 5;
404
- static NODE_RENAMED = 6;
405
- static NODE_VISIBILITY = 7;
406
- static NODE_CARETCHANGED = 8;
407
- type = TreeEvent.NONE;
408
- node;
409
- value;
410
- event;
411
- multiple = false; // Multiple selection
412
- panel = null;
413
- constructor(type, node, value, event) {
414
- this.type = type || TreeEvent.NONE;
415
- this.node = node;
416
- this.value = value;
417
- this.event = event;
418
- }
419
- string() {
420
- switch (this.type) {
421
- case TreeEvent.NONE:
422
- return 'tree_event_none';
423
- case TreeEvent.NODE_SELECTED:
424
- return 'tree_event_selected';
425
- case TreeEvent.NODE_DELETED:
426
- return 'tree_event_deleted';
427
- case TreeEvent.NODE_DBLCLICKED:
428
- return 'tree_event_dblclick';
429
- case TreeEvent.NODE_CONTEXTMENU:
430
- return 'tree_event_contextmenu';
431
- case TreeEvent.NODE_DRAGGED:
432
- return 'tree_event_dragged';
433
- case TreeEvent.NODE_RENAMED:
434
- return 'tree_event_renamed';
435
- case TreeEvent.NODE_VISIBILITY:
436
- return 'tree_event_visibility';
437
- case TreeEvent.NODE_CARETCHANGED:
438
- return 'tree_event_caretchanged';
439
- }
440
- }
441
- }
442
- exports.LX.TreeEvent = TreeEvent;
443
394
 
444
395
  // BaseComponent.ts @jxarco
445
396
  exports.ComponentType = void 0;
@@ -514,8 +465,7 @@
514
465
  this.name = name;
515
466
  this.options = options;
516
467
  this._initialValue = value;
517
- const root = document.createElement('div');
518
- root.className = 'lexcomponent';
468
+ const root = exports.LX.makeElement('div', exports.LX.mergeClass('lexcomponent flex flex-row outline-none items-center text-foreground text-sm overflow-hidden min-h-8 pad-sm', options.className));
519
469
  this.onResize = () => { };
520
470
  if (options.id) {
521
471
  root.id = options.id;
@@ -523,9 +473,6 @@
523
473
  if (options.title) {
524
474
  root.title = options.title;
525
475
  }
526
- if (options.className) {
527
- root.className += ' ' + options.className;
528
- }
529
476
  if (type != exports.ComponentType.TITLE) {
530
477
  if (options.width) {
531
478
  root.style.width = root.style.minWidth = options.width;
@@ -543,12 +490,10 @@
543
490
  }
544
491
  if (name != undefined) {
545
492
  if (!(options.hideName ?? false)) {
546
- let domName = document.createElement('div');
547
- domName.className = 'lexcomponentname';
493
+ let domName = exports.LX.makeElement('div', 'lexcomponentname flex text-sm text-secondary-foreground justify-between whitespace-nowrap overflow-hidden', name);
548
494
  if (options.justifyName) {
549
495
  domName.classList.add('float-' + options.justifyName);
550
496
  }
551
- domName.innerHTML = name;
552
497
  domName.title = options.title ?? domName.innerHTML;
553
498
  domName.style.width = options.nameWidth || exports.LX.DEFAULT_NAME_WIDTH;
554
499
  domName.style.minWidth = domName.style.width;
@@ -777,7 +722,7 @@
777
722
  wValue.prepend(img);
778
723
  }
779
724
  else {
780
- wValue.innerHTML = `<span>${(newValue ?? '')}</span>`;
725
+ wValue.innerHTML = `${(newValue ?? '')}`;
781
726
  }
782
727
  };
783
728
  this.onResize = (rect) => {
@@ -804,9 +749,10 @@
804
749
  this._trigger(new IEvent(name, swapInput ? swapInput.checked : (this.selectable ? v : value), null), callback);
805
750
  }
806
751
  };
807
- var wValue = document.createElement('button');
752
+ var wValue = exports.LX.makeElement('button', exports.LX.mergeClass(['lexbutton', 'inline-flex', 'items-center', 'justify-center', 'whitespace-nowrap', 'transition-all', 'disabled:pointer-events-none',
753
+ 'disabled:opacity-50', '[&_svg]:pointer-events-none', 'shrink-0', '[&_svg]:shrink-0', 'outline-none', 'select-none', 'cursor-pointer',
754
+ 'font-medium', 'text-sm', 'border-1', 'h-9', 'px-2', 'overflow-hidden', 'bg-clip-padding'].join(' '), options.buttonClass ?? 'outline'));
808
755
  wValue.title = options.tooltip ? '' : (options.title ?? '');
809
- wValue.className = 'lexbutton px-3 ' + (options.buttonClass ?? '');
810
756
  this.root.appendChild(wValue);
811
757
  if (options.selected) {
812
758
  wValue.classList.add('selected');
@@ -824,19 +770,19 @@
824
770
  wValue.prepend(icon);
825
771
  }
826
772
  else {
827
- wValue.innerHTML = `<span>${(value || '')}</span>`;
773
+ wValue.innerHTML = `${(value || '')}`;
828
774
  if (iconPosition == 'start') {
829
- wValue.querySelector('span').prepend(icon);
775
+ wValue.prepend(icon);
830
776
  }
831
777
  // "end"
832
778
  else {
833
- wValue.querySelector('span').appendChild(icon);
779
+ wValue.appendChild(icon);
834
780
  }
835
781
  }
836
782
  wValue.classList.add('justify-center');
837
783
  }
838
784
  else {
839
- wValue.innerHTML = `<span>${(value || '')}</span>`;
785
+ wValue.innerHTML = `${(value || '')}`;
840
786
  }
841
787
  if (options.fileInput) {
842
788
  const fileInput = document.createElement('input');
@@ -961,10 +907,9 @@
961
907
  focused = false;
962
908
  _currentDropdown;
963
909
  constructor(items, options = {}) {
964
- this.root = document.createElement('div');
965
- this.root.className = 'lexmenubar';
910
+ this.root = exports.LX.makeElement('div', 'lexmenubar size-full bg-background text-foreground inline-flex gap-1 overflow-hidden text-sm font-medium');
966
911
  if (options.float) {
967
- this.root.style.justifyContent = options.float;
912
+ this.root.className = exports.LX.mergeClass(this.root.className, `justify-${options.float}`);
968
913
  }
969
914
  this.items = items ?? [];
970
915
  this.createEntries();
@@ -1002,8 +947,7 @@
1002
947
  this._resetMenubar(true);
1003
948
  entry.classList.add('selected');
1004
949
  entry.dataset['built'] = 'true';
1005
- this._currentDropdown = exports.LX.addDropdownMenu(entry, item.submenu ?? [], { side: 'bottom', align: 'start',
1006
- onBlur: () => {
950
+ this._currentDropdown = exports.LX.addDropdownMenu(entry, item.submenu ?? [], { side: 'bottom', align: 'start', onBlur: () => {
1007
951
  this._resetMenubar();
1008
952
  } });
1009
953
  };
@@ -1178,7 +1122,7 @@
1178
1122
  const title = data.title;
1179
1123
  const button = new Button(title, data.label, data.callback, {
1180
1124
  title,
1181
- buttonClass: 'bg-none',
1125
+ buttonClass: 'ghost',
1182
1126
  disabled: data.disabled,
1183
1127
  icon: data.icon,
1184
1128
  hideName: true,
@@ -1211,7 +1155,7 @@
1211
1155
  constructor(area, options = {}) {
1212
1156
  this.onclose = options.onclose;
1213
1157
  let container = document.createElement('div');
1214
- container.className = 'lexareatabs ' + (options.fit ? 'fit' : 'row');
1158
+ container.className = 'lexareatabs flex flex-row w-fit ' + (options.fit ? 'fit' : 'row');
1215
1159
  const folding = options.folding ?? false;
1216
1160
  if (folding)
1217
1161
  container.classList.add('folding');
@@ -1273,16 +1217,15 @@
1273
1217
  that.tabs[tabDom.dataset['name']] = content;
1274
1218
  });
1275
1219
  area.root.classList.add('lexareatabscontainer');
1276
- const [tabButtons, content] = area.split({ type: 'vertical', sizes: options.sizes ?? 'auto', resize: false,
1277
- top: 2 });
1220
+ const [tabButtons, content] = area.split({ type: 'vertical', sizes: options.sizes ?? 'auto', resize: false, top: 2 });
1278
1221
  tabButtons.attach(container);
1279
1222
  if (options.parentClass && container.parentElement) {
1280
- container.parentElement.className += ` ${options.parentClass}`;
1223
+ container.parentElement.className = exports.LX.mergeClass(container.parentElement.className, options.parentClass);
1281
1224
  }
1282
1225
  this.area = content;
1283
1226
  this.area.root.className += ' lexareatabscontent';
1284
1227
  if (options.contentClass) {
1285
- this.area.root.className += ` ${options.contentClass}`;
1228
+ this.area.root.className = exports.LX.mergeClass(this.area.root.className, options.contentClass);
1286
1229
  }
1287
1230
  this.selected = null;
1288
1231
  this.root = container;
@@ -1341,8 +1284,7 @@
1341
1284
  if (options.icon) {
1342
1285
  if (!options.icon.includes('.')) { // Not a file
1343
1286
  const classes = options.icon.split(' ');
1344
- options.icon =
1345
- exports.LX.makeIcon(classes[0], { svgClass: 'sm ' + classes.slice(0).join(' ') }).innerHTML;
1287
+ options.icon = exports.LX.makeIcon(classes[0], { svgClass: 'sm ' + classes.slice(0).join(' ') }).innerHTML;
1346
1288
  }
1347
1289
  // an image..
1348
1290
  else {
@@ -1377,10 +1319,9 @@
1377
1319
  e.stopPropagation();
1378
1320
  const scope = tabEl.instance;
1379
1321
  if (!tabEl.fixed) {
1380
- // For folding tabs
1381
1322
  const lastValue = tabEl.selected;
1382
1323
  tabEl.parentElement.querySelectorAll('span').forEach((s) => s.selected = false);
1383
- tabEl.selected = !lastValue || (tabEl._forceSelect ? true : false);
1324
+ tabEl.selected = (scope.folding ? !lastValue : true) || (tabEl._forceSelect ? true : false);
1384
1325
  // Manage selected
1385
1326
  tabEl.parentElement.querySelectorAll('span').forEach((s) => s.classList.remove('selected'));
1386
1327
  tabEl.classList.toggle('selected', tabEl.selected);
@@ -1523,9 +1464,7 @@
1523
1464
  var container = document.createElement('div');
1524
1465
  container.className = 'lexnumber';
1525
1466
  this.root.appendChild(container);
1526
- let box = document.createElement('div');
1527
- box.className = 'numberbox';
1528
- container.appendChild(box);
1467
+ let box = exports.LX.makeElement('div', 'numberbox relative flex flex-col w-full bg-secondary rounded-lg scrollbar-hidden overflow-x-hidden', '', container);
1529
1468
  let valueBox = exports.LX.makeContainer(['auto', '100%'], 'relative flex flex-row cursor-text', '', box);
1530
1469
  let vecinput = document.createElement('input');
1531
1470
  vecinput.id = 'number_' + exports.LX.guidGenerator();
@@ -1543,7 +1482,7 @@
1543
1482
  const dragIcon = exports.LX.makeIcon('MoveVertical', { iconClass: 'drag-icon hidden-opacity', svgClass: 'sm' });
1544
1483
  valueBox.appendChild(dragIcon);
1545
1484
  if (options.units) {
1546
- let unitBox = exports.LX.makeContainer(['auto', 'auto'], 'px-2 bg-secondary content-center', options.units, valueBox, { 'word-break': 'keep-all' });
1485
+ let unitBox = exports.LX.makeContainer(['auto', 'auto'], 'px-2 bg-card content-center break-keep', options.units, valueBox);
1547
1486
  vecinput.unitBox = unitBox;
1548
1487
  }
1549
1488
  if (options.disabled) {
@@ -1704,8 +1643,7 @@
1704
1643
  this.disabled = (options.disabled || options.warning) ?? (options.url ? true : false);
1705
1644
  let wValue = null;
1706
1645
  if (!this.disabled) {
1707
- wValue = document.createElement('input');
1708
- wValue.className = 'lextext ' + (options.inputClass ?? '');
1646
+ wValue = exports.LX.makeElement('input', exports.LX.mergeClass('lextext text-sm', options.inputClass));
1709
1647
  wValue.type = options.type || '';
1710
1648
  wValue.value = value || '';
1711
1649
  wValue.style.textAlign = options.float ?? '';
@@ -1757,10 +1695,10 @@
1757
1695
  wValue.disabled = true;
1758
1696
  wValue.value = value;
1759
1697
  wValue.style.textAlign = options.float ?? '';
1760
- wValue.className = 'lextext ellipsis-overflow ' + (options.inputClass ?? '');
1698
+ wValue.className = exports.LX.mergeClass('lextext ellipsis-overflow', options.inputClass);
1761
1699
  }
1762
1700
  if (options.fit) {
1763
- wValue.classList.add('size-content');
1701
+ wValue.classList.add('field-sizing-content');
1764
1702
  }
1765
1703
  Object.assign(wValue.style, options.style ?? {});
1766
1704
  container.appendChild(wValue);
@@ -1784,7 +1722,7 @@
1784
1722
  this.onSetValue = (newValue, skipCallback, event) => {
1785
1723
  value = newValue;
1786
1724
  let item = null;
1787
- const listOptionsNodes = listOptions.childNodes;
1725
+ const listOptionsNodes = list.childNodes;
1788
1726
  listOptionsNodes.forEach((e) => {
1789
1727
  e.classList.remove('selected');
1790
1728
  if (e.getAttribute('value') == newValue) {
@@ -1885,8 +1823,9 @@
1885
1823
  const parentRect = overflowContainer.getBoundingClientRect();
1886
1824
  maxX = parentRect.x + parentRect.width;
1887
1825
  }
1888
- const showLeft = (leftPosition + listWidth) > maxX;
1889
- if (showLeft) {
1826
+ // "align" basically forces left-right alignment
1827
+ const showLeft = (options.align === 'end') || (leftPosition + listWidth) > maxX;
1828
+ if (showLeft && (options.align ? options.align !== 'start' : true)) {
1890
1829
  parent.style.left = (leftPosition - (listWidth - rect.width)) + 'px';
1891
1830
  }
1892
1831
  }
@@ -1908,17 +1847,17 @@
1908
1847
  if (filter) {
1909
1848
  filter.root.querySelector('input').focus();
1910
1849
  }
1911
- }, { buttonClass: 'array', skipInlineCount: true, disabled: options.disabled });
1850
+ }, { buttonClass: 'outline [&_a]:ml-auto', skipInlineCount: true, disabled: options.disabled });
1912
1851
  selectedOption.root.style.width = '100%';
1913
- selectedOption.root.querySelector('span').appendChild(exports.LX.makeIcon('Down', { svgClass: 'sm' }));
1852
+ selectedOption.root.querySelector('button').appendChild(exports.LX.makeIcon('Down', { svgClass: 'sm' }));
1914
1853
  container.appendChild(selectedOption.root);
1915
1854
  selectedOption.refresh = (v) => {
1916
- const buttonSpan = selectedOption.root.querySelector('span');
1917
- if (buttonSpan.innerText == '') {
1918
- buttonSpan.innerText = v;
1855
+ const button = selectedOption.root.querySelector('button');
1856
+ if (button.innerText == '') {
1857
+ button.innerText = v;
1919
1858
  }
1920
1859
  else {
1921
- buttonSpan.innerHTML = buttonSpan.innerHTML.replaceAll(buttonSpan.innerText, v);
1860
+ button.innerHTML = button.innerHTML.replaceAll(button.innerText, v);
1922
1861
  }
1923
1862
  };
1924
1863
  // Add select options container
@@ -1969,14 +1908,12 @@
1969
1908
  });
1970
1909
  list.appendChild(filter.root);
1971
1910
  }
1972
- // Create option list to empty it easily..
1973
- const listOptions = document.createElement('span');
1974
- listOptions.className = 'lexselectinnerlist';
1975
- list.appendChild(listOptions);
1976
1911
  // Add select options list
1977
1912
  list.refresh = (currentOptions) => {
1978
1913
  // Empty list
1979
- listOptions.innerHTML = '';
1914
+ while (list.childElementCount > (options.filter ?? false ? 1 : 0)) {
1915
+ list.removeChild(list.lastChild);
1916
+ }
1980
1917
  if (!currentOptions.length) {
1981
1918
  let iValue = options.emptyMsg ?? 'No options found.';
1982
1919
  let option = document.createElement('div');
@@ -1985,7 +1922,7 @@
1985
1922
  let li = document.createElement('li');
1986
1923
  li.className = 'lexselectitem empty';
1987
1924
  li.appendChild(option);
1988
- listOptions.appendChild(li);
1925
+ list.appendChild(li);
1989
1926
  return;
1990
1927
  }
1991
1928
  for (let i = 0; i < currentOptions.length; i++) {
@@ -2003,7 +1940,7 @@
2003
1940
  if (iValue.constructor != Object) {
2004
1941
  const asLabel = iValue[0] === '@';
2005
1942
  if (!asLabel) {
2006
- option.innerHTML = `<span>${iValue}</span>`;
1943
+ option.innerHTML = `<span class="flex flex-row justify-between">${iValue}</span>`;
2007
1944
  option.appendChild(exports.LX.makeIcon('Check'));
2008
1945
  option.value = iValue;
2009
1946
  li.setAttribute('value', iValue);
@@ -2035,14 +1972,13 @@
2035
1972
  li.classList.add('selected');
2036
1973
  }
2037
1974
  }
2038
- listOptions.appendChild(li);
1975
+ list.appendChild(li);
2039
1976
  }
2040
1977
  };
2041
1978
  list.refresh(values);
2042
1979
  container.appendChild(listDialog);
2043
1980
  // Element suboptions
2044
- let suboptions = document.createElement('div');
2045
- suboptions.className = 'lexcustomcontainer w-full';
1981
+ let suboptions = exports.LX.makeElement('div', 'lexcustomcontainer w-full');
2046
1982
  const suboptionsFunc = options[`on_${value}`];
2047
1983
  suboptions.toggleAttribute('hidden', !suboptionsFunc);
2048
1984
  if (suboptionsFunc) {
@@ -2085,7 +2021,7 @@
2085
2021
  class ArrayInput extends BaseComponent {
2086
2022
  _updateItems;
2087
2023
  constructor(name, values = [], callback, options = {}) {
2088
- options.nameWidth = '100%';
2024
+ options.nameWidth = 'auto';
2089
2025
  super(exports.ComponentType.ARRAY, name, null, options);
2090
2026
  this.onGetValue = () => {
2091
2027
  return values;
@@ -2099,16 +2035,16 @@
2099
2035
  };
2100
2036
  // Add open array button
2101
2037
  let container = document.createElement('div');
2102
- container.className = 'lexarray';
2103
- container.style.width = '100%';
2038
+ container.className = 'lexarray shrink-1 grow-1 ml-4';
2039
+ container.style.width = 'auto';
2104
2040
  this.root.appendChild(container);
2105
2041
  this.root.dataset['opened'] = false;
2106
2042
  let buttonName = `Array (size ${values.length})`;
2107
2043
  const toggleButton = new Button(null, buttonName, () => {
2108
2044
  this.root.dataset['opened'] = this.root.dataset['opened'] == 'true' ? false : true;
2109
2045
  this.root.querySelector('.lexarrayitems').toggleAttribute('hidden');
2110
- }, { buttonClass: 'array' });
2111
- toggleButton.root.querySelector('span').appendChild(exports.LX.makeIcon('Down', { svgClass: 'sm' }));
2046
+ }, { buttonClass: 'outline [&_a]:ml-auto' });
2047
+ toggleButton.root.querySelector('button').appendChild(exports.LX.makeIcon('Down', { svgClass: 'sm' }));
2112
2048
  container.appendChild(toggleButton.root);
2113
2049
  // Show elements
2114
2050
  let arrayItems = document.createElement('div');
@@ -2117,8 +2053,8 @@
2117
2053
  this.root.appendChild(arrayItems);
2118
2054
  this._updateItems = () => {
2119
2055
  // Update num items
2120
- let buttonSpan = this.root.querySelector('.lexbutton.array span');
2121
- for (let node of buttonSpan.childNodes) {
2056
+ let button = this.root.querySelector('button');
2057
+ for (let node of button.childNodes) {
2122
2058
  if (node.nodeType === Node.TEXT_NODE) {
2123
2059
  node.textContent = `Array (size ${values.length})`;
2124
2060
  break;
@@ -2156,14 +2092,14 @@
2156
2092
  values.splice(values.indexOf(value), 1);
2157
2093
  this._updateItems();
2158
2094
  this._trigger(new IEvent(name, values, event), callback);
2159
- }, { title: 'Remove item', icon: 'Trash3' });
2095
+ }, { buttonClass: 'ghost xs p-0', title: 'Remove item', icon: 'Trash2' });
2160
2096
  component.root.appendChild(removeComponent.root);
2161
2097
  }
2162
2098
  const addButton = new Button(null, exports.LX.makeIcon('Plus', { svgClass: 'sm' }).innerHTML + 'Add item', (v, event) => {
2163
2099
  values.push(options.innerValues ? options.innerValues[0] : '');
2164
2100
  this._updateItems();
2165
2101
  this._trigger(new IEvent(name, values, event), callback);
2166
- }, { buttonClass: 'array' });
2102
+ }, { buttonClass: 'ghost' });
2167
2103
  arrayItems.appendChild(addButton.root);
2168
2104
  };
2169
2105
  this._updateItems();
@@ -2181,22 +2117,22 @@
2181
2117
  options.hideName = true;
2182
2118
  super(exports.ComponentType.CARD, name, null, options);
2183
2119
  this.root.classList.add('place-content-center');
2184
- const container = exports.LX.makeContainer(['100%', 'auto'], 'lexcard max-w-sm flex flex-col gap-4 bg-primary border rounded-xl py-6', '', this.root);
2120
+ const container = exports.LX.makeContainer(['100%', 'auto'], 'lexcard max-w-sm flex flex-col gap-4 bg-card border-color rounded-xl py-6', '', this.root);
2185
2121
  if (options.header) {
2186
2122
  const hasAction = options.header.action !== undefined;
2187
2123
  let header = exports.LX.makeContainer(['100%', 'auto'], `flex ${hasAction ? 'flex-row gap-4' : 'flex-col gap-1'} px-6`, '', container);
2188
2124
  if (hasAction) {
2189
- const actionBtn = new Button(null, options.header.action.name, options.header.action.callback);
2125
+ const actionBtn = new Button(null, options.header.action.name, options.header.action.callback, { buttonClass: 'secondary' });
2190
2126
  header.appendChild(actionBtn.root);
2191
2127
  const titleDescBox = exports.LX.makeContainer(['75%', 'auto'], `flex flex-col gap-1`, '');
2192
2128
  header.prepend(titleDescBox);
2193
2129
  header = titleDescBox;
2194
2130
  }
2195
2131
  if (options.header.title) {
2196
- exports.LX.makeElement('div', 'text-md leading-none font-semibold', options.header.title, header);
2132
+ exports.LX.makeElement('div', 'text-sm text-foreground leading-none font-semibold', options.header.title, header);
2197
2133
  }
2198
2134
  if (options.header.description) {
2199
- exports.LX.makeElement('div', 'text-sm fg-tertiary', options.header.description, header);
2135
+ exports.LX.makeElement('div', 'text-xs text-muted-foreground', options.header.description, header);
2200
2136
  }
2201
2137
  }
2202
2138
  if (options.content) {
@@ -2254,24 +2190,19 @@
2254
2190
  container.style.width = options.inputWidth ?? `calc( 100% - ${realNameWidth})`;
2255
2191
  };
2256
2192
  var container = document.createElement('div');
2257
- container.className = 'lexcheckboxcont';
2193
+ container.className = 'flex items-center gap-2 my-0 mx-auto [&_span]:truncate [&_span]:flex-auto-fill';
2258
2194
  this.root.appendChild(container);
2259
- let checkbox = document.createElement('input');
2195
+ let checkbox = exports.LX.makeElement('input', exports.LX.mergeClass('lexcheckbox rounded-xl', options.className ?? 'primary'));
2260
2196
  checkbox.type = 'checkbox';
2261
- checkbox.className = 'lexcheckbox ' + (options.className ?? 'primary');
2262
2197
  checkbox.checked = value;
2263
2198
  checkbox.disabled = options.disabled ?? false;
2264
2199
  container.appendChild(checkbox);
2265
- let valueName = document.createElement('span');
2266
- valueName.className = 'checkboxtext';
2267
- valueName.innerHTML = options.label ?? 'On';
2268
- container.appendChild(valueName);
2200
+ exports.LX.makeElement('span', 'text-sm', options.label ?? 'On', container);
2269
2201
  checkbox.addEventListener('change', (e) => {
2270
2202
  this.set(checkbox.checked, false, e);
2271
2203
  });
2272
2204
  if (options.suboptions) {
2273
- let suboptions = document.createElement('div');
2274
- suboptions.className = 'lexcheckboxsubmenu';
2205
+ let suboptions = exports.LX.makeElement('div', 'lexcheckboxsubmenu');
2275
2206
  suboptions.toggleAttribute('hidden', !checkbox.checked);
2276
2207
  const suboptionsPanel = new exports.LX.Panel();
2277
2208
  suboptionsPanel.queue(suboptions);
@@ -2382,20 +2313,17 @@
2382
2313
  if (!this.callback) {
2383
2314
  console.warn('Define a callback in _options.onChange_ to allow getting new Color values!');
2384
2315
  }
2385
- this.root = document.createElement('div');
2386
- this.root.className = 'lexcolorpicker';
2316
+ this.root = exports.LX.makeElement('div', 'lexcolorpicker flex flex-col text-sm w-3xs gap-2 p-1');
2387
2317
  this.markerHalfSize = 8;
2388
2318
  this.markerSize = this.markerHalfSize * 2;
2389
2319
  this.currentColor = new Color(hexValue);
2390
2320
  const hueColor = new Color({ h: this.currentColor.hsv.h, s: 1, v: 1 });
2321
+ const colorMarkerClass = 'size-4 rounded-lg bg-transparent absolute pointer-events-none border-3 border-solid border-white';
2391
2322
  // Intensity, Sat
2392
- this.colorPickerBackground = document.createElement('div');
2393
- this.colorPickerBackground.className = 'lexcolorpickerbg';
2394
- this.colorPickerBackground.style.backgroundColor =
2395
- `rgb(${hueColor.css.r}, ${hueColor.css.g}, ${hueColor.css.b})`;
2323
+ this.colorPickerBackground = exports.LX.makeElement('div', 'lexcolorpickerbg w-full aspect-square relative rounded-md cursor-pointer');
2324
+ this.colorPickerBackground.style.backgroundColor = `rgb(${hueColor.css.r}, ${hueColor.css.g}, ${hueColor.css.b})`;
2396
2325
  this.root.appendChild(this.colorPickerBackground);
2397
- this.intSatMarker = document.createElement('div');
2398
- this.intSatMarker.className = 'lexcolormarker';
2326
+ this.intSatMarker = exports.LX.makeElement('div', colorMarkerClass);
2399
2327
  this.intSatMarker.style.backgroundColor = this.currentColor.hex;
2400
2328
  this.colorPickerBackground.appendChild(this.intSatMarker);
2401
2329
  let pickerRect = null;
@@ -2456,11 +2384,9 @@
2456
2384
  }
2457
2385
  const innerHueAlpha = exports.LX.makeContainer(['100%', '100%'], 'flex flex-col gap-2', '', hueAlphaContainer);
2458
2386
  // Hue
2459
- this.colorPickerTracker = document.createElement('div');
2460
- this.colorPickerTracker.className = 'lexhuetracker';
2387
+ this.colorPickerTracker = exports.LX.makeElement('div', 'lexhuetracker w-full h-4 rounded-lg relative cursor-pointer');
2461
2388
  innerHueAlpha.appendChild(this.colorPickerTracker);
2462
- this.hueMarker = document.createElement('div');
2463
- this.hueMarker.className = 'lexcolormarker';
2389
+ this.hueMarker = exports.LX.makeElement('div', colorMarkerClass);
2464
2390
  this.hueMarker.style.backgroundColor = `rgb(${hueColor.css.r}, ${hueColor.css.g}, ${hueColor.css.b})`;
2465
2391
  this.colorPickerTracker.appendChild(this.hueMarker);
2466
2392
  const _fromHueX = (hueX) => {
@@ -2468,8 +2394,7 @@
2468
2394
  this.currentColor.hsv.h = exports.LX.remapRange(hueX, 0, this.colorPickerTracker.offsetWidth - this.markerSize, 0, 360);
2469
2395
  const hueColor = new Color({ h: this.currentColor.hsv.h, s: 1, v: 1 });
2470
2396
  this.hueMarker.style.backgroundColor = `rgb(${hueColor.css.r}, ${hueColor.css.g}, ${hueColor.css.b})`;
2471
- this.colorPickerBackground.style.backgroundColor =
2472
- `rgb(${hueColor.css.r}, ${hueColor.css.g}, ${hueColor.css.b})`;
2397
+ this.colorPickerBackground.style.backgroundColor = `rgb(${hueColor.css.r}, ${hueColor.css.g}, ${hueColor.css.b})`;
2473
2398
  this._updateColorValue();
2474
2399
  };
2475
2400
  let hueTrackerRect = null;
@@ -2504,13 +2429,10 @@
2504
2429
  this.colorPickerTracker.addEventListener('mousedown', innerMouseDownHue);
2505
2430
  // Alpha
2506
2431
  if (this.useAlpha) {
2507
- this.alphaTracker = document.createElement('div');
2508
- this.alphaTracker.className = 'lexalphatracker';
2509
- this.alphaTracker.style.color =
2510
- `rgb(${this.currentColor.css.r}, ${this.currentColor.css.g}, ${this.currentColor.css.b})`;
2432
+ this.alphaTracker = exports.LX.makeElement('div', 'lexalphatracker w-full h-4 rounded-lg relative cursor-pointer');
2433
+ this.alphaTracker.style.color = `rgb(${this.currentColor.css.r}, ${this.currentColor.css.g}, ${this.currentColor.css.b})`;
2511
2434
  innerHueAlpha.appendChild(this.alphaTracker);
2512
- this.alphaMarker = document.createElement('div');
2513
- this.alphaMarker.className = 'lexcolormarker';
2435
+ this.alphaMarker = exports.LX.makeElement('div', colorMarkerClass);
2514
2436
  this.alphaMarker.style.backgroundColor =
2515
2437
  `rgb(${this.currentColor.css.r}, ${this.currentColor.css.g}, ${this.currentColor.css.b},${this.currentColor.css.a})`;
2516
2438
  this.alphaTracker.appendChild(this.alphaMarker);
@@ -2572,7 +2494,7 @@
2572
2494
  copyButtonComponent.root.querySelector("input[type='checkbox']").style.pointerEvents = 'auto';
2573
2495
  }, 3000);
2574
2496
  }, { swap: 'Check', icon: 'Copy', buttonClass: 'bg-none', className: 'ml-auto', title: 'Copy' });
2575
- copyButtonComponent.root.querySelector('.swap-on svg').classList.add('fg-success');
2497
+ copyButtonComponent.root.querySelector('.swap-on svg').classList.add('text-success');
2576
2498
  colorLabel.appendChild(copyButtonComponent.root);
2577
2499
  }
2578
2500
  this._updateColorValue(hexValue, true);
@@ -2604,8 +2526,7 @@
2604
2526
  }
2605
2527
  this.intSatMarker.style.backgroundColor = this.currentColor.hex;
2606
2528
  if (this.useAlpha) {
2607
- this.alphaTracker.style.color =
2608
- `rgb(${this.currentColor.css.r}, ${this.currentColor.css.g}, ${this.currentColor.css.b})`;
2529
+ this.alphaTracker.style.color = `rgb(${this.currentColor.css.r}, ${this.currentColor.css.g}, ${this.currentColor.css.b})`;
2609
2530
  }
2610
2531
  const toFixed = (s, n = 2) => {
2611
2532
  return s.toFixed(n).replace(/([0-9]+(\.[0-9]+[1-9])?)(\.?0+$)/, '$1');
@@ -2642,9 +2563,8 @@
2642
2563
  this.hueMarker.style.backgroundColor =
2643
2564
  this.colorPickerBackground.style.backgroundColor =
2644
2565
  `rgb(${hueColor.css.r}, ${hueColor.css.g}, ${hueColor.css.b})`;
2645
- this.hueMarker.style.left =
2646
- exports.LX.remapRange(h, 0, 360, -this.markerHalfSize, this.colorPickerTracker.offsetWidth - this.markerHalfSize)
2647
- + 'px';
2566
+ this.hueMarker.style.left = exports.LX.remapRange(h, 0, 360, -this.markerHalfSize, this.colorPickerTracker.offsetWidth - this.markerHalfSize)
2567
+ + 'px';
2648
2568
  this._updateColorValue(hexColor);
2649
2569
  }
2650
2570
  }
@@ -2683,10 +2603,9 @@
2683
2603
  this.alignOffset = options.alignOffset ?? this.alignOffset;
2684
2604
  this.avoidCollisions = options.avoidCollisions ?? true;
2685
2605
  this.reference = options.reference;
2686
- this.root = document.createElement('div');
2606
+ this.root = exports.LX.makeElement('div', 'lexpopover fixed bg-background rounded-lg border-color p-1 left-0 top-0');
2687
2607
  this.root.dataset['side'] = this.side;
2688
2608
  this.root.tabIndex = '1';
2689
- this.root.className = 'lexpopover';
2690
2609
  const refElement = trigger ?? this.reference;
2691
2610
  const nestedDialog = refElement.closest('dialog');
2692
2611
  if (nestedDialog && nestedDialog.dataset['modal'] == 'true') {
@@ -2819,11 +2738,11 @@
2819
2738
  const popoverContainer = exports.LX.makeContainer(['auto', 'auto'], 'tour-step-container');
2820
2739
  {
2821
2740
  const headerDiv = exports.LX.makeContainer(['100%', 'auto'], 'flex flex-row', '', popoverContainer);
2822
- exports.LX.makeContainer(['100%', 'auto'], 'p-1 font-medium text-md', title, headerDiv);
2741
+ exports.LX.makeContainer(['100%', 'auto'], 'p-1 font-medium text-base', title, headerDiv);
2823
2742
  }
2824
- exports.LX.makeContainer(['100%', 'auto'], 'p-1 text-md', content, popoverContainer, { maxWidth: '400px' });
2825
- const footer = exports.LX.makeContainer(['100%', 'auto'], 'flex flex-row text-md', '', popoverContainer);
2826
- const footerButtons = exports.LX.makeContainer(['100%', 'auto'], 'text-md', '', footer);
2743
+ exports.LX.makeContainer(['100%', 'auto'], 'p-1 text-base', content, popoverContainer, { maxWidth: '400px' });
2744
+ const footer = exports.LX.makeContainer(['100%', 'auto'], 'flex flex-row text-base', '', popoverContainer);
2745
+ const footerButtons = exports.LX.makeContainer(['100%', 'auto'], 'text-base', '', footer);
2827
2746
  const footerPanel = new exports.LX.Panel();
2828
2747
  footerButtons.appendChild(footerPanel.root);
2829
2748
  footerPanel.sameLine(2, 'justify-end');
@@ -2831,7 +2750,7 @@
2831
2750
  if (onCancel)
2832
2751
  onCancel();
2833
2752
  this._popover?.destroy();
2834
- }, { xbuttonClass: 'contrast' });
2753
+ });
2835
2754
  footerPanel.addButton(null, okText, () => {
2836
2755
  if (onConfirm)
2837
2756
  onConfirm();
@@ -2860,12 +2779,15 @@
2860
2779
  _popover = undefined;
2861
2780
  constructor(name, value, callback, options = {}) {
2862
2781
  value = value ?? '#000000';
2782
+ // Force always hex internally
2783
+ if (value.constructor === String && value.includes('oklch')) {
2784
+ value = exports.LX.oklchToHex(value);
2785
+ }
2863
2786
  const useAlpha = options.useAlpha
2864
2787
  ?? ((value.constructor === Object && 'a' in value)
2865
2788
  || (value.constructor === String && [5, 9].includes(value.length)));
2866
2789
  const componentColor = new Color(value);
2867
- // Force always hex internally
2868
- value = useAlpha ? componentColor.hex : componentColor.hex.substr(0, 7);
2790
+ value = useAlpha ? componentColor.hex : componentColor.hex.substring(0, 7);
2869
2791
  super(exports.ComponentType.COLOR, name, value, options);
2870
2792
  this.onGetValue = () => {
2871
2793
  const currentColor = new Color(value);
@@ -2873,7 +2795,7 @@
2873
2795
  };
2874
2796
  this.onSetValue = (newValue, skipCallback, event) => {
2875
2797
  const newColor = new Color(newValue);
2876
- colorSampleRGB.style.color = value = newColor.hex.substr(0, 7);
2798
+ colorSampleRGB.style.color = value = newColor.hex.substring(0, 7);
2877
2799
  if (useAlpha) {
2878
2800
  colorSampleAlpha.style.color = value = newColor.hex;
2879
2801
  }
@@ -2905,7 +2827,7 @@
2905
2827
  this.set(color.hex);
2906
2828
  }
2907
2829
  });
2908
- let sampleContainer = exports.LX.makeContainer(['18px', '18px'], 'flex flex-row bg-contrast rounded overflow-hidden', '', container);
2830
+ let sampleContainer = exports.LX.makeContainer(['18px', '18px'], 'flex flex-row rounded overflow-hidden', '', container);
2909
2831
  sampleContainer.tabIndex = '1';
2910
2832
  sampleContainer.addEventListener('click', (e) => {
2911
2833
  if ((options.disabled ?? false)) {
@@ -2952,42 +2874,18 @@
2952
2874
  const shouldSelect = !(options.noSelection ?? false);
2953
2875
  let shouldToggle = shouldSelect && (options.toggle ?? false);
2954
2876
  let container = document.createElement('div');
2955
- container.className = 'lexcombobuttons ';
2877
+ container.className = 'lexcombobuttons flex justify-center';
2956
2878
  options.skipReset = true;
2957
2879
  if (options.float) {
2958
- container.className += options.float;
2880
+ container.className = exports.LX.mergeClass(container.className, `justify-${options.float}`);
2959
2881
  }
2960
2882
  let currentValue = [];
2961
- let buttonsBox = document.createElement('div');
2962
- buttonsBox.className = 'lexcombobuttonsbox ';
2963
- container.appendChild(buttonsBox);
2883
+ let buttonsBox = exports.LX.makeElement('div', 'flex w-max bg-secondary pad-sm rounded-lg gap-1', '', container);
2964
2884
  for (let b of values) {
2965
2885
  if (!b.value) {
2966
2886
  throw ("Set 'value' for each button!");
2967
2887
  }
2968
- let buttonEl = document.createElement('button');
2969
- buttonEl.className = 'lexbutton combo';
2970
- buttonEl.title = b.icon ? b.value : '';
2971
- buttonEl.id = b.id ?? '';
2972
- buttonEl.dataset['value'] = b.value;
2973
- if (options.buttonClass) {
2974
- buttonEl.classList.add(options.buttonClass);
2975
- }
2976
- if (shouldSelect && (b.selected || options.selected?.includes(b.value))) {
2977
- buttonEl.classList.add('selected');
2978
- currentValue = currentValue.concat([b.value]);
2979
- }
2980
- if (b.icon) {
2981
- const icon = exports.LX.makeIcon(b.icon);
2982
- buttonEl.appendChild(icon);
2983
- }
2984
- else {
2985
- buttonEl.innerHTML = `<span>${b.value}</span>`;
2986
- }
2987
- if (b.disabled) {
2988
- buttonEl.setAttribute('disabled', 'true');
2989
- }
2990
- buttonEl.addEventListener('click', (e) => {
2888
+ const onClick = (event) => {
2991
2889
  currentValue = [];
2992
2890
  if (shouldSelect) {
2993
2891
  if (shouldToggle) {
@@ -3009,7 +2907,20 @@
3009
2907
  }
3010
2908
  currentValue = currentValue[0];
3011
2909
  this.set(b.value, false, buttonEl.classList.contains('selected'));
2910
+ };
2911
+ const button = new Button(b.name ?? null, b.value, onClick, {
2912
+ title: b.icon ? b.value : '',
2913
+ icon: b.icon,
2914
+ disabled: b.disabled,
2915
+ buttonClass: exports.LX.mergeClass('combo w-auto', options.buttonClass)
3012
2916
  });
2917
+ let buttonEl = button.root.querySelector('button');
2918
+ buttonEl.id = b.id ?? '';
2919
+ buttonEl.dataset['value'] = b.value;
2920
+ if (shouldSelect && (b.selected || options.selected?.includes(b.value))) {
2921
+ buttonEl.classList.add('selected');
2922
+ currentValue = currentValue.concat([b.value]);
2923
+ }
3013
2924
  buttonsBox.appendChild(buttonEl);
3014
2925
  }
3015
2926
  if (currentValue.length > 1) {
@@ -3075,9 +2986,9 @@
3075
2986
  const max = options.max ?? 100;
3076
2987
  const step = options.step ?? 1;
3077
2988
  const container = document.createElement('div');
3078
- container.className = 'flex flex-row border bg-primary rounded-lg shadow';
2989
+ container.className = 'flex flex-row border-color bg-card rounded-lg shadow';
3079
2990
  this.root.appendChild(container);
3080
- const input = exports.LX.makeElement('input', 'lexcounter w-12 bg-primary px-2 fg-primary', '', container);
2991
+ const input = exports.LX.makeElement('input', 'lexcounter w-12 bg-card px-2 text-foreground', '', container);
3081
2992
  input.type = 'number';
3082
2993
  input.value = value;
3083
2994
  if (options.disabled) {
@@ -3088,9 +2999,8 @@
3088
2999
  if (e.shiftKey)
3089
3000
  mult *= 10;
3090
3001
  this.set(this.count - mult, false, e);
3091
- }, { disabled: options.disabled,
3092
- className: `p-0 ${options.disabled ? '' : 'hover:bg-secondary'} border-left border-right`,
3093
- buttonClass: 'bg-none', icon: 'Minus' });
3002
+ }, { disabled: options.disabled, className: `p-0 ${options.disabled ? '' : 'hover:bg-secondary'} border-l-color border-r-color`,
3003
+ buttonClass: 'px-0 bg-none h-7', icon: 'Minus' });
3094
3004
  container.appendChild(substrButton.root);
3095
3005
  const addButton = new Button(null, '', (value, e) => {
3096
3006
  let mult = step ?? 1;
@@ -3098,7 +3008,7 @@
3098
3008
  mult *= 10;
3099
3009
  this.set(this.count + mult, false, e);
3100
3010
  }, { disabled: options.disabled, className: `p-0 ${options.disabled ? '' : 'hover:bg-secondary'} rounded-r-lg`,
3101
- buttonClass: 'bg-none', icon: 'Plus' });
3011
+ buttonClass: 'px-0 bg-none h-7', icon: 'Plus' });
3102
3012
  container.appendChild(addButton.root);
3103
3013
  }
3104
3014
  }
@@ -3114,14 +3024,14 @@
3114
3024
  canvas;
3115
3025
  constructor(value, options = {}) {
3116
3026
  let element = document.createElement('div');
3117
- element.className = 'curve ' + (options.className ? options.className : '');
3027
+ element.className = exports.LX.mergeClass('curve [&_canvas]:rounded', options.className);
3118
3028
  element.style.minHeight = '50px';
3119
3029
  element.style.width = options.width || '100%';
3120
3030
  element.style.minWidth = '50px';
3121
3031
  element.style.minHeight = '20px';
3122
- element.bgcolor = options.bgColor || exports.LX.getThemeColor('global-background');
3123
- element.pointscolor = options.pointsColor || exports.LX.getThemeColor('global-color-accent');
3124
- element.activepointscolor = options.activePointsColor || exports.LX.getThemeColor('global-color-accent-light');
3032
+ element.bgcolor = options.bgColor || exports.LX.getCSSVariable('background');
3033
+ element.pointscolor = options.pointsColor || exports.LX.getCSSVariable('primary');
3034
+ element.activepointscolor = options.activePointsColor || exports.LX.getCSSVariable('primary/50');
3125
3035
  element.linecolor = options.lineColor || '#555';
3126
3036
  element.value = value || [];
3127
3037
  element.xrange = options.xrange || [0, 1]; // min, max
@@ -3135,9 +3045,9 @@
3135
3045
  element.smooth = (options.smooth && typeof (options.smooth) == 'number' ? options.smooth : 0.3) || false;
3136
3046
  element.move_out = options.moveOutAction ?? exports.LX.CURVE_MOVEOUT_DELETE;
3137
3047
  exports.LX.addSignal('@on_new_color_scheme', (el, value) => {
3138
- element.bgcolor = options.bgColor || exports.LX.getThemeColor('global-background');
3139
- element.pointscolor = options.pointsColor || exports.LX.getThemeColor('global-color-accent');
3140
- element.activepointscolor = options.activePointsColor || exports.LX.getThemeColor('global-color-accent-light');
3048
+ element.bgcolor = options.bgColor || exports.LX.getCSSVariable('background');
3049
+ element.pointscolor = options.pointsColor || exports.LX.getCSSVariable('primary');
3050
+ element.activepointscolor = options.activePointsColor || exports.LX.getCSSVariable('primary/50');
3141
3051
  this.redraw();
3142
3052
  });
3143
3053
  this.element = element;
@@ -3194,8 +3104,7 @@
3194
3104
  }
3195
3105
  // Canvas to value
3196
3106
  function unconvert(v) {
3197
- return [v[0] * element.xrange[1] / canvas.width + element.xrange[0],
3198
- v[1] * element.yrange[1] / canvas.height + element.yrange[0]];
3107
+ return [v[0] * element.xrange[1] / canvas.width + element.xrange[0], v[1] * element.yrange[1] / canvas.height + element.yrange[0]];
3199
3108
  }
3200
3109
  let selected = -1;
3201
3110
  element.redraw = function (o = {}) {
@@ -3472,7 +3381,7 @@
3472
3381
  onPreviousMonth;
3473
3382
  onNextMonth;
3474
3383
  constructor(dateString, options = {}) {
3475
- this.root = exports.LX.makeContainer(['256px', 'auto'], 'p-1 text-md');
3384
+ this.root = exports.LX.makeContainer(['256px', 'auto'], 'p-1 flex flex-col gap-2 text-sm');
3476
3385
  this.onChange = options.onChange;
3477
3386
  this.onPreviousMonth = options.onPreviousMonth;
3478
3387
  this.onNextMonth = options.onNextMonth;
@@ -3527,8 +3436,8 @@
3527
3436
  {
3528
3437
  const header = exports.LX.makeContainer(['100%', 'auto'], 'flex flex-row p-1', '', this.root);
3529
3438
  if (!this.skipPrevMonth) {
3530
- const prevMonthIcon = exports.LX.makeIcon('Left', { title: 'Previous Month',
3531
- iconClass: 'border p-1 rounded hover:bg-secondary', svgClass: 'sm' });
3439
+ const prevMonthIcon = exports.LX.makeIcon('Left', { title: 'Previous Month', iconClass: 'border-color p-1 rounded hover:bg-secondary',
3440
+ svgClass: 'sm' });
3532
3441
  header.appendChild(prevMonthIcon);
3533
3442
  prevMonthIcon.addEventListener('click', () => {
3534
3443
  this._previousMonth();
@@ -3536,8 +3445,8 @@
3536
3445
  }
3537
3446
  exports.LX.makeContainer(['100%', 'auto'], 'text-center font-medium select-none', `${this.monthName} ${this.year}`, header);
3538
3447
  if (!this.skipNextMonth) {
3539
- const nextMonthIcon = exports.LX.makeIcon('Right', { title: 'Next Month',
3540
- iconClass: 'border p-1 rounded hover:bg-secondary', svgClass: 'sm' });
3448
+ const nextMonthIcon = exports.LX.makeIcon('Right', { title: 'Next Month', iconClass: 'border-color p-1 rounded hover:bg-secondary',
3449
+ svgClass: 'sm' });
3541
3450
  header.appendChild(nextMonthIcon);
3542
3451
  nextMonthIcon.addEventListener('click', () => {
3543
3452
  this._nextMonth();
@@ -3556,7 +3465,7 @@
3556
3465
  const hrow = document.createElement('tr');
3557
3466
  for (const headData of ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su']) {
3558
3467
  const th = document.createElement('th');
3559
- th.className = 'fg-tertiary text-sm font-normal select-none';
3468
+ th.className = 'text-muted-foreground text-xs font-normal w-10 select-none';
3560
3469
  th.innerHTML = `<span>${headData}</span>`;
3561
3470
  hrow.appendChild(th);
3562
3471
  }
@@ -3573,7 +3482,7 @@
3573
3482
  const weekDays = this.calendarDays.slice(week * 7, week * 7 + 7);
3574
3483
  for (const dayData of weekDays) {
3575
3484
  const th = document.createElement('th');
3576
- th.className = 'leading-loose font-normal rounded select-none cursor-pointer';
3485
+ th.className = 'leading-8 text-xs font-normal rounded select-none cursor-pointer shrink-0 grow-0';
3577
3486
  const dayDate = new Date(`${this.month}/${dayData.day}/${this.year}`);
3578
3487
  const date = new Date();
3579
3488
  // today inclusives
@@ -3597,13 +3506,13 @@
3597
3506
  && (this.month == (toRangeDate.getMonth() + 1))
3598
3507
  && (this.year == toRangeDate.getFullYear());
3599
3508
  if ((!this.range && currentDay) || this.range && (currentFromRange || currentToRange)) {
3600
- th.className += ` bg-contrast fg-contrast`;
3509
+ th.className += ` bg-primary text-primary-foreground`;
3601
3510
  }
3602
3511
  else if (this.range && selectable && (dayDate > fromRangeDate) && (dayDate < toRangeDate)) {
3603
- th.className += ` bg-accent fg-contrast`;
3512
+ th.className += ` bg-accent text-accent-foreground`;
3604
3513
  }
3605
3514
  else {
3606
- th.className += ` ${selectable ? 'fg-primary' : 'fg-tertiary'} hover:bg-secondary`;
3515
+ th.className += ` ${selectable ? 'text-secondary-foreground' : 'text-muted-foreground'} hover:bg-secondary`;
3607
3516
  }
3608
3517
  th.innerHTML = `<span>${dayData.day}</span>`;
3609
3518
  hrow.appendChild(th);
@@ -3847,7 +3756,7 @@
3847
3756
  const calendarIcon = exports.LX.makeIcon('Calendar');
3848
3757
  const calendarButton = new Button(null, d0, () => {
3849
3758
  this._popover = new Popover(calendarButton.root, [this.calendar]);
3850
- }, { buttonClass: `flex flex-row px-3 ${emptyDate ? '' : 'fg-tertiary'} justify-between` });
3759
+ }, { buttonClass: `outline flex flex-row px-3 ${emptyDate ? '' : 'text-muted-foreground'} justify-between` });
3851
3760
  calendarButton.root.querySelector('button').appendChild(calendarIcon);
3852
3761
  calendarButton.root.style.width = '100%';
3853
3762
  container.appendChild(calendarButton.root);
@@ -3858,7 +3767,7 @@
3858
3767
  const calendarIcon = exports.LX.makeIcon('Calendar');
3859
3768
  const calendarButton = new Button(null, d1, () => {
3860
3769
  this._popover = new Popover(calendarButton.root, [this.calendar]);
3861
- }, { buttonClass: `flex flex-row px-3 ${emptyDate ? '' : 'fg-tertiary'} justify-between` });
3770
+ }, { buttonClass: `outline flex flex-row px-3 ${emptyDate ? '' : 'text-muted-foreground'} justify-between` });
3862
3771
  calendarButton.root.querySelector('button').appendChild(calendarIcon);
3863
3772
  calendarButton.root.style.width = '100%';
3864
3773
  container.appendChild(calendarButton.root);
@@ -3887,11 +3796,11 @@
3887
3796
  canvas;
3888
3797
  constructor(value, options = {}) {
3889
3798
  let element = document.createElement('div');
3890
- element.className = 'dial ' + (options.className ? options.className : '');
3799
+ element.className = exports.LX.mergeClass('dial', options.className);
3891
3800
  element.style.width = element.style.height = options.size || '100%';
3892
3801
  element.style.minWidth = element.style.minHeight = '50px';
3893
- element.bgcolor = options.bgColor || exports.LX.getThemeColor('global-background');
3894
- element.pointscolor = options.pointsColor || exports.LX.getThemeColor('global-color-accent-light');
3802
+ element.bgcolor = options.bgColor || exports.LX.getCSSVariable('background');
3803
+ element.pointscolor = options.pointsColor || exports.LX.getCSSVariable('primary/50');
3895
3804
  element.linecolor = options.lineColor || '#555';
3896
3805
  element.value = value || [];
3897
3806
  element.xrange = options.xrange || [0, 1]; // min, max
@@ -3905,8 +3814,8 @@
3905
3814
  element.smooth = (options.smooth && typeof (options.smooth) == 'number' ? options.smooth : 0.3) || false;
3906
3815
  element.move_out = options.moveOutAction ?? exports.LX.CURVE_MOVEOUT_DELETE;
3907
3816
  exports.LX.addSignal('@on_new_color_scheme', (el, value) => {
3908
- element.bgcolor = options.bgColor || exports.LX.getThemeColor('global-background');
3909
- element.pointscolor = options.pointsColor || exports.LX.getThemeColor('global-color-accent-light');
3817
+ element.bgcolor = options.bgColor || exports.LX.getCSSVariable('background');
3818
+ element.pointscolor = options.pointsColor || exports.LX.getCSSVariable('primary/50');
3910
3819
  this.redraw();
3911
3820
  });
3912
3821
  this.element = element;
@@ -3962,8 +3871,7 @@
3962
3871
  }
3963
3872
  // Canvas to value
3964
3873
  function unconvert(v) {
3965
- return [v[0] * element.xrange[1] / canvas.width + element.xrange[0],
3966
- v[1] * element.yrange[1] / canvas.height + element.yrange[0]];
3874
+ return [v[0] * element.xrange[1] / canvas.width + element.xrange[0], v[1] * element.yrange[1] / canvas.height + element.yrange[0]];
3967
3875
  }
3968
3876
  var selected = -1;
3969
3877
  element.redraw = function (o = {}) {
@@ -4320,7 +4228,7 @@
4320
4228
  }
4321
4229
  };
4322
4230
  let container = document.createElement('div');
4323
- container.className = 'lexformdata';
4231
+ container.className = 'flex flex-col gap-1';
4324
4232
  container.style.width = '100%';
4325
4233
  container.formData = {};
4326
4234
  this.root.appendChild(container);
@@ -4336,7 +4244,7 @@
4336
4244
  entryData.ignoreValidation = true;
4337
4245
  if (!(options.skipLabels ?? false)) {
4338
4246
  const label = new TextInput(null, entryData.label ?? entry, null, { disabled: true,
4339
- inputClass: 'formlabel bg-none' });
4247
+ inputClass: 'formlabel text-xs bg-none text-muted-foreground' });
4340
4248
  container.appendChild(label.root);
4341
4249
  }
4342
4250
  entryData.textComponent = new TextInput(null, entryData.constructor == Object ? entryData.value : entryData, (value, event) => {
@@ -4354,7 +4262,7 @@
4354
4262
  if (options.secondaryActionCallback) {
4355
4263
  options.secondaryActionCallback(container.formData, event);
4356
4264
  }
4357
- }, { width: '100%', minWidth: '0', buttonClass: options.secondaryButtonClass ?? 'primary' });
4265
+ }, { width: '100%', minWidth: '0', buttonClass: options.secondaryButtonClass ?? 'secondary' });
4358
4266
  buttonContainer.appendChild(secondaryButton.root);
4359
4267
  }
4360
4268
  const primaryButton = new Button(null, options.primaryActionName ?? 'Submit', (value, event) => {
@@ -4374,7 +4282,7 @@
4374
4282
  if (callback) {
4375
4283
  callback(container.formData, errors, event);
4376
4284
  }
4377
- }, { width: '100%', minWidth: '0', buttonClass: options.primaryButtonClass ?? 'contrast' });
4285
+ }, { width: '100%', minWidth: '0', buttonClass: options.primaryButtonClass ?? 'primary' });
4378
4286
  buttonContainer.appendChild(primaryButton.root);
4379
4287
  }
4380
4288
  }
@@ -4403,9 +4311,7 @@
4403
4311
  const realNameWidth = this.root.domName?.style.width ?? '0px';
4404
4312
  container.style.width = `calc( 100% - ${realNameWidth})`;
4405
4313
  };
4406
- const container = document.createElement('div');
4407
- container.className = 'lexlayers';
4408
- this.root.appendChild(container);
4314
+ const container = exports.LX.makeElement('div', 'lexlayers grid', '', this.root);
4409
4315
  const maxBits = options.maxBits ?? 16;
4410
4316
  this.setLayers = (val) => {
4411
4317
  container.innerHTML = '';
@@ -4417,7 +4323,8 @@
4417
4323
  }
4418
4324
  for (let bit = 0; bit < maxBits; ++bit) {
4419
4325
  let layer = document.createElement('div');
4420
- layer.className = 'lexlayer';
4326
+ layer.className =
4327
+ 'lexlayer size-6 text-secondary-foreground text-center content-center place-self-center cursor-pointer font-semibold text-xs rounded-lg';
4421
4328
  if (val != undefined) {
4422
4329
  const valueBit = binary[maxBits - bit - 1];
4423
4330
  if (valueBit != undefined && valueBit == '1') {
@@ -4505,7 +4412,7 @@
4505
4412
  };
4506
4413
  // Show list
4507
4414
  let listContainer = document.createElement('div');
4508
- listContainer.className = 'lexlist';
4415
+ listContainer.className = 'bg-background flex flex-col gap-1 rounded-xl border-color p-2';
4509
4416
  this.root.appendChild(listContainer);
4510
4417
  this._updateValues(values);
4511
4418
  exports.LX.doAsync(this.onResize.bind(this));
@@ -4951,7 +4858,7 @@
4951
4858
  const calendarIcon = exports.LX.makeIcon('SquareMousePointer');
4952
4859
  const calendarButton = new Button(null, 'Open Map', () => {
4953
4860
  this._popover = new Popover(calendarButton.root, [this.map2d]);
4954
- }, { buttonClass: `flex flex-row px-3 fg-secondary justify-between` });
4861
+ }, { buttonClass: `outline justify-between` });
4955
4862
  calendarButton.root.querySelector('button').appendChild(calendarIcon);
4956
4863
  container.appendChild(calendarButton.root);
4957
4864
  exports.LX.doAsync(this.onResize.bind(this));
@@ -4966,14 +4873,13 @@
4966
4873
  class NodeTree {
4967
4874
  domEl;
4968
4875
  data;
4969
- onevent;
4970
4876
  options;
4971
4877
  selected = [];
4972
4878
  _forceClose = false;
4879
+ _callbacks = {};
4973
4880
  constructor(domEl, data, options = {}) {
4974
4881
  this.domEl = domEl;
4975
4882
  this.data = data;
4976
- this.onevent = options.onevent;
4977
4883
  this.options = options;
4978
4884
  if (data.constructor === Object) {
4979
4885
  this._createItem(null, data);
@@ -5007,8 +4913,8 @@
5007
4913
  isParent = !!hasFolders;
5008
4914
  }
5009
4915
  let item = document.createElement('li');
5010
- item.className = 'lextreeitem ' + 'datalevel' + level + (isParent ? ' parent' : '')
5011
- + (isSelected ? ' selected' : '');
4916
+ item.className =
4917
+ `lextreeitem inline-flex outline-none text-sm items-center h-7 cursor-pointer truncate rounded-lg select-none datalevel${level} ${isParent ? 'parent' : ''} ${isSelected ? ' selected' : ''}`;
5012
4918
  item.id = exports.LX.getSupportedDOMName(node.id);
5013
4919
  item.tabIndex = '0';
5014
4920
  item.treeData = node;
@@ -5018,7 +4924,7 @@
5018
4924
  icon = node.closed ? 'Right' : 'Down';
5019
4925
  }
5020
4926
  if (icon) {
5021
- item.appendChild(exports.LX.makeIcon(icon, { iconClass: 'hierarchy', svgClass: 'xs' }));
4927
+ item.appendChild(exports.LX.makeIcon(icon, { iconClass: 'hierarchy', svgClass: 'sm' }));
5022
4928
  }
5023
4929
  // Add display icon
5024
4930
  icon = node.icon;
@@ -5033,13 +4939,15 @@
5033
4939
  // an image..
5034
4940
  else {
5035
4941
  const rootPath = 'https://raw.githubusercontent.com/jxarco/lexgui.js/master/';
5036
- item.innerHTML += "<img src='" + (rootPath + node.icon) + "'>";
4942
+ item.innerHTML += `<img src="${rootPath + node.icon}">`;
5037
4943
  }
5038
4944
  }
5039
4945
  item.innerHTML += node.rename ? '' : node.id;
5040
- item.setAttribute('draggable', true);
5041
4946
  item.style.paddingLeft = (3 + (level + 1) * 15) + 'px';
5042
4947
  list.appendChild(item);
4948
+ const isDraggable = parent && (node.metadata?.draggable ?? (this.options.defaultDraggable ?? true));
4949
+ if (isDraggable)
4950
+ item.setAttribute('draggable', 'true');
5043
4951
  // Callbacks
5044
4952
  item.addEventListener('click', (e) => {
5045
4953
  if (handled) {
@@ -5054,27 +4962,38 @@
5054
4962
  }
5055
4963
  // Add or remove
5056
4964
  const idx = this.selected.indexOf(node);
4965
+ item.classList.toggle('selected', idx == -1);
5057
4966
  if (idx > -1) {
5058
- item.classList.remove('selected');
5059
4967
  this.selected.splice(idx, 1);
5060
4968
  }
5061
4969
  else {
5062
- item.classList.add('selected');
5063
4970
  this.selected.push(node);
5064
4971
  }
5065
4972
  // Only Show children...
5066
4973
  if (isParent && node.id.length > 1 /* Strange case... */) {
5067
4974
  node.closed = false;
5068
- if (that.onevent) {
5069
- const event = new TreeEvent(TreeEvent.NODE_CARETCHANGED, node, node.closed, e);
5070
- that.onevent(event);
4975
+ const onCaretChanged = that._callbacks['caretChanged'];
4976
+ if (onCaretChanged !== undefined) {
4977
+ const event = {
4978
+ type: 'caret',
4979
+ items: [node],
4980
+ domEvent: e,
4981
+ userInitiated: true
4982
+ };
4983
+ onCaretChanged(event);
5071
4984
  }
5072
4985
  that.frefresh(node.id);
5073
4986
  }
5074
- if (that.onevent) {
5075
- const event = new TreeEvent(TreeEvent.NODE_SELECTED, node, this.selected, e);
5076
- event.multiple = e.shiftKey;
5077
- that.onevent(event);
4987
+ const onSelect = that._callbacks['select'];
4988
+ if (onSelect !== undefined) {
4989
+ const event = {
4990
+ type: 'select',
4991
+ items: [node],
4992
+ result: this.selected,
4993
+ domEvent: e,
4994
+ userInitiated: true
4995
+ };
4996
+ onSelect(event);
5078
4997
  }
5079
4998
  });
5080
4999
  item.addEventListener('dblclick', function (e) {
@@ -5083,27 +5002,40 @@
5083
5002
  node.rename = true;
5084
5003
  that.refresh();
5085
5004
  }
5086
- if (that.onevent) {
5087
- const event = new TreeEvent(TreeEvent.NODE_DBLCLICKED, node, null, e);
5088
- that.onevent(event);
5005
+ const onDblClick = that._callbacks['dblClick'];
5006
+ if (onDblClick !== undefined) {
5007
+ const event = {
5008
+ type: 'dbl_click',
5009
+ items: [node],
5010
+ domEvent: e,
5011
+ userInitiated: true
5012
+ };
5013
+ onDblClick(event);
5089
5014
  }
5090
5015
  });
5091
- item.addEventListener('contextmenu', (e) => {
5016
+ item.addEventListener('contextmenu', async (e) => {
5092
5017
  e.preventDefault();
5093
- if (!that.onevent) {
5018
+ const onContextMenu = that._callbacks['contextMenu'];
5019
+ if (!onContextMenu) {
5094
5020
  return;
5095
5021
  }
5096
- const event = new TreeEvent(TreeEvent.NODE_CONTEXTMENU, node, this.selected, e);
5097
- event.multiple = this.selected.length > 1;
5098
- exports.LX.addContextMenu(event.multiple ? 'Selected Nodes' : event.node.id, event.event, (m) => {
5099
- event.panel = m;
5100
- });
5101
- that.onevent(event);
5102
- if (this.options.addDefault ?? false) {
5103
- if (event.panel.items) {
5104
- event.panel.add('');
5022
+ const event = {
5023
+ type: 'context_menu',
5024
+ items: this.selected,
5025
+ from: node,
5026
+ domEvent: e,
5027
+ userInitiated: true
5028
+ };
5029
+ const r = await onContextMenu(event);
5030
+ const multiple = this.selected.length > 1;
5031
+ exports.LX.addContextMenu(multiple ? 'Selected Nodes' : node.id, e, (m) => {
5032
+ if (r?.length) {
5033
+ for (const i of r) {
5034
+ m.add(i.name, { callback: i.callback });
5035
+ }
5036
+ m.add('');
5105
5037
  }
5106
- event.panel.add('Select Children', () => {
5038
+ m.add('Select Children', () => {
5107
5039
  const selectChildren = (n) => {
5108
5040
  if (n.closed) {
5109
5041
  return;
@@ -5122,15 +5054,53 @@
5122
5054
  this.selected.length = 0;
5123
5055
  // Add childs of the clicked node
5124
5056
  selectChildren(node);
5057
+ const onSelect = this._callbacks['select'];
5058
+ if (onSelect !== undefined) {
5059
+ const event = {
5060
+ type: 'select',
5061
+ items: [node],
5062
+ result: this.selected,
5063
+ domEvent: e,
5064
+ userInitiated: true
5065
+ };
5066
+ onSelect(event);
5067
+ }
5125
5068
  });
5126
- event.panel.add('Delete', { callback: () => {
5127
- const ok = that.deleteNode(node);
5128
- if (ok && that.onevent) {
5129
- const event = new TreeEvent(TreeEvent.NODE_DELETED, node, [node], null);
5130
- that.onevent(event);
5069
+ m.add('Delete', { callback: () => {
5070
+ const onBeforeDelete = this._callbacks['beforeDelete'];
5071
+ const onDelete = this._callbacks['delete'];
5072
+ const resolve = (...args) => {
5073
+ let deletedNodes = [];
5074
+ if (this.selected.length) {
5075
+ deletedNodes.push(...that.deleteNodes(this.selected));
5076
+ }
5077
+ else if (that.deleteNode(node)) {
5078
+ deletedNodes.push(node);
5079
+ }
5080
+ this.refresh();
5081
+ const event = {
5082
+ type: 'delete',
5083
+ items: deletedNodes,
5084
+ userInitiated: true
5085
+ };
5086
+ if (onDelete)
5087
+ onDelete(event, ...args);
5088
+ };
5089
+ if (onBeforeDelete) {
5090
+ const event = {
5091
+ type: 'delete',
5092
+ items: this.selected.length ? this.selected : [node],
5093
+ userInitiated: true
5094
+ };
5095
+ onBeforeDelete(event, resolve);
5096
+ }
5097
+ else {
5098
+ resolve();
5131
5099
  }
5132
- this.refresh();
5133
5100
  } });
5101
+ });
5102
+ if (!(this.options.addDefault ?? false)) {
5103
+ return;
5134
5104
  }
5135
5105
  });
5136
5106
  item.addEventListener('keydown', (e) => {
@@ -5139,20 +5109,40 @@
5139
5109
  }
5140
5110
  e.preventDefault();
5141
5111
  if (e.key == 'Delete') {
5142
- const nodesDeleted = [];
5143
- for (let _node of this.selected) {
5144
- if (that.deleteNode(_node)) {
5145
- nodesDeleted.push(_node);
5112
+ const onBeforeDelete = this._callbacks['beforeDelete'];
5113
+ const onDelete = this._callbacks['delete'];
5114
+ const resolve = (...args) => {
5115
+ const nodesDeleted = [];
5116
+ for (let n of this.selected) {
5117
+ if (that.deleteNode(n)) {
5118
+ nodesDeleted.push(n);
5119
+ }
5146
5120
  }
5121
+ this.selected.length = 0;
5122
+ this.refresh();
5123
+ if (nodesDeleted.length) {
5124
+ const event = {
5125
+ type: 'delete',
5126
+ items: nodesDeleted,
5127
+ domEvent: e,
5128
+ userInitiated: true
5129
+ };
5130
+ if (onDelete)
5131
+ onDelete(event, ...args);
5132
+ }
5133
+ };
5134
+ if (onBeforeDelete) {
5135
+ const event = {
5136
+ type: 'delete',
5137
+ items: this.selected,
5138
+ domEvent: e,
5139
+ userInitiated: true
5140
+ };
5141
+ onBeforeDelete(event, resolve);
5147
5142
  }
5148
- // Send event now so we have the info in selected array..
5149
- if (nodesDeleted.length && that.onevent) {
5150
- const event = new TreeEvent(TreeEvent.NODE_DELETED, node, nodesDeleted, e);
5151
- event.multiple = nodesDeleted.length > 1;
5152
- that.onevent(event);
5143
+ else {
5144
+ resolve();
5153
5145
  }
5154
- this.selected.length = 0;
5155
- this.refresh();
5156
5146
  }
5157
5147
  else if (e.key == 'ArrowUp' || e.key == 'ArrowDown') { // Unique or zero selected
5158
5148
  var selected = this.selected.length > 1
@@ -5168,7 +5158,7 @@
5168
5158
  // Node rename
5169
5159
  const nameInput = document.createElement('input');
5170
5160
  nameInput.toggleAttribute('hidden', !node.rename);
5171
- nameInput.className = 'bg-none';
5161
+ nameInput.className = 'text-foreground bg-none text-sm border-none outline-none';
5172
5162
  nameInput.value = node.id;
5173
5163
  item.appendChild(nameInput);
5174
5164
  if (node.rename) {
@@ -5177,15 +5167,38 @@
5177
5167
  }
5178
5168
  nameInput.addEventListener('keyup', function (e) {
5179
5169
  if (e.key == 'Enter') {
5170
+ const onBeforeRename = that._callbacks['beforeRename'];
5171
+ const onRename = that._callbacks['rename'];
5172
+ const oldName = node.id;
5180
5173
  this.value = this.value.replace(/\s/g, '_');
5181
- if (that.onevent) {
5182
- const event = new TreeEvent(TreeEvent.NODE_RENAMED, node, this.value, e);
5183
- that.onevent(event);
5174
+ const resolve = (...args) => {
5175
+ node.id = exports.LX.getSupportedDOMName(this.value);
5176
+ delete node.rename;
5177
+ that.frefresh(node.id);
5178
+ list.querySelector(`#${node.id}`).classList.add('selected');
5179
+ const event = {
5180
+ type: 'rename',
5181
+ items: [node],
5182
+ oldName,
5183
+ newName: this.value,
5184
+ userInitiated: true
5185
+ };
5186
+ if (onRename)
5187
+ onRename(event, ...args);
5188
+ };
5189
+ if (onBeforeRename) {
5190
+ const event = {
5191
+ type: 'rename',
5192
+ items: [node],
5193
+ oldName,
5194
+ newName: this.value,
5195
+ userInitiated: true
5196
+ };
5197
+ onBeforeRename(event, resolve);
5198
+ }
5199
+ else {
5200
+ resolve();
5184
5201
  }
5185
- node.id = exports.LX.getSupportedDOMName(this.value);
5186
- delete node.rename;
5187
- that.frefresh(node.id);
5188
- list.querySelector('#' + node.id).classList.add('selected');
5189
5202
  }
5190
5203
  else if (e.key == 'Escape') {
5191
5204
  delete node.rename;
@@ -5196,69 +5209,90 @@
5196
5209
  delete node.rename;
5197
5210
  that.refresh();
5198
5211
  });
5199
- if (this.options.draggable ?? true) {
5200
- // Drag nodes
5201
- if (parent) { // Root doesn't move!
5202
- item.addEventListener('dragstart', (e) => {
5203
- window.__tree_node_dragged = node;
5204
- });
5205
- }
5206
- /* Events fired on other node items */
5207
- item.addEventListener('dragover', (e) => {
5208
- e.preventDefault(); // allow drop
5209
- }, false);
5210
- item.addEventListener('dragenter', (e) => {
5211
- e.target.classList.add('draggingover');
5212
- });
5213
- item.addEventListener('dragend', (e) => {
5214
- e.target.classList.remove('draggingover');
5212
+ if (isDraggable) {
5213
+ item.addEventListener('dragstart', (e) => {
5214
+ window.__tree_node_dragged = node;
5215
5215
  });
5216
- item.addEventListener('dragleave', (e) => {
5217
- e.target.classList.remove('draggingover');
5218
- });
5219
- item.addEventListener('drop', (e) => {
5220
- e.preventDefault(); // Prevent default action (open as link for some elements)
5221
- let dragged = window.__tree_node_dragged;
5222
- if (!dragged) {
5223
- // Test if we are moving from AssetView extension
5224
- dragged = window.__av_item_dragged;
5225
- if (dragged) {
5226
- dragged._nodeTarget = node;
5227
- }
5228
- return;
5229
- }
5230
- let target = node;
5231
- // Can't drop to same node
5232
- if (dragged.id == target.id) {
5233
- console.warn('Cannot parent node to itself!');
5234
- return;
5235
- }
5236
- // Can't drop to child node
5237
- const isChild = function (newParent, node) {
5238
- var result = false;
5239
- for (var c of node.children) {
5240
- if (c.id == newParent.id)
5241
- return true;
5242
- result = result || isChild(newParent, c);
5243
- }
5244
- return result;
5245
- };
5246
- if (isChild(target, dragged)) {
5247
- console.warn('Cannot parent node to a current child!');
5248
- return;
5216
+ }
5217
+ /* Events fired on other node items,
5218
+ by now everyone is a drop target, cancel in the event if necessary */
5219
+ item.addEventListener('dragover', (e) => {
5220
+ e.preventDefault(); // allow drop
5221
+ }, false);
5222
+ item.addEventListener('dragenter', (e) => {
5223
+ e.target.classList.add('draggingover');
5224
+ });
5225
+ item.addEventListener('dragend', (e) => {
5226
+ e.target.classList.remove('draggingover');
5227
+ });
5228
+ item.addEventListener('dragleave', (e) => {
5229
+ e.target.classList.remove('draggingover');
5230
+ });
5231
+ item.addEventListener('drop', (e) => {
5232
+ e.preventDefault(); // Prevent default action (open as link for some elements)
5233
+ let dragged = window.__tree_node_dragged;
5234
+ if (!dragged) {
5235
+ // Test if we are moving from AssetView extension
5236
+ dragged = window.__av_item_dragged;
5237
+ if (dragged) {
5238
+ dragged._nodeTarget = node;
5249
5239
  }
5250
- // Trigger node dragger event
5251
- if (that.onevent) {
5252
- const event = new TreeEvent(TreeEvent.NODE_DRAGGED, dragged, target, e);
5253
- that.onevent(event);
5240
+ return;
5241
+ }
5242
+ const domTarget = e.target;
5243
+ domTarget.classList.remove('draggingover');
5244
+ let target = node;
5245
+ // Can't drop to same node
5246
+ if (dragged.id == target.id) {
5247
+ console.warn('Cannot parent node to itself!');
5248
+ return;
5249
+ }
5250
+ // Can't drop to child node
5251
+ const isChild = function (newParent, node) {
5252
+ var result = false;
5253
+ for (var c of node.children) {
5254
+ if (c.id == newParent.id)
5255
+ return true;
5256
+ result = result || isChild(newParent, c);
5254
5257
  }
5258
+ return result;
5259
+ };
5260
+ if (isChild(target, dragged)) {
5261
+ console.warn('Cannot parent node to a current child!');
5262
+ return;
5263
+ }
5264
+ const onBeforeMove = this._callbacks['beforeMove'];
5265
+ const onMove = this._callbacks['move'];
5266
+ const resolve = (...args) => {
5255
5267
  const index = dragged.parent.children.findIndex((n) => n.id == dragged.id);
5256
5268
  const removed = dragged.parent.children.splice(index, 1);
5257
5269
  target.children.push(removed[0]);
5258
5270
  that.refresh();
5259
5271
  delete window.__tree_node_dragged;
5260
- });
5261
- }
5272
+ const event = {
5273
+ type: 'move',
5274
+ items: [dragged],
5275
+ to: target,
5276
+ domEvent: e,
5277
+ userInitiated: true
5278
+ };
5279
+ if (onMove)
5280
+ onMove(event, ...args);
5281
+ };
5282
+ if (onBeforeMove) {
5283
+ const event = {
5284
+ type: 'move',
5285
+ items: [dragged],
5286
+ to: target,
5287
+ domEvent: e,
5288
+ userInitiated: true
5289
+ };
5290
+ onBeforeMove(event, resolve);
5291
+ }
5292
+ else {
5293
+ resolve();
5294
+ }
5295
+ });
5262
5296
  let handled = false;
5263
5297
  // Show/hide children
5264
5298
  if (isParent) {
@@ -5278,15 +5312,21 @@
5278
5312
  else {
5279
5313
  node.closed = !node.closed;
5280
5314
  }
5281
- if (that.onevent) {
5282
- const event = new TreeEvent(TreeEvent.NODE_CARETCHANGED, node, node.closed, e);
5283
- that.onevent(event);
5315
+ const onCaretChanged = that._callbacks['caretChanged'];
5316
+ if (onCaretChanged !== undefined) {
5317
+ const event = {
5318
+ type: 'caret',
5319
+ items: [node],
5320
+ domEvent: e,
5321
+ userInitiated: true
5322
+ };
5323
+ onCaretChanged(event);
5284
5324
  }
5285
5325
  that.frefresh(node.id);
5286
5326
  });
5287
5327
  }
5288
5328
  // Add button icons
5289
- const inputContainer = document.createElement('div');
5329
+ const inputContainer = exports.LX.makeElement('div', 'flex flex-row ml-auto mr-2');
5290
5330
  item.appendChild(inputContainer);
5291
5331
  if (node.actions) {
5292
5332
  for (let i = 0; i < node.actions.length; ++i) {
@@ -5296,15 +5336,8 @@
5296
5336
  if (action.callback) {
5297
5337
  action.callback(node, swapValue, event);
5298
5338
  }
5299
- }, { icon: action.icon, swap: action.swap, title: action.name, hideName: true, className: 'p-0 m-0',
5300
- buttonClass: 'p-0 m-0 bg-none no-h' });
5301
- actionBtn.root.style.minWidth = 'fit-content';
5302
- actionBtn.root.style.margin = '0'; // adding classes does not work
5303
- actionBtn.root.style.padding = '0'; // adding classes does not work
5304
- const _btn = actionBtn.root.querySelector('button');
5305
- _btn.style.minWidth = 'fit-content';
5306
- _btn.style.margin = '0'; // adding classes does not work
5307
- _btn.style.padding = '0'; // adding classes does not work
5339
+ }, { icon: action.icon, swap: action.swap, title: action.name, hideName: true, className: 'p-0 min-h-fit',
5340
+ buttonClass: 'px-0 h-full bg-none' });
5308
5341
  inputContainer.appendChild(actionBtn.root);
5309
5342
  }
5310
5343
  }
@@ -5312,13 +5345,18 @@
5312
5345
  const visibilityBtn = new Button(null, '', (swapValue, e) => {
5313
5346
  e.stopPropagation();
5314
5347
  node.visible = node.visible === undefined ? false : !node.visible;
5315
- // Trigger visibility event
5316
- if (that.onevent) {
5317
- const event = new TreeEvent(TreeEvent.NODE_VISIBILITY, node, node.visible, e);
5318
- that.onevent(event);
5348
+ const onVisibleChanged = this._callbacks['visibleChanged'];
5349
+ if (onVisibleChanged !== undefined) {
5350
+ const event = {
5351
+ type: 'visibility',
5352
+ items: [node],
5353
+ domEvent: e,
5354
+ userInitiated: true
5355
+ };
5356
+ onVisibleChanged(event);
5319
5357
  }
5320
- }, { icon: node.visible ? 'Eye' : 'EyeOff', swap: node.visible ? 'EyeOff' : 'Eye', title: 'Toggle visible',
5321
- className: 'p-0 m-0', buttonClass: 'bg-none' });
5358
+ }, { icon: node.visible ? 'Eye' : 'EyeOff', swap: node.visible ? 'EyeOff' : 'Eye', title: 'Toggle visible', className: 'p-0 min-h-fit',
5359
+ buttonClass: 'px-0 h-full bg-none' });
5322
5360
  inputContainer.appendChild(visibilityBtn.root);
5323
5361
  }
5324
5362
  const _hasChild = function (node, id) {
@@ -5381,6 +5419,15 @@
5381
5419
  this.selected = [el.treeData];
5382
5420
  el.focus();
5383
5421
  }
5422
+ deleteNodes(nodes) {
5423
+ const nodesDeleted = [];
5424
+ for (const n of nodes) {
5425
+ if (this.deleteNode(n)) {
5426
+ nodesDeleted.push(n);
5427
+ }
5428
+ }
5429
+ return nodesDeleted;
5430
+ }
5384
5431
  deleteNode(node) {
5385
5432
  const dataAsArray = this.data.constructor === Array;
5386
5433
  // Can be either Array or Object type data
@@ -5413,16 +5460,11 @@
5413
5460
  constructor(name, data, options = {}) {
5414
5461
  options.hideName = true;
5415
5462
  super(exports.ComponentType.TREE, name, null, options);
5416
- let container = document.createElement('div');
5417
- container.className = 'lextree';
5418
- this.root.appendChild(container);
5463
+ let container = exports.LX.makeElement('div', 'lextree p-1 rounded-lg w-full my-0 mx-auto font-medium text-sm min-h-3', '', this.root);
5419
5464
  if (name) {
5420
- let title = document.createElement('span');
5421
- title.innerHTML = name;
5422
- container.appendChild(title);
5465
+ exports.LX.makeElement('span', 'block p-1 select-none text-base font-medium whitespace-nowrap', name, container);
5423
5466
  }
5424
- let toolsDiv = document.createElement('div');
5425
- toolsDiv.className = 'lextreetools';
5467
+ let toolsDiv = exports.LX.makeElement('div', 'lextreetools flex items-center bg-secondary px-2 rounded-lg gap-2 my-1');
5426
5468
  if (!name) {
5427
5469
  toolsDiv.className += ' notitle';
5428
5470
  }
@@ -5453,13 +5495,20 @@
5453
5495
  container.appendChild(toolsDiv);
5454
5496
  }
5455
5497
  // Tree
5456
- let list = document.createElement('ul');
5498
+ let list = exports.LX.makeElement('ul', 'flex flex-col gap-1 ps-0');
5457
5499
  list.addEventListener('contextmenu', function (e) {
5458
5500
  e.preventDefault();
5459
5501
  });
5460
5502
  container.appendChild(list);
5461
5503
  this.innerTree = new NodeTree(container, data, options);
5462
5504
  }
5505
+ /**
5506
+ * @method on
5507
+ * @description Stores an event callback for the desired action
5508
+ */
5509
+ on(eventName, callback) {
5510
+ this.innerTree._callbacks[eventName] = callback;
5511
+ }
5463
5512
  }
5464
5513
  exports.LX.Tree = Tree;
5465
5514
 
@@ -5484,7 +5533,7 @@
5484
5533
  value = newValue;
5485
5534
  _refreshInput(value);
5486
5535
  if (!skipCallback) {
5487
- this._trigger(new IEvent(name, +newValue, event), callback);
5536
+ this._trigger(new IEvent(name, newValue, event), callback);
5488
5537
  }
5489
5538
  };
5490
5539
  this.onResize = (rect) => {
@@ -5505,7 +5554,7 @@
5505
5554
  for (let j = 0; j < g.length; ++j) {
5506
5555
  let number = valueString[itemsCount++];
5507
5556
  number = number == 'x' ? '' : number;
5508
- const slotDom = exports.LX.makeContainer(['36px', '30px'], 'lexotpslot border-top border-bottom border-left px-3 cursor-text select-none font-medium outline-none', number, container);
5557
+ const slotDom = exports.LX.makeContainer(['36px', '30px'], 'lexotpslot border-t-color border-b-color border-l-color px-3 cursor-text select-none font-medium outline-none', number, container);
5509
5558
  slotDom.tabIndex = '1';
5510
5559
  if (this.disabled) {
5511
5560
  slotDom.classList.add('disabled');
@@ -5515,7 +5564,7 @@
5515
5564
  slotDom.className += ' rounded-l';
5516
5565
  }
5517
5566
  else if (j == (g.length - 1)) {
5518
- slotDom.className += ' rounded-r border-right';
5567
+ slotDom.className += ' rounded-r border-r-color';
5519
5568
  }
5520
5569
  slotDom.addEventListener('click', () => {
5521
5570
  if (this.disabled)
@@ -5697,13 +5746,10 @@
5697
5746
  const realNameWidth = this.root.domName?.style.width ?? '0px';
5698
5747
  container.style.width = `calc( 100% - ${realNameWidth})`;
5699
5748
  };
5700
- const container = document.createElement('div');
5701
- container.className = 'lexprogress';
5702
- this.root.appendChild(container);
5749
+ const container = exports.LX.makeElement('div', 'flex justify-center items-center gap-2', '', this.root);
5703
5750
  // add slider (0-1 if not specified different )
5704
- let progress = document.createElement('meter');
5751
+ let progress = exports.LX.makeElement('meter', 'lexprogressbar outline-none rounded-lg select-none');
5705
5752
  progress.id = 'lexprogressbar-' + name;
5706
- progress.className = 'lexprogressbar';
5707
5753
  progress.step = 'any';
5708
5754
  progress.min = options.min ?? 0;
5709
5755
  progress.max = options.max ?? 1;
@@ -5713,12 +5759,12 @@
5713
5759
  progress.value = value;
5714
5760
  container.appendChild(progress);
5715
5761
  const _updateColor = () => {
5716
- let backgroundColor = exports.LX.getThemeColor('global-selected');
5762
+ let backgroundColor = exports.LX.getCSSVariable('blue-500');
5717
5763
  if (progress.low != undefined && progress.value < progress.low) {
5718
- backgroundColor = exports.LX.getThemeColor('global-color-error');
5764
+ backgroundColor = exports.LX.getCSSVariable('destructive');
5719
5765
  }
5720
5766
  else if (progress.high != undefined && progress.value < progress.high) {
5721
- backgroundColor = exports.LX.getThemeColor('global-color-warning');
5767
+ backgroundColor = exports.LX.getCSSVariable('warning');
5722
5768
  }
5723
5769
  progress.style.background = `color-mix(in srgb, ${backgroundColor} 20%, transparent)`;
5724
5770
  };
@@ -5727,11 +5773,8 @@
5727
5773
  if (oldSpan) {
5728
5774
  oldSpan.remove();
5729
5775
  }
5730
- let span = document.createElement('span');
5776
+ let span = exports.LX.makeElement('span', 'w-12 flex-auto-keep text-center', value, container);
5731
5777
  span.id = 'progressvalue-' + name;
5732
- span.style.padding = '0px 5px';
5733
- span.innerText = value;
5734
- container.appendChild(span);
5735
5778
  }
5736
5779
  if (options.editable ?? false) {
5737
5780
  progress.classList.add('editable');
@@ -5801,14 +5844,13 @@
5801
5844
  }
5802
5845
  };
5803
5846
  var container = document.createElement('div');
5804
- container.className = 'lexradiogroup ' + (options.className ?? '');
5847
+ container.className = exports.LX.mergeClass('lexradiogroup flex flex-col', options.className);
5805
5848
  this.root.appendChild(container);
5806
- let labelSpan = document.createElement('span');
5807
- labelSpan.innerHTML = label;
5808
- container.appendChild(labelSpan);
5849
+ // Make label
5850
+ exports.LX.makeElement('span', 'font-medium mb-2', label, container);
5809
5851
  for (let i = 0; i < values.length; ++i) {
5810
5852
  const optionItem = document.createElement('div');
5811
- optionItem.className = 'lexradiogroupitem';
5853
+ optionItem.className = 'lexradiogroupitem flex items-center gap-2 px-6 py-1';
5812
5854
  container.appendChild(optionItem);
5813
5855
  const optionButton = document.createElement('button');
5814
5856
  optionButton.className = 'flex p-0 rounded-lg cursor-pointer';
@@ -5916,11 +5958,10 @@
5916
5958
  }
5917
5959
  };
5918
5960
  const container = document.createElement('div');
5919
- container.className = 'lexrange relative';
5961
+ container.className = 'lexrange relative py-3';
5920
5962
  this.root.appendChild(container);
5921
5963
  let slider = document.createElement('input');
5922
- slider.className = 'lexrangeslider ' + (isRangeValue ? 'pointer-events-none ' : '')
5923
- + (options.className ?? '');
5964
+ slider.className = exports.LX.mergeClass('lexrangeslider' + (isRangeValue ? ' range pointer-events-none' : ''), options.className);
5924
5965
  slider.min = options.min ?? 0;
5925
5966
  slider.max = options.max ?? 100;
5926
5967
  slider.step = options.step ?? 1;
@@ -5974,15 +6015,12 @@
5974
6015
  const remapped = exports.LX.remapRange(value, options.min, options.max, 0, 1) * 0.5;
5975
6016
  offsetX = container.offsetWidth * remapped - (container.offsetWidth * 0.5);
5976
6017
  }
5977
- exports.LX.asTooltip(container, `${value}${isRangeValue ? `- ${ogValue[1]}` : ``}`, { offsetX,
5978
- callback: (tpDom) => {
6018
+ exports.LX.asTooltip(container, `${value}${isRangeValue ? `- ${ogValue[1]}` : ``}`, { offsetX, callback: (tpDom) => {
5979
6019
  this._labelTooltip = tpDom;
5980
6020
  } });
5981
6021
  });
5982
- if (ogValue.constructor == Array) { // Its a range value
5983
- let maxSlider = document.createElement('input');
5984
- maxSlider.className = 'lexrangeslider no-fill pointer-events-none overlap absolute top-0 left-0 '
5985
- + (options.className ?? '');
6022
+ if (ogValue.constructor == Array) {
6023
+ let maxSlider = exports.LX.makeElement('input', exports.LX.mergeClass('lexrangeslider no-fill pointer-events-none overlap absolute left-0', options.className));
5986
6024
  maxSlider.min = options.min ?? 0;
5987
6025
  maxSlider.max = options.max ?? 100;
5988
6026
  maxSlider.step = options.step ?? 1;
@@ -6047,7 +6085,7 @@
6047
6085
  }, false);
6048
6086
  // Create all layers of stars
6049
6087
  for (let i = 0; i < 5; ++i) {
6050
- const starIcon = exports.LX.makeIcon('Star', { svgClass: `lg fill-current fg-secondary` });
6088
+ const starIcon = exports.LX.makeIcon('Star', { svgClass: `lg fill-current text-accent` });
6051
6089
  starIcon.dataset['idx'] = i + 1;
6052
6090
  starsContainer.appendChild(starIcon);
6053
6091
  starIcon.addEventListener('click', (e) => {
@@ -6056,9 +6094,9 @@
6056
6094
  const half = allowHalf && e.offsetX < (rect.width * 0.5);
6057
6095
  this.set(parseFloat(star.dataset['idx']) - (half ? 0.5 : 0.0));
6058
6096
  }, false);
6059
- const filledStarIcon = exports.LX.makeIcon('Star', { svgClass: `lg fill-current fg-yellow-500` });
6097
+ const filledStarIcon = exports.LX.makeIcon('Star', { svgClass: `lg fill-current text-yellow-400` });
6060
6098
  filledStarsContainer.appendChild(filledStarIcon);
6061
- const halfStarIcon = exports.LX.makeIcon('StarHalf', { svgClass: `lg fill-current fg-yellow-500` });
6099
+ const halfStarIcon = exports.LX.makeIcon('StarHalf', { svgClass: `lg fill-current text-yellow-400` });
6062
6100
  halfStarsContainer.appendChild(halfStarIcon);
6063
6101
  }
6064
6102
  const _updateStars = (v) => {
@@ -6107,8 +6145,13 @@
6107
6145
  this.root.dimensions[i].set(newValue[i], skipCallback);
6108
6146
  }
6109
6147
  };
6148
+ this.onResize = (rect) => {
6149
+ const realNameWidth = this.root.domName?.style.width ?? '0px';
6150
+ container.style.width = `calc( 100% - ${realNameWidth})`;
6151
+ };
6110
6152
  this.root.aspectRatio = value.length == 2 ? value[0] / value[1] : null;
6111
6153
  this.root.dimensions = [];
6154
+ const container = exports.LX.makeElement('div', 'flex', '', this.root);
6112
6155
  for (let i = 0; i < value.length; ++i) {
6113
6156
  const p = new exports.LX.Panel();
6114
6157
  this.root.dimensions[i] = p.addNumber(null, value[i], (v) => {
@@ -6122,18 +6165,15 @@
6122
6165
  if (callback) {
6123
6166
  callback(value);
6124
6167
  }
6125
- }, { min: 0, disabled: options.disabled, precision: options.precision, className: 'flex-fill' });
6126
- this.root.appendChild(this.root.dimensions[i].root);
6168
+ }, { min: 0, disabled: options.disabled, precision: options.precision, className: 'flex-auto-fill' });
6169
+ container.appendChild(this.root.dimensions[i].root);
6127
6170
  if ((i + 1) != value.length) {
6128
- const xIcon = exports.LX.makeIcon('X', { svgClass: 'fg-accent font-bold' });
6129
- this.root.appendChild(xIcon);
6171
+ const xIcon = exports.LX.makeIcon('X', { svgClass: 'text-foreground font-bold' });
6172
+ container.appendChild(xIcon);
6130
6173
  }
6131
6174
  }
6132
6175
  if (options.units) {
6133
- let unitSpan = document.createElement('span');
6134
- unitSpan.className = 'select-none fg-tertiary font-medium';
6135
- unitSpan.innerText = options.units;
6136
- this.root.appendChild(unitSpan);
6176
+ exports.LX.makeElement('span', 'text-muted-foreground align-center content-center font-medium flex-auto-keep select-none', options.units, container);
6137
6177
  }
6138
6178
  // Lock aspect ratio
6139
6179
  if (this.root.aspectRatio) {
@@ -6144,9 +6184,10 @@
6144
6184
  const value = this.value();
6145
6185
  this.root.aspectRatio = value[0] / value[1];
6146
6186
  }
6147
- }, { title: 'Lock Aspect Ratio', icon: 'LockOpen', swap: 'Lock', buttonClass: 'bg-none p-0' });
6148
- this.root.appendChild(lockerButton.root);
6187
+ }, { title: 'Lock Aspect Ratio', icon: 'LockOpen', swap: 'Lock', className: 'flex-auto-keep', buttonClass: 'h-auto bg-none p-0' });
6188
+ container.appendChild(lockerButton.root);
6149
6189
  }
6190
+ exports.LX.doAsync(this.onResize.bind(this));
6150
6191
  }
6151
6192
  }
6152
6193
  exports.LX.SizeInput = SizeInput;
@@ -6191,7 +6232,7 @@
6191
6232
  if (typeof options.onItemsPerPageChange === 'function') {
6192
6233
  this.onItemsPerPageChange = options.onItemsPerPageChange;
6193
6234
  }
6194
- this.root = exports.LX.makeContainer(['auto', 'auto'], 'flex flex-row gap-2 ' + (options.className ?? ''));
6235
+ this.root = exports.LX.makeContainer(['auto', 'auto'], exports.LX.mergeClass('flex flex-row gap-2', options.className));
6195
6236
  if (options.allowChangeItemsPerPage ?? false) {
6196
6237
  const itemsPerPageSelectContainer = exports.LX.makeContainer(['auto', 'auto'], 'flex flex-row items-center', '', this.root);
6197
6238
  const itemsPerPageSelect = new Select(null, Pagination.ITEMS_PER_PAGE_VALUES, this._itemsPerPage, (v) => {
@@ -6228,7 +6269,7 @@
6228
6269
  refresh() {
6229
6270
  this.pagesRoot.innerHTML = '';
6230
6271
  // Previous page button
6231
- this._makeButton(exports.LX.makeIcon('ChevronLeft').innerHTML, this.page === 1, () => this.prev(), `bg-none ${this.page === 1 ? '' : 'hover:bg-tertiary'}`);
6272
+ this._makeButton(exports.LX.makeIcon('ChevronLeft').innerHTML, this.page === 1, () => this.prev(), `bg-none ${this.page === 1 ? '' : 'hover:bg-secondary'}`);
6232
6273
  const pagesContainer = exports.LX.makeContainer(['auto', 'auto'], 'flex flex-row items-center', '', this.pagesRoot);
6233
6274
  const maxButtons = this._maxButtons + 2; // + next and prev
6234
6275
  if (this.pages <= maxButtons) {
@@ -6278,7 +6319,7 @@
6278
6319
  }
6279
6320
  }
6280
6321
  // Next page button
6281
- this._makeButton(exports.LX.makeIcon('ChevronRight').innerHTML, this.page === this.pages, () => this.next(), `bg-none ${this.page === this.pages ? '' : 'hover:bg-tertiary'}`);
6322
+ this._makeButton(exports.LX.makeIcon('ChevronRight').innerHTML, this.page === this.pages, () => this.next(), `bg-none ${this.page === this.pages ? '' : 'hover:bg-secondary'}`);
6282
6323
  }
6283
6324
  _emitChange() {
6284
6325
  // Event callback
@@ -6296,7 +6337,7 @@
6296
6337
  return btn.root;
6297
6338
  }
6298
6339
  _makePageButton(container, i) {
6299
- const buttonClass = i === this.page ? 'bg-secondary border' : 'bg-none';
6340
+ const buttonClass = `h-8 ${i === this.page ? 'primary text-primary-foreground' : 'ghost'}`;
6300
6341
  return this._makeButton(String(i), false, () => this.setPage(i), buttonClass, container);
6301
6342
  }
6302
6343
  }
@@ -6450,10 +6491,10 @@
6450
6491
  }
6451
6492
  if (this.customFilters !== null) {
6452
6493
  const icon = exports.LX.makeIcon('CirclePlus', { svgClass: 'sm' });
6453
- const separatorHtml = `<div class="lexcontainer border-right self-center mx-1" style="width: 1px; height: 70%;"></div>`;
6494
+ const separatorHtml = `<div class="lexcontainer border-r-color place-self-center mx-1" style="width: 1px; height: 70%;"></div>`;
6454
6495
  for (let f of this.customFilters) {
6455
6496
  f.component = new Button(null, icon.innerHTML + f.name, (v) => {
6456
- const spanName = f.component.root.querySelector('span');
6497
+ const buttonRoot = f.component.root.querySelector('button');
6457
6498
  if (f.options) {
6458
6499
  const menuOptions = f.options.map((colName, idx) => {
6459
6500
  const item = {
@@ -6466,8 +6507,8 @@
6466
6507
  delete this.activeCustomFilters[key];
6467
6508
  }
6468
6509
  const activeFilters = Object.keys(this.activeCustomFilters).filter((k) => this.activeCustomFilters[k] == f.name);
6469
- const filterBadgesHtml = activeFilters.reduce((acc, key) => acc += exports.LX.badge(key, 'bg-tertiary fg-secondary text-sm border-0'), '');
6470
- spanName.innerHTML = icon.innerHTML + f.name
6510
+ const filterBadgesHtml = activeFilters.reduce((acc, key) => acc += exports.LX.badge(key, 'xs secondary'), '');
6511
+ buttonRoot.innerHTML = icon.innerHTML + f.name
6471
6512
  + (activeFilters.length ? separatorHtml : '') + filterBadgesHtml;
6472
6513
  this.refresh();
6473
6514
  }
@@ -6478,9 +6519,9 @@
6478
6519
  }
6479
6520
  else if (f.type == 'range') {
6480
6521
  console.assert(f.min != undefined && f.max != undefined, 'Range filter needs min and max values!');
6481
- const container = exports.LX.makeContainer(['240px', 'auto'], 'text-md');
6482
- const panel = new exports.LX.Panel();
6483
- exports.LX.makeContainer(['100%', 'auto'], 'px-3 p-2 pb-0 text-md font-medium', f.name, container);
6522
+ const container = exports.LX.makeContainer(['240px', 'auto'], 'text-base');
6523
+ const panel = new exports.LX.Panel({ className: 'flex flex-col gap-2' });
6524
+ exports.LX.makeContainer(['100%', 'auto'], 'px-3 p-2 pb-0 text-base font-medium', f.name, container);
6484
6525
  f.start = f.start ?? f.min;
6485
6526
  f.end = f.end ?? f.max;
6486
6527
  panel.refresh = () => {
@@ -6489,9 +6530,9 @@
6489
6530
  panel.addNumber(null, f.start, (v) => {
6490
6531
  f.start = v;
6491
6532
  const inUse = f.start != f.min || f.end != f.max;
6492
- spanName.innerHTML = icon.innerHTML + f.name + (inUse
6533
+ buttonRoot.innerHTML = icon.innerHTML + f.name + (inUse
6493
6534
  ? separatorHtml
6494
- + exports.LX.badge(`${f.start} - ${f.end} ${f.units ?? ''}`, 'bg-tertiary fg-secondary text-sm border-0')
6535
+ + exports.LX.badge(`${f.start} - ${f.end} ${f.units ?? ''}`, 'xs secondary')
6495
6536
  : '');
6496
6537
  if (inUse) {
6497
6538
  this._resetCustomFiltersBtn?.root.classList.remove('hidden');
@@ -6501,10 +6542,10 @@
6501
6542
  panel.addNumber(null, f.end, (v) => {
6502
6543
  f.end = v;
6503
6544
  const inUse = f.start != f.min || f.end != f.max;
6504
- spanName.innerHTML = icon.innerHTML + f.name
6545
+ buttonRoot.innerHTML = icon.innerHTML + f.name
6505
6546
  + (inUse
6506
6547
  ? separatorHtml
6507
- + exports.LX.badge(`${f.start} - ${f.end} ${f.units ?? ''}`, 'bg-tertiary fg-secondary text-sm border-0')
6548
+ + exports.LX.badge(`${f.start} - ${f.end} ${f.units ?? ''}`, 'xs secondary')
6508
6549
  : '');
6509
6550
  if (inUse) {
6510
6551
  this._resetCustomFiltersBtn?.root.classList.remove('hidden');
@@ -6514,19 +6555,19 @@
6514
6555
  panel.addButton(null, 'Reset', () => {
6515
6556
  f.start = f.min;
6516
6557
  f.end = f.max;
6517
- spanName.innerHTML = icon.innerHTML + f.name;
6558
+ buttonRoot.innerHTML = icon.innerHTML + f.name;
6518
6559
  panel.refresh();
6519
6560
  this.refresh();
6520
- }, { buttonClass: 'contrast' });
6561
+ }, { buttonClass: 'ghost' });
6521
6562
  };
6522
6563
  panel.refresh();
6523
6564
  container.appendChild(panel.root);
6524
6565
  new Popover(f.component.root, [container], { side: 'bottom' });
6525
6566
  }
6526
6567
  else if (f.type == 'date') {
6527
- const container = exports.LX.makeContainer(['auto', 'auto'], 'text-md');
6568
+ const container = exports.LX.makeContainer(['auto', 'auto'], 'text-base');
6528
6569
  const panel = new exports.LX.Panel();
6529
- exports.LX.makeContainer(['100%', 'auto'], 'px-3 p-2 pb-0 text-md font-medium', f.name, container);
6570
+ exports.LX.makeContainer(['100%', 'auto'], 'px-3 p-2 pb-0 text-base font-medium', f.name, container);
6530
6571
  panel.refresh = () => {
6531
6572
  panel.clear();
6532
6573
  // Generate default value once the filter is used
@@ -6538,9 +6579,9 @@
6538
6579
  const calendar = new CalendarRange(f.value ?? f.default, {
6539
6580
  onChange: (dateRange) => {
6540
6581
  f.value = dateRange;
6541
- spanName.innerHTML = icon.innerHTML + f.name
6582
+ buttonRoot.innerHTML = icon.innerHTML + f.name
6542
6583
  + (separatorHtml
6543
- + exports.LX.badge(`${calendar.getFullDate()}`, 'bg-tertiary fg-secondary text-sm border-0'));
6584
+ + exports.LX.badge(`${calendar.getFullDate()}`, 'xs secondary'));
6544
6585
  this._resetCustomFiltersBtn?.root.classList.remove('hidden');
6545
6586
  this.refresh();
6546
6587
  }
@@ -6551,14 +6592,14 @@
6551
6592
  container.appendChild(panel.root);
6552
6593
  new Popover(f.component.root, [container], { side: 'bottom' });
6553
6594
  }
6554
- }, { buttonClass: 'px-2 primary dashed' });
6595
+ }, { buttonClass: 'sm outline dashed' });
6555
6596
  headerContainer.appendChild(f.component.root);
6556
6597
  }
6557
6598
  this._resetCustomFiltersBtn = new Button(null, 'resetButton', () => {
6558
6599
  this.activeCustomFilters = {};
6559
6600
  this._resetCustomFiltersBtn?.root.classList.add('hidden');
6560
6601
  for (let f of this.customFilters ?? []) {
6561
- f.component.root.querySelector('span').innerHTML = icon.innerHTML + f.name;
6602
+ f.component.root.querySelector('button').innerHTML = icon.innerHTML + f.name;
6562
6603
  if (f.type == 'range') {
6563
6604
  f.start = f.min;
6564
6605
  f.end = f.max;
@@ -6568,7 +6609,7 @@
6568
6609
  }
6569
6610
  }
6570
6611
  this.refresh();
6571
- }, { title: 'Reset filters', tooltip: true, icon: 'X' });
6612
+ }, { title: 'Reset filters', tooltip: true, icon: 'X', buttonClass: 'ghost' });
6572
6613
  headerContainer.appendChild(this._resetCustomFiltersBtn?.root);
6573
6614
  this._resetCustomFiltersBtn?.root.classList.add('hidden');
6574
6615
  }
@@ -6592,15 +6633,13 @@
6592
6633
  return item;
6593
6634
  });
6594
6635
  exports.LX.addDropdownMenu(e.target, menuOptions, { side: 'bottom', align: 'end' });
6595
- }, { hideName: true });
6636
+ }, { hideName: true, buttonClass: 'outline' });
6596
6637
  headerContainer.appendChild(toggleColumnsBtn.root);
6597
6638
  toggleColumnsBtn.root.style.marginLeft = 'auto';
6598
6639
  }
6599
6640
  container.appendChild(headerContainer);
6600
6641
  }
6601
- const table = document.createElement('table');
6602
- exports.LX.addClass(table, options.tableClass);
6603
- container.appendChild(table);
6642
+ const table = exports.LX.makeElement('table', options.tableClass, '', container);
6604
6643
  this.refresh = () => {
6605
6644
  this._currentFilter = this._currentFilter ?? '';
6606
6645
  table.innerHTML = '';
@@ -6622,7 +6661,7 @@
6622
6661
  th.style.width = '0px';
6623
6662
  const input = document.createElement('input');
6624
6663
  input.type = 'checkbox';
6625
- input.className = 'lexcheckbox accent';
6664
+ input.className = 'lexcheckbox primary';
6626
6665
  input.checked = data.checkMap[':root'] ?? false;
6627
6666
  th.appendChild(input);
6628
6667
  input.addEventListener('change', function () {
@@ -6657,8 +6696,7 @@
6657
6696
  console.warn('Invalid column action (missing name):', action);
6658
6697
  continue;
6659
6698
  }
6660
- menuOptions.push({ name: action.name, icon: action.icon, className: action.className,
6661
- callback: () => {
6699
+ menuOptions.push({ name: action.name, icon: action.icon, className: action.className, callback: () => {
6662
6700
  const colRows = this.data.body.map((row) => [row[idx]]);
6663
6701
  const mustRefresh = action.callback(colRows, table);
6664
6702
  if (mustRefresh) {
@@ -6889,7 +6927,7 @@
6889
6927
  const td = document.createElement('td');
6890
6928
  const input = document.createElement('input');
6891
6929
  input.type = 'checkbox';
6892
- input.className = 'lexcheckbox accent';
6930
+ input.className = 'lexcheckbox primary';
6893
6931
  input.checked = data.checkMap[rowId];
6894
6932
  td.appendChild(input);
6895
6933
  input.addEventListener('change', function () {
@@ -7001,7 +7039,7 @@
7001
7039
  const footerContainer = exports.LX.makeContainer(['100%', 'auto'], 'flex flex-row px-3 my-1 align-center', '', container);
7002
7040
  // Show num selected rows
7003
7041
  if (showSelected) {
7004
- const selectedRowsLabelContainer = exports.LX.makeContainer(['100%', 'auto'], 'flex justify-start items-center fg-secondary', '0 row(s) selected.', footerContainer);
7042
+ const selectedRowsLabelContainer = exports.LX.makeContainer(['100%', 'auto'], 'flex justify-start items-center', '0 row(s) selected.', footerContainer);
7005
7043
  exports.LX.addSignal('@rows_selected_changed', (target, n) => {
7006
7044
  if (!this._showSelectedNumber)
7007
7045
  return;
@@ -7097,7 +7135,8 @@
7097
7135
  let tabEl = document.createElement('div');
7098
7136
  tabEl.className = 'lextab ' + ((tab.selected ?? false) ? 'selected' : '');
7099
7137
  tabEl.innerHTML = showNames ? tab.name : '';
7100
- tabEl.appendChild(exports.LX.makeIcon(tab.icon ?? 'Hash', { title: tab.name, iconClass: tab.iconClass, svgClass: tab.svgClass }));
7138
+ tabEl.appendChild(exports.LX.makeIcon(tab.icon ?? 'Hash', { title: tab.name, iconClass: tab.iconClass,
7139
+ svgClass: `lg${tab.svgClass ? ' ' + tab.svgClass : ''}` }));
7101
7140
  this.tabDOMs[tab.name] = tabEl;
7102
7141
  let infoContainer = document.createElement('div');
7103
7142
  infoContainer.id = tab.name.replace(/\s/g, '');
@@ -7170,15 +7209,13 @@
7170
7209
  };
7171
7210
  // Show tags
7172
7211
  const tagsContainer = document.createElement('div');
7173
- tagsContainer.className = 'lextags';
7212
+ tagsContainer.className = 'inline-flex flex-wrap gap-1 bg-card/50 rounded-lg pad-xs [&_input]:w-2/3';
7174
7213
  this.root.appendChild(tagsContainer);
7175
7214
  this.generateTags = (value) => {
7176
7215
  tagsContainer.innerHTML = '';
7177
7216
  for (let i = 0; i < value.length; ++i) {
7178
7217
  const tagName = value[i];
7179
- const tag = document.createElement('span');
7180
- tag.className = 'lextag';
7181
- tag.innerHTML = tagName;
7218
+ const tag = exports.LX.makeElement('span', 'lextag bg-primary px-2 py-1 rounded-xl min-w-2 justify-center text-primary-foreground gap-1 text-sm select-none', tagName);
7182
7219
  const removeButton = exports.LX.makeIcon('X', { svgClass: 'sm' });
7183
7220
  tag.appendChild(removeButton);
7184
7221
  removeButton.addEventListener('click', (e) => {
@@ -7236,13 +7273,12 @@
7236
7273
  container.className = 'lextextarea';
7237
7274
  container.style.display = 'flex';
7238
7275
  this.root.appendChild(container);
7239
- let wValue = document.createElement('textarea');
7276
+ let wValue = exports.LX.makeElement('textarea', options.inputClass ?? '');
7240
7277
  wValue.value = value ?? '';
7241
- wValue.className = options.inputClass ?? '';
7242
7278
  wValue.style.textAlign = options.float ?? '';
7243
7279
  Object.assign(wValue.style, options.style ?? {});
7244
7280
  if (options.fitHeight ?? false) {
7245
- wValue.classList.add('size-content');
7281
+ wValue.classList.add('field-sizing-content');
7246
7282
  }
7247
7283
  if (!(options.resize ?? true)) {
7248
7284
  wValue.classList.add('resize-none');
@@ -7293,7 +7329,8 @@
7293
7329
  console.assert(name.length !== 0, "Can't create Title Component without text!");
7294
7330
  // Note: Titles are not registered in Panel.components by now
7295
7331
  super(exports.ComponentType.TITLE, null, null, options);
7296
- this.root.className = `lextitle ${this.root.className}`;
7332
+ const cn = 'lextitle !w-fit bg-muted text-foreground text-sm font-semibold leading-normal m-3 flex content-center rounded-xl select-none';
7333
+ this.root.className = exports.LX.mergeClass(cn, options.className);
7297
7334
  if (options.icon) {
7298
7335
  let icon = exports.LX.makeIcon(options.icon, { iconClass: 'mr-2' });
7299
7336
  icon.querySelector('svg').style.color = options.iconColor || '';
@@ -7302,16 +7339,14 @@
7302
7339
  let text = document.createElement('span');
7303
7340
  text.innerText = name;
7304
7341
  this.root.appendChild(text);
7305
- Object.assign(this.root.style, options.style ?? {});
7306
7342
  if (options.link != undefined) {
7307
- let linkDom = document.createElement('a');
7308
- linkDom.innerText = name;
7343
+ let linkDom = exports.LX.makeElement('a', `${cn} link`, name);
7309
7344
  linkDom.href = options.link;
7310
7345
  linkDom.target = options.target ?? '';
7311
- linkDom.className = 'lextitle link';
7312
- Object.assign(linkDom.style, options.style ?? {});
7313
7346
  this.root.replaceWith(linkDom);
7347
+ this.root = linkDom;
7314
7348
  }
7349
+ Object.assign(this.root.style, options.style ?? {});
7315
7350
  }
7316
7351
  }
7317
7352
  exports.LX.Title = Title;
@@ -7346,25 +7381,23 @@
7346
7381
  container.style.width = options.inputWidth ?? `calc( 100% - ${realNameWidth})`;
7347
7382
  };
7348
7383
  var container = document.createElement('div');
7349
- container.className = 'lextogglecont';
7384
+ container.className = 'flex flex-row gap-2 items-center';
7350
7385
  this.root.appendChild(container);
7351
- let toggle = document.createElement('input');
7386
+ let toggle = exports.LX.makeElement('input', exports.LX.mergeClass('lextoggle relative inline-grid place-content-center cursor-pointer shrink-0 select-none', options.className));
7352
7387
  toggle.type = 'checkbox';
7353
- toggle.className = 'lextoggle ' + (options.className ?? '');
7354
7388
  toggle.checked = value;
7355
7389
  toggle.iValue = value;
7356
7390
  toggle.disabled = options.disabled ?? false;
7357
7391
  container.appendChild(toggle);
7358
7392
  let valueName = document.createElement('span');
7359
- valueName.className = 'toggletext';
7393
+ valueName.className = 'font-medium w-full overflow-hidden truncate';
7360
7394
  valueName.innerHTML = options.label ?? 'On';
7361
7395
  container.appendChild(valueName);
7362
7396
  toggle.addEventListener('change', (e) => {
7363
7397
  this.set(toggle.checked, false, e);
7364
7398
  });
7365
7399
  if (options.suboptions) {
7366
- let suboptions = document.createElement('div');
7367
- suboptions.className = 'lextogglesubmenu';
7400
+ let suboptions = exports.LX.makeElement('div', 'lextogglesubmenu w-full p-2');
7368
7401
  suboptions.toggleAttribute('hidden', !toggle.checked);
7369
7402
  const suboptionsPanel = new exports.LX.Panel();
7370
7403
  suboptionsPanel.queue(suboptions);
@@ -7383,6 +7416,7 @@
7383
7416
  * @description Vector Component
7384
7417
  */
7385
7418
  class Vector extends BaseComponent {
7419
+ locked = false;
7386
7420
  setLimits;
7387
7421
  constructor(numComponents, name, value, callback, options = {}) {
7388
7422
  numComponents = exports.LX.clamp(numComponents, 2, 4);
@@ -7418,7 +7452,7 @@
7418
7452
  this.setLimits = (newMin, newMax, newStep) => { };
7419
7453
  const vectorInputs = [];
7420
7454
  var container = document.createElement('div');
7421
- container.className = 'lexvector';
7455
+ container.className = 'lexvector flex';
7422
7456
  this.root.appendChild(container);
7423
7457
  this.disabled = options.disabled ?? false;
7424
7458
  const that = this;
@@ -7457,7 +7491,7 @@
7457
7491
  mult = 10;
7458
7492
  else if (e.altKey)
7459
7493
  mult = 0.1;
7460
- if (lockerButton.locked) {
7494
+ if (that.locked) {
7461
7495
  for (let v of vectorInputs) {
7462
7496
  v.value = exports.LX.round(+v.valueAsNumber - mult * (e.deltaY > 0 ? 1 : -1), options.precision);
7463
7497
  BaseComponent._dispatchEvent(v, 'change');
@@ -7474,7 +7508,7 @@
7474
7508
  }
7475
7509
  let val = exports.LX.clamp(e.target.value, +vecinput.min, +vecinput.max);
7476
7510
  val = exports.LX.round(val, options.precision);
7477
- if (lockerButton.locked) {
7511
+ if (this.locked) {
7478
7512
  for (let v of vectorInputs) {
7479
7513
  v.value = val;
7480
7514
  value[v.idx] = val;
@@ -7513,7 +7547,7 @@
7513
7547
  mult = 10;
7514
7548
  else if (e.altKey)
7515
7549
  mult = 0.1;
7516
- if (lockerButton.locked) {
7550
+ if (that.locked) {
7517
7551
  for (let v of vectorInputs) {
7518
7552
  v.value = exports.LX.round(+v.valueAsNumber + mult * dt, options.precision);
7519
7553
  BaseComponent._dispatchEvent(v, 'change');
@@ -7554,10 +7588,12 @@
7554
7588
  this.set(value, true);
7555
7589
  };
7556
7590
  }
7557
- const lockerButton = new Button(null, '', (swapValue) => {
7558
- lockerButton.locked = swapValue;
7559
- }, { title: 'Lock', icon: 'LockOpen', swap: 'Lock', buttonClass: 'no-h bg-none p-0' });
7560
- container.appendChild(lockerButton.root);
7591
+ if (!options.skipLock) {
7592
+ const lockerButton = new Button(null, '', (swapValue) => {
7593
+ this.locked = swapValue;
7594
+ }, { title: 'Lock', icon: 'LockOpen', swap: 'Lock', buttonClass: 'h-auto bg-none p-0' });
7595
+ container.appendChild(lockerButton.root);
7596
+ }
7561
7597
  exports.LX.doAsync(this.onResize.bind(this));
7562
7598
  }
7563
7599
  }
@@ -7580,22 +7616,17 @@
7580
7616
  constructor(name, options = {}) {
7581
7617
  this.name = name;
7582
7618
  var root = document.createElement('div');
7583
- root.className = 'lexbranch';
7584
7619
  if (options.id) {
7585
7620
  root.id = options.id;
7586
7621
  }
7587
- if (options.className) {
7588
- root.className += ' ' + options.className;
7589
- }
7590
- root.style.margin = '0 auto';
7622
+ root.className = exports.LX.mergeClass('lexbranch w-full rounded-lg my-0 mx-auto', options.className);
7591
7623
  var that = this;
7592
7624
  this.closed = options.closed ?? false;
7593
7625
  this.root = root;
7594
7626
  this.components = [];
7595
7627
  this.panel = null;
7596
7628
  // Create element
7597
- const title = document.createElement('div');
7598
- title.className = 'lexbranchtitle';
7629
+ const title = exports.LX.makeElement('div', 'lexbranchtitle flex cursor-pointer select-none pad-lg bg-card text-card-foreground text-lg', '', root);
7599
7630
  if (options.icon) {
7600
7631
  const branchIcon = exports.LX.makeIcon(options.icon, { iconClass: 'mr-2' });
7601
7632
  title.appendChild(branchIcon);
@@ -7603,11 +7634,8 @@
7603
7634
  title.innerHTML += name || 'Branch';
7604
7635
  const collapseIcon = exports.LX.makeIcon('Right', { iconClass: 'switch-branch-button', svgClass: 'sm' });
7605
7636
  title.appendChild(collapseIcon);
7606
- root.appendChild(title);
7607
- var branchContent = document.createElement('div');
7637
+ var branchContent = exports.LX.makeElement('div', 'lexbranchcontent pad-xs bg-card', '', root);
7608
7638
  branchContent.id = name.replace(/\s/g, '');
7609
- branchContent.className = 'lexbranchcontent';
7610
- root.appendChild(branchContent);
7611
7639
  this.content = branchContent;
7612
7640
  this._addBranchSeparator();
7613
7641
  if (this.closed) {
@@ -7762,14 +7790,10 @@
7762
7790
  * style: CSS Style object to be applied to the panel
7763
7791
  */
7764
7792
  constructor(options = {}) {
7765
- var root = document.createElement('div');
7766
- root.className = 'lexpanel';
7793
+ const root = exports.LX.makeElement('div', exports.LX.mergeClass('lexpanel m-0 pad-md overflow-hidden overflow-y-scroll text-foreground scrollbar-hidden', options.className));
7767
7794
  if (options.id) {
7768
7795
  root.id = options.id;
7769
7796
  }
7770
- if (options.className) {
7771
- root.className += ' ' + options.className;
7772
- }
7773
7797
  root.style.width = options.width || '100%';
7774
7798
  root.style.height = options.height || '100%';
7775
7799
  Object.assign(root.style, options.style ?? {});
@@ -7823,8 +7847,7 @@
7823
7847
  const signal = this.components[w].options.signal;
7824
7848
  for (let i = 0; i < exports.LX.signals[signal].length; i++) {
7825
7849
  if (exports.LX.signals[signal][i] == this.components[w]) {
7826
- exports.LX.signals[signal] = [...exports.LX.signals[signal].slice(0, i),
7827
- ...exports.LX.signals[signal].slice(i + 1)];
7850
+ exports.LX.signals[signal] = [...exports.LX.signals[signal].slice(0, i), ...exports.LX.signals[signal].slice(i + 1)];
7828
7851
  }
7829
7852
  }
7830
7853
  }
@@ -7835,8 +7858,7 @@
7835
7858
  let signal = c.options.signal;
7836
7859
  for (let i = 0; i < exports.LX.signals[signal].length; i++) {
7837
7860
  if (exports.LX.signals[signal][i] == c) {
7838
- exports.LX.signals[signal] = [...exports.LX.signals[signal].slice(0, i),
7839
- ...exports.LX.signals[signal].slice(i + 1)];
7861
+ exports.LX.signals[signal] = [...exports.LX.signals[signal].slice(0, i), ...exports.LX.signals[signal].slice(i + 1)];
7840
7862
  }
7841
7863
  }
7842
7864
  }
@@ -8169,7 +8191,7 @@
8169
8191
  */
8170
8192
  addLabel(value, options = {}) {
8171
8193
  options.disabled = true;
8172
- options.inputClass = (options.inputClass ?? '') + ' bg-none';
8194
+ options.inputClass = exports.LX.mergeClass('bg-none', options.inputClass);
8173
8195
  const component = this.addText(null, value, null, options);
8174
8196
  component.type = exports.ComponentType.LABEL;
8175
8197
  return component;
@@ -8231,7 +8253,7 @@
8231
8253
  * @param {Function} callback Callback function on submit form
8232
8254
  * @param {Object} options:
8233
8255
  * primaryActionName: Text to be shown in the primary action button ['Submit']
8234
- * primaryButtonClass: Button class for primary action button ['contrast']
8256
+ * primaryButtonClass: Button class for primary action button ['primary']
8235
8257
  * secondaryActionName: Text to be shown in the secondary action button ['Cancel']
8236
8258
  * secondaryActionCallback: Callback function on press secondary button
8237
8259
  * secondaryButtonClass: Button class for secondary action button ['primary']
@@ -8706,11 +8728,10 @@
8706
8728
  this._buildButtons(buttonsArray, options);
8707
8729
  }
8708
8730
  _buildButtons(buttonsArray, options = {}) {
8709
- options.className = 'lexoverlaybuttons';
8731
+ options.className = 'lexoverlaybuttons flex justify-start gap-2 bg-card m-2 p-1 rounded-2xl border-color';
8710
8732
  let overlayPanel = this.area.addPanel(options);
8711
8733
  let overlayGroup = null;
8712
- const container = document.createElement('div');
8713
- container.className = 'lexoverlaybuttonscontainer';
8734
+ const container = exports.LX.makeElement('div', 'lexoverlaybuttonscontainer absolute flex top-0 w-full pointer-events-none');
8714
8735
  container.appendChild(overlayPanel.root);
8715
8736
  this.area.attach(container);
8716
8737
  const float = options.float;
@@ -8752,6 +8773,7 @@
8752
8773
  icon: b.icon,
8753
8774
  img: b.img,
8754
8775
  className: b.class ?? '',
8776
+ buttonClass: b.buttonClass ?? 'x', // Avoid using default outline
8755
8777
  title: b.name,
8756
8778
  overflowContainerX: overlayPanel.root,
8757
8779
  swap: b.swap
@@ -8759,7 +8781,7 @@
8759
8781
  if (group) {
8760
8782
  if (!overlayGroup) {
8761
8783
  overlayGroup = document.createElement('div');
8762
- overlayGroup.className = 'lexoverlaygroup';
8784
+ overlayGroup.className = 'lexoverlaygroup flex flex-none bg-secondary rounded-xl';
8763
8785
  overlayPanel.queuedContainer = overlayGroup;
8764
8786
  }
8765
8787
  _options.parent = overlayGroup;
@@ -8868,13 +8890,10 @@
8868
8890
  _root;
8869
8891
  constructor(options = {}) {
8870
8892
  var root = document.createElement('div');
8871
- root.className = 'lexarea';
8872
8893
  if (options.id) {
8873
8894
  root.id = options.id;
8874
8895
  }
8875
- if (options.className) {
8876
- root.className += ' ' + options.className;
8877
- }
8896
+ root.className = exports.LX.mergeClass('lexarea m-0 bg-background text-foreground', options.className);
8878
8897
  var width = options.width || '100%';
8879
8898
  var height = options.height || '100%';
8880
8899
  // This has default options..
@@ -9038,8 +9057,7 @@
9038
9057
  const type = layout.type ?? 'horizontal';
9039
9058
  const resize = layout.resize ?? true;
9040
9059
  const minimizable = layout.minimizable ?? false;
9041
- const [splitA, splitB] = area.split({ type, resize, minimizable,
9042
- sizes: [layout.splits[0].size, layout.splits[1].size] });
9060
+ const [splitA, splitB] = area.split({ type, resize, minimizable, sizes: [layout.splits[0].size, layout.splits[1].size] });
9043
9061
  _splitArea(splitA, layout.splits[0]);
9044
9062
  _splitArea(splitB, layout.splits[1]);
9045
9063
  };
@@ -9139,8 +9157,7 @@
9139
9157
  // Create areas
9140
9158
  let area1 = new Area({ width: primarySize[0], height: primarySize[1], skipAppend: true,
9141
9159
  className: 'split' + (options.menubar || options.sidebar ? '' : ' origin') });
9142
- let area2 = new Area({ width: secondarySize[0], height: secondarySize[1], skipAppend: true,
9143
- className: 'split' });
9160
+ let area2 = new Area({ width: secondarySize[0], height: secondarySize[1], skipAppend: true, className: 'split' });
9144
9161
  /*
9145
9162
  If the parent area is not in the DOM, we need to wait for the resize event to get the its correct size
9146
9163
  and set the sizes of the split areas accordingly.
@@ -9412,16 +9429,15 @@
9412
9429
  addMenubar(items, options = {}) {
9413
9430
  let menubar = new Menubar(items, options);
9414
9431
  exports.LX.menubars.push(menubar);
9415
- const [bar, content] = this.split({ type: 'vertical', sizes: ['48px', null], resize: false,
9416
- menubar: true });
9432
+ const [bar, content] = this.split({ type: 'vertical', sizes: ['48px', null], resize: false, menubar: true });
9417
9433
  menubar.siblingArea = content;
9418
9434
  bar.attach(menubar);
9419
9435
  bar.isMenubar = true;
9420
9436
  if (options.sticky ?? true) {
9421
- bar.root.className += ' sticky top-0 z-1000';
9437
+ bar.root.className += ' sticky top-0 z-100';
9422
9438
  }
9423
9439
  if (options.parentClass) {
9424
- bar.root.className += ` ${options.parentClass}`;
9440
+ bar.root.className = exports.LX.mergeClass(bar.root.className, options.parentClass);
9425
9441
  }
9426
9442
  return menubar;
9427
9443
  }
@@ -9451,7 +9467,7 @@
9451
9467
  bar.attach(sidebar);
9452
9468
  bar.isSidebar = true;
9453
9469
  if (options.parentClass) {
9454
- bar.root.className += ` ${options.parentClass}`;
9470
+ bar.root.className = exports.LX.mergeClass(bar.root.className, options.parentClass);
9455
9471
  }
9456
9472
  return sidebar;
9457
9473
  }
@@ -9580,6 +9596,17 @@
9580
9596
  exports.LX.Area = Area;
9581
9597
 
9582
9598
  // Utils.ts @jxarco
9599
+ // @ts-ignore
9600
+ /* Add Tailwind merge utility to LX namespace EXTENDED with new LX class groups*/
9601
+ exports.LX.twMerge = _esm.extendTailwindMerge({
9602
+ extend: {
9603
+ classGroups: {
9604
+ pad: [
9605
+ { pad: ['xs', 'sm', 'md', 'lg', 'xl', '2xl'] }
9606
+ ]
9607
+ }
9608
+ }
9609
+ });
9583
9610
  function clamp(num, min, max) {
9584
9611
  return Math.min(Math.max(num, min), max);
9585
9612
  }
@@ -9670,7 +9697,7 @@
9670
9697
  console.assert(typeof text == 'string', 'getSupportedDOMName: Text is not a string!');
9671
9698
  let name = text.trim();
9672
9699
  // Replace specific known symbols
9673
- name = name.replace(/@/g, '_at_').replace(/\+/g, '_plus_').replace(/\./g, '_dot_');
9700
+ name = name.replace(/\//g, '_slash_').replace(/@/g, '_at_').replace(/\+/g, '_plus_').replace(/\./g, '_dot_');
9674
9701
  name = name.replace(/[^a-zA-Z0-9_-]/g, '_');
9675
9702
  // prefix with an underscore if needed
9676
9703
  if (/^[0-9]/.test(name)) {
@@ -9804,45 +9831,57 @@
9804
9831
  }
9805
9832
  exports.LX.concatTypedArray = concatTypedArray;
9806
9833
  /**
9807
- * @method setTheme
9808
- * @description Set dark or light theme
9834
+ * @method setThemeColor
9835
+ * @description Set colored theme
9836
+ * @param {String} colorThemeName Name of the color
9837
+ */
9838
+ function setThemeColor(colorThemeName) {
9839
+ document.documentElement.className = `theme-${colorThemeName}`;
9840
+ const colorScheme = exports.LX.getMode();
9841
+ document.documentElement.classList.toggle('dark', colorScheme == 'dark');
9842
+ }
9843
+ exports.LX.setThemeColor = setThemeColor;
9844
+ /**
9845
+ * @method setMode
9846
+ * @description Set dark or light scheme mode
9809
9847
  * @param {String} colorScheme Name of the scheme
9810
9848
  * @param {Boolean} storeLocal Store in localStorage
9811
9849
  */
9812
- function setTheme(colorScheme, storeLocal = true) {
9850
+ function setMode(colorScheme, storeLocal = true) {
9813
9851
  colorScheme = (colorScheme == 'light') ? 'light' : 'dark';
9814
- document.documentElement.setAttribute('data-theme', colorScheme);
9852
+ document.documentElement.setAttribute('data-mode', colorScheme);
9853
+ document.documentElement.classList.toggle('dark', colorScheme == 'dark');
9815
9854
  if (storeLocal)
9816
9855
  localStorage.setItem('lxColorScheme', colorScheme);
9817
9856
  exports.LX.emitSignal('@on_new_color_scheme', colorScheme);
9818
9857
  }
9819
- exports.LX.setTheme = setTheme;
9858
+ exports.LX.setMode = setMode;
9820
9859
  /**
9821
- * @method getTheme
9860
+ * @method getMode
9822
9861
  * @description Gets either "dark" or "light" theme value
9823
9862
  */
9824
- function getTheme() {
9825
- return document.documentElement.getAttribute('data-theme') ?? 'dark';
9863
+ function getMode() {
9864
+ return document.documentElement.getAttribute('data-mode') ?? 'dark';
9826
9865
  }
9827
- exports.LX.getTheme = getTheme;
9866
+ exports.LX.getMode = getMode;
9828
9867
  /**
9829
- * @method switchTheme
9868
+ * @method switchMode
9830
9869
  * @description Toggles between "dark" and "light" themes
9831
9870
  */
9832
- function switchTheme() {
9833
- const currentTheme = getTheme();
9834
- setTheme(currentTheme == 'dark' ? 'light' : 'dark');
9871
+ function switchMode() {
9872
+ const currentTheme = getMode();
9873
+ setMode(currentTheme == 'dark' ? 'light' : 'dark');
9835
9874
  }
9836
- exports.LX.switchTheme = switchTheme;
9875
+ exports.LX.switchMode = switchMode;
9837
9876
  /**
9838
- * @method setSystemTheme
9877
+ * @method setSystemMode
9839
9878
  * @description Sets back the system theme
9840
9879
  */
9841
- function setSystemTheme() {
9880
+ function setSystemMode() {
9842
9881
  const currentTheme = (window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches)
9843
9882
  ? 'light'
9844
9883
  : 'dark';
9845
- setTheme(currentTheme);
9884
+ setMode(currentTheme);
9846
9885
  localStorage.removeItem('lxColorScheme');
9847
9886
  // Reapply listener
9848
9887
  if (exports.LX._mqlPrefersDarkScheme) {
@@ -9850,39 +9889,55 @@
9850
9889
  exports.LX._mqlPrefersDarkScheme.addEventListener('change', exports.LX._onChangeSystemTheme);
9851
9890
  }
9852
9891
  }
9853
- exports.LX.setSystemTheme = setSystemTheme;
9892
+ exports.LX.setSystemMode = setSystemMode;
9854
9893
  /**
9855
- * @method setThemeColor
9856
- * @description Sets a new value for one of the main theme variables
9857
- * @param {String} colorName Name of the theme variable
9858
- * @param {String} color Color in rgba/hex
9894
+ * @method setCSSVariable
9895
+ * @description Sets a new value for one of the CSS root variables
9896
+ * @param {String} varName Name of the CSS variable
9897
+ * @param {String} value
9859
9898
  */
9860
- function setThemeColor(colorName, color) {
9899
+ function setCSSVariable(varName, value) {
9861
9900
  const r = document.querySelector(':root');
9862
- r.style.setProperty('--' + colorName, color);
9901
+ r.style.setProperty('--' + varName, value);
9863
9902
  }
9864
- exports.LX.setThemeColor = setThemeColor;
9903
+ exports.LX.setCSSVariable = setCSSVariable;
9865
9904
  /**
9866
- * @method getThemeColor
9867
- * @description Get the value for one of the main theme variables
9868
- * @param {String} colorName Name of the theme variable
9905
+ * @method getCSSVariable
9906
+ * @description Get the value for one of the CSS root variables
9907
+ * @param {String} varName Name of the CSS variable
9869
9908
  */
9870
- function getThemeColor(colorName) {
9909
+ function getCSSVariable(varName) {
9910
+ const [name, opacity] = varName.split('/');
9871
9911
  const r = document.querySelector(':root');
9872
9912
  const s = getComputedStyle(r);
9873
- const value = s.getPropertyValue('--' + colorName);
9913
+ let value = s.getPropertyValue('--' + name);
9914
+ if (!value)
9915
+ return '';
9874
9916
  if (value.includes('light-dark')) {
9875
9917
  const currentScheme = s.getPropertyValue('color-scheme');
9876
9918
  if (currentScheme == 'light') {
9877
- return value.substring(value.indexOf('(') + 1, value.indexOf(',')).replace(/\s/g, '');
9919
+ value = value.substring(value.indexOf('(') + 1, value.indexOf(',')).replace(/\s/g, '');
9878
9920
  }
9879
9921
  else {
9880
- return value.substring(value.indexOf(',') + 1, value.indexOf(')')).replace(/\s/g, '');
9922
+ value = value.substring(value.indexOf(',') + 1, value.indexOf(')')).replace(/\s/g, '');
9923
+ }
9924
+ }
9925
+ if (opacity) {
9926
+ if (value.includes('/'))
9927
+ return value;
9928
+ if (value.startsWith('rgb(') || value.startsWith('hsl(') || value.startsWith('oklch(')
9929
+ || value.startsWith('lab(') || value.startsWith('lch(')) {
9930
+ return value.replace(/\)$/, ` / ${parseFloat(opacity) / 100.0})`);
9931
+ }
9932
+ // Hex fallback
9933
+ if (value.startsWith('#')) {
9934
+ const rgba = exports.LX.hexToRgb(value, opacity);
9935
+ return exports.LX.rgbToHex(rgba);
9881
9936
  }
9882
9937
  }
9883
9938
  return value;
9884
9939
  }
9885
- exports.LX.getThemeColor = getThemeColor;
9940
+ exports.LX.getCSSVariable = getCSSVariable;
9886
9941
  /**
9887
9942
  * @method switchSpacing
9888
9943
  * @description Toggles between "default" and "compact" spacing layouts
@@ -9912,8 +9967,9 @@
9912
9967
  * @method hexToRgb
9913
9968
  * @description Convert a hexadecimal string to a valid RGB color
9914
9969
  * @param {String} hex Hexadecimal color
9970
+ * @param {Number} hex Opacity alpha value
9915
9971
  */
9916
- function hexToRgb(hex) {
9972
+ function hexToRgb(hex, alpha) {
9917
9973
  const hexPattern = /^#(?:[A-Fa-f0-9]{3,4}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{8})$/;
9918
9974
  if (!hexPattern.test(hex)) {
9919
9975
  throw (`Invalid Hex Color: ${hex}`);
@@ -9929,7 +9985,7 @@
9929
9985
  const b = ((bigint >> (hex.length === 8 ? 8 : 0)) & 255) / 255;
9930
9986
  const a = (hex.length === 8 ? (bigint & 255) : (hex.length === 4 ? parseInt(hex.slice(-2), 16) : 255))
9931
9987
  / 255;
9932
- return { r, g, b, a };
9988
+ return { r, g, b, a: (alpha ? alpha / 100 : a) };
9933
9989
  }
9934
9990
  exports.LX.hexToRgb = hexToRgb;
9935
9991
  /**
@@ -9954,12 +10010,48 @@
9954
10010
  rgbArray.push(rgb.a);
9955
10011
  return ('#'
9956
10012
  + rgbArray.map((c) => {
9957
- c = Math.floor(c * scale);
10013
+ c = Math.floor(exports.LX.clamp(c * scale, 0.0, scale));
9958
10014
  const hex = c.toString(16);
9959
10015
  return hex.length === 1 ? ('0' + hex) : hex;
9960
10016
  }).join(''));
9961
10017
  }
9962
10018
  exports.LX.rgbToHex = rgbToHex;
10019
+ /**
10020
+ * @method oklchToHex
10021
+ * @description Convert a oklch color to a hexadecimal string
10022
+ * @param {String} oklch String containing oklch color
10023
+ */
10024
+ function oklchToHex(oklch) {
10025
+ const match = oklch.match(/oklch\(\s*([\d.]+)%\s+([\d.]+)\s+([\d.]+)\s*\)/);
10026
+ if (!match) {
10027
+ console.error('Invalid OKLCH format');
10028
+ return '#000';
10029
+ }
10030
+ let [, Lp, C, h] = match;
10031
+ const L = parseFloat(Lp) / 100;
10032
+ const H = (parseFloat(h) * Math.PI) / 180;
10033
+ // OKLCH -> OKLab
10034
+ const a = parseFloat(C) * Math.cos(H);
10035
+ const b = parseFloat(C) * Math.sin(H);
10036
+ // OKLab -> LMS
10037
+ const l_ = L + 0.3963377774 * a + 0.2158037573 * b;
10038
+ const m_ = L - 0.1055613458 * a - 0.0638541728 * b;
10039
+ const s_ = L - 0.0894841775 * a - 1.2914855480 * b;
10040
+ const l = l_ ** 3;
10041
+ const m = m_ ** 3;
10042
+ const s = s_ ** 3;
10043
+ // LMS -> linear RGB
10044
+ let r = 4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s;
10045
+ let g = -1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s;
10046
+ let b2 = -0.0041960863 * l - 0.7034186147 * m + 1.7076147010 * s;
10047
+ // linear RGB -> sRGB
10048
+ const toSRGB = (x) => x <= 0.0031308 ? 12.92 * x : 1.055 * Math.pow(x, 1 / 2.4) - 0.055;
10049
+ r = toSRGB(r);
10050
+ g = toSRGB(g);
10051
+ b2 = toSRGB(b2);
10052
+ return exports.LX.rgbToHex({ r, g, b: b2 });
10053
+ }
10054
+ exports.LX.oklchToHex = oklchToHex;
9963
10055
  /**
9964
10056
  * @method rgbToCss
9965
10057
  * @description Convert a RGB color (0..1) to a CSS color format
@@ -10199,10 +10291,8 @@
10199
10291
  const fixedOffset = isFixed ? new vec2(parentRect.x, parentRect.y) : new vec2();
10200
10292
  left = left ?? e.clientX - offsetX - parentRect.x;
10201
10293
  top = top ?? e.clientY - offsetY - parentRect.y;
10202
- domEl.style.left =
10203
- exports.LX.clamp(left, dragMargin + fixedOffset.x, fixedOffset.x + parentRect.width - domEl.offsetWidth - dragMargin) + 'px';
10204
- domEl.style.top =
10205
- exports.LX.clamp(top, dragMargin + fixedOffset.y, fixedOffset.y + parentRect.height - domEl.offsetHeight - dragMargin) + 'px';
10294
+ domEl.style.left = exports.LX.clamp(left, dragMargin + fixedOffset.x, fixedOffset.x + parentRect.width - domEl.offsetWidth - dragMargin) + 'px';
10295
+ domEl.style.top = exports.LX.clamp(top, dragMargin + fixedOffset.y, fixedOffset.y + parentRect.height - domEl.offsetHeight - dragMargin) + 'px';
10206
10296
  domEl.style.translate = 'none'; // Force remove translation
10207
10297
  };
10208
10298
  // Initial adjustment
@@ -10328,7 +10418,7 @@
10328
10418
  return;
10329
10419
  }
10330
10420
  const snippet = document.createElement('div');
10331
- snippet.className = 'lexcodesnippet ' + (options.className ?? '');
10421
+ snippet.className = exports.LX.mergeClass('lexcodesnippet relative rounded-xl overflow-hidden', options.className);
10332
10422
  snippet.style.width = size ? size[0] : 'auto';
10333
10423
  snippet.style.height = size ? size[1] : 'auto';
10334
10424
  const area = new Area({ xskipAppend: true });
@@ -10337,7 +10427,7 @@
10337
10427
  disableEdition: true,
10338
10428
  allowAddScripts: false,
10339
10429
  name: options.tabName,
10340
- callback: (instance) => {
10430
+ onReady: (instance) => {
10341
10431
  instance.setText(code, options.language ?? 'Plain Text');
10342
10432
  if (options.linesAdded) {
10343
10433
  const code = instance.root.querySelector('.code');
@@ -10413,9 +10503,10 @@
10413
10503
  'ArrowRight': '→',
10414
10504
  'Space': '␣'
10415
10505
  };
10416
- const kbd = exports.LX.makeContainer(['auto', 'auto'], 'flex flex-row ml-auto');
10506
+ const kbd = exports.LX.makeContainer(['auto', 'auto'], `text-muted-foreground font-sans text-xs inline-flex
10507
+ ml-auto pointer-events-none select-none items-center justify-center gap-1`);
10417
10508
  for (const k of keys) {
10418
- exports.LX.makeContainer(['auto', 'auto'], 'self-center text-xs fg-secondary select-none ' + extraClass, useSpecialKeys ? specialKeys[k] ?? k : k, kbd);
10509
+ exports.LX.makeContainer(['auto', 'auto'], 'bg-muted px-1 rounded-sm ' + extraClass, useSpecialKeys ? specialKeys[k] ?? k : k, kbd);
10419
10510
  }
10420
10511
  return kbd;
10421
10512
  }
@@ -10435,38 +10526,38 @@
10435
10526
  const eraseNum = items.length - maxItems;
10436
10527
  if (eraseNum > 0) {
10437
10528
  const erased = items.splice(1, eraseNum + 1);
10438
- const ellipsisItem = { title: '...', ellipsis: erased.map((v) => v.title).join('/') };
10529
+ const ellipsisItem = { name: '...', ellipsis: erased.map((v) => v.name).join('/') };
10439
10530
  items.splice(1, 0, ellipsisItem);
10440
10531
  }
10441
10532
  for (let i = 0; i < items.length; ++i) {
10442
10533
  const item = items[i];
10443
- console.assert(item.title, 'Breadcrumb item must have a title!');
10534
+ console.assert(item.name, 'Breadcrumb item must have a name!');
10444
10535
  if (i != 0) {
10445
- const icon = exports.LX.makeIcon(separatorIcon, { svgClass: 'sm fg-secondary separator' });
10536
+ const icon = exports.LX.makeIcon(separatorIcon, { svgClass: 'sm text-foreground separator' });
10446
10537
  breadcrumb.appendChild(icon);
10447
10538
  }
10448
- const lastElement = i == items.length - 1;
10449
- const breadcrumbItem = exports.LX.makeContainer(['auto', 'auto'], `p-1 flex flex-row gap-1 items-center ${lastElement ? '' : 'fg-secondary'}`);
10539
+ const lastElement = i == (items.length - 1);
10540
+ const breadcrumbItem = exports.LX.makeContainer(['auto', 'auto'], `p-1 flex flex-row gap-1 items-center ${lastElement ? 'text-foreground' : 'text-muted-foreground'}`);
10450
10541
  breadcrumb.appendChild(breadcrumbItem);
10451
- let itemTitle = exports.LX.makeElement('p', '', item.title);
10542
+ let itemName = exports.LX.makeElement('p', '', item.name);
10452
10543
  if (item.icon) {
10453
10544
  breadcrumbItem.appendChild(exports.LX.makeIcon(item.icon, { svgClass: 'sm' }));
10454
10545
  }
10455
10546
  if (item.items !== undefined) {
10456
- const bDropdownTrigger = exports.LX.makeContainer(['auto', 'auto'], `${lastElement ? '' : 'fg-secondary'}`);
10547
+ const bDropdownTrigger = exports.LX.makeContainer(['auto', 'auto'], `${lastElement ? 'text-foreground' : 'text-muted-foreground'}`);
10457
10548
  exports.LX.listen(bDropdownTrigger, 'click', (e) => {
10458
10549
  exports.LX.addDropdownMenu(e.target, item.items, { side: 'bottom', align: 'start' });
10459
10550
  });
10460
- bDropdownTrigger.append(itemTitle);
10551
+ bDropdownTrigger.append(itemName);
10461
10552
  breadcrumbItem.appendChild(bDropdownTrigger);
10462
10553
  }
10463
10554
  else if (item.url !== undefined) {
10464
- let itemUrl = exports.LX.makeElement('a', `decoration-none fg-${lastElement ? 'primary' : 'secondary'}`, '', breadcrumbItem);
10555
+ let itemUrl = exports.LX.makeElement('a', `decoration-none hover:underline underline-offset-4 ${lastElement ? 'text-foreground' : 'text-muted-foreground'}`, '', breadcrumbItem);
10465
10556
  itemUrl.href = item.url;
10466
- itemUrl.appendChild(itemTitle);
10557
+ itemUrl.appendChild(itemName);
10467
10558
  }
10468
10559
  else {
10469
- breadcrumbItem.appendChild(itemTitle);
10560
+ breadcrumbItem.appendChild(itemName);
10470
10561
  }
10471
10562
  if (item.ellipsis) {
10472
10563
  exports.LX.asTooltip(breadcrumbItem, item.ellipsis, { side: 'bottom', offset: 4 });
@@ -10488,13 +10579,15 @@
10488
10579
  */
10489
10580
  function makeIcon(iconName, options = {}) {
10490
10581
  let svg = null;
10491
- const _createIconFromSVG = (svg) => {
10492
- if (options.svgClass && options.svgClass.length) {
10493
- options.svgClass.split(' ').forEach((c) => svg.classList.add(c));
10494
- }
10495
- const icon = document.createElement('a');
10582
+ const _createIconFromSVG = function (svg) {
10583
+ const cn = options.svgClass;
10584
+ if (cn && cn.length) {
10585
+ const mergedCn = exports.LX.twMerge(...svg.classList, ...cn.split(' '));
10586
+ svg.classList.remove(...svg.classList);
10587
+ mergedCn.split(' ').forEach((c) => svg.classList.add(c));
10588
+ }
10589
+ const icon = exports.LX.makeElement('a', exports.LX.mergeClass('lexicon', options.iconClass));
10496
10590
  icon.title = options.title ?? '';
10497
- icon.className = 'lexicon ' + (options.iconClass ?? '');
10498
10591
  icon.appendChild(svg);
10499
10592
  svg.dataset['name'] = iconName;
10500
10593
  return icon;
@@ -10519,6 +10612,7 @@
10519
10612
  // Create internal icon if variant is the same as requested, there's no lucide/fallback data or if variant is "regular" (default)
10520
10613
  if ((requestedVariant == variant) || !lucideData || variant == 'regular') {
10521
10614
  svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
10615
+ svg.classList.add('text-inherit');
10522
10616
  svg.setAttribute('viewBox', `0 0 ${data[0]} ${data[1]}`);
10523
10617
  if (data[5]) {
10524
10618
  const classes = data[5].svgClass;
@@ -10532,6 +10626,7 @@
10532
10626
  });
10533
10627
  }
10534
10628
  const path = document.createElement('path');
10629
+ path.classList.add('text-inherit');
10535
10630
  path.setAttribute('fill', 'currentColor');
10536
10631
  path.setAttribute('d', data[4]);
10537
10632
  svg.appendChild(path);
@@ -10658,7 +10753,6 @@
10658
10753
  throw ('No message to show');
10659
10754
  }
10660
10755
  options.size = options.size ?? ['max-content', 'auto'];
10661
- options.class = 'lexpopup';
10662
10756
  const time = options.timeout || 3000;
10663
10757
  const dialog = new exports.LX.Dialog(title, (p) => {
10664
10758
  p.addTextArea(null, text, null, { disabled: true, fitHeight: true });
@@ -10732,9 +10826,7 @@
10732
10826
  }
10733
10827
  const nots = exports.LX.notifications;
10734
10828
  console.assert(nots);
10735
- const toast = document.createElement('li');
10736
- toast.className = 'lextoast';
10737
- nots.prepend(toast);
10829
+ const toast = exports.LX.makeElement('li', 'lextoast flex flex-row relative w-full border-color overflow-hidden select-none pointer-events-auto touch-none rounded-lg p-3', '', nots);
10738
10830
  const [positionVertical, positionHorizontal] = options.position
10739
10831
  ? options.position.split('-')
10740
10832
  : ['bottom', 'right'];
@@ -10763,6 +10855,7 @@
10763
10855
  break;
10764
10856
  case 'center':
10765
10857
  nots.style.placeSelf = 'center';
10858
+ nots.style.justifySelf = 'anchor-center';
10766
10859
  break;
10767
10860
  case 'right':
10768
10861
  nots.style.right = '1rem';
@@ -10777,18 +10870,10 @@
10777
10870
  }
10778
10871
  toast.dataset['open'] = true;
10779
10872
  }, 10);
10780
- const content = document.createElement('div');
10781
- content.className = 'lextoastcontent';
10782
- toast.appendChild(content);
10783
- const titleContent = document.createElement('div');
10784
- titleContent.className = 'title';
10785
- titleContent.innerHTML = title;
10786
- content.appendChild(titleContent);
10873
+ const content = exports.LX.makeElement('div', 'grid h-fit max-w-lg gap-1 items-center mr-6 [&_div]:truncate [&_svg]:shrink-0', '', toast);
10874
+ exports.LX.makeElement('div', 'flex flex-row gap-2 text-sm text-foreground items-center min-w-0', title, content);
10787
10875
  if (description) {
10788
- const desc = document.createElement('div');
10789
- desc.className = 'desc';
10790
- desc.innerHTML = description;
10791
- content.appendChild(desc);
10876
+ exports.LX.makeElement('div', 'text-secondary-foreground text-xs', description, content);
10792
10877
  }
10793
10878
  if (options.action) {
10794
10879
  const panel = new Panel();
@@ -10796,7 +10881,7 @@
10796
10881
  width: 'auto',
10797
10882
  maxWidth: '150px',
10798
10883
  className: 'right',
10799
- buttonClass: 'border'
10884
+ buttonClass: 'outline sm'
10800
10885
  });
10801
10886
  toast.appendChild(panel.root.childNodes[0]);
10802
10887
  }
@@ -10811,7 +10896,7 @@
10811
10896
  }, 500);
10812
10897
  };
10813
10898
  if (options.closable ?? true) {
10814
- const closeIcon = exports.LX.makeIcon('X', { iconClass: 'closer' });
10899
+ const closeIcon = exports.LX.makeIcon('X', { iconClass: 'absolute top-2 right-2 text-sm' });
10815
10900
  closeIcon.addEventListener('click', () => {
10816
10901
  toast.close();
10817
10902
  });
@@ -10836,13 +10921,12 @@
10836
10921
  function badge(text, className, options = {}) {
10837
10922
  const container = document.createElement('div');
10838
10923
  container.innerHTML = text;
10839
- container.className = 'lexbadge ' + (className ?? '');
10840
- if (options.chip) {
10841
- container.classList.add('chip');
10842
- }
10924
+ const cn = ['lexbadge', 'inline-flex', 'items-center', 'justify-center', 'rounded-full', 'border', 'px-2', 'py-0.5', 'text-xs', 'font-medium',
10925
+ 'w-fit', 'whitespace-nowrap', 'shrink-0', 'overflow-hidden', 'border-transparent', 'gap-1', 'min-w-5', 'bg-card text-foreground'];
10926
+ container.className = className ? exports.LX.twMerge(...cn, ...className.split(' ')) : cn.join(' ');
10843
10927
  Object.assign(container.style, options.style ?? {});
10844
10928
  if (options.callback) {
10845
- const arrowIcon = exports.LX.makeIcon('ArrowUpRight', { svgClass: 'xs fg-contrast' });
10929
+ const arrowIcon = exports.LX.makeIcon('ArrowUpRight', { svgClass: 'xs' });
10846
10930
  arrowIcon.querySelector('svg').style.marginLeft = '-0.25rem';
10847
10931
  container.innerHTML += arrowIcon.innerHTML;
10848
10932
  container.addEventListener('click', (e) => {
@@ -10921,9 +11005,7 @@
10921
11005
  if (trigger.dataset['disableTooltip'] == 'true') {
10922
11006
  return;
10923
11007
  }
10924
- tooltipDom = document.createElement('div');
10925
- tooltipDom.className = 'lextooltip';
10926
- tooltipDom.innerHTML = trigger.dataset['tooltipContent'] ?? content;
11008
+ tooltipDom = exports.LX.makeElement('div', 'lextooltip fixed bg-secondary-foreground text-secondary text-xs px-2 py-1 rounded-lg pointer-events-none data-closed:opacity-0', trigger.dataset['tooltipContent'] ?? content);
10927
11009
  const nestedDialog = trigger.closest('dialog');
10928
11010
  const tooltipParent = nestedDialog ?? exports.LX.root;
10929
11011
  // Remove other first
@@ -11024,13 +11106,17 @@
11024
11106
  }
11025
11107
  exports.LX.hasClass = hasClass;
11026
11108
  function addClass(el, className) {
11027
- if (className)
11028
- el.classList.add(className);
11109
+ if (!className)
11110
+ return;
11111
+ const cn = className.split(' ');
11112
+ el.classList.add(...cn);
11029
11113
  }
11030
11114
  exports.LX.addClass = addClass;
11031
11115
  function removeClass(el, className) {
11032
- if (className)
11033
- el.classList.remove(className);
11116
+ if (!className)
11117
+ return;
11118
+ const cn = className.split(' ');
11119
+ el.classList.remove(...cn);
11034
11120
  }
11035
11121
  exports.LX.removeClass = removeClass;
11036
11122
  function toggleClass(el, className, force) {
@@ -11038,6 +11124,12 @@
11038
11124
  el.classList.toggle(className, force);
11039
11125
  }
11040
11126
  exports.LX.toggleClass = toggleClass;
11127
+ function mergeClass(className, classNameOverride) {
11128
+ if (classNameOverride)
11129
+ className = [className, classNameOverride].join(' ');
11130
+ return exports.LX.twMerge(...className.split(' '));
11131
+ }
11132
+ exports.LX.mergeClass = mergeClass;
11041
11133
  function lastChar(str) {
11042
11134
  return str[str.length - 1];
11043
11135
  }
@@ -11356,6 +11448,32 @@
11356
11448
  }
11357
11449
  exports.LX.drawSpline = drawSpline;
11358
11450
 
11451
+ // Avatar.ts @jxarco
11452
+ class Avatar {
11453
+ root;
11454
+ imageElement = undefined;
11455
+ fallbackElement = undefined;
11456
+ constructor(desc) {
11457
+ let rootCn = 'lexavatar bg-card items-center flex flex-row relative size-8 shrink-0 overflow-hidden rounded-full';
11458
+ this.root = exports.LX.makeElement('div');
11459
+ if (desc.imgSource) {
11460
+ const cn = 'aspect-square size-full object-cover';
11461
+ const img = exports.LX.makeElement('img', desc.imgClass ? exports.LX.twMerge(...cn.split(' '), ...desc.imgClass.split(' ')) : cn, '', this.root);
11462
+ img.src = desc.imgSource;
11463
+ img.alt = desc.imgAlt;
11464
+ this.imageElement = img;
11465
+ }
11466
+ else if (desc.fallback) {
11467
+ const cn = 'size-full text-sm font-semibold place-self-center text-center content-center';
11468
+ const span = exports.LX.makeElement('span', desc.fallbackClass ? exports.LX.twMerge(...cn.split(' '), ...desc.fallbackClass.split(' ')) : cn, desc.fallback, this.root);
11469
+ this.fallbackElement = span;
11470
+ rootCn += ' border-color';
11471
+ }
11472
+ this.root.className = desc.className ? exports.LX.twMerge(...rootCn.split(' '), ...desc.className.split(' ')) : rootCn;
11473
+ }
11474
+ }
11475
+ exports.LX.Avatar = Avatar;
11476
+
11359
11477
  // Spinner.ts @jxarco
11360
11478
  /**
11361
11479
  * @class Spinner
@@ -11365,8 +11483,8 @@
11365
11483
  constructor(options = {}) {
11366
11484
  const icon = options.icon ?? 'LoaderCircle';
11367
11485
  const size = options.size ?? 'md';
11368
- const iconClass = `flex ${options.iconClass ?? ''}`.trim();
11369
- const svgClass = `animate-spin ${size} ${options.svgClass ?? ''}`.trim();
11486
+ const iconClass = exports.LX.mergeClass('flex', options.iconClass);
11487
+ const svgClass = exports.LX.mergeClass(`animate-spin ${size}`, options.svgClass);
11370
11488
  this.root = exports.LX.makeIcon(icon, { iconClass, svgClass });
11371
11489
  }
11372
11490
  html() {
@@ -11400,7 +11518,7 @@
11400
11518
  this.id = exports.LX.guidGenerator();
11401
11519
  const size = options.size ?? [], position = options.position ?? [], draggable = options.draggable ?? true, dockable = options.dockable ?? false, modal = options.modal ?? false;
11402
11520
  let root = document.createElement('dialog');
11403
- root.className = 'lexdialog ' + (options.className ?? '');
11521
+ root.className = exports.LX.mergeClass('lexdialog absolute outline-none border-color m-0 p-0 min-w-3xs min-h-max overflow-hidden rounded-xl bg-background', options.className);
11404
11522
  root.id = options.id ?? 'dialog' + Dialog._last_id++;
11405
11523
  root.dataset['modal'] = modal;
11406
11524
  exports.LX.root.appendChild(root);
@@ -11410,7 +11528,8 @@
11410
11528
  let that = this;
11411
11529
  const titleDiv = document.createElement('div');
11412
11530
  if (title) {
11413
- titleDiv.className = 'lexdialogtitle';
11531
+ titleDiv.className =
11532
+ 'lexdialogtitle flex w-full outline-none items-center justify-between font-semibold text-xl text-secondary-foreground pad-xl select-none';
11414
11533
  titleDiv.innerHTML = title;
11415
11534
  titleDiv.setAttribute('draggable', 'false');
11416
11535
  root.appendChild(titleDiv);
@@ -11431,7 +11550,8 @@
11431
11550
  options.onclose(this.root);
11432
11551
  }
11433
11552
  };
11434
- const closeButton = exports.LX.makeIcon('X', { title: 'Close', iconClass: 'lexdialogcloser' });
11553
+ const closeButton = exports.LX.makeIcon('X', { title: 'Close',
11554
+ iconClass: 'lexdialogcloser text-lg text-secondary-foreground cursor-pointer z-1 select-none' });
11435
11555
  closeButton.addEventListener('click', this.close);
11436
11556
  const dockButton = exports.LX.makeIcon('Minus', { title: 'Dock', iconClass: 'ml-auto mr-2' });
11437
11557
  dockButton.addEventListener('click', () => {
@@ -11458,8 +11578,7 @@
11458
11578
  root.appendChild(closeButton);
11459
11579
  }
11460
11580
  }
11461
- const panel = new exports.LX.Panel();
11462
- panel.root.classList.add('lexdialogcontent');
11581
+ const panel = new exports.LX.Panel({ className: 'lexdialogcontent w-full p-1 text-secondary-foreground text-sm ml-0 break-all' });
11463
11582
  if (!title) {
11464
11583
  panel.root.classList.add('notitle');
11465
11584
  }
@@ -11523,19 +11642,18 @@
11523
11642
  options.draggable = false;
11524
11643
  options.modal = true;
11525
11644
  super(undefined, (p) => {
11526
- p.root.classList.add('p-4', 'flex', 'flex-col', 'gap-2');
11527
- exports.LX.makeContainer(['100%', '100%'], 'text-xl font-medium', title, p);
11528
- p.addTextArea(null, message, null, { disabled: true, fitHeight: true,
11529
- inputClass: 'bg-none fg-tertiary' });
11645
+ p.root.className = exports.LX.mergeClass(p.root.className, 'pad-2xl flex flex-col gap-2');
11646
+ exports.LX.makeContainer(['100%', '100%'], 'text-lg font-medium text-foreground', title, p);
11647
+ p.addTextArea(null, message, null, { disabled: true, fitHeight: true, inputClass: 'bg-none text-sm text-muted-foreground' });
11530
11648
  p.sameLine(2, 'justify-end');
11531
11649
  p.addButton(null, options.cancelText ?? 'Cancel', () => this.destroy(), {
11532
- buttonClass: 'border bg-primary'
11650
+ buttonClass: 'outline'
11533
11651
  });
11534
11652
  p.addButton(null, options.continueText ?? 'Continue', () => {
11535
11653
  this.destroy();
11536
11654
  if (callback)
11537
11655
  callback();
11538
- }, { buttonClass: 'contrast' });
11656
+ }, { buttonClass: 'primary' });
11539
11657
  }, options);
11540
11658
  }
11541
11659
  }
@@ -11917,8 +12035,9 @@
11917
12035
  return;
11918
12036
  }
11919
12037
  const menuItem = document.createElement('div');
11920
- menuItem.className = 'lexdropdownmenuitem' + ((item.name || item.options) ? '' : ' label')
11921
- + (item.disabled ?? false ? ' disabled' : '') + (` ${item.className ?? ''}`);
12038
+ menuItem.className = exports.LX.mergeClass('lexdropdownmenuitem flex flex-row pad-md rounded-lg gap-2 truncate cursor-pointer select-none'
12039
+ + ((item.name || item.options) ? '' : ' label')
12040
+ + (item.disabled ?? false ? ' disabled' : ''), item.className);
11922
12041
  menuItem.dataset['id'] = pKey;
11923
12042
  menuItem.innerHTML = `<span class="ellipsis-overflow">${key}</span>`;
11924
12043
  menuItem.tabIndex = '1';
@@ -11949,14 +12068,14 @@
11949
12068
  const disabled = item.disabled ?? false;
11950
12069
  if (this._radioGroup !== undefined) {
11951
12070
  if (item.name === this._radioGroup.selected) {
11952
- const icon = exports.LX.makeIcon('Circle', { svgClass: 'xxs fill-current' });
12071
+ const icon = exports.LX.makeIcon('Circle', { svgClass: '2xs fill-current' });
11953
12072
  menuItem.prepend(icon);
11954
12073
  }
11955
12074
  menuItem.setAttribute('data-radioname', this._radioGroup.name);
11956
12075
  }
11957
12076
  else if (item.icon) {
11958
12077
  const icon = item.icon.constructor === String
11959
- ? exports.LX.makeIcon(item.icon, { svgClass: disabled ? 'fg-tertiary' : item.svgClass ?? item.className })
12078
+ ? exports.LX.makeIcon(item.icon, { svgClass: disabled ? 'text-muted-foreground' : item.svgClass ?? item.className })
11960
12079
  : item.icon;
11961
12080
  menuItem.prepend(icon);
11962
12081
  }
@@ -11973,7 +12092,7 @@
11973
12092
  if (f) {
11974
12093
  f.call(this, key, v, menuItem);
11975
12094
  }
11976
- }, { className: 'accent' });
12095
+ }, { className: 'primary' });
11977
12096
  const input = checkbox.root.querySelector('input');
11978
12097
  input.classList.add('ml-auto');
11979
12098
  menuItem.appendChild(input);
@@ -12136,16 +12255,14 @@
12136
12255
  root;
12137
12256
  constructor(options = {}) {
12138
12257
  const root = document.createElement('footer');
12139
- root.className = 'lexfooter' + ` ${options.className ?? ''}`;
12258
+ root.className = exports.LX.mergeClass('lexfooter bg-background p-2 w-full leading-6 [&_p]:text-xs', options.className);
12140
12259
  const wrapper = document.createElement('div');
12141
12260
  wrapper.style.minHeight = '48px';
12142
12261
  wrapper.className = 'w-full';
12143
12262
  root.appendChild(wrapper);
12144
- // const hr = document.createElement( "hr" );
12145
- // wrapper.appendChild( hr );
12146
12263
  if (options.columns && options.columns.constructor == Array) {
12147
12264
  const cols = document.createElement('div');
12148
- cols.className = 'columns';
12265
+ cols.className = 'grid text-center';
12149
12266
  cols.style.gridTemplateColumns = '1fr '.repeat(options.columns.length);
12150
12267
  wrapper.appendChild(cols);
12151
12268
  for (let col of options.columns) {
@@ -12310,7 +12427,7 @@
12310
12427
  this.root.dataset['side'] = this.side;
12311
12428
  this.root.tabIndex = '1';
12312
12429
  this.root.role = 'dialog';
12313
- this.root.className = 'lexsheet fixed z-1000 bg-primary';
12430
+ this.root.className = 'lexsheet fixed z-1000 bg-primary overflow-hidden';
12314
12431
  document.body.appendChild(this.root);
12315
12432
  this.root.addEventListener('keydown', (e) => {
12316
12433
  if (e.key == 'Escape') {
@@ -12437,13 +12554,13 @@
12437
12554
  constructor(options = {}) {
12438
12555
  const mobile = navigator && /Android|iPhone/i.test(navigator.userAgent);
12439
12556
  this.root = document.createElement('div');
12440
- this.root.className = 'lexsidebar flex flex-col ' + (options.className ?? '');
12557
+ this.root.className = exports.LX.mergeClass('lexsidebar flex flex-col pad-xl size-full scrollbar-hidden', options.className);
12441
12558
  this.callback = options.callback ?? null;
12442
- this._displaySelected = options.displaySelected ?? false;
12443
12559
  this.side = options.side ?? 'left';
12444
12560
  this.collapsable = options.collapsable ?? true;
12445
- this._collapseWidth = (options.collapseToIcons ?? true) ? '58px' : '0px';
12446
12561
  this.collapsed = options.collapsed ?? mobile;
12562
+ this._displaySelected = options.displaySelected ?? false;
12563
+ this._collapseWidth = (options.collapseToIcons ?? true) ? '58px' : '0px';
12447
12564
  this.filterString = '';
12448
12565
  exports.LX.doAsync(() => {
12449
12566
  this.root.parentElement.ogWidth = this.root.parentElement.style.width;
@@ -12470,11 +12587,10 @@
12470
12587
  if (!(options.skipHeader ?? false)) {
12471
12588
  this.header = options.header ?? this._generateDefaultHeader(options);
12472
12589
  console.assert(this.header.constructor === HTMLDivElement, 'Use an HTMLDivElement to build your custom header');
12473
- this.header.className = 'lexsidebarheader flex-auto';
12590
+ this.header.className = 'lexsidebarheader w-full h-[48px] flex rounded-lg p-2 mb-2 text-sm cursor-pointer items-center select-none';
12474
12591
  this.root.appendChild(this.header);
12475
12592
  if (this.collapsable) {
12476
- const icon = exports.LX.makeIcon(this.side == 'left' ? 'PanelLeft' : 'PanelRight', { title: 'Toggle Sidebar',
12477
- iconClass: 'toggler' });
12593
+ const icon = exports.LX.makeIcon(this.side == 'left' ? 'PanelLeft' : 'PanelRight', { title: 'Toggle Sidebar', iconClass: 'toggler' });
12478
12594
  this.header.appendChild(icon);
12479
12595
  if (mobile) {
12480
12596
  // create an area and append a sidebar:
@@ -12510,14 +12626,14 @@
12510
12626
  // Content
12511
12627
  {
12512
12628
  this.content = document.createElement('div');
12513
- this.content.className = 'lexsidebarcontent flex-auto-fill';
12629
+ this.content.className = 'lexsidebarcontent overflow-mask flex flex-col overflow-x-hidden overflow-y-scroll flex-auto-fill w-full';
12514
12630
  this.root.appendChild(this.content);
12515
12631
  }
12516
12632
  // Footer
12517
12633
  if (!(options.skipFooter ?? false)) {
12518
12634
  this.footer = options.footer ?? this._generateDefaultFooter(options);
12519
12635
  console.assert(this.footer.constructor === HTMLDivElement, 'Use an HTMLDivElement to build your custom footer');
12520
- this.footer.className = 'lexsidebarfooter flex-auto';
12636
+ this.footer.className = 'lexsidebarfooter w-full h-[48px] flex rounded-lg p-2 mt-2 text-sm cursor-pointer items-center select-none';
12521
12637
  this.root.appendChild(this.footer);
12522
12638
  }
12523
12639
  }
@@ -12533,27 +12649,21 @@
12533
12649
  options.onHeaderPressed(e);
12534
12650
  }
12535
12651
  });
12536
- const avatar = document.createElement('span');
12537
- avatar.className = 'lexavatar';
12538
- header.appendChild(avatar);
12539
- if (options.headerImage) {
12540
- const avatarImg = document.createElement('img');
12541
- avatarImg.src = options.headerImage;
12542
- avatar.appendChild(avatarImg);
12543
- }
12544
- else if (options.headerIcon) {
12545
- const avatarIcon = exports.LX.makeIcon(options.headerIcon);
12546
- avatar.appendChild(avatarIcon);
12547
- }
12652
+ const avatar = new exports.LX.Avatar({
12653
+ imgSource: options.headerImage,
12654
+ fallback: options.headerIcon ? exports.LX.makeIcon(options.headerIcon, { svgClass: 'xl' }).innerHTML : undefined,
12655
+ className: 'rounded-lg'
12656
+ });
12657
+ header.appendChild(avatar.root);
12548
12658
  // Info
12549
12659
  {
12550
12660
  const info = document.createElement('div');
12551
12661
  info.className = 'infodefault';
12552
12662
  header.appendChild(info);
12553
- const infoText = document.createElement('span');
12663
+ const infoText = exports.LX.makeElement('span', 'truncate text-sm font-semibold');
12554
12664
  infoText.innerHTML = options.headerTitle ?? '';
12555
12665
  info.appendChild(infoText);
12556
- const infoSubtext = document.createElement('span');
12666
+ const infoSubtext = exports.LX.makeElement('span', 'truncate text-xs');
12557
12667
  infoSubtext.innerHTML = options.headerSubtitle ?? '';
12558
12668
  info.appendChild(infoSubtext);
12559
12669
  }
@@ -12571,27 +12681,21 @@
12571
12681
  options.onFooterPressed(e, footer);
12572
12682
  }
12573
12683
  });
12574
- const avatar = document.createElement('span');
12575
- avatar.className = 'lexavatar';
12576
- footer.appendChild(avatar);
12577
- if (options.footerImage) {
12578
- const avatarImg = document.createElement('img');
12579
- avatarImg.src = options.footerImage;
12580
- avatar.appendChild(avatarImg);
12581
- }
12582
- else if (options.footerIcon) {
12583
- const avatarIcon = exports.LX.makeIcon(options.footerIcon);
12584
- avatar.appendChild(avatarIcon);
12585
- }
12684
+ const avatar = new exports.LX.Avatar({
12685
+ imgSource: options.footerImage,
12686
+ fallback: options.footerIcon ? exports.LX.makeIcon(options.footerIcon, { svgClass: 'xl' }).innerHTML : undefined,
12687
+ className: 'rounded-lg'
12688
+ });
12689
+ footer.appendChild(avatar.root);
12586
12690
  // Info
12587
12691
  {
12588
12692
  const info = document.createElement('div');
12589
12693
  info.className = 'infodefault';
12590
12694
  footer.appendChild(info);
12591
- const infoText = document.createElement('span');
12695
+ const infoText = exports.LX.makeElement('span', 'truncate text-sm font-semibold');
12592
12696
  infoText.innerHTML = options.footerTitle ?? '';
12593
12697
  info.appendChild(infoText);
12594
- const infoSubtext = document.createElement('span');
12698
+ const infoSubtext = exports.LX.makeElement('span', 'truncate text-xs');
12595
12699
  infoSubtext.innerHTML = options.footerSubtitle ?? '';
12596
12700
  info.appendChild(infoSubtext);
12597
12701
  }
@@ -12726,9 +12830,8 @@
12726
12830
  }
12727
12831
  let pKey = exports.LX.getSupportedDOMName(key);
12728
12832
  let currentGroup = null;
12729
- let entry = document.createElement('div');
12833
+ let entry = exports.LX.makeElement('div', exports.LX.mergeClass('lexsidebarentry w-full rounded-lg cursor-pointer select-none', options.className));
12730
12834
  entry.id = pKey;
12731
- entry.className = 'lexsidebarentry ' + (options.className ?? '');
12732
12835
  if (this.displaySelected && options.selected) {
12733
12836
  entry.classList.add('selected');
12734
12837
  }
@@ -12736,16 +12839,13 @@
12736
12839
  const pGroupKey = item.group.replace(/\s/g, '').replaceAll('.', '');
12737
12840
  currentGroup = this.content.querySelector('#' + pGroupKey);
12738
12841
  if (!currentGroup) {
12739
- currentGroup = document.createElement('div');
12842
+ currentGroup = exports.LX.makeElement('div', 'lexsidebargroup flex flex-col gap-0.5');
12740
12843
  currentGroup.id = pGroupKey;
12741
- currentGroup.className = 'lexsidebargroup';
12742
12844
  this.content.appendChild(currentGroup);
12743
- let groupEntry = document.createElement('div');
12744
- groupEntry.className = 'lexsidebargrouptitle';
12845
+ let groupEntry = exports.LX.makeElement('div', 'lexsidebargrouptitle');
12745
12846
  currentGroup.appendChild(groupEntry);
12746
- let groupLabel = document.createElement('div');
12747
- groupLabel.innerHTML = item.group;
12748
- groupEntry.appendChild(groupLabel);
12847
+ // Group label
12848
+ exports.LX.makeElement('div', '', item.group, groupEntry);
12749
12849
  if (this.groups[item.group] != null) {
12750
12850
  const groupActionIcon = exports.LX.makeIcon(this.groups[item.group].icon, { svgClass: 'sm' });
12751
12851
  groupEntry.appendChild(groupActionIcon);
@@ -12793,7 +12893,7 @@
12793
12893
  item.value = value;
12794
12894
  if (f)
12795
12895
  f.call(this, key, value, event);
12796
- }, { className: 'accent', label: key, signal: ('@checkbox_' + key) });
12896
+ }, { className: 'primary', label: key, signal: ('@checkbox_' + key) });
12797
12897
  itemDom.appendChild(panel.root.childNodes[0]);
12798
12898
  }
12799
12899
  else {
@@ -12870,8 +12970,7 @@
12870
12970
  if (!item[key].length) {
12871
12971
  continue;
12872
12972
  }
12873
- let subentryContainer = document.createElement('div');
12874
- subentryContainer.className = 'lexsidebarsubentrycontainer';
12973
+ let subentryContainer = exports.LX.makeElement('div', 'lexsidebarsubentrycontainer flex flex-col self-center w-full ml-4 px-4 select-none');
12875
12974
  if (isCollapsable) {
12876
12975
  this.collapseContainer.appendChild(subentryContainer);
12877
12976
  delete this.collapseContainer;
@@ -12905,7 +13004,7 @@
12905
13004
  f.call(this, subkey, e);
12906
13005
  });
12907
13006
  }
12908
- subentry.className = 'lexsidebarentry';
13007
+ subentry.className = 'lexsidebarentry w-full rounded-lg cursor-pointer select-none';
12909
13008
  subentry.id = subkey;
12910
13009
  if (suboptions.content) {
12911
13010
  const parentContainer = exports.LX.makeElement('div');
@@ -13041,7 +13140,7 @@
13041
13140
  // using a fullscreen SVG with "rect" elements
13042
13141
  _generateMask(reference) {
13043
13142
  this.tourContainer.innerHTML = ''; // Clear previous content
13044
- this.tourMask = exports.LX.makeContainer(['100%', '100%'], 'tour-mask');
13143
+ this.tourMask = exports.LX.makeContainer(['100%', '100%'], 'tour-mask absolute inset-0');
13045
13144
  this.tourContainer.appendChild(this.tourMask);
13046
13145
  const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
13047
13146
  svg.style.width = '100%';
@@ -13102,7 +13201,7 @@
13102
13201
  clipPath.appendChild(rect);
13103
13202
  }
13104
13203
  // Reference Highlight
13105
- const refContainer = exports.LX.makeContainer(['0', '0'], 'tour-ref-mask');
13204
+ const refContainer = exports.LX.makeContainer(['0', '0'], 'tour-ref-mask absolute');
13106
13205
  refContainer.style.left = `${boundingX - hOffset - 1}px`;
13107
13206
  refContainer.style.top = `${boundingY - vOffset - 1}px`;
13108
13207
  refContainer.style.width = `${boundingWidth + hOffset * 2 + 2}px`;
@@ -13133,7 +13232,7 @@
13133
13232
  const popoverContainer = exports.LX.makeContainer(['auto', 'auto'], 'tour-step-container');
13134
13233
  {
13135
13234
  const header = exports.LX.makeContainer(['100%', 'auto'], 'flex flex-row', '', popoverContainer);
13136
- exports.LX.makeContainer(['70%', 'auto'], 'p-2 font-medium', step.title, header);
13235
+ exports.LX.makeContainer(['70%', 'auto'], 'p-2 font-medium text-base', step.title, header);
13137
13236
  const closer = exports.LX.makeContainer(['30%', 'auto'], 'flex flex-row p-2 justify-end', '', header);
13138
13237
  const closeIcon = exports.LX.makeIcon('X');
13139
13238
  closer.appendChild(closeIcon);
@@ -13141,22 +13240,22 @@
13141
13240
  this.stop();
13142
13241
  });
13143
13242
  }
13144
- exports.LX.makeContainer(['100%', 'auto'], 'p-2 text-md', step.content, popoverContainer, {
13243
+ exports.LX.makeContainer(['100%', 'auto'], 'p-2 text-sm', step.content, popoverContainer, {
13145
13244
  maxWidth: '400px'
13146
13245
  });
13147
- const footer = exports.LX.makeContainer(['100%', 'auto'], 'flex flex-row text-md', '', popoverContainer);
13246
+ const footer = exports.LX.makeContainer(['100%', 'auto'], 'flex flex-row', '', popoverContainer);
13148
13247
  {
13149
- const footerSteps = exports.LX.makeContainer(['50%', 'auto'], 'p-2 gap-1 self-center flex flex-row text-md', '', footer);
13248
+ const footerSteps = exports.LX.makeContainer(['50%', 'auto'], 'p-2 gap-1 place-self-center flex flex-row', '', footer);
13150
13249
  for (let i = 0; i < this.steps.length; i++) {
13151
- const stepIndicator = document.createElement('span');
13152
- stepIndicator.className = 'tour-step-indicator';
13250
+ const stepIndicator = exports.LX.makeElement('span');
13251
+ stepIndicator.className = 'size-3 rounded-full bg-accent inline-flex data-active:bg-primary';
13153
13252
  if (i === this.currentStep) {
13154
- stepIndicator.classList.add('active');
13253
+ stepIndicator.dataset['active'] = 'true';
13155
13254
  }
13156
13255
  footerSteps.appendChild(stepIndicator);
13157
13256
  }
13158
13257
  }
13159
- const footerButtons = exports.LX.makeContainer(['50%', 'auto'], 'text-md', '', footer);
13258
+ const footerButtons = exports.LX.makeContainer(['50%', 'auto'], 'text-base', '', footer);
13160
13259
  const footerPanel = new Panel();
13161
13260
  let numButtons = 1;
13162
13261
  if (previousStep) {
@@ -13168,7 +13267,7 @@
13168
13267
  if (previousStep) {
13169
13268
  footerPanel.addButton(null, 'Previous', () => {
13170
13269
  this._showStep(-1);
13171
- }, { buttonClass: 'contrast' });
13270
+ }, { buttonClass: 'ghost' });
13172
13271
  }
13173
13272
  if (nextStep) {
13174
13273
  footerPanel.addButton(null, 'Next', () => {
@@ -13178,11 +13277,10 @@
13178
13277
  else {
13179
13278
  footerPanel.addButton(null, 'Finish', () => {
13180
13279
  this.stop();
13181
- });
13280
+ }, { buttonClass: 'primary' });
13182
13281
  }
13183
13282
  footerButtons.appendChild(footerPanel.root);
13184
- const sideOffset = (step.side === 'left' || step.side === 'right' ? this.horizontalOffset : this.verticalOffset)
13185
- ?? this.offset;
13283
+ const sideOffset = (step.side === 'left' || step.side === 'right' ? this.horizontalOffset : this.verticalOffset) ?? this.offset;
13186
13284
  const alignOffset = step.align === 'start' || step.align === 'end' ? sideOffset : 0;
13187
13285
  this._popover?.destroy();
13188
13286
  this._popover = new Popover(null, [popoverContainer], {
@@ -13216,19 +13314,20 @@
13216
13314
  await exports.LX.loadScriptSync('https://unpkg.com/lucide@latest');
13217
13315
  // LexGUI root
13218
13316
  console.log(`LexGUI v${this.version}`);
13219
- var root = document.createElement('div');
13317
+ const root = exports.LX.makeElement('div', exports.LX.mergeClass('lexcontainer', options.rootClass));
13220
13318
  root.id = 'lexroot';
13221
- root.className = 'lexcontainer';
13222
13319
  root.tabIndex = -1;
13223
- if (options.rootClass) {
13224
- root.className += ` ${options.rootClass}`;
13225
- }
13226
- this.modal = document.createElement('div');
13320
+ this.modal = exports.LX.makeElement('div', 'inset-0 hidden-opacity bg-black/50 fixed z-100 transition-opacity duration-100 ease-in');
13227
13321
  this.modal.id = 'modal';
13228
- this.modal.classList.add('hidden-opacity');
13229
13322
  this.modal.toggle = function (force) {
13230
13323
  this.classList.toggle('hidden-opacity', force);
13231
13324
  };
13325
+ function blockScroll(e) {
13326
+ e.preventDefault();
13327
+ e.stopPropagation();
13328
+ }
13329
+ this.modal.addEventListener('wheel', blockScroll, { passive: false });
13330
+ this.modal.addEventListener('touchmove', blockScroll, { passive: false });
13232
13331
  this.root = root;
13233
13332
  this.container = document.body;
13234
13333
  if (options.container) {
@@ -13253,7 +13352,7 @@
13253
13352
  const notifSection = document.createElement('section');
13254
13353
  notifSection.className = 'notifications';
13255
13354
  this.notifications = document.createElement('ol');
13256
- this.notifications.className = '';
13355
+ this.notifications.className = 'fixed flex flex-col-reverse m-0 p-0 gap-1 z-1000';
13257
13356
  this.notifications.iWidth = 0;
13258
13357
  notifSection.appendChild(this.notifications);
13259
13358
  document.body.appendChild(notifSection);
@@ -13296,87 +13395,92 @@
13296
13395
  const storedcolorScheme = localStorage.getItem('lxColorScheme');
13297
13396
  if (storedcolorScheme)
13298
13397
  return;
13299
- exports.LX.setTheme(event.matches ? 'dark' : 'light', false);
13398
+ exports.LX.setMode(event.matches ? 'dark' : 'light', false);
13300
13399
  };
13301
13400
  this._mqlPrefersDarkScheme = window.matchMedia ? window.matchMedia('(prefers-color-scheme: dark)') : null;
13302
13401
  const storedcolorScheme = localStorage.getItem('lxColorScheme');
13303
13402
  if (storedcolorScheme) {
13304
- exports.LX.setTheme(storedcolorScheme);
13403
+ exports.LX.setMode(storedcolorScheme);
13305
13404
  }
13306
13405
  else if (this._mqlPrefersDarkScheme && (options.autoTheme ?? true)) {
13307
13406
  if (window.matchMedia('(prefers-color-scheme: light)').matches) {
13308
- exports.LX.setTheme('light', false);
13407
+ exports.LX.setMode('light', false);
13309
13408
  }
13310
13409
  this._mqlPrefersDarkScheme.addEventListener('change', this._onChangeSystemTheme);
13311
13410
  }
13411
+ // LX.setThemeColor( 'rose' );
13312
13412
  return this.mainArea;
13313
- }, /**
13413
+ };
13414
+ /**
13314
13415
  * @method setSpacingMode
13315
13416
  * @param {String} mode: "default" | "compact"
13316
13417
  */
13317
- exports.LX.setSpacingMode = function (mode) {
13318
- this.spacingMode = mode;
13319
- document.documentElement.setAttribute('data-spacing', this.spacingMode);
13320
- }, /**
13418
+ exports.LX.setSpacingMode = function (mode) {
13419
+ this.spacingMode = mode;
13420
+ document.documentElement.setAttribute('data-spacing', this.spacingMode);
13421
+ };
13422
+ /**
13321
13423
  * @method setLayoutMode
13322
13424
  * @param {String} mode: "app" | "document"
13323
13425
  */
13324
- exports.LX.setLayoutMode = function (mode) {
13325
- this.layoutMode = mode;
13326
- document.documentElement.setAttribute('data-layout', this.layoutMode);
13327
- }, /**
13426
+ exports.LX.setLayoutMode = function (mode) {
13427
+ this.layoutMode = mode;
13428
+ document.documentElement.setAttribute('data-layout', this.layoutMode);
13429
+ };
13430
+ /**
13328
13431
  * @method addSignal
13329
13432
  * @param {String} name
13330
13433
  * @param {Object} obj
13331
13434
  * @param {Function} callback
13332
13435
  */
13333
- exports.LX.addSignal = function (name, obj, callback) {
13334
- obj[name] = callback;
13335
- if (!exports.LX.signals[name]) {
13336
- exports.LX.signals[name] = [];
13337
- }
13338
- if (exports.LX.signals[name].indexOf(obj) > -1) {
13339
- return;
13340
- }
13341
- exports.LX.signals[name].push(obj);
13342
- }, /**
13436
+ exports.LX.addSignal = function (name, obj, callback) {
13437
+ obj[name] = callback;
13438
+ if (!exports.LX.signals[name]) {
13439
+ exports.LX.signals[name] = [];
13440
+ }
13441
+ if (exports.LX.signals[name].indexOf(obj) > -1) {
13442
+ return;
13443
+ }
13444
+ exports.LX.signals[name].push(obj);
13445
+ };
13446
+ /**
13343
13447
  * @method emitSignal
13344
13448
  * @param {String} name
13345
13449
  * @param {*} value
13346
13450
  * @param {Object} options
13347
13451
  */
13348
- exports.LX.emitSignal = function (name, value, options = {}) {
13349
- const data = exports.LX.signals[name];
13350
- if (!data) {
13351
- return;
13452
+ exports.LX.emitSignal = function (name, value, options = {}) {
13453
+ const data = exports.LX.signals[name];
13454
+ if (!data) {
13455
+ return;
13456
+ }
13457
+ const target = options.target;
13458
+ if (target) {
13459
+ if (target[name]) {
13460
+ target[name].call(target, value);
13352
13461
  }
13353
- const target = options.target;
13354
- if (target) {
13355
- if (target[name]) {
13356
- target[name].call(target, value);
13357
- }
13358
- return;
13462
+ return;
13463
+ }
13464
+ for (let obj of data) {
13465
+ if (obj instanceof BaseComponent) {
13466
+ obj.set(value, options.skipCallback ?? true);
13359
13467
  }
13360
- for (let obj of data) {
13361
- if (obj instanceof BaseComponent) {
13362
- obj.set(value, options.skipCallback ?? true);
13363
- }
13364
- else if (obj.constructor === Function) {
13365
- const fn = obj;
13366
- fn(null, value);
13367
- }
13368
- else {
13369
- // This is an element
13370
- const fn = obj[name];
13371
- console.assert(fn, `No callback registered with _${name}_ signal`);
13372
- fn.bind(obj)(value);
13373
- }
13468
+ else if (obj.constructor === Function) {
13469
+ const fn = obj;
13470
+ fn(null, value);
13374
13471
  }
13375
- };
13472
+ else {
13473
+ // This is an element
13474
+ const fn = obj[name];
13475
+ console.assert(fn, `No callback registered with _${name}_ signal`);
13476
+ fn.bind(obj)(value);
13477
+ }
13478
+ }
13479
+ };
13376
13480
  // Command bar creation
13377
13481
  exports.LX._createCommandbar = function (root) {
13378
13482
  let commandbar = document.createElement('dialog');
13379
- commandbar.className = 'commandbar';
13483
+ commandbar.className = 'commandbar absolute border-color rounded-lg m-0';
13380
13484
  commandbar.tabIndex = -1;
13381
13485
  root.appendChild(commandbar);
13382
13486
  let allItems = [];
@@ -13425,7 +13529,7 @@
13425
13529
  }
13426
13530
  e.stopPropagation();
13427
13531
  e.stopImmediatePropagation();
13428
- commandbar.close();
13532
+ exports.LX.setCommandbarState(false);
13429
13533
  _resetBar(true);
13430
13534
  });
13431
13535
  root.addEventListener('keydown', (e) => {
@@ -13465,8 +13569,7 @@
13465
13569
  cbTabs.add('All', document.createElement('div'), { selected: true, onSelect: _onSelectTab });
13466
13570
  // cbTabs.add( "Main", document.createElement('div'), { onSelect: _onSelectTab } );
13467
13571
  }
13468
- const itemContainer = document.createElement('div');
13469
- itemContainer.className = 'searchitembox';
13572
+ const itemContainer = exports.LX.makeElement('div', 'searchitembox overflow-y-scroll basis-full scrollbar-hidden');
13470
13573
  let refPrevious = null;
13471
13574
  const _resetBar = (resetInput) => {
13472
13575
  itemContainer.innerHTML = '';
@@ -13476,6 +13579,53 @@
13476
13579
  filter.set('', true);
13477
13580
  }
13478
13581
  };
13582
+ const _filterEntry = function (entryName, filter) {
13583
+ if (!filter?.length)
13584
+ return false;
13585
+ const cleanName = exports.LX.stripTags(entryName).toLowerCase();
13586
+ return cleanName.includes(filter.toLowerCase());
13587
+ };
13588
+ const _getEntries = function (filter) {
13589
+ const entries = [];
13590
+ for (let m of exports.LX.menubars) {
13591
+ for (let i of m.items) {
13592
+ if (_filterEntry(i.name, filter))
13593
+ entries.push(i);
13594
+ }
13595
+ }
13596
+ for (let m of exports.LX.sidebars) {
13597
+ for (let i of m.items) {
13598
+ if (_filterEntry(i.name, filter))
13599
+ entries.push(i);
13600
+ }
13601
+ }
13602
+ for (let entry of exports.LX.extraCommandbarEntries) {
13603
+ if (_filterEntry(entry.name, filter))
13604
+ entries.push(entry);
13605
+ }
13606
+ if (exports.LX.has('CodeEditor')) {
13607
+ const instances = exports.LX.CodeEditor.getInstances();
13608
+ if (!instances.length || !instances[0].area.root.offsetHeight)
13609
+ return entries;
13610
+ const languages = exports.LX.CodeEditor.languages;
13611
+ for (let l of Object.keys(languages)) {
13612
+ const key = 'Language: ' + l;
13613
+ const icon = instances[0]._getFileIcon(null, languages[l].ext);
13614
+ const classes = icon.split(' ');
13615
+ let value = exports.LX.makeIcon(classes[0], { svgClass: `${classes.slice(0).join(' ')}` }).innerHTML;
13616
+ value += key + " <span class='lang-ext'>(" + languages[l].ext + ')</span>';
13617
+ if (!_filterEntry(key, filter)) {
13618
+ continue;
13619
+ }
13620
+ entries.push({ name: value, callback: () => {
13621
+ for (let i of instances) {
13622
+ i._changeLanguage(l);
13623
+ }
13624
+ } });
13625
+ }
13626
+ }
13627
+ return entries;
13628
+ };
13479
13629
  const _addElement = (t, c, p, i) => {
13480
13630
  if (!t.length) {
13481
13631
  return;
@@ -13513,64 +13663,41 @@
13513
13663
  itemContainer.appendChild(searchItem);
13514
13664
  refPrevious = searchItem;
13515
13665
  };
13516
- const _propagateAdd = (item, filter, path, skipPropagation) => {
13666
+ const _propagateAdd = (item, path, skipPropagation) => {
13517
13667
  if (!item || (item.constructor != Object)) {
13518
13668
  return;
13519
13669
  }
13520
- let name = item.name;
13521
- if (name.toLowerCase().includes(filter)) {
13522
- if (item.callback) {
13523
- _addElement(name, item.callback, path, item);
13524
- }
13670
+ if (item.callback) {
13671
+ _addElement(item.name, item.callback, path, item);
13525
13672
  }
13526
- const submenu = item.submenu ?? item[name];
13673
+ const submenu = item.submenu ?? item[item.name];
13527
13674
  if (!submenu) {
13528
13675
  return;
13529
13676
  }
13530
- const icon = exports.LX.makeIcon('ChevronRight', { svgClass: 'sm fg-secondary separator' });
13531
- path += name + icon.innerHTML;
13677
+ const icon = exports.LX.makeIcon('ChevronRight', { svgClass: 'sm text-muted-foreground separator' });
13678
+ path += item.name + icon.innerHTML;
13532
13679
  for (let c of submenu) {
13533
- _propagateAdd(c, filter, path);
13680
+ _propagateAdd(c, path);
13534
13681
  }
13535
13682
  };
13536
13683
  commandbar._addElements = (filter) => {
13537
13684
  _resetBar();
13538
- for (let m of exports.LX.menubars) {
13539
- for (let i of m.items) {
13540
- _propagateAdd(i, filter, '');
13541
- }
13542
- }
13543
- for (let m of exports.LX.sidebars) {
13544
- for (let i of m.items) {
13545
- _propagateAdd(i, filter, '');
13546
- }
13547
- }
13548
- for (let entry of exports.LX.extraCommandbarEntries) {
13549
- const name = entry.name;
13550
- if (!name.toLowerCase().includes(filter)) {
13551
- continue;
13552
- }
13553
- _addElement(name, entry.callback, '', {});
13554
- }
13555
- if (exports.LX.has('CodeEditor')) {
13556
- const instances = exports.LX.CodeEditor.getInstances();
13557
- if (!instances.length || !instances[0].area.root.offsetHeight)
13558
- return;
13559
- const languages = exports.LX.CodeEditor.languages;
13560
- for (let l of Object.keys(languages)) {
13561
- const key = 'Language: ' + l;
13562
- const icon = instances[0]._getFileIcon(null, languages[l].ext);
13563
- const classes = icon.split(' ');
13564
- let value = exports.LX.makeIcon(classes[0], { svgClass: `${classes.slice(0).join(' ')}` }).innerHTML;
13565
- value += key + " <span class='lang-ext'>(" + languages[l].ext + ')</span>';
13566
- if (key.toLowerCase().includes(filter)) {
13567
- _addElement(value, () => {
13568
- for (let i of instances) {
13569
- i._changeLanguage(l);
13570
- }
13571
- }, '', {});
13572
- }
13573
- }
13685
+ let entries = _getEntries(filter);
13686
+ // Order...
13687
+ function scoreEntry(s, prefix) {
13688
+ if (s.startsWith(prefix))
13689
+ return 0; // best option
13690
+ if (s.includes(prefix))
13691
+ return 1;
13692
+ return 2; // worst
13693
+ }
13694
+ entries = entries.sort((a, b) => {
13695
+ const nameA = exports.LX.stripTags(a.name), nameB = exports.LX.stripTags(b.name);
13696
+ return (scoreEntry(nameA, filter) - scoreEntry(nameB, filter)) || nameA.localeCompare(nameB);
13697
+ });
13698
+ entries = entries.slice(0, 48); // Get 48 ocurrences max
13699
+ for (let entry of entries) {
13700
+ _propagateAdd(entry, '');
13574
13701
  }
13575
13702
  };
13576
13703
  commandbar.appendChild(header);
@@ -13578,6 +13705,37 @@
13578
13705
  commandbar.appendChild(itemContainer);
13579
13706
  return commandbar;
13580
13707
  };
13708
+ exports.LX._registerIconsAndColors = function (colorsRootPath = './') {
13709
+ exports.LX.requestJSON(colorsRootPath + 'registry/colors.json', (colors) => {
13710
+ // loop through each color
13711
+ for (const key in colors) {
13712
+ const value = colors[key];
13713
+ if (!Array.isArray(value)) {
13714
+ continue;
13715
+ }
13716
+ value.forEach((entry) => {
13717
+ const color = `${key}-${entry.scale}`;
13718
+ const val = `<span class="flex bg-${color} w-3 h-3 rounded-full mr-2"></span>${color}`;
13719
+ exports.LX.registerCommandbarEntry(val, () => {
13720
+ navigator.clipboard.writeText(color);
13721
+ exports.LX.toast(`${exports.LX.makeIcon('CircleCheck').innerHTML} Copied ${color} to clipboard.`, null, { position: 'top-center',
13722
+ timeout: 3000 });
13723
+ });
13724
+ });
13725
+ }
13726
+ });
13727
+ const lucide = window.lucide;
13728
+ const allIcons = { ...exports.LX.ICONS, ...lucide.icons };
13729
+ for (const iconName in allIcons) {
13730
+ const variant = 'regular';
13731
+ const icon = exports.LX.makeIcon(iconName, { svgClass: 'mr-2 pointer-events-none', variant });
13732
+ const val = `${icon.innerHTML}${iconName}`;
13733
+ exports.LX.registerCommandbarEntry(val, () => {
13734
+ navigator.clipboard.writeText(iconName);
13735
+ exports.LX.toast(`${exports.LX.makeIcon('CircleCheck').innerHTML} Copied ${iconName} to clipboard.`, null, { position: 'top-center', timeout: 3000 });
13736
+ });
13737
+ }
13738
+ };
13581
13739
  /**
13582
13740
  * @method setCommandbarState
13583
13741
  * @param {Boolean} value
@@ -13585,12 +13743,16 @@
13585
13743
  */
13586
13744
  exports.LX.setCommandbarState = function (value, resetEntries = true) {
13587
13745
  const cb = this.commandbar;
13746
+ exports.LX.modal.toggle(!value);
13588
13747
  if (value) {
13748
+ // Get current position based on main scroll
13749
+ cb.style.top = `calc(15% + ${document.scrollingElement?.scrollTop ?? 0}px)`;
13589
13750
  cb.show();
13590
13751
  cb.querySelector('input').focus();
13591
13752
  if (resetEntries) {
13592
13753
  cb._addElements(undefined);
13593
13754
  }
13755
+ exports.LX.modal.toggle(false);
13594
13756
  }
13595
13757
  else {
13596
13758
  cb.close();
@@ -13636,7 +13798,7 @@
13636
13798
  const customIcon = exports.LX.makeIcon(options.icon ?? 'Box');
13637
13799
  const menuIcon = exports.LX.makeIcon('Menu');
13638
13800
  let buttonName = customComponentName + (!instance ? ' [empty]' : '');
13639
- let buttonEl = this.addButton(null, buttonName, (value, event) => {
13801
+ let button = this.addButton(null, buttonName, (value, event) => {
13640
13802
  if (instance) {
13641
13803
  element.querySelector('.lexcustomitems').toggleAttribute('hidden');
13642
13804
  element.dataset['opened'] = !element.querySelector('.lexcustomitems').hasAttribute('hidden');
@@ -13651,11 +13813,11 @@
13651
13813
  });
13652
13814
  });
13653
13815
  }
13654
- }, { buttonClass: 'custom' });
13655
- const buttonSpan = buttonEl.root.querySelector('span');
13656
- buttonSpan.prepend(customIcon);
13657
- buttonSpan.appendChild(menuIcon);
13658
- container.appendChild(buttonEl.root);
13816
+ }, { buttonClass: 'outline custom' });
13817
+ const buttonDom = button.root.querySelector('button');
13818
+ buttonDom.prepend(customIcon);
13819
+ buttonDom.appendChild(menuIcon);
13820
+ container.appendChild(button.root);
13659
13821
  if (instance) {
13660
13822
  menuIcon.addEventListener('click', (e) => {
13661
13823
  e.stopImmediatePropagation();
@@ -13739,6 +13901,7 @@
13739
13901
  exports.Area = Area;
13740
13902
  exports.AreaOverlayButtons = AreaOverlayButtons;
13741
13903
  exports.ArrayInput = ArrayInput;
13904
+ exports.Avatar = Avatar;
13742
13905
  exports.BaseComponent = BaseComponent;
13743
13906
  exports.Branch = Branch;
13744
13907
  exports.Button = Button;
@@ -13787,7 +13950,6 @@
13787
13950
  exports.Toggle = Toggle;
13788
13951
  exports.Tour = Tour;
13789
13952
  exports.Tree = Tree;
13790
- exports.TreeEvent = TreeEvent;
13791
13953
  exports.Vector = Vector;
13792
13954
  exports.addDropdownMenu = addDropdownMenu;
13793
13955
  exports.vec2 = vec2;