@stacksjs/composables 0.70.88 → 0.70.90
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_shared.d.ts +49 -0
- package/dist/_shared.js +23 -0
- package/dist/cloneFnJSON.d.ts +5 -0
- package/dist/cloneFnJSON.js +3 -0
- package/dist/computedAsync.d.ts +28 -0
- package/dist/computedAsync.js +20 -0
- package/dist/computedEager.d.ts +27 -0
- package/dist/computedEager.js +10 -0
- package/dist/createEventHook.d.ts +16 -0
- package/dist/createEventHook.js +15 -0
- package/dist/createFetch.d.ts +14 -0
- package/dist/createFetch.js +8 -0
- package/dist/createGlobalState.d.ts +17 -0
- package/dist/createGlobalState.js +10 -0
- package/dist/createSharedComposable.d.ts +8 -0
- package/dist/createSharedComposable.js +9 -0
- package/dist/extendRef.d.ts +9 -0
- package/dist/extendRef.js +6 -0
- package/dist/formatTimeAgo.d.ts +23 -0
- package/dist/formatTimeAgo.js +33 -0
- package/dist/index.d.ts +271 -0
- package/dist/index.js +210 -0
- package/dist/isDefined.d.ts +5 -0
- package/dist/isDefined.js +3 -0
- package/dist/makeDestructurable.d.ts +18 -0
- package/dist/makeDestructurable.js +16 -0
- package/dist/onClickOutside.d.ts +14 -0
- package/dist/onClickOutside.js +25 -0
- package/dist/onKeyStroke.d.ts +26 -0
- package/dist/onKeyStroke.js +31 -0
- package/dist/onLongPress.d.ts +14 -0
- package/dist/onLongPress.js +43 -0
- package/dist/onStartTyping.d.ts +8 -0
- package/dist/onStartTyping.js +23 -0
- package/dist/refAutoReset.d.ts +11 -0
- package/dist/refAutoReset.js +15 -0
- package/dist/refDefault.d.ts +9 -0
- package/dist/refDefault.js +8 -0
- package/dist/resolveRef.d.ts +7 -0
- package/dist/resolveRef.js +7 -0
- package/dist/ssrHandlers.d.ts +13 -0
- package/dist/ssrHandlers.js +8 -0
- package/dist/syncRef.d.ts +21 -0
- package/dist/syncRef.js +35 -0
- package/dist/tryOnMounted.d.ts +22 -0
- package/dist/tryOnMounted.js +22 -0
- package/dist/unrefElement.d.ts +6 -0
- package/dist/unrefElement.js +9 -0
- package/dist/until.d.ts +34 -0
- package/dist/until.js +62 -0
- package/dist/useActiveElement.d.ts +6 -0
- package/dist/useActiveElement.js +19 -0
- package/dist/useAnimate.d.ts +18 -0
- package/dist/useAnimate.js +48 -0
- package/dist/useArrayUtils.d.ts +42 -0
- package/dist/useArrayUtils.js +114 -0
- package/dist/useAsyncQueue.d.ts +18 -0
- package/dist/useAsyncQueue.js +22 -0
- package/dist/useAsyncState.d.ts +23 -0
- package/dist/useAsyncState.js +35 -0
- package/dist/useBase64.d.ts +12 -0
- package/dist/useBase64.js +45 -0
- package/dist/useBattery.d.ts +15 -0
- package/dist/useBattery.js +38 -0
- package/dist/useBreakpoints.d.ts +96 -0
- package/dist/useBreakpoints.js +97 -0
- package/dist/useBroadcastChannel.d.ts +14 -0
- package/dist/useBroadcastChannel.js +31 -0
- package/dist/useBrowserLocation.d.ts +18 -0
- package/dist/useBrowserLocation.js +64 -0
- package/dist/useClipboard.d.ts +17 -0
- package/dist/useClipboard.js +32 -0
- package/dist/useClipboardItems.d.ts +11 -0
- package/dist/useClipboardItems.js +15 -0
- package/dist/useCloned.d.ts +15 -0
- package/dist/useCloned.js +16 -0
- package/dist/useColorMode.d.ts +18 -0
- package/dist/useColorMode.js +60 -0
- package/dist/useConfirmDialog.d.ts +14 -0
- package/dist/useConfirmDialog.js +34 -0
- package/dist/useCounter.d.ts +20 -0
- package/dist/useCounter.js +28 -0
- package/dist/useCssVar.d.ts +10 -0
- package/dist/useCssVar.js +23 -0
- package/dist/useCycleList.d.ts +18 -0
- package/dist/useCycleList.js +27 -0
- package/dist/useDark.d.ts +11 -0
- package/dist/useDark.js +38 -0
- package/dist/useDateFormat.d.ts +10 -0
- package/dist/useDateFormat.js +11 -0
- package/dist/useDebounce.d.ts +10 -0
- package/dist/useDebounce.js +16 -0
- package/dist/useDebounceFn.d.ts +10 -0
- package/dist/useDebounceFn.js +18 -0
- package/dist/useDebouncedRef.d.ts +11 -0
- package/dist/useDebouncedRef.js +22 -0
- package/dist/useDebouncedRefHistory.d.ts +5 -0
- package/dist/useDebouncedRefHistory.js +36 -0
- package/dist/useDeviceMotion.d.ts +27 -0
- package/dist/useDeviceMotion.js +53 -0
- package/dist/useDeviceOrientation.d.ts +15 -0
- package/dist/useDeviceOrientation.js +23 -0
- package/dist/useDevicePixelRatio.d.ts +5 -0
- package/dist/useDevicePixelRatio.js +24 -0
- package/dist/useDocumentVisibility.d.ts +5 -0
- package/dist/useDocumentVisibility.js +16 -0
- package/dist/useDraggable.d.ts +23 -0
- package/dist/useDraggable.js +58 -0
- package/dist/useDropZone.d.ts +15 -0
- package/dist/useDropZone.js +52 -0
- package/dist/useElementBounding.d.ts +21 -0
- package/dist/useElementBounding.js +59 -0
- package/dist/useElementByPoint.d.ts +10 -0
- package/dist/useElementByPoint.js +18 -0
- package/dist/useElementHover.d.ts +9 -0
- package/dist/useElementHover.js +28 -0
- package/dist/useElementSize.d.ts +19 -0
- package/dist/useElementSize.js +34 -0
- package/dist/useElementVisibility.d.ts +10 -0
- package/dist/useElementVisibility.js +10 -0
- package/dist/useEventBus.d.ts +14 -0
- package/dist/useEventBus.js +41 -0
- package/dist/useEventListener.d.ts +14 -0
- package/dist/useEventListener.js +29 -0
- package/dist/useEventSource.d.ts +32 -0
- package/dist/useEventSource.js +72 -0
- package/dist/useEyeDropper.d.ts +10 -0
- package/dist/useEyeDropper.js +17 -0
- package/dist/useFavicon.d.ts +8 -0
- package/dist/useFavicon.js +22 -0
- package/dist/useFetch.d.ts +35 -0
- package/dist/useFetch.js +61 -0
- package/dist/useFileDialog.d.ts +15 -0
- package/dist/useFileDialog.js +24 -0
- package/dist/useFocus.d.ts +13 -0
- package/dist/useFocus.js +42 -0
- package/dist/useFocusWithin.d.ts +9 -0
- package/dist/useFocusWithin.js +29 -0
- package/dist/useForm.d.ts +97 -0
- package/dist/useForm.js +182 -0
- package/dist/useFps.d.ts +7 -0
- package/dist/useFps.js +22 -0
- package/dist/useFullscreen.d.ts +16 -0
- package/dist/useFullscreen.js +67 -0
- package/dist/useGeolocation.d.ts +26 -0
- package/dist/useGeolocation.js +55 -0
- package/dist/useIdle.d.ts +18 -0
- package/dist/useIdle.js +46 -0
- package/dist/useImage.d.ts +18 -0
- package/dist/useImage.js +32 -0
- package/dist/useInfiniteScroll.d.ts +11 -0
- package/dist/useInfiniteScroll.js +50 -0
- package/dist/useIntersectionObserver.d.ts +16 -0
- package/dist/useIntersectionObserver.js +27 -0
- package/dist/useInterval.d.ts +13 -0
- package/dist/useInterval.js +32 -0
- package/dist/useIntervalFn.d.ts +16 -0
- package/dist/useIntervalFn.js +24 -0
- package/dist/useKeyModifier.d.ts +6 -0
- package/dist/useKeyModifier.js +22 -0
- package/dist/useLastChanged.d.ts +11 -0
- package/dist/useLastChanged.js +8 -0
- package/dist/useLocalStorage.d.ts +17 -0
- package/dist/useLocalStorage.js +4 -0
- package/dist/useMagicKeys.d.ts +16 -0
- package/dist/useMagicKeys.js +81 -0
- package/dist/useManualRefHistory.d.ts +27 -0
- package/dist/useManualRefHistory.js +64 -0
- package/dist/useMath.d.ts +17 -0
- package/dist/useMath.js +52 -0
- package/dist/useMediaQuery.d.ts +9 -0
- package/dist/useMediaQuery.js +19 -0
- package/dist/useMemoize.d.ts +13 -0
- package/dist/useMemoize.js +24 -0
- package/dist/useMounted.d.ts +6 -0
- package/dist/useMounted.js +8 -0
- package/dist/useMouse.d.ts +19 -0
- package/dist/useMouse.js +67 -0
- package/dist/useMouseInElement.d.ts +17 -0
- package/dist/useMouseInElement.js +31 -0
- package/dist/useMousePressed.d.ts +10 -0
- package/dist/useMousePressed.js +31 -0
- package/dist/useMutationObserver.d.ts +16 -0
- package/dist/useMutationObserver.js +27 -0
- package/dist/useNavigatorLanguage.d.ts +5 -0
- package/dist/useNavigatorLanguage.js +17 -0
- package/dist/useNetwork.d.ts +18 -0
- package/dist/useNetwork.js +58 -0
- package/dist/useNow.d.ts +8 -0
- package/dist/useNow.js +10 -0
- package/dist/useObjectUrl.d.ts +8 -0
- package/dist/useObjectUrl.js +23 -0
- package/dist/useOffsetPagination.d.ts +21 -0
- package/dist/useOffsetPagination.js +45 -0
- package/dist/useOnline.d.ts +7 -0
- package/dist/useOnline.js +20 -0
- package/dist/usePageLeave.d.ts +9 -0
- package/dist/usePageLeave.js +27 -0
- package/dist/useParallax.d.ts +15 -0
- package/dist/useParallax.js +33 -0
- package/dist/useParentElement.d.ts +6 -0
- package/dist/useParentElement.js +8 -0
- package/dist/usePermission.d.ts +7 -0
- package/dist/usePermission.js +21 -0
- package/dist/usePointer.d.ts +15 -0
- package/dist/usePointer.js +32 -0
- package/dist/usePointerLock.d.ts +13 -0
- package/dist/usePointerLock.js +33 -0
- package/dist/usePointerSwipe.d.ts +20 -0
- package/dist/usePointerSwipe.js +52 -0
- package/dist/usePreferredColorScheme.d.ts +6 -0
- package/dist/usePreferredColorScheme.js +25 -0
- package/dist/usePreferredContrast.d.ts +6 -0
- package/dist/usePreferredContrast.js +29 -0
- package/dist/usePreferredLanguages.d.ts +5 -0
- package/dist/usePreferredLanguages.js +16 -0
- package/dist/usePreferredReducedMotion.d.ts +6 -0
- package/dist/usePreferredReducedMotion.js +18 -0
- package/dist/usePrevious.d.ts +9 -0
- package/dist/usePrevious.js +8 -0
- package/dist/useQuery.d.ts +106 -0
- package/dist/useQuery.js +265 -0
- package/dist/useRafFn.d.ts +19 -0
- package/dist/useRafFn.js +37 -0
- package/dist/useRefHistory.d.ts +28 -0
- package/dist/useRefHistory.js +72 -0
- package/dist/useResizeObserver.d.ts +16 -0
- package/dist/useResizeObserver.js +27 -0
- package/dist/useScreenOrientation.d.ts +13 -0
- package/dist/useScreenOrientation.js +27 -0
- package/dist/useScreenSafeArea.d.ts +12 -0
- package/dist/useScreenSafeArea.js +25 -0
- package/dist/useScriptTag.d.ts +20 -0
- package/dist/useScriptTag.js +52 -0
- package/dist/useScroll.d.ts +36 -0
- package/dist/useScroll.js +116 -0
- package/dist/useScrollLock.d.ts +10 -0
- package/dist/useScrollLock.js +39 -0
- package/dist/useSessionStorage.d.ts +17 -0
- package/dist/useSessionStorage.js +4 -0
- package/dist/useShare.d.ts +15 -0
- package/dist/useShare.js +11 -0
- package/dist/useSorted.d.ts +10 -0
- package/dist/useSorted.js +10 -0
- package/dist/useStepper.d.ts +23 -0
- package/dist/useStepper.js +46 -0
- package/dist/useStorage.d.ts +18 -0
- package/dist/useStorage.js +54 -0
- package/dist/useStyleTag.d.ts +17 -0
- package/dist/useStyleTag.js +39 -0
- package/dist/useSupported.d.ts +8 -0
- package/dist/useSupported.js +10 -0
- package/dist/useSwipe.d.ts +20 -0
- package/dist/useSwipe.js +58 -0
- package/dist/useTextDirection.d.ts +9 -0
- package/dist/useTextDirection.js +16 -0
- package/dist/useTextSelection.d.ts +10 -0
- package/dist/useTextSelection.js +27 -0
- package/dist/useTextareaAutosize.d.ts +10 -0
- package/dist/useTextareaAutosize.js +20 -0
- package/dist/useThrottle.d.ts +9 -0
- package/dist/useThrottle.js +23 -0
- package/dist/useThrottleFn.d.ts +11 -0
- package/dist/useThrottleFn.js +36 -0
- package/dist/useThrottledRef.d.ts +11 -0
- package/dist/useThrottledRef.js +30 -0
- package/dist/useThrottledRefHistory.d.ts +5 -0
- package/dist/useThrottledRefHistory.js +43 -0
- package/dist/useTimeAgo.d.ts +16 -0
- package/dist/useTimeAgo.js +58 -0
- package/dist/useTimeout.d.ts +12 -0
- package/dist/useTimeout.js +32 -0
- package/dist/useTimeoutFn.d.ts +16 -0
- package/dist/useTimeoutFn.js +27 -0
- package/dist/useTimeoutPoll.d.ts +10 -0
- package/dist/useTimeoutPoll.js +33 -0
- package/dist/useTimestamp.d.ts +15 -0
- package/dist/useTimestamp.js +43 -0
- package/dist/useTitle.d.ts +10 -0
- package/dist/useTitle.js +12 -0
- package/dist/useToNumber.d.ts +11 -0
- package/dist/useToNumber.js +25 -0
- package/dist/useToString.d.ts +6 -0
- package/dist/useToString.js +10 -0
- package/dist/useToggle.d.ts +6 -0
- package/dist/useToggle.js +12 -0
- package/dist/useTransition.d.ts +28 -0
- package/dist/useTransition.js +89 -0
- package/dist/useUrlSearchParams.d.ts +18 -0
- package/dist/useUrlSearchParams.js +72 -0
- package/dist/useVibrate.d.ts +13 -0
- package/dist/useVibrate.js +14 -0
- package/dist/useVirtualList.d.ts +23 -0
- package/dist/useVirtualList.js +49 -0
- package/dist/useWakeLock.d.ts +12 -0
- package/dist/useWakeLock.js +32 -0
- package/dist/useWebNotification.d.ts +25 -0
- package/dist/useWebNotification.js +39 -0
- package/dist/useWebSocket.d.ts +38 -0
- package/dist/useWebSocket.js +103 -0
- package/dist/useWebWorker.d.ts +18 -0
- package/dist/useWebWorker.js +56 -0
- package/dist/useWindowFocus.d.ts +5 -0
- package/dist/useWindowFocus.js +20 -0
- package/dist/useWindowScroll.d.ts +9 -0
- package/dist/useWindowScroll.js +17 -0
- package/dist/useWindowSize.d.ts +15 -0
- package/dist/useWindowSize.js +28 -0
- package/dist/watchArray.d.ts +5 -0
- package/dist/watchArray.js +9 -0
- package/dist/watchAtMost.d.ts +5 -0
- package/dist/watchAtMost.js +12 -0
- package/dist/watchDebounced.d.ts +23 -0
- package/dist/watchDebounced.js +20 -0
- package/dist/watchDeep.d.ts +7 -0
- package/dist/watchDeep.js +13 -0
- package/dist/watchIgnorable.d.ts +12 -0
- package/dist/watchIgnorable.js +19 -0
- package/dist/watchImmediate.d.ts +5 -0
- package/dist/watchImmediate.js +7 -0
- package/dist/watchOnce.d.ts +19 -0
- package/dist/watchOnce.js +17 -0
- package/dist/watchPausable.d.ts +13 -0
- package/dist/watchPausable.js +23 -0
- package/dist/watchThrottled.d.ts +23 -0
- package/dist/watchThrottled.js +37 -0
- package/dist/watchTriggerable.d.ts +5 -0
- package/dist/watchTriggerable.js +10 -0
- package/dist/watchWithFilter.d.ts +7 -0
- package/dist/watchWithFilter.js +6 -0
- package/dist/whenever.d.ts +18 -0
- package/dist/whenever.js +7 -0
- package/package.json +2 -2
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { computed, ref, onUnmounted } from "@stacksjs/stx";
|
|
2
|
+
import { defaultWindow } from "./_shared";
|
|
3
|
+
export function useBreakpoints(breakpoints) {
|
|
4
|
+
const win = defaultWindow(), width = ref(win ? win.innerWidth : 0);
|
|
5
|
+
function updateWidth() {
|
|
6
|
+
if (win)
|
|
7
|
+
width.value = win.innerWidth;
|
|
8
|
+
}
|
|
9
|
+
if (win) {
|
|
10
|
+
win.addEventListener("resize", updateWidth);
|
|
11
|
+
try {
|
|
12
|
+
onUnmounted(() => {
|
|
13
|
+
win.removeEventListener("resize", updateWidth);
|
|
14
|
+
});
|
|
15
|
+
} catch {}
|
|
16
|
+
}
|
|
17
|
+
function getValue(k) {
|
|
18
|
+
return breakpoints[k];
|
|
19
|
+
}
|
|
20
|
+
function greaterOrEqual(k) {
|
|
21
|
+
return computed(() => width.value >= getValue(k));
|
|
22
|
+
}
|
|
23
|
+
function smallerOrEqual(k) {
|
|
24
|
+
return computed(() => width.value <= getValue(k));
|
|
25
|
+
}
|
|
26
|
+
function between(a, b) {
|
|
27
|
+
return computed(() => width.value >= getValue(a) && width.value < getValue(b));
|
|
28
|
+
}
|
|
29
|
+
function isGreater(k) {
|
|
30
|
+
return computed(() => width.value > getValue(k));
|
|
31
|
+
}
|
|
32
|
+
function isSmaller(k) {
|
|
33
|
+
return computed(() => width.value < getValue(k));
|
|
34
|
+
}
|
|
35
|
+
function current() {
|
|
36
|
+
return computed(() => {
|
|
37
|
+
return Object.keys(breakpoints).sort((a, b) => breakpoints[a] - breakpoints[b]).filter((k) => width.value >= breakpoints[k]);
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
greaterOrEqual,
|
|
42
|
+
smallerOrEqual,
|
|
43
|
+
between,
|
|
44
|
+
isGreater,
|
|
45
|
+
isSmaller,
|
|
46
|
+
current
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
export const breakpointsTailwind = {
|
|
50
|
+
sm: 640,
|
|
51
|
+
md: 768,
|
|
52
|
+
lg: 1024,
|
|
53
|
+
xl: 1280,
|
|
54
|
+
"2xl": 1536
|
|
55
|
+
}, breakpointsBootstrap = {
|
|
56
|
+
sm: 576,
|
|
57
|
+
md: 768,
|
|
58
|
+
lg: 992,
|
|
59
|
+
xl: 1200,
|
|
60
|
+
xxl: 1400
|
|
61
|
+
}, breakpointsBootstrapV5 = breakpointsBootstrap, breakpointsAntDesign = {
|
|
62
|
+
xs: 480,
|
|
63
|
+
sm: 576,
|
|
64
|
+
md: 768,
|
|
65
|
+
lg: 992,
|
|
66
|
+
xl: 1200,
|
|
67
|
+
xxl: 1600
|
|
68
|
+
}, breakpointsVuetify = {
|
|
69
|
+
xs: 600,
|
|
70
|
+
sm: 960,
|
|
71
|
+
md: 1264,
|
|
72
|
+
lg: 1904
|
|
73
|
+
}, breakpointsQuasar = {
|
|
74
|
+
xs: 600,
|
|
75
|
+
sm: 1024,
|
|
76
|
+
md: 1440,
|
|
77
|
+
lg: 1920
|
|
78
|
+
}, breakpointsMasterCss = {
|
|
79
|
+
"3xs": 360,
|
|
80
|
+
"2xs": 480,
|
|
81
|
+
xs: 600,
|
|
82
|
+
sm: 768,
|
|
83
|
+
md: 1024,
|
|
84
|
+
lg: 1280,
|
|
85
|
+
xl: 1440,
|
|
86
|
+
"2xl": 1600,
|
|
87
|
+
"3xl": 1920,
|
|
88
|
+
"4xl": 2560
|
|
89
|
+
}, breakpointsSematic = {
|
|
90
|
+
mobileS: 320,
|
|
91
|
+
mobileM: 375,
|
|
92
|
+
mobileL: 425,
|
|
93
|
+
tablet: 768,
|
|
94
|
+
laptop: 1024,
|
|
95
|
+
laptopL: 1440,
|
|
96
|
+
desktop: 2560
|
|
97
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Ref } from '@stacksjs/stx';
|
|
2
|
+
/**
|
|
3
|
+
* Reactive BroadcastChannel API for cross-tab communication.
|
|
4
|
+
*/
|
|
5
|
+
export declare function useBroadcastChannel(name: string): UseBroadcastChannelReturn;
|
|
6
|
+
export declare interface UseBroadcastChannelReturn {
|
|
7
|
+
isSupported: Ref<boolean>
|
|
8
|
+
channel: Ref<BroadcastChannel | undefined>
|
|
9
|
+
data: Ref<any>
|
|
10
|
+
error: Ref<any>
|
|
11
|
+
post: (data: any) => void
|
|
12
|
+
close: () => void
|
|
13
|
+
isClosed: Ref<boolean>
|
|
14
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { onUnmounted, ref } from "@stacksjs/stx";
|
|
2
|
+
export function useBroadcastChannel(name) {
|
|
3
|
+
const isSupported = ref(typeof BroadcastChannel < "u"), channel = ref(void 0), data = ref(null), error = ref(null), isClosed = ref(!1);
|
|
4
|
+
if (isSupported.value) {
|
|
5
|
+
const bc = new BroadcastChannel(name);
|
|
6
|
+
channel.value = bc;
|
|
7
|
+
bc.onmessage = (e) => {
|
|
8
|
+
data.value = e.data;
|
|
9
|
+
};
|
|
10
|
+
bc.onmessageerror = (e) => {
|
|
11
|
+
error.value = e;
|
|
12
|
+
};
|
|
13
|
+
try {
|
|
14
|
+
onUnmounted(() => {
|
|
15
|
+
bc.close();
|
|
16
|
+
isClosed.value = !0;
|
|
17
|
+
});
|
|
18
|
+
} catch {}
|
|
19
|
+
}
|
|
20
|
+
function post(message) {
|
|
21
|
+
if (channel.value && !isClosed.value)
|
|
22
|
+
channel.value.postMessage(message);
|
|
23
|
+
}
|
|
24
|
+
function close() {
|
|
25
|
+
if (channel.value && !isClosed.value) {
|
|
26
|
+
channel.value.close();
|
|
27
|
+
isClosed.value = !0;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return { isSupported, channel, data, error, post, close, isClosed };
|
|
31
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Ref } from '@stacksjs/stx';
|
|
2
|
+
/**
|
|
3
|
+
* Reactive browser location.
|
|
4
|
+
* Returns reactive refs for each part of window.location.
|
|
5
|
+
* Listens for popstate events to keep refs updated.
|
|
6
|
+
*/
|
|
7
|
+
export declare function useBrowserLocation(): UseBrowserLocationReturn;
|
|
8
|
+
export declare interface UseBrowserLocationReturn {
|
|
9
|
+
href: Ref<string>
|
|
10
|
+
protocol: Ref<string>
|
|
11
|
+
host: Ref<string>
|
|
12
|
+
hostname: Ref<string>
|
|
13
|
+
port: Ref<string>
|
|
14
|
+
pathname: Ref<string>
|
|
15
|
+
search: Ref<string>
|
|
16
|
+
hash: Ref<string>
|
|
17
|
+
origin: Ref<string>
|
|
18
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { onUnmounted, ref } from "@stacksjs/stx";
|
|
2
|
+
import { defaultWindow } from "./_shared";
|
|
3
|
+
export function useBrowserLocation() {
|
|
4
|
+
const win = defaultWindow();
|
|
5
|
+
function readLocation() {
|
|
6
|
+
if (!win)
|
|
7
|
+
return {
|
|
8
|
+
href: "",
|
|
9
|
+
protocol: "",
|
|
10
|
+
host: "",
|
|
11
|
+
hostname: "",
|
|
12
|
+
port: "",
|
|
13
|
+
pathname: "",
|
|
14
|
+
search: "",
|
|
15
|
+
hash: "",
|
|
16
|
+
origin: ""
|
|
17
|
+
};
|
|
18
|
+
return {
|
|
19
|
+
href: win.location.href,
|
|
20
|
+
protocol: win.location.protocol,
|
|
21
|
+
host: win.location.host,
|
|
22
|
+
hostname: win.location.hostname,
|
|
23
|
+
port: win.location.port,
|
|
24
|
+
pathname: win.location.pathname,
|
|
25
|
+
search: win.location.search,
|
|
26
|
+
hash: win.location.hash,
|
|
27
|
+
origin: win.location.origin
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
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);
|
|
31
|
+
function update() {
|
|
32
|
+
const loc = readLocation();
|
|
33
|
+
href.value = loc.href;
|
|
34
|
+
protocol.value = loc.protocol;
|
|
35
|
+
host.value = loc.host;
|
|
36
|
+
hostname.value = loc.hostname;
|
|
37
|
+
port.value = loc.port;
|
|
38
|
+
pathname.value = loc.pathname;
|
|
39
|
+
search.value = loc.search;
|
|
40
|
+
hash.value = loc.hash;
|
|
41
|
+
origin.value = loc.origin;
|
|
42
|
+
}
|
|
43
|
+
if (win) {
|
|
44
|
+
win.addEventListener("popstate", update);
|
|
45
|
+
win.addEventListener("hashchange", update);
|
|
46
|
+
try {
|
|
47
|
+
onUnmounted(() => {
|
|
48
|
+
win.removeEventListener("popstate", update);
|
|
49
|
+
win.removeEventListener("hashchange", update);
|
|
50
|
+
});
|
|
51
|
+
} catch {}
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
href,
|
|
55
|
+
protocol,
|
|
56
|
+
host,
|
|
57
|
+
hostname,
|
|
58
|
+
port,
|
|
59
|
+
pathname,
|
|
60
|
+
search,
|
|
61
|
+
hash,
|
|
62
|
+
origin
|
|
63
|
+
};
|
|
64
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { MaybeRefOrGetter } from './_shared';
|
|
2
|
+
import type { Ref } from '@stacksjs/stx';
|
|
3
|
+
/**
|
|
4
|
+
* Reactive Clipboard API.
|
|
5
|
+
* Read and write to the clipboard reactively.
|
|
6
|
+
*/
|
|
7
|
+
export declare function useClipboard(options?: UseClipboardOptions): UseClipboardReturn;
|
|
8
|
+
export declare interface UseClipboardOptions {
|
|
9
|
+
source?: MaybeRefOrGetter<string>
|
|
10
|
+
copiedDuring?: number
|
|
11
|
+
}
|
|
12
|
+
export declare interface UseClipboardReturn {
|
|
13
|
+
text: Ref<string>
|
|
14
|
+
isSupported: Ref<boolean>
|
|
15
|
+
copied: Ref<boolean>
|
|
16
|
+
copy: (text?: string) => Promise<void>
|
|
17
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { ref } from "@stacksjs/stx";
|
|
2
|
+
import { defaultNavigator, toValue } from "./_shared";
|
|
3
|
+
export function useClipboard(options) {
|
|
4
|
+
const {
|
|
5
|
+
source,
|
|
6
|
+
copiedDuring = 1500
|
|
7
|
+
} = options ?? {}, nav = defaultNavigator(), isSupported = ref(!!nav && "clipboard" in nav), text = ref(""), copied = ref(!1);
|
|
8
|
+
let copiedTimer;
|
|
9
|
+
async function copy(value) {
|
|
10
|
+
if (!isSupported.value)
|
|
11
|
+
return;
|
|
12
|
+
const valueToCopy = value ?? (source !== void 0 ? toValue(source) : void 0);
|
|
13
|
+
if (valueToCopy === void 0)
|
|
14
|
+
return;
|
|
15
|
+
try {
|
|
16
|
+
await nav.clipboard.writeText(valueToCopy);
|
|
17
|
+
text.value = valueToCopy;
|
|
18
|
+
copied.value = !0;
|
|
19
|
+
if (copiedTimer)
|
|
20
|
+
clearTimeout(copiedTimer);
|
|
21
|
+
copiedTimer = setTimeout(() => {
|
|
22
|
+
copied.value = !1;
|
|
23
|
+
}, copiedDuring);
|
|
24
|
+
} catch {}
|
|
25
|
+
}
|
|
26
|
+
return {
|
|
27
|
+
text,
|
|
28
|
+
isSupported,
|
|
29
|
+
copied,
|
|
30
|
+
copy
|
|
31
|
+
};
|
|
32
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Ref } from '@stacksjs/stx';
|
|
2
|
+
/**
|
|
3
|
+
* Reactive ClipboardItems API for rich content (images, etc.).
|
|
4
|
+
*/
|
|
5
|
+
export declare function useClipboardItems(): UseClipboardItemsReturn;
|
|
6
|
+
export declare interface UseClipboardItemsReturn {
|
|
7
|
+
isSupported: Ref<boolean>
|
|
8
|
+
content: Ref<ClipboardItems>
|
|
9
|
+
copy: (items: ClipboardItems) => Promise<void>
|
|
10
|
+
read: () => Promise<void>
|
|
11
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ref } from "@stacksjs/stx";
|
|
2
|
+
export function useClipboardItems() {
|
|
3
|
+
const isSupported = ref(typeof navigator < "u" && "clipboard" in navigator && typeof ClipboardItem < "u"), content = ref([]);
|
|
4
|
+
async function copy(items) {
|
|
5
|
+
if (isSupported.value) {
|
|
6
|
+
await navigator.clipboard.write(items);
|
|
7
|
+
content.value = items;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
async function read() {
|
|
11
|
+
if (isSupported.value)
|
|
12
|
+
content.value = await navigator.clipboard.read();
|
|
13
|
+
}
|
|
14
|
+
return { isSupported, content, copy, read };
|
|
15
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Ref } from '@stacksjs/stx';
|
|
2
|
+
/**
|
|
3
|
+
* Deep clone a ref value. Returns a cloned ref that syncs when the source changes.
|
|
4
|
+
*
|
|
5
|
+
* @param source - The source ref to clone
|
|
6
|
+
* @param options - Optional custom clone function
|
|
7
|
+
*/
|
|
8
|
+
export declare function useCloned<T>(source: Ref<T>, options?: UseClonedOptions<T>): UseClonedReturn<T>;
|
|
9
|
+
export declare interface UseClonedOptions<T> {
|
|
10
|
+
clone?: (val: T) => T
|
|
11
|
+
}
|
|
12
|
+
export declare interface UseClonedReturn<T> {
|
|
13
|
+
cloned: Ref<T>
|
|
14
|
+
sync: () => void
|
|
15
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ref, watch } from "@stacksjs/stx";
|
|
2
|
+
function defaultClone(val) {
|
|
3
|
+
if (typeof structuredClone === "function")
|
|
4
|
+
return structuredClone(val);
|
|
5
|
+
return JSON.parse(JSON.stringify(val));
|
|
6
|
+
}
|
|
7
|
+
export function useCloned(source, options = {}) {
|
|
8
|
+
const cloneFn = options.clone ?? defaultClone, cloned = ref(cloneFn(source.value));
|
|
9
|
+
function sync() {
|
|
10
|
+
cloned.value = cloneFn(source.value);
|
|
11
|
+
}
|
|
12
|
+
watch(source, () => {
|
|
13
|
+
sync();
|
|
14
|
+
});
|
|
15
|
+
return { cloned, sync };
|
|
16
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Ref } from '@stacksjs/stx';
|
|
2
|
+
/**
|
|
3
|
+
* Reactive color mode (dark / light / custom) with auto-detection and persistence.
|
|
4
|
+
*/
|
|
5
|
+
export declare function useColorMode(options?: UseColorModeOptions): UseColorModeReturn;
|
|
6
|
+
export declare interface UseColorModeOptions {
|
|
7
|
+
attribute?: string
|
|
8
|
+
initialValue?: ColorMode
|
|
9
|
+
modes?: Record<string, string>
|
|
10
|
+
storageKey?: string
|
|
11
|
+
selector?: string
|
|
12
|
+
}
|
|
13
|
+
export declare interface UseColorModeReturn {
|
|
14
|
+
mode: Ref<ColorMode>
|
|
15
|
+
system: Ref<'dark' | 'light'>
|
|
16
|
+
store: Ref<ColorMode>
|
|
17
|
+
}
|
|
18
|
+
export type ColorMode = 'dark' | 'light' | 'auto' | (string & {});
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { onUnmounted, ref, watch } from "@stacksjs/stx";
|
|
2
|
+
export function useColorMode(options = {}) {
|
|
3
|
+
const {
|
|
4
|
+
attribute = "class",
|
|
5
|
+
initialValue = "auto",
|
|
6
|
+
modes = {},
|
|
7
|
+
storageKey = "color-mode",
|
|
8
|
+
selector
|
|
9
|
+
} = options, system = ref("light");
|
|
10
|
+
if (typeof window < "u" && window.matchMedia) {
|
|
11
|
+
const mq = window.matchMedia("(prefers-color-scheme: dark)");
|
|
12
|
+
system.value = mq.matches ? "dark" : "light";
|
|
13
|
+
const onChange = (e) => {
|
|
14
|
+
system.value = e.matches ? "dark" : "light";
|
|
15
|
+
};
|
|
16
|
+
mq.addEventListener("change", onChange);
|
|
17
|
+
try {
|
|
18
|
+
onUnmounted(() => {
|
|
19
|
+
mq.removeEventListener("change", onChange);
|
|
20
|
+
});
|
|
21
|
+
} catch {}
|
|
22
|
+
}
|
|
23
|
+
let stored = initialValue;
|
|
24
|
+
if (typeof localStorage < "u") {
|
|
25
|
+
const val = localStorage.getItem(storageKey);
|
|
26
|
+
if (val)
|
|
27
|
+
stored = val;
|
|
28
|
+
}
|
|
29
|
+
const store = ref(stored), mode = ref(store.value === "auto" ? system.value : store.value);
|
|
30
|
+
function applyMode(m) {
|
|
31
|
+
if (typeof document > "u")
|
|
32
|
+
return;
|
|
33
|
+
const el = selector ? document.querySelector(selector) : document.documentElement;
|
|
34
|
+
if (!el)
|
|
35
|
+
return;
|
|
36
|
+
const value = modes[m] ?? m;
|
|
37
|
+
if (attribute === "class") {
|
|
38
|
+
const allModes = ["dark", "light", ...Object.keys(modes), ...Object.values(modes)];
|
|
39
|
+
for (const cls of allModes)
|
|
40
|
+
el.classList.remove(cls);
|
|
41
|
+
if (value)
|
|
42
|
+
el.classList.add(value);
|
|
43
|
+
} else
|
|
44
|
+
el.setAttribute(attribute, value);
|
|
45
|
+
}
|
|
46
|
+
watch(store, (val) => {
|
|
47
|
+
if (typeof localStorage < "u")
|
|
48
|
+
localStorage.setItem(storageKey, val);
|
|
49
|
+
mode.value = val === "auto" ? system.value : val;
|
|
50
|
+
});
|
|
51
|
+
watch(system, (val) => {
|
|
52
|
+
if (store.value === "auto")
|
|
53
|
+
mode.value = val;
|
|
54
|
+
});
|
|
55
|
+
watch(mode, (val) => {
|
|
56
|
+
applyMode(val);
|
|
57
|
+
});
|
|
58
|
+
applyMode(mode.value);
|
|
59
|
+
return { mode, system, store };
|
|
60
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Ref } from '@stacksjs/stx';
|
|
2
|
+
/**
|
|
3
|
+
* Create a confirm dialog composable with reveal/confirm/cancel flow.
|
|
4
|
+
*/
|
|
5
|
+
export declare function useConfirmDialog<T = any, C = any>(): UseConfirmDialogReturn<T, C>;
|
|
6
|
+
export declare interface UseConfirmDialogReturn<T = any, C = any> {
|
|
7
|
+
isRevealed: Ref<boolean>
|
|
8
|
+
reveal: (data?: T) => Promise<{ data?: C, isCanceled: boolean }>
|
|
9
|
+
confirm: (data?: C) => void
|
|
10
|
+
cancel: () => void
|
|
11
|
+
onConfirm: (fn: (data?: C) => void) => { off: () => void }
|
|
12
|
+
onCancel: (fn: () => void) => { off: () => void }
|
|
13
|
+
onReveal: (fn: (data?: T) => void) => { off: () => void }
|
|
14
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { ref } from "@stacksjs/stx";
|
|
2
|
+
import { createEventHook } from "./createEventHook";
|
|
3
|
+
export function useConfirmDialog() {
|
|
4
|
+
const isRevealed = ref(!1), confirmHook = createEventHook(), cancelHook = createEventHook(), revealHook = createEventHook();
|
|
5
|
+
let resolvePromise = null;
|
|
6
|
+
function reveal(data) {
|
|
7
|
+
isRevealed.value = !0;
|
|
8
|
+
revealHook.trigger(data);
|
|
9
|
+
return new Promise((resolve) => {
|
|
10
|
+
resolvePromise = resolve;
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
function confirm(data) {
|
|
14
|
+
isRevealed.value = !1;
|
|
15
|
+
confirmHook.trigger(data);
|
|
16
|
+
resolvePromise?.({ data, isCanceled: !1 });
|
|
17
|
+
resolvePromise = null;
|
|
18
|
+
}
|
|
19
|
+
function cancel() {
|
|
20
|
+
isRevealed.value = !1;
|
|
21
|
+
cancelHook.trigger(void 0);
|
|
22
|
+
resolvePromise?.({ isCanceled: !0 });
|
|
23
|
+
resolvePromise = null;
|
|
24
|
+
}
|
|
25
|
+
return {
|
|
26
|
+
isRevealed,
|
|
27
|
+
reveal,
|
|
28
|
+
confirm,
|
|
29
|
+
cancel,
|
|
30
|
+
onConfirm: confirmHook.on,
|
|
31
|
+
onCancel: cancelHook.on,
|
|
32
|
+
onReveal: revealHook.on
|
|
33
|
+
};
|
|
34
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Ref } from '@stacksjs/stx';
|
|
2
|
+
/**
|
|
3
|
+
* Reactive counter with increment, decrement, set, reset, and min/max bounds.
|
|
4
|
+
*
|
|
5
|
+
* @param initialValue - Starting value (default 0)
|
|
6
|
+
* @param options - Optional min/max bounds
|
|
7
|
+
*/
|
|
8
|
+
export declare function useCounter(initialValue?: number, options?: UseCounterOptions): UseCounterReturn;
|
|
9
|
+
export declare interface UseCounterOptions {
|
|
10
|
+
min?: number
|
|
11
|
+
max?: number
|
|
12
|
+
}
|
|
13
|
+
export declare interface UseCounterReturn {
|
|
14
|
+
count: Ref<number>
|
|
15
|
+
inc: (delta?: number) => number
|
|
16
|
+
dec: (delta?: number) => number
|
|
17
|
+
set: (val: number) => number
|
|
18
|
+
reset: (val?: number) => number
|
|
19
|
+
get: () => number
|
|
20
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { ref } from "@stacksjs/stx";
|
|
2
|
+
export function useCounter(initialValue = 0, options = {}) {
|
|
3
|
+
const { min = -1 / 0, max = 1 / 0 } = options;
|
|
4
|
+
function clamp(val) {
|
|
5
|
+
return Math.min(max, Math.max(min, val));
|
|
6
|
+
}
|
|
7
|
+
const count = ref(clamp(initialValue));
|
|
8
|
+
function inc(delta = 1) {
|
|
9
|
+
count.value = clamp(count.value + delta);
|
|
10
|
+
return count.value;
|
|
11
|
+
}
|
|
12
|
+
function dec(delta = 1) {
|
|
13
|
+
count.value = clamp(count.value - delta);
|
|
14
|
+
return count.value;
|
|
15
|
+
}
|
|
16
|
+
function set(val) {
|
|
17
|
+
count.value = clamp(val);
|
|
18
|
+
return count.value;
|
|
19
|
+
}
|
|
20
|
+
function reset(val = initialValue) {
|
|
21
|
+
count.value = clamp(val);
|
|
22
|
+
return count.value;
|
|
23
|
+
}
|
|
24
|
+
function get() {
|
|
25
|
+
return count.value;
|
|
26
|
+
}
|
|
27
|
+
return { count, inc, dec, set, reset, get };
|
|
28
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { MaybeRef } from './_shared';
|
|
2
|
+
import type { Ref } from '@stacksjs/stx';
|
|
3
|
+
/**
|
|
4
|
+
* Reactive CSS variable binding.
|
|
5
|
+
*
|
|
6
|
+
* @param name - The CSS variable name (e.g., '--color')
|
|
7
|
+
* @param target - The target element (defaults to document.documentElement)
|
|
8
|
+
* @param defaultValue - Default value if the variable is not set
|
|
9
|
+
*/
|
|
10
|
+
export declare function useCssVar(name: MaybeRef<string>, target?: MaybeRef<HTMLElement | null | undefined>, defaultValue?: string): Ref<string>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { onUnmounted, ref, watch } from "@stacksjs/stx";
|
|
2
|
+
import { unref } from "./_shared";
|
|
3
|
+
export function useCssVar(name, target, defaultValue) {
|
|
4
|
+
const variable = ref(defaultValue ?? ""), getEl = () => {
|
|
5
|
+
const t = unref(target);
|
|
6
|
+
if (t)
|
|
7
|
+
return t;
|
|
8
|
+
if (typeof document < "u")
|
|
9
|
+
return document.documentElement;
|
|
10
|
+
return null;
|
|
11
|
+
}, el = getEl();
|
|
12
|
+
if (el) {
|
|
13
|
+
const current = getComputedStyle(el).getPropertyValue(unref(name)).trim();
|
|
14
|
+
if (current)
|
|
15
|
+
variable.value = current;
|
|
16
|
+
}
|
|
17
|
+
watch(variable, (val) => {
|
|
18
|
+
const element = getEl();
|
|
19
|
+
if (element)
|
|
20
|
+
element.style.setProperty(unref(name), val);
|
|
21
|
+
});
|
|
22
|
+
return variable;
|
|
23
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Ref } from '@stacksjs/stx';
|
|
2
|
+
/**
|
|
3
|
+
* Cycle through a list of values with wrap-around.
|
|
4
|
+
*
|
|
5
|
+
* @param list - Array of values to cycle through
|
|
6
|
+
* @param options - Optional initial value
|
|
7
|
+
*/
|
|
8
|
+
export declare function useCycleList<T>(list: T[], options?: UseCycleListOptions<T>): UseCycleListReturn<T>;
|
|
9
|
+
export declare interface UseCycleListOptions<T> {
|
|
10
|
+
initialValue?: T
|
|
11
|
+
}
|
|
12
|
+
export declare interface UseCycleListReturn<T> {
|
|
13
|
+
state: Ref<T>
|
|
14
|
+
index: Ref<number>
|
|
15
|
+
next: (n?: number) => T
|
|
16
|
+
prev: (n?: number) => T
|
|
17
|
+
go: (i: number) => T
|
|
18
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { computed, ref } from "@stacksjs/stx";
|
|
2
|
+
export function useCycleList(list, options = {}) {
|
|
3
|
+
const length = list.length;
|
|
4
|
+
if (length === 0)
|
|
5
|
+
throw Error("useCycleList requires a non-empty list");
|
|
6
|
+
const initialIndex = options.initialValue !== void 0 ? list.indexOf(options.initialValue) : 0, index = ref(initialIndex >= 0 ? initialIndex : 0);
|
|
7
|
+
function at(i) {
|
|
8
|
+
return list[i];
|
|
9
|
+
}
|
|
10
|
+
const state = computed(() => at(index.value));
|
|
11
|
+
function normalizeIndex(i) {
|
|
12
|
+
return (i % length + length) % length;
|
|
13
|
+
}
|
|
14
|
+
function next(n = 1) {
|
|
15
|
+
index.value = normalizeIndex(index.value + n);
|
|
16
|
+
return at(index.value);
|
|
17
|
+
}
|
|
18
|
+
function prev(n = 1) {
|
|
19
|
+
index.value = normalizeIndex(index.value - n);
|
|
20
|
+
return at(index.value);
|
|
21
|
+
}
|
|
22
|
+
function go(i) {
|
|
23
|
+
index.value = normalizeIndex(i);
|
|
24
|
+
return at(index.value);
|
|
25
|
+
}
|
|
26
|
+
return { state, index, next, prev, go };
|
|
27
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Ref } from '@stacksjs/stx';
|
|
2
|
+
/**
|
|
3
|
+
* Reactive preferred color scheme detection.
|
|
4
|
+
* Returns a ref that tracks the user's OS-level dark mode preference.
|
|
5
|
+
*/
|
|
6
|
+
export declare function usePreferredDark(): Ref<boolean>;
|
|
7
|
+
/**
|
|
8
|
+
* Reactive dark mode with localStorage persistence.
|
|
9
|
+
* Adds/removes the 'dark' class on document.documentElement.
|
|
10
|
+
*/
|
|
11
|
+
export declare function useDark(): Ref<boolean>;
|
package/dist/useDark.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { onUnmounted, ref, watch } from "@stacksjs/stx";
|
|
2
|
+
export function usePreferredDark() {
|
|
3
|
+
const matches = ref(!1);
|
|
4
|
+
if (typeof window < "u" && window.matchMedia) {
|
|
5
|
+
const mq = window.matchMedia("(prefers-color-scheme: dark)");
|
|
6
|
+
matches.value = mq.matches;
|
|
7
|
+
const onChange = (e) => {
|
|
8
|
+
matches.value = e.matches;
|
|
9
|
+
};
|
|
10
|
+
mq.addEventListener("change", onChange);
|
|
11
|
+
try {
|
|
12
|
+
onUnmounted(() => {
|
|
13
|
+
mq.removeEventListener("change", onChange);
|
|
14
|
+
});
|
|
15
|
+
} catch {}
|
|
16
|
+
}
|
|
17
|
+
return matches;
|
|
18
|
+
}
|
|
19
|
+
export function useDark() {
|
|
20
|
+
let initial = usePreferredDark().value;
|
|
21
|
+
if (typeof localStorage < "u") {
|
|
22
|
+
const stored = localStorage.getItem("color-scheme");
|
|
23
|
+
if (stored === "dark")
|
|
24
|
+
initial = !0;
|
|
25
|
+
else if (stored === "light")
|
|
26
|
+
initial = !1;
|
|
27
|
+
}
|
|
28
|
+
const isDark = ref(initial);
|
|
29
|
+
watch(isDark, (val) => {
|
|
30
|
+
if (typeof document < "u")
|
|
31
|
+
document.documentElement.classList.toggle("dark", val);
|
|
32
|
+
if (typeof localStorage < "u")
|
|
33
|
+
localStorage.setItem("color-scheme", val ? "dark" : "light");
|
|
34
|
+
});
|
|
35
|
+
if (typeof document < "u")
|
|
36
|
+
document.documentElement.classList.toggle("dark", isDark.value);
|
|
37
|
+
return isDark;
|
|
38
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Ref } from '@stacksjs/stx';
|
|
2
|
+
/**
|
|
3
|
+
* Reactive date formatting composable.
|
|
4
|
+
* Returns a ref containing the formatted date string.
|
|
5
|
+
* Uses @stacksjs/datetime format() under the hood.
|
|
6
|
+
*
|
|
7
|
+
* @param date - Date value (or ref) to format
|
|
8
|
+
* @param formatStr - Token-based format string (e.g. 'YYYY-MM-DD HH:mm:ss')
|
|
9
|
+
*/
|
|
10
|
+
export declare function useDateFormat(date: Ref<Date | string | number> | Date | string | number, formatStr: string): Ref<string>;
|