@vueuse/components
Version:
Renderless components for VueUse
1,712 lines (1,655 loc) • 76.3 kB
JavaScript
import { onClickOutside as onClickOutside$1, useActiveElement, useBattery, useBrowserLocation, useClipboard, useDark, useDeviceMotion, useDeviceOrientation, useDevicePixelRatio, useDevicesList, useDocumentVisibility, useStorage as useStorage$1, isClient as isClient$1, useDraggable, useElementBounding as useElementBounding$1, useElementSize as useElementSize$1, useElementVisibility as useElementVisibility$1, useEyeDropper, useFullscreen, useGeolocation, useIdle, useMouse as useMouse$1, useMouseInElement as useMouseInElement$1, useMousePressed, useNetwork, useNow, useObjectUrl, useOffsetPagination, useOnline, usePageLeave, usePointer, usePointerLock, usePreferredColorScheme, usePreferredContrast, usePreferredDark as usePreferredDark$1, usePreferredLanguages, usePreferredReducedMotion, usePreferredReducedTransparency, useTimeAgo, useTimestamp, useVirtualList, useWindowFocus, useWindowSize } from '@vueuse/core';
import { defineComponent, shallowRef, h, toValue, computed, unref, reactive, hasInjectionContext, getCurrentInstance, onMounted, watchEffect, ref, watch, nextTick, toRefs } from 'vue';
import { isClient, toArray, watchImmediate, isObject, tryOnScopeDispose, noop, isIOS, injectLocal, pxValue, pausableWatch, tryOnMounted, toRef, useToggle, notNullish, watchOnce, promiseTimeout, until, useDebounceFn, useThrottleFn, tryOnUnmounted, reactiveOmit } from '@vueuse/shared';
const OnClickOutside = /* @__PURE__ */ defineComponent({
name: "OnClickOutside",
props: ["as", "options"],
emits: ["trigger"],
setup(props, { slots, emit }) {
const target = shallowRef();
onClickOutside$1(target, (e) => {
emit("trigger", e);
}, props.options);
return () => {
if (slots.default)
return h(props.as || "div", { ref: target }, slots.default());
};
}
});
const defaultWindow = isClient ? window : void 0;
function unrefElement(elRef) {
var _a;
const plain = toValue(elRef);
return (_a = plain == null ? void 0 : plain.$el) != null ? _a : plain;
}
function useEventListener(...args) {
const cleanups = [];
const cleanup = () => {
cleanups.forEach((fn) => fn());
cleanups.length = 0;
};
const register = (el, event, listener, options) => {
el.addEventListener(event, listener, options);
return () => el.removeEventListener(event, listener, options);
};
const firstParamTargets = computed(() => {
const test = toArray(toValue(args[0])).filter((e) => e != null);
return test.every((e) => typeof e !== "string") ? test : void 0;
});
const stopWatch = watchImmediate(
() => {
var _a, _b;
return [
(_b = (_a = firstParamTargets.value) == null ? void 0 : _a.map((e) => unrefElement(e))) != null ? _b : [defaultWindow].filter((e) => e != null),
toArray(toValue(firstParamTargets.value ? args[1] : args[0])),
toArray(unref(firstParamTargets.value ? args[2] : args[1])),
// @ts-expect-error - TypeScript gets the correct types, but somehow still complains
toValue(firstParamTargets.value ? args[3] : args[2])
];
},
([raw_targets, raw_events, raw_listeners, raw_options]) => {
cleanup();
if (!(raw_targets == null ? void 0 : raw_targets.length) || !(raw_events == null ? void 0 : raw_events.length) || !(raw_listeners == null ? void 0 : raw_listeners.length))
return;
const optionsClone = isObject(raw_options) ? { ...raw_options } : raw_options;
cleanups.push(
...raw_targets.flatMap(
(el) => raw_events.flatMap(
(event) => raw_listeners.map((listener) => register(el, event, listener, optionsClone))
)
)
);
},
{ flush: "post" }
);
const stop = () => {
stopWatch();
cleanup();
};
tryOnScopeDispose(cleanup);
return stop;
}
let _iOSWorkaround = false;
function onClickOutside(target, handler, options = {}) {
const { window = defaultWindow, ignore = [], capture = true, detectIframe = false, controls = false } = options;
if (!window) {
return controls ? { stop: noop, cancel: noop, trigger: noop } : noop;
}
if (isIOS && !_iOSWorkaround) {
_iOSWorkaround = true;
const listenerOptions = { passive: true };
Array.from(window.document.body.children).forEach((el) => el.addEventListener("click", noop, listenerOptions));
window.document.documentElement.addEventListener("click", noop, listenerOptions);
}
let shouldListen = true;
const shouldIgnore = (event) => {
return toValue(ignore).some((target2) => {
if (typeof target2 === "string") {
return Array.from(window.document.querySelectorAll(target2)).some((el) => el === event.target || event.composedPath().includes(el));
} else {
const el = unrefElement(target2);
return el && (event.target === el || event.composedPath().includes(el));
}
});
};
function hasMultipleRoots(target2) {
const vm = toValue(target2);
return vm && vm.$.subTree.shapeFlag === 16;
}
function checkMultipleRoots(target2, event) {
const vm = toValue(target2);
const children = vm.$.subTree && vm.$.subTree.children;
if (children == null || !Array.isArray(children))
return false;
return children.some((child) => child.el === event.target || event.composedPath().includes(child.el));
}
const listener = (event) => {
const el = unrefElement(target);
if (event.target == null)
return;
if (!(el instanceof Element) && hasMultipleRoots(target) && checkMultipleRoots(target, event))
return;
if (!el || el === event.target || event.composedPath().includes(el))
return;
if ("detail" in event && event.detail === 0)
shouldListen = !shouldIgnore(event);
if (!shouldListen) {
shouldListen = true;
return;
}
handler(event);
};
let isProcessingClick = false;
const cleanup = [
useEventListener(window, "click", (event) => {
if (!isProcessingClick) {
isProcessingClick = true;
setTimeout(() => {
isProcessingClick = false;
}, 0);
listener(event);
}
}, { passive: true, capture }),
useEventListener(window, "pointerdown", (e) => {
const el = unrefElement(target);
shouldListen = !shouldIgnore(e) && !!(el && !e.composedPath().includes(el));
}, { passive: true }),
detectIframe && useEventListener(window, "blur", (event) => {
setTimeout(() => {
var _a;
const el = unrefElement(target);
if (((_a = window.document.activeElement) == null ? void 0 : _a.tagName) === "IFRAME" && !(el == null ? void 0 : el.contains(window.document.activeElement))) {
handler(event);
}
}, 0);
}, { passive: true })
].filter(Boolean);
const stop = () => cleanup.forEach((fn) => fn());
if (controls) {
return {
stop,
cancel: () => {
shouldListen = false;
},
trigger: (event) => {
shouldListen = true;
listener(event);
shouldListen = false;
}
};
}
return stop;
}
const stopClickOutsideMap = /* @__PURE__ */ new WeakMap();
const vOnClickOutside = {
mounted(el, binding) {
const capture = !binding.modifiers.bubble;
let stop;
if (typeof binding.value === "function") {
stop = onClickOutside(el, binding.value, { capture });
} else {
const [handler, options] = binding.value;
stop = onClickOutside(el, handler, Object.assign({ capture }, options));
}
stopClickOutsideMap.set(el, stop);
},
unmounted(el) {
const stop = stopClickOutsideMap.get(el);
if (stop && typeof stop === "function") {
stop();
} else {
stop == null ? void 0 : stop.stop();
}
stopClickOutsideMap.delete(el);
}
};
function createKeyPredicate(keyFilter) {
if (typeof keyFilter === "function")
return keyFilter;
else if (typeof keyFilter === "string")
return (event) => event.key === keyFilter;
else if (Array.isArray(keyFilter))
return (event) => keyFilter.includes(event.key);
return () => true;
}
function onKeyStroke(...args) {
let key;
let handler;
let options = {};
if (args.length === 3) {
key = args[0];
handler = args[1];
options = args[2];
} else if (args.length === 2) {
if (typeof args[1] === "object") {
key = true;
handler = args[0];
options = args[1];
} else {
key = args[0];
handler = args[1];
}
} else {
key = true;
handler = args[0];
}
const {
target = defaultWindow,
eventName = "keydown",
passive = false,
dedupe = false
} = options;
const predicate = createKeyPredicate(key);
const listener = (e) => {
if (e.repeat && toValue(dedupe))
return;
if (predicate(e))
handler(e);
};
return useEventListener(target, eventName, listener, passive);
}
const vOnKeyStroke = {
mounted(el, binding) {
var _a, _b;
const keys = (_b = (_a = binding.arg) == null ? void 0 : _a.split(",")) != null ? _b : true;
if (typeof binding.value === "function") {
onKeyStroke(keys, binding.value, {
target: el
});
} else {
const [handler, options] = binding.value;
onKeyStroke(keys, handler, {
target: el,
...options
});
}
}
};
const DEFAULT_DELAY = 500;
const DEFAULT_THRESHOLD = 10;
function onLongPress(target, handler, options) {
var _a, _b;
const elementRef = computed(() => unrefElement(target));
let timeout;
let posStart;
let startTimestamp;
let hasLongPressed = false;
function clear() {
if (timeout) {
clearTimeout(timeout);
timeout = void 0;
}
posStart = void 0;
startTimestamp = void 0;
hasLongPressed = false;
}
function onRelease(ev) {
var _a2, _b2, _c;
const [_startTimestamp, _posStart, _hasLongPressed] = [startTimestamp, posStart, hasLongPressed];
clear();
if (!(options == null ? void 0 : options.onMouseUp) || !_posStart || !_startTimestamp)
return;
if (((_a2 = options == null ? void 0 : options.modifiers) == null ? void 0 : _a2.self) && ev.target !== elementRef.value)
return;
if ((_b2 = options == null ? void 0 : options.modifiers) == null ? void 0 : _b2.prevent)
ev.preventDefault();
if ((_c = options == null ? void 0 : options.modifiers) == null ? void 0 : _c.stop)
ev.stopPropagation();
const dx = ev.x - _posStart.x;
const dy = ev.y - _posStart.y;
const distance = Math.sqrt(dx * dx + dy * dy);
options.onMouseUp(ev.timeStamp - _startTimestamp, distance, _hasLongPressed);
}
function onDown(ev) {
var _a2, _b2, _c, _d;
if (((_a2 = options == null ? void 0 : options.modifiers) == null ? void 0 : _a2.self) && ev.target !== elementRef.value)
return;
clear();
if ((_b2 = options == null ? void 0 : options.modifiers) == null ? void 0 : _b2.prevent)
ev.preventDefault();
if ((_c = options == null ? void 0 : options.modifiers) == null ? void 0 : _c.stop)
ev.stopPropagation();
posStart = {
x: ev.x,
y: ev.y
};
startTimestamp = ev.timeStamp;
timeout = setTimeout(
() => {
hasLongPressed = true;
handler(ev);
},
(_d = options == null ? void 0 : options.delay) != null ? _d : DEFAULT_DELAY
);
}
function onMove(ev) {
var _a2, _b2, _c, _d;
if (((_a2 = options == null ? void 0 : options.modifiers) == null ? void 0 : _a2.self) && ev.target !== elementRef.value)
return;
if (!posStart || (options == null ? void 0 : options.distanceThreshold) === false)
return;
if ((_b2 = options == null ? void 0 : options.modifiers) == null ? void 0 : _b2.prevent)
ev.preventDefault();
if ((_c = options == null ? void 0 : options.modifiers) == null ? void 0 : _c.stop)
ev.stopPropagation();
const dx = ev.x - posStart.x;
const dy = ev.y - posStart.y;
const distance = Math.sqrt(dx * dx + dy * dy);
if (distance >= ((_d = options == null ? void 0 : options.distanceThreshold) != null ? _d : DEFAULT_THRESHOLD))
clear();
}
const listenerOptions = {
capture: (_a = options == null ? void 0 : options.modifiers) == null ? void 0 : _a.capture,
once: (_b = options == null ? void 0 : options.modifiers) == null ? void 0 : _b.once
};
const cleanup = [
useEventListener(elementRef, "pointerdown", onDown, listenerOptions),
useEventListener(elementRef, "pointermove", onMove, listenerOptions),
useEventListener(elementRef, ["pointerup", "pointerleave"], onRelease, listenerOptions)
];
const stop = () => cleanup.forEach((fn) => fn());
return stop;
}
const OnLongPress = /* @__PURE__ */ defineComponent({
name: "OnLongPress",
props: ["as", "options"],
emits: ["trigger"],
setup(props, { slots, emit }) {
const target = shallowRef();
onLongPress(
target,
(e) => {
emit("trigger", e);
},
props.options
);
return () => {
if (slots.default)
return h(props.as || "div", { ref: target }, slots.default());
};
}
});
const vOnLongPress = {
mounted(el, binding) {
if (typeof binding.value === "function")
onLongPress(el, binding.value, { modifiers: binding.modifiers });
else
onLongPress(el, ...binding.value);
}
};
const UseActiveElement = /* @__PURE__ */ defineComponent({
name: "UseActiveElement",
setup(props, { slots }) {
const data = reactive({
element: useActiveElement()
});
return () => {
if (slots.default)
return slots.default(data);
};
}
});
const UseBattery = /* @__PURE__ */ defineComponent({
name: "UseBattery",
setup(props, { slots }) {
const data = reactive(useBattery(props));
return () => {
if (slots.default)
return slots.default(data);
};
}
});
const UseBrowserLocation = /* @__PURE__ */ defineComponent({
name: "UseBrowserLocation",
setup(props, { slots }) {
const data = reactive(useBrowserLocation());
return () => {
if (slots.default)
return slots.default(data);
};
}
});
const UseClipboard = /* @__PURE__ */ defineComponent({
name: "UseClipboard",
props: [
"source",
"read",
"navigator",
"copiedDuring",
"legacy"
],
setup(props, { slots }) {
const data = reactive(useClipboard(props));
return () => {
var _a;
return (_a = slots.default) == null ? void 0 : _a.call(slots, data);
};
}
});
const _global = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
const globalKey = "__vueuse_ssr_handlers__";
const handlers = /* @__PURE__ */ getHandlers();
function getHandlers() {
if (!(globalKey in _global))
_global[globalKey] = _global[globalKey] || {};
return _global[globalKey];
}
function getSSRHandler(key, fallback) {
return handlers[key] || fallback;
}
const ssrWidthSymbol = Symbol("vueuse-ssr-width");
// @__NO_SIDE_EFFECTS__
function useSSRWidth() {
const ssrWidth = hasInjectionContext() ? injectLocal(ssrWidthSymbol, null) : null;
return typeof ssrWidth === "number" ? ssrWidth : void 0;
}
// @__NO_SIDE_EFFECTS__
function useMounted() {
const isMounted = shallowRef(false);
const instance = getCurrentInstance();
if (instance) {
onMounted(() => {
isMounted.value = true;
}, instance);
}
return isMounted;
}
// @__NO_SIDE_EFFECTS__
function useSupported(callback) {
const isMounted = useMounted();
return computed(() => {
isMounted.value;
return Boolean(callback());
});
}
function useMediaQuery(query, options = {}) {
const { window = defaultWindow, ssrWidth = useSSRWidth() } = options;
const isSupported = useSupported(() => window && "matchMedia" in window && typeof window.matchMedia === "function");
const ssrSupport = shallowRef(typeof ssrWidth === "number");
const mediaQuery = shallowRef();
const matches = shallowRef(false);
const handler = (event) => {
matches.value = event.matches;
};
watchEffect(() => {
if (ssrSupport.value) {
ssrSupport.value = !isSupported.value;
const queryStrings = toValue(query).split(",");
matches.value = queryStrings.some((queryString) => {
const not = queryString.includes("not all");
const minWidth = queryString.match(/\(\s*min-width:\s*(-?\d+(?:\.\d*)?[a-z]+\s*)\)/);
const maxWidth = queryString.match(/\(\s*max-width:\s*(-?\d+(?:\.\d*)?[a-z]+\s*)\)/);
let res = Boolean(minWidth || maxWidth);
if (minWidth && res) {
res = ssrWidth >= pxValue(minWidth[1]);
}
if (maxWidth && res) {
res = ssrWidth <= pxValue(maxWidth[1]);
}
return not ? !res : res;
});
return;
}
if (!isSupported.value)
return;
mediaQuery.value = window.matchMedia(toValue(query));
matches.value = mediaQuery.value.matches;
});
useEventListener(mediaQuery, "change", handler, { passive: true });
return computed(() => matches.value);
}
// @__NO_SIDE_EFFECTS__
function usePreferredDark(options) {
return useMediaQuery("(prefers-color-scheme: dark)", options);
}
function guessSerializerType(rawInit) {
return rawInit == null ? "any" : rawInit instanceof Set ? "set" : rawInit instanceof Map ? "map" : rawInit instanceof Date ? "date" : typeof rawInit === "boolean" ? "boolean" : typeof rawInit === "string" ? "string" : typeof rawInit === "object" ? "object" : !Number.isNaN(rawInit) ? "number" : "any";
}
const StorageSerializers = {
boolean: {
read: (v) => v === "true",
write: (v) => String(v)
},
object: {
read: (v) => JSON.parse(v),
write: (v) => JSON.stringify(v)
},
number: {
read: (v) => Number.parseFloat(v),
write: (v) => String(v)
},
any: {
read: (v) => v,
write: (v) => String(v)
},
string: {
read: (v) => v,
write: (v) => String(v)
},
map: {
read: (v) => new Map(JSON.parse(v)),
write: (v) => JSON.stringify(Array.from(v.entries()))
},
set: {
read: (v) => new Set(JSON.parse(v)),
write: (v) => JSON.stringify(Array.from(v))
},
date: {
read: (v) => new Date(v),
write: (v) => v.toISOString()
}
};
const customStorageEventName = "vueuse-storage";
function useStorage(key, defaults, storage, options = {}) {
var _a;
const {
flush = "pre",
deep = true,
listenToStorageChanges = true,
writeDefaults = true,
mergeDefaults = false,
shallow,
window = defaultWindow,
eventFilter,
onError = (e) => {
console.error(e);
},
initOnMounted
} = options;
const data = (shallow ? shallowRef : ref)(typeof defaults === "function" ? defaults() : defaults);
const keyComputed = computed(() => toValue(key));
if (!storage) {
try {
storage = getSSRHandler("getDefaultStorage", () => {
var _a2;
return (_a2 = defaultWindow) == null ? void 0 : _a2.localStorage;
})();
} catch (e) {
onError(e);
}
}
if (!storage)
return data;
const rawInit = toValue(defaults);
const type = guessSerializerType(rawInit);
const serializer = (_a = options.serializer) != null ? _a : StorageSerializers[type];
const { pause: pauseWatch, resume: resumeWatch } = pausableWatch(
data,
() => write(data.value),
{ flush, deep, eventFilter }
);
watch(keyComputed, () => update(), { flush });
let firstMounted = false;
const onStorageEvent = (ev) => {
if (initOnMounted && !firstMounted) {
return;
}
update(ev);
};
const onStorageCustomEvent = (ev) => {
if (initOnMounted && !firstMounted) {
return;
}
updateFromCustomEvent(ev);
};
if (window && listenToStorageChanges) {
if (storage instanceof Storage)
useEventListener(window, "storage", onStorageEvent, { passive: true });
else
useEventListener(window, customStorageEventName, onStorageCustomEvent);
}
if (initOnMounted) {
tryOnMounted(() => {
firstMounted = true;
update();
});
} else {
update();
}
function dispatchWriteEvent(oldValue, newValue) {
if (window) {
const payload = {
key: keyComputed.value,
oldValue,
newValue,
storageArea: storage
};
window.dispatchEvent(storage instanceof Storage ? new StorageEvent("storage", payload) : new CustomEvent(customStorageEventName, {
detail: payload
}));
}
}
function write(v) {
try {
const oldValue = storage.getItem(keyComputed.value);
if (v == null) {
dispatchWriteEvent(oldValue, null);
storage.removeItem(keyComputed.value);
} else {
const serialized = serializer.write(v);
if (oldValue !== serialized) {
storage.setItem(keyComputed.value, serialized);
dispatchWriteEvent(oldValue, serialized);
}
}
} catch (e) {
onError(e);
}
}
function read(event) {
const rawValue = event ? event.newValue : storage.getItem(keyComputed.value);
if (rawValue == null) {
if (writeDefaults && rawInit != null)
storage.setItem(keyComputed.value, serializer.write(rawInit));
return rawInit;
} else if (!event && mergeDefaults) {
const value = serializer.read(rawValue);
if (typeof mergeDefaults === "function")
return mergeDefaults(value, rawInit);
else if (type === "object" && !Array.isArray(value))
return { ...rawInit, ...value };
return value;
} else if (typeof rawValue !== "string") {
return rawValue;
} else {
return serializer.read(rawValue);
}
}
function update(event) {
if (event && event.storageArea !== storage)
return;
if (event && event.key == null) {
data.value = rawInit;
return;
}
if (event && event.key !== keyComputed.value)
return;
pauseWatch();
try {
if ((event == null ? void 0 : event.newValue) !== serializer.write(data.value))
data.value = read(event);
} catch (e) {
onError(e);
} finally {
if (event)
nextTick(resumeWatch);
else
resumeWatch();
}
}
function updateFromCustomEvent(event) {
update(event.detail);
}
return data;
}
const CSS_DISABLE_TRANS = "*,*::before,*::after{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;-ms-transition:none!important;transition:none!important}";
function useColorMode(options = {}) {
const {
selector = "html",
attribute = "class",
initialValue = "auto",
window = defaultWindow,
storage,
storageKey = "vueuse-color-scheme",
listenToStorageChanges = true,
storageRef,
emitAuto,
disableTransition = true
} = options;
const modes = {
auto: "",
light: "light",
dark: "dark",
...options.modes || {}
};
const preferredDark = usePreferredDark({ window });
const system = computed(() => preferredDark.value ? "dark" : "light");
const store = storageRef || (storageKey == null ? toRef(initialValue) : useStorage(storageKey, initialValue, storage, { window, listenToStorageChanges }));
const state = computed(() => store.value === "auto" ? system.value : store.value);
const updateHTMLAttrs = getSSRHandler(
"updateHTMLAttrs",
(selector2, attribute2, value) => {
const el = typeof selector2 === "string" ? window == null ? void 0 : window.document.querySelector(selector2) : unrefElement(selector2);
if (!el)
return;
const classesToAdd = /* @__PURE__ */ new Set();
const classesToRemove = /* @__PURE__ */ new Set();
let attributeToChange = null;
if (attribute2 === "class") {
const current = value.split(/\s/g);
Object.values(modes).flatMap((i) => (i || "").split(/\s/g)).filter(Boolean).forEach((v) => {
if (current.includes(v))
classesToAdd.add(v);
else
classesToRemove.add(v);
});
} else {
attributeToChange = { key: attribute2, value };
}
if (classesToAdd.size === 0 && classesToRemove.size === 0 && attributeToChange === null)
return;
let style;
if (disableTransition) {
style = window.document.createElement("style");
style.appendChild(document.createTextNode(CSS_DISABLE_TRANS));
window.document.head.appendChild(style);
}
for (const c of classesToAdd) {
el.classList.add(c);
}
for (const c of classesToRemove) {
el.classList.remove(c);
}
if (attributeToChange) {
el.setAttribute(attributeToChange.key, attributeToChange.value);
}
if (disableTransition) {
window.getComputedStyle(style).opacity;
document.head.removeChild(style);
}
}
);
function defaultOnChanged(mode) {
var _a;
updateHTMLAttrs(selector, attribute, (_a = modes[mode]) != null ? _a : mode);
}
function onChanged(mode) {
if (options.onChanged)
options.onChanged(mode, defaultOnChanged);
else
defaultOnChanged(mode);
}
watch(state, onChanged, { flush: "post", immediate: true });
tryOnMounted(() => onChanged(state.value));
const auto = computed({
get() {
return emitAuto ? store.value : state.value;
},
set(v) {
store.value = v;
}
});
return Object.assign(auto, { store, system, state });
}
const UseColorMode = /* @__PURE__ */ defineComponent({
name: "UseColorMode",
props: ["selector", "attribute", "modes", "onChanged", "storageKey", "storage", "emitAuto"],
setup(props, { slots }) {
const mode = useColorMode(props);
const data = reactive({
mode,
system: mode.system,
store: mode.store
});
return () => {
if (slots.default)
return slots.default(data);
};
}
});
const UseDark = /* @__PURE__ */ defineComponent({
name: "UseDark",
props: ["selector", "attribute", "valueDark", "valueLight", "onChanged", "storageKey", "storage"],
setup(props, { slots }) {
const isDark = useDark(props);
const data = reactive({
isDark,
toggleDark: useToggle(isDark)
});
return () => {
if (slots.default)
return slots.default(data);
};
}
});
const UseDeviceMotion = /* @__PURE__ */ defineComponent({
name: "UseDeviceMotion",
setup(props, { slots }) {
const data = useDeviceMotion();
return () => {
if (slots.default)
return slots.default(data);
};
}
});
const UseDeviceOrientation = /* @__PURE__ */ defineComponent({
name: "UseDeviceOrientation",
setup(props, { slots }) {
const data = reactive(useDeviceOrientation());
return () => {
if (slots.default)
return slots.default(data);
};
}
});
const UseDevicePixelRatio = /* @__PURE__ */ defineComponent({
name: "UseDevicePixelRatio",
setup(props, { slots }) {
const data = reactive({
pixelRatio: useDevicePixelRatio()
});
return () => {
if (slots.default)
return slots.default(data);
};
}
});
const UseDevicesList = /* @__PURE__ */ defineComponent({
name: "UseDevicesList",
props: ["onUpdated", "requestPermissions", "constraints"],
setup(props, { slots }) {
const data = reactive(useDevicesList(props));
return () => {
if (slots.default)
return slots.default(data);
};
}
});
const UseDocumentVisibility = /* @__PURE__ */ defineComponent({
name: "UseDocumentVisibility",
setup(props, { slots }) {
const data = reactive({
visibility: useDocumentVisibility()
});
return () => {
if (slots.default)
return slots.default(data);
};
}
});
const UseDraggable = /* @__PURE__ */ defineComponent({
name: "UseDraggable",
props: [
"storageKey",
"storageType",
"initialValue",
"exact",
"preventDefault",
"stopPropagation",
"pointerTypes",
"as",
"handle",
"axis",
"onStart",
"onMove",
"onEnd",
"disabled",
"buttons",
"containerElement",
"capture"
],
setup(props, { slots }) {
const target = shallowRef();
const handle = computed(() => {
var _a;
return (_a = toValue(props.handle)) != null ? _a : target.value;
});
const containerElement = computed(() => {
var _a;
return (_a = props.containerElement) != null ? _a : void 0;
});
const disabled = computed(() => !!props.disabled);
const storageValue = props.storageKey && useStorage$1(
props.storageKey,
toValue(props.initialValue) || { x: 0, y: 0 },
isClient$1 ? props.storageType === "session" ? sessionStorage : localStorage : void 0
);
const initialValue = storageValue || props.initialValue || { x: 0, y: 0 };
const onEnd = (position, event) => {
var _a;
(_a = props.onEnd) == null ? void 0 : _a.call(props, position, event);
if (!storageValue)
return;
storageValue.value.x = position.x;
storageValue.value.y = position.y;
};
const data = reactive(useDraggable(target, {
...props,
handle,
initialValue,
onEnd,
disabled,
containerElement
}));
return () => {
if (slots.default)
return h(props.as || "div", { ref: target, style: `touch-action:none;${data.style}` }, slots.default(data));
};
}
});
const UseElementBounding = /* @__PURE__ */ defineComponent({
name: "UseElementBounding",
props: ["box", "as"],
setup(props, { slots }) {
const target = shallowRef();
const data = reactive(useElementBounding$1(target));
return () => {
if (slots.default)
return h(props.as || "div", { ref: target }, slots.default(data));
};
}
});
function useMutationObserver(target, callback, options = {}) {
const { window = defaultWindow, ...mutationOptions } = options;
let observer;
const isSupported = useSupported(() => window && "MutationObserver" in window);
const cleanup = () => {
if (observer) {
observer.disconnect();
observer = void 0;
}
};
const targets = computed(() => {
const value = toValue(target);
const items = toArray(value).map(unrefElement).filter(notNullish);
return new Set(items);
});
const stopWatch = watch(
() => targets.value,
(targets2) => {
cleanup();
if (isSupported.value && targets2.size) {
observer = new MutationObserver(callback);
targets2.forEach((el) => observer.observe(el, mutationOptions));
}
},
{ immediate: true, flush: "post" }
);
const takeRecords = () => {
return observer == null ? void 0 : observer.takeRecords();
};
const stop = () => {
stopWatch();
cleanup();
};
tryOnScopeDispose(stop);
return {
isSupported,
stop,
takeRecords
};
}
function useResizeObserver(target, callback, options = {}) {
const { window = defaultWindow, ...observerOptions } = options;
let observer;
const isSupported = useSupported(() => window && "ResizeObserver" in window);
const cleanup = () => {
if (observer) {
observer.disconnect();
observer = void 0;
}
};
const targets = computed(() => {
const _targets = toValue(target);
return Array.isArray(_targets) ? _targets.map((el) => unrefElement(el)) : [unrefElement(_targets)];
});
const stopWatch = watch(
targets,
(els) => {
cleanup();
if (isSupported.value && window) {
observer = new ResizeObserver(callback);
for (const _el of els) {
if (_el)
observer.observe(_el, observerOptions);
}
}
},
{ immediate: true, flush: "post" }
);
const stop = () => {
cleanup();
stopWatch();
};
tryOnScopeDispose(stop);
return {
isSupported,
stop
};
}
function useElementBounding(target, options = {}) {
const {
reset = true,
windowResize = true,
windowScroll = true,
immediate = true,
updateTiming = "sync"
} = options;
const height = shallowRef(0);
const bottom = shallowRef(0);
const left = shallowRef(0);
const right = shallowRef(0);
const top = shallowRef(0);
const width = shallowRef(0);
const x = shallowRef(0);
const y = shallowRef(0);
function recalculate() {
const el = unrefElement(target);
if (!el) {
if (reset) {
height.value = 0;
bottom.value = 0;
left.value = 0;
right.value = 0;
top.value = 0;
width.value = 0;
x.value = 0;
y.value = 0;
}
return;
}
const rect = el.getBoundingClientRect();
height.value = rect.height;
bottom.value = rect.bottom;
left.value = rect.left;
right.value = rect.right;
top.value = rect.top;
width.value = rect.width;
x.value = rect.x;
y.value = rect.y;
}
function update() {
if (updateTiming === "sync")
recalculate();
else if (updateTiming === "next-frame")
requestAnimationFrame(() => recalculate());
}
useResizeObserver(target, update);
watch(() => unrefElement(target), (ele) => !ele && update());
useMutationObserver(target, update, {
attributeFilter: ["style", "class"]
});
if (windowScroll)
useEventListener("scroll", update, { capture: true, passive: true });
if (windowResize)
useEventListener("resize", update, { passive: true });
tryOnMounted(() => {
if (immediate)
update();
});
return {
height,
bottom,
left,
right,
top,
width,
x,
y,
update
};
}
const vElementBounding = {
mounted(el, binding) {
const [handler, options] = typeof binding.value === "function" ? [binding.value, {}] : binding.value;
const {
height,
bottom,
left,
right,
top,
width,
x,
y
} = useElementBounding(el, options);
watch([height, bottom, left, right, top, width, x, y], () => handler({ height, bottom, left, right, top, width, x, y }));
}
};
function onElementRemoval(target, callback, options = {}) {
const {
window = defaultWindow,
document = window == null ? void 0 : window.document,
flush = "sync"
} = options;
if (!window || !document)
return noop;
let stopFn;
const cleanupAndUpdate = (fn) => {
stopFn == null ? void 0 : stopFn();
stopFn = fn;
};
const stopWatch = watchEffect(() => {
const el = unrefElement(target);
if (el) {
const { stop } = useMutationObserver(
document,
(mutationsList) => {
const targetRemoved = mutationsList.map((mutation) => [...mutation.removedNodes]).flat().some((node) => node === el || node.contains(el));
if (targetRemoved) {
callback(mutationsList);
}
},
{
window,
childList: true,
subtree: true
}
);
cleanupAndUpdate(stop);
}
}, { flush });
const stopHandle = () => {
stopWatch();
cleanupAndUpdate();
};
tryOnScopeDispose(stopHandle);
return stopHandle;
}
function useElementHover(el, options = {}) {
const {
delayEnter = 0,
delayLeave = 0,
triggerOnRemoval = false,
window = defaultWindow
} = options;
const isHovered = shallowRef(false);
let timer;
const toggle = (entering) => {
const delay = entering ? delayEnter : delayLeave;
if (timer) {
clearTimeout(timer);
timer = void 0;
}
if (delay)
timer = setTimeout(() => isHovered.value = entering, delay);
else
isHovered.value = entering;
};
if (!window)
return isHovered;
useEventListener(el, "mouseenter", () => toggle(true), { passive: true });
useEventListener(el, "mouseleave", () => toggle(false), { passive: true });
if (triggerOnRemoval) {
onElementRemoval(
computed(() => unrefElement(el)),
() => toggle(false)
);
}
return isHovered;
}
const vElementHover = {
mounted(el, binding) {
const value = binding.value;
if (typeof value === "function") {
const isHovered = useElementHover(el);
watch(isHovered, (v) => value(v));
} else {
const [handler, options] = value;
const isHovered = useElementHover(el, options);
watch(isHovered, (v) => handler(v));
}
}
};
const UseElementSize = /* @__PURE__ */ defineComponent({
name: "UseElementSize",
props: ["width", "height", "box", "as"],
setup(props, { slots }) {
var _a, _b;
const target = shallowRef();
const data = reactive(useElementSize$1(target, { width: (_a = props.width) != null ? _a : 0, height: (_b = props.height) != null ? _b : 0 }, { box: props.box }));
return () => {
if (slots.default)
return h(props.as || "div", { ref: target }, slots.default(data));
};
}
});
function useElementSize(target, initialSize = { width: 0, height: 0 }, options = {}) {
const { window = defaultWindow, box = "content-box" } = options;
const isSVG = computed(() => {
var _a, _b;
return (_b = (_a = unrefElement(target)) == null ? void 0 : _a.namespaceURI) == null ? void 0 : _b.includes("svg");
});
const width = shallowRef(initialSize.width);
const height = shallowRef(initialSize.height);
const { stop: stop1 } = useResizeObserver(
target,
([entry]) => {
const boxSize = box === "border-box" ? entry.borderBoxSize : box === "content-box" ? entry.contentBoxSize : entry.devicePixelContentBoxSize;
if (window && isSVG.value) {
const $elem = unrefElement(target);
if ($elem) {
const rect = $elem.getBoundingClientRect();
width.value = rect.width;
height.value = rect.height;
}
} else {
if (boxSize) {
const formatBoxSize = toArray(boxSize);
width.value = formatBoxSize.reduce((acc, { inlineSize }) => acc + inlineSize, 0);
height.value = formatBoxSize.reduce((acc, { blockSize }) => acc + blockSize, 0);
} else {
width.value = entry.contentRect.width;
height.value = entry.contentRect.height;
}
}
},
options
);
tryOnMounted(() => {
const ele = unrefElement(target);
if (ele) {
width.value = "offsetWidth" in ele ? ele.offsetWidth : initialSize.width;
height.value = "offsetHeight" in ele ? ele.offsetHeight : initialSize.height;
}
});
const stop2 = watch(
() => unrefElement(target),
(ele) => {
width.value = ele ? initialSize.width : 0;
height.value = ele ? initialSize.height : 0;
}
);
function stop() {
stop1();
stop2();
}
return {
width,
height,
stop
};
}
const vElementSize = {
mounted(el, binding) {
var _a;
const handler = typeof binding.value === "function" ? binding.value : (_a = binding.value) == null ? void 0 : _a[0];
const options = typeof binding.value === "function" ? [] : binding.value.slice(1);
const { width, height } = useElementSize(el, ...options);
watch([width, height], ([width2, height2]) => handler({ width: width2, height: height2 }));
}
};
const UseElementVisibility = /* @__PURE__ */ defineComponent({
name: "UseElementVisibility",
props: ["as"],
setup(props, { slots }) {
const target = shallowRef();
const data = reactive({
isVisible: useElementVisibility$1(target)
});
return () => {
if (slots.default)
return h(props.as || "div", { ref: target }, slots.default(data));
};
}
});
function useIntersectionObserver(target, callback, options = {}) {
const {
root,
rootMargin = "0px",
threshold = 0,
window = defaultWindow,
immediate = true
} = options;
const isSupported = useSupported(() => window && "IntersectionObserver" in window);
const targets = computed(() => {
const _target = toValue(target);
return toArray(_target).map(unrefElement).filter(notNullish);
});
let cleanup = noop;
const isActive = shallowRef(immediate);
const stopWatch = isSupported.value ? watch(
() => [targets.value, unrefElement(root), isActive.value],
([targets2, root2]) => {
cleanup();
if (!isActive.value)
return;
if (!targets2.length)
return;
const observer = new IntersectionObserver(
callback,
{
root: unrefElement(root2),
rootMargin,
threshold
}
);
targets2.forEach((el) => el && observer.observe(el));
cleanup = () => {
observer.disconnect();
cleanup = noop;
};
},
{ immediate, flush: "post" }
) : noop;
const stop = () => {
cleanup();
stopWatch();
isActive.value = false;
};
tryOnScopeDispose(stop);
return {
isSupported,
isActive,
pause() {
cleanup();
isActive.value = false;
},
resume() {
isActive.value = true;
},
stop
};
}
function useElementVisibility(element, options = {}) {
const {
window = defaultWindow,
scrollTarget,
threshold = 0,
rootMargin,
once = false
} = options;
const elementIsVisible = shallowRef(false);
const { stop } = useIntersectionObserver(
element,
(intersectionObserverEntries) => {
let isIntersecting = elementIsVisible.value;
let latestTime = 0;
for (const entry of intersectionObserverEntries) {
if (entry.time >= latestTime) {
latestTime = entry.time;
isIntersecting = entry.isIntersecting;
}
}
elementIsVisible.value = isIntersecting;
if (once) {
watchOnce(elementIsVisible, () => {
stop();
});
}
},
{
root: scrollTarget,
window,
threshold,
rootMargin: toValue(rootMargin)
}
);
return elementIsVisible;
}
const vElementVisibility = {
mounted(el, binding) {
if (typeof binding.value === "function") {
const handler = binding.value;
const isVisible = useElementVisibility(el);
watch(isVisible, (v) => handler(v), { immediate: true });
} else {
const [handler, options] = binding.value;
const isVisible = useElementVisibility(el, options);
watch(isVisible, (v) => handler(v), { immediate: true });
}
}
};
const UseEyeDropper = /* @__PURE__ */ defineComponent({
name: "UseEyeDropper",
props: {
sRGBHex: String
},
setup(props, { slots }) {
const data = reactive(useEyeDropper());
return () => {
if (slots.default)
return slots.default(data);
};
}
});
const UseFullscreen = /* @__PURE__ */ defineComponent({
name: "UseFullscreen",
props: ["as"],
setup(props, { slots }) {
const target = shallowRef();
const data = reactive(useFullscreen(target));
return () => {
if (slots.default)
return h(props.as || "div", { ref: target }, slots.default(data));
};
}
});
const UseGeolocation = /* @__PURE__ */ defineComponent({
name: "UseGeolocation",
props: ["enableHighAccuracy", "maximumAge", "timeout", "navigator"],
setup(props, { slots }) {
const data = reactive(useGeolocation(props));
return () => {
if (slots.default)
return slots.default(data);
};
}
});
const UseIdle = /* @__PURE__ */ defineComponent({
name: "UseIdle",
props: ["timeout", "events", "listenForVisibilityChange", "initialState"],
setup(props, { slots }) {
const data = reactive(useIdle(props.timeout, props));
return () => {
if (slots.default)
return slots.default(data);
};
}
});
function useAsyncState(promise, initialState, options) {
const {
immediate = true,
delay = 0,
onError = noop,
onSuccess = noop,
resetOnExecute = true,
shallow = true,
throwError
} = options != null ? options : {};
const state = shallow ? shallowRef(initialState) : ref(initialState);
const isReady = shallowRef(false);
const isLoading = shallowRef(false);
const error = shallowRef(void 0);
async function execute(delay2 = 0, ...args) {
if (resetOnExecute)
state.value = initialState;
error.value = void 0;
isReady.value = false;
isLoading.value = true;
if (delay2 > 0)
await promiseTimeout(delay2);
const _promise = typeof promise === "function" ? promise(...args) : promise;
try {
const data = await _promise;
state.value = data;
isReady.value = true;
onSuccess(data);
} catch (e) {
error.value = e;
onError(e);
if (throwError)
throw e;
} finally {
isLoading.value = false;
}
return state.value;
}
if (immediate) {
execute(delay);
}
const shell = {
state,
isReady,
isLoading,
error,
execute,
executeImmediate: (...args) => execute(0, ...args)
};
function waitUntilIsLoaded() {
return new Promise((resolve, reject) => {
until(isLoading).toBe(false).then(() => resolve(shell)).catch(reject);
});
}
return {
...shell,
then(onFulfilled, onRejected) {
return waitUntilIsLoaded().then(onFulfilled, onRejected);
}
};
}
async function loadImage(options) {
return new Promise((resolve, reject) => {
const img = new Image();
const { src, srcset, sizes, class: clazz, loading, crossorigin, referrerPolicy, width, height, decoding, fetchPriority, ismap, usemap } = options;
img.src = src;
if (srcset != null)
img.srcset = srcset;
if (sizes != null)
img.sizes = sizes;
if (clazz != null)
img.className = clazz;
if (loading != null)
img.loading = loading;
if (crossorigin != null)
img.crossOrigin = crossorigin;
if (referrerPolicy != null)
img.referrerPolicy = referrerPolicy;
if (width != null)
img.width = width;
if (height != null)
img.height = height;
if (decoding != null)
img.decoding = decoding;
if (fetchPriority != null)
img.fetchPriority = fetchPriority;
if (ismap != null)
img.isMap = ismap;
if (usemap != null)
img.useMap = usemap;
img.onload = () => resolve(img);
img.onerror = reject;
});
}
function useImage(options, asyncStateOptions = {}) {
const state = useAsyncState(
() => loadImage(toValue(options)),
void 0,
{
resetOnExecute: true,
...asyncStateOptions
}
);
watch(
() => toValue(options),
() => state.execute(asyncStateOptions.delay),
{ deep: true }
);
return state;
}
const UseImage = /* @__PURE__ */ defineComponent({
name: "UseImage",
props: [
"src",
"srcset",
"sizes",
"as",
"alt",
"class",
"loading",
"crossorigin",
"referrerPolicy",
"width",
"height",
"decoding",
"fetchPriority",
"ismap",
"usemap"
],
setup(props, { slots }) {
const data = reactive(useImage(props));
return () => {
if (data.isLoading && slots.loading)
return slots.loading(data);
else if (data.error && slots.error)
return slots.error(data.error);
if (slots.default)
return slots.default(data);
return h(props.as || "img", props);
};
}
});
function resolveElement(el) {
if (typeof Window !== "undefined" && el instanceof Window)
return el.document.documentElement;
if (typeof Document !== "undefined" && el instanceof Document)
return el.documentElement;
return el;
}
const ARRIVED_STATE_THRESHOLD_PIXELS = 1;
function useScroll(element, options = {}) {
const {
throttle = 0,
idle = 200,
onStop = noop,
onScroll = noop,
offset = {
left: 0,
right: 0,
top: 0,
bottom: 0
},
observe: _observe = {
mutation: false
},
eventListenerOptions = {
capture: false,
passive: true
},
behavior = "auto",
window = defaultWindow,
onError = (e) => {
console.error(e);
}
} = options;
const observe = typeof _observe === "boolean" ? {
mutation: _observe
} : _observe;
const internalX = shallowRef(0);
const internalY = shallowRef(0);
const x = computed({
get() {
return internalX.value;
},
set(x2) {
scrollTo(x2, void 0);
}
});
const y = computed({
get() {
return internalY.value;
},
set(y2) {
scrollTo(void 0, y2);
}
});
function scrollTo(_x, _y) {
var _a, _b, _c, _d;
if (!window)
return;
const _element = toValue(element);
if (!_element)
return;
(_c = _element instanceof Document ? window.document.body : _element) == null ? void 0 : _c.scrollTo({
top: (_a = toValue(_y)) != null ? _a : y.value,
left: (_b = toValue(_x)) != null ? _b : x.value,
behavior: toValue(behavior)
});
const scrollContainer = ((_d = _element == null ? void 0 : _element.document) == null ? void 0 : _d.documentElement) || (_element == null ? void 0 : _element.documentElement) || _element;
if (x != null)
internalX.value = scrollContainer.scrollLeft;
if (y != null)
internalY.value = scrollContainer.scrollTop;
}
const isScrolling = shallowRef(false);
const arrivedState = reactive({
left: true,
right: false,
top: true,
bottom: false
});
const directions = reactive({
left: false,
right: false,
top: false,
bottom: false
});
const onScrollEnd = (e) => {
if (!isScrolling.value)
return;
isScrolling.value = false;
directions.left = false;
directions.right = false;
directions.top = false;
directions.bottom = false;
onStop(e);
};
const onScrollEndDebounced = useDebounceFn(onScrollEnd, throttle + idle);
const setArrivedState = (target) => {
var _a;
if (!window)
return;
const el = ((_a = target == null ? void 0 : target.document) == null ? void 0 : _a.documentElement) || (target == null ? void 0 : target.documentElement) || unrefElement(target);
const { display, flexDirection, direction } = getComputedStyle(el);
const directionMultipler = direction === "rtl" ? -1 : 1;
const scrollLeft = el.scrollLeft;
directions.left = scrollLeft < internalX.value;