@hkdigital/lib-core 0.3.11 → 0.3.13

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 (293) hide show
  1. package/README.md +173 -149
  2. package/dist/assets/autospuiten/car-paint-picker.js +41 -41
  3. package/dist/assets/autospuiten/labels.js +7 -7
  4. package/dist/classes/data/IterableTree.js +242 -242
  5. package/dist/classes/data/Selector.js +190 -190
  6. package/dist/classes/data/index.js +2 -2
  7. package/dist/classes/data/typedef.js +9 -9
  8. package/dist/classes/event-emitter/EventEmitter.js +273 -273
  9. package/dist/classes/event-emitter/index.js +2 -2
  10. package/dist/classes/index.js +4 -4
  11. package/dist/classes/promise/HkPromise.js +384 -384
  12. package/dist/classes/promise/index.js +1 -1
  13. package/dist/classes/stores/SubscribersCount.js +107 -107
  14. package/dist/classes/stores/index.js +1 -1
  15. package/dist/classes/streams/LogTransformStream.js +19 -19
  16. package/dist/classes/streams/ServerEventsStore.js +111 -111
  17. package/dist/classes/streams/TimeStampSource.js +26 -26
  18. package/dist/classes/streams/index.js +3 -3
  19. package/dist/classes/svelte/finite-state-machine/FiniteStateMachine.svelte.js +133 -133
  20. package/dist/classes/svelte/finite-state-machine/index.js +1 -1
  21. package/dist/classes/svelte/index.js +1 -11
  22. package/dist/classes/svelte/loading-state-machine/LoadingStateMachine.svelte.js +109 -109
  23. package/dist/classes/svelte/loading-state-machine/constants.js +16 -16
  24. package/dist/classes/svelte/loading-state-machine/index.js +3 -3
  25. package/dist/config/README.md +197 -196
  26. package/dist/config/generators/imagetools.js +189 -189
  27. package/dist/config/generators/vite.js +148 -142
  28. package/dist/config/imagetools.d.ts +72 -72
  29. package/dist/config/vite.js +4 -4
  30. package/dist/constants/bases/index.js +13 -13
  31. package/dist/constants/http/headers.js +6 -6
  32. package/dist/constants/http/index.js +2 -2
  33. package/dist/constants/http/methods.js +14 -14
  34. package/dist/constants/index.js +6 -6
  35. package/dist/constants/mime/application.js +5 -5
  36. package/dist/constants/mime/audio.js +13 -13
  37. package/dist/constants/mime/image.js +3 -3
  38. package/dist/constants/mime/index.js +4 -4
  39. package/dist/constants/mime/text.js +2 -2
  40. package/dist/constants/regexp/README.md +96 -95
  41. package/dist/constants/regexp/index.js +31 -31
  42. package/dist/constants/regexp/inspiratie.js__ +95 -95
  43. package/dist/constants/regexp/text.d.ts +4 -4
  44. package/dist/constants/regexp/text.js +49 -49
  45. package/dist/constants/regexp/url.js +3 -3
  46. package/dist/constants/regexp/user.js +29 -29
  47. package/dist/constants/states/drag.js +6 -6
  48. package/dist/constants/states/drop.js +6 -6
  49. package/dist/constants/states/index.js +4 -4
  50. package/dist/constants/states/input.js +11 -11
  51. package/dist/constants/states/submit.js +4 -4
  52. package/dist/constants/time/index.js +28 -28
  53. package/dist/css/utilities.css +43 -43
  54. package/dist/design/README.md +405 -405
  55. package/dist/design/config/design-config.js +73 -73
  56. package/dist/design/generators/index.js +288 -288
  57. package/dist/design/index.js +96 -96
  58. package/dist/design/plugins/skeleton.js +208 -208
  59. package/dist/design/tailwind-theme-extend.js +158 -158
  60. package/dist/design/themes/README.md +102 -102
  61. package/dist/design/themes/hkdev/components/blocks/text-block.css +34 -34
  62. package/dist/design/themes/hkdev/components/boxes/game-box.css +11 -11
  63. package/dist/design/themes/hkdev/components/buttons/button-icon-steeze.css +22 -22
  64. package/dist/design/themes/hkdev/components/buttons/button-text.css +32 -32
  65. package/dist/design/themes/hkdev/components/buttons/button.css +146 -146
  66. package/dist/design/themes/hkdev/components/buttons/skip-button.css +5 -5
  67. package/dist/design/themes/hkdev/components/drag-drop/draggable.css +73 -73
  68. package/dist/design/themes/hkdev/components/drag-drop/drop-zone.css +58 -58
  69. package/dist/design/themes/hkdev/components/icons/icon-steeze.css +15 -15
  70. package/dist/design/themes/hkdev/components/inputs/text-input.css +102 -102
  71. package/dist/design/themes/hkdev/components/panels/panel.css +25 -25
  72. package/dist/design/themes/hkdev/components/rows/panel-grid-row.css +4 -4
  73. package/dist/design/themes/hkdev/components/rows/panel-row-2.css +5 -5
  74. package/dist/design/themes/hkdev/components.css +29 -29
  75. package/dist/design/themes/hkdev/debug.css +1 -1
  76. package/dist/design/themes/hkdev/global/layout.css +32 -32
  77. package/dist/design/themes/hkdev/global/on-colors.css +32 -32
  78. package/dist/design/themes/hkdev/globals.css +3 -3
  79. package/dist/design/themes/hkdev/responsive.css +12 -12
  80. package/dist/design/themes/hkdev/theme-ext.js +12 -12
  81. package/dist/design/themes/hkdev/theme.css +218 -218
  82. package/dist/design/utils/clamp.js +66 -66
  83. package/dist/design/utils/root-vars.js +102 -102
  84. package/dist/design/utils/scaling.js +228 -228
  85. package/dist/design/utils/states.js +22 -22
  86. package/dist/errors/api.js +9 -9
  87. package/dist/errors/generic.js +20 -20
  88. package/dist/errors/http.js +16 -16
  89. package/dist/errors/index.js +5 -5
  90. package/dist/errors/jwt.js +5 -5
  91. package/dist/errors/promise.js +25 -25
  92. package/dist/logging/README.md +158 -0
  93. package/dist/logging/index.d.ts +3 -1
  94. package/dist/logging/index.js +11 -7
  95. package/dist/logging/internal/adapters/console.js +114 -114
  96. package/dist/logging/internal/adapters/index.js +2 -2
  97. package/dist/logging/internal/adapters/pino.js +160 -142
  98. package/dist/logging/internal/adapters/typedef.js +10 -10
  99. package/dist/logging/internal/{unified-logger/constants.js → constants.js} +22 -22
  100. package/dist/logging/internal/factories/client.d.ts +1 -1
  101. package/dist/logging/internal/factories/client.js +21 -21
  102. package/dist/logging/internal/factories/server.d.ts +1 -1
  103. package/dist/logging/internal/factories/server.js +22 -22
  104. package/dist/logging/internal/factories/universal.d.ts +2 -2
  105. package/dist/logging/internal/factories/universal.js +22 -22
  106. package/dist/logging/internal/{unified-logger → logger}/Logger.d.ts +2 -2
  107. package/dist/logging/internal/{unified-logger → logger}/Logger.js +217 -217
  108. package/dist/logging/internal/logger/index.d.ts +1 -0
  109. package/dist/logging/internal/logger/index.js +1 -0
  110. package/dist/logging/internal/{unified-logger/typedef.d.ts → typedef.d.ts} +2 -1
  111. package/dist/logging/internal/{unified-logger/typedef.js → typedef.js} +21 -17
  112. package/dist/network/README.md +172 -172
  113. package/dist/network/cache/IndexedDbCache.js +1407 -1407
  114. package/dist/network/cache/MemoryResponseCache.js +138 -138
  115. package/dist/network/cache/index.js +5 -5
  116. package/dist/network/cache/typedef.js +41 -41
  117. package/dist/network/cache.js +3 -3
  118. package/dist/network/http/caching.js +261 -261
  119. package/dist/network/http/errors.js +97 -97
  120. package/dist/network/http/headers.js +75 -75
  121. package/dist/network/http/http-request.js +578 -578
  122. package/dist/network/http/index.js +22 -22
  123. package/dist/network/http/json-request.js +224 -224
  124. package/dist/network/http/mocks.js +65 -65
  125. package/dist/network/http/response.js +318 -318
  126. package/dist/network/http/test-data__/content-length-test-hkdigital-small.V4HfZyBQ.avif +0 -0
  127. package/dist/network/http/typedef.js +93 -93
  128. package/dist/network/http/url.js +52 -52
  129. package/dist/network/http.js +5 -5
  130. package/dist/network/loaders/README.md +254 -254
  131. package/dist/network/loaders/audio/AudioLoader.svelte.js +58 -58
  132. package/dist/network/loaders/audio/AudioScene.svelte.js +324 -324
  133. package/dist/network/loaders/audio/mocks.js +35 -35
  134. package/dist/network/loaders/audio.js +1 -1
  135. package/dist/network/loaders/image/ImageLoader.svelte.js +44 -44
  136. package/dist/network/loaders/image/ImageScene.svelte.js +248 -248
  137. package/dist/network/loaders/image/ImageVariantsLoader.svelte.js +150 -150
  138. package/dist/network/loaders/image/index.js +4 -4
  139. package/dist/network/loaders/image/mocks.js +35 -35
  140. package/dist/network/loaders/image/typedef.js +8 -8
  141. package/dist/network/loaders/image/utils/index.js +86 -86
  142. package/dist/network/loaders/image.js +7 -7
  143. package/dist/network/loaders/typedef.js +38 -38
  144. package/dist/network/loaders.js +2 -2
  145. package/dist/network/states/NetworkLoader.svelte.js +338 -338
  146. package/dist/network/states/constants.js +3 -3
  147. package/dist/network/states/index.js +3 -3
  148. package/dist/network/states/mocks.js +30 -30
  149. package/dist/network/states/typedef.js +8 -8
  150. package/dist/network/typedef.js +9 -9
  151. package/dist/services/README.md +200 -0
  152. package/dist/services/index.d.ts +6 -1
  153. package/dist/services/index.js +8 -1
  154. package/dist/services/{internal/service-base → service-base}/ServiceBase.d.ts +2 -2
  155. package/dist/services/{internal/service-base → service-base}/ServiceBase.js +462 -462
  156. package/dist/services/{internal/service-base → service-base}/constants.d.ts +0 -12
  157. package/dist/services/{internal/service-base → service-base}/constants.js +98 -110
  158. package/dist/services/{internal/service-base → service-base}/index.js +3 -3
  159. package/dist/services/{internal/service-base → service-base}/typedef.d.ts +1 -1
  160. package/dist/services/{internal/service-base → service-base}/typedef.js +101 -101
  161. package/dist/services/{internal/service-manager → service-manager}/ServiceManager.d.ts +2 -2
  162. package/dist/services/{internal/service-manager → service-manager}/ServiceManager.js +608 -608
  163. package/dist/services/{internal/service-manager → service-manager}/constants.js +6 -6
  164. package/dist/services/{internal/service-manager → service-manager}/typedef.js +90 -90
  165. package/dist/states/index.js +1 -1
  166. package/dist/states/navigation.svelte.js +55 -55
  167. package/dist/stores/index.js +1 -1
  168. package/dist/stores/theme.js +80 -80
  169. package/dist/typedef/context.js +6 -6
  170. package/dist/typedef/drag.js +25 -25
  171. package/dist/typedef/drop.js +12 -12
  172. package/dist/typedef/index.d.ts +1 -0
  173. package/dist/typedef/index.js +4 -4
  174. package/dist/ui/components/button-group/ButtonGroup.svelte +82 -82
  175. package/dist/ui/components/button-group/typedef.js +10 -10
  176. package/dist/ui/components/compare-left-right/CompareLeftRight.svelte +179 -179
  177. package/dist/ui/components/compare-left-right/index.js +1 -1
  178. package/dist/ui/components/game-box/GameBox.svelte +577 -577
  179. package/dist/ui/components/game-box/gamebox.util.js +83 -83
  180. package/dist/ui/components/hk-app-layout/HkAppLayout.state.svelte.js +25 -25
  181. package/dist/ui/components/hk-app-layout/HkAppLayout.svelte +251 -251
  182. package/dist/ui/components/image-box/ImageBox.svelte +210 -210
  183. package/dist/ui/components/image-box/index.js +5 -5
  184. package/dist/ui/components/image-box/typedef.js +32 -32
  185. package/dist/ui/components/index.js +23 -23
  186. package/dist/ui/components/presenter/ImageSlide.svelte +64 -64
  187. package/dist/ui/components/presenter/Presenter.state.svelte.js +638 -638
  188. package/dist/ui/components/presenter/Presenter.svelte +142 -142
  189. package/dist/ui/components/presenter/constants.js +7 -7
  190. package/dist/ui/components/presenter/index.js +10 -10
  191. package/dist/ui/components/presenter/typedef.js +106 -106
  192. package/dist/ui/components/presenter/util.js +210 -210
  193. package/dist/ui/components/virtual-viewport/VirtualViewport.svelte +196 -196
  194. package/dist/ui/primitives/area/HkArea.svelte +49 -49
  195. package/dist/ui/primitives/area/HkGridArea.svelte +77 -77
  196. package/dist/ui/primitives/area/index.js +2 -2
  197. package/dist/ui/primitives/buttons/button/Button.svelte +82 -82
  198. package/dist/ui/primitives/buttons/button-icon-steeze/SteezeIconButton.svelte +30 -30
  199. package/dist/ui/primitives/buttons/button-text/TextButton.svelte +21 -21
  200. package/dist/ui/primitives/buttons/index.js +3 -3
  201. package/dist/ui/primitives/debug/debug-panel-design-scaling/DebugPanelDesignScaling.svelte +146 -146
  202. package/dist/ui/primitives/debug/index.js +1 -1
  203. package/dist/ui/primitives/drag-drop/DragController.js +44 -44
  204. package/dist/ui/primitives/drag-drop/DragDropContext.svelte +111 -111
  205. package/dist/ui/primitives/drag-drop/Draggable.svelte +519 -519
  206. package/dist/ui/primitives/drag-drop/DropZone.svelte +258 -258
  207. package/dist/ui/primitives/drag-drop/DropZoneArea.svelte +119 -119
  208. package/dist/ui/primitives/drag-drop/DropZoneList.svelte +125 -125
  209. package/dist/ui/primitives/drag-drop/actions.js +26 -26
  210. package/dist/ui/primitives/drag-drop/drag-state.svelte.js +322 -322
  211. package/dist/ui/primitives/drag-drop/index.js +7 -7
  212. package/dist/ui/primitives/drag-drop/util.js +85 -85
  213. package/dist/ui/primitives/hkdev/blocks/TextBlock.svelte +46 -46
  214. package/dist/ui/primitives/hkdev/buttons/CheckButton.svelte +62 -62
  215. package/dist/ui/primitives/icons/HkIcon.svelte +86 -86
  216. package/dist/ui/primitives/icons/HkTabIcon.svelte +116 -116
  217. package/dist/ui/primitives/icons/SteezeIcon.svelte +97 -97
  218. package/dist/ui/primitives/icons/index.js +6 -6
  219. package/dist/ui/primitives/icons/typedef.js +16 -16
  220. package/dist/ui/primitives/index.js +2 -2
  221. package/dist/ui/primitives/inputs/index.js +1 -1
  222. package/dist/ui/primitives/inputs/text-input/TestTextInput.svelte__ +102 -0
  223. package/dist/ui/primitives/inputs/text-input/TextInput.svelte +223 -223
  224. package/dist/ui/primitives/inputs/text-input/TextInput.svelte___ +83 -0
  225. package/dist/ui/primitives/inputs/text-input/assets/IconInvalid.svelte +14 -14
  226. package/dist/ui/primitives/inputs/text-input/assets/IconValid.svelte +12 -12
  227. package/dist/ui/primitives/layout/grid-layers/GridLayers.svelte +63 -63
  228. package/dist/ui/primitives/layout/grid-layers/GridLayers.svelte__heightFrom__ +372 -0
  229. package/dist/ui/primitives/layout/grid-layers/util.js +74 -74
  230. package/dist/ui/primitives/layout/index.js +1 -1
  231. package/dist/ui/primitives/panels/index.js +1 -1
  232. package/dist/ui/primitives/panels/panel/Panel.svelte +43 -43
  233. package/dist/ui/primitives/rows/index.js +3 -3
  234. package/dist/ui/primitives/rows/panel-grid-row/PanelGridRow.svelte +104 -104
  235. package/dist/ui/primitives/rows/panel-row-2/PanelRow2.svelte +40 -40
  236. package/dist/ui/primitives/tab-bar/HkTabBar.state.svelte.js +149 -149
  237. package/dist/ui/primitives/tab-bar/HkTabBar.svelte +74 -74
  238. package/dist/ui/primitives/tab-bar/HkTabBarSelector.state.svelte.js +93 -93
  239. package/dist/ui/primitives/tab-bar/HkTabBarSelector.svelte +49 -49
  240. package/dist/ui/primitives/tab-bar/index.js +17 -17
  241. package/dist/ui/primitives/tab-bar/typedef.js +11 -11
  242. package/dist/util/array/index.js +436 -436
  243. package/dist/util/bases/base58.js +262 -262
  244. package/dist/util/bases/index.js +1 -1
  245. package/dist/util/compare/index.js +247 -247
  246. package/dist/util/css/css-vars.js +83 -83
  247. package/dist/util/css/index.js +1 -1
  248. package/dist/util/env/index.js +9 -9
  249. package/dist/util/exceptions/index.d.ts +4 -3
  250. package/dist/util/exceptions/index.js +26 -23
  251. package/dist/util/expect/arrays.js +47 -47
  252. package/dist/util/expect/index.js +259 -259
  253. package/dist/util/expect/primitives.js +55 -55
  254. package/dist/util/expect/url.js +60 -60
  255. package/dist/util/function/index.js +218 -218
  256. package/dist/util/geo/index.js +26 -26
  257. package/dist/util/index.js +7 -7
  258. package/dist/util/is/index.js +147 -147
  259. package/dist/util/iterate/index.js +204 -204
  260. package/dist/util/object/index.js +1345 -1345
  261. package/dist/util/singleton/index.js +97 -97
  262. package/dist/util/string/array-path.js +75 -75
  263. package/dist/util/string/convert.js +54 -54
  264. package/dist/util/string/fs.js +226 -226
  265. package/dist/util/string/index.js +5 -5
  266. package/dist/util/string/interpolate.js +61 -61
  267. package/dist/util/string/pad.js +10 -10
  268. package/dist/util/svelte/index.js +4 -4
  269. package/dist/util/svelte/loading/loading-tracker.svelte.js +108 -108
  270. package/dist/util/svelte/observe/index.js +49 -49
  271. package/dist/util/svelte/state-context/index.js +117 -117
  272. package/dist/util/svelte/wait/index.js +38 -38
  273. package/dist/util/sveltekit/index.js +1 -1
  274. package/dist/util/sveltekit/route-folders/index.js +101 -101
  275. package/dist/util/time/index.js +328 -328
  276. package/dist/util/unique/index.js +231 -231
  277. package/dist/valibot/README.md +61 -50
  278. package/dist/valibot/index.js +8 -8
  279. package/dist/valibot/parsers/date.js__ +10 -0
  280. package/dist/valibot/parsers/email.d.ts +12 -0
  281. package/dist/valibot/parsers/email.js +34 -0
  282. package/dist/valibot/parsers/url.js +110 -110
  283. package/dist/valibot/parsers/user.js +23 -23
  284. package/dist/valibot/parsers.js +3 -3
  285. package/package.json +131 -131
  286. package/dist/logging/internal/unified-logger/index.d.ts +0 -3
  287. package/dist/logging/internal/unified-logger/index.js +0 -6
  288. package/dist/services/internal/index.d.ts +0 -6
  289. package/dist/services/internal/index.js +0 -8
  290. /package/dist/logging/internal/{unified-logger/constants.d.ts → constants.d.ts} +0 -0
  291. /package/dist/services/{internal/service-base → service-base}/index.d.ts +0 -0
  292. /package/dist/services/{internal/service-manager → service-manager}/constants.d.ts +0 -0
  293. /package/dist/services/{internal/service-manager → service-manager}/typedef.d.ts +0 -0
@@ -1,63 +1,63 @@
1
- <script>
2
- /**
3
- * GridLayers Component
4
- *
5
- * Creates a single-cell grid where all children occupy the same space,
6
- * enabling layered layouts with natural height behavior.
7
- *
8
- * @type {{
9
- * base?: string,
10
- * bg?: string,
11
- * padding?: string,
12
- * margin?: string,
13
- * classes?: string,
14
- * style?: string,
15
- * overflow?: string,
16
- * children: import('svelte').Snippet,
17
- * [attr: string]: any
18
- * }}
19
- */
20
- const {
21
- // Container styles
22
- base = '',
23
- bg = '',
24
- padding = '',
25
- margin = '',
26
- classes = '',
27
- style = '',
28
- overflow = '',
29
-
30
- // Content
31
- children,
32
-
33
- // Attributes
34
- ...attrs
35
- } = $props();
36
-
37
- // Build the inline style
38
- let containerStyle = $derived.by(() => {
39
- const styles = ['grid-template: 1fr / 1fr;'];
40
-
41
- if (style) {
42
- styles.push(style);
43
- }
44
-
45
- return styles.join(' ');
46
- });
47
- </script>
48
-
49
- <div
50
- data-component="grid-layers"
51
- class="grid {base} {bg} {classes} {margin} {padding} {overflow}"
52
- style={containerStyle}
53
- {...attrs}
54
- >
55
- {@render children()}
56
- </div>
57
-
58
- <style>
59
- /* All direct children occupy the same grid area */
60
- div > :global(*) {
61
- grid-area: 1 / 1;
62
- }
63
- </style>
1
+ <script>
2
+ /**
3
+ * GridLayers Component
4
+ *
5
+ * Creates a single-cell grid where all children occupy the same space,
6
+ * enabling layered layouts with natural height behavior.
7
+ *
8
+ * @type {{
9
+ * base?: string,
10
+ * bg?: string,
11
+ * padding?: string,
12
+ * margin?: string,
13
+ * classes?: string,
14
+ * style?: string,
15
+ * overflow?: string,
16
+ * children: import('svelte').Snippet,
17
+ * [attr: string]: any
18
+ * }}
19
+ */
20
+ const {
21
+ // Container styles
22
+ base = '',
23
+ bg = '',
24
+ padding = '',
25
+ margin = '',
26
+ classes = '',
27
+ style = '',
28
+ overflow = '',
29
+
30
+ // Content
31
+ children,
32
+
33
+ // Attributes
34
+ ...attrs
35
+ } = $props();
36
+
37
+ // Build the inline style
38
+ let containerStyle = $derived.by(() => {
39
+ const styles = ['grid-template: 1fr / 1fr;'];
40
+
41
+ if (style) {
42
+ styles.push(style);
43
+ }
44
+
45
+ return styles.join(' ');
46
+ });
47
+ </script>
48
+
49
+ <div
50
+ data-component="grid-layers"
51
+ class="grid {base} {bg} {classes} {margin} {padding} {overflow}"
52
+ style={containerStyle}
53
+ {...attrs}
54
+ >
55
+ {@render children()}
56
+ </div>
57
+
58
+ <style>
59
+ /* All direct children occupy the same grid area */
60
+ div > :global(*) {
61
+ grid-area: 1 / 1;
62
+ }
63
+ </style>
@@ -0,0 +1,372 @@
1
+ <script>
2
+ import { onMount, onDestroy } from 'svelte';
3
+ import { setupLayerObserver, measureTargetLayer } from './util.js';
4
+
5
+ /**
6
+ * # GridLayers Component
7
+ *
8
+ * A Svelte 5 component that creates a layered grid layout where all
9
+ * children occupy the same grid area, allowing for overlapping content with
10
+ * precise positioning control.
11
+ *
12
+ * ## Overview
13
+ *
14
+ * GridLayers uses CSS Grid to stack multiple elements in the same grid cell
15
+ * (1x1 grid), enabling layered layouts without absolute positioning on the
16
+ * children. This approach maintains the natural flow and sizing behavior of
17
+ * grid items while allowing them to overlap.
18
+ *
19
+ * ## Height Control
20
+ *
21
+ * The component offers two methods for controlling height:
22
+ *
23
+ * ### 1. Fixed Height (default)
24
+ *
25
+ * Use the `height` prop with Tailwind classes:
26
+ * ```svelte
27
+ * <GridLayers height="h-[500px]">
28
+ * <!-- content -->
29
+ * </GridLayers>
30
+ * ```
31
+ *
32
+ * ### 2. Dynamic Height
33
+ * Use the `heightFrom` prop to make the container's height match a specific
34
+ * child layer:
35
+ *
36
+ * ```svelte
37
+ * <GridLayers heightFrom="content">
38
+ * <div data-layer="content">
39
+ * <!-- This layer's height determines the container height -->
40
+ * </div>
41
+ * <div data-layer="overlay">
42
+ * <!-- Other layers adapt to the container -->
43
+ * </div>
44
+ * </GridLayers>
45
+ * ```
46
+ *
47
+ * The `heightFrom` value should match a child's `data-layer` attribute.
48
+ * The component will:
49
+ * - Initially render invisibly to measure the target layer
50
+ * - Apply the measured height to the container
51
+ * - Watch for changes and update automatically
52
+ *
53
+ * ## Positioning Layers
54
+ *
55
+ * Each child element can be positioned within the grid cell using Tailwind's
56
+ * alignment utilities:
57
+ *
58
+ * ### justify-self (Horizontal Alignment)
59
+ * - `justify-self-start` - Align to the left
60
+ * - `justify-self-center` - Center horizontally
61
+ * - `justify-self-end` - Align to the right
62
+ * - `justify-self-stretch` - Stretch to full width (default)
63
+ *
64
+ * ### self (Vertical Alignment)
65
+ * - `self-start` - Align to the top
66
+ * - `self-center` - Center vertically
67
+ * - `self-end` - Align to the bottom
68
+ * - `self-stretch` - Stretch to full height (default)
69
+ *
70
+ * ### Combining Positions
71
+ * ```svelte
72
+ * <GridLayers height="h-[400px]">
73
+ * <div class="justify-self-start self-start">Top Left</div>
74
+ * <div class="justify-self-center self-center">Centered</div>
75
+ * <div class="justify-self-end self-end">Bottom Right</div>
76
+ * </GridLayers>
77
+ * ```
78
+ *
79
+ * ### Fine-tuning with Margins
80
+ * For precise positioning adjustments, use margins:
81
+ * ```svelte
82
+ * <div class="justify-self-end self-end mr-4 mb-4">
83
+ * <!-- Positioned at bottom-right with 1rem spacing -->
84
+ * </div>
85
+ * ```
86
+ *
87
+ * ## Technical Implementation
88
+ *
89
+ * ### The Grid Container
90
+ * The inner grid container uses `absolute inset-0` which:
91
+ * - Positions it absolutely within the relative parent
92
+ * - `inset-0` is shorthand for `top: 0, right: 0, bottom: 0, left: 0`
93
+ * - Makes the grid fill the entire parent container
94
+ * - Ensures the grid respects the parent's dimensions (fixed or dynamic)
95
+ *
96
+ * This approach creates a stable positioning context while maintaining the
97
+ * parent's flow in the document.
98
+ *
99
+ * ### Grid Structure
100
+ * All children are assigned to the same grid cell:
101
+ * ```css
102
+ * grid-template-columns: 1fr;
103
+ * grid-template-rows: 1fr;
104
+ * grid-column: 1;
105
+ * grid-row: 1;
106
+ * ```
107
+ *
108
+ * ## Overflow Behavior
109
+ *
110
+ * When a layer's content exceeds the container bounds:
111
+ *
112
+ * ### Default Behavior
113
+ * - Content will overflow and be visible outside the container
114
+ * - This can break layouts or create unwanted scrollbars
115
+ *
116
+ * ### Controlling Overflow
117
+ * Add overflow utilities to the container:
118
+ * ```svelte
119
+ * <!-- Hide overflow -->
120
+ * <GridLayers classes="overflow-hidden">
121
+ *
122
+ * <!-- Scroll if needed -->
123
+ * <GridLayers classes="overflow-auto">
124
+ *
125
+ * <!-- Scroll specific layer -->
126
+ * <GridLayers>
127
+ * <div class="overflow-auto">
128
+ * <!-- Scrollable content -->
129
+ * </div>
130
+ * </GridLayers>
131
+ * ```
132
+ *
133
+ * ### Best Practices for Overflow
134
+ * 1. Use `overflow-hidden` on the container when layers should be clipped
135
+ * 2. Apply `overflow-auto` to specific layers that need scrolling
136
+ * 3. Consider using `max-h-*` classes on content layers
137
+ * 4. Test with different content sizes to ensure proper behavior
138
+ *
139
+ * ## Z-Index Stacking
140
+ *
141
+ * Layers have a base `z-index: 0` and stack in DOM order. Control stacking with:
142
+ * ```svelte
143
+ * <div class="z-10">Top layer</div>
144
+ * <div class="z-0">Base layer</div>
145
+ * <div class="z-20">Topmost layer</div>
146
+ * ```
147
+ *
148
+ * ## Common Patterns
149
+ *
150
+ * ### Header/Content/Footer
151
+ * ```svelte
152
+ * <GridLayers heightFrom="content">
153
+ * <div data-layer="header" class="self-start">
154
+ * <header>Fixed header</header>
155
+ * </div>
156
+ * <div data-layer="content" class="self-center">
157
+ * <main>Dynamic content</main>
158
+ * </div>
159
+ * <div data-layer="footer" class="self-end">
160
+ * <footer>Fixed footer</footer>
161
+ * </div>
162
+ * </GridLayers>
163
+ * ```
164
+ *
165
+ * ### Centered Overlay
166
+ * ```svelte
167
+ * <GridLayers height="h-screen">
168
+ * <div class="z-0">
169
+ * <img src="background.jpg" class="w-full h-full object-cover" />
170
+ * </div>
171
+ * <div class="z-10 justify-self-center self-center">
172
+ * <div class="bg-white p-8 rounded shadow-lg">
173
+ * Centered content over background
174
+ * </div>
175
+ * </div>
176
+ * </GridLayers>
177
+ * ```
178
+ *
179
+ * ### Corner Badges
180
+ * ```svelte
181
+ * <GridLayers height="h-64">
182
+ * <div class="justify-self-end self-start m-4 z-10">
183
+ * <span class="badge">New</span>
184
+ * </div>
185
+ * <div>
186
+ * Main content
187
+ * </div>
188
+ * </GridLayers>
189
+ * ```
190
+ */
191
+
192
+ /**
193
+ * @type {{
194
+ * base?: string,
195
+ * bg?: string,
196
+ * padding?: string,
197
+ * margin?: string,
198
+ * height?: string,
199
+ * classes?: string,
200
+ * style?: string,
201
+ * cellBase?: string,
202
+ * cellBg?: string,
203
+ * cellPadding?: string,
204
+ * cellMargin?: string,
205
+ * cellClasses?: string,
206
+ * cellStyle?: string,
207
+ * heightFrom?: string|null,
208
+ * children: import('svelte').Snippet,
209
+ * cellAttrs?: { [attr: string]: any },
210
+ * [attr: string]: any
211
+ * }}
212
+ */
213
+ const {
214
+ // Style
215
+ base = '',
216
+ bg = '',
217
+ padding = '',
218
+ margin = '',
219
+ height = 'h-full',
220
+ classes = '',
221
+ style = '',
222
+ cellBase = '',
223
+ cellBg = '',
224
+ cellPadding = '',
225
+ cellMargin = '',
226
+ cellClasses = '',
227
+ cellStyle = '',
228
+
229
+ // Behavior
230
+ heightFrom = null,
231
+
232
+ // Props
233
+ cellAttrs = {},
234
+ children,
235
+
236
+ // Attributes
237
+ ...attrs
238
+ } = $props();
239
+
240
+ // Component state
241
+ let gridContent = $state(null);
242
+ let calculatedHeight = $state(0);
243
+ let observer = $state(null);
244
+
245
+ // Start with true if heightFrom is provided
246
+ let isFirstRender = $state(heightFrom !== null);
247
+
248
+ let preCalculatedHeight = $state(0);
249
+
250
+ // Derived container style that updates reactively when dependencies change
251
+ let containerStyle = $derived.by(() => {
252
+ const styles = [];
253
+
254
+ if (style) {
255
+ styles.push(style);
256
+ }
257
+
258
+ if (heightFrom && calculatedHeight > 0) {
259
+ styles.push(`height: ${calculatedHeight}px;`);
260
+ }
261
+
262
+ return styles.join(' ');
263
+ });
264
+
265
+ /**
266
+ * Handler for height changes detected by the observer
267
+ * @param {number} newHeight - The new calculated height
268
+ */
269
+ function handleHeightChange(newHeight) {
270
+ calculatedHeight = newHeight;
271
+ }
272
+
273
+ /**
274
+ * Initialize height measurement and observation
275
+ */
276
+ function initializeHeightTracking() {
277
+ if (!heightFrom || !gridContent) return;
278
+
279
+ // Measure the layer initially
280
+ const { element, height } = measureTargetLayer(gridContent, heightFrom);
281
+
282
+ if (element) {
283
+ calculatedHeight = height;
284
+
285
+ // Setup observer for future changes
286
+ observer = setupLayerObserver(element, handleHeightChange);
287
+ }
288
+ }
289
+
290
+ // Initialize on mount with the two-pass rendering approach
291
+ onMount(() => {
292
+ if (heightFrom) {
293
+ // First render: measure invisibly
294
+ requestAnimationFrame(() => {
295
+ if (gridContent) {
296
+ const { element, height } = measureTargetLayer(gridContent, heightFrom);
297
+
298
+ if (element) {
299
+ preCalculatedHeight = height;
300
+
301
+ // Second render: show with correct height
302
+ requestAnimationFrame(() => {
303
+ calculatedHeight = preCalculatedHeight;
304
+ isFirstRender = false;
305
+
306
+ // Setup observer for future changes
307
+ observer = setupLayerObserver(element, handleHeightChange);
308
+ });
309
+ } else {
310
+ // No target layer found, just show the component
311
+ isFirstRender = false;
312
+ }
313
+ } else {
314
+ // No grid content, just show the component
315
+ isFirstRender = false;
316
+ }
317
+ });
318
+ } else {
319
+ // No heightFrom, no need for measurement
320
+ isFirstRender = false;
321
+ }
322
+ });
323
+
324
+ // Effect to re-setup observer when either the target layer or heightFrom changes
325
+ $effect(() => {
326
+ // Only handle changes after initial setup
327
+ if (!isFirstRender && heightFrom && gridContent && !observer) {
328
+ initializeHeightTracking();
329
+ }
330
+ });
331
+
332
+ // Clean up on destroy
333
+ onDestroy(() => {
334
+ if (observer) {
335
+ observer.disconnect();
336
+ observer = null;
337
+ }
338
+ });
339
+
340
+ </script>
341
+
342
+ <div
343
+ data-component="grid-layers"
344
+ class="relative {isFirstRender ? 'invisible' : ''} {base} {bg} {heightFrom ? '' : height} {classes} {margin} {padding}"
345
+ style={containerStyle}
346
+ {...attrs}
347
+ >
348
+ <div
349
+ data-section="grid"
350
+ bind:this={gridContent}
351
+ class="absolute inset-0 grid {cellBase} {cellBg} {cellPadding} {cellMargin} {cellClasses}"
352
+ style={cellStyle}
353
+ {...cellAttrs}
354
+ >
355
+ {@render children()}
356
+ </div>
357
+ </div>
358
+
359
+ <style>
360
+ /* All children of the layer share the same grid area
361
+ but aren't absolutely positioned */
362
+ [data-section='grid'] {
363
+ grid-template-columns: 1fr;
364
+ grid-template-rows: 1fr;
365
+ }
366
+
367
+ [data-section='grid'] > :global(*) {
368
+ grid-column: 1;
369
+ grid-row: 1;
370
+ z-index: 0; /* Base z-index to allow explicit stacking order */
371
+ }
372
+ </style>
@@ -1,74 +1,74 @@
1
- // lib/primitives/layout/gridLayers.utils.js
2
-
3
- /**
4
- * Sets up a ResizeObserver on the target layer
5
- *
6
- * @param {HTMLElement|null} targetLayer - The layer element to observe
7
- * @param {Function} onHeightChange - Callback when height changes
8
- * @returns {ResizeObserver|null} - The created observer or null
9
- */
10
- export function setupLayerObserver(targetLayer, onHeightChange) {
11
- if (!targetLayer || !window.ResizeObserver) return null;
12
-
13
- // Create new observer
14
- const observer = new ResizeObserver(entries => {
15
- for (const entry of entries) {
16
- if (entry.target === targetLayer) {
17
- // Get the computed style to access margin values
18
- const computedStyle = window.getComputedStyle(targetLayer);
19
- const marginTop = parseInt(computedStyle.marginTop, 10);
20
- const marginBottom = parseInt(computedStyle.marginBottom, 10);
21
-
22
- // Calculate height including border box and margins
23
- let elementHeight = 0;
24
-
25
- if (entry.borderBoxSize) {
26
- const borderBoxSize = Array.isArray(entry.borderBoxSize)
27
- ? entry.borderBoxSize[0]
28
- : entry.borderBoxSize;
29
- elementHeight = borderBoxSize.blockSize;
30
- } else {
31
- // Fallback to getBoundingClientRect
32
- const rect = targetLayer.getBoundingClientRect();
33
- elementHeight = rect.height;
34
- }
35
-
36
- // Add margins to the height
37
- const totalHeight = elementHeight + marginTop + marginBottom;
38
- onHeightChange(totalHeight);
39
- }
40
- }
41
- });
42
-
43
- // Start observing
44
- observer.observe(targetLayer);
45
- return observer;
46
- }
47
-
48
- /**
49
- * Measures the height of the specified layer, including margins
50
- *
51
- * @param {HTMLElement|null} container - The container to search in
52
- * @param {string} layerId - The data-layer attribute value to find
53
- * @returns {{ element: HTMLElement|null, height: number }} The element and its height
54
- */
55
- export function measureTargetLayer(container, layerId) {
56
- if (!layerId || !container) return { element: null, height: 0 };
57
-
58
- const layerElement = container.querySelector(`[data-layer="${layerId}"]`);
59
-
60
- if (!layerElement) return { element: null, height: 0 };
61
-
62
- // Get the computed style to access margin values
63
- const computedStyle = window.getComputedStyle(layerElement);
64
- const marginTop = parseInt(computedStyle.marginTop, 10);
65
- const marginBottom = parseInt(computedStyle.marginBottom, 10);
66
-
67
- // Get the element's border box height
68
- const rect = layerElement.getBoundingClientRect();
69
-
70
- // Calculate total height including margins
71
- const height = rect.height > 0 ? rect.height + marginTop + marginBottom : 0;
72
-
73
- return { element: layerElement, height };
74
- }
1
+ // lib/primitives/layout/gridLayers.utils.js
2
+
3
+ /**
4
+ * Sets up a ResizeObserver on the target layer
5
+ *
6
+ * @param {HTMLElement|null} targetLayer - The layer element to observe
7
+ * @param {Function} onHeightChange - Callback when height changes
8
+ * @returns {ResizeObserver|null} - The created observer or null
9
+ */
10
+ export function setupLayerObserver(targetLayer, onHeightChange) {
11
+ if (!targetLayer || !window.ResizeObserver) return null;
12
+
13
+ // Create new observer
14
+ const observer = new ResizeObserver(entries => {
15
+ for (const entry of entries) {
16
+ if (entry.target === targetLayer) {
17
+ // Get the computed style to access margin values
18
+ const computedStyle = window.getComputedStyle(targetLayer);
19
+ const marginTop = parseInt(computedStyle.marginTop, 10);
20
+ const marginBottom = parseInt(computedStyle.marginBottom, 10);
21
+
22
+ // Calculate height including border box and margins
23
+ let elementHeight = 0;
24
+
25
+ if (entry.borderBoxSize) {
26
+ const borderBoxSize = Array.isArray(entry.borderBoxSize)
27
+ ? entry.borderBoxSize[0]
28
+ : entry.borderBoxSize;
29
+ elementHeight = borderBoxSize.blockSize;
30
+ } else {
31
+ // Fallback to getBoundingClientRect
32
+ const rect = targetLayer.getBoundingClientRect();
33
+ elementHeight = rect.height;
34
+ }
35
+
36
+ // Add margins to the height
37
+ const totalHeight = elementHeight + marginTop + marginBottom;
38
+ onHeightChange(totalHeight);
39
+ }
40
+ }
41
+ });
42
+
43
+ // Start observing
44
+ observer.observe(targetLayer);
45
+ return observer;
46
+ }
47
+
48
+ /**
49
+ * Measures the height of the specified layer, including margins
50
+ *
51
+ * @param {HTMLElement|null} container - The container to search in
52
+ * @param {string} layerId - The data-layer attribute value to find
53
+ * @returns {{ element: HTMLElement|null, height: number }} The element and its height
54
+ */
55
+ export function measureTargetLayer(container, layerId) {
56
+ if (!layerId || !container) return { element: null, height: 0 };
57
+
58
+ const layerElement = container.querySelector(`[data-layer="${layerId}"]`);
59
+
60
+ if (!layerElement) return { element: null, height: 0 };
61
+
62
+ // Get the computed style to access margin values
63
+ const computedStyle = window.getComputedStyle(layerElement);
64
+ const marginTop = parseInt(computedStyle.marginTop, 10);
65
+ const marginBottom = parseInt(computedStyle.marginBottom, 10);
66
+
67
+ // Get the element's border box height
68
+ const rect = layerElement.getBoundingClientRect();
69
+
70
+ // Calculate total height including margins
71
+ const height = rect.height > 0 ? rect.height + marginTop + marginBottom : 0;
72
+
73
+ return { element: layerElement, height };
74
+ }
@@ -1 +1 @@
1
- export { default as GridLayers } from './grid-layers/GridLayers.svelte';
1
+ export { default as GridLayers } from './grid-layers/GridLayers.svelte';
@@ -1 +1 @@
1
- export { default as Panel } from './panel/Panel.svelte';
1
+ export { default as Panel } from './panel/Panel.svelte';