@nextcloud/vue
Version:
Nextcloud vue components
175 lines (174 loc) • 6.72 kB
JavaScript
import '../assets/NcAppNavigation-f2zUqaiQ.css';
import { defineComponent, useModel, computed, createElementBlock, openBlock, createVNode, unref, withCtx, inject, warn, useTemplateRef, ref, watchEffect, watch, onMounted, onUnmounted, normalizeClass, createElementVNode, withKeys, createBlock, createCommentVNode, renderSlot } from "vue";
import { subscribe, emit, unsubscribe } from "@nextcloud/event-bus";
import { createFocusTrap } from "focus-trap";
import { N as NcAppNavigationList } from "./NcAppNavigationList-BX0wE-dB.mjs";
import { E as mdiMenuOpen, F as mdiMenu } from "./mdi-XFJRiRqJ.mjs";
import { N as NcIconSvgWrapper } from "./NcIconSvgWrapper-BvLanNaW.mjs";
import { r as register, a as t } from "./_l10n-DrTiip5c.mjs";
import { N as NcButton } from "./NcButton-Dc8V4Urj.mjs";
import { _ as _export_sfc } from "./_plugin-vue_export-helper-1tPrXgE0.mjs";
import { useIsMobile } from "../composables/useIsMobile/index.mjs";
import { g as getTrapStack } from "./focusTrap-HJQ4pqHV.mjs";
import { H as HAS_APP_NAVIGATION_KEY } from "./constants-DrSznhwy.mjs";
register();
const _hoisted_1$1 = { class: "app-navigation-toggle-wrapper" };
const _sfc_main$1 = /* @__PURE__ */ defineComponent({
__name: "NcAppNavigationToggle",
props: {
"open": { type: Boolean, ...{ required: true } },
"openModifiers": {}
},
emits: ["update:open"],
setup(__props) {
const open = useModel(__props, "open");
const title = computed(() => open.value ? t("Close navigation") : t("Open navigation"));
return (_ctx, _cache) => {
return openBlock(), createElementBlock("div", _hoisted_1$1, [
createVNode(unref(NcButton), {
class: "app-navigation-toggle",
"aria-controls": "app-navigation-vue",
"aria-expanded": open.value ? "true" : "false",
"aria-label": title.value,
title: title.value,
variant: "tertiary",
onClick: _cache[0] || (_cache[0] = ($event) => open.value = !open.value)
}, {
icon: withCtx(() => [
createVNode(NcIconSvgWrapper, {
path: open.value ? unref(mdiMenuOpen) : unref(mdiMenu)
}, null, 8, ["path"])
]),
_: 1
}, 8, ["aria-expanded", "aria-label", "title"])
]);
};
}
});
const NcAppNavigationToggle = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-5a15295d"]]);
const _hoisted_1 = ["aria-hidden", "aria-label", "aria-labelledby", "inert"];
const _hoisted_2 = { class: "app-navigation__search" };
const _sfc_main = /* @__PURE__ */ defineComponent({
__name: "NcAppNavigation",
props: {
ariaLabel: {},
ariaLabelledby: {}
},
setup(__props) {
const props = __props;
let focusTrap;
const setHasAppNavigation = inject(
HAS_APP_NAVIGATION_KEY,
() => warn("NcAppNavigation is not mounted inside NcContent, this is probably an error."),
false
);
const appNavigationContainerElement = useTemplateRef("appNavigationContainer");
const isMobile = useIsMobile();
const open = ref(!isMobile.value);
watchEffect(() => {
if (!props.ariaLabel && !props.ariaLabelledby) {
warn("NcAppNavigation requires either `ariaLabel` or `ariaLabelledby` to be set for accessibility.");
}
});
watch(isMobile, () => {
open.value = !isMobile.value;
});
watch(open, () => {
toggleFocusTrap();
});
onMounted(() => {
setHasAppNavigation(true);
subscribe("toggle-navigation", toggleNavigationByEventBus);
emit("navigation-toggled", {
open: open.value
});
focusTrap = createFocusTrap(appNavigationContainerElement.value, {
allowOutsideClick: true,
fallbackFocus: appNavigationContainerElement.value,
trapStack: getTrapStack(),
escapeDeactivates: false
});
toggleFocusTrap();
});
onUnmounted(() => {
setHasAppNavigation(false);
unsubscribe("toggle-navigation", toggleNavigationByEventBus);
focusTrap.deactivate();
});
function toggleNavigation(state) {
if (open.value === state) {
emit("navigation-toggled", {
open: open.value
});
return;
}
open.value = state === void 0 ? !open.value : state;
const bodyStyles = getComputedStyle(document.body);
const animationLength = parseInt(bodyStyles.getPropertyValue("--animation-quick")) || 100;
setTimeout(() => {
emit("navigation-toggled", {
open: open.value
});
}, 1.5 * animationLength);
}
function toggleNavigationByEventBus({ open: open2 }) {
return toggleNavigation(open2);
}
function toggleFocusTrap() {
if (isMobile.value && open.value) {
focusTrap.activate();
} else {
focusTrap.deactivate();
}
}
function handleEsc() {
if (isMobile.value) {
toggleNavigation(false);
}
}
return (_ctx, _cache) => {
return openBlock(), createElementBlock("div", {
ref: "appNavigationContainer",
class: normalizeClass(["app-navigation", { "app-navigation--closed": !open.value }])
}, [
createElementVNode("nav", {
id: "app-navigation-vue",
"aria-hidden": open.value ? "false" : "true",
"aria-label": _ctx.ariaLabel || void 0,
"aria-labelledby": _ctx.ariaLabelledby || void 0,
class: "app-navigation__content",
inert: !open.value || void 0,
onKeydown: withKeys(handleEsc, ["esc"])
}, [
createElementVNode("div", _hoisted_2, [
renderSlot(_ctx.$slots, "search", {}, void 0, true)
]),
createElementVNode("div", {
class: normalizeClass(["app-navigation__body", { "app-navigation__body--no-list": !_ctx.$slots.list }])
}, [
renderSlot(_ctx.$slots, "default", {}, void 0, true)
], 2),
_ctx.$slots.list ? (openBlock(), createBlock(NcAppNavigationList, {
key: 0,
class: "app-navigation__list"
}, {
default: withCtx(() => [
renderSlot(_ctx.$slots, "list", {}, void 0, true)
]),
_: 3
})) : createCommentVNode("", true),
renderSlot(_ctx.$slots, "footer", {}, void 0, true)
], 40, _hoisted_1),
createVNode(NcAppNavigationToggle, {
open: open.value,
"onUpdate:open": toggleNavigation
}, null, 8, ["open"])
], 2);
};
}
});
const NcAppNavigation = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-d5ce90cd"]]);
export {
NcAppNavigation as N
};
//# sourceMappingURL=NcAppNavigation-NSjIVdnb.mjs.map