neo.mjs 6.10.15 → 6.10.17
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/form/neo-config.json +1 -1
- package/apps/form/view/SideNavList.mjs +4 -0
- package/apps/form/view/pages/Page6.mjs +6 -4
- package/apps/portal/neo-config.json +1 -1
- package/apps/portal/view/learn/LivePreview.mjs +3 -2
- package/examples/ServiceWorker.mjs +2 -2
- package/examples/button/base/neo-config.json +1 -2
- package/package.json +71 -71
- package/resources/data/deck/learnneo/p/2023-10-14T19-25-08-153Z.md +1 -0
- package/resources/data/deck/learnneo/p/DescribingTheUI.md +1 -1
- package/resources/data/deck/learnneo/p/Earthquakes.md +3 -0
- package/resources/scss/src/apps/portal/learn/ContentView.scss +1 -0
- package/resources/scss/src/list/Base.scss +1 -57
- package/src/DefaultConfig.mjs +2 -2
- package/src/button/Base.mjs +4 -6
- package/src/data/RecordFactory.mjs +6 -9
- package/src/form/field/Text.mjs +2 -2
- package/src/form/field/TextArea.mjs +35 -11
- package/src/layout/Flexbox.mjs +31 -23
- package/src/layout/HBox.mjs +1 -1
- package/src/layout/VBox.mjs +1 -1
- package/src/list/Base.mjs +19 -13
- package/src/main/DomAccess.mjs +11 -4
- package/src/main/addon/Navigator.mjs +18 -11
- package/src/menu/List.mjs +5 -1
- package/src/model/Component.mjs +1 -1
- package/src/tree/List.mjs +3 -5
- package/src/vdom/Helper.mjs +8 -3
- 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
package/apps/ServiceWorker.mjs
CHANGED
@@ -20,24 +20,26 @@ class Page6 extends FormPageContainer {
|
|
20
20
|
* @member {Object} itemDefaults
|
21
21
|
*/
|
22
22
|
itemDefaults: {
|
23
|
-
module: TextArea
|
23
|
+
module : TextArea,
|
24
|
+
autoGrow: true
|
24
25
|
},
|
25
26
|
/**
|
26
27
|
* @member {Object[]} items
|
27
28
|
*/
|
28
29
|
items: [{
|
29
|
-
height : 200,
|
30
30
|
labelText: 'Page 6 Field 1',
|
31
|
+
minHeight: 150,
|
31
32
|
name : 'field1',
|
32
33
|
required : true,
|
33
34
|
value : 'Lorem ipsum'
|
34
35
|
}, {
|
35
|
-
height : 300,
|
36
36
|
labelText: 'Page 6 Field 2',
|
37
|
+
minHeight: 150,
|
37
38
|
name : 'field2'
|
38
39
|
}, {
|
39
40
|
labelText: 'Page 6 Field 3',
|
40
|
-
name : 'field3'
|
41
|
+
name : 'field3',
|
42
|
+
readOnly : true
|
41
43
|
}]
|
42
44
|
}
|
43
45
|
}
|
@@ -3,6 +3,6 @@
|
|
3
3
|
"basePath" : "../../",
|
4
4
|
"environment" : "development",
|
5
5
|
"mainPath" : "./Main.mjs",
|
6
|
-
"mainThreadAddons": ["DragDrop", "HighlightJS", "Stylesheet", "Markdown"],
|
6
|
+
"mainThreadAddons": ["DragDrop", "HighlightJS", "Navigator", "Stylesheet", "Markdown"],
|
7
7
|
"themes" : ["neo-theme-neo-light"]
|
8
8
|
}
|
@@ -1,6 +1,6 @@
|
|
1
|
-
import Base
|
1
|
+
import Base from '../../../../src/container/Base.mjs';
|
2
2
|
import TabContainer from '../../../../src/tab/Container.mjs';
|
3
|
-
import TextArea
|
3
|
+
import TextArea from '../../../../src/form/field/TextArea.mjs';
|
4
4
|
|
5
5
|
/**
|
6
6
|
* @class Portal.view.learn.LivePreview
|
@@ -76,6 +76,7 @@ class LivePreview extends Base {
|
|
76
76
|
|
77
77
|
const className = this.findLastClassName(source);
|
78
78
|
|
79
|
+
|
79
80
|
source.split('\n').forEach(line => {
|
80
81
|
let importMatch = line.match(importRegex);
|
81
82
|
if (importMatch) {
|
package/package.json
CHANGED
@@ -1,73 +1,73 @@
|
|
1
1
|
{
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
2
|
+
"name": "neo.mjs",
|
3
|
+
"version": "6.10.17",
|
4
|
+
"description": "The webworkers driven UI framework",
|
5
|
+
"type": "module",
|
6
|
+
"repository": {
|
7
|
+
"type": "git",
|
8
|
+
"url": "https://github.com/neomjs/neo.git"
|
9
|
+
},
|
10
|
+
"bin": {
|
11
|
+
"neo-cc": "./buildScripts/createClass.mjs"
|
12
|
+
},
|
13
|
+
"scripts": {
|
14
|
+
"add-config": "node ./buildScripts/addConfig.mjs",
|
15
|
+
"build-all": "node ./buildScripts/buildAll.mjs -f -n",
|
16
|
+
"build-all-questions": "node ./buildScripts/buildAll.mjs -f",
|
17
|
+
"build-themes": "node ./buildScripts/buildThemes.mjs -f",
|
18
|
+
"build-threads": "node ./buildScripts/webpack/buildThreads.mjs -f",
|
19
|
+
"convert-design-tokens": "node ./buildScripts/convertDesignTokens.mjs",
|
20
|
+
"create-app": "node ./buildScripts/createApp.mjs",
|
21
|
+
"create-app-minimal": "node ./buildScripts/createAppMinimal.mjs",
|
22
|
+
"create-class": "node ./buildScripts/createClass.mjs",
|
23
|
+
"create-component": "node ./buildScripts/createComponent.mjs",
|
24
|
+
"generate-docs-json": "node ./buildScripts/docs/jsdocx.mjs",
|
25
|
+
"inject-package-version": "node ./buildScripts/injectPackageVersion.mjs",
|
26
|
+
"server-start": "webpack serve -c ./buildScripts/webpack/webpack.server.config.mjs --open",
|
27
|
+
"test": "echo \"Error: no test specified\" && exit 1",
|
28
|
+
"watch-themes": "node ./buildScripts/watchThemes.mjs"
|
29
|
+
},
|
30
|
+
"keywords": [
|
31
|
+
"javascript",
|
32
|
+
"frontend",
|
33
|
+
"framework",
|
34
|
+
"webworker",
|
35
|
+
"ecmascript",
|
36
|
+
"css",
|
37
|
+
"json"
|
38
|
+
],
|
39
|
+
"author": "Tobias Uhlig, Rich Waters",
|
40
|
+
"license": "MIT",
|
41
|
+
"bugs": {
|
42
|
+
"url": "https://github.com/neomjs/neo/issues"
|
43
|
+
},
|
44
|
+
"homepage": "https://neomjs.github.io/pages/",
|
45
|
+
"devDependencies": {
|
46
|
+
"@fortawesome/fontawesome-free": "^6.5.1",
|
47
|
+
"autoprefixer": "^10.4.17",
|
48
|
+
"chalk": "^5.3.0",
|
49
|
+
"clean-webpack-plugin": "^4.0.0",
|
50
|
+
"commander": "^12.0.0",
|
51
|
+
"cssnano": "^6.0.3",
|
52
|
+
"envinfo": "^7.11.1",
|
53
|
+
"fs-extra": "^11.2.0",
|
54
|
+
"highlightjs-line-numbers.js": "^2.8.0",
|
55
|
+
"inquirer": "^9.2.14",
|
56
|
+
"neo-jsdoc": "1.0.1",
|
57
|
+
"neo-jsdoc-x": "1.0.5",
|
58
|
+
"postcss": "^8.4.33",
|
59
|
+
"sass": "^1.70.0",
|
60
|
+
"siesta-lite": "5.5.2",
|
61
|
+
"showdown": "^2.1.0",
|
62
|
+
"url": "^0.11.3",
|
63
|
+
"webpack": "^5.90.1",
|
64
|
+
"webpack-cli": "^5.1.4",
|
65
|
+
"webpack-dev-server": "4.15.1",
|
66
|
+
"webpack-hook-plugin": "^1.0.7",
|
67
|
+
"webpack-node-externals": "^3.0.0"
|
68
|
+
},
|
69
|
+
"funding": {
|
70
|
+
"type": "GitHub Sponsors",
|
71
|
+
"url": "https://github.com/sponsors/tobiu"
|
72
|
+
}
|
73
73
|
}
|
@@ -91,6 +91,7 @@ Neo.applyClassConfig(MainView);
|
|
91
91
|
export default MainView;
|
92
92
|
</pre>
|
93
93
|
|
94
|
+
|
94
95
|
Note the entry in `items:[]`. That's a description of the button that will be the single item in our
|
95
96
|
container. In Neo.mjs terms we're _configuring_ the button. Neo.mjs is a declarative framework, in
|
96
97
|
which components and objects are described. It's an abstraction. In other words, the code describes
|
@@ -64,4 +64,4 @@ modify the code to specify `ntype:'hbox'` and run it again.
|
|
64
64
|
|
65
65
|
Note that the layout specifies `ntype` rather than `module`. An `ntype` is an alias for a class
|
66
66
|
that has already been imported. Containers import all the layout types, so since we've already
|
67
|
-
imported container we can simply use `ntype` to specify which layout we want.
|
67
|
+
imported container we can simply use `ntype` to specify which layout we want.
|
@@ -289,6 +289,7 @@ layout: {
|
|
289
289
|
|
290
290
|
<img src="https://s3.amazonaws.com/mjs.neo.learning.images/earthquakes/EarthquakesSingleVoxStartButton.png" style="width:80%"/>
|
291
291
|
|
292
|
+
|
292
293
|
</details>
|
293
294
|
|
294
295
|
<!-- /lab -->
|
@@ -1403,4 +1404,6 @@ Save, refresh, and confirm that you see the value logged when you click on a map
|
|
1403
1404
|
|
1404
1405
|
</details>
|
1405
1406
|
|
1407
|
+
|
1408
|
+
|
1406
1409
|
<!-- /lab -->
|
@@ -54,63 +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);
|
102
|
-
color : var(--list-container-list-color);
|
103
|
-
}
|
104
|
-
&:active {
|
105
|
-
background-color: var(--list-item-background-color-active);
|
106
|
-
color : var(--list-container-list-color);
|
107
|
-
}
|
108
|
-
&:active {
|
109
|
-
background-color: var(--list-item-background-color-active);
|
110
|
-
color : var(--list-container-list-color);
|
111
|
-
}
|
112
|
-
&:active {
|
113
|
-
background-color: var(--list-item-background-color-active);
|
57
|
+
background-color: var(--list-item-background-color-hover);
|
114
58
|
color : var(--list-container-list-color);
|
115
59
|
}
|
116
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.17'
|
240
240
|
* @memberOf! module:Neo
|
241
241
|
* @name config.version
|
242
242
|
* @type String
|
243
243
|
*/
|
244
|
-
version: '6.10.
|
244
|
+
version: '6.10.17'
|
245
245
|
};
|
246
246
|
|
247
247
|
Object.assign(DefaultConfig, {
|
package/src/button/Base.mjs
CHANGED
@@ -258,7 +258,7 @@ class Base extends Component {
|
|
258
258
|
menuConfig = isArray ? {} : value,
|
259
259
|
model = me.getModel(),
|
260
260
|
|
261
|
-
config = {
|
261
|
+
config = Neo.merge({
|
262
262
|
module : module.default,
|
263
263
|
align : {edgeAlign : 't0-b0', target: me.id},
|
264
264
|
appName : me.appName,
|
@@ -266,9 +266,8 @@ class Base extends Component {
|
|
266
266
|
floating : true,
|
267
267
|
hidden : true,
|
268
268
|
parentComponent: me,
|
269
|
-
theme : me.theme
|
270
|
-
|
271
|
-
};
|
269
|
+
theme : me.theme
|
270
|
+
}, menuConfig);
|
272
271
|
|
273
272
|
if (items) {
|
274
273
|
config.items = items
|
@@ -544,8 +543,7 @@ class Base extends Component {
|
|
544
543
|
menuList.hidden = hidden;
|
545
544
|
|
546
545
|
if (!hidden) {
|
547
|
-
await this.timeout(50)
|
548
|
-
menuList.focus()
|
546
|
+
await this.timeout(50)
|
549
547
|
}
|
550
548
|
}
|
551
549
|
}
|
@@ -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
|
@@ -129,8 +126,8 @@ class RecordFactory extends Base {
|
|
129
126
|
}
|
130
127
|
}
|
131
128
|
|
132
|
-
Object.defineProperties(me, properties)
|
133
|
-
})
|
129
|
+
Object.defineProperties(me, properties)
|
130
|
+
})
|
134
131
|
}
|
135
132
|
}
|
136
133
|
|
@@ -139,7 +136,7 @@ class RecordFactory extends Base {
|
|
139
136
|
* @param {Object} fields
|
140
137
|
*/
|
141
138
|
set(fields) {
|
142
|
-
instance.setRecordFields(model, this, fields)
|
139
|
+
instance.setRecordFields(model, this, fields)
|
143
140
|
}
|
144
141
|
|
145
142
|
/**
|
@@ -147,17 +144,17 @@ class RecordFactory extends Base {
|
|
147
144
|
* @param {Object} fields
|
148
145
|
*/
|
149
146
|
setSilent(fields) {
|
150
|
-
instance.setRecordFields(model, this, fields, true)
|
147
|
+
instance.setRecordFields(model, this, fields, true)
|
151
148
|
}
|
152
149
|
};
|
153
150
|
|
154
151
|
Object.defineProperty(cls.prototype, 'isRecord', { value : true });
|
155
152
|
Object.defineProperty(cls, 'isClass', { vale : true });
|
156
153
|
|
157
|
-
return ns[key]
|
154
|
+
return ns[key]
|
158
155
|
}
|
159
156
|
|
160
|
-
return ns
|
157
|
+
return ns
|
161
158
|
}
|
162
159
|
}
|
163
160
|
|
package/src/form/field/Text.mjs
CHANGED
@@ -1325,7 +1325,7 @@ class Text extends Base {
|
|
1325
1325
|
onInputValueChange(data) {
|
1326
1326
|
let me = this,
|
1327
1327
|
oldValue = me.value,
|
1328
|
-
value = data.value
|
1328
|
+
value = data.value,
|
1329
1329
|
vnode = VNodeUtil.findChildVnode(me.vnode, {nodeName: 'input'});
|
1330
1330
|
|
1331
1331
|
if (vnode) {
|
@@ -1528,7 +1528,7 @@ class Text extends Base {
|
|
1528
1528
|
minLength = me.minLength,
|
1529
1529
|
required = me.required,
|
1530
1530
|
returnValue = true,
|
1531
|
-
value = me.value
|
1531
|
+
value = me.value,
|
1532
1532
|
valueLength = value?.toString().length,
|
1533
1533
|
inputPattern = me.inputPattern,
|
1534
1534
|
isEmpty = value !== 0 && (!value || valueLength < 1),
|
@@ -79,12 +79,20 @@ class TextArea extends Text {
|
|
79
79
|
wrap_: null
|
80
80
|
}
|
81
81
|
|
82
|
-
|
83
|
-
|
82
|
+
/**
|
83
|
+
* Triggered after the autoGrow config got changed
|
84
|
+
* @param {Boolean} value
|
85
|
+
* @param {Boolean} oldValue
|
86
|
+
* @protected
|
87
|
+
*/
|
88
|
+
afterSetAutoGrow(value, oldValue) {
|
89
|
+
let me = this;
|
90
|
+
|
91
|
+
value && me.syncAutoGrowMonitor();
|
84
92
|
|
85
93
|
// Restore any configured height if autoGrow turned off
|
86
|
-
if (!
|
87
|
-
|
94
|
+
if (!value) {
|
95
|
+
me.afterSetHeight(me._height);
|
88
96
|
}
|
89
97
|
}
|
90
98
|
|
@@ -150,13 +158,24 @@ class TextArea extends Text {
|
|
150
158
|
* @protected
|
151
159
|
*/
|
152
160
|
afterSetValue(value, oldValue) {
|
153
|
-
let
|
161
|
+
let me = this,
|
162
|
+
inputEl = me.getInputEl();
|
154
163
|
|
155
164
|
if (inputEl) {
|
156
165
|
inputEl.html = StringUtil.escapeHtml(value);
|
157
166
|
}
|
158
167
|
|
159
168
|
super.afterSetValue(value, oldValue);
|
169
|
+
|
170
|
+
if (me.autoGrow && me.mounted && me.readOnly) {
|
171
|
+
setTimeout(() => {
|
172
|
+
Neo.main.DomAccess.monitorAutoGrowHandler({
|
173
|
+
appName : me.appName,
|
174
|
+
id : inputEl.id,
|
175
|
+
windowId: me.windowId
|
176
|
+
})
|
177
|
+
}, 50)
|
178
|
+
}
|
160
179
|
}
|
161
180
|
|
162
181
|
/**
|
@@ -180,14 +199,19 @@ class TextArea extends Text {
|
|
180
199
|
return this.beforeSetEnumValue(value, oldValue, 'wrap', 'wrapValues');
|
181
200
|
}
|
182
201
|
|
202
|
+
/**
|
203
|
+
*
|
204
|
+
*/
|
183
205
|
async syncAutoGrowMonitor() {
|
184
|
-
|
185
|
-
|
206
|
+
let me = this;
|
207
|
+
|
208
|
+
if (me.mounted && me.autoGrow) {
|
209
|
+
// Delegate monitoring of sizes to the main thread.
|
186
210
|
Neo.main.DomAccess.monitorAutoGrow({
|
187
|
-
appName :
|
188
|
-
id :
|
189
|
-
autoGrow :
|
190
|
-
})
|
211
|
+
appName : me.appName,
|
212
|
+
id : me.getInputElId(),
|
213
|
+
autoGrow : me.autoGrow
|
214
|
+
})
|
191
215
|
}
|
192
216
|
}
|
193
217
|
}
|
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
|
}
|
package/src/layout/HBox.mjs
CHANGED
package/src/layout/VBox.mjs
CHANGED
package/src/list/Base.mjs
CHANGED
@@ -250,30 +250,32 @@ class Base extends Component {
|
|
250
250
|
* @protected
|
251
251
|
*/
|
252
252
|
afterSetHeaderlessActiveIndex(value, oldValue) {
|
253
|
-
let me = this
|
254
|
-
activeIndex;
|
253
|
+
let me = this;
|
255
254
|
|
256
255
|
if (Neo.isNumber(value)) {
|
257
|
-
activeIndex = me.
|
258
|
-
|
259
|
-
me.activeIndex = activeIndex
|
256
|
+
me.activeIndex = me.store.getCount() ? value: null
|
260
257
|
} else if (Neo.isNumber(oldValue)) {
|
261
258
|
me.activeIndex = null
|
262
259
|
}
|
263
260
|
}
|
264
261
|
|
265
|
-
|
262
|
+
/**
|
263
|
+
* Triggered after the mounted config got changed
|
264
|
+
* @param {Boolean} value
|
265
|
+
* @param {Boolean} oldValue
|
266
|
+
* @protected
|
267
|
+
*/
|
268
|
+
afterSetMounted(value, oldValue) {
|
266
269
|
const me = this;
|
267
270
|
|
268
271
|
// Tear down navigation before we lose the element
|
269
272
|
if (!value && me.hasNavigator) {
|
270
273
|
Neo.main.addon.Navigator.unsubscribe(me.navigator);
|
274
|
+
|
271
275
|
me.hasNavigator = false;
|
272
|
-
me.activeIndex
|
276
|
+
me.activeIndex = null
|
273
277
|
}
|
274
278
|
|
275
|
-
super.afterSetMounted(...arguments);
|
276
|
-
|
277
279
|
if (value) {
|
278
280
|
// Set up item navigation in the list
|
279
281
|
if (!me.hasNavigator) {
|
@@ -282,11 +284,15 @@ class Base extends Component {
|
|
282
284
|
id : me.id,
|
283
285
|
selector : `.${me.itemCls}:not(.neo-disabled,.neo-list-header)`,
|
284
286
|
...me.navigator
|
285
|
-
}
|
286
|
-
|
287
|
+
};
|
288
|
+
|
289
|
+
me.hasNavigator = true
|
287
290
|
}
|
291
|
+
|
288
292
|
Neo.main.addon.Navigator.subscribe(me.navigator)
|
289
293
|
}
|
294
|
+
|
295
|
+
super.afterSetMounted(value, oldValue)
|
290
296
|
}
|
291
297
|
|
292
298
|
/**
|
@@ -546,10 +552,10 @@ class Base extends Component {
|
|
546
552
|
|
547
553
|
/**
|
548
554
|
* Calls focus() on the top level DOM node of this component or on a given node via id
|
549
|
-
* @param {String}
|
555
|
+
* @param {String} id
|
550
556
|
*/
|
551
557
|
focus(id) {
|
552
|
-
Neo.main.addon.Navigator.navigateTo(id, this.navigator)
|
558
|
+
Neo.main.addon.Navigator.navigateTo([id, this.navigator])
|
553
559
|
}
|
554
560
|
|
555
561
|
/**
|
package/src/main/DomAccess.mjs
CHANGED
@@ -88,6 +88,7 @@ class DomAccess extends Base {
|
|
88
88
|
'getScrollingDimensions',
|
89
89
|
'measure',
|
90
90
|
'monitorAutoGrow',
|
91
|
+
'monitorAutoGrowHandler',
|
91
92
|
'navigate',
|
92
93
|
'navigateTo',
|
93
94
|
'scrollBy',
|
@@ -362,9 +363,8 @@ class DomAccess extends Base {
|
|
362
363
|
if (node) {
|
363
364
|
// The children property means focus inner elements if possible.
|
364
365
|
if (!DomUtils.isFocusable(node) && data.children) {
|
365
|
-
//
|
366
|
-
|
367
|
-
node = node.querySelector('input:not(:disabled)') || node.querySelector('textarea:not(:disabled)') || node.querySelector('button:not(:disabled)') || [...node.querySelectorAll('*')].find(DomUtils.isFocusable);
|
366
|
+
// query for the first focusable decendent
|
367
|
+
node = DomUtils.query(node, DomUtils.isFocusable);
|
368
368
|
}
|
369
369
|
if (node) {
|
370
370
|
node.focus();
|
@@ -638,8 +638,15 @@ class DomAccess extends Base {
|
|
638
638
|
})
|
639
639
|
}
|
640
640
|
|
641
|
-
|
641
|
+
/**
|
642
|
+
*
|
643
|
+
* @param {Event|Object} data
|
644
|
+
* @param {String} [data.id]
|
645
|
+
* @param {HTMLElement} [data.target]
|
646
|
+
*/
|
647
|
+
monitorAutoGrowHandler(data) {
|
642
648
|
const
|
649
|
+
target = data.target || this.getElement(data.id),
|
643
650
|
{ style } = target,
|
644
651
|
{ style : inputStyle } = target.closest('.neo-textarea');
|
645
652
|
|
@@ -30,9 +30,9 @@ class Navigator extends Base {
|
|
30
30
|
*/
|
31
31
|
remote: {
|
32
32
|
app: [
|
33
|
+
'navigateTo',
|
33
34
|
'subscribe',
|
34
|
-
'unsubscribe'
|
35
|
-
'navigateTo'
|
35
|
+
'unsubscribe'
|
36
36
|
]
|
37
37
|
},
|
38
38
|
/**
|
@@ -114,7 +114,7 @@ class Navigator extends Base {
|
|
114
114
|
// The navigables we are dealing with, if they are focusable must *not* be tabbable.
|
115
115
|
// Only *one* must be tabbable, so that tabbing into the subject element goes to the
|
116
116
|
// one active element.
|
117
|
-
//
|
117
|
+
//
|
118
118
|
// Tabbing *from* that must exit the subject element.
|
119
119
|
//
|
120
120
|
// So we must ensure that all the focusable elements except the first are not tabbable.
|
@@ -127,7 +127,14 @@ class Navigator extends Base {
|
|
127
127
|
}
|
128
128
|
|
129
129
|
const
|
130
|
-
|
130
|
+
// Extract all our navigable items, and find the focusable within
|
131
|
+
focusables = Array.from(data.subject.querySelectorAll(data.selector)).reduce((value,item ) => {
|
132
|
+
const f = DomUtils.query(item, DomUtils.isFocusable);
|
133
|
+
if (f){
|
134
|
+
value.push(f);
|
135
|
+
}
|
136
|
+
return value;
|
137
|
+
}, []),
|
131
138
|
defaultActiveItem = focusables[0] || data.subject.querySelector(data.selector);
|
132
139
|
|
133
140
|
// Ensure the items are not tabbable.
|
@@ -192,7 +199,7 @@ class Navigator extends Base {
|
|
192
199
|
const { target } = e;
|
193
200
|
|
194
201
|
// Clear active class from the item we are leaving from.
|
195
|
-
target.closest(data.selector)
|
202
|
+
target.closest(data.selector)?.classList.remove(data.activeCls);
|
196
203
|
|
197
204
|
// On focusout, leave the last active item as tabbable so user can TAB back in here
|
198
205
|
if (!DomUtils.isTabbable(target)) {
|
@@ -205,7 +212,7 @@ class Navigator extends Base {
|
|
205
212
|
|
206
213
|
// If there was a focusable under the mouse, mousedown will have focused it and and we
|
207
214
|
// will have respond to that in navigateFocusInHandler.
|
208
|
-
// If not, we navigate
|
215
|
+
// If not, we navigate programmatically.
|
209
216
|
if (target && !data.findFocusable(target)) {
|
210
217
|
this.navigateTo(target, data);
|
211
218
|
}
|
@@ -214,8 +221,8 @@ class Navigator extends Base {
|
|
214
221
|
navigateMouseDownHandler(e, data) {
|
215
222
|
const target = e.target.closest(data.selector);
|
216
223
|
|
217
|
-
// If there is a focusable
|
218
|
-
// If not, we have to
|
224
|
+
// If there is a focusable under the mouse, it will take focus, and we respond to that in navigateFocusInHandler.
|
225
|
+
// If not, we have to programmatically activate on click, but we must not draw focus away from
|
219
226
|
// where it is, so preventDefault
|
220
227
|
if (target && !data.findFocusable(target)) {
|
221
228
|
e.preventDefault();
|
@@ -241,12 +248,12 @@ class Navigator extends Base {
|
|
241
248
|
if (containerStyle.display === 'flex' && containerStyle.flexDirection === 'row'
|
242
249
|
|| itemStyle.display === 'inline' || itemStyle.display === 'inline-block') {
|
243
250
|
data.previousKey = 'ArrowLeft';
|
244
|
-
data.nextKey
|
251
|
+
data.nextKey = 'ArrowRight';
|
245
252
|
}
|
246
253
|
// Child elements layed out vertically.
|
247
254
|
else {
|
248
255
|
data.previousKey = 'ArrowUp';
|
249
|
-
data.nextKey
|
256
|
+
data.nextKey = 'ArrowDown';
|
250
257
|
}
|
251
258
|
}
|
252
259
|
|
@@ -314,7 +321,7 @@ class Navigator extends Base {
|
|
314
321
|
}
|
315
322
|
|
316
323
|
/**
|
317
|
-
* Navigates to the passed
|
324
|
+
* Navigates to the passed
|
318
325
|
* @param {String|Number} newActiveElement The id of the new active element in the subject
|
319
326
|
* element, or the index of the item.
|
320
327
|
* @param {Object} data The data block as passed to {@link #subscribe}
|
package/src/menu/List.mjs
CHANGED
@@ -38,6 +38,10 @@ class List extends BaseList {
|
|
38
38
|
* @member {Boolean} hideOnLeafItemClick=true
|
39
39
|
*/
|
40
40
|
hideOnLeafItemClick: true,
|
41
|
+
/**
|
42
|
+
* @member {Boolean} itemsFocusable=true
|
43
|
+
*/
|
44
|
+
itemsFocusable: true,
|
41
45
|
/**
|
42
46
|
* Optionally pass menu.Store data directly
|
43
47
|
* @member {Object[]|null} items_=null
|
@@ -100,7 +104,7 @@ class List extends BaseList {
|
|
100
104
|
* @member {Object} _vdom
|
101
105
|
*/
|
102
106
|
_vdom:
|
103
|
-
{tag: 'ul',
|
107
|
+
{tag: 'ul', cn: []}
|
104
108
|
}
|
105
109
|
|
106
110
|
/**
|
package/src/model/Component.mjs
CHANGED
@@ -494,7 +494,7 @@ class Component extends Base {
|
|
494
494
|
let me = this,
|
495
495
|
data, keyLeaf, parentModel, scope;
|
496
496
|
|
497
|
-
if (Neo.isObject(value) && !value
|
497
|
+
if (Neo.isObject(value) && !value.isRecord) {
|
498
498
|
Object.entries(value).forEach(([dataKey, dataValue]) => {
|
499
499
|
me.internalSetData(`${key}.${dataKey}`, dataValue, originModel)
|
500
500
|
})
|
package/src/tree/List.mjs
CHANGED
@@ -60,11 +60,9 @@ class Tree extends Base {
|
|
60
60
|
* @member {Object} _vdom
|
61
61
|
*/
|
62
62
|
_vdom:
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
]
|
67
|
-
}
|
63
|
+
{cn: [
|
64
|
+
{tag: 'ul', cls: ['neo-list-container', 'neo-list'], tabIndex: -1, cn: []}
|
65
|
+
]}
|
68
66
|
}
|
69
67
|
|
70
68
|
/**
|
package/src/vdom/Helper.mjs
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
import Base from '../core/Base.mjs';
|
2
2
|
import NeoArray from '../util/Array.mjs';
|
3
|
+
import NeoString from '../util/String.mjs';
|
3
4
|
import Style from '../util/Style.mjs';
|
4
5
|
import VNode from './VNode.mjs';
|
5
6
|
import VNodeUtil from '../util/VNode.mjs';
|
@@ -577,14 +578,18 @@ class Helper extends Base {
|
|
577
578
|
Object.entries(attributes).forEach(([key, value]) => {
|
578
579
|
if (this.voidAttributes.includes(key)) {
|
579
580
|
if (value === 'true') { // vnode attribute values get converted into strings
|
580
|
-
string += ` ${key}
|
581
|
+
string += ` ${key}`
|
581
582
|
}
|
582
583
|
} else if (key !== 'removeDom') {
|
583
|
-
|
584
|
+
if (key === 'value') {
|
585
|
+
value = NeoString.escapeHtml(value)
|
586
|
+
}
|
587
|
+
|
588
|
+
string += ` ${key}="${value?.replaceAll?.('"', '"') ?? value}"`
|
584
589
|
}
|
585
590
|
});
|
586
591
|
|
587
|
-
return string + '>'
|
592
|
+
return string + '>'
|
588
593
|
}
|
589
594
|
|
590
595
|
/**
|
@@ -1 +0,0 @@
|
|
1
|
-
### todo: Adding Properties
|
@@ -1 +0,0 @@
|
|
1
|
-
### todo: Updating View State
|
@@ -1,32 +0,0 @@
|
|
1
|
-
.newwebsite-viewport {
|
2
|
-
align-items : center !important;
|
3
|
-
display : flex !important;
|
4
|
-
gap : 48px;
|
5
|
-
justify-content: center !important;
|
6
|
-
padding : 10% 15% 15% 15%;
|
7
|
-
}
|
8
|
-
|
9
|
-
.button-group {
|
10
|
-
display : flex !important;
|
11
|
-
flex-direction: row-reverse !important;
|
12
|
-
gap : 8px !important;
|
13
|
-
}
|
14
|
-
|
15
|
-
.neo-h1 {
|
16
|
-
font-size : 48px;
|
17
|
-
font-weight: 600;
|
18
|
-
text-align : center;
|
19
|
-
}
|
20
|
-
|
21
|
-
.vector {
|
22
|
-
background-image : url("../../../../../../resources/images/Neo_Vector.svg");
|
23
|
-
background-position: center center;
|
24
|
-
background-repeat : no-repeat;
|
25
|
-
background-size : contain;
|
26
|
-
height : 150px;
|
27
|
-
width : 100%;
|
28
|
-
}
|
29
|
-
|
30
|
-
.get-started-button {
|
31
|
-
cursor: not-allowed !important;
|
32
|
-
}
|