elements-kit 0.0.9 → 0.0.11

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 (313) hide show
  1. package/README.md +3 -4
  2. package/dist/builder/dom.d.mts +1 -1
  3. package/dist/builder/index.d.mts +87 -1
  4. package/dist/builder/index.mjs +1 -1
  5. package/dist/{element-Ddk9YaoE.mjs → element-MXzFk4G2.mjs} +1 -1
  6. package/dist/{index-BtqiEEfc.d.mts → index-Cvdhuy6Y.d.mts} +8 -4
  7. package/dist/index.d.mts +1 -1
  8. package/dist/index.mjs +3 -3
  9. package/dist/{signals/lib → integrations}/react.d.mts +2 -2
  10. package/dist/{signals/lib → integrations}/react.mjs +2 -2
  11. package/dist/jsx-runtime/index.d.mts +2 -2
  12. package/dist/jsx-runtime/index.mjs +3 -3
  13. package/dist/lib-BYJ5jPTG.d.mts +4 -0
  14. package/dist/polyfill-DR5XVnh_.d.mts +9 -0
  15. package/dist/signals/index.d.mts +2 -2
  16. package/dist/signals/index.mjs +2 -2
  17. package/dist/{signals-CLAPw8kk.mjs → signals-DcgXhkU2.mjs} +41 -9
  18. package/dist/slot.d.mts +1 -2
  19. package/dist/{test.BmQO5GaM-CR2qjV1t.mjs → test.BmQO5GaM-ANkhHvbr.mjs} +1 -1
  20. package/dist/utilities/active-element.d.mts +6 -0
  21. package/dist/utilities/active-element.mjs +13 -0
  22. package/dist/utilities/active-element.test.mjs +24 -0
  23. package/dist/{signals/lib → utilities}/debounced.d.mts +3 -3
  24. package/dist/{signals/lib → utilities}/debounced.mjs +7 -6
  25. package/dist/{signals/lib → utilities}/debounced.test.mjs +3 -3
  26. package/dist/{signals/lib → utilities}/element-rect.d.mts +3 -3
  27. package/dist/{signals/lib → utilities}/element-rect.mjs +7 -7
  28. package/dist/{signals/lib → utilities}/element-rect.test.mjs +3 -3
  29. package/dist/utilities/element-scroll.d.mts +16 -0
  30. package/dist/utilities/element-scroll.mjs +52 -0
  31. package/dist/utilities/element-scroll.test.mjs +25 -0
  32. package/dist/utilities/event-driven.d.mts +47 -0
  33. package/dist/utilities/event-driven.mjs +38 -0
  34. package/dist/utilities/event-listener.d.mts +16 -0
  35. package/dist/{signals/lib → utilities}/event-listener.mjs +4 -4
  36. package/dist/{signals/lib → utilities}/event-listener.test.mjs +8 -8
  37. package/dist/utilities/focus-within.d.mts +10 -0
  38. package/dist/utilities/focus-within.mjs +20 -0
  39. package/dist/{signals/lib/is-focus-within.test.mjs → utilities/focus-within.test.mjs} +10 -11
  40. package/dist/utilities/hover.d.mts +11 -0
  41. package/dist/utilities/hover.mjs +20 -0
  42. package/dist/{signals/lib → utilities}/hover.test.mjs +5 -16
  43. package/dist/utilities/intersection-observer.d.mts +8 -0
  44. package/dist/{signals/lib → utilities}/intersection-observer.mjs +3 -4
  45. package/dist/{signals/lib → utilities}/intersection-observer.test.mjs +3 -3
  46. package/dist/{signals/lib → utilities}/interval.d.mts +2 -2
  47. package/dist/{signals/lib → utilities}/interval.mjs +6 -5
  48. package/dist/{signals/lib → utilities}/interval.test.mjs +3 -3
  49. package/dist/utilities/location.d.mts +24 -0
  50. package/dist/utilities/location.mjs +54 -0
  51. package/dist/utilities/location.test.mjs +60 -0
  52. package/dist/utilities/long-press.d.mts +10 -0
  53. package/dist/utilities/long-press.mjs +27 -0
  54. package/dist/{signals/lib → utilities}/long-press.test.mjs +3 -3
  55. package/dist/{signals/lib → utilities}/media-devices.d.mts +3 -3
  56. package/dist/{signals/lib → utilities}/media-devices.mjs +5 -5
  57. package/dist/{signals/lib → utilities}/media-devices.test.mjs +6 -8
  58. package/dist/utilities/media-player.d.mts +22 -0
  59. package/dist/utilities/media-player.mjs +36 -0
  60. package/dist/utilities/media-player.test.mjs +100 -0
  61. package/dist/{signals/lib/media.d.mts → utilities/media-query.d.mts} +4 -4
  62. package/dist/utilities/media-query.mjs +19 -0
  63. package/dist/utilities/mutation-observer.d.mts +8 -0
  64. package/dist/{signals/lib → utilities}/mutation-observer.mjs +3 -3
  65. package/dist/{signals/lib → utilities}/mutation-observer.test.mjs +3 -3
  66. package/dist/{signals/lib → utilities}/on-click-outside.d.mts +3 -3
  67. package/dist/utilities/on-click-outside.mjs +17 -0
  68. package/dist/{signals/lib → utilities}/on-click-outside.test.mjs +7 -18
  69. package/dist/utilities/orientation.d.mts +10 -0
  70. package/dist/utilities/orientation.mjs +21 -0
  71. package/dist/utilities/previous.d.mts +12 -0
  72. package/dist/utilities/previous.mjs +24 -0
  73. package/dist/utilities/previous.test.mjs +88 -0
  74. package/dist/utilities/resize-observer.d.mts +8 -0
  75. package/dist/{signals/lib → utilities}/resize-observer.mjs +4 -5
  76. package/dist/utilities/routing.d.mts +59 -0
  77. package/dist/utilities/routing.mjs +89 -0
  78. package/dist/utilities/routing.test.mjs +128 -0
  79. package/dist/utilities/search-params.d.mts +13 -0
  80. package/dist/utilities/search-params.mjs +23 -0
  81. package/dist/utilities/search-params.test.mjs +35 -0
  82. package/dist/utilities/storage.d.mts +22 -0
  83. package/dist/utilities/storage.mjs +65 -0
  84. package/dist/utilities/storage.test.mjs +137 -0
  85. package/dist/{signals/lib → utilities}/throttled.d.mts +2 -2
  86. package/dist/utilities/throttled.mjs +36 -0
  87. package/dist/{signals/lib → utilities}/throttled.test.mjs +3 -3
  88. package/dist/{signals/lib → utilities}/timeout.d.mts +6 -5
  89. package/dist/utilities/timeout.mjs +42 -0
  90. package/dist/{signals/lib → utilities}/timeout.test.mjs +7 -7
  91. package/dist/utilities/window-size.d.mts +10 -0
  92. package/dist/utilities/window-size.mjs +22 -0
  93. package/dist/utilities/window-size.test.mjs +42 -0
  94. package/package.json +11 -6
  95. package/dist/index-CKjDUp1B.d.mts +0 -89
  96. package/dist/polyfill-AFIi9kAN.d.mts +0 -14
  97. package/dist/signals/lib/active-element.d.mts +0 -10
  98. package/dist/signals/lib/active-element.mjs +0 -20
  99. package/dist/signals/lib/active-element.test.mjs +0 -39
  100. package/dist/signals/lib/animation-frames.d.mts +0 -18
  101. package/dist/signals/lib/animation-frames.mjs +0 -48
  102. package/dist/signals/lib/animation-frames.test.mjs +0 -52
  103. package/dist/signals/lib/async-retry.d.mts +0 -21
  104. package/dist/signals/lib/async-retry.mjs +0 -57
  105. package/dist/signals/lib/async-retry.test.mjs +0 -57
  106. package/dist/signals/lib/audio.d.mts +0 -26
  107. package/dist/signals/lib/audio.mjs +0 -60
  108. package/dist/signals/lib/audio.test.mjs +0 -54
  109. package/dist/signals/lib/battery.d.mts +0 -17
  110. package/dist/signals/lib/battery.mjs +0 -45
  111. package/dist/signals/lib/battery.test.mjs +0 -38
  112. package/dist/signals/lib/before-unload.d.mts +0 -11
  113. package/dist/signals/lib/before-unload.mjs +0 -20
  114. package/dist/signals/lib/before-unload.test.mjs +0 -29
  115. package/dist/signals/lib/clipboard.d.mts +0 -15
  116. package/dist/signals/lib/clipboard.mjs +0 -25
  117. package/dist/signals/lib/clipboard.test.mjs +0 -53
  118. package/dist/signals/lib/counter.d.mts +0 -18
  119. package/dist/signals/lib/counter.mjs +0 -21
  120. package/dist/signals/lib/counter.test.d.mts +0 -1
  121. package/dist/signals/lib/counter.test.mjs +0 -74
  122. package/dist/signals/lib/document-title.d.mts +0 -10
  123. package/dist/signals/lib/document-title.mjs +0 -15
  124. package/dist/signals/lib/document-title.test.d.mts +0 -1
  125. package/dist/signals/lib/document-title.test.mjs +0 -33
  126. package/dist/signals/lib/element-size.d.mts +0 -16
  127. package/dist/signals/lib/element-size.mjs +0 -32
  128. package/dist/signals/lib/element-size.test.d.mts +0 -1
  129. package/dist/signals/lib/element-size.test.mjs +0 -86
  130. package/dist/signals/lib/event-listener.d.mts +0 -14
  131. package/dist/signals/lib/favicon.d.mts +0 -10
  132. package/dist/signals/lib/favicon.mjs +0 -24
  133. package/dist/signals/lib/favicon.test.d.mts +0 -1
  134. package/dist/signals/lib/favicon.test.mjs +0 -28
  135. package/dist/signals/lib/finite-state-machine.d.mts +0 -22
  136. package/dist/signals/lib/finite-state-machine.mjs +0 -26
  137. package/dist/signals/lib/finite-state-machine.test.d.mts +0 -1
  138. package/dist/signals/lib/finite-state-machine.test.mjs +0 -66
  139. package/dist/signals/lib/fullscreen.d.mts +0 -15
  140. package/dist/signals/lib/fullscreen.mjs +0 -26
  141. package/dist/signals/lib/fullscreen.test.d.mts +0 -1
  142. package/dist/signals/lib/fullscreen.test.mjs +0 -56
  143. package/dist/signals/lib/geolocation.d.mts +0 -15
  144. package/dist/signals/lib/geolocation.mjs +0 -30
  145. package/dist/signals/lib/geolocation.test.d.mts +0 -1
  146. package/dist/signals/lib/geolocation.test.mjs +0 -37
  147. package/dist/signals/lib/hash.d.mts +0 -10
  148. package/dist/signals/lib/hash.mjs +0 -20
  149. package/dist/signals/lib/hash.test.d.mts +0 -1
  150. package/dist/signals/lib/hash.test.mjs +0 -47
  151. package/dist/signals/lib/hover.d.mts +0 -11
  152. package/dist/signals/lib/hover.mjs +0 -23
  153. package/dist/signals/lib/intersection-observer.d.mts +0 -8
  154. package/dist/signals/lib/is-document-visible.d.mts +0 -11
  155. package/dist/signals/lib/is-document-visible.mjs +0 -19
  156. package/dist/signals/lib/is-document-visible.test.d.mts +0 -1
  157. package/dist/signals/lib/is-document-visible.test.mjs +0 -58
  158. package/dist/signals/lib/is-focus-within.d.mts +0 -10
  159. package/dist/signals/lib/is-focus-within.mjs +0 -28
  160. package/dist/signals/lib/is-focus-within.test.d.mts +0 -1
  161. package/dist/signals/lib/is-idle.d.mts +0 -10
  162. package/dist/signals/lib/is-idle.mjs +0 -37
  163. package/dist/signals/lib/is-idle.test.d.mts +0 -1
  164. package/dist/signals/lib/is-idle.test.mjs +0 -50
  165. package/dist/signals/lib/is-in-viewport.d.mts +0 -10
  166. package/dist/signals/lib/is-in-viewport.mjs +0 -16
  167. package/dist/signals/lib/is-in-viewport.test.d.mts +0 -1
  168. package/dist/signals/lib/is-in-viewport.test.mjs +0 -74
  169. package/dist/signals/lib/key-press.d.mts +0 -13
  170. package/dist/signals/lib/key-press.mjs +0 -25
  171. package/dist/signals/lib/key-press.test.d.mts +0 -1
  172. package/dist/signals/lib/key-press.test.mjs +0 -52
  173. package/dist/signals/lib/list.d.mts +0 -19
  174. package/dist/signals/lib/list.mjs +0 -36
  175. package/dist/signals/lib/list.test.d.mts +0 -1
  176. package/dist/signals/lib/list.test.mjs +0 -104
  177. package/dist/signals/lib/lock-body-scroll.d.mts +0 -8
  178. package/dist/signals/lib/lock-body-scroll.mjs +0 -17
  179. package/dist/signals/lib/lock-body-scroll.test.d.mts +0 -1
  180. package/dist/signals/lib/lock-body-scroll.test.mjs +0 -37
  181. package/dist/signals/lib/long-press.d.mts +0 -10
  182. package/dist/signals/lib/long-press.mjs +0 -29
  183. package/dist/signals/lib/map.d.mts +0 -18
  184. package/dist/signals/lib/map.mjs +0 -33
  185. package/dist/signals/lib/map.test.d.mts +0 -1
  186. package/dist/signals/lib/map.test.mjs +0 -60
  187. package/dist/signals/lib/media.mjs +0 -26
  188. package/dist/signals/lib/motion.d.mts +0 -15
  189. package/dist/signals/lib/motion.mjs +0 -27
  190. package/dist/signals/lib/motion.test.d.mts +0 -1
  191. package/dist/signals/lib/motion.test.mjs +0 -51
  192. package/dist/signals/lib/mouse-position.d.mts +0 -14
  193. package/dist/signals/lib/mouse-position.mjs +0 -22
  194. package/dist/signals/lib/mouse-position.test.d.mts +0 -1
  195. package/dist/signals/lib/mouse-position.test.mjs +0 -44
  196. package/dist/signals/lib/mouse-wheel.d.mts +0 -10
  197. package/dist/signals/lib/mouse-wheel.mjs +0 -17
  198. package/dist/signals/lib/mouse-wheel.test.d.mts +0 -1
  199. package/dist/signals/lib/mouse-wheel.test.mjs +0 -38
  200. package/dist/signals/lib/mutation-observer.d.mts +0 -8
  201. package/dist/signals/lib/network-state.d.mts +0 -17
  202. package/dist/signals/lib/network-state.mjs +0 -34
  203. package/dist/signals/lib/network-state.test.d.mts +0 -1
  204. package/dist/signals/lib/network-state.test.mjs +0 -61
  205. package/dist/signals/lib/on-click-outside.mjs +0 -20
  206. package/dist/signals/lib/orientation.d.mts +0 -13
  207. package/dist/signals/lib/orientation.mjs +0 -21
  208. package/dist/signals/lib/orientation.test.d.mts +0 -1
  209. package/dist/signals/lib/orientation.test.mjs +0 -43
  210. package/dist/signals/lib/page-leave.d.mts +0 -8
  211. package/dist/signals/lib/page-leave.mjs +0 -12
  212. package/dist/signals/lib/page-leave.test.d.mts +0 -1
  213. package/dist/signals/lib/page-leave.test.mjs +0 -29
  214. package/dist/signals/lib/permission.d.mts +0 -14
  215. package/dist/signals/lib/permission.mjs +0 -26
  216. package/dist/signals/lib/permission.test.d.mts +0 -1
  217. package/dist/signals/lib/permission.test.mjs +0 -50
  218. package/dist/signals/lib/persisted-state.d.mts +0 -11
  219. package/dist/signals/lib/persisted-state.mjs +0 -25
  220. package/dist/signals/lib/persisted-state.test.d.mts +0 -1
  221. package/dist/signals/lib/persisted-state.test.mjs +0 -70
  222. package/dist/signals/lib/pressed-keys.d.mts +0 -10
  223. package/dist/signals/lib/pressed-keys.mjs +0 -32
  224. package/dist/signals/lib/pressed-keys.test.d.mts +0 -1
  225. package/dist/signals/lib/pressed-keys.test.mjs +0 -54
  226. package/dist/signals/lib/previous-distinct.d.mts +0 -10
  227. package/dist/signals/lib/previous-distinct.mjs +0 -22
  228. package/dist/signals/lib/previous-distinct.test.d.mts +0 -1
  229. package/dist/signals/lib/previous-distinct.test.mjs +0 -50
  230. package/dist/signals/lib/previous.d.mts +0 -10
  231. package/dist/signals/lib/previous.mjs +0 -18
  232. package/dist/signals/lib/previous.test.mjs +0 -47
  233. package/dist/signals/lib/queue.d.mts +0 -17
  234. package/dist/signals/lib/queue.mjs +0 -28
  235. package/dist/signals/lib/queue.test.d.mts +0 -1
  236. package/dist/signals/lib/queue.test.mjs +0 -61
  237. package/dist/signals/lib/raf.d.mts +0 -17
  238. package/dist/signals/lib/raf.mjs +0 -38
  239. package/dist/signals/lib/raf.test.d.mts +0 -1
  240. package/dist/signals/lib/raf.test.mjs +0 -58
  241. package/dist/signals/lib/resize-observer.d.mts +0 -8
  242. package/dist/signals/lib/resize-observer.test.d.mts +0 -1
  243. package/dist/signals/lib/resize-observer.test.mjs +0 -44
  244. package/dist/signals/lib/resource.d.mts +0 -23
  245. package/dist/signals/lib/resource.mjs +0 -43
  246. package/dist/signals/lib/resource.test.d.mts +0 -1
  247. package/dist/signals/lib/resource.test.mjs +0 -56
  248. package/dist/signals/lib/scroll-state.d.mts +0 -19
  249. package/dist/signals/lib/scroll-state.mjs +0 -46
  250. package/dist/signals/lib/scroll-state.test.d.mts +0 -1
  251. package/dist/signals/lib/scroll-state.test.mjs +0 -94
  252. package/dist/signals/lib/scrolling.d.mts +0 -12
  253. package/dist/signals/lib/scrolling.mjs +0 -26
  254. package/dist/signals/lib/scrolling.test.d.mts +0 -1
  255. package/dist/signals/lib/scrolling.test.mjs +0 -57
  256. package/dist/signals/lib/search-params.d.mts +0 -16
  257. package/dist/signals/lib/search-params.mjs +0 -37
  258. package/dist/signals/lib/search-params.test.mjs +0 -56
  259. package/dist/signals/lib/set.d.mts +0 -18
  260. package/dist/signals/lib/set.mjs +0 -38
  261. package/dist/signals/lib/set.test.d.mts +0 -1
  262. package/dist/signals/lib/set.test.mjs +0 -70
  263. package/dist/signals/lib/start-typing.d.mts +0 -9
  264. package/dist/signals/lib/start-typing.mjs +0 -39
  265. package/dist/signals/lib/start-typing.test.d.mts +0 -1
  266. package/dist/signals/lib/start-typing.test.mjs +0 -64
  267. package/dist/signals/lib/state-history.d.mts +0 -21
  268. package/dist/signals/lib/state-history.mjs +0 -61
  269. package/dist/signals/lib/state-history.test.d.mts +0 -1
  270. package/dist/signals/lib/state-history.test.mjs +0 -106
  271. package/dist/signals/lib/state-validator.d.mts +0 -16
  272. package/dist/signals/lib/state-validator.mjs +0 -21
  273. package/dist/signals/lib/state-validator.test.d.mts +0 -1
  274. package/dist/signals/lib/state-validator.test.mjs +0 -41
  275. package/dist/signals/lib/throttled.mjs +0 -45
  276. package/dist/signals/lib/timeout.mjs +0 -39
  277. package/dist/signals/lib/toggle.d.mts +0 -12
  278. package/dist/signals/lib/toggle.mjs +0 -12
  279. package/dist/signals/lib/toggle.test.d.mts +0 -1
  280. package/dist/signals/lib/toggle.test.mjs +0 -43
  281. package/dist/signals/lib/video.d.mts +0 -25
  282. package/dist/signals/lib/video.mjs +0 -59
  283. package/dist/signals/lib/video.test.d.mts +0 -1
  284. package/dist/signals/lib/video.test.mjs +0 -51
  285. package/dist/signals/lib/watch.d.mts +0 -16
  286. package/dist/signals/lib/watch.mjs +0 -31
  287. package/dist/signals/lib/watch.test.d.mts +0 -1
  288. package/dist/signals/lib/watch.test.mjs +0 -51
  289. package/dist/signals/lib/window-size.d.mts +0 -14
  290. package/dist/signals/lib/window-size.mjs +0 -22
  291. package/dist/signals/lib/window-size.test.mjs +0 -50
  292. /package/dist/{signals/lib → utilities}/active-element.test.d.mts +0 -0
  293. /package/dist/{signals/lib → utilities}/debounced.test.d.mts +0 -0
  294. /package/dist/{signals/lib → utilities}/element-rect.test.d.mts +0 -0
  295. /package/dist/{signals/lib/animation-frames.test.d.mts → utilities/element-scroll.test.d.mts} +0 -0
  296. /package/dist/{signals/lib → utilities}/event-listener.test.d.mts +0 -0
  297. /package/dist/{signals/lib/async-retry.test.d.mts → utilities/focus-within.test.d.mts} +0 -0
  298. /package/dist/{signals/lib → utilities}/hover.test.d.mts +0 -0
  299. /package/dist/{signals/lib → utilities}/intersection-observer.test.d.mts +0 -0
  300. /package/dist/{signals/lib → utilities}/interval.test.d.mts +0 -0
  301. /package/dist/{signals/lib/audio.test.d.mts → utilities/location.test.d.mts} +0 -0
  302. /package/dist/{signals/lib → utilities}/long-press.test.d.mts +0 -0
  303. /package/dist/{signals/lib → utilities}/media-devices.test.d.mts +0 -0
  304. /package/dist/{signals/lib/battery.test.d.mts → utilities/media-player.test.d.mts} +0 -0
  305. /package/dist/{signals/lib → utilities}/mutation-observer.test.d.mts +0 -0
  306. /package/dist/{signals/lib → utilities}/on-click-outside.test.d.mts +0 -0
  307. /package/dist/{signals/lib → utilities}/previous.test.d.mts +0 -0
  308. /package/dist/{signals/lib/before-unload.test.d.mts → utilities/routing.test.d.mts} +0 -0
  309. /package/dist/{signals/lib → utilities}/search-params.test.d.mts +0 -0
  310. /package/dist/{signals/lib/clipboard.test.d.mts → utilities/storage.test.d.mts} +0 -0
  311. /package/dist/{signals/lib → utilities}/throttled.test.d.mts +0 -0
  312. /package/dist/{signals/lib → utilities}/timeout.test.d.mts +0 -0
  313. /package/dist/{signals/lib → utilities}/window-size.test.d.mts +0 -0
@@ -0,0 +1,89 @@
1
+ import { a as computed } from "../signals-DcgXhkU2.mjs";
2
+ import { currentLocation } from "./location.mjs";
3
+ //#region src/utilities/routing.ts
4
+ const patchHistoryMethod = (method) => {
5
+ const original = history[method];
6
+ history[method] = function(data, unused, url) {
7
+ const result = original.apply(this, [
8
+ data,
9
+ unused,
10
+ url
11
+ ]);
12
+ const event = new Event(method.toLowerCase());
13
+ event.state = data;
14
+ window.dispatchEvent(event);
15
+ return result;
16
+ };
17
+ };
18
+ function patchHistory() {
19
+ if (typeof window !== "undefined" && typeof history !== "undefined") {
20
+ patchHistoryMethod("pushState");
21
+ patchHistoryMethod("replaceState");
22
+ }
23
+ }
24
+ /**
25
+ * Navigates to `url` via `history.pushState` (or `replaceState` when
26
+ * `replace` is `true`).
27
+ *
28
+ * `history.pushState` / `replaceState` are patched once at module load so
29
+ * all navigation — including third-party router calls — dispatches the
30
+ * `pushstate` / `replacestate` events that `currentLocation` signals react to.
31
+ */
32
+ function navigate(url, { replace = false, state = null } = {}) {
33
+ if (replace) history.replaceState(state, "", url);
34
+ else history.pushState(state, "", url);
35
+ }
36
+ /**
37
+ * Returns `true` when a click event on an `<a>` element should be handled
38
+ * client-side — same origin, primary button, no modifier keys, no download,
39
+ * no `_blank` target. Walks up to the nearest anchor via `closest("a")`.
40
+ *
41
+ * Use alongside `navigate()` to intercept anchor clicks:
42
+ *
43
+ * ```ts
44
+ * el.addEventListener("click", (e) => {
45
+ * if (isLocalNavigationEvent(e)) { e.preventDefault(); navigate(el.href); }
46
+ * });
47
+ * ```
48
+ */
49
+ function isLocalNavigationEvent(e) {
50
+ if (e.button !== 0) return false;
51
+ if (e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return false;
52
+ const el = e.currentTarget?.closest("a") ?? e.target?.closest("a");
53
+ if (!el) return false;
54
+ if (el.hasAttribute("download")) return false;
55
+ if (el.getAttribute("target") === "_blank") return false;
56
+ if (new URL(el.href, location.href).origin !== location.origin) return false;
57
+ return true;
58
+ }
59
+ /**
60
+ * Returns `Computed<boolean>` — `true` when the current URL matches `input`.
61
+ * Uses `URLPattern.test()` — faster than `match` when you don't need
62
+ * captured groups.
63
+ *
64
+ * Use object form: `{ pathname: "/users/:id" }`. Relative string patterns
65
+ * require a base URL and will throw.
66
+ *
67
+ * Requires `urlpattern-polyfill` for Safari < 26 and Firefox < 142.
68
+ */
69
+ function matches(input, options) {
70
+ const pattern = options ? new URLPattern(input, options) : new URLPattern(input);
71
+ return computed(() => pattern.test(currentLocation.href()));
72
+ }
73
+ /**
74
+ * Returns `Computed<URLPatternResult | null>` — the full match result when
75
+ * the current URL matches `input`, `null` when it does not.
76
+ * Use when you need captured groups (params). For a boolean gate,
77
+ * prefer `matches()` which is faster.
78
+ *
79
+ * Use object form: `{ pathname: "/users/:id" }`. Relative string patterns
80
+ * require a base URL and will throw.
81
+ *
82
+ * Requires `urlpattern-polyfill` for Safari < 26 and Firefox < 142.
83
+ */
84
+ function match(input, options) {
85
+ const pattern = options ? new URLPattern(input, options) : new URLPattern(input);
86
+ return computed(() => pattern.exec(currentLocation.href()));
87
+ }
88
+ //#endregion
89
+ export { isLocalNavigationEvent, match, matches, navigate, patchHistory };
@@ -0,0 +1,128 @@
1
+ import { i as beforeAll, n as vi, o as describe, r as afterEach, s as it, t as globalExpect } from "../test.BmQO5GaM-ANkhHvbr.mjs";
2
+ import { isLocalNavigationEvent, match, matches, navigate, patchHistory } from "./routing.mjs";
3
+ //#region src/utilities/routing.test.ts
4
+ beforeAll(() => {
5
+ patchHistory();
6
+ });
7
+ afterEach(() => {
8
+ history.replaceState(null, "", "/");
9
+ });
10
+ describe("navigate", () => {
11
+ it("pushes a new history entry", () => {
12
+ navigate("/about");
13
+ globalExpect(location.pathname).toBe("/about");
14
+ });
15
+ it("replaces the current entry when replace is true", () => {
16
+ const before = history.length;
17
+ navigate("/replaced", { replace: true });
18
+ globalExpect(location.pathname).toBe("/replaced");
19
+ globalExpect(history.length).toBe(before);
20
+ });
21
+ it("dispatches pushstate event so currentLocation updates", () => {
22
+ const handler = vi.fn();
23
+ window.addEventListener("pushstate", handler);
24
+ navigate("/dispatched");
25
+ window.removeEventListener("pushstate", handler);
26
+ globalExpect(handler).toHaveBeenCalledOnce();
27
+ });
28
+ it("dispatches replacestate event on replace", () => {
29
+ const handler = vi.fn();
30
+ window.addEventListener("replacestate", handler);
31
+ navigate("/dispatched", { replace: true });
32
+ window.removeEventListener("replacestate", handler);
33
+ globalExpect(handler).toHaveBeenCalledOnce();
34
+ });
35
+ });
36
+ describe("isLocalNavigationEvent", () => {
37
+ function makeClick(el, init = {}) {
38
+ const e = new MouseEvent("click", {
39
+ bubbles: true,
40
+ cancelable: true,
41
+ ...init
42
+ });
43
+ Object.defineProperty(e, "currentTarget", {
44
+ value: el,
45
+ configurable: true
46
+ });
47
+ return e;
48
+ }
49
+ it("returns true for a same-origin link", () => {
50
+ const el = document.createElement("a");
51
+ el.href = "/linked";
52
+ globalExpect(isLocalNavigationEvent(makeClick(el))).toBe(true);
53
+ });
54
+ it("returns false for an external link", () => {
55
+ const el = document.createElement("a");
56
+ el.href = "https://example.com/page";
57
+ globalExpect(isLocalNavigationEvent(makeClick(el))).toBe(false);
58
+ });
59
+ it("returns false when metaKey is held", () => {
60
+ const el = document.createElement("a");
61
+ el.href = "/about";
62
+ globalExpect(isLocalNavigationEvent(makeClick(el, { metaKey: true }))).toBe(false);
63
+ });
64
+ it("returns false when ctrlKey is held", () => {
65
+ const el = document.createElement("a");
66
+ el.href = "/about";
67
+ globalExpect(isLocalNavigationEvent(makeClick(el, { ctrlKey: true }))).toBe(false);
68
+ });
69
+ it("returns false for download links", () => {
70
+ const el = document.createElement("a");
71
+ el.href = "/file.pdf";
72
+ el.setAttribute("download", "");
73
+ globalExpect(isLocalNavigationEvent(makeClick(el))).toBe(false);
74
+ });
75
+ it("returns false for _blank links", () => {
76
+ const el = document.createElement("a");
77
+ el.href = "/page";
78
+ el.setAttribute("target", "_blank");
79
+ globalExpect(isLocalNavigationEvent(makeClick(el))).toBe(false);
80
+ });
81
+ it("returns false for non-primary button clicks", () => {
82
+ const el = document.createElement("a");
83
+ el.href = "/page";
84
+ globalExpect(isLocalNavigationEvent(makeClick(el, { button: 1 }))).toBe(false);
85
+ });
86
+ });
87
+ describe("matches", () => {
88
+ it("returns true when current URL matches", () => {
89
+ navigate("/users/42");
90
+ globalExpect(matches({ pathname: "/users/:id" })()).toBe(true);
91
+ });
92
+ it("returns false when current URL does not match", () => {
93
+ navigate("/other");
94
+ globalExpect(matches({ pathname: "/users/:id" })()).toBe(false);
95
+ });
96
+ it("updates reactively on navigation", () => {
97
+ const result = matches({ pathname: "/home" });
98
+ navigate("/other");
99
+ globalExpect(result()).toBe(false);
100
+ navigate("/home");
101
+ globalExpect(result()).toBe(true);
102
+ });
103
+ });
104
+ describe("match", () => {
105
+ it("returns null when current URL does not match", () => {
106
+ navigate("/other");
107
+ globalExpect(match({ pathname: "/users/:id" })()).toBeNull();
108
+ });
109
+ it("returns URLPatternResult with groups when matched", () => {
110
+ navigate("/users/42");
111
+ globalExpect(match({ pathname: "/users/:id" })()?.pathname.groups.id).toBe("42");
112
+ });
113
+ it("updates reactively on navigation", () => {
114
+ const result = match({ pathname: "/posts/:slug" });
115
+ navigate("/posts/hello");
116
+ globalExpect(result()?.pathname.groups.slug).toBe("hello");
117
+ navigate("/other");
118
+ globalExpect(result()).toBeNull();
119
+ });
120
+ it("extracts multiple params", () => {
121
+ navigate("/posts/2024/my-slug");
122
+ const result = match({ pathname: "/posts/:year/:slug" });
123
+ globalExpect(result()?.pathname.groups.year).toBe("2024");
124
+ globalExpect(result()?.pathname.groups.slug).toBe("my-slug");
125
+ });
126
+ });
127
+ //#endregion
128
+ export {};
@@ -0,0 +1,13 @@
1
+ import { t as Computed } from "../index-Cvdhuy6Y.mjs";
2
+
3
+ //#region src/utilities/search-params.d.ts
4
+ /**
5
+ * Returns a read-only `Computed<string | null>` bound to a single URL search
6
+ * parameter.
7
+ *
8
+ * Returns the raw string value, or `null` when absent.
9
+ * Reacts to `popstate` so back/forward navigation is reflected.
10
+ */
11
+ declare function createSearchParam(key: string): Computed<string | null>;
12
+ //#endregion
13
+ export { createSearchParam };
@@ -0,0 +1,23 @@
1
+ import { fromEvent, sync } from "./event-driven.mjs";
2
+ //#region src/utilities/search-params.ts
3
+ /**
4
+ * Returns a read-only `Computed<string | null>` bound to a single URL search
5
+ * parameter.
6
+ *
7
+ * Returns the raw string value, or `null` when absent.
8
+ * Reacts to `popstate` so back/forward navigation is reflected.
9
+ */
10
+ function createSearchParam(key) {
11
+ const read = () => {
12
+ if (typeof location === "undefined") return null;
13
+ return new URLSearchParams(location.search).get(key);
14
+ };
15
+ const [s] = sync(fromEvent(window, [
16
+ "popstate",
17
+ "pushstate",
18
+ "replacestate"
19
+ ]), read);
20
+ return s;
21
+ }
22
+ //#endregion
23
+ export { createSearchParam };
@@ -0,0 +1,35 @@
1
+ import { s as effectScope } from "../signals-DcgXhkU2.mjs";
2
+ import { o as describe, r as afterEach, s as it, t as globalExpect } from "../test.BmQO5GaM-ANkhHvbr.mjs";
3
+ import { createSearchParam } from "./search-params.mjs";
4
+ //#region src/utilities/search-params.test.ts
5
+ afterEach(() => {
6
+ history.replaceState(null, "", location.pathname);
7
+ });
8
+ describe("createSearchParam", () => {
9
+ it("returns null when param is absent", () => {
10
+ let s;
11
+ effectScope(() => {
12
+ s = createSearchParam("q");
13
+ });
14
+ globalExpect(s()).toBeNull();
15
+ });
16
+ it("reads an existing param from the URL", () => {
17
+ history.replaceState(null, "", "?q=hello");
18
+ let s;
19
+ effectScope(() => {
20
+ s = createSearchParam("q");
21
+ });
22
+ globalExpect(s()).toBe("hello");
23
+ });
24
+ it("reacts to popstate events", () => {
25
+ let s;
26
+ effectScope(() => {
27
+ s = createSearchParam("q");
28
+ });
29
+ history.replaceState(null, "", "?q=changed");
30
+ window.dispatchEvent(new PopStateEvent("popstate"));
31
+ globalExpect(s()).toBe("changed");
32
+ });
33
+ });
34
+ //#endregion
35
+ export {};
@@ -0,0 +1,22 @@
1
+ import { r as Signal } from "../index-Cvdhuy6Y.mjs";
2
+
3
+ //#region src/utilities/storage.d.ts
4
+ type StorageOptions<T> = {
5
+ /** Custom serialiser (default `JSON.stringify`). */serialise?: (value: T) => string; /** Custom deserialiser (default `JSON.parse`). */
6
+ deserialise?: (raw: string) => T;
7
+ };
8
+ /**
9
+ * Returns a `Signal` persisted to `localStorage`.
10
+ *
11
+ * Changes made in other tabs/windows are synchronised automatically via
12
+ * the `StorageEvent`.
13
+ */
14
+ declare function createLocalStorage<T>(key: string, initialValue: T, options?: StorageOptions<T>): Signal<T>;
15
+ /**
16
+ * Returns a `Signal` persisted to `sessionStorage`.
17
+ *
18
+ * Session storage is scoped to the current tab — no cross-tab sync.
19
+ */
20
+ declare function createSessionStorage<T>(key: string, initialValue: T, options?: StorageOptions<T>): Signal<T>;
21
+ //#endregion
22
+ export { createLocalStorage, createSessionStorage };
@@ -0,0 +1,65 @@
1
+ import { sync } from "./event-driven.mjs";
2
+ //#region src/utilities/storage.ts
3
+ function readOrDefault(storage, key, initialValue, deserialise) {
4
+ try {
5
+ const item = storage.getItem(key);
6
+ if (item !== null) return deserialise(item);
7
+ } catch {}
8
+ return initialValue;
9
+ }
10
+ /**
11
+ * Returns a `Signal` persisted to `localStorage`.
12
+ *
13
+ * Changes made in other tabs/windows are synchronised automatically via
14
+ * the `StorageEvent`.
15
+ */
16
+ function createLocalStorage(key, initialValue, options) {
17
+ const serialise = options?.serialise ?? ((v) => JSON.stringify(v));
18
+ const deserialise = options?.deserialise ?? ((raw) => JSON.parse(raw));
19
+ const storage = localStorage;
20
+ let notify;
21
+ const subscribe = (cb) => {
22
+ notify = cb;
23
+ const handler = (e) => {
24
+ if (e.key === key && e.storageArea === storage) cb();
25
+ };
26
+ window.addEventListener("storage", handler);
27
+ return () => {
28
+ window.removeEventListener("storage", handler);
29
+ notify = void 0;
30
+ };
31
+ };
32
+ const [s] = sync(subscribe, () => readOrDefault(storage, key, initialValue, deserialise), (v) => {
33
+ try {
34
+ storage.setItem(key, serialise(v));
35
+ } catch {}
36
+ notify?.();
37
+ });
38
+ return s;
39
+ }
40
+ /**
41
+ * Returns a `Signal` persisted to `sessionStorage`.
42
+ *
43
+ * Session storage is scoped to the current tab — no cross-tab sync.
44
+ */
45
+ function createSessionStorage(key, initialValue, options) {
46
+ const serialise = options?.serialise ?? ((v) => JSON.stringify(v));
47
+ const deserialise = options?.deserialise ?? ((raw) => JSON.parse(raw));
48
+ const storage = sessionStorage;
49
+ let notify;
50
+ const subscribe = (cb) => {
51
+ notify = cb;
52
+ return () => {
53
+ notify = void 0;
54
+ };
55
+ };
56
+ const [s] = sync(subscribe, () => readOrDefault(storage, key, initialValue, deserialise), (v) => {
57
+ try {
58
+ storage.setItem(key, serialise(v));
59
+ } catch {}
60
+ notify?.();
61
+ });
62
+ return s;
63
+ }
64
+ //#endregion
65
+ export { createLocalStorage, createSessionStorage };
@@ -0,0 +1,137 @@
1
+ import { s as effectScope } from "../signals-DcgXhkU2.mjs";
2
+ import { o as describe, r as afterEach, s as it, t as globalExpect } from "../test.BmQO5GaM-ANkhHvbr.mjs";
3
+ import { createLocalStorage, createSessionStorage } from "./storage.mjs";
4
+ //#region src/utilities/storage.test.ts
5
+ describe("createLocalStorage", () => {
6
+ afterEach(() => {
7
+ localStorage.clear();
8
+ });
9
+ it("uses initialValue when storage is empty", () => {
10
+ let s;
11
+ effectScope(() => {
12
+ s = createLocalStorage("count", 0);
13
+ });
14
+ globalExpect(s()).toBe(0);
15
+ });
16
+ it("reads an existing value from localStorage", () => {
17
+ localStorage.setItem("count", "42");
18
+ let s;
19
+ effectScope(() => {
20
+ s = createLocalStorage("count", 0);
21
+ });
22
+ globalExpect(s()).toBe(42);
23
+ });
24
+ it("persists writes to localStorage", () => {
25
+ let s;
26
+ effectScope(() => {
27
+ s = createLocalStorage("key", "a");
28
+ });
29
+ s("b");
30
+ globalExpect(JSON.parse(localStorage.getItem("key"))).toBe("b");
31
+ });
32
+ it("persists complex values as JSON", () => {
33
+ let s;
34
+ effectScope(() => {
35
+ s = createLocalStorage("obj", { x: 1 });
36
+ });
37
+ s({ x: 99 });
38
+ globalExpect(JSON.parse(localStorage.getItem("obj"))).toEqual({ x: 99 });
39
+ });
40
+ it("falls back to initialValue on invalid JSON", () => {
41
+ localStorage.setItem("broken", "{not json}");
42
+ let s;
43
+ effectScope(() => {
44
+ s = createLocalStorage("broken", 7);
45
+ });
46
+ globalExpect(s()).toBe(7);
47
+ });
48
+ it("supports custom serialise / deserialise", () => {
49
+ let s;
50
+ effectScope(() => {
51
+ s = createLocalStorage("date", /* @__PURE__ */ new Date("2024-01-01"), {
52
+ serialise: (d) => d.toISOString(),
53
+ deserialise: (raw) => new Date(raw)
54
+ });
55
+ });
56
+ const d = /* @__PURE__ */ new Date("2025-06-15");
57
+ s(d);
58
+ globalExpect(localStorage.getItem("date")).toBe(d.toISOString());
59
+ });
60
+ it("reacts to storage events from other tabs", () => {
61
+ let s;
62
+ effectScope(() => {
63
+ s = createLocalStorage("sync-key", "init");
64
+ });
65
+ localStorage.setItem("sync-key", JSON.stringify("from-other-tab"));
66
+ window.dispatchEvent(new StorageEvent("storage", {
67
+ key: "sync-key",
68
+ newValue: JSON.stringify("from-other-tab"),
69
+ storageArea: localStorage
70
+ }));
71
+ globalExpect(s()).toBe("from-other-tab");
72
+ });
73
+ it("ignores storage events for different keys", () => {
74
+ let s;
75
+ effectScope(() => {
76
+ s = createLocalStorage("my-key", "init");
77
+ });
78
+ window.dispatchEvent(new StorageEvent("storage", {
79
+ key: "other-key",
80
+ newValue: JSON.stringify("nope"),
81
+ storageArea: localStorage
82
+ }));
83
+ globalExpect(s()).toBe("init");
84
+ });
85
+ it("resets to initialValue when key is removed", () => {
86
+ let s;
87
+ effectScope(() => {
88
+ s = createLocalStorage("rm-key", "default");
89
+ });
90
+ s("changed");
91
+ localStorage.removeItem("rm-key");
92
+ window.dispatchEvent(new StorageEvent("storage", {
93
+ key: "rm-key",
94
+ newValue: null,
95
+ storageArea: localStorage
96
+ }));
97
+ globalExpect(s()).toBe("default");
98
+ });
99
+ });
100
+ describe("createSessionStorage", () => {
101
+ afterEach(() => {
102
+ sessionStorage.clear();
103
+ });
104
+ it("uses initialValue when storage is empty", () => {
105
+ let s;
106
+ effectScope(() => {
107
+ s = createSessionStorage("count", 0);
108
+ });
109
+ globalExpect(s()).toBe(0);
110
+ });
111
+ it("reads an existing value from sessionStorage", () => {
112
+ sessionStorage.setItem("count", "42");
113
+ let s;
114
+ effectScope(() => {
115
+ s = createSessionStorage("count", 0);
116
+ });
117
+ globalExpect(s()).toBe(42);
118
+ });
119
+ it("persists writes to sessionStorage", () => {
120
+ let s;
121
+ effectScope(() => {
122
+ s = createSessionStorage("key", "a");
123
+ });
124
+ s("b");
125
+ globalExpect(JSON.parse(sessionStorage.getItem("key"))).toBe("b");
126
+ });
127
+ it("falls back to initialValue on invalid JSON", () => {
128
+ sessionStorage.setItem("broken", "{not json}");
129
+ let s;
130
+ effectScope(() => {
131
+ s = createSessionStorage("broken", 7);
132
+ });
133
+ globalExpect(s()).toBe(7);
134
+ });
135
+ });
136
+ //#endregion
137
+ export {};
@@ -1,6 +1,6 @@
1
- import { t as Computed } from "../../index-BtqiEEfc.mjs";
1
+ import { t as Computed } from "../index-Cvdhuy6Y.mjs";
2
2
 
3
- //#region src/signals/lib/throttled.d.ts
3
+ //#region src/utilities/throttled.d.ts
4
4
  /**
5
5
  * Returns a `Computed` that mirrors `getter` but updates at most once per
6
6
  * `interval` milliseconds. A trailing-edge update is scheduled so the final
@@ -0,0 +1,36 @@
1
+ import { o as effect, p as signal } from "../signals-DcgXhkU2.mjs";
2
+ import { createTimeout } from "./timeout.mjs";
3
+ //#region src/utilities/throttled.ts
4
+ /**
5
+ * Returns a `Computed` that mirrors `getter` but updates at most once per
6
+ * `interval` milliseconds. A trailing-edge update is scheduled so the final
7
+ * value is never lost.
8
+ *
9
+ * The initial value is read synchronously.
10
+ */
11
+ function createThrottled(getter, interval) {
12
+ const s = signal(getter());
13
+ let lastRun = -Infinity;
14
+ let firstRun = true;
15
+ let latest;
16
+ const { stop, reset } = createTimeout(() => {
17
+ lastRun = Date.now();
18
+ s(latest);
19
+ }, () => interval - (Date.now() - lastRun), false);
20
+ effect(() => {
21
+ latest = getter();
22
+ if (firstRun) {
23
+ firstRun = false;
24
+ return;
25
+ }
26
+ const elapsed = Date.now() - lastRun;
27
+ stop();
28
+ if (elapsed >= interval) {
29
+ lastRun = Date.now();
30
+ s(latest);
31
+ } else reset();
32
+ });
33
+ return s;
34
+ }
35
+ //#endregion
36
+ export { createThrottled };
@@ -1,7 +1,7 @@
1
- import { f as signal, o as effectScope } from "../../signals-CLAPw8kk.mjs";
2
- import { a as describe, i as beforeEach, n as vi, o as it, r as afterEach, t as globalExpect } from "../../test.BmQO5GaM-CR2qjV1t.mjs";
1
+ import { p as signal, s as effectScope } from "../signals-DcgXhkU2.mjs";
2
+ import { a as beforeEach, n as vi, o as describe, r as afterEach, s as it, t as globalExpect } from "../test.BmQO5GaM-ANkhHvbr.mjs";
3
3
  import { createThrottled } from "./throttled.mjs";
4
- //#region src/signals/lib/throttled.test.ts
4
+ //#region src/utilities/throttled.test.ts
5
5
  beforeEach(() => {
6
6
  vi.useFakeTimers();
7
7
  });
@@ -1,16 +1,17 @@
1
- import { t as Computed } from "../../index-BtqiEEfc.mjs";
1
+ import { t as Computed } from "../index-Cvdhuy6Y.mjs";
2
2
 
3
- //#region src/signals/lib/timeout.d.ts
3
+ //#region src/utilities/timeout.d.ts
4
4
  type TimeoutResult = {
5
- isPending: Computed<boolean>;
5
+ isRunning: Computed<boolean>;
6
6
  start(): void;
7
7
  stop(): void;
8
8
  reset(): void;
9
9
  } & Disposable;
10
10
  /**
11
11
  * Reactive `setTimeout` wrapper with pause/resume/reset control.
12
- * The callback fires once after `delay` ms. Starts running immediately.
12
+ * The callback fires once after `delay` ms. Starts running immediately
13
+ * unless `immediate` is set to `false`.
13
14
  */
14
- declare function createTimeout(callback: () => void, delay: number): TimeoutResult;
15
+ declare function createTimeout(callback: () => void, delay: number | (() => number), immediate?: boolean): TimeoutResult;
15
16
  //#endregion
16
17
  export { createTimeout };
@@ -0,0 +1,42 @@
1
+ import { f as onCleanup, p as signal } from "../signals-DcgXhkU2.mjs";
2
+ //#region src/utilities/timeout.ts
3
+ /**
4
+ * Reactive `setTimeout` wrapper with pause/resume/reset control.
5
+ * The callback fires once after `delay` ms. Starts running immediately
6
+ * unless `immediate` is set to `false`.
7
+ */
8
+ function createTimeout(callback, delay, immediate = true) {
9
+ const isRunning = signal(false);
10
+ let id;
11
+ const getDelay = typeof delay === "function" ? delay : () => delay;
12
+ const stop = () => {
13
+ clearTimeout(id);
14
+ id = void 0;
15
+ isRunning(false);
16
+ };
17
+ const start = () => {
18
+ if (isRunning()) return;
19
+ isRunning(true);
20
+ id = setTimeout(() => {
21
+ isRunning(false);
22
+ id = void 0;
23
+ callback();
24
+ }, getDelay());
25
+ };
26
+ const reset = () => {
27
+ stop();
28
+ start();
29
+ };
30
+ if (immediate) start();
31
+ const cleanup = () => stop();
32
+ onCleanup(cleanup);
33
+ return {
34
+ isRunning,
35
+ start,
36
+ stop,
37
+ reset,
38
+ [Symbol.dispose]: cleanup
39
+ };
40
+ }
41
+ //#endregion
42
+ export { createTimeout };