nodality 1.0.221 → 1.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 (279) hide show
  1. package/API.md +227 -0
  2. package/bin/nodality.js +64 -0
  3. package/dist/animator.cjs.js +1 -1
  4. package/dist/animator.cjs.js.LICENSE.txt +1 -1
  5. package/dist/animator.esm.js +1 -1
  6. package/dist/animator.esm.js.LICENSE.txt +1 -1
  7. package/dist/audionew.cjs.js +1 -1
  8. package/dist/audionew.cjs.js.LICENSE.txt +1 -1
  9. package/dist/audionew.esm.js +1 -1
  10. package/dist/audionew.esm.js.LICENSE.txt +1 -1
  11. package/dist/base.cjs.js +1 -1
  12. package/dist/base.cjs.js.LICENSE.txt +1 -1
  13. package/dist/base.esm.js +1 -1
  14. package/dist/base.esm.js.LICENSE.txt +1 -1
  15. package/dist/beta-desktop-bar.cjs.js +1 -1
  16. package/dist/beta-desktop-bar.cjs.js.LICENSE.txt +1 -1
  17. package/dist/beta-desktop-bar.esm.js +1 -1
  18. package/dist/beta-desktop-bar.esm.js.LICENSE.txt +1 -1
  19. package/dist/beta-mobile-bar.cjs.js +1 -1
  20. package/dist/beta-mobile-bar.cjs.js.LICENSE.txt +1 -1
  21. package/dist/beta-mobile-bar.esm.js +1 -1
  22. package/dist/beta-mobile-bar.esm.js.LICENSE.txt +1 -1
  23. package/dist/bundle.umd.js +1 -1
  24. package/dist/bundle.umd.js.LICENSE.txt +131 -1
  25. package/dist/button.cjs.js +1 -1
  26. package/dist/button.cjs.js.LICENSE.txt +1 -1
  27. package/dist/button.esm.js +1 -1
  28. package/dist/button.esm.js.LICENSE.txt +1 -1
  29. package/dist/card-getter.cjs.js.LICENSE.txt +1 -1
  30. package/dist/card-getter.esm.js.LICENSE.txt +1 -1
  31. package/dist/center.cjs.js +1 -1
  32. package/dist/center.cjs.js.LICENSE.txt +1 -1
  33. package/dist/center.esm.js +1 -1
  34. package/dist/center.esm.js.LICENSE.txt +1 -1
  35. package/dist/checkbox.cjs.js +1 -1
  36. package/dist/checkbox.cjs.js.LICENSE.txt +1 -1
  37. package/dist/checkbox.esm.js +1 -1
  38. package/dist/checkbox.esm.js.LICENSE.txt +1 -1
  39. package/dist/code.cjs.js +1 -1
  40. package/dist/code.cjs.js.LICENSE.txt +1 -1
  41. package/dist/code.esm.js +1 -1
  42. package/dist/code.esm.js.LICENSE.txt +1 -1
  43. package/dist/container.cjs.js +1 -1
  44. package/dist/container.cjs.js.LICENSE.txt +1 -1
  45. package/dist/container.esm.js +1 -1
  46. package/dist/container.esm.js.LICENSE.txt +1 -1
  47. package/dist/data-list.cjs.js +1 -1
  48. package/dist/data-list.cjs.js.LICENSE.txt +1 -1
  49. package/dist/data-list.esm.js +1 -1
  50. package/dist/data-list.esm.js.LICENSE.txt +1 -1
  51. package/dist/designer.cjs.js +1 -1
  52. package/dist/designer.cjs.js.LICENSE.txt +97 -1
  53. package/dist/designer.esm.js +1 -1
  54. package/dist/designer.esm.js.LICENSE.txt +97 -1
  55. package/dist/element-mapper.cjs.js +1 -1
  56. package/dist/element-mapper.cjs.js.LICENSE.txt +17 -1
  57. package/dist/element-mapper.esm.js +1 -1
  58. package/dist/element-mapper.esm.js.LICENSE.txt +17 -1
  59. package/dist/finalresult.esm.js +1 -1
  60. package/dist/finalresult.esm.js.LICENSE.txt +158 -1
  61. package/dist/flex-card.cjs.js +1 -1
  62. package/dist/flex-card.cjs.js.LICENSE.txt +1 -1
  63. package/dist/flex-card.esm.js +1 -1
  64. package/dist/flex-card.esm.js.LICENSE.txt +1 -1
  65. package/dist/flex-grid.cjs.js +1 -1
  66. package/dist/flex-grid.cjs.js.LICENSE.txt +1 -1
  67. package/dist/flex-grid.esm.js +1 -1
  68. package/dist/flex-grid.esm.js.LICENSE.txt +1 -1
  69. package/dist/flex-row.cjs.js +1 -1
  70. package/dist/flex-row.cjs.js.LICENSE.txt +1 -1
  71. package/dist/flex-row.esm.js +1 -1
  72. package/dist/flex-row.esm.js.LICENSE.txt +1 -1
  73. package/dist/floating-input.cjs.js +1 -1
  74. package/dist/floating-input.cjs.js.LICENSE.txt +1 -1
  75. package/dist/floating-input.esm.js +1 -1
  76. package/dist/floating-input.esm.js.LICENSE.txt +1 -1
  77. package/dist/free.cjs.js +1 -1
  78. package/dist/free.cjs.js.LICENSE.txt +1 -1
  79. package/dist/free.esm.js +1 -1
  80. package/dist/free.esm.js.LICENSE.txt +1 -1
  81. package/dist/horizontal-scroller.cjs.js.LICENSE.txt +1 -1
  82. package/dist/horizontal-scroller.esm.js.LICENSE.txt +1 -1
  83. package/dist/image-picker.cjs.js +1 -1
  84. package/dist/image-picker.cjs.js.LICENSE.txt +1 -1
  85. package/dist/image-picker.esm.js +1 -1
  86. package/dist/image-picker.esm.js.LICENSE.txt +1 -1
  87. package/dist/image.cjs.js +1 -1
  88. package/dist/image.cjs.js.LICENSE.txt +1 -1
  89. package/dist/image.esm.js +1 -1
  90. package/dist/image.esm.js.LICENSE.txt +1 -1
  91. package/dist/index.cjs.js +1 -1
  92. package/dist/index.cjs.js.LICENSE.txt +158 -1
  93. package/dist/index.d.ts +962 -0
  94. package/dist/index.esm.js +1 -1
  95. package/dist/index.esm.js.LICENSE.txt +158 -1
  96. package/dist/keyframe-animation.cjs.js.LICENSE.txt +1 -1
  97. package/dist/keyframe-animation.esm.js.LICENSE.txt +1 -1
  98. package/dist/link-getter.cjs.js +1 -1
  99. package/dist/link-getter.cjs.js.LICENSE.txt +1 -1
  100. package/dist/link-getter.esm.js +1 -1
  101. package/dist/link-getter.esm.js.LICENSE.txt +1 -1
  102. package/dist/link.cjs.js +1 -1
  103. package/dist/link.cjs.js.LICENSE.txt +1 -1
  104. package/dist/link.esm.js +1 -1
  105. package/dist/link.esm.js.LICENSE.txt +1 -1
  106. package/dist/meta-adder.cjs.js +1 -1
  107. package/dist/meta-adder.cjs.js.LICENSE.txt +1 -1
  108. package/dist/meta-adder.esm.js +1 -1
  109. package/dist/meta-adder.esm.js.LICENSE.txt +1 -1
  110. package/dist/modal-2025.cjs.js +1 -1
  111. package/dist/modal-2025.cjs.js.LICENSE.txt +1 -1
  112. package/dist/modal-2025.esm.js +1 -1
  113. package/dist/modal-2025.esm.js.LICENSE.txt +1 -1
  114. package/dist/multiswitcher.cjs.js +1 -1
  115. package/dist/multiswitcher.cjs.js.LICENSE.txt +1 -1
  116. package/dist/multiswitcher.esm.js +1 -1
  117. package/dist/multiswitcher.esm.js.LICENSE.txt +1 -1
  118. package/dist/new-nav-bar.cjs.js +1 -1
  119. package/dist/new-nav-bar.cjs.js.LICENSE.txt +1 -1
  120. package/dist/new-nav-bar.esm.js +1 -1
  121. package/dist/new-nav-bar.esm.js.LICENSE.txt +1 -1
  122. package/dist/picker.cjs.js +1 -1
  123. package/dist/picker.cjs.js.LICENSE.txt +1 -1
  124. package/dist/picker.esm.js +1 -1
  125. package/dist/picker.esm.js.LICENSE.txt +1 -1
  126. package/dist/progress.cjs.js +1 -1
  127. package/dist/progress.cjs.js.LICENSE.txt +1 -1
  128. package/dist/progress.esm.js +1 -1
  129. package/dist/progress.esm.js.LICENSE.txt +1 -1
  130. package/dist/radio.cjs.js +1 -1
  131. package/dist/radio.cjs.js.LICENSE.txt +1 -1
  132. package/dist/radio.esm.js +1 -1
  133. package/dist/radio.esm.js.LICENSE.txt +1 -1
  134. package/dist/range.cjs.js +1 -1
  135. package/dist/range.cjs.js.LICENSE.txt +1 -1
  136. package/dist/range.esm.js +1 -1
  137. package/dist/range.esm.js.LICENSE.txt +1 -1
  138. package/dist/scroll-video.cjs.js.LICENSE.txt +1 -1
  139. package/dist/scroll-video.esm.js.LICENSE.txt +1 -1
  140. package/dist/side-bar.cjs.js +1 -1
  141. package/dist/side-bar.cjs.js.LICENSE.txt +1 -1
  142. package/dist/side-bar.esm.js +1 -1
  143. package/dist/side-bar.esm.js.LICENSE.txt +1 -1
  144. package/dist/side-nav-bar.cjs.js +1 -1
  145. package/dist/side-nav-bar.cjs.js.LICENSE.txt +1 -1
  146. package/dist/side-nav-bar.esm.js +1 -1
  147. package/dist/side-nav-bar.esm.js.LICENSE.txt +1 -1
  148. package/dist/simple-bar.cjs.js +1 -1
  149. package/dist/simple-bar.cjs.js.LICENSE.txt +1 -1
  150. package/dist/simple-bar.esm.js +1 -1
  151. package/dist/simple-bar.esm.js.LICENSE.txt +1 -1
  152. package/dist/slider-2025.cjs.js +1 -1
  153. package/dist/slider-2025.cjs.js.LICENSE.txt +1 -1
  154. package/dist/slider-2025.esm.js +1 -1
  155. package/dist/slider-2025.esm.js.LICENSE.txt +1 -1
  156. package/dist/spacer.cjs.js +1 -1
  157. package/dist/spacer.cjs.js.LICENSE.txt +1 -1
  158. package/dist/spacer.esm.js +1 -1
  159. package/dist/spacer.esm.js.LICENSE.txt +1 -1
  160. package/dist/stack.cjs.js +1 -1
  161. package/dist/stack.cjs.js.LICENSE.txt +1 -1
  162. package/dist/stack.esm.js +1 -1
  163. package/dist/stack.esm.js.LICENSE.txt +1 -1
  164. package/dist/stacker.cjs.js.LICENSE.txt +1 -1
  165. package/dist/stacker.esm.js.LICENSE.txt +1 -1
  166. package/dist/table.cjs.js +1 -1
  167. package/dist/table.cjs.js.LICENSE.txt +1 -1
  168. package/dist/table.esm.js +1 -1
  169. package/dist/table.esm.js.LICENSE.txt +1 -1
  170. package/dist/text-field.cjs.js +1 -1
  171. package/dist/text-field.cjs.js.LICENSE.txt +1 -1
  172. package/dist/text-field.esm.js +1 -1
  173. package/dist/text-field.esm.js.LICENSE.txt +1 -1
  174. package/dist/text.cjs.js +1 -1
  175. package/dist/text.cjs.js.LICENSE.txt +1 -1
  176. package/dist/text.esm.js +1 -1
  177. package/dist/text.esm.js.LICENSE.txt +1 -1
  178. package/dist/theme.cjs.js.LICENSE.txt +1 -1
  179. package/dist/theme.esm.js.LICENSE.txt +1 -1
  180. package/dist/transform-anim.cjs.js.LICENSE.txt +1 -1
  181. package/dist/transform-anim.esm.js.LICENSE.txt +1 -1
  182. package/dist/ulist.cjs.js +1 -1
  183. package/dist/ulist.cjs.js.LICENSE.txt +1 -1
  184. package/dist/ulist.esm.js +1 -1
  185. package/dist/ulist.esm.js.LICENSE.txt +1 -1
  186. package/dist/video.cjs.js +1 -1
  187. package/dist/video.cjs.js.LICENSE.txt +1 -1
  188. package/dist/video.esm.js +1 -1
  189. package/dist/video.esm.js.LICENSE.txt +1 -1
  190. package/dist/wrap.cjs.js +1 -1
  191. package/dist/wrap.cjs.js.LICENSE.txt +1 -1
  192. package/dist/wrap.esm.js +1 -1
  193. package/dist/wrap.esm.js.LICENSE.txt +1 -1
  194. package/dist/zoom-card.cjs.js +1 -1
  195. package/dist/zoom-card.cjs.js.LICENSE.txt +1 -1
  196. package/dist/zoom-card.esm.js +1 -1
  197. package/dist/zoom-card.esm.js.LICENSE.txt +1 -1
  198. package/examples/custom-raster-op.js +174 -0
  199. package/layout/animator.js +30 -2
  200. package/layout/audio.js +1 -1
  201. package/layout/audionew.js +1 -1
  202. package/layout/base.js +1 -1
  203. package/layout/beta-desktop-bar.js +1 -1
  204. package/layout/beta-mobile-bar.js +3 -2
  205. package/layout/button.js +1 -1
  206. package/layout/center.js +1 -1
  207. package/layout/checkbox.js +2 -2
  208. package/layout/circle.js +3 -2
  209. package/layout/code.js +3 -2
  210. package/layout/container.js +3 -4
  211. package/layout/dropdown-2025.js +1 -1
  212. package/layout/flex-card.js +1 -1
  213. package/layout/flex-grid.js +1 -1
  214. package/layout/flex-row.js +3 -2
  215. package/layout/form-components/custom.js +1 -1
  216. package/layout/form-components/data-list.js +2 -2
  217. package/layout/form-components/floating-input.js +2 -2
  218. package/layout/form-components/form-all.js +2 -2
  219. package/layout/form-components/form.js +1 -1
  220. package/layout/form-components/image-picker.js +1 -1
  221. package/layout/form-components/picker.js +2 -2
  222. package/layout/form-components/radio.js +2 -2
  223. package/layout/form-components/radiogroup.js +2 -2
  224. package/layout/form-components/range.js +2 -2
  225. package/layout/free.js +3 -4
  226. package/layout/grid-switcher.js +1 -1
  227. package/layout/grid.js +1 -1
  228. package/layout/horizontal-scroller.js +1 -1
  229. package/layout/image.js +1 -1
  230. package/layout/index.js +1 -1
  231. package/layout/link.js +5 -5
  232. package/layout/list.js +3 -4
  233. package/layout/meta-adder.js +1 -1
  234. package/layout/modal-2025.js +1 -1
  235. package/layout/morph.js +1003 -0
  236. package/layout/multiswitcher.js +11 -3
  237. package/layout/nav-bar.js +2 -3
  238. package/layout/nav-factor/custom-div.js +2 -2
  239. package/layout/new-nav-bar.js +11 -4
  240. package/layout/polygon.js +3 -4
  241. package/layout/prerender-site.js +1 -1
  242. package/layout/prerender.js +1 -1
  243. package/layout/progress.js +1 -1
  244. package/layout/row.js +1 -1
  245. package/layout/scroll-video.js +1 -1
  246. package/layout/side-bar.js +1 -1
  247. package/layout/side-nav-bar.js +1 -1
  248. package/layout/simple-bar.js +1 -1
  249. package/layout/slider-2025.js +1 -1
  250. package/layout/spacer.js +1 -1
  251. package/layout/stack.js +1 -1
  252. package/layout/svg.js +3 -4
  253. package/layout/switcher.js +1 -1
  254. package/layout/table.js +1 -1
  255. package/layout/text-field.js +1 -1
  256. package/layout/text.js +5 -5
  257. package/layout/ulist.js +1 -1
  258. package/layout/video.js +1 -1
  259. package/layout/wrap.js +1 -1
  260. package/layout/zoom-card.js +1 -1
  261. package/lib/card-getter.js +1 -1
  262. package/lib/codegen.js +62 -0
  263. package/lib/data.js +37 -1
  264. package/lib/designer.js +18 -1
  265. package/lib/element-mapper.js +351 -247
  266. package/lib/keyframe-animation.js +1 -1
  267. package/lib/link-getter.js +1 -1
  268. package/lib/morph-node.js +424 -0
  269. package/lib/raster-inspect.js +409 -0
  270. package/lib/raster-ops.js +1980 -81
  271. package/lib/raster-presets.js +329 -0
  272. package/lib/scroll-video.js +1 -1
  273. package/lib/seo.js +28 -1
  274. package/lib/stacker.js +1 -1
  275. package/lib/suggest.js +66 -0
  276. package/lib/theme.js +1 -1
  277. package/lib/transform-anim.js +1 -1
  278. package/lib/transition.js +205 -0
  279. package/package.json +20 -7
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.0.221
2
+ * nodality v1.1.0
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -16,9 +16,14 @@ class /*Multi*/Switcher extends Animator {
16
16
  this.resizeListener = null;
17
17
  }
18
18
 
19
- set({ breakpoints }) {
19
+ //@ id: DOM id for the switcher's own box. The views are swapped in and out, so an id belongs here rather than on a view that may not be mounted.
20
+ //@ area: The switcher's grid-area — the name of a cell declared in the parent's `areas`. It goes here because the switcher's box IS the grid item; the views live inside it, so an area set on a view would never reach the grid.
21
+ set({ breakpoints, id, area }) {
20
22
 
21
23
  this.options = {breakpoints: breakpoints};
24
+ // Applied in render(): the box does not exist until then.
25
+ this._id = id;
26
+ this._area = area;
22
27
 
23
28
  if (!Array.isArray(breakpoints)) {
24
29
  throw new Error("Breakpoints should be an array of objects with 'at' and 'view' properties.");
@@ -64,7 +69,10 @@ str += `{ at: "${this.options.breakpoints[i].at}", view: ${this.options.breakpoi
64
69
  //alert(val)
65
70
  // Create an internal div for switching content
66
71
  this.internalDiv = document.createElement("div");
67
-
72
+ this.res = this.internalDiv;
73
+ if (this._id) this.internalDiv.setAttribute("id", this._id);
74
+ if (this._area) this.internalDiv.style.gridArea = this._area;
75
+
68
76
  // Apply the initial view
69
77
  this.applyView();
70
78
 
package/layout/nav-bar.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.0.221
2
+ * nodality v1.1.0
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -319,6 +319,5 @@ adjust(w) {
319
319
  }
320
320
  }
321
321
 
322
- window.NavBar = NavBar;
323
-
322
+ if (typeof window !== "undefined") window.NavBar = NavBar;
324
323
  export { NavBar };
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.0.221
2
+ * nodality v1.1.0
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -60,5 +60,5 @@ class CustomDivRenderer {
60
60
  }
61
61
  }
62
62
 
63
- window.CustomDivRenderer = CustomDivRenderer;
63
+ if (typeof window !== "undefined") window.CustomDivRenderer = CustomDivRenderer;
64
64
  export { CustomDivRenderer };
@@ -1,10 +1,11 @@
1
1
  /*!
2
- * nodality v1.0.221
2
+ * nodality v1.1.0
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
6
6
 
7
7
  import {Animator} from "./animator.js";
8
+ import { toObjectSource } from "../lib/codegen.js";
8
9
  // import {CustomDivRenderer} from "./navFactor/customDiv.js";
9
10
  // CORRECT
10
11
  class CustomDivRenderer {
@@ -80,7 +81,7 @@ class UINavBar extends Animator {
80
81
  // 16:01:09 09/11/24 What????
81
82
  // Convert attributes to .set({...}) format if there are any attributes
82
83
  if (Object.keys(this.attributes).length > 0) {
83
- codeStr += `.setup(${JSON.stringify(this.attributes, null, 2).replace(/"([^"]+)":/g, '$1:')})`;
84
+ codeStr += `.setup(${toObjectSource(this.attributes, 2)})`;
84
85
 
85
86
  } else {
86
87
  codeStr += `.setup({})`;
@@ -95,8 +96,14 @@ class UINavBar extends Animator {
95
96
 
96
97
  codeStr += `\n])`;
97
98
 
98
- return codeStr;
99
-
99
+ // An ARRAY, like every other class's toCode(). Returning a bare
100
+ // string meant a bar could never be a child of a Wrapper at all:
101
+ // Wrapper.add() does `el.toCode().flatMap(...)`, and a string has
102
+ // no flatMap, so building the tree threw. Consumers that push the
103
+ // result and flatten later (designer.js) are unaffected, and a
104
+ // one-element array concatenates to exactly what the string did.
105
+ return [codeStr];
106
+
100
107
  }
101
108
 
102
109
  styled(obj) {
package/layout/polygon.js CHANGED
@@ -1,11 +1,12 @@
1
1
  /*!
2
- * nodality v1.0.221
2
+ * nodality v1.1.0
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
6
6
 
7
7
  import { Animator } from "./animator.js";
8
8
 
9
+ import { toObjectSource } from "../lib/codegen.js";
9
10
  class Polygon extends Animator {
10
11
  constructor(obj = {}) {
11
12
  super();
@@ -32,9 +33,7 @@ class Polygon extends Animator {
32
33
  toCode(){
33
34
  const codeObj = this.options || {};
34
35
  // stringify with indentation
35
- let str = JSON.stringify(codeObj, null, 2);
36
- // remove quotes around keys
37
- str = str.replace(/"([^"]+)":/g, '$1:');
36
+ let str = toObjectSource(codeObj, 2);
38
37
  return `new Polygon().set(${str})`;
39
38
  }
40
39
 
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.0.221
2
+ * nodality v1.1.0
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.0.221
2
+ * nodality v1.1.0
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.0.221
2
+ * nodality v1.1.0
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
package/layout/row.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.0.221
2
+ * nodality v1.1.0
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.0.221
2
+ * nodality v1.1.0
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.0.221
2
+ * nodality v1.1.0
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.0.221
2
+ * nodality v1.1.0
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.0.221
2
+ * nodality v1.1.0
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.0.221
2
+ * nodality v1.1.0
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
package/layout/spacer.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.0.221
2
+ * nodality v1.1.0
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
package/layout/stack.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.0.221
2
+ * nodality v1.1.0
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
package/layout/svg.js CHANGED
@@ -1,11 +1,12 @@
1
1
  /*!
2
- * nodality v1.0.221
2
+ * nodality v1.1.0
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
6
6
 
7
7
  import { Wrapper } from "./container.js";
8
8
 
9
+ import { toObjectSource } from "../lib/codegen.js";
9
10
  /**
10
11
  * Svg — a Nodality primitive for inline SVG icons.
11
12
  *
@@ -99,9 +100,7 @@ class Svg extends Wrapper {
99
100
  const cleanedObj = Object.fromEntries(
100
101
  Object.entries(this.obj).filter(([k, v]) => v !== null)
101
102
  );
102
- const objString = JSON
103
- .stringify(cleanedObj, null, 2)
104
- .replace(/"([^"]+)":/g, "$1:");
103
+ const objString = toObjectSource(cleanedObj, 2);
105
104
  code += `\n${pad} .set(${objString})`;
106
105
  }
107
106
  code += `\n${pad}`;
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.0.221
2
+ * nodality v1.1.0
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
package/layout/table.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.0.221
2
+ * nodality v1.1.0
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.0.221
2
+ * nodality v1.1.0
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
package/layout/text.js CHANGED
@@ -1,11 +1,13 @@
1
1
  /*!
2
- * nodality v1.0.221
2
+ * nodality v1.1.0
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
6
6
 
7
7
  import {Animator} from "./animator.js";
8
8
 
9
+ import { toObjectSource } from "../lib/codegen.js";
10
+ import { keyPattern } from "../lib/codegen.js";
9
11
  // 13:28 07/04/2020 - BEGIN NOTHING GONNA STOP US NOW Lets go!
10
12
 
11
13
  // 22:29:11
@@ -37,9 +39,7 @@ class Text extends Animator {
37
39
  Object.entries(this.options).filter(([key, value]) => value !== null)
38
40
  );
39
41
 
40
- const objString = JSON
41
- .stringify(cleanedObj, null, 4)
42
- .replace(/"([^"]+)":/g, '$1:');
42
+ const objString = toObjectSource(cleanedObj, 4);
43
43
 
44
44
  return [`new Text("${this.text}").set(${objString})`];
45
45
  }
@@ -99,7 +99,7 @@ class Text extends Animator {
99
99
  }
100
100
 
101
101
  removeQuotesFromFirstWord(jsonString) {
102
- const modifiedJSON = jsonString.replace(/"([^"]+)":/g, '$1:');
102
+ const modifiedJSON = jsonString.replace(keyPattern(), "$1:");
103
103
  return modifiedJSON;
104
104
  }
105
105
 
package/layout/ulist.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.0.221
2
+ * nodality v1.1.0
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
package/layout/video.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.0.221
2
+ * nodality v1.1.0
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
package/layout/wrap.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.0.221
2
+ * nodality v1.1.0
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.0.221
2
+ * nodality v1.1.0
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.0.221
2
+ * nodality v1.1.0
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
package/lib/codegen.js ADDED
@@ -0,0 +1,62 @@
1
+ /*!
2
+ * nodality v1.1.0
3
+ * (c) 2026 Filip Vabrousek
4
+ * License: MIT
5
+ */
6
+
7
+ /*!
8
+ * codegen.js — options object -> JavaScript source, for toCode().
9
+ *
10
+ * Every toCode() in the library used to hand-roll the same two steps:
11
+ *
12
+ * JSON.stringify(obj, null, 4).replace(/"([^"]+)":/g, '$1:')
13
+ *
14
+ * The replace unquotes EVERY key. That is correct for `radius` and wrong
15
+ * for any key that is not a bare identifier — and the library emits those
16
+ * now: `vars: { --nod-split: 0.9 }` from the morph expansion, and content
17
+ * slots like `"main.hero.title"`. Neither parses as JavaScript, so the
18
+ * emitted code could not be run, pasted, or ejected. Fourteen copies of
19
+ * the bad spelling had drifted across twelve files, while the correct one
20
+ * (`/"(\w+)"\s*:/g`) already sat in image.js, table.js, button.js and
21
+ * side-nav-bar.js — the same rule, written both ways, in one codebase.
22
+ *
23
+ * This module is the one place that rule lives now. It is pure: no DOM, no
24
+ * imports, safe to load anywhere (see __tests__/unit/import-inert).
25
+ *
26
+ * toObjectSource(obj, 4) // an object -> "{\n radius: \"2px\"\n}"
27
+ * unquoteKeys(jsonString) // already have the JSON? just fix the keys
28
+ * IDENT_KEY // the pattern, for call sites that chain
29
+ * // further replaces onto the same string
30
+ */
31
+
32
+ // A quoted JSON key whose bare form is a valid JS identifier. Anything
33
+ // else — "--nod-split", "main.hero.title", "kebab-case", "0" — is left
34
+ // quoted, because unquoting it would produce a syntax error.
35
+ //
36
+ // Not global-flagged at the source: a /g regex carries mutable lastIndex,
37
+ // and a module-level constant shared by a dozen callers must not. Each
38
+ // consumer gets a fresh copy via keyPattern().
39
+ const IDENT_KEY_SOURCE = '"([A-Za-z_$][A-Za-z0-9_$]*)"\\s*:';
40
+
41
+ /** A fresh global regex matching unquotable keys. */
42
+ function keyPattern() {
43
+ return new RegExp(IDENT_KEY_SOURCE, "g");
44
+ }
45
+
46
+ /** Unquote the identifier-shaped keys of an already-stringified object. */
47
+ function unquoteKeys(jsonString) {
48
+ if (typeof jsonString !== "string") return jsonString;
49
+ return jsonString.replace(keyPattern(), "$1:");
50
+ }
51
+
52
+ /**
53
+ * Serialize an options object as JavaScript source.
54
+ *
55
+ * `indent` matches JSON.stringify's third argument; call sites historically
56
+ * used 2 or 4 and both are kept so emitted code keeps its existing shape.
57
+ */
58
+ function toObjectSource(value, indent = 4) {
59
+ return unquoteKeys(JSON.stringify(value, null, indent));
60
+ }
61
+
62
+ export { toObjectSource, unquoteKeys, keyPattern };
package/lib/data.js CHANGED
@@ -1,9 +1,45 @@
1
1
  /*!
2
- * nodality v1.0.221
2
+ * nodality v1.1.0
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
6
6
 
7
+ /*!
8
+ * nodality/data — runtime/SSG-aware data loader
9
+ *
10
+ * `loadJson(name, opts?)` resolves JSON in whichever environment the
11
+ * page entry is currently executing:
12
+ *
13
+ * • Browser → relative `fetch("./<name>")` from the page's URL.
14
+ * • Node → ESM JSON import from `../<name>` relative to this
15
+ * module (i.e. from the project's `upload/` directory).
16
+ *
17
+ * The two paths differ because under SSG (nodality prerender + jsdom)
18
+ * there is no dev server to fetch from — fetches silently fail and
19
+ * the page ships an empty mount. The ESM import path reads the JSON
20
+ * straight off disk, embedding the data into the prerendered HTML so
21
+ * crawlers see real content.
22
+ *
23
+ * Usage in a page entry:
24
+ *
25
+ * import { loadJson } from "nodality/data";
26
+ * const products = await loadJson("products.json");
27
+ *
28
+ * Conventions:
29
+ * • At runtime the file must live next to the page HTML (so
30
+ * `./products.json` resolves under the deployed origin).
31
+ * • At build time the file must live in `upload/` (the project's
32
+ * `uploadDir`) — which is the same place. Single source of truth.
33
+ *
34
+ * `fallback` is an opt-in escape hatch: pass `{ fallback: [] }` to
35
+ * return the supplied value instead of throwing when the file is
36
+ * missing. Useful for "team.json doesn't exist yet" stub pages.
37
+ *
38
+ * Add `{ quiet: true }` when that missing file is the EXPECTED state, so
39
+ * the build stays silent for a stub and still warns when a file that is
40
+ * supposed to be there fails to load.
41
+ */
42
+
7
43
  const IS_NODE = typeof process !== "undefined" && !!process.versions?.node;
8
44
 
9
45
  // `nodeImport` is a Function-constructor dynamic import that webpack
package/lib/designer.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.0.221
2
+ * nodality v1.1.0
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -10,6 +10,7 @@ ElementMapper
10
10
 
11
11
  // CORE
12
12
  import { ElementMapper } from "../lib/element-mapper.js";
13
+ import { applyMorphNodes } from "../lib/morph-node.js";
13
14
  import { Animator } from "../layout/animator.js";
14
15
  import { Base } from "../layout/base.js";
15
16
  import { Text } from "../layout/text.js";
@@ -429,6 +430,11 @@ new Text("row.").set({
429
430
 
430
431
  add(arr) {
431
432
 
433
+ // Kept for phase T: a morph node resolves `from`/`to` ids against
434
+ // the rendered children BY POSITION, so it needs the descriptor
435
+ // order — components do not all carry their id into the DOM.
436
+ this._elements = Array.isArray(arr) ? arr : [];
437
+
432
438
  this.css = [];
433
439
  this.elCSS = [];
434
440
  this.elHTML = [];
@@ -1388,6 +1394,17 @@ const components = {
1388
1394
  new Function(...Object.keys(components), sub)(...Object.values(components));
1389
1395
  // eval(`${sub}`);
1390
1396
  }
1397
+
1398
+ // Morph nodes run LAST, and they run here rather than in the
1399
+ // mapper because they need rendered geometry: a transition
1400
+ // interpolates a box, and both ends are measured from real
1401
+ // layout. Everything above only had descriptors.
1402
+ try {
1403
+ const host = document.querySelector((obj && obj.mount) || "#mount");
1404
+ this._morphs = applyMorphNodes(host, this._elements, this.protoOptions);
1405
+ } catch (e) {
1406
+ console.warn("[nodality] morph node skipped:", e);
1407
+ }
1391
1408
  }
1392
1409
  }
1393
1410