UNPKG

bootstrap-vue-next

Version:

BootstrapVueNext is an early and lovely component library for Vue 3 & Nuxt 3 based on Bootstrap 5 and Typescript.

1,181 lines (1,180 loc) 37.1 kB
import { m as makeDestructurable, n as noop, i as isIOS, t as tryOnMounted, a as toRef, b as toArray, c as notNullish, d as tryOnScopeDispose, w as watchImmediate, e as timestamp, f as useIntervalFn, g as isClient, h as camelize, j as injectLocal, p as pxValue, k as increaseWithUnit, l as watchPausable, o as isObject } from "./index-CaguhSuF.mjs"; import { shallowRef, defineComponent, computed, reactive, watch, toValue, watchEffect, hasInjectionContext, ref, nextTick, readonly, getCurrentInstance, onMounted, unref } from "vue"; function createReusableTemplate(options = {}) { const { inheritAttrs = true } = options; const render = shallowRef(); const define = /* @__PURE__ */ defineComponent({ setup(_, { slots }) { return () => { render.value = slots.default; }; } }); const reuse = /* @__PURE__ */ defineComponent({ inheritAttrs, props: options.props, setup(props, { attrs, slots }) { return () => { var _a; if (!render.value && process.env.NODE_ENV !== "production") throw new Error("[VueUse] Failed to find the definition of reusable template"); const vnode = (_a = render.value) == null ? void 0 : _a.call(render, { ...options.props == null ? keysToCamelKebabCase(attrs) : props, $slots: slots }); return inheritAttrs && (vnode == null ? void 0 : vnode.length) === 1 ? vnode[0] : vnode; }; } }); return makeDestructurable( { define, reuse }, [define, reuse] ); } function keysToCamelKebabCase(obj) { const newObj = {}; for (const key in obj) newObj[camelize(key)] = obj[key]; return newObj; } 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: window2 = defaultWindow, ignore = [], capture = true, detectIframe = false, controls = false } = options; if (!window2) { return controls ? { stop: noop, cancel: noop, trigger: noop } : noop; } if (isIOS && !_iOSWorkaround) { _iOSWorkaround = true; const listenerOptions = { passive: true }; Array.from(window2.document.body.children).forEach((el) => useEventListener(el, "click", noop, listenerOptions)); useEventListener(window2.document.documentElement, "click", noop, listenerOptions); } let shouldListen = true; const shouldIgnore = (event) => { return toValue(ignore).some((target2) => { if (typeof target2 === "string") { return Array.from(window2.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(window2, "click", (event) => { if (!isProcessingClick) { isProcessingClick = true; setTimeout(() => { isProcessingClick = false; }, 0); listener(event); } }, { passive: true, capture }), useEventListener(window2, "pointerdown", (e) => { const el = unrefElement(target); shouldListen = !shouldIgnore(e) && !!(el && !e.composedPath().includes(el)); }, { passive: true }), detectIframe && useEventListener(window2, "blur", (event) => { setTimeout(() => { var _a; const el = unrefElement(target); if (((_a = window2.document.activeElement) == null ? void 0 : _a.tagName) === "IFRAME" && !(el == null ? void 0 : el.contains(window2.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; } function useMounted() { const isMounted = shallowRef(false); const instance = getCurrentInstance(); if (instance) { onMounted(() => { isMounted.value = true; }, instance); } return isMounted; } function useSupported(callback) { const isMounted = useMounted(); return computed(() => { isMounted.value; return Boolean(callback()); }); } function useMutationObserver(target, callback, options = {}) { const { window: window2 = defaultWindow, ...mutationOptions } = options; let observer; const isSupported = useSupported(() => window2 && "MutationObserver" in window2); 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 onElementRemoval(target, callback, options = {}) { const { window: window2 = defaultWindow, document: document2 = window2 == null ? void 0 : window2.document, flush = "sync" } = options; if (!window2 || !document2) 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( document2, (mutationsList) => { const targetRemoved = mutationsList.map((mutation) => [...mutation.removedNodes]).flat().some((node) => node === el || node.contains(el)); if (targetRemoved) { callback(mutationsList); } }, { window: window2, childList: true, subtree: true } ); cleanupAndUpdate(stop); } }, { flush }); const stopHandle = () => { stopWatch(); cleanupAndUpdate(); }; tryOnScopeDispose(stopHandle); return stopHandle; } 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); } function useRafFn(fn, options = {}) { const { immediate = true, fpsLimit = void 0, window: window2 = defaultWindow, once = false } = options; const isActive = shallowRef(false); const intervalLimit = computed(() => { return fpsLimit ? 1e3 / toValue(fpsLimit) : null; }); let previousFrameTimestamp = 0; let rafId = null; function loop(timestamp2) { if (!isActive.value || !window2) return; if (!previousFrameTimestamp) previousFrameTimestamp = timestamp2; const delta = timestamp2 - previousFrameTimestamp; if (intervalLimit.value && delta < intervalLimit.value) { rafId = window2.requestAnimationFrame(loop); return; } previousFrameTimestamp = timestamp2; fn({ delta, timestamp: timestamp2 }); if (once) { isActive.value = false; rafId = null; return; } rafId = window2.requestAnimationFrame(loop); } function resume() { if (!isActive.value && window2) { isActive.value = true; previousFrameTimestamp = 0; rafId = window2.requestAnimationFrame(loop); } } function pause() { isActive.value = false; if (rafId != null && window2) { window2.cancelAnimationFrame(rafId); rafId = null; } } if (immediate) resume(); tryOnScopeDispose(pause); return { isActive: readonly(isActive), pause, resume }; } const ssrWidthSymbol = Symbol("vueuse-ssr-width"); function useSSRWidth() { const ssrWidth = hasInjectionContext() ? injectLocal(ssrWidthSymbol, null) : null; return typeof ssrWidth === "number" ? ssrWidth : void 0; } function useMediaQuery(query, options = {}) { const { window: window2 = defaultWindow, ssrWidth = useSSRWidth() } = options; const isSupported = useSupported(() => window2 && "matchMedia" in window2 && typeof window2.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 = window2.matchMedia(toValue(query)); matches.value = mediaQuery.value.matches; }); useEventListener(mediaQuery, "change", handler, { passive: true }); return computed(() => matches.value); } const breakpointsBootstrapV5 = { xs: 0, sm: 576, md: 768, lg: 992, xl: 1200, xxl: 1400 }; function useBreakpoints(breakpoints, options = {}) { function getValue(k, delta) { let v = toValue(breakpoints[toValue(k)]); if (delta != null) v = increaseWithUnit(v, delta); if (typeof v === "number") v = `${v}px`; return v; } const { window: window2 = defaultWindow, strategy = "min-width", ssrWidth = useSSRWidth() } = options; const ssrSupport = typeof ssrWidth === "number"; const mounted = ssrSupport ? shallowRef(false) : { value: true }; if (ssrSupport) { tryOnMounted(() => mounted.value = !!window2); } function match(query, size) { if (!mounted.value && ssrSupport) { return query === "min" ? ssrWidth >= pxValue(size) : ssrWidth <= pxValue(size); } if (!window2) return false; return window2.matchMedia(`(${query}-width: ${size})`).matches; } const greaterOrEqual = (k) => { return useMediaQuery(() => `(min-width: ${getValue(k)})`, options); }; const smallerOrEqual = (k) => { return useMediaQuery(() => `(max-width: ${getValue(k)})`, options); }; const shortcutMethods = Object.keys(breakpoints).reduce((shortcuts, k) => { Object.defineProperty(shortcuts, k, { get: () => strategy === "min-width" ? greaterOrEqual(k) : smallerOrEqual(k), enumerable: true, configurable: true }); return shortcuts; }, {}); function current() { const points = Object.keys(breakpoints).map((k) => [k, shortcutMethods[k], pxValue(getValue(k))]).sort((a, b) => a[2] - b[2]); return computed(() => points.filter(([, v]) => v.value).map(([k]) => k)); } return Object.assign(shortcutMethods, { greaterOrEqual, smallerOrEqual, greater(k) { return useMediaQuery(() => `(min-width: ${getValue(k, 0.1)})`, options); }, smaller(k) { return useMediaQuery(() => `(max-width: ${getValue(k, -0.1)})`, options); }, between(a, b) { return useMediaQuery(() => `(min-width: ${getValue(a)}) and (max-width: ${getValue(b, -0.1)})`, options); }, isGreater(k) { return match("min", getValue(k, 0.1)); }, isGreaterOrEqual(k) { return match("min", getValue(k)); }, isSmaller(k) { return match("max", getValue(k, -0.1)); }, isSmallerOrEqual(k) { return match("max", getValue(k)); }, isInBetween(a, b) { return match("min", getValue(a)) && match("max", getValue(b, -0.1)); }, current, active() { const bps = current(); return computed(() => bps.value.length === 0 ? "" : bps.value.at(strategy === "min-width" ? -1 : 0)); } }); } 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; } 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: window2 = 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 } = watchPausable( data, () => write(data.value), { flush, deep, eventFilter } ); watch(keyComputed, () => update(), { flush }); if (window2 && listenToStorageChanges) { tryOnMounted(() => { if (storage instanceof Storage) useEventListener(window2, "storage", update, { passive: true }); else useEventListener(window2, customStorageEventName, updateFromCustomEvent); if (initOnMounted) update(); }); } if (!initOnMounted) update(); function dispatchWriteEvent(oldValue, newValue) { if (window2) { const payload = { key: keyComputed.value, oldValue, newValue, storageArea: storage }; window2.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: window2 = 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: window2 }); const system = computed(() => preferredDark.value ? "dark" : "light"); const store = storageRef || (storageKey == null ? toRef(initialValue) : useStorage(storageKey, initialValue, storage, { window: window2, listenToStorageChanges })); const state = computed(() => store.value === "auto" ? system.value : store.value); const updateHTMLAttrs = getSSRHandler( "updateHTMLAttrs", (selector2, attribute2, value) => { const el = typeof selector2 === "string" ? window2 == null ? void 0 : window2.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 = window2.document.createElement("style"); style.appendChild(document.createTextNode(CSS_DISABLE_TRANS)); window2.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) { window2.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 }); } function useElementHover(el, options = {}) { const { delayEnter = 0, delayLeave = 0, triggerOnRemoval = false, window: window2 = 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 (!window2) 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; } function useIntersectionObserver(target, callback, options = {}) { const { root, rootMargin = "0px", threshold = 0, window: window2 = defaultWindow, immediate = true } = options; const isSupported = useSupported(() => window2 && "IntersectionObserver" in window2); 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 useFocus(target, options = {}) { const { initialValue = false, focusVisible = false, preventScroll = false } = options; const innerFocused = shallowRef(false); const targetElement = computed(() => unrefElement(target)); const listenerOptions = { passive: true }; useEventListener(targetElement, "focus", (event) => { var _a, _b; if (!focusVisible || ((_b = (_a = event.target).matches) == null ? void 0 : _b.call(_a, ":focus-visible"))) innerFocused.value = true; }, listenerOptions); useEventListener(targetElement, "blur", () => innerFocused.value = false, listenerOptions); const focused = computed({ get: () => innerFocused.value, set(value) { var _a, _b; if (!value && innerFocused.value) (_a = targetElement.value) == null ? void 0 : _a.blur(); else if (value && !innerFocused.value) (_b = targetElement.value) == null ? void 0 : _b.focus({ preventScroll }); } }); watch( targetElement, () => { focused.value = initialValue; }, { immediate: true, flush: "post" } ); return { focused }; } 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 UseMouseBuiltinExtractors = { page: (event) => [event.pageX, event.pageY], client: (event) => [event.clientX, event.clientY], screen: (event) => [event.screenX, event.screenY], movement: (event) => event instanceof MouseEvent ? [event.movementX, event.movementY] : null }; function useMouse(options = {}) { const { type = "page", touch = true, resetOnTouchEnds = false, initialValue = { x: 0, y: 0 }, window: window2 = defaultWindow, target = window2, scroll = true, eventFilter } = options; let _prevMouseEvent = null; let _prevScrollX = 0; let _prevScrollY = 0; const x = shallowRef(initialValue.x); const y = shallowRef(initialValue.y); const sourceType = shallowRef(null); const extractor = typeof type === "function" ? type : UseMouseBuiltinExtractors[type]; const mouseHandler = (event) => { const result = extractor(event); _prevMouseEvent = event; if (result) { [x.value, y.value] = result; sourceType.value = "mouse"; } if (window2) { _prevScrollX = window2.scrollX; _prevScrollY = window2.scrollY; } }; const touchHandler = (event) => { if (event.touches.length > 0) { const result = extractor(event.touches[0]); if (result) { [x.value, y.value] = result; sourceType.value = "touch"; } } }; const scrollHandler = () => { if (!_prevMouseEvent || !window2) return; const pos = extractor(_prevMouseEvent); if (_prevMouseEvent instanceof MouseEvent && pos) { x.value = pos[0] + window2.scrollX - _prevScrollX; y.value = pos[1] + window2.scrollY - _prevScrollY; } }; const reset = () => { x.value = initialValue.x; y.value = initialValue.y; }; const mouseHandlerWrapper = eventFilter ? (event) => eventFilter(() => mouseHandler(event), {}) : (event) => mouseHandler(event); const touchHandlerWrapper = eventFilter ? (event) => eventFilter(() => touchHandler(event), {}) : (event) => touchHandler(event); const scrollHandlerWrapper = eventFilter ? () => eventFilter(() => scrollHandler(), {}) : () => scrollHandler(); if (target) { const listenerOptions = { passive: true }; useEventListener(target, ["mousemove", "dragover"], mouseHandlerWrapper, listenerOptions); if (touch && type !== "movement") { useEventListener(target, ["touchstart", "touchmove"], touchHandlerWrapper, listenerOptions); if (resetOnTouchEnds) useEventListener(target, "touchend", reset, listenerOptions); } if (scroll && type === "page") useEventListener(window2, "scroll", scrollHandlerWrapper, listenerOptions); } return { x, y, sourceType }; } function checkOverflowScroll(ele) { const style = window.getComputedStyle(ele); if (style.overflowX === "scroll" || style.overflowY === "scroll" || style.overflowX === "auto" && ele.clientWidth < ele.scrollWidth || style.overflowY === "auto" && ele.clientHeight < ele.scrollHeight) { return true; } else { const parent = ele.parentNode; if (!parent || parent.tagName === "BODY") return false; return checkOverflowScroll(parent); } } function preventDefault(rawEvent) { const e = rawEvent || window.event; const _target = e.target; if (checkOverflowScroll(_target)) return false; if (e.touches.length > 1) return true; if (e.preventDefault) e.preventDefault(); return false; } const elInitialOverflow = /* @__PURE__ */ new WeakMap(); function useScrollLock(element, initialState = false) { const isLocked = shallowRef(initialState); let stopTouchMoveListener = null; let initialOverflow = ""; watch(toRef(element), (el) => { const target = resolveElement(toValue(el)); if (target) { const ele = target; if (!elInitialOverflow.get(ele)) elInitialOverflow.set(ele, ele.style.overflow); if (ele.style.overflow !== "hidden") initialOverflow = ele.style.overflow; if (ele.style.overflow === "hidden") return isLocked.value = true; if (isLocked.value) return ele.style.overflow = "hidden"; } }, { immediate: true }); const lock = () => { const el = resolveElement(toValue(element)); if (!el || isLocked.value) return; if (isIOS) { stopTouchMoveListener = useEventListener( el, "touchmove", (e) => { preventDefault(e); }, { passive: false } ); } el.style.overflow = "hidden"; isLocked.value = true; }; const unlock = () => { const el = resolveElement(toValue(element)); if (!el || !isLocked.value) return; if (isIOS) stopTouchMoveListener == null ? void 0 : stopTouchMoveListener(); el.style.overflow = initialOverflow; elInitialOverflow.delete(el); isLocked.value = false; }; tryOnScopeDispose(unlock); return computed({ get() { return isLocked.value; }, set(v) { if (v) lock(); else unlock(); } }); } function useSwipe(target, options = {}) { const { threshold = 50, onSwipe, onSwipeEnd, onSwipeStart, passive = true } = options; const coordsStart = reactive({ x: 0, y: 0 }); const coordsEnd = reactive({ x: 0, y: 0 }); const diffX = computed(() => coordsStart.x - coordsEnd.x); const diffY = computed(() => coordsStart.y - coordsEnd.y); const { max, abs } = Math; const isThresholdExceeded = computed(() => max(abs(diffX.value), abs(diffY.value)) >= threshold); const isSwiping = shallowRef(false); const direction = computed(() => { if (!isThresholdExceeded.value) return "none"; if (abs(diffX.value) > abs(diffY.value)) { return diffX.value > 0 ? "left" : "right"; } else { return diffY.value > 0 ? "up" : "down"; } }); const getTouchEventCoords = (e) => [e.touches[0].clientX, e.touches[0].clientY]; const updateCoordsStart = (x, y) => { coordsStart.x = x; coordsStart.y = y; }; const updateCoordsEnd = (x, y) => { coordsEnd.x = x; coordsEnd.y = y; }; const listenerOptions = { passive, capture: !passive }; const onTouchEnd = (e) => { if (isSwiping.value) onSwipeEnd == null ? void 0 : onSwipeEnd(e, direction.value); isSwiping.value = false; }; const stops = [ useEventListener(target, "touchstart", (e) => { if (e.touches.length !== 1) return; const [x, y] = getTouchEventCoords(e); updateCoordsStart(x, y); updateCoordsEnd(x, y); onSwipeStart == null ? void 0 : onSwipeStart(e); }, listenerOptions), useEventListener(target, "touchmove", (e) => { if (e.touches.length !== 1) return; const [x, y] = getTouchEventCoords(e); updateCoordsEnd(x, y); if (listenerOptions.capture && !listenerOptions.passive && Math.abs(diffX.value) > Math.abs(diffY.value)) e.preventDefault(); if (!isSwiping.value && isThresholdExceeded.value) isSwiping.value = true; if (isSwiping.value) onSwipe == null ? void 0 : onSwipe(e); }, listenerOptions), useEventListener(target, ["touchend", "touchcancel"], onTouchEnd, listenerOptions) ]; const stop = () => stops.forEach((s) => s()); return { isSwiping, direction, coordsStart, coordsEnd, lengthX: diffX, lengthY: diffY, stop, // TODO: Remove in the next major version isPassiveEventSupported: true }; } function useTimestamp(options = {}) { const { controls: exposeControls = false, offset = 0, immediate = true, interval = "requestAnimationFrame", callback } = options; const ts = shallowRef(timestamp() + offset); const update = () => ts.value = timestamp() + offset; const cb = callback ? () => { update(); callback(ts.value); } : update; const controls = interval === "requestAnimationFrame" ? useRafFn(cb, { immediate }) : useIntervalFn(cb, interval, { immediate }); if (exposeControls) { return { timestamp: ts, ...controls }; } else { return ts; } } export { onClickOutside as a, useColorMode as b, useIntersectionObserver as c, useMutationObserver as d, useEventListener as e, unrefElement as f, getSSRHandler as g, createReusableTemplate as h, useTimestamp as i, useElementHover as j, useSwipe as k, useBreakpoints as l, breakpointsBootstrapV5 as m, useScrollLock as n, onKeyStroke as o, useMouse as p, useFocus as u }; //# sourceMappingURL=index-CMqRvrZx.mjs.map