import { defineComponent, h, nextTick, onBeforeUnmount, ref, watch } from "vue";
import { iconNode } from "../utils.js";
import GnNavList from "./GnNavList.js";
let shellId = 0;
export default defineComponent({
name: "GnNavigationShell",
props: {
brand: { type: String, default: "GNexus UI Kit" },
logoSrc: { type: String, default: "/assets/imgs/gnexus-mark.svg" },
current: { type: String, default: "" },
title: { type: String, default: "Sections" },
subtitle: { type: String, default: "Navigation" },
footerLeft: { type: String, default: "" },
footerRight: { type: String, default: "" },
items: { type: Array, default: () => [] }
},
emits: ["select"],
setup(props, { emit, slots }) {
const open = ref(false);
const drawerId = `gn-nav-drawer-${++shellId}`;
const drawerRef = ref(null);
let previousFocus = null;
const close = () => {
open.value = false;
};
const toggle = () => {
open.value = !open.value;
};
const onKeydown = event => {
if(event.key === "Escape") {
event.preventDefault();
close();
}
};
watch(open, isOpen => {
if(isOpen) {
previousFocus = document.activeElement;
document.body.classList.add("nav-drawer-open");
document.addEventListener("keydown", onKeydown);
nextTick(() => drawerRef.value?.focus());
} else {
document.body.classList.remove("nav-drawer-open");
document.removeEventListener("keydown", onKeydown);
previousFocus?.focus?.();
previousFocus = null;
}
});
onBeforeUnmount(() => {
document.body.classList.remove("nav-drawer-open");
document.removeEventListener("keydown", onKeydown);
});
return () => [
h("header", { class: "nav-topbar" }, [
h("button", {
class: "nav-topbar-toggle",
type: "button",
"aria-controls": drawerId,
"aria-expanded": open.value ? "true" : "false",
onClick: toggle
}, [
iconNode("ph-sidebar-simple"),
h("span", {}, "Menu")
]),
h("div", { class: "nav-topbar-brand" }, [
props.logoSrc && h("img", { src: props.logoSrc, alt: "", "aria-hidden": "true" }),
h("span", {}, slots.brand?.() || props.brand)
]),
h("div", { class: "nav-topbar-current" }, slots.current?.() || props.current)
]),
h("div", { class: "nav-drawer-backdrop", onClick: close }),
h("aside", {
ref: drawerRef,
class: ["nav-drawer", { "is-open": open.value }],
id: drawerId,
"aria-label": "Navigation",
"aria-hidden": open.value ? "false" : "true",
tabindex: "-1"
}, [
h("header", { class: "nav-drawer-header" }, [
h("div", {}, [
h("div", { class: "nav-drawer-title" }, slots.title?.() || props.title),
h("div", { class: "nav-drawer-subtitle" }, slots.subtitle?.() || props.subtitle)
]),
h("button", {
class: "nav-drawer-close",
type: "button",
"aria-label": "Close navigation",
onClick: close
}, [iconNode("ph-x")])
]),
h("nav", { class: "nav-drawer-body" }, [
slots.default?.({ close }) || h(GnNavList, {
items: props.items,
onSelect: item => {
emit("select", item);
close();
}
})
]),
(slots.footer || props.footerLeft || props.footerRight) && h("footer", { class: "nav-drawer-footer" },
slots.footer?.() || [
h("span", {}, props.footerLeft),
h("span", {}, props.footerRight)
]
)
]),
slots.content?.()
];
}
});