neo.mjs 6.10.12 → 6.10.14

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.
Files changed (37) hide show
  1. package/apps/ServiceWorker.mjs +2 -2
  2. package/apps/portal/view/learn/LivePreview.mjs +4 -2
  3. package/buildScripts/createAppMinimal.mjs +0 -30
  4. package/examples/ServiceWorker.mjs +2 -2
  5. package/examples/button/base/neo-config.json +1 -2
  6. package/examples/dialog/MainContainer.mjs +2 -0
  7. package/package.json +4 -4
  8. package/resources/data/deck/learnneo/p/2023-10-14T19-25-08-153Z.md +1 -0
  9. package/resources/data/deck/learnneo/p/ComponentModels.md +27 -13
  10. package/resources/data/deck/learnneo/p/DescribingTheUI.md +1 -1
  11. package/resources/data/deck/learnneo/p/Earthquakes.md +1226 -31
  12. package/resources/data/deck/learnneo/p/Events.md +11 -0
  13. package/resources/data/deck/learnneo/p/GuideEvents.md +153 -0
  14. package/resources/data/deck/learnneo/t.json +3 -1
  15. package/resources/scss/src/apps/portal/learn/ContentView.scss +1 -0
  16. package/resources/scss/src/list/Base.scss +1 -45
  17. package/src/DefaultConfig.mjs +2 -2
  18. package/src/component/Base.mjs +32 -0
  19. package/src/data/RecordFactory.mjs +0 -3
  20. package/src/dialog/Base.mjs +14 -7
  21. package/src/form/field/Picker.mjs +9 -1
  22. package/src/form/field/Select.mjs +23 -4
  23. package/src/form/field/Text.mjs +4 -2
  24. package/src/layout/Flexbox.mjs +31 -23
  25. package/src/layout/HBox.mjs +1 -1
  26. package/src/layout/VBox.mjs +1 -1
  27. package/src/main/DomAccess.mjs +11 -3
  28. package/src/main/DomUtils.mjs +26 -3
  29. package/src/main/addon/Navigator.mjs +139 -27
  30. package/src/manager/DomEvent.mjs +9 -3
  31. package/src/manager/Focus.mjs +3 -1
  32. package/src/util/String.mjs +3 -2
  33. package/test/components/files/form/field/Select.mjs +25 -4
  34. package/resources/data/deck/learnneo/p/AddingProperties.md +0 -1
  35. package/resources/data/deck/learnneo/p/ComponentState.md +0 -1
  36. package/resources/scss/src/apps/newwebsite/Viewport.scss +0 -32
  37. package/resources/scss/theme-neo-light/design-tokens/Components.scss +0 -3
@@ -140,3 +140,14 @@ class MainView extends Base {
140
140
  }
141
141
  Neo.applyClassConfig(MainView);
142
142
  </pre>
143
+
144
+ How are events set up? We don't really care, but in case you're curious: Neo.mjs has a `Neo.core.Observable` class
145
+ that can be mixed into any class. It maintains a `listeners` object map that's a key-value pair, where
146
+ the key is the event name, and the value is an array of function references. The first time a listener is
147
+ added an entry is added to the map using the event name as the key, and the event handler added as the first
148
+ item in the associated array. If another listener is added for the same event, a second item is added to the
149
+ array. If a new event is added, a new entry is added. Etc. When the event is fired, Neo.mjs looks up the map
150
+ entry for the event name, then runs each function in the array, passing whatever data is specified in the
151
+ call to `fire()`.
152
+
153
+ <img style="width:80%" src="https://s3.amazonaws.com/mjs.neo.learning.images/gettingStarted/events/ObservableInMemory.png"></img>
@@ -0,0 +1,153 @@
1
+ All components fire events. For example, form fields fire a `change` event, various
2
+ focus events, and others. Some other types fire events too, such as `Neo.data.Store`,
3
+ which fires a `load` event after the store is loaded with data.
4
+
5
+ Some terminology related to events is that events are _fired_, and as a result, some
6
+ event _handler_ &mdash; or _listener_ &mdash; is run.
7
+
8
+ To specify an event handler, use `listeners: {}`, specifying in as many event/handler
9
+ pairs as you need.
10
+
11
+ The code below shows two text fields, with `listeners` for `change` and `focusEnter`.
12
+ (The events for any component are documened in the API docs.)
13
+
14
+ <pre data-neo>
15
+ import Base from '../../../../src/container/Base.mjs';
16
+ import TextField from '../../../../src/form/field/Text.mjs';
17
+ class MainView extends Base {
18
+ static config = {
19
+ className : 'Example.view.MainView',
20
+ layout: {ntype:'vbox', align:'start'},
21
+ items : [{
22
+ module: TextField,
23
+ labelText : 'First name',
24
+ listeners: {
25
+ change: data=>console.log(data.value), // There are other properties, like oldValue
26
+ focusEnter: data=>console.log(`Entering ${data.component.labelText}`)
27
+ }
28
+ },
29
+ {
30
+ module: TextField,
31
+ labelText : 'Last name',
32
+ listeners: {
33
+ change: data=>console.log(data.value), // There are other properties, like oldValue
34
+ focusEnter: data=>console.log(`Entering ${data.component.labelText}`)
35
+ }
36
+ }]
37
+ }
38
+ }
39
+ Neo.applyClassConfig(MainView);
40
+ </pre>
41
+
42
+ If you run the example, and open the browser's debugger, you'll see the console being logged as you type or give
43
+ focus to either field.
44
+
45
+ Note that the handlers specify an in-line function. For trivial cases, that might be ok. But normally
46
+ you'd want better separation of concerns by placing those event handlers in a separate class. Neo.mjs provides
47
+ that with a _component controller_.
48
+
49
+ A `Neo.controller.Component` is a simple class associated with a component class. As a view is created, an
50
+ instance of its associated contoller is automatically created.
51
+
52
+ <pre data-neo>
53
+ import Base from '../../../../src/container/Base.mjs';
54
+ import Controller from '../../../../src/controller/Component.mjs';
55
+ import TextField from '../../../../src/form/field/Text.mjs';
56
+
57
+ class MainViewController extends Controller {
58
+ static config = {
59
+ className: 'Example.view.MainViewController'
60
+ }
61
+ onChange(data){
62
+ console.log(data.value);
63
+ }
64
+ }
65
+ Neo.applyClassConfig(MainViewController);
66
+
67
+
68
+ class MainView extends Base {
69
+ static config = {
70
+ className : 'Example.view.MainView',
71
+ controller: MainViewController,
72
+ layout: {ntype:'vbox', align:'start'},
73
+ items : [{
74
+ module: TextField,
75
+ labelText : 'Name',
76
+ listeners: {
77
+ change: 'onChange'
78
+ }
79
+ }]
80
+ }
81
+ }
82
+ Neo.applyClassConfig(MainView);
83
+ </pre>
84
+
85
+ (It's important to keep in mind that in Neo.mjs, all class definitions are coded in their own
86
+ source file: one class per file. In the examples we're putting all the relevant classes together
87
+ to make it easier to see the source code for every class being used. But in an
88
+ actual applications the controller class would be coded in its own source file &mdash; named something
89
+ like `MainViewController.mjs` &mdash; and that would be imported into the view.)
90
+
91
+ The ability to fire events and add listeners is provided by `Neo.core.Observable`, which is mixed into
92
+ classes that need that ability. All components are observable, `Neo.data.Store` is observable, and some
93
+ others. `Neo.core.Observable` introduces a few methods and properties, such as `listeners`, which
94
+ is used in the examples above, `on()` for procedurally adding an event listener, and `fire()`, which is
95
+ how you fire events in the custom classes you create.
96
+
97
+ Here's example illustrating how `fire()` is used. The code defines a `ToggleButton`
98
+ class, which is just a button with a `checked` property: the button shows a checked or unchecked
99
+ checkbox depending on the value of `checked`.
100
+
101
+ The code uses a special Neo.mjs feature you haven't seen yet &mdash; the use of an underscore property.
102
+ We'll discuss that at length later, but in a nutshell, config properties ending in an underscore
103
+ automatically get lifecycle methods run before the value is assigned, after the value is assigned, and
104
+ before the value is accessed. We're using the _after_ method to fire a `change` event.
105
+
106
+ <pre data-neo>
107
+ import Base from '../../../../src/container/Base.mjs';
108
+ import Button from '../../../../src/button/Base.mjs';
109
+ import TextField from '../../../../src/form/field/Text.mjs';
110
+
111
+ class ToggleButton extends Button {
112
+ static config = {
113
+ className: 'Example.view.ToggleButton',
114
+ checked_: false
115
+ }
116
+ afterSetChecked(checked){
117
+ this.iconCls = checked?'fa fa-square-check':'fa fa-square';
118
+ this.fire('change', {component: this, checked}); // This is where our custom event is being fired
119
+ }
120
+ onClick(data){
121
+ super.onClick(data);
122
+ this.checked = !this.checked;
123
+ }
124
+ }
125
+ Neo.applyClassConfig(ToggleButton);
126
+
127
+
128
+ class MainView extends Base {
129
+ static config = {
130
+ className : 'Example.view.MainView',
131
+ layout: {ntype:'vbox', align:'start'},
132
+ items : [{
133
+ module: ToggleButton,
134
+ text: 'Toggle',
135
+ listeners: {
136
+ change: data => console.log(data.checked) // Here, we're listening to the custom event
137
+ }
138
+ }]
139
+ }
140
+ }
141
+ Neo.applyClassConfig(MainView);
142
+ </pre>
143
+
144
+ How are events set up? We don't really care, but in case you're curious: Neo.mjs has a `Neo.core.Observable` class
145
+ that can be mixed into any class. It maintains a `listeners` object map that's a key-value pair, where
146
+ the key is the event name, and the value is an array of function references. The first time a listener is
147
+ added an entry is added to the map using the event name as the key, and the event handler added as the first
148
+ item in the associated array. If another listener is added for the same event, a second item is added to the
149
+ array. If a new event is added, a new entry is added. Etc. When the event is fired, Neo.mjs looks up the map
150
+ entry for the event name, then runs each function in the array, passing whatever data is specified in the
151
+ call to `fire()`.
152
+
153
+ <img style="width:80%" src="https://s3.amazonaws.com/mjs.neo.learning.images/gettingStarted/events/ObservableInMemory.png"></img>
@@ -12,11 +12,13 @@
12
12
  {"name": "Tutorials", "parentId": null, "isLeaf": false, "expanded": false, "id": "Tutorials"},
13
13
  {"name": "Rock Scissors Paper", "parentId": "Tutorials", "isLeaf": true, "expanded": false, "id": "RSP"},
14
14
  {"name": "Earthquakes", "parentId": "Tutorials", "isLeaf": true, "expanded": false, "id": "Earthquakes"},
15
- {"name": "Cookbook", "parentId": null, "isLeaf": false, "expanded": false, "id": "InDepth"},
15
+ {"name": "Guides", "parentId": null, "isLeaf": false, "expanded": false, "id": "InDepth"},
16
16
  {"name": "Config", "parentId": "InDepth", "isLeaf": false, "id": "Config"},
17
17
  {"name": "Instance Lifecycle", "parentId": "InDepth", "isLeaf": false, "id": "InstanceLifecycle"},
18
18
  {"name": "User Input (Forms)", "parentId": "InDepth", "isLeaf": false, "id": "Forms"},
19
+ {"name": "Layouts", "parentId": "InDepth", "isLeaf": false, "id": "Layouts"},
19
20
  {"name": "Custom Components", "parentId": "InDepth", "isLeaf": false, "id": "CustomComponents"},
21
+ {"name": "Events", "parentId": "InDepth", "isLeaf": true, "expanded": false, "id": "GuideEvents"},
20
22
  {"name": "Tables (Stores)", "parentId": "InDepth", "isLeaf": false, "id": "Tables"},
21
23
  {"name": "Shared Bindable Data (Component Models)", "parentId": "InDepth", "isLeaf": false, "id": "InDepthComponentModels"},
22
24
  {"name": "Multi-Window Applications", "parentId": "InDepth", "isLeaf": false, "id": "MultiWindow"},
@@ -77,4 +77,5 @@
77
77
  box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.2);
78
78
  }
79
79
 
80
+
80
81
  }
@@ -54,51 +54,7 @@
54
54
  cursor: pointer;
55
55
 
56
56
  &:hover {
57
- background-color: var(--list-item-background-color-hover) !important;
58
- color : var(--list-container-list-color);
59
- }
60
- &:active {
61
- background-color: var(--list-item-background-color-active);
62
- color : var(--list-container-list-color);
63
- }
64
- &:active {
65
- background-color: var(--list-item-background-color-active);
66
- color : var(--list-container-list-color);
67
- }
68
- &:active {
69
- background-color: var(--list-item-background-color-active);
70
- color : var(--list-container-list-color);
71
- }
72
- &:active {
73
- background-color: var(--list-item-background-color-active);
74
- color : var(--list-container-list-color);
75
- }
76
- &:active {
77
- background-color: var(--list-item-background-color-active);
78
- color : var(--list-container-list-color);
79
- }
80
- &:active {
81
- background-color: var(--list-item-background-color-active);
82
- color : var(--list-container-list-color);
83
- }
84
- &:active {
85
- background-color: var(--list-item-background-color-active);
86
- color : var(--list-container-list-color);
87
- }
88
- &:active {
89
- background-color: var(--list-item-background-color-active);
90
- color : var(--list-container-list-color);
91
- }
92
- &:active {
93
- background-color: var(--list-item-background-color-active);
94
- color : var(--list-container-list-color);
95
- }
96
- &:active {
97
- background-color: var(--list-item-background-color-active);
98
- color : var(--list-container-list-color);
99
- }
100
- &:active {
101
- background-color: var(--list-item-background-color-active);
57
+ background-color: var(--list-item-background-color-hover);
102
58
  color : var(--list-container-list-color);
103
59
  }
104
60
  &:active {
@@ -236,12 +236,12 @@ const DefaultConfig = {
236
236
  useVdomWorker: true,
237
237
  /**
238
238
  * buildScripts/injectPackageVersion.mjs will update this value
239
- * @default '6.10.12'
239
+ * @default '6.10.14'
240
240
  * @memberOf! module:Neo
241
241
  * @name config.version
242
242
  * @type String
243
243
  */
244
- version: '6.10.12'
244
+ version: '6.10.14'
245
245
  };
246
246
 
247
247
  Object.assign(DefaultConfig, {
@@ -643,6 +643,10 @@ class Base extends CoreBase {
643
643
  me[state]()
644
644
  }
645
645
 
646
+ if (!value) {
647
+ me.revertFocus();
648
+ }
649
+
646
650
  me.fire(state, {id: me.id});
647
651
  me.fire('hiddenChange', {id: me.id, oldValue, value})
648
652
  }
@@ -781,10 +785,25 @@ class Base extends CoreBase {
781
785
 
782
786
  if (me.floating) {
783
787
  me.alignTo();
788
+
789
+ // Focus will be pushed into the first input field or other focusable item
790
+ Neo.main.DomAccess.focus({
791
+ id : this.id,
792
+ children : true
793
+ });
784
794
  }
785
795
 
786
796
  me.fire('mounted', me.id)
787
797
  }
798
+ else {
799
+ me.revertFocus();
800
+ }
801
+ }
802
+ }
803
+
804
+ revertFocus() {
805
+ if (this.containsFocus && this.focusEnterData?.relatedTarget) {
806
+ Neo.getComponent(this.focusEnterData.relatedTarget.id)?.focus();
788
807
  }
789
808
  }
790
809
 
@@ -1131,6 +1150,7 @@ class Base extends CoreBase {
1131
1150
 
1132
1151
  if (value) {
1133
1152
  value = ClassSystemUtil.beforeSetInstance(value, KeyNavigation, {
1153
+ keyDownEventBubble : true,
1134
1154
  keys: value
1135
1155
  })
1136
1156
  }
@@ -1257,6 +1277,8 @@ class Base extends CoreBase {
1257
1277
  parentModel = parent?.getModel(),
1258
1278
  parentVdom;
1259
1279
 
1280
+ me.revertFocus();
1281
+
1260
1282
  me.domListeners = [];
1261
1283
 
1262
1284
  me.controller = null; // triggers destroy()
@@ -1816,6 +1838,16 @@ class Base extends CoreBase {
1816
1838
  this.keys?.register(this)
1817
1839
  }
1818
1840
 
1841
+ onFocusEnter(data) {
1842
+ // If we are hidden, or unmounted while we still contain focus, we have to revert
1843
+ // focus to where it came from if possible
1844
+ this.focusEnterData = data;
1845
+ }
1846
+
1847
+ onFocusLeave() {
1848
+ this.focusEnterData = null;
1849
+ }
1850
+
1819
1851
  /**
1820
1852
  * Triggered by manager.Focus
1821
1853
  * @name onFocusEnter
@@ -68,9 +68,6 @@ class RecordFactory extends Base {
68
68
  properties;
69
69
 
70
70
  Object.defineProperties(me, {
71
- [Symbol.for('isRecord')]: {
72
- value: true
73
- },
74
71
  _isModified: {
75
72
  value : false,
76
73
  writable: true
@@ -100,6 +100,9 @@ class Base extends Panel {
100
100
  * @protected
101
101
  */
102
102
  isDragging: false,
103
+ keys: {
104
+ Escape: 'onKeyDownEscape'
105
+ },
103
106
  /**
104
107
  * @member {String} maximizeCls='far fa-window-maximize'
105
108
  */
@@ -216,8 +219,7 @@ class Base extends Panel {
216
219
  * @protected
217
220
  */
218
221
  afterSetDraggable(value, oldValue) {
219
- let me = this,
220
- domListeners = me.domListeners,
222
+ let me = this,
221
223
  cls;
222
224
 
223
225
  if (oldValue !== undefined && me.headerToolbar) {
@@ -230,21 +232,21 @@ class Base extends Panel {
230
232
  DragZone = module.default;
231
233
 
232
234
  if (!me.dragListenersAdded) {
233
- domListeners.push(
235
+ const dragListeners = [
234
236
  {'drag:end' : me.onDragEnd, scope: me, delegate: '.neo-header-toolbar'},
235
237
  {'drag:start': me.onDragStart, scope: me, delegate: '.neo-header-toolbar'}
236
- );
238
+ ];
237
239
 
238
240
  if (me.dragZoneConfig?.alwaysFireDragMove) {
239
- domListeners.push(
241
+ dragListeners.push(
240
242
  {'drag:move': me.onDragMove, scope: me, delegate: '.neo-header-toolbar'}
241
243
  )
242
244
  }
243
245
 
244
- me.domListeners = domListeners;
246
+ me.domListeners = [...me.domListeners, ...dragListeners];
245
247
  me.dragListenersAdded = true
246
248
  }
247
- })
249
+ });
248
250
  }
249
251
 
250
252
  /**
@@ -444,6 +446,7 @@ class Base extends Panel {
444
446
  close(animate=!!this.animateTargetId) {
445
447
  let me = this;
446
448
 
449
+ me.revertFocus();
447
450
  if (animate) {
448
451
  me.animateHide()
449
452
  } else {
@@ -694,6 +697,10 @@ class Base extends Panel {
694
697
  }
695
698
  }
696
699
 
700
+ onKeyDownEscape() {
701
+ this.hidden = true;
702
+ }
703
+
697
704
  /**
698
705
  * @param {Boolean} animate=!!this.animateTargetId
699
706
  */
@@ -282,7 +282,15 @@ class Picker extends Text {
282
282
  * @protected
283
283
  */
284
284
  onKeyDownEscape(data) {
285
- this.pickerIsMounted && this.hidePicker()
285
+ if (this.pickerIsMounted) {
286
+ this.hidePicker();
287
+
288
+ // We processed this event, and it should not proceed to ancestor components
289
+ data.cancelBubble = true;
290
+
291
+ // And no further listeers should be notified
292
+ return false;
293
+ }
286
294
  }
287
295
 
288
296
  /**
@@ -219,20 +219,40 @@ class Select extends Picker {
219
219
  * @protected
220
220
  */
221
221
  beforeSetStore(value, oldValue) {
222
+ const
223
+ me = this,
224
+ { valueField, displayField} = me;
225
+
222
226
  oldValue?.destroy();
223
227
 
228
+ // Promote an array of items to be a Store
229
+ if (Array.isArray(value)) {
230
+ value = {
231
+ data : value.map((v, i) => {
232
+ // Simplest case is just picking string values.
233
+ if (typeof v === 'string') {
234
+ v = {
235
+ [valueField] : v,
236
+ [displayField] : v
237
+ };
238
+ }
239
+ return v;
240
+ })
241
+ };
242
+ }
243
+
224
244
  // to reduce boilerplate code, a store config object without a defined model should default
225
245
  // to displayField & valueField defaults
226
246
  if (Neo.typeOf(value) === 'Object' && !value.model && !value.module && !value.ntype) {
227
247
  value.model = {
228
248
  fields: [
229
- {name: 'id', type: 'String'},
230
- {name: 'name', type: 'String'}
249
+ {name: valueField, type: 'String'},
250
+ {name: displayField, type: 'String'}
231
251
  ]
232
252
  }
233
253
  }
234
254
 
235
- return ClassSystemUtil.beforeSetInstance(value, Store)
255
+ return ClassSystemUtil.beforeSetInstance(value, Store);
236
256
  }
237
257
 
238
258
  /**
@@ -515,7 +535,6 @@ class Select extends Picker {
515
535
 
516
536
  me.activeRecord = store.getAt(activeIndex)
517
537
  me.activeRecordId = me.activeRecord[store.keyProperty || model.keyProperty]
518
- me.getInputEl()['aria-activedescendant'] = activeItem;
519
538
 
520
539
  // Update typeahead hint (which updates DOM), or update DOM
521
540
  me.typeAhead ? me.updateTypeAheadValue(me.lastManualInput) : me.update();
@@ -1266,6 +1266,8 @@ class Text extends Base {
1266
1266
  * @protected
1267
1267
  */
1268
1268
  onFocusEnter(data) {
1269
+ super.onFocusEnter(data);
1270
+
1269
1271
  let me = this,
1270
1272
  cls = me.cls;
1271
1273
 
@@ -1323,7 +1325,7 @@ class Text extends Base {
1323
1325
  onInputValueChange(data) {
1324
1326
  let me = this,
1325
1327
  oldValue = me.value,
1326
- value = data.value ? data.value.toString().trim() : me.emptyValue,
1328
+ value = data.value,
1327
1329
  vnode = VNodeUtil.findChildVnode(me.vnode, {nodeName: 'input'});
1328
1330
 
1329
1331
  if (vnode) {
@@ -1526,7 +1528,7 @@ class Text extends Base {
1526
1528
  minLength = me.minLength,
1527
1529
  required = me.required,
1528
1530
  returnValue = true,
1529
- value = me.value ? me.value.toString().trim() : me.emptyValue,
1531
+ value = me.value,
1530
1532
  valueLength = value?.toString().length,
1531
1533
  inputPattern = me.inputPattern,
1532
1534
  isEmpty = value !== 0 && (!value || valueLength < 1),
@@ -85,7 +85,7 @@ class Flexbox extends Base {
85
85
  * @protected
86
86
  */
87
87
  afterSetAlign(value, oldValue) {
88
- oldValue && this.updateInputValue(value, oldValue, 'align')
88
+ oldValue && this.updateInputValue(value, oldValue, 'align');
89
89
  }
90
90
 
91
91
  /**
@@ -95,7 +95,7 @@ class Flexbox extends Base {
95
95
  * @protected
96
96
  */
97
97
  afterSetDirection(value, oldValue) {
98
- oldValue && this.updateInputValue(value, oldValue, 'direction')
98
+ oldValue && this.updateInputValue(value, oldValue, 'direction');
99
99
  }
100
100
 
101
101
  /**
@@ -111,7 +111,7 @@ class Flexbox extends Base {
111
111
  style = item.wrapperStyle;
112
112
 
113
113
  style.gap = value;
114
- item.wrapperStyle = style
114
+ item.wrapperStyle = style;
115
115
  }
116
116
 
117
117
  /**
@@ -121,7 +121,7 @@ class Flexbox extends Base {
121
121
  * @protected
122
122
  */
123
123
  afterSetPack(value, oldValue) {
124
- oldValue && this.updateInputValue(value, oldValue, 'pack')
124
+ oldValue && this.updateInputValue(value, oldValue, 'pack');
125
125
  }
126
126
 
127
127
  /**
@@ -131,7 +131,7 @@ class Flexbox extends Base {
131
131
  * @protected
132
132
  */
133
133
  afterSetWrap(value, oldValue) {
134
- oldValue && this.updateInputValue(value, oldValue, 'wrap')
134
+ oldValue && this.updateInputValue(value, oldValue, 'wrap');
135
135
  }
136
136
 
137
137
  /**
@@ -143,11 +143,11 @@ class Flexbox extends Base {
143
143
  flex = style.flex || item.flex || (this.align === 'stretch' ? 1 : '0 1 auto');
144
144
 
145
145
  if (flex === 1) {
146
- flex = '1 1 auto'
146
+ flex = '1 1 auto';
147
147
  }
148
148
 
149
149
  style.flex = flex;
150
- item.wrapperStyle = style
150
+ item.wrapperStyle = style;
151
151
  }
152
152
 
153
153
  /**
@@ -160,7 +160,7 @@ class Flexbox extends Base {
160
160
  wrapperCls = container?.wrapperCls || [];
161
161
 
162
162
  if (!container) {
163
- Neo.logError('layout.Flexbox: applyRenderAttributes -> container not yet created', me.containerId)
163
+ Neo.logError('layout.Flexbox: applyRenderAttributes -> container not yet created', me.containerId);
164
164
  }
165
165
 
166
166
  NeoArray.add(wrapperCls, prefix + 'container');
@@ -170,7 +170,7 @@ class Flexbox extends Base {
170
170
  me.pack && NeoArray.add(wrapperCls, prefix + 'pack-' + me.pack);
171
171
  me.wrap && NeoArray.add(wrapperCls, prefix + 'wrap-' + me.wrap);
172
172
 
173
- container.wrapperCls = wrapperCls
173
+ container.wrapperCls = wrapperCls;
174
174
  }
175
175
 
176
176
  /**
@@ -181,7 +181,7 @@ class Flexbox extends Base {
181
181
  * @returns {String|null} value
182
182
  */
183
183
  beforeSetAlign(value, oldValue) {
184
- return this.testInputValue(value, oldValue, 'alignValues', 'align')
184
+ return this.testInputValue(value, oldValue, 'alignValues', 'align');
185
185
  }
186
186
 
187
187
  /**
@@ -203,7 +203,7 @@ class Flexbox extends Base {
203
203
  * @returns {String|null} value
204
204
  */
205
205
  beforeSetPack(value, oldValue) {
206
- return this.testInputValue(value, oldValue, 'packValues', 'pack')
206
+ return this.testInputValue(value, oldValue, 'packValues', 'pack');
207
207
  }
208
208
 
209
209
  /**
@@ -214,7 +214,7 @@ class Flexbox extends Base {
214
214
  * @returns {String} value
215
215
  */
216
216
  beforeSetWrap(value, oldValue) {
217
- return this.testInputValue(value, oldValue, 'wrapValues', 'wrap')
217
+ return this.testInputValue(value, oldValue, 'wrapValues', 'wrap');
218
218
  }
219
219
 
220
220
  /**
@@ -227,7 +227,7 @@ class Flexbox extends Base {
227
227
  let style = item.wrapperStyle || {};
228
228
 
229
229
  style.flex = item.flex || null;
230
- item.wrapperStyle = style
230
+ item.wrapperStyle = style;
231
231
  }
232
232
 
233
233
  /**
@@ -242,17 +242,25 @@ class Flexbox extends Base {
242
242
  wrapperCls = container?.wrapperCls || [];
243
243
 
244
244
  if (!container) {
245
- Neo.logError('layout.Flexbox: removeRenderAttributes -> container not yet created', me.containerId)
245
+ Neo.logError('layout.Flexbox: removeRenderAttributes -> container not yet created', me.containerId);
246
246
  }
247
247
 
248
248
  NeoArray.remove(wrapperCls, prefix + 'container');
249
249
 
250
- me.align && NeoArray.remove(wrapperCls, prefix + 'align-' + me.align);
251
- me.direction && NeoArray.remove(wrapperCls, prefix + 'direction-' + me.direction);
252
- me.pack && NeoArray.remove(wrapperCls, prefix + 'pack-' + me.pack);
253
- me.wrap && NeoArray.remove(wrapperCls, prefix + 'wrap-' + me.wrap);
250
+ if (me.align) {
251
+ NeoArray.remove(wrapperCls, prefix + 'align-' + me.align);
252
+ }
253
+ if (me.direction) {
254
+ NeoArray.remove(wrapperCls, prefix + 'direction-' + me.direction);
255
+ }
256
+ if (me.pack) {
257
+ NeoArray.remove(wrapperCls, prefix + 'pack-' + me.pack);
258
+ }
259
+ if (me.wrap) {
260
+ NeoArray.remove(wrapperCls, prefix + 'wrap-' + me.wrap);
261
+ }
254
262
 
255
- container.wrapperCls = wrapperCls
263
+ container.wrapperCls = wrapperCls;
256
264
  }
257
265
 
258
266
  /**
@@ -269,10 +277,10 @@ class Flexbox extends Base {
269
277
 
270
278
  if (!NeoArray.hasItem(validValues, value)) {
271
279
  Neo.logError(this.containerId, '-> layout: supported values for "' + propertyName + '" are' , validValues);
272
- return oldValue
280
+ return oldValue;
273
281
  }
274
282
 
275
- return value
283
+ return value;
276
284
  }
277
285
 
278
286
  /**
@@ -292,10 +300,10 @@ class Flexbox extends Base {
292
300
  NeoArray.remove(wrapperCls, prefix + propertyName + '-' + oldValue);
293
301
 
294
302
  if (value !== null) {
295
- NeoArray.add(wrapperCls, prefix + propertyName + '-' + value)
303
+ NeoArray.add(wrapperCls, prefix + propertyName + '-' + value);
296
304
  }
297
305
 
298
- container.wrapperCls = wrapperCls
306
+ container.wrapperCls = wrapperCls;
299
307
  }
300
308
  }
301
309
  }