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.
Files changed (33) hide show
  1. package/apps/ServiceWorker.mjs +2 -2
  2. package/apps/form/neo-config.json +1 -1
  3. package/apps/form/view/SideNavList.mjs +4 -0
  4. package/apps/form/view/pages/Page6.mjs +6 -4
  5. package/apps/portal/neo-config.json +1 -1
  6. package/apps/portal/view/learn/LivePreview.mjs +3 -2
  7. package/examples/ServiceWorker.mjs +2 -2
  8. package/examples/button/base/neo-config.json +1 -2
  9. package/package.json +71 -71
  10. package/resources/data/deck/learnneo/p/2023-10-14T19-25-08-153Z.md +1 -0
  11. package/resources/data/deck/learnneo/p/DescribingTheUI.md +1 -1
  12. package/resources/data/deck/learnneo/p/Earthquakes.md +3 -0
  13. package/resources/scss/src/apps/portal/learn/ContentView.scss +1 -0
  14. package/resources/scss/src/list/Base.scss +1 -57
  15. package/src/DefaultConfig.mjs +2 -2
  16. package/src/button/Base.mjs +4 -6
  17. package/src/data/RecordFactory.mjs +6 -9
  18. package/src/form/field/Text.mjs +2 -2
  19. package/src/form/field/TextArea.mjs +35 -11
  20. package/src/layout/Flexbox.mjs +31 -23
  21. package/src/layout/HBox.mjs +1 -1
  22. package/src/layout/VBox.mjs +1 -1
  23. package/src/list/Base.mjs +19 -13
  24. package/src/main/DomAccess.mjs +11 -4
  25. package/src/main/addon/Navigator.mjs +18 -11
  26. package/src/menu/List.mjs +5 -1
  27. package/src/model/Component.mjs +1 -1
  28. package/src/tree/List.mjs +3 -5
  29. package/src/vdom/Helper.mjs +8 -3
  30. package/resources/data/deck/learnneo/p/AddingProperties.md +0 -1
  31. package/resources/data/deck/learnneo/p/ComponentState.md +0 -1
  32. package/resources/scss/src/apps/newwebsite/Viewport.scss +0 -32
  33. package/resources/scss/theme-neo-light/design-tokens/Components.scss +0 -3
@@ -20,9 +20,9 @@ class ServiceWorker extends ServiceBase {
20
20
  */
21
21
  singleton: true,
22
22
  /**
23
- * @member {String} version='6.10.15'
23
+ * @member {String} version='6.10.17'
24
24
  */
25
- version: '6.10.15'
25
+ version: '6.10.17'
26
26
  }
27
27
 
28
28
  /**
@@ -3,5 +3,5 @@
3
3
  "basePath" : "../../",
4
4
  "environment" : "development",
5
5
  "mainPath" : "./Main.mjs",
6
- "mainThreadAddons": ["DragDrop", "LocalStorage", "Stylesheet"]
6
+ "mainThreadAddons": ["DragDrop", "LocalStorage", "Navigator", "Stylesheet"]
7
7
  }
@@ -16,6 +16,10 @@ class SideNavList extends List {
16
16
  * @protected
17
17
  */
18
18
  baseCls: ['form-side-nav-list', 'neo-list'],
19
+ /**
20
+ * @member {Boolean} itemsFocusable=true
21
+ */
22
+ itemsFocusable: true,
19
23
  /**
20
24
  * @member {Boolean} useHeaders=true
21
25
  */
@@ -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 from '../../../../src/container/Base.mjs';
1
+ import Base from '../../../../src/container/Base.mjs';
2
2
  import TabContainer from '../../../../src/tab/Container.mjs';
3
- import TextArea from '../../../../src/form/field/TextArea.mjs';
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) {
@@ -20,9 +20,9 @@ class ServiceWorker extends ServiceBase {
20
20
  */
21
21
  singleton: true,
22
22
  /**
23
- * @member {String} version='6.10.15'
23
+ * @member {String} version='6.10.17'
24
24
  */
25
- version: '6.10.15'
25
+ version: '6.10.17'
26
26
  }
27
27
 
28
28
  /**
@@ -2,6 +2,5 @@
2
2
  "appPath" : "examples/button/base/app.mjs",
3
3
  "basePath" : "../../../",
4
4
  "environment": "development",
5
- "mainPath" : "./Main.mjs",
6
- "themes" : ["neo-theme-neo-light"]
5
+ "mainPath" : "./Main.mjs"
7
6
  }
package/package.json CHANGED
@@ -1,73 +1,73 @@
1
1
  {
2
- "name" : "neo.mjs",
3
- "version" : "6.10.15",
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" : "^11.1.0",
51
- "cssnano" : "^6.0.3",
52
- "envinfo" : "^7.11.0",
53
- "fs-extra" : "^11.2.0",
54
- "highlightjs-line-numbers.js" : "^2.8.0",
55
- "inquirer" : "^9.2.12",
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.0",
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
- }
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 -->
@@ -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,63 +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);
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 {
@@ -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.15'
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.15'
244
+ version: '6.10.17'
245
245
  };
246
246
 
247
247
  Object.assign(DefaultConfig, {
@@ -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
- ...menuConfig
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
 
@@ -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 ? data.value.toString().trim() : me.emptyValue,
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 ? me.value.toString().trim() : me.emptyValue,
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
- afterSetAutoGrow(autoGrow) {
83
- autoGrow && this.syncAutoGrowMonitor();
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 (!autoGrow) {
87
- this.afterSetHeight(this._height);
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 inputEl = this.getInputEl();
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
- if (this.mounted && this.autoGrow) {
185
- // Delegate monitoring of sizes to the VDOM thread.
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 : this.appName,
188
- id : this.getInputElId(),
189
- autoGrow : this.autoGrow
190
- });
211
+ appName : me.appName,
212
+ id : me.getInputElId(),
213
+ autoGrow : me.autoGrow
214
+ })
191
215
  }
192
216
  }
193
217
  }
@@ -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
  }
@@ -29,7 +29,7 @@ class HBox extends Flexbox {
29
29
  */
30
30
  applyChildAttributes(item) {
31
31
  // Do not apply flex if fixed width
32
- !item.width && super.applyChildAttributes(item)
32
+ !item.width && super.applyChildAttributes(item);
33
33
  }
34
34
  }
35
35
 
@@ -29,7 +29,7 @@ class VBox extends Flexbox {
29
29
  */
30
30
  applyChildAttributes(item) {
31
31
  // Do not apply flex if fixed height
32
- !item.height && super.applyChildAttributes(item)
32
+ !item.height && super.applyChildAttributes(item);
33
33
  }
34
34
  }
35
35
 
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.getActiveIndex(value);
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
- afterSetMounted(value) {
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 = null
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
- me.hasNavigator = true;
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} [id]
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
  /**
@@ -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
- // Prefer to focus input fields over buttons.
366
- // querySelector('input,textarea,button') returns buttons first, so use multiple calls.
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
- monitorAutoGrowHandler({ target }) {
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
- focusables = DomUtils.queryAll(data.subject, DomUtils.isFocusable),
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).classList.remove(data.activeCls);
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 programatically.
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 undet the mouse, it will take focus, and we respond to that in navigateFocusInHandler.
218
- // If not, we have to programatically activate on click, but we must not draw focus away from
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 = 'ArrowRight';
251
+ data.nextKey = 'ArrowRight';
245
252
  }
246
253
  // Child elements layed out vertically.
247
254
  else {
248
255
  data.previousKey = 'ArrowUp';
249
- data.nextKey = 'ArrowDown';
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', tabIndex: -1, cn: []}
107
+ {tag: 'ul', cn: []}
104
108
  }
105
109
 
106
110
  /**
@@ -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[Symbol.for('isRecord')]) {
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
- cn: [
65
- {tag: 'ul', cls: ['neo-list-container', 'neo-list'], tabIndex: -1, cn: []}
66
- ]
67
- }
63
+ {cn: [
64
+ {tag: 'ul', cls: ['neo-list-container', 'neo-list'], tabIndex: -1, cn: []}
65
+ ]}
68
66
  }
69
67
 
70
68
  /**
@@ -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
- string += ` ${key}="${value?.replaceAll?.('"', '&quot;') ?? value}"`;
584
+ if (key === 'value') {
585
+ value = NeoString.escapeHtml(value)
586
+ }
587
+
588
+ string += ` ${key}="${value?.replaceAll?.('"', '&quot;') ?? 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
- }
@@ -1,3 +0,0 @@
1
- :root .neo-theme-neo-light {
2
- --cmp-button-bg : blue;
3
- }