jsuites 6.1.2 → 6.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/dist/jsuites.css +4 -2
- package/dist/jsuites.js +147 -66
- package/package.json +3 -3
package/dist/jsuites.css
CHANGED
|
@@ -3977,7 +3977,8 @@ body.lm-dark-mode {
|
|
|
3977
3977
|
}
|
|
3978
3978
|
|
|
3979
3979
|
.lm-menu-submenu > div.lm-menu-item:hover,
|
|
3980
|
-
.lm-menu-submenu > div.lm-menu-item[data-cursor="true"]
|
|
3980
|
+
.lm-menu-submenu > div.lm-menu-item[data-cursor="true"],
|
|
3981
|
+
.lm-menu-submenu > div.lm-menu-item[aria-expanded="true"] {
|
|
3981
3982
|
background-color: var(--lm-background-color-highlight, #ebebeb);
|
|
3982
3983
|
}
|
|
3983
3984
|
|
|
@@ -4007,7 +4008,8 @@ body.lm-dark-mode {
|
|
|
4007
4008
|
}
|
|
4008
4009
|
|
|
4009
4010
|
.lm-dark-mode .lm-menu-submenu > div.lm-menu-item:hover,
|
|
4010
|
-
.lm-dark-mode .lm-menu-submenu > div.lm-menu-item[data-cursor="true"]
|
|
4011
|
+
.lm-dark-mode .lm-menu-submenu > div.lm-menu-item[data-cursor="true"],
|
|
4012
|
+
.lm-dark-mode .lm-menu-submenu > div.lm-menu-item[aria-expanded="true"] {
|
|
4011
4013
|
background-color: var(--lm-background-color-highlight, #2d2d2d);
|
|
4012
4014
|
}
|
|
4013
4015
|
|
package/dist/jsuites.js
CHANGED
|
@@ -298,7 +298,7 @@ var jSuites;
|
|
|
298
298
|
// Number
|
|
299
299
|
fraction: [ '#{0,1}.*?\\?+\\/[0-9?]+' ],
|
|
300
300
|
// Currency tokens
|
|
301
|
-
currency: [ '#(.{1})##0?(.{1}0+)?( ?;(.*)?)?' ],
|
|
301
|
+
currency: [ '#(.{1})##0?(.{1}[0#]+)?( ?;(.*)?)?' ],
|
|
302
302
|
// Scientific
|
|
303
303
|
scientific: [ '[0#]+([.,]{1}0*#*)?E{1}\\+0+' ],
|
|
304
304
|
// Percentage
|
|
@@ -1749,7 +1749,7 @@ var jSuites;
|
|
|
1749
1749
|
this.values[this.index] = '';
|
|
1750
1750
|
}
|
|
1751
1751
|
},
|
|
1752
|
-
'#(.{1})##0?(.{1}0+)?( ?;(.*)?)?': function(v) {
|
|
1752
|
+
'#(.{1})##0?(.{1}[0#]+)?( ?;(.*)?)?': function(v) {
|
|
1753
1753
|
// Process first the number
|
|
1754
1754
|
parseMethods['[0#]+([.,]{1}0*#*)?'].call(this, v, true);
|
|
1755
1755
|
// Create the separators
|
|
@@ -2382,77 +2382,89 @@ var jSuites;
|
|
|
2382
2382
|
const adjustNumberOfDecimalPlaces = function(config, value) {
|
|
2383
2383
|
let temp = value;
|
|
2384
2384
|
let mask = config.mask;
|
|
2385
|
-
let expo;
|
|
2386
2385
|
|
|
2387
2386
|
if (config.type === 'scientific') {
|
|
2387
|
+
// Scientific notation handling
|
|
2388
2388
|
mask = config.mask.toUpperCase().split('E')[0];
|
|
2389
2389
|
|
|
2390
2390
|
let numOfDecimalPlaces = mask.split(config.decimal);
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
temp = Number(expo[0]);
|
|
2396
|
-
}
|
|
2397
|
-
|
|
2398
|
-
if (mask.indexOf(config.decimal) === -1) {
|
|
2399
|
-
// No decimal places
|
|
2400
|
-
if (! Number.isInteger(temp)) {
|
|
2401
|
-
temp = temp.toFixed(0);
|
|
2402
|
-
}
|
|
2403
|
-
} else {
|
|
2404
|
-
// Length of the decimal
|
|
2405
|
-
let mandatoryDecimalPlaces = mask.split(config.decimal);
|
|
2406
|
-
mandatoryDecimalPlaces = mandatoryDecimalPlaces[1].match(/0+/g);
|
|
2407
|
-
if (mandatoryDecimalPlaces) {
|
|
2408
|
-
mandatoryDecimalPlaces = mandatoryDecimalPlaces[0].length;
|
|
2409
|
-
} else {
|
|
2410
|
-
mandatoryDecimalPlaces = 0;
|
|
2411
|
-
}
|
|
2412
|
-
// Amount of decimal
|
|
2413
|
-
let numOfDecimalPlaces = temp.toString().split(config.decimal)
|
|
2414
|
-
numOfDecimalPlaces = numOfDecimalPlaces[1]?.length ?? 0;
|
|
2415
|
-
// Necessary adjustment
|
|
2416
|
-
let necessaryAdjustment = 0;
|
|
2417
|
-
if (numOfDecimalPlaces < mandatoryDecimalPlaces) {
|
|
2418
|
-
necessaryAdjustment = mandatoryDecimalPlaces;
|
|
2391
|
+
// Handle masks without decimal (e.g., '0E+00')
|
|
2392
|
+
if (numOfDecimalPlaces[1]) {
|
|
2393
|
+
numOfDecimalPlaces = numOfDecimalPlaces[1].match(/[0#]+/g);
|
|
2394
|
+
numOfDecimalPlaces = numOfDecimalPlaces[0]?.length ?? 0;
|
|
2419
2395
|
} else {
|
|
2420
|
-
|
|
2421
|
-
let optionalDecimalPlaces = mask.split(config.decimal);
|
|
2422
|
-
optionalDecimalPlaces = optionalDecimalPlaces[1].match(/[0#]+/g);
|
|
2423
|
-
if (optionalDecimalPlaces) {
|
|
2424
|
-
optionalDecimalPlaces = optionalDecimalPlaces[0].length;
|
|
2425
|
-
if (numOfDecimalPlaces > optionalDecimalPlaces) {
|
|
2426
|
-
necessaryAdjustment = optionalDecimalPlaces;
|
|
2427
|
-
}
|
|
2428
|
-
}
|
|
2429
|
-
}
|
|
2430
|
-
// Adjust decimal numbers if applicable
|
|
2431
|
-
if (necessaryAdjustment) {
|
|
2432
|
-
let t = temp.toFixed(necessaryAdjustment);
|
|
2433
|
-
let n = temp.toString().split('.');
|
|
2434
|
-
let fraction = n[1];
|
|
2435
|
-
if (fraction && fraction.length > necessaryAdjustment && fraction[fraction.length - 1] === '5') {
|
|
2436
|
-
t = parseFloat(n[0] + '.' + fraction + '1').toFixed(necessaryAdjustment);
|
|
2437
|
-
}
|
|
2438
|
-
temp = t;
|
|
2396
|
+
numOfDecimalPlaces = 0;
|
|
2439
2397
|
}
|
|
2440
|
-
|
|
2398
|
+
temp = temp.toExponential(numOfDecimalPlaces);
|
|
2399
|
+
// Split by 'e' to handle both positive (e+) and negative (e-) exponents
|
|
2400
|
+
let expo = temp.toString().split('e');
|
|
2401
|
+
// Keep coefficient as string to preserve decimal places (e.g., '1.00' not 1)
|
|
2402
|
+
temp = expo[0];
|
|
2441
2403
|
|
|
2442
|
-
|
|
2404
|
+
// Process padding zeros for coefficient
|
|
2443
2405
|
let ret = processPaddingZeros(mask, temp, config.decimal);
|
|
2444
2406
|
if (ret) {
|
|
2445
2407
|
temp = ret;
|
|
2446
2408
|
}
|
|
2447
2409
|
expo[0] = temp;
|
|
2448
2410
|
|
|
2449
|
-
|
|
2450
|
-
|
|
2411
|
+
// Handle both E+ and E- in mask for exponent
|
|
2412
|
+
mask = config.mask.toUpperCase().split(/E[+-]?/)[1];
|
|
2413
|
+
ret = processPaddingZeros(mask, expo[1]?.replace(/^[+-]/, ''), config.decimal);
|
|
2451
2414
|
if (ret) {
|
|
2452
|
-
|
|
2415
|
+
// Preserve the sign from the original exponent
|
|
2416
|
+
let sign = expo[1]?.charAt(0);
|
|
2417
|
+
expo[1] = (sign === '-' ? '-' : '+') + ret;
|
|
2453
2418
|
}
|
|
2454
2419
|
|
|
2455
|
-
temp = expo.join('e
|
|
2420
|
+
temp = expo.join('e');
|
|
2421
|
+
} else {
|
|
2422
|
+
// Non-scientific decimal adjustment
|
|
2423
|
+
if (mask.indexOf(config.decimal) === -1) {
|
|
2424
|
+
// No decimal places
|
|
2425
|
+
if (! Number.isInteger(temp)) {
|
|
2426
|
+
temp = temp.toFixed(0);
|
|
2427
|
+
}
|
|
2428
|
+
} else {
|
|
2429
|
+
// Length of the decimal
|
|
2430
|
+
let mandatoryDecimalPlaces = mask.split(config.decimal);
|
|
2431
|
+
mandatoryDecimalPlaces = mandatoryDecimalPlaces[1].match(/0+/g);
|
|
2432
|
+
if (mandatoryDecimalPlaces) {
|
|
2433
|
+
mandatoryDecimalPlaces = mandatoryDecimalPlaces[0].length;
|
|
2434
|
+
} else {
|
|
2435
|
+
mandatoryDecimalPlaces = 0;
|
|
2436
|
+
}
|
|
2437
|
+
|
|
2438
|
+
// Amount of decimal (use original value to check decimal separator)
|
|
2439
|
+
let valueStr = value.toString();
|
|
2440
|
+
let numOfDecimalPlaces = valueStr.split(valueStr.includes('.') ? '.' : (config.decimal || '.'))
|
|
2441
|
+
numOfDecimalPlaces = numOfDecimalPlaces[1]?.length ?? 0;
|
|
2442
|
+
// Necessary adjustment
|
|
2443
|
+
let necessaryAdjustment = 0;
|
|
2444
|
+
if (numOfDecimalPlaces < mandatoryDecimalPlaces) {
|
|
2445
|
+
necessaryAdjustment = mandatoryDecimalPlaces;
|
|
2446
|
+
} else {
|
|
2447
|
+
// Optional
|
|
2448
|
+
let optionalDecimalPlaces = mask.split(config.decimal);
|
|
2449
|
+
optionalDecimalPlaces = optionalDecimalPlaces[1].match(/[0#]+/g);
|
|
2450
|
+
if (optionalDecimalPlaces) {
|
|
2451
|
+
optionalDecimalPlaces = optionalDecimalPlaces[0].length;
|
|
2452
|
+
if (numOfDecimalPlaces > optionalDecimalPlaces) {
|
|
2453
|
+
necessaryAdjustment = optionalDecimalPlaces;
|
|
2454
|
+
}
|
|
2455
|
+
}
|
|
2456
|
+
}
|
|
2457
|
+
// Adjust decimal numbers if applicable
|
|
2458
|
+
if (necessaryAdjustment) {
|
|
2459
|
+
let t = temp.toFixed(necessaryAdjustment);
|
|
2460
|
+
let n = temp.toString().split('.');
|
|
2461
|
+
let fraction = n[1];
|
|
2462
|
+
if (fraction && fraction.length > necessaryAdjustment && fraction[fraction.length - 1] === '5') {
|
|
2463
|
+
t = parseFloat(n[0] + '.' + fraction + '1').toFixed(necessaryAdjustment);
|
|
2464
|
+
}
|
|
2465
|
+
temp = t;
|
|
2466
|
+
}
|
|
2467
|
+
}
|
|
2456
2468
|
}
|
|
2457
2469
|
|
|
2458
2470
|
return temp;
|
|
@@ -3598,12 +3610,15 @@ var jSuites;
|
|
|
3598
3610
|
return value;
|
|
3599
3611
|
};
|
|
3600
3612
|
|
|
3601
|
-
Component.render = function(value, options, fullMask) {
|
|
3613
|
+
Component.render = function(value, options, fullMask, strict) {
|
|
3602
3614
|
// Nothing to render
|
|
3603
3615
|
if (value === '' || value === undefined || value === null) {
|
|
3604
3616
|
return '';
|
|
3605
3617
|
}
|
|
3606
3618
|
|
|
3619
|
+
// Store original value for strict mode
|
|
3620
|
+
const originalValue = value;
|
|
3621
|
+
|
|
3607
3622
|
// Config
|
|
3608
3623
|
const config = getConfig(options, value);
|
|
3609
3624
|
|
|
@@ -3624,6 +3639,11 @@ var jSuites;
|
|
|
3624
3639
|
value = value.toString();
|
|
3625
3640
|
}
|
|
3626
3641
|
} else {
|
|
3642
|
+
// Strict mode: for numeric masks, if string input is not a valid number,
|
|
3643
|
+
// return original value unchanged (Excel-like behavior)
|
|
3644
|
+
if (strict && typeof(originalValue) === 'string' && !isNumber(originalValue)) {
|
|
3645
|
+
return originalValue;
|
|
3646
|
+
}
|
|
3627
3647
|
if (config.type === 'percentage') {
|
|
3628
3648
|
if (typeof (value) === 'string' && value.indexOf('%') !== -1) {
|
|
3629
3649
|
value = value.replace('%', '');
|
|
@@ -5714,7 +5734,7 @@ if (! Modal && "function" === 'function') {
|
|
|
5714
5734
|
// Initialize expanded state
|
|
5715
5735
|
self.expanded = false;
|
|
5716
5736
|
|
|
5717
|
-
if (self.type === 'line') {
|
|
5737
|
+
if (self.type === 'line' || self.type === 'divisor') {
|
|
5718
5738
|
return `<hr role="separator" />`;
|
|
5719
5739
|
} else if (self.type === 'inline') {
|
|
5720
5740
|
return `<div></div>`;
|
|
@@ -5789,9 +5809,69 @@ if (! Modal && "function" === 'function') {
|
|
|
5789
5809
|
let rect = parent.modal.el.getBoundingClientRect();
|
|
5790
5810
|
// Update modal
|
|
5791
5811
|
current.modal.open();
|
|
5792
|
-
|
|
5793
|
-
|
|
5794
|
-
|
|
5812
|
+
|
|
5813
|
+
// Calculate initial position using item's actual screen position (accounts for scroll)
|
|
5814
|
+
let itemRect = s.el.getBoundingClientRect();
|
|
5815
|
+
let submenuWidth = 250;
|
|
5816
|
+
let submenuTop = itemRect.y;
|
|
5817
|
+
let submenuLeft = rect.x + rect.width - 2; // Position to the right of parent
|
|
5818
|
+
|
|
5819
|
+
// Check if parent was positioned to the left (has negative margin or is on left side)
|
|
5820
|
+
let parentOpenedLeft = parent.openedLeft || false;
|
|
5821
|
+
|
|
5822
|
+
// Check horizontal space
|
|
5823
|
+
let spaceOnRight = window.innerWidth - (rect.x + rect.width);
|
|
5824
|
+
let spaceOnLeft = rect.x;
|
|
5825
|
+
|
|
5826
|
+
// Determine which side to open the submenu
|
|
5827
|
+
let openLeft = parentOpenedLeft; // Follow parent's direction by default
|
|
5828
|
+
|
|
5829
|
+
// If parent opened to right, check if we still have space
|
|
5830
|
+
if (!parentOpenedLeft && spaceOnRight < submenuWidth + 10) {
|
|
5831
|
+
// Not enough space on right, switch to left
|
|
5832
|
+
openLeft = true;
|
|
5833
|
+
}
|
|
5834
|
+
// If parent opened to left, check if we still have space on left
|
|
5835
|
+
if (parentOpenedLeft && spaceOnLeft < submenuWidth + 10) {
|
|
5836
|
+
// Not enough space on left, switch to right if possible
|
|
5837
|
+
if (spaceOnRight >= submenuWidth + 10) {
|
|
5838
|
+
openLeft = false;
|
|
5839
|
+
}
|
|
5840
|
+
}
|
|
5841
|
+
|
|
5842
|
+
if (openLeft) {
|
|
5843
|
+
// Position to the left of parent menu
|
|
5844
|
+
submenuLeft = rect.x - submenuWidth + 2;
|
|
5845
|
+
// Ensure it doesn't go off the left edge
|
|
5846
|
+
if (submenuLeft < 10) {
|
|
5847
|
+
submenuLeft = 10;
|
|
5848
|
+
}
|
|
5849
|
+
current.openedLeft = true;
|
|
5850
|
+
} else {
|
|
5851
|
+
current.openedLeft = false;
|
|
5852
|
+
}
|
|
5853
|
+
|
|
5854
|
+
// Set position
|
|
5855
|
+
current.modal.top = submenuTop;
|
|
5856
|
+
current.modal.left = submenuLeft;
|
|
5857
|
+
|
|
5858
|
+
// Adjust vertical position after render
|
|
5859
|
+
queueMicrotask(() => {
|
|
5860
|
+
let submenuEl = current.modal.el;
|
|
5861
|
+
let submenuRect = submenuEl.getBoundingClientRect();
|
|
5862
|
+
|
|
5863
|
+
// Check if submenu goes off the bottom
|
|
5864
|
+
if (submenuRect.bottom > window.innerHeight - 10) {
|
|
5865
|
+
let overflow = submenuRect.bottom - (window.innerHeight - 10);
|
|
5866
|
+
let newTop = submenuTop - overflow;
|
|
5867
|
+
// Don't go above the top of the screen
|
|
5868
|
+
if (newTop < 10) {
|
|
5869
|
+
newTop = 10;
|
|
5870
|
+
}
|
|
5871
|
+
current.modal.top = newTop;
|
|
5872
|
+
}
|
|
5873
|
+
});
|
|
5874
|
+
|
|
5795
5875
|
// Keep current item for each modal
|
|
5796
5876
|
current.item = s;
|
|
5797
5877
|
s.expanded = true;
|
|
@@ -6052,6 +6132,7 @@ if (! Modal && "function" === 'function') {
|
|
|
6052
6132
|
menu.item.expanded = false;
|
|
6053
6133
|
menu.item = null;
|
|
6054
6134
|
}
|
|
6135
|
+
menu.openedLeft = false;
|
|
6055
6136
|
menu.modal.close();
|
|
6056
6137
|
}
|
|
6057
6138
|
});
|
|
@@ -12409,7 +12490,7 @@ function Path(pathString, value, remove) {
|
|
|
12409
12490
|
if (
|
|
12410
12491
|
currentObject != null &&
|
|
12411
12492
|
isValidPathObj(currentObject) &&
|
|
12412
|
-
|
|
12493
|
+
key in currentObject
|
|
12413
12494
|
) {
|
|
12414
12495
|
currentObject = currentObject[key];
|
|
12415
12496
|
} else {
|
|
@@ -12434,11 +12515,11 @@ function Path(pathString, value, remove) {
|
|
|
12434
12515
|
|
|
12435
12516
|
// If the key exists but is null/undefined or a non-object, replace it with an empty object
|
|
12436
12517
|
if (
|
|
12437
|
-
|
|
12518
|
+
key in currentObject &&
|
|
12438
12519
|
(currentObject[key] == null || ! isValidPathObj(currentObject[key]))
|
|
12439
12520
|
) {
|
|
12440
12521
|
currentObject[key] = {};
|
|
12441
|
-
} else if (!
|
|
12522
|
+
} else if (!(key in currentObject)) {
|
|
12442
12523
|
// If the key doesn't exist, create an empty object
|
|
12443
12524
|
currentObject[key] = {};
|
|
12444
12525
|
}
|
|
@@ -12457,7 +12538,7 @@ function Path(pathString, value, remove) {
|
|
|
12457
12538
|
|
|
12458
12539
|
// Delete the property if remove is true
|
|
12459
12540
|
if (remove === true) {
|
|
12460
|
-
if (
|
|
12541
|
+
if (finalKey in currentObject) {
|
|
12461
12542
|
delete currentObject[finalKey];
|
|
12462
12543
|
return true;
|
|
12463
12544
|
}
|
|
@@ -23065,7 +23146,7 @@ var jSuites = {
|
|
|
23065
23146
|
...dictionary,
|
|
23066
23147
|
...helpers,
|
|
23067
23148
|
/** Current version */
|
|
23068
|
-
version: '6.
|
|
23149
|
+
version: '6.2.0',
|
|
23069
23150
|
/** Bind new extensions to Jsuites */
|
|
23070
23151
|
setExtensions: function(o) {
|
|
23071
23152
|
if (typeof(o) == 'object') {
|
package/package.json
CHANGED
|
@@ -26,16 +26,16 @@
|
|
|
26
26
|
},
|
|
27
27
|
"main": "dist/jsuites.js",
|
|
28
28
|
"types": "dist/jsuites.d.ts",
|
|
29
|
-
"version": "6.
|
|
29
|
+
"version": "6.2.0",
|
|
30
30
|
"bugs": "https://github.com/jsuites/jsuites/issues",
|
|
31
31
|
"homepage": "https://github.com/jsuites/jsuites",
|
|
32
32
|
"docs": "https://jsuites.net",
|
|
33
33
|
"download": "https://github.com/jsuites/jsuites/archive/master.zip",
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@jsuites/utils": "^6.0.
|
|
35
|
+
"@jsuites/utils": "^6.0.4",
|
|
36
36
|
"@lemonadejs/calendar": "^5.8.3",
|
|
37
37
|
"@lemonadejs/color": "^5.8.0",
|
|
38
|
-
"@lemonadejs/contextmenu": "^5.8.
|
|
38
|
+
"@lemonadejs/contextmenu": "^5.8.3",
|
|
39
39
|
"@lemonadejs/dropdown": "^5.8.2",
|
|
40
40
|
"@lemonadejs/modal": "^5.8.2",
|
|
41
41
|
"@lemonadejs/rating": "^5.8.1",
|