Skip to content

Commit

Permalink
Allow to add exclude list for v-click-outside
Browse files Browse the repository at this point in the history
Signed-off-by: Georg Ehrke <[email protected]>
  • Loading branch information
georgehrke committed Apr 2, 2020
1 parent e9d0ab8 commit 815025f
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 1 deletion.
12 changes: 11 additions & 1 deletion src/components/AppNavigationSettings/AppNavigationSettings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

<template>
<div id="app-settings"
v-click-outside="closeMenu"
v-click-outside="clickOutsideConfig"
:class="{ open }">
<div id="app-settings-header">
<button class="settings-button"
Expand All @@ -41,11 +41,15 @@
<script>
import { directive as ClickOutside } from 'v-click-outside'
import { t } from '../../l10n'
import { excludeClickOutsideClasses } from '../../mixins'

export default {
directives: {
ClickOutside,
},
mixins: [
excludeClickOutsideClasses,
],
props: {
title: {
type: String,
Expand All @@ -56,6 +60,12 @@ export default {
data() {
return {
open: false,
clickOutsideConfig: {
handler: this.closeMenu,
middleware: this.clickOutsideMiddleware,
events: ['click', 'dblclick', 'touchstart'],
isActive: true,
},
}
},
methods: {
Expand Down
67 changes: 67 additions & 0 deletions src/mixins/excludeClickOutsideClasses.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/**
* @copyright Copyright (c) 2020 Georg Ehrke <[email protected]>
*
* @author Georg Ehrke <[email protected]>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/

export default {
props: {
excludeClickOutsideClasses: {
type: String | Array,
default: [],
},
},
methods: {
/**
* Middleware Handler for V-Click-Outside
*
* @param {Event} event The click event
* @returns {Boolean}
*/
clickOutsideMiddleware(event) {
const excludedClassList = Array.isArray(this.excludeClickOutsideClasses)
? this.excludeClickOutsideClasses
: [this.excludeClickOutsideClasses]

// No need to iterate through all parents
// if class-list is empty
if (excludedClassList.length === 0) {
return true
}

return !this.hasNodeOrAnyParentClass(event.target, excludedClassList)
},
/**
* Checks if given node or any of it's parents have a class of classArray
*
* @param {Element} node Node to test
* @param {Array} classArray List of classes to check for
* @returns {Boolean}
*/
hasNodeOrAnyParentClass(node, classArray) {
for (const className of classArray) {
if (node.classList.contains(className)) {
return true
}
}

return node.parentElement && this.hasNodeOrAnyParentClass(node.parentElement, classArray)
},
},
}
2 changes: 2 additions & 0 deletions src/mixins/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,12 @@
*
*/

import excludeClickOutsideClasses from './excludeClickOutsideClasses.js'
import isFullscreen from './isFullscreen'
import isMobile from './isMobile'

export {
excludeClickOutsideClasses,
isFullscreen,
isMobile,
}

0 comments on commit 815025f

Please sign in to comment.