@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
+ export function useScreenOrientation() {
3
+ const isSupported = ref(typeof screen < "u" && "orientation" in screen), orientation = ref(void 0), angle = ref(0);
4
+ if (isSupported.value) {
5
+ orientation.value = screen.orientation.type;
6
+ angle.value = screen.orientation.angle;
7
+ const handler = () => {
8
+ orientation.value = screen.orientation.type;
9
+ angle.value = screen.orientation.angle;
10
+ };
11
+ screen.orientation.addEventListener("change", handler);
12
+ try {
13
+ onUnmounted(() => {
14
+ screen.orientation.removeEventListener("change", handler);
15
+ });
16
+ } catch {}
17
+ }
18
+ async function lockOrientation(type) {
19
+ if (isSupported.value)
20
+ await screen.orientation.lock(type);
21
+ }
22
+ function unlockOrientation() {
23
+ if (isSupported.value)
24
+ screen.orientation.unlock();
25
+ }
26
+ return { isSupported, orientation, angle, lockOrientation, unlockOrientation };
27
+ }
@@ -0,0 +1,12 @@
1
+ import type { Ref } from '@stacksjs/stx';
2
+ /**
3
+ * Reactive `env(safe-area-inset-*)` values.
4
+ */
5
+ export declare function useScreenSafeArea(): UseScreenSafeAreaReturn;
6
+ export declare interface UseScreenSafeAreaReturn {
7
+ top: Ref<string>
8
+ right: Ref<string>
9
+ bottom: Ref<string>
10
+ left: Ref<string>
11
+ update: () => void
12
+ }
@@ -0,0 +1,25 @@
1
+ import { ref } from "@stacksjs/stx";
2
+ export function useScreenSafeArea() {
3
+ const top = ref("0px"), right = ref("0px"), bottom = ref("0px"), left = ref("0px");
4
+ function update() {
5
+ if (typeof document > "u" || typeof getComputedStyle > "u")
6
+ return;
7
+ const div = document.createElement("div");
8
+ div.style.position = "fixed";
9
+ div.style.top = "env(safe-area-inset-top, 0px)";
10
+ div.style.right = "env(safe-area-inset-right, 0px)";
11
+ div.style.bottom = "env(safe-area-inset-bottom, 0px)";
12
+ div.style.left = "env(safe-area-inset-left, 0px)";
13
+ div.style.pointerEvents = "none";
14
+ div.style.visibility = "hidden";
15
+ document.body.appendChild(div);
16
+ const style = getComputedStyle(div);
17
+ top.value = style.top;
18
+ right.value = style.right;
19
+ bottom.value = style.bottom;
20
+ left.value = style.left;
21
+ document.body.removeChild(div);
22
+ }
23
+ update();
24
+ return { top, right, bottom, left, update };
25
+ }
@@ -0,0 +1,20 @@
1
+ import type { Ref } from '@stacksjs/stx';
2
+ /**
3
+ * Inject a script tag into the document.
4
+ */
5
+ export declare function useScriptTag(src: string, onLoaded?: (el: HTMLScriptElement) => void, options?: UseScriptTagOptions): UseScriptTagReturn;
6
+ export declare interface UseScriptTagOptions {
7
+ immediate?: boolean
8
+ type?: string
9
+ async?: boolean
10
+ defer?: boolean
11
+ crossOrigin?: string
12
+ referrerPolicy?: string
13
+ manual?: boolean
14
+ attrs?: Record<string, string>
15
+ }
16
+ export declare interface UseScriptTagReturn {
17
+ scriptTag: Ref<HTMLScriptElement | null>
18
+ load: () => Promise<HTMLScriptElement>
19
+ unload: () => void
20
+ }
@@ -0,0 +1,52 @@
1
+ import { onUnmounted, ref } from "@stacksjs/stx";
2
+ export function useScriptTag(src, onLoaded, options = {}) {
3
+ const {
4
+ immediate = !0,
5
+ type = "text/javascript",
6
+ manual = !1,
7
+ attrs = {}
8
+ } = options, scriptTag = ref(null);
9
+ function load() {
10
+ return new Promise((resolve, reject) => {
11
+ if (typeof document > "u") {
12
+ reject(Error("Document is not available"));
13
+ return;
14
+ }
15
+ const el = document.createElement("script");
16
+ el.type = type;
17
+ el.src = src;
18
+ if (options.async)
19
+ el.async = !0;
20
+ if (options.defer)
21
+ el.defer = !0;
22
+ if (options.crossOrigin)
23
+ el.crossOrigin = options.crossOrigin;
24
+ if (options.referrerPolicy)
25
+ el.referrerPolicy = options.referrerPolicy;
26
+ for (const [key, value] of Object.entries(attrs))
27
+ el.setAttribute(key, value);
28
+ el.addEventListener("load", () => {
29
+ scriptTag.value = el;
30
+ onLoaded?.(el);
31
+ resolve(el);
32
+ });
33
+ el.addEventListener("error", (event) => {
34
+ reject(event);
35
+ });
36
+ document.head.appendChild(el);
37
+ });
38
+ }
39
+ function unload() {
40
+ if (scriptTag.value) {
41
+ scriptTag.value.remove();
42
+ scriptTag.value = null;
43
+ }
44
+ }
45
+ if (immediate)
46
+ load();
47
+ if (!manual)
48
+ try {
49
+ onUnmounted(() => unload());
50
+ } catch {}
51
+ return { scriptTag, load, unload };
52
+ }
@@ -0,0 +1,36 @@
1
+ import type { MaybeRef } from './_shared';
2
+ import type { Ref } from '@stacksjs/stx';
3
+ /**
4
+ * Reactive scroll position tracking.
5
+ * Tracks scroll position, scrolling state, arrived edges, and scroll directions.
6
+ *
7
+ * @param target - Scroll target element or window
8
+ * @param options - Configuration options
9
+ */
10
+ export declare function useScroll(target?: MaybeRef<HTMLElement | Window | Document | null>, options?: UseScrollOptions): UseScrollReturn;
11
+ export declare interface UseScrollOptions {
12
+ throttle?: number
13
+ offset?: {
14
+ top?: number
15
+ bottom?: number
16
+ left?: number
17
+ right?: number
18
+ }
19
+ }
20
+ export declare interface UseScrollReturn {
21
+ x: Ref<number>
22
+ y: Ref<number>
23
+ isScrolling: Ref<boolean>
24
+ arrivedState: {
25
+ top: Ref<boolean>
26
+ bottom: Ref<boolean>
27
+ left: Ref<boolean>
28
+ right: Ref<boolean>
29
+ }
30
+ directions: {
31
+ top: Ref<boolean>
32
+ bottom: Ref<boolean>
33
+ left: Ref<boolean>
34
+ right: Ref<boolean>
35
+ }
36
+ }
@@ -0,0 +1,116 @@
1
+ import { onUnmounted, ref } from "@stacksjs/stx";
2
+ import { unref } from "./_shared";
3
+ export function useScroll(target, options) {
4
+ const { throttle = 0, offset = {} } = options ?? {}, offsetTop = offset.top ?? 0, offsetBottom = offset.bottom ?? 0, offsetLeft = offset.left ?? 0, offsetRight = offset.right ?? 0, x = ref(0), y = ref(0), isScrolling = ref(!1), arrivedTop = ref(!0), arrivedBottom = ref(!1), arrivedLeft = ref(!0), arrivedRight = ref(!1), dirTop = ref(!1), dirBottom = ref(!1), dirLeft = ref(!1), dirRight = ref(!1);
5
+ let scrollingTimer, lastX = 0, lastY = 0, throttleTimer, isThrottled = !1;
6
+ function getScrollPosition(el) {
7
+ if (typeof window < "u" && el === window || "innerHeight" in el && "scrollX" in el) {
8
+ const win = el, doc = typeof document < "u" ? document : void 0;
9
+ return {
10
+ scrollLeft: win.scrollX ?? win.pageXOffset ?? 0,
11
+ scrollTop: win.scrollY ?? win.pageYOffset ?? 0,
12
+ scrollHeight: doc?.documentElement?.scrollHeight ?? 0,
13
+ scrollWidth: doc?.documentElement?.scrollWidth ?? 0,
14
+ clientHeight: win.innerHeight,
15
+ clientWidth: win.innerWidth
16
+ };
17
+ }
18
+ if (typeof document < "u" && el === document || "documentElement" in el) {
19
+ const docEl = el.documentElement;
20
+ return {
21
+ scrollLeft: docEl.scrollLeft,
22
+ scrollTop: docEl.scrollTop,
23
+ scrollHeight: docEl.scrollHeight,
24
+ scrollWidth: docEl.scrollWidth,
25
+ clientHeight: docEl.clientHeight,
26
+ clientWidth: docEl.clientWidth
27
+ };
28
+ }
29
+ const htmlEl = el;
30
+ return {
31
+ scrollLeft: htmlEl.scrollLeft,
32
+ scrollTop: htmlEl.scrollTop,
33
+ scrollHeight: htmlEl.scrollHeight,
34
+ scrollWidth: htmlEl.scrollWidth,
35
+ clientHeight: htmlEl.clientHeight,
36
+ clientWidth: htmlEl.clientWidth
37
+ };
38
+ }
39
+ function update() {
40
+ const el = target ? unref(target) : typeof window < "u" ? window : null;
41
+ if (!el)
42
+ return;
43
+ const pos = getScrollPosition(el);
44
+ dirTop.value = pos.scrollTop < lastY;
45
+ dirBottom.value = pos.scrollTop > lastY;
46
+ dirLeft.value = pos.scrollLeft < lastX;
47
+ dirRight.value = pos.scrollLeft > lastX;
48
+ lastX = pos.scrollLeft;
49
+ lastY = pos.scrollTop;
50
+ x.value = pos.scrollLeft;
51
+ y.value = pos.scrollTop;
52
+ arrivedTop.value = pos.scrollTop <= offsetTop;
53
+ arrivedLeft.value = pos.scrollLeft <= offsetLeft;
54
+ arrivedBottom.value = pos.scrollTop + pos.clientHeight >= pos.scrollHeight - offsetBottom;
55
+ arrivedRight.value = pos.scrollLeft + pos.clientWidth >= pos.scrollWidth - offsetRight;
56
+ isScrolling.value = !0;
57
+ if (scrollingTimer)
58
+ clearTimeout(scrollingTimer);
59
+ scrollingTimer = setTimeout(() => {
60
+ isScrolling.value = !1;
61
+ }, 150);
62
+ }
63
+ function onScroll() {
64
+ if (throttle > 0) {
65
+ if (!isThrottled) {
66
+ update();
67
+ isThrottled = !0;
68
+ throttleTimer = setTimeout(() => {
69
+ isThrottled = !1;
70
+ }, throttle);
71
+ }
72
+ } else
73
+ update();
74
+ }
75
+ if (typeof window < "u") {
76
+ const el = target ? unref(target) : window;
77
+ if (el) {
78
+ const pos = getScrollPosition(el);
79
+ x.value = pos.scrollLeft;
80
+ y.value = pos.scrollTop;
81
+ lastX = pos.scrollLeft;
82
+ lastY = pos.scrollTop;
83
+ arrivedTop.value = pos.scrollTop <= offsetTop;
84
+ arrivedLeft.value = pos.scrollLeft <= offsetLeft;
85
+ arrivedBottom.value = pos.scrollTop + pos.clientHeight >= pos.scrollHeight - offsetBottom;
86
+ arrivedRight.value = pos.scrollLeft + pos.clientWidth >= pos.scrollWidth - offsetRight;
87
+ el.addEventListener("scroll", onScroll, { passive: !0 });
88
+ try {
89
+ onUnmounted(() => {
90
+ el.removeEventListener("scroll", onScroll);
91
+ if (scrollingTimer)
92
+ clearTimeout(scrollingTimer);
93
+ if (throttleTimer)
94
+ clearTimeout(throttleTimer);
95
+ });
96
+ } catch {}
97
+ }
98
+ }
99
+ return {
100
+ x,
101
+ y,
102
+ isScrolling,
103
+ arrivedState: {
104
+ top: arrivedTop,
105
+ bottom: arrivedBottom,
106
+ left: arrivedLeft,
107
+ right: arrivedRight
108
+ },
109
+ directions: {
110
+ top: dirTop,
111
+ bottom: dirBottom,
112
+ left: dirLeft,
113
+ right: dirRight
114
+ }
115
+ };
116
+ }
@@ -0,0 +1,10 @@
1
+ import type { MaybeRef } from './_shared';
2
+ import type { Ref } from '@stacksjs/stx';
3
+ /**
4
+ * Reactive scroll lock.
5
+ * Returns a writable ref: set to true to lock scrolling, false to unlock.
6
+ * Sets `overflow: hidden` on the target element.
7
+ *
8
+ * @param element - Target element to lock (defaults to document.body)
9
+ */
10
+ export declare function useScrollLock(element?: MaybeRef<HTMLElement | null>): Ref<boolean>;
@@ -0,0 +1,39 @@
1
+ import { onUnmounted, ref, watch } from "@stacksjs/stx";
2
+ import { unref } from "./_shared";
3
+ export function useScrollLock(element) {
4
+ const isLocked = ref(!1);
5
+ let originalOverflow = "";
6
+ function getElement() {
7
+ if (element)
8
+ return unref(element);
9
+ if (typeof document < "u")
10
+ return document.body;
11
+ return null;
12
+ }
13
+ function lock() {
14
+ const el = getElement();
15
+ if (!el)
16
+ return;
17
+ originalOverflow = el.style.overflow;
18
+ el.style.overflow = "hidden";
19
+ }
20
+ function unlock() {
21
+ const el = getElement();
22
+ if (!el)
23
+ return;
24
+ el.style.overflow = originalOverflow;
25
+ }
26
+ watch(isLocked, (val) => {
27
+ if (val)
28
+ lock();
29
+ else
30
+ unlock();
31
+ });
32
+ try {
33
+ onUnmounted(() => {
34
+ if (isLocked.value)
35
+ unlock();
36
+ });
37
+ } catch {}
38
+ return isLocked;
39
+ }
@@ -0,0 +1,17 @@
1
+ import type { Ref } from '@stacksjs/stx';
2
+ /**
3
+ * Reactive sessionStorage wrapper.
4
+ * Convenience composable that delegates to useStorage with sessionStorage.
5
+ *
6
+ * @param key - Storage key
7
+ * @param defaultValue - Default value when key doesn't exist
8
+ * @param options - Serializer options
9
+ */
10
+ export declare function useSessionStorage<T>(key: string, defaultValue: T, options?: UseSessionStorageOptions<T>): Ref<T>;
11
+ declare interface UseSessionStorageSerializer<T> {
12
+ read: (raw: string) => T
13
+ write: (value: T) => string
14
+ }
15
+ declare interface UseSessionStorageOptions<T> {
16
+ serializer?: UseSessionStorageSerializer<T>
17
+ }
@@ -0,0 +1,4 @@
1
+ import { useStorage } from "./useStorage";
2
+ export function useSessionStorage(key, defaultValue, options) {
3
+ return useStorage(key, defaultValue, typeof sessionStorage < "u" ? sessionStorage : void 0, options);
4
+ }
@@ -0,0 +1,15 @@
1
+ import type { Ref } from '@stacksjs/stx';
2
+ /**
3
+ * Reactive Web Share API.
4
+ */
5
+ export declare function useShare(options?: UseShareOptions): UseShareReturn;
6
+ export declare interface UseShareOptions {
7
+ title?: string
8
+ text?: string
9
+ url?: string
10
+ files?: File[]
11
+ }
12
+ export declare interface UseShareReturn {
13
+ share: (overrideOptions?: UseShareOptions) => Promise<void>
14
+ isSupported: Ref<boolean>
15
+ }
@@ -0,0 +1,11 @@
1
+ import { ref } from "@stacksjs/stx";
2
+ export function useShare(options = {}) {
3
+ const isSupported = ref(typeof navigator < "u" && "share" in navigator);
4
+ async function share(overrideOptions) {
5
+ if (!isSupported.value)
6
+ return;
7
+ const shareData = { ...options, ...overrideOptions };
8
+ await navigator.share(shareData);
9
+ }
10
+ return { share, isSupported };
11
+ }
@@ -0,0 +1,10 @@
1
+ import type { MaybeRef } from './_shared';
2
+ import type { Ref } from '@stacksjs/stx';
3
+ /**
4
+ * Reactive sorted array. Returns a computed ref containing a sorted copy
5
+ * of the source array.
6
+ *
7
+ * @param source - Source array (raw or ref)
8
+ * @param compareFn - Optional comparison function (defaults to natural order)
9
+ */
10
+ export declare function useSorted<T>(source: MaybeRef<T[]>, compareFn?: (a: T, b: T) => number): Ref<T[]>;
@@ -0,0 +1,10 @@
1
+ import { computed } from "@stacksjs/stx";
2
+ import { unref } from "./_shared";
3
+ export function useSorted(source, compareFn) {
4
+ return computed(() => {
5
+ const arr = [...unref(source)];
6
+ if (compareFn)
7
+ return arr.sort(compareFn);
8
+ return arr.sort();
9
+ });
10
+ }
@@ -0,0 +1,23 @@
1
+ import type { Ref } from '@stacksjs/stx';
2
+ /**
3
+ * Step-by-step navigation composable.
4
+ * Provides reactive state and controls for stepping through an ordered list.
5
+ *
6
+ * @param steps - Array of step values
7
+ * @param initialStep - Optional initial step (defaults to first step)
8
+ */
9
+ export declare function useStepper<T>(steps: T[], initialStep?: T): UseStepperReturn<T>;
10
+ export declare interface UseStepperReturn<T> {
11
+ steps: Ref<T[]>
12
+ current: Ref<T>
13
+ index: Ref<number>
14
+ isFirst: Ref<boolean>
15
+ isLast: Ref<boolean>
16
+ next: () => void
17
+ previous: () => void
18
+ goTo: (step: T) => void
19
+ goToIndex: (index: number) => void
20
+ isBefore: (step: T) => boolean
21
+ isAfter: (step: T) => boolean
22
+ isCurrent: (step: T) => boolean
23
+ }
@@ -0,0 +1,46 @@
1
+ import { computed, ref } from "@stacksjs/stx";
2
+ export function useStepper(steps, initialStep) {
3
+ const stepsRef = ref([...steps]), initialIndex = initialStep !== void 0 ? steps.indexOf(initialStep) : 0, index = ref(initialIndex >= 0 ? initialIndex : 0), current = computed(() => stepsRef.value[index.value]), isFirst = computed(() => index.value === 0), isLast = computed(() => index.value === stepsRef.value.length - 1);
4
+ function next() {
5
+ if (index.value < stepsRef.value.length - 1)
6
+ index.value++;
7
+ }
8
+ function previous() {
9
+ if (index.value > 0)
10
+ index.value--;
11
+ }
12
+ function goTo(step) {
13
+ const idx = stepsRef.value.indexOf(step);
14
+ if (idx >= 0)
15
+ index.value = idx;
16
+ }
17
+ function goToIndex(idx) {
18
+ if (idx >= 0 && idx < stepsRef.value.length)
19
+ index.value = idx;
20
+ }
21
+ function isBefore(step) {
22
+ const stepIndex = stepsRef.value.indexOf(step);
23
+ return stepIndex >= 0 && index.value < stepIndex;
24
+ }
25
+ function isAfter(step) {
26
+ const stepIndex = stepsRef.value.indexOf(step);
27
+ return stepIndex >= 0 && index.value > stepIndex;
28
+ }
29
+ function isCurrent(step) {
30
+ return stepsRef.value[index.value] === step;
31
+ }
32
+ return {
33
+ steps: stepsRef,
34
+ current,
35
+ index,
36
+ isFirst,
37
+ isLast,
38
+ next,
39
+ previous,
40
+ goTo,
41
+ goToIndex,
42
+ isBefore,
43
+ isAfter,
44
+ isCurrent
45
+ };
46
+ }
@@ -0,0 +1,18 @@
1
+ import type { Ref } from '@stacksjs/stx';
2
+ /**
3
+ * Reactive localStorage/sessionStorage wrapper.
4
+ * Creates a stx ref that syncs with browser storage.
5
+ *
6
+ * @param key - Storage key
7
+ * @param defaultValue - Default value when key doesn't exist
8
+ * @param storage - Storage backend (defaults to localStorage)
9
+ * @param options - Serializer options
10
+ */
11
+ export declare function useStorage<T>(key: string, defaultValue: T, storage?: Storage, options?: UseStorageOptions<T>): Ref<T>;
12
+ declare interface UseStorageSerializer<T> {
13
+ read: (raw: string) => T
14
+ write: (value: T) => string
15
+ }
16
+ declare interface UseStorageOptions<T> {
17
+ serializer?: UseStorageSerializer<T>
18
+ }
@@ -0,0 +1,54 @@
1
+ import { onUnmounted, ref, watch } from "@stacksjs/stx";
2
+ export function useStorage(key, defaultValue, storage, options) {
3
+ const store = storage ?? (typeof localStorage < "u" ? localStorage : void 0), serializer = options?.serializer ?? {
4
+ read: (raw) => {
5
+ try {
6
+ return JSON.parse(raw);
7
+ } catch {
8
+ return raw;
9
+ }
10
+ },
11
+ write: (value) => JSON.stringify(value)
12
+ };
13
+ let initialValue = defaultValue;
14
+ if (store)
15
+ try {
16
+ const raw = store.getItem(key);
17
+ if (raw !== null)
18
+ initialValue = serializer.read(raw);
19
+ } catch {}
20
+ const data = ref(initialValue);
21
+ watch(data, (val) => {
22
+ if (!store)
23
+ return;
24
+ try {
25
+ if (val === null || val === void 0)
26
+ store.removeItem(key);
27
+ else
28
+ store.setItem(key, serializer.write(val));
29
+ } catch (err) {
30
+ const name = err?.name ?? "", msg = err?.message ?? String(err);
31
+ if (name === "QuotaExceededError" || /quota/i.test(msg))
32
+ console.warn(`[useStorage] ${key}: storage quota exceeded \u2014 value not persisted.`);
33
+ else
34
+ console.warn(`[useStorage] ${key}: failed to persist value \u2014 ${msg}`);
35
+ }
36
+ });
37
+ if (typeof window < "u") {
38
+ const onStorageChange = (e) => {
39
+ if (e.key !== key || e.storageArea !== store)
40
+ return;
41
+ if (e.newValue === null)
42
+ data.value = defaultValue;
43
+ else
44
+ try {
45
+ data.value = serializer.read(e.newValue);
46
+ } catch {
47
+ data.value = defaultValue;
48
+ }
49
+ };
50
+ window.addEventListener("storage", onStorageChange);
51
+ onUnmounted(() => window.removeEventListener("storage", onStorageChange));
52
+ }
53
+ return data;
54
+ }
@@ -0,0 +1,17 @@
1
+ import type { Ref } from '@stacksjs/stx';
2
+ /**
3
+ * Inject a style tag into the document head.
4
+ */
5
+ export declare function useStyleTag(initialCss: string, options?: UseStyleTagOptions): UseStyleTagReturn;
6
+ export declare interface UseStyleTagOptions {
7
+ immediate?: boolean
8
+ id?: string
9
+ media?: string
10
+ }
11
+ export declare interface UseStyleTagReturn {
12
+ id: string
13
+ css: Ref<string>
14
+ load: () => void
15
+ unload: () => void
16
+ isLoaded: Ref<boolean>
17
+ }
@@ -0,0 +1,39 @@
1
+ import { onUnmounted, ref, watch } from "@stacksjs/stx";
2
+ export function useStyleTag(initialCss, options = {}) {
3
+ const {
4
+ immediate = !0,
5
+ id = `style-${Math.random().toString(36).slice(2, 9)}`,
6
+ media
7
+ } = options, css = ref(initialCss), isLoaded = ref(!1);
8
+ let styleEl = null;
9
+ function load() {
10
+ if (typeof document > "u")
11
+ return;
12
+ if (styleEl)
13
+ return;
14
+ styleEl = document.createElement("style");
15
+ styleEl.id = id;
16
+ if (media)
17
+ styleEl.media = media;
18
+ styleEl.textContent = css.value;
19
+ document.head.appendChild(styleEl);
20
+ isLoaded.value = !0;
21
+ }
22
+ function unload() {
23
+ if (styleEl) {
24
+ styleEl.remove();
25
+ styleEl = null;
26
+ isLoaded.value = !1;
27
+ }
28
+ }
29
+ watch(css, (val) => {
30
+ if (styleEl)
31
+ styleEl.textContent = val;
32
+ });
33
+ if (immediate)
34
+ load();
35
+ try {
36
+ onUnmounted(() => unload());
37
+ } catch {}
38
+ return { id, css, load, unload, isLoaded };
39
+ }
@@ -0,0 +1,8 @@
1
+ import type { Ref } from '@stacksjs/stx';
2
+ /**
3
+ * Check if a browser feature is supported.
4
+ *
5
+ * @param callback - A function that returns true if the feature is supported
6
+ * @returns A reactive ref indicating support status
7
+ */
8
+ export declare function useSupported(callback: () => boolean): Ref<boolean>;
@@ -0,0 +1,10 @@
1
+ import { ref } from "@stacksjs/stx";
2
+ export function useSupported(callback) {
3
+ const isSupported = ref(!1);
4
+ try {
5
+ isSupported.value = callback();
6
+ } catch {
7
+ isSupported.value = !1;
8
+ }
9
+ return isSupported;
10
+ }
@@ -0,0 +1,20 @@
1
+ import type { MaybeRef } from './_shared';
2
+ import type { Ref } from '@stacksjs/stx';
3
+ /**
4
+ * Reactive swipe detection.
5
+ */
6
+ export declare function useSwipe(target: MaybeRef<HTMLElement | Window | null | undefined>, options?: UseSwipeOptions): UseSwipeReturn;
7
+ export declare interface UseSwipeOptions {
8
+ threshold?: number
9
+ onSwipe?: (direction: SwipeDirection) => void
10
+ onSwipeStart?: (e: TouchEvent) => void
11
+ onSwipeEnd?: (e: TouchEvent, direction: SwipeDirection) => void
12
+ passive?: boolean
13
+ }
14
+ export declare interface UseSwipeReturn {
15
+ isSwiping: Ref<boolean>
16
+ direction: Ref<SwipeDirection>
17
+ lengthX: Ref<number>
18
+ lengthY: Ref<number>
19
+ }
20
+ export type SwipeDirection = 'up' | 'down' | 'left' | 'right' | 'none';