import { computed, defineComponent, h } from "vue";
import { cx, iconNode } from "../utils.js";
export default defineComponent({
name: "GnTabs",
props: {
modelValue: { type: String, default: "" },
items: { type: Array, required: true },
compact: { type: Boolean, default: false },
vertical: { type: Boolean, default: false },
ariaLabel: { type: String, default: "Tabs" }
},
emits: ["update:modelValue"],
setup(props, { emit, slots }) {
const activeId = computed(() => props.modelValue || props.items.find(item => !item.disabled)?.id || props.items[0]?.id);
const activate = item => {
if(!item.disabled) {
emit("update:modelValue", item.id);
}
};
const enabledItems = () => props.items.filter(item => !item.disabled);
const move = (item, direction) => {
const items = enabledItems();
const index = items.findIndex(enabled => enabled.id === item.id);
const next = items[(index + direction + items.length) % items.length];
activate(next);
};
const handleKeydown = (event, item) => {
if(event.key === "ArrowRight" || event.key === "ArrowDown") {
event.preventDefault();
move(item, 1);
} else if(event.key === "ArrowLeft" || event.key === "ArrowUp") {
event.preventDefault();
move(item, -1);
} else if(event.key === "Home") {
event.preventDefault();
activate(enabledItems()[0]);
} else if(event.key === "End") {
event.preventDefault();
const items = enabledItems();
activate(items[items.length - 1]);
}
};
return () => h("div", {
class: cx("tabs", {
"tabs-compact": props.compact,
"tabs-vertical": props.vertical
})
}, [
h("div", { class: "tabs-list", role: "tablist", "aria-label": props.ariaLabel }, props.items.map(item => {
const active = item.id === activeId.value;
const panelId = `${item.id}-panel`;
return h("button", {
class: cx("tab", { "tab-active": active }),
type: "button",
role: "tab",
"aria-selected": active ? "true" : "false",
"aria-controls": panelId,
"aria-disabled": item.disabled ? "true" : undefined,
tabindex: active ? "0" : "-1",
onClick: () => activate(item),
onKeydown: event => handleKeydown(event, item)
}, [
iconNode(item.icon),
item.label
]);
})),
h("div", { class: "tabs-panels" }, props.items.map(item => {
const active = item.id === activeId.value;
return h("div", {
id: `${item.id}-panel`,
class: cx("tab-panel", { "tab-panel-active": active }),
role: "tabpanel",
hidden: !active
}, slots[item.id]?.({ item, active }) || (active && slots.default?.({ item, active })));
}))
]);
}
});