@stacksjs/composables 0.75.515 → 0.75.518

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 (155) hide show
  1. package/dist/_shared.js +1 -1
  2. package/dist/computedAsync.js +1 -1
  3. package/dist/computedEager.js +1 -1
  4. package/dist/createGlobalState.js +1 -1
  5. package/dist/createSharedComposable.js +1 -1
  6. package/dist/extendRef.js +1 -1
  7. package/dist/formatTimeAgo.js +1 -1
  8. package/dist/isDefined.js +1 -1
  9. package/dist/makeDestructurable.js +1 -1
  10. package/dist/onClickOutside.js +1 -1
  11. package/dist/onKeyStroke.js +1 -1
  12. package/dist/onLongPress.js +1 -1
  13. package/dist/onStartTyping.js +1 -1
  14. package/dist/session-handoff.js +1 -1
  15. package/dist/syncRef.js +1 -1
  16. package/dist/until.js +1 -1
  17. package/dist/useActiveElement.js +1 -1
  18. package/dist/useAnimate.js +1 -1
  19. package/dist/useArrayUtils.js +1 -1
  20. package/dist/useAsyncQueue.js +1 -1
  21. package/dist/useAsyncState.js +1 -1
  22. package/dist/useBase64.js +1 -1
  23. package/dist/useBattery.js +1 -1
  24. package/dist/useBreakpoints.js +1 -1
  25. package/dist/useBroadcastChannel.js +1 -1
  26. package/dist/useBrowserLocation.js +1 -1
  27. package/dist/useClipboard.js +1 -1
  28. package/dist/useClipboardItems.js +1 -1
  29. package/dist/useCloned.js +1 -1
  30. package/dist/useColorMode.js +1 -1
  31. package/dist/useConfirmDialog.js +1 -1
  32. package/dist/useCookieConsent.js +1 -1
  33. package/dist/useCssVar.js +1 -1
  34. package/dist/useCycleList.js +1 -1
  35. package/dist/useDark.js +1 -1
  36. package/dist/useDateFormat.js +1 -1
  37. package/dist/useDebounce.js +1 -1
  38. package/dist/useDebounceFn.js +1 -1
  39. package/dist/useDebouncedRef.js +1 -1
  40. package/dist/useDebouncedRefHistory.js +1 -1
  41. package/dist/useDeviceMotion.js +1 -1
  42. package/dist/useDeviceOrientation.js +1 -1
  43. package/dist/useDevicePixelRatio.js +1 -1
  44. package/dist/useDocumentVisibility.js +1 -1
  45. package/dist/useDraggable.js +1 -1
  46. package/dist/useDropZone.js +1 -1
  47. package/dist/useElementBounding.js +1 -1
  48. package/dist/useElementByPoint.js +1 -1
  49. package/dist/useElementHover.js +1 -1
  50. package/dist/useElementSize.js +1 -1
  51. package/dist/useElementVisibility.js +1 -1
  52. package/dist/useEventBus.js +1 -1
  53. package/dist/useEventListener.js +1 -1
  54. package/dist/useEventSource.js +1 -1
  55. package/dist/useEyeDropper.js +1 -1
  56. package/dist/useFavicon.js +1 -1
  57. package/dist/useFetch.js +1 -1
  58. package/dist/useFileDialog.js +1 -1
  59. package/dist/useFocus.js +1 -1
  60. package/dist/useFocusWithin.js +1 -1
  61. package/dist/useForm.js +1 -1
  62. package/dist/useFps.js +1 -1
  63. package/dist/useFullscreen.js +1 -1
  64. package/dist/useGeolocation.js +1 -1
  65. package/dist/useIdle.js +1 -1
  66. package/dist/useImage.js +1 -1
  67. package/dist/useInfiniteScroll.js +1 -1
  68. package/dist/useIntersectionObserver.js +1 -1
  69. package/dist/useInterval.js +1 -1
  70. package/dist/useIntervalFn.js +1 -1
  71. package/dist/useKeyModifier.js +1 -1
  72. package/dist/useLastChanged.js +1 -1
  73. package/dist/useLocalStorage.js +1 -1
  74. package/dist/useMagicKeys.js +1 -1
  75. package/dist/useManualRefHistory.js +1 -1
  76. package/dist/useMath.js +1 -1
  77. package/dist/useMediaQuery.js +1 -1
  78. package/dist/useMemoize.js +1 -1
  79. package/dist/useMounted.js +1 -1
  80. package/dist/useMouse.js +1 -1
  81. package/dist/useMouseInElement.js +1 -1
  82. package/dist/useMousePressed.js +1 -1
  83. package/dist/useMutationObserver.js +1 -1
  84. package/dist/useNavigatorLanguage.js +1 -1
  85. package/dist/useNetwork.js +1 -1
  86. package/dist/useNow.js +1 -1
  87. package/dist/useObjectUrl.js +1 -1
  88. package/dist/useOffsetPagination.js +1 -1
  89. package/dist/useOnline.js +1 -1
  90. package/dist/usePageLeave.js +1 -1
  91. package/dist/useParallax.js +1 -1
  92. package/dist/useParentElement.js +1 -1
  93. package/dist/usePermission.js +1 -1
  94. package/dist/usePointer.js +1 -1
  95. package/dist/usePointerLock.js +1 -1
  96. package/dist/usePointerSwipe.js +1 -1
  97. package/dist/usePreferredColorScheme.js +1 -1
  98. package/dist/usePreferredContrast.js +1 -1
  99. package/dist/usePreferredLanguages.js +1 -1
  100. package/dist/usePreferredReducedMotion.js +1 -1
  101. package/dist/useQuery.js +1 -1
  102. package/dist/useRafFn.js +1 -1
  103. package/dist/useRefHistory.js +1 -1
  104. package/dist/useResizeObserver.js +1 -1
  105. package/dist/useScreenOrientation.js +1 -1
  106. package/dist/useScreenSafeArea.js +1 -1
  107. package/dist/useScriptTag.js +1 -1
  108. package/dist/useScroll.js +1 -1
  109. package/dist/useScrollLock.js +1 -1
  110. package/dist/useSessionStorage.js +1 -1
  111. package/dist/useShare.js +1 -1
  112. package/dist/useSorted.js +1 -1
  113. package/dist/useStepper.js +1 -1
  114. package/dist/useStorage.js +1 -1
  115. package/dist/useStyleTag.js +1 -1
  116. package/dist/useSupported.js +1 -1
  117. package/dist/useSwipe.js +1 -1
  118. package/dist/useTextDirection.js +1 -1
  119. package/dist/useTextSelection.js +1 -1
  120. package/dist/useTextareaAutosize.js +1 -1
  121. package/dist/useThrottle.js +1 -1
  122. package/dist/useThrottleFn.js +1 -1
  123. package/dist/useThrottledRef.js +1 -1
  124. package/dist/useThrottledRefHistory.js +1 -1
  125. package/dist/useTimeAgo.js +1 -1
  126. package/dist/useTimeout.js +1 -1
  127. package/dist/useTimeoutFn.js +1 -1
  128. package/dist/useTimeoutPoll.js +1 -1
  129. package/dist/useTimestamp.js +1 -1
  130. package/dist/useTitle.js +1 -1
  131. package/dist/useToNumber.js +1 -1
  132. package/dist/useToString.js +1 -1
  133. package/dist/useToggle.js +1 -1
  134. package/dist/useTransition.js +1 -1
  135. package/dist/useUrlSearchParams.js +1 -1
  136. package/dist/useVibrate.js +1 -1
  137. package/dist/useVirtualList.js +1 -1
  138. package/dist/useWakeLock.js +1 -1
  139. package/dist/useWebNotification.js +1 -1
  140. package/dist/useWebSocket.js +1 -1
  141. package/dist/useWebWorker.js +1 -1
  142. package/dist/useWindowFocus.js +1 -1
  143. package/dist/useWindowScroll.js +1 -1
  144. package/dist/useWindowSize.js +1 -1
  145. package/dist/watchArray.js +1 -1
  146. package/dist/watchAtMost.js +1 -1
  147. package/dist/watchDebounced.js +1 -1
  148. package/dist/watchDeep.js +1 -1
  149. package/dist/watchIgnorable.js +1 -1
  150. package/dist/watchOnce.js +1 -1
  151. package/dist/watchPausable.js +1 -1
  152. package/dist/watchThrottled.js +1 -1
  153. package/dist/watchWithFilter.js +1 -1
  154. package/dist/whenever.js +1 -1
  155. package/package.json +2 -2
package/dist/_shared.js CHANGED
@@ -1 +1 @@
1
- export function unref(val){if(val&&typeof val==="object"&&"value"in val&&"subscribe"in val)return val.value;return val}export function toValue(val){if(typeof val==="function")return val();return unref(val)}export function isRef(val){return val!==null&&typeof val==="object"&&"value"in val&&"subscribe"in val}export function noop(){}export function defaultWindow(){return typeof window<"u"?window:void 0}export function defaultDocument(){return typeof document<"u"?document:void 0}export function defaultNavigator(){return typeof navigator<"u"?navigator:void 0}
1
+ export function unref(val){if(val&&typeof val==="object"&&"value"in val&&"subscribe"in val){return val.value}return val}export function toValue(val){if(typeof val==="function"){return val()}return unref(val)}export function isRef(val){return val!==null&&typeof val==="object"&&"value"in val&&"subscribe"in val}export function noop(){}export function defaultWindow(){return typeof window!=="undefined"?window:undefined}export function defaultDocument(){return typeof document!=="undefined"?document:undefined}export function defaultNavigator(){return typeof navigator!=="undefined"?navigator:undefined}
@@ -1 +1 @@
1
- import{ref,watch}from"@stacksjs/stx";export function computedAsync(evaluationCallback,initialState,deps){const result=ref(initialState);let currentEvalId=0;async function evaluate(){const evalId=++currentEvalId;try{const value=await evaluationCallback();if(evalId===currentEvalId)result.value=value}catch{}}evaluate();if(deps&&deps.length>0)for(const dep of deps)watch(dep,()=>{evaluate()});return result}
1
+ import{ref,watch}from"@stacksjs/stx";export function computedAsync(evaluationCallback,initialState,deps){const result=ref(initialState);let currentEvalId=0;async function evaluate(){const evalId=++currentEvalId;try{const value=await evaluationCallback();if(evalId===currentEvalId){result.value=value}}catch{}}evaluate();if(deps&&deps.length>0){for(const dep of deps){watch(dep,()=>{evaluate()})}}return result}
@@ -1 +1 @@
1
- import{ref,watch}from"@stacksjs/stx";export function computedEager(fn,deps){const result=ref(fn());if(deps&&deps.length>0)for(const dep of deps)watch(dep,()=>{result.value=fn()});return result}
1
+ import{ref,watch}from"@stacksjs/stx";export function computedEager(fn,deps){const result=ref(fn());if(deps&&deps.length>0){for(const dep of deps){watch(dep,()=>{result.value=fn()})}}return result}
@@ -1 +1 @@
1
- export function createGlobalState(stateFactory){let initialized=!1,state;return()=>{if(!initialized){state=stateFactory();initialized=!0}return state}}
1
+ export function createGlobalState(stateFactory){let initialized=false;let state;return()=>{if(!initialized){state=stateFactory();initialized=true}return state}}
@@ -1 +1 @@
1
- export function createSharedComposable(composable){let subscribers=0,state;return(...args)=>{subscribers++;if(!state)state=composable(...args);return state}}
1
+ export function createSharedComposable(composable){let subscribers=0;let state;return(...args)=>{subscribers++;if(!state)state=composable(...args);return state}}
package/dist/extendRef.js CHANGED
@@ -1 +1 @@
1
- export function extendRef(r,extend){for(const[key,value]of Object.entries(extend))if(key!=="value")r[key]=value;return r}
1
+ export function extendRef(r,extend){for(const[key,value]of Object.entries(extend)){if(key!=="value")r[key]=value}return r}
@@ -1 +1 @@
1
- const defaultMessages={justNow:"just now",past:(n)=>`${n} ago`,future:(n)=>`in ${n}`,second:(n)=>`${n} second${n>1?"s":""}`,minute:(n)=>`${n} minute${n>1?"s":""}`,hour:(n)=>`${n} hour${n>1?"s":""}`,day:(n)=>`${n} day${n>1?"s":""}`,week:(n)=>`${n} week${n>1?"s":""}`,month:(n)=>`${n} month${n>1?"s":""}`,year:(n)=>`${n} year${n>1?"s":""}`};export function formatTimeAgo(date,options={}){const messages={...defaultMessages,...options.messages},d=date instanceof Date?date:new Date(date),diff=Date.now()-d.getTime(),absDiff=Math.abs(diff),seconds=Math.floor(absDiff/1000),minutes=Math.floor(seconds/60),hours=Math.floor(minutes/60),days=Math.floor(hours/24),weeks=Math.floor(days/7),months=Math.floor(days/30),years=Math.floor(days/365),isFuture=diff<0;function format(value){return isFuture?messages.future(value):messages.past(value)}if(seconds<5)return messages.justNow;if(seconds<60)return format(messages.second(seconds));if(minutes<60)return format(messages.minute(minutes));if(hours<24)return format(messages.hour(hours));if(days<7)return format(messages.day(days));if(weeks<4)return format(messages.week(weeks));if(months<12)return format(messages.month(months));return format(messages.year(years))}
1
+ const defaultMessages={justNow:"just now",past:(n)=>`${n} ago`,future:(n)=>`in ${n}`,second:(n)=>`${n} second${n>1?"s":""}`,minute:(n)=>`${n} minute${n>1?"s":""}`,hour:(n)=>`${n} hour${n>1?"s":""}`,day:(n)=>`${n} day${n>1?"s":""}`,week:(n)=>`${n} week${n>1?"s":""}`,month:(n)=>`${n} month${n>1?"s":""}`,year:(n)=>`${n} year${n>1?"s":""}`};export function formatTimeAgo(date,options={}){const messages={...defaultMessages,...options.messages};const d=date instanceof Date?date:new Date(date);const now=Date.now();const diff=now-d.getTime();const absDiff=Math.abs(diff);const seconds=Math.floor(absDiff/1000);const minutes=Math.floor(seconds/60);const hours=Math.floor(minutes/60);const days=Math.floor(hours/24);const weeks=Math.floor(days/7);const months=Math.floor(days/30);const years=Math.floor(days/365);const isFuture=diff<0;function format(value){return isFuture?messages.future(value):messages.past(value)}if(seconds<5)return messages.justNow;if(seconds<60)return format(messages.second(seconds));if(minutes<60)return format(messages.minute(minutes));if(hours<24)return format(messages.hour(hours));if(days<7)return format(messages.day(days));if(weeks<4)return format(messages.week(weeks));if(months<12)return format(messages.month(months));return format(messages.year(years))}
package/dist/isDefined.js CHANGED
@@ -1 +1 @@
1
- export function isDefined(v){return v.value!==null&&v.value!==void 0}
1
+ export function isDefined(v){return v.value!==null&&v.value!==undefined}
@@ -1 +1 @@
1
- export function makeDestructurable(obj,arr){const clone={...obj};Object.defineProperty(clone,Symbol.iterator,{enumerable:!1,value(){let index=0;return{next:()=>({value:arr[index++],done:index>arr.length})}}});return clone}
1
+ export function makeDestructurable(obj,arr){const clone={...obj};Object.defineProperty(clone,Symbol.iterator,{enumerable:false,value(){let index=0;return{next:()=>({value:arr[index++],done:index>arr.length})}}});return clone}
@@ -1 +1 @@
1
- import{defaultWindow,unref}from"./_shared";export function onClickOutside(target,handler,options){const win=defaultWindow();if(!win)return()=>{};const{ignore=[]}=options??{};function listener(event){const el=unref(target);if(!el)return;const mouseEvent=event,composedPath=mouseEvent.composedPath?.()??[];if(el===mouseEvent.target||composedPath.includes(el)||el.contains(mouseEvent.target))return;for(const ignored of ignore){const ignoredEl=unref(ignored);if(ignoredEl&&(ignoredEl===mouseEvent.target||composedPath.includes(ignoredEl)||ignoredEl.contains(mouseEvent.target)))return}handler(mouseEvent)}win.addEventListener("pointerdown",listener,{passive:!0});return()=>{win.removeEventListener("pointerdown",listener)}}
1
+ import{defaultWindow,unref}from"./_shared";export function onClickOutside(target,handler,options){const win=defaultWindow();if(!win){return()=>{}}const{ignore=[]}=options??{};function listener(event){const el=unref(target);if(!el)return;const mouseEvent=event;const composedPath=mouseEvent.composedPath?.()??[];if(el===mouseEvent.target||composedPath.includes(el)||el.contains(mouseEvent.target)){return}for(const ignored of ignore){const ignoredEl=unref(ignored);if(ignoredEl&&(ignoredEl===mouseEvent.target||composedPath.includes(ignoredEl)||ignoredEl.contains(mouseEvent.target))){return}}handler(mouseEvent)}win.addEventListener("pointerdown",listener,{passive:true});const cleanup=()=>{win.removeEventListener("pointerdown",listener)};return cleanup}
@@ -1 +1 @@
1
- import{defaultWindow,unref}from"./_shared";export function onKeyStroke(key,handler,options){const{eventName="keydown",target}=options??{},win=defaultWindow(),eventTarget=target?unref(target):win;if(!eventTarget)return()=>{};function createKeyFilter(keyDef){if(typeof keyDef==="function")return keyDef;if(typeof keyDef==="string")return(event)=>event.key===keyDef;if(Array.isArray(keyDef))return(event)=>keyDef.includes(event.key);return()=>!0}const filter=createKeyFilter(key);function listener(event){const keyEvent=event;if(filter(keyEvent))handler(keyEvent)}eventTarget.addEventListener(eventName,listener);return()=>{eventTarget.removeEventListener(eventName,listener)}}export function onKeyDown(key,handler,options){return onKeyStroke(key,handler,{...options,eventName:"keydown"})}export function onKeyUp(key,handler,options){return onKeyStroke(key,handler,{...options,eventName:"keyup"})}
1
+ import{defaultWindow,unref}from"./_shared";export function onKeyStroke(key,handler,options){const{eventName="keydown",target}=options??{};const win=defaultWindow();const eventTarget=target?unref(target):win;if(!eventTarget){return()=>{}}function createKeyFilter(keyDef){if(typeof keyDef==="function"){return keyDef}if(typeof keyDef==="string"){return(event)=>event.key===keyDef}if(Array.isArray(keyDef)){return(event)=>keyDef.includes(event.key)}return()=>true}const filter=createKeyFilter(key);function listener(event){const keyEvent=event;if(filter(keyEvent)){handler(keyEvent)}}eventTarget.addEventListener(eventName,listener);const cleanup=()=>{eventTarget.removeEventListener(eventName,listener)};return cleanup}export function onKeyDown(key,handler,options){return onKeyStroke(key,handler,{...options,eventName:"keydown"})}export function onKeyUp(key,handler,options){return onKeyStroke(key,handler,{...options,eventName:"keyup"})}
@@ -1 +1 @@
1
- import{onUnmounted}from"@stacksjs/stx";import{unref}from"./_shared";export function onLongPress(target,handler,options={}){const{delay=500,distanceThreshold=10}=options;let timer=null,startX=0,startY=0;const el=unref(target);if(!el)return()=>{};const clear=()=>{if(timer!==null){clearTimeout(timer);timer=null}},onDown=(e)=>{startX=e.clientX;startY=e.clientY;clear();timer=setTimeout(()=>handler(e),delay)},onMove=(e)=>{if(timer===null)return;const dx=Math.abs(e.clientX-startX),dy=Math.abs(e.clientY-startY);if(dx>distanceThreshold||dy>distanceThreshold)clear()},onUp=()=>{clear()};el.addEventListener("pointerdown",onDown);el.addEventListener("pointermove",onMove);el.addEventListener("pointerup",onUp);el.addEventListener("pointercancel",onUp);const cleanup=()=>{clear();el.removeEventListener("pointerdown",onDown);el.removeEventListener("pointermove",onMove);el.removeEventListener("pointerup",onUp);el.removeEventListener("pointercancel",onUp)};try{onUnmounted(cleanup)}catch{}return cleanup}
1
+ import{onUnmounted}from"@stacksjs/stx";import{unref}from"./_shared";export function onLongPress(target,handler,options={}){const{delay=500,distanceThreshold=10}=options;let timer=null;let startX=0;let startY=0;const el=unref(target);if(!el)return()=>{};const clear=()=>{if(timer!==null){clearTimeout(timer);timer=null}};const onDown=(e)=>{startX=e.clientX;startY=e.clientY;clear();timer=setTimeout(()=>handler(e),delay)};const onMove=(e)=>{if(timer===null)return;const dx=Math.abs(e.clientX-startX);const dy=Math.abs(e.clientY-startY);if(dx>distanceThreshold||dy>distanceThreshold)clear()};const onUp=()=>{clear()};el.addEventListener("pointerdown",onDown);el.addEventListener("pointermove",onMove);el.addEventListener("pointerup",onUp);el.addEventListener("pointercancel",onUp);const cleanup=()=>{clear();el.removeEventListener("pointerdown",onDown);el.removeEventListener("pointermove",onMove);el.removeEventListener("pointerup",onUp);el.removeEventListener("pointercancel",onUp)};try{onUnmounted(cleanup)}catch{}return cleanup}
@@ -1 +1 @@
1
- import{onUnmounted}from"@stacksjs/stx";export function onStartTyping(callback){if(typeof document>"u")return()=>{};const handler=(e)=>{const active=document.activeElement;if(active){const tag=active.tagName.toLowerCase();if(tag==="input"||tag==="textarea"||active.isContentEditable)return}if(e.key.length===1&&!e.ctrlKey&&!e.metaKey&&!e.altKey)callback(e)};document.addEventListener("keydown",handler);const cleanup=()=>{document.removeEventListener("keydown",handler)};try{onUnmounted(cleanup)}catch{}return cleanup}
1
+ import{onUnmounted}from"@stacksjs/stx";export function onStartTyping(callback){if(typeof document==="undefined")return()=>{};const handler=(e)=>{const active=document.activeElement;if(active){const tag=active.tagName.toLowerCase();if(tag==="input"||tag==="textarea"||active.isContentEditable)return}if(e.key.length===1&&!e.ctrlKey&&!e.metaKey&&!e.altKey)callback(e)};document.addEventListener("keydown",handler);const cleanup=()=>{document.removeEventListener("keydown",handler)};try{onUnmounted(cleanup)}catch{}return cleanup}
@@ -1 +1 @@
1
- export const SESSION_HANDOFF_KEY="stx_auth",SESSION_HANDOFF_CODE_KEY="stx_handoff";const HANDOFF_CODE_SHAPE=/^[a-f0-9]{64}$/;function toBase64Url(input){const bytes=new TextEncoder().encode(input);let binary="";for(const byte of bytes)binary+=String.fromCharCode(byte);return btoa(binary).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function fromBase64Url(input){const padded=input.replace(/-/g,"+").replace(/_/g,"/")+"=".repeat((4-input.length%4)%4),binary=atob(padded),bytes=new Uint8Array(binary.length);for(let i=0;i<binary.length;i++)bytes[i]=binary.charCodeAt(i);return new TextDecoder().decode(bytes)}export function encodeSessionHandoff(pack){return toBase64Url(JSON.stringify({token:pack.token,refresh_token:pack.refreshToken,user:pack.user,expires_in:pack.expiresIn}))}export function decodeSessionHandoff(value){if(!value)return null;try{const parsed=JSON.parse(fromBase64Url(value)),token=parsed.token??parsed.access_token;if(typeof token!=="string"||token.length===0)return null;return{token,refreshToken:typeof parsed.refresh_token==="string"?parsed.refresh_token:void 0,user:parsed.user,expiresIn:typeof parsed.expires_in==="number"?parsed.expires_in:void 0}}catch{return null}}export function buildSessionHandoffUrl(redirectTo,pack){const encoded=encodeSessionHandoff(pack),[base,existingHash]=splitHash(redirectTo),prefix=existingHash?`${existingHash}&`:"";return`${base}#${prefix}${SESSION_HANDOFF_KEY}=${encoded}`}export function readSessionHandoff(hash){if(!hash)return null;const params=new URLSearchParams(hash.startsWith("#")?hash.slice(1):hash);return decodeSessionHandoff(params.get(SESSION_HANDOFF_KEY))}export function buildSessionHandoffCodeUrl(redirectTo,code){if(!HANDOFF_CODE_SHAPE.test(code))throw TypeError("A session handoff code is 64 lowercase hex characters.");const[base,existingHash]=splitHash(redirectTo),prefix=existingHash?`${existingHash}&`:"";return`${base}#${prefix}${SESSION_HANDOFF_CODE_KEY}=${code}`}export function readSessionHandoffCode(hash){if(!hash)return null;const code=new URLSearchParams(hash.startsWith("#")?hash.slice(1):hash).get(SESSION_HANDOFF_CODE_KEY);return code&&HANDOFF_CODE_SHAPE.test(code)?code:null}export function stripSessionHandoff(hash){if(!hash)return"";const params=new URLSearchParams(hash.startsWith("#")?hash.slice(1):hash);params.delete(SESSION_HANDOFF_KEY);params.delete(SESSION_HANDOFF_CODE_KEY);const rest=params.toString();return rest?`#${rest}`:""}function splitHash(url){const at=url.indexOf("#");return at===-1?[url,""]:[url.slice(0,at),url.slice(at+1)]}
1
+ export const SESSION_HANDOFF_KEY="stx_auth";export const SESSION_HANDOFF_CODE_KEY="stx_handoff";const HANDOFF_CODE_SHAPE=/^[a-f0-9]{64}$/;function toBase64Url(input){const bytes=new TextEncoder().encode(input);let binary="";for(const byte of bytes)binary+=String.fromCharCode(byte);return btoa(binary).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function fromBase64Url(input){const padded=input.replace(/-/g,"+").replace(/_/g,"/")+"=".repeat((4-input.length%4)%4);const binary=atob(padded);const bytes=new Uint8Array(binary.length);for(let i=0;i<binary.length;i++)bytes[i]=binary.charCodeAt(i);return new TextDecoder().decode(bytes)}export function encodeSessionHandoff(pack){return toBase64Url(JSON.stringify({token:pack.token,refresh_token:pack.refreshToken,user:pack.user,expires_in:pack.expiresIn}))}export function decodeSessionHandoff(value){if(!value)return null;try{const parsed=JSON.parse(fromBase64Url(value));const token=parsed.token??parsed.access_token;if(typeof token!=="string"||token.length===0)return null;return{token,refreshToken:typeof parsed.refresh_token==="string"?parsed.refresh_token:undefined,user:parsed.user,expiresIn:typeof parsed.expires_in==="number"?parsed.expires_in:undefined}}catch{return null}}export function buildSessionHandoffUrl(redirectTo,pack){const encoded=encodeSessionHandoff(pack);const[base,existingHash]=splitHash(redirectTo);const prefix=existingHash?`${existingHash}&`:"";return`${base}#${prefix}${SESSION_HANDOFF_KEY}=${encoded}`}export function readSessionHandoff(hash){if(!hash)return null;const params=new URLSearchParams(hash.startsWith("#")?hash.slice(1):hash);return decodeSessionHandoff(params.get(SESSION_HANDOFF_KEY))}export function buildSessionHandoffCodeUrl(redirectTo,code){if(!HANDOFF_CODE_SHAPE.test(code))throw new TypeError("A session handoff code is 64 lowercase hex characters.");const[base,existingHash]=splitHash(redirectTo);const prefix=existingHash?`${existingHash}&`:"";return`${base}#${prefix}${SESSION_HANDOFF_CODE_KEY}=${code}`}export function readSessionHandoffCode(hash){if(!hash)return null;const code=new URLSearchParams(hash.startsWith("#")?hash.slice(1):hash).get(SESSION_HANDOFF_CODE_KEY);return code&&HANDOFF_CODE_SHAPE.test(code)?code:null}export function stripSessionHandoff(hash){if(!hash)return"";const params=new URLSearchParams(hash.startsWith("#")?hash.slice(1):hash);params.delete(SESSION_HANDOFF_KEY);params.delete(SESSION_HANDOFF_CODE_KEY);const rest=params.toString();return rest?`#${rest}`:""}function splitHash(url){const at=url.indexOf("#");return at===-1?[url,""]:[url.slice(0,at),url.slice(at+1)]}
package/dist/syncRef.js CHANGED
@@ -1 +1 @@
1
- import{watch}from"@stacksjs/stx";export function syncRef(left,right,options={}){const{direction="both"}=options;let syncing=!1;const unwatchers=[];if(direction==="both"||direction==="ltr")unwatchers.push(watch(left,(val)=>{if(syncing)return;syncing=!0;right.value=val;syncing=!1}));if(direction==="both"||direction==="rtl")unwatchers.push(watch(right,(val)=>{if(syncing)return;syncing=!0;left.value=val;syncing=!1}));return()=>{for(const unwatch of unwatchers)unwatch()}}export function syncRefs(sources,target){const unwatchers=sources.map((source)=>watch(source,(val)=>{target.value=val}));return()=>{for(const unwatch of unwatchers)unwatch()}}
1
+ import{watch}from"@stacksjs/stx";export function syncRef(left,right,options={}){const{direction="both"}=options;let syncing=false;const unwatchers=[];if(direction==="both"||direction==="ltr"){unwatchers.push(watch(left,(val)=>{if(syncing)return;syncing=true;right.value=val;syncing=false}))}if(direction==="both"||direction==="rtl"){unwatchers.push(watch(right,(val)=>{if(syncing)return;syncing=true;left.value=val;syncing=false}))}return()=>{for(const unwatch of unwatchers)unwatch()}}export function syncRefs(sources,target){const unwatchers=sources.map((source)=>watch(source,(val)=>{target.value=val}));return()=>{for(const unwatch of unwatchers)unwatch()}}
package/dist/until.js CHANGED
@@ -1 +1 @@
1
- import{watch}from"@stacksjs/stx";export function until(r){function toMatch(condition,options={}){const{timeout,throwOnTimeout=!1}=options;if(condition(r.value))return Promise.resolve(r.value);return new Promise((resolve,reject)=>{let timer=null;const unwatch=watch(r,(newVal)=>{if(condition(newVal)){unwatch();if(timer!==null)clearTimeout(timer);resolve(newVal)}});if(timeout!==void 0)timer=setTimeout(()=>{unwatch();if(throwOnTimeout)reject(Error("Timeout"));else resolve(r.value)},timeout)})}function toBe(value,options){return toMatch((v)=>v===value,options)}function toBeTruthy(options){return toMatch((v)=>Boolean(v),options)}function toBeNull(options){return toMatch((v)=>v===null,options)}function toBeUndefined(options){return toMatch((v)=>v===void 0,options)}function toBeNaN(options){return toMatch((v)=>Number.isNaN(v),options)}function changed(options){const initial=r.value;return toMatch((v)=>v!==initial,options)}return{toMatch,toBe,toBeTruthy,toBeNull,toBeUndefined,toBeNaN,changed,not:{toBe:(value,options)=>toMatch((v)=>v!==value,options),toBeTruthy:(options)=>toMatch((v)=>!v,options),toBeNull:(options)=>toMatch((v)=>v!==null,options),toBeUndefined:(options)=>toMatch((v)=>v!==void 0,options),toBeNaN:(options)=>toMatch((v)=>!Number.isNaN(v),options)}}}
1
+ import{watch}from"@stacksjs/stx";export function until(r){function toMatch(condition,options={}){const{timeout,throwOnTimeout=false}=options;if(condition(r.value))return Promise.resolve(r.value);return new Promise((resolve,reject)=>{let timer=null;const unwatch=watch(r,(newVal)=>{if(condition(newVal)){unwatch();if(timer!==null)clearTimeout(timer);resolve(newVal)}});if(timeout!==undefined){timer=setTimeout(()=>{unwatch();if(throwOnTimeout)reject(new Error("Timeout"));else resolve(r.value)},timeout)}})}function toBe(value,options){return toMatch((v)=>v===value,options)}function toBeTruthy(options){return toMatch((v)=>Boolean(v),options)}function toBeNull(options){return toMatch((v)=>v===null,options)}function toBeUndefined(options){return toMatch((v)=>v===undefined,options)}function toBeNaN(options){return toMatch((v)=>Number.isNaN(v),options)}function changed(options){const initial=r.value;return toMatch((v)=>v!==initial,options)}return{toMatch,toBe,toBeTruthy,toBeNull,toBeUndefined,toBeNaN,changed,not:{toBe:(value,options)=>toMatch((v)=>v!==value,options),toBeTruthy:(options)=>toMatch((v)=>!v,options),toBeNull:(options)=>toMatch((v)=>v!==null,options),toBeUndefined:(options)=>toMatch((v)=>v!==undefined,options),toBeNaN:(options)=>toMatch((v)=>!Number.isNaN(v),options)}}}
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";export function useActiveElement(){const activeElement=ref(null);if(typeof document>"u")return activeElement;activeElement.value=document.activeElement;const handler=()=>{activeElement.value=document.activeElement};document.addEventListener("focusin",handler,{passive:!0});document.addEventListener("focusout",handler,{passive:!0});try{onUnmounted(()=>{document.removeEventListener("focusin",handler);document.removeEventListener("focusout",handler)})}catch{}return activeElement}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";export function useActiveElement(){const activeElement=ref(null);if(typeof document==="undefined")return activeElement;activeElement.value=document.activeElement;const handler=()=>{activeElement.value=document.activeElement};document.addEventListener("focusin",handler,{passive:true});document.addEventListener("focusout",handler,{passive:true});try{onUnmounted(()=>{document.removeEventListener("focusin",handler);document.removeEventListener("focusout",handler)})}catch{}return activeElement}
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";import{unref}from"./_shared";export function useAnimate(target,keyframes,options){const isSupported=ref(typeof HTMLElement<"u"&&"animate"in HTMLElement.prototype),animate=ref(void 0),pending=ref(!1),playState=ref("idle"),currentTime=ref(null);function syncState(){if(animate.value){pending.value=animate.value.pending;playState.value=animate.value.playState;currentTime.value=animate.value.currentTime}}function init(){const el=unref(target);if(!el||!isSupported.value)return;animate.value=el.animate(keyframes,options);animate.value.addEventListener("finish",syncState);animate.value.addEventListener("cancel",syncState);syncState()}function play(){animate.value?.play();syncState()}function pause(){animate.value?.pause();syncState()}function reverse(){animate.value?.reverse();syncState()}function finish(){animate.value?.finish();syncState()}function cancel(){animate.value?.cancel();syncState()}init();try{onUnmounted(()=>{animate.value?.cancel()})}catch{}return{isSupported,animate,play,pause,reverse,finish,cancel,pending,playState,currentTime}}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";import{unref}from"./_shared";export function useAnimate(target,keyframes,options){const isSupported=ref(typeof HTMLElement!=="undefined"&&"animate"in HTMLElement.prototype);const animate=ref(undefined);const pending=ref(false);const playState=ref("idle");const currentTime=ref(null);function syncState(){if(animate.value){pending.value=animate.value.pending;playState.value=animate.value.playState;currentTime.value=animate.value.currentTime}}function init(){const el=unref(target);if(!el||!isSupported.value)return;animate.value=el.animate(keyframes,options);animate.value.addEventListener("finish",syncState);animate.value.addEventListener("cancel",syncState);syncState()}function play(){animate.value?.play();syncState()}function pause(){animate.value?.pause();syncState()}function reverse(){animate.value?.reverse();syncState()}function finish(){animate.value?.finish();syncState()}function cancel(){animate.value?.cancel();syncState()}init();try{onUnmounted(()=>{animate.value?.cancel()})}catch{}return{isSupported,animate,play,pause,reverse,finish,cancel,pending,playState,currentTime}}
@@ -1 +1 @@
1
- import{ref,watch}from"@stacksjs/stx";import{isRef,unref}from"./_shared";function watchSource(source,cb){if(isRef(source))watch(source,cb)}function getArray(source){return unref(source)}export function useArrayDifference(list,other,compareFn){const result=ref([]);function update(){const arr=getArray(list),otherArr=getArray(other);if(compareFn)result.value=arr.filter((item)=>!otherArr.some((o)=>compareFn(item,o)));else result.value=arr.filter((item)=>!otherArr.includes(item))}update();watchSource(list,update);watchSource(other,update);return result}export function useArrayEvery(list,fn){const result=ref(!1);function update(){result.value=getArray(list).every(fn)}update();watchSource(list,update);return result}export function useArrayFilter(list,fn){const result=ref([]);function update(){result.value=getArray(list).filter(fn)}update();watchSource(list,update);return result}export function useArrayFind(list,fn){const result=ref(void 0);function update(){result.value=getArray(list).find(fn)}update();watchSource(list,update);return result}export function useArrayFindIndex(list,fn){const result=ref(-1);function update(){result.value=getArray(list).findIndex(fn)}update();watchSource(list,update);return result}export function useArrayIncludes(list,value,compareFn){const result=ref(!1);function update(){const arr=getArray(list),v=unref(value);if(compareFn)result.value=arr.some((item)=>compareFn(item,v));else result.value=arr.includes(v)}update();watchSource(list,update);if(isRef(value))watch(value,update);return result}export function useArrayMap(list,fn){const result=ref([]);function update(){result.value=getArray(list).map(fn)}update();watchSource(list,update);return result}export function useArrayReduce(list,fn,initialValue){const result=ref(initialValue);function update(){result.value=getArray(list).reduce(fn,initialValue)}update();watchSource(list,update);return result}export function useArraySome(list,fn){const result=ref(!1);function update(){result.value=getArray(list).some(fn)}update();watchSource(list,update);return result}export function useArrayUnique(list,compareFn){const result=ref([]);function update(){const arr=getArray(list);if(compareFn)result.value=arr.filter((item,index)=>arr.findIndex((other)=>compareFn(item,other))===index);else result.value=[...new Set(arr)]}update();watchSource(list,update);return result}
1
+ import{ref,watch}from"@stacksjs/stx";import{isRef,unref}from"./_shared";function watchSource(source,cb){if(isRef(source))watch(source,cb)}function getArray(source){return unref(source)}export function useArrayDifference(list,other,compareFn){const result=ref([]);function update(){const arr=getArray(list);const otherArr=getArray(other);if(compareFn)result.value=arr.filter((item)=>!otherArr.some((o)=>compareFn(item,o)));else result.value=arr.filter((item)=>!otherArr.includes(item))}update();watchSource(list,update);watchSource(other,update);return result}export function useArrayEvery(list,fn){const result=ref(false);function update(){result.value=getArray(list).every(fn)}update();watchSource(list,update);return result}export function useArrayFilter(list,fn){const result=ref([]);function update(){result.value=getArray(list).filter(fn)}update();watchSource(list,update);return result}export function useArrayFind(list,fn){const result=ref(undefined);function update(){result.value=getArray(list).find(fn)}update();watchSource(list,update);return result}export function useArrayFindIndex(list,fn){const result=ref(-1);function update(){result.value=getArray(list).findIndex(fn)}update();watchSource(list,update);return result}export function useArrayIncludes(list,value,compareFn){const result=ref(false);function update(){const arr=getArray(list);const v=unref(value);if(compareFn)result.value=arr.some((item)=>compareFn(item,v));else result.value=arr.includes(v)}update();watchSource(list,update);if(isRef(value))watch(value,update);return result}export function useArrayMap(list,fn){const result=ref([]);function update(){result.value=getArray(list).map(fn)}update();watchSource(list,update);return result}export function useArrayReduce(list,fn,initialValue){const result=ref(initialValue);function update(){result.value=getArray(list).reduce(fn,initialValue)}update();watchSource(list,update);return result}export function useArraySome(list,fn){const result=ref(false);function update(){result.value=getArray(list).some(fn)}update();watchSource(list,update);return result}export function useArrayUnique(list,compareFn){const result=ref([]);function update(){const arr=getArray(list);if(compareFn)result.value=arr.filter((item,index)=>arr.findIndex((other)=>compareFn(item,other))===index);else result.value=[...new Set(arr)]}update();watchSource(list,update);return result}
@@ -1 +1 @@
1
- import{ref}from"@stacksjs/stx";export function useAsyncQueue(tasks){const activeIndex=ref(-1),isFinished=ref(!1),result=ref(tasks.map(()=>({state:"pending"})));async function runTasks(){for(let i=0;i<tasks.length;i++){activeIndex.value=i;const task=tasks[i];if(!task)continue;try{const data=await task();result.value=result.value.map((r,idx)=>idx===i?{state:"fulfilled",data}:r)}catch(e){result.value=result.value.map((r,idx)=>idx===i?{state:"rejected",data:e}:r)}}activeIndex.value=tasks.length;isFinished.value=!0}runTasks();return{activeIndex,result,isFinished}}
1
+ import{ref}from"@stacksjs/stx";export function useAsyncQueue(tasks){const activeIndex=ref(-1);const isFinished=ref(false);const result=ref(tasks.map(()=>({state:"pending"})));async function runTasks(){for(let i=0;i<tasks.length;i++){activeIndex.value=i;const task=tasks[i];if(!task)continue;try{const data=await task();result.value=result.value.map((r,idx)=>idx===i?{state:"fulfilled",data}:r)}catch(e){result.value=result.value.map((r,idx)=>idx===i?{state:"rejected",data:e}:r)}}activeIndex.value=tasks.length;isFinished.value=true}runTasks();return{activeIndex,result,isFinished}}
@@ -1 +1 @@
1
- import{ref}from"@stacksjs/stx";export function useAsyncState(promise,initialState,options={}){const{immediate=!0,onError,resetOnExecute=!0,delay=0}=options,state=ref(initialState),isReady=ref(!1),isLoading=ref(!1),error=ref(void 0);async function execute(executeDelay){const delayMs=executeDelay??delay;if(resetOnExecute)state.value=initialState;error.value=void 0;isReady.value=!1;isLoading.value=!0;if(delayMs>0)await new Promise((resolve)=>setTimeout(resolve,delayMs));try{const result=typeof promise==="function"?await promise():await promise;state.value=result;isReady.value=!0;return result}catch(e){error.value=e;if(onError)onError(e);return state.value}finally{isLoading.value=!1}}if(immediate)execute();return{state,isReady,isLoading,error,execute}}
1
+ import{ref}from"@stacksjs/stx";export function useAsyncState(promise,initialState,options={}){const{immediate=true,onError,resetOnExecute=true,delay=0}=options;const state=ref(initialState);const isReady=ref(false);const isLoading=ref(false);const error=ref(undefined);async function execute(executeDelay){const delayMs=executeDelay??delay;if(resetOnExecute){state.value=initialState}error.value=undefined;isReady.value=false;isLoading.value=true;if(delayMs>0){await new Promise((resolve)=>setTimeout(resolve,delayMs))}try{const result=typeof promise==="function"?await promise():await promise;state.value=result;isReady.value=true;return result}catch(e){error.value=e;if(onError){onError(e)}return state.value}finally{isLoading.value=false}}if(immediate){execute()}return{state,isReady,isLoading,error,execute}}
package/dist/useBase64.js CHANGED
@@ -1 +1 @@
1
- import{ref,watch}from"@stacksjs/stx";import{isRef,unref}from"./_shared";export function useBase64(source){const base64=ref("");async function encode(input){if(typeof input==="string"){if(typeof btoa<"u")return btoa(input);return Buffer.from(input).toString("base64")}if(input instanceof ArrayBuffer){const bytes=new Uint8Array(input);let binary="";for(const byte of bytes)binary+=String.fromCharCode(byte);if(typeof btoa<"u")return btoa(binary);return Buffer.from(input).toString("base64")}if(typeof Blob<"u"&&input instanceof Blob)return new Promise((resolve,reject)=>{const reader=new FileReader;reader.onload=()=>{const result=reader.result,base64Part=result.split(",")[1]??result;resolve(base64Part)};reader.onerror=reject;reader.readAsDataURL(input)});if(typeof HTMLCanvasElement<"u"&&input instanceof HTMLCanvasElement)return input.toDataURL().split(",")[1]??"";return""}async function execute(){const val=unref(source),result=await encode(val);base64.value=result;return result}execute().catch(()=>{});if(isRef(source))watch(source,()=>{execute().catch(()=>{})});return{base64,execute}}
1
+ import{ref,watch}from"@stacksjs/stx";import{isRef,unref}from"./_shared";export function useBase64(source){const base64=ref("");async function encode(input){if(typeof input==="string"){if(typeof btoa!=="undefined")return btoa(input);return Buffer.from(input).toString("base64")}if(input instanceof ArrayBuffer){const bytes=new Uint8Array(input);let binary="";for(const byte of bytes)binary+=String.fromCharCode(byte);if(typeof btoa!=="undefined")return btoa(binary);return Buffer.from(input).toString("base64")}if(typeof Blob!=="undefined"&&input instanceof Blob){return new Promise((resolve,reject)=>{const reader=new FileReader;reader.onload=()=>{const result=reader.result;const base64Part=result.split(",")[1]??result;resolve(base64Part)};reader.onerror=reject;reader.readAsDataURL(input)})}if(typeof HTMLCanvasElement!=="undefined"&&input instanceof HTMLCanvasElement){const dataUrl=input.toDataURL();return dataUrl.split(",")[1]??""}return""}async function execute(){const val=unref(source);const result=await encode(val);base64.value=result;return result}execute().catch(()=>{});if(isRef(source)){watch(source,()=>{execute().catch(()=>{})})}return{base64,execute}}
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";import{noop}from"./_shared";export function useBattery(){const nav=typeof navigator<"u"?navigator:void 0,isSupported=ref(!!nav?.getBattery),charging=ref(!1),chargingTime=ref(0),dischargingTime=ref(0),level=ref(1),cleanups=[];let cleanup=noop;if(isSupported.value&&nav?.getBattery)nav.getBattery().then((battery)=>{const updateBatteryInfo=()=>{charging.value=battery.charging;chargingTime.value=battery.chargingTime;dischargingTime.value=battery.dischargingTime;level.value=battery.level};updateBatteryInfo();battery.addEventListener("chargingchange",updateBatteryInfo);battery.addEventListener("chargingtimechange",updateBatteryInfo);battery.addEventListener("dischargingtimechange",updateBatteryInfo);battery.addEventListener("levelchange",updateBatteryInfo);cleanups.push(()=>{battery.removeEventListener("chargingchange",updateBatteryInfo);battery.removeEventListener("chargingtimechange",updateBatteryInfo);battery.removeEventListener("dischargingtimechange",updateBatteryInfo);battery.removeEventListener("levelchange",updateBatteryInfo)});cleanup=()=>{for(const fn of cleanups)fn();cleanups.length=0;cleanup=noop}}).catch(()=>{isSupported.value=!1});try{onUnmounted(()=>cleanup())}catch{}return{charging,chargingTime,dischargingTime,level,isSupported}}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";import{noop}from"./_shared";export function useBattery(){const nav=typeof navigator!=="undefined"?navigator:undefined;const isSupported=ref(!!nav?.getBattery);const charging=ref(false);const chargingTime=ref(0);const dischargingTime=ref(0);const level=ref(1);const cleanups=[];let cleanup=noop;if(isSupported.value&&nav?.getBattery){nav.getBattery().then((battery)=>{const updateBatteryInfo=()=>{charging.value=battery.charging;chargingTime.value=battery.chargingTime;dischargingTime.value=battery.dischargingTime;level.value=battery.level};updateBatteryInfo();battery.addEventListener("chargingchange",updateBatteryInfo);battery.addEventListener("chargingtimechange",updateBatteryInfo);battery.addEventListener("dischargingtimechange",updateBatteryInfo);battery.addEventListener("levelchange",updateBatteryInfo);cleanups.push(()=>{battery.removeEventListener("chargingchange",updateBatteryInfo);battery.removeEventListener("chargingtimechange",updateBatteryInfo);battery.removeEventListener("dischargingtimechange",updateBatteryInfo);battery.removeEventListener("levelchange",updateBatteryInfo)});cleanup=()=>{for(const fn of cleanups)fn();cleanups.length=0;cleanup=noop}}).catch(()=>{isSupported.value=false})}try{onUnmounted(()=>cleanup())}catch{}return{charging,chargingTime,dischargingTime,level,isSupported}}
@@ -1 +1 @@
1
- import{computed,ref,onUnmounted}from"@stacksjs/stx";import{defaultWindow}from"./_shared";export function useBreakpoints(breakpoints){const win=defaultWindow(),width=ref(win?win.innerWidth:0);function updateWidth(){if(win)width.value=win.innerWidth}if(win){win.addEventListener("resize",updateWidth);try{onUnmounted(()=>{win.removeEventListener("resize",updateWidth)})}catch{}}function getValue(k){return breakpoints[k]}function greaterOrEqual(k){return computed(()=>width.value>=getValue(k))}function smallerOrEqual(k){return computed(()=>width.value<=getValue(k))}function between(a,b){return computed(()=>width.value>=getValue(a)&&width.value<getValue(b))}function isGreater(k){return computed(()=>width.value>getValue(k))}function isSmaller(k){return computed(()=>width.value<getValue(k))}function current(){return computed(()=>{return Object.keys(breakpoints).sort((a,b)=>breakpoints[a]-breakpoints[b]).filter((k)=>width.value>=breakpoints[k])})}return{greaterOrEqual,smallerOrEqual,between,isGreater,isSmaller,current}}export const breakpointsTailwind={sm:640,md:768,lg:1024,xl:1280,"2xl":1536},breakpointsBootstrap={sm:576,md:768,lg:992,xl:1200,xxl:1400},breakpointsBootstrapV5=breakpointsBootstrap,breakpointsAntDesign={xs:480,sm:576,md:768,lg:992,xl:1200,xxl:1600},breakpointsMaterialDesign={xs:600,sm:960,md:1264,lg:1904},breakpointsQuasar={xs:600,sm:1024,md:1440,lg:1920},breakpointsMasterCss={"3xs":360,"2xs":480,xs:600,sm:768,md:1024,lg:1280,xl:1440,"2xl":1600,"3xl":1920,"4xl":2560},breakpointsSematic={mobileS:320,mobileM:375,mobileL:425,tablet:768,laptop:1024,laptopL:1440,desktop:2560};
1
+ import{computed,ref,onUnmounted}from"@stacksjs/stx";import{defaultWindow}from"./_shared";export function useBreakpoints(breakpoints){const win=defaultWindow();const width=ref(win?win.innerWidth:0);function updateWidth(){if(win){width.value=win.innerWidth}}if(win){win.addEventListener("resize",updateWidth);try{onUnmounted(()=>{win.removeEventListener("resize",updateWidth)})}catch{}}function getValue(k){return breakpoints[k]}function greaterOrEqual(k){return computed(()=>width.value>=getValue(k))}function smallerOrEqual(k){return computed(()=>width.value<=getValue(k))}function between(a,b){return computed(()=>width.value>=getValue(a)&&width.value<getValue(b))}function isGreater(k){return computed(()=>width.value>getValue(k))}function isSmaller(k){return computed(()=>width.value<getValue(k))}function current(){return computed(()=>{const sorted=Object.keys(breakpoints).sort((a,b)=>breakpoints[a]-breakpoints[b]);return sorted.filter((k)=>width.value>=breakpoints[k])})}return{greaterOrEqual,smallerOrEqual,between,isGreater,isSmaller,current}}export const breakpointsTailwind={sm:640,md:768,lg:1024,xl:1280,"2xl":1536};export const breakpointsBootstrap={sm:576,md:768,lg:992,xl:1200,xxl:1400};export const breakpointsBootstrapV5=breakpointsBootstrap;export const breakpointsAntDesign={xs:480,sm:576,md:768,lg:992,xl:1200,xxl:1600};export const breakpointsMaterialDesign={xs:600,sm:960,md:1264,lg:1904};export const breakpointsQuasar={xs:600,sm:1024,md:1440,lg:1920};export const breakpointsMasterCss={"3xs":360,"2xs":480,xs:600,sm:768,md:1024,lg:1280,xl:1440,"2xl":1600,"3xl":1920,"4xl":2560};export const breakpointsSematic={mobileS:320,mobileM:375,mobileL:425,tablet:768,laptop:1024,laptopL:1440,desktop:2560};
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";export function useBroadcastChannel(name){const isSupported=ref(typeof BroadcastChannel<"u"),channel=ref(void 0),data=ref(null),error=ref(null),isClosed=ref(!1);if(isSupported.value){const bc=new BroadcastChannel(name);channel.value=bc;bc.onmessage=(e)=>{data.value=e.data};bc.onmessageerror=(e)=>{error.value=e};try{onUnmounted(()=>{bc.close();isClosed.value=!0})}catch{}}function post(message){if(channel.value&&!isClosed.value)channel.value.postMessage(message)}function close(){if(channel.value&&!isClosed.value){channel.value.close();isClosed.value=!0}}return{isSupported,channel,data,error,post,close,isClosed}}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";export function useBroadcastChannel(name){const isSupported=ref(typeof BroadcastChannel!=="undefined");const channel=ref(undefined);const data=ref(null);const error=ref(null);const isClosed=ref(false);if(isSupported.value){const bc=new BroadcastChannel(name);channel.value=bc;bc.onmessage=(e)=>{data.value=e.data};bc.onmessageerror=(e)=>{error.value=e};try{onUnmounted(()=>{bc.close();isClosed.value=true})}catch{}}function post(message){if(channel.value&&!isClosed.value)channel.value.postMessage(message)}function close(){if(channel.value&&!isClosed.value){channel.value.close();isClosed.value=true}}return{isSupported,channel,data,error,post,close,isClosed}}
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";import{defaultWindow}from"./_shared";export function useBrowserLocation(){const win=defaultWindow();function readLocation(){if(!win)return{href:"",protocol:"",host:"",hostname:"",port:"",pathname:"",search:"",hash:"",origin:""};return{href:win.location.href,protocol:win.location.protocol,host:win.location.host,hostname:win.location.hostname,port:win.location.port,pathname:win.location.pathname,search:win.location.search,hash:win.location.hash,origin:win.location.origin}}const initial=readLocation(),href=ref(initial.href),protocol=ref(initial.protocol),host=ref(initial.host),hostname=ref(initial.hostname),port=ref(initial.port),pathname=ref(initial.pathname),search=ref(initial.search),hash=ref(initial.hash),origin=ref(initial.origin);function update(){const loc=readLocation();href.value=loc.href;protocol.value=loc.protocol;host.value=loc.host;hostname.value=loc.hostname;port.value=loc.port;pathname.value=loc.pathname;search.value=loc.search;hash.value=loc.hash;origin.value=loc.origin}if(win){win.addEventListener("popstate",update);win.addEventListener("hashchange",update);try{onUnmounted(()=>{win.removeEventListener("popstate",update);win.removeEventListener("hashchange",update)})}catch{}}return{href,protocol,host,hostname,port,pathname,search,hash,origin}}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";import{defaultWindow}from"./_shared";export function useBrowserLocation(){const win=defaultWindow();function readLocation(){if(!win){return{href:"",protocol:"",host:"",hostname:"",port:"",pathname:"",search:"",hash:"",origin:""}}return{href:win.location.href,protocol:win.location.protocol,host:win.location.host,hostname:win.location.hostname,port:win.location.port,pathname:win.location.pathname,search:win.location.search,hash:win.location.hash,origin:win.location.origin}}const initial=readLocation();const href=ref(initial.href);const protocol=ref(initial.protocol);const host=ref(initial.host);const hostname=ref(initial.hostname);const port=ref(initial.port);const pathname=ref(initial.pathname);const search=ref(initial.search);const hash=ref(initial.hash);const origin=ref(initial.origin);function update(){const loc=readLocation();href.value=loc.href;protocol.value=loc.protocol;host.value=loc.host;hostname.value=loc.hostname;port.value=loc.port;pathname.value=loc.pathname;search.value=loc.search;hash.value=loc.hash;origin.value=loc.origin}if(win){win.addEventListener("popstate",update);win.addEventListener("hashchange",update);try{onUnmounted(()=>{win.removeEventListener("popstate",update);win.removeEventListener("hashchange",update)})}catch{}}return{href,protocol,host,hostname,port,pathname,search,hash,origin}}
@@ -1 +1 @@
1
- import{ref}from"@stacksjs/stx";import{defaultNavigator,toValue}from"./_shared";export function useClipboard(options){const{source,copiedDuring=1500}=options??{},nav=defaultNavigator(),isSupported=ref(!!nav&&"clipboard"in nav),text=ref(""),copied=ref(!1);let copiedTimer;async function copy(value){if(!isSupported.value)return;const valueToCopy=value??(source!==void 0?toValue(source):void 0);if(valueToCopy===void 0)return;try{await nav.clipboard.writeText(valueToCopy);text.value=valueToCopy;copied.value=!0;if(copiedTimer)clearTimeout(copiedTimer);copiedTimer=setTimeout(()=>{copied.value=!1},copiedDuring)}catch{}}return{text,isSupported,copied,copy}}
1
+ import{ref}from"@stacksjs/stx";import{defaultNavigator,toValue}from"./_shared";export function useClipboard(options){const{source,copiedDuring=1500}=options??{};const nav=defaultNavigator();const isSupported=ref(!!nav&&"clipboard"in nav);const text=ref("");const copied=ref(false);let copiedTimer;async function copy(value){if(!isSupported.value)return;const valueToCopy=value??(source!==undefined?toValue(source):undefined);if(valueToCopy===undefined)return;try{await nav.clipboard.writeText(valueToCopy);text.value=valueToCopy;copied.value=true;if(copiedTimer)clearTimeout(copiedTimer);copiedTimer=setTimeout(()=>{copied.value=false},copiedDuring)}catch{}}return{text,isSupported,copied,copy}}
@@ -1 +1 @@
1
- import{ref}from"@stacksjs/stx";export function useClipboardItems(){const isSupported=ref(typeof navigator<"u"&&"clipboard"in navigator&&typeof ClipboardItem<"u"),content=ref([]);async function copy(items){if(isSupported.value){await navigator.clipboard.write(items);content.value=items}}async function read(){if(isSupported.value)content.value=await navigator.clipboard.read()}return{isSupported,content,copy,read}}
1
+ import{ref}from"@stacksjs/stx";export function useClipboardItems(){const isSupported=ref(typeof navigator!=="undefined"&&"clipboard"in navigator&&typeof ClipboardItem!=="undefined");const content=ref([]);async function copy(items){if(isSupported.value){await navigator.clipboard.write(items);content.value=items}}async function read(){if(isSupported.value){content.value=await navigator.clipboard.read()}}return{isSupported,content,copy,read}}
package/dist/useCloned.js CHANGED
@@ -1 +1 @@
1
- import{ref,watch}from"@stacksjs/stx";function defaultClone(val){if(typeof structuredClone==="function")return structuredClone(val);return JSON.parse(JSON.stringify(val))}export function useCloned(source,options={}){const cloneFn=options.clone??defaultClone,cloned=ref(cloneFn(source.value));function sync(){cloned.value=cloneFn(source.value)}watch(source,()=>{sync()});return{cloned,sync}}
1
+ import{ref,watch}from"@stacksjs/stx";function defaultClone(val){if(typeof structuredClone==="function"){return structuredClone(val)}return JSON.parse(JSON.stringify(val))}export function useCloned(source,options={}){const cloneFn=options.clone??defaultClone;const cloned=ref(cloneFn(source.value));function sync(){cloned.value=cloneFn(source.value)}watch(source,()=>{sync()});return{cloned,sync}}
@@ -1 +1 @@
1
- import{onUnmounted,ref,watch}from"@stacksjs/stx";export function useColorMode(options={}){const{attribute="class",initialValue="auto",modes={},storageKey="color-mode",selector}=options,system=ref("light");if(typeof window<"u"&&window.matchMedia){const mq=window.matchMedia("(prefers-color-scheme: dark)");system.value=mq.matches?"dark":"light";const onChange=(e)=>{system.value=e.matches?"dark":"light"};mq.addEventListener("change",onChange);try{onUnmounted(()=>{mq.removeEventListener("change",onChange)})}catch{}}let stored=initialValue;if(typeof localStorage<"u"){const val=localStorage.getItem(storageKey);if(val)stored=val}const store=ref(stored),mode=ref(store.value==="auto"?system.value:store.value);function applyMode(m){if(typeof document>"u")return;const el=selector?document.querySelector(selector):document.documentElement;if(!el)return;const value=modes[m]??m;if(attribute==="class"){const allModes=["dark","light",...Object.keys(modes),...Object.values(modes)];for(const cls of allModes)el.classList.remove(cls);if(value)el.classList.add(value)}else el.setAttribute(attribute,value)}watch(store,(val)=>{if(typeof localStorage<"u")localStorage.setItem(storageKey,val);mode.value=val==="auto"?system.value:val});watch(system,(val)=>{if(store.value==="auto")mode.value=val});watch(mode,(val)=>{applyMode(val)});applyMode(mode.value);return{mode,system,store}}
1
+ import{onUnmounted,ref,watch}from"@stacksjs/stx";export function useColorMode(options={}){const{attribute="class",initialValue="auto",modes={},storageKey="color-mode",selector}=options;const system=ref("light");if(typeof window!=="undefined"&&window.matchMedia){const mq=window.matchMedia("(prefers-color-scheme: dark)");system.value=mq.matches?"dark":"light";const onChange=(e)=>{system.value=e.matches?"dark":"light"};mq.addEventListener("change",onChange);try{onUnmounted(()=>{mq.removeEventListener("change",onChange)})}catch{}}let stored=initialValue;if(typeof localStorage!=="undefined"){const val=localStorage.getItem(storageKey);if(val)stored=val}const store=ref(stored);const mode=ref(store.value==="auto"?system.value:store.value);function applyMode(m){if(typeof document==="undefined")return;const el=selector?document.querySelector(selector):document.documentElement;if(!el)return;const value=modes[m]??m;if(attribute==="class"){const allModes=["dark","light",...Object.keys(modes),...Object.values(modes)];for(const cls of allModes)el.classList.remove(cls);if(value)el.classList.add(value)}else{el.setAttribute(attribute,value)}}watch(store,(val)=>{if(typeof localStorage!=="undefined")localStorage.setItem(storageKey,val);mode.value=val==="auto"?system.value:val});watch(system,(val)=>{if(store.value==="auto")mode.value=val});watch(mode,(val)=>{applyMode(val)});applyMode(mode.value);return{mode,system,store}}
@@ -1 +1 @@
1
- import{ref}from"@stacksjs/stx";import{createEventHook}from"./createEventHook";export function useConfirmDialog(){const isRevealed=ref(!1),confirmHook=createEventHook(),cancelHook=createEventHook(),revealHook=createEventHook();let resolvePromise=null;function reveal(data){isRevealed.value=!0;revealHook.trigger(data);return new Promise((resolve)=>{resolvePromise=resolve})}function confirm(data){isRevealed.value=!1;confirmHook.trigger(data);resolvePromise?.({data,isCanceled:!1});resolvePromise=null}function cancel(){isRevealed.value=!1;cancelHook.trigger(void 0);resolvePromise?.({isCanceled:!0});resolvePromise=null}return{isRevealed,reveal,confirm,cancel,onConfirm:confirmHook.on,onCancel:cancelHook.on,onReveal:revealHook.on}}
1
+ import{ref}from"@stacksjs/stx";import{createEventHook}from"./createEventHook";export function useConfirmDialog(){const isRevealed=ref(false);const confirmHook=createEventHook();const cancelHook=createEventHook();const revealHook=createEventHook();let resolvePromise=null;function reveal(data){isRevealed.value=true;revealHook.trigger(data);return new Promise((resolve)=>{resolvePromise=resolve})}function confirm(data){isRevealed.value=false;confirmHook.trigger(data);resolvePromise?.({data,isCanceled:false});resolvePromise=null}function cancel(){isRevealed.value=false;cancelHook.trigger(undefined);resolvePromise?.({isCanceled:true});resolvePromise=null}return{isRevealed,reveal,confirm,cancel,onConfirm:confirmHook.on,onCancel:cancelHook.on,onReveal:revealHook.on}}
@@ -1 +1 @@
1
- import{ref}from"@stacksjs/stx";export const OPTIONAL_CATEGORIES=["preferences","analytics","marketing"];const DEFAULT_KEY="stacks:cookie-consent:v1";export function emptyCategories(){return{necessary:!0,preferences:!1,analytics:!1,marketing:!1}}export function parseDecision(raw,policyVersion){if(!raw)return null;let parsed;try{parsed=JSON.parse(raw)}catch{return null}if(!parsed||typeof parsed!=="object")return null;const candidate=parsed;if(candidate.policyVersion!==policyVersion)return null;if(!candidate.categories||typeof candidate.categories!=="object")return null;if(typeof candidate.decidedAt!=="string")return null;const categories=emptyCategories();for(const category of OPTIONAL_CATEGORIES)categories[category]=candidate.categories[category]===!0;return{categories,policyVersion,decidedAt:candidate.decidedAt}}function readStored(key){try{return globalThis.localStorage?.getItem(key)??null}catch{return null}}function writeStored(key,value){try{if(value===null)globalThis.localStorage?.removeItem(key);else globalThis.localStorage?.setItem(key,value)}catch{}}export function useCookieConsent(options={}){const policyVersion=options.policyVersion??"1.0",storageKey=options.storageKey??DEFAULT_KEY,decision=ref(parseDecision(readStored(storageKey),policyVersion)),needsDecision=ref(decision.value===null);if(decision.value)options.onChange?.(decision.value);function commit(categories){const next={categories:{...categories,necessary:!0},policyVersion,decidedAt:new Date().toISOString()};decision.value=next;needsDecision.value=!1;writeStored(storageKey,JSON.stringify(next));options.onChange?.(next);return next}return{decision,needsDecision,allows(category){if(category==="necessary")return!0;return decision.value?.categories[category]===!0},accept(categories=OPTIONAL_CATEGORIES){const next=emptyCategories();for(const category of categories)if(category!=="necessary")next[category]=!0;return commit(next)},acceptAll(){const next=emptyCategories();for(const category of OPTIONAL_CATEGORIES)next[category]=!0;return commit(next)},declineAll(){return commit(emptyCategories())},withdraw(){decision.value=null;needsDecision.value=!0;writeStored(storageKey,null);options.onChange?.(null)}}}
1
+ import{ref}from"@stacksjs/stx";export const OPTIONAL_CATEGORIES=["preferences","analytics","marketing"];const DEFAULT_KEY="stacks:cookie-consent:v1";export function emptyCategories(){return{necessary:true,preferences:false,analytics:false,marketing:false}}export function parseDecision(raw,policyVersion){if(!raw)return null;let parsed;try{parsed=JSON.parse(raw)}catch{return null}if(!parsed||typeof parsed!=="object")return null;const candidate=parsed;if(candidate.policyVersion!==policyVersion)return null;if(!candidate.categories||typeof candidate.categories!=="object")return null;if(typeof candidate.decidedAt!=="string")return null;const categories=emptyCategories();for(const category of OPTIONAL_CATEGORIES)categories[category]=candidate.categories[category]===true;return{categories,policyVersion,decidedAt:candidate.decidedAt}}function readStored(key){try{return globalThis.localStorage?.getItem(key)??null}catch{return null}}function writeStored(key,value){try{if(value===null)globalThis.localStorage?.removeItem(key);else globalThis.localStorage?.setItem(key,value)}catch{}}export function useCookieConsent(options={}){const policyVersion=options.policyVersion??"1.0";const storageKey=options.storageKey??DEFAULT_KEY;const decision=ref(parseDecision(readStored(storageKey),policyVersion));const needsDecision=ref(decision.value===null);if(decision.value)options.onChange?.(decision.value);function commit(categories){const next={categories:{...categories,necessary:true},policyVersion,decidedAt:new Date().toISOString()};decision.value=next;needsDecision.value=false;writeStored(storageKey,JSON.stringify(next));options.onChange?.(next);return next}return{decision,needsDecision,allows(category){if(category==="necessary")return true;return decision.value?.categories[category]===true},accept(categories=OPTIONAL_CATEGORIES){const next=emptyCategories();for(const category of categories){if(category!=="necessary")next[category]=true}return commit(next)},acceptAll(){const next=emptyCategories();for(const category of OPTIONAL_CATEGORIES)next[category]=true;return commit(next)},declineAll(){return commit(emptyCategories())},withdraw(){decision.value=null;needsDecision.value=true;writeStored(storageKey,null);options.onChange?.(null)}}}
package/dist/useCssVar.js CHANGED
@@ -1 +1 @@
1
- import{ref,watch}from"@stacksjs/stx";import{unref}from"./_shared";export function useCssVar(name,target,defaultValue){const variable=ref(defaultValue??""),getEl=()=>{const t=unref(target);if(t)return t;if(typeof document<"u")return document.documentElement;return null},el=getEl();if(el){const current=getComputedStyle(el).getPropertyValue(unref(name)).trim();if(current)variable.value=current}watch(variable,(val)=>{const element=getEl();if(element)element.style.setProperty(unref(name),val)});return variable}
1
+ import{ref,watch}from"@stacksjs/stx";import{unref}from"./_shared";export function useCssVar(name,target,defaultValue){const variable=ref(defaultValue??"");const getEl=()=>{const t=unref(target);if(t)return t;if(typeof document!=="undefined")return document.documentElement;return null};const el=getEl();if(el){const current=getComputedStyle(el).getPropertyValue(unref(name)).trim();if(current)variable.value=current}watch(variable,(val)=>{const element=getEl();if(element)element.style.setProperty(unref(name),val)});return variable}
@@ -1 +1 @@
1
- import{computed,ref}from"@stacksjs/stx";export function useCycleList(list,options={}){const length=list.length;if(length===0)throw Error("useCycleList requires a non-empty list");const initialIndex=options.initialValue!==void 0?list.indexOf(options.initialValue):0,index=ref(initialIndex>=0?initialIndex:0);function at(i){return list[i]}const state=computed(()=>at(index.value));function normalizeIndex(i){return(i%length+length)%length}function next(n=1){index.value=normalizeIndex(index.value+n);return at(index.value)}function prev(n=1){index.value=normalizeIndex(index.value-n);return at(index.value)}function go(i){index.value=normalizeIndex(i);return at(index.value)}return{state,index,next,prev,go}}
1
+ import{computed,ref}from"@stacksjs/stx";export function useCycleList(list,options={}){const length=list.length;if(length===0){throw new Error("useCycleList requires a non-empty list")}const initialIndex=options.initialValue!==undefined?list.indexOf(options.initialValue):0;const index=ref(initialIndex>=0?initialIndex:0);function at(i){return list[i]}const state=computed(()=>at(index.value));function normalizeIndex(i){return(i%length+length)%length}function next(n=1){index.value=normalizeIndex(index.value+n);return at(index.value)}function prev(n=1){index.value=normalizeIndex(index.value-n);return at(index.value)}function go(i){index.value=normalizeIndex(i);return at(index.value)}return{state,index,next,prev,go}}
package/dist/useDark.js CHANGED
@@ -1 +1 @@
1
- import{onUnmounted,ref,watch}from"@stacksjs/stx";export function usePreferredDark(){const matches=ref(!1);if(typeof window<"u"&&window.matchMedia){const mq=window.matchMedia("(prefers-color-scheme: dark)");matches.value=mq.matches;const onChange=(e)=>{matches.value=e.matches};mq.addEventListener("change",onChange);try{onUnmounted(()=>{mq.removeEventListener("change",onChange)})}catch{}}return matches}export function useDark(){let initial=usePreferredDark().value;if(typeof localStorage<"u"){const stored=localStorage.getItem("color-scheme");if(stored==="dark")initial=!0;else if(stored==="light")initial=!1}const isDark=ref(initial);watch(isDark,(val)=>{if(typeof document<"u")document.documentElement.classList.toggle("dark",val);if(typeof localStorage<"u")localStorage.setItem("color-scheme",val?"dark":"light")});if(typeof document<"u")document.documentElement.classList.toggle("dark",isDark.value);return isDark}
1
+ import{onUnmounted,ref,watch}from"@stacksjs/stx";export function usePreferredDark(){const matches=ref(false);if(typeof window!=="undefined"&&window.matchMedia){const mq=window.matchMedia("(prefers-color-scheme: dark)");matches.value=mq.matches;const onChange=(e)=>{matches.value=e.matches};mq.addEventListener("change",onChange);try{onUnmounted(()=>{mq.removeEventListener("change",onChange)})}catch{}}return matches}export function useDark(){const prefersDark=usePreferredDark();let initial=prefersDark.value;if(typeof localStorage!=="undefined"){const stored=localStorage.getItem("color-scheme");if(stored==="dark")initial=true;else if(stored==="light")initial=false}const isDark=ref(initial);watch(isDark,(val)=>{if(typeof document!=="undefined"){document.documentElement.classList.toggle("dark",val)}if(typeof localStorage!=="undefined"){localStorage.setItem("color-scheme",val?"dark":"light")}});if(typeof document!=="undefined"){document.documentElement.classList.toggle("dark",isDark.value)}return isDark}
@@ -1 +1 @@
1
- import{computed,ref}from"@stacksjs/stx";import{format}from"@stacksjs/datetime";export function useDateFormat(date,formatStr){if(typeof date==="object"&&date!==null&&"value"in date&&"subscribe"in date)return computed(()=>{const d=date.value;return format(d instanceof Date?d:new Date(d),formatStr)});const d=date instanceof Date?date:new Date(date);return ref(format(d,formatStr))}
1
+ import{computed,ref}from"@stacksjs/stx";import{format}from"@stacksjs/datetime";export function useDateFormat(date,formatStr){if(typeof date==="object"&&date!==null&&"value"in date&&"subscribe"in date){return computed(()=>{const d=date.value;return format(d instanceof Date?d:new Date(d),formatStr)})}const d=date instanceof Date?date:new Date(date);return ref(format(d,formatStr))}
@@ -1 +1 @@
1
- import{ref,watch}from"@stacksjs/stx";import{isRef,unref}from"./_shared";export function useDebounce(value,ms=200){const debounced=ref(unref(value));let timer=null;if(isRef(value))watch(value,(newVal)=>{if(timer!==null)clearTimeout(timer);timer=setTimeout(()=>{debounced.value=newVal;timer=null},ms)});return debounced}
1
+ import{ref,watch}from"@stacksjs/stx";import{isRef,unref}from"./_shared";export function useDebounce(value,ms=200){const debounced=ref(unref(value));let timer=null;if(isRef(value)){watch(value,(newVal)=>{if(timer!==null)clearTimeout(timer);timer=setTimeout(()=>{debounced.value=newVal;timer=null},ms)})}return debounced}
@@ -1 +1 @@
1
- export function useDebounceFn(fn,ms=200){let timeoutId=null;const debounced=function(...args){if(timeoutId!==null)clearTimeout(timeoutId);timeoutId=setTimeout(()=>{timeoutId=null;fn.apply(this,args)},ms)};debounced.cancel=()=>{if(timeoutId!==null){clearTimeout(timeoutId);timeoutId=null}};return debounced}
1
+ export function useDebounceFn(fn,ms=200){let timeoutId=null;const debounced=function(...args){if(timeoutId!==null){clearTimeout(timeoutId)}timeoutId=setTimeout(()=>{timeoutId=null;fn.apply(this,args)},ms)};debounced.cancel=()=>{if(timeoutId!==null){clearTimeout(timeoutId);timeoutId=null}};return debounced}
@@ -1 +1 @@
1
- import{ref,watch}from"@stacksjs/stx";export function useDebouncedRef(value,delay=200){const source=ref(value),debounced=ref(value);let timeoutId=null;watch(source,(newVal)=>{if(timeoutId!==null)clearTimeout(timeoutId);timeoutId=setTimeout(()=>{debounced.value=newVal;timeoutId=null},delay)});return{get value(){return debounced.value},set value(newVal){source.value=newVal},subscribe:debounced.subscribe}}
1
+ import{ref,watch}from"@stacksjs/stx";export function useDebouncedRef(value,delay=200){const source=ref(value);const debounced=ref(value);let timeoutId=null;watch(source,(newVal)=>{if(timeoutId!==null){clearTimeout(timeoutId)}timeoutId=setTimeout(()=>{debounced.value=newVal;timeoutId=null},delay)});return{get value(){return debounced.value},set value(newVal){source.value=newVal},subscribe:debounced.subscribe}}
@@ -1 +1 @@
1
- import{useManualRefHistory}from"./useManualRefHistory";import{watch}from"@stacksjs/stx";export function useDebouncedRefHistory(source,options){const delay=options?.debounce??200,{history,commit,undo,redo,canUndo,canRedo,clear,last}=useManualRefHistory(source,options);let timer=null,ignoreNext=!1;watch(source,()=>{if(ignoreNext){ignoreNext=!1;return}if(timer!==null)clearTimeout(timer);timer=setTimeout(()=>{timer=null;commit()},delay)});const origUndo=undo,origRedo=redo;function debouncedUndo(){if(timer!==null){clearTimeout(timer);timer=null}ignoreNext=!0;origUndo()}function debouncedRedo(){if(timer!==null){clearTimeout(timer);timer=null}ignoreNext=!0;origRedo()}return{history,commit,undo:debouncedUndo,redo:debouncedRedo,canUndo,canRedo,clear,last}}
1
+ import{useManualRefHistory}from"./useManualRefHistory";import{watch}from"@stacksjs/stx";export function useDebouncedRefHistory(source,options){const delay=options?.debounce??200;const{history,commit,undo,redo,canUndo,canRedo,clear,last}=useManualRefHistory(source,options);let timer=null;let ignoreNext=false;watch(source,()=>{if(ignoreNext){ignoreNext=false;return}if(timer!==null)clearTimeout(timer);timer=setTimeout(()=>{timer=null;commit()},delay)});const origUndo=undo;const origRedo=redo;function debouncedUndo(){if(timer!==null){clearTimeout(timer);timer=null}ignoreNext=true;origUndo()}function debouncedRedo(){if(timer!==null){clearTimeout(timer);timer=null}ignoreNext=true;origRedo()}return{history,commit,undo:debouncedUndo,redo:debouncedRedo,canUndo,canRedo,clear,last}}
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";import{noop}from"./_shared";export function useDeviceMotion(){const isSupported=ref(typeof window<"u"&&"DeviceMotionEvent"in window),acceleration={x:ref(null),y:ref(null),z:ref(null)},accelerationIncludingGravity={x:ref(null),y:ref(null),z:ref(null)},rotationRate={alpha:ref(null),beta:ref(null),gamma:ref(null)},interval=ref(0);let cleanup=noop;if(typeof window<"u"&&isSupported.value){const handler=(event)=>{if(event.acceleration){acceleration.x.value=event.acceleration.x;acceleration.y.value=event.acceleration.y;acceleration.z.value=event.acceleration.z}if(event.accelerationIncludingGravity){accelerationIncludingGravity.x.value=event.accelerationIncludingGravity.x;accelerationIncludingGravity.y.value=event.accelerationIncludingGravity.y;accelerationIncludingGravity.z.value=event.accelerationIncludingGravity.z}if(event.rotationRate){rotationRate.alpha.value=event.rotationRate.alpha;rotationRate.beta.value=event.rotationRate.beta;rotationRate.gamma.value=event.rotationRate.gamma}interval.value=event.interval};window.addEventListener("devicemotion",handler,{passive:!0});cleanup=()=>{window.removeEventListener("devicemotion",handler);cleanup=noop}}try{onUnmounted(()=>cleanup())}catch{}return{acceleration,accelerationIncludingGravity,rotationRate,interval,isSupported}}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";import{noop}from"./_shared";export function useDeviceMotion(){const isSupported=ref(typeof window!=="undefined"&&"DeviceMotionEvent"in window);const acceleration={x:ref(null),y:ref(null),z:ref(null)};const accelerationIncludingGravity={x:ref(null),y:ref(null),z:ref(null)};const rotationRate={alpha:ref(null),beta:ref(null),gamma:ref(null)};const interval=ref(0);let cleanup=noop;if(typeof window!=="undefined"&&isSupported.value){const handler=(event)=>{if(event.acceleration){acceleration.x.value=event.acceleration.x;acceleration.y.value=event.acceleration.y;acceleration.z.value=event.acceleration.z}if(event.accelerationIncludingGravity){accelerationIncludingGravity.x.value=event.accelerationIncludingGravity.x;accelerationIncludingGravity.y.value=event.accelerationIncludingGravity.y;accelerationIncludingGravity.z.value=event.accelerationIncludingGravity.z}if(event.rotationRate){rotationRate.alpha.value=event.rotationRate.alpha;rotationRate.beta.value=event.rotationRate.beta;rotationRate.gamma.value=event.rotationRate.gamma}interval.value=event.interval};window.addEventListener("devicemotion",handler,{passive:true});cleanup=()=>{window.removeEventListener("devicemotion",handler);cleanup=noop}}try{onUnmounted(()=>cleanup())}catch{}return{acceleration,accelerationIncludingGravity,rotationRate,interval,isSupported}}
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";import{noop}from"./_shared";export function useDeviceOrientation(){const isSupported=ref(typeof window<"u"&&"DeviceOrientationEvent"in window),alpha=ref(null),beta=ref(null),gamma=ref(null),absolute=ref(!1);let cleanup=noop;if(typeof window<"u"&&isSupported.value){const handler=(event)=>{alpha.value=event.alpha;beta.value=event.beta;gamma.value=event.gamma;absolute.value=event.absolute};window.addEventListener("deviceorientation",handler,{passive:!0});cleanup=()=>{window.removeEventListener("deviceorientation",handler);cleanup=noop}}try{onUnmounted(()=>cleanup())}catch{}return{alpha,beta,gamma,absolute,isSupported}}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";import{noop}from"./_shared";export function useDeviceOrientation(){const isSupported=ref(typeof window!=="undefined"&&"DeviceOrientationEvent"in window);const alpha=ref(null);const beta=ref(null);const gamma=ref(null);const absolute=ref(false);let cleanup=noop;if(typeof window!=="undefined"&&isSupported.value){const handler=(event)=>{alpha.value=event.alpha;beta.value=event.beta;gamma.value=event.gamma;absolute.value=event.absolute};window.addEventListener("deviceorientation",handler,{passive:true});cleanup=()=>{window.removeEventListener("deviceorientation",handler);cleanup=noop}}try{onUnmounted(()=>cleanup())}catch{}return{alpha,beta,gamma,absolute,isSupported}}
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";export function useDevicePixelRatio(){const pixelRatio=ref(typeof window<"u"?window.devicePixelRatio:1);if(typeof window>"u")return{pixelRatio};let mq=null,cleanup=()=>{};function observe(){cleanup();mq=window.matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`);const handler=()=>{pixelRatio.value=window.devicePixelRatio;observe()};mq.addEventListener("change",handler,{once:!0});cleanup=()=>{mq?.removeEventListener("change",handler)}}observe();try{onUnmounted(()=>cleanup())}catch{}return{pixelRatio}}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";export function useDevicePixelRatio(){const pixelRatio=ref(typeof window!=="undefined"?window.devicePixelRatio:1);if(typeof window==="undefined")return{pixelRatio};let mq=null;let cleanup=()=>{};function observe(){cleanup();mq=window.matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`);const handler=()=>{pixelRatio.value=window.devicePixelRatio;observe()};mq.addEventListener("change",handler,{once:true});cleanup=()=>{mq?.removeEventListener("change",handler)}}observe();try{onUnmounted(()=>cleanup())}catch{}return{pixelRatio}}
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";export function useDocumentVisibility(){const visibility=ref(typeof document<"u"?document.visibilityState:"visible");if(typeof document>"u")return visibility;const handler=()=>{visibility.value=document.visibilityState};document.addEventListener("visibilitychange",handler,{passive:!0});try{onUnmounted(()=>{document.removeEventListener("visibilitychange",handler)})}catch{}return visibility}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";export function useDocumentVisibility(){const visibility=ref(typeof document!=="undefined"?document.visibilityState:"visible");if(typeof document==="undefined")return visibility;const handler=()=>{visibility.value=document.visibilityState};document.addEventListener("visibilitychange",handler,{passive:true});try{onUnmounted(()=>{document.removeEventListener("visibilitychange",handler)})}catch{}return visibility}
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";import{unref,noop}from"./_shared";export function useDraggable(target,options){const initialX=options?.initialValue?.x??0,initialY=options?.initialValue?.y??0,x=ref(initialX),y=ref(initialY),isDragging=ref(!1),style=ref(`left: ${initialX}px; top: ${initialY}px;`);let cleanup=noop;if(typeof window<"u"){const cleanups=[];let startX=0,startY=0,offsetX=0,offsetY=0;const updateStyle=()=>{style.value=`left: ${x.value}px; top: ${y.value}px;`},onPointerMove=(event)=>{if(!isDragging.value)return;x.value=event.clientX-offsetX;y.value=event.clientY-offsetY;updateStyle();if(options?.onMove)options.onMove({x:x.value,y:y.value},event)},onPointerUp=(event)=>{if(!isDragging.value)return;isDragging.value=!1;if(options?.onEnd)options.onEnd({x:x.value,y:y.value},event);window.removeEventListener("pointermove",onPointerMove);window.removeEventListener("pointerup",onPointerUp)},onPointerDown=(event)=>{const pos={x:x.value,y:y.value};if(options?.onStart){if(options.onStart(pos,event)===!1)return}startX=event.clientX;startY=event.clientY;offsetX=startX-x.value;offsetY=startY-y.value;isDragging.value=!0;window.addEventListener("pointermove",onPointerMove);window.addEventListener("pointerup",onPointerUp)},el=unref(target);if(el){el.addEventListener("pointerdown",onPointerDown);cleanups.push(()=>el.removeEventListener("pointerdown",onPointerDown))}cleanup=()=>{for(const fn of cleanups)fn();cleanups.length=0;window.removeEventListener("pointermove",onPointerMove);window.removeEventListener("pointerup",onPointerUp);cleanup=noop}}try{onUnmounted(()=>cleanup())}catch{}return{x,y,isDragging,style}}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";import{unref,noop}from"./_shared";export function useDraggable(target,options){const initialX=options?.initialValue?.x??0;const initialY=options?.initialValue?.y??0;const x=ref(initialX);const y=ref(initialY);const isDragging=ref(false);const style=ref(`left: ${initialX}px; top: ${initialY}px;`);let cleanup=noop;if(typeof window!=="undefined"){const cleanups=[];let startX=0;let startY=0;let offsetX=0;let offsetY=0;const updateStyle=()=>{style.value=`left: ${x.value}px; top: ${y.value}px;`};const onPointerMove=(event)=>{if(!isDragging.value)return;x.value=event.clientX-offsetX;y.value=event.clientY-offsetY;updateStyle();if(options?.onMove){options.onMove({x:x.value,y:y.value},event)}};const onPointerUp=(event)=>{if(!isDragging.value)return;isDragging.value=false;if(options?.onEnd){options.onEnd({x:x.value,y:y.value},event)}window.removeEventListener("pointermove",onPointerMove);window.removeEventListener("pointerup",onPointerUp)};const onPointerDown=(event)=>{const pos={x:x.value,y:y.value};if(options?.onStart){const result=options.onStart(pos,event);if(result===false)return}startX=event.clientX;startY=event.clientY;offsetX=startX-x.value;offsetY=startY-y.value;isDragging.value=true;window.addEventListener("pointermove",onPointerMove);window.addEventListener("pointerup",onPointerUp)};const el=unref(target);if(el){el.addEventListener("pointerdown",onPointerDown);cleanups.push(()=>el.removeEventListener("pointerdown",onPointerDown))}cleanup=()=>{for(const fn of cleanups)fn();cleanups.length=0;window.removeEventListener("pointermove",onPointerMove);window.removeEventListener("pointerup",onPointerUp);cleanup=noop}}try{onUnmounted(()=>cleanup())}catch{}return{x,y,isDragging,style}}
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";import{unref,noop}from"./_shared";export function useDropZone(target,onDrop){const isOverDropZone=ref(!1),files=ref(null);let cleanup=noop,dragCounter=0;if(typeof window<"u"){const el=unref(target);if(el){const cleanups=[],onDragEnter=(event)=>{event.preventDefault();dragCounter++;isOverDropZone.value=!0},onDragOver=(event)=>{event.preventDefault();isOverDropZone.value=!0},onDragLeave=(event)=>{event.preventDefault();dragCounter--;if(dragCounter<=0){dragCounter=0;isOverDropZone.value=!1}},onDropHandler=(event)=>{event.preventDefault();dragCounter=0;isOverDropZone.value=!1;const droppedFiles=event.dataTransfer?.files;if(droppedFiles&&droppedFiles.length>0)files.value=Array.from(droppedFiles);else files.value=null;if(onDrop)onDrop(files.value)};el.addEventListener("dragenter",onDragEnter);el.addEventListener("dragover",onDragOver);el.addEventListener("dragleave",onDragLeave);el.addEventListener("drop",onDropHandler);cleanups.push(()=>el.removeEventListener("dragenter",onDragEnter),()=>el.removeEventListener("dragover",onDragOver),()=>el.removeEventListener("dragleave",onDragLeave),()=>el.removeEventListener("drop",onDropHandler));cleanup=()=>{for(const fn of cleanups)fn();cleanups.length=0;cleanup=noop}}}try{onUnmounted(()=>cleanup())}catch{}return{isOverDropZone,files}}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";import{unref,noop}from"./_shared";export function useDropZone(target,onDrop){const isOverDropZone=ref(false);const files=ref(null);let cleanup=noop;let dragCounter=0;if(typeof window!=="undefined"){const el=unref(target);if(el){const cleanups=[];const onDragEnter=(event)=>{event.preventDefault();dragCounter++;isOverDropZone.value=true};const onDragOver=(event)=>{event.preventDefault();isOverDropZone.value=true};const onDragLeave=(event)=>{event.preventDefault();dragCounter--;if(dragCounter<=0){dragCounter=0;isOverDropZone.value=false}};const onDropHandler=(event)=>{event.preventDefault();dragCounter=0;isOverDropZone.value=false;const droppedFiles=event.dataTransfer?.files;if(droppedFiles&&droppedFiles.length>0){files.value=Array.from(droppedFiles)}else{files.value=null}if(onDrop){onDrop(files.value)}};el.addEventListener("dragenter",onDragEnter);el.addEventListener("dragover",onDragOver);el.addEventListener("dragleave",onDragLeave);el.addEventListener("drop",onDropHandler);cleanups.push(()=>el.removeEventListener("dragenter",onDragEnter),()=>el.removeEventListener("dragover",onDragOver),()=>el.removeEventListener("dragleave",onDragLeave),()=>el.removeEventListener("drop",onDropHandler));cleanup=()=>{for(const fn of cleanups)fn();cleanups.length=0;cleanup=noop}}}try{onUnmounted(()=>cleanup())}catch{}return{isOverDropZone,files}}
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";import{unref,noop}from"./_shared";export function useElementBounding(target){const x=ref(0),y=ref(0),top=ref(0),right=ref(0),bottom=ref(0),left=ref(0),width=ref(0),height=ref(0),cleanups=[];let cleanup=noop;const update=()=>{const el=unref(target);if(!el)return;const rect=el.getBoundingClientRect();x.value=rect.x;y.value=rect.y;top.value=rect.top;right.value=rect.right;bottom.value=rect.bottom;left.value=rect.left;width.value=rect.width;height.value=rect.height};if(typeof window<"u"){update();const onResize=()=>update();window.addEventListener("resize",onResize,{passive:!0});cleanups.push(()=>window.removeEventListener("resize",onResize));const onScroll=()=>update();window.addEventListener("scroll",onScroll,{passive:!0});cleanups.push(()=>window.removeEventListener("scroll",onScroll));if("ResizeObserver"in window){const el=unref(target);if(el){const resizeObserver=new ResizeObserver(update);resizeObserver.observe(el);cleanups.push(()=>resizeObserver.disconnect())}}if("MutationObserver"in window){const el=unref(target);if(el){const mutationObserver=new MutationObserver(update);mutationObserver.observe(el,{childList:!0,subtree:!0,attributes:!0});cleanups.push(()=>mutationObserver.disconnect())}}cleanup=()=>{for(const fn of cleanups)fn();cleanups.length=0;cleanup=noop}}try{onUnmounted(()=>cleanup())}catch{}return{x,y,top,right,bottom,left,width,height,update}}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";import{unref,noop}from"./_shared";export function useElementBounding(target){const x=ref(0);const y=ref(0);const top=ref(0);const right=ref(0);const bottom=ref(0);const left=ref(0);const width=ref(0);const height=ref(0);const cleanups=[];let cleanup=noop;const update=()=>{const el=unref(target);if(!el)return;const rect=el.getBoundingClientRect();x.value=rect.x;y.value=rect.y;top.value=rect.top;right.value=rect.right;bottom.value=rect.bottom;left.value=rect.left;width.value=rect.width;height.value=rect.height};if(typeof window!=="undefined"){update();const onResize=()=>update();window.addEventListener("resize",onResize,{passive:true});cleanups.push(()=>window.removeEventListener("resize",onResize));const onScroll=()=>update();window.addEventListener("scroll",onScroll,{passive:true});cleanups.push(()=>window.removeEventListener("scroll",onScroll));if("ResizeObserver"in window){const el=unref(target);if(el){const resizeObserver=new ResizeObserver(update);resizeObserver.observe(el);cleanups.push(()=>resizeObserver.disconnect())}}if("MutationObserver"in window){const el=unref(target);if(el){const mutationObserver=new MutationObserver(update);mutationObserver.observe(el,{childList:true,subtree:true,attributes:true});cleanups.push(()=>mutationObserver.disconnect())}}cleanup=()=>{for(const fn of cleanups)fn();cleanups.length=0;cleanup=noop}}try{onUnmounted(()=>cleanup())}catch{}return{x,y,top,right,bottom,left,width,height,update}}
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";export function useElementByPoint(options){const x=options?.x??ref(0),y=options?.y??ref(0),element=ref(null);if(typeof document>"u")return{element,x,y};const handler=(e)=>{x.value=e.clientX;y.value=e.clientY;element.value=document.elementFromPoint(e.clientX,e.clientY)};document.addEventListener("mousemove",handler,{passive:!0});try{onUnmounted(()=>{document.removeEventListener("mousemove",handler)})}catch{}return{element,x,y}}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";export function useElementByPoint(options){const x=options?.x??ref(0);const y=options?.y??ref(0);const element=ref(null);if(typeof document==="undefined")return{element,x,y};const handler=(e)=>{x.value=e.clientX;y.value=e.clientY;element.value=document.elementFromPoint(e.clientX,e.clientY)};document.addEventListener("mousemove",handler,{passive:true});try{onUnmounted(()=>{document.removeEventListener("mousemove",handler)})}catch{}return{element,x,y}}
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";import{unref}from"./_shared";export function useElementHover(target){const isHovered=ref(!1);let cleanup=()=>{};function setup(el){cleanup();if(!el)return;const onEnter=()=>{isHovered.value=!0},onLeave=()=>{isHovered.value=!1};el.addEventListener("mouseenter",onEnter,{passive:!0});el.addEventListener("mouseleave",onLeave,{passive:!0});cleanup=()=>{el.removeEventListener("mouseenter",onEnter);el.removeEventListener("mouseleave",onLeave);cleanup=()=>{}}}setup(unref(target));try{onUnmounted(()=>cleanup())}catch{}return isHovered}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";import{unref}from"./_shared";export function useElementHover(target){const isHovered=ref(false);let cleanup=()=>{};function setup(el){cleanup();if(!el)return;const onEnter=()=>{isHovered.value=true};const onLeave=()=>{isHovered.value=false};el.addEventListener("mouseenter",onEnter,{passive:true});el.addEventListener("mouseleave",onLeave,{passive:true});cleanup=()=>{el.removeEventListener("mouseenter",onEnter);el.removeEventListener("mouseleave",onLeave);cleanup=()=>{}}}setup(unref(target));try{onUnmounted(()=>cleanup())}catch{}return isHovered}
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";import{unref,noop}from"./_shared";export function useElementSize(target,options){const width=ref(options?.initialSize?.width??0),height=ref(options?.initialSize?.height??0),isSupported=typeof window<"u"&&"ResizeObserver"in window;let cleanup=noop;if(isSupported){const el=unref(target);if(el){const observer=new ResizeObserver((entries)=>{for(const entry of entries)if(entry.contentBoxSize){const boxSize=Array.isArray(entry.contentBoxSize)?entry.contentBoxSize[0]:entry.contentBoxSize;width.value=boxSize.inlineSize;height.value=boxSize.blockSize}else{width.value=entry.contentRect.width;height.value=entry.contentRect.height}});observer.observe(el);cleanup=()=>{observer.disconnect();cleanup=noop}}}const stop=()=>{cleanup()};try{onUnmounted(stop)}catch{}return{width,height,stop}}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";import{unref,noop}from"./_shared";export function useElementSize(target,options){const width=ref(options?.initialSize?.width??0);const height=ref(options?.initialSize?.height??0);const isSupported=typeof window!=="undefined"&&"ResizeObserver"in window;let cleanup=noop;if(isSupported){const el=unref(target);if(el){const observer=new ResizeObserver((entries)=>{for(const entry of entries){if(entry.contentBoxSize){const boxSize=Array.isArray(entry.contentBoxSize)?entry.contentBoxSize[0]:entry.contentBoxSize;width.value=boxSize.inlineSize;height.value=boxSize.blockSize}else{width.value=entry.contentRect.width;height.value=entry.contentRect.height}}});observer.observe(el);cleanup=()=>{observer.disconnect();cleanup=noop}}}const stop=()=>{cleanup()};try{onUnmounted(stop)}catch{}return{width,height,stop}}
@@ -1 +1 @@
1
- import{ref}from"@stacksjs/stx";import{useIntersectionObserver}from"./useIntersectionObserver";export function useElementVisibility(target){const isVisible=ref(!1);useIntersectionObserver(target,(entries)=>{for(const entry of entries)isVisible.value=entry.isIntersecting},{threshold:0});return isVisible}
1
+ import{ref}from"@stacksjs/stx";import{useIntersectionObserver}from"./useIntersectionObserver";export function useElementVisibility(target){const isVisible=ref(false);useIntersectionObserver(target,(entries)=>{for(const entry of entries){isVisible.value=entry.isIntersecting}},{threshold:0});return isVisible}
@@ -1 +1 @@
1
- import{onUnmounted}from"@stacksjs/stx";const buses=new Map;export function useEventBus(key){if(!buses.has(key))buses.set(key,new Set);const listeners=buses.get(key),localListeners=[];function on(listener){listeners.add(listener);localListeners.push(listener);return()=>off(listener)}function once(listener){const wrapper=(event)=>{listener(event);off(wrapper)};return on(wrapper)}function emit(event){for(const listener of listeners)listener(event)}function off(listener){listeners.delete(listener);const idx=localListeners.indexOf(listener);if(idx!==-1)localListeners.splice(idx,1)}function reset(){listeners.clear();localListeners.length=0}try{onUnmounted(()=>{for(const listener of localListeners)listeners.delete(listener);localListeners.length=0})}catch{}return{on,once,emit,off,reset}}
1
+ import{onUnmounted}from"@stacksjs/stx";const buses=new Map;export function useEventBus(key){if(!buses.has(key))buses.set(key,new Set);const listeners=buses.get(key);const localListeners=[];function on(listener){listeners.add(listener);localListeners.push(listener);return()=>off(listener)}function once(listener){const wrapper=(event)=>{listener(event);off(wrapper)};return on(wrapper)}function emit(event){for(const listener of listeners)listener(event)}function off(listener){listeners.delete(listener);const idx=localListeners.indexOf(listener);if(idx!==-1)localListeners.splice(idx,1)}function reset(){listeners.clear();localListeners.length=0}try{onUnmounted(()=>{for(const listener of localListeners)listeners.delete(listener);localListeners.length=0})}catch{}return{on,once,emit,off,reset}}
@@ -1 +1 @@
1
- import{onUnmounted,watch}from"@stacksjs/stx";import{isRef,unref,noop}from"./_shared";export function useEventListener(target,event,handler,options){let cleanup=noop;const register=(el)=>{if(!el)return noop;el.addEventListener(event,handler,options);return()=>{el.removeEventListener(event,handler,options)}};if(isRef(target)){watch(target,(_newTarget,_oldTarget)=>{cleanup();cleanup=register(unref(target))});cleanup=register(unref(target))}else cleanup=register(target);const stop=()=>{cleanup();cleanup=noop};try{onUnmounted(stop)}catch{}return stop}
1
+ import{onUnmounted,watch}from"@stacksjs/stx";import{isRef,unref,noop}from"./_shared";export function useEventListener(target,event,handler,options){let cleanup=noop;const register=(el)=>{if(!el)return noop;el.addEventListener(event,handler,options);return()=>{el.removeEventListener(event,handler,options)}};if(isRef(target)){watch(target,(_newTarget,_oldTarget)=>{cleanup();cleanup=register(unref(target))});cleanup=register(unref(target))}else{cleanup=register(target)}const stop=()=>{cleanup();cleanup=noop};try{onUnmounted(stop)}catch{}return stop}
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";import{toValue}from"./_shared";export function useEventSource(url,events=[],options={}){const{withCredentials=!1,immediate=!0}=options,data=ref(null),event=ref(null),status=ref("CLOSED"),error=ref(null),eventSourceRef=ref(null);let listeners=[];function close(){const es=eventSourceRef.value;if(es){for(const{eventName,handler}of listeners)es.removeEventListener(eventName,handler);listeners=[];es.close();eventSourceRef.value=null;status.value="CLOSED"}}function open(){if(typeof EventSource>"u")return;close();const resolvedUrl=toValue(url);status.value="CONNECTING";const es=new EventSource(resolvedUrl,{withCredentials});eventSourceRef.value=es;es.onopen=()=>{status.value="OPEN";error.value=null};es.onerror=(e)=>{error.value=e;if(es.readyState===EventSource.CLOSED)status.value="CLOSED";else status.value="CONNECTING"};const messageHandler=(e)=>{const messageEvent=e;data.value=messageEvent.data;event.value="message"};es.addEventListener("message",messageHandler);listeners.push({eventName:"message",handler:messageHandler});for(const eventName of events){const handler=(e)=>{const messageEvent=e;data.value=messageEvent.data;event.value=eventName};es.addEventListener(eventName,handler);listeners.push({eventName,handler})}}if(immediate)open();try{onUnmounted(()=>{close()})}catch{}return{data,event,status,error,eventSource:eventSourceRef,close,open}}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";import{toValue}from"./_shared";export function useEventSource(url,events=[],options={}){const{withCredentials=false,immediate=true}=options;const data=ref(null);const event=ref(null);const status=ref("CLOSED");const error=ref(null);const eventSourceRef=ref(null);let listeners=[];function close(){const es=eventSourceRef.value;if(es){for(const{eventName,handler}of listeners){es.removeEventListener(eventName,handler)}listeners=[];es.close();eventSourceRef.value=null;status.value="CLOSED"}}function open(){if(typeof EventSource==="undefined")return;close();const resolvedUrl=toValue(url);status.value="CONNECTING";const es=new EventSource(resolvedUrl,{withCredentials});eventSourceRef.value=es;es.onopen=()=>{status.value="OPEN";error.value=null};es.onerror=(e)=>{error.value=e;if(es.readyState===EventSource.CLOSED){status.value="CLOSED"}else{status.value="CONNECTING"}};const messageHandler=(e)=>{const messageEvent=e;data.value=messageEvent.data;event.value="message"};es.addEventListener("message",messageHandler);listeners.push({eventName:"message",handler:messageHandler});for(const eventName of events){const handler=(e)=>{const messageEvent=e;data.value=messageEvent.data;event.value=eventName};es.addEventListener(eventName,handler);listeners.push({eventName,handler})}}if(immediate){open()}try{onUnmounted(()=>{close()})}catch{}return{data,event,status,error,eventSource:eventSourceRef,close,open}}
@@ -1 +1 @@
1
- import"./types/dom-vendor";import{ref}from"@stacksjs/stx";export function useEyeDropper(){const isSupported=ref(typeof window<"u"&&"EyeDropper"in window),sRGBHex=ref("");async function open(){if(!isSupported.value)return;const Picker=window.EyeDropper;if(!Picker)return;const dropper=new Picker;try{const result=await dropper.open();sRGBHex.value=result.sRGBHex;return result}catch{return}}return{isSupported,sRGBHex,open}}
1
+ import"./types/dom-vendor";import{ref}from"@stacksjs/stx";export function useEyeDropper(){const isSupported=ref(typeof window!=="undefined"&&"EyeDropper"in window);const sRGBHex=ref("");async function open(){if(!isSupported.value)return;const Picker=window.EyeDropper;if(!Picker)return;const dropper=new Picker;try{const result=await dropper.open();sRGBHex.value=result.sRGBHex;return result}catch{return}}return{isSupported,sRGBHex,open}}
@@ -1 +1 @@
1
- import{ref,watch}from"@stacksjs/stx";import{toValue}from"./_shared";export function useFavicon(newIcon){const favicon=ref(toValue(newIcon??null));function applyIcon(icon){if(typeof document>"u"||!icon)return;let link=document.querySelector('link[rel*="icon"]');if(!link){link=document.createElement("link");link.rel="icon";link.type="image/x-icon";document.head.appendChild(link)}link.href=icon}watch(favicon,(val)=>{applyIcon(val)});applyIcon(favicon.value);return favicon}
1
+ import{ref,watch}from"@stacksjs/stx";import{toValue}from"./_shared";export function useFavicon(newIcon){const favicon=ref(toValue(newIcon??null));function applyIcon(icon){if(typeof document==="undefined"||!icon)return;let link=document.querySelector('link[rel*="icon"]');if(!link){link=document.createElement("link");link.rel="icon";link.type="image/x-icon";document.head.appendChild(link)}link.href=icon}watch(favicon,(val)=>{applyIcon(val)});applyIcon(favicon.value);return favicon}
package/dist/useFetch.js CHANGED
@@ -1 +1 @@
1
- import{ref}from"@stacksjs/stx";export function useFetch(url){let method="GET",body;const builder={get(){method="GET";body=void 0;return builder},post(b){method="POST";body=b;return builder},patch(b){method="PATCH";body=b;return builder},put(b){method="PUT";body=b;return builder},delete(){method="DELETE";body=void 0;return builder},json(){const data=ref(null),error=ref(null),isFetching=ref(!0),init={method,headers:{Accept:"application/json"}};if(body&&method!=="GET"&&method!=="DELETE"){init.headers={...init.headers,"Content-Type":"application/json"};init.body=body}const result={data,error},fetchPromise=fetch(url,init).then(async(response)=>{const json=await response.json();if(response.ok)data.value=json;else error.value=json}).catch((e)=>{error.value=e}).finally(()=>{isFetching.value=!1});return{data,error,isFetching,then(resolve){return fetchPromise.then(()=>resolve(result))}}}};return builder}
1
+ import{ref}from"@stacksjs/stx";export function useFetch(url){let method="GET";let body;const builder={get(){method="GET";body=undefined;return builder},post(b){method="POST";body=b;return builder},patch(b){method="PATCH";body=b;return builder},put(b){method="PUT";body=b;return builder},delete(){method="DELETE";body=undefined;return builder},json(){const data=ref(null);const error=ref(null);const isFetching=ref(true);const init={method,headers:{Accept:"application/json"}};if(body&&method!=="GET"&&method!=="DELETE"){init.headers={...init.headers,"Content-Type":"application/json"};init.body=body}const result={data,error};const fetchPromise=fetch(url,init).then(async(response)=>{const json=await response.json();if(response.ok){data.value=json}else{error.value=json}}).catch((e)=>{error.value=e}).finally(()=>{isFetching.value=false});return{data,error,isFetching,then(resolve){return fetchPromise.then(()=>resolve(result))}}}};return builder}
@@ -1 +1 @@
1
- import{ref}from"@stacksjs/stx";export function useFileDialog(options={}){const files=ref(null);function open(overrideOptions){if(typeof document>"u")return;const opts={...options,...overrideOptions},input=document.createElement("input");input.type="file";if(opts.accept)input.accept=opts.accept;if(opts.multiple)input.multiple=!0;if(opts.capture)input.setAttribute("capture",opts.capture);input.onchange=()=>{files.value=input.files};input.click()}function reset(){files.value=null}return{files,open,reset}}
1
+ import{ref}from"@stacksjs/stx";export function useFileDialog(options={}){const files=ref(null);function open(overrideOptions){if(typeof document==="undefined")return;const opts={...options,...overrideOptions};const input=document.createElement("input");input.type="file";if(opts.accept)input.accept=opts.accept;if(opts.multiple)input.multiple=true;if(opts.capture)input.setAttribute("capture",opts.capture);input.onchange=()=>{files.value=input.files};input.click()}function reset(){files.value=null}return{files,open,reset}}
package/dist/useFocus.js CHANGED
@@ -1 +1 @@
1
- import{onUnmounted,ref,watch}from"@stacksjs/stx";import{unref}from"./_shared";export function useFocus(target,options={}){const{initialValue=!1}=options,focused=ref(initialValue);let cleanup=()=>{};function setup(el){cleanup();if(!el)return;const onFocus=()=>{focused.value=!0},onBlur=()=>{focused.value=!1};el.addEventListener("focus",onFocus,{passive:!0});el.addEventListener("blur",onBlur,{passive:!0});cleanup=()=>{el.removeEventListener("focus",onFocus);el.removeEventListener("blur",onBlur);cleanup=()=>{}};if(document.activeElement===el)focused.value=!0;if(initialValue)el.focus()}const el=unref(target);setup(el);watch(focused,(val)=>{const element=unref(target);if(!element)return;if(val)element.focus();else element.blur()});try{onUnmounted(()=>cleanup())}catch{}return{focused}}
1
+ import{onUnmounted,ref,watch}from"@stacksjs/stx";import{unref}from"./_shared";export function useFocus(target,options={}){const{initialValue=false}=options;const focused=ref(initialValue);let cleanup=()=>{};function setup(el){cleanup();if(!el)return;const onFocus=()=>{focused.value=true};const onBlur=()=>{focused.value=false};el.addEventListener("focus",onFocus,{passive:true});el.addEventListener("blur",onBlur,{passive:true});cleanup=()=>{el.removeEventListener("focus",onFocus);el.removeEventListener("blur",onBlur);cleanup=()=>{}};if(document.activeElement===el)focused.value=true;if(initialValue)el.focus()}const el=unref(target);setup(el);watch(focused,(val)=>{const element=unref(target);if(!element)return;if(val)element.focus();else element.blur()});try{onUnmounted(()=>cleanup())}catch{}return{focused}}
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";import{unref}from"./_shared";export function useFocusWithin(target){const focused=ref(!1);let cleanup=()=>{};function setup(el){cleanup();if(!el)return;const onFocusIn=()=>{focused.value=!0},onFocusOut=(e)=>{if(!el.contains(e.relatedTarget))focused.value=!1};el.addEventListener("focusin",onFocusIn,{passive:!0});el.addEventListener("focusout",onFocusOut);cleanup=()=>{el.removeEventListener("focusin",onFocusIn);el.removeEventListener("focusout",onFocusOut);cleanup=()=>{}}}setup(unref(target));try{onUnmounted(()=>cleanup())}catch{}return{focused}}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";import{unref}from"./_shared";export function useFocusWithin(target){const focused=ref(false);let cleanup=()=>{};function setup(el){cleanup();if(!el)return;const onFocusIn=()=>{focused.value=true};const onFocusOut=(e)=>{if(!el.contains(e.relatedTarget))focused.value=false};el.addEventListener("focusin",onFocusIn,{passive:true});el.addEventListener("focusout",onFocusOut);cleanup=()=>{el.removeEventListener("focusin",onFocusIn);el.removeEventListener("focusout",onFocusOut);cleanup=()=>{}}}setup(unref(target));try{onUnmounted(()=>cleanup())}catch{}return{focused}}
package/dist/useForm.js CHANGED
@@ -1 +1 @@
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}}
1
+ import{ref}from"@stacksjs/stx";export function useForm(opts){const validateOn=opts.validateOn??"submit";const initial={...opts.initialValues};const values=ref({...initial});const errors=ref({});const touched=ref({});const dirty=ref({});const isSubmitting=ref(false);const isValid=ref(true);const isDirty=ref(false);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 true;const result=v.validate(values.value[name]);const message=firstMessage(result);if(message){errors.value={...errors.value,[name]:message};isValid.value=false;return false}if(errors.value[name]){const{[name]:_,...rest}=errors.value;errors.value=rest}isValid.value=Object.keys(errors.value).length===0;return true}function setFieldValue(name,value){values.value={...values.value,[name]:value};dirty.value={...dirty.value,[name]:value!==initial[name]};isDirty.value=true;if(validateOn==="change")validateField(name)}function setFieldTouched(name,isTouched=true){touched.value={...touched.value,[name]:isTouched};if(isTouched)isDirty.value=true}function field(name){const key=name;const errorId=`${key}-error`;const onBlur=()=>{setFieldTouched(name,true);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:undefined}}}}function validateAll(){let ok=true;for(const name of Object.keys(opts.schema??{})){if(!validateField(name))ok=false}return ok}function setError(name,message){errors.value={...errors.value,[name]:message};isValid.value=false}function setErrors(errorMap){const next={...errors.value};let changed=false;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=true}errors.value=next;if(changed)isValid.value=false}function clearErrors(name){if(name==null){errors.value={};isValid.value=true;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]=true;touched.value=allTouched;if(!validateAll()){opts.onError?.(errors.value);return}isSubmitting.value=true;try{await opts.onSubmit(values.value)}catch(err){const e=err instanceof Error?err:new Error(String(err));setError("form",e.message);opts.onError?.(e)}finally{isSubmitting.value=false}}function reset(){values.value={...initial};errors.value={};touched.value={};dirty.value={};isSubmitting.value=false;isValid.value=true;isDirty.value=false}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 +1 @@
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
+ import{onUnmounted,ref}from"@stacksjs/stx";export function useFps(every=10){const fps=ref(0);if(typeof requestAnimationFrame==="undefined")return fps;let last=performance.now();let ticks=0;let rafId;function loop(){ticks++;if(ticks>=every){const now=performance.now();const 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 +1 @@
1
- import"./types/dom-vendor";import{onUnmounted,ref}from"@stacksjs/stx";import{defaultDocument,toValue}from"./_shared";export function useFullscreen(target){const doc=defaultDocument(),isFullscreen=ref(!1),isSupported=ref(!!doc&&(doc.fullscreenEnabled===!0||doc.webkitFullscreenEnabled===!0));function getTarget(){if(target)return toValue(target);return doc?.documentElement??null}function getFullscreenElement(){if(!doc)return null;return doc.fullscreenElement??doc.webkitFullscreenElement??null}function updateState(){isFullscreen.value=getFullscreenElement()===getTarget()&&getTarget()!==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();updateState()}catch{}}async function exit(){if(!isSupported.value||!doc)return;try{if(doc.exitFullscreen)await doc.exitFullscreen();else if(doc.webkitExitFullscreen)await doc.webkitExitFullscreen();updateState()}catch{}}async function toggle(){if(isFullscreen.value)await exit();else await enter()}updateState();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
+ import"./types/dom-vendor";import{onUnmounted,ref}from"@stacksjs/stx";import{defaultDocument,toValue}from"./_shared";export function useFullscreen(target){const doc=defaultDocument();const isFullscreen=ref(false);const isSupported=ref(!!doc&&(doc.fullscreenEnabled===true||doc.webkitFullscreenEnabled===true));function getTarget(){if(target){return toValue(target)}return doc?.documentElement??null}function getFullscreenElement(){if(!doc)return null;return doc.fullscreenElement??doc.webkitFullscreenElement??null}function updateState(){isFullscreen.value=getFullscreenElement()===getTarget()&&getTarget()!==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()}updateState()}catch{}}async function exit(){if(!isSupported.value||!doc)return;try{if(doc.exitFullscreen){await doc.exitFullscreen()}else if(doc.webkitExitFullscreen){await doc.webkitExitFullscreen()}updateState()}catch{}}async function toggle(){if(isFullscreen.value){await exit()}else{await enter()}}updateState();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 +1 @@
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}}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";import{noop}from"./_shared";export function useGeolocation(options){const{immediate=true,...positionOptions}=options??{};const isSupported=ref(typeof navigator!=="undefined"&&"geolocation"in navigator);const coords={latitude:ref(null),longitude:ref(null),accuracy:ref(null),altitude:ref(null),altitudeAccuracy:ref(null),heading:ref(null),speed:ref(null)};const locatedAt=ref(null);const error=ref(null);let watchId=null;let 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};const onError=(err)=>{error.value=err};const 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}};const pause=()=>{cleanup()};if(immediate){resume()}try{onUnmounted(pause)}catch{}return{coords,locatedAt,error,isSupported,pause,resume}}
package/dist/useIdle.js CHANGED
@@ -1 +1 @@
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}}
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;const initialState=options?.initialState??false;const idle=ref(initialState);const lastActive=ref(Date.now());let timer=null;let cleanup=noop;if(typeof window!=="undefined"){const cleanups=[];const reset=()=>{idle.value=false;lastActive.value=Date.now();if(timer!==null){clearTimeout(timer)}timer=setTimeout(()=>{idle.value=true},timeout)};for(const event of events){window.addEventListener(event,reset,{passive:true});cleanups.push(()=>window.removeEventListener(event,reset))}timer=setTimeout(()=>{idle.value=true},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 +1 @@
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
+ import{ref}from"@stacksjs/stx";export function useImage(options){const isLoading=ref(true);const isReady=ref(false);const error=ref(null);if(typeof Image==="undefined"){isLoading.value=false;return{isLoading,error,isReady}}const img=new Image;img.onload=()=>{isLoading.value=false;isReady.value=true};img.onerror=(e)=>{isLoading.value=false;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}}