lexgui 0.7.8 → 0.7.10

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
@@ -252,6 +252,11 @@ body {
252
252
  box-sizing: border-box;
253
253
  }
254
254
 
255
+ .no-transition,
256
+ .no-transition * {
257
+ transition: none !important;
258
+ }
259
+
255
260
  blockquote, dd, dl, figure, h1, h2, h3, h4, h5, h6, hr, p, pre {
256
261
  margin: 0;
257
262
  }
@@ -4471,28 +4476,40 @@ meter:-moz-meter-sub-sub-optimum::-moz-meter-bar {
4471
4476
  margin-left: 12px;
4472
4477
  }
4473
4478
 
4479
+ /* Height, Width transitions */
4480
+
4481
+ .lexarea .minimize-vertical, .lexarea .maximize-vertical {
4482
+ transition: height 0.1s ease-out;
4483
+ }
4484
+
4485
+ .lexarea .minimize-horizontal, .lexarea .maximize-horizontal {
4486
+ transition: width 0.1s ease-out;
4487
+ }
4488
+
4489
+ /* Opacity transitions */
4490
+
4474
4491
  .lexarea .fadein-vertical {
4475
4492
  animation-name: fadein;
4493
+ animation-duration: 0.1s;
4476
4494
  animation-fill-mode: forwards;
4477
4495
  }
4478
4496
 
4479
4497
  .lexarea .fadeout-vertical {
4480
4498
  animation-name: fadeout;
4481
- animation-duration: 0.25s;
4499
+ animation-duration: 0.1s;
4482
4500
  animation-fill-mode: forwards;
4483
- transition: height;
4484
4501
  }
4485
4502
 
4486
4503
  .lexarea .fadein-horizontal {
4487
4504
  animation-name: fadein;
4505
+ animation-duration: 0.1s;
4488
4506
  animation-fill-mode: forwards;
4489
4507
  }
4490
4508
 
4491
4509
  .lexarea .fadeout-horizontal {
4492
4510
  animation-name: fadeout;
4493
- animation-duration: 0.25s;
4511
+ animation-duration: 0.1s;
4494
4512
  animation-fill-mode: forwards;
4495
- transition: width;
4496
4513
  }
4497
4514
 
4498
4515
  @keyframes fadein {
@@ -4711,7 +4728,7 @@ ul.lexassetscontent {
4711
4728
  }
4712
4729
 
4713
4730
  .lexassetscontent li.script {
4714
- border-color: rgb(104, 129, 195);
4731
+ border-color: rgb(207, 127, 36);
4715
4732
  }
4716
4733
 
4717
4734
  .lexassetscontent li.json {
@@ -4730,6 +4747,10 @@ ul.lexassetscontent {
4730
4747
  border-color: rgb(154, 188, 101);
4731
4748
  }
4732
4749
 
4750
+ .lexassetscontent li.video {
4751
+ border-color: rgb(84, 119, 214);
4752
+ }
4753
+
4733
4754
  .lexassetscontent li:hover {
4734
4755
  outline: 2px solid var(--global-color-accent);
4735
4756
  }
@@ -4825,6 +4846,12 @@ ul.lexassetscontent {
4825
4846
  transition: all 0.2s;
4826
4847
  }
4827
4848
 
4849
+ .lexassetscontent li video {
4850
+ z-index: 1;
4851
+ object-fit: cover;
4852
+ height: calc(100% - 24px);
4853
+ }
4854
+
4828
4855
  .lexassetscontent.list img, .lexassetscontent.compact img {
4829
4856
  width: unset;
4830
4857
  object-fit: contain;
@@ -6348,6 +6375,7 @@ ul.lexassetscontent {
6348
6375
  .w-full { width: 100% }
6349
6376
  .w-screen { width: 100vw }
6350
6377
  .w-auto { width: auto }
6378
+ .w-fit-content { width: fit-content }
6351
6379
 
6352
6380
  .w-2\/3 { width: 66.666% }
6353
6381
  .w-1\/2 { width: 50% }
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.8",
17
+ version: "0.7.10",
18
18
  ready: false,
19
19
  extensions: [], // Store extensions used
20
20
  signals: {}, // Events and triggers
@@ -1332,18 +1332,18 @@ class DropdownMenu {
1332
1332
  else
1333
1333
  {
1334
1334
  menuItem.addEventListener( "click", () => {
1335
- const f = item.callback;
1336
- if( f )
1337
- {
1338
- f.call( this, key, menuItem );
1339
- }
1340
-
1341
1335
  const radioName = menuItem.getAttribute( "data-radioname" );
1342
1336
  if( radioName )
1343
1337
  {
1344
1338
  this._trigger[ radioName ] = key;
1345
1339
  }
1346
1340
 
1341
+ const f = item.callback;
1342
+ if( f )
1343
+ {
1344
+ f.call( this, key, menuItem, radioName );
1345
+ }
1346
+
1347
1347
  // If has options, it's a radio group label, so don't close the menu
1348
1348
  if( !item.options && ( item.closeOnClick ?? true ) )
1349
1349
  {
@@ -2584,9 +2584,11 @@ class Tabs {
2584
2584
 
2585
2585
  if( isSelected && this.thumb )
2586
2586
  {
2587
+ this.thumb.classList.add( "no-transition" );
2587
2588
  this.thumb.style.transform = "translate( " + ( tabEl.childIndex * tabEl.offsetWidth ) + "px )";
2588
2589
  this.thumb.style.width = ( tabEl.offsetWidth ) + "px";
2589
2590
  this.thumb.item = tabEl;
2591
+ this.thumb.classList.remove( "no-transition" );
2590
2592
  }
2591
2593
 
2592
2594
  }, 10 );
@@ -5542,47 +5544,49 @@ function makeCodeSnippet( code, size, options = { } )
5542
5544
  disableEdition: true,
5543
5545
  allowAddScripts: false,
5544
5546
  name: options.tabName,
5545
- // showTab: options.showTab ?? true
5546
- } );
5547
- editor.setText( code, options.language ?? "Plain Text" );
5548
-
5549
- if( options.linesAdded )
5550
- {
5551
- const code = editor.root.querySelector( ".code" );
5552
- for( let l of options.linesAdded )
5547
+ callback: () =>
5553
5548
  {
5554
- if( l.constructor == Number )
5555
- {
5556
- code.childNodes[ l - 1 ].classList.add( "added" );
5557
- }
5558
- else if( l.constructor == Array ) // It's a range
5549
+ if( options.linesAdded )
5559
5550
  {
5560
- for( let i = ( l[ 0 ] - 1 ); i <= ( l[ 1 ] - 1 ); i++ )
5551
+ const code = editor.root.querySelector( ".code" );
5552
+ for( let l of options.linesAdded )
5561
5553
  {
5562
- code.childNodes[ i ].classList.add( "added" );
5554
+ if( l.constructor == Number )
5555
+ {
5556
+ code.childNodes[ l - 1 ].classList.add( "added" );
5557
+ }
5558
+ else if( l.constructor == Array ) // It's a range
5559
+ {
5560
+ for( let i = ( l[ 0 ] - 1 ); i <= ( l[ 1 ] - 1 ); i++ )
5561
+ {
5562
+ code.childNodes[ i ].classList.add( "added" );
5563
+ }
5564
+ }
5563
5565
  }
5564
5566
  }
5565
- }
5566
- }
5567
5567
 
5568
- if( options.linesRemoved )
5569
- {
5570
- const code = editor.root.querySelector( ".code" );
5571
- for( let l of options.linesRemoved )
5572
- {
5573
- if( l.constructor == Number )
5568
+ if( options.linesRemoved )
5574
5569
  {
5575
- code.childNodes[ l - 1 ].classList.add( "removed" );
5576
- }
5577
- else if( l.constructor == Array ) // It's a range
5578
- {
5579
- for( let i = ( l[ 0 ] - 1 ); i <= ( l[ 1 ] - 1 ); i++ )
5570
+ const code = editor.root.querySelector( ".code" );
5571
+ for( let l of options.linesRemoved )
5580
5572
  {
5581
- code.childNodes[ i ].classList.add( "removed" );
5573
+ if( l.constructor == Number )
5574
+ {
5575
+ code.childNodes[ l - 1 ].classList.add( "removed" );
5576
+ }
5577
+ else if( l.constructor == Array ) // It's a range
5578
+ {
5579
+ for( let i = ( l[ 0 ] - 1 ); i <= ( l[ 1 ] - 1 ); i++ )
5580
+ {
5581
+ code.childNodes[ i ].classList.add( "removed" );
5582
+ }
5583
+ }
5582
5584
  }
5583
5585
  }
5584
5586
  }
5585
- }
5587
+ } );
5588
+
5589
+ editor.setText( code, options.language ?? "Plain Text" );
5586
5590
 
5587
5591
  if( options.windowMode )
5588
5592
  {
@@ -5607,6 +5611,7 @@ function makeCodeSnippet( code, size, options = { } )
5607
5611
  }
5608
5612
 
5609
5613
  snippet.appendChild( area.root );
5614
+
5610
5615
  return snippet;
5611
5616
  }
5612
5617
 
@@ -7539,21 +7544,25 @@ class Area {
7539
7544
  let [ area1, area2 ] = this.sections;
7540
7545
  this.splitExtended = true;
7541
7546
 
7547
+ area1.root.classList.add( `maximize-${ this.type }` );
7548
+ area2.root.classList.add( `minimize-${ this.type }` );
7549
+ area2.root.classList.add( `fadeout-${ this.type }` );
7550
+ area2.root.classList.remove( `fadein-${ this.type }` );
7551
+
7542
7552
  if( this.type == "vertical" )
7543
7553
  {
7544
7554
  this.offset = area2.root.offsetHeight;
7545
- area2.root.classList.add("fadeout-vertical");
7546
7555
  this._moveSplit( -Infinity, true );
7547
-
7548
7556
  }
7549
7557
  else
7550
7558
  {
7551
7559
  this.offset = area2.root.offsetWidth - 8; // Force some height here...
7552
- area2.root.classList.add("fadeout-horizontal");
7553
7560
  this._moveSplit( -Infinity, true, 8 );
7554
7561
  }
7555
7562
 
7556
- LX.doAsync( () => this.propagateEvent('onresize'), 150 );
7563
+ LX.doAsync( () => {
7564
+ this.propagateEvent( 'onresize' );
7565
+ }, 100 );
7557
7566
  }
7558
7567
 
7559
7568
  /**
@@ -7563,23 +7572,24 @@ class Area {
7563
7572
  reduce() {
7564
7573
 
7565
7574
  if( !this.splitExtended )
7566
- return;
7575
+ {
7576
+ return;
7577
+ }
7567
7578
 
7568
7579
  this.splitExtended = false;
7569
- let [area1, area2] = this.sections;
7570
7580
 
7571
- if( this.type == "vertical")
7572
- {
7573
- area2.root.classList.add("fadein-vertical");
7574
- this._moveSplit(this.offset);
7575
- }
7576
- else
7577
- {
7578
- area2.root.classList.add("fadein-horizontal");
7579
- this._moveSplit(this.offset);
7580
- }
7581
+ let [ area1, area2 ] = this.sections;
7582
+
7583
+ area1.root.classList.add( `minimize-${ this.type }` );
7584
+ area2.root.classList.add( `maximize-${ this.type }` );
7585
+ area2.root.classList.add( `fadein-${ this.type }` );
7586
+ area2.root.classList.remove( `fadeout-${ this.type }` );
7581
7587
 
7582
- LX.doAsync( () => this.propagateEvent('onresize'), 150 );
7588
+ this._moveSplit( this.offset );
7589
+
7590
+ LX.doAsync( () => {
7591
+ this.propagateEvent( 'onresize' );
7592
+ }, 100 );
7583
7593
  }
7584
7594
 
7585
7595
  /**
@@ -15169,17 +15179,26 @@ class Menubar {
15169
15179
  } });
15170
15180
  };
15171
15181
 
15172
- entry.addEventListener("click", () => {
15182
+ entry.addEventListener("mousedown", (e) => {
15183
+ e.preventDefault();
15184
+ });
15185
+
15186
+ entry.addEventListener("mouseup", (e) => {
15187
+
15188
+ e.preventDefault();
15189
+
15173
15190
  const f = item[ 'callback' ];
15174
15191
  if( f )
15175
15192
  {
15176
- f.call( this, key, entry );
15193
+ f.call( this, key, entry, e );
15177
15194
  return;
15178
15195
  }
15179
15196
 
15180
15197
  _showEntry();
15181
15198
 
15182
15199
  this.focused = true;
15200
+
15201
+ return false;
15183
15202
  });
15184
15203
 
15185
15204
  entry.addEventListener( "mouseover", (e) => {
@@ -15346,7 +15365,12 @@ class Menubar {
15346
15365
  }
15347
15366
 
15348
15367
  const _b = button.querySelector('a');
15349
- _b.addEventListener("click", (e) => {
15368
+
15369
+ _b.addEventListener( "mousedown", (e) => {
15370
+ e.preventDefault();
15371
+ });
15372
+
15373
+ _b.addEventListener( "mouseup", (e) => {
15350
15374
  if( callback && !disabled )
15351
15375
  {
15352
15376
  callback.call( this, _b, e );
@@ -16581,13 +16605,13 @@ class AssetView {
16581
16605
  const isListLayout = ( this.layout == AssetView.LAYOUT_LIST );
16582
16606
 
16583
16607
  this.filter = filter ?? ( this.filter ?? "None" );
16584
- this.searchValue = searchValue ?? (this.searchValue ?? "");
16608
+ this.searchValue = searchValue ?? ( this.searchValue ?? "" );
16585
16609
  this.content.innerHTML = "";
16586
16610
  this.content.className = `lexassetscontent${ isCompactLayout ? " compact" : ( isListLayout ? " list" : "" ) }`;
16587
16611
  let that = this;
16588
16612
 
16589
- const _addItem = function(item) {
16590
-
16613
+ const _addItem = function( item )
16614
+ {
16591
16615
  const type = item.type.charAt( 0 ).toUpperCase() + item.type.slice( 1 );
16592
16616
  const extension = LX.getExtension( item.id );
16593
16617
  const isFolder = type === "Folder";
@@ -16606,10 +16630,11 @@ class AssetView {
16606
16630
  {
16607
16631
  let desc = document.createElement( 'span' );
16608
16632
  desc.className = 'lexitemdesc';
16609
- desc.innerHTML = "File: " + item.id + "<br>Type: " + type;
16633
+ desc.id = `floatingTitle_${ item.id }`;
16634
+ desc.innerHTML = `File: ${ item.id }<br>Type: ${ type }`;
16610
16635
  that.content.appendChild( desc );
16611
16636
 
16612
- itemEl.addEventListener("mousemove", e => {
16637
+ itemEl.addEventListener( "mousemove", e => {
16613
16638
 
16614
16639
  if( !isGridLayout )
16615
16640
  {
@@ -16637,23 +16662,7 @@ class AssetView {
16637
16662
 
16638
16663
  desc.style.left = ( localOffsetX ) + "px";
16639
16664
  desc.style.top = ( localOffsetY - 36 ) + "px";
16640
- });
16641
-
16642
- itemEl.addEventListener("mouseenter", () => {
16643
- if( isGridLayout )
16644
- {
16645
- desc.style.display = "unset";
16646
- }
16647
- });
16648
-
16649
- itemEl.addEventListener("mouseleave", () => {
16650
- if( isGridLayout )
16651
- {
16652
- setTimeout( () => {
16653
- desc.style.display = "none";
16654
- }, 100 );
16655
- }
16656
- });
16665
+ } );
16657
16666
  }
16658
16667
  else
16659
16668
  {
@@ -16688,26 +16697,49 @@ class AssetView {
16688
16697
 
16689
16698
  if( !that.skipPreview )
16690
16699
  {
16700
+ if( item.type === 'video' )
16701
+ {
16702
+ const itemVideo = LX.makeElement( 'video', 'absolute left-0 top-0 w-full border-none pointer-events-none', '', itemEl );
16703
+ itemVideo.setAttribute( 'disablePictureInPicture', false );
16704
+ itemVideo.setAttribute( 'disableRemotePlayback', false );
16705
+ itemVideo.setAttribute( 'loop', true );
16706
+ itemVideo.setAttribute( 'async', true );
16707
+ itemVideo.style.transition = 'opacity 0.2s ease-out';
16708
+ itemVideo.style.opacity = item.preview ? '0' : '1';
16709
+ itemVideo.src = item.src;
16710
+ itemVideo.volume = item.videoVolume ?? 0.4;
16711
+ }
16712
+
16691
16713
  let preview = null;
16692
- const hasImage = item.src && (['png', 'jpg'].indexOf( LX.getExtension( item.src ) ) > -1 || item.src.includes("data:image/") ); // Support b64 image as src
16693
16714
 
16694
- if( hasImage || isFolder || !isGridLayout)
16715
+ const previewSrc = item.preview ?? item.src;
16716
+ const hasImage = previewSrc && (
16717
+ (() => {
16718
+ const ext = LX.getExtension( previewSrc.split( '?' )[ 0 ].split( '#' )[ 0 ]); // get final source without url parameters/anchors
16719
+ return ext ? ['png', 'jpg', 'jpeg', 'gif', 'bmp', 'avif'].includes( ext.toLowerCase() ) : false;
16720
+ })()
16721
+ || previewSrc.startsWith( 'data:image/' )
16722
+ );
16723
+
16724
+ if( hasImage || isFolder || !isGridLayout )
16695
16725
  {
16726
+ const defaultPreviewPath = `${ that.rootPath }images/file.png`;
16727
+ const defaultFolderPath = `${ that.rootPath }images/folder.png`;
16728
+
16696
16729
  preview = document.createElement('img');
16697
- let real_src = item.unknown_extension ? that.rootPath + "images/file.png" : (isFolder ? that.rootPath + "images/folder.png" : item.src);
16698
- preview.src = (isGridLayout || isFolder ? real_src : that.rootPath + "images/file.png");
16730
+ let realSrc = item.unknownExtension ? defaultPreviewPath : ( isFolder ? defaultFolderPath : previewSrc );
16731
+ preview.src = ( isGridLayout || isFolder ? realSrc : defaultPreviewPath );
16699
16732
  itemEl.appendChild( preview );
16700
16733
  }
16701
16734
  else
16702
16735
  {
16703
- preview = document.createElement('svg');
16704
- preview.className = "asset-file-preview";
16705
- itemEl.appendChild(preview);
16736
+ preview = document.createElement( 'svg' );
16737
+ preview.className = 'asset-file-preview';
16738
+ itemEl.appendChild( preview );
16706
16739
 
16707
- let textEl = document.createElement('text');
16708
- preview.appendChild(textEl);
16709
- // If no extension, e.g. Clip, use the type...
16710
- textEl.innerText = (!extension || extension == item.id) ? item.type.toUpperCase() : ("." + extension.toUpperCase());
16740
+ let textEl = document.createElement( 'text' );
16741
+ textEl.innerText = ( !extension || extension == item.id ) ? item.type.toUpperCase() : ( `.${ extension.toUpperCase() }` ); // If no extension, e.g. Clip, use the type...
16742
+ preview.appendChild( textEl );
16711
16743
 
16712
16744
  var newLength = textEl.innerText.length;
16713
16745
  var charsPerLine = 2.5;
@@ -16717,8 +16749,8 @@ class AssetView {
16717
16749
  if( newEmSize < 1 )
16718
16750
  {
16719
16751
  var newFontSize = newEmSize * textBaseSize;
16720
- textEl.style.fontSize = newFontSize + "px";
16721
- preview.style.paddingTop = "calc(50% - " + (textEl.offsetHeight * 0.5 + 10) + "px)";
16752
+ textEl.style.fontSize = newFontSize + 'px';
16753
+ preview.style.paddingTop = `calc(50% - ${ ( textEl.offsetHeight * 0.5 + 10 ) }px)`;
16722
16754
  }
16723
16755
  }
16724
16756
  }
@@ -16732,7 +16764,7 @@ class AssetView {
16732
16764
  if( item.lastModifiedDate ) itemInfoHtml += ` | ${ item.lastModifiedDate }`;
16733
16765
  }
16734
16766
 
16735
- LX.makeContainer( [ "auto", "auto" ], "lexassetinfo", itemInfoHtml, itemEl );
16767
+ LX.makeContainer( [ 'auto', 'auto' ], 'lexassetinfo', itemInfoHtml, itemEl );
16736
16768
 
16737
16769
  itemEl.addEventListener('click', function( e ) {
16738
16770
  e.stopImmediatePropagation();
@@ -16744,10 +16776,10 @@ class AssetView {
16744
16776
  {
16745
16777
  if( !e.shiftKey )
16746
16778
  {
16747
- that.content.querySelectorAll('.lexassetitem').forEach( i => i.classList.remove('selected') );
16779
+ that.content.querySelectorAll( '.lexassetitem').forEach( i => i.classList.remove( 'selected' ) );
16748
16780
  }
16749
16781
 
16750
- this.classList.add('selected');
16782
+ this.classList.add( 'selected' );
16751
16783
  that.selectedItem = item;
16752
16784
 
16753
16785
  if( !that.skipPreview )
@@ -16800,6 +16832,42 @@ class AssetView {
16800
16832
  e.preventDefault();
16801
16833
  }, false );
16802
16834
 
16835
+ itemEl.addEventListener( "mouseenter", ( e ) => {
16836
+
16837
+ if( !that.useNativeTitle && isGridLayout )
16838
+ {
16839
+ const desc = that.content.querySelector( `#floatingTitle_${ item.id }` );
16840
+ if( desc ) desc.style.display = "unset";
16841
+ }
16842
+
16843
+ if( item.type !== "video" ) return;
16844
+ e.preventDefault();
16845
+ const video = itemEl.querySelector( "video" );
16846
+ video.style.opacity = "1";
16847
+ video.play();
16848
+ } );
16849
+
16850
+ itemEl.addEventListener( "mouseleave", ( e ) => {
16851
+
16852
+ if( !that.useNativeTitle && isGridLayout )
16853
+ {
16854
+ setTimeout( () => {
16855
+ const desc = that.content.querySelector( `#floatingTitle_${ item.id }` );
16856
+ if( desc ) desc.style.display = "none";
16857
+ }, 100 );
16858
+ }
16859
+
16860
+ if( item.type !== "video" ) return;
16861
+ e.preventDefault();
16862
+ const video = itemEl.querySelector( "video" );
16863
+ video.pause();
16864
+ video.currentTime = 0;
16865
+ if( item.preview )
16866
+ {
16867
+ video.style.opacity = "0";
16868
+ }
16869
+ } );
16870
+
16803
16871
  return itemEl;
16804
16872
  };
16805
16873
 
@@ -16944,7 +17012,7 @@ class AssetView {
16944
17012
  item.type = "mesh"; break;
16945
17013
  default:
16946
17014
  item.type = ext;
16947
- item.unknown_extension = true;
17015
+ item.unknownExtension = true;
16948
17016
  break;
16949
17017
  }
16950
17018