nodality 1.3.7 → 1.3.9

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 (245) hide show
  1. package/bin/nodality.mjs +1 -1
  2. package/dist/animator.cjs.js +1 -1
  3. package/dist/animator.cjs.js.LICENSE.txt +1 -1
  4. package/dist/animator.esm.js.LICENSE.txt +1 -1
  5. package/dist/audionew.cjs.js +1 -1
  6. package/dist/audionew.cjs.js.LICENSE.txt +1 -1
  7. package/dist/audionew.esm.js.LICENSE.txt +1 -1
  8. package/dist/base.cjs.js +1 -1
  9. package/dist/base.cjs.js.LICENSE.txt +1 -1
  10. package/dist/base.esm.js.LICENSE.txt +1 -1
  11. package/dist/beta-desktop-bar.cjs.js +1 -1
  12. package/dist/beta-desktop-bar.cjs.js.LICENSE.txt +1 -1
  13. package/dist/beta-desktop-bar.esm.js.LICENSE.txt +1 -1
  14. package/dist/beta-mobile-bar.cjs.js +1 -1
  15. package/dist/beta-mobile-bar.cjs.js.LICENSE.txt +1 -1
  16. package/dist/beta-mobile-bar.esm.js.LICENSE.txt +1 -1
  17. package/dist/bundle.umd.js +1 -1
  18. package/dist/bundle.umd.js.LICENSE.txt +1 -1
  19. package/dist/button.cjs.js +1 -1
  20. package/dist/button.cjs.js.LICENSE.txt +1 -1
  21. package/dist/button.esm.js.LICENSE.txt +1 -1
  22. package/dist/card-getter.cjs.js.LICENSE.txt +1 -1
  23. package/dist/card-getter.esm.js.LICENSE.txt +1 -1
  24. package/dist/center.cjs.js +1 -1
  25. package/dist/center.cjs.js.LICENSE.txt +1 -1
  26. package/dist/center.esm.js.LICENSE.txt +1 -1
  27. package/dist/checkbox.cjs.js +1 -1
  28. package/dist/checkbox.cjs.js.LICENSE.txt +1 -1
  29. package/dist/checkbox.esm.js.LICENSE.txt +1 -1
  30. package/dist/code.cjs.js +1 -1
  31. package/dist/code.cjs.js.LICENSE.txt +1 -1
  32. package/dist/code.esm.js.LICENSE.txt +1 -1
  33. package/dist/container.cjs.js +1 -1
  34. package/dist/container.cjs.js.LICENSE.txt +1 -1
  35. package/dist/container.esm.js.LICENSE.txt +1 -1
  36. package/dist/data-list.cjs.js.LICENSE.txt +1 -1
  37. package/dist/data-list.esm.js.LICENSE.txt +1 -1
  38. package/dist/designer.cjs.js +1 -1
  39. package/dist/designer.cjs.js.LICENSE.txt +1 -1
  40. package/dist/designer.esm.js +1 -1
  41. package/dist/designer.esm.js.LICENSE.txt +1 -1
  42. package/dist/element-mapper.cjs.js +1 -1
  43. package/dist/element-mapper.cjs.js.LICENSE.txt +1 -1
  44. package/dist/element-mapper.esm.js +1 -1
  45. package/dist/element-mapper.esm.js.LICENSE.txt +1 -1
  46. package/dist/finalresult.esm.js +2 -2
  47. package/dist/finalresult.esm.js.LICENSE.txt +1 -1
  48. package/dist/flex-card.cjs.js +1 -1
  49. package/dist/flex-card.cjs.js.LICENSE.txt +1 -1
  50. package/dist/flex-card.esm.js.LICENSE.txt +1 -1
  51. package/dist/flex-grid.cjs.js +1 -1
  52. package/dist/flex-grid.cjs.js.LICENSE.txt +1 -1
  53. package/dist/flex-grid.esm.js.LICENSE.txt +1 -1
  54. package/dist/flex-row.cjs.js +1 -1
  55. package/dist/flex-row.cjs.js.LICENSE.txt +1 -1
  56. package/dist/flex-row.esm.js.LICENSE.txt +1 -1
  57. package/dist/floating-input.cjs.js +1 -1
  58. package/dist/floating-input.cjs.js.LICENSE.txt +1 -1
  59. package/dist/floating-input.esm.js.LICENSE.txt +1 -1
  60. package/dist/free.cjs.js +1 -1
  61. package/dist/free.cjs.js.LICENSE.txt +1 -1
  62. package/dist/free.esm.js.LICENSE.txt +1 -1
  63. package/dist/horizontal-scroller.cjs.js.LICENSE.txt +1 -1
  64. package/dist/horizontal-scroller.esm.js.LICENSE.txt +1 -1
  65. package/dist/image-picker.cjs.js +1 -1
  66. package/dist/image-picker.cjs.js.LICENSE.txt +1 -1
  67. package/dist/image-picker.esm.js.LICENSE.txt +1 -1
  68. package/dist/image.cjs.js +1 -1
  69. package/dist/image.cjs.js.LICENSE.txt +1 -1
  70. package/dist/image.esm.js.LICENSE.txt +1 -1
  71. package/dist/index.cjs.js +1 -1
  72. package/dist/index.cjs.js.LICENSE.txt +1 -1
  73. package/dist/index.d.ts +17 -2
  74. package/dist/index.esm.js +2 -2
  75. package/dist/index.esm.js.LICENSE.txt +1 -1
  76. package/dist/keyframe-animation.cjs.js.LICENSE.txt +1 -1
  77. package/dist/keyframe-animation.esm.js.LICENSE.txt +1 -1
  78. package/dist/link-getter.cjs.js +1 -1
  79. package/dist/link-getter.cjs.js.LICENSE.txt +1 -1
  80. package/dist/link-getter.esm.js.LICENSE.txt +1 -1
  81. package/dist/link.cjs.js +1 -1
  82. package/dist/link.cjs.js.LICENSE.txt +1 -1
  83. package/dist/link.esm.js.LICENSE.txt +1 -1
  84. package/dist/meta-adder.cjs.js +1 -1
  85. package/dist/meta-adder.cjs.js.LICENSE.txt +1 -1
  86. package/dist/meta-adder.esm.js.LICENSE.txt +1 -1
  87. package/dist/modal-2025.cjs.js +1 -1
  88. package/dist/modal-2025.cjs.js.LICENSE.txt +1 -1
  89. package/dist/modal-2025.esm.js.LICENSE.txt +1 -1
  90. package/dist/multiswitcher.cjs.js +1 -1
  91. package/dist/multiswitcher.cjs.js.LICENSE.txt +1 -1
  92. package/dist/multiswitcher.esm.js.LICENSE.txt +1 -1
  93. package/dist/new-nav-bar.cjs.js +1 -1
  94. package/dist/new-nav-bar.cjs.js.LICENSE.txt +1 -1
  95. package/dist/new-nav-bar.esm.js.LICENSE.txt +1 -1
  96. package/dist/picker.cjs.js +1 -1
  97. package/dist/picker.cjs.js.LICENSE.txt +1 -1
  98. package/dist/picker.esm.js.LICENSE.txt +1 -1
  99. package/dist/progress.cjs.js +1 -1
  100. package/dist/progress.cjs.js.LICENSE.txt +1 -1
  101. package/dist/progress.esm.js.LICENSE.txt +1 -1
  102. package/dist/radio.cjs.js.LICENSE.txt +1 -1
  103. package/dist/radio.esm.js.LICENSE.txt +1 -1
  104. package/dist/range.cjs.js.LICENSE.txt +1 -1
  105. package/dist/range.esm.js.LICENSE.txt +1 -1
  106. package/dist/scroll-video.cjs.js.LICENSE.txt +1 -1
  107. package/dist/scroll-video.esm.js.LICENSE.txt +1 -1
  108. package/dist/side-bar.cjs.js +1 -1
  109. package/dist/side-bar.cjs.js.LICENSE.txt +1 -1
  110. package/dist/side-bar.esm.js.LICENSE.txt +1 -1
  111. package/dist/side-nav-bar.cjs.js +1 -1
  112. package/dist/side-nav-bar.cjs.js.LICENSE.txt +1 -1
  113. package/dist/side-nav-bar.esm.js.LICENSE.txt +1 -1
  114. package/dist/simple-bar.cjs.js +1 -1
  115. package/dist/simple-bar.cjs.js.LICENSE.txt +1 -1
  116. package/dist/simple-bar.esm.js.LICENSE.txt +1 -1
  117. package/dist/slider-2025.cjs.js +1 -1
  118. package/dist/slider-2025.cjs.js.LICENSE.txt +1 -1
  119. package/dist/slider-2025.esm.js.LICENSE.txt +1 -1
  120. package/dist/spacer.cjs.js +1 -1
  121. package/dist/spacer.cjs.js.LICENSE.txt +1 -1
  122. package/dist/spacer.esm.js.LICENSE.txt +1 -1
  123. package/dist/stack.cjs.js +1 -1
  124. package/dist/stack.cjs.js.LICENSE.txt +1 -1
  125. package/dist/stack.esm.js.LICENSE.txt +1 -1
  126. package/dist/stacker.cjs.js.LICENSE.txt +1 -1
  127. package/dist/stacker.esm.js.LICENSE.txt +1 -1
  128. package/dist/table.cjs.js +1 -1
  129. package/dist/table.cjs.js.LICENSE.txt +1 -1
  130. package/dist/table.esm.js.LICENSE.txt +1 -1
  131. package/dist/text-field.cjs.js +1 -1
  132. package/dist/text-field.cjs.js.LICENSE.txt +1 -1
  133. package/dist/text-field.esm.js.LICENSE.txt +1 -1
  134. package/dist/text.cjs.js +1 -1
  135. package/dist/text.cjs.js.LICENSE.txt +1 -1
  136. package/dist/text.esm.js.LICENSE.txt +1 -1
  137. package/dist/theme.cjs.js.LICENSE.txt +1 -1
  138. package/dist/theme.esm.js.LICENSE.txt +1 -1
  139. package/dist/transform-anim.cjs.js.LICENSE.txt +1 -1
  140. package/dist/transform-anim.esm.js.LICENSE.txt +1 -1
  141. package/dist/ulist.cjs.js +1 -1
  142. package/dist/ulist.cjs.js.LICENSE.txt +1 -1
  143. package/dist/ulist.esm.js.LICENSE.txt +1 -1
  144. package/dist/video.cjs.js +1 -1
  145. package/dist/video.cjs.js.LICENSE.txt +1 -1
  146. package/dist/video.esm.js +1 -1
  147. package/dist/video.esm.js.LICENSE.txt +1 -1
  148. package/dist/wrap.cjs.js +1 -1
  149. package/dist/wrap.cjs.js.LICENSE.txt +1 -1
  150. package/dist/wrap.esm.js.LICENSE.txt +1 -1
  151. package/dist/zoom-card.cjs.js +1 -1
  152. package/dist/zoom-card.cjs.js.LICENSE.txt +1 -1
  153. package/dist/zoom-card.esm.js.LICENSE.txt +1 -1
  154. package/layout/animator.js +1 -1
  155. package/layout/audio.js +1 -1
  156. package/layout/audionew.js +1 -1
  157. package/layout/base.js +1 -1
  158. package/layout/beta-desktop-bar.js +1 -1
  159. package/layout/beta-mobile-bar.js +1 -1
  160. package/layout/button.js +1 -1
  161. package/layout/center.js +1 -1
  162. package/layout/checkbox.js +1 -1
  163. package/layout/circle.js +1 -1
  164. package/layout/code.js +1 -1
  165. package/layout/container.js +1 -1
  166. package/layout/dropdown-2025.js +1 -1
  167. package/layout/flex-card.js +1 -1
  168. package/layout/flex-grid.js +1 -1
  169. package/layout/flex-row.js +1 -1
  170. package/layout/form-components/custom.js +1 -1
  171. package/layout/form-components/data-list.js +1 -1
  172. package/layout/form-components/floating-input.js +1 -1
  173. package/layout/form-components/form-all.js +1 -1
  174. package/layout/form-components/form.js +1 -1
  175. package/layout/form-components/image-picker.js +1 -1
  176. package/layout/form-components/picker.js +1 -1
  177. package/layout/form-components/radio.js +1 -1
  178. package/layout/form-components/radiogroup.js +1 -1
  179. package/layout/form-components/range.js +1 -1
  180. package/layout/free.js +1 -1
  181. package/layout/grid-overlay.js +296 -0
  182. package/layout/grid-switcher.js +1 -1
  183. package/layout/grid.js +1 -1
  184. package/layout/horizontal-scroller.js +1 -1
  185. package/layout/image.js +1 -1
  186. package/layout/index.js +5 -1
  187. package/layout/link.js +1 -1
  188. package/layout/list.js +1 -1
  189. package/layout/meta-adder.js +1 -1
  190. package/layout/modal-2025.js +1 -1
  191. package/layout/morph.js +1 -1
  192. package/layout/multiswitcher.js +1 -1
  193. package/layout/nav-bar.js +1 -1
  194. package/layout/nav-factor/custom-div.js +1 -1
  195. package/layout/new-nav-bar.js +1 -1
  196. package/layout/polygon.js +1 -1
  197. package/layout/prerender-site.js +1 -1
  198. package/layout/prerender.js +1 -1
  199. package/layout/progress.js +1 -1
  200. package/layout/row.js +1 -1
  201. package/layout/scroll-video.js +1 -1
  202. package/layout/side-bar.js +1 -1
  203. package/layout/side-nav-bar.js +1 -1
  204. package/layout/simple-bar.js +1 -1
  205. package/layout/slider-2025.js +1 -1
  206. package/layout/spacer.js +1 -1
  207. package/layout/stack.js +1 -1
  208. package/layout/svg.js +1 -1
  209. package/layout/switcher.js +1 -1
  210. package/layout/table.js +1 -1
  211. package/layout/text-field.js +1 -1
  212. package/layout/text.js +1 -1
  213. package/layout/ulist.js +1 -1
  214. package/layout/video.js +203 -38
  215. package/layout/wrap.js +1 -1
  216. package/layout/zoom-card.js +1 -1
  217. package/lib/agent-surface.js +1 -1
  218. package/lib/card-getter.js +1 -1
  219. package/lib/check-page.js +1 -1
  220. package/lib/codegen.js +1 -1
  221. package/lib/data.js +1 -1
  222. package/lib/designer.js +4 -2
  223. package/lib/element-mapper.js +36 -3
  224. package/lib/element-params.generated.js +2 -2
  225. package/lib/grid-geometry.js +137 -0
  226. package/lib/keyframe-animation.js +1 -1
  227. package/lib/link-getter.js +1 -1
  228. package/lib/morph-node.js +1 -1
  229. package/lib/normalize-spec.js +1 -1
  230. package/lib/parse-html.js +1 -1
  231. package/lib/raster-inspect.js +1 -1
  232. package/lib/raster-ops.js +42 -3
  233. package/lib/raster-presets.js +1 -1
  234. package/lib/resolve-refs.js +1 -1
  235. package/lib/scroll-video.js +1 -1
  236. package/lib/seo.js +1 -1
  237. package/lib/stacker.js +1 -1
  238. package/lib/suggest.js +1 -1
  239. package/lib/theme.js +1 -1
  240. package/lib/transform-anim.js +1 -1
  241. package/lib/transition.js +1 -1
  242. package/lib/validate-nodes.js +1 -1
  243. package/lib/webmcp-adapter.js +1 -1
  244. package/package.json +1 -1
  245. package/schema.json +164 -5
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.3.6
2
+ * nodality v1.3.8
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.3.6
2
+ * nodality v1.3.8
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.3.7
2
+ * nodality v1.3.9
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
package/layout/audio.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.3.7
2
+ * nodality v1.3.9
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.3.7
2
+ * nodality v1.3.9
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
package/layout/base.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.3.7
2
+ * nodality v1.3.9
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.3.7
2
+ * nodality v1.3.9
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.3.7
2
+ * nodality v1.3.9
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
package/layout/button.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.3.7
2
+ * nodality v1.3.9
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
package/layout/center.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.3.7
2
+ * nodality v1.3.9
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.3.7
2
+ * nodality v1.3.9
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
package/layout/circle.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.3.7
2
+ * nodality v1.3.9
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
package/layout/code.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.3.7
2
+ * nodality v1.3.9
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.3.7
2
+ * nodality v1.3.9
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.3.7
2
+ * nodality v1.3.9
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.3.7
2
+ * nodality v1.3.9
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.3.7
2
+ * nodality v1.3.9
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.3.7
2
+ * nodality v1.3.9
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.3.7
2
+ * nodality v1.3.9
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.3.7
2
+ * nodality v1.3.9
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.3.7
2
+ * nodality v1.3.9
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.3.7
2
+ * nodality v1.3.9
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.3.7
2
+ * nodality v1.3.9
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.3.7
2
+ * nodality v1.3.9
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.3.7
2
+ * nodality v1.3.9
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.3.7
2
+ * nodality v1.3.9
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.3.7
2
+ * nodality v1.3.9
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.3.7
2
+ * nodality v1.3.9
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
package/layout/free.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.3.7
2
+ * nodality v1.3.9
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -0,0 +1,296 @@
1
+ /*!
2
+ * nodality v1.3.9
3
+ * (c) 2026 Filip Vabrousek
4
+ * License: MIT
5
+ */
6
+
7
+ import { Animator } from "./animator.js";
8
+ import { toObjectSource } from "../lib/codegen.js";
9
+ import { gridGeometry, resolveGridOptions, readoutPosition } from "../lib/grid-geometry.js";
10
+
11
+ // GridOverlay — a blueprint grid drawn over the page: lines, registration
12
+ // marks at the intersections, and small uppercase readouts beside chosen
13
+ // intersections.
14
+ //
15
+ // new GridOverlay().set({
16
+ // columns: 4, rows: 2, inset: 16, color: "#fff",
17
+ // readouts: [{ id: "angle", col: 1, row: 1, text: "horná časť · 412 mm" }],
18
+ // mobile: { columns: 1, rows: 4 },
19
+ // }).render("#mount");
20
+ //
21
+ // It is decoration by contract: `aria-hidden`, `pointer-events: none`, and
22
+ // nothing in it is focusable. Anything a readout says must also exist as
23
+ // real text on the page.
24
+ //
25
+ // Lines use `currentColor`, so `color` recolours the whole grid, and Theme
26
+ // defaults apply when no colour is given.
27
+ //
28
+ // `position: "fixed"` (default) pins the grid to the viewport so it stays
29
+ // while content scrolls under it. `position: "absolute"` fills the nearest
30
+ // positioned ancestor instead — give that ancestor `position: relative`.
31
+ //
32
+ // Geometry comes from lib/grid-geometry.js, which layout components that
33
+ // place content on the same grid should share.
34
+
35
+ const SVG_NS = "http://www.w3.org/2000/svg";
36
+
37
+ const DEFAULTS = {
38
+ columns: 4,
39
+ rows: 2,
40
+ inset: 16,
41
+ lineWidth: 1,
42
+ lineOpacity: 0.35,
43
+ marks: "square", // "square" | "cross" | "none"
44
+ markSize: 8,
45
+ position: "fixed", // "fixed" | "absolute"
46
+ zIndex: 2,
47
+ font: "ui-monospace, SFMono-Regular, Menlo, Consolas, monospace",
48
+ fontSize: 11,
49
+ letterSpacing: "0.04em",
50
+ uppercase: true,
51
+ breakpoint: 768,
52
+ readouts: [],
53
+ };
54
+
55
+ class GridOverlay extends Animator {
56
+ constructor() {
57
+ super();
58
+ this.options = {};
59
+ this.config = null;
60
+ this._readoutEls = new Map();
61
+ this._readoutText = new Map();
62
+ this.setup();
63
+ }
64
+
65
+ setup() {
66
+ const host = document.createElement("div");
67
+ host.setAttribute("aria-hidden", "true");
68
+ host.setAttribute("data-nodality", "grid-overlay");
69
+ host.style.pointerEvents = "none";
70
+ host.style.top = "0";
71
+ host.style.right = "0";
72
+ host.style.bottom = "0";
73
+ host.style.left = "0";
74
+ host.style.overflow = "hidden";
75
+
76
+ const svg = document.createElementNS(SVG_NS, "svg");
77
+ svg.setAttribute("width", "100%");
78
+ svg.setAttribute("height", "100%");
79
+ svg.setAttribute("focusable", "false");
80
+ svg.style.display = "block";
81
+ host.appendChild(svg);
82
+
83
+ this.res = host;
84
+ this.svg = svg;
85
+ return this;
86
+ }
87
+
88
+ set(obj = {}) {
89
+ this.options = obj;
90
+
91
+ // Every option is read as a literal `obj.name`: the schema generator
92
+ // discovers a type's parameters from exactly these reads, so a spread
93
+ // or a destructure here would hide them from `get_schema` and make the
94
+ // validator reject valid specs.
95
+ this.config = {
96
+ //@ gridOverlay.columns: Columns, counted as cells (N cells draw N+1 lines). 0 draws no vertical lines. Default 4. Named `columns`, not `cols`: the library's shared `cols` means grid-template-columns verbatim.
97
+ columns: obj.columns ?? DEFAULTS.columns,
98
+ //@ gridOverlay.rows: Rows across the overlay's height, counted as cells. 0 draws no horizontal lines. Default 2.
99
+ rows: obj.rows ?? DEFAULTS.rows,
100
+ //@ gridOverlay.inset: Distance of the outermost lines from the edge in px. A number, or {x, y}. Default 16.
101
+ inset: obj.inset ?? DEFAULTS.inset,
102
+ //@ gridOverlay.color: Colour of lines, marks and readouts (drawn with currentColor). Falls back to the Theme text colour.
103
+ color: obj.color,
104
+ //@ gridOverlay.lineWidth: Stroke width of the grid lines in px. Default 1.
105
+ lineWidth: obj.lineWidth ?? DEFAULTS.lineWidth,
106
+ //@ gridOverlay.lineOpacity: Opacity of the lines only; marks and readouts stay opaque. 0–1, default 0.35.
107
+ lineOpacity: obj.lineOpacity ?? DEFAULTS.lineOpacity,
108
+ //@ gridOverlay.marks: Registration mark at each intersection: "square" (default), "cross" or "none".
109
+ marks: obj.marks ?? DEFAULTS.marks,
110
+ //@ gridOverlay.markSize: Size of each registration mark in px. Default 8.
111
+ markSize: obj.markSize ?? DEFAULTS.markSize,
112
+ //@ gridOverlay.position: "fixed" (default) pins the grid to the viewport; "absolute" fills the nearest positioned ancestor.
113
+ position: obj.position ?? DEFAULTS.position,
114
+ //@ gridOverlay.zIndex: Stacking order of the overlay. Default 2 — keep navigation above it.
115
+ zIndex: obj.zIndex ?? DEFAULTS.zIndex,
116
+ //@ gridOverlay.font: Font family of the readouts. Default a monospace stack.
117
+ font: obj.font ?? DEFAULTS.font,
118
+ //@ gridOverlay.fontSize: Readout font size in px. Default 11.
119
+ fontSize: obj.fontSize ?? DEFAULTS.fontSize,
120
+ //@ gridOverlay.letterSpacing: Readout letter spacing, any CSS length. Default "0.04em".
121
+ letterSpacing: obj.letterSpacing ?? DEFAULTS.letterSpacing,
122
+ //@ gridOverlay.uppercase: Uppercase the readout text. Default true.
123
+ uppercase: obj.uppercase ?? DEFAULTS.uppercase,
124
+ //@ gridOverlay.breakpoint: Viewport width in px below which `mobile` applies. Default 768.
125
+ breakpoint: obj.breakpoint ?? DEFAULTS.breakpoint,
126
+ //@ gridOverlay.mobile: Options that replace their desktop values below `breakpoint`, e.g. {columns: 1, rows: 4}.
127
+ mobile: obj.mobile,
128
+ //@ gridOverlay.readouts: Labels beside intersections: [{id, col, row, text, anchor}]. col/row index lines from 0; anchor "br" (default), "bl", "tr" or "tl", flipped automatically when the label would fall outside. Decorative — say the same thing in real page text.
129
+ readouts: obj.readouts ?? DEFAULTS.readouts,
130
+ };
131
+
132
+ const c = this.config;
133
+ this.res.style.position = c.position === "absolute" ? "absolute" : "fixed";
134
+ this.res.style.zIndex = String(c.zIndex);
135
+ obj.color && (this.res.style.color = obj.color);
136
+ obj.id && this.res.setAttribute("id", obj.id);
137
+
138
+ this._watchSize();
139
+ this.draw();
140
+
141
+ //@ gridOverlay.raster: Raster op nodes for the overlay, e.g. an offset driven by hover to bend the lines near the cursor.
142
+ obj.raster && this.rasterize(obj.raster);
143
+ return this;
144
+ }
145
+
146
+ // Change one readout's text without rebuilding the grid — the path for
147
+ // live values such as a rotation angle.
148
+ readout(id, text) {
149
+ this._readoutText.set(id, text);
150
+ const el = this._readoutEls.get(id);
151
+ if (el) el.textContent = this._format(text);
152
+ return this;
153
+ }
154
+
155
+ // The geometry currently drawn, for callers that align content to it.
156
+ geometry() {
157
+ return this._geometry || null;
158
+ }
159
+
160
+ draw() {
161
+ if (!this.config) return this;
162
+ const { width, height } = this._measure();
163
+ const c = resolveGridOptions(this.config, this._viewportWidth());
164
+ const g = gridGeometry({
165
+ width, height,
166
+ columns: c.columns, rows: c.rows,
167
+ inset: c.inset, lineWidth: c.lineWidth,
168
+ });
169
+ this._geometry = g;
170
+
171
+ const svg = this.svg;
172
+ while (svg.firstChild) svg.removeChild(svg.firstChild);
173
+ this._readoutEls.clear();
174
+ if (!width || !height) return this;
175
+
176
+ svg.setAttribute("viewBox", `0 0 ${width} ${height}`);
177
+
178
+ // Lines run edge to edge; the inset only decides where they sit.
179
+ const lines = this._node("g", {
180
+ stroke: "currentColor",
181
+ "stroke-width": c.lineWidth,
182
+ "stroke-opacity": c.lineOpacity,
183
+ "shape-rendering": "crispEdges",
184
+ });
185
+ for (const x of g.x) lines.appendChild(this._node("line", { x1: x, y1: 0, x2: x, y2: height }));
186
+ for (const y of g.y) lines.appendChild(this._node("line", { x1: 0, y1: y, x2: width, y2: y }));
187
+ svg.appendChild(lines);
188
+
189
+ const s = Number(c.markSize) || 0;
190
+ if (s > 0 && c.marks === "square") {
191
+ const marks = this._node("g", { fill: "currentColor", "shape-rendering": "crispEdges" });
192
+ for (const p of g.intersections) {
193
+ marks.appendChild(this._node("rect", { x: p.x - s / 2, y: p.y - s / 2, width: s, height: s }));
194
+ }
195
+ svg.appendChild(marks);
196
+ } else if (s > 0 && c.marks === "cross") {
197
+ const d = g.intersections
198
+ .map((p) => `M${p.x - s / 2} ${p.y}H${p.x + s / 2}M${p.x} ${p.y - s / 2}V${p.y + s / 2}`)
199
+ .join("");
200
+ if (d) {
201
+ svg.appendChild(this._node("path", {
202
+ d, fill: "none", stroke: "currentColor",
203
+ "stroke-width": c.lineWidth, "shape-rendering": "crispEdges",
204
+ }));
205
+ }
206
+ }
207
+
208
+ const readouts = Array.isArray(c.readouts) ? c.readouts : [];
209
+ if (readouts.length) {
210
+ const group = this._node("g", {
211
+ fill: "currentColor",
212
+ "font-family": c.font,
213
+ "font-size": c.fontSize,
214
+ "letter-spacing": c.letterSpacing,
215
+ });
216
+ const gap = s / 2 + 6;
217
+ readouts.forEach((r, i) => {
218
+ if (!r) return;
219
+ const point = g.intersections.find((p) => p.col === r.col && p.row === r.row);
220
+ if (!point) return;
221
+ const pos = readoutPosition(point, r.anchor, gap, { width, height });
222
+ const id = r.id != null ? String(r.id) : `readout-${i}`;
223
+ const text = this._node("text", {
224
+ x: pos.x, y: pos.y,
225
+ "text-anchor": pos.textAnchor,
226
+ "dominant-baseline": pos.baseline,
227
+ "data-readout": id,
228
+ });
229
+ text.textContent = this._format(this._readoutText.has(id) ? this._readoutText.get(id) : r.text);
230
+ group.appendChild(text);
231
+ this._readoutEls.set(id, text);
232
+ });
233
+ svg.appendChild(group);
234
+ }
235
+ return this;
236
+ }
237
+
238
+ _format(text) {
239
+ const s = text == null ? "" : String(text);
240
+ return this.config && this.config.uppercase === false ? s : s.toUpperCase();
241
+ }
242
+
243
+ _node(tag, attrs) {
244
+ const el = document.createElementNS(SVG_NS, tag);
245
+ for (const k in attrs) el.setAttribute(k, String(attrs[k]));
246
+ return el;
247
+ }
248
+
249
+ _viewportWidth() {
250
+ return typeof window !== "undefined" && window.innerWidth ? window.innerWidth : Infinity;
251
+ }
252
+
253
+ // The host's own box once laid out; the viewport before that. Before
254
+ // render() the element has no box, and under jsdom it never does.
255
+ _measure() {
256
+ const hasWindow = typeof window !== "undefined";
257
+ const width = this.res.clientWidth || (hasWindow ? window.innerWidth : 0) || 0;
258
+ const height = this.res.clientHeight || (hasWindow ? window.innerHeight : 0) || 0;
259
+ return { width, height };
260
+ }
261
+
262
+ _watchSize() {
263
+ if (this._watching || typeof window === "undefined") return;
264
+ this._watching = true;
265
+ if (typeof window.ResizeObserver === "function") {
266
+ const ro = new window.ResizeObserver(() => this.draw());
267
+ ro.observe(this.res);
268
+ this._track(() => ro.disconnect());
269
+ } else {
270
+ this._on(window, "resize", () => this.draw());
271
+ }
272
+ }
273
+
274
+ toCode() {
275
+ if (this.excludeFromCodeTrue) return [""];
276
+ const cleaned = Object.fromEntries(
277
+ Object.entries(this.options || {}).filter(([, v]) => v != null)
278
+ );
279
+ return [`new GridOverlay().set(${toObjectSource(cleaned, 4)})`];
280
+ }
281
+
282
+ excludeFromCode() { this.excludeFromCodeTrue = true; return this; }
283
+
284
+ render(selector) {
285
+ if (selector) {
286
+ const parent = document.querySelector(selector);
287
+ if (parent) {
288
+ parent.appendChild(this.res);
289
+ this.draw();
290
+ }
291
+ }
292
+ return this.res;
293
+ }
294
+ }
295
+
296
+ export { GridOverlay };
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.3.7
2
+ * nodality v1.3.9
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
package/layout/grid.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.3.7
2
+ * nodality v1.3.9
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.3.7
2
+ * nodality v1.3.9
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
package/layout/image.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.3.7
2
+ * nodality v1.3.9
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
package/layout/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.3.7
2
+ * nodality v1.3.9
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -69,6 +69,7 @@ import { Theme } from "../lib/theme.js";
69
69
  import { AreaSwitcher } from "../layout/grid-switcher.js";
70
70
  import { Polygon } from "../layout/polygon.js";
71
71
  import { Circle } from "../layout/circle.js";
72
+ import { GridOverlay } from "../layout/grid-overlay.js";
72
73
 
73
74
  // SEO + data helpers — also surface via package.json subpath exports
74
75
  // (`nodality/seo`, `nodality/data`) for Node-side tree-shaking, but we
@@ -140,6 +141,7 @@ if (typeof window !== 'undefined') {
140
141
  window.Slider = Slider;
141
142
  window.Polygon = Polygon;
142
143
  window.Circle = Circle;
144
+ window.GridOverlay = GridOverlay;
143
145
  window.FloatingInput = FloatingInput;
144
146
  window.Form = Form;
145
147
  }
@@ -200,6 +202,7 @@ if (typeof global !== 'undefined') {
200
202
  global.Slider = Slider;
201
203
  global.Polygon = Polygon;
202
204
  global.Circle = Circle;
205
+ global.GridOverlay = GridOverlay;
203
206
  global.FloatingInput = FloatingInput;
204
207
  global.Form = Form;
205
208
  }
@@ -260,6 +263,7 @@ export {
260
263
  Slider,
261
264
  Polygon,
262
265
  Circle,
266
+ GridOverlay,
263
267
  FloatingInput,
264
268
  Form,
265
269
  // SEO + data helpers — see explanation above the imports block.
package/layout/link.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.3.7
2
+ * nodality v1.3.9
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
package/layout/list.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.3.7
2
+ * nodality v1.3.9
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.3.7
2
+ * nodality v1.3.9
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.3.7
2
+ * nodality v1.3.9
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
package/layout/morph.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.3.7
2
+ * nodality v1.3.9
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.3.7
2
+ * nodality v1.3.9
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
package/layout/nav-bar.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.3.7
2
+ * nodality v1.3.9
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.3.7
2
+ * nodality v1.3.9
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */