lexgui 8.2.1 → 8.2.3
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/BaseComponent.d.ts +75 -73
- package/build/components/Form.d.ts +14 -8
- package/build/components/TextInput.d.ts +13 -11
- package/build/core/Namespace.js +1 -1
- package/build/core/Namespace.js.map +1 -1
- package/build/extensions/AssetView.d.ts +1 -1
- package/build/extensions/AssetView.js +5 -5
- package/build/extensions/AssetView.js.map +1 -1
- package/build/extensions/Audio.js +163 -163
- package/build/extensions/Audio.js.map +1 -1
- package/build/extensions/CodeEditor.js +5054 -5054
- package/build/extensions/DocMaker.d.ts +28 -27
- package/build/extensions/DocMaker.js +49 -26
- package/build/extensions/DocMaker.js.map +1 -1
- package/build/extensions/Timeline.js +3948 -3948
- package/build/extensions/VideoEditor.d.ts +150 -150
- package/build/extensions/VideoEditor.js +1014 -1014
- package/build/lexgui.all.js +209 -120
- package/build/lexgui.all.js.map +1 -1
- package/build/lexgui.all.min.js +1 -1
- package/build/lexgui.all.module.js +209 -120
- package/build/lexgui.all.module.js.map +1 -1
- package/build/lexgui.all.module.min.js +1 -1
- package/build/lexgui.css +68 -54
- package/build/lexgui.js +153 -87
- package/build/lexgui.js.map +1 -1
- package/build/lexgui.min.css +2 -2
- package/build/lexgui.min.js +1 -1
- package/build/lexgui.module.js +153 -87
- package/build/lexgui.module.js.map +1 -1
- package/build/lexgui.module.min.js +1 -1
- package/changelog.md +29 -1
- package/demo.js +2 -2
- package/examples/all-components.html +16 -2
- package/examples/asset-view.html +1 -1
- package/examples/editor.html +8 -6
- package/examples/side-bar.html +3 -1
- package/package.json +1 -1
package/build/lexgui.module.js
CHANGED
|
@@ -12,7 +12,7 @@ const g = globalThis;
|
|
|
12
12
|
let LX = g.LX;
|
|
13
13
|
if (!LX) {
|
|
14
14
|
LX = {
|
|
15
|
-
version: '8.2.
|
|
15
|
+
version: '8.2.3',
|
|
16
16
|
ready: false,
|
|
17
17
|
extensions: [], // Store extensions used
|
|
18
18
|
extraCommandbarEntries: [], // User specific entries for command bar
|
|
@@ -449,6 +449,7 @@ class BaseComponent {
|
|
|
449
449
|
onGetValue;
|
|
450
450
|
onAllowPaste;
|
|
451
451
|
onResize;
|
|
452
|
+
onSetDisabled;
|
|
452
453
|
_initialValue;
|
|
453
454
|
static NO_CONTEXT_TYPES = [
|
|
454
455
|
ComponentType.BUTTON,
|
|
@@ -517,6 +518,7 @@ class BaseComponent {
|
|
|
517
518
|
}
|
|
518
519
|
this.root = root;
|
|
519
520
|
this.root.jsInstance = this;
|
|
521
|
+
this.disabled = options.disabled ?? false;
|
|
520
522
|
this.options = options;
|
|
521
523
|
}
|
|
522
524
|
static _dispatchEvent(element, type, data, bubbles, cancelable) {
|
|
@@ -677,6 +679,12 @@ class BaseComponent {
|
|
|
677
679
|
}
|
|
678
680
|
console.error(`Unknown Component type: ${this.type}`);
|
|
679
681
|
}
|
|
682
|
+
setDisabled(disabled) {
|
|
683
|
+
this.disabled = disabled;
|
|
684
|
+
if (this.onSetDisabled) {
|
|
685
|
+
this.onSetDisabled(disabled);
|
|
686
|
+
}
|
|
687
|
+
}
|
|
680
688
|
refresh(value) {
|
|
681
689
|
}
|
|
682
690
|
}
|
|
@@ -748,6 +756,7 @@ class Button extends BaseComponent {
|
|
|
748
756
|
var wValue = LX.makeElement('button', LX.mergeClass(['lexbutton', 'inline-flex', 'items-center', 'justify-center', 'whitespace-nowrap', 'transition-all', 'disabled:pointer-events-none',
|
|
749
757
|
'disabled:opacity-50', '[&_svg]:pointer-events-none', 'shrink-0', '[&_svg]:shrink-0', 'outline-none', 'select-none', 'cursor-pointer',
|
|
750
758
|
'font-medium', 'text-sm', 'border-1', 'h-9', 'px-2', 'overflow-hidden', 'bg-clip-padding'].join(' '), options.buttonClass ?? 'outline'));
|
|
759
|
+
wValue.disabled = this.disabled;
|
|
751
760
|
wValue.title = options.tooltip ? '' : (options.title ?? '');
|
|
752
761
|
this.root.appendChild(wValue);
|
|
753
762
|
if (options.selected) {
|
|
@@ -806,10 +815,6 @@ class Button extends BaseComponent {
|
|
|
806
815
|
};
|
|
807
816
|
});
|
|
808
817
|
}
|
|
809
|
-
if (options.disabled) {
|
|
810
|
-
this.disabled = true;
|
|
811
|
-
wValue.setAttribute('disabled', true);
|
|
812
|
-
}
|
|
813
818
|
let trigger = wValue;
|
|
814
819
|
if (options.swap) {
|
|
815
820
|
wValue.classList.add('swap');
|
|
@@ -1469,6 +1474,7 @@ class NumberInput extends BaseComponent {
|
|
|
1469
1474
|
vecinput.max = options.max ?? 1e24;
|
|
1470
1475
|
vecinput.step = options.step ?? 'any';
|
|
1471
1476
|
vecinput.type = 'number';
|
|
1477
|
+
vecinput.disabled = this.disabled;
|
|
1472
1478
|
if (value.constructor == Number) {
|
|
1473
1479
|
value = LX.clamp(value, +vecinput.min, +vecinput.max);
|
|
1474
1480
|
value = LX.round(value, options.precision);
|
|
@@ -1481,9 +1487,6 @@ class NumberInput extends BaseComponent {
|
|
|
1481
1487
|
let unitBox = LX.makeContainer(['auto', 'auto'], 'px-2 bg-card content-center break-keep', options.units, valueBox);
|
|
1482
1488
|
vecinput.unitBox = unitBox;
|
|
1483
1489
|
}
|
|
1484
|
-
if (options.disabled) {
|
|
1485
|
-
this.disabled = vecinput.disabled = true;
|
|
1486
|
-
}
|
|
1487
1490
|
// Add slider below
|
|
1488
1491
|
if (!options.skipSlider && options.min !== undefined && options.max !== undefined) {
|
|
1489
1492
|
let sliderBox = LX.makeContainer(['100%', 'auto'], 'z-1 input-box', '', box);
|
|
@@ -1598,6 +1601,7 @@ LX.NumberInput = NumberInput;
|
|
|
1598
1601
|
*/
|
|
1599
1602
|
class TextInput extends BaseComponent {
|
|
1600
1603
|
valid;
|
|
1604
|
+
input;
|
|
1601
1605
|
_triggerEvent;
|
|
1602
1606
|
_lastValueTriggered;
|
|
1603
1607
|
constructor(name, value, callback, options = {}) {
|
|
@@ -1636,13 +1640,12 @@ class TextInput extends BaseComponent {
|
|
|
1636
1640
|
container.style.display = 'flex';
|
|
1637
1641
|
container.style.position = 'relative';
|
|
1638
1642
|
this.root.appendChild(container);
|
|
1639
|
-
|
|
1643
|
+
// override disabled (default is options.disable)
|
|
1644
|
+
this.disabled = (this.disabled || options.warning) ?? (options.url ? true : false);
|
|
1640
1645
|
let wValue = null;
|
|
1641
1646
|
if (!this.disabled) {
|
|
1642
1647
|
wValue = LX.makeElement('input', LX.mergeClass('lextext text-sm', options.inputClass));
|
|
1643
1648
|
wValue.type = options.type || '';
|
|
1644
|
-
wValue.value = value || '';
|
|
1645
|
-
wValue.style.textAlign = options.float ?? '';
|
|
1646
1649
|
wValue.setAttribute('placeholder', options.placeholder ?? '');
|
|
1647
1650
|
if (options.required) {
|
|
1648
1651
|
wValue.setAttribute('required', options.required);
|
|
@@ -1689,17 +1692,46 @@ class TextInput extends BaseComponent {
|
|
|
1689
1692
|
else {
|
|
1690
1693
|
wValue = document.createElement('input');
|
|
1691
1694
|
wValue.disabled = true;
|
|
1692
|
-
wValue.value = value;
|
|
1693
|
-
wValue.style.textAlign = options.float ?? '';
|
|
1694
1695
|
wValue.className = LX.mergeClass('lextext ellipsis-overflow', options.inputClass);
|
|
1695
1696
|
}
|
|
1696
1697
|
if (options.fit) {
|
|
1697
1698
|
wValue.classList.add('field-sizing-content');
|
|
1698
1699
|
}
|
|
1700
|
+
if (wValue instanceof HTMLInputElement) {
|
|
1701
|
+
wValue.name = options.name;
|
|
1702
|
+
wValue.value = value ?? '';
|
|
1703
|
+
if (options.autocomplete) {
|
|
1704
|
+
wValue.autocomplete = options.autocomplete;
|
|
1705
|
+
}
|
|
1706
|
+
else if (wValue.type === 'password') {
|
|
1707
|
+
// allow password managers by default
|
|
1708
|
+
wValue.autocomplete = 'current-password';
|
|
1709
|
+
}
|
|
1710
|
+
else if (options.name === 'username' || options.name === 'email') {
|
|
1711
|
+
wValue.autocomplete = options.name;
|
|
1712
|
+
}
|
|
1713
|
+
else {
|
|
1714
|
+
// neutral default, don't break browser heuristics
|
|
1715
|
+
wValue.autocomplete = 'on';
|
|
1716
|
+
}
|
|
1717
|
+
wValue.style.textAlign = options.float ?? '';
|
|
1718
|
+
wValue.addEventListener('transitionstart', (e) => {
|
|
1719
|
+
if (e.propertyName === 'background-color' &&
|
|
1720
|
+
wValue.matches(':-webkit-autofill')) {
|
|
1721
|
+
this.syncFromDOM();
|
|
1722
|
+
}
|
|
1723
|
+
});
|
|
1724
|
+
}
|
|
1699
1725
|
Object.assign(wValue.style, options.style ?? {});
|
|
1700
1726
|
container.appendChild(wValue);
|
|
1727
|
+
this.input = wValue;
|
|
1701
1728
|
LX.doAsync(this.onResize.bind(this));
|
|
1702
1729
|
}
|
|
1730
|
+
syncFromDOM(skipCallback = true) {
|
|
1731
|
+
if (this.input instanceof HTMLInputElement) {
|
|
1732
|
+
this.set(this.input.value, skipCallback);
|
|
1733
|
+
}
|
|
1734
|
+
}
|
|
1703
1735
|
}
|
|
1704
1736
|
LX.TextInput = TextInput;
|
|
1705
1737
|
|
|
@@ -1843,7 +1875,7 @@ class Select extends BaseComponent {
|
|
|
1843
1875
|
if (filter) {
|
|
1844
1876
|
filter.root.querySelector('input').focus();
|
|
1845
1877
|
}
|
|
1846
|
-
}, { buttonClass: 'outline [&_a]:ml-auto', skipInlineCount: true, disabled:
|
|
1878
|
+
}, { buttonClass: 'outline [&_a]:ml-auto', skipInlineCount: true, disabled: this.disabled });
|
|
1847
1879
|
selectedOption.root.style.width = '100%';
|
|
1848
1880
|
selectedOption.root.querySelector('button').appendChild(LX.makeIcon('Down', { svgClass: 'sm' }));
|
|
1849
1881
|
container.appendChild(selectedOption.root);
|
|
@@ -2067,36 +2099,40 @@ class ArrayInput extends BaseComponent {
|
|
|
2067
2099
|
component = new TextInput(i + '', value, function (value) {
|
|
2068
2100
|
values[i] = value;
|
|
2069
2101
|
callback(values);
|
|
2070
|
-
}, { nameWidth: '12px', className: 'p-0', skipReset: true });
|
|
2102
|
+
}, { nameWidth: '12px', className: 'p-0', disabled: this.disabled, skipReset: true });
|
|
2071
2103
|
break;
|
|
2072
2104
|
case Number:
|
|
2073
2105
|
component = new NumberInput(i + '', value, function (value) {
|
|
2074
2106
|
values[i] = value;
|
|
2075
2107
|
callback(values);
|
|
2076
|
-
}, { nameWidth: '12px', className: 'p-0', skipReset: true });
|
|
2108
|
+
}, { nameWidth: '12px', className: 'p-0', disabled: this.disabled, skipReset: true });
|
|
2077
2109
|
break;
|
|
2078
2110
|
case 'select':
|
|
2079
2111
|
component = new Select(i + '', options.innerValues, value, function (value) {
|
|
2080
2112
|
values[i] = value;
|
|
2081
2113
|
callback(values);
|
|
2082
|
-
}, { nameWidth: '12px', className: 'p-0', skipReset: true });
|
|
2114
|
+
}, { nameWidth: '12px', className: 'p-0', disabled: this.disabled, skipReset: true });
|
|
2083
2115
|
break;
|
|
2084
2116
|
}
|
|
2085
2117
|
console.assert(component, `Value of type ${baseclass} cannot be modified in ArrayInput`);
|
|
2086
2118
|
arrayItems.appendChild(component.root);
|
|
2087
|
-
|
|
2088
|
-
|
|
2119
|
+
if (!this.disabled) {
|
|
2120
|
+
const removeComponent = new Button(null, '', (v, event) => {
|
|
2121
|
+
values.splice(values.indexOf(value), 1);
|
|
2122
|
+
this._updateItems();
|
|
2123
|
+
this._trigger(new IEvent(name, values, event), callback);
|
|
2124
|
+
}, { buttonClass: 'ghost sm p-0', title: 'Remove item', icon: 'Trash2' });
|
|
2125
|
+
component.root.appendChild(removeComponent.root);
|
|
2126
|
+
}
|
|
2127
|
+
}
|
|
2128
|
+
if (!this.disabled) {
|
|
2129
|
+
const addButton = new Button(null, LX.makeIcon('Plus', { svgClass: 'sm' }).innerHTML + 'Add item', (v, event) => {
|
|
2130
|
+
values.push(options.innerValues ? options.innerValues[0] : '');
|
|
2089
2131
|
this._updateItems();
|
|
2090
2132
|
this._trigger(new IEvent(name, values, event), callback);
|
|
2091
|
-
}, { buttonClass: 'ghost
|
|
2092
|
-
|
|
2133
|
+
}, { buttonClass: 'ghost' });
|
|
2134
|
+
arrayItems.appendChild(addButton.root);
|
|
2093
2135
|
}
|
|
2094
|
-
const addButton = new Button(null, LX.makeIcon('Plus', { svgClass: 'sm' }).innerHTML + 'Add item', (v, event) => {
|
|
2095
|
-
values.push(options.innerValues ? options.innerValues[0] : '');
|
|
2096
|
-
this._updateItems();
|
|
2097
|
-
this._trigger(new IEvent(name, values, event), callback);
|
|
2098
|
-
}, { buttonClass: 'ghost' });
|
|
2099
|
-
arrayItems.appendChild(addButton.root);
|
|
2100
2136
|
};
|
|
2101
2137
|
this._updateItems();
|
|
2102
2138
|
}
|
|
@@ -2191,7 +2227,7 @@ class Checkbox extends BaseComponent {
|
|
|
2191
2227
|
let checkbox = LX.makeElement('input', LX.mergeClass('lexcheckbox rounded-xl', options.className ?? 'primary'));
|
|
2192
2228
|
checkbox.type = 'checkbox';
|
|
2193
2229
|
checkbox.checked = value;
|
|
2194
|
-
checkbox.disabled =
|
|
2230
|
+
checkbox.disabled = this.disabled;
|
|
2195
2231
|
container.appendChild(checkbox);
|
|
2196
2232
|
LX.makeElement('span', 'text-sm', options.label ?? 'On', container);
|
|
2197
2233
|
checkbox.addEventListener('change', (e) => {
|
|
@@ -2826,7 +2862,7 @@ class ColorInput extends BaseComponent {
|
|
|
2826
2862
|
let sampleContainer = LX.makeContainer(['18px', '18px'], 'flex flex-row rounded overflow-hidden', '', container);
|
|
2827
2863
|
sampleContainer.tabIndex = '1';
|
|
2828
2864
|
sampleContainer.addEventListener('click', (e) => {
|
|
2829
|
-
if (
|
|
2865
|
+
if (this.disabled) {
|
|
2830
2866
|
return;
|
|
2831
2867
|
}
|
|
2832
2868
|
this._popover = new Popover(sampleContainer, [this.picker]);
|
|
@@ -2850,7 +2886,7 @@ class ColorInput extends BaseComponent {
|
|
|
2850
2886
|
this.set(v);
|
|
2851
2887
|
delete this._skipTextUpdate;
|
|
2852
2888
|
this.picker.fromHexColor(v);
|
|
2853
|
-
}, { width: 'calc( 100% - 24px )', disabled:
|
|
2889
|
+
}, { width: 'calc( 100% - 24px )', disabled: this.disabled });
|
|
2854
2890
|
textComponent.root.style.marginLeft = '6px';
|
|
2855
2891
|
container.appendChild(textComponent.root);
|
|
2856
2892
|
LX.doAsync(this.onResize.bind(this));
|
|
@@ -2987,15 +3023,13 @@ class Counter extends BaseComponent {
|
|
|
2987
3023
|
const input = LX.makeElement('input', 'lexcounter w-12 bg-card px-2 text-foreground', '', container);
|
|
2988
3024
|
input.type = 'number';
|
|
2989
3025
|
input.value = value;
|
|
2990
|
-
|
|
2991
|
-
input.setAttribute('disabled', 'true');
|
|
2992
|
-
}
|
|
3026
|
+
input.disabled = this.disabled;
|
|
2993
3027
|
const substrButton = new Button(null, '', (value, e) => {
|
|
2994
3028
|
let mult = step ?? 1;
|
|
2995
3029
|
if (e.shiftKey)
|
|
2996
3030
|
mult *= 10;
|
|
2997
3031
|
this.set(this.count - mult, false, e);
|
|
2998
|
-
}, { disabled:
|
|
3032
|
+
}, { disabled: this.disabled, className: `p-0 ${this.disabled ? '' : 'hover:bg-secondary'} border-l-color border-r-color`,
|
|
2999
3033
|
buttonClass: 'px-0 bg-none h-7', icon: 'Minus' });
|
|
3000
3034
|
container.appendChild(substrButton.root);
|
|
3001
3035
|
const addButton = new Button(null, '', (value, e) => {
|
|
@@ -3003,7 +3037,7 @@ class Counter extends BaseComponent {
|
|
|
3003
3037
|
if (e.shiftKey)
|
|
3004
3038
|
mult *= 10;
|
|
3005
3039
|
this.set(this.count + mult, false, e);
|
|
3006
|
-
}, { disabled:
|
|
3040
|
+
}, { disabled: this.disabled, className: `p-0 ${this.disabled ? '' : 'hover:bg-secondary'} rounded-r-lg`,
|
|
3007
3041
|
buttonClass: 'px-0 bg-none h-7', icon: 'Plus' });
|
|
3008
3042
|
container.appendChild(addButton.root);
|
|
3009
3043
|
}
|
|
@@ -3752,7 +3786,7 @@ class DatePicker extends BaseComponent {
|
|
|
3752
3786
|
const calendarIcon = LX.makeIcon('Calendar');
|
|
3753
3787
|
const calendarButton = new Button(null, d0, () => {
|
|
3754
3788
|
this._popover = new Popover(calendarButton.root, [this.calendar]);
|
|
3755
|
-
}, { buttonClass: `outline flex flex-row px-3 ${emptyDate ? '' : 'text-muted-foreground'} justify-between` });
|
|
3789
|
+
}, { disabled: this.disabled, buttonClass: `outline flex flex-row px-3 ${emptyDate ? '' : 'text-muted-foreground'} justify-between` });
|
|
3756
3790
|
calendarButton.root.querySelector('button').appendChild(calendarIcon);
|
|
3757
3791
|
calendarButton.root.style.width = '100%';
|
|
3758
3792
|
container.appendChild(calendarButton.root);
|
|
@@ -3763,7 +3797,7 @@ class DatePicker extends BaseComponent {
|
|
|
3763
3797
|
const calendarIcon = LX.makeIcon('Calendar');
|
|
3764
3798
|
const calendarButton = new Button(null, d1, () => {
|
|
3765
3799
|
this._popover = new Popover(calendarButton.root, [this.calendar]);
|
|
3766
|
-
}, { buttonClass: `outline flex flex-row px-3 ${emptyDate ? '' : 'text-muted-foreground'} justify-between` });
|
|
3800
|
+
}, { disabled: this.disabled, buttonClass: `outline flex flex-row px-3 ${emptyDate ? '' : 'text-muted-foreground'} justify-between` });
|
|
3767
3801
|
calendarButton.root.querySelector('button').appendChild(calendarIcon);
|
|
3768
3802
|
calendarButton.root.style.width = '100%';
|
|
3769
3803
|
container.appendChild(calendarButton.root);
|
|
@@ -4134,7 +4168,7 @@ class FileInput extends BaseComponent {
|
|
|
4134
4168
|
let input = document.createElement('input');
|
|
4135
4169
|
input.className = 'lexfileinput';
|
|
4136
4170
|
input.type = 'file';
|
|
4137
|
-
input.disabled =
|
|
4171
|
+
input.disabled = this.disabled;
|
|
4138
4172
|
this.root.appendChild(input);
|
|
4139
4173
|
if (options.placeholder) {
|
|
4140
4174
|
input.placeholder = options.placeholder;
|
|
@@ -4184,7 +4218,7 @@ class FileInput extends BaseComponent {
|
|
|
4184
4218
|
root.remove();
|
|
4185
4219
|
settingsDialog = null;
|
|
4186
4220
|
} });
|
|
4187
|
-
}, { skipInlineCount: true, title: 'Settings', disabled:
|
|
4221
|
+
}, { skipInlineCount: true, title: 'Settings', disabled: this.disabled, icon: 'Settings' });
|
|
4188
4222
|
this.root.appendChild(settingButton.root);
|
|
4189
4223
|
}
|
|
4190
4224
|
LX.doAsync(this.onResize.bind(this));
|
|
@@ -4198,6 +4232,9 @@ LX.FileInput = FileInput;
|
|
|
4198
4232
|
* @description Form Component
|
|
4199
4233
|
*/
|
|
4200
4234
|
class Form extends BaseComponent {
|
|
4235
|
+
data;
|
|
4236
|
+
formData = {};
|
|
4237
|
+
primaryButton;
|
|
4201
4238
|
constructor(name, data, callback, options = {}) {
|
|
4202
4239
|
if (data.constructor != Object) {
|
|
4203
4240
|
console.error('Form data must be an Object');
|
|
@@ -4207,10 +4244,10 @@ class Form extends BaseComponent {
|
|
|
4207
4244
|
options.hideName = true;
|
|
4208
4245
|
super(ComponentType.FORM, name, null, options);
|
|
4209
4246
|
this.onGetValue = () => {
|
|
4210
|
-
return
|
|
4247
|
+
return this.formData;
|
|
4211
4248
|
};
|
|
4212
4249
|
this.onSetValue = (newValue, skipCallback, event) => {
|
|
4213
|
-
|
|
4250
|
+
this.formData = newValue;
|
|
4214
4251
|
const entries = container.querySelectorAll('.lexcomponent');
|
|
4215
4252
|
for (let i = 0; i < entries.length; ++i) {
|
|
4216
4253
|
const entry = entries[i];
|
|
@@ -4226,7 +4263,6 @@ class Form extends BaseComponent {
|
|
|
4226
4263
|
let container = document.createElement('div');
|
|
4227
4264
|
container.className = 'flex flex-col gap-1';
|
|
4228
4265
|
container.style.width = '100%';
|
|
4229
|
-
container.formData = {};
|
|
4230
4266
|
this.root.appendChild(container);
|
|
4231
4267
|
for (let entry in data) {
|
|
4232
4268
|
let entryData = data[entry];
|
|
@@ -4244,42 +4280,68 @@ class Form extends BaseComponent {
|
|
|
4244
4280
|
container.appendChild(label.root);
|
|
4245
4281
|
}
|
|
4246
4282
|
entryData.textComponent = new TextInput(null, entryData.constructor == Object ? entryData.value : entryData, (value, event) => {
|
|
4247
|
-
|
|
4248
|
-
if (entryData.submit && event
|
|
4249
|
-
|
|
4283
|
+
this.formData[entry] = value;
|
|
4284
|
+
if (entryData.submit && event?.constructor === KeyboardEvent) {
|
|
4285
|
+
this.submit();
|
|
4250
4286
|
}
|
|
4251
4287
|
}, entryData);
|
|
4252
4288
|
container.appendChild(entryData.textComponent.root);
|
|
4253
|
-
|
|
4289
|
+
this.formData[entry] = entryData.constructor == Object ? entryData.value : entryData;
|
|
4254
4290
|
}
|
|
4255
4291
|
const buttonContainer = LX.makeContainer(['100%', 'auto'], 'flex flex-row mt-2', '', container);
|
|
4256
4292
|
if (options.secondaryActionName || options.secondaryActionCallback) {
|
|
4257
4293
|
const secondaryButton = new Button(null, options.secondaryActionName ?? 'Cancel', (value, event) => {
|
|
4258
4294
|
if (options.secondaryActionCallback) {
|
|
4259
|
-
options.secondaryActionCallback(
|
|
4295
|
+
options.secondaryActionCallback(this.formData, event);
|
|
4260
4296
|
}
|
|
4261
4297
|
}, { width: '100%', minWidth: '0', buttonClass: options.secondaryButtonClass ?? 'secondary' });
|
|
4262
4298
|
buttonContainer.appendChild(secondaryButton.root);
|
|
4263
4299
|
}
|
|
4264
|
-
|
|
4300
|
+
// This is basically the "submit" button
|
|
4301
|
+
this.primaryButton = new Button(null, options.primaryActionName ?? 'Submit', (value, event) => {
|
|
4265
4302
|
const errors = [];
|
|
4266
4303
|
for (let entry in data) {
|
|
4267
4304
|
let entryData = data[entry];
|
|
4268
4305
|
const pattern = entryData.pattern;
|
|
4269
|
-
const matchField = pattern?.fieldMatchName ?
|
|
4306
|
+
const matchField = pattern?.fieldMatchName ? this.formData[pattern.fieldMatchName] : undefined;
|
|
4270
4307
|
if (!entryData.textComponent.valid(undefined, matchField)) {
|
|
4271
4308
|
const err = { entry, type: 'input_not_valid', messages: [] };
|
|
4272
4309
|
if (pattern) {
|
|
4273
|
-
err.messages = LX.validateValueAtPattern(
|
|
4310
|
+
err.messages = LX.validateValueAtPattern(this.formData[entry], pattern, matchField);
|
|
4274
4311
|
}
|
|
4275
4312
|
errors.push(err);
|
|
4276
4313
|
}
|
|
4277
4314
|
}
|
|
4278
4315
|
if (callback) {
|
|
4279
|
-
callback(
|
|
4316
|
+
callback(this.formData, errors, event);
|
|
4280
4317
|
}
|
|
4281
4318
|
}, { width: '100%', minWidth: '0', buttonClass: options.primaryButtonClass ?? 'primary' });
|
|
4282
|
-
buttonContainer.appendChild(primaryButton.root);
|
|
4319
|
+
buttonContainer.appendChild(this.primaryButton.root);
|
|
4320
|
+
if (!(options.skipEnterSubmit ?? false)) {
|
|
4321
|
+
this.root.addEventListener('keydown', (e) => {
|
|
4322
|
+
if (e.key !== 'Enter' || e.shiftKey)
|
|
4323
|
+
return;
|
|
4324
|
+
const target = e.target;
|
|
4325
|
+
if (target.tagName === 'TEXTAREA')
|
|
4326
|
+
return;
|
|
4327
|
+
e.preventDefault();
|
|
4328
|
+
this.submit();
|
|
4329
|
+
});
|
|
4330
|
+
}
|
|
4331
|
+
this.data = data;
|
|
4332
|
+
}
|
|
4333
|
+
submit() {
|
|
4334
|
+
this.syncInputs();
|
|
4335
|
+
this.primaryButton?.click();
|
|
4336
|
+
}
|
|
4337
|
+
syncInputs() {
|
|
4338
|
+
for (const entry in this.data) {
|
|
4339
|
+
const component = this.data[entry].textComponent;
|
|
4340
|
+
if (component instanceof TextInput) {
|
|
4341
|
+
component.syncFromDOM();
|
|
4342
|
+
this.formData[entry] = component.value();
|
|
4343
|
+
}
|
|
4344
|
+
}
|
|
4283
4345
|
}
|
|
4284
4346
|
}
|
|
4285
4347
|
LX.Form = Form;
|
|
@@ -4318,9 +4380,10 @@ class Layers extends BaseComponent {
|
|
|
4318
4380
|
binary = '0' + binary;
|
|
4319
4381
|
}
|
|
4320
4382
|
for (let bit = 0; bit < maxBits; ++bit) {
|
|
4321
|
-
let layer = document.createElement('
|
|
4322
|
-
layer.className =
|
|
4323
|
-
|
|
4383
|
+
let layer = document.createElement('button');
|
|
4384
|
+
layer.className = `lexlayer size-6 text-secondary-foreground text-center content-center place-self-center cursor-pointer font-semibold text-xs rounded-lg select-none
|
|
4385
|
+
disabled:pointer-events-none disabled:opacity-50`;
|
|
4386
|
+
layer.disabled = this.disabled;
|
|
4324
4387
|
if (val != undefined) {
|
|
4325
4388
|
const valueBit = binary[maxBits - bit - 1];
|
|
4326
4389
|
if (valueBit != undefined && valueBit == '1') {
|
|
@@ -4391,8 +4454,9 @@ class List extends BaseComponent {
|
|
|
4391
4454
|
icon = itemValue[1];
|
|
4392
4455
|
itemValue = itemValue[0];
|
|
4393
4456
|
}
|
|
4394
|
-
let listElement = document.createElement('
|
|
4395
|
-
listElement.className =
|
|
4457
|
+
let listElement = document.createElement('button');
|
|
4458
|
+
listElement.className = `lexlistitem disabled:pointer-events-none disabled:opacity-50 ${(value == itemValue) ? 'selected' : ''}`;
|
|
4459
|
+
listElement.disabled = this.disabled;
|
|
4396
4460
|
if (icon) {
|
|
4397
4461
|
listElement.appendChild(LX.makeIcon(icon));
|
|
4398
4462
|
}
|
|
@@ -4851,10 +4915,10 @@ class Map2D extends BaseComponent {
|
|
|
4851
4915
|
container.className = 'lexmap2d';
|
|
4852
4916
|
this.root.appendChild(container);
|
|
4853
4917
|
this.map2d = new CanvasMap2D(points, callback, options);
|
|
4854
|
-
const calendarIcon = LX.makeIcon('SquareMousePointer');
|
|
4918
|
+
const calendarIcon = LX.makeIcon(options.mapIcon ?? 'SquareMousePointer');
|
|
4855
4919
|
const calendarButton = new Button(null, 'Open Map', () => {
|
|
4856
4920
|
this._popover = new Popover(calendarButton.root, [this.map2d]);
|
|
4857
|
-
}, { buttonClass: `outline justify-between
|
|
4921
|
+
}, { buttonClass: `outline justify-between`, disabled: this.disabled });
|
|
4858
4922
|
calendarButton.root.querySelector('button').appendChild(calendarIcon);
|
|
4859
4923
|
container.appendChild(calendarButton.root);
|
|
4860
4924
|
LX.doAsync(this.onResize.bind(this));
|
|
@@ -5409,7 +5473,7 @@ class NodeTree {
|
|
|
5409
5473
|
return;
|
|
5410
5474
|
}
|
|
5411
5475
|
// Element should exist, since tree was refreshed to show it
|
|
5412
|
-
const el = this.domEl.querySelector('#' + id);
|
|
5476
|
+
const el = this.domEl.querySelector('#' + LX.getSupportedDOMName(id));
|
|
5413
5477
|
console.assert(el, "NodeTree: Can't select node " + id);
|
|
5414
5478
|
el.classList.add('selected');
|
|
5415
5479
|
this.selected = [el.treeData];
|
|
@@ -5536,7 +5600,6 @@ class OTPInput extends BaseComponent {
|
|
|
5536
5600
|
const realNameWidth = this.root.domName?.style.width ?? '0px';
|
|
5537
5601
|
container.style.width = `calc( 100% - ${realNameWidth})`;
|
|
5538
5602
|
};
|
|
5539
|
-
this.disabled = options.disabled ?? false;
|
|
5540
5603
|
const container = document.createElement('div');
|
|
5541
5604
|
container.className = 'lexotp flex flex-row items-center';
|
|
5542
5605
|
this.root.appendChild(container);
|
|
@@ -5647,17 +5710,18 @@ class Pad extends BaseComponent {
|
|
|
5647
5710
|
const realNameWidth = this.root.domName?.style.width ?? '0px';
|
|
5648
5711
|
container.style.width = `calc( 100% - ${realNameWidth})`;
|
|
5649
5712
|
};
|
|
5650
|
-
|
|
5713
|
+
let container = document.createElement('div');
|
|
5651
5714
|
container.className = 'lexpad';
|
|
5652
5715
|
this.root.appendChild(container);
|
|
5653
5716
|
let pad = document.createElement('div');
|
|
5654
5717
|
pad.id = 'lexpad-' + name;
|
|
5655
|
-
pad.className = 'lexinnerpad';
|
|
5718
|
+
pad.className = 'lexinnerpad data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 border-color';
|
|
5656
5719
|
pad.style.width = options.padSize ?? '96px';
|
|
5657
5720
|
pad.style.height = options.padSize ?? '96px';
|
|
5721
|
+
pad.dataset['disabled'] = this.disabled.toString();
|
|
5658
5722
|
container.appendChild(pad);
|
|
5659
5723
|
let thumb = document.createElement('div');
|
|
5660
|
-
thumb.className = 'lexpadthumb';
|
|
5724
|
+
thumb.className = 'lexpadthumb opacity-inherit';
|
|
5661
5725
|
thumb.value = new vec2(value[0], value[1]);
|
|
5662
5726
|
thumb.min = options.min ?? 0;
|
|
5663
5727
|
thumb.max = options.max ?? 1;
|
|
@@ -5850,7 +5914,7 @@ class RadioGroup extends BaseComponent {
|
|
|
5850
5914
|
container.appendChild(optionItem);
|
|
5851
5915
|
const optionButton = document.createElement('button');
|
|
5852
5916
|
optionButton.className = 'flex p-0 rounded-lg cursor-pointer';
|
|
5853
|
-
optionButton.disabled =
|
|
5917
|
+
optionButton.disabled = this.disabled;
|
|
5854
5918
|
optionItem.appendChild(optionButton);
|
|
5855
5919
|
optionButton.addEventListener('click', (e) => {
|
|
5856
5920
|
this.set(i, false, e);
|
|
@@ -5962,7 +6026,7 @@ class RangeInput extends BaseComponent {
|
|
|
5962
6026
|
slider.max = options.max ?? 100;
|
|
5963
6027
|
slider.step = options.step ?? 1;
|
|
5964
6028
|
slider.type = 'range';
|
|
5965
|
-
slider.disabled =
|
|
6029
|
+
slider.disabled = this.disabled;
|
|
5966
6030
|
if (value.constructor == Number) {
|
|
5967
6031
|
value = LX.clamp(value, +slider.min, +slider.max);
|
|
5968
6032
|
}
|
|
@@ -6021,7 +6085,7 @@ class RangeInput extends BaseComponent {
|
|
|
6021
6085
|
maxSlider.max = options.max ?? 100;
|
|
6022
6086
|
maxSlider.step = options.step ?? 1;
|
|
6023
6087
|
maxSlider.type = 'range';
|
|
6024
|
-
maxSlider.disabled =
|
|
6088
|
+
maxSlider.disabled = this.disabled;
|
|
6025
6089
|
this._maxSlider = maxSlider;
|
|
6026
6090
|
let maxRangeValue = ogValue[1];
|
|
6027
6091
|
maxSlider.value = maxRangeValue = LX.clamp(maxRangeValue, +maxSlider.min, +maxSlider.max);
|
|
@@ -6062,7 +6126,8 @@ class Rate extends BaseComponent {
|
|
|
6062
6126
|
container.style.width = `calc( 100% - ${realNameWidth})`;
|
|
6063
6127
|
};
|
|
6064
6128
|
const container = document.createElement('div');
|
|
6065
|
-
container.className = 'lexrate relative';
|
|
6129
|
+
container.className = 'lexrate relative data-[disabled=true]:pointer-events-none';
|
|
6130
|
+
container.dataset['disabled'] = this.disabled.toString();
|
|
6066
6131
|
this.root.appendChild(container);
|
|
6067
6132
|
const starsContainer = LX.makeContainer(['fit-content', 'auto'], 'flex flex-row gap-1', '', container);
|
|
6068
6133
|
const filledStarsContainer = LX.makeContainer(['fit-content', 'auto'], 'absolute top-0 flex flex-row gap-1 pointer-events-none', '', container);
|
|
@@ -6161,7 +6226,7 @@ class SizeInput extends BaseComponent {
|
|
|
6161
6226
|
if (callback) {
|
|
6162
6227
|
callback(value);
|
|
6163
6228
|
}
|
|
6164
|
-
}, { min: 0, disabled:
|
|
6229
|
+
}, { min: 0, disabled: this.disabled, precision: options.precision, className: 'flex-auto-fill' });
|
|
6165
6230
|
container.appendChild(this.root.dimensions[i].root);
|
|
6166
6231
|
if ((i + 1) != value.length) {
|
|
6167
6232
|
const xIcon = LX.makeIcon('X', { svgClass: 'text-foreground font-bold' });
|
|
@@ -7212,15 +7277,20 @@ class Tags extends BaseComponent {
|
|
|
7212
7277
|
for (let i = 0; i < value.length; ++i) {
|
|
7213
7278
|
const tagName = value[i];
|
|
7214
7279
|
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);
|
|
7215
|
-
|
|
7216
|
-
|
|
7217
|
-
|
|
7218
|
-
|
|
7219
|
-
|
|
7220
|
-
|
|
7221
|
-
|
|
7280
|
+
if (!this.disabled) {
|
|
7281
|
+
const removeButton = LX.makeIcon('X', { svgClass: 'sm' });
|
|
7282
|
+
tag.appendChild(removeButton);
|
|
7283
|
+
removeButton.addEventListener('click', (e) => {
|
|
7284
|
+
tag.remove();
|
|
7285
|
+
value.splice(value.indexOf(tagName), 1);
|
|
7286
|
+
this.set(value, false, e);
|
|
7287
|
+
});
|
|
7288
|
+
}
|
|
7222
7289
|
tagsContainer.appendChild(tag);
|
|
7223
7290
|
}
|
|
7291
|
+
if (this.disabled) {
|
|
7292
|
+
return;
|
|
7293
|
+
}
|
|
7224
7294
|
let tagInput = document.createElement('input');
|
|
7225
7295
|
tagInput.value = '';
|
|
7226
7296
|
tagInput.placeholder = 'Add tag...';
|
|
@@ -7272,6 +7342,7 @@ class TextArea extends BaseComponent {
|
|
|
7272
7342
|
let wValue = LX.makeElement('textarea', options.inputClass ?? '');
|
|
7273
7343
|
wValue.value = value ?? '';
|
|
7274
7344
|
wValue.style.textAlign = options.float ?? '';
|
|
7345
|
+
wValue.disabled = this.disabled;
|
|
7275
7346
|
Object.assign(wValue.style, options.style ?? {});
|
|
7276
7347
|
if (options.fitHeight ?? false) {
|
|
7277
7348
|
wValue.classList.add('field-sizing-content');
|
|
@@ -7280,10 +7351,6 @@ class TextArea extends BaseComponent {
|
|
|
7280
7351
|
wValue.classList.add('resize-none');
|
|
7281
7352
|
}
|
|
7282
7353
|
container.appendChild(wValue);
|
|
7283
|
-
if (options.disabled ?? false) {
|
|
7284
|
-
this.disabled = true;
|
|
7285
|
-
wValue.setAttribute('disabled', 'true');
|
|
7286
|
-
}
|
|
7287
7354
|
if (options.placeholder) {
|
|
7288
7355
|
wValue.setAttribute('placeholder', options.placeholder);
|
|
7289
7356
|
}
|
|
@@ -7383,7 +7450,7 @@ class Toggle extends BaseComponent {
|
|
|
7383
7450
|
toggle.type = 'checkbox';
|
|
7384
7451
|
toggle.checked = value;
|
|
7385
7452
|
toggle.iValue = value;
|
|
7386
|
-
toggle.disabled =
|
|
7453
|
+
toggle.disabled = this.disabled;
|
|
7387
7454
|
container.appendChild(toggle);
|
|
7388
7455
|
let valueName = document.createElement('span');
|
|
7389
7456
|
valueName.className = 'font-medium w-full overflow-hidden truncate';
|
|
@@ -7450,7 +7517,6 @@ class Vector extends BaseComponent {
|
|
|
7450
7517
|
var container = document.createElement('div');
|
|
7451
7518
|
container.className = 'lexvector flex';
|
|
7452
7519
|
this.root.appendChild(container);
|
|
7453
|
-
this.disabled = options.disabled ?? false;
|
|
7454
7520
|
const that = this;
|
|
7455
7521
|
for (let i = 0; i < numComponents; ++i) {
|
|
7456
7522
|
let box = document.createElement('div');
|
|
@@ -7464,6 +7530,7 @@ class Vector extends BaseComponent {
|
|
|
7464
7530
|
vecinput.type = 'number';
|
|
7465
7531
|
vecinput.id = 'vec' + numComponents + '_' + LX.guidGenerator();
|
|
7466
7532
|
vecinput.idx = i;
|
|
7533
|
+
vecinput.disabled = this.disabled;
|
|
7467
7534
|
vectorInputs[i] = vecinput;
|
|
7468
7535
|
box.appendChild(vecinput);
|
|
7469
7536
|
if (value[i].constructor == Number) {
|
|
@@ -7473,9 +7540,6 @@ class Vector extends BaseComponent {
|
|
|
7473
7540
|
vecinput.value = vecinput.iValue = value[i];
|
|
7474
7541
|
const dragIcon = LX.makeIcon('MoveVertical', { iconClass: 'drag-icon hidden-opacity', svgClass: 'sm' });
|
|
7475
7542
|
box.appendChild(dragIcon);
|
|
7476
|
-
if (this.disabled) {
|
|
7477
|
-
vecinput.disabled = true;
|
|
7478
|
-
}
|
|
7479
7543
|
// Add wheel input
|
|
7480
7544
|
vecinput.addEventListener('wheel', function (e) {
|
|
7481
7545
|
e.preventDefault();
|
|
@@ -10372,8 +10436,10 @@ function makeCollapsible(domEl, content, parent, options = {}) {
|
|
|
10372
10436
|
const collapsed = options.collapsed ?? true;
|
|
10373
10437
|
const actionIcon = LX.makeIcon('Right');
|
|
10374
10438
|
actionIcon.classList.add('collapser');
|
|
10375
|
-
if (collapsed)
|
|
10376
|
-
actionIcon.dataset['collapsed'] =
|
|
10439
|
+
if (collapsed) {
|
|
10440
|
+
actionIcon.dataset['collapsed'] = `true`;
|
|
10441
|
+
content.style.display = 'none';
|
|
10442
|
+
}
|
|
10377
10443
|
actionIcon.style.marginLeft = 'auto';
|
|
10378
10444
|
actionIcon.style.marginRight = '0.2rem';
|
|
10379
10445
|
actionIcon.addEventListener('click', function (e) {
|