neo.mjs 6.18.2 → 6.19.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 (108) hide show
  1. package/README.md +28 -214
  2. package/apps/ServiceWorker.mjs +2 -2
  3. package/apps/colors/view/ViewportController.mjs +7 -3
  4. package/apps/portal/data/blog.json +13 -0
  5. package/apps/portal/view/HeaderToolbar.mjs +2 -2
  6. package/apps/portal/view/Viewport.mjs +4 -2
  7. package/apps/portal/view/ViewportController.mjs +89 -8
  8. package/apps/portal/view/blog/Container.mjs +8 -8
  9. package/apps/portal/view/blog/List.mjs +6 -6
  10. package/apps/portal/view/home/MainContainer.mjs +9 -10
  11. package/apps/portal/view/home/parts/BaseContainer.mjs +8 -1
  12. package/apps/portal/view/home/parts/Colors.mjs +4 -4
  13. package/apps/portal/view/home/parts/Helix.mjs +2 -2
  14. package/apps/portal/view/home/parts/How.mjs +3 -3
  15. package/apps/portal/view/home/parts/MainNeo.mjs +6 -7
  16. package/apps/portal/view/home/parts/References.mjs +88 -0
  17. package/apps/portal/view/learn/ContentView.mjs +3 -1
  18. package/apps/portal/view/learn/MainContainer.mjs +3 -2
  19. package/apps/portal/view/learn/MainContainerController.mjs +11 -0
  20. package/apps/portal/view/learn/PageContainer.mjs +5 -3
  21. package/apps/portal/view/services/Component.mjs +73 -0
  22. package/apps/website/data/blog.json +13 -0
  23. package/examples/ServiceWorker.mjs +2 -2
  24. package/examples/component/carousel/MainContainer.mjs +42 -33
  25. package/examples/layout/cube/MainContainer.mjs +217 -0
  26. package/examples/layout/cube/app.mjs +6 -0
  27. package/examples/layout/cube/index.html +11 -0
  28. package/examples/layout/cube/neo-config.json +6 -0
  29. package/package.json +7 -7
  30. package/resources/data/deck/learnneo/pages/2023-10-14T19-25-08-153Z.md +2 -2
  31. package/resources/data/deck/learnneo/pages/ComponentModels.md +6 -6
  32. package/resources/data/deck/learnneo/pages/ComponentsAndContainers.md +10 -10
  33. package/resources/data/deck/learnneo/pages/Config.md +6 -6
  34. package/resources/data/deck/learnneo/pages/CustomComponents.md +4 -4
  35. package/resources/data/deck/learnneo/pages/DescribingTheUI.md +4 -4
  36. package/resources/data/deck/learnneo/pages/Earthquakes-01-goals.md +32 -0
  37. package/resources/data/deck/learnneo/pages/Earthquakes-Lab-01-generate-a-workspace.md +47 -0
  38. package/resources/data/deck/learnneo/pages/Earthquakes-Lab-02-generate-the-starter-app.md +150 -0
  39. package/resources/data/deck/learnneo/pages/Earthquakes-Lab-03-debugging.md +136 -0
  40. package/resources/data/deck/learnneo/pages/Earthquakes-Lab-04-fetch-data.md +146 -0
  41. package/resources/data/deck/learnneo/pages/Earthquakes-Lab-05-refactor-the-table.md +146 -0
  42. package/resources/data/deck/learnneo/pages/Earthquakes-Lab-06-use-a-view-model.md +301 -0
  43. package/resources/data/deck/learnneo/pages/Earthquakes-Lab-07-use-the-google-maps-addon.md +175 -0
  44. package/resources/data/deck/learnneo/pages/Earthquakes-Lab-08-events.md +38 -0
  45. package/resources/data/deck/learnneo/pages/Earthquakes.md +10 -10
  46. package/resources/data/deck/learnneo/pages/Events.md +7 -7
  47. package/resources/data/deck/learnneo/pages/Extending.md +7 -7
  48. package/resources/data/deck/learnneo/pages/Glossary.md +0 -0
  49. package/resources/data/deck/learnneo/pages/GuideEvents.md +97 -19
  50. package/resources/data/deck/learnneo/pages/GuideViewModels.md +21 -21
  51. package/resources/data/deck/learnneo/pages/References.md +8 -8
  52. package/resources/data/deck/learnneo/pages/TestLivePreview.md +5 -4
  53. package/resources/data/deck/learnneo/pages/TodoList.md +9 -9
  54. package/resources/data/deck/learnneo/pages/Welcome.md +3 -3
  55. package/resources/data/deck/learnneo/pages/WhyNeo-Multi-Window.md +2 -2
  56. package/resources/data/deck/learnneo/pages/WhyNeo-Speed.md +2 -2
  57. package/resources/data/deck/learnneo/tree.json +2 -1
  58. package/resources/images/apps/portal/neo-references.png +0 -0
  59. package/resources/scss/src/apps/portal/HeaderToolbar.scss +0 -46
  60. package/resources/scss/src/apps/portal/Viewport.scss +16 -1
  61. package/resources/scss/src/apps/portal/blog/Container.scss +7 -7
  62. package/resources/scss/src/apps/portal/blog/List.scss +20 -16
  63. package/resources/scss/src/apps/portal/home/parts/BaseContainer.scss +33 -4
  64. package/resources/scss/src/apps/portal/home/parts/MainNeo.scss +4 -5
  65. package/resources/scss/src/apps/portal/home/parts/References.scss +46 -0
  66. package/resources/scss/src/apps/portal/learn/ContentTreeList.scss +20 -0
  67. package/resources/scss/src/apps/portal/learn/ContentView.scss +4 -0
  68. package/resources/scss/src/apps/portal/learn/MainContainer.scss +1 -1
  69. package/resources/scss/src/apps/portal/learn/PageContainer.scss +22 -16
  70. package/resources/scss/src/apps/portal/services/Component.scss +20 -0
  71. package/resources/scss/src/{apps/portal/learn → code}/LivePreview.scss +1 -1
  72. package/resources/scss/src/component/Carousel.scss +21 -0
  73. package/resources/scss/src/component/Helix.scss +1 -2
  74. package/resources/scss/src/examples/layout/cube/MainContainer.scss +7 -0
  75. package/resources/scss/src/layout/Cube.scss +80 -0
  76. package/resources/scss/src/tab/Container.scss +10 -10
  77. package/resources/scss/theme-neo-light/apps/portal/blog/Container.scss +3 -0
  78. package/resources/scss/theme-neo-light/form/field/Search.scss +1 -1
  79. package/resources/scss/theme-neo-light/tooltip/Base.scss +1 -1
  80. package/src/DefaultConfig.mjs +2 -2
  81. package/src/Main.mjs +15 -1
  82. package/src/Neo.mjs +14 -3
  83. package/{apps/portal/view/learn → src/code}/LivePreview.mjs +43 -27
  84. package/src/component/Base.mjs +18 -1
  85. package/src/container/Base.mjs +3 -1
  86. package/src/dialog/Base.mjs +1 -2
  87. package/src/layout/Base.mjs +43 -6
  88. package/src/layout/Card.mjs +21 -59
  89. package/src/layout/Cube.mjs +428 -0
  90. package/src/layout/Fit.mjs +9 -38
  91. package/src/layout/Flexbox.mjs +16 -17
  92. package/src/layout/Form.mjs +13 -70
  93. package/src/layout/Grid.mjs +6 -18
  94. package/src/main/addon/ResizeObserver.mjs +18 -2
  95. package/src/main/mixin/DeltaUpdates.mjs +16 -3
  96. package/src/util/Array.mjs +36 -0
  97. package/src/vdom/Helper.mjs +328 -445
  98. package/src/vdom/VNode.mjs +12 -1
  99. package/test/siesta/siesta.js +16 -1
  100. package/test/siesta/tests/VdomCalendar.mjs +2111 -37
  101. package/test/siesta/tests/VdomHelper.mjs +283 -47
  102. package/test/siesta/tests/vdom/Advanced.mjs +367 -0
  103. package/test/siesta/tests/vdom/layout/Cube.mjs +189 -0
  104. package/test/siesta/tests/vdom/table/Container.mjs +133 -0
  105. package/apps/portal/view/home/parts/HelloWorld.mjs +0 -83
  106. package/apps/portal/view/home/preview/PageCodeContainer.mjs +0 -55
  107. package/resources/scss/src/apps/portal/home/preview/PageCodeContainer.scss +0 -115
  108. package/resources/scss/theme-neo-light/apps/portal/learn/ContentTreeList.scss +0 -23
@@ -16,7 +16,12 @@ class Fit extends Base {
16
16
  * @member {String} ntype='layout-fit'
17
17
  * @protected
18
18
  */
19
- ntype: 'layout-fit'
19
+ ntype: 'layout-fit',
20
+ /**
21
+ * @member {String|null} containerCls='neo-layout-fit'
22
+ * @protected
23
+ */
24
+ containerCls: 'neo-layout-fit'
20
25
  }
21
26
 
22
27
  /**
@@ -30,54 +35,20 @@ class Fit extends Base {
30
35
  }
31
36
  }
32
37
 
33
- /**
34
- * Applies CSS classes to the container this layout is bound to
35
- */
36
- applyRenderAttributes() {
37
- let me = this,
38
- container = Neo.getComponent(me.containerId),
39
- wrapperCls = container?.wrapperCls || [];
40
-
41
- if (!container) {
42
- Neo.logError('layout.Fit: applyRenderAttributes -> container not yet created', me.containerId)
43
- }
44
-
45
- NeoArray.add(wrapperCls, 'neo-layout-fit');
46
-
47
- container.wrapperCls = wrapperCls
48
- }
49
-
50
38
  /**
51
39
  * Removes all CSS rules from a container item this layout is bound to.
52
40
  * Gets called when switching to a different layout.
53
41
  * @param {Neo.component.Base} item
42
+ * @param {Number} index
54
43
  */
55
- removeChildAttributes(item) {
44
+ removeChildAttributes(item, index) {
56
45
  if (!item.ignoreLayout) {
57
- let wrapperCls = item.wrapperCls;
46
+ let {wrapperCls} = item;
58
47
 
59
48
  NeoArray.remove(wrapperCls, 'neo-layout-fit-item');
60
49
  item.wrapperCls = wrapperCls
61
50
  }
62
51
  }
63
-
64
- /**
65
- * Removes all CSS rules from the container this layout is bound to.
66
- * Gets called when switching to a different layout.
67
- */
68
- removeRenderAttributes() {
69
- let me = this,
70
- container = Neo.getComponent(me.containerId),
71
- wrapperCls = container?.wrapperCls || [];
72
-
73
- if (!container) {
74
- Neo.logError('layout.Fit: removeRenderAttributes -> container not yet created', me.containerId)
75
- }
76
-
77
- NeoArray.remove(wrapperCls, 'neo-layout-fit');
78
-
79
- container.wrapperCls = wrapperCls
80
- }
81
52
  }
82
53
 
83
54
  Neo.setupClass(Fit);
@@ -107,11 +107,12 @@ class Flexbox extends Base {
107
107
  afterSetGap(value, oldValue) {
108
108
  if (!value && !oldValue) return;
109
109
 
110
- let item = Neo.getComponent(this.containerId),
111
- style = item.wrapperStyle;
110
+ let {container} = this,
111
+ {wrapperStyle} = container;
112
112
 
113
- style.gap = value;
114
- item.wrapperStyle = style
113
+ wrapperStyle.gap = value;
114
+
115
+ container.wrapperStyle = wrapperStyle
115
116
  }
116
117
 
117
118
  /**
@@ -155,10 +156,9 @@ class Flexbox extends Base {
155
156
  * Applies CSS classes to the container this layout is bound to
156
157
  */
157
158
  applyRenderAttributes() {
158
- let me = this,
159
- container = Neo.getComponent(me.containerId),
160
- {prefix} = me,
161
- wrapperCls = container?.wrapperCls || [];
159
+ let me = this,
160
+ {container, prefix} = me,
161
+ {wrapperCls} = container;
162
162
 
163
163
  if (!container) {
164
164
  Neo.logError('layout.Flexbox: applyRenderAttributes -> container not yet created', me.containerId)
@@ -222,9 +222,10 @@ class Flexbox extends Base {
222
222
  * Removes all CSS rules from a container item this layout is bound to.
223
223
  * Gets called when switching to a different layout.
224
224
  * @param {Neo.component.Base} item
225
+ * @param {Number} index
225
226
  * @protected
226
227
  */
227
- removeChildAttributes(item) {
228
+ removeChildAttributes(item, index) {
228
229
  let style = item.wrapperStyle || {};
229
230
 
230
231
  style.flex = item.flex || null;
@@ -237,10 +238,9 @@ class Flexbox extends Base {
237
238
  * @protected
238
239
  */
239
240
  removeRenderAttributes() {
240
- let me = this,
241
- container = Neo.getComponent(me.containerId),
242
- {prefix} = me,
243
- wrapperCls = container?.wrapperCls || [];
241
+ let me = this,
242
+ {container, prefix} = me,
243
+ {wrapperCls} = container;
244
244
 
245
245
  if (!container) {
246
246
  Neo.logError('layout.Flexbox: removeRenderAttributes -> container not yet created', me.containerId)
@@ -292,10 +292,9 @@ class Flexbox extends Base {
292
292
  * @protected
293
293
  */
294
294
  updateInputValue(value, oldValue, propertyName) {
295
- let me = this,
296
- container = Neo.getComponent(me.containerId),
297
- {prefix} = me,
298
- wrapperCls = container?.wrapperCls;
295
+ let me = this,
296
+ {container, prefix} = me,
297
+ {wrapperCls} = container;
299
298
 
300
299
  if (container?.rendered) {
301
300
  NeoArray.remove(wrapperCls, prefix + propertyName + '-' + oldValue);
@@ -18,15 +18,15 @@ class Form extends Base {
18
18
  */
19
19
  ntype: 'layout-form',
20
20
  /**
21
- * flex css allows gap. This adds it to the component style
22
- * @member {String} gap_=null
21
+ * @member {String|null} containerCls='neo-layout-fit'
22
+ * @protected
23
23
  */
24
- gap_: null,
24
+ containerCls: 'neo-layout-form',
25
25
  /**
26
- * CSS className prefix
27
- * @member {String} prefix='neo-form-'
26
+ * flex css allows gap. This adds it to the component style
27
+ * @member {String} gap_=null
28
28
  */
29
- prefix: 'neo-layout-form-'
29
+ gap_: null
30
30
  }
31
31
 
32
32
  /**
@@ -38,11 +38,12 @@ class Form extends Base {
38
38
  afterSetGap(value, oldValue) {
39
39
  if (!value && !oldValue) return;
40
40
 
41
- let item = Neo.getComponent(this.containerId),
42
- style = item.wrapperStyle;
41
+ let {container} = this,
42
+ {wrapperStyle} = container;
43
43
 
44
- style.gap = value;
45
- item.wrapperStyle = style
44
+ wrapperStyle.gap = value;
45
+
46
+ container.wrapperStyle = wrapperStyle
46
47
  }
47
48
 
48
49
  /**
@@ -62,77 +63,19 @@ class Form extends Base {
62
63
  }
63
64
  }
64
65
 
65
- /**
66
- * Applies CSS classes to the container this layout is bound to
67
- */
68
- applyRenderAttributes() {
69
- let me = this,
70
- container = Neo.getComponent(me.containerId),
71
- wrapperCls = container?.wrapperCls || [];
72
-
73
- if (!container) {
74
- Neo.logError('layout.Form: applyRenderAttributes -> container not yet created', me.containerId)
75
- }
76
-
77
- NeoArray.add(wrapperCls, 'neo-layout-form');
78
-
79
- container.wrapperCls = wrapperCls
80
- }
81
-
82
66
  /**
83
67
  * Removes all CSS rules from an container item this layout is bound to.
84
68
  * Gets called when switching to a different layout.
85
69
  * @param {Neo.component.Base} item
70
+ * @param {Number} index
86
71
  * @protected
87
72
  */
88
- removeChildAttributes(item) {
73
+ removeChildAttributes(item, index) {
89
74
  let style = item.wrapperStyle || {};
90
75
 
91
76
  style.flex = item.flex || null;
92
77
  item.wrapperStyle = style
93
78
  }
94
-
95
- /**
96
- * Removes all CSS rules from the container this layout is bound to.
97
- * Gets called when switching to a different layout.
98
- */
99
- removeRenderAttributes() {
100
- let me = this,
101
- container = Neo.getComponent(me.containerId),
102
- wrapperCls = container?.wrapperCls || [];
103
-
104
- if (!container) {
105
- Neo.logError('layout.Form: removeRenderAttributes -> container not yet created', me.containerId)
106
- }
107
-
108
- NeoArray.remove(wrapperCls, 'neo-layout-form');
109
-
110
- container.wrapperCls = wrapperCls
111
- }
112
-
113
- /**
114
- * Updates the Container CSS wrapperCls
115
- * @param {String|null} value
116
- * @param {String|null} oldValue
117
- * @param {String} propertyName
118
- * @protected
119
- */
120
- updateInputValue(value, oldValue, propertyName) {
121
- let me = this,
122
- container = Neo.getComponent(me.containerId),
123
- {prefix} = me,
124
- wrapperCls = container?.wrapperCls;
125
-
126
- if (container?.rendered) {
127
- NeoArray.remove(wrapperCls, prefix + propertyName + '-' + oldValue);
128
-
129
- if (value !== null) {
130
- NeoArray.add(wrapperCls, prefix + propertyName + '-' + value)
131
- }
132
-
133
- container.wrapperCls = wrapperCls
134
- }
135
- }
136
79
  }
137
80
 
138
81
  Neo.setupClass(Form);
@@ -16,24 +16,12 @@ class Grid extends Base {
16
16
  * @member {String} ntype='layout-hbox'
17
17
  * @protected
18
18
  */
19
- ntype: 'layout-grid'
20
- }
21
-
22
- /**
23
- * Applies CSS classes to the container this layout is bound to
24
- */
25
- applyRenderAttributes() {
26
- let me = this,
27
- container = Neo.getComponent(me.containerId),
28
- wrapperCls = container?.wrapperCls || [];
29
-
30
- if (!container) {
31
- Neo.logError('layout.Grid: applyRenderAttributes -> container not yet created', me.containerId)
32
- }
33
-
34
- NeoArray.add(wrapperCls, 'neo-layout-grid');
35
-
36
- container.wrapperCls = wrapperCls
19
+ ntype: 'layout-grid',
20
+ /**
21
+ * @member {String|null} containerCls='neo-layout-fit'
22
+ * @protected
23
+ */
24
+ containerCls: 'neo-layout-grid'
37
25
  }
38
26
  }
39
27
 
@@ -19,6 +19,12 @@ class NeoResizeObserver extends Base {
19
19
  * @protected
20
20
  */
21
21
  instance: null,
22
+ /**
23
+ * If a target node is not found when calling register(),
24
+ * we can specify the amount of retries with a 100ms delay.
25
+ * @member {Number} registerAttempts=3
26
+ */
27
+ registerAttempts: 3,
22
28
  /**
23
29
  * Remote method access for other workers
24
30
  * @member {Object} remote
@@ -92,9 +98,19 @@ class NeoResizeObserver extends Base {
92
98
  /**
93
99
  * @param {Object} data
94
100
  * @param {String} data.id
101
+ * @param {Number} count=0
95
102
  */
96
- register(data) {
97
- this.instance.observe(DomAccess.getElement(data.id))
103
+ async register(data, count=0) {
104
+ let me = this,
105
+ node = DomAccess.getElement(data.id);
106
+
107
+ if (node) {
108
+ me.instance.observe(node)
109
+ } else if (count < me.registerAttempts) {
110
+ await me.timeout(100);
111
+ count++;
112
+ me.register(data, count)
113
+ }
98
114
  }
99
115
 
100
116
  /**
@@ -120,7 +120,7 @@ class DeltaUpdates extends Base {
120
120
  node = this.getElement(delta.id),
121
121
  parentNode = this.getElement(delta.parentId);
122
122
 
123
- if (parentNode) {
123
+ if (node && parentNode) {
124
124
  if (index >= parentNode.children.length) {
125
125
  parentNode.appendChild(node)
126
126
  } else {
@@ -132,6 +132,18 @@ class DeltaUpdates extends Base {
132
132
  }
133
133
  }
134
134
 
135
+ /**
136
+ * @param {Object} delta
137
+ * @param {String} delta.parentId
138
+ */
139
+ du_removeAll(delta) {
140
+ let node = this.getElement(delta.parentId);
141
+
142
+ if (node) {
143
+ node.innerHTML = ''
144
+ }
145
+ }
146
+
135
147
  /**
136
148
  * @param {Object} delta
137
149
  * @param {String} delta.id
@@ -225,8 +237,8 @@ class DeltaUpdates extends Base {
225
237
  });
226
238
  break
227
239
  case 'cls':
228
- node.classList.add(...value.add || []);
229
- node.classList.remove(...value.remove || []);
240
+ value.add && node.classList.add(...value.add);
241
+ value.remove && node.classList.remove(...value.remove);
230
242
  break
231
243
  case 'innerHTML':
232
244
  node.innerHTML = value || '';
@@ -311,6 +323,7 @@ class DeltaUpdates extends Base {
311
323
  focusNode : me.du_focusNode,
312
324
  insertNode : me.du_insertNode,
313
325
  moveNode : me.du_moveNode,
326
+ removeAll : me.du_removeAll,
314
327
  removeNode : me.du_removeNode,
315
328
  replaceChild : me.du_replaceChild,
316
329
  setTextContent: me.du_setTextContent,
@@ -18,6 +18,7 @@ class NeoArray extends Base {
18
18
  * Only primitive items will get found as duplicates
19
19
  * @param {Array} arr
20
20
  * @param {*} items
21
+ * @returns {Array}
21
22
  */
22
23
  static add(arr, items) {
23
24
  if (!Array.isArray(items)) {
@@ -52,6 +53,41 @@ class NeoArray extends Base {
52
53
  return arr.includes(item)
53
54
  }
54
55
 
56
+ /**
57
+ * Inserts an item or Array of items to an array in case it does not already exist.
58
+ * Duplicates will only get matched by reference.
59
+ * @param {Array} arr
60
+ * @param {Number} index
61
+ * @param {*} items
62
+ * @returns {Array}
63
+ */
64
+ static insert(arr, index, items) {
65
+ if (!Array.isArray(items)) {
66
+ items = [items]
67
+ }
68
+
69
+ let len = items.length -1,
70
+ i = len,
71
+ currentIndex, item;
72
+
73
+ // Iterate backwards
74
+ for (; i > -1; i--) {
75
+ item = items[i];
76
+
77
+ currentIndex = arr.indexOf(item);
78
+
79
+ if (index !== currentIndex) {
80
+ if (currentIndex > -1) {
81
+ this.move(arr, currentIndex, index)
82
+ } else {
83
+ arr.splice(index, 0, item)
84
+ }
85
+ }
86
+ }
87
+
88
+ return arr
89
+ }
90
+
55
91
  /**
56
92
  * Returns an array of items which are present in array1 and array2
57
93
  * Only supports primitive items