@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
JavaScript
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