/**
* GnRouterTabs — Router-aware tab switcher.
*
* Wraps GnTabs and drives active state from the current vue-router route.
* When a tab is activated, the component calls router.push(item.to)
* instead of emitting update:modelValue.
*
* @typedef {Object} GnRouterTabsItem
* @property {string} id - Slot name and tab identifier
* @property {string|Object} to - Route target (string path or { name, params, query })
* @property {string} label - Tab label text
* @property {string} [icon] - Phosphor icon name with ph- prefix
* @property {boolean} [disabled] - Disabled state
*
* @typedef {Object} GnRouterTabsProps
* @property {Array} items - Array of GnRouterTabsItem
* @property {boolean} [compact=false] - Compact size
* @property {boolean} [vertical=false] - Vertical layout
* @property {string} [ariaLabel='Tabs'] - ARIA label
* @property {string} [activeMatch='prefix'] - 'exact' | 'prefix' — how to match current route against item.to
*
* @slots [item.id] - One slot per item id
*/
import { computed, defineComponent, h, watch } from "vue";
import { tryUseRouter, tryUseRoute, isRouteActive } from "../composables/useVueRouter.js";
import GnTabs from "./GnTabs.js";
export default defineComponent({
name: "GnRouterTabs",
props: {
items: { type: Array, required: true },
compact: { type: Boolean, default: false },
vertical: { type: Boolean, default: false },
ariaLabel: { type: String, default: "Tabs" },
activeMatch: { type: String, default: "prefix" }
},
setup(props, { slots }) {
const router = tryUseRouter();
const route = tryUseRoute();
const hasRouter = Boolean(router && route);
if(!hasRouter && typeof process !== "undefined" && process.env && process.env.NODE_ENV !== "production") {
// eslint-disable-next-line no-console
console.warn("[gnexus-ui-kit] GnRouterTabs requires vue-router. Falling back to standard tabs.");
}
const tabItems = computed(() => props.items.map(item => ({
id: item.id,
label: item.label,
icon: item.icon,
disabled: item.disabled,
to: item.to
})));
const activeId = computed(() => {
if(!hasRouter) {
return tabItems.value.find(item => !item.disabled)?.id || "";
}
const matched = tabItems.value.find(item => {
if(item.disabled || !item.to) {
return false;
}
return isRouteActive(route, item.to, props.activeMatch);
});
return matched?.id || tabItems.value.find(item => !item.disabled)?.id || "";
});
const onUpdate = id => {
if(!hasRouter) {
return;
}
const item = tabItems.value.find(i => i.id === id);
if(item && item.to) {
router.push(item.to);
}
};
return () => h(GnTabs, {
modelValue: activeId.value,
items: tabItems.value,
compact: props.compact,
vertical: props.vertical,
ariaLabel: props.ariaLabel,
"onUpdate:modelValue": onUpdate
}, slots);
}
});