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 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
- numOfDecimalPlaces = numOfDecimalPlaces[1].match(/[0#]+/g);
2392
- numOfDecimalPlaces = numOfDecimalPlaces[0]?.length ?? 0;
2393
- temp = temp.toExponential(numOfDecimalPlaces);
2394
- expo = temp.toString().split('e+');
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
- // Optional
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
- if (config.type === 'scientific') {
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
- mask = config.mask.toUpperCase().split('E+')[1];
2450
- ret = processPaddingZeros(mask, expo[1], config.decimal);
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
- expo[1] = ret;
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
- // Aria indication
5793
- current.modal.top = rect.y + s.el.offsetTop + 2;
5794
- current.modal.left = rect.x + 248;
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
- Object.prototype.hasOwnProperty.call(currentObject, key)
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
- Object.prototype.hasOwnProperty.call(currentObject, key) &&
12518
+ key in currentObject &&
12438
12519
  (currentObject[key] == null || ! isValidPathObj(currentObject[key]))
12439
12520
  ) {
12440
12521
  currentObject[key] = {};
12441
- } else if (!Object.prototype.hasOwnProperty.call(currentObject, key)) {
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 (Object.prototype.hasOwnProperty.call(currentObject, finalKey)) {
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.1.2',
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.1.2",
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.3",
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.1",
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",