@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,25 @@
1
+ import { computed, ref, watch } from "@stacksjs/stx";
2
+ import { toValue } from "./_shared";
3
+ export function useToNumber(value, options = {}) {
4
+ const { method = "parseFloat", radix = 10, nanToZero = !1 } = options, result = ref(0);
5
+ function convert(val) {
6
+ if (typeof val === "number")
7
+ return val;
8
+ let num;
9
+ if (method === "parseInt")
10
+ num = Number.parseInt(val, radix);
11
+ else
12
+ num = Number.parseFloat(val);
13
+ if (nanToZero && Number.isNaN(num))
14
+ return 0;
15
+ return num;
16
+ }
17
+ result.value = convert(toValue(value));
18
+ if (typeof value === "function")
19
+ ;
20
+ else if (value && typeof value === "object" && "value" in value && "subscribe" in value)
21
+ watch(value, (newVal) => {
22
+ result.value = convert(newVal);
23
+ });
24
+ return result;
25
+ }
@@ -0,0 +1,6 @@
1
+ import type { MaybeRefOrGetter } from './_shared';
2
+ import type { Ref } from '@stacksjs/stx';
3
+ /**
4
+ * Reactively convert a value to a string.
5
+ */
6
+ export declare function useToString(value: MaybeRefOrGetter<any>): Ref<string>;
@@ -0,0 +1,10 @@
1
+ import { ref, watch } from "@stacksjs/stx";
2
+ import { isRef, toValue } from "./_shared";
3
+ export function useToString(value) {
4
+ const result = ref(String(toValue(value) ?? ""));
5
+ if (isRef(value))
6
+ watch(value, (newVal) => {
7
+ result.value = String(newVal ?? "");
8
+ });
9
+ return result;
10
+ }
@@ -0,0 +1,6 @@
1
+ import type { Ref } from '@stacksjs/stx';
2
+ /**
3
+ * Simple boolean toggle.
4
+ * Returns [state, toggleFn] where toggleFn flips the boolean or sets a specific value.
5
+ */
6
+ export declare function useToggle(initialValue?: Ref<boolean> | boolean): [Ref<boolean>, (value?: boolean) => boolean];
@@ -0,0 +1,12 @@
1
+ import { ref } from "@stacksjs/stx";
2
+ export function useToggle(initialValue = !1) {
3
+ const state = typeof initialValue === "boolean" ? ref(initialValue) : initialValue;
4
+ function toggle(value) {
5
+ if (typeof value === "boolean")
6
+ state.value = value;
7
+ else
8
+ state.value = !state.value;
9
+ return state.value;
10
+ }
11
+ return [state, toggle];
12
+ }
@@ -0,0 +1,28 @@
1
+ import type { MaybeRef } from './_shared';
2
+ import type { Ref } from '@stacksjs/stx';
3
+ /**
4
+ * Reactive value transition. Smoothly transitions between values over time.
5
+ */
6
+ export declare function useTransition(source: MaybeRef<number>, options?: UseTransitionOptions): Ref<number>;
7
+ /**
8
+ * Execute a transition between values.
9
+ */
10
+ export declare function executeTransition(_from: number, _to: number, options?: UseTransitionOptions): Promise<void>;
11
+ // Common easing functions
12
+ export declare const TransitionPresets: {
13
+ linear: (t: number) => number;
14
+ easeInQuad: (t: number) => number;
15
+ easeOutQuad: (t: number) => number;
16
+ easeInOutQuad: (t: number) => number;
17
+ easeInCubic: (t: number) => number;
18
+ easeOutCubic: (t: number) => unknown;
19
+ easeInOutCubic: (t: number) => number
20
+ };
21
+ export declare interface UseTransitionOptions {
22
+ duration?: number
23
+ transition?: TransitionFunction
24
+ delay?: number
25
+ onFinished?: () => void
26
+ onStarted?: () => void
27
+ }
28
+ export type TransitionFunction = (_t: number) => number;
@@ -0,0 +1,89 @@
1
+ import { onUnmounted, ref, watch } from "@stacksjs/stx";
2
+ import { unref } from "./_shared";
3
+ export const TransitionPresets = {
4
+ linear: (t) => t,
5
+ easeInQuad: (t) => t * t,
6
+ easeOutQuad: (t) => t * (2 - t),
7
+ easeInOutQuad: (t) => t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t,
8
+ easeInCubic: (t) => t * t * t,
9
+ easeOutCubic: (t) => --t * t * t + 1,
10
+ easeInOutCubic: (t) => t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1
11
+ };
12
+ export function useTransition(source, options = {}) {
13
+ const {
14
+ duration = 300,
15
+ transition = TransitionPresets.linear,
16
+ delay = 0,
17
+ onFinished,
18
+ onStarted
19
+ } = options, output = ref(unref(source));
20
+ let rafId = null;
21
+ function startTransition(from, to) {
22
+ if (rafId !== null)
23
+ cancelAnimationFrame(rafId);
24
+ const start = performance.now() + delay;
25
+ onStarted?.();
26
+ function tick(now) {
27
+ const elapsed = now - start;
28
+ if (elapsed < 0) {
29
+ rafId = requestAnimationFrame(tick);
30
+ return;
31
+ }
32
+ const progress = Math.min(elapsed / duration, 1), eased = transition(progress);
33
+ output.value = from + (to - from) * eased;
34
+ if (progress < 1)
35
+ rafId = requestAnimationFrame(tick);
36
+ else {
37
+ rafId = null;
38
+ output.value = to;
39
+ onFinished?.();
40
+ }
41
+ }
42
+ rafId = requestAnimationFrame(tick);
43
+ }
44
+ if (typeof source === "object" && source && "value" in source && "subscribe" in source)
45
+ watch(source, (newValue) => {
46
+ if (typeof requestAnimationFrame < "u")
47
+ startTransition(output.value, newValue);
48
+ else
49
+ output.value = newValue;
50
+ });
51
+ try {
52
+ onUnmounted(() => {
53
+ if (rafId !== null)
54
+ cancelAnimationFrame(rafId);
55
+ });
56
+ } catch {}
57
+ return output;
58
+ }
59
+ export function executeTransition(_from, _to, options = {}) {
60
+ return new Promise((resolve) => {
61
+ const {
62
+ duration = 300,
63
+ transition = TransitionPresets.linear,
64
+ delay = 0,
65
+ onFinished,
66
+ onStarted
67
+ } = options;
68
+ if (typeof requestAnimationFrame > "u") {
69
+ onFinished?.();
70
+ resolve();
71
+ return;
72
+ }
73
+ const start = performance.now() + delay;
74
+ onStarted?.();
75
+ function tick(now) {
76
+ const elapsed = now - start;
77
+ if (elapsed < 0) {
78
+ requestAnimationFrame(tick);
79
+ return;
80
+ }
81
+ if (Math.min(elapsed / duration, 1) >= 1) {
82
+ onFinished?.();
83
+ resolve();
84
+ } else
85
+ requestAnimationFrame(tick);
86
+ }
87
+ requestAnimationFrame(tick);
88
+ });
89
+ }
@@ -0,0 +1,18 @@
1
+ import type { Ref } from '@stacksjs/stx';
2
+ /**
3
+ * Reactive URL search params.
4
+ * Reads and writes query string parameters reactively.
5
+ *
6
+ * @param mode - 'history' for URL search params, 'hash' for hash-based params
7
+ * @param options - Configuration options
8
+ */
9
+ export declare function useUrlSearchParams<T extends Record<string, string> = Record<string, string>>(mode?: 'history' | 'hash', options?: UseUrlSearchParamsOptions<T>): UseUrlSearchParamsReturn;
10
+ export declare interface UseUrlSearchParamsOptions<T extends Record<string, string> = Record<string, string>> {
11
+ initialValue?: T
12
+ }
13
+ export declare interface UseUrlSearchParamsReturn {
14
+ params: Ref<Record<string, string>>
15
+ get: (key: string) => string | null
16
+ set: (key: string, value: string) => void
17
+ delete: (key: string) => void
18
+ }
@@ -0,0 +1,72 @@
1
+ import { onUnmounted, ref } from "@stacksjs/stx";
2
+ import { defaultWindow } from "./_shared";
3
+ export function useUrlSearchParams(mode = "history", options) {
4
+ const win = defaultWindow(), { initialValue } = options ?? {};
5
+ function readParams() {
6
+ if (!win)
7
+ return { ...initialValue };
8
+ let search = "";
9
+ if (mode === "hash") {
10
+ const hash = win.location.hash, idx = hash.indexOf("?");
11
+ search = idx >= 0 ? hash.slice(idx + 1) : "";
12
+ } else
13
+ search = win.location.search.slice(1);
14
+ const result = { ...initialValue };
15
+ new URLSearchParams(search).forEach((value, key) => {
16
+ result[key] = value;
17
+ });
18
+ return result;
19
+ }
20
+ const params = ref(readParams());
21
+ function writeParams() {
22
+ if (!win)
23
+ return;
24
+ const searchParams = new URLSearchParams;
25
+ for (const [key, value] of Object.entries(params.value))
26
+ if (value !== void 0 && value !== null && value !== "")
27
+ searchParams.set(key, value);
28
+ const query = searchParams.toString();
29
+ if (mode === "hash") {
30
+ const basePath = win.location.hash.split("?")[0] || "#";
31
+ win.location.hash = query ? `${basePath}?${query}` : basePath;
32
+ } else {
33
+ const url = query ? `${win.location.pathname}?${query}` : win.location.pathname;
34
+ win.history.replaceState(win.history.state, "", url);
35
+ }
36
+ }
37
+ function get(key) {
38
+ return params.value[key] ?? null;
39
+ }
40
+ function set(key, value) {
41
+ const current = { ...params.value };
42
+ current[key] = value;
43
+ params.value = current;
44
+ writeParams();
45
+ }
46
+ function del(key) {
47
+ const current = { ...params.value };
48
+ delete current[key];
49
+ params.value = current;
50
+ writeParams();
51
+ }
52
+ if (win) {
53
+ const onPopState = () => {
54
+ params.value = readParams();
55
+ }, onHashChange = () => {
56
+ if (mode === "hash")
57
+ params.value = readParams();
58
+ };
59
+ win.addEventListener("popstate", onPopState);
60
+ win.addEventListener("hashchange", onHashChange);
61
+ onUnmounted(() => {
62
+ win.removeEventListener("popstate", onPopState);
63
+ win.removeEventListener("hashchange", onHashChange);
64
+ });
65
+ }
66
+ return {
67
+ params,
68
+ get,
69
+ set,
70
+ delete: del
71
+ };
72
+ }
@@ -0,0 +1,13 @@
1
+ import type { Ref } from '@stacksjs/stx';
2
+ /**
3
+ * Reactive Vibration API.
4
+ */
5
+ export declare function useVibrate(options?: UseVibrateOptions): UseVibrateReturn;
6
+ export declare interface UseVibrateOptions {
7
+ pattern?: number | number[]
8
+ }
9
+ export declare interface UseVibrateReturn {
10
+ isSupported: Ref<boolean>
11
+ vibrate: (pattern?: number | number[]) => boolean
12
+ stop: () => void
13
+ }
@@ -0,0 +1,14 @@
1
+ import { ref } from "@stacksjs/stx";
2
+ export function useVibrate(options = {}) {
3
+ const { pattern = 200 } = options, isSupported = ref(typeof navigator < "u" && "vibrate" in navigator);
4
+ function vibrate(p) {
5
+ if (!isSupported.value)
6
+ return !1;
7
+ return navigator.vibrate(p ?? pattern);
8
+ }
9
+ function stop() {
10
+ if (isSupported.value)
11
+ navigator.vibrate(0);
12
+ }
13
+ return { isSupported, vibrate, stop };
14
+ }
@@ -0,0 +1,23 @@
1
+ import type { MaybeRef } from './_shared';
2
+ import type { Ref } from '@stacksjs/stx';
3
+ /**
4
+ * Virtual list for efficiently rendering large lists.
5
+ */
6
+ export declare function useVirtualList<T>(source: MaybeRef<T[]>, options: UseVirtualListOptions): UseVirtualListReturn<T>;
7
+ export declare interface UseVirtualListOptions {
8
+ itemHeight: number
9
+ overscan?: number
10
+ }
11
+ export declare interface UseVirtualListItem<T> {
12
+ data: T
13
+ index: number
14
+ }
15
+ export declare interface UseVirtualListReturn<T> {
16
+ list: Ref<UseVirtualListItem<T>[]>
17
+ containerProps: {
18
+ onScroll: (e: Event) => void
19
+ style: { overflow: string, position: string }
20
+ }
21
+ wrapperProps: Ref<{ style: { width: string, height: string, marginTop: string } }>
22
+ scrollTo: (index: number) => void
23
+ }
@@ -0,0 +1,49 @@
1
+ import { ref, watch } from "@stacksjs/stx";
2
+ import { unref } from "./_shared";
3
+ export function useVirtualList(source, options) {
4
+ const { itemHeight, overscan = 5 } = options, list = ref([]), containerHeight = ref(0), scrollTop = ref(0), wrapperProps = ref({
5
+ style: { width: "100%", height: "0px", marginTop: "0px" }
6
+ });
7
+ function getItems() {
8
+ return unref(source);
9
+ }
10
+ function update() {
11
+ const items = getItems(), totalHeight = items.length * itemHeight, startIndex = Math.max(0, Math.floor(scrollTop.value / itemHeight) - overscan), endIndex = Math.min(items.length, Math.ceil((scrollTop.value + containerHeight.value) / itemHeight) + overscan), visibleItems = [];
12
+ for (let i = startIndex;i < endIndex; i++) {
13
+ const data = items[i];
14
+ if (data === void 0 && !(i in items))
15
+ continue;
16
+ visibleItems.push({ data, index: i });
17
+ }
18
+ list.value = visibleItems;
19
+ wrapperProps.value = {
20
+ style: {
21
+ width: "100%",
22
+ height: `${totalHeight - startIndex * itemHeight}px`,
23
+ marginTop: `${startIndex * itemHeight}px`
24
+ }
25
+ };
26
+ }
27
+ const onScroll = (e) => {
28
+ const target = e.target;
29
+ scrollTop.value = target.scrollTop;
30
+ containerHeight.value = target.clientHeight;
31
+ update();
32
+ };
33
+ update();
34
+ if (typeof source === "object" && source && "value" in source && "subscribe" in source)
35
+ watch(source, () => update());
36
+ function scrollTo(index) {
37
+ scrollTop.value = index * itemHeight;
38
+ update();
39
+ }
40
+ return {
41
+ list,
42
+ containerProps: {
43
+ onScroll,
44
+ style: { overflow: "auto", position: "relative" }
45
+ },
46
+ wrapperProps,
47
+ scrollTo
48
+ };
49
+ }
@@ -0,0 +1,12 @@
1
+ import type { Ref } from '@stacksjs/stx';
2
+ /**
3
+ * Reactive Screen Wake Lock API.
4
+ * Prevents the screen from dimming/locking.
5
+ */
6
+ export declare function useWakeLock(): UseWakeLockReturn;
7
+ export declare interface UseWakeLockReturn {
8
+ isSupported: Ref<boolean>
9
+ isActive: Ref<boolean>
10
+ request: () => Promise<void>
11
+ release: () => Promise<void>
12
+ }
@@ -0,0 +1,32 @@
1
+ import { onUnmounted, ref } from "@stacksjs/stx";
2
+ export function useWakeLock() {
3
+ const isSupported = ref(typeof navigator < "u" && "wakeLock" in navigator), isActive = ref(!1);
4
+ let sentinel = null;
5
+ async function request() {
6
+ if (!isSupported.value)
7
+ return;
8
+ try {
9
+ sentinel = await navigator.wakeLock.request("screen");
10
+ isActive.value = !0;
11
+ sentinel.addEventListener("release", () => {
12
+ isActive.value = !1;
13
+ sentinel = null;
14
+ });
15
+ } catch {
16
+ isActive.value = !1;
17
+ }
18
+ }
19
+ async function release() {
20
+ if (sentinel) {
21
+ await sentinel.release();
22
+ sentinel = null;
23
+ isActive.value = !1;
24
+ }
25
+ }
26
+ try {
27
+ onUnmounted(() => {
28
+ release();
29
+ });
30
+ } catch {}
31
+ return { isSupported, isActive, request, release };
32
+ }
@@ -0,0 +1,25 @@
1
+ import type { Ref } from '@stacksjs/stx';
2
+ /**
3
+ * Reactive Web Notification API.
4
+ */
5
+ export declare function useWebNotification(options?: UseWebNotificationOptions): UseWebNotificationReturn;
6
+ export declare interface UseWebNotificationOptions {
7
+ title?: string
8
+ body?: string
9
+ icon?: string
10
+ dir?: NotificationDirection
11
+ lang?: string
12
+ tag?: string
13
+ requireInteraction?: boolean
14
+ }
15
+ export declare interface UseWebNotificationReturn {
16
+ isSupported: Ref<boolean>
17
+ notification: Ref<Notification | null>
18
+ permissionGranted: Ref<boolean>
19
+ show: (overrideOptions?: UseWebNotificationOptions) => Promise<Notification | undefined>
20
+ close: () => void
21
+ onClick: Ref<((_evt: Event) => void) | null>
22
+ onShow: Ref<((_evt: Event) => void) | null>
23
+ onError: Ref<((_evt: Event) => void) | null>
24
+ onClose: Ref<((_evt: Event) => void) | null>
25
+ }
@@ -0,0 +1,39 @@
1
+ import { onUnmounted, ref } from "@stacksjs/stx";
2
+ export function useWebNotification(options = {}) {
3
+ const isSupported = ref(typeof Notification < "u"), notification = ref(null), permissionGranted = ref(isSupported.value && Notification.permission === "granted"), onClick = ref(null), onShow = ref(null), onError = ref(null), onClose = ref(null);
4
+ async function show(overrideOptions) {
5
+ if (!isSupported.value)
6
+ return;
7
+ if (Notification.permission !== "granted") {
8
+ const result = await Notification.requestPermission();
9
+ permissionGranted.value = result === "granted";
10
+ if (!permissionGranted.value)
11
+ return;
12
+ }
13
+ const opts = { ...options, ...overrideOptions }, title = opts.title ?? "", n = new Notification(title, {
14
+ body: opts.body,
15
+ icon: opts.icon,
16
+ dir: opts.dir,
17
+ lang: opts.lang,
18
+ tag: opts.tag,
19
+ requireInteraction: opts.requireInteraction
20
+ });
21
+ notification.value = n;
22
+ n.onclick = (e) => onClick.value?.(e);
23
+ n.onshow = (e) => onShow.value?.(e);
24
+ n.onerror = (e) => onError.value?.(e);
25
+ n.onclose = (e) => {
26
+ onClose.value?.(e);
27
+ notification.value = null;
28
+ };
29
+ return n;
30
+ }
31
+ function close() {
32
+ notification.value?.close();
33
+ notification.value = null;
34
+ }
35
+ try {
36
+ onUnmounted(() => close());
37
+ } catch {}
38
+ return { isSupported, notification, permissionGranted, show, close, onClick, onShow, onError, onClose };
39
+ }
@@ -0,0 +1,38 @@
1
+ import type { MaybeRefOrGetter } from './_shared';
2
+ import type { Ref } from '@stacksjs/stx';
3
+ /**
4
+ * Reactive WebSocket connection.
5
+ *
6
+ * @param url - The WebSocket URL (can be a ref, getter, or raw string)
7
+ * @param options - Configuration options
8
+ * @returns Reactive WebSocket state and control methods
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * const { data, status, send, close } = useWebSocket('ws://localhost:8080', {
13
+ * onConnected(ws) { console.log('Connected') },
14
+ * onMessage(ws, event) { console.log('Message:', event.data) },
15
+ * autoReconnect: { retries: 3, delay: 1000 },
16
+ * })
17
+ * ```
18
+ */
19
+ export declare function useWebSocket(url: MaybeRefOrGetter<string>, options?: UseWebSocketOptions): UseWebSocketReturn;
20
+ export declare interface UseWebSocketOptions {
21
+ onConnected?: (ws: WebSocket) => void
22
+ onDisconnected?: (ws: WebSocket, event: CloseEvent) => void
23
+ onError?: (ws: WebSocket, event: Event) => void
24
+ onMessage?: (ws: WebSocket, event: MessageEvent) => void
25
+ immediate?: boolean
26
+ autoReconnect?: boolean | { retries?: number, delay?: number }
27
+ heartbeat?: boolean | { interval?: number, message?: string }
28
+ protocols?: string | string[]
29
+ }
30
+ export declare interface UseWebSocketReturn {
31
+ data: Ref<string | null>
32
+ status: Ref<WebSocketStatus>
33
+ ws: Ref<WebSocket | null>
34
+ open: () => void
35
+ close: (code?: number, reason?: string) => void
36
+ send: (data: string | ArrayBuffer | Blob) => void
37
+ }
38
+ export type WebSocketStatus = 'CONNECTING' | 'OPEN' | 'CLOSING' | 'CLOSED';
@@ -0,0 +1,103 @@
1
+ import { onUnmounted, ref } from "@stacksjs/stx";
2
+ import { toValue } from "./_shared";
3
+ export function useWebSocket(url, options = {}) {
4
+ const {
5
+ onConnected,
6
+ onDisconnected,
7
+ onError,
8
+ onMessage,
9
+ immediate = !0,
10
+ autoReconnect = !1,
11
+ heartbeat = !1,
12
+ protocols
13
+ } = options, data = ref(null), status = ref("CLOSED"), wsRef = ref(null);
14
+ let retryCount = 0, retryTimer = null, heartbeatTimer = null, explicitlyClosed = !1;
15
+ const heartbeatInterval = typeof heartbeat === "object" ? heartbeat.interval ?? 30000 : 30000, heartbeatMessage = typeof heartbeat === "object" ? heartbeat.message ?? "ping" : "ping", maxRetries = typeof autoReconnect === "object" ? autoReconnect.retries ?? 3 : autoReconnect ? 1 / 0 : 0, retryDelay = typeof autoReconnect === "object" ? autoReconnect.delay ?? 1000 : 1000;
16
+ function startHeartbeat(ws) {
17
+ stopHeartbeat();
18
+ if (!heartbeat)
19
+ return;
20
+ heartbeatTimer = setInterval(() => {
21
+ if (ws.readyState === WebSocket.OPEN)
22
+ ws.send(heartbeatMessage);
23
+ }, heartbeatInterval);
24
+ }
25
+ function stopHeartbeat() {
26
+ if (heartbeatTimer !== null) {
27
+ clearInterval(heartbeatTimer);
28
+ heartbeatTimer = null;
29
+ }
30
+ }
31
+ function open() {
32
+ if (typeof WebSocket > "u")
33
+ return;
34
+ close();
35
+ explicitlyClosed = !1;
36
+ retryCount = 0;
37
+ const resolvedUrl = toValue(url);
38
+ status.value = "CONNECTING";
39
+ const ws = protocols ? new WebSocket(resolvedUrl, protocols) : new WebSocket(resolvedUrl);
40
+ wsRef.value = ws;
41
+ ws.onopen = () => {
42
+ status.value = "OPEN";
43
+ retryCount = 0;
44
+ startHeartbeat(ws);
45
+ onConnected?.(ws);
46
+ };
47
+ ws.onclose = (event) => {
48
+ status.value = "CLOSED";
49
+ wsRef.value = null;
50
+ stopHeartbeat();
51
+ onDisconnected?.(ws, event);
52
+ if (!explicitlyClosed && autoReconnect && retryCount < maxRetries) {
53
+ retryCount++;
54
+ retryTimer = setTimeout(() => {
55
+ open();
56
+ }, retryDelay);
57
+ }
58
+ };
59
+ ws.onerror = (event) => {
60
+ onError?.(ws, event);
61
+ };
62
+ ws.onmessage = (event) => {
63
+ data.value = typeof event.data === "string" ? event.data : String(event.data);
64
+ onMessage?.(ws, event);
65
+ };
66
+ }
67
+ function close(code, reason) {
68
+ explicitlyClosed = !0;
69
+ stopHeartbeat();
70
+ if (retryTimer !== null) {
71
+ clearTimeout(retryTimer);
72
+ retryTimer = null;
73
+ }
74
+ const ws = wsRef.value;
75
+ if (ws) {
76
+ if (ws.readyState === WebSocket.OPEN || ws.readyState === WebSocket.CONNECTING) {
77
+ status.value = "CLOSING";
78
+ ws.close(code, reason);
79
+ }
80
+ wsRef.value = null;
81
+ }
82
+ }
83
+ function send(sendData) {
84
+ const ws = wsRef.value;
85
+ if (ws && ws.readyState === WebSocket.OPEN)
86
+ ws.send(sendData);
87
+ }
88
+ if (immediate)
89
+ open();
90
+ try {
91
+ onUnmounted(() => {
92
+ close();
93
+ });
94
+ } catch {}
95
+ return {
96
+ data,
97
+ status,
98
+ ws: wsRef,
99
+ open,
100
+ close,
101
+ send
102
+ };
103
+ }
@@ -0,0 +1,18 @@
1
+ import type { Ref } from '@stacksjs/stx';
2
+ /**
3
+ * Reactive Web Worker.
4
+ */
5
+ export declare function useWebWorker(url: string | URL, workerOptions?: WorkerOptions): UseWebWorkerReturn;
6
+ /**
7
+ * Run a function in a Web Worker via inline blob.
8
+ */
9
+ export declare function useWebWorkerFn<T extends (...args: any[]) => any>(fn: T): {
10
+ workerFn: (...args: Parameters<T>) => Promise<ReturnType<T>>
11
+ terminate: () => void
12
+ };
13
+ export declare interface UseWebWorkerReturn {
14
+ data: Ref<any>
15
+ post: (message: any) => void
16
+ terminate: () => void
17
+ worker: Ref<Worker | undefined>
18
+ }