import '../assets/NcMentionBubble-BL05HUeF.css'; import '../assets/NcHeaderMenu-BYjnMPPl.css'; import { vOnClickOutside } from "@vueuse/components"; import { createFocusTrap } from "focus-trap"; import { G as GenRandomId } from "./GenRandomId-CMooMQt0.mjs"; import clickOutsideOptions from "../Mixins/clickOutsideOptions.mjs"; import "../Composables/useIsFullscreen.mjs"; import "../Composables/useIsMobile.mjs"; import "@nextcloud/router"; /* empty css */ import { n as normalizeComponent } from "./_plugin-vue2_normalizer-DU4iP6Vu.mjs"; import "escape-html"; import "striptags"; import "vue"; import "@nextcloud/auth"; import "@nextcloud/axios"; import "@nextcloud/capabilities"; import { g as getTrapStack } from "./focusTrap-Cecv_gjR.mjs"; import NcButton from "../Components/NcButton.mjs"; const _sfc_main = { name: "NcHeaderMenu", components: { NcButton }, directives: { ClickOutside: vOnClickOutside }, mixins: [ clickOutsideOptions ], props: { /** * Unique id for this menu */ id: { type: String, required: true }, /** * aria-label attribute of the menu open button */ ariaLabel: { type: String, default: "" }, /** * Current menu open state */ open: { type: Boolean, default: false }, /** * Pass `true` if the header menu is used for website navigation * * The wrapper tag will be set to `nav` and its `aria-labelledby` * will be associated with the menu open button */ isNav: { type: Boolean, default: false }, /** * Additional visually hidden description text for the menu * open button */ description: { type: String, default: null } }, emits: [ "close", "closed", "open", "opened", "update:open", "cancel" ], data() { return { focusTrap: null, opened: this.open, shortcutsDisabled: window.OCP?.Accessibility?.disableKeyboardShortcuts?.(), triggerId: GenRandomId(), descriptionId: GenRandomId() }; }, computed: { wrapperTag() { return this.isNav ? "nav" : "div"; }, clickOutsideConfig() { return [ this.closeMenu, this.clickOutsideOptions ]; }, listeners() { if (this.isNav) { return { focusout: this.onFocusOut }; } return null; } }, watch: { open(open) { if (open) { 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() { if (!this.opened) { this.openMenu(); } else { this.closeMenu(); } }, /** * Close the current menu * * @param {boolean} cancelled emit a cancel event instead of close */ closeMenu(cancelled = false) { this.opened = false; this.$emit(cancelled ? "cancel" : "close"); this.$emit("update:open", false); this.clearFocusTrap(); this.$nextTick(() => { this.$emit("closed"); }); }, /** * Open the current menu */ openMenu() { this.opened = true; this.$emit("open"); this.$emit("update:open", true); this.$nextTick(() => { this.useFocusTrap(); this.$emit("opened"); }); }, onKeyDown(event) { if (this.shortcutsDisabled || !this.opened) { return; } if (event.key === "Escape") { event.preventDefault(); this.closeMenu(true); } }, /** * @param {FocusEvent} event The focus event */ onFocusOut(event) { if (!this.$refs.headerMenu.contains(event.relatedTarget)) { this.closeMenu(); } }, /** * Add focus trap for accessibility. * Shall only be used when all children are mounted * and available in the DOM. We use $nextTick for that. */ async useFocusTrap() { if (this.isNav || this.focusTrap) { return; } const contentContainer = this.$refs.content; this.focusTrap = createFocusTrap(contentContainer, { allowOutsideClick: true, trapStack: getTrapStack(), fallbackFocus: this.$refs.trigger }); this.focusTrap.activate(); }, clearFocusTrap() { this.focusTrap?.deactivate(); this.focusTrap = null; } } }; var _sfc_render = function render() { var _vm = this, _c = _vm._self._c; return _c(_vm.wrapperTag, _vm._g({ directives: [{ name: "click-outside", rawName: "v-click-outside", value: _vm.clickOutsideConfig, expression: "clickOutsideConfig" }], ref: "headerMenu", tag: "component", staticClass: "header-menu", class: { "header-menu--opened": _vm.opened }, attrs: { "id": _vm.id, "aria-labelledby": _vm.isNav ? _vm.triggerId : null } }, _vm.listeners), [_c("NcButton", { ref: "trigger", staticClass: "header-menu__trigger", attrs: { "id": _vm.isNav ? _vm.triggerId : null, "type": "tertiary-no-background", "aria-label": _vm.ariaLabel, "aria-describedby": _vm.description ? _vm.descriptionId : null, "aria-controls": `header-menu-${_vm.id}`, "aria-expanded": _vm.opened.toString(), "size": "large" }, on: { "click": function($event) { $event.preventDefault(); return _vm.toggleMenu.apply(null, arguments); } }, scopedSlots: _vm._u([{ key: "icon", fn: function() { return [_vm._t("trigger")]; }, proxy: true }], null, true) }), _vm.description ? _c("span", { staticClass: "header-menu__description hidden-visually", attrs: { "id": _vm.descriptionId } }, [_vm._v(" " + _vm._s(_vm.description) + " ")]) : _vm._e(), _c("div", { directives: [{ name: "show", rawName: "v-show", value: _vm.opened, expression: "opened" }], staticClass: "header-menu__carret" }), _c("div", { directives: [{ name: "show", rawName: "v-show", value: _vm.opened, expression: "opened" }], staticClass: "header-menu__wrapper", attrs: { "id": `header-menu-${_vm.id}` } }, [_c("div", { ref: "content", staticClass: "header-menu__content" }, [_vm._t("default")], 2)])], 1); }; var _sfc_staticRenderFns = []; var __component__ = /* @__PURE__ */ normalizeComponent( _sfc_main, _sfc_render, _sfc_staticRenderFns, false, null, "ba584e05" ); const NcHeaderMenu = __component__.exports; export { NcHeaderMenu as N };