neo.mjs 5.0.2 → 5.1.0

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 (36) hide show
  1. package/.github/CODING_GUIDELINES.md +436 -0
  2. package/apps/ServiceWorker.mjs +2 -2
  3. package/apps/website/data/blog.json +13 -0
  4. package/examples/ServiceWorker.mjs +2 -2
  5. package/package.json +3 -3
  6. package/resources/scss/src/apps/website/HeaderContainer.scss +5 -4
  7. package/src/DefaultConfig.mjs +2 -2
  8. package/src/Neo.mjs +25 -27
  9. package/src/button/Base.mjs +21 -26
  10. package/src/calendar/view/week/Component.mjs +1 -2
  11. package/src/collection/Base.mjs +1 -1
  12. package/src/component/wrapper/GoogleMaps.mjs +35 -35
  13. package/src/core/Base.mjs +66 -0
  14. package/src/data/connection/Fetch.mjs +5 -5
  15. package/src/data/connection/WebSocket.mjs +25 -24
  16. package/src/dialog/header/Toolbar.mjs +12 -12
  17. package/src/form/field/Search.mjs +1 -1
  18. package/src/form/field/Select.mjs +10 -10
  19. package/src/form/field/Text.mjs +25 -24
  20. package/src/form/field/trigger/Date.mjs +3 -3
  21. package/src/form/field/trigger/Search.mjs +28 -0
  22. package/src/grid/Container.mjs +20 -20
  23. package/src/grid/header/Button.mjs +10 -10
  24. package/src/list/Color.mjs +7 -7
  25. package/src/main/addon/CesiumJS.mjs +6 -6
  26. package/src/main/addon/GoogleMaps.mjs +13 -13
  27. package/src/manager/Component.mjs +5 -5
  28. package/src/manager/Task.mjs +2 -2
  29. package/src/manager/Toast.mjs +13 -13
  30. package/src/manager/rpc/Message.mjs +20 -20
  31. package/src/vdom/Helper.mjs +24 -24
  32. package/src/worker/App.mjs +18 -18
  33. package/src/worker/Base.mjs +17 -17
  34. package/src/worker/Data.mjs +11 -11
  35. package/src/worker/Manager.mjs +9 -9
  36. package/src/worker/ServiceBase.mjs +25 -25
@@ -0,0 +1,436 @@
1
+ # neo.mjs Coding Guidelines
2
+
3
+ Inside the neo repo the following coding guidelines are mandatory.
4
+ They ensure a high code quality and consistency.
5
+ We strongly recommend to also stick to them when creating your own workspaces and apps via `npx neo-app`.
6
+
7
+ In case you do find spots inside the neo.mjs code base which do not stick to the new guidelines,
8
+ you are very welcome to create a ticket here: https://github.com/neomjs/neo/issues.
9
+ Once approved, sending a PR is also highly appreciated (an easy way to get into the contributors list).
10
+
11
+ In the long run, we are planning to convert as many of the rules as possible into linter specs.
12
+
13
+ ## Content
14
+ 1. General rules
15
+ 2. Import statements
16
+ 3. Neo className
17
+ 4. Anatomy of a neo class / JS module
18
+ 5. Config order
19
+ 6. Formatting vdom
20
+ 7. Container items
21
+ 8. Class methods
22
+ 9. data.Model fields
23
+ 10. Misc
24
+
25
+
26
+ ## 1. General rules
27
+ * (1) The neo.mjs code base follows the "easy to read for the human eye" paradigm.
28
+ * (2) A lot of the code is using block-formatting. Inside Jetbrains IDEs like WebStorm you can use the
29
+ `align: 'On colon'` setting.
30
+ * (3) Use single quotes over double quotes.
31
+ * (4) Never use more than 1 empty line.
32
+ * (5) For indentation, we are using 4 spaces (no tab chars).
33
+ * (6) A lot of items inside various spots are ordered chronologically.
34
+
35
+ ## 2. import statements
36
+ ```javascript
37
+ import Container from '../../../node_modules/neo.mjs/src/container/Base.mjs';
38
+ import EarthquakesTable from './earthquakes/Table.mjs';
39
+ import GoogleMapsComponent from '../../../node_modules/neo.mjs/src/component/wrapper/GoogleMaps.mjs';
40
+ import Toast from '../../../node_modules/neo.mjs/src/component/Toast.mjs';
41
+ import ViewController from './MainViewController.mjs';
42
+ import ViewModel from './MainViewModel.mjs';
43
+ ```
44
+ * (7) Use block formatting. This makes it easy to spot invalid paths.
45
+ * (8) Use single quotes.
46
+ * (9) Imports get sorted by module name. There are ongoing discussions if we should switch to a path based sorting instead.
47
+ * (10) Feel free to rename module import names as needed. Neo classes are using the default export.
48
+
49
+ ## 3. Neo className
50
+ Examples:
51
+ ```
52
+ Neo.component.Base
53
+ Neo.data.Store
54
+ Neo.tab.header.Button
55
+ ```
56
+ * (11) class names strictly follow the folder and file structure.
57
+ * (12) class names start with
58
+ + your app name like `MyApp` which maps to `./apps/myapp`
59
+ + or `Neo` which maps to `./src`
60
+ * (13) the first item is formatted in pascal-case or upper-case for abbreviations.
61
+ * (14) class names use dots => `.` instead of `/`, so it is important that you do not use dots within item names.
62
+ * (15) the last item (class file) is using pascal-case as well.
63
+ * (16) all items in between (folders) use lower-case syntax.
64
+ * (17) `ntype` is using lower-case syntax as well.
65
+
66
+ ## 4. Anatomy of a neo class / JS module
67
+ ```javascript
68
+ import Component from '../component/Base.mjs';
69
+ import NeoArray from '../util/Array.mjs';
70
+
71
+ /**
72
+ * @class Neo.button.Base
73
+ * @extends Neo.component.Base
74
+ */
75
+ class Base extends Component {
76
+ /**
77
+ * Valid values for badgePosition
78
+ * @member {String[]} badgePositions=['bottom-left','bottom-right','top-left','top-right']
79
+ * @protected
80
+ * @static
81
+ */
82
+ static badgePositions = ['bottom-left', 'bottom-right', 'top-left', 'top-right']
83
+ /**
84
+ * Valid values for iconPosition
85
+ * @member {String[]} iconPositions=['top','right','bottom','left']
86
+ * @protected
87
+ * @static
88
+ */
89
+ static iconPositions = ['top', 'right', 'bottom', 'left']
90
+
91
+ static config = {
92
+ /**
93
+ * @member {String} className='Neo.button.Base'
94
+ * @protected
95
+ */
96
+ className: 'Neo.button.Base',
97
+ /**
98
+ * @member {String} ntype='button'
99
+ * @protected
100
+ */
101
+ ntype: 'button',
102
+ /**
103
+ * Change the browser hash value on click
104
+ * @member {String|null} route_=null
105
+ */
106
+ route_: null,
107
+ /**
108
+ * True adds an expanding circle on click
109
+ * @member {Boolean} useRippleEffect_=true
110
+ */
111
+ useRippleEffect_: true,
112
+ /**
113
+ * @member {Object} _vdom
114
+ */
115
+ _vdom:
116
+ {tag: 'button', type: 'button', cn: [
117
+ {tag: 'span', cls: ['neo-button-glyph']},
118
+ {tag: 'span', cls: ['neo-button-text']},
119
+ {cls: ['neo-button-badge']},
120
+ {cls: ['neo-button-ripple-wrapper'], cn: [
121
+ {cls: ['neo-button-ripple']}
122
+ ]}
123
+ ]}
124
+ }
125
+
126
+ /**
127
+ * Time in ms for the ripple effect when clicking on the button.
128
+ * Only active if useRippleEffect is set to true.
129
+ * @member {Number} rippleEffectDuration=400
130
+ */
131
+ rippleEffectDuration = 400
132
+ /**
133
+ * Internal flag to store the last setTimeout() id for ripple effect remove node callbacks
134
+ * @member {Number} #rippleTimeoutId=null
135
+ * @private
136
+ */
137
+ #rippleTimeoutId = null
138
+
139
+ /**
140
+ * Triggered after the route config got changed
141
+ * @param {String} value
142
+ * @param {String} oldValue
143
+ * @protected
144
+ */
145
+ afterSetRoute(value, oldValue) {
146
+ let me = this;
147
+
148
+ value && me.addDomListeners({
149
+ click: me.changeRoute,
150
+ scope: me
151
+ });
152
+ }
153
+
154
+ /**
155
+ * Triggered before the iconPosition config gets changed
156
+ * @param {String} value
157
+ * @param {String} oldValue
158
+ * @protected
159
+ */
160
+ beforeSetIconPosition(value, oldValue) {
161
+ return this.beforeSetEnumValue(value, oldValue, 'iconPosition');
162
+ }
163
+
164
+ /**
165
+ * Convenience shortcut
166
+ * @returns {Object}
167
+ */
168
+ getIconNode() {
169
+ return this.getVdomRoot().cn[0];
170
+ }
171
+ }
172
+
173
+ Neo.applyClassConfig(Base);
174
+
175
+ export default Base;
176
+
177
+ ```
178
+ * (18) Use JSDoc based comments for all top level items as well as top level configs
179
+ * (19) Class content order:
180
+ - static configs (ordered chronologically)
181
+ - static config as the last item. This one does not need a comment, but is prefixed with an empty line.
182
+ - non-static class fields (ordered chronologically)
183
+ - construct() in case you are using it
184
+ - all other class methods are ordered chronologically and are prefixed with an empty line.
185
+ * (20) Module order:
186
+ - Import statements formatted according to 1.
187
+ - empty line
188
+ - class definition
189
+ - empty line
190
+ - Neo.applyClassConfig(<ClassName>)
191
+ - empty line
192
+ - export statement
193
+ - empty line
194
+
195
+ ## 5. Config order
196
+ ```javascript
197
+ static config = {
198
+ /**
199
+ * @member {String} className='Neo.button.Base'
200
+ * @protected
201
+ */
202
+ className: 'Neo.button.Base',
203
+ /**
204
+ * @member {String} ntype='button'
205
+ * @protected
206
+ */
207
+ ntype: 'button',
208
+ /**
209
+ * Change the browser hash value on click
210
+ * @member {String|null} route_=null
211
+ */
212
+ route_: null,
213
+ /**
214
+ * True adds an expanding circle on click
215
+ * @member {Boolean} useRippleEffect_=true
216
+ */
217
+ useRippleEffect_: true,
218
+ /**
219
+ * @member {Object} _vdom
220
+ */
221
+ _vdom:
222
+ {tag: 'button', type: 'button', cn: [
223
+ {tag: 'span', cls: ['neo-button-glyph']},
224
+ {tag: 'span', cls: ['neo-button-text']},
225
+ {cls: ['neo-button-badge']},
226
+ {cls: ['neo-button-ripple-wrapper'], cn: [
227
+ {cls: ['neo-button-ripple']}
228
+ ]}
229
+ ]}
230
+ }
231
+ ```
232
+ * (21) class content order
233
+ + className first
234
+ + ntype second (if used)
235
+ + All other configs are ordered chronologically
236
+ + _vdom last
237
+ + configs use camel-case syntax
238
+ + JSDoc comments are required
239
+ + no empty lines between configs
240
+
241
+ ## 6. Formatting vdom
242
+ ```javascript
243
+ _vdom:
244
+ {tag: 'button', type: 'button', cn: [
245
+ {tag: 'span', cls: ['neo-button-glyph']},
246
+ {tag: 'span', cls: ['neo-button-text']},
247
+ {cls: ['neo-button-badge']},
248
+ {cls: ['neo-button-ripple-wrapper'], cn: [
249
+ {cls: ['neo-button-ripple']}
250
+ ]}
251
+ ]}
252
+ ```
253
+ The idea is to format the structure in a way that is similar to html tags and allows us to easily see the DOM hierarchy.
254
+
255
+ * (22) The vdom object starts inside a new line, to keep the structure intact plus keep us more space to the right side.
256
+ * (23) vdom Objects start with the `tag` property.
257
+ * (24) the `tag` property is not needed for `div` tags, since this is the default value.
258
+ * (25) All other attributes are ordered chronologically.
259
+ * (26) `cn` (child nodes) is always the last attribute.
260
+
261
+ There is a blog post which dives a bit deeper into this formatting strategy:</br>
262
+ https://itnext.io/new-formatting-concept-for-json-based-virtual-dom-ee52acc5e04a?source=friends_link&sk=94f69dc71f662e0027118052ceb2db38
263
+
264
+ ## 7. Container items
265
+ ```javascript
266
+ items: [HeaderContainer, {
267
+ module : TabContainer,
268
+ activeIndex: null, // render no items initially
269
+ flex : 1,
270
+ reference : 'tab-container',
271
+ sortable : true,
272
+ style : {margin: '10px', marginTop: 0},
273
+
274
+ items: [{
275
+ module : () => import('./TableContainer.mjs'),
276
+ reference : 'table-container',
277
+ tabButtonConfig: {
278
+ iconCls: 'fa fa-table',
279
+ route : 'mainview=table',
280
+ text : 'Table'
281
+ }
282
+ }, {
283
+ module : () => import('./mapboxGl/Container.mjs'),
284
+ tabButtonConfig: {
285
+ iconCls: 'fa fa-globe-americas',
286
+ route : 'mainview=mapboxglmap',
287
+ text : 'Mapbox GL Map'
288
+ }
289
+ }]
290
+ }, FooterContainer]
291
+ ```
292
+ Most arrays inside the neo.mjs code base use a compact formatting:
293
+ ```javascript
294
+ items: [{
295
+ // content
296
+ }, {
297
+ // content
298
+ }, {
299
+ // content
300
+ }]
301
+ ```
302
+
303
+ It saves several lines of code compared to:
304
+ ```javascript
305
+ items: [
306
+ {
307
+ // content
308
+ },
309
+ {
310
+ // content
311
+ },
312
+ {
313
+ // content
314
+ }
315
+ ]
316
+ ```
317
+ (27) So, please stick to the first version.
318
+
319
+ Container items can contain:
320
+ * imported JS modules / neo classes
321
+ * neo instances
322
+ * config objects
323
+
324
+ (28) Config objects get formatted in the following way:
325
+ * Either `module`, `ntype` or `className` as the first item
326
+ * All other items sorted chronologically
327
+ * Exception: You can also sort everything which can get described in 1 line chronologically and use an empty
328
+ blank line afterwards. This "resets" the block formatting and order. Afterwards you can add "bigger" properties
329
+ like nested item arrays or complex objects (e.g. style). Each of those item starts with an empty line and they
330
+ do get sorted chronologically as well.
331
+
332
+ ## 8. Class methods
333
+ ```javascript
334
+
335
+ /**
336
+ * @param {Object} data
337
+ * @param {Neo.component.Base} data.component
338
+ * @param {Number} data.rowHeight
339
+ * @param {Number} data.rowsPerItem
340
+ * @param {Number} data.totalHeight
341
+ * @param {Boolean} [silent=false]
342
+ */
343
+ adjustTotalHeight(data, silent=false) {
344
+ let me = this,
345
+ rowHeight = data.rowHeight,
346
+ rowsPerItem = data.rowsPerItem,
347
+ height = data.totalHeight - rowHeight,
348
+ i = 0,
349
+ gradient = [];
350
+
351
+ for (; i < rowsPerItem; i++) {
352
+ gradient.push(
353
+ `var(--c-w-background-color) ${i * rowHeight + i}px`,
354
+ `var(--c-w-background-color) ${(i + 1) * rowHeight + i}px`,
355
+ 'var(--c-w-border-color) 0'
356
+ );
357
+ }
358
+
359
+ Object.assign(me.getColumnContainer().style, {
360
+ backgroundImage: `linear-gradient(${gradient.join(',')})`,
361
+ backgroundSize : `1px ${rowsPerItem * rowHeight + rowsPerItem}px`,
362
+ height : `${height}px`,
363
+ maxHeight : `${height}px`
364
+ });
365
+
366
+ !silent && me.update();
367
+ }
368
+ ```
369
+ * (29) Above every class method is one empty line
370
+ * (30) Each class method has JSDoc comments for the params
371
+ + While doc commons support `@returns` & `@return`, we do stick to `@returns` (consistency)
372
+ * (31) Try to define most (if not all) variables at the top of the method body.
373
+ * (32) Variables do use block formatting
374
+ * (33) Variables are separated by commas (file size)
375
+ * (34) Create variables for every item which you use more than 2 times. (maintainability, readability & file size)
376
+ + This rule also counts for `this`.
377
+ * (35) The framework source code is using `const` very(!) rarely. The only reason is the minified bundle size.
378
+
379
+ Example:
380
+ ```javascript
381
+ let a = 1;
382
+ const b = 2;
383
+ let c = 3;
384
+ const d = 4;
385
+
386
+ // minified:
387
+ let a=1;const b=2;let c=3;const d=4; // 36 chars
388
+
389
+ let a = 1,
390
+ b = 2,
391
+ c = 3,
392
+ d = 4;
393
+
394
+ // minified:
395
+ let a=1,b=2,c=3,d=4; // 20 chars
396
+ ```
397
+
398
+ ## 9. data.Model fields
399
+ ```javascript
400
+ fields: [{
401
+ name: 'active',
402
+ type: 'Boolean'
403
+ }, {
404
+ name: 'color',
405
+ type: 'String'
406
+ }, {
407
+ name: 'id',
408
+ type: 'Integer'
409
+ }, {
410
+ name: 'name',
411
+ type: 'String'
412
+ }]
413
+ ```
414
+ * (36) Compact array formatting (same as for container items)
415
+ * (37) Sorted by the value of the name property
416
+
417
+ ## 10. Misc
418
+ * (38) prefer using maps instead of `switch` whenever possible.
419
+ * (39) `if (/**/) {` if, blank char, parenthesis, blank char, curly bracket
420
+ * (40) `for (/**/) {` for, blank char, parenthesis, blank char, curly bracket
421
+ * (41) `switch(/**/) {` switch, parenthesis, blank char, curly bracket `// could get changed to use a blank char as well
422
+ * (42) Use optional chaining => `?.` where it makes sense
423
+ + Bad: `myView && myView.myFn && myView.myFn();`
424
+ + Good: `myView?.myFn?.();`
425
+ + https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining
426
+ * (43) Use method definitions (meaning avoid using the term `function`)
427
+ + Bad: `let obj = {a: function() {/**/}};`
428
+ + Good: `let obj = {a() {/**/}};`
429
+ + https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Method_definitions
430
+ * (44) Use shorthand property names when possible
431
+ + Bad: `let obj = {record: record}`
432
+ + Good: `let obj = {record};`
433
+ + https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer#property_definitions
434
+ * (45) Do not use killing commas (while IE6 is luckily no longer an issue => file size)
435
+ + Bad: `let obj = {a: 1,}`
436
+ + Good: `let obj = {a: 1};`
@@ -20,9 +20,9 @@ class ServiceWorker extends ServiceBase {
20
20
  */
21
21
  singleton: true,
22
22
  /**
23
- * @member {String} version='5.0.2'
23
+ * @member {String} version='5.1.0'
24
24
  */
25
- version: '5.0.2'
25
+ version: '5.1.0'
26
26
  }
27
27
 
28
28
  /**
@@ -1,4 +1,17 @@
1
1
  [
2
+ {
3
+ "author" : "Torsten Dinkheller",
4
+ "authorImage" : "author_TorstenDinkheller.jpg",
5
+ "date" : "Jan 28, 2023",
6
+ "id" : 56,
7
+ "image" : "toast-tutorial-medium.jpg",
8
+ "name" : "Reusable Next Gen Toast — to Industry Standard",
9
+ "provider" : "Medium",
10
+ "publisher" : "ITNEXT",
11
+ "selectedInto": [],
12
+ "type" : "Blog Post",
13
+ "url" : "https://itnext.io/reusable-next-gen-toast-to-industry-standard-502d2950701f?source=friends_link&sk=f74ba5b5161986d9d8dec6e91ba11a5b"
14
+ },
2
15
  {
3
16
  "author" : "Tobias Uhlig",
4
17
  "authorImage" : "author_TobiasUhlig.jpeg",
@@ -20,9 +20,9 @@ class ServiceWorker extends ServiceBase {
20
20
  */
21
21
  singleton: true,
22
22
  /**
23
- * @member {String} version='5.0.2'
23
+ * @member {String} version='5.1.0'
24
24
  */
25
- version: '5.0.2'
25
+ version: '5.1.0'
26
26
  }
27
27
 
28
28
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neo.mjs",
3
- "version": "5.0.2",
3
+ "version": "5.1.0",
4
4
  "description": "The webworkers driven UI framework",
5
5
  "type": "module",
6
6
  "repository": {
@@ -54,9 +54,9 @@
54
54
  "highlightjs-line-numbers.js": "^2.8.0",
55
55
  "inquirer": "^9.1.4",
56
56
  "neo-jsdoc": "^1.0.1",
57
- "neo-jsdoc-x": "^1.0.4",
57
+ "neo-jsdoc-x": "^1.0.5",
58
58
  "postcss": "^8.4.21",
59
- "sass": "^1.57.1",
59
+ "sass": "^1.58.0",
60
60
  "webpack": "^5.75.0",
61
61
  "webpack-cli": "^5.0.1",
62
62
  "webpack-dev-server": "4.11.1",
@@ -65,9 +65,10 @@
65
65
  }
66
66
 
67
67
  .website-header-buttons {
68
- position: absolute;
69
- right : 0;
70
- top : 0;
68
+ background-color: transparent;
69
+ position : absolute;
70
+ right : 0;
71
+ top : 0;
71
72
  }
72
73
 
73
74
  @media (max-height: 400px), (max-width: 600px) {
@@ -132,4 +133,4 @@
132
133
  margin-right: 5px;
133
134
  }
134
135
  }
135
- }
136
+ }
@@ -237,12 +237,12 @@ const DefaultConfig = {
237
237
  useVdomWorker: true,
238
238
  /**
239
239
  * buildScripts/injectPackageVersion.mjs will update this value
240
- * @default '5.0.2'
240
+ * @default '5.1.0'
241
241
  * @memberOf! module:Neo
242
242
  * @name config.version
243
243
  * @type String
244
244
  */
245
- version: '5.0.2'
245
+ version: '5.1.0'
246
246
  };
247
247
 
248
248
  Object.assign(DefaultConfig, {
package/src/Neo.mjs CHANGED
@@ -52,7 +52,7 @@ Neo = globalThis.Neo = Object.assign({
52
52
  ntypeMap = Neo.ntypeMap,
53
53
  proto = cls.prototype || cls,
54
54
  protos = [],
55
- config, ctor, overrides;
55
+ cfg, config, ctor, overrides;
56
56
 
57
57
  while (proto.__proto__) {
58
58
  ctor = proto.constructor;
@@ -69,31 +69,34 @@ Neo = globalThis.Neo = Object.assign({
69
69
  config = baseCfg || {};
70
70
 
71
71
  protos.forEach(element => {
72
+ let mixins;
73
+
72
74
  ctor = element.constructor;
73
75
 
74
- let cfg = ctor.config || {},
75
- mixins;
76
+ cfg = ctor.config || {};
77
+
78
+ if (Neo.overrides) {
79
+ ctor.applyOverrides(cfg);
80
+ }
76
81
 
77
- if (cfg) {
78
- Object.entries(cfg).forEach(([key, value]) => {
79
- if (key.slice(-1) === '_') {
80
- delete cfg[key];
81
- key = key.slice(0, -1);
82
- cfg[key] = value;
83
- autoGenerateGetSet(element, key);
84
- }
82
+ Object.entries(cfg).forEach(([key, value]) => {
83
+ if (key.slice(-1) === '_') {
84
+ delete cfg[key];
85
+ key = key.slice(0, -1);
86
+ cfg[key] = value;
87
+ autoGenerateGetSet(element, key);
88
+ }
85
89
 
86
- // only apply properties which have no setters inside the prototype chain
87
- // those will get applied on create (Neo.core.Base -> initConfig)
88
- else if (!Neo.hasPropertySetter(element, key)) {
89
- Object.defineProperty(element, key, {
90
- enumerable: true,
91
- value,
92
- writable : true
93
- });
94
- }
95
- });
96
- }
90
+ // only apply properties which have no setters inside the prototype chain
91
+ // those will get applied on create (Neo.core.Base -> initConfig)
92
+ else if (!Neo.hasPropertySetter(element, key)) {
93
+ Object.defineProperty(element, key, {
94
+ enumerable: true,
95
+ value,
96
+ writable : true
97
+ });
98
+ }
99
+ });
97
100
 
98
101
  if (Object.hasOwn(cfg, 'ntype')) {
99
102
  if (Object.hasOwn(ntypeMap, cfg.ntype)) {
@@ -126,11 +129,6 @@ Neo = globalThis.Neo = Object.assign({
126
129
 
127
130
  Object.assign(config, cfg);
128
131
 
129
- if (Neo.overrides) {
130
- overrides = Neo.ns(config.className, false, Neo.overrides);
131
- overrides && Object.assign(config, overrides);
132
- }
133
-
134
132
  Object.assign(ctor, {
135
133
  classConfigApplied: true,
136
134
  config : Neo.clone(config, true),