UNPKG

@shopware-ag/meteor-component-library

Version:

The meteor component library is a Vue component library developed by Shopware. It is based on the [Meteor Design System](https://shopware.design/).

360 lines (359 loc) 11.4 kB
import { n as noop, i as isIOS, t as tryOnMounted, b as useTimeoutFn, c as isClient, d as toArray, w as watchImmediate, e as tryOnScopeDispose, f as isObject, g as createSingletonPromise } from "./index-221bad05.mjs"; import { isRef, shallowRef, ref, watchEffect, computed, getCurrentInstance, customRef, onUpdated, toValue, unref, onMounted, toRaw } from "vue"; function computedAsync(evaluationCallback, initialState, optionsOrRef) { let options; if (isRef(optionsOrRef)) { options = { evaluating: optionsOrRef }; } else { options = optionsOrRef || {}; } const { lazy = false, evaluating = void 0, shallow = true, onError = noop } = options; const started = shallowRef(!lazy); const current = shallow ? shallowRef(initialState) : ref(initialState); let counter = 0; watchEffect(async (onInvalidate) => { if (!started.value) return; counter++; const counterAtBeginning = counter; let hasFinished = false; if (evaluating) { Promise.resolve().then(() => { evaluating.value = true; }); } try { const result = await evaluationCallback((cancelCallback) => { onInvalidate(() => { if (evaluating) evaluating.value = false; if (!hasFinished) cancelCallback(); }); }); if (counterAtBeginning === counter) current.value = result; } catch (e) { onError(e); } finally { if (evaluating && counterAtBeginning === counter) evaluating.value = false; hasFinished = true; } }); if (lazy) { return computed(() => { started.value = true; return current.value; }); } else { return current; } } const defaultWindow = isClient ? window : void 0; const defaultNavigator = isClient ? window.navigator : 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 templateRef(key, initialValue = null) { const instance = getCurrentInstance(); let _trigger = () => { }; const element = customRef((track, trigger) => { _trigger = trigger; return { get() { var _a, _b; track(); return (_b = (_a = instance == null ? void 0 : instance.proxy) == null ? void 0 : _a.$refs[key]) != null ? _b : initialValue; }, set() { } }; }); tryOnMounted(_trigger); onUpdated(_trigger); return element; } function usePermission(permissionDesc, options = {}) { const { controls = false, navigator = defaultNavigator } = options; const isSupported = useSupported(() => navigator && "permissions" in navigator); const permissionStatus = shallowRef(); const desc = typeof permissionDesc === "string" ? { name: permissionDesc } : permissionDesc; const state = shallowRef(); const update = () => { var _a, _b; state.value = (_b = (_a = permissionStatus.value) == null ? void 0 : _a.state) != null ? _b : "prompt"; }; useEventListener(permissionStatus, "change", update, { passive: true }); const query = createSingletonPromise(async () => { if (!isSupported.value) return; if (!permissionStatus.value) { try { permissionStatus.value = await navigator.permissions.query(desc); } catch (e) { permissionStatus.value = void 0; } finally { update(); } } if (controls) return toRaw(permissionStatus.value); }); query(); if (controls) { return { state, isSupported, query }; } else { return state; } } function useClipboard(options = {}) { const { navigator = defaultNavigator, read = false, source, copiedDuring = 1500, legacy = false } = options; const isClipboardApiSupported = useSupported(() => navigator && "clipboard" in navigator); const permissionRead = usePermission("clipboard-read"); const permissionWrite = usePermission("clipboard-write"); const isSupported = computed(() => isClipboardApiSupported.value || legacy); const text = shallowRef(""); const copied = shallowRef(false); const timeout = useTimeoutFn(() => copied.value = false, copiedDuring, { immediate: false }); async function updateText() { let useLegacy = !(isClipboardApiSupported.value && isAllowed(permissionRead.value)); if (!useLegacy) { try { text.value = await navigator.clipboard.readText(); } catch (e) { useLegacy = true; } } if (useLegacy) { text.value = legacyRead(); } } if (isSupported.value && read) useEventListener(["copy", "cut"], updateText, { passive: true }); async function copy(value = toValue(source)) { if (isSupported.value && value != null) { let useLegacy = !(isClipboardApiSupported.value && isAllowed(permissionWrite.value)); if (!useLegacy) { try { await navigator.clipboard.writeText(value); } catch (e) { useLegacy = true; } } if (useLegacy) legacyCopy(value); text.value = value; copied.value = true; timeout.start(); } } function legacyCopy(value) { const ta = document.createElement("textarea"); ta.value = value != null ? value : ""; ta.style.position = "absolute"; ta.style.opacity = "0"; document.body.appendChild(ta); ta.select(); document.execCommand("copy"); ta.remove(); } function legacyRead() { var _a, _b, _c; return (_c = (_b = (_a = document == null ? void 0 : document.getSelection) == null ? void 0 : _a.call(document)) == null ? void 0 : _b.toString()) != null ? _c : ""; } function isAllowed(status) { return status === "granted" || status === "prompt"; } return { isSupported, text, copied, copy }; } export { computedAsync as c, onClickOutside as o, templateRef as t, useClipboard as u }; //# sourceMappingURL=index-c0f92ea5.mjs.map