nodality 1.0.220 → 1.0.224

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 +48 -2
  200. package/layout/audio.js +1 -1
  201. package/layout/audionew.js +1 -1
  202. package/layout/base.js +8 -3
  203. package/layout/beta-desktop-bar.js +1 -1
  204. package/layout/beta-mobile-bar.js +3 -2
  205. package/layout/button.js +3 -11
  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 +4 -8
  211. package/layout/dropdown-2025.js +1 -1
  212. package/layout/flex-card.js +1 -16
  213. package/layout/flex-grid.js +3 -6
  214. package/layout/flex-row.js +7 -12
  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 +16 -7
  227. package/layout/grid.js +7 -2
  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 +6 -25
  232. package/layout/list.js +14 -6
  233. package/layout/meta-adder.js +8 -3
  234. package/layout/modal-2025.js +7 -2
  235. package/layout/morph.js +1003 -0
  236. package/layout/multiswitcher.js +11 -3
  237. package/layout/nav-bar.js +50 -46
  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 +7 -2
  244. package/layout/row.js +7 -2
  245. package/layout/scroll-video.js +7 -2
  246. package/layout/side-bar.js +15 -10
  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 +7 -2
  251. package/layout/stack.js +7 -2
  252. package/layout/svg.js +3 -4
  253. package/layout/switcher.js +7 -2
  254. package/layout/table.js +1 -1
  255. package/layout/text-field.js +3 -13
  256. package/layout/text.js +5 -15
  257. package/layout/ulist.js +1 -1
  258. package/layout/video.js +1 -1
  259. package/layout/wrap.js +7 -2
  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 +1902 -80
  271. package/lib/raster-presets.js +314 -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
package/layout/text.js CHANGED
@@ -1,11 +1,13 @@
1
1
  /*!
2
- * nodality v1.0.220
2
+ * nodality v1.0.224
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,20 +39,12 @@ 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
  }
46
46
 
47
- toCSS(){
48
- return this.css;
49
- }
50
47
 
51
- toHTMLA(){
52
- return this.html;
53
- }
54
48
 
55
49
  toElCSS(){
56
50
  this.elCSS = this.elCSS.map(el => " " + el);
@@ -92,10 +86,6 @@ class Text extends Animator {
92
86
  }
93
87
 
94
88
 
95
- onTap(e){
96
- this.res.addEventListener("click", e);
97
- return this;
98
- }
99
89
 
100
90
  setClass(name){
101
91
  this.res.setAttribute("class", name);
@@ -109,7 +99,7 @@ class Text extends Animator {
109
99
  }
110
100
 
111
101
  removeQuotesFromFirstWord(jsonString) {
112
- const modifiedJSON = jsonString.replace(/"([^"]+)":/g, '$1:');
102
+ const modifiedJSON = jsonString.replace(keyPattern(), "$1:");
113
103
  return modifiedJSON;
114
104
  }
115
105
 
package/layout/ulist.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.0.220
2
+ * nodality v1.0.224
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.220
2
+ * nodality v1.0.224
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
package/layout/wrap.js CHANGED
@@ -1,11 +1,16 @@
1
1
  /*!
2
- * nodality v1.0.220
2
+ * nodality v1.0.224
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
6
6
 
7
- class Wrap {
7
+ import {Animator} from "./animator.js";
8
+ class Wrap extends Animator {
8
9
  constructor(els){
10
+ super();
11
+ // Converted from a standalone class. Opting out of Theme keeps rendering
12
+ // byte-identical to the pre-conversion behaviour; opt in per component.
13
+ this._noTheme = true;
9
14
  this.code = [];
10
15
 
11
16
  this.setup();
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.0.220
2
+ * nodality v1.0.224
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.0.220
2
+ * nodality v1.0.224
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.0.224
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.220
2
+ * nodality v1.0.224
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.220
2
+ * nodality v1.0.224
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