UNPKG

@efelle/proton

Version:

An elegant Vue.js Tailwind component library

77 lines (61 loc) 2.27 kB
const isTouch = typeof window !== 'undefined' && ('ontouchstart' in window || navigator.msMaxTouchPoints > 0) const events = isTouch ? ['touchstart', 'click'] : ['click'] const instances = [] function processDirectiveArguments(bindingValue) { const isFunction = typeof bindingValue === 'function' if (!isFunction && typeof bindingValue !== 'object') { throw new Error('v-click-outside: Binding value must be a function or an object') } return { handler: isFunction ? bindingValue : bindingValue.handler, middleware: bindingValue.middleware || ((isClickOutside) => isClickOutside), events: bindingValue.events || events, } } function onEvent({ el, event, handler, middleware }) { const isClickOutside = event.target !== el && !el.contains(event.target) if (! isClickOutside) { return } if (middleware(event, el)) { handler(event, el) } } function bind(el, { value }) { const { handler, middleware, events } = processDirectiveArguments(value) const instance = { el, eventHandlers: events.map((eventName) => ({ event: eventName, handler: (event) => onEvent({ event, el, handler, middleware }), })), } instance.eventHandlers.forEach(({ event, handler }) => document.addEventListener(event, handler)) instances.push(instance) } function update(el, { value }) { const { handler, middleware, events } = processDirectiveArguments(value) const instance = instances.find((instance) => instance.el === el) instance.eventHandlers.forEach(({ event, handler }) => document.removeEventListener(event, handler), ) instance.eventHandlers = events.map((eventName) => ({ event: eventName, handler: (event) => onEvent({ event, el, handler, middleware }), })) instance.eventHandlers.forEach(({ event, handler }) => document.addEventListener(event, handler)) } function unbind(el) { const instance = instances.find((instance) => instance.el === el) instance.eventHandlers.forEach(({ event, handler }) => document.removeEventListener(event, handler), ) } const directive = { bind, update, unbind, instances, } export default directive