lexgui 0.7.11 → 0.7.13
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/extensions/codeeditor.js +85 -25
- package/build/extensions/timeline.js +206 -110
- package/build/lexgui.css +0 -1
- package/build/lexgui.js +129 -33
- package/build/lexgui.min.css +1 -1
- package/build/lexgui.min.js +1 -1
- package/build/lexgui.module.js +153 -57
- package/build/lexgui.module.min.js +1 -1
- package/changelog.md +30 -1
- package/examples/editor.html +31 -4
- package/package.json +1 -1
package/build/lexgui.css
CHANGED
package/build/lexgui.js
CHANGED
|
@@ -14,7 +14,7 @@ console.warn( 'Script _build/lexgui.js_ is depracated and will be removed soon.
|
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
16
|
const LX = {
|
|
17
|
-
version: "0.7.
|
|
17
|
+
version: "0.7.13",
|
|
18
18
|
ready: false,
|
|
19
19
|
extensions: [], // Store extensions used
|
|
20
20
|
signals: {}, // Events and triggers
|
|
@@ -5329,11 +5329,12 @@ LX.guidGenerator = guidGenerator;
|
|
|
5329
5329
|
function buildTextPattern( options = {} )
|
|
5330
5330
|
{
|
|
5331
5331
|
let patterns = [];
|
|
5332
|
-
if
|
|
5333
|
-
if
|
|
5334
|
-
if
|
|
5335
|
-
if
|
|
5336
|
-
if
|
|
5332
|
+
if( options.lowercase ) patterns.push("(?=.*[a-z])");
|
|
5333
|
+
if( options.uppercase ) patterns.push("(?=.*[A-Z])");
|
|
5334
|
+
if( options.digit ) patterns.push("(?=.*\\d)");
|
|
5335
|
+
if( options.specialChar ) patterns.push("(?=.*[@#$%^&+=!])");
|
|
5336
|
+
if( options.noSpaces ) patterns.push("(?!.*\\s)");
|
|
5337
|
+
if( options.email ) patterns.push("(^[^\s@]+@[^\s@]+\.[^\s@]+$)");
|
|
5337
5338
|
|
|
5338
5339
|
let minLength = options.minLength || 0;
|
|
5339
5340
|
let maxLength = options.maxLength || ""; // Empty means no max length restriction
|
|
@@ -5344,6 +5345,45 @@ function buildTextPattern( options = {} )
|
|
|
5344
5345
|
|
|
5345
5346
|
LX.buildTextPattern = buildTextPattern;
|
|
5346
5347
|
|
|
5348
|
+
/**
|
|
5349
|
+
* Checks a value against a set of pattern requirements and returns an array
|
|
5350
|
+
* of specific error messages for all criteria that failed.
|
|
5351
|
+
* @param { String } value The string to validate.
|
|
5352
|
+
* @param { Object } pattern The pattern options
|
|
5353
|
+
* @returns { Array } An array of error messages for failed criteria.
|
|
5354
|
+
*/
|
|
5355
|
+
function validateValueAtPattern( value, pattern = {}, ...args )
|
|
5356
|
+
{
|
|
5357
|
+
const errors = [];
|
|
5358
|
+
const minLength = pattern.minLength || 0;
|
|
5359
|
+
const maxLength = pattern.maxLength; // undefined means no max limit
|
|
5360
|
+
|
|
5361
|
+
// Length requirements
|
|
5362
|
+
if( value.length < minLength ) errors.push(`Must be at least ${ minLength } characters long.`);
|
|
5363
|
+
else if( maxLength !== undefined && value.length > maxLength ) errors.push(`Must be no more than ${ maxLength } characters long.`);
|
|
5364
|
+
|
|
5365
|
+
// Check for Lowercase, Uppercase, Digits
|
|
5366
|
+
if( pattern.lowercase && !/[a-z]/.test( value ) ) errors.push( "Must contain at least one lowercase letter (a-z)." );
|
|
5367
|
+
if( pattern.uppercase && !/[A-Z]/.test( value ) ) errors.push( "Must contain at least one uppercase letter (A-Z)." );
|
|
5368
|
+
if( pattern.digit && !/\d/.test( value ) ) errors.push( "Must contain at least one number (0-9)." );
|
|
5369
|
+
|
|
5370
|
+
// Check for No Spaces (The original regex was (?!.*\s), meaning 'not followed by any character and a space')
|
|
5371
|
+
if( pattern.noSpaces && /\s/.test(value)) errors.push("Must NOT contain any spaces.");
|
|
5372
|
+
|
|
5373
|
+
// Check for Special Character (using the same set as buildTextPattern)
|
|
5374
|
+
if( pattern.specialChar && !/[@#$%^&+=!]/.test( value ) ) errors.push("Must contain at least one special character (e.g., @, #, $, %, ^, &, +, =, !).");
|
|
5375
|
+
|
|
5376
|
+
// Check email formatting
|
|
5377
|
+
if( pattern.email && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test( value ) ) errors.push("Must have a valid email format.");
|
|
5378
|
+
|
|
5379
|
+
// Check match to any other text word
|
|
5380
|
+
if( pattern.fieldMatchName && value !== ( args[ 0 ] ) ) errors.push(`Must match ${ pattern.fieldMatchName } field.`);
|
|
5381
|
+
|
|
5382
|
+
return errors;
|
|
5383
|
+
}
|
|
5384
|
+
|
|
5385
|
+
LX.validateValueAtPattern = validateValueAtPattern;
|
|
5386
|
+
|
|
5347
5387
|
/**
|
|
5348
5388
|
* @method makeDraggable
|
|
5349
5389
|
* @description Allows an element to be dragged
|
|
@@ -9062,7 +9102,14 @@ class TextInput extends BaseComponent
|
|
|
9062
9102
|
|
|
9063
9103
|
this.onSetValue = ( newValue, skipCallback, event ) => {
|
|
9064
9104
|
|
|
9065
|
-
|
|
9105
|
+
let skipTrigger = ( this._lastValueTriggered == newValue );
|
|
9106
|
+
|
|
9107
|
+
if( !options.ignoreValidation )
|
|
9108
|
+
{
|
|
9109
|
+
skipTrigger |= ( !this.valid( newValue ) );
|
|
9110
|
+
}
|
|
9111
|
+
|
|
9112
|
+
if( skipTrigger )
|
|
9066
9113
|
{
|
|
9067
9114
|
return;
|
|
9068
9115
|
}
|
|
@@ -9082,11 +9129,11 @@ class TextInput extends BaseComponent
|
|
|
9082
9129
|
container.style.width = options.inputWidth ?? `calc( 100% - ${ realNameWidth })`;
|
|
9083
9130
|
};
|
|
9084
9131
|
|
|
9085
|
-
this.valid = ( v ) => {
|
|
9132
|
+
this.valid = ( v, matchField ) => {
|
|
9086
9133
|
v = v ?? this.value();
|
|
9087
|
-
if(
|
|
9088
|
-
const
|
|
9089
|
-
return
|
|
9134
|
+
if( !options.pattern ) return true;
|
|
9135
|
+
const errs = LX.validateValueAtPattern( v, options.pattern, matchField );
|
|
9136
|
+
return ( errs.length == 0 );
|
|
9090
9137
|
};
|
|
9091
9138
|
|
|
9092
9139
|
let container = document.createElement( 'div' );
|
|
@@ -9115,7 +9162,7 @@ class TextInput extends BaseComponent
|
|
|
9115
9162
|
|
|
9116
9163
|
if( options.pattern )
|
|
9117
9164
|
{
|
|
9118
|
-
wValue.setAttribute( "pattern", options.pattern );
|
|
9165
|
+
wValue.setAttribute( "pattern", LX.buildTextPattern( options.pattern ) );
|
|
9119
9166
|
}
|
|
9120
9167
|
|
|
9121
9168
|
const trigger = options.trigger ?? "default";
|
|
@@ -9785,13 +9832,14 @@ class Form extends BaseComponent
|
|
|
9785
9832
|
|
|
9786
9833
|
if( entryData.constructor != Object )
|
|
9787
9834
|
{
|
|
9788
|
-
const oldValue =
|
|
9835
|
+
const oldValue = LX.deepCopy( entryData );
|
|
9789
9836
|
entryData = { value: oldValue };
|
|
9790
9837
|
data[ entry ] = entryData;
|
|
9791
9838
|
}
|
|
9792
9839
|
|
|
9793
|
-
entryData.placeholder = entryData.placeholder ?? ( entryData.label ?? `Enter ${ entry }` );
|
|
9794
9840
|
entryData.width = "100%";
|
|
9841
|
+
entryData.placeholder = entryData.placeholder ?? ( entryData.label ?? `Enter ${ entry }` );
|
|
9842
|
+
entryData.ignoreValidation = true;
|
|
9795
9843
|
|
|
9796
9844
|
if( !( options.skipLabels ?? false ) )
|
|
9797
9845
|
{
|
|
@@ -9807,14 +9855,14 @@ class Form extends BaseComponent
|
|
|
9807
9855
|
container.formData[ entry ] = entryData.constructor == Object ? entryData.value : entryData;
|
|
9808
9856
|
}
|
|
9809
9857
|
|
|
9810
|
-
const buttonContainer = LX.makeContainer( ["100%", "auto"], "flex flex-row", "", container );
|
|
9858
|
+
const buttonContainer = LX.makeContainer( ["100%", "auto"], "flex flex-row mt-2", "", container );
|
|
9811
9859
|
|
|
9812
9860
|
if( options.secondaryActionName || options.secondaryActionCallback )
|
|
9813
9861
|
{
|
|
9814
9862
|
const secondaryButton = new LX.Button( null, options.secondaryActionName ?? "Cancel", ( value, event ) => {
|
|
9815
|
-
if(
|
|
9863
|
+
if( options.secondaryActionCallback )
|
|
9816
9864
|
{
|
|
9817
|
-
|
|
9865
|
+
options.secondaryActionCallback( container.formData, event );
|
|
9818
9866
|
}
|
|
9819
9867
|
}, { width: "100%", minWidth: "0", buttonClass: options.secondaryButtonClass ?? "primary" } );
|
|
9820
9868
|
|
|
@@ -9829,9 +9877,22 @@ class Form extends BaseComponent
|
|
|
9829
9877
|
{
|
|
9830
9878
|
let entryData = data[ entry ];
|
|
9831
9879
|
|
|
9832
|
-
|
|
9880
|
+
const pattern = entryData.pattern;
|
|
9881
|
+
const matchField = pattern?.fieldMatchName ? container.formData[ pattern.fieldMatchName ] : undefined;
|
|
9882
|
+
|
|
9883
|
+
if( !entryData.textComponent.valid( undefined, matchField ) )
|
|
9833
9884
|
{
|
|
9834
|
-
|
|
9885
|
+
const err = { entry, type: "input_not_valid" };
|
|
9886
|
+
err.messages = [];
|
|
9887
|
+
if( pattern )
|
|
9888
|
+
{
|
|
9889
|
+
err.messages = LX.validateValueAtPattern(
|
|
9890
|
+
container.formData[ entry ],
|
|
9891
|
+
pattern,
|
|
9892
|
+
matchField
|
|
9893
|
+
);
|
|
9894
|
+
}
|
|
9895
|
+
errors.push( err );
|
|
9835
9896
|
}
|
|
9836
9897
|
}
|
|
9837
9898
|
|
|
@@ -12705,6 +12766,7 @@ class Table extends BaseComponent
|
|
|
12705
12766
|
this.filter = options.filter ?? false;
|
|
12706
12767
|
this.customFilters = options.customFilters ?? false;
|
|
12707
12768
|
this._toggleColumns = options.toggleColumns ?? false;
|
|
12769
|
+
this._sortColumns = options.sortColumns ?? true;
|
|
12708
12770
|
this._currentFilter = options.filterValue;
|
|
12709
12771
|
|
|
12710
12772
|
data.head = data.head ?? [];
|
|
@@ -12971,28 +13033,62 @@ class Table extends BaseComponent
|
|
|
12971
13033
|
th.classList.add( "centered" );
|
|
12972
13034
|
}
|
|
12973
13035
|
|
|
12974
|
-
const menuOptions = [
|
|
12975
|
-
{ name: "Asc", icon: "ArrowUpAZ", callback: sortFn.bind( this, idx, 1 ) },
|
|
12976
|
-
{ name: "Desc", icon: "ArrowDownAZ", callback: sortFn.bind( this, idx, -1 ) }
|
|
12977
|
-
];
|
|
13036
|
+
const menuOptions = [];
|
|
12978
13037
|
|
|
12979
|
-
if(
|
|
13038
|
+
if( options.columnActions )
|
|
12980
13039
|
{
|
|
12981
|
-
|
|
12982
|
-
|
|
13040
|
+
for( let action of options.columnActions )
|
|
13041
|
+
{
|
|
13042
|
+
if( !action.name )
|
|
12983
13043
|
{
|
|
12984
|
-
|
|
12985
|
-
|
|
12986
|
-
const cells = table.querySelectorAll(`tr > *:nth-child(${idx + this.rowOffsetCount + 1})`);
|
|
12987
|
-
cells.forEach( cell => {
|
|
12988
|
-
cell.style.display = ( cell.style.display === "none" ) ? "" : "none";
|
|
12989
|
-
} );
|
|
12990
|
-
}
|
|
13044
|
+
console.warn( "Invalid column action (missing name):", action );
|
|
13045
|
+
continue;
|
|
12991
13046
|
}
|
|
13047
|
+
|
|
13048
|
+
menuOptions.push( { name: action.name, icon: action.icon, className: action.className, callback: () => {
|
|
13049
|
+
const colRows = this.data.body.map( row => [ row[ idx ] ] );
|
|
13050
|
+
const mustRefresh = action.callback( colRows, table );
|
|
13051
|
+
if( mustRefresh )
|
|
13052
|
+
{
|
|
13053
|
+
this.refresh();
|
|
13054
|
+
}
|
|
13055
|
+
} } );
|
|
13056
|
+
}
|
|
13057
|
+
}
|
|
13058
|
+
|
|
13059
|
+
if( this._sortColumns )
|
|
13060
|
+
{
|
|
13061
|
+
if( menuOptions.length > 0 )
|
|
13062
|
+
{
|
|
13063
|
+
menuOptions.push( null );
|
|
13064
|
+
}
|
|
13065
|
+
|
|
13066
|
+
menuOptions.push(
|
|
13067
|
+
{ name: "Asc", icon: "ArrowUpAZ", callback: sortFn.bind( this, idx, 1 ) },
|
|
13068
|
+
{ name: "Desc", icon: "ArrowDownAZ", callback: sortFn.bind( this, idx, -1 ) }
|
|
12992
13069
|
);
|
|
12993
13070
|
}
|
|
12994
13071
|
|
|
13072
|
+
if( this._toggleColumns )
|
|
13073
|
+
{
|
|
13074
|
+
if( menuOptions.length > 0 )
|
|
13075
|
+
{
|
|
13076
|
+
menuOptions.push( null );
|
|
13077
|
+
}
|
|
13078
|
+
|
|
13079
|
+
menuOptions.push( {
|
|
13080
|
+
name: "Hide", icon: "EyeOff", callback: () => {
|
|
13081
|
+
data.colVisibilityMap[ idx ] = false;
|
|
13082
|
+
const cells = table.querySelectorAll(`tr > *:nth-child(${idx + this.rowOffsetCount + 1})`);
|
|
13083
|
+
cells.forEach( cell => {
|
|
13084
|
+
cell.style.display = ( cell.style.display === "none" ) ? "" : "none";
|
|
13085
|
+
} );
|
|
13086
|
+
}
|
|
13087
|
+
} );
|
|
13088
|
+
}
|
|
13089
|
+
|
|
12995
13090
|
th.addEventListener( 'click', event => {
|
|
13091
|
+
if( menuOptions.length === 0 ) return;
|
|
12996
13092
|
new LX.DropdownMenu( event.target, menuOptions, { side: "bottom", align: "start" });
|
|
12997
13093
|
});
|
|
12998
13094
|
|