maz-ui
Version:
A standalone components library for Vue.Js 3 & Nuxt.Js 3
108 lines (107 loc) • 3.34 kB
JavaScript
import { nextTick } from "vue";
function isServer() {
return typeof document > "u" || typeof globalThis.window > "u";
}
const eventHandlers = /* @__PURE__ */ new WeakMap();
function getEventType() {
return isServer() ? "click" : document.ontouchstart === null ? "touchstart" : "click";
}
function isOptionsObject(value) {
return typeof value == "object" && value !== null && "callback" in value;
}
function getOptionsFromBinding(binding) {
const value = binding.value;
return isOptionsObject(value) ? {
ignore: [],
capture: !1,
once: !1,
stopPropagation: !1,
...value
} : {
callback: value,
ignore: [],
capture: !1,
once: !1,
stopPropagation: !1
};
}
function shouldIgnoreElement(target, ignoreSelectors) {
return isServer() ? !1 : ignoreSelectors.some((selector) => {
try {
if (target.matches && target.matches(selector) || target.closest && target.closest(selector) !== null)
return !0;
const excludedElement = document.querySelector(selector);
if (excludedElement) {
const elementId = excludedElement.getAttribute("id");
if (elementId && target instanceof HTMLElement && target.getAttribute("id") === elementId || excludedElement.contains(target))
return !0;
}
return !1;
} catch {
return !1;
}
});
}
async function onMounted(el, binding) {
if (!isServer())
try {
onUnmounted(el);
const vm = binding.instance, options = getOptionsFromBinding(binding), { callback, ignore = [], capture = !1, once = !1, stopPropagation = !1 } = options, isCallbackFunction = typeof callback == "function";
if (!isCallbackFunction)
throw new Error("[maz-ui](vClickOutside) the callback should be a function");
await nextTick();
const eventHandler = (event) => {
stopPropagation && event.stopPropagation();
const target = event.target;
if (!target || !el)
return;
const isOutside = !el.contains(target), shouldIgnore = ignore.length > 0 && shouldIgnoreElement(target, ignore);
if (isOutside && !shouldIgnore && callback && isCallbackFunction)
return callback.call(vm, event);
};
eventHandlers.set(el, eventHandler);
const eventType = getEventType(), eventOptions = {
passive: !0,
capture,
once
};
document.addEventListener(eventType, eventHandler, eventOptions);
} catch (error) {
console.error("[maz-ui](vClickOutside)", error);
}
}
function onUnmounted(el) {
if (!isServer())
try {
const eventHandler = eventHandlers.get(el);
if (eventHandler) {
const eventType = getEventType();
document.removeEventListener(eventType, eventHandler, !1), eventHandlers.delete(el);
}
} catch (error) {
console.error("[maz-ui](vClickOutside)", error);
}
}
function onUpdated(el, binding) {
try {
if (binding.value === binding.oldValue)
return;
onMounted(el, binding);
} catch (error) {
console.error("[maz-ui](vClickOutside)", error);
}
}
const directive = {
mounted: onMounted,
updated: onUpdated,
unmounted: onUnmounted
}, plugin = {
install: (app) => {
app.directive("click-outside", directive);
}
};
export {
directive as d,
isServer as i,
plugin as p
};