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.
- package/apps/ServiceWorker.mjs +2 -2
- package/apps/portal/view/learn/LivePreview.mjs +4 -2
- package/buildScripts/createAppMinimal.mjs +0 -30
- package/examples/ServiceWorker.mjs +2 -2
- package/examples/button/base/neo-config.json +1 -2
- package/examples/dialog/MainContainer.mjs +2 -0
- package/package.json +4 -4
- package/resources/data/deck/learnneo/p/2023-10-14T19-25-08-153Z.md +1 -0
- package/resources/data/deck/learnneo/p/ComponentModels.md +27 -13
- package/resources/data/deck/learnneo/p/DescribingTheUI.md +1 -1
- package/resources/data/deck/learnneo/p/Earthquakes.md +1226 -31
- package/resources/data/deck/learnneo/p/Events.md +11 -0
- package/resources/data/deck/learnneo/p/GuideEvents.md +153 -0
- package/resources/data/deck/learnneo/t.json +3 -1
- package/resources/scss/src/apps/portal/learn/ContentView.scss +1 -0
- package/resources/scss/src/list/Base.scss +1 -45
- package/src/DefaultConfig.mjs +2 -2
- package/src/component/Base.mjs +32 -0
- package/src/data/RecordFactory.mjs +0 -3
- package/src/dialog/Base.mjs +14 -7
- package/src/form/field/Picker.mjs +9 -1
- package/src/form/field/Select.mjs +23 -4
- package/src/form/field/Text.mjs +4 -2
- package/src/layout/Flexbox.mjs +31 -23
- package/src/layout/HBox.mjs +1 -1
- package/src/layout/VBox.mjs +1 -1
- package/src/main/DomAccess.mjs +11 -3
- package/src/main/DomUtils.mjs +26 -3
- package/src/main/addon/Navigator.mjs +139 -27
- package/src/manager/DomEvent.mjs +9 -3
- package/src/manager/Focus.mjs +3 -1
- package/src/util/String.mjs +3 -2
- package/test/components/files/form/field/Select.mjs +25 -4
- package/resources/data/deck/learnneo/p/AddingProperties.md +0 -1
- package/resources/data/deck/learnneo/p/ComponentState.md +0 -1
- package/resources/scss/src/apps/newwebsite/Viewport.scss +0 -32
- 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_ — or _listener_ — 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 — named something
|
89
|
+
like `MainViewController.mjs` — 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 — 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": "
|
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"},
|
@@ -54,51 +54,7 @@
|
|
54
54
|
cursor: pointer;
|
55
55
|
|
56
56
|
&:hover {
|
57
|
-
background-color: var(--list-item-background-color-hover)
|
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 {
|
package/src/DefaultConfig.mjs
CHANGED
@@ -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.
|
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.
|
244
|
+
version: '6.10.14'
|
245
245
|
};
|
246
246
|
|
247
247
|
Object.assign(DefaultConfig, {
|
package/src/component/Base.mjs
CHANGED
@@ -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
|
package/src/dialog/Base.mjs
CHANGED
@@ -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
|
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
|
-
|
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
|
-
|
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
|
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:
|
230
|
-
{name:
|
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();
|
package/src/form/field/Text.mjs
CHANGED
@@ -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
|
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
|
1531
|
+
value = me.value,
|
1530
1532
|
valueLength = value?.toString().length,
|
1531
1533
|
inputPattern = me.inputPattern,
|
1532
1534
|
isEmpty = value !== 0 && (!value || valueLength < 1),
|
package/src/layout/Flexbox.mjs
CHANGED
@@ -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
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
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
|
}
|