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.
- package/build/components/Avatar.d.ts +15 -0
- package/build/components/NodeTree.d.ts +51 -26
- package/build/components/Vector.d.ts +10 -9
- package/build/core/Event.d.ts +6 -26
- package/build/core/Namespace.js +1 -1
- package/build/core/Namespace.js.map +1 -1
- package/build/core/Panel.d.ts +538 -538
- package/build/extensions/AssetView.d.ts +7 -6
- package/build/extensions/AssetView.js +194 -155
- package/build/extensions/AssetView.js.map +1 -1
- package/build/extensions/Audio.js.map +1 -1
- package/build/extensions/CodeEditor.d.ts +358 -350
- package/build/extensions/CodeEditor.js +5054 -5022
- package/build/extensions/CodeEditor.js.map +1 -1
- package/build/extensions/DocMaker.js +330 -327
- package/build/extensions/DocMaker.js.map +1 -1
- package/build/extensions/GraphEditor.js +2754 -2760
- package/build/extensions/GraphEditor.js.map +1 -1
- package/build/extensions/Timeline.d.ts +668 -670
- package/build/extensions/Timeline.js +3948 -3955
- package/build/extensions/Timeline.js.map +1 -1
- package/build/extensions/VideoEditor.d.ts +128 -128
- package/build/extensions/VideoEditor.js +893 -898
- package/build/extensions/VideoEditor.js.map +1 -1
- package/build/index.css.d.ts +3 -4
- package/build/index.d.ts +57 -56
- package/build/lexgui.all.js +1587 -1369
- package/build/lexgui.all.js.map +1 -1
- package/build/lexgui.all.min.js +1 -1
- package/build/lexgui.all.module.js +1584 -1364
- package/build/lexgui.all.module.js.map +1 -1
- package/build/lexgui.all.module.min.js +1 -1
- package/build/lexgui.css +6157 -5583
- package/build/lexgui.js +977 -815
- package/build/lexgui.js.map +1 -1
- package/build/lexgui.min.css +2 -3
- package/build/lexgui.min.js +1 -1
- package/build/lexgui.module.js +975 -811
- package/build/lexgui.module.js.map +1 -1
- package/build/lexgui.module.min.js +1 -1
- package/changelog.md +52 -1
- package/demo.js +167 -65
- package/examples/all-components.html +38 -52
- package/examples/asset-view.html +27 -0
- package/examples/code-editor.html +1 -1
- package/examples/editor.html +10 -95
- package/examples/index.html +2 -2
- package/examples/side-bar.html +1 -1
- package/examples/timeline.html +2 -2
- package/examples/video-editor.html +1 -1
- package/examples/video-editor2.html +2 -2
- package/package.json +7 -4
package/build/lexgui.module.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
// This is a generated file. Do not edit.
|
|
2
|
+
import { extendTailwindMerge } from 'https://cdn.jsdelivr.net/npm/tailwind-merge@3.4.0/+esm';
|
|
3
|
+
|
|
2
4
|
// Namespace.ts @jxarco
|
|
3
5
|
/**
|
|
4
6
|
* Main namespace
|
|
@@ -10,7 +12,7 @@ const g = globalThis;
|
|
|
10
12
|
let LX = g.LX;
|
|
11
13
|
if (!LX) {
|
|
12
14
|
LX = {
|
|
13
|
-
version: '8.
|
|
15
|
+
version: '8.2',
|
|
14
16
|
ready: false,
|
|
15
17
|
extensions: [], // Store extensions used
|
|
16
18
|
extraCommandbarEntries: [], // User specific entries for command bar
|
|
@@ -121,8 +123,7 @@ const RAW_ICONS = {
|
|
|
121
123
|
'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'],
|
|
122
124
|
'WindowMaximize': [512, 512, [], 'solid',
|
|
123
125
|
'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'],
|
|
124
|
-
'WindowMinimize': [512, 512, [], 'solid',
|
|
125
|
-
'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'],
|
|
126
|
+
'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'],
|
|
126
127
|
'VrCardboard': [640, 512, ['VR'], 'solid',
|
|
127
128
|
'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'],
|
|
128
129
|
'C': [32, 32, [], 'solid',
|
|
@@ -168,8 +169,7 @@ const RAW_ICONS = {
|
|
|
168
169
|
'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'],
|
|
169
170
|
'Rust': [512, 512, [], 'solid',
|
|
170
171
|
'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'],
|
|
171
|
-
'Unity': [16, 16, [], 'solid',
|
|
172
|
-
'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'],
|
|
172
|
+
'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'],
|
|
173
173
|
'UnrealEngine': [24, 24, [], 'regular',
|
|
174
174
|
'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'],
|
|
175
175
|
'UnrealEngine@solid': [24, 24, [], 'solid',
|
|
@@ -256,8 +256,7 @@ const RAW_ICONS = {
|
|
|
256
256
|
'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'],
|
|
257
257
|
'Function': [384, 512, [], 'solid',
|
|
258
258
|
'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'],
|
|
259
|
-
'Stop': [384, 512, [], 'solid',
|
|
260
|
-
'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'],
|
|
259
|
+
'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'],
|
|
261
260
|
'Image': [512, 512, [], 'solid',
|
|
262
261
|
'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'],
|
|
263
262
|
'Images': [576, 512, [], 'solid',
|
|
@@ -388,52 +387,6 @@ class IEvent {
|
|
|
388
387
|
}
|
|
389
388
|
}
|
|
390
389
|
LX.IEvent = IEvent;
|
|
391
|
-
class TreeEvent {
|
|
392
|
-
static NONE = 0;
|
|
393
|
-
static NODE_SELECTED = 1;
|
|
394
|
-
static NODE_DELETED = 2;
|
|
395
|
-
static NODE_DBLCLICKED = 3;
|
|
396
|
-
static NODE_CONTEXTMENU = 4;
|
|
397
|
-
static NODE_DRAGGED = 5;
|
|
398
|
-
static NODE_RENAMED = 6;
|
|
399
|
-
static NODE_VISIBILITY = 7;
|
|
400
|
-
static NODE_CARETCHANGED = 8;
|
|
401
|
-
type = TreeEvent.NONE;
|
|
402
|
-
node;
|
|
403
|
-
value;
|
|
404
|
-
event;
|
|
405
|
-
multiple = false; // Multiple selection
|
|
406
|
-
panel = null;
|
|
407
|
-
constructor(type, node, value, event) {
|
|
408
|
-
this.type = type || TreeEvent.NONE;
|
|
409
|
-
this.node = node;
|
|
410
|
-
this.value = value;
|
|
411
|
-
this.event = event;
|
|
412
|
-
}
|
|
413
|
-
string() {
|
|
414
|
-
switch (this.type) {
|
|
415
|
-
case TreeEvent.NONE:
|
|
416
|
-
return 'tree_event_none';
|
|
417
|
-
case TreeEvent.NODE_SELECTED:
|
|
418
|
-
return 'tree_event_selected';
|
|
419
|
-
case TreeEvent.NODE_DELETED:
|
|
420
|
-
return 'tree_event_deleted';
|
|
421
|
-
case TreeEvent.NODE_DBLCLICKED:
|
|
422
|
-
return 'tree_event_dblclick';
|
|
423
|
-
case TreeEvent.NODE_CONTEXTMENU:
|
|
424
|
-
return 'tree_event_contextmenu';
|
|
425
|
-
case TreeEvent.NODE_DRAGGED:
|
|
426
|
-
return 'tree_event_dragged';
|
|
427
|
-
case TreeEvent.NODE_RENAMED:
|
|
428
|
-
return 'tree_event_renamed';
|
|
429
|
-
case TreeEvent.NODE_VISIBILITY:
|
|
430
|
-
return 'tree_event_visibility';
|
|
431
|
-
case TreeEvent.NODE_CARETCHANGED:
|
|
432
|
-
return 'tree_event_caretchanged';
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
LX.TreeEvent = TreeEvent;
|
|
437
390
|
|
|
438
391
|
// BaseComponent.ts @jxarco
|
|
439
392
|
var ComponentType;
|
|
@@ -508,8 +461,7 @@ class BaseComponent {
|
|
|
508
461
|
this.name = name;
|
|
509
462
|
this.options = options;
|
|
510
463
|
this._initialValue = value;
|
|
511
|
-
const root =
|
|
512
|
-
root.className = 'lexcomponent';
|
|
464
|
+
const root = LX.makeElement('div', LX.mergeClass('lexcomponent flex flex-row outline-none items-center text-foreground text-sm overflow-hidden min-h-8 pad-sm', options.className));
|
|
513
465
|
this.onResize = () => { };
|
|
514
466
|
if (options.id) {
|
|
515
467
|
root.id = options.id;
|
|
@@ -517,9 +469,6 @@ class BaseComponent {
|
|
|
517
469
|
if (options.title) {
|
|
518
470
|
root.title = options.title;
|
|
519
471
|
}
|
|
520
|
-
if (options.className) {
|
|
521
|
-
root.className += ' ' + options.className;
|
|
522
|
-
}
|
|
523
472
|
if (type != ComponentType.TITLE) {
|
|
524
473
|
if (options.width) {
|
|
525
474
|
root.style.width = root.style.minWidth = options.width;
|
|
@@ -537,12 +486,10 @@ class BaseComponent {
|
|
|
537
486
|
}
|
|
538
487
|
if (name != undefined) {
|
|
539
488
|
if (!(options.hideName ?? false)) {
|
|
540
|
-
let domName =
|
|
541
|
-
domName.className = 'lexcomponentname';
|
|
489
|
+
let domName = LX.makeElement('div', 'lexcomponentname flex text-sm text-secondary-foreground justify-between whitespace-nowrap overflow-hidden', name);
|
|
542
490
|
if (options.justifyName) {
|
|
543
491
|
domName.classList.add('float-' + options.justifyName);
|
|
544
492
|
}
|
|
545
|
-
domName.innerHTML = name;
|
|
546
493
|
domName.title = options.title ?? domName.innerHTML;
|
|
547
494
|
domName.style.width = options.nameWidth || LX.DEFAULT_NAME_WIDTH;
|
|
548
495
|
domName.style.minWidth = domName.style.width;
|
|
@@ -771,7 +718,7 @@ class Button extends BaseComponent {
|
|
|
771
718
|
wValue.prepend(img);
|
|
772
719
|
}
|
|
773
720
|
else {
|
|
774
|
-
wValue.innerHTML =
|
|
721
|
+
wValue.innerHTML = `${(newValue ?? '')}`;
|
|
775
722
|
}
|
|
776
723
|
};
|
|
777
724
|
this.onResize = (rect) => {
|
|
@@ -798,9 +745,10 @@ class Button extends BaseComponent {
|
|
|
798
745
|
this._trigger(new IEvent(name, swapInput ? swapInput.checked : (this.selectable ? v : value), null), callback);
|
|
799
746
|
}
|
|
800
747
|
};
|
|
801
|
-
var wValue =
|
|
748
|
+
var wValue = LX.makeElement('button', LX.mergeClass(['lexbutton', 'inline-flex', 'items-center', 'justify-center', 'whitespace-nowrap', 'transition-all', 'disabled:pointer-events-none',
|
|
749
|
+
'disabled:opacity-50', '[&_svg]:pointer-events-none', 'shrink-0', '[&_svg]:shrink-0', 'outline-none', 'select-none', 'cursor-pointer',
|
|
750
|
+
'font-medium', 'text-sm', 'border-1', 'h-9', 'px-2', 'overflow-hidden', 'bg-clip-padding'].join(' '), options.buttonClass ?? 'outline'));
|
|
802
751
|
wValue.title = options.tooltip ? '' : (options.title ?? '');
|
|
803
|
-
wValue.className = 'lexbutton px-3 ' + (options.buttonClass ?? '');
|
|
804
752
|
this.root.appendChild(wValue);
|
|
805
753
|
if (options.selected) {
|
|
806
754
|
wValue.classList.add('selected');
|
|
@@ -818,19 +766,19 @@ class Button extends BaseComponent {
|
|
|
818
766
|
wValue.prepend(icon);
|
|
819
767
|
}
|
|
820
768
|
else {
|
|
821
|
-
wValue.innerHTML =
|
|
769
|
+
wValue.innerHTML = `${(value || '')}`;
|
|
822
770
|
if (iconPosition == 'start') {
|
|
823
|
-
wValue.
|
|
771
|
+
wValue.prepend(icon);
|
|
824
772
|
}
|
|
825
773
|
// "end"
|
|
826
774
|
else {
|
|
827
|
-
wValue.
|
|
775
|
+
wValue.appendChild(icon);
|
|
828
776
|
}
|
|
829
777
|
}
|
|
830
778
|
wValue.classList.add('justify-center');
|
|
831
779
|
}
|
|
832
780
|
else {
|
|
833
|
-
wValue.innerHTML =
|
|
781
|
+
wValue.innerHTML = `${(value || '')}`;
|
|
834
782
|
}
|
|
835
783
|
if (options.fileInput) {
|
|
836
784
|
const fileInput = document.createElement('input');
|
|
@@ -955,10 +903,9 @@ class Menubar {
|
|
|
955
903
|
focused = false;
|
|
956
904
|
_currentDropdown;
|
|
957
905
|
constructor(items, options = {}) {
|
|
958
|
-
this.root =
|
|
959
|
-
this.root.className = 'lexmenubar';
|
|
906
|
+
this.root = LX.makeElement('div', 'lexmenubar size-full bg-background text-foreground inline-flex gap-1 overflow-hidden text-sm font-medium');
|
|
960
907
|
if (options.float) {
|
|
961
|
-
this.root.
|
|
908
|
+
this.root.className = LX.mergeClass(this.root.className, `justify-${options.float}`);
|
|
962
909
|
}
|
|
963
910
|
this.items = items ?? [];
|
|
964
911
|
this.createEntries();
|
|
@@ -996,8 +943,7 @@ class Menubar {
|
|
|
996
943
|
this._resetMenubar(true);
|
|
997
944
|
entry.classList.add('selected');
|
|
998
945
|
entry.dataset['built'] = 'true';
|
|
999
|
-
this._currentDropdown = LX.addDropdownMenu(entry, item.submenu ?? [], { side: 'bottom', align: 'start',
|
|
1000
|
-
onBlur: () => {
|
|
946
|
+
this._currentDropdown = LX.addDropdownMenu(entry, item.submenu ?? [], { side: 'bottom', align: 'start', onBlur: () => {
|
|
1001
947
|
this._resetMenubar();
|
|
1002
948
|
} });
|
|
1003
949
|
};
|
|
@@ -1172,7 +1118,7 @@ class Menubar {
|
|
|
1172
1118
|
const title = data.title;
|
|
1173
1119
|
const button = new Button(title, data.label, data.callback, {
|
|
1174
1120
|
title,
|
|
1175
|
-
buttonClass: '
|
|
1121
|
+
buttonClass: 'ghost',
|
|
1176
1122
|
disabled: data.disabled,
|
|
1177
1123
|
icon: data.icon,
|
|
1178
1124
|
hideName: true,
|
|
@@ -1205,7 +1151,7 @@ class Tabs {
|
|
|
1205
1151
|
constructor(area, options = {}) {
|
|
1206
1152
|
this.onclose = options.onclose;
|
|
1207
1153
|
let container = document.createElement('div');
|
|
1208
|
-
container.className = 'lexareatabs ' + (options.fit ? 'fit' : 'row');
|
|
1154
|
+
container.className = 'lexareatabs flex flex-row w-fit ' + (options.fit ? 'fit' : 'row');
|
|
1209
1155
|
const folding = options.folding ?? false;
|
|
1210
1156
|
if (folding)
|
|
1211
1157
|
container.classList.add('folding');
|
|
@@ -1267,16 +1213,15 @@ class Tabs {
|
|
|
1267
1213
|
that.tabs[tabDom.dataset['name']] = content;
|
|
1268
1214
|
});
|
|
1269
1215
|
area.root.classList.add('lexareatabscontainer');
|
|
1270
|
-
const [tabButtons, content] = area.split({ type: 'vertical', sizes: options.sizes ?? 'auto', resize: false,
|
|
1271
|
-
top: 2 });
|
|
1216
|
+
const [tabButtons, content] = area.split({ type: 'vertical', sizes: options.sizes ?? 'auto', resize: false, top: 2 });
|
|
1272
1217
|
tabButtons.attach(container);
|
|
1273
1218
|
if (options.parentClass && container.parentElement) {
|
|
1274
|
-
container.parentElement.className
|
|
1219
|
+
container.parentElement.className = LX.mergeClass(container.parentElement.className, options.parentClass);
|
|
1275
1220
|
}
|
|
1276
1221
|
this.area = content;
|
|
1277
1222
|
this.area.root.className += ' lexareatabscontent';
|
|
1278
1223
|
if (options.contentClass) {
|
|
1279
|
-
this.area.root.className
|
|
1224
|
+
this.area.root.className = LX.mergeClass(this.area.root.className, options.contentClass);
|
|
1280
1225
|
}
|
|
1281
1226
|
this.selected = null;
|
|
1282
1227
|
this.root = container;
|
|
@@ -1335,8 +1280,7 @@ class Tabs {
|
|
|
1335
1280
|
if (options.icon) {
|
|
1336
1281
|
if (!options.icon.includes('.')) { // Not a file
|
|
1337
1282
|
const classes = options.icon.split(' ');
|
|
1338
|
-
options.icon =
|
|
1339
|
-
LX.makeIcon(classes[0], { svgClass: 'sm ' + classes.slice(0).join(' ') }).innerHTML;
|
|
1283
|
+
options.icon = LX.makeIcon(classes[0], { svgClass: 'sm ' + classes.slice(0).join(' ') }).innerHTML;
|
|
1340
1284
|
}
|
|
1341
1285
|
// an image..
|
|
1342
1286
|
else {
|
|
@@ -1371,10 +1315,9 @@ class Tabs {
|
|
|
1371
1315
|
e.stopPropagation();
|
|
1372
1316
|
const scope = tabEl.instance;
|
|
1373
1317
|
if (!tabEl.fixed) {
|
|
1374
|
-
// For folding tabs
|
|
1375
1318
|
const lastValue = tabEl.selected;
|
|
1376
1319
|
tabEl.parentElement.querySelectorAll('span').forEach((s) => s.selected = false);
|
|
1377
|
-
tabEl.selected = !lastValue || (tabEl._forceSelect ? true : false);
|
|
1320
|
+
tabEl.selected = (scope.folding ? !lastValue : true) || (tabEl._forceSelect ? true : false);
|
|
1378
1321
|
// Manage selected
|
|
1379
1322
|
tabEl.parentElement.querySelectorAll('span').forEach((s) => s.classList.remove('selected'));
|
|
1380
1323
|
tabEl.classList.toggle('selected', tabEl.selected);
|
|
@@ -1517,9 +1460,7 @@ class NumberInput extends BaseComponent {
|
|
|
1517
1460
|
var container = document.createElement('div');
|
|
1518
1461
|
container.className = 'lexnumber';
|
|
1519
1462
|
this.root.appendChild(container);
|
|
1520
|
-
let box =
|
|
1521
|
-
box.className = 'numberbox';
|
|
1522
|
-
container.appendChild(box);
|
|
1463
|
+
let box = LX.makeElement('div', 'numberbox relative flex flex-col w-full bg-secondary rounded-lg scrollbar-hidden overflow-x-hidden', '', container);
|
|
1523
1464
|
let valueBox = LX.makeContainer(['auto', '100%'], 'relative flex flex-row cursor-text', '', box);
|
|
1524
1465
|
let vecinput = document.createElement('input');
|
|
1525
1466
|
vecinput.id = 'number_' + LX.guidGenerator();
|
|
@@ -1537,7 +1478,7 @@ class NumberInput extends BaseComponent {
|
|
|
1537
1478
|
const dragIcon = LX.makeIcon('MoveVertical', { iconClass: 'drag-icon hidden-opacity', svgClass: 'sm' });
|
|
1538
1479
|
valueBox.appendChild(dragIcon);
|
|
1539
1480
|
if (options.units) {
|
|
1540
|
-
let unitBox = LX.makeContainer(['auto', 'auto'], 'px-2 bg-
|
|
1481
|
+
let unitBox = LX.makeContainer(['auto', 'auto'], 'px-2 bg-card content-center break-keep', options.units, valueBox);
|
|
1541
1482
|
vecinput.unitBox = unitBox;
|
|
1542
1483
|
}
|
|
1543
1484
|
if (options.disabled) {
|
|
@@ -1698,8 +1639,7 @@ class TextInput extends BaseComponent {
|
|
|
1698
1639
|
this.disabled = (options.disabled || options.warning) ?? (options.url ? true : false);
|
|
1699
1640
|
let wValue = null;
|
|
1700
1641
|
if (!this.disabled) {
|
|
1701
|
-
wValue =
|
|
1702
|
-
wValue.className = 'lextext ' + (options.inputClass ?? '');
|
|
1642
|
+
wValue = LX.makeElement('input', LX.mergeClass('lextext text-sm', options.inputClass));
|
|
1703
1643
|
wValue.type = options.type || '';
|
|
1704
1644
|
wValue.value = value || '';
|
|
1705
1645
|
wValue.style.textAlign = options.float ?? '';
|
|
@@ -1751,10 +1691,10 @@ class TextInput extends BaseComponent {
|
|
|
1751
1691
|
wValue.disabled = true;
|
|
1752
1692
|
wValue.value = value;
|
|
1753
1693
|
wValue.style.textAlign = options.float ?? '';
|
|
1754
|
-
wValue.className = 'lextext ellipsis-overflow
|
|
1694
|
+
wValue.className = LX.mergeClass('lextext ellipsis-overflow', options.inputClass);
|
|
1755
1695
|
}
|
|
1756
1696
|
if (options.fit) {
|
|
1757
|
-
wValue.classList.add('
|
|
1697
|
+
wValue.classList.add('field-sizing-content');
|
|
1758
1698
|
}
|
|
1759
1699
|
Object.assign(wValue.style, options.style ?? {});
|
|
1760
1700
|
container.appendChild(wValue);
|
|
@@ -1778,7 +1718,7 @@ class Select extends BaseComponent {
|
|
|
1778
1718
|
this.onSetValue = (newValue, skipCallback, event) => {
|
|
1779
1719
|
value = newValue;
|
|
1780
1720
|
let item = null;
|
|
1781
|
-
const listOptionsNodes =
|
|
1721
|
+
const listOptionsNodes = list.childNodes;
|
|
1782
1722
|
listOptionsNodes.forEach((e) => {
|
|
1783
1723
|
e.classList.remove('selected');
|
|
1784
1724
|
if (e.getAttribute('value') == newValue) {
|
|
@@ -1879,8 +1819,9 @@ class Select extends BaseComponent {
|
|
|
1879
1819
|
const parentRect = overflowContainer.getBoundingClientRect();
|
|
1880
1820
|
maxX = parentRect.x + parentRect.width;
|
|
1881
1821
|
}
|
|
1882
|
-
|
|
1883
|
-
|
|
1822
|
+
// "align" basically forces left-right alignment
|
|
1823
|
+
const showLeft = (options.align === 'end') || (leftPosition + listWidth) > maxX;
|
|
1824
|
+
if (showLeft && (options.align ? options.align !== 'start' : true)) {
|
|
1884
1825
|
parent.style.left = (leftPosition - (listWidth - rect.width)) + 'px';
|
|
1885
1826
|
}
|
|
1886
1827
|
}
|
|
@@ -1902,17 +1843,17 @@ class Select extends BaseComponent {
|
|
|
1902
1843
|
if (filter) {
|
|
1903
1844
|
filter.root.querySelector('input').focus();
|
|
1904
1845
|
}
|
|
1905
|
-
}, { buttonClass: '
|
|
1846
|
+
}, { buttonClass: 'outline [&_a]:ml-auto', skipInlineCount: true, disabled: options.disabled });
|
|
1906
1847
|
selectedOption.root.style.width = '100%';
|
|
1907
|
-
selectedOption.root.querySelector('
|
|
1848
|
+
selectedOption.root.querySelector('button').appendChild(LX.makeIcon('Down', { svgClass: 'sm' }));
|
|
1908
1849
|
container.appendChild(selectedOption.root);
|
|
1909
1850
|
selectedOption.refresh = (v) => {
|
|
1910
|
-
const
|
|
1911
|
-
if (
|
|
1912
|
-
|
|
1851
|
+
const button = selectedOption.root.querySelector('button');
|
|
1852
|
+
if (button.innerText == '') {
|
|
1853
|
+
button.innerText = v;
|
|
1913
1854
|
}
|
|
1914
1855
|
else {
|
|
1915
|
-
|
|
1856
|
+
button.innerHTML = button.innerHTML.replaceAll(button.innerText, v);
|
|
1916
1857
|
}
|
|
1917
1858
|
};
|
|
1918
1859
|
// Add select options container
|
|
@@ -1963,14 +1904,12 @@ class Select extends BaseComponent {
|
|
|
1963
1904
|
});
|
|
1964
1905
|
list.appendChild(filter.root);
|
|
1965
1906
|
}
|
|
1966
|
-
// Create option list to empty it easily..
|
|
1967
|
-
const listOptions = document.createElement('span');
|
|
1968
|
-
listOptions.className = 'lexselectinnerlist';
|
|
1969
|
-
list.appendChild(listOptions);
|
|
1970
1907
|
// Add select options list
|
|
1971
1908
|
list.refresh = (currentOptions) => {
|
|
1972
1909
|
// Empty list
|
|
1973
|
-
|
|
1910
|
+
while (list.childElementCount > (options.filter ?? false ? 1 : 0)) {
|
|
1911
|
+
list.removeChild(list.lastChild);
|
|
1912
|
+
}
|
|
1974
1913
|
if (!currentOptions.length) {
|
|
1975
1914
|
let iValue = options.emptyMsg ?? 'No options found.';
|
|
1976
1915
|
let option = document.createElement('div');
|
|
@@ -1979,7 +1918,7 @@ class Select extends BaseComponent {
|
|
|
1979
1918
|
let li = document.createElement('li');
|
|
1980
1919
|
li.className = 'lexselectitem empty';
|
|
1981
1920
|
li.appendChild(option);
|
|
1982
|
-
|
|
1921
|
+
list.appendChild(li);
|
|
1983
1922
|
return;
|
|
1984
1923
|
}
|
|
1985
1924
|
for (let i = 0; i < currentOptions.length; i++) {
|
|
@@ -1997,7 +1936,7 @@ class Select extends BaseComponent {
|
|
|
1997
1936
|
if (iValue.constructor != Object) {
|
|
1998
1937
|
const asLabel = iValue[0] === '@';
|
|
1999
1938
|
if (!asLabel) {
|
|
2000
|
-
option.innerHTML = `<span>${iValue}</span>`;
|
|
1939
|
+
option.innerHTML = `<span class="flex flex-row justify-between">${iValue}</span>`;
|
|
2001
1940
|
option.appendChild(LX.makeIcon('Check'));
|
|
2002
1941
|
option.value = iValue;
|
|
2003
1942
|
li.setAttribute('value', iValue);
|
|
@@ -2029,14 +1968,13 @@ class Select extends BaseComponent {
|
|
|
2029
1968
|
li.classList.add('selected');
|
|
2030
1969
|
}
|
|
2031
1970
|
}
|
|
2032
|
-
|
|
1971
|
+
list.appendChild(li);
|
|
2033
1972
|
}
|
|
2034
1973
|
};
|
|
2035
1974
|
list.refresh(values);
|
|
2036
1975
|
container.appendChild(listDialog);
|
|
2037
1976
|
// Element suboptions
|
|
2038
|
-
let suboptions =
|
|
2039
|
-
suboptions.className = 'lexcustomcontainer w-full';
|
|
1977
|
+
let suboptions = LX.makeElement('div', 'lexcustomcontainer w-full');
|
|
2040
1978
|
const suboptionsFunc = options[`on_${value}`];
|
|
2041
1979
|
suboptions.toggleAttribute('hidden', !suboptionsFunc);
|
|
2042
1980
|
if (suboptionsFunc) {
|
|
@@ -2079,7 +2017,7 @@ LX.Select = Select;
|
|
|
2079
2017
|
class ArrayInput extends BaseComponent {
|
|
2080
2018
|
_updateItems;
|
|
2081
2019
|
constructor(name, values = [], callback, options = {}) {
|
|
2082
|
-
options.nameWidth = '
|
|
2020
|
+
options.nameWidth = 'auto';
|
|
2083
2021
|
super(ComponentType.ARRAY, name, null, options);
|
|
2084
2022
|
this.onGetValue = () => {
|
|
2085
2023
|
return values;
|
|
@@ -2093,16 +2031,16 @@ class ArrayInput extends BaseComponent {
|
|
|
2093
2031
|
};
|
|
2094
2032
|
// Add open array button
|
|
2095
2033
|
let container = document.createElement('div');
|
|
2096
|
-
container.className = 'lexarray';
|
|
2097
|
-
container.style.width = '
|
|
2034
|
+
container.className = 'lexarray shrink-1 grow-1 ml-4';
|
|
2035
|
+
container.style.width = 'auto';
|
|
2098
2036
|
this.root.appendChild(container);
|
|
2099
2037
|
this.root.dataset['opened'] = false;
|
|
2100
2038
|
let buttonName = `Array (size ${values.length})`;
|
|
2101
2039
|
const toggleButton = new Button(null, buttonName, () => {
|
|
2102
2040
|
this.root.dataset['opened'] = this.root.dataset['opened'] == 'true' ? false : true;
|
|
2103
2041
|
this.root.querySelector('.lexarrayitems').toggleAttribute('hidden');
|
|
2104
|
-
}, { buttonClass: '
|
|
2105
|
-
toggleButton.root.querySelector('
|
|
2042
|
+
}, { buttonClass: 'outline [&_a]:ml-auto' });
|
|
2043
|
+
toggleButton.root.querySelector('button').appendChild(LX.makeIcon('Down', { svgClass: 'sm' }));
|
|
2106
2044
|
container.appendChild(toggleButton.root);
|
|
2107
2045
|
// Show elements
|
|
2108
2046
|
let arrayItems = document.createElement('div');
|
|
@@ -2111,8 +2049,8 @@ class ArrayInput extends BaseComponent {
|
|
|
2111
2049
|
this.root.appendChild(arrayItems);
|
|
2112
2050
|
this._updateItems = () => {
|
|
2113
2051
|
// Update num items
|
|
2114
|
-
let
|
|
2115
|
-
for (let node of
|
|
2052
|
+
let button = this.root.querySelector('button');
|
|
2053
|
+
for (let node of button.childNodes) {
|
|
2116
2054
|
if (node.nodeType === Node.TEXT_NODE) {
|
|
2117
2055
|
node.textContent = `Array (size ${values.length})`;
|
|
2118
2056
|
break;
|
|
@@ -2150,14 +2088,14 @@ class ArrayInput extends BaseComponent {
|
|
|
2150
2088
|
values.splice(values.indexOf(value), 1);
|
|
2151
2089
|
this._updateItems();
|
|
2152
2090
|
this._trigger(new IEvent(name, values, event), callback);
|
|
2153
|
-
}, { title: 'Remove item', icon: '
|
|
2091
|
+
}, { buttonClass: 'ghost xs p-0', title: 'Remove item', icon: 'Trash2' });
|
|
2154
2092
|
component.root.appendChild(removeComponent.root);
|
|
2155
2093
|
}
|
|
2156
2094
|
const addButton = new Button(null, LX.makeIcon('Plus', { svgClass: 'sm' }).innerHTML + 'Add item', (v, event) => {
|
|
2157
2095
|
values.push(options.innerValues ? options.innerValues[0] : '');
|
|
2158
2096
|
this._updateItems();
|
|
2159
2097
|
this._trigger(new IEvent(name, values, event), callback);
|
|
2160
|
-
}, { buttonClass: '
|
|
2098
|
+
}, { buttonClass: 'ghost' });
|
|
2161
2099
|
arrayItems.appendChild(addButton.root);
|
|
2162
2100
|
};
|
|
2163
2101
|
this._updateItems();
|
|
@@ -2175,22 +2113,22 @@ class Card extends BaseComponent {
|
|
|
2175
2113
|
options.hideName = true;
|
|
2176
2114
|
super(ComponentType.CARD, name, null, options);
|
|
2177
2115
|
this.root.classList.add('place-content-center');
|
|
2178
|
-
const container = LX.makeContainer(['100%', 'auto'], 'lexcard max-w-sm flex flex-col gap-4 bg-
|
|
2116
|
+
const container = LX.makeContainer(['100%', 'auto'], 'lexcard max-w-sm flex flex-col gap-4 bg-card border-color rounded-xl py-6', '', this.root);
|
|
2179
2117
|
if (options.header) {
|
|
2180
2118
|
const hasAction = options.header.action !== undefined;
|
|
2181
2119
|
let header = LX.makeContainer(['100%', 'auto'], `flex ${hasAction ? 'flex-row gap-4' : 'flex-col gap-1'} px-6`, '', container);
|
|
2182
2120
|
if (hasAction) {
|
|
2183
|
-
const actionBtn = new Button(null, options.header.action.name, options.header.action.callback);
|
|
2121
|
+
const actionBtn = new Button(null, options.header.action.name, options.header.action.callback, { buttonClass: 'secondary' });
|
|
2184
2122
|
header.appendChild(actionBtn.root);
|
|
2185
2123
|
const titleDescBox = LX.makeContainer(['75%', 'auto'], `flex flex-col gap-1`, '');
|
|
2186
2124
|
header.prepend(titleDescBox);
|
|
2187
2125
|
header = titleDescBox;
|
|
2188
2126
|
}
|
|
2189
2127
|
if (options.header.title) {
|
|
2190
|
-
LX.makeElement('div', 'text-
|
|
2128
|
+
LX.makeElement('div', 'text-sm text-foreground leading-none font-semibold', options.header.title, header);
|
|
2191
2129
|
}
|
|
2192
2130
|
if (options.header.description) {
|
|
2193
|
-
LX.makeElement('div', 'text-
|
|
2131
|
+
LX.makeElement('div', 'text-xs text-muted-foreground', options.header.description, header);
|
|
2194
2132
|
}
|
|
2195
2133
|
}
|
|
2196
2134
|
if (options.content) {
|
|
@@ -2248,24 +2186,19 @@ class Checkbox extends BaseComponent {
|
|
|
2248
2186
|
container.style.width = options.inputWidth ?? `calc( 100% - ${realNameWidth})`;
|
|
2249
2187
|
};
|
|
2250
2188
|
var container = document.createElement('div');
|
|
2251
|
-
container.className = '
|
|
2189
|
+
container.className = 'flex items-center gap-2 my-0 mx-auto [&_span]:truncate [&_span]:flex-auto-fill';
|
|
2252
2190
|
this.root.appendChild(container);
|
|
2253
|
-
let checkbox =
|
|
2191
|
+
let checkbox = LX.makeElement('input', LX.mergeClass('lexcheckbox rounded-xl', options.className ?? 'primary'));
|
|
2254
2192
|
checkbox.type = 'checkbox';
|
|
2255
|
-
checkbox.className = 'lexcheckbox ' + (options.className ?? 'primary');
|
|
2256
2193
|
checkbox.checked = value;
|
|
2257
2194
|
checkbox.disabled = options.disabled ?? false;
|
|
2258
2195
|
container.appendChild(checkbox);
|
|
2259
|
-
|
|
2260
|
-
valueName.className = 'checkboxtext';
|
|
2261
|
-
valueName.innerHTML = options.label ?? 'On';
|
|
2262
|
-
container.appendChild(valueName);
|
|
2196
|
+
LX.makeElement('span', 'text-sm', options.label ?? 'On', container);
|
|
2263
2197
|
checkbox.addEventListener('change', (e) => {
|
|
2264
2198
|
this.set(checkbox.checked, false, e);
|
|
2265
2199
|
});
|
|
2266
2200
|
if (options.suboptions) {
|
|
2267
|
-
let suboptions =
|
|
2268
|
-
suboptions.className = 'lexcheckboxsubmenu';
|
|
2201
|
+
let suboptions = LX.makeElement('div', 'lexcheckboxsubmenu');
|
|
2269
2202
|
suboptions.toggleAttribute('hidden', !checkbox.checked);
|
|
2270
2203
|
const suboptionsPanel = new LX.Panel();
|
|
2271
2204
|
suboptionsPanel.queue(suboptions);
|
|
@@ -2376,20 +2309,17 @@ class ColorPicker {
|
|
|
2376
2309
|
if (!this.callback) {
|
|
2377
2310
|
console.warn('Define a callback in _options.onChange_ to allow getting new Color values!');
|
|
2378
2311
|
}
|
|
2379
|
-
this.root =
|
|
2380
|
-
this.root.className = 'lexcolorpicker';
|
|
2312
|
+
this.root = LX.makeElement('div', 'lexcolorpicker flex flex-col text-sm w-3xs gap-2 p-1');
|
|
2381
2313
|
this.markerHalfSize = 8;
|
|
2382
2314
|
this.markerSize = this.markerHalfSize * 2;
|
|
2383
2315
|
this.currentColor = new Color(hexValue);
|
|
2384
2316
|
const hueColor = new Color({ h: this.currentColor.hsv.h, s: 1, v: 1 });
|
|
2317
|
+
const colorMarkerClass = 'size-4 rounded-lg bg-transparent absolute pointer-events-none border-3 border-solid border-white';
|
|
2385
2318
|
// Intensity, Sat
|
|
2386
|
-
this.colorPickerBackground =
|
|
2387
|
-
this.colorPickerBackground.
|
|
2388
|
-
this.colorPickerBackground.style.backgroundColor =
|
|
2389
|
-
`rgb(${hueColor.css.r}, ${hueColor.css.g}, ${hueColor.css.b})`;
|
|
2319
|
+
this.colorPickerBackground = LX.makeElement('div', 'lexcolorpickerbg w-full aspect-square relative rounded-md cursor-pointer');
|
|
2320
|
+
this.colorPickerBackground.style.backgroundColor = `rgb(${hueColor.css.r}, ${hueColor.css.g}, ${hueColor.css.b})`;
|
|
2390
2321
|
this.root.appendChild(this.colorPickerBackground);
|
|
2391
|
-
this.intSatMarker =
|
|
2392
|
-
this.intSatMarker.className = 'lexcolormarker';
|
|
2322
|
+
this.intSatMarker = LX.makeElement('div', colorMarkerClass);
|
|
2393
2323
|
this.intSatMarker.style.backgroundColor = this.currentColor.hex;
|
|
2394
2324
|
this.colorPickerBackground.appendChild(this.intSatMarker);
|
|
2395
2325
|
let pickerRect = null;
|
|
@@ -2450,11 +2380,9 @@ class ColorPicker {
|
|
|
2450
2380
|
}
|
|
2451
2381
|
const innerHueAlpha = LX.makeContainer(['100%', '100%'], 'flex flex-col gap-2', '', hueAlphaContainer);
|
|
2452
2382
|
// Hue
|
|
2453
|
-
this.colorPickerTracker =
|
|
2454
|
-
this.colorPickerTracker.className = 'lexhuetracker';
|
|
2383
|
+
this.colorPickerTracker = LX.makeElement('div', 'lexhuetracker w-full h-4 rounded-lg relative cursor-pointer');
|
|
2455
2384
|
innerHueAlpha.appendChild(this.colorPickerTracker);
|
|
2456
|
-
this.hueMarker =
|
|
2457
|
-
this.hueMarker.className = 'lexcolormarker';
|
|
2385
|
+
this.hueMarker = LX.makeElement('div', colorMarkerClass);
|
|
2458
2386
|
this.hueMarker.style.backgroundColor = `rgb(${hueColor.css.r}, ${hueColor.css.g}, ${hueColor.css.b})`;
|
|
2459
2387
|
this.colorPickerTracker.appendChild(this.hueMarker);
|
|
2460
2388
|
const _fromHueX = (hueX) => {
|
|
@@ -2462,8 +2390,7 @@ class ColorPicker {
|
|
|
2462
2390
|
this.currentColor.hsv.h = LX.remapRange(hueX, 0, this.colorPickerTracker.offsetWidth - this.markerSize, 0, 360);
|
|
2463
2391
|
const hueColor = new Color({ h: this.currentColor.hsv.h, s: 1, v: 1 });
|
|
2464
2392
|
this.hueMarker.style.backgroundColor = `rgb(${hueColor.css.r}, ${hueColor.css.g}, ${hueColor.css.b})`;
|
|
2465
|
-
this.colorPickerBackground.style.backgroundColor =
|
|
2466
|
-
`rgb(${hueColor.css.r}, ${hueColor.css.g}, ${hueColor.css.b})`;
|
|
2393
|
+
this.colorPickerBackground.style.backgroundColor = `rgb(${hueColor.css.r}, ${hueColor.css.g}, ${hueColor.css.b})`;
|
|
2467
2394
|
this._updateColorValue();
|
|
2468
2395
|
};
|
|
2469
2396
|
let hueTrackerRect = null;
|
|
@@ -2498,13 +2425,10 @@ class ColorPicker {
|
|
|
2498
2425
|
this.colorPickerTracker.addEventListener('mousedown', innerMouseDownHue);
|
|
2499
2426
|
// Alpha
|
|
2500
2427
|
if (this.useAlpha) {
|
|
2501
|
-
this.alphaTracker =
|
|
2502
|
-
this.alphaTracker.
|
|
2503
|
-
this.alphaTracker.style.color =
|
|
2504
|
-
`rgb(${this.currentColor.css.r}, ${this.currentColor.css.g}, ${this.currentColor.css.b})`;
|
|
2428
|
+
this.alphaTracker = LX.makeElement('div', 'lexalphatracker w-full h-4 rounded-lg relative cursor-pointer');
|
|
2429
|
+
this.alphaTracker.style.color = `rgb(${this.currentColor.css.r}, ${this.currentColor.css.g}, ${this.currentColor.css.b})`;
|
|
2505
2430
|
innerHueAlpha.appendChild(this.alphaTracker);
|
|
2506
|
-
this.alphaMarker =
|
|
2507
|
-
this.alphaMarker.className = 'lexcolormarker';
|
|
2431
|
+
this.alphaMarker = LX.makeElement('div', colorMarkerClass);
|
|
2508
2432
|
this.alphaMarker.style.backgroundColor =
|
|
2509
2433
|
`rgb(${this.currentColor.css.r}, ${this.currentColor.css.g}, ${this.currentColor.css.b},${this.currentColor.css.a})`;
|
|
2510
2434
|
this.alphaTracker.appendChild(this.alphaMarker);
|
|
@@ -2566,7 +2490,7 @@ class ColorPicker {
|
|
|
2566
2490
|
copyButtonComponent.root.querySelector("input[type='checkbox']").style.pointerEvents = 'auto';
|
|
2567
2491
|
}, 3000);
|
|
2568
2492
|
}, { swap: 'Check', icon: 'Copy', buttonClass: 'bg-none', className: 'ml-auto', title: 'Copy' });
|
|
2569
|
-
copyButtonComponent.root.querySelector('.swap-on svg').classList.add('
|
|
2493
|
+
copyButtonComponent.root.querySelector('.swap-on svg').classList.add('text-success');
|
|
2570
2494
|
colorLabel.appendChild(copyButtonComponent.root);
|
|
2571
2495
|
}
|
|
2572
2496
|
this._updateColorValue(hexValue, true);
|
|
@@ -2598,8 +2522,7 @@ class ColorPicker {
|
|
|
2598
2522
|
}
|
|
2599
2523
|
this.intSatMarker.style.backgroundColor = this.currentColor.hex;
|
|
2600
2524
|
if (this.useAlpha) {
|
|
2601
|
-
this.alphaTracker.style.color =
|
|
2602
|
-
`rgb(${this.currentColor.css.r}, ${this.currentColor.css.g}, ${this.currentColor.css.b})`;
|
|
2525
|
+
this.alphaTracker.style.color = `rgb(${this.currentColor.css.r}, ${this.currentColor.css.g}, ${this.currentColor.css.b})`;
|
|
2603
2526
|
}
|
|
2604
2527
|
const toFixed = (s, n = 2) => {
|
|
2605
2528
|
return s.toFixed(n).replace(/([0-9]+(\.[0-9]+[1-9])?)(\.?0+$)/, '$1');
|
|
@@ -2636,9 +2559,8 @@ class ColorPicker {
|
|
|
2636
2559
|
this.hueMarker.style.backgroundColor =
|
|
2637
2560
|
this.colorPickerBackground.style.backgroundColor =
|
|
2638
2561
|
`rgb(${hueColor.css.r}, ${hueColor.css.g}, ${hueColor.css.b})`;
|
|
2639
|
-
this.hueMarker.style.left =
|
|
2640
|
-
|
|
2641
|
-
+ 'px';
|
|
2562
|
+
this.hueMarker.style.left = LX.remapRange(h, 0, 360, -this.markerHalfSize, this.colorPickerTracker.offsetWidth - this.markerHalfSize)
|
|
2563
|
+
+ 'px';
|
|
2642
2564
|
this._updateColorValue(hexColor);
|
|
2643
2565
|
}
|
|
2644
2566
|
}
|
|
@@ -2677,10 +2599,9 @@ class Popover {
|
|
|
2677
2599
|
this.alignOffset = options.alignOffset ?? this.alignOffset;
|
|
2678
2600
|
this.avoidCollisions = options.avoidCollisions ?? true;
|
|
2679
2601
|
this.reference = options.reference;
|
|
2680
|
-
this.root =
|
|
2602
|
+
this.root = LX.makeElement('div', 'lexpopover fixed bg-background rounded-lg border-color p-1 left-0 top-0');
|
|
2681
2603
|
this.root.dataset['side'] = this.side;
|
|
2682
2604
|
this.root.tabIndex = '1';
|
|
2683
|
-
this.root.className = 'lexpopover';
|
|
2684
2605
|
const refElement = trigger ?? this.reference;
|
|
2685
2606
|
const nestedDialog = refElement.closest('dialog');
|
|
2686
2607
|
if (nestedDialog && nestedDialog.dataset['modal'] == 'true') {
|
|
@@ -2813,11 +2734,11 @@ class PopConfirm {
|
|
|
2813
2734
|
const popoverContainer = LX.makeContainer(['auto', 'auto'], 'tour-step-container');
|
|
2814
2735
|
{
|
|
2815
2736
|
const headerDiv = LX.makeContainer(['100%', 'auto'], 'flex flex-row', '', popoverContainer);
|
|
2816
|
-
LX.makeContainer(['100%', 'auto'], 'p-1 font-medium text-
|
|
2737
|
+
LX.makeContainer(['100%', 'auto'], 'p-1 font-medium text-base', title, headerDiv);
|
|
2817
2738
|
}
|
|
2818
|
-
LX.makeContainer(['100%', 'auto'], 'p-1 text-
|
|
2819
|
-
const footer = LX.makeContainer(['100%', 'auto'], 'flex flex-row text-
|
|
2820
|
-
const footerButtons = LX.makeContainer(['100%', 'auto'], 'text-
|
|
2739
|
+
LX.makeContainer(['100%', 'auto'], 'p-1 text-base', content, popoverContainer, { maxWidth: '400px' });
|
|
2740
|
+
const footer = LX.makeContainer(['100%', 'auto'], 'flex flex-row text-base', '', popoverContainer);
|
|
2741
|
+
const footerButtons = LX.makeContainer(['100%', 'auto'], 'text-base', '', footer);
|
|
2821
2742
|
const footerPanel = new LX.Panel();
|
|
2822
2743
|
footerButtons.appendChild(footerPanel.root);
|
|
2823
2744
|
footerPanel.sameLine(2, 'justify-end');
|
|
@@ -2825,7 +2746,7 @@ class PopConfirm {
|
|
|
2825
2746
|
if (onCancel)
|
|
2826
2747
|
onCancel();
|
|
2827
2748
|
this._popover?.destroy();
|
|
2828
|
-
}
|
|
2749
|
+
});
|
|
2829
2750
|
footerPanel.addButton(null, okText, () => {
|
|
2830
2751
|
if (onConfirm)
|
|
2831
2752
|
onConfirm();
|
|
@@ -2854,12 +2775,15 @@ class ColorInput extends BaseComponent {
|
|
|
2854
2775
|
_popover = undefined;
|
|
2855
2776
|
constructor(name, value, callback, options = {}) {
|
|
2856
2777
|
value = value ?? '#000000';
|
|
2778
|
+
// Force always hex internally
|
|
2779
|
+
if (value.constructor === String && value.includes('oklch')) {
|
|
2780
|
+
value = LX.oklchToHex(value);
|
|
2781
|
+
}
|
|
2857
2782
|
const useAlpha = options.useAlpha
|
|
2858
2783
|
?? ((value.constructor === Object && 'a' in value)
|
|
2859
2784
|
|| (value.constructor === String && [5, 9].includes(value.length)));
|
|
2860
2785
|
const componentColor = new Color(value);
|
|
2861
|
-
|
|
2862
|
-
value = useAlpha ? componentColor.hex : componentColor.hex.substr(0, 7);
|
|
2786
|
+
value = useAlpha ? componentColor.hex : componentColor.hex.substring(0, 7);
|
|
2863
2787
|
super(ComponentType.COLOR, name, value, options);
|
|
2864
2788
|
this.onGetValue = () => {
|
|
2865
2789
|
const currentColor = new Color(value);
|
|
@@ -2867,7 +2791,7 @@ class ColorInput extends BaseComponent {
|
|
|
2867
2791
|
};
|
|
2868
2792
|
this.onSetValue = (newValue, skipCallback, event) => {
|
|
2869
2793
|
const newColor = new Color(newValue);
|
|
2870
|
-
colorSampleRGB.style.color = value = newColor.hex.
|
|
2794
|
+
colorSampleRGB.style.color = value = newColor.hex.substring(0, 7);
|
|
2871
2795
|
if (useAlpha) {
|
|
2872
2796
|
colorSampleAlpha.style.color = value = newColor.hex;
|
|
2873
2797
|
}
|
|
@@ -2899,7 +2823,7 @@ class ColorInput extends BaseComponent {
|
|
|
2899
2823
|
this.set(color.hex);
|
|
2900
2824
|
}
|
|
2901
2825
|
});
|
|
2902
|
-
let sampleContainer = LX.makeContainer(['18px', '18px'], 'flex flex-row
|
|
2826
|
+
let sampleContainer = LX.makeContainer(['18px', '18px'], 'flex flex-row rounded overflow-hidden', '', container);
|
|
2903
2827
|
sampleContainer.tabIndex = '1';
|
|
2904
2828
|
sampleContainer.addEventListener('click', (e) => {
|
|
2905
2829
|
if ((options.disabled ?? false)) {
|
|
@@ -2946,42 +2870,18 @@ class ComboButtons extends BaseComponent {
|
|
|
2946
2870
|
const shouldSelect = !(options.noSelection ?? false);
|
|
2947
2871
|
let shouldToggle = shouldSelect && (options.toggle ?? false);
|
|
2948
2872
|
let container = document.createElement('div');
|
|
2949
|
-
container.className = 'lexcombobuttons ';
|
|
2873
|
+
container.className = 'lexcombobuttons flex justify-center';
|
|
2950
2874
|
options.skipReset = true;
|
|
2951
2875
|
if (options.float) {
|
|
2952
|
-
container.className
|
|
2876
|
+
container.className = LX.mergeClass(container.className, `justify-${options.float}`);
|
|
2953
2877
|
}
|
|
2954
2878
|
let currentValue = [];
|
|
2955
|
-
let buttonsBox =
|
|
2956
|
-
buttonsBox.className = 'lexcombobuttonsbox ';
|
|
2957
|
-
container.appendChild(buttonsBox);
|
|
2879
|
+
let buttonsBox = LX.makeElement('div', 'flex w-max bg-secondary pad-sm rounded-lg gap-1', '', container);
|
|
2958
2880
|
for (let b of values) {
|
|
2959
2881
|
if (!b.value) {
|
|
2960
2882
|
throw ("Set 'value' for each button!");
|
|
2961
2883
|
}
|
|
2962
|
-
|
|
2963
|
-
buttonEl.className = 'lexbutton combo';
|
|
2964
|
-
buttonEl.title = b.icon ? b.value : '';
|
|
2965
|
-
buttonEl.id = b.id ?? '';
|
|
2966
|
-
buttonEl.dataset['value'] = b.value;
|
|
2967
|
-
if (options.buttonClass) {
|
|
2968
|
-
buttonEl.classList.add(options.buttonClass);
|
|
2969
|
-
}
|
|
2970
|
-
if (shouldSelect && (b.selected || options.selected?.includes(b.value))) {
|
|
2971
|
-
buttonEl.classList.add('selected');
|
|
2972
|
-
currentValue = currentValue.concat([b.value]);
|
|
2973
|
-
}
|
|
2974
|
-
if (b.icon) {
|
|
2975
|
-
const icon = LX.makeIcon(b.icon);
|
|
2976
|
-
buttonEl.appendChild(icon);
|
|
2977
|
-
}
|
|
2978
|
-
else {
|
|
2979
|
-
buttonEl.innerHTML = `<span>${b.value}</span>`;
|
|
2980
|
-
}
|
|
2981
|
-
if (b.disabled) {
|
|
2982
|
-
buttonEl.setAttribute('disabled', 'true');
|
|
2983
|
-
}
|
|
2984
|
-
buttonEl.addEventListener('click', (e) => {
|
|
2884
|
+
const onClick = (event) => {
|
|
2985
2885
|
currentValue = [];
|
|
2986
2886
|
if (shouldSelect) {
|
|
2987
2887
|
if (shouldToggle) {
|
|
@@ -3003,7 +2903,20 @@ class ComboButtons extends BaseComponent {
|
|
|
3003
2903
|
}
|
|
3004
2904
|
currentValue = currentValue[0];
|
|
3005
2905
|
this.set(b.value, false, buttonEl.classList.contains('selected'));
|
|
2906
|
+
};
|
|
2907
|
+
const button = new Button(b.name ?? null, b.value, onClick, {
|
|
2908
|
+
title: b.icon ? b.value : '',
|
|
2909
|
+
icon: b.icon,
|
|
2910
|
+
disabled: b.disabled,
|
|
2911
|
+
buttonClass: LX.mergeClass('combo w-auto', options.buttonClass)
|
|
3006
2912
|
});
|
|
2913
|
+
let buttonEl = button.root.querySelector('button');
|
|
2914
|
+
buttonEl.id = b.id ?? '';
|
|
2915
|
+
buttonEl.dataset['value'] = b.value;
|
|
2916
|
+
if (shouldSelect && (b.selected || options.selected?.includes(b.value))) {
|
|
2917
|
+
buttonEl.classList.add('selected');
|
|
2918
|
+
currentValue = currentValue.concat([b.value]);
|
|
2919
|
+
}
|
|
3007
2920
|
buttonsBox.appendChild(buttonEl);
|
|
3008
2921
|
}
|
|
3009
2922
|
if (currentValue.length > 1) {
|
|
@@ -3069,9 +2982,9 @@ class Counter extends BaseComponent {
|
|
|
3069
2982
|
const max = options.max ?? 100;
|
|
3070
2983
|
const step = options.step ?? 1;
|
|
3071
2984
|
const container = document.createElement('div');
|
|
3072
|
-
container.className = 'flex flex-row border bg-
|
|
2985
|
+
container.className = 'flex flex-row border-color bg-card rounded-lg shadow';
|
|
3073
2986
|
this.root.appendChild(container);
|
|
3074
|
-
const input = LX.makeElement('input', 'lexcounter w-12 bg-
|
|
2987
|
+
const input = LX.makeElement('input', 'lexcounter w-12 bg-card px-2 text-foreground', '', container);
|
|
3075
2988
|
input.type = 'number';
|
|
3076
2989
|
input.value = value;
|
|
3077
2990
|
if (options.disabled) {
|
|
@@ -3082,9 +2995,8 @@ class Counter extends BaseComponent {
|
|
|
3082
2995
|
if (e.shiftKey)
|
|
3083
2996
|
mult *= 10;
|
|
3084
2997
|
this.set(this.count - mult, false, e);
|
|
3085
|
-
}, { disabled: options.disabled,
|
|
3086
|
-
|
|
3087
|
-
buttonClass: 'bg-none', icon: 'Minus' });
|
|
2998
|
+
}, { disabled: options.disabled, className: `p-0 ${options.disabled ? '' : 'hover:bg-secondary'} border-l-color border-r-color`,
|
|
2999
|
+
buttonClass: 'px-0 bg-none h-7', icon: 'Minus' });
|
|
3088
3000
|
container.appendChild(substrButton.root);
|
|
3089
3001
|
const addButton = new Button(null, '', (value, e) => {
|
|
3090
3002
|
let mult = step ?? 1;
|
|
@@ -3092,7 +3004,7 @@ class Counter extends BaseComponent {
|
|
|
3092
3004
|
mult *= 10;
|
|
3093
3005
|
this.set(this.count + mult, false, e);
|
|
3094
3006
|
}, { disabled: options.disabled, className: `p-0 ${options.disabled ? '' : 'hover:bg-secondary'} rounded-r-lg`,
|
|
3095
|
-
buttonClass: 'bg-none', icon: 'Plus' });
|
|
3007
|
+
buttonClass: 'px-0 bg-none h-7', icon: 'Plus' });
|
|
3096
3008
|
container.appendChild(addButton.root);
|
|
3097
3009
|
}
|
|
3098
3010
|
}
|
|
@@ -3108,14 +3020,14 @@ class CanvasCurve {
|
|
|
3108
3020
|
canvas;
|
|
3109
3021
|
constructor(value, options = {}) {
|
|
3110
3022
|
let element = document.createElement('div');
|
|
3111
|
-
element.className = 'curve '
|
|
3023
|
+
element.className = LX.mergeClass('curve [&_canvas]:rounded', options.className);
|
|
3112
3024
|
element.style.minHeight = '50px';
|
|
3113
3025
|
element.style.width = options.width || '100%';
|
|
3114
3026
|
element.style.minWidth = '50px';
|
|
3115
3027
|
element.style.minHeight = '20px';
|
|
3116
|
-
element.bgcolor = options.bgColor || LX.
|
|
3117
|
-
element.pointscolor = options.pointsColor || LX.
|
|
3118
|
-
element.activepointscolor = options.activePointsColor || LX.
|
|
3028
|
+
element.bgcolor = options.bgColor || LX.getCSSVariable('background');
|
|
3029
|
+
element.pointscolor = options.pointsColor || LX.getCSSVariable('primary');
|
|
3030
|
+
element.activepointscolor = options.activePointsColor || LX.getCSSVariable('primary/50');
|
|
3119
3031
|
element.linecolor = options.lineColor || '#555';
|
|
3120
3032
|
element.value = value || [];
|
|
3121
3033
|
element.xrange = options.xrange || [0, 1]; // min, max
|
|
@@ -3129,9 +3041,9 @@ class CanvasCurve {
|
|
|
3129
3041
|
element.smooth = (options.smooth && typeof (options.smooth) == 'number' ? options.smooth : 0.3) || false;
|
|
3130
3042
|
element.move_out = options.moveOutAction ?? LX.CURVE_MOVEOUT_DELETE;
|
|
3131
3043
|
LX.addSignal('@on_new_color_scheme', (el, value) => {
|
|
3132
|
-
element.bgcolor = options.bgColor || LX.
|
|
3133
|
-
element.pointscolor = options.pointsColor || LX.
|
|
3134
|
-
element.activepointscolor = options.activePointsColor || LX.
|
|
3044
|
+
element.bgcolor = options.bgColor || LX.getCSSVariable('background');
|
|
3045
|
+
element.pointscolor = options.pointsColor || LX.getCSSVariable('primary');
|
|
3046
|
+
element.activepointscolor = options.activePointsColor || LX.getCSSVariable('primary/50');
|
|
3135
3047
|
this.redraw();
|
|
3136
3048
|
});
|
|
3137
3049
|
this.element = element;
|
|
@@ -3188,8 +3100,7 @@ class CanvasCurve {
|
|
|
3188
3100
|
}
|
|
3189
3101
|
// Canvas to value
|
|
3190
3102
|
function unconvert(v) {
|
|
3191
|
-
return [v[0] * element.xrange[1] / canvas.width + element.xrange[0],
|
|
3192
|
-
v[1] * element.yrange[1] / canvas.height + element.yrange[0]];
|
|
3103
|
+
return [v[0] * element.xrange[1] / canvas.width + element.xrange[0], v[1] * element.yrange[1] / canvas.height + element.yrange[0]];
|
|
3193
3104
|
}
|
|
3194
3105
|
let selected = -1;
|
|
3195
3106
|
element.redraw = function (o = {}) {
|
|
@@ -3466,7 +3377,7 @@ class Calendar {
|
|
|
3466
3377
|
onPreviousMonth;
|
|
3467
3378
|
onNextMonth;
|
|
3468
3379
|
constructor(dateString, options = {}) {
|
|
3469
|
-
this.root = LX.makeContainer(['256px', 'auto'], 'p-1 text-
|
|
3380
|
+
this.root = LX.makeContainer(['256px', 'auto'], 'p-1 flex flex-col gap-2 text-sm');
|
|
3470
3381
|
this.onChange = options.onChange;
|
|
3471
3382
|
this.onPreviousMonth = options.onPreviousMonth;
|
|
3472
3383
|
this.onNextMonth = options.onNextMonth;
|
|
@@ -3521,8 +3432,8 @@ class Calendar {
|
|
|
3521
3432
|
{
|
|
3522
3433
|
const header = LX.makeContainer(['100%', 'auto'], 'flex flex-row p-1', '', this.root);
|
|
3523
3434
|
if (!this.skipPrevMonth) {
|
|
3524
|
-
const prevMonthIcon = LX.makeIcon('Left', { title: 'Previous Month',
|
|
3525
|
-
|
|
3435
|
+
const prevMonthIcon = LX.makeIcon('Left', { title: 'Previous Month', iconClass: 'border-color p-1 rounded hover:bg-secondary',
|
|
3436
|
+
svgClass: 'sm' });
|
|
3526
3437
|
header.appendChild(prevMonthIcon);
|
|
3527
3438
|
prevMonthIcon.addEventListener('click', () => {
|
|
3528
3439
|
this._previousMonth();
|
|
@@ -3530,8 +3441,8 @@ class Calendar {
|
|
|
3530
3441
|
}
|
|
3531
3442
|
LX.makeContainer(['100%', 'auto'], 'text-center font-medium select-none', `${this.monthName} ${this.year}`, header);
|
|
3532
3443
|
if (!this.skipNextMonth) {
|
|
3533
|
-
const nextMonthIcon = LX.makeIcon('Right', { title: 'Next Month',
|
|
3534
|
-
|
|
3444
|
+
const nextMonthIcon = LX.makeIcon('Right', { title: 'Next Month', iconClass: 'border-color p-1 rounded hover:bg-secondary',
|
|
3445
|
+
svgClass: 'sm' });
|
|
3535
3446
|
header.appendChild(nextMonthIcon);
|
|
3536
3447
|
nextMonthIcon.addEventListener('click', () => {
|
|
3537
3448
|
this._nextMonth();
|
|
@@ -3550,7 +3461,7 @@ class Calendar {
|
|
|
3550
3461
|
const hrow = document.createElement('tr');
|
|
3551
3462
|
for (const headData of ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su']) {
|
|
3552
3463
|
const th = document.createElement('th');
|
|
3553
|
-
th.className = '
|
|
3464
|
+
th.className = 'text-muted-foreground text-xs font-normal w-10 select-none';
|
|
3554
3465
|
th.innerHTML = `<span>${headData}</span>`;
|
|
3555
3466
|
hrow.appendChild(th);
|
|
3556
3467
|
}
|
|
@@ -3567,7 +3478,7 @@ class Calendar {
|
|
|
3567
3478
|
const weekDays = this.calendarDays.slice(week * 7, week * 7 + 7);
|
|
3568
3479
|
for (const dayData of weekDays) {
|
|
3569
3480
|
const th = document.createElement('th');
|
|
3570
|
-
th.className = 'leading-
|
|
3481
|
+
th.className = 'leading-8 text-xs font-normal rounded select-none cursor-pointer shrink-0 grow-0';
|
|
3571
3482
|
const dayDate = new Date(`${this.month}/${dayData.day}/${this.year}`);
|
|
3572
3483
|
const date = new Date();
|
|
3573
3484
|
// today inclusives
|
|
@@ -3591,13 +3502,13 @@ class Calendar {
|
|
|
3591
3502
|
&& (this.month == (toRangeDate.getMonth() + 1))
|
|
3592
3503
|
&& (this.year == toRangeDate.getFullYear());
|
|
3593
3504
|
if ((!this.range && currentDay) || this.range && (currentFromRange || currentToRange)) {
|
|
3594
|
-
th.className += ` bg-
|
|
3505
|
+
th.className += ` bg-primary text-primary-foreground`;
|
|
3595
3506
|
}
|
|
3596
3507
|
else if (this.range && selectable && (dayDate > fromRangeDate) && (dayDate < toRangeDate)) {
|
|
3597
|
-
th.className += ` bg-accent
|
|
3508
|
+
th.className += ` bg-accent text-accent-foreground`;
|
|
3598
3509
|
}
|
|
3599
3510
|
else {
|
|
3600
|
-
th.className += ` ${selectable ? '
|
|
3511
|
+
th.className += ` ${selectable ? 'text-secondary-foreground' : 'text-muted-foreground'} hover:bg-secondary`;
|
|
3601
3512
|
}
|
|
3602
3513
|
th.innerHTML = `<span>${dayData.day}</span>`;
|
|
3603
3514
|
hrow.appendChild(th);
|
|
@@ -3841,7 +3752,7 @@ class DatePicker extends BaseComponent {
|
|
|
3841
3752
|
const calendarIcon = LX.makeIcon('Calendar');
|
|
3842
3753
|
const calendarButton = new Button(null, d0, () => {
|
|
3843
3754
|
this._popover = new Popover(calendarButton.root, [this.calendar]);
|
|
3844
|
-
}, { buttonClass: `flex flex-row px-3 ${emptyDate ? '' : '
|
|
3755
|
+
}, { buttonClass: `outline flex flex-row px-3 ${emptyDate ? '' : 'text-muted-foreground'} justify-between` });
|
|
3845
3756
|
calendarButton.root.querySelector('button').appendChild(calendarIcon);
|
|
3846
3757
|
calendarButton.root.style.width = '100%';
|
|
3847
3758
|
container.appendChild(calendarButton.root);
|
|
@@ -3852,7 +3763,7 @@ class DatePicker extends BaseComponent {
|
|
|
3852
3763
|
const calendarIcon = LX.makeIcon('Calendar');
|
|
3853
3764
|
const calendarButton = new Button(null, d1, () => {
|
|
3854
3765
|
this._popover = new Popover(calendarButton.root, [this.calendar]);
|
|
3855
|
-
}, { buttonClass: `flex flex-row px-3 ${emptyDate ? '' : '
|
|
3766
|
+
}, { buttonClass: `outline flex flex-row px-3 ${emptyDate ? '' : 'text-muted-foreground'} justify-between` });
|
|
3856
3767
|
calendarButton.root.querySelector('button').appendChild(calendarIcon);
|
|
3857
3768
|
calendarButton.root.style.width = '100%';
|
|
3858
3769
|
container.appendChild(calendarButton.root);
|
|
@@ -3881,11 +3792,11 @@ class CanvasDial {
|
|
|
3881
3792
|
canvas;
|
|
3882
3793
|
constructor(value, options = {}) {
|
|
3883
3794
|
let element = document.createElement('div');
|
|
3884
|
-
element.className = 'dial
|
|
3795
|
+
element.className = LX.mergeClass('dial', options.className);
|
|
3885
3796
|
element.style.width = element.style.height = options.size || '100%';
|
|
3886
3797
|
element.style.minWidth = element.style.minHeight = '50px';
|
|
3887
|
-
element.bgcolor = options.bgColor || LX.
|
|
3888
|
-
element.pointscolor = options.pointsColor || LX.
|
|
3798
|
+
element.bgcolor = options.bgColor || LX.getCSSVariable('background');
|
|
3799
|
+
element.pointscolor = options.pointsColor || LX.getCSSVariable('primary/50');
|
|
3889
3800
|
element.linecolor = options.lineColor || '#555';
|
|
3890
3801
|
element.value = value || [];
|
|
3891
3802
|
element.xrange = options.xrange || [0, 1]; // min, max
|
|
@@ -3899,8 +3810,8 @@ class CanvasDial {
|
|
|
3899
3810
|
element.smooth = (options.smooth && typeof (options.smooth) == 'number' ? options.smooth : 0.3) || false;
|
|
3900
3811
|
element.move_out = options.moveOutAction ?? LX.CURVE_MOVEOUT_DELETE;
|
|
3901
3812
|
LX.addSignal('@on_new_color_scheme', (el, value) => {
|
|
3902
|
-
element.bgcolor = options.bgColor || LX.
|
|
3903
|
-
element.pointscolor = options.pointsColor || LX.
|
|
3813
|
+
element.bgcolor = options.bgColor || LX.getCSSVariable('background');
|
|
3814
|
+
element.pointscolor = options.pointsColor || LX.getCSSVariable('primary/50');
|
|
3904
3815
|
this.redraw();
|
|
3905
3816
|
});
|
|
3906
3817
|
this.element = element;
|
|
@@ -3956,8 +3867,7 @@ class CanvasDial {
|
|
|
3956
3867
|
}
|
|
3957
3868
|
// Canvas to value
|
|
3958
3869
|
function unconvert(v) {
|
|
3959
|
-
return [v[0] * element.xrange[1] / canvas.width + element.xrange[0],
|
|
3960
|
-
v[1] * element.yrange[1] / canvas.height + element.yrange[0]];
|
|
3870
|
+
return [v[0] * element.xrange[1] / canvas.width + element.xrange[0], v[1] * element.yrange[1] / canvas.height + element.yrange[0]];
|
|
3961
3871
|
}
|
|
3962
3872
|
var selected = -1;
|
|
3963
3873
|
element.redraw = function (o = {}) {
|
|
@@ -4314,7 +4224,7 @@ class Form extends BaseComponent {
|
|
|
4314
4224
|
}
|
|
4315
4225
|
};
|
|
4316
4226
|
let container = document.createElement('div');
|
|
4317
|
-
container.className = '
|
|
4227
|
+
container.className = 'flex flex-col gap-1';
|
|
4318
4228
|
container.style.width = '100%';
|
|
4319
4229
|
container.formData = {};
|
|
4320
4230
|
this.root.appendChild(container);
|
|
@@ -4330,7 +4240,7 @@ class Form extends BaseComponent {
|
|
|
4330
4240
|
entryData.ignoreValidation = true;
|
|
4331
4241
|
if (!(options.skipLabels ?? false)) {
|
|
4332
4242
|
const label = new TextInput(null, entryData.label ?? entry, null, { disabled: true,
|
|
4333
|
-
inputClass: 'formlabel bg-none' });
|
|
4243
|
+
inputClass: 'formlabel text-xs bg-none text-muted-foreground' });
|
|
4334
4244
|
container.appendChild(label.root);
|
|
4335
4245
|
}
|
|
4336
4246
|
entryData.textComponent = new TextInput(null, entryData.constructor == Object ? entryData.value : entryData, (value, event) => {
|
|
@@ -4348,7 +4258,7 @@ class Form extends BaseComponent {
|
|
|
4348
4258
|
if (options.secondaryActionCallback) {
|
|
4349
4259
|
options.secondaryActionCallback(container.formData, event);
|
|
4350
4260
|
}
|
|
4351
|
-
}, { width: '100%', minWidth: '0', buttonClass: options.secondaryButtonClass ?? '
|
|
4261
|
+
}, { width: '100%', minWidth: '0', buttonClass: options.secondaryButtonClass ?? 'secondary' });
|
|
4352
4262
|
buttonContainer.appendChild(secondaryButton.root);
|
|
4353
4263
|
}
|
|
4354
4264
|
const primaryButton = new Button(null, options.primaryActionName ?? 'Submit', (value, event) => {
|
|
@@ -4368,7 +4278,7 @@ class Form extends BaseComponent {
|
|
|
4368
4278
|
if (callback) {
|
|
4369
4279
|
callback(container.formData, errors, event);
|
|
4370
4280
|
}
|
|
4371
|
-
}, { width: '100%', minWidth: '0', buttonClass: options.primaryButtonClass ?? '
|
|
4281
|
+
}, { width: '100%', minWidth: '0', buttonClass: options.primaryButtonClass ?? 'primary' });
|
|
4372
4282
|
buttonContainer.appendChild(primaryButton.root);
|
|
4373
4283
|
}
|
|
4374
4284
|
}
|
|
@@ -4397,9 +4307,7 @@ class Layers extends BaseComponent {
|
|
|
4397
4307
|
const realNameWidth = this.root.domName?.style.width ?? '0px';
|
|
4398
4308
|
container.style.width = `calc( 100% - ${realNameWidth})`;
|
|
4399
4309
|
};
|
|
4400
|
-
const container =
|
|
4401
|
-
container.className = 'lexlayers';
|
|
4402
|
-
this.root.appendChild(container);
|
|
4310
|
+
const container = LX.makeElement('div', 'lexlayers grid', '', this.root);
|
|
4403
4311
|
const maxBits = options.maxBits ?? 16;
|
|
4404
4312
|
this.setLayers = (val) => {
|
|
4405
4313
|
container.innerHTML = '';
|
|
@@ -4411,7 +4319,8 @@ class Layers extends BaseComponent {
|
|
|
4411
4319
|
}
|
|
4412
4320
|
for (let bit = 0; bit < maxBits; ++bit) {
|
|
4413
4321
|
let layer = document.createElement('div');
|
|
4414
|
-
layer.className =
|
|
4322
|
+
layer.className =
|
|
4323
|
+
'lexlayer size-6 text-secondary-foreground text-center content-center place-self-center cursor-pointer font-semibold text-xs rounded-lg';
|
|
4415
4324
|
if (val != undefined) {
|
|
4416
4325
|
const valueBit = binary[maxBits - bit - 1];
|
|
4417
4326
|
if (valueBit != undefined && valueBit == '1') {
|
|
@@ -4499,7 +4408,7 @@ class List extends BaseComponent {
|
|
|
4499
4408
|
};
|
|
4500
4409
|
// Show list
|
|
4501
4410
|
let listContainer = document.createElement('div');
|
|
4502
|
-
listContainer.className = '
|
|
4411
|
+
listContainer.className = 'bg-background flex flex-col gap-1 rounded-xl border-color p-2';
|
|
4503
4412
|
this.root.appendChild(listContainer);
|
|
4504
4413
|
this._updateValues(values);
|
|
4505
4414
|
LX.doAsync(this.onResize.bind(this));
|
|
@@ -4945,7 +4854,7 @@ class Map2D extends BaseComponent {
|
|
|
4945
4854
|
const calendarIcon = LX.makeIcon('SquareMousePointer');
|
|
4946
4855
|
const calendarButton = new Button(null, 'Open Map', () => {
|
|
4947
4856
|
this._popover = new Popover(calendarButton.root, [this.map2d]);
|
|
4948
|
-
}, { buttonClass: `
|
|
4857
|
+
}, { buttonClass: `outline justify-between` });
|
|
4949
4858
|
calendarButton.root.querySelector('button').appendChild(calendarIcon);
|
|
4950
4859
|
container.appendChild(calendarButton.root);
|
|
4951
4860
|
LX.doAsync(this.onResize.bind(this));
|
|
@@ -4960,14 +4869,13 @@ LX.Map2D = Map2D;
|
|
|
4960
4869
|
class NodeTree {
|
|
4961
4870
|
domEl;
|
|
4962
4871
|
data;
|
|
4963
|
-
onevent;
|
|
4964
4872
|
options;
|
|
4965
4873
|
selected = [];
|
|
4966
4874
|
_forceClose = false;
|
|
4875
|
+
_callbacks = {};
|
|
4967
4876
|
constructor(domEl, data, options = {}) {
|
|
4968
4877
|
this.domEl = domEl;
|
|
4969
4878
|
this.data = data;
|
|
4970
|
-
this.onevent = options.onevent;
|
|
4971
4879
|
this.options = options;
|
|
4972
4880
|
if (data.constructor === Object) {
|
|
4973
4881
|
this._createItem(null, data);
|
|
@@ -5001,8 +4909,8 @@ class NodeTree {
|
|
|
5001
4909
|
isParent = !!hasFolders;
|
|
5002
4910
|
}
|
|
5003
4911
|
let item = document.createElement('li');
|
|
5004
|
-
item.className =
|
|
5005
|
-
|
|
4912
|
+
item.className =
|
|
4913
|
+
`lextreeitem inline-flex outline-none text-sm items-center h-7 cursor-pointer truncate rounded-lg select-none datalevel${level} ${isParent ? 'parent' : ''} ${isSelected ? ' selected' : ''}`;
|
|
5006
4914
|
item.id = LX.getSupportedDOMName(node.id);
|
|
5007
4915
|
item.tabIndex = '0';
|
|
5008
4916
|
item.treeData = node;
|
|
@@ -5012,7 +4920,7 @@ class NodeTree {
|
|
|
5012
4920
|
icon = node.closed ? 'Right' : 'Down';
|
|
5013
4921
|
}
|
|
5014
4922
|
if (icon) {
|
|
5015
|
-
item.appendChild(LX.makeIcon(icon, { iconClass: 'hierarchy', svgClass: '
|
|
4923
|
+
item.appendChild(LX.makeIcon(icon, { iconClass: 'hierarchy', svgClass: 'sm' }));
|
|
5016
4924
|
}
|
|
5017
4925
|
// Add display icon
|
|
5018
4926
|
icon = node.icon;
|
|
@@ -5027,13 +4935,15 @@ class NodeTree {
|
|
|
5027
4935
|
// an image..
|
|
5028
4936
|
else {
|
|
5029
4937
|
const rootPath = 'https://raw.githubusercontent.com/jxarco/lexgui.js/master/';
|
|
5030
|
-
item.innerHTML +=
|
|
4938
|
+
item.innerHTML += `<img src="${rootPath + node.icon}">`;
|
|
5031
4939
|
}
|
|
5032
4940
|
}
|
|
5033
4941
|
item.innerHTML += node.rename ? '' : node.id;
|
|
5034
|
-
item.setAttribute('draggable', true);
|
|
5035
4942
|
item.style.paddingLeft = (3 + (level + 1) * 15) + 'px';
|
|
5036
4943
|
list.appendChild(item);
|
|
4944
|
+
const isDraggable = parent && (node.metadata?.draggable ?? (this.options.defaultDraggable ?? true));
|
|
4945
|
+
if (isDraggable)
|
|
4946
|
+
item.setAttribute('draggable', 'true');
|
|
5037
4947
|
// Callbacks
|
|
5038
4948
|
item.addEventListener('click', (e) => {
|
|
5039
4949
|
if (handled) {
|
|
@@ -5048,27 +4958,38 @@ class NodeTree {
|
|
|
5048
4958
|
}
|
|
5049
4959
|
// Add or remove
|
|
5050
4960
|
const idx = this.selected.indexOf(node);
|
|
4961
|
+
item.classList.toggle('selected', idx == -1);
|
|
5051
4962
|
if (idx > -1) {
|
|
5052
|
-
item.classList.remove('selected');
|
|
5053
4963
|
this.selected.splice(idx, 1);
|
|
5054
4964
|
}
|
|
5055
4965
|
else {
|
|
5056
|
-
item.classList.add('selected');
|
|
5057
4966
|
this.selected.push(node);
|
|
5058
4967
|
}
|
|
5059
4968
|
// Only Show children...
|
|
5060
4969
|
if (isParent && node.id.length > 1 /* Strange case... */) {
|
|
5061
4970
|
node.closed = false;
|
|
5062
|
-
|
|
5063
|
-
|
|
5064
|
-
|
|
4971
|
+
const onCaretChanged = that._callbacks['caretChanged'];
|
|
4972
|
+
if (onCaretChanged !== undefined) {
|
|
4973
|
+
const event = {
|
|
4974
|
+
type: 'caret',
|
|
4975
|
+
items: [node],
|
|
4976
|
+
domEvent: e,
|
|
4977
|
+
userInitiated: true
|
|
4978
|
+
};
|
|
4979
|
+
onCaretChanged(event);
|
|
5065
4980
|
}
|
|
5066
4981
|
that.frefresh(node.id);
|
|
5067
4982
|
}
|
|
5068
|
-
|
|
5069
|
-
|
|
5070
|
-
event
|
|
5071
|
-
|
|
4983
|
+
const onSelect = that._callbacks['select'];
|
|
4984
|
+
if (onSelect !== undefined) {
|
|
4985
|
+
const event = {
|
|
4986
|
+
type: 'select',
|
|
4987
|
+
items: [node],
|
|
4988
|
+
result: this.selected,
|
|
4989
|
+
domEvent: e,
|
|
4990
|
+
userInitiated: true
|
|
4991
|
+
};
|
|
4992
|
+
onSelect(event);
|
|
5072
4993
|
}
|
|
5073
4994
|
});
|
|
5074
4995
|
item.addEventListener('dblclick', function (e) {
|
|
@@ -5077,27 +4998,40 @@ class NodeTree {
|
|
|
5077
4998
|
node.rename = true;
|
|
5078
4999
|
that.refresh();
|
|
5079
5000
|
}
|
|
5080
|
-
|
|
5081
|
-
|
|
5082
|
-
|
|
5001
|
+
const onDblClick = that._callbacks['dblClick'];
|
|
5002
|
+
if (onDblClick !== undefined) {
|
|
5003
|
+
const event = {
|
|
5004
|
+
type: 'dbl_click',
|
|
5005
|
+
items: [node],
|
|
5006
|
+
domEvent: e,
|
|
5007
|
+
userInitiated: true
|
|
5008
|
+
};
|
|
5009
|
+
onDblClick(event);
|
|
5083
5010
|
}
|
|
5084
5011
|
});
|
|
5085
|
-
item.addEventListener('contextmenu', (e) => {
|
|
5012
|
+
item.addEventListener('contextmenu', async (e) => {
|
|
5086
5013
|
e.preventDefault();
|
|
5087
|
-
|
|
5014
|
+
const onContextMenu = that._callbacks['contextMenu'];
|
|
5015
|
+
if (!onContextMenu) {
|
|
5088
5016
|
return;
|
|
5089
5017
|
}
|
|
5090
|
-
const event =
|
|
5091
|
-
|
|
5092
|
-
|
|
5093
|
-
|
|
5094
|
-
|
|
5095
|
-
|
|
5096
|
-
|
|
5097
|
-
|
|
5098
|
-
|
|
5018
|
+
const event = {
|
|
5019
|
+
type: 'context_menu',
|
|
5020
|
+
items: this.selected,
|
|
5021
|
+
from: node,
|
|
5022
|
+
domEvent: e,
|
|
5023
|
+
userInitiated: true
|
|
5024
|
+
};
|
|
5025
|
+
const r = await onContextMenu(event);
|
|
5026
|
+
const multiple = this.selected.length > 1;
|
|
5027
|
+
LX.addContextMenu(multiple ? 'Selected Nodes' : node.id, e, (m) => {
|
|
5028
|
+
if (r?.length) {
|
|
5029
|
+
for (const i of r) {
|
|
5030
|
+
m.add(i.name, { callback: i.callback });
|
|
5031
|
+
}
|
|
5032
|
+
m.add('');
|
|
5099
5033
|
}
|
|
5100
|
-
|
|
5034
|
+
m.add('Select Children', () => {
|
|
5101
5035
|
const selectChildren = (n) => {
|
|
5102
5036
|
if (n.closed) {
|
|
5103
5037
|
return;
|
|
@@ -5116,15 +5050,53 @@ class NodeTree {
|
|
|
5116
5050
|
this.selected.length = 0;
|
|
5117
5051
|
// Add childs of the clicked node
|
|
5118
5052
|
selectChildren(node);
|
|
5053
|
+
const onSelect = this._callbacks['select'];
|
|
5054
|
+
if (onSelect !== undefined) {
|
|
5055
|
+
const event = {
|
|
5056
|
+
type: 'select',
|
|
5057
|
+
items: [node],
|
|
5058
|
+
result: this.selected,
|
|
5059
|
+
domEvent: e,
|
|
5060
|
+
userInitiated: true
|
|
5061
|
+
};
|
|
5062
|
+
onSelect(event);
|
|
5063
|
+
}
|
|
5119
5064
|
});
|
|
5120
|
-
|
|
5121
|
-
const
|
|
5122
|
-
|
|
5123
|
-
|
|
5124
|
-
|
|
5065
|
+
m.add('Delete', { callback: () => {
|
|
5066
|
+
const onBeforeDelete = this._callbacks['beforeDelete'];
|
|
5067
|
+
const onDelete = this._callbacks['delete'];
|
|
5068
|
+
const resolve = (...args) => {
|
|
5069
|
+
let deletedNodes = [];
|
|
5070
|
+
if (this.selected.length) {
|
|
5071
|
+
deletedNodes.push(...that.deleteNodes(this.selected));
|
|
5072
|
+
}
|
|
5073
|
+
else if (that.deleteNode(node)) {
|
|
5074
|
+
deletedNodes.push(node);
|
|
5075
|
+
}
|
|
5076
|
+
this.refresh();
|
|
5077
|
+
const event = {
|
|
5078
|
+
type: 'delete',
|
|
5079
|
+
items: deletedNodes,
|
|
5080
|
+
userInitiated: true
|
|
5081
|
+
};
|
|
5082
|
+
if (onDelete)
|
|
5083
|
+
onDelete(event, ...args);
|
|
5084
|
+
};
|
|
5085
|
+
if (onBeforeDelete) {
|
|
5086
|
+
const event = {
|
|
5087
|
+
type: 'delete',
|
|
5088
|
+
items: this.selected.length ? this.selected : [node],
|
|
5089
|
+
userInitiated: true
|
|
5090
|
+
};
|
|
5091
|
+
onBeforeDelete(event, resolve);
|
|
5092
|
+
}
|
|
5093
|
+
else {
|
|
5094
|
+
resolve();
|
|
5125
5095
|
}
|
|
5126
|
-
this.refresh();
|
|
5127
5096
|
} });
|
|
5097
|
+
});
|
|
5098
|
+
if (!(this.options.addDefault ?? false)) {
|
|
5099
|
+
return;
|
|
5128
5100
|
}
|
|
5129
5101
|
});
|
|
5130
5102
|
item.addEventListener('keydown', (e) => {
|
|
@@ -5133,20 +5105,40 @@ class NodeTree {
|
|
|
5133
5105
|
}
|
|
5134
5106
|
e.preventDefault();
|
|
5135
5107
|
if (e.key == 'Delete') {
|
|
5136
|
-
const
|
|
5137
|
-
|
|
5138
|
-
|
|
5139
|
-
|
|
5108
|
+
const onBeforeDelete = this._callbacks['beforeDelete'];
|
|
5109
|
+
const onDelete = this._callbacks['delete'];
|
|
5110
|
+
const resolve = (...args) => {
|
|
5111
|
+
const nodesDeleted = [];
|
|
5112
|
+
for (let n of this.selected) {
|
|
5113
|
+
if (that.deleteNode(n)) {
|
|
5114
|
+
nodesDeleted.push(n);
|
|
5115
|
+
}
|
|
5116
|
+
}
|
|
5117
|
+
this.selected.length = 0;
|
|
5118
|
+
this.refresh();
|
|
5119
|
+
if (nodesDeleted.length) {
|
|
5120
|
+
const event = {
|
|
5121
|
+
type: 'delete',
|
|
5122
|
+
items: nodesDeleted,
|
|
5123
|
+
domEvent: e,
|
|
5124
|
+
userInitiated: true
|
|
5125
|
+
};
|
|
5126
|
+
if (onDelete)
|
|
5127
|
+
onDelete(event, ...args);
|
|
5140
5128
|
}
|
|
5129
|
+
};
|
|
5130
|
+
if (onBeforeDelete) {
|
|
5131
|
+
const event = {
|
|
5132
|
+
type: 'delete',
|
|
5133
|
+
items: this.selected,
|
|
5134
|
+
domEvent: e,
|
|
5135
|
+
userInitiated: true
|
|
5136
|
+
};
|
|
5137
|
+
onBeforeDelete(event, resolve);
|
|
5141
5138
|
}
|
|
5142
|
-
|
|
5143
|
-
|
|
5144
|
-
const event = new TreeEvent(TreeEvent.NODE_DELETED, node, nodesDeleted, e);
|
|
5145
|
-
event.multiple = nodesDeleted.length > 1;
|
|
5146
|
-
that.onevent(event);
|
|
5139
|
+
else {
|
|
5140
|
+
resolve();
|
|
5147
5141
|
}
|
|
5148
|
-
this.selected.length = 0;
|
|
5149
|
-
this.refresh();
|
|
5150
5142
|
}
|
|
5151
5143
|
else if (e.key == 'ArrowUp' || e.key == 'ArrowDown') { // Unique or zero selected
|
|
5152
5144
|
var selected = this.selected.length > 1
|
|
@@ -5162,7 +5154,7 @@ class NodeTree {
|
|
|
5162
5154
|
// Node rename
|
|
5163
5155
|
const nameInput = document.createElement('input');
|
|
5164
5156
|
nameInput.toggleAttribute('hidden', !node.rename);
|
|
5165
|
-
nameInput.className = 'bg-none';
|
|
5157
|
+
nameInput.className = 'text-foreground bg-none text-sm border-none outline-none';
|
|
5166
5158
|
nameInput.value = node.id;
|
|
5167
5159
|
item.appendChild(nameInput);
|
|
5168
5160
|
if (node.rename) {
|
|
@@ -5171,15 +5163,38 @@ class NodeTree {
|
|
|
5171
5163
|
}
|
|
5172
5164
|
nameInput.addEventListener('keyup', function (e) {
|
|
5173
5165
|
if (e.key == 'Enter') {
|
|
5166
|
+
const onBeforeRename = that._callbacks['beforeRename'];
|
|
5167
|
+
const onRename = that._callbacks['rename'];
|
|
5168
|
+
const oldName = node.id;
|
|
5174
5169
|
this.value = this.value.replace(/\s/g, '_');
|
|
5175
|
-
|
|
5176
|
-
|
|
5177
|
-
|
|
5170
|
+
const resolve = (...args) => {
|
|
5171
|
+
node.id = LX.getSupportedDOMName(this.value);
|
|
5172
|
+
delete node.rename;
|
|
5173
|
+
that.frefresh(node.id);
|
|
5174
|
+
list.querySelector(`#${node.id}`).classList.add('selected');
|
|
5175
|
+
const event = {
|
|
5176
|
+
type: 'rename',
|
|
5177
|
+
items: [node],
|
|
5178
|
+
oldName,
|
|
5179
|
+
newName: this.value,
|
|
5180
|
+
userInitiated: true
|
|
5181
|
+
};
|
|
5182
|
+
if (onRename)
|
|
5183
|
+
onRename(event, ...args);
|
|
5184
|
+
};
|
|
5185
|
+
if (onBeforeRename) {
|
|
5186
|
+
const event = {
|
|
5187
|
+
type: 'rename',
|
|
5188
|
+
items: [node],
|
|
5189
|
+
oldName,
|
|
5190
|
+
newName: this.value,
|
|
5191
|
+
userInitiated: true
|
|
5192
|
+
};
|
|
5193
|
+
onBeforeRename(event, resolve);
|
|
5194
|
+
}
|
|
5195
|
+
else {
|
|
5196
|
+
resolve();
|
|
5178
5197
|
}
|
|
5179
|
-
node.id = LX.getSupportedDOMName(this.value);
|
|
5180
|
-
delete node.rename;
|
|
5181
|
-
that.frefresh(node.id);
|
|
5182
|
-
list.querySelector('#' + node.id).classList.add('selected');
|
|
5183
5198
|
}
|
|
5184
5199
|
else if (e.key == 'Escape') {
|
|
5185
5200
|
delete node.rename;
|
|
@@ -5190,69 +5205,90 @@ class NodeTree {
|
|
|
5190
5205
|
delete node.rename;
|
|
5191
5206
|
that.refresh();
|
|
5192
5207
|
});
|
|
5193
|
-
if (
|
|
5194
|
-
|
|
5195
|
-
|
|
5196
|
-
item.addEventListener('dragstart', (e) => {
|
|
5197
|
-
window.__tree_node_dragged = node;
|
|
5198
|
-
});
|
|
5199
|
-
}
|
|
5200
|
-
/* Events fired on other node items */
|
|
5201
|
-
item.addEventListener('dragover', (e) => {
|
|
5202
|
-
e.preventDefault(); // allow drop
|
|
5203
|
-
}, false);
|
|
5204
|
-
item.addEventListener('dragenter', (e) => {
|
|
5205
|
-
e.target.classList.add('draggingover');
|
|
5206
|
-
});
|
|
5207
|
-
item.addEventListener('dragend', (e) => {
|
|
5208
|
-
e.target.classList.remove('draggingover');
|
|
5208
|
+
if (isDraggable) {
|
|
5209
|
+
item.addEventListener('dragstart', (e) => {
|
|
5210
|
+
window.__tree_node_dragged = node;
|
|
5209
5211
|
});
|
|
5210
|
-
|
|
5211
|
-
|
|
5212
|
-
|
|
5213
|
-
|
|
5214
|
-
|
|
5215
|
-
|
|
5216
|
-
|
|
5217
|
-
|
|
5218
|
-
|
|
5219
|
-
|
|
5220
|
-
|
|
5221
|
-
|
|
5222
|
-
|
|
5223
|
-
|
|
5224
|
-
|
|
5225
|
-
|
|
5226
|
-
|
|
5227
|
-
|
|
5228
|
-
|
|
5229
|
-
|
|
5230
|
-
|
|
5231
|
-
|
|
5232
|
-
|
|
5233
|
-
for (var c of node.children) {
|
|
5234
|
-
if (c.id == newParent.id)
|
|
5235
|
-
return true;
|
|
5236
|
-
result = result || isChild(newParent, c);
|
|
5237
|
-
}
|
|
5238
|
-
return result;
|
|
5239
|
-
};
|
|
5240
|
-
if (isChild(target, dragged)) {
|
|
5241
|
-
console.warn('Cannot parent node to a current child!');
|
|
5242
|
-
return;
|
|
5212
|
+
}
|
|
5213
|
+
/* Events fired on other node items,
|
|
5214
|
+
by now everyone is a drop target, cancel in the event if necessary */
|
|
5215
|
+
item.addEventListener('dragover', (e) => {
|
|
5216
|
+
e.preventDefault(); // allow drop
|
|
5217
|
+
}, false);
|
|
5218
|
+
item.addEventListener('dragenter', (e) => {
|
|
5219
|
+
e.target.classList.add('draggingover');
|
|
5220
|
+
});
|
|
5221
|
+
item.addEventListener('dragend', (e) => {
|
|
5222
|
+
e.target.classList.remove('draggingover');
|
|
5223
|
+
});
|
|
5224
|
+
item.addEventListener('dragleave', (e) => {
|
|
5225
|
+
e.target.classList.remove('draggingover');
|
|
5226
|
+
});
|
|
5227
|
+
item.addEventListener('drop', (e) => {
|
|
5228
|
+
e.preventDefault(); // Prevent default action (open as link for some elements)
|
|
5229
|
+
let dragged = window.__tree_node_dragged;
|
|
5230
|
+
if (!dragged) {
|
|
5231
|
+
// Test if we are moving from AssetView extension
|
|
5232
|
+
dragged = window.__av_item_dragged;
|
|
5233
|
+
if (dragged) {
|
|
5234
|
+
dragged._nodeTarget = node;
|
|
5243
5235
|
}
|
|
5244
|
-
|
|
5245
|
-
|
|
5246
|
-
|
|
5247
|
-
|
|
5236
|
+
return;
|
|
5237
|
+
}
|
|
5238
|
+
const domTarget = e.target;
|
|
5239
|
+
domTarget.classList.remove('draggingover');
|
|
5240
|
+
let target = node;
|
|
5241
|
+
// Can't drop to same node
|
|
5242
|
+
if (dragged.id == target.id) {
|
|
5243
|
+
console.warn('Cannot parent node to itself!');
|
|
5244
|
+
return;
|
|
5245
|
+
}
|
|
5246
|
+
// Can't drop to child node
|
|
5247
|
+
const isChild = function (newParent, node) {
|
|
5248
|
+
var result = false;
|
|
5249
|
+
for (var c of node.children) {
|
|
5250
|
+
if (c.id == newParent.id)
|
|
5251
|
+
return true;
|
|
5252
|
+
result = result || isChild(newParent, c);
|
|
5248
5253
|
}
|
|
5254
|
+
return result;
|
|
5255
|
+
};
|
|
5256
|
+
if (isChild(target, dragged)) {
|
|
5257
|
+
console.warn('Cannot parent node to a current child!');
|
|
5258
|
+
return;
|
|
5259
|
+
}
|
|
5260
|
+
const onBeforeMove = this._callbacks['beforeMove'];
|
|
5261
|
+
const onMove = this._callbacks['move'];
|
|
5262
|
+
const resolve = (...args) => {
|
|
5249
5263
|
const index = dragged.parent.children.findIndex((n) => n.id == dragged.id);
|
|
5250
5264
|
const removed = dragged.parent.children.splice(index, 1);
|
|
5251
5265
|
target.children.push(removed[0]);
|
|
5252
5266
|
that.refresh();
|
|
5253
5267
|
delete window.__tree_node_dragged;
|
|
5254
|
-
|
|
5255
|
-
|
|
5268
|
+
const event = {
|
|
5269
|
+
type: 'move',
|
|
5270
|
+
items: [dragged],
|
|
5271
|
+
to: target,
|
|
5272
|
+
domEvent: e,
|
|
5273
|
+
userInitiated: true
|
|
5274
|
+
};
|
|
5275
|
+
if (onMove)
|
|
5276
|
+
onMove(event, ...args);
|
|
5277
|
+
};
|
|
5278
|
+
if (onBeforeMove) {
|
|
5279
|
+
const event = {
|
|
5280
|
+
type: 'move',
|
|
5281
|
+
items: [dragged],
|
|
5282
|
+
to: target,
|
|
5283
|
+
domEvent: e,
|
|
5284
|
+
userInitiated: true
|
|
5285
|
+
};
|
|
5286
|
+
onBeforeMove(event, resolve);
|
|
5287
|
+
}
|
|
5288
|
+
else {
|
|
5289
|
+
resolve();
|
|
5290
|
+
}
|
|
5291
|
+
});
|
|
5256
5292
|
let handled = false;
|
|
5257
5293
|
// Show/hide children
|
|
5258
5294
|
if (isParent) {
|
|
@@ -5272,15 +5308,21 @@ class NodeTree {
|
|
|
5272
5308
|
else {
|
|
5273
5309
|
node.closed = !node.closed;
|
|
5274
5310
|
}
|
|
5275
|
-
|
|
5276
|
-
|
|
5277
|
-
|
|
5311
|
+
const onCaretChanged = that._callbacks['caretChanged'];
|
|
5312
|
+
if (onCaretChanged !== undefined) {
|
|
5313
|
+
const event = {
|
|
5314
|
+
type: 'caret',
|
|
5315
|
+
items: [node],
|
|
5316
|
+
domEvent: e,
|
|
5317
|
+
userInitiated: true
|
|
5318
|
+
};
|
|
5319
|
+
onCaretChanged(event);
|
|
5278
5320
|
}
|
|
5279
5321
|
that.frefresh(node.id);
|
|
5280
5322
|
});
|
|
5281
5323
|
}
|
|
5282
5324
|
// Add button icons
|
|
5283
|
-
const inputContainer =
|
|
5325
|
+
const inputContainer = LX.makeElement('div', 'flex flex-row ml-auto mr-2');
|
|
5284
5326
|
item.appendChild(inputContainer);
|
|
5285
5327
|
if (node.actions) {
|
|
5286
5328
|
for (let i = 0; i < node.actions.length; ++i) {
|
|
@@ -5290,15 +5332,8 @@ class NodeTree {
|
|
|
5290
5332
|
if (action.callback) {
|
|
5291
5333
|
action.callback(node, swapValue, event);
|
|
5292
5334
|
}
|
|
5293
|
-
}, { icon: action.icon, swap: action.swap, title: action.name, hideName: true, className: 'p-0
|
|
5294
|
-
buttonClass: '
|
|
5295
|
-
actionBtn.root.style.minWidth = 'fit-content';
|
|
5296
|
-
actionBtn.root.style.margin = '0'; // adding classes does not work
|
|
5297
|
-
actionBtn.root.style.padding = '0'; // adding classes does not work
|
|
5298
|
-
const _btn = actionBtn.root.querySelector('button');
|
|
5299
|
-
_btn.style.minWidth = 'fit-content';
|
|
5300
|
-
_btn.style.margin = '0'; // adding classes does not work
|
|
5301
|
-
_btn.style.padding = '0'; // adding classes does not work
|
|
5335
|
+
}, { icon: action.icon, swap: action.swap, title: action.name, hideName: true, className: 'p-0 min-h-fit',
|
|
5336
|
+
buttonClass: 'px-0 h-full bg-none' });
|
|
5302
5337
|
inputContainer.appendChild(actionBtn.root);
|
|
5303
5338
|
}
|
|
5304
5339
|
}
|
|
@@ -5306,13 +5341,18 @@ class NodeTree {
|
|
|
5306
5341
|
const visibilityBtn = new Button(null, '', (swapValue, e) => {
|
|
5307
5342
|
e.stopPropagation();
|
|
5308
5343
|
node.visible = node.visible === undefined ? false : !node.visible;
|
|
5309
|
-
|
|
5310
|
-
if (
|
|
5311
|
-
const event =
|
|
5312
|
-
|
|
5344
|
+
const onVisibleChanged = this._callbacks['visibleChanged'];
|
|
5345
|
+
if (onVisibleChanged !== undefined) {
|
|
5346
|
+
const event = {
|
|
5347
|
+
type: 'visibility',
|
|
5348
|
+
items: [node],
|
|
5349
|
+
domEvent: e,
|
|
5350
|
+
userInitiated: true
|
|
5351
|
+
};
|
|
5352
|
+
onVisibleChanged(event);
|
|
5313
5353
|
}
|
|
5314
|
-
}, { icon: node.visible ? 'Eye' : 'EyeOff', swap: node.visible ? 'EyeOff' : 'Eye', title: 'Toggle visible',
|
|
5315
|
-
|
|
5354
|
+
}, { icon: node.visible ? 'Eye' : 'EyeOff', swap: node.visible ? 'EyeOff' : 'Eye', title: 'Toggle visible', className: 'p-0 min-h-fit',
|
|
5355
|
+
buttonClass: 'px-0 h-full bg-none' });
|
|
5316
5356
|
inputContainer.appendChild(visibilityBtn.root);
|
|
5317
5357
|
}
|
|
5318
5358
|
const _hasChild = function (node, id) {
|
|
@@ -5375,6 +5415,15 @@ class NodeTree {
|
|
|
5375
5415
|
this.selected = [el.treeData];
|
|
5376
5416
|
el.focus();
|
|
5377
5417
|
}
|
|
5418
|
+
deleteNodes(nodes) {
|
|
5419
|
+
const nodesDeleted = [];
|
|
5420
|
+
for (const n of nodes) {
|
|
5421
|
+
if (this.deleteNode(n)) {
|
|
5422
|
+
nodesDeleted.push(n);
|
|
5423
|
+
}
|
|
5424
|
+
}
|
|
5425
|
+
return nodesDeleted;
|
|
5426
|
+
}
|
|
5378
5427
|
deleteNode(node) {
|
|
5379
5428
|
const dataAsArray = this.data.constructor === Array;
|
|
5380
5429
|
// Can be either Array or Object type data
|
|
@@ -5407,16 +5456,11 @@ class Tree extends BaseComponent {
|
|
|
5407
5456
|
constructor(name, data, options = {}) {
|
|
5408
5457
|
options.hideName = true;
|
|
5409
5458
|
super(ComponentType.TREE, name, null, options);
|
|
5410
|
-
let container =
|
|
5411
|
-
container.className = 'lextree';
|
|
5412
|
-
this.root.appendChild(container);
|
|
5459
|
+
let container = LX.makeElement('div', 'lextree p-1 rounded-lg w-full my-0 mx-auto font-medium text-sm min-h-3', '', this.root);
|
|
5413
5460
|
if (name) {
|
|
5414
|
-
|
|
5415
|
-
title.innerHTML = name;
|
|
5416
|
-
container.appendChild(title);
|
|
5461
|
+
LX.makeElement('span', 'block p-1 select-none text-base font-medium whitespace-nowrap', name, container);
|
|
5417
5462
|
}
|
|
5418
|
-
let toolsDiv =
|
|
5419
|
-
toolsDiv.className = 'lextreetools';
|
|
5463
|
+
let toolsDiv = LX.makeElement('div', 'lextreetools flex items-center bg-secondary px-2 rounded-lg gap-2 my-1');
|
|
5420
5464
|
if (!name) {
|
|
5421
5465
|
toolsDiv.className += ' notitle';
|
|
5422
5466
|
}
|
|
@@ -5447,13 +5491,20 @@ class Tree extends BaseComponent {
|
|
|
5447
5491
|
container.appendChild(toolsDiv);
|
|
5448
5492
|
}
|
|
5449
5493
|
// Tree
|
|
5450
|
-
let list =
|
|
5494
|
+
let list = LX.makeElement('ul', 'flex flex-col gap-1 ps-0');
|
|
5451
5495
|
list.addEventListener('contextmenu', function (e) {
|
|
5452
5496
|
e.preventDefault();
|
|
5453
5497
|
});
|
|
5454
5498
|
container.appendChild(list);
|
|
5455
5499
|
this.innerTree = new NodeTree(container, data, options);
|
|
5456
5500
|
}
|
|
5501
|
+
/**
|
|
5502
|
+
* @method on
|
|
5503
|
+
* @description Stores an event callback for the desired action
|
|
5504
|
+
*/
|
|
5505
|
+
on(eventName, callback) {
|
|
5506
|
+
this.innerTree._callbacks[eventName] = callback;
|
|
5507
|
+
}
|
|
5457
5508
|
}
|
|
5458
5509
|
LX.Tree = Tree;
|
|
5459
5510
|
|
|
@@ -5478,7 +5529,7 @@ class OTPInput extends BaseComponent {
|
|
|
5478
5529
|
value = newValue;
|
|
5479
5530
|
_refreshInput(value);
|
|
5480
5531
|
if (!skipCallback) {
|
|
5481
|
-
this._trigger(new IEvent(name,
|
|
5532
|
+
this._trigger(new IEvent(name, newValue, event), callback);
|
|
5482
5533
|
}
|
|
5483
5534
|
};
|
|
5484
5535
|
this.onResize = (rect) => {
|
|
@@ -5499,7 +5550,7 @@ class OTPInput extends BaseComponent {
|
|
|
5499
5550
|
for (let j = 0; j < g.length; ++j) {
|
|
5500
5551
|
let number = valueString[itemsCount++];
|
|
5501
5552
|
number = number == 'x' ? '' : number;
|
|
5502
|
-
const slotDom = LX.makeContainer(['36px', '30px'], 'lexotpslot border-
|
|
5553
|
+
const slotDom = 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);
|
|
5503
5554
|
slotDom.tabIndex = '1';
|
|
5504
5555
|
if (this.disabled) {
|
|
5505
5556
|
slotDom.classList.add('disabled');
|
|
@@ -5509,7 +5560,7 @@ class OTPInput extends BaseComponent {
|
|
|
5509
5560
|
slotDom.className += ' rounded-l';
|
|
5510
5561
|
}
|
|
5511
5562
|
else if (j == (g.length - 1)) {
|
|
5512
|
-
slotDom.className += ' rounded-r border-
|
|
5563
|
+
slotDom.className += ' rounded-r border-r-color';
|
|
5513
5564
|
}
|
|
5514
5565
|
slotDom.addEventListener('click', () => {
|
|
5515
5566
|
if (this.disabled)
|
|
@@ -5691,13 +5742,10 @@ class Progress extends BaseComponent {
|
|
|
5691
5742
|
const realNameWidth = this.root.domName?.style.width ?? '0px';
|
|
5692
5743
|
container.style.width = `calc( 100% - ${realNameWidth})`;
|
|
5693
5744
|
};
|
|
5694
|
-
const container =
|
|
5695
|
-
container.className = 'lexprogress';
|
|
5696
|
-
this.root.appendChild(container);
|
|
5745
|
+
const container = LX.makeElement('div', 'flex justify-center items-center gap-2', '', this.root);
|
|
5697
5746
|
// add slider (0-1 if not specified different )
|
|
5698
|
-
let progress =
|
|
5747
|
+
let progress = LX.makeElement('meter', 'lexprogressbar outline-none rounded-lg select-none');
|
|
5699
5748
|
progress.id = 'lexprogressbar-' + name;
|
|
5700
|
-
progress.className = 'lexprogressbar';
|
|
5701
5749
|
progress.step = 'any';
|
|
5702
5750
|
progress.min = options.min ?? 0;
|
|
5703
5751
|
progress.max = options.max ?? 1;
|
|
@@ -5707,12 +5755,12 @@ class Progress extends BaseComponent {
|
|
|
5707
5755
|
progress.value = value;
|
|
5708
5756
|
container.appendChild(progress);
|
|
5709
5757
|
const _updateColor = () => {
|
|
5710
|
-
let backgroundColor = LX.
|
|
5758
|
+
let backgroundColor = LX.getCSSVariable('blue-500');
|
|
5711
5759
|
if (progress.low != undefined && progress.value < progress.low) {
|
|
5712
|
-
backgroundColor = LX.
|
|
5760
|
+
backgroundColor = LX.getCSSVariable('destructive');
|
|
5713
5761
|
}
|
|
5714
5762
|
else if (progress.high != undefined && progress.value < progress.high) {
|
|
5715
|
-
backgroundColor = LX.
|
|
5763
|
+
backgroundColor = LX.getCSSVariable('warning');
|
|
5716
5764
|
}
|
|
5717
5765
|
progress.style.background = `color-mix(in srgb, ${backgroundColor} 20%, transparent)`;
|
|
5718
5766
|
};
|
|
@@ -5721,11 +5769,8 @@ class Progress extends BaseComponent {
|
|
|
5721
5769
|
if (oldSpan) {
|
|
5722
5770
|
oldSpan.remove();
|
|
5723
5771
|
}
|
|
5724
|
-
let span =
|
|
5772
|
+
let span = LX.makeElement('span', 'w-12 flex-auto-keep text-center', value, container);
|
|
5725
5773
|
span.id = 'progressvalue-' + name;
|
|
5726
|
-
span.style.padding = '0px 5px';
|
|
5727
|
-
span.innerText = value;
|
|
5728
|
-
container.appendChild(span);
|
|
5729
5774
|
}
|
|
5730
5775
|
if (options.editable ?? false) {
|
|
5731
5776
|
progress.classList.add('editable');
|
|
@@ -5795,14 +5840,13 @@ class RadioGroup extends BaseComponent {
|
|
|
5795
5840
|
}
|
|
5796
5841
|
};
|
|
5797
5842
|
var container = document.createElement('div');
|
|
5798
|
-
container.className = 'lexradiogroup '
|
|
5843
|
+
container.className = LX.mergeClass('lexradiogroup flex flex-col', options.className);
|
|
5799
5844
|
this.root.appendChild(container);
|
|
5800
|
-
|
|
5801
|
-
|
|
5802
|
-
container.appendChild(labelSpan);
|
|
5845
|
+
// Make label
|
|
5846
|
+
LX.makeElement('span', 'font-medium mb-2', label, container);
|
|
5803
5847
|
for (let i = 0; i < values.length; ++i) {
|
|
5804
5848
|
const optionItem = document.createElement('div');
|
|
5805
|
-
optionItem.className = 'lexradiogroupitem';
|
|
5849
|
+
optionItem.className = 'lexradiogroupitem flex items-center gap-2 px-6 py-1';
|
|
5806
5850
|
container.appendChild(optionItem);
|
|
5807
5851
|
const optionButton = document.createElement('button');
|
|
5808
5852
|
optionButton.className = 'flex p-0 rounded-lg cursor-pointer';
|
|
@@ -5910,11 +5954,10 @@ class RangeInput extends BaseComponent {
|
|
|
5910
5954
|
}
|
|
5911
5955
|
};
|
|
5912
5956
|
const container = document.createElement('div');
|
|
5913
|
-
container.className = 'lexrange relative';
|
|
5957
|
+
container.className = 'lexrange relative py-3';
|
|
5914
5958
|
this.root.appendChild(container);
|
|
5915
5959
|
let slider = document.createElement('input');
|
|
5916
|
-
slider.className = 'lexrangeslider
|
|
5917
|
-
+ (options.className ?? '');
|
|
5960
|
+
slider.className = LX.mergeClass('lexrangeslider' + (isRangeValue ? ' range pointer-events-none' : ''), options.className);
|
|
5918
5961
|
slider.min = options.min ?? 0;
|
|
5919
5962
|
slider.max = options.max ?? 100;
|
|
5920
5963
|
slider.step = options.step ?? 1;
|
|
@@ -5968,15 +6011,12 @@ class RangeInput extends BaseComponent {
|
|
|
5968
6011
|
const remapped = LX.remapRange(value, options.min, options.max, 0, 1) * 0.5;
|
|
5969
6012
|
offsetX = container.offsetWidth * remapped - (container.offsetWidth * 0.5);
|
|
5970
6013
|
}
|
|
5971
|
-
LX.asTooltip(container, `${value}${isRangeValue ? `- ${ogValue[1]}` : ``}`, { offsetX,
|
|
5972
|
-
callback: (tpDom) => {
|
|
6014
|
+
LX.asTooltip(container, `${value}${isRangeValue ? `- ${ogValue[1]}` : ``}`, { offsetX, callback: (tpDom) => {
|
|
5973
6015
|
this._labelTooltip = tpDom;
|
|
5974
6016
|
} });
|
|
5975
6017
|
});
|
|
5976
|
-
if (ogValue.constructor == Array) {
|
|
5977
|
-
let maxSlider =
|
|
5978
|
-
maxSlider.className = 'lexrangeslider no-fill pointer-events-none overlap absolute top-0 left-0 '
|
|
5979
|
-
+ (options.className ?? '');
|
|
6018
|
+
if (ogValue.constructor == Array) {
|
|
6019
|
+
let maxSlider = LX.makeElement('input', LX.mergeClass('lexrangeslider no-fill pointer-events-none overlap absolute left-0', options.className));
|
|
5980
6020
|
maxSlider.min = options.min ?? 0;
|
|
5981
6021
|
maxSlider.max = options.max ?? 100;
|
|
5982
6022
|
maxSlider.step = options.step ?? 1;
|
|
@@ -6041,7 +6081,7 @@ class Rate extends BaseComponent {
|
|
|
6041
6081
|
}, false);
|
|
6042
6082
|
// Create all layers of stars
|
|
6043
6083
|
for (let i = 0; i < 5; ++i) {
|
|
6044
|
-
const starIcon = LX.makeIcon('Star', { svgClass: `lg fill-current
|
|
6084
|
+
const starIcon = LX.makeIcon('Star', { svgClass: `lg fill-current text-accent` });
|
|
6045
6085
|
starIcon.dataset['idx'] = i + 1;
|
|
6046
6086
|
starsContainer.appendChild(starIcon);
|
|
6047
6087
|
starIcon.addEventListener('click', (e) => {
|
|
@@ -6050,9 +6090,9 @@ class Rate extends BaseComponent {
|
|
|
6050
6090
|
const half = allowHalf && e.offsetX < (rect.width * 0.5);
|
|
6051
6091
|
this.set(parseFloat(star.dataset['idx']) - (half ? 0.5 : 0.0));
|
|
6052
6092
|
}, false);
|
|
6053
|
-
const filledStarIcon = LX.makeIcon('Star', { svgClass: `lg fill-current
|
|
6093
|
+
const filledStarIcon = LX.makeIcon('Star', { svgClass: `lg fill-current text-yellow-400` });
|
|
6054
6094
|
filledStarsContainer.appendChild(filledStarIcon);
|
|
6055
|
-
const halfStarIcon = LX.makeIcon('StarHalf', { svgClass: `lg fill-current
|
|
6095
|
+
const halfStarIcon = LX.makeIcon('StarHalf', { svgClass: `lg fill-current text-yellow-400` });
|
|
6056
6096
|
halfStarsContainer.appendChild(halfStarIcon);
|
|
6057
6097
|
}
|
|
6058
6098
|
const _updateStars = (v) => {
|
|
@@ -6101,8 +6141,13 @@ class SizeInput extends BaseComponent {
|
|
|
6101
6141
|
this.root.dimensions[i].set(newValue[i], skipCallback);
|
|
6102
6142
|
}
|
|
6103
6143
|
};
|
|
6144
|
+
this.onResize = (rect) => {
|
|
6145
|
+
const realNameWidth = this.root.domName?.style.width ?? '0px';
|
|
6146
|
+
container.style.width = `calc( 100% - ${realNameWidth})`;
|
|
6147
|
+
};
|
|
6104
6148
|
this.root.aspectRatio = value.length == 2 ? value[0] / value[1] : null;
|
|
6105
6149
|
this.root.dimensions = [];
|
|
6150
|
+
const container = LX.makeElement('div', 'flex', '', this.root);
|
|
6106
6151
|
for (let i = 0; i < value.length; ++i) {
|
|
6107
6152
|
const p = new LX.Panel();
|
|
6108
6153
|
this.root.dimensions[i] = p.addNumber(null, value[i], (v) => {
|
|
@@ -6116,18 +6161,15 @@ class SizeInput extends BaseComponent {
|
|
|
6116
6161
|
if (callback) {
|
|
6117
6162
|
callback(value);
|
|
6118
6163
|
}
|
|
6119
|
-
}, { min: 0, disabled: options.disabled, precision: options.precision, className: 'flex-fill' });
|
|
6120
|
-
|
|
6164
|
+
}, { min: 0, disabled: options.disabled, precision: options.precision, className: 'flex-auto-fill' });
|
|
6165
|
+
container.appendChild(this.root.dimensions[i].root);
|
|
6121
6166
|
if ((i + 1) != value.length) {
|
|
6122
|
-
const xIcon = LX.makeIcon('X', { svgClass: '
|
|
6123
|
-
|
|
6167
|
+
const xIcon = LX.makeIcon('X', { svgClass: 'text-foreground font-bold' });
|
|
6168
|
+
container.appendChild(xIcon);
|
|
6124
6169
|
}
|
|
6125
6170
|
}
|
|
6126
6171
|
if (options.units) {
|
|
6127
|
-
|
|
6128
|
-
unitSpan.className = 'select-none fg-tertiary font-medium';
|
|
6129
|
-
unitSpan.innerText = options.units;
|
|
6130
|
-
this.root.appendChild(unitSpan);
|
|
6172
|
+
LX.makeElement('span', 'text-muted-foreground align-center content-center font-medium flex-auto-keep select-none', options.units, container);
|
|
6131
6173
|
}
|
|
6132
6174
|
// Lock aspect ratio
|
|
6133
6175
|
if (this.root.aspectRatio) {
|
|
@@ -6138,9 +6180,10 @@ class SizeInput extends BaseComponent {
|
|
|
6138
6180
|
const value = this.value();
|
|
6139
6181
|
this.root.aspectRatio = value[0] / value[1];
|
|
6140
6182
|
}
|
|
6141
|
-
}, { title: 'Lock Aspect Ratio', icon: 'LockOpen', swap: 'Lock', buttonClass: 'bg-none p-0' });
|
|
6142
|
-
|
|
6183
|
+
}, { title: 'Lock Aspect Ratio', icon: 'LockOpen', swap: 'Lock', className: 'flex-auto-keep', buttonClass: 'h-auto bg-none p-0' });
|
|
6184
|
+
container.appendChild(lockerButton.root);
|
|
6143
6185
|
}
|
|
6186
|
+
LX.doAsync(this.onResize.bind(this));
|
|
6144
6187
|
}
|
|
6145
6188
|
}
|
|
6146
6189
|
LX.SizeInput = SizeInput;
|
|
@@ -6185,7 +6228,7 @@ class Pagination {
|
|
|
6185
6228
|
if (typeof options.onItemsPerPageChange === 'function') {
|
|
6186
6229
|
this.onItemsPerPageChange = options.onItemsPerPageChange;
|
|
6187
6230
|
}
|
|
6188
|
-
this.root = LX.makeContainer(['auto', 'auto'], 'flex flex-row gap-2
|
|
6231
|
+
this.root = LX.makeContainer(['auto', 'auto'], LX.mergeClass('flex flex-row gap-2', options.className));
|
|
6189
6232
|
if (options.allowChangeItemsPerPage ?? false) {
|
|
6190
6233
|
const itemsPerPageSelectContainer = LX.makeContainer(['auto', 'auto'], 'flex flex-row items-center', '', this.root);
|
|
6191
6234
|
const itemsPerPageSelect = new Select(null, Pagination.ITEMS_PER_PAGE_VALUES, this._itemsPerPage, (v) => {
|
|
@@ -6222,7 +6265,7 @@ class Pagination {
|
|
|
6222
6265
|
refresh() {
|
|
6223
6266
|
this.pagesRoot.innerHTML = '';
|
|
6224
6267
|
// Previous page button
|
|
6225
|
-
this._makeButton(LX.makeIcon('ChevronLeft').innerHTML, this.page === 1, () => this.prev(), `bg-none ${this.page === 1 ? '' : 'hover:bg-
|
|
6268
|
+
this._makeButton(LX.makeIcon('ChevronLeft').innerHTML, this.page === 1, () => this.prev(), `bg-none ${this.page === 1 ? '' : 'hover:bg-secondary'}`);
|
|
6226
6269
|
const pagesContainer = LX.makeContainer(['auto', 'auto'], 'flex flex-row items-center', '', this.pagesRoot);
|
|
6227
6270
|
const maxButtons = this._maxButtons + 2; // + next and prev
|
|
6228
6271
|
if (this.pages <= maxButtons) {
|
|
@@ -6272,7 +6315,7 @@ class Pagination {
|
|
|
6272
6315
|
}
|
|
6273
6316
|
}
|
|
6274
6317
|
// Next page button
|
|
6275
|
-
this._makeButton(LX.makeIcon('ChevronRight').innerHTML, this.page === this.pages, () => this.next(), `bg-none ${this.page === this.pages ? '' : 'hover:bg-
|
|
6318
|
+
this._makeButton(LX.makeIcon('ChevronRight').innerHTML, this.page === this.pages, () => this.next(), `bg-none ${this.page === this.pages ? '' : 'hover:bg-secondary'}`);
|
|
6276
6319
|
}
|
|
6277
6320
|
_emitChange() {
|
|
6278
6321
|
// Event callback
|
|
@@ -6290,7 +6333,7 @@ class Pagination {
|
|
|
6290
6333
|
return btn.root;
|
|
6291
6334
|
}
|
|
6292
6335
|
_makePageButton(container, i) {
|
|
6293
|
-
const buttonClass = i === this.page ? '
|
|
6336
|
+
const buttonClass = `h-8 ${i === this.page ? 'primary text-primary-foreground' : 'ghost'}`;
|
|
6294
6337
|
return this._makeButton(String(i), false, () => this.setPage(i), buttonClass, container);
|
|
6295
6338
|
}
|
|
6296
6339
|
}
|
|
@@ -6444,10 +6487,10 @@ class Table extends BaseComponent {
|
|
|
6444
6487
|
}
|
|
6445
6488
|
if (this.customFilters !== null) {
|
|
6446
6489
|
const icon = LX.makeIcon('CirclePlus', { svgClass: 'sm' });
|
|
6447
|
-
const separatorHtml = `<div class="lexcontainer border-
|
|
6490
|
+
const separatorHtml = `<div class="lexcontainer border-r-color place-self-center mx-1" style="width: 1px; height: 70%;"></div>`;
|
|
6448
6491
|
for (let f of this.customFilters) {
|
|
6449
6492
|
f.component = new Button(null, icon.innerHTML + f.name, (v) => {
|
|
6450
|
-
const
|
|
6493
|
+
const buttonRoot = f.component.root.querySelector('button');
|
|
6451
6494
|
if (f.options) {
|
|
6452
6495
|
const menuOptions = f.options.map((colName, idx) => {
|
|
6453
6496
|
const item = {
|
|
@@ -6460,8 +6503,8 @@ class Table extends BaseComponent {
|
|
|
6460
6503
|
delete this.activeCustomFilters[key];
|
|
6461
6504
|
}
|
|
6462
6505
|
const activeFilters = Object.keys(this.activeCustomFilters).filter((k) => this.activeCustomFilters[k] == f.name);
|
|
6463
|
-
const filterBadgesHtml = activeFilters.reduce((acc, key) => acc += LX.badge(key, '
|
|
6464
|
-
|
|
6506
|
+
const filterBadgesHtml = activeFilters.reduce((acc, key) => acc += LX.badge(key, 'xs secondary'), '');
|
|
6507
|
+
buttonRoot.innerHTML = icon.innerHTML + f.name
|
|
6465
6508
|
+ (activeFilters.length ? separatorHtml : '') + filterBadgesHtml;
|
|
6466
6509
|
this.refresh();
|
|
6467
6510
|
}
|
|
@@ -6472,9 +6515,9 @@ class Table extends BaseComponent {
|
|
|
6472
6515
|
}
|
|
6473
6516
|
else if (f.type == 'range') {
|
|
6474
6517
|
console.assert(f.min != undefined && f.max != undefined, 'Range filter needs min and max values!');
|
|
6475
|
-
const container = LX.makeContainer(['240px', 'auto'], 'text-
|
|
6476
|
-
const panel = new LX.Panel();
|
|
6477
|
-
LX.makeContainer(['100%', 'auto'], 'px-3 p-2 pb-0 text-
|
|
6518
|
+
const container = LX.makeContainer(['240px', 'auto'], 'text-base');
|
|
6519
|
+
const panel = new LX.Panel({ className: 'flex flex-col gap-2' });
|
|
6520
|
+
LX.makeContainer(['100%', 'auto'], 'px-3 p-2 pb-0 text-base font-medium', f.name, container);
|
|
6478
6521
|
f.start = f.start ?? f.min;
|
|
6479
6522
|
f.end = f.end ?? f.max;
|
|
6480
6523
|
panel.refresh = () => {
|
|
@@ -6483,9 +6526,9 @@ class Table extends BaseComponent {
|
|
|
6483
6526
|
panel.addNumber(null, f.start, (v) => {
|
|
6484
6527
|
f.start = v;
|
|
6485
6528
|
const inUse = f.start != f.min || f.end != f.max;
|
|
6486
|
-
|
|
6529
|
+
buttonRoot.innerHTML = icon.innerHTML + f.name + (inUse
|
|
6487
6530
|
? separatorHtml
|
|
6488
|
-
+ LX.badge(`${f.start} - ${f.end} ${f.units ?? ''}`, '
|
|
6531
|
+
+ LX.badge(`${f.start} - ${f.end} ${f.units ?? ''}`, 'xs secondary')
|
|
6489
6532
|
: '');
|
|
6490
6533
|
if (inUse) {
|
|
6491
6534
|
this._resetCustomFiltersBtn?.root.classList.remove('hidden');
|
|
@@ -6495,10 +6538,10 @@ class Table extends BaseComponent {
|
|
|
6495
6538
|
panel.addNumber(null, f.end, (v) => {
|
|
6496
6539
|
f.end = v;
|
|
6497
6540
|
const inUse = f.start != f.min || f.end != f.max;
|
|
6498
|
-
|
|
6541
|
+
buttonRoot.innerHTML = icon.innerHTML + f.name
|
|
6499
6542
|
+ (inUse
|
|
6500
6543
|
? separatorHtml
|
|
6501
|
-
+ LX.badge(`${f.start} - ${f.end} ${f.units ?? ''}`, '
|
|
6544
|
+
+ LX.badge(`${f.start} - ${f.end} ${f.units ?? ''}`, 'xs secondary')
|
|
6502
6545
|
: '');
|
|
6503
6546
|
if (inUse) {
|
|
6504
6547
|
this._resetCustomFiltersBtn?.root.classList.remove('hidden');
|
|
@@ -6508,19 +6551,19 @@ class Table extends BaseComponent {
|
|
|
6508
6551
|
panel.addButton(null, 'Reset', () => {
|
|
6509
6552
|
f.start = f.min;
|
|
6510
6553
|
f.end = f.max;
|
|
6511
|
-
|
|
6554
|
+
buttonRoot.innerHTML = icon.innerHTML + f.name;
|
|
6512
6555
|
panel.refresh();
|
|
6513
6556
|
this.refresh();
|
|
6514
|
-
}, { buttonClass: '
|
|
6557
|
+
}, { buttonClass: 'ghost' });
|
|
6515
6558
|
};
|
|
6516
6559
|
panel.refresh();
|
|
6517
6560
|
container.appendChild(panel.root);
|
|
6518
6561
|
new Popover(f.component.root, [container], { side: 'bottom' });
|
|
6519
6562
|
}
|
|
6520
6563
|
else if (f.type == 'date') {
|
|
6521
|
-
const container = LX.makeContainer(['auto', 'auto'], 'text-
|
|
6564
|
+
const container = LX.makeContainer(['auto', 'auto'], 'text-base');
|
|
6522
6565
|
const panel = new LX.Panel();
|
|
6523
|
-
LX.makeContainer(['100%', 'auto'], 'px-3 p-2 pb-0 text-
|
|
6566
|
+
LX.makeContainer(['100%', 'auto'], 'px-3 p-2 pb-0 text-base font-medium', f.name, container);
|
|
6524
6567
|
panel.refresh = () => {
|
|
6525
6568
|
panel.clear();
|
|
6526
6569
|
// Generate default value once the filter is used
|
|
@@ -6532,9 +6575,9 @@ class Table extends BaseComponent {
|
|
|
6532
6575
|
const calendar = new CalendarRange(f.value ?? f.default, {
|
|
6533
6576
|
onChange: (dateRange) => {
|
|
6534
6577
|
f.value = dateRange;
|
|
6535
|
-
|
|
6578
|
+
buttonRoot.innerHTML = icon.innerHTML + f.name
|
|
6536
6579
|
+ (separatorHtml
|
|
6537
|
-
+ LX.badge(`${calendar.getFullDate()}`, '
|
|
6580
|
+
+ LX.badge(`${calendar.getFullDate()}`, 'xs secondary'));
|
|
6538
6581
|
this._resetCustomFiltersBtn?.root.classList.remove('hidden');
|
|
6539
6582
|
this.refresh();
|
|
6540
6583
|
}
|
|
@@ -6545,14 +6588,14 @@ class Table extends BaseComponent {
|
|
|
6545
6588
|
container.appendChild(panel.root);
|
|
6546
6589
|
new Popover(f.component.root, [container], { side: 'bottom' });
|
|
6547
6590
|
}
|
|
6548
|
-
}, { buttonClass: '
|
|
6591
|
+
}, { buttonClass: 'sm outline dashed' });
|
|
6549
6592
|
headerContainer.appendChild(f.component.root);
|
|
6550
6593
|
}
|
|
6551
6594
|
this._resetCustomFiltersBtn = new Button(null, 'resetButton', () => {
|
|
6552
6595
|
this.activeCustomFilters = {};
|
|
6553
6596
|
this._resetCustomFiltersBtn?.root.classList.add('hidden');
|
|
6554
6597
|
for (let f of this.customFilters ?? []) {
|
|
6555
|
-
f.component.root.querySelector('
|
|
6598
|
+
f.component.root.querySelector('button').innerHTML = icon.innerHTML + f.name;
|
|
6556
6599
|
if (f.type == 'range') {
|
|
6557
6600
|
f.start = f.min;
|
|
6558
6601
|
f.end = f.max;
|
|
@@ -6562,7 +6605,7 @@ class Table extends BaseComponent {
|
|
|
6562
6605
|
}
|
|
6563
6606
|
}
|
|
6564
6607
|
this.refresh();
|
|
6565
|
-
}, { title: 'Reset filters', tooltip: true, icon: 'X' });
|
|
6608
|
+
}, { title: 'Reset filters', tooltip: true, icon: 'X', buttonClass: 'ghost' });
|
|
6566
6609
|
headerContainer.appendChild(this._resetCustomFiltersBtn?.root);
|
|
6567
6610
|
this._resetCustomFiltersBtn?.root.classList.add('hidden');
|
|
6568
6611
|
}
|
|
@@ -6586,15 +6629,13 @@ class Table extends BaseComponent {
|
|
|
6586
6629
|
return item;
|
|
6587
6630
|
});
|
|
6588
6631
|
LX.addDropdownMenu(e.target, menuOptions, { side: 'bottom', align: 'end' });
|
|
6589
|
-
}, { hideName: true });
|
|
6632
|
+
}, { hideName: true, buttonClass: 'outline' });
|
|
6590
6633
|
headerContainer.appendChild(toggleColumnsBtn.root);
|
|
6591
6634
|
toggleColumnsBtn.root.style.marginLeft = 'auto';
|
|
6592
6635
|
}
|
|
6593
6636
|
container.appendChild(headerContainer);
|
|
6594
6637
|
}
|
|
6595
|
-
const table =
|
|
6596
|
-
LX.addClass(table, options.tableClass);
|
|
6597
|
-
container.appendChild(table);
|
|
6638
|
+
const table = LX.makeElement('table', options.tableClass, '', container);
|
|
6598
6639
|
this.refresh = () => {
|
|
6599
6640
|
this._currentFilter = this._currentFilter ?? '';
|
|
6600
6641
|
table.innerHTML = '';
|
|
@@ -6616,7 +6657,7 @@ class Table extends BaseComponent {
|
|
|
6616
6657
|
th.style.width = '0px';
|
|
6617
6658
|
const input = document.createElement('input');
|
|
6618
6659
|
input.type = 'checkbox';
|
|
6619
|
-
input.className = 'lexcheckbox
|
|
6660
|
+
input.className = 'lexcheckbox primary';
|
|
6620
6661
|
input.checked = data.checkMap[':root'] ?? false;
|
|
6621
6662
|
th.appendChild(input);
|
|
6622
6663
|
input.addEventListener('change', function () {
|
|
@@ -6651,8 +6692,7 @@ class Table extends BaseComponent {
|
|
|
6651
6692
|
console.warn('Invalid column action (missing name):', action);
|
|
6652
6693
|
continue;
|
|
6653
6694
|
}
|
|
6654
|
-
menuOptions.push({ name: action.name, icon: action.icon, className: action.className,
|
|
6655
|
-
callback: () => {
|
|
6695
|
+
menuOptions.push({ name: action.name, icon: action.icon, className: action.className, callback: () => {
|
|
6656
6696
|
const colRows = this.data.body.map((row) => [row[idx]]);
|
|
6657
6697
|
const mustRefresh = action.callback(colRows, table);
|
|
6658
6698
|
if (mustRefresh) {
|
|
@@ -6883,7 +6923,7 @@ class Table extends BaseComponent {
|
|
|
6883
6923
|
const td = document.createElement('td');
|
|
6884
6924
|
const input = document.createElement('input');
|
|
6885
6925
|
input.type = 'checkbox';
|
|
6886
|
-
input.className = 'lexcheckbox
|
|
6926
|
+
input.className = 'lexcheckbox primary';
|
|
6887
6927
|
input.checked = data.checkMap[rowId];
|
|
6888
6928
|
td.appendChild(input);
|
|
6889
6929
|
input.addEventListener('change', function () {
|
|
@@ -6995,7 +7035,7 @@ class Table extends BaseComponent {
|
|
|
6995
7035
|
const footerContainer = LX.makeContainer(['100%', 'auto'], 'flex flex-row px-3 my-1 align-center', '', container);
|
|
6996
7036
|
// Show num selected rows
|
|
6997
7037
|
if (showSelected) {
|
|
6998
|
-
const selectedRowsLabelContainer = LX.makeContainer(['100%', 'auto'], 'flex justify-start items-center
|
|
7038
|
+
const selectedRowsLabelContainer = LX.makeContainer(['100%', 'auto'], 'flex justify-start items-center', '0 row(s) selected.', footerContainer);
|
|
6999
7039
|
LX.addSignal('@rows_selected_changed', (target, n) => {
|
|
7000
7040
|
if (!this._showSelectedNumber)
|
|
7001
7041
|
return;
|
|
@@ -7091,7 +7131,8 @@ class TabSections extends BaseComponent {
|
|
|
7091
7131
|
let tabEl = document.createElement('div');
|
|
7092
7132
|
tabEl.className = 'lextab ' + ((tab.selected ?? false) ? 'selected' : '');
|
|
7093
7133
|
tabEl.innerHTML = showNames ? tab.name : '';
|
|
7094
|
-
tabEl.appendChild(LX.makeIcon(tab.icon ?? 'Hash', { title: tab.name, iconClass: tab.iconClass,
|
|
7134
|
+
tabEl.appendChild(LX.makeIcon(tab.icon ?? 'Hash', { title: tab.name, iconClass: tab.iconClass,
|
|
7135
|
+
svgClass: `lg${tab.svgClass ? ' ' + tab.svgClass : ''}` }));
|
|
7095
7136
|
this.tabDOMs[tab.name] = tabEl;
|
|
7096
7137
|
let infoContainer = document.createElement('div');
|
|
7097
7138
|
infoContainer.id = tab.name.replace(/\s/g, '');
|
|
@@ -7164,15 +7205,13 @@ class Tags extends BaseComponent {
|
|
|
7164
7205
|
};
|
|
7165
7206
|
// Show tags
|
|
7166
7207
|
const tagsContainer = document.createElement('div');
|
|
7167
|
-
tagsContainer.className = '
|
|
7208
|
+
tagsContainer.className = 'inline-flex flex-wrap gap-1 bg-card/50 rounded-lg pad-xs [&_input]:w-2/3';
|
|
7168
7209
|
this.root.appendChild(tagsContainer);
|
|
7169
7210
|
this.generateTags = (value) => {
|
|
7170
7211
|
tagsContainer.innerHTML = '';
|
|
7171
7212
|
for (let i = 0; i < value.length; ++i) {
|
|
7172
7213
|
const tagName = value[i];
|
|
7173
|
-
const tag =
|
|
7174
|
-
tag.className = 'lextag';
|
|
7175
|
-
tag.innerHTML = tagName;
|
|
7214
|
+
const tag = 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);
|
|
7176
7215
|
const removeButton = LX.makeIcon('X', { svgClass: 'sm' });
|
|
7177
7216
|
tag.appendChild(removeButton);
|
|
7178
7217
|
removeButton.addEventListener('click', (e) => {
|
|
@@ -7230,13 +7269,12 @@ class TextArea extends BaseComponent {
|
|
|
7230
7269
|
container.className = 'lextextarea';
|
|
7231
7270
|
container.style.display = 'flex';
|
|
7232
7271
|
this.root.appendChild(container);
|
|
7233
|
-
let wValue =
|
|
7272
|
+
let wValue = LX.makeElement('textarea', options.inputClass ?? '');
|
|
7234
7273
|
wValue.value = value ?? '';
|
|
7235
|
-
wValue.className = options.inputClass ?? '';
|
|
7236
7274
|
wValue.style.textAlign = options.float ?? '';
|
|
7237
7275
|
Object.assign(wValue.style, options.style ?? {});
|
|
7238
7276
|
if (options.fitHeight ?? false) {
|
|
7239
|
-
wValue.classList.add('
|
|
7277
|
+
wValue.classList.add('field-sizing-content');
|
|
7240
7278
|
}
|
|
7241
7279
|
if (!(options.resize ?? true)) {
|
|
7242
7280
|
wValue.classList.add('resize-none');
|
|
@@ -7287,7 +7325,8 @@ class Title extends BaseComponent {
|
|
|
7287
7325
|
console.assert(name.length !== 0, "Can't create Title Component without text!");
|
|
7288
7326
|
// Note: Titles are not registered in Panel.components by now
|
|
7289
7327
|
super(ComponentType.TITLE, null, null, options);
|
|
7290
|
-
|
|
7328
|
+
const cn = 'lextitle !w-fit bg-muted text-foreground text-sm font-semibold leading-normal m-3 flex content-center rounded-xl select-none';
|
|
7329
|
+
this.root.className = LX.mergeClass(cn, options.className);
|
|
7291
7330
|
if (options.icon) {
|
|
7292
7331
|
let icon = LX.makeIcon(options.icon, { iconClass: 'mr-2' });
|
|
7293
7332
|
icon.querySelector('svg').style.color = options.iconColor || '';
|
|
@@ -7296,16 +7335,14 @@ class Title extends BaseComponent {
|
|
|
7296
7335
|
let text = document.createElement('span');
|
|
7297
7336
|
text.innerText = name;
|
|
7298
7337
|
this.root.appendChild(text);
|
|
7299
|
-
Object.assign(this.root.style, options.style ?? {});
|
|
7300
7338
|
if (options.link != undefined) {
|
|
7301
|
-
let linkDom =
|
|
7302
|
-
linkDom.innerText = name;
|
|
7339
|
+
let linkDom = LX.makeElement('a', `${cn} link`, name);
|
|
7303
7340
|
linkDom.href = options.link;
|
|
7304
7341
|
linkDom.target = options.target ?? '';
|
|
7305
|
-
linkDom.className = 'lextitle link';
|
|
7306
|
-
Object.assign(linkDom.style, options.style ?? {});
|
|
7307
7342
|
this.root.replaceWith(linkDom);
|
|
7343
|
+
this.root = linkDom;
|
|
7308
7344
|
}
|
|
7345
|
+
Object.assign(this.root.style, options.style ?? {});
|
|
7309
7346
|
}
|
|
7310
7347
|
}
|
|
7311
7348
|
LX.Title = Title;
|
|
@@ -7340,25 +7377,23 @@ class Toggle extends BaseComponent {
|
|
|
7340
7377
|
container.style.width = options.inputWidth ?? `calc( 100% - ${realNameWidth})`;
|
|
7341
7378
|
};
|
|
7342
7379
|
var container = document.createElement('div');
|
|
7343
|
-
container.className = '
|
|
7380
|
+
container.className = 'flex flex-row gap-2 items-center';
|
|
7344
7381
|
this.root.appendChild(container);
|
|
7345
|
-
let toggle =
|
|
7382
|
+
let toggle = LX.makeElement('input', LX.mergeClass('lextoggle relative inline-grid place-content-center cursor-pointer shrink-0 select-none', options.className));
|
|
7346
7383
|
toggle.type = 'checkbox';
|
|
7347
|
-
toggle.className = 'lextoggle ' + (options.className ?? '');
|
|
7348
7384
|
toggle.checked = value;
|
|
7349
7385
|
toggle.iValue = value;
|
|
7350
7386
|
toggle.disabled = options.disabled ?? false;
|
|
7351
7387
|
container.appendChild(toggle);
|
|
7352
7388
|
let valueName = document.createElement('span');
|
|
7353
|
-
valueName.className = '
|
|
7389
|
+
valueName.className = 'font-medium w-full overflow-hidden truncate';
|
|
7354
7390
|
valueName.innerHTML = options.label ?? 'On';
|
|
7355
7391
|
container.appendChild(valueName);
|
|
7356
7392
|
toggle.addEventListener('change', (e) => {
|
|
7357
7393
|
this.set(toggle.checked, false, e);
|
|
7358
7394
|
});
|
|
7359
7395
|
if (options.suboptions) {
|
|
7360
|
-
let suboptions =
|
|
7361
|
-
suboptions.className = 'lextogglesubmenu';
|
|
7396
|
+
let suboptions = LX.makeElement('div', 'lextogglesubmenu w-full p-2');
|
|
7362
7397
|
suboptions.toggleAttribute('hidden', !toggle.checked);
|
|
7363
7398
|
const suboptionsPanel = new LX.Panel();
|
|
7364
7399
|
suboptionsPanel.queue(suboptions);
|
|
@@ -7377,6 +7412,7 @@ LX.Toggle = Toggle;
|
|
|
7377
7412
|
* @description Vector Component
|
|
7378
7413
|
*/
|
|
7379
7414
|
class Vector extends BaseComponent {
|
|
7415
|
+
locked = false;
|
|
7380
7416
|
setLimits;
|
|
7381
7417
|
constructor(numComponents, name, value, callback, options = {}) {
|
|
7382
7418
|
numComponents = LX.clamp(numComponents, 2, 4);
|
|
@@ -7412,7 +7448,7 @@ class Vector extends BaseComponent {
|
|
|
7412
7448
|
this.setLimits = (newMin, newMax, newStep) => { };
|
|
7413
7449
|
const vectorInputs = [];
|
|
7414
7450
|
var container = document.createElement('div');
|
|
7415
|
-
container.className = 'lexvector';
|
|
7451
|
+
container.className = 'lexvector flex';
|
|
7416
7452
|
this.root.appendChild(container);
|
|
7417
7453
|
this.disabled = options.disabled ?? false;
|
|
7418
7454
|
const that = this;
|
|
@@ -7451,7 +7487,7 @@ class Vector extends BaseComponent {
|
|
|
7451
7487
|
mult = 10;
|
|
7452
7488
|
else if (e.altKey)
|
|
7453
7489
|
mult = 0.1;
|
|
7454
|
-
if (
|
|
7490
|
+
if (that.locked) {
|
|
7455
7491
|
for (let v of vectorInputs) {
|
|
7456
7492
|
v.value = LX.round(+v.valueAsNumber - mult * (e.deltaY > 0 ? 1 : -1), options.precision);
|
|
7457
7493
|
BaseComponent._dispatchEvent(v, 'change');
|
|
@@ -7468,7 +7504,7 @@ class Vector extends BaseComponent {
|
|
|
7468
7504
|
}
|
|
7469
7505
|
let val = LX.clamp(e.target.value, +vecinput.min, +vecinput.max);
|
|
7470
7506
|
val = LX.round(val, options.precision);
|
|
7471
|
-
if (
|
|
7507
|
+
if (this.locked) {
|
|
7472
7508
|
for (let v of vectorInputs) {
|
|
7473
7509
|
v.value = val;
|
|
7474
7510
|
value[v.idx] = val;
|
|
@@ -7507,7 +7543,7 @@ class Vector extends BaseComponent {
|
|
|
7507
7543
|
mult = 10;
|
|
7508
7544
|
else if (e.altKey)
|
|
7509
7545
|
mult = 0.1;
|
|
7510
|
-
if (
|
|
7546
|
+
if (that.locked) {
|
|
7511
7547
|
for (let v of vectorInputs) {
|
|
7512
7548
|
v.value = LX.round(+v.valueAsNumber + mult * dt, options.precision);
|
|
7513
7549
|
BaseComponent._dispatchEvent(v, 'change');
|
|
@@ -7548,10 +7584,12 @@ class Vector extends BaseComponent {
|
|
|
7548
7584
|
this.set(value, true);
|
|
7549
7585
|
};
|
|
7550
7586
|
}
|
|
7551
|
-
|
|
7552
|
-
lockerButton
|
|
7553
|
-
|
|
7554
|
-
|
|
7587
|
+
if (!options.skipLock) {
|
|
7588
|
+
const lockerButton = new Button(null, '', (swapValue) => {
|
|
7589
|
+
this.locked = swapValue;
|
|
7590
|
+
}, { title: 'Lock', icon: 'LockOpen', swap: 'Lock', buttonClass: 'h-auto bg-none p-0' });
|
|
7591
|
+
container.appendChild(lockerButton.root);
|
|
7592
|
+
}
|
|
7555
7593
|
LX.doAsync(this.onResize.bind(this));
|
|
7556
7594
|
}
|
|
7557
7595
|
}
|
|
@@ -7574,22 +7612,17 @@ class Branch {
|
|
|
7574
7612
|
constructor(name, options = {}) {
|
|
7575
7613
|
this.name = name;
|
|
7576
7614
|
var root = document.createElement('div');
|
|
7577
|
-
root.className = 'lexbranch';
|
|
7578
7615
|
if (options.id) {
|
|
7579
7616
|
root.id = options.id;
|
|
7580
7617
|
}
|
|
7581
|
-
|
|
7582
|
-
root.className += ' ' + options.className;
|
|
7583
|
-
}
|
|
7584
|
-
root.style.margin = '0 auto';
|
|
7618
|
+
root.className = LX.mergeClass('lexbranch w-full rounded-lg my-0 mx-auto', options.className);
|
|
7585
7619
|
var that = this;
|
|
7586
7620
|
this.closed = options.closed ?? false;
|
|
7587
7621
|
this.root = root;
|
|
7588
7622
|
this.components = [];
|
|
7589
7623
|
this.panel = null;
|
|
7590
7624
|
// Create element
|
|
7591
|
-
const title =
|
|
7592
|
-
title.className = 'lexbranchtitle';
|
|
7625
|
+
const title = LX.makeElement('div', 'lexbranchtitle flex cursor-pointer select-none pad-lg bg-card text-card-foreground text-lg', '', root);
|
|
7593
7626
|
if (options.icon) {
|
|
7594
7627
|
const branchIcon = LX.makeIcon(options.icon, { iconClass: 'mr-2' });
|
|
7595
7628
|
title.appendChild(branchIcon);
|
|
@@ -7597,11 +7630,8 @@ class Branch {
|
|
|
7597
7630
|
title.innerHTML += name || 'Branch';
|
|
7598
7631
|
const collapseIcon = LX.makeIcon('Right', { iconClass: 'switch-branch-button', svgClass: 'sm' });
|
|
7599
7632
|
title.appendChild(collapseIcon);
|
|
7600
|
-
|
|
7601
|
-
var branchContent = document.createElement('div');
|
|
7633
|
+
var branchContent = LX.makeElement('div', 'lexbranchcontent pad-xs bg-card', '', root);
|
|
7602
7634
|
branchContent.id = name.replace(/\s/g, '');
|
|
7603
|
-
branchContent.className = 'lexbranchcontent';
|
|
7604
|
-
root.appendChild(branchContent);
|
|
7605
7635
|
this.content = branchContent;
|
|
7606
7636
|
this._addBranchSeparator();
|
|
7607
7637
|
if (this.closed) {
|
|
@@ -7756,14 +7786,10 @@ class Panel {
|
|
|
7756
7786
|
* style: CSS Style object to be applied to the panel
|
|
7757
7787
|
*/
|
|
7758
7788
|
constructor(options = {}) {
|
|
7759
|
-
|
|
7760
|
-
root.className = 'lexpanel';
|
|
7789
|
+
const root = LX.makeElement('div', LX.mergeClass('lexpanel m-0 pad-md overflow-hidden overflow-y-scroll text-foreground scrollbar-hidden', options.className));
|
|
7761
7790
|
if (options.id) {
|
|
7762
7791
|
root.id = options.id;
|
|
7763
7792
|
}
|
|
7764
|
-
if (options.className) {
|
|
7765
|
-
root.className += ' ' + options.className;
|
|
7766
|
-
}
|
|
7767
7793
|
root.style.width = options.width || '100%';
|
|
7768
7794
|
root.style.height = options.height || '100%';
|
|
7769
7795
|
Object.assign(root.style, options.style ?? {});
|
|
@@ -7817,8 +7843,7 @@ class Panel {
|
|
|
7817
7843
|
const signal = this.components[w].options.signal;
|
|
7818
7844
|
for (let i = 0; i < LX.signals[signal].length; i++) {
|
|
7819
7845
|
if (LX.signals[signal][i] == this.components[w]) {
|
|
7820
|
-
LX.signals[signal] = [...LX.signals[signal].slice(0, i),
|
|
7821
|
-
...LX.signals[signal].slice(i + 1)];
|
|
7846
|
+
LX.signals[signal] = [...LX.signals[signal].slice(0, i), ...LX.signals[signal].slice(i + 1)];
|
|
7822
7847
|
}
|
|
7823
7848
|
}
|
|
7824
7849
|
}
|
|
@@ -7829,8 +7854,7 @@ class Panel {
|
|
|
7829
7854
|
let signal = c.options.signal;
|
|
7830
7855
|
for (let i = 0; i < LX.signals[signal].length; i++) {
|
|
7831
7856
|
if (LX.signals[signal][i] == c) {
|
|
7832
|
-
LX.signals[signal] = [...LX.signals[signal].slice(0, i),
|
|
7833
|
-
...LX.signals[signal].slice(i + 1)];
|
|
7857
|
+
LX.signals[signal] = [...LX.signals[signal].slice(0, i), ...LX.signals[signal].slice(i + 1)];
|
|
7834
7858
|
}
|
|
7835
7859
|
}
|
|
7836
7860
|
}
|
|
@@ -8163,7 +8187,7 @@ class Panel {
|
|
|
8163
8187
|
*/
|
|
8164
8188
|
addLabel(value, options = {}) {
|
|
8165
8189
|
options.disabled = true;
|
|
8166
|
-
options.inputClass = (
|
|
8190
|
+
options.inputClass = LX.mergeClass('bg-none', options.inputClass);
|
|
8167
8191
|
const component = this.addText(null, value, null, options);
|
|
8168
8192
|
component.type = ComponentType.LABEL;
|
|
8169
8193
|
return component;
|
|
@@ -8225,7 +8249,7 @@ class Panel {
|
|
|
8225
8249
|
* @param {Function} callback Callback function on submit form
|
|
8226
8250
|
* @param {Object} options:
|
|
8227
8251
|
* primaryActionName: Text to be shown in the primary action button ['Submit']
|
|
8228
|
-
* primaryButtonClass: Button class for primary action button ['
|
|
8252
|
+
* primaryButtonClass: Button class for primary action button ['primary']
|
|
8229
8253
|
* secondaryActionName: Text to be shown in the secondary action button ['Cancel']
|
|
8230
8254
|
* secondaryActionCallback: Callback function on press secondary button
|
|
8231
8255
|
* secondaryButtonClass: Button class for secondary action button ['primary']
|
|
@@ -8700,11 +8724,10 @@ class AreaOverlayButtons {
|
|
|
8700
8724
|
this._buildButtons(buttonsArray, options);
|
|
8701
8725
|
}
|
|
8702
8726
|
_buildButtons(buttonsArray, options = {}) {
|
|
8703
|
-
options.className = 'lexoverlaybuttons';
|
|
8727
|
+
options.className = 'lexoverlaybuttons flex justify-start gap-2 bg-card m-2 p-1 rounded-2xl border-color';
|
|
8704
8728
|
let overlayPanel = this.area.addPanel(options);
|
|
8705
8729
|
let overlayGroup = null;
|
|
8706
|
-
const container =
|
|
8707
|
-
container.className = 'lexoverlaybuttonscontainer';
|
|
8730
|
+
const container = LX.makeElement('div', 'lexoverlaybuttonscontainer absolute flex top-0 w-full pointer-events-none');
|
|
8708
8731
|
container.appendChild(overlayPanel.root);
|
|
8709
8732
|
this.area.attach(container);
|
|
8710
8733
|
const float = options.float;
|
|
@@ -8746,6 +8769,7 @@ class AreaOverlayButtons {
|
|
|
8746
8769
|
icon: b.icon,
|
|
8747
8770
|
img: b.img,
|
|
8748
8771
|
className: b.class ?? '',
|
|
8772
|
+
buttonClass: b.buttonClass ?? 'x', // Avoid using default outline
|
|
8749
8773
|
title: b.name,
|
|
8750
8774
|
overflowContainerX: overlayPanel.root,
|
|
8751
8775
|
swap: b.swap
|
|
@@ -8753,7 +8777,7 @@ class AreaOverlayButtons {
|
|
|
8753
8777
|
if (group) {
|
|
8754
8778
|
if (!overlayGroup) {
|
|
8755
8779
|
overlayGroup = document.createElement('div');
|
|
8756
|
-
overlayGroup.className = 'lexoverlaygroup';
|
|
8780
|
+
overlayGroup.className = 'lexoverlaygroup flex flex-none bg-secondary rounded-xl';
|
|
8757
8781
|
overlayPanel.queuedContainer = overlayGroup;
|
|
8758
8782
|
}
|
|
8759
8783
|
_options.parent = overlayGroup;
|
|
@@ -8862,13 +8886,10 @@ class Area {
|
|
|
8862
8886
|
_root;
|
|
8863
8887
|
constructor(options = {}) {
|
|
8864
8888
|
var root = document.createElement('div');
|
|
8865
|
-
root.className = 'lexarea';
|
|
8866
8889
|
if (options.id) {
|
|
8867
8890
|
root.id = options.id;
|
|
8868
8891
|
}
|
|
8869
|
-
|
|
8870
|
-
root.className += ' ' + options.className;
|
|
8871
|
-
}
|
|
8892
|
+
root.className = LX.mergeClass('lexarea m-0 bg-background text-foreground', options.className);
|
|
8872
8893
|
var width = options.width || '100%';
|
|
8873
8894
|
var height = options.height || '100%';
|
|
8874
8895
|
// This has default options..
|
|
@@ -9032,8 +9053,7 @@ class Area {
|
|
|
9032
9053
|
const type = layout.type ?? 'horizontal';
|
|
9033
9054
|
const resize = layout.resize ?? true;
|
|
9034
9055
|
const minimizable = layout.minimizable ?? false;
|
|
9035
|
-
const [splitA, splitB] = area.split({ type, resize, minimizable,
|
|
9036
|
-
sizes: [layout.splits[0].size, layout.splits[1].size] });
|
|
9056
|
+
const [splitA, splitB] = area.split({ type, resize, minimizable, sizes: [layout.splits[0].size, layout.splits[1].size] });
|
|
9037
9057
|
_splitArea(splitA, layout.splits[0]);
|
|
9038
9058
|
_splitArea(splitB, layout.splits[1]);
|
|
9039
9059
|
};
|
|
@@ -9133,8 +9153,7 @@ class Area {
|
|
|
9133
9153
|
// Create areas
|
|
9134
9154
|
let area1 = new Area({ width: primarySize[0], height: primarySize[1], skipAppend: true,
|
|
9135
9155
|
className: 'split' + (options.menubar || options.sidebar ? '' : ' origin') });
|
|
9136
|
-
let area2 = new Area({ width: secondarySize[0], height: secondarySize[1], skipAppend: true,
|
|
9137
|
-
className: 'split' });
|
|
9156
|
+
let area2 = new Area({ width: secondarySize[0], height: secondarySize[1], skipAppend: true, className: 'split' });
|
|
9138
9157
|
/*
|
|
9139
9158
|
If the parent area is not in the DOM, we need to wait for the resize event to get the its correct size
|
|
9140
9159
|
and set the sizes of the split areas accordingly.
|
|
@@ -9406,16 +9425,15 @@ class Area {
|
|
|
9406
9425
|
addMenubar(items, options = {}) {
|
|
9407
9426
|
let menubar = new Menubar(items, options);
|
|
9408
9427
|
LX.menubars.push(menubar);
|
|
9409
|
-
const [bar, content] = this.split({ type: 'vertical', sizes: ['48px', null], resize: false,
|
|
9410
|
-
menubar: true });
|
|
9428
|
+
const [bar, content] = this.split({ type: 'vertical', sizes: ['48px', null], resize: false, menubar: true });
|
|
9411
9429
|
menubar.siblingArea = content;
|
|
9412
9430
|
bar.attach(menubar);
|
|
9413
9431
|
bar.isMenubar = true;
|
|
9414
9432
|
if (options.sticky ?? true) {
|
|
9415
|
-
bar.root.className += ' sticky top-0 z-
|
|
9433
|
+
bar.root.className += ' sticky top-0 z-100';
|
|
9416
9434
|
}
|
|
9417
9435
|
if (options.parentClass) {
|
|
9418
|
-
bar.root.className
|
|
9436
|
+
bar.root.className = LX.mergeClass(bar.root.className, options.parentClass);
|
|
9419
9437
|
}
|
|
9420
9438
|
return menubar;
|
|
9421
9439
|
}
|
|
@@ -9445,7 +9463,7 @@ class Area {
|
|
|
9445
9463
|
bar.attach(sidebar);
|
|
9446
9464
|
bar.isSidebar = true;
|
|
9447
9465
|
if (options.parentClass) {
|
|
9448
|
-
bar.root.className
|
|
9466
|
+
bar.root.className = LX.mergeClass(bar.root.className, options.parentClass);
|
|
9449
9467
|
}
|
|
9450
9468
|
return sidebar;
|
|
9451
9469
|
}
|
|
@@ -9574,6 +9592,17 @@ class Area {
|
|
|
9574
9592
|
LX.Area = Area;
|
|
9575
9593
|
|
|
9576
9594
|
// Utils.ts @jxarco
|
|
9595
|
+
// @ts-ignore
|
|
9596
|
+
/* Add Tailwind merge utility to LX namespace EXTENDED with new LX class groups*/
|
|
9597
|
+
LX.twMerge = extendTailwindMerge({
|
|
9598
|
+
extend: {
|
|
9599
|
+
classGroups: {
|
|
9600
|
+
pad: [
|
|
9601
|
+
{ pad: ['xs', 'sm', 'md', 'lg', 'xl', '2xl'] }
|
|
9602
|
+
]
|
|
9603
|
+
}
|
|
9604
|
+
}
|
|
9605
|
+
});
|
|
9577
9606
|
function clamp(num, min, max) {
|
|
9578
9607
|
return Math.min(Math.max(num, min), max);
|
|
9579
9608
|
}
|
|
@@ -9664,7 +9693,7 @@ function getSupportedDOMName(text) {
|
|
|
9664
9693
|
console.assert(typeof text == 'string', 'getSupportedDOMName: Text is not a string!');
|
|
9665
9694
|
let name = text.trim();
|
|
9666
9695
|
// Replace specific known symbols
|
|
9667
|
-
name = name.replace(/@/g, '_at_').replace(/\+/g, '_plus_').replace(/\./g, '_dot_');
|
|
9696
|
+
name = name.replace(/\//g, '_slash_').replace(/@/g, '_at_').replace(/\+/g, '_plus_').replace(/\./g, '_dot_');
|
|
9668
9697
|
name = name.replace(/[^a-zA-Z0-9_-]/g, '_');
|
|
9669
9698
|
// prefix with an underscore if needed
|
|
9670
9699
|
if (/^[0-9]/.test(name)) {
|
|
@@ -9798,45 +9827,57 @@ function concatTypedArray(arrays, ArrayType) {
|
|
|
9798
9827
|
}
|
|
9799
9828
|
LX.concatTypedArray = concatTypedArray;
|
|
9800
9829
|
/**
|
|
9801
|
-
* @method
|
|
9802
|
-
* @description Set
|
|
9830
|
+
* @method setThemeColor
|
|
9831
|
+
* @description Set colored theme
|
|
9832
|
+
* @param {String} colorThemeName Name of the color
|
|
9833
|
+
*/
|
|
9834
|
+
function setThemeColor(colorThemeName) {
|
|
9835
|
+
document.documentElement.className = `theme-${colorThemeName}`;
|
|
9836
|
+
const colorScheme = LX.getMode();
|
|
9837
|
+
document.documentElement.classList.toggle('dark', colorScheme == 'dark');
|
|
9838
|
+
}
|
|
9839
|
+
LX.setThemeColor = setThemeColor;
|
|
9840
|
+
/**
|
|
9841
|
+
* @method setMode
|
|
9842
|
+
* @description Set dark or light scheme mode
|
|
9803
9843
|
* @param {String} colorScheme Name of the scheme
|
|
9804
9844
|
* @param {Boolean} storeLocal Store in localStorage
|
|
9805
9845
|
*/
|
|
9806
|
-
function
|
|
9846
|
+
function setMode(colorScheme, storeLocal = true) {
|
|
9807
9847
|
colorScheme = (colorScheme == 'light') ? 'light' : 'dark';
|
|
9808
|
-
document.documentElement.setAttribute('data-
|
|
9848
|
+
document.documentElement.setAttribute('data-mode', colorScheme);
|
|
9849
|
+
document.documentElement.classList.toggle('dark', colorScheme == 'dark');
|
|
9809
9850
|
if (storeLocal)
|
|
9810
9851
|
localStorage.setItem('lxColorScheme', colorScheme);
|
|
9811
9852
|
LX.emitSignal('@on_new_color_scheme', colorScheme);
|
|
9812
9853
|
}
|
|
9813
|
-
LX.
|
|
9854
|
+
LX.setMode = setMode;
|
|
9814
9855
|
/**
|
|
9815
|
-
* @method
|
|
9856
|
+
* @method getMode
|
|
9816
9857
|
* @description Gets either "dark" or "light" theme value
|
|
9817
9858
|
*/
|
|
9818
|
-
function
|
|
9819
|
-
return document.documentElement.getAttribute('data-
|
|
9859
|
+
function getMode() {
|
|
9860
|
+
return document.documentElement.getAttribute('data-mode') ?? 'dark';
|
|
9820
9861
|
}
|
|
9821
|
-
LX.
|
|
9862
|
+
LX.getMode = getMode;
|
|
9822
9863
|
/**
|
|
9823
|
-
* @method
|
|
9864
|
+
* @method switchMode
|
|
9824
9865
|
* @description Toggles between "dark" and "light" themes
|
|
9825
9866
|
*/
|
|
9826
|
-
function
|
|
9827
|
-
const currentTheme =
|
|
9828
|
-
|
|
9867
|
+
function switchMode() {
|
|
9868
|
+
const currentTheme = getMode();
|
|
9869
|
+
setMode(currentTheme == 'dark' ? 'light' : 'dark');
|
|
9829
9870
|
}
|
|
9830
|
-
LX.
|
|
9871
|
+
LX.switchMode = switchMode;
|
|
9831
9872
|
/**
|
|
9832
|
-
* @method
|
|
9873
|
+
* @method setSystemMode
|
|
9833
9874
|
* @description Sets back the system theme
|
|
9834
9875
|
*/
|
|
9835
|
-
function
|
|
9876
|
+
function setSystemMode() {
|
|
9836
9877
|
const currentTheme = (window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches)
|
|
9837
9878
|
? 'light'
|
|
9838
9879
|
: 'dark';
|
|
9839
|
-
|
|
9880
|
+
setMode(currentTheme);
|
|
9840
9881
|
localStorage.removeItem('lxColorScheme');
|
|
9841
9882
|
// Reapply listener
|
|
9842
9883
|
if (LX._mqlPrefersDarkScheme) {
|
|
@@ -9844,39 +9885,55 @@ function setSystemTheme() {
|
|
|
9844
9885
|
LX._mqlPrefersDarkScheme.addEventListener('change', LX._onChangeSystemTheme);
|
|
9845
9886
|
}
|
|
9846
9887
|
}
|
|
9847
|
-
LX.
|
|
9888
|
+
LX.setSystemMode = setSystemMode;
|
|
9848
9889
|
/**
|
|
9849
|
-
* @method
|
|
9850
|
-
* @description Sets a new value for one of the
|
|
9851
|
-
* @param {String}
|
|
9852
|
-
* @param {String}
|
|
9890
|
+
* @method setCSSVariable
|
|
9891
|
+
* @description Sets a new value for one of the CSS root variables
|
|
9892
|
+
* @param {String} varName Name of the CSS variable
|
|
9893
|
+
* @param {String} value
|
|
9853
9894
|
*/
|
|
9854
|
-
function
|
|
9895
|
+
function setCSSVariable(varName, value) {
|
|
9855
9896
|
const r = document.querySelector(':root');
|
|
9856
|
-
r.style.setProperty('--' +
|
|
9897
|
+
r.style.setProperty('--' + varName, value);
|
|
9857
9898
|
}
|
|
9858
|
-
LX.
|
|
9899
|
+
LX.setCSSVariable = setCSSVariable;
|
|
9859
9900
|
/**
|
|
9860
|
-
* @method
|
|
9861
|
-
* @description Get the value for one of the
|
|
9862
|
-
* @param {String}
|
|
9901
|
+
* @method getCSSVariable
|
|
9902
|
+
* @description Get the value for one of the CSS root variables
|
|
9903
|
+
* @param {String} varName Name of the CSS variable
|
|
9863
9904
|
*/
|
|
9864
|
-
function
|
|
9905
|
+
function getCSSVariable(varName) {
|
|
9906
|
+
const [name, opacity] = varName.split('/');
|
|
9865
9907
|
const r = document.querySelector(':root');
|
|
9866
9908
|
const s = getComputedStyle(r);
|
|
9867
|
-
|
|
9909
|
+
let value = s.getPropertyValue('--' + name);
|
|
9910
|
+
if (!value)
|
|
9911
|
+
return '';
|
|
9868
9912
|
if (value.includes('light-dark')) {
|
|
9869
9913
|
const currentScheme = s.getPropertyValue('color-scheme');
|
|
9870
9914
|
if (currentScheme == 'light') {
|
|
9871
|
-
|
|
9915
|
+
value = value.substring(value.indexOf('(') + 1, value.indexOf(',')).replace(/\s/g, '');
|
|
9872
9916
|
}
|
|
9873
9917
|
else {
|
|
9874
|
-
|
|
9918
|
+
value = value.substring(value.indexOf(',') + 1, value.indexOf(')')).replace(/\s/g, '');
|
|
9919
|
+
}
|
|
9920
|
+
}
|
|
9921
|
+
if (opacity) {
|
|
9922
|
+
if (value.includes('/'))
|
|
9923
|
+
return value;
|
|
9924
|
+
if (value.startsWith('rgb(') || value.startsWith('hsl(') || value.startsWith('oklch(')
|
|
9925
|
+
|| value.startsWith('lab(') || value.startsWith('lch(')) {
|
|
9926
|
+
return value.replace(/\)$/, ` / ${parseFloat(opacity) / 100.0})`);
|
|
9927
|
+
}
|
|
9928
|
+
// Hex fallback
|
|
9929
|
+
if (value.startsWith('#')) {
|
|
9930
|
+
const rgba = LX.hexToRgb(value, opacity);
|
|
9931
|
+
return LX.rgbToHex(rgba);
|
|
9875
9932
|
}
|
|
9876
9933
|
}
|
|
9877
9934
|
return value;
|
|
9878
9935
|
}
|
|
9879
|
-
LX.
|
|
9936
|
+
LX.getCSSVariable = getCSSVariable;
|
|
9880
9937
|
/**
|
|
9881
9938
|
* @method switchSpacing
|
|
9882
9939
|
* @description Toggles between "default" and "compact" spacing layouts
|
|
@@ -9906,8 +9963,9 @@ LX.getBase64Image = getBase64Image;
|
|
|
9906
9963
|
* @method hexToRgb
|
|
9907
9964
|
* @description Convert a hexadecimal string to a valid RGB color
|
|
9908
9965
|
* @param {String} hex Hexadecimal color
|
|
9966
|
+
* @param {Number} hex Opacity alpha value
|
|
9909
9967
|
*/
|
|
9910
|
-
function hexToRgb(hex) {
|
|
9968
|
+
function hexToRgb(hex, alpha) {
|
|
9911
9969
|
const hexPattern = /^#(?:[A-Fa-f0-9]{3,4}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{8})$/;
|
|
9912
9970
|
if (!hexPattern.test(hex)) {
|
|
9913
9971
|
throw (`Invalid Hex Color: ${hex}`);
|
|
@@ -9923,7 +9981,7 @@ function hexToRgb(hex) {
|
|
|
9923
9981
|
const b = ((bigint >> (hex.length === 8 ? 8 : 0)) & 255) / 255;
|
|
9924
9982
|
const a = (hex.length === 8 ? (bigint & 255) : (hex.length === 4 ? parseInt(hex.slice(-2), 16) : 255))
|
|
9925
9983
|
/ 255;
|
|
9926
|
-
return { r, g, b, a };
|
|
9984
|
+
return { r, g, b, a: (alpha ? alpha / 100 : a) };
|
|
9927
9985
|
}
|
|
9928
9986
|
LX.hexToRgb = hexToRgb;
|
|
9929
9987
|
/**
|
|
@@ -9948,12 +10006,48 @@ function rgbToHex(rgb, scale = 255) {
|
|
|
9948
10006
|
rgbArray.push(rgb.a);
|
|
9949
10007
|
return ('#'
|
|
9950
10008
|
+ rgbArray.map((c) => {
|
|
9951
|
-
c = Math.floor(c * scale);
|
|
10009
|
+
c = Math.floor(LX.clamp(c * scale, 0.0, scale));
|
|
9952
10010
|
const hex = c.toString(16);
|
|
9953
10011
|
return hex.length === 1 ? ('0' + hex) : hex;
|
|
9954
10012
|
}).join(''));
|
|
9955
10013
|
}
|
|
9956
10014
|
LX.rgbToHex = rgbToHex;
|
|
10015
|
+
/**
|
|
10016
|
+
* @method oklchToHex
|
|
10017
|
+
* @description Convert a oklch color to a hexadecimal string
|
|
10018
|
+
* @param {String} oklch String containing oklch color
|
|
10019
|
+
*/
|
|
10020
|
+
function oklchToHex(oklch) {
|
|
10021
|
+
const match = oklch.match(/oklch\(\s*([\d.]+)%\s+([\d.]+)\s+([\d.]+)\s*\)/);
|
|
10022
|
+
if (!match) {
|
|
10023
|
+
console.error('Invalid OKLCH format');
|
|
10024
|
+
return '#000';
|
|
10025
|
+
}
|
|
10026
|
+
let [, Lp, C, h] = match;
|
|
10027
|
+
const L = parseFloat(Lp) / 100;
|
|
10028
|
+
const H = (parseFloat(h) * Math.PI) / 180;
|
|
10029
|
+
// OKLCH -> OKLab
|
|
10030
|
+
const a = parseFloat(C) * Math.cos(H);
|
|
10031
|
+
const b = parseFloat(C) * Math.sin(H);
|
|
10032
|
+
// OKLab -> LMS
|
|
10033
|
+
const l_ = L + 0.3963377774 * a + 0.2158037573 * b;
|
|
10034
|
+
const m_ = L - 0.1055613458 * a - 0.0638541728 * b;
|
|
10035
|
+
const s_ = L - 0.0894841775 * a - 1.2914855480 * b;
|
|
10036
|
+
const l = l_ ** 3;
|
|
10037
|
+
const m = m_ ** 3;
|
|
10038
|
+
const s = s_ ** 3;
|
|
10039
|
+
// LMS -> linear RGB
|
|
10040
|
+
let r = 4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s;
|
|
10041
|
+
let g = -1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s;
|
|
10042
|
+
let b2 = -0.0041960863 * l - 0.7034186147 * m + 1.7076147010 * s;
|
|
10043
|
+
// linear RGB -> sRGB
|
|
10044
|
+
const toSRGB = (x) => x <= 0.0031308 ? 12.92 * x : 1.055 * Math.pow(x, 1 / 2.4) - 0.055;
|
|
10045
|
+
r = toSRGB(r);
|
|
10046
|
+
g = toSRGB(g);
|
|
10047
|
+
b2 = toSRGB(b2);
|
|
10048
|
+
return LX.rgbToHex({ r, g, b: b2 });
|
|
10049
|
+
}
|
|
10050
|
+
LX.oklchToHex = oklchToHex;
|
|
9957
10051
|
/**
|
|
9958
10052
|
* @method rgbToCss
|
|
9959
10053
|
* @description Convert a RGB color (0..1) to a CSS color format
|
|
@@ -10193,10 +10287,8 @@ function makeDraggable(domEl, options = {}) {
|
|
|
10193
10287
|
const fixedOffset = isFixed ? new vec2(parentRect.x, parentRect.y) : new vec2();
|
|
10194
10288
|
left = left ?? e.clientX - offsetX - parentRect.x;
|
|
10195
10289
|
top = top ?? e.clientY - offsetY - parentRect.y;
|
|
10196
|
-
domEl.style.left =
|
|
10197
|
-
|
|
10198
|
-
domEl.style.top =
|
|
10199
|
-
LX.clamp(top, dragMargin + fixedOffset.y, fixedOffset.y + parentRect.height - domEl.offsetHeight - dragMargin) + 'px';
|
|
10290
|
+
domEl.style.left = LX.clamp(left, dragMargin + fixedOffset.x, fixedOffset.x + parentRect.width - domEl.offsetWidth - dragMargin) + 'px';
|
|
10291
|
+
domEl.style.top = LX.clamp(top, dragMargin + fixedOffset.y, fixedOffset.y + parentRect.height - domEl.offsetHeight - dragMargin) + 'px';
|
|
10200
10292
|
domEl.style.translate = 'none'; // Force remove translation
|
|
10201
10293
|
};
|
|
10202
10294
|
// Initial adjustment
|
|
@@ -10322,7 +10414,7 @@ function makeCodeSnippet(code, size, options = {}) {
|
|
|
10322
10414
|
return;
|
|
10323
10415
|
}
|
|
10324
10416
|
const snippet = document.createElement('div');
|
|
10325
|
-
snippet.className = 'lexcodesnippet '
|
|
10417
|
+
snippet.className = LX.mergeClass('lexcodesnippet relative rounded-xl overflow-hidden', options.className);
|
|
10326
10418
|
snippet.style.width = size ? size[0] : 'auto';
|
|
10327
10419
|
snippet.style.height = size ? size[1] : 'auto';
|
|
10328
10420
|
const area = new Area({ xskipAppend: true });
|
|
@@ -10331,7 +10423,7 @@ function makeCodeSnippet(code, size, options = {}) {
|
|
|
10331
10423
|
disableEdition: true,
|
|
10332
10424
|
allowAddScripts: false,
|
|
10333
10425
|
name: options.tabName,
|
|
10334
|
-
|
|
10426
|
+
onReady: (instance) => {
|
|
10335
10427
|
instance.setText(code, options.language ?? 'Plain Text');
|
|
10336
10428
|
if (options.linesAdded) {
|
|
10337
10429
|
const code = instance.root.querySelector('.code');
|
|
@@ -10407,9 +10499,10 @@ function makeKbd(keys, useSpecialKeys = true, extraClass = '') {
|
|
|
10407
10499
|
'ArrowRight': '→',
|
|
10408
10500
|
'Space': '␣'
|
|
10409
10501
|
};
|
|
10410
|
-
const kbd = LX.makeContainer(['auto', 'auto'],
|
|
10502
|
+
const kbd = LX.makeContainer(['auto', 'auto'], `text-muted-foreground font-sans text-xs inline-flex
|
|
10503
|
+
ml-auto pointer-events-none select-none items-center justify-center gap-1`);
|
|
10411
10504
|
for (const k of keys) {
|
|
10412
|
-
LX.makeContainer(['auto', 'auto'], '
|
|
10505
|
+
LX.makeContainer(['auto', 'auto'], 'bg-muted px-1 rounded-sm ' + extraClass, useSpecialKeys ? specialKeys[k] ?? k : k, kbd);
|
|
10413
10506
|
}
|
|
10414
10507
|
return kbd;
|
|
10415
10508
|
}
|
|
@@ -10429,38 +10522,38 @@ function makeBreadcrumb(items, options = {}) {
|
|
|
10429
10522
|
const eraseNum = items.length - maxItems;
|
|
10430
10523
|
if (eraseNum > 0) {
|
|
10431
10524
|
const erased = items.splice(1, eraseNum + 1);
|
|
10432
|
-
const ellipsisItem = {
|
|
10525
|
+
const ellipsisItem = { name: '...', ellipsis: erased.map((v) => v.name).join('/') };
|
|
10433
10526
|
items.splice(1, 0, ellipsisItem);
|
|
10434
10527
|
}
|
|
10435
10528
|
for (let i = 0; i < items.length; ++i) {
|
|
10436
10529
|
const item = items[i];
|
|
10437
|
-
console.assert(item.
|
|
10530
|
+
console.assert(item.name, 'Breadcrumb item must have a name!');
|
|
10438
10531
|
if (i != 0) {
|
|
10439
|
-
const icon = LX.makeIcon(separatorIcon, { svgClass: 'sm
|
|
10532
|
+
const icon = LX.makeIcon(separatorIcon, { svgClass: 'sm text-foreground separator' });
|
|
10440
10533
|
breadcrumb.appendChild(icon);
|
|
10441
10534
|
}
|
|
10442
|
-
const lastElement = i == items.length - 1;
|
|
10443
|
-
const breadcrumbItem = LX.makeContainer(['auto', 'auto'], `p-1 flex flex-row gap-1 items-center ${lastElement ? '' : '
|
|
10535
|
+
const lastElement = i == (items.length - 1);
|
|
10536
|
+
const breadcrumbItem = LX.makeContainer(['auto', 'auto'], `p-1 flex flex-row gap-1 items-center ${lastElement ? 'text-foreground' : 'text-muted-foreground'}`);
|
|
10444
10537
|
breadcrumb.appendChild(breadcrumbItem);
|
|
10445
|
-
let
|
|
10538
|
+
let itemName = LX.makeElement('p', '', item.name);
|
|
10446
10539
|
if (item.icon) {
|
|
10447
10540
|
breadcrumbItem.appendChild(LX.makeIcon(item.icon, { svgClass: 'sm' }));
|
|
10448
10541
|
}
|
|
10449
10542
|
if (item.items !== undefined) {
|
|
10450
|
-
const bDropdownTrigger = LX.makeContainer(['auto', 'auto'], `${lastElement ? '' : '
|
|
10543
|
+
const bDropdownTrigger = LX.makeContainer(['auto', 'auto'], `${lastElement ? 'text-foreground' : 'text-muted-foreground'}`);
|
|
10451
10544
|
LX.listen(bDropdownTrigger, 'click', (e) => {
|
|
10452
10545
|
LX.addDropdownMenu(e.target, item.items, { side: 'bottom', align: 'start' });
|
|
10453
10546
|
});
|
|
10454
|
-
bDropdownTrigger.append(
|
|
10547
|
+
bDropdownTrigger.append(itemName);
|
|
10455
10548
|
breadcrumbItem.appendChild(bDropdownTrigger);
|
|
10456
10549
|
}
|
|
10457
10550
|
else if (item.url !== undefined) {
|
|
10458
|
-
let itemUrl = LX.makeElement('a', `decoration-none
|
|
10551
|
+
let itemUrl = LX.makeElement('a', `decoration-none hover:underline underline-offset-4 ${lastElement ? 'text-foreground' : 'text-muted-foreground'}`, '', breadcrumbItem);
|
|
10459
10552
|
itemUrl.href = item.url;
|
|
10460
|
-
itemUrl.appendChild(
|
|
10553
|
+
itemUrl.appendChild(itemName);
|
|
10461
10554
|
}
|
|
10462
10555
|
else {
|
|
10463
|
-
breadcrumbItem.appendChild(
|
|
10556
|
+
breadcrumbItem.appendChild(itemName);
|
|
10464
10557
|
}
|
|
10465
10558
|
if (item.ellipsis) {
|
|
10466
10559
|
LX.asTooltip(breadcrumbItem, item.ellipsis, { side: 'bottom', offset: 4 });
|
|
@@ -10482,13 +10575,15 @@ LX.makeBreadcrumb = makeBreadcrumb;
|
|
|
10482
10575
|
*/
|
|
10483
10576
|
function makeIcon(iconName, options = {}) {
|
|
10484
10577
|
let svg = null;
|
|
10485
|
-
const _createIconFromSVG = (svg)
|
|
10486
|
-
|
|
10487
|
-
|
|
10488
|
-
|
|
10489
|
-
|
|
10578
|
+
const _createIconFromSVG = function (svg) {
|
|
10579
|
+
const cn = options.svgClass;
|
|
10580
|
+
if (cn && cn.length) {
|
|
10581
|
+
const mergedCn = LX.twMerge(...svg.classList, ...cn.split(' '));
|
|
10582
|
+
svg.classList.remove(...svg.classList);
|
|
10583
|
+
mergedCn.split(' ').forEach((c) => svg.classList.add(c));
|
|
10584
|
+
}
|
|
10585
|
+
const icon = LX.makeElement('a', LX.mergeClass('lexicon', options.iconClass));
|
|
10490
10586
|
icon.title = options.title ?? '';
|
|
10491
|
-
icon.className = 'lexicon ' + (options.iconClass ?? '');
|
|
10492
10587
|
icon.appendChild(svg);
|
|
10493
10588
|
svg.dataset['name'] = iconName;
|
|
10494
10589
|
return icon;
|
|
@@ -10513,6 +10608,7 @@ function makeIcon(iconName, options = {}) {
|
|
|
10513
10608
|
// Create internal icon if variant is the same as requested, there's no lucide/fallback data or if variant is "regular" (default)
|
|
10514
10609
|
if ((requestedVariant == variant) || !lucideData || variant == 'regular') {
|
|
10515
10610
|
svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
|
10611
|
+
svg.classList.add('text-inherit');
|
|
10516
10612
|
svg.setAttribute('viewBox', `0 0 ${data[0]} ${data[1]}`);
|
|
10517
10613
|
if (data[5]) {
|
|
10518
10614
|
const classes = data[5].svgClass;
|
|
@@ -10526,6 +10622,7 @@ function makeIcon(iconName, options = {}) {
|
|
|
10526
10622
|
});
|
|
10527
10623
|
}
|
|
10528
10624
|
const path = document.createElement('path');
|
|
10625
|
+
path.classList.add('text-inherit');
|
|
10529
10626
|
path.setAttribute('fill', 'currentColor');
|
|
10530
10627
|
path.setAttribute('d', data[4]);
|
|
10531
10628
|
svg.appendChild(path);
|
|
@@ -10652,7 +10749,6 @@ function popup(text, title, options = {}) {
|
|
|
10652
10749
|
throw ('No message to show');
|
|
10653
10750
|
}
|
|
10654
10751
|
options.size = options.size ?? ['max-content', 'auto'];
|
|
10655
|
-
options.class = 'lexpopup';
|
|
10656
10752
|
const time = options.timeout || 3000;
|
|
10657
10753
|
const dialog = new LX.Dialog(title, (p) => {
|
|
10658
10754
|
p.addTextArea(null, text, null, { disabled: true, fitHeight: true });
|
|
@@ -10726,9 +10822,7 @@ function toast(title, description, options = {}) {
|
|
|
10726
10822
|
}
|
|
10727
10823
|
const nots = LX.notifications;
|
|
10728
10824
|
console.assert(nots);
|
|
10729
|
-
const toast =
|
|
10730
|
-
toast.className = 'lextoast';
|
|
10731
|
-
nots.prepend(toast);
|
|
10825
|
+
const toast = 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);
|
|
10732
10826
|
const [positionVertical, positionHorizontal] = options.position
|
|
10733
10827
|
? options.position.split('-')
|
|
10734
10828
|
: ['bottom', 'right'];
|
|
@@ -10757,6 +10851,7 @@ function toast(title, description, options = {}) {
|
|
|
10757
10851
|
break;
|
|
10758
10852
|
case 'center':
|
|
10759
10853
|
nots.style.placeSelf = 'center';
|
|
10854
|
+
nots.style.justifySelf = 'anchor-center';
|
|
10760
10855
|
break;
|
|
10761
10856
|
case 'right':
|
|
10762
10857
|
nots.style.right = '1rem';
|
|
@@ -10771,18 +10866,10 @@ function toast(title, description, options = {}) {
|
|
|
10771
10866
|
}
|
|
10772
10867
|
toast.dataset['open'] = true;
|
|
10773
10868
|
}, 10);
|
|
10774
|
-
const content =
|
|
10775
|
-
|
|
10776
|
-
toast.appendChild(content);
|
|
10777
|
-
const titleContent = document.createElement('div');
|
|
10778
|
-
titleContent.className = 'title';
|
|
10779
|
-
titleContent.innerHTML = title;
|
|
10780
|
-
content.appendChild(titleContent);
|
|
10869
|
+
const content = LX.makeElement('div', 'grid h-fit max-w-lg gap-1 items-center mr-6 [&_div]:truncate [&_svg]:shrink-0', '', toast);
|
|
10870
|
+
LX.makeElement('div', 'flex flex-row gap-2 text-sm text-foreground items-center min-w-0', title, content);
|
|
10781
10871
|
if (description) {
|
|
10782
|
-
|
|
10783
|
-
desc.className = 'desc';
|
|
10784
|
-
desc.innerHTML = description;
|
|
10785
|
-
content.appendChild(desc);
|
|
10872
|
+
LX.makeElement('div', 'text-secondary-foreground text-xs', description, content);
|
|
10786
10873
|
}
|
|
10787
10874
|
if (options.action) {
|
|
10788
10875
|
const panel = new Panel();
|
|
@@ -10790,7 +10877,7 @@ function toast(title, description, options = {}) {
|
|
|
10790
10877
|
width: 'auto',
|
|
10791
10878
|
maxWidth: '150px',
|
|
10792
10879
|
className: 'right',
|
|
10793
|
-
buttonClass: '
|
|
10880
|
+
buttonClass: 'outline sm'
|
|
10794
10881
|
});
|
|
10795
10882
|
toast.appendChild(panel.root.childNodes[0]);
|
|
10796
10883
|
}
|
|
@@ -10805,7 +10892,7 @@ function toast(title, description, options = {}) {
|
|
|
10805
10892
|
}, 500);
|
|
10806
10893
|
};
|
|
10807
10894
|
if (options.closable ?? true) {
|
|
10808
|
-
const closeIcon = LX.makeIcon('X', { iconClass: '
|
|
10895
|
+
const closeIcon = LX.makeIcon('X', { iconClass: 'absolute top-2 right-2 text-sm' });
|
|
10809
10896
|
closeIcon.addEventListener('click', () => {
|
|
10810
10897
|
toast.close();
|
|
10811
10898
|
});
|
|
@@ -10830,13 +10917,12 @@ LX.toast = toast;
|
|
|
10830
10917
|
function badge(text, className, options = {}) {
|
|
10831
10918
|
const container = document.createElement('div');
|
|
10832
10919
|
container.innerHTML = text;
|
|
10833
|
-
|
|
10834
|
-
|
|
10835
|
-
|
|
10836
|
-
}
|
|
10920
|
+
const cn = ['lexbadge', 'inline-flex', 'items-center', 'justify-center', 'rounded-full', 'border', 'px-2', 'py-0.5', 'text-xs', 'font-medium',
|
|
10921
|
+
'w-fit', 'whitespace-nowrap', 'shrink-0', 'overflow-hidden', 'border-transparent', 'gap-1', 'min-w-5', 'bg-card text-foreground'];
|
|
10922
|
+
container.className = className ? LX.twMerge(...cn, ...className.split(' ')) : cn.join(' ');
|
|
10837
10923
|
Object.assign(container.style, options.style ?? {});
|
|
10838
10924
|
if (options.callback) {
|
|
10839
|
-
const arrowIcon = LX.makeIcon('ArrowUpRight', { svgClass: 'xs
|
|
10925
|
+
const arrowIcon = LX.makeIcon('ArrowUpRight', { svgClass: 'xs' });
|
|
10840
10926
|
arrowIcon.querySelector('svg').style.marginLeft = '-0.25rem';
|
|
10841
10927
|
container.innerHTML += arrowIcon.innerHTML;
|
|
10842
10928
|
container.addEventListener('click', (e) => {
|
|
@@ -10915,9 +11001,7 @@ function asTooltip(trigger, content, options = {}) {
|
|
|
10915
11001
|
if (trigger.dataset['disableTooltip'] == 'true') {
|
|
10916
11002
|
return;
|
|
10917
11003
|
}
|
|
10918
|
-
tooltipDom =
|
|
10919
|
-
tooltipDom.className = 'lextooltip';
|
|
10920
|
-
tooltipDom.innerHTML = trigger.dataset['tooltipContent'] ?? content;
|
|
11004
|
+
tooltipDom = 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);
|
|
10921
11005
|
const nestedDialog = trigger.closest('dialog');
|
|
10922
11006
|
const tooltipParent = nestedDialog ?? LX.root;
|
|
10923
11007
|
// Remove other first
|
|
@@ -11018,13 +11102,17 @@ function hasClass(el, list) {
|
|
|
11018
11102
|
}
|
|
11019
11103
|
LX.hasClass = hasClass;
|
|
11020
11104
|
function addClass(el, className) {
|
|
11021
|
-
if (className)
|
|
11022
|
-
|
|
11105
|
+
if (!className)
|
|
11106
|
+
return;
|
|
11107
|
+
const cn = className.split(' ');
|
|
11108
|
+
el.classList.add(...cn);
|
|
11023
11109
|
}
|
|
11024
11110
|
LX.addClass = addClass;
|
|
11025
11111
|
function removeClass(el, className) {
|
|
11026
|
-
if (className)
|
|
11027
|
-
|
|
11112
|
+
if (!className)
|
|
11113
|
+
return;
|
|
11114
|
+
const cn = className.split(' ');
|
|
11115
|
+
el.classList.remove(...cn);
|
|
11028
11116
|
}
|
|
11029
11117
|
LX.removeClass = removeClass;
|
|
11030
11118
|
function toggleClass(el, className, force) {
|
|
@@ -11032,6 +11120,12 @@ function toggleClass(el, className, force) {
|
|
|
11032
11120
|
el.classList.toggle(className, force);
|
|
11033
11121
|
}
|
|
11034
11122
|
LX.toggleClass = toggleClass;
|
|
11123
|
+
function mergeClass(className, classNameOverride) {
|
|
11124
|
+
if (classNameOverride)
|
|
11125
|
+
className = [className, classNameOverride].join(' ');
|
|
11126
|
+
return LX.twMerge(...className.split(' '));
|
|
11127
|
+
}
|
|
11128
|
+
LX.mergeClass = mergeClass;
|
|
11035
11129
|
function lastChar(str) {
|
|
11036
11130
|
return str[str.length - 1];
|
|
11037
11131
|
}
|
|
@@ -11350,6 +11444,32 @@ function drawSpline(ctx, pts, t) {
|
|
|
11350
11444
|
}
|
|
11351
11445
|
LX.drawSpline = drawSpline;
|
|
11352
11446
|
|
|
11447
|
+
// Avatar.ts @jxarco
|
|
11448
|
+
class Avatar {
|
|
11449
|
+
root;
|
|
11450
|
+
imageElement = undefined;
|
|
11451
|
+
fallbackElement = undefined;
|
|
11452
|
+
constructor(desc) {
|
|
11453
|
+
let rootCn = 'lexavatar bg-card items-center flex flex-row relative size-8 shrink-0 overflow-hidden rounded-full';
|
|
11454
|
+
this.root = LX.makeElement('div');
|
|
11455
|
+
if (desc.imgSource) {
|
|
11456
|
+
const cn = 'aspect-square size-full object-cover';
|
|
11457
|
+
const img = LX.makeElement('img', desc.imgClass ? LX.twMerge(...cn.split(' '), ...desc.imgClass.split(' ')) : cn, '', this.root);
|
|
11458
|
+
img.src = desc.imgSource;
|
|
11459
|
+
img.alt = desc.imgAlt;
|
|
11460
|
+
this.imageElement = img;
|
|
11461
|
+
}
|
|
11462
|
+
else if (desc.fallback) {
|
|
11463
|
+
const cn = 'size-full text-sm font-semibold place-self-center text-center content-center';
|
|
11464
|
+
const span = LX.makeElement('span', desc.fallbackClass ? LX.twMerge(...cn.split(' '), ...desc.fallbackClass.split(' ')) : cn, desc.fallback, this.root);
|
|
11465
|
+
this.fallbackElement = span;
|
|
11466
|
+
rootCn += ' border-color';
|
|
11467
|
+
}
|
|
11468
|
+
this.root.className = desc.className ? LX.twMerge(...rootCn.split(' '), ...desc.className.split(' ')) : rootCn;
|
|
11469
|
+
}
|
|
11470
|
+
}
|
|
11471
|
+
LX.Avatar = Avatar;
|
|
11472
|
+
|
|
11353
11473
|
// Spinner.ts @jxarco
|
|
11354
11474
|
/**
|
|
11355
11475
|
* @class Spinner
|
|
@@ -11359,8 +11479,8 @@ class Spinner {
|
|
|
11359
11479
|
constructor(options = {}) {
|
|
11360
11480
|
const icon = options.icon ?? 'LoaderCircle';
|
|
11361
11481
|
const size = options.size ?? 'md';
|
|
11362
|
-
const iconClass =
|
|
11363
|
-
const svgClass = `animate-spin ${size}
|
|
11482
|
+
const iconClass = LX.mergeClass('flex', options.iconClass);
|
|
11483
|
+
const svgClass = LX.mergeClass(`animate-spin ${size}`, options.svgClass);
|
|
11364
11484
|
this.root = LX.makeIcon(icon, { iconClass, svgClass });
|
|
11365
11485
|
}
|
|
11366
11486
|
html() {
|
|
@@ -11394,7 +11514,7 @@ class Dialog {
|
|
|
11394
11514
|
this.id = LX.guidGenerator();
|
|
11395
11515
|
const size = options.size ?? [], position = options.position ?? [], draggable = options.draggable ?? true, dockable = options.dockable ?? false, modal = options.modal ?? false;
|
|
11396
11516
|
let root = document.createElement('dialog');
|
|
11397
|
-
root.className = 'lexdialog '
|
|
11517
|
+
root.className = 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);
|
|
11398
11518
|
root.id = options.id ?? 'dialog' + Dialog._last_id++;
|
|
11399
11519
|
root.dataset['modal'] = modal;
|
|
11400
11520
|
LX.root.appendChild(root);
|
|
@@ -11404,7 +11524,8 @@ class Dialog {
|
|
|
11404
11524
|
let that = this;
|
|
11405
11525
|
const titleDiv = document.createElement('div');
|
|
11406
11526
|
if (title) {
|
|
11407
|
-
titleDiv.className =
|
|
11527
|
+
titleDiv.className =
|
|
11528
|
+
'lexdialogtitle flex w-full outline-none items-center justify-between font-semibold text-xl text-secondary-foreground pad-xl select-none';
|
|
11408
11529
|
titleDiv.innerHTML = title;
|
|
11409
11530
|
titleDiv.setAttribute('draggable', 'false');
|
|
11410
11531
|
root.appendChild(titleDiv);
|
|
@@ -11425,7 +11546,8 @@ class Dialog {
|
|
|
11425
11546
|
options.onclose(this.root);
|
|
11426
11547
|
}
|
|
11427
11548
|
};
|
|
11428
|
-
const closeButton = LX.makeIcon('X', { title: 'Close',
|
|
11549
|
+
const closeButton = LX.makeIcon('X', { title: 'Close',
|
|
11550
|
+
iconClass: 'lexdialogcloser text-lg text-secondary-foreground cursor-pointer z-1 select-none' });
|
|
11429
11551
|
closeButton.addEventListener('click', this.close);
|
|
11430
11552
|
const dockButton = LX.makeIcon('Minus', { title: 'Dock', iconClass: 'ml-auto mr-2' });
|
|
11431
11553
|
dockButton.addEventListener('click', () => {
|
|
@@ -11452,8 +11574,7 @@ class Dialog {
|
|
|
11452
11574
|
root.appendChild(closeButton);
|
|
11453
11575
|
}
|
|
11454
11576
|
}
|
|
11455
|
-
const panel = new LX.Panel();
|
|
11456
|
-
panel.root.classList.add('lexdialogcontent');
|
|
11577
|
+
const panel = new LX.Panel({ className: 'lexdialogcontent w-full p-1 text-secondary-foreground text-sm ml-0 break-all' });
|
|
11457
11578
|
if (!title) {
|
|
11458
11579
|
panel.root.classList.add('notitle');
|
|
11459
11580
|
}
|
|
@@ -11517,19 +11638,18 @@ class AlertDialog extends Dialog {
|
|
|
11517
11638
|
options.draggable = false;
|
|
11518
11639
|
options.modal = true;
|
|
11519
11640
|
super(undefined, (p) => {
|
|
11520
|
-
p.root.
|
|
11521
|
-
LX.makeContainer(['100%', '100%'], 'text-
|
|
11522
|
-
p.addTextArea(null, message, null, { disabled: true, fitHeight: true,
|
|
11523
|
-
inputClass: 'bg-none fg-tertiary' });
|
|
11641
|
+
p.root.className = LX.mergeClass(p.root.className, 'pad-2xl flex flex-col gap-2');
|
|
11642
|
+
LX.makeContainer(['100%', '100%'], 'text-lg font-medium text-foreground', title, p);
|
|
11643
|
+
p.addTextArea(null, message, null, { disabled: true, fitHeight: true, inputClass: 'bg-none text-sm text-muted-foreground' });
|
|
11524
11644
|
p.sameLine(2, 'justify-end');
|
|
11525
11645
|
p.addButton(null, options.cancelText ?? 'Cancel', () => this.destroy(), {
|
|
11526
|
-
buttonClass: '
|
|
11646
|
+
buttonClass: 'outline'
|
|
11527
11647
|
});
|
|
11528
11648
|
p.addButton(null, options.continueText ?? 'Continue', () => {
|
|
11529
11649
|
this.destroy();
|
|
11530
11650
|
if (callback)
|
|
11531
11651
|
callback();
|
|
11532
|
-
}, { buttonClass: '
|
|
11652
|
+
}, { buttonClass: 'primary' });
|
|
11533
11653
|
}, options);
|
|
11534
11654
|
}
|
|
11535
11655
|
}
|
|
@@ -11911,8 +12031,9 @@ class DropdownMenu {
|
|
|
11911
12031
|
return;
|
|
11912
12032
|
}
|
|
11913
12033
|
const menuItem = document.createElement('div');
|
|
11914
|
-
menuItem.className = 'lexdropdownmenuitem
|
|
11915
|
-
+ (item.
|
|
12034
|
+
menuItem.className = LX.mergeClass('lexdropdownmenuitem flex flex-row pad-md rounded-lg gap-2 truncate cursor-pointer select-none'
|
|
12035
|
+
+ ((item.name || item.options) ? '' : ' label')
|
|
12036
|
+
+ (item.disabled ?? false ? ' disabled' : ''), item.className);
|
|
11916
12037
|
menuItem.dataset['id'] = pKey;
|
|
11917
12038
|
menuItem.innerHTML = `<span class="ellipsis-overflow">${key}</span>`;
|
|
11918
12039
|
menuItem.tabIndex = '1';
|
|
@@ -11943,14 +12064,14 @@ class DropdownMenu {
|
|
|
11943
12064
|
const disabled = item.disabled ?? false;
|
|
11944
12065
|
if (this._radioGroup !== undefined) {
|
|
11945
12066
|
if (item.name === this._radioGroup.selected) {
|
|
11946
|
-
const icon = LX.makeIcon('Circle', { svgClass: '
|
|
12067
|
+
const icon = LX.makeIcon('Circle', { svgClass: '2xs fill-current' });
|
|
11947
12068
|
menuItem.prepend(icon);
|
|
11948
12069
|
}
|
|
11949
12070
|
menuItem.setAttribute('data-radioname', this._radioGroup.name);
|
|
11950
12071
|
}
|
|
11951
12072
|
else if (item.icon) {
|
|
11952
12073
|
const icon = item.icon.constructor === String
|
|
11953
|
-
? LX.makeIcon(item.icon, { svgClass: disabled ? '
|
|
12074
|
+
? LX.makeIcon(item.icon, { svgClass: disabled ? 'text-muted-foreground' : item.svgClass ?? item.className })
|
|
11954
12075
|
: item.icon;
|
|
11955
12076
|
menuItem.prepend(icon);
|
|
11956
12077
|
}
|
|
@@ -11967,7 +12088,7 @@ class DropdownMenu {
|
|
|
11967
12088
|
if (f) {
|
|
11968
12089
|
f.call(this, key, v, menuItem);
|
|
11969
12090
|
}
|
|
11970
|
-
}, { className: '
|
|
12091
|
+
}, { className: 'primary' });
|
|
11971
12092
|
const input = checkbox.root.querySelector('input');
|
|
11972
12093
|
input.classList.add('ml-auto');
|
|
11973
12094
|
menuItem.appendChild(input);
|
|
@@ -12130,16 +12251,14 @@ class Footer {
|
|
|
12130
12251
|
root;
|
|
12131
12252
|
constructor(options = {}) {
|
|
12132
12253
|
const root = document.createElement('footer');
|
|
12133
|
-
root.className = 'lexfooter
|
|
12254
|
+
root.className = LX.mergeClass('lexfooter bg-background p-2 w-full leading-6 [&_p]:text-xs', options.className);
|
|
12134
12255
|
const wrapper = document.createElement('div');
|
|
12135
12256
|
wrapper.style.minHeight = '48px';
|
|
12136
12257
|
wrapper.className = 'w-full';
|
|
12137
12258
|
root.appendChild(wrapper);
|
|
12138
|
-
// const hr = document.createElement( "hr" );
|
|
12139
|
-
// wrapper.appendChild( hr );
|
|
12140
12259
|
if (options.columns && options.columns.constructor == Array) {
|
|
12141
12260
|
const cols = document.createElement('div');
|
|
12142
|
-
cols.className = '
|
|
12261
|
+
cols.className = 'grid text-center';
|
|
12143
12262
|
cols.style.gridTemplateColumns = '1fr '.repeat(options.columns.length);
|
|
12144
12263
|
wrapper.appendChild(cols);
|
|
12145
12264
|
for (let col of options.columns) {
|
|
@@ -12304,7 +12423,7 @@ class Sheet {
|
|
|
12304
12423
|
this.root.dataset['side'] = this.side;
|
|
12305
12424
|
this.root.tabIndex = '1';
|
|
12306
12425
|
this.root.role = 'dialog';
|
|
12307
|
-
this.root.className = 'lexsheet fixed z-1000 bg-primary';
|
|
12426
|
+
this.root.className = 'lexsheet fixed z-1000 bg-primary overflow-hidden';
|
|
12308
12427
|
document.body.appendChild(this.root);
|
|
12309
12428
|
this.root.addEventListener('keydown', (e) => {
|
|
12310
12429
|
if (e.key == 'Escape') {
|
|
@@ -12431,13 +12550,13 @@ class Sidebar {
|
|
|
12431
12550
|
constructor(options = {}) {
|
|
12432
12551
|
const mobile = navigator && /Android|iPhone/i.test(navigator.userAgent);
|
|
12433
12552
|
this.root = document.createElement('div');
|
|
12434
|
-
this.root.className = 'lexsidebar flex flex-col '
|
|
12553
|
+
this.root.className = LX.mergeClass('lexsidebar flex flex-col pad-xl size-full scrollbar-hidden', options.className);
|
|
12435
12554
|
this.callback = options.callback ?? null;
|
|
12436
|
-
this._displaySelected = options.displaySelected ?? false;
|
|
12437
12555
|
this.side = options.side ?? 'left';
|
|
12438
12556
|
this.collapsable = options.collapsable ?? true;
|
|
12439
|
-
this._collapseWidth = (options.collapseToIcons ?? true) ? '58px' : '0px';
|
|
12440
12557
|
this.collapsed = options.collapsed ?? mobile;
|
|
12558
|
+
this._displaySelected = options.displaySelected ?? false;
|
|
12559
|
+
this._collapseWidth = (options.collapseToIcons ?? true) ? '58px' : '0px';
|
|
12441
12560
|
this.filterString = '';
|
|
12442
12561
|
LX.doAsync(() => {
|
|
12443
12562
|
this.root.parentElement.ogWidth = this.root.parentElement.style.width;
|
|
@@ -12464,11 +12583,10 @@ class Sidebar {
|
|
|
12464
12583
|
if (!(options.skipHeader ?? false)) {
|
|
12465
12584
|
this.header = options.header ?? this._generateDefaultHeader(options);
|
|
12466
12585
|
console.assert(this.header.constructor === HTMLDivElement, 'Use an HTMLDivElement to build your custom header');
|
|
12467
|
-
this.header.className = 'lexsidebarheader flex-
|
|
12586
|
+
this.header.className = 'lexsidebarheader w-full h-[48px] flex rounded-lg p-2 mb-2 text-sm cursor-pointer items-center select-none';
|
|
12468
12587
|
this.root.appendChild(this.header);
|
|
12469
12588
|
if (this.collapsable) {
|
|
12470
|
-
const icon = LX.makeIcon(this.side == 'left' ? 'PanelLeft' : 'PanelRight', { title: 'Toggle Sidebar',
|
|
12471
|
-
iconClass: 'toggler' });
|
|
12589
|
+
const icon = LX.makeIcon(this.side == 'left' ? 'PanelLeft' : 'PanelRight', { title: 'Toggle Sidebar', iconClass: 'toggler' });
|
|
12472
12590
|
this.header.appendChild(icon);
|
|
12473
12591
|
if (mobile) {
|
|
12474
12592
|
// create an area and append a sidebar:
|
|
@@ -12504,14 +12622,14 @@ class Sidebar {
|
|
|
12504
12622
|
// Content
|
|
12505
12623
|
{
|
|
12506
12624
|
this.content = document.createElement('div');
|
|
12507
|
-
this.content.className = 'lexsidebarcontent flex-auto-fill';
|
|
12625
|
+
this.content.className = 'lexsidebarcontent overflow-mask flex flex-col overflow-x-hidden overflow-y-scroll flex-auto-fill w-full';
|
|
12508
12626
|
this.root.appendChild(this.content);
|
|
12509
12627
|
}
|
|
12510
12628
|
// Footer
|
|
12511
12629
|
if (!(options.skipFooter ?? false)) {
|
|
12512
12630
|
this.footer = options.footer ?? this._generateDefaultFooter(options);
|
|
12513
12631
|
console.assert(this.footer.constructor === HTMLDivElement, 'Use an HTMLDivElement to build your custom footer');
|
|
12514
|
-
this.footer.className = 'lexsidebarfooter flex-
|
|
12632
|
+
this.footer.className = 'lexsidebarfooter w-full h-[48px] flex rounded-lg p-2 mt-2 text-sm cursor-pointer items-center select-none';
|
|
12515
12633
|
this.root.appendChild(this.footer);
|
|
12516
12634
|
}
|
|
12517
12635
|
}
|
|
@@ -12527,27 +12645,21 @@ class Sidebar {
|
|
|
12527
12645
|
options.onHeaderPressed(e);
|
|
12528
12646
|
}
|
|
12529
12647
|
});
|
|
12530
|
-
const avatar =
|
|
12531
|
-
|
|
12532
|
-
|
|
12533
|
-
|
|
12534
|
-
|
|
12535
|
-
|
|
12536
|
-
avatar.appendChild(avatarImg);
|
|
12537
|
-
}
|
|
12538
|
-
else if (options.headerIcon) {
|
|
12539
|
-
const avatarIcon = LX.makeIcon(options.headerIcon);
|
|
12540
|
-
avatar.appendChild(avatarIcon);
|
|
12541
|
-
}
|
|
12648
|
+
const avatar = new LX.Avatar({
|
|
12649
|
+
imgSource: options.headerImage,
|
|
12650
|
+
fallback: options.headerIcon ? LX.makeIcon(options.headerIcon, { svgClass: 'xl' }).innerHTML : undefined,
|
|
12651
|
+
className: 'rounded-lg'
|
|
12652
|
+
});
|
|
12653
|
+
header.appendChild(avatar.root);
|
|
12542
12654
|
// Info
|
|
12543
12655
|
{
|
|
12544
12656
|
const info = document.createElement('div');
|
|
12545
12657
|
info.className = 'infodefault';
|
|
12546
12658
|
header.appendChild(info);
|
|
12547
|
-
const infoText =
|
|
12659
|
+
const infoText = LX.makeElement('span', 'truncate text-sm font-semibold');
|
|
12548
12660
|
infoText.innerHTML = options.headerTitle ?? '';
|
|
12549
12661
|
info.appendChild(infoText);
|
|
12550
|
-
const infoSubtext =
|
|
12662
|
+
const infoSubtext = LX.makeElement('span', 'truncate text-xs');
|
|
12551
12663
|
infoSubtext.innerHTML = options.headerSubtitle ?? '';
|
|
12552
12664
|
info.appendChild(infoSubtext);
|
|
12553
12665
|
}
|
|
@@ -12565,27 +12677,21 @@ class Sidebar {
|
|
|
12565
12677
|
options.onFooterPressed(e, footer);
|
|
12566
12678
|
}
|
|
12567
12679
|
});
|
|
12568
|
-
const avatar =
|
|
12569
|
-
|
|
12570
|
-
|
|
12571
|
-
|
|
12572
|
-
|
|
12573
|
-
|
|
12574
|
-
avatar.appendChild(avatarImg);
|
|
12575
|
-
}
|
|
12576
|
-
else if (options.footerIcon) {
|
|
12577
|
-
const avatarIcon = LX.makeIcon(options.footerIcon);
|
|
12578
|
-
avatar.appendChild(avatarIcon);
|
|
12579
|
-
}
|
|
12680
|
+
const avatar = new LX.Avatar({
|
|
12681
|
+
imgSource: options.footerImage,
|
|
12682
|
+
fallback: options.footerIcon ? LX.makeIcon(options.footerIcon, { svgClass: 'xl' }).innerHTML : undefined,
|
|
12683
|
+
className: 'rounded-lg'
|
|
12684
|
+
});
|
|
12685
|
+
footer.appendChild(avatar.root);
|
|
12580
12686
|
// Info
|
|
12581
12687
|
{
|
|
12582
12688
|
const info = document.createElement('div');
|
|
12583
12689
|
info.className = 'infodefault';
|
|
12584
12690
|
footer.appendChild(info);
|
|
12585
|
-
const infoText =
|
|
12691
|
+
const infoText = LX.makeElement('span', 'truncate text-sm font-semibold');
|
|
12586
12692
|
infoText.innerHTML = options.footerTitle ?? '';
|
|
12587
12693
|
info.appendChild(infoText);
|
|
12588
|
-
const infoSubtext =
|
|
12694
|
+
const infoSubtext = LX.makeElement('span', 'truncate text-xs');
|
|
12589
12695
|
infoSubtext.innerHTML = options.footerSubtitle ?? '';
|
|
12590
12696
|
info.appendChild(infoSubtext);
|
|
12591
12697
|
}
|
|
@@ -12720,9 +12826,8 @@ class Sidebar {
|
|
|
12720
12826
|
}
|
|
12721
12827
|
let pKey = LX.getSupportedDOMName(key);
|
|
12722
12828
|
let currentGroup = null;
|
|
12723
|
-
let entry =
|
|
12829
|
+
let entry = LX.makeElement('div', LX.mergeClass('lexsidebarentry w-full rounded-lg cursor-pointer select-none', options.className));
|
|
12724
12830
|
entry.id = pKey;
|
|
12725
|
-
entry.className = 'lexsidebarentry ' + (options.className ?? '');
|
|
12726
12831
|
if (this.displaySelected && options.selected) {
|
|
12727
12832
|
entry.classList.add('selected');
|
|
12728
12833
|
}
|
|
@@ -12730,16 +12835,13 @@ class Sidebar {
|
|
|
12730
12835
|
const pGroupKey = item.group.replace(/\s/g, '').replaceAll('.', '');
|
|
12731
12836
|
currentGroup = this.content.querySelector('#' + pGroupKey);
|
|
12732
12837
|
if (!currentGroup) {
|
|
12733
|
-
currentGroup =
|
|
12838
|
+
currentGroup = LX.makeElement('div', 'lexsidebargroup flex flex-col gap-0.5');
|
|
12734
12839
|
currentGroup.id = pGroupKey;
|
|
12735
|
-
currentGroup.className = 'lexsidebargroup';
|
|
12736
12840
|
this.content.appendChild(currentGroup);
|
|
12737
|
-
let groupEntry =
|
|
12738
|
-
groupEntry.className = 'lexsidebargrouptitle';
|
|
12841
|
+
let groupEntry = LX.makeElement('div', 'lexsidebargrouptitle');
|
|
12739
12842
|
currentGroup.appendChild(groupEntry);
|
|
12740
|
-
|
|
12741
|
-
|
|
12742
|
-
groupEntry.appendChild(groupLabel);
|
|
12843
|
+
// Group label
|
|
12844
|
+
LX.makeElement('div', '', item.group, groupEntry);
|
|
12743
12845
|
if (this.groups[item.group] != null) {
|
|
12744
12846
|
const groupActionIcon = LX.makeIcon(this.groups[item.group].icon, { svgClass: 'sm' });
|
|
12745
12847
|
groupEntry.appendChild(groupActionIcon);
|
|
@@ -12787,7 +12889,7 @@ class Sidebar {
|
|
|
12787
12889
|
item.value = value;
|
|
12788
12890
|
if (f)
|
|
12789
12891
|
f.call(this, key, value, event);
|
|
12790
|
-
}, { className: '
|
|
12892
|
+
}, { className: 'primary', label: key, signal: ('@checkbox_' + key) });
|
|
12791
12893
|
itemDom.appendChild(panel.root.childNodes[0]);
|
|
12792
12894
|
}
|
|
12793
12895
|
else {
|
|
@@ -12864,8 +12966,7 @@ class Sidebar {
|
|
|
12864
12966
|
if (!item[key].length) {
|
|
12865
12967
|
continue;
|
|
12866
12968
|
}
|
|
12867
|
-
let subentryContainer =
|
|
12868
|
-
subentryContainer.className = 'lexsidebarsubentrycontainer';
|
|
12969
|
+
let subentryContainer = LX.makeElement('div', 'lexsidebarsubentrycontainer flex flex-col self-center w-full ml-4 px-4 select-none');
|
|
12869
12970
|
if (isCollapsable) {
|
|
12870
12971
|
this.collapseContainer.appendChild(subentryContainer);
|
|
12871
12972
|
delete this.collapseContainer;
|
|
@@ -12899,7 +13000,7 @@ class Sidebar {
|
|
|
12899
13000
|
f.call(this, subkey, e);
|
|
12900
13001
|
});
|
|
12901
13002
|
}
|
|
12902
|
-
subentry.className = 'lexsidebarentry';
|
|
13003
|
+
subentry.className = 'lexsidebarentry w-full rounded-lg cursor-pointer select-none';
|
|
12903
13004
|
subentry.id = subkey;
|
|
12904
13005
|
if (suboptions.content) {
|
|
12905
13006
|
const parentContainer = LX.makeElement('div');
|
|
@@ -13035,7 +13136,7 @@ class Tour {
|
|
|
13035
13136
|
// using a fullscreen SVG with "rect" elements
|
|
13036
13137
|
_generateMask(reference) {
|
|
13037
13138
|
this.tourContainer.innerHTML = ''; // Clear previous content
|
|
13038
|
-
this.tourMask = LX.makeContainer(['100%', '100%'], 'tour-mask');
|
|
13139
|
+
this.tourMask = LX.makeContainer(['100%', '100%'], 'tour-mask absolute inset-0');
|
|
13039
13140
|
this.tourContainer.appendChild(this.tourMask);
|
|
13040
13141
|
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
|
13041
13142
|
svg.style.width = '100%';
|
|
@@ -13096,7 +13197,7 @@ class Tour {
|
|
|
13096
13197
|
clipPath.appendChild(rect);
|
|
13097
13198
|
}
|
|
13098
13199
|
// Reference Highlight
|
|
13099
|
-
const refContainer = LX.makeContainer(['0', '0'], 'tour-ref-mask');
|
|
13200
|
+
const refContainer = LX.makeContainer(['0', '0'], 'tour-ref-mask absolute');
|
|
13100
13201
|
refContainer.style.left = `${boundingX - hOffset - 1}px`;
|
|
13101
13202
|
refContainer.style.top = `${boundingY - vOffset - 1}px`;
|
|
13102
13203
|
refContainer.style.width = `${boundingWidth + hOffset * 2 + 2}px`;
|
|
@@ -13127,7 +13228,7 @@ class Tour {
|
|
|
13127
13228
|
const popoverContainer = LX.makeContainer(['auto', 'auto'], 'tour-step-container');
|
|
13128
13229
|
{
|
|
13129
13230
|
const header = LX.makeContainer(['100%', 'auto'], 'flex flex-row', '', popoverContainer);
|
|
13130
|
-
LX.makeContainer(['70%', 'auto'], 'p-2 font-medium', step.title, header);
|
|
13231
|
+
LX.makeContainer(['70%', 'auto'], 'p-2 font-medium text-base', step.title, header);
|
|
13131
13232
|
const closer = LX.makeContainer(['30%', 'auto'], 'flex flex-row p-2 justify-end', '', header);
|
|
13132
13233
|
const closeIcon = LX.makeIcon('X');
|
|
13133
13234
|
closer.appendChild(closeIcon);
|
|
@@ -13135,22 +13236,22 @@ class Tour {
|
|
|
13135
13236
|
this.stop();
|
|
13136
13237
|
});
|
|
13137
13238
|
}
|
|
13138
|
-
LX.makeContainer(['100%', 'auto'], 'p-2 text-
|
|
13239
|
+
LX.makeContainer(['100%', 'auto'], 'p-2 text-sm', step.content, popoverContainer, {
|
|
13139
13240
|
maxWidth: '400px'
|
|
13140
13241
|
});
|
|
13141
|
-
const footer = LX.makeContainer(['100%', 'auto'], 'flex flex-row
|
|
13242
|
+
const footer = LX.makeContainer(['100%', 'auto'], 'flex flex-row', '', popoverContainer);
|
|
13142
13243
|
{
|
|
13143
|
-
const footerSteps = LX.makeContainer(['50%', 'auto'], 'p-2 gap-1 self-center flex flex-row
|
|
13244
|
+
const footerSteps = LX.makeContainer(['50%', 'auto'], 'p-2 gap-1 place-self-center flex flex-row', '', footer);
|
|
13144
13245
|
for (let i = 0; i < this.steps.length; i++) {
|
|
13145
|
-
const stepIndicator =
|
|
13146
|
-
stepIndicator.className = '
|
|
13246
|
+
const stepIndicator = LX.makeElement('span');
|
|
13247
|
+
stepIndicator.className = 'size-3 rounded-full bg-accent inline-flex data-active:bg-primary';
|
|
13147
13248
|
if (i === this.currentStep) {
|
|
13148
|
-
stepIndicator.
|
|
13249
|
+
stepIndicator.dataset['active'] = 'true';
|
|
13149
13250
|
}
|
|
13150
13251
|
footerSteps.appendChild(stepIndicator);
|
|
13151
13252
|
}
|
|
13152
13253
|
}
|
|
13153
|
-
const footerButtons = LX.makeContainer(['50%', 'auto'], 'text-
|
|
13254
|
+
const footerButtons = LX.makeContainer(['50%', 'auto'], 'text-base', '', footer);
|
|
13154
13255
|
const footerPanel = new Panel();
|
|
13155
13256
|
let numButtons = 1;
|
|
13156
13257
|
if (previousStep) {
|
|
@@ -13162,7 +13263,7 @@ class Tour {
|
|
|
13162
13263
|
if (previousStep) {
|
|
13163
13264
|
footerPanel.addButton(null, 'Previous', () => {
|
|
13164
13265
|
this._showStep(-1);
|
|
13165
|
-
}, { buttonClass: '
|
|
13266
|
+
}, { buttonClass: 'ghost' });
|
|
13166
13267
|
}
|
|
13167
13268
|
if (nextStep) {
|
|
13168
13269
|
footerPanel.addButton(null, 'Next', () => {
|
|
@@ -13172,11 +13273,10 @@ class Tour {
|
|
|
13172
13273
|
else {
|
|
13173
13274
|
footerPanel.addButton(null, 'Finish', () => {
|
|
13174
13275
|
this.stop();
|
|
13175
|
-
});
|
|
13276
|
+
}, { buttonClass: 'primary' });
|
|
13176
13277
|
}
|
|
13177
13278
|
footerButtons.appendChild(footerPanel.root);
|
|
13178
|
-
const sideOffset = (step.side === 'left' || step.side === 'right' ? this.horizontalOffset : this.verticalOffset)
|
|
13179
|
-
?? this.offset;
|
|
13279
|
+
const sideOffset = (step.side === 'left' || step.side === 'right' ? this.horizontalOffset : this.verticalOffset) ?? this.offset;
|
|
13180
13280
|
const alignOffset = step.align === 'start' || step.align === 'end' ? sideOffset : 0;
|
|
13181
13281
|
this._popover?.destroy();
|
|
13182
13282
|
this._popover = new Popover(null, [popoverContainer], {
|
|
@@ -13210,19 +13310,20 @@ LX.init = async function (options = {}) {
|
|
|
13210
13310
|
await LX.loadScriptSync('https://unpkg.com/lucide@latest');
|
|
13211
13311
|
// LexGUI root
|
|
13212
13312
|
console.log(`LexGUI v${this.version}`);
|
|
13213
|
-
|
|
13313
|
+
const root = LX.makeElement('div', LX.mergeClass('lexcontainer', options.rootClass));
|
|
13214
13314
|
root.id = 'lexroot';
|
|
13215
|
-
root.className = 'lexcontainer';
|
|
13216
13315
|
root.tabIndex = -1;
|
|
13217
|
-
|
|
13218
|
-
root.className += ` ${options.rootClass}`;
|
|
13219
|
-
}
|
|
13220
|
-
this.modal = document.createElement('div');
|
|
13316
|
+
this.modal = LX.makeElement('div', 'inset-0 hidden-opacity bg-black/50 fixed z-100 transition-opacity duration-100 ease-in');
|
|
13221
13317
|
this.modal.id = 'modal';
|
|
13222
|
-
this.modal.classList.add('hidden-opacity');
|
|
13223
13318
|
this.modal.toggle = function (force) {
|
|
13224
13319
|
this.classList.toggle('hidden-opacity', force);
|
|
13225
13320
|
};
|
|
13321
|
+
function blockScroll(e) {
|
|
13322
|
+
e.preventDefault();
|
|
13323
|
+
e.stopPropagation();
|
|
13324
|
+
}
|
|
13325
|
+
this.modal.addEventListener('wheel', blockScroll, { passive: false });
|
|
13326
|
+
this.modal.addEventListener('touchmove', blockScroll, { passive: false });
|
|
13226
13327
|
this.root = root;
|
|
13227
13328
|
this.container = document.body;
|
|
13228
13329
|
if (options.container) {
|
|
@@ -13247,7 +13348,7 @@ LX.init = async function (options = {}) {
|
|
|
13247
13348
|
const notifSection = document.createElement('section');
|
|
13248
13349
|
notifSection.className = 'notifications';
|
|
13249
13350
|
this.notifications = document.createElement('ol');
|
|
13250
|
-
this.notifications.className = '';
|
|
13351
|
+
this.notifications.className = 'fixed flex flex-col-reverse m-0 p-0 gap-1 z-1000';
|
|
13251
13352
|
this.notifications.iWidth = 0;
|
|
13252
13353
|
notifSection.appendChild(this.notifications);
|
|
13253
13354
|
document.body.appendChild(notifSection);
|
|
@@ -13290,87 +13391,92 @@ LX.init = async function (options = {}) {
|
|
|
13290
13391
|
const storedcolorScheme = localStorage.getItem('lxColorScheme');
|
|
13291
13392
|
if (storedcolorScheme)
|
|
13292
13393
|
return;
|
|
13293
|
-
LX.
|
|
13394
|
+
LX.setMode(event.matches ? 'dark' : 'light', false);
|
|
13294
13395
|
};
|
|
13295
13396
|
this._mqlPrefersDarkScheme = window.matchMedia ? window.matchMedia('(prefers-color-scheme: dark)') : null;
|
|
13296
13397
|
const storedcolorScheme = localStorage.getItem('lxColorScheme');
|
|
13297
13398
|
if (storedcolorScheme) {
|
|
13298
|
-
LX.
|
|
13399
|
+
LX.setMode(storedcolorScheme);
|
|
13299
13400
|
}
|
|
13300
13401
|
else if (this._mqlPrefersDarkScheme && (options.autoTheme ?? true)) {
|
|
13301
13402
|
if (window.matchMedia('(prefers-color-scheme: light)').matches) {
|
|
13302
|
-
LX.
|
|
13403
|
+
LX.setMode('light', false);
|
|
13303
13404
|
}
|
|
13304
13405
|
this._mqlPrefersDarkScheme.addEventListener('change', this._onChangeSystemTheme);
|
|
13305
13406
|
}
|
|
13407
|
+
// LX.setThemeColor( 'rose' );
|
|
13306
13408
|
return this.mainArea;
|
|
13307
|
-
}
|
|
13409
|
+
};
|
|
13410
|
+
/**
|
|
13308
13411
|
* @method setSpacingMode
|
|
13309
13412
|
* @param {String} mode: "default" | "compact"
|
|
13310
13413
|
*/
|
|
13311
|
-
|
|
13312
|
-
|
|
13313
|
-
|
|
13314
|
-
|
|
13414
|
+
LX.setSpacingMode = function (mode) {
|
|
13415
|
+
this.spacingMode = mode;
|
|
13416
|
+
document.documentElement.setAttribute('data-spacing', this.spacingMode);
|
|
13417
|
+
};
|
|
13418
|
+
/**
|
|
13315
13419
|
* @method setLayoutMode
|
|
13316
13420
|
* @param {String} mode: "app" | "document"
|
|
13317
13421
|
*/
|
|
13318
|
-
|
|
13319
|
-
|
|
13320
|
-
|
|
13321
|
-
|
|
13422
|
+
LX.setLayoutMode = function (mode) {
|
|
13423
|
+
this.layoutMode = mode;
|
|
13424
|
+
document.documentElement.setAttribute('data-layout', this.layoutMode);
|
|
13425
|
+
};
|
|
13426
|
+
/**
|
|
13322
13427
|
* @method addSignal
|
|
13323
13428
|
* @param {String} name
|
|
13324
13429
|
* @param {Object} obj
|
|
13325
13430
|
* @param {Function} callback
|
|
13326
13431
|
*/
|
|
13327
|
-
|
|
13328
|
-
|
|
13329
|
-
|
|
13330
|
-
|
|
13331
|
-
|
|
13332
|
-
|
|
13333
|
-
|
|
13334
|
-
|
|
13335
|
-
|
|
13336
|
-
|
|
13432
|
+
LX.addSignal = function (name, obj, callback) {
|
|
13433
|
+
obj[name] = callback;
|
|
13434
|
+
if (!LX.signals[name]) {
|
|
13435
|
+
LX.signals[name] = [];
|
|
13436
|
+
}
|
|
13437
|
+
if (LX.signals[name].indexOf(obj) > -1) {
|
|
13438
|
+
return;
|
|
13439
|
+
}
|
|
13440
|
+
LX.signals[name].push(obj);
|
|
13441
|
+
};
|
|
13442
|
+
/**
|
|
13337
13443
|
* @method emitSignal
|
|
13338
13444
|
* @param {String} name
|
|
13339
13445
|
* @param {*} value
|
|
13340
13446
|
* @param {Object} options
|
|
13341
13447
|
*/
|
|
13342
|
-
|
|
13343
|
-
|
|
13344
|
-
|
|
13345
|
-
|
|
13448
|
+
LX.emitSignal = function (name, value, options = {}) {
|
|
13449
|
+
const data = LX.signals[name];
|
|
13450
|
+
if (!data) {
|
|
13451
|
+
return;
|
|
13452
|
+
}
|
|
13453
|
+
const target = options.target;
|
|
13454
|
+
if (target) {
|
|
13455
|
+
if (target[name]) {
|
|
13456
|
+
target[name].call(target, value);
|
|
13346
13457
|
}
|
|
13347
|
-
|
|
13348
|
-
|
|
13349
|
-
|
|
13350
|
-
|
|
13351
|
-
|
|
13352
|
-
return;
|
|
13458
|
+
return;
|
|
13459
|
+
}
|
|
13460
|
+
for (let obj of data) {
|
|
13461
|
+
if (obj instanceof BaseComponent) {
|
|
13462
|
+
obj.set(value, options.skipCallback ?? true);
|
|
13353
13463
|
}
|
|
13354
|
-
|
|
13355
|
-
|
|
13356
|
-
|
|
13357
|
-
}
|
|
13358
|
-
else if (obj.constructor === Function) {
|
|
13359
|
-
const fn = obj;
|
|
13360
|
-
fn(null, value);
|
|
13361
|
-
}
|
|
13362
|
-
else {
|
|
13363
|
-
// This is an element
|
|
13364
|
-
const fn = obj[name];
|
|
13365
|
-
console.assert(fn, `No callback registered with _${name}_ signal`);
|
|
13366
|
-
fn.bind(obj)(value);
|
|
13367
|
-
}
|
|
13464
|
+
else if (obj.constructor === Function) {
|
|
13465
|
+
const fn = obj;
|
|
13466
|
+
fn(null, value);
|
|
13368
13467
|
}
|
|
13369
|
-
|
|
13468
|
+
else {
|
|
13469
|
+
// This is an element
|
|
13470
|
+
const fn = obj[name];
|
|
13471
|
+
console.assert(fn, `No callback registered with _${name}_ signal`);
|
|
13472
|
+
fn.bind(obj)(value);
|
|
13473
|
+
}
|
|
13474
|
+
}
|
|
13475
|
+
};
|
|
13370
13476
|
// Command bar creation
|
|
13371
13477
|
LX._createCommandbar = function (root) {
|
|
13372
13478
|
let commandbar = document.createElement('dialog');
|
|
13373
|
-
commandbar.className = 'commandbar';
|
|
13479
|
+
commandbar.className = 'commandbar absolute border-color rounded-lg m-0';
|
|
13374
13480
|
commandbar.tabIndex = -1;
|
|
13375
13481
|
root.appendChild(commandbar);
|
|
13376
13482
|
let allItems = [];
|
|
@@ -13419,7 +13525,7 @@ LX._createCommandbar = function (root) {
|
|
|
13419
13525
|
}
|
|
13420
13526
|
e.stopPropagation();
|
|
13421
13527
|
e.stopImmediatePropagation();
|
|
13422
|
-
|
|
13528
|
+
LX.setCommandbarState(false);
|
|
13423
13529
|
_resetBar(true);
|
|
13424
13530
|
});
|
|
13425
13531
|
root.addEventListener('keydown', (e) => {
|
|
@@ -13459,8 +13565,7 @@ LX._createCommandbar = function (root) {
|
|
|
13459
13565
|
cbTabs.add('All', document.createElement('div'), { selected: true, onSelect: _onSelectTab });
|
|
13460
13566
|
// cbTabs.add( "Main", document.createElement('div'), { onSelect: _onSelectTab } );
|
|
13461
13567
|
}
|
|
13462
|
-
const itemContainer =
|
|
13463
|
-
itemContainer.className = 'searchitembox';
|
|
13568
|
+
const itemContainer = LX.makeElement('div', 'searchitembox overflow-y-scroll basis-full scrollbar-hidden');
|
|
13464
13569
|
let refPrevious = null;
|
|
13465
13570
|
const _resetBar = (resetInput) => {
|
|
13466
13571
|
itemContainer.innerHTML = '';
|
|
@@ -13470,6 +13575,53 @@ LX._createCommandbar = function (root) {
|
|
|
13470
13575
|
filter.set('', true);
|
|
13471
13576
|
}
|
|
13472
13577
|
};
|
|
13578
|
+
const _filterEntry = function (entryName, filter) {
|
|
13579
|
+
if (!filter?.length)
|
|
13580
|
+
return false;
|
|
13581
|
+
const cleanName = LX.stripTags(entryName).toLowerCase();
|
|
13582
|
+
return cleanName.includes(filter.toLowerCase());
|
|
13583
|
+
};
|
|
13584
|
+
const _getEntries = function (filter) {
|
|
13585
|
+
const entries = [];
|
|
13586
|
+
for (let m of LX.menubars) {
|
|
13587
|
+
for (let i of m.items) {
|
|
13588
|
+
if (_filterEntry(i.name, filter))
|
|
13589
|
+
entries.push(i);
|
|
13590
|
+
}
|
|
13591
|
+
}
|
|
13592
|
+
for (let m of LX.sidebars) {
|
|
13593
|
+
for (let i of m.items) {
|
|
13594
|
+
if (_filterEntry(i.name, filter))
|
|
13595
|
+
entries.push(i);
|
|
13596
|
+
}
|
|
13597
|
+
}
|
|
13598
|
+
for (let entry of LX.extraCommandbarEntries) {
|
|
13599
|
+
if (_filterEntry(entry.name, filter))
|
|
13600
|
+
entries.push(entry);
|
|
13601
|
+
}
|
|
13602
|
+
if (LX.has('CodeEditor')) {
|
|
13603
|
+
const instances = LX.CodeEditor.getInstances();
|
|
13604
|
+
if (!instances.length || !instances[0].area.root.offsetHeight)
|
|
13605
|
+
return entries;
|
|
13606
|
+
const languages = LX.CodeEditor.languages;
|
|
13607
|
+
for (let l of Object.keys(languages)) {
|
|
13608
|
+
const key = 'Language: ' + l;
|
|
13609
|
+
const icon = instances[0]._getFileIcon(null, languages[l].ext);
|
|
13610
|
+
const classes = icon.split(' ');
|
|
13611
|
+
let value = LX.makeIcon(classes[0], { svgClass: `${classes.slice(0).join(' ')}` }).innerHTML;
|
|
13612
|
+
value += key + " <span class='lang-ext'>(" + languages[l].ext + ')</span>';
|
|
13613
|
+
if (!_filterEntry(key, filter)) {
|
|
13614
|
+
continue;
|
|
13615
|
+
}
|
|
13616
|
+
entries.push({ name: value, callback: () => {
|
|
13617
|
+
for (let i of instances) {
|
|
13618
|
+
i._changeLanguage(l);
|
|
13619
|
+
}
|
|
13620
|
+
} });
|
|
13621
|
+
}
|
|
13622
|
+
}
|
|
13623
|
+
return entries;
|
|
13624
|
+
};
|
|
13473
13625
|
const _addElement = (t, c, p, i) => {
|
|
13474
13626
|
if (!t.length) {
|
|
13475
13627
|
return;
|
|
@@ -13507,64 +13659,41 @@ LX._createCommandbar = function (root) {
|
|
|
13507
13659
|
itemContainer.appendChild(searchItem);
|
|
13508
13660
|
refPrevious = searchItem;
|
|
13509
13661
|
};
|
|
13510
|
-
const _propagateAdd = (item,
|
|
13662
|
+
const _propagateAdd = (item, path, skipPropagation) => {
|
|
13511
13663
|
if (!item || (item.constructor != Object)) {
|
|
13512
13664
|
return;
|
|
13513
13665
|
}
|
|
13514
|
-
|
|
13515
|
-
|
|
13516
|
-
if (item.callback) {
|
|
13517
|
-
_addElement(name, item.callback, path, item);
|
|
13518
|
-
}
|
|
13666
|
+
if (item.callback) {
|
|
13667
|
+
_addElement(item.name, item.callback, path, item);
|
|
13519
13668
|
}
|
|
13520
|
-
const submenu = item.submenu ?? item[name];
|
|
13669
|
+
const submenu = item.submenu ?? item[item.name];
|
|
13521
13670
|
if (!submenu) {
|
|
13522
13671
|
return;
|
|
13523
13672
|
}
|
|
13524
|
-
const icon = LX.makeIcon('ChevronRight', { svgClass: 'sm
|
|
13525
|
-
path += name + icon.innerHTML;
|
|
13673
|
+
const icon = LX.makeIcon('ChevronRight', { svgClass: 'sm text-muted-foreground separator' });
|
|
13674
|
+
path += item.name + icon.innerHTML;
|
|
13526
13675
|
for (let c of submenu) {
|
|
13527
|
-
_propagateAdd(c,
|
|
13676
|
+
_propagateAdd(c, path);
|
|
13528
13677
|
}
|
|
13529
13678
|
};
|
|
13530
13679
|
commandbar._addElements = (filter) => {
|
|
13531
13680
|
_resetBar();
|
|
13532
|
-
|
|
13533
|
-
|
|
13534
|
-
|
|
13535
|
-
|
|
13536
|
-
|
|
13537
|
-
|
|
13538
|
-
|
|
13539
|
-
|
|
13540
|
-
|
|
13541
|
-
|
|
13542
|
-
|
|
13543
|
-
|
|
13544
|
-
|
|
13545
|
-
|
|
13546
|
-
|
|
13547
|
-
|
|
13548
|
-
}
|
|
13549
|
-
if (LX.has('CodeEditor')) {
|
|
13550
|
-
const instances = LX.CodeEditor.getInstances();
|
|
13551
|
-
if (!instances.length || !instances[0].area.root.offsetHeight)
|
|
13552
|
-
return;
|
|
13553
|
-
const languages = LX.CodeEditor.languages;
|
|
13554
|
-
for (let l of Object.keys(languages)) {
|
|
13555
|
-
const key = 'Language: ' + l;
|
|
13556
|
-
const icon = instances[0]._getFileIcon(null, languages[l].ext);
|
|
13557
|
-
const classes = icon.split(' ');
|
|
13558
|
-
let value = LX.makeIcon(classes[0], { svgClass: `${classes.slice(0).join(' ')}` }).innerHTML;
|
|
13559
|
-
value += key + " <span class='lang-ext'>(" + languages[l].ext + ')</span>';
|
|
13560
|
-
if (key.toLowerCase().includes(filter)) {
|
|
13561
|
-
_addElement(value, () => {
|
|
13562
|
-
for (let i of instances) {
|
|
13563
|
-
i._changeLanguage(l);
|
|
13564
|
-
}
|
|
13565
|
-
}, '', {});
|
|
13566
|
-
}
|
|
13567
|
-
}
|
|
13681
|
+
let entries = _getEntries(filter);
|
|
13682
|
+
// Order...
|
|
13683
|
+
function scoreEntry(s, prefix) {
|
|
13684
|
+
if (s.startsWith(prefix))
|
|
13685
|
+
return 0; // best option
|
|
13686
|
+
if (s.includes(prefix))
|
|
13687
|
+
return 1;
|
|
13688
|
+
return 2; // worst
|
|
13689
|
+
}
|
|
13690
|
+
entries = entries.sort((a, b) => {
|
|
13691
|
+
const nameA = LX.stripTags(a.name), nameB = LX.stripTags(b.name);
|
|
13692
|
+
return (scoreEntry(nameA, filter) - scoreEntry(nameB, filter)) || nameA.localeCompare(nameB);
|
|
13693
|
+
});
|
|
13694
|
+
entries = entries.slice(0, 48); // Get 48 ocurrences max
|
|
13695
|
+
for (let entry of entries) {
|
|
13696
|
+
_propagateAdd(entry, '');
|
|
13568
13697
|
}
|
|
13569
13698
|
};
|
|
13570
13699
|
commandbar.appendChild(header);
|
|
@@ -13572,6 +13701,37 @@ LX._createCommandbar = function (root) {
|
|
|
13572
13701
|
commandbar.appendChild(itemContainer);
|
|
13573
13702
|
return commandbar;
|
|
13574
13703
|
};
|
|
13704
|
+
LX._registerIconsAndColors = function (colorsRootPath = './') {
|
|
13705
|
+
LX.requestJSON(colorsRootPath + 'registry/colors.json', (colors) => {
|
|
13706
|
+
// loop through each color
|
|
13707
|
+
for (const key in colors) {
|
|
13708
|
+
const value = colors[key];
|
|
13709
|
+
if (!Array.isArray(value)) {
|
|
13710
|
+
continue;
|
|
13711
|
+
}
|
|
13712
|
+
value.forEach((entry) => {
|
|
13713
|
+
const color = `${key}-${entry.scale}`;
|
|
13714
|
+
const val = `<span class="flex bg-${color} w-3 h-3 rounded-full mr-2"></span>${color}`;
|
|
13715
|
+
LX.registerCommandbarEntry(val, () => {
|
|
13716
|
+
navigator.clipboard.writeText(color);
|
|
13717
|
+
LX.toast(`${LX.makeIcon('CircleCheck').innerHTML} Copied ${color} to clipboard.`, null, { position: 'top-center',
|
|
13718
|
+
timeout: 3000 });
|
|
13719
|
+
});
|
|
13720
|
+
});
|
|
13721
|
+
}
|
|
13722
|
+
});
|
|
13723
|
+
const lucide = window.lucide;
|
|
13724
|
+
const allIcons = { ...LX.ICONS, ...lucide.icons };
|
|
13725
|
+
for (const iconName in allIcons) {
|
|
13726
|
+
const variant = 'regular';
|
|
13727
|
+
const icon = LX.makeIcon(iconName, { svgClass: 'mr-2 pointer-events-none', variant });
|
|
13728
|
+
const val = `${icon.innerHTML}${iconName}`;
|
|
13729
|
+
LX.registerCommandbarEntry(val, () => {
|
|
13730
|
+
navigator.clipboard.writeText(iconName);
|
|
13731
|
+
LX.toast(`${LX.makeIcon('CircleCheck').innerHTML} Copied ${iconName} to clipboard.`, null, { position: 'top-center', timeout: 3000 });
|
|
13732
|
+
});
|
|
13733
|
+
}
|
|
13734
|
+
};
|
|
13575
13735
|
/**
|
|
13576
13736
|
* @method setCommandbarState
|
|
13577
13737
|
* @param {Boolean} value
|
|
@@ -13579,12 +13739,16 @@ LX._createCommandbar = function (root) {
|
|
|
13579
13739
|
*/
|
|
13580
13740
|
LX.setCommandbarState = function (value, resetEntries = true) {
|
|
13581
13741
|
const cb = this.commandbar;
|
|
13742
|
+
LX.modal.toggle(!value);
|
|
13582
13743
|
if (value) {
|
|
13744
|
+
// Get current position based on main scroll
|
|
13745
|
+
cb.style.top = `calc(15% + ${document.scrollingElement?.scrollTop ?? 0}px)`;
|
|
13583
13746
|
cb.show();
|
|
13584
13747
|
cb.querySelector('input').focus();
|
|
13585
13748
|
if (resetEntries) {
|
|
13586
13749
|
cb._addElements(undefined);
|
|
13587
13750
|
}
|
|
13751
|
+
LX.modal.toggle(false);
|
|
13588
13752
|
}
|
|
13589
13753
|
else {
|
|
13590
13754
|
cb.close();
|
|
@@ -13630,7 +13794,7 @@ LX.REGISTER_COMPONENT = function (customComponentName, options = {}) {
|
|
|
13630
13794
|
const customIcon = LX.makeIcon(options.icon ?? 'Box');
|
|
13631
13795
|
const menuIcon = LX.makeIcon('Menu');
|
|
13632
13796
|
let buttonName = customComponentName + (!instance ? ' [empty]' : '');
|
|
13633
|
-
let
|
|
13797
|
+
let button = this.addButton(null, buttonName, (value, event) => {
|
|
13634
13798
|
if (instance) {
|
|
13635
13799
|
element.querySelector('.lexcustomitems').toggleAttribute('hidden');
|
|
13636
13800
|
element.dataset['opened'] = !element.querySelector('.lexcustomitems').hasAttribute('hidden');
|
|
@@ -13645,11 +13809,11 @@ LX.REGISTER_COMPONENT = function (customComponentName, options = {}) {
|
|
|
13645
13809
|
});
|
|
13646
13810
|
});
|
|
13647
13811
|
}
|
|
13648
|
-
}, { buttonClass: 'custom' });
|
|
13649
|
-
const
|
|
13650
|
-
|
|
13651
|
-
|
|
13652
|
-
container.appendChild(
|
|
13812
|
+
}, { buttonClass: 'outline custom' });
|
|
13813
|
+
const buttonDom = button.root.querySelector('button');
|
|
13814
|
+
buttonDom.prepend(customIcon);
|
|
13815
|
+
buttonDom.appendChild(menuIcon);
|
|
13816
|
+
container.appendChild(button.root);
|
|
13653
13817
|
if (instance) {
|
|
13654
13818
|
menuIcon.addEventListener('click', (e) => {
|
|
13655
13819
|
e.stopImmediatePropagation();
|
|
@@ -13729,5 +13893,5 @@ LX.REGISTER_COMPONENT = function (customComponentName, options = {}) {
|
|
|
13729
13893
|
};
|
|
13730
13894
|
};
|
|
13731
13895
|
|
|
13732
|
-
export { AlertDialog, Area, AreaOverlayButtons, ArrayInput, BaseComponent, Branch, Button, Checkbox, ColorInput, ComboButtons, ComponentType, ContextMenu, Counter, Curve, DatePicker, Dial, Dialog, DropdownMenu, FileInput, Footer, Form, IEvent, LX, Layers, List, Map2D, NodeTree, NumberInput, OTPInput, Pad, Pagination, Panel, PocketDialog, Popover, Progress, RadioGroup, RangeInput, Rate, Select, Sheet, Sidebar, SizeInput, Skeleton, Spinner, TabSections, Table, Tabs, Tags, TextArea, TextInput, Title, Toggle, Tour, Tree,
|
|
13896
|
+
export { AlertDialog, Area, AreaOverlayButtons, ArrayInput, Avatar, BaseComponent, Branch, Button, Checkbox, ColorInput, ComboButtons, ComponentType, ContextMenu, Counter, Curve, DatePicker, Dial, Dialog, DropdownMenu, FileInput, Footer, Form, IEvent, LX, Layers, List, Map2D, NodeTree, NumberInput, OTPInput, Pad, Pagination, Panel, PocketDialog, Popover, Progress, RadioGroup, RangeInput, Rate, Select, Sheet, Sidebar, SizeInput, Skeleton, Spinner, TabSections, Table, Tabs, Tags, TextArea, TextInput, Title, Toggle, Tour, Tree, Vector, addDropdownMenu, vec2 };
|
|
13733
13897
|
//# sourceMappingURL=lexgui.module.js.map
|