diff --git a/src/main.js b/src/main.js index c4e7361c..ca08f56d 100644 --- a/src/main.js +++ b/src/main.js @@ -7,16 +7,18 @@ import VSelect from 'vue-select'; // Select dropdown component import VTabs from 'vue-material-tabs'; // Tab view component, used on the config page import Toasted from 'vue-toasted'; // Toast component, used to show confirmation notifications -import { toastedOptions } from './utils/defaults'; -import Dashy from './App.vue'; -import router from './router'; -import registerServiceWorker from './registerServiceWorker'; +import { toastedOptions } from '@/utils/defaults'; +import Dashy from '@/App.vue'; +import router from '@/router'; +import registerServiceWorker from '@/registerServiceWorker'; +import clickOutside from '@/utils/ClickOutside'; Vue.use(VTooltip); Vue.use(VModal); Vue.use(VTabs); Vue.use(Toasted, toastedOptions); Vue.component('v-select', VSelect); +Vue.directive('clickOutside', clickOutside); Vue.config.productionTip = false; diff --git a/src/utils/ClickOutside.js b/src/utils/ClickOutside.js new file mode 100644 index 00000000..83bb4bbc --- /dev/null +++ b/src/utils/ClickOutside.js @@ -0,0 +1,37 @@ +/** + * A simple Vue directive to trigger an event when the user + * clicks anywhere other than the specified element. + * Used to close context menu's popup menus and tips. + */ + +const instances = []; + +function onDocumentClick(e, el, fn) { + const { target } = e; + if (el !== target && !el.contains(target)) { + fn(e); + } +} + +export default { + bind(element, binding) { + const el = element; + el.dataset.outsideClickIndex = instances.length; + + const fn = binding.value; + const click = (e) => { + onDocumentClick(e, el, fn); + }; + + document.addEventListener('click', click); + document.addEventListener('touchstart', click); + instances.push(click); + }, + unbind(el) { + if (!el.dataset) return; + const index = el.dataset.outsideClickIndex; + const handler = instances[index]; + document.removeEventListener('click', handler); + instances.splice(index, 1); + }, +};