lexgui 0.6.7 → 0.6.9

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.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.6.7",
17
+ version: "0.6.9",
18
18
  ready: false,
19
19
  components: [], // Specific pre-build components
20
20
  signals: {}, // Events and triggers
@@ -5077,7 +5077,7 @@ LX.makeCodeSnippet = makeCodeSnippet;
5077
5077
  * @param {Array} keys
5078
5078
  * @param {String} extraClass
5079
5079
  */
5080
- function makeKbd( keys, extraClass = "" )
5080
+ function makeKbd( keys, useSpecialKeys = true, extraClass = "" )
5081
5081
  {
5082
5082
  const specialKeys = {
5083
5083
  "Ctrl": '⌃',
@@ -5099,7 +5099,7 @@ function makeKbd( keys, extraClass = "" )
5099
5099
 
5100
5100
  for( const k of keys )
5101
5101
  {
5102
- LX.makeContainer( ["auto", "auto"], "self-center text-xs fg-secondary select-none", specialKeys[ k ] ?? k, kbd );
5102
+ LX.makeContainer( ["auto", "auto"], "self-center text-xs fg-secondary select-none " + extraClass, useSpecialKeys ? specialKeys[ k ] ?? k : k, kbd );
5103
5103
  }
5104
5104
 
5105
5105
  return kbd;
@@ -6432,16 +6432,15 @@ class Area {
6432
6432
  if( auto && type == "vertical" )
6433
6433
  {
6434
6434
  // Listen resize event on first area
6435
- const resizeObserver = new ResizeObserver( entries => {
6435
+ this._autoVerticalResizeObserver = new ResizeObserver( entries => {
6436
6436
  for ( const entry of entries )
6437
6437
  {
6438
6438
  const size = entry.target.getComputedSize();
6439
6439
  area2.root.style.height = "calc(100% - " + ( size.height ) + "px )";
6440
6440
  }
6441
- resizeObserver.disconnect();
6442
6441
  });
6443
6442
 
6444
- resizeObserver.observe( area1.root );
6443
+ this._autoVerticalResizeObserver.observe( area1.root );
6445
6444
  }
6446
6445
 
6447
6446
  // Being minimizable means it's also resizeable!
@@ -6806,6 +6805,7 @@ class Area {
6806
6805
  this.attach( container );
6807
6806
 
6808
6807
  const float = options.float;
6808
+ let floatClass = "";
6809
6809
 
6810
6810
  if( float )
6811
6811
  {
@@ -6815,15 +6815,17 @@ class Area {
6815
6815
  switch( t )
6816
6816
  {
6817
6817
  case 'h': break;
6818
- case 'v': container.className += " vertical"; break;
6818
+ case 'v': floatClass += " vertical"; break;
6819
6819
  case 't': break;
6820
- case 'm': container.className += " middle"; break;
6821
- case 'b': container.className += " bottom"; break;
6820
+ case 'm': floatClass += " middle"; break;
6821
+ case 'b': floatClass += " bottom"; break;
6822
6822
  case 'l': break;
6823
- case 'c': container.className += " center"; break;
6824
- case 'r': container.className += " right"; break;
6823
+ case 'c': floatClass += " center"; break;
6824
+ case 'r': floatClass += " right"; break;
6825
6825
  }
6826
6826
  }
6827
+
6828
+ container.className += ` ${ floatClass }`;
6827
6829
  }
6828
6830
 
6829
6831
  const _addButton = function( b, group, last ) {
@@ -6898,6 +6900,15 @@ class Area {
6898
6900
 
6899
6901
  for( let b of buttons )
6900
6902
  {
6903
+ if( b === null )
6904
+ {
6905
+ // Add a separator
6906
+ const separator = document.createElement("div");
6907
+ separator.className = "lexoverlayseparator" + floatClass;
6908
+ overlayPanel.root.appendChild( separator );
6909
+ continue;
6910
+ }
6911
+
6901
6912
  if( b.constructor === Array )
6902
6913
  {
6903
6914
  for( let i = 0; i < b.length; ++i )
@@ -6963,6 +6974,12 @@ class Area {
6963
6974
  return;
6964
6975
  }
6965
6976
 
6977
+ // When manual resizing, we don't need the observer anymore
6978
+ if( this._autoVerticalResizeObserver )
6979
+ {
6980
+ this._autoVerticalResizeObserver.disconnect();
6981
+ }
6982
+
6966
6983
  const a1 = this.sections[ 0 ];
6967
6984
  var a1Root = a1.root;
6968
6985
 
@@ -7383,7 +7400,7 @@ function ADD_CUSTOM_WIDGET( customWidgetName, options = {} )
7383
7400
 
7384
7401
  LX.Panel.prototype[ 'add' + customWidgetName ] = function( name, instance, callback ) {
7385
7402
 
7386
- options.nameWidth = "100%";
7403
+ const userParams = Array.from( arguments ).slice( 3 );
7387
7404
 
7388
7405
  let widget = new Widget( Widget.CUSTOM, name, null, options );
7389
7406
  this._attachWidget( widget );
@@ -7405,6 +7422,11 @@ function ADD_CUSTOM_WIDGET( customWidgetName, options = {} )
7405
7422
  }
7406
7423
  };
7407
7424
 
7425
+ widget.onResize = ( rect ) => {
7426
+ const realNameWidth = ( widget.root.domName?.style.width ?? "0px" );
7427
+ container.style.width = `calc( 100% - ${ realNameWidth })`;
7428
+ };
7429
+
7408
7430
  const element = widget.root;
7409
7431
 
7410
7432
  let container, customWidgetsDom;
@@ -7418,8 +7440,7 @@ function ADD_CUSTOM_WIDGET( customWidgetName, options = {} )
7418
7440
  if( customWidgetsDom ) customWidgetsDom.remove();
7419
7441
 
7420
7442
  container = document.createElement('div');
7421
- container.className = "lexcustomcontainer";
7422
- container.style.width = "100%";
7443
+ container.className = "lexcustomcontainer w-full";
7423
7444
  element.appendChild( container );
7424
7445
  element.dataset["opened"] = false;
7425
7446
 
@@ -7543,6 +7564,11 @@ function ADD_CUSTOM_WIDGET( customWidgetName, options = {} )
7543
7564
  }
7544
7565
  }
7545
7566
 
7567
+ if( options.onCreate )
7568
+ {
7569
+ options.onCreate.call( this, this, ...userParams );
7570
+ }
7571
+
7546
7572
  this.clearQueue();
7547
7573
  }
7548
7574
  };
@@ -7608,9 +7634,9 @@ class NodeTree {
7608
7634
 
7609
7635
  if( this.options.onlyFolders )
7610
7636
  {
7611
- let has_folders = false;
7612
- node.children.forEach( c => has_folders |= (c.type == 'folder') );
7613
- isParent = !!has_folders;
7637
+ let hasFolders = false;
7638
+ node.children.forEach( c => hasFolders |= (c.type == 'folder') );
7639
+ isParent = !!hasFolders;
7614
7640
  }
7615
7641
 
7616
7642
  let item = document.createElement('li');
@@ -7775,23 +7801,15 @@ class NodeTree {
7775
7801
  } );
7776
7802
 
7777
7803
  event.panel.add( "Delete", { callback: () => {
7778
- // It's the root node
7779
- if( !node.parent )
7780
- {
7781
- return;
7782
- }
7783
7804
 
7784
- if( that.onevent )
7805
+ const ok = that.deleteNode( node );
7806
+
7807
+ if( ok && that.onevent )
7785
7808
  {
7786
7809
  const event = new LX.TreeEvent( LX.TreeEvent.NODE_DELETED, node, e );
7787
7810
  that.onevent( event );
7788
7811
  }
7789
7812
 
7790
- // Delete nodes now
7791
- let childs = node.parent.children;
7792
- const index = childs.indexOf( node );
7793
- childs.splice( index, 1 );
7794
-
7795
7813
  this.refresh();
7796
7814
  } } );
7797
7815
  }
@@ -7808,23 +7826,26 @@ class NodeTree {
7808
7826
 
7809
7827
  if( e.key == "Delete" )
7810
7828
  {
7811
- // Send event now so we have the info in selected array..
7812
- if( that.onevent )
7829
+ const nodesDeleted = [];
7830
+
7831
+ for( let _node of this.selected )
7813
7832
  {
7814
- const event = new LX.TreeEvent( LX.TreeEvent.NODE_DELETED, this.selected.length > 1 ? this.selected : node, e );
7815
- event.multiple = this.selected.length > 1;
7816
- that.onevent( event );
7833
+ if( that.deleteNode( _node ) )
7834
+ {
7835
+ nodesDeleted.push( _node );
7836
+ }
7817
7837
  }
7818
7838
 
7819
- // Delete nodes now
7820
- for( let _node of this.selected )
7839
+ // Send event now so we have the info in selected array..
7840
+ if( nodesDeleted.length && that.onevent )
7821
7841
  {
7822
- let childs = _node.parent.children;
7823
- const index = childs.indexOf( _node );
7824
- childs.splice( index, 1 );
7842
+ const event = new LX.TreeEvent( LX.TreeEvent.NODE_DELETED, nodesDeleted.length > 1 ? nodesDeleted : node, e );
7843
+ event.multiple = nodesDeleted.length > 1;
7844
+ that.onevent( event );
7825
7845
  }
7826
7846
 
7827
7847
  this.selected.length = 0;
7848
+
7828
7849
  this.refresh();
7829
7850
  }
7830
7851
  else if( e.key == "ArrowUp" || e.key == "ArrowDown" ) // Unique or zero selected
@@ -8093,6 +8114,35 @@ class NodeTree {
8093
8114
  this.selected = [ el.treeData ];
8094
8115
  el.focus();
8095
8116
  }
8117
+
8118
+ deleteNode( node ) {
8119
+
8120
+ const dataAsArray = ( this.data.constructor === Array );
8121
+
8122
+ // Can be either Array or Object type data
8123
+ if( node.parent )
8124
+ {
8125
+ let childs = node.parent.children;
8126
+ const index = childs.indexOf( node );
8127
+ childs.splice( index, 1 );
8128
+ }
8129
+ else
8130
+ {
8131
+ if( dataAsArray )
8132
+ {
8133
+ const index = this.data.indexOf( node );
8134
+ console.assert( index > -1, "NodeTree: Can't delete root node " + node.id + " from data array!" );
8135
+ this.data.splice( index, 1 );
8136
+ }
8137
+ else
8138
+ {
8139
+ console.warn( "NodeTree: Can't delete root node from object data!" );
8140
+ return false;
8141
+ }
8142
+ }
8143
+
8144
+ return true;
8145
+ }
8096
8146
  }
8097
8147
 
8098
8148
  LX.NodeTree = NodeTree;
@@ -8460,18 +8510,38 @@ class Button extends Widget {
8460
8510
  wValue.classList.add( "selected" );
8461
8511
  }
8462
8512
 
8463
- if( options.icon )
8464
- {
8465
- const icon = LX.makeIcon( options.icon );
8466
- wValue.prepend( icon );
8467
- wValue.classList.add( "justify-center" );
8468
- }
8469
- else if( options.img )
8513
+ if( options.img )
8470
8514
  {
8471
8515
  let img = document.createElement( 'img' );
8472
8516
  img.src = options.img;
8473
8517
  wValue.prepend( img );
8474
8518
  }
8519
+ else if( options.icon )
8520
+ {
8521
+ const icon = LX.makeIcon( options.icon );
8522
+ const iconPosition = options.iconPosition ?? "cover";
8523
+
8524
+ // Default
8525
+ if( iconPosition == "cover" || ( options.swap !== undefined ) )
8526
+ {
8527
+ wValue.prepend( icon );
8528
+ }
8529
+ else
8530
+ {
8531
+ wValue.innerHTML = `<span>${ ( value || "" ) }</span>`;
8532
+
8533
+ if( iconPosition == "start" )
8534
+ {
8535
+ wValue.querySelector( "span" ).prepend( icon );
8536
+ }
8537
+ else // "end"
8538
+ {
8539
+ wValue.querySelector( "span" ).appendChild( icon );
8540
+ }
8541
+ }
8542
+
8543
+ wValue.classList.add( "justify-center" );
8544
+ }
8475
8545
  else
8476
8546
  {
8477
8547
  wValue.innerHTML = `<span>${ ( value || "" ) }</span>`;
@@ -8927,8 +8997,8 @@ class Select extends Widget {
8927
8997
  value = newValue;
8928
8998
 
8929
8999
  let item = null;
8930
- const options = listOptions.childNodes;
8931
- options.forEach( e => {
9000
+ const listOptionsNodes = listOptions.childNodes;
9001
+ listOptionsNodes.forEach( e => {
8932
9002
  e.classList.remove( "selected" );
8933
9003
  if( e.getAttribute( "value" ) == newValue )
8934
9004
  {
@@ -8948,6 +9018,22 @@ class Select extends Widget {
8948
9018
  list.refresh( filteredOptions );
8949
9019
  }
8950
9020
 
9021
+ // Update suboptions menu
9022
+ const suboptions = this.root.querySelector( ".lexcustomcontainer" );
9023
+ const suboptionsFunc = options[ `on_${ value }` ];
9024
+ suboptions.toggleAttribute( "hidden", !suboptionsFunc );
9025
+
9026
+ if( suboptionsFunc )
9027
+ {
9028
+ suboptions.innerHTML = "";
9029
+ const suboptionsPanel = new LX.Panel();
9030
+ suboptionsPanel.queue( suboptions );
9031
+ suboptionsFunc.call(this, suboptionsPanel);
9032
+ suboptionsPanel.clearQueue();
9033
+ }
9034
+
9035
+ this.root.dataset["opened"] = ( !!suboptionsFunc );
9036
+
8951
9037
  if( !skipCallback )
8952
9038
  {
8953
9039
  this._trigger( new LX.IEvent( name, value, event ), callback );
@@ -9244,6 +9330,25 @@ class Select extends Widget {
9244
9330
 
9245
9331
  container.appendChild( listDialog );
9246
9332
 
9333
+ // Element suboptions
9334
+ let suboptions = document.createElement( "div" );
9335
+ suboptions.className = "lexcustomcontainer w-full";
9336
+
9337
+ const suboptionsFunc = options[ `on_${ value }` ];
9338
+ suboptions.toggleAttribute( "hidden", !suboptionsFunc );
9339
+
9340
+ if( suboptionsFunc )
9341
+ {
9342
+ suboptions.innerHTML = "";
9343
+ const suboptionsPanel = new LX.Panel();
9344
+ suboptionsPanel.queue( suboptions );
9345
+ suboptionsFunc.call( this, suboptionsPanel );
9346
+ suboptionsPanel.clearQueue();
9347
+ }
9348
+
9349
+ this.root.appendChild( suboptions );
9350
+ this.root.dataset["opened"] = ( !!suboptionsFunc );
9351
+
9247
9352
  LX.doAsync( this.onResize.bind( this ) );
9248
9353
  }
9249
9354
 
@@ -10347,6 +10452,7 @@ class NumberInput extends Widget {
10347
10452
  slider.step = options.step ?? 1;
10348
10453
  slider.type = "range";
10349
10454
  slider.value = value;
10455
+ slider.disabled = this.disabled;
10350
10456
 
10351
10457
  slider.addEventListener( "input", ( e ) => {
10352
10458
  this.set( slider.valueAsNumber, false, e );
@@ -11434,7 +11540,7 @@ class TabSections extends Widget {
11434
11540
  let tabEl = document.createElement( "div" );
11435
11541
  tabEl.className = "lextab " + (i == tabs.length - 1 ? "last" : "") + ( isSelected ? "selected" : "" );
11436
11542
  tabEl.innerHTML = ( showNames ? tab.name : "" );
11437
- tabEl.appendChild( LX.makeIcon( tab.icon ?? "Hash", { title: tab.name } ) );
11543
+ tabEl.appendChild( LX.makeIcon( tab.icon ?? "Hash", { title: tab.name, iconClass: tab.iconClass, svgClass: tab.svgClass } ) );
11438
11544
 
11439
11545
  let infoContainer = document.createElement( "div" );
11440
11546
  infoContainer.id = tab.name.replace( /\s/g, '' );
@@ -11470,7 +11576,7 @@ class TabSections extends Widget {
11470
11576
  // Push to tab space
11471
11577
  const creationPanel = new LX.Panel();
11472
11578
  creationPanel.queue( infoContainer );
11473
- tab.onCreate.call(this, creationPanel);
11579
+ tab.onCreate.call( this, creationPanel, infoContainer );
11474
11580
  creationPanel.clearQueue();
11475
11581
  }
11476
11582
  }
@@ -11574,16 +11680,16 @@ class Table extends Widget {
11574
11680
  container.className = "lextable";
11575
11681
  this.root.appendChild( container );
11576
11682
 
11577
- this.centered = options.centered ?? false;
11578
- if( this.centered === true )
11683
+ this._centered = options.centered ?? false;
11684
+ if( this._centered === true )
11579
11685
  {
11580
11686
  container.classList.add( "centered" );
11581
11687
  }
11582
11688
 
11689
+ this.activeCustomFilters = {};
11583
11690
  this.filter = options.filter ?? false;
11584
- this.toggleColumns = options.toggleColumns ?? false;
11585
11691
  this.customFilters = options.customFilters ?? false;
11586
- this.activeCustomFilters = {};
11692
+ this._toggleColumns = options.toggleColumns ?? false;
11587
11693
  this._currentFilter = options.filterValue;
11588
11694
 
11589
11695
  data.head = data.head ?? [];
@@ -11591,6 +11697,7 @@ class Table extends Widget {
11591
11697
  data.checkMap = { };
11592
11698
  data.colVisibilityMap = { };
11593
11699
  data.head.forEach( (col, index) => { data.colVisibilityMap[ index ] = true; });
11700
+ this.data = data;
11594
11701
 
11595
11702
  const compareFn = ( idx, order, a, b) => {
11596
11703
  if (a[idx] < b[idx]) return -order;
@@ -11604,7 +11711,7 @@ class Table extends Widget {
11604
11711
  };
11605
11712
 
11606
11713
  // Append header
11607
- if( this.filter || this.customFilters || this.toggleColumns )
11714
+ if( this.filter || this.customFilters || this._toggleColumns )
11608
11715
  {
11609
11716
  const headerContainer = LX.makeContainer( [ "100%", "auto" ], "flex flex-row" );
11610
11717
 
@@ -11716,7 +11823,7 @@ class Table extends Widget {
11716
11823
  this._resetCustomFiltersBtn.root.classList.add( "hidden" );
11717
11824
  }
11718
11825
 
11719
- if( this.toggleColumns )
11826
+ if( this._toggleColumns )
11720
11827
  {
11721
11828
  const icon = LX.makeIcon( "Settings2" );
11722
11829
  const toggleColumnsBtn = new LX.Button( "toggleColumnsBtn", icon.innerHTML + "View", (value, e) => {
@@ -11788,7 +11895,9 @@ class Table extends Widget {
11788
11895
  const body = table.querySelector( "tbody" );
11789
11896
  for( const el of body.childNodes )
11790
11897
  {
11791
- data.checkMap[ el.getAttribute( "rowId" ) ] = this.checked;
11898
+ const rowId = el.getAttribute( "rowId" );
11899
+ if( !rowId ) continue;
11900
+ data.checkMap[ rowId ] = this.checked;
11792
11901
  el.querySelector( "input[type='checkbox']" ).checked = this.checked;
11793
11902
  }
11794
11903
  });
@@ -11804,7 +11913,7 @@ class Table extends Widget {
11804
11913
  th.querySelector( "span" ).appendChild( LX.makeIcon( "MenuArrows", { svgClass: "sm" } ) );
11805
11914
 
11806
11915
  const idx = data.head.indexOf( headData );
11807
- if( this.centered && this.centered.indexOf( idx ) > -1 )
11916
+ if( this._centered?.indexOf && this._centered.indexOf( idx ) > -1 )
11808
11917
  {
11809
11918
  th.classList.add( "centered" );
11810
11919
  }
@@ -11814,7 +11923,7 @@ class Table extends Widget {
11814
11923
  { name: "Desc", icon: "ArrowDownAZ", callback: sortFn.bind( this, idx, -1 ) }
11815
11924
  ];
11816
11925
 
11817
- if( this.toggleColumns )
11926
+ if( this._toggleColumns )
11818
11927
  {
11819
11928
  menuOptions.push(
11820
11929
  null,
@@ -11876,6 +11985,9 @@ class Table extends Widget {
11876
11985
  // Origin row should go to the target row, and the rest should be moved up/down
11877
11986
  const fromIdx = rIdx - 1;
11878
11987
  const targetIdx = movePending[ 1 ] - 1;
11988
+
11989
+ LX.emit( "@on_table_sort", { instance: this, fromIdx, targetIdx } );
11990
+
11879
11991
  const b = data.body[ fromIdx ];
11880
11992
  let targetOffset = 0;
11881
11993
 
@@ -11996,8 +12108,8 @@ class Table extends Widget {
11996
12108
  }
11997
12109
 
11998
12110
  const row = document.createElement( 'tr' );
11999
- const rowId = LX.getSupportedDOMName( bodyData.join( '-' ) );
12000
- row.setAttribute( "rowId", rowId.substr(0, 32) );
12111
+ const rowId = LX.getSupportedDOMName( bodyData.join( '-' ) ).substr(0, 32);
12112
+ row.setAttribute( "rowId", rowId );
12001
12113
 
12002
12114
  if( options.sortable ?? false )
12003
12115
  {
@@ -12081,7 +12193,7 @@ class Table extends Widget {
12081
12193
  td.innerHTML = `${ rowData }`;
12082
12194
 
12083
12195
  const idx = bodyData.indexOf( rowData );
12084
- if( this.centered && this.centered.indexOf( idx ) > -1 )
12196
+ if( this._centered?.indexOf && this._centered.indexOf( idx ) > -1 )
12085
12197
  {
12086
12198
  td.classList.add( "centered" );
12087
12199
  }
@@ -12113,7 +12225,7 @@ class Table extends Widget {
12113
12225
  }
12114
12226
  else if( action == "menu" )
12115
12227
  {
12116
- button = LX.makeIcon( "Ellipsis", { title: "Menu" } );
12228
+ button = LX.makeIcon( "EllipsisVertical", { title: "Menu" } );
12117
12229
  button.addEventListener( 'click', function( event ) {
12118
12230
  if( !options.onMenuAction )
12119
12231
  {
@@ -12152,6 +12264,17 @@ class Table extends Widget {
12152
12264
 
12153
12265
  body.appendChild( row );
12154
12266
  }
12267
+
12268
+ if( body.childNodes.length == 0 )
12269
+ {
12270
+ const row = document.createElement( 'tr' );
12271
+ const td = document.createElement( 'td' );
12272
+ td.setAttribute( "colspan", data.head.length + this.rowOffsetCount + 1 ); // +1 for rowActions
12273
+ td.className = "empty-row";
12274
+ td.innerHTML = "No results.";
12275
+ row.appendChild( td );
12276
+ body.appendChild( row );
12277
+ }
12155
12278
  }
12156
12279
 
12157
12280
  for( const v in data.colVisibilityMap )
@@ -12171,8 +12294,50 @@ class Table extends Widget {
12171
12294
 
12172
12295
  LX.doAsync( this.onResize.bind( this ) );
12173
12296
  }
12297
+
12298
+ getSelectedRows() {
12299
+
12300
+ const selectedRows = [];
12301
+
12302
+ for( const row of this.data.body )
12303
+ {
12304
+ const rowId = LX.getSupportedDOMName( row.join( '-' ) ).substr( 0, 32 );
12305
+ if( this.data.checkMap[ rowId ] === true )
12306
+ {
12307
+ selectedRows.push( row );
12308
+ }
12309
+ }
12310
+
12311
+ return selectedRows;
12312
+ }
12313
+
12314
+ _setCentered( v ) {
12315
+
12316
+ if( v.constructor == Boolean )
12317
+ {
12318
+ const container = this.root.querySelector( ".lextable" );
12319
+ container.classList.toggle( "centered", v );
12320
+ }
12321
+ else
12322
+ {
12323
+ // Make sure this is an array containing which columns have
12324
+ // to be centered
12325
+ v = [].concat( v );
12326
+ }
12327
+
12328
+ this._centered = v;
12329
+
12330
+ this.refresh();
12331
+ }
12174
12332
  }
12175
12333
 
12334
+ Object.defineProperty( Table.prototype, "centered", {
12335
+ get: function() { return this._centered; },
12336
+ set: function( v ) { this._setCentered( v ); },
12337
+ enumerable: true,
12338
+ configurable: true
12339
+ });
12340
+
12176
12341
  LX.Table = Table;
12177
12342
 
12178
12343
  /**
@@ -12894,6 +13059,7 @@ class Panel {
12894
13059
  * hideName: Don't use name as label [false]
12895
13060
  * disabled: Make the widget disabled [false]
12896
13061
  * icon: Icon class to show as button value
13062
+ * iconPosition: Icon position (cover|start|end)
12897
13063
  * fileInput: Button click requests a file
12898
13064
  * fileInputType: Type of the requested file
12899
13065
  * img: Path to image to show as button value
@@ -13385,6 +13551,8 @@ class Panel {
13385
13551
  * @param {Array} tabs Contains objects with {
13386
13552
  * name: Name of the tab (if icon, use as title)
13387
13553
  * icon: Icon to be used as the tab icon (optional)
13554
+ * iconClass: Class to be added to the icon (optional)
13555
+ * svgClass: Class to be added to the inner SVG of the icon (optional)
13388
13556
  * onCreate: Func to be called at tab creation
13389
13557
  * onSelect: Func to be called on select tab (optional)
13390
13558
  * }
@@ -13984,7 +14152,7 @@ class Menubar {
13984
14152
  this.buttonContainer.className = "lexmenubuttons";
13985
14153
  this.buttonContainer.classList.add( options.float ?? "center" );
13986
14154
 
13987
- if( options.position == "right" )
14155
+ if( options.float == "right" )
13988
14156
  {
13989
14157
  this.buttonContainer.right = true;
13990
14158
  }
@@ -14003,7 +14171,7 @@ class Menubar {
14003
14171
  {
14004
14172
  const data = buttons[ i ];
14005
14173
  const title = data.title;
14006
- const button = new LX.Button( title, "", data.callback, { title, buttonClass: "bg-none", disabled: data.disabled, icon: data.icon, hideName: true, swap: data.swap } );
14174
+ const button = new LX.Button( title, data.label, data.callback, { title, buttonClass: "bg-none", disabled: data.disabled, icon: data.icon, hideName: true, swap: data.swap, iconPosition: "start" } );
14007
14175
  this.buttonContainer.appendChild( button.root );
14008
14176
 
14009
14177
  if( title )