@stacksjs/composables 0.70.258 → 0.70.260

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 (167) hide show
  1. package/dist/_shared.js +1 -23
  2. package/dist/cloneFnJSON.js +1 -3
  3. package/dist/computedAsync.js +1 -20
  4. package/dist/computedEager.js +1 -10
  5. package/dist/createEventHook.js +1 -15
  6. package/dist/createFetch.js +1 -8
  7. package/dist/createGlobalState.js +1 -10
  8. package/dist/createSharedComposable.js +1 -9
  9. package/dist/extendRef.js +1 -6
  10. package/dist/formatTimeAgo.js +1 -33
  11. package/dist/index.js +1 -210
  12. package/dist/isDefined.js +1 -3
  13. package/dist/makeDestructurable.js +1 -16
  14. package/dist/onClickOutside.js +1 -25
  15. package/dist/onKeyStroke.js +1 -31
  16. package/dist/onLongPress.js +1 -43
  17. package/dist/onStartTyping.js +1 -23
  18. package/dist/refAutoReset.js +1 -15
  19. package/dist/refDefault.js +1 -8
  20. package/dist/resolveRef.js +1 -7
  21. package/dist/ssrHandlers.js +1 -8
  22. package/dist/syncRef.js +1 -35
  23. package/dist/tryOnMounted.js +1 -22
  24. package/dist/unrefElement.js +1 -9
  25. package/dist/until.js +1 -62
  26. package/dist/useActiveElement.js +1 -19
  27. package/dist/useAnimate.js +1 -48
  28. package/dist/useArrayUtils.js +1 -114
  29. package/dist/useAsyncQueue.js +1 -22
  30. package/dist/useAsyncState.js +1 -35
  31. package/dist/useBase64.js +1 -45
  32. package/dist/useBattery.js +1 -38
  33. package/dist/useBreakpoints.js +1 -97
  34. package/dist/useBroadcastChannel.js +1 -31
  35. package/dist/useBrowserLocation.js +1 -64
  36. package/dist/useClipboard.js +1 -32
  37. package/dist/useClipboardItems.js +1 -15
  38. package/dist/useCloned.js +1 -16
  39. package/dist/useColorMode.js +1 -60
  40. package/dist/useConfirmDialog.js +1 -34
  41. package/dist/useCounter.js +1 -28
  42. package/dist/useCssVar.js +1 -23
  43. package/dist/useCycleList.js +1 -27
  44. package/dist/useDark.js +1 -38
  45. package/dist/useDateFormat.js +1 -11
  46. package/dist/useDebounce.js +1 -16
  47. package/dist/useDebounceFn.js +1 -18
  48. package/dist/useDebouncedRef.js +1 -22
  49. package/dist/useDebouncedRefHistory.js +1 -36
  50. package/dist/useDeviceMotion.js +1 -53
  51. package/dist/useDeviceOrientation.js +1 -23
  52. package/dist/useDevicePixelRatio.js +1 -24
  53. package/dist/useDocumentVisibility.js +1 -16
  54. package/dist/useDraggable.js +1 -58
  55. package/dist/useDropZone.js +1 -52
  56. package/dist/useElementBounding.js +1 -59
  57. package/dist/useElementByPoint.js +1 -18
  58. package/dist/useElementHover.js +1 -28
  59. package/dist/useElementSize.js +1 -34
  60. package/dist/useElementVisibility.js +1 -10
  61. package/dist/useEventBus.js +1 -41
  62. package/dist/useEventListener.js +1 -29
  63. package/dist/useEventSource.js +1 -72
  64. package/dist/useEyeDropper.js +1 -17
  65. package/dist/useFavicon.js +1 -22
  66. package/dist/useFetch.js +1 -61
  67. package/dist/useFileDialog.js +1 -24
  68. package/dist/useFocus.js +1 -42
  69. package/dist/useFocusWithin.js +1 -29
  70. package/dist/useForm.js +1 -182
  71. package/dist/useFps.js +1 -22
  72. package/dist/useFullscreen.js +1 -67
  73. package/dist/useGeolocation.js +1 -55
  74. package/dist/useIdle.js +1 -46
  75. package/dist/useImage.js +1 -32
  76. package/dist/useInfiniteScroll.js +1 -50
  77. package/dist/useIntersectionObserver.js +1 -27
  78. package/dist/useInterval.js +1 -32
  79. package/dist/useIntervalFn.js +1 -24
  80. package/dist/useKeyModifier.js +1 -22
  81. package/dist/useLastChanged.js +1 -8
  82. package/dist/useLocalStorage.js +1 -4
  83. package/dist/useMagicKeys.js +1 -81
  84. package/dist/useManualRefHistory.js +1 -64
  85. package/dist/useMath.js +1 -52
  86. package/dist/useMediaQuery.js +1 -19
  87. package/dist/useMemoize.js +1 -24
  88. package/dist/useMounted.js +1 -8
  89. package/dist/useMouse.js +1 -67
  90. package/dist/useMouseInElement.js +1 -31
  91. package/dist/useMousePressed.js +1 -31
  92. package/dist/useMutationObserver.js +1 -27
  93. package/dist/useNavigatorLanguage.js +1 -17
  94. package/dist/useNetwork.js +1 -58
  95. package/dist/useNow.js +1 -10
  96. package/dist/useObjectUrl.js +1 -23
  97. package/dist/useOffsetPagination.js +1 -45
  98. package/dist/useOnline.js +1 -20
  99. package/dist/usePageLeave.js +1 -27
  100. package/dist/useParallax.js +1 -33
  101. package/dist/useParentElement.js +1 -8
  102. package/dist/usePermission.js +1 -21
  103. package/dist/usePointer.js +1 -32
  104. package/dist/usePointerLock.js +1 -33
  105. package/dist/usePointerSwipe.js +1 -52
  106. package/dist/usePreferredColorScheme.js +1 -25
  107. package/dist/usePreferredContrast.js +1 -29
  108. package/dist/usePreferredLanguages.js +1 -16
  109. package/dist/usePreferredReducedMotion.js +1 -18
  110. package/dist/usePrevious.js +1 -8
  111. package/dist/useQuery.js +1 -265
  112. package/dist/useRafFn.js +1 -37
  113. package/dist/useRefHistory.js +1 -72
  114. package/dist/useResizeObserver.js +1 -27
  115. package/dist/useScreenOrientation.js +1 -27
  116. package/dist/useScreenSafeArea.js +1 -25
  117. package/dist/useScriptTag.js +1 -52
  118. package/dist/useScroll.js +1 -116
  119. package/dist/useScrollLock.js +1 -39
  120. package/dist/useSessionStorage.js +1 -4
  121. package/dist/useShare.js +1 -11
  122. package/dist/useSorted.js +1 -10
  123. package/dist/useStepper.js +1 -46
  124. package/dist/useStorage.js +1 -54
  125. package/dist/useStyleTag.js +1 -39
  126. package/dist/useSupported.js +1 -10
  127. package/dist/useSwipe.js +1 -58
  128. package/dist/useTextDirection.js +1 -16
  129. package/dist/useTextSelection.js +1 -27
  130. package/dist/useTextareaAutosize.js +1 -20
  131. package/dist/useThrottle.js +1 -23
  132. package/dist/useThrottleFn.js +1 -36
  133. package/dist/useThrottledRef.js +1 -30
  134. package/dist/useThrottledRefHistory.js +1 -43
  135. package/dist/useTimeAgo.js +1 -58
  136. package/dist/useTimeout.js +1 -32
  137. package/dist/useTimeoutFn.js +1 -27
  138. package/dist/useTimeoutPoll.js +1 -33
  139. package/dist/useTimestamp.js +1 -43
  140. package/dist/useTitle.js +1 -12
  141. package/dist/useToNumber.js +1 -25
  142. package/dist/useToString.js +1 -10
  143. package/dist/useToggle.js +1 -12
  144. package/dist/useTransition.js +1 -89
  145. package/dist/useUrlSearchParams.js +1 -72
  146. package/dist/useVibrate.js +1 -14
  147. package/dist/useVirtualList.js +1 -49
  148. package/dist/useWakeLock.js +1 -32
  149. package/dist/useWebNotification.js +1 -39
  150. package/dist/useWebSocket.js +1 -103
  151. package/dist/useWebWorker.js +1 -56
  152. package/dist/useWindowFocus.js +1 -20
  153. package/dist/useWindowScroll.js +1 -17
  154. package/dist/useWindowSize.js +1 -28
  155. package/dist/watchArray.js +1 -9
  156. package/dist/watchAtMost.js +1 -12
  157. package/dist/watchDebounced.js +1 -20
  158. package/dist/watchDeep.js +1 -13
  159. package/dist/watchIgnorable.js +1 -19
  160. package/dist/watchImmediate.js +1 -7
  161. package/dist/watchOnce.js +1 -17
  162. package/dist/watchPausable.js +1 -23
  163. package/dist/watchThrottled.js +1 -37
  164. package/dist/watchTriggerable.js +1 -10
  165. package/dist/watchWithFilter.js +1 -6
  166. package/dist/whenever.js +1 -7
  167. package/package.json +2 -2
@@ -1,33 +1 @@
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
- }
1
+ import{onUnmounted,ref}from"@stacksjs/stx";import{unref}from"./_shared";export function useParallax(target,options={}){const tilt=ref(0),roll=ref(0),source=ref("mouse");if(typeof window>"u")return{tilt,roll,source};const mouseHandler=(e)=>{const el=unref(target);if(!el)return;const rect=el.getBoundingClientRect(),centerX=rect.left+rect.width/2,centerY=rect.top+rect.height/2;tilt.value=(e.clientX-centerX)/(rect.width/2)*0.5;roll.value=(e.clientY-centerY)/(rect.height/2)*0.5;source.value="mouse"};window.addEventListener("mousemove",mouseHandler,{passive:!0});const orientationHandler=(e)=>{if(e.gamma!==null&&e.beta!==null){const tiltVal=e.gamma/90,rollVal=(e.beta-45)/90;tilt.value=options.deviceOrientationTiltAdjust?.(tiltVal)??tiltVal*0.5;roll.value=options.deviceOrientationRollAdjust?.(rollVal)??rollVal*0.5;source.value="deviceOrientation"}};window.addEventListener("deviceorientation",orientationHandler,{passive:!0});try{onUnmounted(()=>{window.removeEventListener("mousemove",mouseHandler);window.removeEventListener("deviceorientation",orientationHandler)})}catch{}return{tilt,roll,source}}
@@ -1,8 +1 @@
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
- }
1
+ import{ref}from"@stacksjs/stx";import{unref}from"./_shared";export function useParentElement(element){const parent=ref(null),el=unref(element);if(el)parent.value=el.parentElement;return parent}
@@ -1,21 +1 @@
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
- }
1
+ import{onUnmounted,ref}from"@stacksjs/stx";export function usePermission(permissionName){const isSupported=ref(typeof navigator<"u"&&"permissions"in navigator),state=ref("prompt");if(!isSupported.value)return{state,isSupported};let permissionStatus=null;navigator.permissions.query({name:permissionName}).then((status)=>{permissionStatus=status;state.value=status.state;const handler=()=>{state.value=status.state};status.addEventListener("change",handler);try{onUnmounted(()=>{status.removeEventListener("change",handler)})}catch{}}).catch(()=>{});return{state,isSupported}}
@@ -1,32 +1 @@
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
- }
1
+ import{onUnmounted,ref}from"@stacksjs/stx";export function usePointer(target){const x=ref(0),y=ref(0),pointerId=ref(0),pressure=ref(0),tiltX=ref(0),tiltY=ref(0),pointerType=ref(""),isInside=ref(!1);if(typeof window>"u")return{isInside,x,y,pointerId,pressure,tiltX,tiltY,pointerType};const el=target??window,handler=(e)=>{x.value=e.pageX;y.value=e.pageY;pointerId.value=e.pointerId;pressure.value=e.pressure;tiltX.value=e.tiltX;tiltY.value=e.tiltY;pointerType.value=e.pointerType},onEnter=()=>{isInside.value=!0},onLeave=()=>{isInside.value=!1};el.addEventListener("pointermove",handler,{passive:!0});el.addEventListener("pointerdown",handler,{passive:!0});el.addEventListener("pointerenter",onEnter,{passive:!0});el.addEventListener("pointerleave",onLeave,{passive:!0});try{onUnmounted(()=>{el.removeEventListener("pointermove",handler);el.removeEventListener("pointerdown",handler);el.removeEventListener("pointerenter",onEnter);el.removeEventListener("pointerleave",onLeave)})}catch{}return{isInside,x,y,pointerId,pressure,tiltX,tiltY,pointerType}}
@@ -1,33 +1 @@
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
- }
1
+ import{onUnmounted,ref}from"@stacksjs/stx";import{unref}from"./_shared";export function usePointerLock(target){const isSupported=ref(typeof document<"u"&&"pointerLockElement"in document),isLocked=ref(!1),element=ref(null);if(typeof document<"u"){const handler=()=>{isLocked.value=!!document.pointerLockElement;element.value=document.pointerLockElement};document.addEventListener("pointerlockchange",handler);document.addEventListener("pointerlockerror",handler);try{onUnmounted(()=>{document.removeEventListener("pointerlockchange",handler);document.removeEventListener("pointerlockerror",handler)})}catch{}}async function lock(el){if(!isSupported.value)return;const targetEl=el??unref(target);if(targetEl)await targetEl.requestPointerLock()}function unlock(){if(!isSupported.value)return;if(document.pointerLockElement)document.exitPointerLock()}return{isSupported,isLocked,lock,unlock,element}}
@@ -1,52 +1 @@
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
- }
1
+ import{onUnmounted,ref}from"@stacksjs/stx";import{unref}from"./_shared";export function usePointerSwipe(target,options={}){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});if(typeof window>"u")return{isSwiping,direction,distanceX,distanceY,posStart,posEnd};const el=unref(target);if(!el)return{isSwiping,direction,distanceX,distanceY,posStart,posEnd};const onPointerDown=(e)=>{isSwiping.value=!0;direction.value="none";posStart.value={x:e.clientX,y:e.clientY};posEnd.value={x:e.clientX,y:e.clientY};distanceX.value=0;distanceY.value=0;el.setPointerCapture(e.pointerId)},onPointerMove=(e)=>{if(!isSwiping.value)return;posEnd.value={x:e.clientX,y:e.clientY};distanceX.value=posEnd.value.x-posStart.value.x;distanceY.value=posEnd.value.y-posStart.value.y;const absX=Math.abs(distanceX.value),absY=Math.abs(distanceY.value);if(absX>absY)direction.value=distanceX.value>0?"right":"left";else if(absY>absX)direction.value=distanceY.value>0?"down":"up"},onPointerUp=(e)=>{if(!isSwiping.value)return;isSwiping.value=!1;if(Math.max(Math.abs(distanceX.value),Math.abs(distanceY.value))>=threshold){onSwipe?.(direction.value);onSwipeEnd?.(e,direction.value)}else{direction.value="none";onSwipeEnd?.(e,"none")}};el.addEventListener("pointerdown",onPointerDown);el.addEventListener("pointermove",onPointerMove);el.addEventListener("pointerup",onPointerUp);try{onUnmounted(()=>{el.removeEventListener("pointerdown",onPointerDown);el.removeEventListener("pointermove",onPointerMove);el.removeEventListener("pointerup",onPointerUp)})}catch{}return{isSwiping,direction,distanceX,distanceY,posStart,posEnd}}
@@ -1,25 +1 @@
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
- }
1
+ import{onUnmounted,ref}from"@stacksjs/stx";export function usePreferredColorScheme(){const scheme=ref("no-preference");if(typeof window>"u"||!window.matchMedia)return scheme;const dark=window.matchMedia("(prefers-color-scheme: dark)"),light=window.matchMedia("(prefers-color-scheme: light)");function update(){if(dark.matches)scheme.value="dark";else if(light.matches)scheme.value="light";else scheme.value="no-preference"}update();dark.addEventListener("change",update);light.addEventListener("change",update);try{onUnmounted(()=>{dark.removeEventListener("change",update);light.removeEventListener("change",update)})}catch{}return scheme}
@@ -1,29 +1 @@
1
- import { onUnmounted, ref } from "@stacksjs/stx";
2
- export function usePreferredContrast() {
3
- const contrast = ref("no-preference");
4
- if (typeof window > "u" || !window.matchMedia)
5
- return contrast;
6
- const more = window.matchMedia("(prefers-contrast: more)"), less = window.matchMedia("(prefers-contrast: less)"), custom = window.matchMedia("(prefers-contrast: custom)");
7
- function update() {
8
- if (more.matches)
9
- contrast.value = "more";
10
- else if (less.matches)
11
- contrast.value = "less";
12
- else if (custom.matches)
13
- contrast.value = "custom";
14
- else
15
- contrast.value = "no-preference";
16
- }
17
- update();
18
- more.addEventListener("change", update);
19
- less.addEventListener("change", update);
20
- custom.addEventListener("change", update);
21
- try {
22
- onUnmounted(() => {
23
- more.removeEventListener("change", update);
24
- less.removeEventListener("change", update);
25
- custom.removeEventListener("change", update);
26
- });
27
- } catch {}
28
- return contrast;
29
- }
1
+ import{onUnmounted,ref}from"@stacksjs/stx";export function usePreferredContrast(){const contrast=ref("no-preference");if(typeof window>"u"||!window.matchMedia)return contrast;const more=window.matchMedia("(prefers-contrast: more)"),less=window.matchMedia("(prefers-contrast: less)"),custom=window.matchMedia("(prefers-contrast: custom)");function update(){if(more.matches)contrast.value="more";else if(less.matches)contrast.value="less";else if(custom.matches)contrast.value="custom";else contrast.value="no-preference"}update();more.addEventListener("change",update);less.addEventListener("change",update);custom.addEventListener("change",update);try{onUnmounted(()=>{more.removeEventListener("change",update);less.removeEventListener("change",update);custom.removeEventListener("change",update)})}catch{}return contrast}
@@ -1,16 +1 @@
1
- import { onUnmounted, ref } from "@stacksjs/stx";
2
- export function usePreferredLanguages() {
3
- const languages = ref(typeof navigator < "u" ? navigator.languages : []);
4
- if (typeof window > "u")
5
- return languages;
6
- const handler = () => {
7
- languages.value = navigator.languages;
8
- };
9
- window.addEventListener("languagechange", handler, { passive: !0 });
10
- try {
11
- onUnmounted(() => {
12
- window.removeEventListener("languagechange", handler);
13
- });
14
- } catch {}
15
- return languages;
16
- }
1
+ import{onUnmounted,ref}from"@stacksjs/stx";export function usePreferredLanguages(){const languages=ref(typeof navigator<"u"?navigator.languages:[]);if(typeof window>"u")return languages;const handler=()=>{languages.value=navigator.languages};window.addEventListener("languagechange",handler,{passive:!0});try{onUnmounted(()=>{window.removeEventListener("languagechange",handler)})}catch{}return languages}
@@ -1,18 +1 @@
1
- import { onUnmounted, ref } from "@stacksjs/stx";
2
- export function usePreferredReducedMotion() {
3
- const motion = ref("no-preference");
4
- if (typeof window > "u" || !window.matchMedia)
5
- return motion;
6
- const mq = window.matchMedia("(prefers-reduced-motion: reduce)");
7
- function update() {
8
- motion.value = mq.matches ? "reduce" : "no-preference";
9
- }
10
- update();
11
- mq.addEventListener("change", update);
12
- try {
13
- onUnmounted(() => {
14
- mq.removeEventListener("change", update);
15
- });
16
- } catch {}
17
- return motion;
18
- }
1
+ import{onUnmounted,ref}from"@stacksjs/stx";export function usePreferredReducedMotion(){const motion=ref("no-preference");if(typeof window>"u"||!window.matchMedia)return motion;const mq=window.matchMedia("(prefers-reduced-motion: reduce)");function update(){motion.value=mq.matches?"reduce":"no-preference"}update();mq.addEventListener("change",update);try{onUnmounted(()=>{mq.removeEventListener("change",update)})}catch{}return motion}
@@ -1,8 +1 @@
1
- import { ref, watch } from "@stacksjs/stx";
2
- export function usePrevious(value, initialValue) {
3
- const previous = ref(initialValue);
4
- watch(value, (_newVal, oldVal) => {
5
- previous.value = oldVal;
6
- });
7
- return previous;
8
- }
1
+ import{ref,watch}from"@stacksjs/stx";export function usePrevious(value,initialValue){const previous=ref(initialValue);watch(value,(_newVal,oldVal)=>{previous.value=oldVal});return previous}
package/dist/useQuery.js CHANGED
@@ -1,265 +1 @@
1
- import { ref } from "@stacksjs/stx";
2
- function stableStringify(value) {
3
- if (value === null || typeof value !== "object")
4
- return JSON.stringify(value);
5
- if (Array.isArray(value))
6
- return `[${value.map(stableStringify).join(",")}]`;
7
- return `{${Object.keys(value).sort().map((k) => `${JSON.stringify(k)}:${stableStringify(value[k])}`).join(",")}}`;
8
- }
9
- function hashKey(key) {
10
- return stableStringify(key);
11
- }
12
- export function createQueryClient(options = {}) {
13
- const entries = new Map, gcTime = options.gcTime ?? 300000, gcTimers = new Map;
14
- function collectable(e) {
15
- return e.subscribers.size === 0 && e.inflight === null;
16
- }
17
- function removeIfCollectable(hash) {
18
- const e = entries.get(hash);
19
- if (e && collectable(e))
20
- entries.delete(hash);
21
- gcTimers.delete(hash);
22
- }
23
- function scheduleGc(hash) {
24
- const existing = gcTimers.get(hash);
25
- if (existing)
26
- clearTimeout(existing);
27
- if (!Number.isFinite(gcTime))
28
- return;
29
- if (gcTime <= 0) {
30
- removeIfCollectable(hash);
31
- return;
32
- }
33
- const t = setTimeout(() => removeIfCollectable(hash), gcTime);
34
- t.unref?.();
35
- gcTimers.set(hash, t);
36
- }
37
- function cancelGc(hash) {
38
- const t = gcTimers.get(hash);
39
- if (t) {
40
- clearTimeout(t);
41
- gcTimers.delete(hash);
42
- }
43
- }
44
- function entry(key) {
45
- const hash = hashKey(key);
46
- let e = entries.get(hash);
47
- if (!e) {
48
- e = {
49
- key,
50
- hash,
51
- data: void 0,
52
- error: null,
53
- updatedAt: 0,
54
- status: "idle",
55
- inflight: null,
56
- invalidated: !1,
57
- subscribers: new Set
58
- };
59
- entries.set(hash, e);
60
- }
61
- return e;
62
- }
63
- function notify(hash) {
64
- const e = entries.get(hash);
65
- if (!e)
66
- return;
67
- for (const fn of e.subscribers)
68
- fn();
69
- }
70
- function prefixMatches(prefix, candidate) {
71
- if (prefix.length > candidate.length)
72
- return !1;
73
- for (let i = 0;i < prefix.length; i++)
74
- if (stableStringify(prefix[i]) !== stableStringify(candidate[i]))
75
- return !1;
76
- return !0;
77
- }
78
- return {
79
- get(key) {
80
- const hash = hashKey(key);
81
- return entries.get(hash)?.data;
82
- },
83
- set(key, value) {
84
- const e = entry(key), next = typeof value === "function" ? value(e.data) : value;
85
- e.data = next;
86
- e.updatedAt = Date.now();
87
- e.status = "success";
88
- e.error = null;
89
- e.invalidated = !1;
90
- notify(e.hash);
91
- },
92
- async invalidate(matcher) {
93
- const matches = Array.isArray(matcher) ? (key) => prefixMatches(matcher, key) : matcher.predicate, refetches = [];
94
- for (const e of entries.values()) {
95
- if (!matches(e.key))
96
- continue;
97
- e.updatedAt = 0;
98
- e.invalidated = !0;
99
- for (const fn of e.subscribers) {
100
- const result = fn();
101
- if (result && typeof result.then === "function")
102
- refetches.push(result);
103
- }
104
- }
105
- await Promise.all(refetches);
106
- },
107
- clear() {
108
- for (const t of gcTimers.values())
109
- clearTimeout(t);
110
- gcTimers.clear();
111
- entries.clear();
112
- },
113
- gc() {
114
- let removed = 0;
115
- for (const [hash, e] of entries)
116
- if (collectable(e)) {
117
- entries.delete(hash);
118
- cancelGc(hash);
119
- removed++;
120
- }
121
- return removed;
122
- },
123
- _subscribe(hash, fn) {
124
- const e = entries.get(hash);
125
- if (!e)
126
- return () => {};
127
- cancelGc(hash);
128
- e.subscribers.add(fn);
129
- return () => {
130
- e.subscribers.delete(fn);
131
- if (e.subscribers.size === 0)
132
- scheduleGc(hash);
133
- };
134
- },
135
- _entry: entry,
136
- _notify: notify
137
- };
138
- }
139
- export const queryClient = createQueryClient();
140
- export function useQuery(opts) {
141
- const client = opts.client ?? queryClient, staleTime = opts.staleTime ?? 0, enabled = opts.enabled ?? !0, e = client._entry(opts.queryKey), data = ref(e.data), error = ref(e.error), isLoading = ref(e.data === void 0 && enabled), isFetching = ref(!1);
142
- function sync() {
143
- data.value = e.data;
144
- error.value = e.error;
145
- isFetching.value = e.status === "fetching";
146
- if (e.data !== void 0 || e.error !== null)
147
- isLoading.value = !1;
148
- }
149
- async function doFetch(force) {
150
- if (!force) {
151
- if (e.data !== void 0 && Date.now() - e.updatedAt < staleTime) {
152
- sync();
153
- return;
154
- }
155
- }
156
- if (e.inflight) {
157
- try {
158
- await e.inflight;
159
- } catch {}
160
- sync();
161
- return;
162
- }
163
- const controller = new AbortController;
164
- e.status = "fetching";
165
- isFetching.value = !0;
166
- if (e.data === void 0)
167
- isLoading.value = !0;
168
- const p = opts.queryFn({ signal: controller.signal }).then((result) => {
169
- e.data = result;
170
- e.error = null;
171
- e.updatedAt = Date.now();
172
- e.status = "success";
173
- e.invalidated = !1;
174
- return result;
175
- }).catch((err) => {
176
- e.error = err instanceof Error ? err : Error(String(err));
177
- e.status = "error";
178
- e.invalidated = !1;
179
- throw e.error;
180
- }).finally(() => {
181
- e.inflight = null;
182
- client._notify(e.hash);
183
- });
184
- e.inflight = p;
185
- try {
186
- await p;
187
- } catch {}
188
- sync();
189
- }
190
- const unsubscribeCache = client._subscribe(e.hash, () => {
191
- if (e.invalidated && enabled && e.status !== "fetching")
192
- return doFetch(!0);
193
- sync();
194
- return;
195
- }), target = opts.window ?? (typeof window < "u" ? window : void 0), winListeners = [];
196
- if (target && enabled) {
197
- const onWake = () => {
198
- if (e.status !== "fetching")
199
- doFetch(!1);
200
- };
201
- if (opts.refetchOnFocus)
202
- winListeners.push(["focus", onWake]);
203
- if (opts.refetchOnReconnect)
204
- winListeners.push(["online", onWake]);
205
- for (const [evt, fn] of winListeners)
206
- target.addEventListener(evt, fn);
207
- }
208
- function unsubscribe() {
209
- unsubscribeCache();
210
- if (target)
211
- for (const [evt, fn] of winListeners)
212
- target.removeEventListener(evt, fn);
213
- }
214
- if (enabled)
215
- doFetch(!1);
216
- else
217
- sync();
218
- return {
219
- data,
220
- error,
221
- isLoading,
222
- isFetching,
223
- refetch: () => doFetch(!0),
224
- unsubscribe
225
- };
226
- }
227
- export function useMutation(opts) {
228
- const data = ref(void 0), error = ref(null), isPending = ref(!1);
229
- async function run(vars) {
230
- isPending.value = !0;
231
- error.value = null;
232
- let ctx;
233
- try {
234
- if (opts.onMutate)
235
- ctx = await opts.onMutate(vars);
236
- const result = await opts.mutationFn(vars);
237
- data.value = result;
238
- await opts.onSuccess?.(result, vars, ctx);
239
- await opts.onSettled?.(result, null, vars, ctx);
240
- return result;
241
- } catch (err) {
242
- const e = err instanceof Error ? err : Error(String(err));
243
- error.value = e;
244
- await opts.onError?.(e, vars, ctx);
245
- await opts.onSettled?.(void 0, e, vars, ctx);
246
- throw e;
247
- } finally {
248
- isPending.value = !1;
249
- }
250
- }
251
- return {
252
- data,
253
- error,
254
- isPending,
255
- mutate(vars) {
256
- run(vars).catch(() => {});
257
- },
258
- mutateAsync: run,
259
- reset() {
260
- data.value = void 0;
261
- error.value = null;
262
- isPending.value = !1;
263
- }
264
- };
265
- }
1
+ import{ref}from"@stacksjs/stx";function stableStringify(value){if(value===null||typeof value!=="object")return JSON.stringify(value);if(Array.isArray(value))return`[${value.map(stableStringify).join(",")}]`;return`{${Object.keys(value).sort().map((k)=>`${JSON.stringify(k)}:${stableStringify(value[k])}`).join(",")}}`}function hashKey(key){return stableStringify(key)}export function createQueryClient(options={}){const entries=new Map,gcTime=options.gcTime??300000,gcTimers=new Map;function collectable(e){return e.subscribers.size===0&&e.inflight===null}function removeIfCollectable(hash){const e=entries.get(hash);if(e&&collectable(e))entries.delete(hash);gcTimers.delete(hash)}function scheduleGc(hash){const existing=gcTimers.get(hash);if(existing)clearTimeout(existing);if(!Number.isFinite(gcTime))return;if(gcTime<=0){removeIfCollectable(hash);return}const t=setTimeout(()=>removeIfCollectable(hash),gcTime);t.unref?.();gcTimers.set(hash,t)}function cancelGc(hash){const t=gcTimers.get(hash);if(t){clearTimeout(t);gcTimers.delete(hash)}}function entry(key){const hash=hashKey(key);let e=entries.get(hash);if(!e){e={key,hash,data:void 0,error:null,updatedAt:0,status:"idle",inflight:null,invalidated:!1,subscribers:new Set};entries.set(hash,e)}return e}function notify(hash){const e=entries.get(hash);if(!e)return;for(const fn of e.subscribers)fn()}function prefixMatches(prefix,candidate){if(prefix.length>candidate.length)return!1;for(let i=0;i<prefix.length;i++)if(stableStringify(prefix[i])!==stableStringify(candidate[i]))return!1;return!0}return{get(key){const hash=hashKey(key);return entries.get(hash)?.data},set(key,value){const e=entry(key),next=typeof value==="function"?value(e.data):value;e.data=next;e.updatedAt=Date.now();e.status="success";e.error=null;e.invalidated=!1;notify(e.hash)},async invalidate(matcher){const matches=Array.isArray(matcher)?(key)=>prefixMatches(matcher,key):matcher.predicate,refetches=[];for(const e of entries.values()){if(!matches(e.key))continue;e.updatedAt=0;e.invalidated=!0;for(const fn of e.subscribers){const result=fn();if(result&&typeof result.then==="function")refetches.push(result)}}await Promise.all(refetches)},clear(){for(const t of gcTimers.values())clearTimeout(t);gcTimers.clear();entries.clear()},gc(){let removed=0;for(const[hash,e]of entries)if(collectable(e)){entries.delete(hash);cancelGc(hash);removed++}return removed},_subscribe(hash,fn){const e=entries.get(hash);if(!e)return()=>{};cancelGc(hash);e.subscribers.add(fn);return()=>{e.subscribers.delete(fn);if(e.subscribers.size===0)scheduleGc(hash)}},_entry:entry,_notify:notify}}export const queryClient=createQueryClient();export function useQuery(opts){const client=opts.client??queryClient,staleTime=opts.staleTime??0,enabled=opts.enabled??!0,e=client._entry(opts.queryKey),data=ref(e.data),error=ref(e.error),isLoading=ref(e.data===void 0&&enabled),isFetching=ref(!1);function sync(){data.value=e.data;error.value=e.error;isFetching.value=e.status==="fetching";if(e.data!==void 0||e.error!==null)isLoading.value=!1}async function doFetch(force){if(!force){if(e.data!==void 0&&Date.now()-e.updatedAt<staleTime){sync();return}}if(e.inflight){try{await e.inflight}catch{}sync();return}const controller=new AbortController;e.status="fetching";isFetching.value=!0;if(e.data===void 0)isLoading.value=!0;const p=opts.queryFn({signal:controller.signal}).then((result)=>{e.data=result;e.error=null;e.updatedAt=Date.now();e.status="success";e.invalidated=!1;return result}).catch((err)=>{e.error=err instanceof Error?err:Error(String(err));e.status="error";e.invalidated=!1;throw e.error}).finally(()=>{e.inflight=null;client._notify(e.hash)});e.inflight=p;try{await p}catch{}sync()}const unsubscribeCache=client._subscribe(e.hash,()=>{if(e.invalidated&&enabled&&e.status!=="fetching")return doFetch(!0);sync();return}),target=opts.window??(typeof window<"u"?window:void 0),winListeners=[];if(target&&enabled){const onWake=()=>{if(e.status!=="fetching")doFetch(!1)};if(opts.refetchOnFocus)winListeners.push(["focus",onWake]);if(opts.refetchOnReconnect)winListeners.push(["online",onWake]);for(const[evt,fn]of winListeners)target.addEventListener(evt,fn)}function unsubscribe(){unsubscribeCache();if(target)for(const[evt,fn]of winListeners)target.removeEventListener(evt,fn)}if(enabled)doFetch(!1);else sync();return{data,error,isLoading,isFetching,refetch:()=>doFetch(!0),unsubscribe}}export function useMutation(opts){const data=ref(void 0),error=ref(null),isPending=ref(!1);async function run(vars){isPending.value=!0;error.value=null;let ctx;try{if(opts.onMutate)ctx=await opts.onMutate(vars);const result=await opts.mutationFn(vars);data.value=result;await opts.onSuccess?.(result,vars,ctx);await opts.onSettled?.(result,null,vars,ctx);return result}catch(err){const e=err instanceof Error?err:Error(String(err));error.value=e;await opts.onError?.(e,vars,ctx);await opts.onSettled?.(void 0,e,vars,ctx);throw e}finally{isPending.value=!1}}return{data,error,isPending,mutate(vars){run(vars).catch(()=>{})},mutateAsync:run,reset(){data.value=void 0;error.value=null;isPending.value=!1}}}
package/dist/useRafFn.js CHANGED
@@ -1,37 +1 @@
1
- import { onUnmounted, ref } from "@stacksjs/stx";
2
- export function useRafFn(fn, options = {}) {
3
- const { immediate = !0 } = options, isActive = ref(!1);
4
- let rafId = null, previousTimestamp = 0;
5
- function loop(timestamp) {
6
- if (!isActive.value)
7
- return;
8
- const delta = previousTimestamp ? timestamp - previousTimestamp : 0;
9
- previousTimestamp = timestamp;
10
- fn({ delta, timestamp });
11
- rafId = requestAnimationFrame(loop);
12
- }
13
- function resume() {
14
- if (isActive.value)
15
- return;
16
- if (typeof requestAnimationFrame > "u")
17
- return;
18
- isActive.value = !0;
19
- previousTimestamp = 0;
20
- rafId = requestAnimationFrame(loop);
21
- }
22
- function pause() {
23
- if (!isActive.value)
24
- return;
25
- isActive.value = !1;
26
- if (rafId !== null && typeof cancelAnimationFrame < "u") {
27
- cancelAnimationFrame(rafId);
28
- rafId = null;
29
- }
30
- }
31
- if (immediate)
32
- resume();
33
- try {
34
- onUnmounted(pause);
35
- } catch {}
36
- return { pause, resume, isActive };
37
- }
1
+ import{onUnmounted,ref}from"@stacksjs/stx";export function useRafFn(fn,options={}){const{immediate=!0}=options,isActive=ref(!1);let rafId=null,previousTimestamp=0;function loop(timestamp){if(!isActive.value)return;const delta=previousTimestamp?timestamp-previousTimestamp:0;previousTimestamp=timestamp;fn({delta,timestamp});rafId=requestAnimationFrame(loop)}function resume(){if(isActive.value)return;if(typeof requestAnimationFrame>"u")return;isActive.value=!0;previousTimestamp=0;rafId=requestAnimationFrame(loop)}function pause(){if(!isActive.value)return;isActive.value=!1;if(rafId!==null&&typeof cancelAnimationFrame<"u"){cancelAnimationFrame(rafId);rafId=null}}if(immediate)resume();try{onUnmounted(pause)}catch{}return{pause,resume,isActive}}