lexgui 0.7.10 → 0.7.12

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.7.10",
17
+ version: "0.7.12",
18
18
  ready: false,
19
19
  extensions: [], // Store extensions used
20
20
  signals: {}, // Events and triggers
@@ -654,10 +654,11 @@ class TreeEvent {
654
654
  static NODE_VISIBILITY = 7;
655
655
  static NODE_CARETCHANGED = 8;
656
656
 
657
- constructor( type, node, value ) {
657
+ constructor( type, node, value, event ) {
658
658
  this.type = type || TreeEvent.NONE;
659
659
  this.node = node;
660
660
  this.value = value;
661
+ this.event = event;
661
662
  this.multiple = false; // Multiple selection
662
663
  this.panel = null;
663
664
  }
@@ -7952,8 +7953,8 @@ class BaseComponent {
7952
7953
  BaseComponent.PROGRESS
7953
7954
  ];
7954
7955
 
7955
- constructor( type, name, value, options = {} ) {
7956
-
7956
+ constructor( type, name, value, options = {} )
7957
+ {
7957
7958
  this.type = type;
7958
7959
  this.name = name;
7959
7960
  this.options = options;
@@ -8051,13 +8052,14 @@ class BaseComponent {
8051
8052
  this.options = options;
8052
8053
  }
8053
8054
 
8054
- static _dispatchEvent( element, type, data, bubbles, cancelable ) {
8055
+ static _dispatchEvent( element, type, data, bubbles, cancelable )
8056
+ {
8055
8057
  let event = new CustomEvent( type, { 'detail': data, 'bubbles': bubbles, 'cancelable': cancelable } );
8056
8058
  element.dispatchEvent( event );
8057
8059
  }
8058
8060
 
8059
- _addResetProperty( container, callback ) {
8060
-
8061
+ _addResetProperty( container, callback )
8062
+ {
8061
8063
  const domEl = LX.makeIcon( "Undo2", { iconClass: "ml-0 mr-1 px-1", title: "Reset" } );
8062
8064
  domEl.style.display = "none";
8063
8065
  domEl.addEventListener( "click", callback );
@@ -8065,7 +8067,8 @@ class BaseComponent {
8065
8067
  return domEl;
8066
8068
  }
8067
8069
 
8068
- _canPaste() {
8070
+ _canPaste()
8071
+ {
8069
8072
  let pasteAllowed = this.type === BaseComponent.CUSTOM ?
8070
8073
  ( navigator.clipboard.customIdx !== undefined && this.customIdx == navigator.clipboard.customIdx ) : navigator.clipboard.type === this.type;
8071
8074
 
@@ -8079,8 +8082,8 @@ class BaseComponent {
8079
8082
  return pasteAllowed;
8080
8083
  }
8081
8084
 
8082
- _trigger( event, callback, scope = this ) {
8083
-
8085
+ _trigger( event, callback, scope = this )
8086
+ {
8084
8087
  if( !callback )
8085
8088
  {
8086
8089
  return;
@@ -8089,8 +8092,8 @@ class BaseComponent {
8089
8092
  callback.call( scope, event.value, event.domEvent, event.name );
8090
8093
  }
8091
8094
 
8092
- value() {
8093
-
8095
+ value()
8096
+ {
8094
8097
  if( this.onGetValue )
8095
8098
  {
8096
8099
  return this.onGetValue();
@@ -8099,8 +8102,8 @@ class BaseComponent {
8099
8102
  console.warn( "Can't get value of " + this.typeName() );
8100
8103
  }
8101
8104
 
8102
- set( value, skipCallback, event ) {
8103
-
8105
+ set( value, skipCallback, event )
8106
+ {
8104
8107
  if( this.onSetValue )
8105
8108
  {
8106
8109
  let resetButton = this.root.querySelector( ".lexcomponentname .lexicon" );
@@ -8108,12 +8111,13 @@ class BaseComponent {
8108
8111
  {
8109
8112
  resetButton.style.display = ( value != this.value() ? "block" : "none" );
8110
8113
 
8111
- const equalInitial = value.constructor === Array ? (function arraysEqual(a, b) {
8112
- if (a === b) return true;
8113
- if (a == null || b == null) return false;
8114
- if (a.length !== b.length) return false;
8115
- for (var i = 0; i < a.length; ++i) {
8116
- if (a[ i ] !== b[ i ]) return false;
8114
+ const equalInitial = value.constructor === Array ? (function arraysEqual( a, b ) {
8115
+ if( a === b ) return true;
8116
+ if( a == null || b == null ) return false;
8117
+ if( a.length !== b.length ) return false;
8118
+ for( var i = 0; i < a.length; ++i )
8119
+ {
8120
+ if( a[ i ] !== b[ i ] ) return false;
8117
8121
  }
8118
8122
  return true;
8119
8123
  })( value, this._initialValue ) : ( value == this._initialValue );
@@ -8124,11 +8128,11 @@ class BaseComponent {
8124
8128
  return this.onSetValue( value, skipCallback ?? false, event );
8125
8129
  }
8126
8130
 
8127
- console.warn("Can't set value of " + this.typeName());
8131
+ console.warn( `Can't set value of ${ this.typeName() }`);
8128
8132
  }
8129
8133
 
8130
- oncontextmenu( e ) {
8131
-
8134
+ oncontextmenu( e )
8135
+ {
8132
8136
  if( BaseComponent.NO_CONTEXT_TYPES.includes( this.type ) )
8133
8137
  {
8134
8138
  return;
@@ -8140,14 +8144,16 @@ class BaseComponent {
8140
8144
  });
8141
8145
  }
8142
8146
 
8143
- copy() {
8147
+ copy()
8148
+ {
8144
8149
  navigator.clipboard.type = this.type;
8145
8150
  navigator.clipboard.customIdx = this.customIdx;
8146
8151
  navigator.clipboard.data = this.value();
8147
8152
  navigator.clipboard.writeText( navigator.clipboard.data );
8148
8153
  }
8149
8154
 
8150
- paste() {
8155
+ paste()
8156
+ {
8151
8157
  if( !this._canPaste() )
8152
8158
  {
8153
8159
  return;
@@ -8156,8 +8162,8 @@ class BaseComponent {
8156
8162
  this.set( navigator.clipboard.data );
8157
8163
  }
8158
8164
 
8159
- typeName() {
8160
-
8165
+ typeName()
8166
+ {
8161
8167
  switch( this.type )
8162
8168
  {
8163
8169
  case BaseComponent.TEXT: return "Text";
@@ -8209,8 +8215,8 @@ function ADD_CUSTOM_COMPONENT( customComponentName, options = {} )
8209
8215
  {
8210
8216
  let customIdx = LX.guidGenerator();
8211
8217
 
8212
- LX.Panel.prototype[ 'add' + customComponentName ] = function( name, instance, callback ) {
8213
-
8218
+ LX.Panel.prototype[ 'add' + customComponentName ] = function( name, instance, callback )
8219
+ {
8214
8220
  const userParams = Array.from( arguments ).slice( 3 );
8215
8221
 
8216
8222
  let component = new BaseComponent( BaseComponent.CUSTOM, name, null, options );
@@ -8396,8 +8402,8 @@ LX.ADD_CUSTOM_COMPONENT = ADD_CUSTOM_COMPONENT;
8396
8402
 
8397
8403
  class NodeTree {
8398
8404
 
8399
- constructor( domEl, data, options ) {
8400
-
8405
+ constructor( domEl, data, options )
8406
+ {
8401
8407
  this.domEl = domEl;
8402
8408
  this.data = data;
8403
8409
  this.onevent = options.onevent;
@@ -8419,8 +8425,8 @@ class NodeTree {
8419
8425
  }
8420
8426
  }
8421
8427
 
8422
- _createItem( parent, node, level = 0, selectedId ) {
8423
-
8428
+ _createItem( parent, node, level = 0, selectedId )
8429
+ {
8424
8430
  const that = this;
8425
8431
  const nodeFilterInput = this.domEl.querySelector( ".lexnodetreefilter" );
8426
8432
 
@@ -8446,7 +8452,7 @@ class NodeTree {
8446
8452
  if( this.options.onlyFolders )
8447
8453
  {
8448
8454
  let hasFolders = false;
8449
- node.children.forEach( c => hasFolders |= (c.type == 'folder') );
8455
+ node.children.forEach( c => hasFolders |= ( c.type == 'folder' ) );
8450
8456
  isParent = !!hasFolders;
8451
8457
  }
8452
8458
 
@@ -8526,7 +8532,7 @@ class NodeTree {
8526
8532
  node.closed = false;
8527
8533
  if( that.onevent )
8528
8534
  {
8529
- const event = new LX.TreeEvent( LX.TreeEvent.NODE_CARETCHANGED, node, node.closed );
8535
+ const event = new LX.TreeEvent( LX.TreeEvent.NODE_CARETCHANGED, node, node.closed, e );
8530
8536
  that.onevent( event );
8531
8537
  }
8532
8538
  that.frefresh( node.id );
@@ -8534,13 +8540,13 @@ class NodeTree {
8534
8540
 
8535
8541
  if( that.onevent )
8536
8542
  {
8537
- const event = new LX.TreeEvent(LX.TreeEvent.NODE_SELECTED, e.shiftKey ? this.selected : node );
8543
+ const event = new LX.TreeEvent( LX.TreeEvent.NODE_SELECTED, node, this.selected, e );
8538
8544
  event.multiple = e.shiftKey;
8539
8545
  that.onevent( event );
8540
8546
  }
8541
8547
  });
8542
8548
 
8543
- item.addEventListener("dblclick", function() {
8549
+ item.addEventListener("dblclick", function(e) {
8544
8550
 
8545
8551
  if( that.options.rename ?? true )
8546
8552
  {
@@ -8551,7 +8557,7 @@ class NodeTree {
8551
8557
 
8552
8558
  if( that.onevent )
8553
8559
  {
8554
- const event = new LX.TreeEvent( LX.TreeEvent.NODE_DBLCLICKED, node );
8560
+ const event = new LX.TreeEvent( LX.TreeEvent.NODE_DBLCLICKED, node, null, e );
8555
8561
  that.onevent( event );
8556
8562
  }
8557
8563
  });
@@ -8565,10 +8571,10 @@ class NodeTree {
8565
8571
  return;
8566
8572
  }
8567
8573
 
8568
- const event = new LX.TreeEvent(LX.TreeEvent.NODE_CONTEXTMENU, this.selected.length > 1 ? this.selected : node, e);
8574
+ const event = new LX.TreeEvent( LX.TreeEvent.NODE_CONTEXTMENU, node, this.selected, e );
8569
8575
  event.multiple = this.selected.length > 1;
8570
8576
 
8571
- LX.addContextMenu( event.multiple ? "Selected Nodes" : event.node.id, event.value, m => {
8577
+ LX.addContextMenu( event.multiple ? "Selected Nodes" : event.node.id, event.event, m => {
8572
8578
  event.panel = m;
8573
8579
  });
8574
8580
 
@@ -8617,7 +8623,7 @@ class NodeTree {
8617
8623
 
8618
8624
  if( ok && that.onevent )
8619
8625
  {
8620
- const event = new LX.TreeEvent( LX.TreeEvent.NODE_DELETED, node, e );
8626
+ const event = new LX.TreeEvent( LX.TreeEvent.NODE_DELETED, node, [ node ], null );
8621
8627
  that.onevent( event );
8622
8628
  }
8623
8629
 
@@ -8650,7 +8656,7 @@ class NodeTree {
8650
8656
  // Send event now so we have the info in selected array..
8651
8657
  if( nodesDeleted.length && that.onevent )
8652
8658
  {
8653
- const event = new LX.TreeEvent( LX.TreeEvent.NODE_DELETED, nodesDeleted.length > 1 ? nodesDeleted : node, e );
8659
+ const event = new LX.TreeEvent( LX.TreeEvent.NODE_DELETED, node, nodesDeleted, e );
8654
8660
  event.multiple = nodesDeleted.length > 1;
8655
8661
  that.onevent( event );
8656
8662
  }
@@ -8692,7 +8698,7 @@ class NodeTree {
8692
8698
 
8693
8699
  if( that.onevent )
8694
8700
  {
8695
- const event = new LX.TreeEvent(LX.TreeEvent.NODE_RENAMED, node, this.value);
8701
+ const event = new LX.TreeEvent( LX.TreeEvent.NODE_RENAMED, node, this.value, e );
8696
8702
  that.onevent( event );
8697
8703
  }
8698
8704
 
@@ -8766,7 +8772,7 @@ class NodeTree {
8766
8772
  // Trigger node dragger event
8767
8773
  if( that.onevent )
8768
8774
  {
8769
- const event = new LX.TreeEvent(LX.TreeEvent.NODE_DRAGGED, dragged, target);
8775
+ const event = new LX.TreeEvent( LX.TreeEvent.NODE_DRAGGED, dragged, target, e );
8770
8776
  that.onevent( event );
8771
8777
  }
8772
8778
 
@@ -8807,7 +8813,7 @@ class NodeTree {
8807
8813
 
8808
8814
  if( that.onevent )
8809
8815
  {
8810
- const event = new LX.TreeEvent(LX.TreeEvent.NODE_CARETCHANGED, node, node.closed);
8816
+ const event = new LX.TreeEvent( LX.TreeEvent.NODE_CARETCHANGED, node, node.closed, e );
8811
8817
  that.onevent( event );
8812
8818
  }
8813
8819
  that.frefresh( node.id );
@@ -8824,28 +8830,34 @@ class NodeTree {
8824
8830
  for( let i = 0; i < node.actions.length; ++i )
8825
8831
  {
8826
8832
  const action = node.actions[ i ];
8827
- const actionIcon = LX.makeIcon( action.icon, { title: action.name } );
8828
- actionIcon.addEventListener("click", function( e ) {
8833
+ const actionBtn = new LX.Button( null, "", ( swapValue, event ) => {
8834
+ event.stopPropagation();
8829
8835
  if( action.callback )
8830
8836
  {
8831
- action.callback( node, actionIcon );
8832
- e.stopPropagation();
8837
+ action.callback( node, swapValue, event );
8833
8838
  }
8834
- });
8839
+ }, { icon: action.icon, swap: action.swap, title: action.name, hideName:true, className: "p-0 m-0", buttonClass: "p-0 m-0 bg-none" } );
8840
+ actionBtn.root.style.minWidth = "fit-content";
8841
+ actionBtn.root.style.margin = "0"; // adding classes does not work
8842
+ actionBtn.root.style.padding = "0"; // adding classes does not work
8843
+ const _btn = actionBtn.root.querySelector("button");
8844
+ _btn.style.minWidth = "fit-content";
8845
+ _btn.style.margin = "0"; // adding classes does not work
8846
+ _btn.style.padding = "0"; // adding classes does not work
8835
8847
 
8836
- inputContainer.appendChild( actionIcon );
8848
+ inputContainer.appendChild( actionBtn.root );
8837
8849
  }
8838
8850
  }
8839
8851
 
8840
8852
  if( !node.skipVisibility ?? false )
8841
8853
  {
8842
- const visibilityBtn = new LX.Button( null, "", ( swapValue, event ) => {
8843
- event.stopPropagation();
8854
+ const visibilityBtn = new LX.Button( null, "", ( swapValue, e ) => {
8855
+ e.stopPropagation();
8844
8856
  node.visible = node.visible === undefined ? false : !node.visible;
8845
8857
  // Trigger visibility event
8846
8858
  if( that.onevent )
8847
8859
  {
8848
- const event = new LX.TreeEvent( LX.TreeEvent.NODE_VISIBILITY, node, node.visible );
8860
+ const event = new LX.TreeEvent( LX.TreeEvent.NODE_VISIBILITY, node, node.visible, e );
8849
8861
  that.onevent( event );
8850
8862
  }
8851
8863
  }, { icon: node.visible ? "Eye" : "EyeOff", swap: node.visible ? "EyeOff" : "Eye", title: "Toggle visible", className: "p-0 m-0", buttonClass: "bg-none" } );
@@ -8901,22 +8913,35 @@ class NodeTree {
8901
8913
  }
8902
8914
 
8903
8915
  /* Refreshes the tree and focuses current element */
8904
- frefresh( id ) {
8905
-
8916
+ frefresh( id )
8917
+ {
8906
8918
  this.refresh();
8907
- var el = this.domEl.querySelector( "#" + id );
8919
+ var el = this.domEl.querySelector( `#${ id }` );
8908
8920
  if( el )
8909
8921
  {
8910
8922
  el.focus();
8911
8923
  }
8912
8924
  }
8913
8925
 
8914
- select( id ) {
8926
+ select( id )
8927
+ {
8928
+ const nodeFilter = this.domEl.querySelector( ".lexnodetreefilter" );
8929
+ if( nodeFilter )
8930
+ {
8931
+ nodeFilter.value = "";
8932
+ }
8915
8933
 
8916
8934
  this.refresh( null, id );
8917
8935
 
8918
8936
  this.domEl.querySelectorAll( ".selected" ).forEach( i => i.classList.remove( "selected" ) );
8919
8937
 
8938
+ // Unselect
8939
+ if( !id )
8940
+ {
8941
+ this.selected.length = 0;
8942
+ return;
8943
+ }
8944
+
8920
8945
  // Element should exist, since tree was refreshed to show it
8921
8946
  const el = this.domEl.querySelector( "#" + id );
8922
8947
  console.assert( el, "NodeTree: Can't select node " + id );
@@ -8926,8 +8951,8 @@ class NodeTree {
8926
8951
  el.focus();
8927
8952
  }
8928
8953
 
8929
- deleteNode( node ) {
8930
-
8954
+ deleteNode( node )
8955
+ {
8931
8956
  const dataAsArray = ( this.data.constructor === Array );
8932
8957
 
8933
8958
  // Can be either Array or Object type data
@@ -8963,10 +8988,10 @@ LX.NodeTree = NodeTree;
8963
8988
  * @description Blank Component
8964
8989
  */
8965
8990
 
8966
- class Blank extends BaseComponent {
8967
-
8968
- constructor( width, height ) {
8969
-
8991
+ class Blank extends BaseComponent
8992
+ {
8993
+ constructor( width, height )
8994
+ {
8970
8995
  super( BaseComponent.BLANK );
8971
8996
 
8972
8997
  this.root.style.width = width ?? "auto";
@@ -8981,10 +9006,10 @@ LX.Blank = Blank;
8981
9006
  * @description Title Component
8982
9007
  */
8983
9008
 
8984
- class Title extends BaseComponent {
8985
-
8986
- constructor( name, options = {} ) {
8987
-
9009
+ class Title extends BaseComponent
9010
+ {
9011
+ constructor( name, options = {} )
9012
+ {
8988
9013
  console.assert( name, "Can't create Title Component without text!" );
8989
9014
 
8990
9015
  // Note: Titles are not registered in Panel.components by now
@@ -9025,10 +9050,10 @@ LX.Title = Title;
9025
9050
  * @description TextInput Component
9026
9051
  */
9027
9052
 
9028
- class TextInput extends BaseComponent {
9029
-
9030
- constructor( name, value, callback, options = {} ) {
9031
-
9053
+ class TextInput extends BaseComponent
9054
+ {
9055
+ constructor( name, value, callback, options = {} )
9056
+ {
9032
9057
  super( BaseComponent.TEXT, name, String( value ), options );
9033
9058
 
9034
9059
  this.onGetValue = () => {
@@ -9115,7 +9140,7 @@ class TextInput extends BaseComponent {
9115
9140
  });
9116
9141
  }
9117
9142
 
9118
- wValue.addEventListener( "mousedown", function( e ){
9143
+ wValue.addEventListener( "mousedown", function( e ) {
9119
9144
  e.stopImmediatePropagation();
9120
9145
  e.stopPropagation();
9121
9146
  });
@@ -9165,10 +9190,10 @@ LX.TextInput = TextInput;
9165
9190
  * @description TextArea Component
9166
9191
  */
9167
9192
 
9168
- class TextArea extends BaseComponent {
9169
-
9170
- constructor( name, value, callback, options = {} ) {
9171
-
9193
+ class TextArea extends BaseComponent
9194
+ {
9195
+ constructor( name, value, callback, options = {} )
9196
+ {
9172
9197
  super( BaseComponent.TEXTAREA, name, value, options );
9173
9198
 
9174
9199
  this.onGetValue = () => {
@@ -9266,10 +9291,10 @@ LX.TextArea = TextArea;
9266
9291
  * @description Button Component
9267
9292
  */
9268
9293
 
9269
- class Button extends BaseComponent {
9270
-
9271
- constructor( name, value, callback, options = {} ) {
9272
-
9294
+ class Button extends BaseComponent
9295
+ {
9296
+ constructor( name, value, callback, options = {} )
9297
+ {
9273
9298
  super( BaseComponent.BUTTON, name, null, options );
9274
9299
 
9275
9300
  this.onGetValue = () => {
@@ -9488,10 +9513,10 @@ LX.Button = Button;
9488
9513
  * @description ComboButtons Component
9489
9514
  */
9490
9515
 
9491
- class ComboButtons extends BaseComponent {
9492
-
9493
- constructor( name, values, options = {} ) {
9494
-
9516
+ class ComboButtons extends BaseComponent
9517
+ {
9518
+ constructor( name, values, options = {} )
9519
+ {
9495
9520
  const shouldSelect = !( options.noSelection ?? false );
9496
9521
  let shouldToggle = shouldSelect && ( options.toggle ?? false );
9497
9522
 
@@ -9649,10 +9674,10 @@ LX.ComboButtons = ComboButtons;
9649
9674
  * @description Card Component
9650
9675
  */
9651
9676
 
9652
- class Card extends BaseComponent {
9653
-
9654
- constructor( name, options = {} ) {
9655
-
9677
+ class Card extends BaseComponent
9678
+ {
9679
+ constructor( name, options = {} )
9680
+ {
9656
9681
  options.hideName = true;
9657
9682
 
9658
9683
  super( BaseComponent.CARD, name, null, options );
@@ -9712,10 +9737,10 @@ LX.Card = Card;
9712
9737
  * @description Form Component
9713
9738
  */
9714
9739
 
9715
- class Form extends BaseComponent {
9716
-
9717
- constructor( name, data, callback, options = {} ) {
9718
-
9740
+ class Form extends BaseComponent
9741
+ {
9742
+ constructor( name, data, callback, options = {} )
9743
+ {
9719
9744
  if( data.constructor != Object )
9720
9745
  {
9721
9746
  console.error( "Form data must be an Object" );
@@ -9827,10 +9852,10 @@ LX.Form = Form;
9827
9852
  * @description Select Component
9828
9853
  */
9829
9854
 
9830
- class Select extends BaseComponent {
9831
-
9832
- constructor( name, values, value, callback, options = {} ) {
9833
-
9855
+ class Select extends BaseComponent
9856
+ {
9857
+ constructor( name, values, value, callback, options = {} )
9858
+ {
9834
9859
  super( BaseComponent.SELECT, name, value, options );
9835
9860
 
9836
9861
  this.onGetValue = () => {
@@ -10239,10 +10264,10 @@ LX.Select = Select;
10239
10264
  * @description Curve Component
10240
10265
  */
10241
10266
 
10242
- class Curve extends BaseComponent {
10243
-
10244
- constructor( name, values, callback, options = {} ) {
10245
-
10267
+ class Curve extends BaseComponent
10268
+ {
10269
+ constructor( name, values, callback, options = {} )
10270
+ {
10246
10271
  let defaultValues = JSON.parse( JSON.stringify( values ) );
10247
10272
 
10248
10273
  super( BaseComponent.CURVE, name, defaultValues, options );
@@ -10300,10 +10325,10 @@ LX.Curve = Curve;
10300
10325
  * @description Dial Component
10301
10326
  */
10302
10327
 
10303
- class Dial extends BaseComponent {
10304
-
10305
- constructor( name, values, callback, options = {} ) {
10306
-
10328
+ class Dial extends BaseComponent
10329
+ {
10330
+ constructor( name, values, callback, options = {} )
10331
+ {
10307
10332
  let defaultValues = JSON.parse( JSON.stringify( values ) );
10308
10333
 
10309
10334
  super( BaseComponent.DIAL, name, defaultValues, options );
@@ -10357,10 +10382,10 @@ LX.Dial = Dial;
10357
10382
  * @description Layers Component
10358
10383
  */
10359
10384
 
10360
- class Layers extends BaseComponent {
10361
-
10362
- constructor( name, value, callback, options = {} ) {
10363
-
10385
+ class Layers extends BaseComponent
10386
+ {
10387
+ constructor( name, value, callback, options = {} )
10388
+ {
10364
10389
  super( BaseComponent.LAYERS, name, value, options );
10365
10390
 
10366
10391
  this.onGetValue = () => {
@@ -10441,10 +10466,10 @@ LX.Layers = Layers;
10441
10466
  * @description ItemArray Component
10442
10467
  */
10443
10468
 
10444
- class ItemArray extends BaseComponent {
10445
-
10446
- constructor( name, values = [], callback, options = {} ) {
10447
-
10469
+ class ItemArray extends BaseComponent
10470
+ {
10471
+ constructor( name, values = [], callback, options = {} )
10472
+ {
10448
10473
  options.nameWidth = "100%";
10449
10474
 
10450
10475
  super( BaseComponent.ARRAY, name, null, options );
@@ -10559,10 +10584,10 @@ LX.ItemArray = ItemArray;
10559
10584
  * @description List Component
10560
10585
  */
10561
10586
 
10562
- class List extends BaseComponent {
10563
-
10564
- constructor( name, values, value, callback, options = {} ) {
10565
-
10587
+ class List extends BaseComponent
10588
+ {
10589
+ constructor( name, values, value, callback, options = {} )
10590
+ {
10566
10591
  super( BaseComponent.LIST, name, value, options );
10567
10592
 
10568
10593
  this.onGetValue = () => {
@@ -10659,10 +10684,10 @@ LX.List = List;
10659
10684
  * @description Tags Component
10660
10685
  */
10661
10686
 
10662
- class Tags extends BaseComponent {
10663
-
10664
- constructor( name, value, callback, options = {} ) {
10665
-
10687
+ class Tags extends BaseComponent
10688
+ {
10689
+ constructor( name, value, callback, options = {} )
10690
+ {
10666
10691
  value = value.replace( /\s/g, '' ).split( ',' );
10667
10692
 
10668
10693
  let defaultValue = [].concat( value );
@@ -10748,10 +10773,10 @@ LX.Tags = Tags;
10748
10773
  * @description Checkbox Component
10749
10774
  */
10750
10775
 
10751
- class Checkbox extends BaseComponent {
10752
-
10753
- constructor( name, value, callback, options = {} ) {
10754
-
10776
+ class Checkbox extends BaseComponent
10777
+ {
10778
+ constructor( name, value, callback, options = {} )
10779
+ {
10755
10780
  if( !name && !options.label )
10756
10781
  {
10757
10782
  throw( "Set Component Name or at least a label!" );
@@ -10831,10 +10856,10 @@ LX.Checkbox = Checkbox;
10831
10856
  * @description Toggle Component
10832
10857
  */
10833
10858
 
10834
- class Toggle extends BaseComponent {
10835
-
10836
- constructor( name, value, callback, options = {} ) {
10837
-
10859
+ class Toggle extends BaseComponent
10860
+ {
10861
+ constructor( name, value, callback, options = {} )
10862
+ {
10838
10863
  if( !name && !options.label )
10839
10864
  {
10840
10865
  throw( "Set Component Name or at least a label!" );
@@ -10915,10 +10940,10 @@ LX.Toggle = Toggle;
10915
10940
  * @description RadioGroup Component
10916
10941
  */
10917
10942
 
10918
- class RadioGroup extends BaseComponent {
10919
-
10920
- constructor( name, label, values, callback, options = {} ) {
10921
-
10943
+ class RadioGroup extends BaseComponent
10944
+ {
10945
+ constructor( name, label, values, callback, options = {} )
10946
+ {
10922
10947
  super( BaseComponent.RADIO, name, null, options );
10923
10948
 
10924
10949
  let currentIndex = null;
@@ -10994,10 +11019,10 @@ LX.RadioGroup = RadioGroup;
10994
11019
  * @description ColorInput Component
10995
11020
  */
10996
11021
 
10997
- class ColorInput extends BaseComponent {
10998
-
10999
- constructor( name, value, callback, options = {} ) {
11000
-
11022
+ class ColorInput extends BaseComponent
11023
+ {
11024
+ constructor( name, value, callback, options = {} )
11025
+ {
11001
11026
  value = value ?? "#000000";
11002
11027
 
11003
11028
  const useAlpha = options.useAlpha ??
@@ -11117,10 +11142,10 @@ LX.ColorInput = ColorInput;
11117
11142
  * @description RangeInput Component
11118
11143
  */
11119
11144
 
11120
- class RangeInput extends BaseComponent {
11121
-
11122
- constructor( name, value, callback, options = {} ) {
11123
-
11145
+ class RangeInput extends BaseComponent
11146
+ {
11147
+ constructor( name, value, callback, options = {} )
11148
+ {
11124
11149
  const ogValue = LX.deepCopy( value );
11125
11150
 
11126
11151
  super( BaseComponent.RANGE, name, LX.deepCopy( ogValue ), options );
@@ -11331,10 +11356,10 @@ LX.RangeInput = RangeInput;
11331
11356
  * @description NumberInput Component
11332
11357
  */
11333
11358
 
11334
- class NumberInput extends BaseComponent {
11335
-
11336
- constructor( name, value, callback, options = {} ) {
11337
-
11359
+ class NumberInput extends BaseComponent
11360
+ {
11361
+ constructor( name, value, callback, options = {} )
11362
+ {
11338
11363
  super( BaseComponent.NUMBER, name, value, options );
11339
11364
 
11340
11365
  this.onGetValue = () => {
@@ -11553,10 +11578,10 @@ LX.NumberInput = NumberInput;
11553
11578
  * @description Vector Component
11554
11579
  */
11555
11580
 
11556
- class Vector extends BaseComponent {
11557
-
11558
- constructor( numComponents, name, value, callback, options = {} ) {
11559
-
11581
+ class Vector extends BaseComponent
11582
+ {
11583
+ constructor( numComponents, name, value, callback, options = {} )
11584
+ {
11560
11585
  numComponents = LX.clamp( numComponents, 2, 4 );
11561
11586
  value = value ?? new Array( numComponents ).fill( 0 );
11562
11587
 
@@ -11803,10 +11828,10 @@ LX.Vector = Vector;
11803
11828
  * @description SizeInput Component
11804
11829
  */
11805
11830
 
11806
- class SizeInput extends BaseComponent {
11807
-
11808
- constructor( name, value, callback, options = {} ) {
11809
-
11831
+ class SizeInput extends BaseComponent
11832
+ {
11833
+ constructor( name, value, callback, options = {} )
11834
+ {
11810
11835
  super( BaseComponent.SIZE, name, value, options );
11811
11836
 
11812
11837
  this.onGetValue = () => {
@@ -11891,10 +11916,10 @@ LX.SizeInput = SizeInput;
11891
11916
  * @description OTPInput Component
11892
11917
  */
11893
11918
 
11894
- class OTPInput extends BaseComponent {
11895
-
11896
- constructor( name, value, callback, options = {} ) {
11897
-
11919
+ class OTPInput extends BaseComponent
11920
+ {
11921
+ constructor( name, value, callback, options = {} )
11922
+ {
11898
11923
  const pattern = options.pattern ?? "xxx-xxx";
11899
11924
  const patternSize = ( pattern.match(/x/g) || [] ).length;
11900
11925
 
@@ -12049,10 +12074,10 @@ LX.OTPInput = OTPInput;
12049
12074
  * @description Pad Component
12050
12075
  */
12051
12076
 
12052
- class Pad extends BaseComponent {
12053
-
12054
- constructor( name, value, callback, options = {} ) {
12055
-
12077
+ class Pad extends BaseComponent
12078
+ {
12079
+ constructor( name, value, callback, options = {} )
12080
+ {
12056
12081
  super( BaseComponent.PAD, name, null, options );
12057
12082
 
12058
12083
  this.onGetValue = () => {
@@ -12169,10 +12194,10 @@ LX.Pad = Pad;
12169
12194
  * @description Progress Component
12170
12195
  */
12171
12196
 
12172
- class Progress extends BaseComponent {
12173
-
12174
- constructor( name, value, options = {} ) {
12175
-
12197
+ class Progress extends BaseComponent
12198
+ {
12199
+ constructor( name, value, options = {} )
12200
+ {
12176
12201
  super( BaseComponent.PROGRESS, name, value, options );
12177
12202
 
12178
12203
  this.onGetValue = () => {
@@ -12306,10 +12331,10 @@ LX.Progress = Progress;
12306
12331
  * @description FileInput Component
12307
12332
  */
12308
12333
 
12309
- class FileInput extends BaseComponent {
12310
-
12311
- constructor( name, callback, options = { } ) {
12312
-
12334
+ class FileInput extends BaseComponent
12335
+ {
12336
+ constructor( name, callback, options = { } )
12337
+ {
12313
12338
  super( BaseComponent.FILE, name, null, options );
12314
12339
 
12315
12340
  let local = options.local ?? true;
@@ -12391,10 +12416,10 @@ LX.FileInput = FileInput;
12391
12416
  * @description Tree Component
12392
12417
  */
12393
12418
 
12394
- class Tree extends BaseComponent {
12395
-
12396
- constructor( name, data, options = {} ) {
12397
-
12419
+ class Tree extends BaseComponent
12420
+ {
12421
+ constructor( name, data, options = {} )
12422
+ {
12398
12423
  options.hideName = true;
12399
12424
 
12400
12425
  super( BaseComponent.TREE, name, null, options );
@@ -12473,10 +12498,10 @@ LX.Tree = Tree;
12473
12498
  * @description TabSections Component
12474
12499
  */
12475
12500
 
12476
- class TabSections extends BaseComponent {
12477
-
12478
- constructor( name, tabs, options = {} ) {
12479
-
12501
+ class TabSections extends BaseComponent
12502
+ {
12503
+ constructor( name, tabs, options = {} )
12504
+ {
12480
12505
  options.hideName = true;
12481
12506
 
12482
12507
  super( BaseComponent.TABS, name, null, options );
@@ -12580,10 +12605,10 @@ LX.TabSections = TabSections;
12580
12605
  * @description Counter Component
12581
12606
  */
12582
12607
 
12583
- class Counter extends BaseComponent {
12584
-
12585
- constructor( name, value, callback, options = { } ) {
12586
-
12608
+ class Counter extends BaseComponent
12609
+ {
12610
+ constructor( name, value, callback, options = { } )
12611
+ {
12587
12612
  super( BaseComponent.COUNTER, name, value, options );
12588
12613
 
12589
12614
  this.onGetValue = () => {
@@ -12650,10 +12675,10 @@ LX.Counter = Counter;
12650
12675
  * @description Table Component
12651
12676
  */
12652
12677
 
12653
- class Table extends BaseComponent {
12654
-
12655
- constructor( name, data, options = { } ) {
12656
-
12678
+ class Table extends BaseComponent
12679
+ {
12680
+ constructor( name, data, options = { } )
12681
+ {
12657
12682
  if( !data )
12658
12683
  {
12659
12684
  throw( "Data is needed to create a table!" );
@@ -12680,18 +12705,19 @@ class Table extends BaseComponent {
12680
12705
  this.filter = options.filter ?? false;
12681
12706
  this.customFilters = options.customFilters ?? false;
12682
12707
  this._toggleColumns = options.toggleColumns ?? false;
12708
+ this._sortColumns = options.sortColumns ?? true;
12683
12709
  this._currentFilter = options.filterValue;
12684
12710
 
12685
12711
  data.head = data.head ?? [];
12686
12712
  data.body = data.body ?? [];
12687
12713
  data.checkMap = { };
12688
12714
  data.colVisibilityMap = { };
12689
- data.head.forEach( (col, index) => { data.colVisibilityMap[ index ] = true; });
12715
+ data.head.forEach( ( col, index ) => { data.colVisibilityMap[ index ] = true; });
12690
12716
  this.data = data;
12691
12717
 
12692
- const compareFn = ( idx, order, a, b) => {
12693
- if (a[idx] < b[idx]) return -order;
12694
- else if (a[idx] > b[idx]) return order;
12718
+ const compareFn = ( idx, order, a, b ) => {
12719
+ if( a[ idx ] < b[ idx ] ) return -order;
12720
+ else if( a[ idx ] > b[ idx ] ) return order;
12695
12721
  return 0;
12696
12722
  };
12697
12723
 
@@ -12861,10 +12887,10 @@ class Table extends BaseComponent {
12861
12887
  icon: "Check",
12862
12888
  callback: () => {
12863
12889
  data.colVisibilityMap[ idx ] = !data.colVisibilityMap[ idx ];
12864
- const cells = table.querySelectorAll(`tr > *:nth-child(${idx + this.rowOffsetCount + 1})`);
12865
- cells.forEach(cell => {
12866
- cell.style.display = (cell.style.display === "none") ? "" : "none";
12867
- });
12890
+ const cells = table.querySelectorAll( `tr > *:nth-child(${idx + this.rowOffsetCount + 1})` );
12891
+ cells.forEach( cell => {
12892
+ cell.style.display = ( cell.style.display === "none" ) ? "" : "none";
12893
+ } );
12868
12894
  }
12869
12895
  };
12870
12896
  if( !data.colVisibilityMap[ idx ] ) delete item.icon;
@@ -12946,28 +12972,62 @@ class Table extends BaseComponent {
12946
12972
  th.classList.add( "centered" );
12947
12973
  }
12948
12974
 
12949
- const menuOptions = [
12950
- { name: "Asc", icon: "ArrowUpAZ", callback: sortFn.bind( this, idx, 1 ) },
12951
- { name: "Desc", icon: "ArrowDownAZ", callback: sortFn.bind( this, idx, -1 ) }
12952
- ];
12975
+ const menuOptions = [];
12953
12976
 
12954
- if( this._toggleColumns )
12977
+ if( options.columnActions )
12955
12978
  {
12956
- menuOptions.push(
12957
- null,
12979
+ for( let action of options.columnActions )
12980
+ {
12981
+ if( !action.name )
12958
12982
  {
12959
- name: "Hide", icon: "EyeOff", callback: () => {
12960
- data.colVisibilityMap[ idx ] = false;
12961
- const cells = table.querySelectorAll(`tr > *:nth-child(${idx + this.rowOffsetCount + 1})`);
12962
- cells.forEach(cell => {
12963
- cell.style.display = (cell.style.display === "none") ? "" : "none";
12964
- });
12965
- }
12983
+ console.warn( "Invalid column action (missing name):", action );
12984
+ continue;
12966
12985
  }
12986
+
12987
+ menuOptions.push( { name: action.name, icon: action.icon, className: action.className, callback: () => {
12988
+ const colRows = this.data.body.map( row => [ row[ idx ] ] );
12989
+ const mustRefresh = action.callback( colRows, table );
12990
+ if( mustRefresh )
12991
+ {
12992
+ this.refresh();
12993
+ }
12994
+ } } );
12995
+ }
12996
+ }
12997
+
12998
+ if( this._sortColumns )
12999
+ {
13000
+ if( menuOptions.length > 0 )
13001
+ {
13002
+ menuOptions.push( null );
13003
+ }
13004
+
13005
+ menuOptions.push(
13006
+ { name: "Asc", icon: "ArrowUpAZ", callback: sortFn.bind( this, idx, 1 ) },
13007
+ { name: "Desc", icon: "ArrowDownAZ", callback: sortFn.bind( this, idx, -1 ) }
12967
13008
  );
12968
13009
  }
12969
13010
 
13011
+ if( this._toggleColumns )
13012
+ {
13013
+ if( menuOptions.length > 0 )
13014
+ {
13015
+ menuOptions.push( null );
13016
+ }
13017
+
13018
+ menuOptions.push( {
13019
+ name: "Hide", icon: "EyeOff", callback: () => {
13020
+ data.colVisibilityMap[ idx ] = false;
13021
+ const cells = table.querySelectorAll(`tr > *:nth-child(${idx + this.rowOffsetCount + 1})`);
13022
+ cells.forEach( cell => {
13023
+ cell.style.display = ( cell.style.display === "none" ) ? "" : "none";
13024
+ } );
13025
+ }
13026
+ } );
13027
+ }
13028
+
12970
13029
  th.addEventListener( 'click', event => {
13030
+ if( menuOptions.length === 0 ) return;
12971
13031
  new LX.DropdownMenu( event.target, menuOptions, { side: "bottom", align: "start" });
12972
13032
  });
12973
13033
 
@@ -13333,10 +13393,10 @@ class Table extends BaseComponent {
13333
13393
  const idx = parseInt( v );
13334
13394
  if( !data.colVisibilityMap[ idx ] )
13335
13395
  {
13336
- const cells = table.querySelectorAll(`tr > *:nth-child(${idx + this.rowOffsetCount + 1})`);
13337
- cells.forEach(cell => {
13338
- cell.style.display = (cell.style.display === "none") ? "" : "none";
13339
- });
13396
+ const cells = table.querySelectorAll( `tr > *:nth-child(${idx + this.rowOffsetCount + 1})` );
13397
+ cells.forEach( cell => {
13398
+ cell.style.display = ( cell.style.display === "none" ) ? "" : "none";
13399
+ } );
13340
13400
  }
13341
13401
  }
13342
13402
  };
@@ -13346,8 +13406,8 @@ class Table extends BaseComponent {
13346
13406
  LX.doAsync( this.onResize.bind( this ) );
13347
13407
  }
13348
13408
 
13349
- getSelectedRows() {
13350
-
13409
+ getSelectedRows()
13410
+ {
13351
13411
  const selectedRows = [];
13352
13412
 
13353
13413
  for( const row of this.data.body )
@@ -13362,8 +13422,8 @@ class Table extends BaseComponent {
13362
13422
  return selectedRows;
13363
13423
  }
13364
13424
 
13365
- _setCentered( v ) {
13366
-
13425
+ _setCentered( v )
13426
+ {
13367
13427
  if( v.constructor == Boolean )
13368
13428
  {
13369
13429
  const container = this.root.querySelector( ".lextable" );
@@ -13396,10 +13456,10 @@ LX.Table = Table;
13396
13456
  * @description DatePicker Component
13397
13457
  */
13398
13458
 
13399
- class DatePicker extends BaseComponent {
13400
-
13401
- constructor( name, dateValue, callback, options = { } ) {
13402
-
13459
+ class DatePicker extends BaseComponent
13460
+ {
13461
+ constructor( name, dateValue, callback, options = { } )
13462
+ {
13403
13463
  super( BaseComponent.DATE, name, null, options );
13404
13464
 
13405
13465
  const dateAsRange = ( dateValue?.constructor === Array );
@@ -13514,10 +13574,10 @@ LX.DatePicker = DatePicker;
13514
13574
  * @description Map2D Component
13515
13575
  */
13516
13576
 
13517
- class Map2D extends BaseComponent {
13518
-
13519
- constructor( name, points, callback, options = {} ) {
13520
-
13577
+ class Map2D extends BaseComponent
13578
+ {
13579
+ constructor( name, points, callback, options = {} )
13580
+ {
13521
13581
  super( BaseComponent.MAP2D, name, null, options );
13522
13582
 
13523
13583
  this.onGetValue = () => {
@@ -13561,13 +13621,13 @@ LX.Map2D = Map2D;
13561
13621
  * @description Rate Component
13562
13622
  */
13563
13623
 
13564
- class Rate extends BaseComponent {
13565
-
13566
- constructor( name, value, callback, options = {} ) {
13567
-
13624
+ class Rate extends BaseComponent
13625
+ {
13626
+ constructor( name, value, callback, options = {} )
13627
+ {
13568
13628
  const allowHalf = options.allowHalf ?? false;
13569
13629
 
13570
- if( !allowHalf)
13630
+ if( !allowHalf )
13571
13631
  {
13572
13632
  value = Math.floor( value );
13573
13633
  }
@@ -15110,8 +15170,8 @@ LX.Branch = Branch;
15110
15170
 
15111
15171
  class Menubar {
15112
15172
 
15113
- constructor( items, options = {} ) {
15114
-
15173
+ constructor( items, options = {} )
15174
+ {
15115
15175
  this.root = document.createElement( "div" );
15116
15176
  this.root.className = "lexmenubar";
15117
15177
 
@@ -15128,8 +15188,8 @@ class Menubar {
15128
15188
  this.createEntries();
15129
15189
  }
15130
15190
 
15131
- _resetMenubar( focus ) {
15132
-
15191
+ _resetMenubar( focus )
15192
+ {
15133
15193
  this.root.querySelectorAll(".lexmenuentry").forEach( e => {
15134
15194
  e.classList.remove( 'selected' );
15135
15195
  delete e.dataset[ "built" ];
@@ -15149,8 +15209,8 @@ class Menubar {
15149
15209
  * @method createEntries
15150
15210
  */
15151
15211
 
15152
- createEntries() {
15153
-
15212
+ createEntries()
15213
+ {
15154
15214
  for( let item of this.items )
15155
15215
  {
15156
15216
  let key = item.name;
@@ -15216,7 +15276,8 @@ class Menubar {
15216
15276
  * @param {String} name
15217
15277
  */
15218
15278
 
15219
- getButton( name ) {
15279
+ getButton( name )
15280
+ {
15220
15281
  return this.buttons[ name ];
15221
15282
  }
15222
15283
 
@@ -15225,26 +15286,23 @@ class Menubar {
15225
15286
  * @param {Object} item: parent item
15226
15287
  * @param {Array} tokens: split path strings
15227
15288
  */
15228
- getSubitem( item, tokens ) {
15229
-
15230
- let subitem = null;
15231
- let path = tokens[ 0 ];
15232
-
15233
- for( let i = 0; i < item.length; i++ )
15289
+ getSubitem( item, tokens )
15290
+ {
15291
+ for( const s of item )
15234
15292
  {
15235
- if( item[ i ][ path ] )
15293
+ if ( s?.name != tokens[ 0 ] )
15236
15294
  {
15237
- if( tokens.length == 1 )
15238
- {
15239
- subitem = item[ i ];
15240
- return subitem;
15241
- }
15242
- else
15243
- {
15244
- tokens.splice( 0, 1 );
15245
- return this.getSubitem( item[ i ][ path ], tokens );
15246
- }
15295
+ continue;
15296
+ }
15247
15297
 
15298
+ if( tokens.length == 1 )
15299
+ {
15300
+ return s;
15301
+ }
15302
+ else if ( s.submenu )
15303
+ {
15304
+ tokens.shift();
15305
+ return this.getSubitem( s.submenu, tokens );
15248
15306
  }
15249
15307
  }
15250
15308
  }
@@ -15253,12 +15311,11 @@ class Menubar {
15253
15311
  * @method getItem
15254
15312
  * @param {String} path
15255
15313
  */
15256
- getItem( path ) {
15257
-
15258
- // process path
15259
- const tokens = path.split("/");
15260
-
15261
- return this.getSubitem(this.items, tokens)
15314
+ getItem( path )
15315
+ {
15316
+ // Process path
15317
+ const tokens = path.split( '/' );
15318
+ return this.getSubitem( this.items, tokens );
15262
15319
  }
15263
15320
 
15264
15321
  /**
@@ -15269,8 +15326,8 @@ class Menubar {
15269
15326
  * @param {Object} options
15270
15327
  */
15271
15328
 
15272
- setButtonIcon( name, icon, callback, options = {} ) {
15273
-
15329
+ setButtonIcon( name, icon, callback, options = {} )
15330
+ {
15274
15331
  if( !name )
15275
15332
  {
15276
15333
  throw( "Set Button Name!" );
@@ -15325,8 +15382,8 @@ class Menubar {
15325
15382
  * @param {Object} options
15326
15383
  */
15327
15384
 
15328
- setButtonImage( name, src, callback, options = {} ) {
15329
-
15385
+ setButtonImage( name, src, callback, options = {} )
15386
+ {
15330
15387
  if( !name )
15331
15388
  {
15332
15389
  throw( "Set Button Name!" );
@@ -15335,14 +15392,14 @@ class Menubar {
15335
15392
  let button = this.buttons[ name ];
15336
15393
  if( button )
15337
15394
  {
15338
- button.querySelector('img').src = src;
15395
+ button.querySelector( 'img' ).src = src;
15339
15396
  return;
15340
15397
  }
15341
15398
 
15342
15399
  // Otherwise, create it
15343
- button = document.createElement('div');
15400
+ button = document.createElement( 'div' );
15344
15401
  const disabled = options.disabled ?? false;
15345
- button.className = "lexmenubutton main" + (disabled ? " disabled" : "");
15402
+ button.className = "lexmenubutton main" + ( disabled ? " disabled" : "" );
15346
15403
  button.title = name;
15347
15404
  button.innerHTML = "<a><image src='" + src + "' class='lexicon' style='height:32px;'></a>";
15348
15405
 
@@ -15366,11 +15423,11 @@ class Menubar {
15366
15423
 
15367
15424
  const _b = button.querySelector('a');
15368
15425
 
15369
- _b.addEventListener( "mousedown", (e) => {
15426
+ _b.addEventListener( "mousedown", e => {
15370
15427
  e.preventDefault();
15371
15428
  });
15372
15429
 
15373
- _b.addEventListener( "mouseup", (e) => {
15430
+ _b.addEventListener( "mouseup", e => {
15374
15431
  if( callback && !disabled )
15375
15432
  {
15376
15433
  callback.call( this, _b, e );
@@ -15387,8 +15444,8 @@ class Menubar {
15387
15444
  * float: center (Default), right
15388
15445
  */
15389
15446
 
15390
- addButtons( buttons, options = {} ) {
15391
-
15447
+ addButtons( buttons, options = {} )
15448
+ {
15392
15449
  if( !buttons )
15393
15450
  {
15394
15451
  throw( "No buttons to add!" );
@@ -15415,9 +15472,8 @@ class Menubar {
15415
15472
  }
15416
15473
  }
15417
15474
 
15418
- for( let i = 0; i < buttons.length; ++i )
15475
+ for( const data of buttons )
15419
15476
  {
15420
- const data = buttons[ i ];
15421
15477
  const title = data.title;
15422
15478
  const button = new LX.Button( title, data.label, data.callback, {
15423
15479
  title,