diff options
author | Christopher Ng <chrng8@gmail.com> | 2023-01-18 01:43:19 +0000 |
---|---|---|
committer | Christopher Ng <chrng8@gmail.com> | 2023-01-18 11:04:25 -0800 |
commit | 966872f23bfcbd3016c3954700fc9185e146d0f6 (patch) | |
tree | 53fc7653ac26f02fd414c15e54d13d9eac04c741 /core/src/components/HeaderMenu.vue | |
parent | 06a572ff55b193f51930571c5bb686787f709c67 (diff) | |
download | nextcloud-server-966872f23bfcbd3016c3954700fc9185e146d0f6.tar.gz nextcloud-server-966872f23bfcbd3016c3954700fc9185e146d0f6.zip |
Port global search menu to focus trapped NcHeaderMenu
Signed-off-by: Christopher Ng <chrng8@gmail.com>
Diffstat (limited to 'core/src/components/HeaderMenu.vue')
-rw-r--r-- | core/src/components/HeaderMenu.vue | 238 |
1 files changed, 0 insertions, 238 deletions
diff --git a/core/src/components/HeaderMenu.vue b/core/src/components/HeaderMenu.vue deleted file mode 100644 index 096294e3799..00000000000 --- a/core/src/components/HeaderMenu.vue +++ /dev/null @@ -1,238 +0,0 @@ - <!-- - - @copyright Copyright (c) 2020 John Molakvoæ <skjnldsv@protonmail.com> - - - - @author John Molakvoæ <skjnldsv@protonmail.com> - - - - @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/>. - - - --> -<template> - <div :id="id" - v-click-outside="clickOutsideConfig" - :class="{ 'header-menu--opened': opened }" - class="header-menu"> - <a class="header-menu__trigger" - href="#" - :aria-label="ariaLabel" - :aria-controls="`header-menu-${id}`" - :aria-expanded="opened.toString()" - @click.prevent="toggleMenu"> - <slot name="trigger" /> - </a> - <div v-show="opened" class="header-menu__carret" /> - <div v-show="opened" - :id="`header-menu-${id}`" - class="header-menu__wrapper" - role="menu" - @focusout="handleFocusOut"> - <div class="header-menu__content"> - <slot /> - </div> - </div> - </div> -</template> - -<script> -import { directive as ClickOutside } from 'v-click-outside' -import excludeClickOutsideClasses from '@nextcloud/vue/dist/Mixins/excludeClickOutsideClasses' - -export default { - name: 'HeaderMenu', - - directives: { - ClickOutside, - }, - - mixins: [ - excludeClickOutsideClasses, - ], - - props: { - id: { - type: String, - required: true, - }, - ariaLabel: { - type: String, - default: '', - }, - open: { - type: Boolean, - default: false, - }, - }, - - data() { - return { - opened: this.open, - clickOutsideConfig: { - handler: this.closeMenu, - middleware: this.clickOutsideMiddleware, - }, - shortcutsDisabled: OCP.Accessibility.disableKeyboardShortcuts(), - } - }, - - watch: { - open(newVal) { - this.opened = newVal - this.$nextTick(() => { - if (this.opened) { - this.openMenu() - } else { - this.closeMenu() - } - }) - }, - }, - - mounted() { - document.addEventListener('keydown', this.onKeyDown) - }, - beforeDestroy() { - document.removeEventListener('keydown', this.onKeyDown) - }, - - methods: { - /** - * Toggle the current menu open state - */ - toggleMenu() { - // Toggling current state - if (!this.opened) { - this.openMenu() - } else { - this.closeMenu() - } - }, - - /** - * Close the current menu - */ - closeMenu() { - if (!this.opened) { - return - } - - this.opened = false - this.$emit('close') - this.$emit('update:open', false) - }, - - /** - * Open the current menu - */ - openMenu() { - if (this.opened) { - return - } - - this.opened = true - this.$emit('open') - this.$emit('update:open', true) - }, - - onKeyDown(event) { - if (this.shortcutsDisabled) { - return - } - - // If opened and escape pressed, close - if (event.key === 'Escape' && this.opened) { - event.preventDefault() - - /** user cancelled the menu by pressing escape */ - this.$emit('cancel') - - /** we do NOT fire a close event to differentiate cancel and close */ - this.opened = false - this.$emit('update:open', false) - } - }, - - handleFocusOut(event) { - if (!event.currentTarget.contains(event.relatedTarget)) { - this.closeMenu() - } - }, - }, -} -</script> - -<style lang="scss" scoped> -$externalMargin: 8px; - -.header-menu { - &__trigger { - display: flex; - align-items: center; - justify-content: center; - width: 50px; - height: 44px; - margin: 2px 0; - padding: 0; - cursor: pointer; - opacity: .85; - } - - &--opened &__trigger, - &__trigger:hover, - &__trigger:focus, - &__trigger:active { - opacity: 1; - } - - &__trigger:focus-visible { - outline: none; - } - - &__wrapper { - position: fixed; - z-index: 2000; - top: 50px; - right: 0; - box-sizing: border-box; - margin: 0 $externalMargin; - border-radius: 0 0 var(--border-radius) var(--border-radius); - background-color: var(--color-main-background); - filter: drop-shadow(0 1px 5px var(--color-box-shadow)); - padding: 8px; - border-radius: var(--border-radius-large); - } - - &__carret { - position: absolute; - z-index: 2001; // Because __wrapper is 2000. - left: calc(50% - 10px); - bottom: 0; - width: 0; - height: 0; - content: ' '; - pointer-events: none; - border: 10px solid transparent; - border-bottom-color: var(--color-main-background); - } - - &__content { - overflow: auto; - width: 350px; - max-width: calc(100vw - 2 * $externalMargin); - min-height: calc(44px * 1.5); - max-height: calc(100vh - 50px * 2); - } -} - -</style> |