@stacksjs/composables 0.70.258 → 0.70.259

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
package/dist/useForm.js CHANGED
@@ -1,182 +1 @@
1
- import { ref } from "@stacksjs/stx";
2
- export function useForm(opts) {
3
- const validateOn = opts.validateOn ?? "submit", initial = { ...opts.initialValues }, values = ref({ ...initial }), errors = ref({}), touched = ref({}), dirty = ref({}), isSubmitting = ref(!1), isValid = ref(!0), isDirty = ref(!1);
4
- function firstMessage(result) {
5
- if (result.valid)
6
- return "";
7
- if (Array.isArray(result.errors))
8
- return result.errors[0]?.message ?? "Invalid";
9
- for (const list of Object.values(result.errors))
10
- if (list.length > 0)
11
- return list[0]?.message ?? "Invalid";
12
- return "Invalid";
13
- }
14
- function validateField(name) {
15
- const v = opts.schema?.[name];
16
- if (!v)
17
- return !0;
18
- const result = v.validate(values.value[name]), message = firstMessage(result);
19
- if (message) {
20
- errors.value = { ...errors.value, [name]: message };
21
- isValid.value = !1;
22
- return !1;
23
- }
24
- if (errors.value[name]) {
25
- const { [name]: _, ...rest } = errors.value;
26
- errors.value = rest;
27
- }
28
- isValid.value = Object.keys(errors.value).length === 0;
29
- return !0;
30
- }
31
- function setFieldValue(name, value) {
32
- values.value = { ...values.value, [name]: value };
33
- dirty.value = { ...dirty.value, [name]: value !== initial[name] };
34
- isDirty.value = !0;
35
- if (validateOn === "change")
36
- validateField(name);
37
- }
38
- function setFieldTouched(name, isTouched = !0) {
39
- touched.value = { ...touched.value, [name]: isTouched };
40
- if (isTouched)
41
- isDirty.value = !0;
42
- }
43
- function field(name) {
44
- const key = name, errorId = `${key}-error`, onBlur = () => {
45
- setFieldTouched(name, !0);
46
- if (validateOn === "blur" || validateOn === "change")
47
- validateField(name);
48
- };
49
- return {
50
- get value() {
51
- return values.value[name];
52
- },
53
- get error() {
54
- return errors.value[key] ?? "";
55
- },
56
- get touched() {
57
- return !!touched.value[key];
58
- },
59
- get dirty() {
60
- return !!dirty.value[key];
61
- },
62
- errorId,
63
- setValue: (next) => setFieldValue(name, next),
64
- onBlur,
65
- validate: () => validateField(name),
66
- inputProps: () => {
67
- const hasError = !!errors.value[key];
68
- return {
69
- name: key,
70
- value: values.value[name],
71
- onInput: (eventOrValue) => {
72
- const next = eventOrValue && typeof eventOrValue === "object" && "target" in eventOrValue ? eventOrValue.target.value : eventOrValue;
73
- setFieldValue(name, next);
74
- },
75
- onBlur,
76
- "aria-invalid": hasError,
77
- "aria-describedby": hasError ? errorId : void 0
78
- };
79
- }
80
- };
81
- }
82
- function validateAll() {
83
- let ok = !0;
84
- for (const name of Object.keys(opts.schema ?? {}))
85
- if (!validateField(name))
86
- ok = !1;
87
- return ok;
88
- }
89
- function setError(name, message) {
90
- errors.value = { ...errors.value, [name]: message };
91
- isValid.value = !1;
92
- }
93
- function setErrors(errorMap) {
94
- const next = { ...errors.value };
95
- let changed = !1;
96
- const list = Object.entries(errorMap);
97
- for (const [key, msg] of list) {
98
- if (msg == null)
99
- continue;
100
- const message = Array.isArray(msg) ? msg[0] : msg;
101
- if (message == null || message === "")
102
- continue;
103
- next[key] = message;
104
- changed = !0;
105
- }
106
- errors.value = next;
107
- if (changed)
108
- isValid.value = !1;
109
- }
110
- function clearErrors(name) {
111
- if (name == null) {
112
- errors.value = {};
113
- isValid.value = !0;
114
- return;
115
- }
116
- const { [name]: _, ...rest } = errors.value;
117
- errors.value = rest;
118
- isValid.value = Object.keys(errors.value).length === 0;
119
- }
120
- async function handleSubmit() {
121
- const allTouched = {};
122
- for (const k of Object.keys(values.value))
123
- allTouched[k] = !0;
124
- touched.value = allTouched;
125
- if (!validateAll()) {
126
- opts.onError?.(errors.value);
127
- return;
128
- }
129
- isSubmitting.value = !0;
130
- try {
131
- await opts.onSubmit(values.value);
132
- } catch (err) {
133
- const e = err instanceof Error ? err : Error(String(err));
134
- setError("form", e.message);
135
- opts.onError?.(e);
136
- } finally {
137
- isSubmitting.value = !1;
138
- }
139
- }
140
- function reset() {
141
- values.value = { ...initial };
142
- errors.value = {};
143
- touched.value = {};
144
- dirty.value = {};
145
- isSubmitting.value = !1;
146
- isValid.value = !0;
147
- isDirty.value = !1;
148
- }
149
- function submitButtonProps() {
150
- return {
151
- type: "submit",
152
- disabled: isSubmitting.value,
153
- "aria-busy": isSubmitting.value
154
- };
155
- }
156
- function firstErrorField() {
157
- for (const k of Object.keys(initial))
158
- if (errors.value[k])
159
- return k;
160
- return null;
161
- }
162
- return {
163
- values,
164
- errors,
165
- touched,
166
- dirty,
167
- isSubmitting,
168
- isValid,
169
- isDirty,
170
- field,
171
- setValue: setFieldValue,
172
- setError,
173
- setErrors,
174
- clearErrors,
175
- setTouched: setFieldTouched,
176
- validate: validateAll,
177
- handleSubmit,
178
- reset,
179
- submitButtonProps,
180
- firstErrorField
181
- };
182
- }
1
+ import{ref}from"@stacksjs/stx";export function useForm(opts){const validateOn=opts.validateOn??"submit",initial={...opts.initialValues},values=ref({...initial}),errors=ref({}),touched=ref({}),dirty=ref({}),isSubmitting=ref(!1),isValid=ref(!0),isDirty=ref(!1);function firstMessage(result){if(result.valid)return"";if(Array.isArray(result.errors))return result.errors[0]?.message??"Invalid";for(const list of Object.values(result.errors))if(list.length>0)return list[0]?.message??"Invalid";return"Invalid"}function validateField(name){const v=opts.schema?.[name];if(!v)return!0;const result=v.validate(values.value[name]),message=firstMessage(result);if(message){errors.value={...errors.value,[name]:message};isValid.value=!1;return!1}if(errors.value[name]){const{[name]:_,...rest}=errors.value;errors.value=rest}isValid.value=Object.keys(errors.value).length===0;return!0}function setFieldValue(name,value){values.value={...values.value,[name]:value};dirty.value={...dirty.value,[name]:value!==initial[name]};isDirty.value=!0;if(validateOn==="change")validateField(name)}function setFieldTouched(name,isTouched=!0){touched.value={...touched.value,[name]:isTouched};if(isTouched)isDirty.value=!0}function field(name){const key=name,errorId=`${key}-error`,onBlur=()=>{setFieldTouched(name,!0);if(validateOn==="blur"||validateOn==="change")validateField(name)};return{get value(){return values.value[name]},get error(){return errors.value[key]??""},get touched(){return!!touched.value[key]},get dirty(){return!!dirty.value[key]},errorId,setValue:(next)=>setFieldValue(name,next),onBlur,validate:()=>validateField(name),inputProps:()=>{const hasError=!!errors.value[key];return{name:key,value:values.value[name],onInput:(eventOrValue)=>{const next=eventOrValue&&typeof eventOrValue==="object"&&"target"in eventOrValue?eventOrValue.target.value:eventOrValue;setFieldValue(name,next)},onBlur,"aria-invalid":hasError,"aria-describedby":hasError?errorId:void 0}}}}function validateAll(){let ok=!0;for(const name of Object.keys(opts.schema??{}))if(!validateField(name))ok=!1;return ok}function setError(name,message){errors.value={...errors.value,[name]:message};isValid.value=!1}function setErrors(errorMap){const next={...errors.value};let changed=!1;const list=Object.entries(errorMap);for(const[key,msg]of list){if(msg==null)continue;const message=Array.isArray(msg)?msg[0]:msg;if(message==null||message==="")continue;next[key]=message;changed=!0}errors.value=next;if(changed)isValid.value=!1}function clearErrors(name){if(name==null){errors.value={};isValid.value=!0;return}const{[name]:_,...rest}=errors.value;errors.value=rest;isValid.value=Object.keys(errors.value).length===0}async function handleSubmit(){const allTouched={};for(const k of Object.keys(values.value))allTouched[k]=!0;touched.value=allTouched;if(!validateAll()){opts.onError?.(errors.value);return}isSubmitting.value=!0;try{await opts.onSubmit(values.value)}catch(err){const e=err instanceof Error?err:Error(String(err));setError("form",e.message);opts.onError?.(e)}finally{isSubmitting.value=!1}}function reset(){values.value={...initial};errors.value={};touched.value={};dirty.value={};isSubmitting.value=!1;isValid.value=!0;isDirty.value=!1}function submitButtonProps(){return{type:"submit",disabled:isSubmitting.value,"aria-busy":isSubmitting.value}}function firstErrorField(){for(const k of Object.keys(initial))if(errors.value[k])return k;return null}return{values,errors,touched,dirty,isSubmitting,isValid,isDirty,field,setValue:setFieldValue,setError,setErrors,clearErrors,setTouched:setFieldTouched,validate:validateAll,handleSubmit,reset,submitButtonProps,firstErrorField}}
package/dist/useFps.js CHANGED
@@ -1,22 +1 @@
1
- import { onUnmounted, ref } from "@stacksjs/stx";
2
- export function useFps(every = 10) {
3
- const fps = ref(0);
4
- if (typeof requestAnimationFrame > "u")
5
- return fps;
6
- let last = performance.now(), ticks = 0, rafId;
7
- function loop() {
8
- ticks++;
9
- if (ticks >= every) {
10
- const now = performance.now(), diff = now - last;
11
- fps.value = Math.round(ticks / diff * 1000);
12
- last = now;
13
- ticks = 0;
14
- }
15
- rafId = requestAnimationFrame(loop);
16
- }
17
- rafId = requestAnimationFrame(loop);
18
- try {
19
- onUnmounted(() => cancelAnimationFrame(rafId));
20
- } catch {}
21
- return fps;
22
- }
1
+ import{onUnmounted,ref}from"@stacksjs/stx";export function useFps(every=10){const fps=ref(0);if(typeof requestAnimationFrame>"u")return fps;let last=performance.now(),ticks=0,rafId;function loop(){ticks++;if(ticks>=every){const now=performance.now(),diff=now-last;fps.value=Math.round(ticks/diff*1000);last=now;ticks=0}rafId=requestAnimationFrame(loop)}rafId=requestAnimationFrame(loop);try{onUnmounted(()=>cancelAnimationFrame(rafId))}catch{}return fps}
@@ -1,67 +1 @@
1
- import { onUnmounted, ref } from "@stacksjs/stx";
2
- import { defaultDocument, unref } from "./_shared";
3
- export function useFullscreen(target) {
4
- const doc = defaultDocument(), isFullscreen = ref(!1), isSupported = ref(!!doc && (("fullscreenEnabled" in doc) || ("webkitFullscreenEnabled" in doc)));
5
- function getTarget() {
6
- if (target)
7
- return unref(target);
8
- return doc?.documentElement ?? null;
9
- }
10
- function getFullscreenElement() {
11
- if (!doc)
12
- return null;
13
- return doc.fullscreenElement ?? doc.webkitFullscreenElement ?? null;
14
- }
15
- function updateState() {
16
- isFullscreen.value = getFullscreenElement() !== null;
17
- }
18
- async function enter() {
19
- if (!isSupported.value)
20
- return;
21
- const el = getTarget();
22
- if (!el)
23
- return;
24
- try {
25
- if (el.requestFullscreen)
26
- await el.requestFullscreen();
27
- else if (el.webkitRequestFullscreen)
28
- await el.webkitRequestFullscreen();
29
- isFullscreen.value = !0;
30
- } catch {}
31
- }
32
- async function exit() {
33
- if (!isSupported.value || !doc)
34
- return;
35
- try {
36
- if (doc.exitFullscreen)
37
- await doc.exitFullscreen();
38
- else if (doc.webkitExitFullscreen)
39
- await doc.webkitExitFullscreen();
40
- isFullscreen.value = !1;
41
- } catch {}
42
- }
43
- async function toggle() {
44
- if (isFullscreen.value)
45
- await exit();
46
- else
47
- await enter();
48
- }
49
- if (doc) {
50
- const handler = () => updateState();
51
- doc.addEventListener("fullscreenchange", handler);
52
- doc.addEventListener("webkitfullscreenchange", handler);
53
- try {
54
- onUnmounted(() => {
55
- doc.removeEventListener("fullscreenchange", handler);
56
- doc.removeEventListener("webkitfullscreenchange", handler);
57
- });
58
- } catch {}
59
- }
60
- return {
61
- isFullscreen,
62
- isSupported,
63
- enter,
64
- exit,
65
- toggle
66
- };
67
- }
1
+ import{onUnmounted,ref}from"@stacksjs/stx";import{defaultDocument,unref}from"./_shared";export function useFullscreen(target){const doc=defaultDocument(),isFullscreen=ref(!1),isSupported=ref(!!doc&&(("fullscreenEnabled"in doc)||("webkitFullscreenEnabled"in doc)));function getTarget(){if(target)return unref(target);return doc?.documentElement??null}function getFullscreenElement(){if(!doc)return null;return doc.fullscreenElement??doc.webkitFullscreenElement??null}function updateState(){isFullscreen.value=getFullscreenElement()!==null}async function enter(){if(!isSupported.value)return;const el=getTarget();if(!el)return;try{if(el.requestFullscreen)await el.requestFullscreen();else if(el.webkitRequestFullscreen)await el.webkitRequestFullscreen();isFullscreen.value=!0}catch{}}async function exit(){if(!isSupported.value||!doc)return;try{if(doc.exitFullscreen)await doc.exitFullscreen();else if(doc.webkitExitFullscreen)await doc.webkitExitFullscreen();isFullscreen.value=!1}catch{}}async function toggle(){if(isFullscreen.value)await exit();else await enter()}if(doc){const handler=()=>updateState();doc.addEventListener("fullscreenchange",handler);doc.addEventListener("webkitfullscreenchange",handler);try{onUnmounted(()=>{doc.removeEventListener("fullscreenchange",handler);doc.removeEventListener("webkitfullscreenchange",handler)})}catch{}}return{isFullscreen,isSupported,enter,exit,toggle}}
@@ -1,55 +1 @@
1
- import { onUnmounted, ref } from "@stacksjs/stx";
2
- import { noop } from "./_shared";
3
- export function useGeolocation(options) {
4
- const { immediate = !0, ...positionOptions } = options ?? {}, isSupported = ref(typeof navigator < "u" && "geolocation" in navigator), coords = {
5
- latitude: ref(null),
6
- longitude: ref(null),
7
- accuracy: ref(null),
8
- altitude: ref(null),
9
- altitudeAccuracy: ref(null),
10
- heading: ref(null),
11
- speed: ref(null)
12
- }, locatedAt = ref(null), error = ref(null);
13
- let watchId = null, cleanup = noop;
14
- const updatePosition = (position) => {
15
- coords.latitude.value = position.coords.latitude;
16
- coords.longitude.value = position.coords.longitude;
17
- coords.accuracy.value = position.coords.accuracy;
18
- coords.altitude.value = position.coords.altitude;
19
- coords.altitudeAccuracy.value = position.coords.altitudeAccuracy;
20
- coords.heading.value = position.coords.heading;
21
- coords.speed.value = position.coords.speed;
22
- locatedAt.value = position.timestamp;
23
- error.value = null;
24
- }, onError = (err) => {
25
- error.value = err;
26
- }, resume = () => {
27
- if (!isSupported.value)
28
- return;
29
- if (watchId !== null)
30
- return;
31
- watchId = navigator.geolocation.watchPosition(updatePosition, onError, positionOptions);
32
- cleanup = () => {
33
- if (watchId !== null) {
34
- navigator.geolocation.clearWatch(watchId);
35
- watchId = null;
36
- }
37
- cleanup = noop;
38
- };
39
- }, pause = () => {
40
- cleanup();
41
- };
42
- if (immediate)
43
- resume();
44
- try {
45
- onUnmounted(pause);
46
- } catch {}
47
- return {
48
- coords,
49
- locatedAt,
50
- error,
51
- isSupported,
52
- pause,
53
- resume
54
- };
55
- }
1
+ import{onUnmounted,ref}from"@stacksjs/stx";import{noop}from"./_shared";export function useGeolocation(options){const{immediate=!0,...positionOptions}=options??{},isSupported=ref(typeof navigator<"u"&&"geolocation"in navigator),coords={latitude:ref(null),longitude:ref(null),accuracy:ref(null),altitude:ref(null),altitudeAccuracy:ref(null),heading:ref(null),speed:ref(null)},locatedAt=ref(null),error=ref(null);let watchId=null,cleanup=noop;const updatePosition=(position)=>{coords.latitude.value=position.coords.latitude;coords.longitude.value=position.coords.longitude;coords.accuracy.value=position.coords.accuracy;coords.altitude.value=position.coords.altitude;coords.altitudeAccuracy.value=position.coords.altitudeAccuracy;coords.heading.value=position.coords.heading;coords.speed.value=position.coords.speed;locatedAt.value=position.timestamp;error.value=null},onError=(err)=>{error.value=err},resume=()=>{if(!isSupported.value)return;if(watchId!==null)return;watchId=navigator.geolocation.watchPosition(updatePosition,onError,positionOptions);cleanup=()=>{if(watchId!==null){navigator.geolocation.clearWatch(watchId);watchId=null}cleanup=noop}},pause=()=>{cleanup()};if(immediate)resume();try{onUnmounted(pause)}catch{}return{coords,locatedAt,error,isSupported,pause,resume}}
package/dist/useIdle.js CHANGED
@@ -1,46 +1 @@
1
- import { onUnmounted, ref } from "@stacksjs/stx";
2
- import { noop } from "./_shared";
3
- const DEFAULT_EVENTS = [
4
- "mousemove",
5
- "mousedown",
6
- "resize",
7
- "keydown",
8
- "touchstart",
9
- "wheel"
10
- ];
11
- export function useIdle(timeout = 60000, options) {
12
- const events = options?.events ?? DEFAULT_EVENTS, initialState = options?.initialState ?? !1, idle = ref(initialState), lastActive = ref(Date.now());
13
- let timer = null, cleanup = noop;
14
- if (typeof window < "u") {
15
- const cleanups = [], reset = () => {
16
- idle.value = !1;
17
- lastActive.value = Date.now();
18
- if (timer !== null)
19
- clearTimeout(timer);
20
- timer = setTimeout(() => {
21
- idle.value = !0;
22
- }, timeout);
23
- };
24
- for (const event of events) {
25
- window.addEventListener(event, reset, { passive: !0 });
26
- cleanups.push(() => window.removeEventListener(event, reset));
27
- }
28
- timer = setTimeout(() => {
29
- idle.value = !0;
30
- }, timeout);
31
- cleanup = () => {
32
- for (const fn of cleanups)
33
- fn();
34
- cleanups.length = 0;
35
- if (timer !== null) {
36
- clearTimeout(timer);
37
- timer = null;
38
- }
39
- cleanup = noop;
40
- };
41
- }
42
- try {
43
- onUnmounted(() => cleanup());
44
- } catch {}
45
- return { idle, lastActive };
46
- }
1
+ import{onUnmounted,ref}from"@stacksjs/stx";import{noop}from"./_shared";const DEFAULT_EVENTS=["mousemove","mousedown","resize","keydown","touchstart","wheel"];export function useIdle(timeout=60000,options){const events=options?.events??DEFAULT_EVENTS,initialState=options?.initialState??!1,idle=ref(initialState),lastActive=ref(Date.now());let timer=null,cleanup=noop;if(typeof window<"u"){const cleanups=[],reset=()=>{idle.value=!1;lastActive.value=Date.now();if(timer!==null)clearTimeout(timer);timer=setTimeout(()=>{idle.value=!0},timeout)};for(const event of events){window.addEventListener(event,reset,{passive:!0});cleanups.push(()=>window.removeEventListener(event,reset))}timer=setTimeout(()=>{idle.value=!0},timeout);cleanup=()=>{for(const fn of cleanups)fn();cleanups.length=0;if(timer!==null){clearTimeout(timer);timer=null}cleanup=noop}}try{onUnmounted(()=>cleanup())}catch{}return{idle,lastActive}}
package/dist/useImage.js CHANGED
@@ -1,32 +1 @@
1
- import { ref } from "@stacksjs/stx";
2
- export function useImage(options) {
3
- const isLoading = ref(!0), isReady = ref(!1), error = ref(null);
4
- if (typeof Image > "u") {
5
- isLoading.value = !1;
6
- return { isLoading, error, isReady };
7
- }
8
- const img = new Image;
9
- img.onload = () => {
10
- isLoading.value = !1;
11
- isReady.value = !0;
12
- };
13
- img.onerror = (e) => {
14
- isLoading.value = !1;
15
- if (typeof e === "string")
16
- error.value = e;
17
- else if (e instanceof Event && e.type === "error")
18
- error.value = `Failed to load image: ${options.src}`;
19
- else
20
- error.value = "Failed to load image";
21
- };
22
- if (options.crossorigin)
23
- img.crossOrigin = options.crossorigin;
24
- if (options.referrerpolicy)
25
- img.referrerPolicy = options.referrerpolicy;
26
- if (options.sizes)
27
- img.sizes = options.sizes;
28
- if (options.srcset)
29
- img.srcset = options.srcset;
30
- img.src = options.src;
31
- return { isLoading, error, isReady };
32
- }
1
+ import{ref}from"@stacksjs/stx";export function useImage(options){const isLoading=ref(!0),isReady=ref(!1),error=ref(null);if(typeof Image>"u"){isLoading.value=!1;return{isLoading,error,isReady}}const img=new Image;img.onload=()=>{isLoading.value=!1;isReady.value=!0};img.onerror=(e)=>{isLoading.value=!1;if(typeof e==="string")error.value=e;else if(e instanceof Event&&e.type==="error")error.value=`Failed to load image: ${options.src}`;else error.value="Failed to load image"};if(options.crossorigin)img.crossOrigin=options.crossorigin;if(options.referrerpolicy)img.referrerPolicy=options.referrerpolicy;if(options.sizes)img.sizes=options.sizes;if(options.srcset)img.srcset=options.srcset;img.src=options.src;return{isLoading,error,isReady}}
@@ -1,50 +1 @@
1
- import { onUnmounted, ref, watch } from "@stacksjs/stx";
2
- import { unref } from "./_shared";
3
- export function useInfiniteScroll(target, onLoadMore, options = {}) {
4
- const { distance = 100, direction = "bottom" } = options, isLoading = ref(!1);
5
- let active = !0;
6
- const handler = async () => {
7
- if (!active || isLoading.value)
8
- return;
9
- const el = unref(target);
10
- if (!el)
11
- return;
12
- let shouldLoad = !1;
13
- if (el === window || el === document.documentElement) {
14
- const scrollTop = window.scrollY || document.documentElement.scrollTop, scrollHeight = document.documentElement.scrollHeight, clientHeight = window.innerHeight;
15
- if (direction === "bottom")
16
- shouldLoad = scrollHeight - scrollTop - clientHeight <= distance;
17
- else if (direction === "top")
18
- shouldLoad = scrollTop <= distance;
19
- } else {
20
- const element = el;
21
- if (direction === "bottom")
22
- shouldLoad = element.scrollHeight - element.scrollTop - element.clientHeight <= distance;
23
- else if (direction === "top")
24
- shouldLoad = element.scrollTop <= distance;
25
- else if (direction === "right")
26
- shouldLoad = element.scrollWidth - element.scrollLeft - element.clientWidth <= distance;
27
- else if (direction === "left")
28
- shouldLoad = element.scrollLeft <= distance;
29
- }
30
- if (shouldLoad) {
31
- isLoading.value = !0;
32
- try {
33
- await onLoadMore();
34
- } finally {
35
- isLoading.value = !1;
36
- }
37
- }
38
- }, el = unref(target);
39
- if (el) {
40
- const scrollTarget = el === document.documentElement ? window : el;
41
- scrollTarget.addEventListener("scroll", handler, { passive: !0 });
42
- try {
43
- onUnmounted(() => {
44
- active = !1;
45
- scrollTarget.removeEventListener("scroll", handler);
46
- });
47
- } catch {}
48
- }
49
- return { isLoading };
50
- }
1
+ import{onUnmounted,ref,watch}from"@stacksjs/stx";import{unref}from"./_shared";export function useInfiniteScroll(target,onLoadMore,options={}){const{distance=100,direction="bottom"}=options,isLoading=ref(!1);let active=!0;const handler=async()=>{if(!active||isLoading.value)return;const el=unref(target);if(!el)return;let shouldLoad=!1;if(el===window||el===document.documentElement){const scrollTop=window.scrollY||document.documentElement.scrollTop,scrollHeight=document.documentElement.scrollHeight,clientHeight=window.innerHeight;if(direction==="bottom")shouldLoad=scrollHeight-scrollTop-clientHeight<=distance;else if(direction==="top")shouldLoad=scrollTop<=distance}else{const element=el;if(direction==="bottom")shouldLoad=element.scrollHeight-element.scrollTop-element.clientHeight<=distance;else if(direction==="top")shouldLoad=element.scrollTop<=distance;else if(direction==="right")shouldLoad=element.scrollWidth-element.scrollLeft-element.clientWidth<=distance;else if(direction==="left")shouldLoad=element.scrollLeft<=distance}if(shouldLoad){isLoading.value=!0;try{await onLoadMore()}finally{isLoading.value=!1}}},el=unref(target);if(el){const scrollTarget=el===document.documentElement?window:el;scrollTarget.addEventListener("scroll",handler,{passive:!0});try{onUnmounted(()=>{active=!1;scrollTarget.removeEventListener("scroll",handler)})}catch{}}return{isLoading}}
@@ -1,27 +1 @@
1
- import { onUnmounted, ref } from "@stacksjs/stx";
2
- import { unref, noop } from "./_shared";
3
- export function useIntersectionObserver(target, callback, options) {
4
- const isSupported = ref(typeof window < "u" && "IntersectionObserver" in window);
5
- let cleanup = noop;
6
- (() => {
7
- cleanup();
8
- if (!isSupported.value)
9
- return;
10
- const el = unref(target);
11
- if (!el)
12
- return;
13
- const observer = new IntersectionObserver(callback, options);
14
- observer.observe(el);
15
- cleanup = () => {
16
- observer.disconnect();
17
- cleanup = noop;
18
- };
19
- })();
20
- const stop = () => {
21
- cleanup();
22
- };
23
- try {
24
- onUnmounted(stop);
25
- } catch {}
26
- return { isSupported, stop };
27
- }
1
+ import{onUnmounted,ref}from"@stacksjs/stx";import{unref,noop}from"./_shared";export function useIntersectionObserver(target,callback,options){const isSupported=ref(typeof window<"u"&&"IntersectionObserver"in window);let cleanup=noop;(()=>{cleanup();if(!isSupported.value)return;const el=unref(target);if(!el)return;const observer=new IntersectionObserver(callback,options);observer.observe(el);cleanup=()=>{observer.disconnect();cleanup=noop}})();const stop=()=>{cleanup()};try{onUnmounted(stop)}catch{}return{isSupported,stop}}
@@ -1,32 +1 @@
1
- import { onUnmounted, ref } from "@stacksjs/stx";
2
- export function useInterval(interval = 1000, options = {}) {
3
- const { controls = !1, immediate = !0 } = options, counter = ref(0);
4
- let intervalId = null;
5
- function pause() {
6
- if (intervalId !== null) {
7
- clearInterval(intervalId);
8
- intervalId = null;
9
- }
10
- }
11
- function resume() {
12
- if (intervalId !== null)
13
- return;
14
- intervalId = setInterval(() => {
15
- counter.value++;
16
- }, interval);
17
- }
18
- function reset() {
19
- counter.value = 0;
20
- pause();
21
- if (immediate)
22
- resume();
23
- }
24
- if (immediate)
25
- resume();
26
- try {
27
- onUnmounted(pause);
28
- } catch {}
29
- if (controls)
30
- return { counter, pause, resume, reset };
31
- return counter;
32
- }
1
+ import{onUnmounted,ref}from"@stacksjs/stx";export function useInterval(interval=1000,options={}){const{controls=!1,immediate=!0}=options,counter=ref(0);let intervalId=null;function pause(){if(intervalId!==null){clearInterval(intervalId);intervalId=null}}function resume(){if(intervalId!==null)return;intervalId=setInterval(()=>{counter.value++},interval)}function reset(){counter.value=0;pause();if(immediate)resume()}if(immediate)resume();try{onUnmounted(pause)}catch{}if(controls)return{counter,pause,resume,reset};return counter}
@@ -1,24 +1 @@
1
- import { onUnmounted, ref } from "@stacksjs/stx";
2
- export function useIntervalFn(cb, interval = 1000, options = {}) {
3
- const { immediate = !0 } = options, isActive = ref(!1);
4
- let intervalId = null;
5
- function pause() {
6
- if (intervalId !== null) {
7
- clearInterval(intervalId);
8
- intervalId = null;
9
- }
10
- isActive.value = !1;
11
- }
12
- function resume() {
13
- if (intervalId !== null)
14
- return;
15
- isActive.value = !0;
16
- intervalId = setInterval(cb, interval);
17
- }
18
- if (immediate)
19
- resume();
20
- try {
21
- onUnmounted(pause);
22
- } catch {}
23
- return { pause, resume, isActive };
24
- }
1
+ import{onUnmounted,ref}from"@stacksjs/stx";export function useIntervalFn(cb,interval=1000,options={}){const{immediate=!0}=options,isActive=ref(!1);let intervalId=null;function pause(){if(intervalId!==null){clearInterval(intervalId);intervalId=null}isActive.value=!1}function resume(){if(intervalId!==null)return;isActive.value=!0;intervalId=setInterval(cb,interval)}if(immediate)resume();try{onUnmounted(pause)}catch{}return{pause,resume,isActive}}
@@ -1,22 +1 @@
1
- import { onUnmounted, ref } from "@stacksjs/stx";
2
- export function useKeyModifier(modifier) {
3
- const state = ref(!1);
4
- if (typeof window > "u")
5
- return state;
6
- const handler = (e) => {
7
- state.value = e.getModifierState(modifier);
8
- };
9
- window.addEventListener("keydown", handler, { passive: !0 });
10
- window.addEventListener("keyup", handler, { passive: !0 });
11
- window.addEventListener("mousedown", handler, { passive: !0 });
12
- window.addEventListener("mouseup", handler, { passive: !0 });
13
- try {
14
- onUnmounted(() => {
15
- window.removeEventListener("keydown", handler);
16
- window.removeEventListener("keyup", handler);
17
- window.removeEventListener("mousedown", handler);
18
- window.removeEventListener("mouseup", handler);
19
- });
20
- } catch {}
21
- return state;
22
- }
1
+ import{onUnmounted,ref}from"@stacksjs/stx";export function useKeyModifier(modifier){const state=ref(!1);if(typeof window>"u")return state;const handler=(e)=>{state.value=e.getModifierState(modifier)};window.addEventListener("keydown",handler,{passive:!0});window.addEventListener("keyup",handler,{passive:!0});window.addEventListener("mousedown",handler,{passive:!0});window.addEventListener("mouseup",handler,{passive:!0});try{onUnmounted(()=>{window.removeEventListener("keydown",handler);window.removeEventListener("keyup",handler);window.removeEventListener("mousedown",handler);window.removeEventListener("mouseup",handler)})}catch{}return state}
@@ -1,8 +1 @@
1
- import { ref, watch } from "@stacksjs/stx";
2
- export function useLastChanged(source, options = {}) {
3
- const { initialValue = null } = options, lastChanged = ref(initialValue);
4
- watch(source, () => {
5
- lastChanged.value = Date.now();
6
- });
7
- return lastChanged;
8
- }
1
+ import{ref,watch}from"@stacksjs/stx";export function useLastChanged(source,options={}){const{initialValue=null}=options,lastChanged=ref(initialValue);watch(source,()=>{lastChanged.value=Date.now()});return lastChanged}
@@ -1,4 +1 @@
1
- import { useStorage } from "./useStorage";
2
- export function useLocalStorage(key, defaultValue, options) {
3
- return useStorage(key, defaultValue, typeof localStorage < "u" ? localStorage : void 0, options);
4
- }
1
+ import{useStorage}from"./useStorage";export function useLocalStorage(key,defaultValue,options){return useStorage(key,defaultValue,typeof localStorage<"u"?localStorage:void 0,options)}