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,145 lines (1,144 loc) 34.5 kB
import { m as makeDestructurable, n as noop, t as toValue, i as isObject, a as tryOnScopeDispose, b as isIOS, c as isClient, d as notNullish, e as increaseWithUnit, f as toRef, g as tryOnMounted, h as timestamp, j as useIntervalFn, k as camelize, w as watchPausable } from "./index-DlGgXMQF.mjs"; import { shallowRef, watch, computed, ref, reactive, watchEffect, defineComponent, readonly, nextTick, getCurrentInstance, onMounted } 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, setup(_, { 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, { ...keysToCamelKebabCase(attrs), $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; } function unrefElement(elRef) { var _a; const plain = toValue(elRef); return (_a = plain == null ? void 0 : plain.$el) != null ? _a : plain; } const defaultWindow = isClient ? window : void 0; function useEventListener(...args) { let target; let events; let listeners; let options; if (typeof args[0] === "string" || Array.isArray(args[0])) { [events, listeners, options] = args; target = defaultWindow; } else { [target, events, listeners, options] = args; } if (!target) return noop; if (!Array.isArray(events)) events = [events]; if (!Array.isArray(listeners)) listeners = [listeners]; const cleanups = []; const cleanup = () => { cleanups.forEach((fn) => fn()); cleanups.length = 0; }; const register = (el, event, listener, options2) => { el.addEventListener(event, listener, options2); return () => el.removeEventListener(event, listener, options2); }; const stopWatch = watch( () => [unrefElement(target), toValue(options)], ([el, options2]) => { cleanup(); if (!el) return; const optionsClone = isObject(options2) ? { ...options2 } : options2; cleanups.push( ...events.flatMap((event) => { return listeners.map((listener) => register(el, event, listener, optionsClone)); }) ); }, { immediate: true, flush: "post" } ); const stop = () => { stopWatch(); cleanup(); }; tryOnScopeDispose(stop); return stop; } let _iOSWorkaround = false; function onClickOutside(target, handler, options = {}) { const { window: window2 = defaultWindow, ignore = [], capture = true, detectIframe = false } = options; if (!window2) return noop; if (isIOS && !_iOSWorkaround) { _iOSWorkaround = true; Array.from(window2.document.body.children).forEach((el) => el.addEventListener("click", noop)); window2.document.documentElement.addEventListener("click", noop); } let shouldListen = true; const shouldIgnore = (event) => { return 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)); } }); }; const listener = (event) => { const el = unrefElement(target); if (!el || el === event.target || event.composedPath().includes(el)) return; if (event.detail === 0) shouldListen = !shouldIgnore(event); if (!shouldListen) { shouldListen = true; return; } handler(event); }; const cleanup = [ useEventListener(window2, "click", listener, { 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); }) ].filter(Boolean); const stop = () => cleanup.forEach((fn) => fn()); return stop; } 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 useMounted() { const isMounted = ref(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 = (Array.isArray(value) ? value : [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 useRafFn(fn, options = {}) { const { immediate = true, fpsLimit = void 0, window: window2 = defaultWindow } = options; const isActive = ref(false); const intervalLimit = fpsLimit ? 1e3 / 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 && delta < intervalLimit) { rafId = window2.requestAnimationFrame(loop); return; } previousFrameTimestamp = timestamp2; fn({ delta, timestamp: timestamp2 }); 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 }; } function useMediaQuery(query, options = {}) { const { window: window2 = defaultWindow } = options; const isSupported = useSupported(() => window2 && "matchMedia" in window2 && typeof window2.matchMedia === "function"); let mediaQuery; const matches = ref(false); const handler = (event) => { matches.value = event.matches; }; const cleanup = () => { if (!mediaQuery) return; if ("removeEventListener" in mediaQuery) mediaQuery.removeEventListener("change", handler); else mediaQuery.removeListener(handler); }; const stopWatch = watchEffect(() => { if (!isSupported.value) return; cleanup(); mediaQuery = window2.matchMedia(toValue(query)); if ("addEventListener" in mediaQuery) mediaQuery.addEventListener("change", handler); else mediaQuery.addListener(handler); matches.value = mediaQuery.matches; }); tryOnScopeDispose(() => { stopWatch(); cleanup(); mediaQuery = void 0; }); return matches; } 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" } = options; function match(query) { if (!window2) return false; return window2.matchMedia(query).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((i) => [i, greaterOrEqual(i)]); 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-width: ${getValue(k, 0.1)})`); }, isGreaterOrEqual(k) { return match(`(min-width: ${getValue(k)})`); }, isSmaller(k) { return match(`(max-width: ${getValue(k, -0.1)})`); }, isSmallerOrEqual(k) { return match(`(max-width: ${getValue(k)})`); }, isInBetween(a, b) { return match(`(min-width: ${getValue(a)}) and (max-width: ${getValue(b, -0.1)})`); }, current, active() { const bps = current(); return computed(() => bps.value.length === 0 ? "" : bps.value.at(-1)); } }); } 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 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); 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 } ); if (window2 && listenToStorageChanges) { tryOnMounted(() => { if (storage instanceof Storage) useEventListener(window2, "storage", update); else useEventListener(window2, customStorageEventName, updateFromCustomEvent); if (initOnMounted) update(); }); } if (!initOnMounted) update(); function dispatchWriteEvent(oldValue, newValue) { if (window2) { const payload = { key, 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(key); if (v == null) { dispatchWriteEvent(oldValue, null); storage.removeItem(key); } else { const serialized = serializer.write(v); if (oldValue !== serialized) { storage.setItem(key, serialized); dispatchWriteEvent(oldValue, serialized); } } } catch (e) { onError(e); } } function read(event) { const rawValue = event ? event.newValue : storage.getItem(key); if (rawValue == null) { if (writeDefaults && rawInit != null) storage.setItem(key, 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 !== key) 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; } function usePreferredDark(options) { return useMediaQuery("(prefers-color-scheme: dark)", options); } 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; } }); try { return Object.assign(auto, { store, system, state }); } catch (e) { return auto; } } function useElementHover(el, options = {}) { const { delayEnter = 0, delayLeave = 0, window: window2 = defaultWindow } = options; const isHovered = ref(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 }); 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 (Array.isArray(_target) ? _target : [_target]).map(unrefElement).filter(notNullish); }); let cleanup = noop; const isActive = ref(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 = ref(false); const targetElement = computed(() => unrefElement(target)); 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; }); useEventListener(targetElement, "blur", () => innerFocused.value = false); 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 Touch ? null : [event.movementX, event.movementY] }; 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; const x = ref(initialValue.x); const y = ref(initialValue.y); const sourceType = ref(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"; } }; 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; y.value = pos[1] + window2.scrollY; } }; 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, { passive: true }); } return { x, y, sourceType }; } function useMouseInElement(target, options = {}) { const { handleOutside = true, window: window2 = defaultWindow } = options; const type = options.type || "page"; const { x, y, sourceType } = useMouse(options); const targetRef = ref(target != null ? target : window2 == null ? void 0 : window2.document.body); const elementX = ref(0); const elementY = ref(0); const elementPositionX = ref(0); const elementPositionY = ref(0); const elementHeight = ref(0); const elementWidth = ref(0); const isOutside = ref(true); let stop = () => { }; if (window2) { stop = watch( [targetRef, x, y], () => { const el = unrefElement(targetRef); if (!el || !(el instanceof HTMLElement)) return; const { left, top, width, height } = el.getBoundingClientRect(); elementPositionX.value = left + (type === "page" ? window2.pageXOffset : 0); elementPositionY.value = top + (type === "page" ? window2.pageYOffset : 0); elementHeight.value = height; elementWidth.value = width; const elX = x.value - elementPositionX.value; const elY = y.value - elementPositionY.value; isOutside.value = width === 0 || height === 0 || elX < 0 || elY < 0 || elX > width || elY > height; if (handleOutside || !isOutside.value) { elementX.value = elX; elementY.value = elY; } }, { immediate: true } ); useEventListener(document, "mouseleave", () => { isOutside.value = true; }); } return { x, y, sourceType, elementX, elementY, elementPositionX, elementPositionY, elementHeight, elementWidth, isOutside, stop }; } 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 = ref(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, window: window2 = defaultWindow } = 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 = ref(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; }; let listenerOptions; const isPassiveEventSupported = checkPassiveEventSupport(window2 == null ? void 0 : window2.document); if (!passive) listenerOptions = isPassiveEventSupported ? { passive: false, capture: true } : { capture: true }; else listenerOptions = isPassiveEventSupported ? { passive: true } : { capture: false }; 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; if (listenerOptions.capture && !listenerOptions.passive) e.preventDefault(); 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 (!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 { isPassiveEventSupported, isSwiping, direction, coordsStart, coordsEnd, lengthX: diffX, lengthY: diffY, stop }; } function checkPassiveEventSupport(document2) { if (!document2) return false; let supportsPassive = false; const optionsBlock = { get passive() { supportsPassive = true; return false; } }; document2.addEventListener("x", noop, optionsBlock); document2.removeEventListener("x", noop); return supportsPassive; } function useTimestamp(options = {}) { const { controls: exposeControls = false, offset = 0, immediate = true, interval = "requestAnimationFrame", callback } = options; const ts = ref(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 { useIntersectionObserver as a, useMutationObserver as b, useEventListener as c, onClickOutside as d, useFocus as e, useBreakpoints as f, breakpointsBootstrapV5 as g, getSSRHandler as h, unrefElement as i, createReusableTemplate as j, useTimestamp as k, useElementHover as l, useSwipe as m, useScrollLock as n, onKeyStroke as o, useMouseInElement as p, useColorMode as u }; //# sourceMappingURL=index-DngH9Pjm.mjs.map