@nextcloud/vue
Version:
Nextcloud vue components
143 lines (142 loc) • 5.82 kB
JavaScript
import '../assets/NcHeaderMenu-Hy0UKyUu.css';
import { defineComponent, ref, computed, useTemplateRef, watch, nextTick, createBlock, openBlock, resolveDynamicComponent, normalizeClass, unref, withCtx, createVNode, createElementBlock, createCommentVNode, withDirectives, withModifiers, renderSlot, toDisplayString, createElementVNode, vShow } from "vue";
import { onClickOutside } from "@vueuse/core";
import { createFocusTrap } from "focus-trap";
import "../composables/useFormatDateTime/index.mjs";
import { useHotKey } from "../composables/useHotKey/index.mjs";
import "../composables/useIsDarkTheme/index.mjs";
import "../composables/useIsFullscreen/index.mjs";
import "../composables/useIsMobile/index.mjs";
import { u as useTrapStackControl } from "./useTrapStackControl-B6cEicto.mjs";
import { c as createElementId } from "./createElementId-DhjFt1I9.mjs";
import { g as getTrapStack } from "./focusTrap-HJQ4pqHV.mjs";
import { N as NcButton } from "./NcButton-Dc8V4Urj.mjs";
import { _ as _export_sfc } from "./_plugin-vue_export-helper-1tPrXgE0.mjs";
const _hoisted_1 = ["id"];
const _hoisted_2 = { class: "header-menu__caret" };
const _hoisted_3 = ["id"];
const _hoisted_4 = {
ref: "contentContainer",
class: "header-menu__content"
};
const _sfc_main = /* @__PURE__ */ defineComponent({
__name: "NcHeaderMenu",
props: {
id: {},
ariaLabel: { default: () => void 0 },
open: { type: Boolean, default: false },
isNav: { type: Boolean, default: false },
description: { default: () => void 0 },
excludeClickOutsideSelectors: { default: () => [] }
},
emits: ["closed", "opened", "update:open"],
setup(__props, { emit: __emit }) {
const emit = __emit;
const descriptionId = createElementId();
const triggerId = createElementId();
const focusTrap = ref();
const isOpened = ref(__props.open);
const wrapperTag = computed(() => __props.isNav ? "nav" : "div");
const contentContainerElement = useTemplateRef("contentContainer");
const headerMenuElement = useTemplateRef("headerMenu");
const triggerButtonInstance = useTemplateRef("triggerButton");
const ignore = computed(() => Array.isArray(__props.excludeClickOutsideSelectors) ? __props.excludeClickOutsideSelectors : __props.excludeClickOutsideSelectors.split(" "));
onClickOutside(headerMenuElement, () => setMenuState(false), { ignore });
useHotKey("Escape", () => setMenuState(false), { prevent: true });
useTrapStackControl(isOpened, {
disabled: () => !__props.isNav
});
watch(() => __props.open, (state) => setMenuState(state));
function toggleMenu() {
setMenuState(!isOpened.value);
}
async function setMenuState(state) {
if (state === isOpened.value) {
return;
}
isOpened.value = state;
emit("update:open", state);
await nextTick();
await (state ? addFocusTrap() : clearFocusTrap());
emit(state ? "opened" : "closed");
}
function onFocusOut(event) {
if (!__props.isNav) {
return;
}
if (!(event.relatedTarget instanceof Node)) {
return;
}
if (headerMenuElement.value?.contains(event.relatedTarget)) {
setMenuState(false);
}
}
async function addFocusTrap() {
if (__props.isNav || focusTrap.value) {
return;
}
focusTrap.value = createFocusTrap(contentContainerElement.value, {
allowOutsideClick: true,
trapStack: getTrapStack(),
fallbackFocus: triggerButtonInstance.value?.$el
});
focusTrap.value.activate();
}
function clearFocusTrap() {
focusTrap.value?.deactivate();
focusTrap.value = void 0;
}
return (_ctx, _cache) => {
return openBlock(), createBlock(resolveDynamicComponent(wrapperTag.value), {
id: _ctx.id,
ref: "headerMenu",
"aria-labelledby": _ctx.isNav ? unref(triggerId) : null,
class: normalizeClass([{ "header-menu--opened": isOpened.value }, "header-menu"]),
onFocusout: onFocusOut
}, {
default: withCtx(() => [
createVNode(unref(NcButton), {
id: _ctx.isNav ? unref(triggerId) : null,
ref: "triggerButton",
"aria-controls": `header-menu-${_ctx.id}`,
"aria-expanded": isOpened.value.toString(),
"aria-label": _ctx.ariaLabel,
class: "header-menu__trigger",
size: "large",
variant: "tertiary-no-background",
onClick: withModifiers(toggleMenu, ["prevent"])
}, {
icon: withCtx(() => [
renderSlot(_ctx.$slots, "trigger", {}, void 0, true)
]),
_: 3
}, 8, ["id", "aria-controls", "aria-expanded", "aria-label"]),
_ctx.description ? (openBlock(), createElementBlock("span", {
key: 0,
id: unref(descriptionId),
class: "header-menu__description hidden-visually"
}, toDisplayString(_ctx.description), 9, _hoisted_1)) : createCommentVNode("", true),
withDirectives(createElementVNode("div", _hoisted_2, null, 512), [
[vShow, isOpened.value]
]),
withDirectives(createElementVNode("div", {
id: `header-menu-${_ctx.id}`,
class: "header-menu__wrapper"
}, [
createElementVNode("div", _hoisted_4, [
renderSlot(_ctx.$slots, "default", {}, void 0, true)
], 512)
], 8, _hoisted_3), [
[vShow, isOpened.value]
])
]),
_: 3
}, 40, ["id", "aria-labelledby", "class"]);
};
}
});
const NcHeaderMenu = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-d45c5788"]]);
export {
NcHeaderMenu as N
};
//# sourceMappingURL=NcHeaderMenu-CdlSBOyC.mjs.map