@stacksjs/composables 0.70.87 → 0.70.90

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 (333) hide show
  1. package/dist/_shared.d.ts +49 -0
  2. package/dist/_shared.js +23 -0
  3. package/dist/cloneFnJSON.d.ts +5 -0
  4. package/dist/cloneFnJSON.js +3 -0
  5. package/dist/computedAsync.d.ts +28 -0
  6. package/dist/computedAsync.js +20 -0
  7. package/dist/computedEager.d.ts +27 -0
  8. package/dist/computedEager.js +10 -0
  9. package/dist/createEventHook.d.ts +16 -0
  10. package/dist/createEventHook.js +15 -0
  11. package/dist/createFetch.d.ts +14 -0
  12. package/dist/createFetch.js +8 -0
  13. package/dist/createGlobalState.d.ts +17 -0
  14. package/dist/createGlobalState.js +10 -0
  15. package/dist/createSharedComposable.d.ts +8 -0
  16. package/dist/createSharedComposable.js +9 -0
  17. package/dist/extendRef.d.ts +9 -0
  18. package/dist/extendRef.js +6 -0
  19. package/dist/formatTimeAgo.d.ts +23 -0
  20. package/dist/formatTimeAgo.js +33 -0
  21. package/dist/index.d.ts +271 -0
  22. package/dist/index.js +210 -2
  23. package/dist/isDefined.d.ts +5 -0
  24. package/dist/isDefined.js +3 -0
  25. package/dist/makeDestructurable.d.ts +18 -0
  26. package/dist/makeDestructurable.js +16 -0
  27. package/dist/onClickOutside.d.ts +14 -0
  28. package/dist/onClickOutside.js +25 -0
  29. package/dist/onKeyStroke.d.ts +26 -0
  30. package/dist/onKeyStroke.js +31 -0
  31. package/dist/onLongPress.d.ts +14 -0
  32. package/dist/onLongPress.js +43 -0
  33. package/dist/onStartTyping.d.ts +8 -0
  34. package/dist/onStartTyping.js +23 -0
  35. package/dist/refAutoReset.d.ts +11 -0
  36. package/dist/refAutoReset.js +15 -0
  37. package/dist/refDefault.d.ts +9 -0
  38. package/dist/refDefault.js +8 -0
  39. package/dist/resolveRef.d.ts +7 -0
  40. package/dist/resolveRef.js +7 -0
  41. package/dist/ssrHandlers.d.ts +13 -0
  42. package/dist/ssrHandlers.js +8 -0
  43. package/dist/syncRef.d.ts +21 -0
  44. package/dist/syncRef.js +35 -0
  45. package/dist/tryOnMounted.d.ts +22 -0
  46. package/dist/tryOnMounted.js +22 -0
  47. package/dist/unrefElement.d.ts +6 -0
  48. package/dist/unrefElement.js +9 -0
  49. package/dist/until.d.ts +34 -0
  50. package/dist/until.js +62 -0
  51. package/dist/useActiveElement.d.ts +6 -0
  52. package/dist/useActiveElement.js +19 -0
  53. package/dist/useAnimate.d.ts +18 -0
  54. package/dist/useAnimate.js +48 -0
  55. package/dist/useArrayUtils.d.ts +42 -0
  56. package/dist/useArrayUtils.js +114 -0
  57. package/dist/useAsyncQueue.d.ts +18 -0
  58. package/dist/useAsyncQueue.js +22 -0
  59. package/dist/useAsyncState.d.ts +23 -0
  60. package/dist/useAsyncState.js +35 -0
  61. package/dist/useBase64.d.ts +12 -0
  62. package/dist/useBase64.js +45 -0
  63. package/dist/useBattery.d.ts +15 -0
  64. package/dist/useBattery.js +38 -0
  65. package/dist/useBreakpoints.d.ts +96 -0
  66. package/dist/useBreakpoints.js +97 -0
  67. package/dist/useBroadcastChannel.d.ts +14 -0
  68. package/dist/useBroadcastChannel.js +31 -0
  69. package/dist/useBrowserLocation.d.ts +18 -0
  70. package/dist/useBrowserLocation.js +64 -0
  71. package/dist/useClipboard.d.ts +17 -0
  72. package/dist/useClipboard.js +32 -0
  73. package/dist/useClipboardItems.d.ts +11 -0
  74. package/dist/useClipboardItems.js +15 -0
  75. package/dist/useCloned.d.ts +15 -0
  76. package/dist/useCloned.js +16 -0
  77. package/dist/useColorMode.d.ts +18 -0
  78. package/dist/useColorMode.js +60 -0
  79. package/dist/useConfirmDialog.d.ts +14 -0
  80. package/dist/useConfirmDialog.js +34 -0
  81. package/dist/useCounter.d.ts +20 -0
  82. package/dist/useCounter.js +28 -0
  83. package/dist/useCssVar.d.ts +10 -0
  84. package/dist/useCssVar.js +23 -0
  85. package/dist/useCycleList.d.ts +18 -0
  86. package/dist/useCycleList.js +27 -0
  87. package/dist/useDark.d.ts +11 -0
  88. package/dist/useDark.js +38 -0
  89. package/dist/useDateFormat.d.ts +10 -0
  90. package/dist/useDateFormat.js +11 -0
  91. package/dist/useDebounce.d.ts +10 -0
  92. package/dist/useDebounce.js +16 -0
  93. package/dist/useDebounceFn.d.ts +10 -0
  94. package/dist/useDebounceFn.js +18 -0
  95. package/dist/useDebouncedRef.d.ts +11 -0
  96. package/dist/useDebouncedRef.js +22 -0
  97. package/dist/useDebouncedRefHistory.d.ts +5 -0
  98. package/dist/useDebouncedRefHistory.js +36 -0
  99. package/dist/useDeviceMotion.d.ts +27 -0
  100. package/dist/useDeviceMotion.js +53 -0
  101. package/dist/useDeviceOrientation.d.ts +15 -0
  102. package/dist/useDeviceOrientation.js +23 -0
  103. package/dist/useDevicePixelRatio.d.ts +5 -0
  104. package/dist/useDevicePixelRatio.js +24 -0
  105. package/dist/useDocumentVisibility.d.ts +5 -0
  106. package/dist/useDocumentVisibility.js +16 -0
  107. package/dist/useDraggable.d.ts +23 -0
  108. package/dist/useDraggable.js +58 -0
  109. package/dist/useDropZone.d.ts +15 -0
  110. package/dist/useDropZone.js +52 -0
  111. package/dist/useElementBounding.d.ts +21 -0
  112. package/dist/useElementBounding.js +59 -0
  113. package/dist/useElementByPoint.d.ts +10 -0
  114. package/dist/useElementByPoint.js +18 -0
  115. package/dist/useElementHover.d.ts +9 -0
  116. package/dist/useElementHover.js +28 -0
  117. package/dist/useElementSize.d.ts +19 -0
  118. package/dist/useElementSize.js +34 -0
  119. package/dist/useElementVisibility.d.ts +10 -0
  120. package/dist/useElementVisibility.js +10 -0
  121. package/dist/useEventBus.d.ts +14 -0
  122. package/dist/useEventBus.js +41 -0
  123. package/dist/useEventListener.d.ts +14 -0
  124. package/dist/useEventListener.js +29 -0
  125. package/dist/useEventSource.d.ts +32 -0
  126. package/dist/useEventSource.js +72 -0
  127. package/dist/useEyeDropper.d.ts +10 -0
  128. package/dist/useEyeDropper.js +17 -0
  129. package/dist/useFavicon.d.ts +8 -0
  130. package/dist/useFavicon.js +22 -0
  131. package/dist/useFetch.d.ts +35 -0
  132. package/dist/useFetch.js +61 -0
  133. package/dist/useFileDialog.d.ts +15 -0
  134. package/dist/useFileDialog.js +24 -0
  135. package/dist/useFocus.d.ts +13 -0
  136. package/dist/useFocus.js +42 -0
  137. package/dist/useFocusWithin.d.ts +9 -0
  138. package/dist/useFocusWithin.js +29 -0
  139. package/dist/useForm.d.ts +97 -0
  140. package/dist/useForm.js +182 -0
  141. package/dist/useFps.d.ts +7 -0
  142. package/dist/useFps.js +22 -0
  143. package/dist/useFullscreen.d.ts +16 -0
  144. package/dist/useFullscreen.js +67 -0
  145. package/dist/useGeolocation.d.ts +26 -0
  146. package/dist/useGeolocation.js +55 -0
  147. package/dist/useIdle.d.ts +18 -0
  148. package/dist/useIdle.js +46 -0
  149. package/dist/useImage.d.ts +18 -0
  150. package/dist/useImage.js +32 -0
  151. package/dist/useInfiniteScroll.d.ts +11 -0
  152. package/dist/useInfiniteScroll.js +50 -0
  153. package/dist/useIntersectionObserver.d.ts +16 -0
  154. package/dist/useIntersectionObserver.js +27 -0
  155. package/dist/useInterval.d.ts +13 -0
  156. package/dist/useInterval.js +32 -0
  157. package/dist/useIntervalFn.d.ts +16 -0
  158. package/dist/useIntervalFn.js +24 -0
  159. package/dist/useKeyModifier.d.ts +6 -0
  160. package/dist/useKeyModifier.js +22 -0
  161. package/dist/useLastChanged.d.ts +11 -0
  162. package/dist/useLastChanged.js +8 -0
  163. package/dist/useLocalStorage.d.ts +17 -0
  164. package/dist/useLocalStorage.js +4 -0
  165. package/dist/useMagicKeys.d.ts +16 -0
  166. package/dist/useMagicKeys.js +81 -0
  167. package/dist/useManualRefHistory.d.ts +27 -0
  168. package/dist/useManualRefHistory.js +64 -0
  169. package/dist/useMath.d.ts +17 -0
  170. package/dist/useMath.js +52 -0
  171. package/dist/useMediaQuery.d.ts +9 -0
  172. package/dist/useMediaQuery.js +19 -0
  173. package/dist/useMemoize.d.ts +13 -0
  174. package/dist/useMemoize.js +24 -0
  175. package/dist/useMounted.d.ts +6 -0
  176. package/dist/useMounted.js +8 -0
  177. package/dist/useMouse.d.ts +19 -0
  178. package/dist/useMouse.js +67 -0
  179. package/dist/useMouseInElement.d.ts +17 -0
  180. package/dist/useMouseInElement.js +31 -0
  181. package/dist/useMousePressed.d.ts +10 -0
  182. package/dist/useMousePressed.js +31 -0
  183. package/dist/useMutationObserver.d.ts +16 -0
  184. package/dist/useMutationObserver.js +27 -0
  185. package/dist/useNavigatorLanguage.d.ts +5 -0
  186. package/dist/useNavigatorLanguage.js +17 -0
  187. package/dist/useNetwork.d.ts +18 -0
  188. package/dist/useNetwork.js +58 -0
  189. package/dist/useNow.d.ts +8 -0
  190. package/dist/useNow.js +10 -0
  191. package/dist/useObjectUrl.d.ts +8 -0
  192. package/dist/useObjectUrl.js +23 -0
  193. package/dist/useOffsetPagination.d.ts +21 -0
  194. package/dist/useOffsetPagination.js +45 -0
  195. package/dist/useOnline.d.ts +7 -0
  196. package/dist/useOnline.js +20 -0
  197. package/dist/usePageLeave.d.ts +9 -0
  198. package/dist/usePageLeave.js +27 -0
  199. package/dist/useParallax.d.ts +15 -0
  200. package/dist/useParallax.js +33 -0
  201. package/dist/useParentElement.d.ts +6 -0
  202. package/dist/useParentElement.js +8 -0
  203. package/dist/usePermission.d.ts +7 -0
  204. package/dist/usePermission.js +21 -0
  205. package/dist/usePointer.d.ts +15 -0
  206. package/dist/usePointer.js +32 -0
  207. package/dist/usePointerLock.d.ts +13 -0
  208. package/dist/usePointerLock.js +33 -0
  209. package/dist/usePointerSwipe.d.ts +20 -0
  210. package/dist/usePointerSwipe.js +52 -0
  211. package/dist/usePreferredColorScheme.d.ts +6 -0
  212. package/dist/usePreferredColorScheme.js +25 -0
  213. package/dist/usePreferredContrast.d.ts +6 -0
  214. package/dist/usePreferredContrast.js +29 -0
  215. package/dist/usePreferredLanguages.d.ts +5 -0
  216. package/dist/usePreferredLanguages.js +16 -0
  217. package/dist/usePreferredReducedMotion.d.ts +6 -0
  218. package/dist/usePreferredReducedMotion.js +18 -0
  219. package/dist/usePrevious.d.ts +9 -0
  220. package/dist/usePrevious.js +8 -0
  221. package/dist/useQuery.d.ts +106 -0
  222. package/dist/useQuery.js +265 -0
  223. package/dist/useRafFn.d.ts +19 -0
  224. package/dist/useRafFn.js +37 -0
  225. package/dist/useRefHistory.d.ts +28 -0
  226. package/dist/useRefHistory.js +72 -0
  227. package/dist/useResizeObserver.d.ts +16 -0
  228. package/dist/useResizeObserver.js +27 -0
  229. package/dist/useScreenOrientation.d.ts +13 -0
  230. package/dist/useScreenOrientation.js +27 -0
  231. package/dist/useScreenSafeArea.d.ts +12 -0
  232. package/dist/useScreenSafeArea.js +25 -0
  233. package/dist/useScriptTag.d.ts +20 -0
  234. package/dist/useScriptTag.js +52 -0
  235. package/dist/useScroll.d.ts +36 -0
  236. package/dist/useScroll.js +116 -0
  237. package/dist/useScrollLock.d.ts +10 -0
  238. package/dist/useScrollLock.js +39 -0
  239. package/dist/useSessionStorage.d.ts +17 -0
  240. package/dist/useSessionStorage.js +4 -0
  241. package/dist/useShare.d.ts +15 -0
  242. package/dist/useShare.js +11 -0
  243. package/dist/useSorted.d.ts +10 -0
  244. package/dist/useSorted.js +10 -0
  245. package/dist/useStepper.d.ts +23 -0
  246. package/dist/useStepper.js +46 -0
  247. package/dist/useStorage.d.ts +18 -0
  248. package/dist/useStorage.js +54 -0
  249. package/dist/useStyleTag.d.ts +17 -0
  250. package/dist/useStyleTag.js +39 -0
  251. package/dist/useSupported.d.ts +8 -0
  252. package/dist/useSupported.js +10 -0
  253. package/dist/useSwipe.d.ts +20 -0
  254. package/dist/useSwipe.js +58 -0
  255. package/dist/useTextDirection.d.ts +9 -0
  256. package/dist/useTextDirection.js +16 -0
  257. package/dist/useTextSelection.d.ts +10 -0
  258. package/dist/useTextSelection.js +27 -0
  259. package/dist/useTextareaAutosize.d.ts +10 -0
  260. package/dist/useTextareaAutosize.js +20 -0
  261. package/dist/useThrottle.d.ts +9 -0
  262. package/dist/useThrottle.js +23 -0
  263. package/dist/useThrottleFn.d.ts +11 -0
  264. package/dist/useThrottleFn.js +36 -0
  265. package/dist/useThrottledRef.d.ts +11 -0
  266. package/dist/useThrottledRef.js +30 -0
  267. package/dist/useThrottledRefHistory.d.ts +5 -0
  268. package/dist/useThrottledRefHistory.js +43 -0
  269. package/dist/useTimeAgo.d.ts +16 -0
  270. package/dist/useTimeAgo.js +58 -0
  271. package/dist/useTimeout.d.ts +12 -0
  272. package/dist/useTimeout.js +32 -0
  273. package/dist/useTimeoutFn.d.ts +16 -0
  274. package/dist/useTimeoutFn.js +27 -0
  275. package/dist/useTimeoutPoll.d.ts +10 -0
  276. package/dist/useTimeoutPoll.js +33 -0
  277. package/dist/useTimestamp.d.ts +15 -0
  278. package/dist/useTimestamp.js +43 -0
  279. package/dist/useTitle.d.ts +10 -0
  280. package/dist/useTitle.js +12 -0
  281. package/dist/useToNumber.d.ts +11 -0
  282. package/dist/useToNumber.js +25 -0
  283. package/dist/useToString.d.ts +6 -0
  284. package/dist/useToString.js +10 -0
  285. package/dist/useToggle.d.ts +6 -0
  286. package/dist/useToggle.js +12 -0
  287. package/dist/useTransition.d.ts +28 -0
  288. package/dist/useTransition.js +89 -0
  289. package/dist/useUrlSearchParams.d.ts +18 -0
  290. package/dist/useUrlSearchParams.js +72 -0
  291. package/dist/useVibrate.d.ts +13 -0
  292. package/dist/useVibrate.js +14 -0
  293. package/dist/useVirtualList.d.ts +23 -0
  294. package/dist/useVirtualList.js +49 -0
  295. package/dist/useWakeLock.d.ts +12 -0
  296. package/dist/useWakeLock.js +32 -0
  297. package/dist/useWebNotification.d.ts +25 -0
  298. package/dist/useWebNotification.js +39 -0
  299. package/dist/useWebSocket.d.ts +38 -0
  300. package/dist/useWebSocket.js +103 -0
  301. package/dist/useWebWorker.d.ts +18 -0
  302. package/dist/useWebWorker.js +56 -0
  303. package/dist/useWindowFocus.d.ts +5 -0
  304. package/dist/useWindowFocus.js +20 -0
  305. package/dist/useWindowScroll.d.ts +9 -0
  306. package/dist/useWindowScroll.js +17 -0
  307. package/dist/useWindowSize.d.ts +15 -0
  308. package/dist/useWindowSize.js +28 -0
  309. package/dist/watchArray.d.ts +5 -0
  310. package/dist/watchArray.js +9 -0
  311. package/dist/watchAtMost.d.ts +5 -0
  312. package/dist/watchAtMost.js +12 -0
  313. package/dist/watchDebounced.d.ts +23 -0
  314. package/dist/watchDebounced.js +20 -0
  315. package/dist/watchDeep.d.ts +7 -0
  316. package/dist/watchDeep.js +13 -0
  317. package/dist/watchIgnorable.d.ts +12 -0
  318. package/dist/watchIgnorable.js +19 -0
  319. package/dist/watchImmediate.d.ts +5 -0
  320. package/dist/watchImmediate.js +7 -0
  321. package/dist/watchOnce.d.ts +19 -0
  322. package/dist/watchOnce.js +17 -0
  323. package/dist/watchPausable.d.ts +13 -0
  324. package/dist/watchPausable.js +23 -0
  325. package/dist/watchThrottled.d.ts +23 -0
  326. package/dist/watchThrottled.js +37 -0
  327. package/dist/watchTriggerable.d.ts +5 -0
  328. package/dist/watchTriggerable.js +10 -0
  329. package/dist/watchWithFilter.d.ts +7 -0
  330. package/dist/watchWithFilter.js +6 -0
  331. package/dist/whenever.d.ts +18 -0
  332. package/dist/whenever.js +7 -0
  333. package/package.json +2 -2
@@ -0,0 +1,27 @@
1
+ import { onUnmounted, ref } from "@stacksjs/stx";
2
+ import { unref, noop } from "./_shared";
3
+ export function useMutationObserver(target, callback, options) {
4
+ const isSupported = ref(typeof window < "u" && "MutationObserver" in window);
5
+ let cleanup = noop;
6
+ (() => {
7
+ cleanup();
8
+ if (!isSupported.value)
9
+ return;
10
+ const el = unref(target);
11
+ if (!el)
12
+ return;
13
+ const observer = new MutationObserver(callback);
14
+ observer.observe(el, options ?? { childList: !0, subtree: !0 });
15
+ cleanup = () => {
16
+ observer.disconnect();
17
+ cleanup = noop;
18
+ };
19
+ })();
20
+ const stop = () => {
21
+ cleanup();
22
+ };
23
+ try {
24
+ onUnmounted(stop);
25
+ } catch {}
26
+ return { isSupported, stop };
27
+ }
@@ -0,0 +1,5 @@
1
+ import type { Ref } from '@stacksjs/stx';
2
+ /**
3
+ * Reactive navigator language.
4
+ */
5
+ export declare function useNavigatorLanguage(): { language: Ref<string>, isSupported: Ref<boolean> };
@@ -0,0 +1,17 @@
1
+ import { onUnmounted, ref } from "@stacksjs/stx";
2
+ export function useNavigatorLanguage() {
3
+ const isSupported = ref(typeof navigator < "u" && "language" in navigator), language = ref(isSupported.value ? navigator.language : "");
4
+ if (typeof window < "u") {
5
+ const handler = () => {
6
+ if (isSupported.value)
7
+ language.value = navigator.language;
8
+ };
9
+ window.addEventListener("languagechange", handler, { passive: !0 });
10
+ try {
11
+ onUnmounted(() => {
12
+ window.removeEventListener("languagechange", handler);
13
+ });
14
+ } catch {}
15
+ }
16
+ return { language, isSupported };
17
+ }
@@ -0,0 +1,18 @@
1
+ import type { Ref } from '@stacksjs/stx';
2
+ /**
3
+ * Reactive Network Information API.
4
+ */
5
+ export declare function useNetwork(): UseNetworkReturn;
6
+ export declare interface UseNetworkReturn {
7
+ isSupported: Ref<boolean>
8
+ isOnline: Ref<boolean>
9
+ offlineAt: Ref<number | undefined>
10
+ onlineAt: Ref<number | undefined>
11
+ downlink: Ref<number | undefined>
12
+ downlinkMax: Ref<number | undefined>
13
+ effectiveType: Ref<NetworkEffectiveType>
14
+ rtt: Ref<number | undefined>
15
+ saveData: Ref<boolean | undefined>
16
+ type: Ref<string | undefined>
17
+ }
18
+ export type NetworkEffectiveType = 'slow-2g' | '2g' | '3g' | '4g' | undefined;
@@ -0,0 +1,58 @@
1
+ import { onUnmounted, ref } from "@stacksjs/stx";
2
+ export function useNetwork() {
3
+ const isSupported = ref(typeof navigator < "u" && "connection" in navigator), isOnline = ref(typeof navigator < "u" ? navigator.onLine : !0), offlineAt = ref(void 0), onlineAt = ref(void 0), downlink = ref(void 0), downlinkMax = ref(void 0), effectiveType = ref(void 0), rtt = ref(void 0), saveData = ref(void 0), type = ref(void 0);
4
+ function updateNetworkInfo() {
5
+ if (!isSupported.value)
6
+ return;
7
+ const conn = navigator.connection;
8
+ if (conn) {
9
+ downlink.value = conn.downlink;
10
+ downlinkMax.value = conn.downlinkMax;
11
+ effectiveType.value = conn.effectiveType;
12
+ rtt.value = conn.rtt;
13
+ saveData.value = conn.saveData;
14
+ type.value = conn.type;
15
+ }
16
+ }
17
+ updateNetworkInfo();
18
+ if (typeof window < "u") {
19
+ const onOnline = () => {
20
+ isOnline.value = !0;
21
+ onlineAt.value = Date.now();
22
+ }, onOffline = () => {
23
+ isOnline.value = !1;
24
+ offlineAt.value = Date.now();
25
+ };
26
+ window.addEventListener("online", onOnline);
27
+ window.addEventListener("offline", onOffline);
28
+ try {
29
+ onUnmounted(() => {
30
+ window.removeEventListener("online", onOnline);
31
+ window.removeEventListener("offline", onOffline);
32
+ });
33
+ } catch {}
34
+ if (isSupported.value) {
35
+ const conn = navigator.connection;
36
+ if (conn?.addEventListener) {
37
+ conn.addEventListener("change", updateNetworkInfo);
38
+ try {
39
+ onUnmounted(() => {
40
+ conn.removeEventListener("change", updateNetworkInfo);
41
+ });
42
+ } catch {}
43
+ }
44
+ }
45
+ }
46
+ return {
47
+ isSupported,
48
+ isOnline,
49
+ offlineAt,
50
+ onlineAt,
51
+ downlink,
52
+ downlinkMax,
53
+ effectiveType,
54
+ rtt,
55
+ saveData,
56
+ type
57
+ };
58
+ }
@@ -0,0 +1,8 @@
1
+ import type { Ref } from '@stacksjs/stx';
2
+ /**
3
+ * Reactive current time.
4
+ * Returns a ref that updates every `interval` milliseconds.
5
+ *
6
+ * @param options - Configuration with interval (default 1000ms)
7
+ */
8
+ export declare function useNow(options?: { interval?: number }): Ref<Date>;
package/dist/useNow.js ADDED
@@ -0,0 +1,10 @@
1
+ import { onUnmounted, ref } from "@stacksjs/stx";
2
+ export function useNow(options) {
3
+ const interval = options?.interval ?? 1000, now = ref(new Date), timer = setInterval(() => {
4
+ now.value = new Date;
5
+ }, interval);
6
+ try {
7
+ onUnmounted(() => clearInterval(timer));
8
+ } catch {}
9
+ return now;
10
+ }
@@ -0,0 +1,8 @@
1
+ import type { Ref } from '@stacksjs/stx';
2
+ /**
3
+ * Reactive URL representing an object (Blob/File).
4
+ * The URL is automatically revoked when the source changes or on unmount.
5
+ *
6
+ * @param source - A ref containing a Blob, File, MediaSource, or null/undefined
7
+ */
8
+ export declare function useObjectUrl(source: Ref<Blob | File | MediaSource | null | undefined>): Ref<string | undefined>;
@@ -0,0 +1,23 @@
1
+ import { onUnmounted, ref, watch } from "@stacksjs/stx";
2
+ export function useObjectUrl(source) {
3
+ const url = ref(void 0);
4
+ function release() {
5
+ if (url.value) {
6
+ URL.revokeObjectURL(url.value);
7
+ url.value = void 0;
8
+ }
9
+ }
10
+ function update(val) {
11
+ release();
12
+ if (val)
13
+ url.value = URL.createObjectURL(val);
14
+ }
15
+ update(source.value);
16
+ watch(source, (val) => {
17
+ update(val);
18
+ });
19
+ try {
20
+ onUnmounted(() => release());
21
+ } catch {}
22
+ return url;
23
+ }
@@ -0,0 +1,21 @@
1
+ import type { Ref } from '@stacksjs/stx';
2
+ /**
3
+ * Reactive offset-based pagination.
4
+ */
5
+ export declare function useOffsetPagination(options?: UseOffsetPaginationOptions): UseOffsetPaginationReturn;
6
+ export declare interface UseOffsetPaginationOptions {
7
+ total?: Ref<number> | number
8
+ pageSize?: number
9
+ page?: number
10
+ onPageChange?: (returnValue: { currentPage: number, currentPageSize: number }) => void
11
+ onPageSizeChange?: (returnValue: { currentPage: number, currentPageSize: number }) => void
12
+ }
13
+ export declare interface UseOffsetPaginationReturn {
14
+ currentPage: Ref<number>
15
+ currentPageSize: Ref<number>
16
+ pageCount: Ref<number>
17
+ isFirstPage: Ref<boolean>
18
+ isLastPage: Ref<boolean>
19
+ prev: () => void
20
+ next: () => void
21
+ }
@@ -0,0 +1,45 @@
1
+ import { computed, ref, watch } from "@stacksjs/stx";
2
+ export function useOffsetPagination(options = {}) {
3
+ const {
4
+ total: totalOption,
5
+ pageSize = 10,
6
+ page = 1,
7
+ onPageChange,
8
+ onPageSizeChange
9
+ } = options, currentPage = ref(page), currentPageSize = ref(pageSize), totalItems = typeof totalOption === "object" && totalOption && "value" in totalOption ? totalOption : ref(typeof totalOption === "number" ? totalOption : 0), pageCount = ref(Math.max(1, Math.ceil(totalItems.value / currentPageSize.value))), isFirstPage = ref(currentPage.value <= 1), isLastPage = ref(currentPage.value >= pageCount.value);
10
+ function updateComputed() {
11
+ pageCount.value = Math.max(1, Math.ceil(totalItems.value / currentPageSize.value));
12
+ isFirstPage.value = currentPage.value <= 1;
13
+ isLastPage.value = currentPage.value >= pageCount.value;
14
+ }
15
+ watch(currentPage, () => {
16
+ updateComputed();
17
+ onPageChange?.({ currentPage: currentPage.value, currentPageSize: currentPageSize.value });
18
+ });
19
+ watch(currentPageSize, () => {
20
+ currentPage.value = 1;
21
+ updateComputed();
22
+ onPageSizeChange?.({ currentPage: currentPage.value, currentPageSize: currentPageSize.value });
23
+ });
24
+ watch(totalItems, () => {
25
+ updateComputed();
26
+ });
27
+ function prev() {
28
+ if (currentPage.value > 1)
29
+ currentPage.value--;
30
+ }
31
+ function next() {
32
+ if (currentPage.value < pageCount.value)
33
+ currentPage.value++;
34
+ }
35
+ updateComputed();
36
+ return {
37
+ currentPage,
38
+ currentPageSize,
39
+ pageCount,
40
+ isFirstPage,
41
+ isLastPage,
42
+ prev,
43
+ next
44
+ };
45
+ }
@@ -0,0 +1,7 @@
1
+ import type { Ref } from '@stacksjs/stx';
2
+ /**
3
+ * Reactive online status.
4
+ * Tracks navigator.onLine and listens for online/offline events.
5
+ * In non-browser environments, defaults to true.
6
+ */
7
+ export declare function useOnline(): Ref<boolean>;
@@ -0,0 +1,20 @@
1
+ import { onUnmounted, ref } from "@stacksjs/stx";
2
+ export function useOnline() {
3
+ const isOnline = ref(typeof navigator < "u" ? navigator.onLine : !0);
4
+ if (typeof window < "u") {
5
+ const onOnline = () => {
6
+ isOnline.value = !0;
7
+ }, onOffline = () => {
8
+ isOnline.value = !1;
9
+ };
10
+ window.addEventListener("online", onOnline);
11
+ window.addEventListener("offline", onOffline);
12
+ try {
13
+ onUnmounted(() => {
14
+ window.removeEventListener("online", onOnline);
15
+ window.removeEventListener("offline", onOffline);
16
+ });
17
+ } catch {}
18
+ }
19
+ return isOnline;
20
+ }
@@ -0,0 +1,9 @@
1
+ import type { Ref } from '@stacksjs/stx';
2
+ /**
3
+ * Page leave detection.
4
+ * Returns a ref that is true when the mouse has left the page (document).
5
+ * Uses mouseleave and mouseenter events on the document element.
6
+ *
7
+ * @returns A ref that is true when the mouse is outside the page
8
+ */
9
+ export declare function usePageLeave(): Ref<boolean>;
@@ -0,0 +1,27 @@
1
+ import { onUnmounted, ref } from "@stacksjs/stx";
2
+ import { noop } from "./_shared";
3
+ export function usePageLeave() {
4
+ const isLeft = ref(!1);
5
+ let cleanup = noop;
6
+ if (typeof document < "u") {
7
+ const cleanups = [], onLeave = (event) => {
8
+ if (event.clientY <= 0 || event.clientX <= 0 || event.clientX >= (typeof window < "u" ? window.innerWidth : 0) || event.clientY >= (typeof window < "u" ? window.innerHeight : 0))
9
+ isLeft.value = !0;
10
+ }, onEnter = () => {
11
+ isLeft.value = !1;
12
+ };
13
+ document.documentElement.addEventListener("mouseleave", onLeave);
14
+ document.documentElement.addEventListener("mouseenter", onEnter);
15
+ cleanups.push(() => document.documentElement.removeEventListener("mouseleave", onLeave), () => document.documentElement.removeEventListener("mouseenter", onEnter));
16
+ cleanup = () => {
17
+ for (const fn of cleanups)
18
+ fn();
19
+ cleanups.length = 0;
20
+ cleanup = noop;
21
+ };
22
+ }
23
+ try {
24
+ onUnmounted(() => cleanup());
25
+ } catch {}
26
+ return isLeft;
27
+ }
@@ -0,0 +1,15 @@
1
+ import type { MaybeRef } from './_shared';
2
+ import type { Ref } from '@stacksjs/stx';
3
+ /**
4
+ * Reactive parallax effect based on mouse position or device orientation.
5
+ */
6
+ export declare function useParallax(target: MaybeRef<HTMLElement | null | undefined>, options?: UseParallaxOptions): UseParallaxReturn;
7
+ export declare interface UseParallaxReturn {
8
+ tilt: Ref<number>
9
+ roll: Ref<number>
10
+ source: Ref<'mouse' | 'deviceOrientation'>
11
+ }
12
+ export declare interface UseParallaxOptions {
13
+ deviceOrientationTiltAdjust?: (value: number) => number
14
+ deviceOrientationRollAdjust?: (value: number) => number
15
+ }
@@ -0,0 +1,33 @@
1
+ import { onUnmounted, ref } from "@stacksjs/stx";
2
+ import { unref } from "./_shared";
3
+ export function useParallax(target, options = {}) {
4
+ const tilt = ref(0), roll = ref(0), source = ref("mouse");
5
+ if (typeof window > "u")
6
+ return { tilt, roll, source };
7
+ const mouseHandler = (e) => {
8
+ const el = unref(target);
9
+ if (!el)
10
+ return;
11
+ const rect = el.getBoundingClientRect(), centerX = rect.left + rect.width / 2, centerY = rect.top + rect.height / 2;
12
+ tilt.value = (e.clientX - centerX) / (rect.width / 2) * 0.5;
13
+ roll.value = (e.clientY - centerY) / (rect.height / 2) * 0.5;
14
+ source.value = "mouse";
15
+ };
16
+ window.addEventListener("mousemove", mouseHandler, { passive: !0 });
17
+ const orientationHandler = (e) => {
18
+ if (e.gamma !== null && e.beta !== null) {
19
+ const tiltVal = e.gamma / 90, rollVal = (e.beta - 45) / 90;
20
+ tilt.value = options.deviceOrientationTiltAdjust?.(tiltVal) ?? tiltVal * 0.5;
21
+ roll.value = options.deviceOrientationRollAdjust?.(rollVal) ?? rollVal * 0.5;
22
+ source.value = "deviceOrientation";
23
+ }
24
+ };
25
+ window.addEventListener("deviceorientation", orientationHandler, { passive: !0 });
26
+ try {
27
+ onUnmounted(() => {
28
+ window.removeEventListener("mousemove", mouseHandler);
29
+ window.removeEventListener("deviceorientation", orientationHandler);
30
+ });
31
+ } catch {}
32
+ return { tilt, roll, source };
33
+ }
@@ -0,0 +1,6 @@
1
+ import type { MaybeRef } from './_shared';
2
+ import type { Ref } from '@stacksjs/stx';
3
+ /**
4
+ * Get the parent element of a given element.
5
+ */
6
+ export declare function useParentElement(element?: MaybeRef<HTMLElement | null | undefined>): Ref<HTMLElement | null>;
@@ -0,0 +1,8 @@
1
+ import { ref } from "@stacksjs/stx";
2
+ import { unref } from "./_shared";
3
+ export function useParentElement(element) {
4
+ const parent = ref(null), el = unref(element);
5
+ if (el)
6
+ parent.value = el.parentElement;
7
+ return parent;
8
+ }
@@ -0,0 +1,7 @@
1
+ import type { Ref } from '@stacksjs/stx';
2
+ /**
3
+ * Reactive Permissions API.
4
+ *
5
+ * @param permissionName - Name of the permission to query
6
+ */
7
+ export declare function usePermission(permissionName: PermissionName): { state: Ref<PermissionState>, isSupported: Ref<boolean> };
@@ -0,0 +1,21 @@
1
+ import { onUnmounted, ref } from "@stacksjs/stx";
2
+ export function usePermission(permissionName) {
3
+ const isSupported = ref(typeof navigator < "u" && "permissions" in navigator), state = ref("prompt");
4
+ if (!isSupported.value)
5
+ return { state, isSupported };
6
+ let permissionStatus = null;
7
+ navigator.permissions.query({ name: permissionName }).then((status) => {
8
+ permissionStatus = status;
9
+ state.value = status.state;
10
+ const handler = () => {
11
+ state.value = status.state;
12
+ };
13
+ status.addEventListener("change", handler);
14
+ try {
15
+ onUnmounted(() => {
16
+ status.removeEventListener("change", handler);
17
+ });
18
+ } catch {}
19
+ }).catch(() => {});
20
+ return { state, isSupported };
21
+ }
@@ -0,0 +1,15 @@
1
+ import type { Ref } from '@stacksjs/stx';
2
+ /**
3
+ * Reactive pointer position and state.
4
+ */
5
+ export declare function usePointer(target?: HTMLElement | Window): UsePointerReturn;
6
+ export declare interface UsePointerReturn {
7
+ isInside: Ref<boolean>
8
+ x: Ref<number>
9
+ y: Ref<number>
10
+ pointerId: Ref<number>
11
+ pressure: Ref<number>
12
+ tiltX: Ref<number>
13
+ tiltY: Ref<number>
14
+ pointerType: Ref<string>
15
+ }
@@ -0,0 +1,32 @@
1
+ import { onUnmounted, ref } from "@stacksjs/stx";
2
+ export function usePointer(target) {
3
+ const x = ref(0), y = ref(0), pointerId = ref(0), pressure = ref(0), tiltX = ref(0), tiltY = ref(0), pointerType = ref(""), isInside = ref(!1);
4
+ if (typeof window > "u")
5
+ return { isInside, x, y, pointerId, pressure, tiltX, tiltY, pointerType };
6
+ const el = target ?? window, handler = (e) => {
7
+ x.value = e.pageX;
8
+ y.value = e.pageY;
9
+ pointerId.value = e.pointerId;
10
+ pressure.value = e.pressure;
11
+ tiltX.value = e.tiltX;
12
+ tiltY.value = e.tiltY;
13
+ pointerType.value = e.pointerType;
14
+ }, onEnter = () => {
15
+ isInside.value = !0;
16
+ }, onLeave = () => {
17
+ isInside.value = !1;
18
+ };
19
+ el.addEventListener("pointermove", handler, { passive: !0 });
20
+ el.addEventListener("pointerdown", handler, { passive: !0 });
21
+ el.addEventListener("pointerenter", onEnter, { passive: !0 });
22
+ el.addEventListener("pointerleave", onLeave, { passive: !0 });
23
+ try {
24
+ onUnmounted(() => {
25
+ el.removeEventListener("pointermove", handler);
26
+ el.removeEventListener("pointerdown", handler);
27
+ el.removeEventListener("pointerenter", onEnter);
28
+ el.removeEventListener("pointerleave", onLeave);
29
+ });
30
+ } catch {}
31
+ return { isInside, x, y, pointerId, pressure, tiltX, tiltY, pointerType };
32
+ }
@@ -0,0 +1,13 @@
1
+ import type { MaybeRef } from './_shared';
2
+ import type { Ref } from '@stacksjs/stx';
3
+ /**
4
+ * Reactive Pointer Lock API.
5
+ */
6
+ export declare function usePointerLock(target?: MaybeRef<HTMLElement | null | undefined>): UsePointerLockReturn;
7
+ export declare interface UsePointerLockReturn {
8
+ isSupported: Ref<boolean>
9
+ isLocked: Ref<boolean>
10
+ lock: (target?: HTMLElement) => Promise<void>
11
+ unlock: () => void
12
+ element: Ref<Element | null>
13
+ }
@@ -0,0 +1,33 @@
1
+ import { onUnmounted, ref } from "@stacksjs/stx";
2
+ import { unref } from "./_shared";
3
+ export function usePointerLock(target) {
4
+ const isSupported = ref(typeof document < "u" && "pointerLockElement" in document), isLocked = ref(!1), element = ref(null);
5
+ if (typeof document < "u") {
6
+ const handler = () => {
7
+ isLocked.value = !!document.pointerLockElement;
8
+ element.value = document.pointerLockElement;
9
+ };
10
+ document.addEventListener("pointerlockchange", handler);
11
+ document.addEventListener("pointerlockerror", handler);
12
+ try {
13
+ onUnmounted(() => {
14
+ document.removeEventListener("pointerlockchange", handler);
15
+ document.removeEventListener("pointerlockerror", handler);
16
+ });
17
+ } catch {}
18
+ }
19
+ async function lock(el) {
20
+ if (!isSupported.value)
21
+ return;
22
+ const targetEl = el ?? unref(target);
23
+ if (targetEl)
24
+ await targetEl.requestPointerLock();
25
+ }
26
+ function unlock() {
27
+ if (!isSupported.value)
28
+ return;
29
+ if (document.pointerLockElement)
30
+ document.exitPointerLock();
31
+ }
32
+ return { isSupported, isLocked, lock, unlock, element };
33
+ }
@@ -0,0 +1,20 @@
1
+ import type { MaybeRef } from './_shared';
2
+ import type { Ref } from '@stacksjs/stx';
3
+ import type { SwipeDirection } from './useSwipe';
4
+ /**
5
+ * Reactive pointer-based swipe detection.
6
+ */
7
+ export declare function usePointerSwipe(target: MaybeRef<HTMLElement | null | undefined>, options?: UsePointerSwipeOptions): UsePointerSwipeReturn;
8
+ export declare interface UsePointerSwipeOptions {
9
+ threshold?: number
10
+ onSwipe?: (direction: SwipeDirection) => void
11
+ onSwipeEnd?: (e: PointerEvent, direction: SwipeDirection) => void
12
+ }
13
+ export declare interface UsePointerSwipeReturn {
14
+ isSwiping: Ref<boolean>
15
+ direction: Ref<SwipeDirection>
16
+ distanceX: Ref<number>
17
+ distanceY: Ref<number>
18
+ posStart: Ref<{ x: number, y: number }>
19
+ posEnd: Ref<{ x: number, y: number }>
20
+ }
@@ -0,0 +1,52 @@
1
+ import { onUnmounted, ref } from "@stacksjs/stx";
2
+ import { unref } from "./_shared";
3
+ export function usePointerSwipe(target, options = {}) {
4
+ const { threshold = 50, onSwipe, onSwipeEnd } = options, isSwiping = ref(!1), direction = ref("none"), distanceX = ref(0), distanceY = ref(0), posStart = ref({ x: 0, y: 0 }), posEnd = ref({ x: 0, y: 0 });
5
+ if (typeof window > "u")
6
+ return { isSwiping, direction, distanceX, distanceY, posStart, posEnd };
7
+ const el = unref(target);
8
+ if (!el)
9
+ return { isSwiping, direction, distanceX, distanceY, posStart, posEnd };
10
+ const onPointerDown = (e) => {
11
+ isSwiping.value = !0;
12
+ direction.value = "none";
13
+ posStart.value = { x: e.clientX, y: e.clientY };
14
+ posEnd.value = { x: e.clientX, y: e.clientY };
15
+ distanceX.value = 0;
16
+ distanceY.value = 0;
17
+ el.setPointerCapture(e.pointerId);
18
+ }, onPointerMove = (e) => {
19
+ if (!isSwiping.value)
20
+ return;
21
+ posEnd.value = { x: e.clientX, y: e.clientY };
22
+ distanceX.value = posEnd.value.x - posStart.value.x;
23
+ distanceY.value = posEnd.value.y - posStart.value.y;
24
+ const absX = Math.abs(distanceX.value), absY = Math.abs(distanceY.value);
25
+ if (absX > absY)
26
+ direction.value = distanceX.value > 0 ? "right" : "left";
27
+ else if (absY > absX)
28
+ direction.value = distanceY.value > 0 ? "down" : "up";
29
+ }, onPointerUp = (e) => {
30
+ if (!isSwiping.value)
31
+ return;
32
+ isSwiping.value = !1;
33
+ if (Math.max(Math.abs(distanceX.value), Math.abs(distanceY.value)) >= threshold) {
34
+ onSwipe?.(direction.value);
35
+ onSwipeEnd?.(e, direction.value);
36
+ } else {
37
+ direction.value = "none";
38
+ onSwipeEnd?.(e, "none");
39
+ }
40
+ };
41
+ el.addEventListener("pointerdown", onPointerDown);
42
+ el.addEventListener("pointermove", onPointerMove);
43
+ el.addEventListener("pointerup", onPointerUp);
44
+ try {
45
+ onUnmounted(() => {
46
+ el.removeEventListener("pointerdown", onPointerDown);
47
+ el.removeEventListener("pointermove", onPointerMove);
48
+ el.removeEventListener("pointerup", onPointerUp);
49
+ });
50
+ } catch {}
51
+ return { isSwiping, direction, distanceX, distanceY, posStart, posEnd };
52
+ }
@@ -0,0 +1,6 @@
1
+ import type { Ref } from '@stacksjs/stx';
2
+ /**
3
+ * Reactive preferred color scheme.
4
+ */
5
+ export declare function usePreferredColorScheme(): Ref<ColorSchemeType>;
6
+ export type ColorSchemeType = 'dark' | 'light' | 'no-preference';
@@ -0,0 +1,25 @@
1
+ import { onUnmounted, ref } from "@stacksjs/stx";
2
+ export function usePreferredColorScheme() {
3
+ const scheme = ref("no-preference");
4
+ if (typeof window > "u" || !window.matchMedia)
5
+ return scheme;
6
+ const dark = window.matchMedia("(prefers-color-scheme: dark)"), light = window.matchMedia("(prefers-color-scheme: light)");
7
+ function update() {
8
+ if (dark.matches)
9
+ scheme.value = "dark";
10
+ else if (light.matches)
11
+ scheme.value = "light";
12
+ else
13
+ scheme.value = "no-preference";
14
+ }
15
+ update();
16
+ dark.addEventListener("change", update);
17
+ light.addEventListener("change", update);
18
+ try {
19
+ onUnmounted(() => {
20
+ dark.removeEventListener("change", update);
21
+ light.removeEventListener("change", update);
22
+ });
23
+ } catch {}
24
+ return scheme;
25
+ }
@@ -0,0 +1,6 @@
1
+ import type { Ref } from '@stacksjs/stx';
2
+ /**
3
+ * Reactive preferred contrast.
4
+ */
5
+ export declare function usePreferredContrast(): Ref<ContrastType>;
6
+ export type ContrastType = 'more' | 'less' | 'custom' | 'no-preference';