lexgui 0.7.0 → 0.7.1

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/lexgui.css CHANGED
@@ -2478,7 +2478,7 @@ input[type=number] {
2478
2478
  --range-thumb-size: 1rem;
2479
2479
  --range-progress: currentColor;
2480
2480
  --range-fill: 1;
2481
- --range-thumb-padding: 0.15rem;
2481
+ --range-thumb-padding: 0.2rem;
2482
2482
  --range-bg: color-mix(in oklab,currentColor 20%,#0000);
2483
2483
  --range-dir: 1;
2484
2484
  --radius-selector: 0.5rem;
@@ -2521,7 +2521,19 @@ input[type=number] {
2521
2521
 
2522
2522
  .lexrangeslider.no-fill {
2523
2523
  --range-fill: 0;
2524
- --range-bg: currentColor;
2524
+ --in-range-color: color-mix(in oklab,currentColor 30%,#0000);
2525
+ --range-bg: linear-gradient(to right,
2526
+ var(--in-range-color) 0%,
2527
+ var(--in-range-color) calc(var(--range-min-value) + var(--range-fix-min-offset)),
2528
+ currentColor calc(var(--range-min-value) + var(--range-fix-min-offset)),
2529
+ currentColor calc( var(--range-max-value) - var(--range-fix-max-offset)),
2530
+ var(--in-range-color) calc( var(--range-max-value) - var(--range-fix-max-offset)),
2531
+ var(--in-range-color) 100%);
2532
+ background: var(--range-bg);
2533
+ }
2534
+
2535
+ .lexrangeslider.overlap {
2536
+ --range-bg: transparent;
2525
2537
  }
2526
2538
 
2527
2539
  .lexrangeslider:hover {
@@ -2560,6 +2572,7 @@ input[type=number] {
2560
2572
  background-color: currentColor;
2561
2573
  position: relative;
2562
2574
  top: 50%;
2575
+ pointer-events: all !important;
2563
2576
  transform: translateY(-50%);
2564
2577
  }
2565
2578
 
@@ -2574,6 +2587,7 @@ input[type=number] {
2574
2587
  background-color: currentColor;
2575
2588
  position: relative;
2576
2589
  top: 50%;
2590
+ pointer-events: all !important;
2577
2591
  }
2578
2592
 
2579
2593
  /* OTP Component */
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.0",
17
+ version: "0.7.1",
18
18
  ready: false,
19
19
  extensions: [], // Store extensions used
20
20
  signals: {}, // Events and triggers
@@ -769,7 +769,8 @@ class Popover {
769
769
  this.root.tabIndex = "1";
770
770
  this.root.className = "lexpopover";
771
771
 
772
- const nestedDialog = trigger.closest( "dialog" );
772
+ const refElement = trigger ?? this.reference;
773
+ const nestedDialog = refElement.closest( "dialog" );
773
774
  if( nestedDialog && nestedDialog.dataset[ "modal" ] == 'true' )
774
775
  {
775
776
  this._parent = nestedDialog;
@@ -6209,7 +6210,10 @@ LX.makeContainer = makeContainer;
6209
6210
  * @param {Object} options
6210
6211
  * side: Side of the tooltip
6211
6212
  * offset: Tooltip margin offset
6213
+ * offsetX: Tooltip margin horizontal offset
6214
+ * offsetY: Tooltip margin vertical offset
6212
6215
  * active: Tooltip active by default [true]
6216
+ * callback: Callback function to execute when the tooltip is shown
6213
6217
  */
6214
6218
 
6215
6219
  function asTooltip( trigger, content, options = {} )
@@ -6221,6 +6225,10 @@ function asTooltip( trigger, content, options = {} )
6221
6225
  let tooltipDom = null;
6222
6226
  let tooltipParent = LX.root;
6223
6227
 
6228
+ const _offset = options.offset ?? 6;
6229
+ const _offsetX = options.offsetX ?? _offset;
6230
+ const _offsetY = options.offsetY ?? _offset;
6231
+
6224
6232
  trigger.addEventListener( "mouseenter", function(e) {
6225
6233
 
6226
6234
  if( trigger.dataset[ "disableTooltip" ] == "true" )
@@ -6230,7 +6238,7 @@ function asTooltip( trigger, content, options = {} )
6230
6238
 
6231
6239
  tooltipDom = document.createElement( "div" );
6232
6240
  tooltipDom.className = "lextooltip";
6233
- tooltipDom.innerHTML = content;
6241
+ tooltipDom.innerHTML = trigger.dataset[ "tooltipContent" ] ?? content;
6234
6242
 
6235
6243
  const nestedDialog = trigger.closest( "dialog" );
6236
6244
  if( nestedDialog && nestedDialog.dataset[ "modal" ] == 'true' )
@@ -6247,32 +6255,33 @@ function asTooltip( trigger, content, options = {} )
6247
6255
  LX.doAsync( () => {
6248
6256
 
6249
6257
  const position = [ 0, 0 ];
6258
+ const offsetX = parseFloat( trigger.dataset[ "tooltipOffsetX" ] ?? _offsetX );
6259
+ const offsetY = parseFloat( trigger.dataset[ "tooltipOffsetY" ] ?? _offsetY );
6250
6260
  const rect = this.getBoundingClientRect();
6251
- const offset = options.offset ?? 6;
6252
6261
  let alignWidth = true;
6253
6262
 
6254
6263
  switch( options.side ?? "top" )
6255
6264
  {
6256
6265
  case "left":
6257
- position[ 0 ] += ( rect.x - tooltipDom.offsetWidth - offset );
6266
+ position[ 0 ] += ( rect.x - tooltipDom.offsetWidth - offsetX );
6258
6267
  alignWidth = false;
6259
6268
  break;
6260
6269
  case "right":
6261
- position[ 0 ] += ( rect.x + rect.width + offset );
6270
+ position[ 0 ] += ( rect.x + rect.width + offsetX );
6262
6271
  alignWidth = false;
6263
6272
  break;
6264
6273
  case "top":
6265
- position[ 1 ] += ( rect.y - tooltipDom.offsetHeight - offset );
6274
+ position[ 1 ] += ( rect.y - tooltipDom.offsetHeight - offsetY );
6266
6275
  alignWidth = true;
6267
6276
  break;
6268
6277
  case "bottom":
6269
- position[ 1 ] += ( rect.y + rect.height + offset );
6278
+ position[ 1 ] += ( rect.y + rect.height + offsetY );
6270
6279
  alignWidth = true;
6271
6280
  break;
6272
6281
  }
6273
6282
 
6274
- if( alignWidth ) { position[ 0 ] += ( rect.x + rect.width * 0.5 ) - tooltipDom.offsetWidth * 0.5; }
6275
- else { position[ 1 ] += ( rect.y + rect.height * 0.5 ) - tooltipDom.offsetHeight * 0.5; }
6283
+ if( alignWidth ) { position[ 0 ] += ( rect.x + rect.width * 0.5 ) - tooltipDom.offsetWidth * 0.5 + offsetX; }
6284
+ else { position[ 1 ] += ( rect.y + rect.height * 0.5 ) - tooltipDom.offsetHeight * 0.5 + offsetY; }
6276
6285
 
6277
6286
  // Avoid collisions
6278
6287
  position[ 0 ] = LX.clamp( position[ 0 ], 0, window.innerWidth - tooltipDom.offsetWidth - 4 );
@@ -6287,6 +6296,11 @@ function asTooltip( trigger, content, options = {} )
6287
6296
 
6288
6297
  tooltipDom.style.left = `${ position[ 0 ] }px`;
6289
6298
  tooltipDom.style.top = `${ position[ 1 ] }px`;
6299
+
6300
+ if( options.callback )
6301
+ {
6302
+ options.callback( tooltipDom, trigger );
6303
+ }
6290
6304
  } );
6291
6305
  } );
6292
6306
 
@@ -11022,38 +11036,110 @@ class RangeInput extends BaseComponent {
11022
11036
 
11023
11037
  constructor( name, value, callback, options = {} ) {
11024
11038
 
11025
- super( BaseComponent.RANGE, name, value, options );
11039
+ const ogValue = LX.deepCopy( value );
11040
+
11041
+ super( BaseComponent.RANGE, name, LX.deepCopy( ogValue ), options );
11042
+
11043
+ const isRangeValue = ( value.constructor == Array && value.length == 2 );
11044
+ if( isRangeValue )
11045
+ {
11046
+ value = ogValue[ 0 ];
11047
+ options.fill = false; // Range inputs do not fill by default
11048
+ }
11026
11049
 
11027
11050
  this.onGetValue = () => {
11028
- return value;
11051
+ let finalValue = value;
11052
+ if( isRangeValue )
11053
+ {
11054
+ finalValue = [ value, ogValue[ 1 ] ];
11055
+ }
11056
+ else if( options.left )
11057
+ {
11058
+ finalValue = ( ( +slider.max ) - value + ( +slider.min ) );
11059
+ }
11060
+ return finalValue;
11029
11061
  };
11030
11062
 
11031
11063
  this.onSetValue = ( newValue, skipCallback, event ) => {
11032
11064
 
11033
- if( isNaN( newValue ) )
11065
+ let newTpContent = "";
11066
+
11067
+ const diff = ( options.max - options.min );
11068
+
11069
+ if( isRangeValue )
11034
11070
  {
11035
- return;
11071
+ slider.value = value = LX.clamp( +newValue[ 0 ], +slider.min, +slider.max );
11072
+ this._maxSlider.value = ogValue[ 1 ] = LX.clamp( +newValue[ 1 ], +slider.min, +slider.max );
11073
+
11074
+ // Update the range slider
11075
+ const diffOffset = ( value / diff ) - 0.5;
11076
+ const diffMaxOffset = ( ogValue[ 1 ] / diff ) - 0.5;
11077
+ const remappedMin = LX.remapRange( value, options.min, options.max, 0, 1 );
11078
+ const remappedMax = LX.remapRange( ogValue[ 1 ], options.min, options.max, 0, 1 );
11079
+ slider.style.setProperty("--range-min-value", `${ remappedMin * 100 }%`);
11080
+ slider.style.setProperty("--range-max-value", `${ remappedMax * 100 }%`);
11081
+ slider.style.setProperty("--range-fix-min-offset", `${ -diffOffset }rem`);
11082
+ slider.style.setProperty("--range-fix-max-offset", `${ diffMaxOffset }rem`);
11083
+
11084
+ container.dataset[ "tooltipOffsetX" ] = container.offsetWidth * remappedMin + container.offsetWidth * ( remappedMax - remappedMin ) * 0.5 - ( container.offsetWidth * 0.5 );
11085
+ newTpContent = `${ value } - ${ ogValue[ 1 ] }`;
11036
11086
  }
11087
+ else
11088
+ {
11089
+ if( isNaN( newValue ) )
11090
+ {
11091
+ return;
11092
+ }
11037
11093
 
11038
- slider.value = value = LX.clamp( +newValue, +slider.min, +slider.max );
11094
+ slider.value = value = LX.clamp( +newValue, +slider.min, +slider.max );
11095
+ const remapped = LX.remapRange( value, options.min, options.max, 0, 1 ) * 0.5;
11096
+ container.dataset[ "tooltipOffsetX" ] = container.offsetWidth * remapped - ( container.offsetWidth * 0.5 );
11097
+ newTpContent = `${ value }`;
11098
+ }
11099
+
11100
+ container.dataset[ "tooltipContent" ] = newTpContent;
11101
+ if( this._labelTooltip )
11102
+ {
11103
+ this._labelTooltip.innerHTML = newTpContent;
11104
+ }
11039
11105
 
11040
11106
  if( !skipCallback )
11041
11107
  {
11042
- this._trigger( new LX.IEvent( name, options.left ? ( ( +slider.max ) - value + ( +slider.min ) ) : value, event ), callback );
11108
+ let finalValue = value;
11109
+ if( isRangeValue )
11110
+ {
11111
+ finalValue = [ value, ogValue[ 1 ] ];
11112
+ }
11113
+ else if( options.left )
11114
+ {
11115
+ finalValue = ( ( +slider.max ) - value + ( +slider.min ) );
11116
+ }
11117
+
11118
+ this._trigger( new LX.IEvent( name, finalValue, event ), callback );
11043
11119
  }
11044
11120
  };
11045
11121
 
11046
11122
  this.onResize = ( rect ) => {
11047
11123
  const realNameWidth = ( this.root.domName?.style.width ?? "0px" );
11048
11124
  container.style.width = options.inputWidth ?? `calc( 100% - ${ realNameWidth })`;
11125
+ if( isRangeValue )
11126
+ {
11127
+ const diff = ( options.max - options.min );
11128
+ const diffOffset = ( value / diff ) - 0.5;
11129
+ const diffMaxOffset = ( ogValue[ 1 ] / diff ) - 0.5;
11130
+ slider.style.setProperty("--range-min-value", `${ LX.remapRange( value, options.min, options.max, 0, 1 ) * 100 }%`);
11131
+ slider.style.setProperty("--range-max-value", `${ LX.remapRange( ogValue[ 1 ], options.min, options.max, 0, 1 ) * 100 }%`);
11132
+ slider.style.setProperty("--range-fix-min-offset", `${ -diffOffset }rem`);
11133
+ slider.style.setProperty("--range-fix-max-offset", `${ diffMaxOffset }rem`);
11134
+ }
11049
11135
  };
11050
11136
 
11051
11137
  const container = document.createElement( 'div' );
11052
- container.className = "lexrange";
11138
+ container.className = "lexrange relative";
11053
11139
  this.root.appendChild( container );
11054
11140
 
11055
11141
  let slider = document.createElement( 'input' );
11056
- slider.className = "lexrangeslider " + ( options.className ?? "" );
11142
+ slider.className = "lexrangeslider " + ( isRangeValue ? "pointer-events-none " : "" ) + ( options.className ?? "" );
11057
11143
  slider.min = options.min ?? 0;
11058
11144
  slider.max = options.max ?? 100;
11059
11145
  slider.step = options.step ?? 1;
@@ -11065,16 +11151,9 @@ class RangeInput extends BaseComponent {
11065
11151
  value = LX.clamp( value, +slider.min, +slider.max );
11066
11152
  }
11067
11153
 
11068
- if( options.left )
11069
- {
11070
- value = ( ( +slider.max ) - value + ( +slider.min ) );
11071
- }
11072
-
11073
- slider.value = value;
11074
- container.appendChild( slider );
11075
-
11076
11154
  if( options.left ?? false )
11077
11155
  {
11156
+ value = ( ( +slider.max ) - value + ( +slider.min ) );
11078
11157
  slider.classList.add( "left" );
11079
11158
  }
11080
11159
 
@@ -11083,23 +11162,30 @@ class RangeInput extends BaseComponent {
11083
11162
  slider.classList.add( "no-fill" );
11084
11163
  }
11085
11164
 
11165
+ slider.value = value;
11166
+ container.appendChild( slider );
11167
+
11086
11168
  slider.addEventListener( "input", e => {
11087
- this.set( e.target.valueAsNumber, false, e );
11169
+ this.set( isRangeValue ? [ e.target.valueAsNumber, ogValue[ 1 ] ] : e.target.valueAsNumber, false, e );
11088
11170
  }, { passive: false });
11089
11171
 
11090
- slider.addEventListener( "mousedown", function( e ) {
11091
- if( options.onPress )
11092
- {
11093
- options.onPress.bind( slider )( e, slider );
11094
- }
11095
- }, false );
11172
+ // If its a range value, we need to update the slider using the thumbs
11173
+ if( !isRangeValue )
11174
+ {
11175
+ slider.addEventListener( "mousedown", function( e ) {
11176
+ if( options.onPress )
11177
+ {
11178
+ options.onPress.bind( slider )( e, slider );
11179
+ }
11180
+ }, false );
11096
11181
 
11097
- slider.addEventListener( "mouseup", function( e ) {
11098
- if( options.onRelease )
11099
- {
11100
- options.onRelease.bind( slider )( e, slider );
11101
- }
11102
- }, false );
11182
+ slider.addEventListener( "mouseup", function( e ) {
11183
+ if( options.onRelease )
11184
+ {
11185
+ options.onRelease.bind( slider )( e, slider );
11186
+ }
11187
+ }, false );
11188
+ }
11103
11189
 
11104
11190
  // Method to change min, max, step parameters
11105
11191
  this.setLimits = ( newMin, newMax, newStep ) => {
@@ -11109,7 +11195,47 @@ class RangeInput extends BaseComponent {
11109
11195
  BaseComponent._dispatchEvent( slider, "input", true );
11110
11196
  };
11111
11197
 
11112
- LX.doAsync( this.onResize.bind( this ) );
11198
+ LX.doAsync( () => {
11199
+
11200
+ this.onResize();
11201
+
11202
+ let offsetX = 0;
11203
+ if( isRangeValue )
11204
+ {
11205
+ const remappedMin = LX.remapRange( value, options.min, options.max, 0, 1 );
11206
+ const remappedMax = LX.remapRange( ogValue[ 1 ], options.min, options.max, 0, 1 );
11207
+ offsetX = container.offsetWidth * remappedMin + container.offsetWidth * ( remappedMax - remappedMin ) * 0.5 - ( container.offsetWidth * 0.5 );
11208
+ }
11209
+ else
11210
+ {
11211
+ const remapped = LX.remapRange( value, options.min, options.max, 0, 1 ) * 0.5;
11212
+ offsetX = container.offsetWidth * remapped - ( container.offsetWidth * 0.5 );
11213
+ }
11214
+ LX.asTooltip( container, `${ value }${ isRangeValue ? `- ${ ogValue[ 1 ] }` : `` }`, { offsetX, callback: ( tpDom ) => {
11215
+ this._labelTooltip = tpDom;
11216
+ } } );
11217
+ } );
11218
+
11219
+ if( ogValue.constructor == Array ) // Its a range value
11220
+ {
11221
+ let maxSlider = document.createElement( 'input' );
11222
+ maxSlider.className = "lexrangeslider no-fill pointer-events-none overlap absolute top-0 left-0 " + ( options.className ?? "" );
11223
+ maxSlider.min = options.min ?? 0;
11224
+ maxSlider.max = options.max ?? 100;
11225
+ maxSlider.step = options.step ?? 1;
11226
+ maxSlider.type = "range";
11227
+ maxSlider.disabled = options.disabled ?? false;
11228
+ this._maxSlider = maxSlider;
11229
+
11230
+ let maxRangeValue = ogValue[ 1 ];
11231
+ maxSlider.value = maxRangeValue = LX.clamp( maxRangeValue, +maxSlider.min, +maxSlider.max );
11232
+ container.appendChild( maxSlider );
11233
+
11234
+ maxSlider.addEventListener( "input", e => {
11235
+ ogValue[ 1 ] = +e.target.valueAsNumber;
11236
+ this.set( [ value, ogValue[ 1 ] ], false, e );
11237
+ }, { passive: false });
11238
+ }
11113
11239
  }
11114
11240
  }
11115
11241