@wfrog/vc
Version:
vue3 组件库 vc
676 lines (658 loc) • 22.6 kB
JavaScript
import { i as isDef, t as tryOnScopeDispose, b as isClient, n as noop, p as pausableWatch, c as tryOnMounted, d as toArray, w as watchImmediate, e as isObject, f as pxValue, g as injectLocal } from './GvCnndsC.mjs';
import { getCurrentInstance, ref, watch, nextTick, computed, shallowRef, onMounted, toValue, unref, watchEffect, hasInjectionContext } from 'vue';
//#endregion
//#region _configurable.ts
const defaultWindow = isClient ? window : void 0;
const defaultNavigator = isClient ? window.navigator : void 0;
//#endregion
//#region unrefElement/index.ts
/**
* Get the dom element of a ref of element or Vue component instance
*
* @param elRef
*/
function unrefElement(elRef) {
var _$el;
const plain = toValue(elRef);
return (_$el = plain === null || plain === void 0 ? void 0 : plain.$el) !== null && _$el !== void 0 ? _$el : plain;
}
//#endregion
//#region useEventListener/index.ts
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 _firstParamTargets$va, _firstParamTargets$va2;
return [
(_firstParamTargets$va = (_firstParamTargets$va2 = firstParamTargets.value) === null || _firstParamTargets$va2 === void 0 ? void 0 : _firstParamTargets$va2.map((e) => unrefElement(e))) !== null && _firstParamTargets$va !== void 0 ? _firstParamTargets$va : [defaultWindow].filter((e) => e != null),
toArray(toValue(firstParamTargets.value ? args[1] : args[0])),
toArray(unref(firstParamTargets.value ? args[2] : args[1])),
toValue(firstParamTargets.value ? args[3] : args[2])
];
}, ([raw_targets, raw_events, raw_listeners, raw_options]) => {
cleanup();
if (!(raw_targets === null || raw_targets === void 0 ? void 0 : raw_targets.length) || !(raw_events === null || raw_events === void 0 ? void 0 : raw_events.length) || !(raw_listeners === null || raw_listeners === void 0 ? 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;
}
function onClickOutside(target, handler, options = {}) {
const { window: window$1 = defaultWindow, ignore = [], capture = true, detectIframe = false, controls = false } = options;
if (!window$1) return controls ? {
stop: noop,
cancel: noop,
trigger: noop
} : noop;
let shouldListen = true;
const shouldIgnore = (event) => {
return toValue(ignore).some((target$1) => {
if (typeof target$1 === "string") return Array.from(window$1.document.querySelectorAll(target$1)).some((el) => el === event.target || event.composedPath().includes(el));
else {
const el = unrefElement(target$1);
return el && (event.target === el || event.composedPath().includes(el));
}
});
};
/**
* Determines if the given target has multiple root elements.
* Referenced from: https://github.com/vuejs/test-utils/blob/ccb460be55f9f6be05ab708500a41ec8adf6f4bc/src/vue-wrapper.ts#L21
*/
function hasMultipleRoots(target$1) {
const vm = toValue(target$1);
return vm && vm.$.subTree.shapeFlag === 16;
}
function checkMultipleRoots(target$1, event) {
const vm = toValue(target$1);
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$1, "click", (event) => {
if (!isProcessingClick) {
isProcessingClick = true;
setTimeout(() => {
isProcessingClick = false;
}, 0);
listener(event);
}
}, {
passive: true,
capture
}),
useEventListener(window$1, "pointerdown", (e) => {
const el = unrefElement(target);
shouldListen = !shouldIgnore(e) && !!(el && !e.composedPath().includes(el));
}, { passive: true }),
detectIframe && useEventListener(window$1, "blur", (event) => {
setTimeout(() => {
var _window$document$acti;
const el = unrefElement(target);
if (((_window$document$acti = window$1.document.activeElement) === null || _window$document$acti === void 0 ? void 0 : _window$document$acti.tagName) === "IFRAME" && !(el === null || el === void 0 ? void 0 : el.contains(window$1.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;
}
//#endregion
//#region useMounted/index.ts
/**
* Mounted state in ref.
*
* @see https://vueuse.org/useMounted
*
* @__NO_SIDE_EFFECTS__
*/
function useMounted() {
const isMounted = shallowRef(false);
const instance = getCurrentInstance();
if (instance) onMounted(() => {
isMounted.value = true;
}, instance);
return isMounted;
}
//#endregion
//#region useSupported/index.ts
/* @__NO_SIDE_EFFECTS__ */
function useSupported(callback) {
const isMounted = useMounted();
return computed(() => {
isMounted.value;
return Boolean(callback());
});
}
//#endregion
//#region useSSRWidth/index.ts
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;
}
//#endregion
//#region useMediaQuery/index.ts
/**
* Reactive Media Query.
*
* @see https://vueuse.org/useMediaQuery
* @param query
* @param options
*/
function useMediaQuery(query, options = {}) {
const { window: window$1 = defaultWindow, ssrWidth = /* @__PURE__ */ useSSRWidth() } = options;
const isSupported = /* @__PURE__ */ useSupported(() => window$1 && "matchMedia" in window$1 && typeof window$1.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;
matches.value = toValue(query).split(",").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$1.matchMedia(toValue(query));
matches.value = mediaQuery.value.matches;
});
useEventListener(mediaQuery, "change", handler, { passive: true });
return computed(() => matches.value);
}
//#endregion
//#region useCloned/index.ts
function cloneFnJSON(source) {
return JSON.parse(JSON.stringify(source));
}
//#endregion
//#region ssr-handlers.ts
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;
}
//#endregion
//#region useStorage/guess.ts
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";
}
//#endregion
//#region useStorage/index.ts
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";
/**
* Reactive LocalStorage/SessionStorage.
*
* @see https://vueuse.org/useStorage
*/
function useStorage(key, defaults$1, storage, options = {}) {
var _options$serializer;
const { flush = "pre", deep = true, listenToStorageChanges = true, writeDefaults = true, mergeDefaults = false, shallow, window: window$1 = defaultWindow, eventFilter, onError = (e) => {
console.error(e);
}, initOnMounted } = options;
const data = (shallow ? shallowRef : ref)(typeof defaults$1 === "function" ? defaults$1() : defaults$1);
const keyComputed = computed(() => toValue(key));
if (!storage) try {
storage = getSSRHandler("getDefaultStorage", () => defaultWindow === null || defaultWindow === void 0 ? void 0 : defaultWindow.localStorage)();
} catch (e) {
onError(e);
}
if (!storage) return data;
const rawInit = toValue(defaults$1);
const type = guessSerializerType(rawInit);
const serializer = (_options$serializer = options.serializer) !== null && _options$serializer !== void 0 ? _options$serializer : StorageSerializers[type];
const { pause: pauseWatch, resume: resumeWatch } = pausableWatch(data, (newValue) => write(newValue), {
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);
};
/**
* The custom event is needed for same-document syncing when using custom
* storage backends, but it doesn't work across different documents.
*
* TODO: Consider implementing a BroadcastChannel-based solution that fixes this.
*/
if (window$1 && listenToStorageChanges) if (storage instanceof Storage) useEventListener(window$1, "storage", onStorageEvent, { passive: true });
else useEventListener(window$1, customStorageEventName, onStorageCustomEvent);
if (initOnMounted) tryOnMounted(() => {
firstMounted = true;
update();
});
else update();
function dispatchWriteEvent(oldValue, newValue) {
if (window$1) {
const payload = {
key: keyComputed.value,
oldValue,
newValue,
storageArea: storage
};
window$1.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 {
const serializedData = serializer.write(data.value);
if (event === void 0 || (event === null || event === void 0 ? void 0 : event.newValue) !== serializedData) data.value = read(event);
} catch (e) {
onError(e);
} finally {
if (event) nextTick(resumeWatch);
else resumeWatch();
}
}
function updateFromCustomEvent(event) {
update(event.detail);
}
return data;
}
//#endregion
//#region useResizeObserver/index.ts
/**
* Reports changes to the dimensions of an Element's content or the border-box
*
* @see https://vueuse.org/useResizeObserver
* @param target
* @param callback
* @param options
*/
function useResizeObserver(target, callback, options = {}) {
const { window: window$1 = defaultWindow,...observerOptions } = options;
let observer;
const isSupported = /* @__PURE__ */ useSupported(() => window$1 && "ResizeObserver" in window$1);
const cleanup = () => {
if (observer) {
observer.disconnect();
observer = void 0;
}
};
const stopWatch = watch(computed(() => {
const _targets = toValue(target);
return Array.isArray(_targets) ? _targets.map((el) => unrefElement(el)) : [unrefElement(_targets)];
}), (els) => {
cleanup();
if (isSupported.value && window$1) {
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
};
}
//#endregion
//#region useElementSize/index.ts
/**
* Reactive size of an HTML element.
*
* @see https://vueuse.org/useElementSize
*/
function useElementSize(target, initialSize = {
width: 0,
height: 0
}, options = {}) {
const { window: window$1 = defaultWindow, box = "content-box" } = options;
const isSVG = computed(() => {
var _unrefElement;
return (_unrefElement = unrefElement(target)) === null || _unrefElement === void 0 || (_unrefElement = _unrefElement.namespaceURI) === null || _unrefElement === void 0 ? void 0 : _unrefElement.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$1 && 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
};
}
//#endregion
//#region useUserMedia/index.ts
/**
* Reactive `mediaDevices.getUserMedia` streaming
*
* @see https://vueuse.org/useUserMedia
* @param options
*/
function useUserMedia(options = {}) {
var _options$enabled, _options$autoSwitch;
const enabled = shallowRef((_options$enabled = options.enabled) !== null && _options$enabled !== void 0 ? _options$enabled : false);
const autoSwitch = shallowRef((_options$autoSwitch = options.autoSwitch) !== null && _options$autoSwitch !== void 0 ? _options$autoSwitch : true);
const constraints = ref(options.constraints);
const { navigator: navigator$1 = defaultNavigator } = options;
const isSupported = /* @__PURE__ */ useSupported(() => {
var _navigator$mediaDevic;
return navigator$1 === null || navigator$1 === void 0 || (_navigator$mediaDevic = navigator$1.mediaDevices) === null || _navigator$mediaDevic === void 0 ? void 0 : _navigator$mediaDevic.getUserMedia;
});
const stream = shallowRef();
function getDeviceOptions(type) {
switch (type) {
case "video":
if (constraints.value) return constraints.value.video || false;
break;
case "audio":
if (constraints.value) return constraints.value.audio || false;
break;
}
}
async function _start() {
if (!isSupported.value || stream.value) return;
stream.value = await navigator$1.mediaDevices.getUserMedia({
video: getDeviceOptions("video"),
audio: getDeviceOptions("audio")
});
return stream.value;
}
function _stop() {
var _stream$value;
(_stream$value = stream.value) === null || _stream$value === void 0 || _stream$value.getTracks().forEach((t) => t.stop());
stream.value = void 0;
}
function stop() {
_stop();
enabled.value = false;
}
async function start() {
await _start();
if (stream.value) enabled.value = true;
return stream.value;
}
async function restart() {
_stop();
return await start();
}
watch(enabled, (v) => {
if (v) _start();
else _stop();
}, { immediate: true });
watch(constraints, () => {
if (autoSwitch.value && stream.value) restart();
}, {
immediate: true,
deep: true
});
tryOnScopeDispose(() => {
stop();
});
return {
isSupported,
stream,
start,
stop,
restart,
constraints,
enabled,
autoSwitch
};
}
//#endregion
//#region useVModel/index.ts
/**
* Shorthand for v-model binding, props + emit -> ref
*
* @see https://vueuse.org/useVModel
* @param props
* @param key (default 'modelValue')
* @param emit
* @param options
*
* @__NO_SIDE_EFFECTS__
*/
function useVModel(props, key, emit, options = {}) {
var _vm$$emit, _vm$proxy;
const { clone = false, passive = false, eventName, deep = false, defaultValue, shouldEmit } = options;
const vm = getCurrentInstance();
const _emit = emit || (vm === null || vm === void 0 ? void 0 : vm.emit) || (vm === null || vm === void 0 || (_vm$$emit = vm.$emit) === null || _vm$$emit === void 0 ? void 0 : _vm$$emit.bind(vm)) || (vm === null || vm === void 0 || (_vm$proxy = vm.proxy) === null || _vm$proxy === void 0 || (_vm$proxy = _vm$proxy.$emit) === null || _vm$proxy === void 0 ? void 0 : _vm$proxy.bind(vm === null || vm === void 0 ? void 0 : vm.proxy));
let event = eventName;
event = event || `update:${key.toString()}`;
const cloneFn = (val) => !clone ? val : typeof clone === "function" ? clone(val) : cloneFnJSON(val);
const getValue$1 = () => isDef(props[key]) ? cloneFn(props[key]) : defaultValue;
const triggerEmit = (value) => {
if (shouldEmit) {
if (shouldEmit(value)) _emit(event, value);
} else _emit(event, value);
};
if (passive) {
const proxy = ref(getValue$1());
let isUpdating = false;
watch(() => props[key], (v) => {
if (!isUpdating) {
isUpdating = true;
proxy.value = cloneFn(v);
nextTick(() => isUpdating = false);
}
});
watch(proxy, (v) => {
if (!isUpdating && (v !== props[key] || deep)) triggerEmit(v);
}, { deep });
return proxy;
} else return computed({
get() {
return getValue$1();
},
set(value) {
triggerEmit(value);
}
});
}
//#endregion
//#region useWindowSize/index.ts
/**
* Reactive window size.
*
* @see https://vueuse.org/useWindowSize
* @param options
*
* @__NO_SIDE_EFFECTS__
*/
function useWindowSize(options = {}) {
const { window: window$1 = defaultWindow, initialWidth = Number.POSITIVE_INFINITY, initialHeight = Number.POSITIVE_INFINITY, listenOrientation = true, includeScrollbar = true, type = "inner" } = options;
const width = shallowRef(initialWidth);
const height = shallowRef(initialHeight);
const update = () => {
if (window$1) if (type === "outer") {
width.value = window$1.outerWidth;
height.value = window$1.outerHeight;
} else if (type === "visual" && window$1.visualViewport) {
const { width: visualViewportWidth, height: visualViewportHeight, scale } = window$1.visualViewport;
width.value = Math.round(visualViewportWidth * scale);
height.value = Math.round(visualViewportHeight * scale);
} else if (includeScrollbar) {
width.value = window$1.innerWidth;
height.value = window$1.innerHeight;
} else {
width.value = window$1.document.documentElement.clientWidth;
height.value = window$1.document.documentElement.clientHeight;
}
};
update();
tryOnMounted(update);
const listenerOptions = { passive: true };
useEventListener("resize", update, listenerOptions);
if (window$1 && type === "visual" && window$1.visualViewport) useEventListener(window$1.visualViewport, "resize", update, listenerOptions);
if (listenOrientation) watch(useMediaQuery("(orientation: portrait)"), () => update());
return {
width,
height
};
}
export { useUserMedia as a, useStorage as b, useElementSize as c, useWindowSize as d, onClickOutside as o, useVModel as u };