@phila/phila-ui-tabs
v0.1.0-beta.0
Published
Tab strip component for navigation
Readme
Tabs Component
A composable tab navigation system for Vue 3. Supports two visual variants, optional managed panels, and full keyboard navigation.
Installation
npm install @phila/phila-ui-tabs
# or
pnpm add @phila/phila-ui-tabsComponents
| Component | Description |
| ------------- | ---------------------------------------------------------------------------------- |
| PhlTabNav | Root container. Manages active tab state and provides context to children. |
| PhlTab | A single tab button. Must be placed in PhlTabNav's default slot. |
| PhlTabPanel | A content panel tied to a tab by id. Optional — see Nav Only usage. |
Usage
With Panels
Place PhlTab components in the default slot and PhlTabPanel components in the #panels slot. Each panel is linked to its tab via a shared id.
<script setup lang="ts">
import { PhlTabNav, PhlTab, PhlTabPanel } from "@phila/phila-ui-tabs";
</script>
<template>
<PhlTabNav>
<PhlTab id="overview" label="Overview" />
<PhlTab id="details" label="Details" />
<PhlTab id="history" label="History" />
<template #panels>
<PhlTabPanel id="overview">
<p>Overview content.</p>
</PhlTabPanel>
<PhlTabPanel id="details">
<p>Details content.</p>
</PhlTabPanel>
<PhlTabPanel id="history">
<p>History content.</p>
</PhlTabPanel>
</template>
</PhlTabNav>
</template>Controlled with v-model
Use v-model to control which tab is active from outside the component, or to read the active tab ID.
<script setup lang="ts">
import { ref } from "vue";
import { PhlTabNav, PhlTab, PhlTabPanel } from "@phila/phila-ui-tabs";
const activeTab = ref("details");
</script>
<template>
<PhlTabNav v-model="activeTab">
<PhlTab id="overview" label="Overview" />
<PhlTab id="details" label="Details" />
<PhlTab id="history" label="History" />
<template #panels>
<PhlTabPanel id="overview"><p>Overview content.</p></PhlTabPanel>
<PhlTabPanel id="details"><p>Details content.</p></PhlTabPanel>
<PhlTabPanel id="history"><p>History content.</p></PhlTabPanel>
</template>
</PhlTabNav>
</template>Nav Only
Omit the #panels slot entirely and listen to @change (or v-model) to handle content or route changes yourself.
<script setup lang="ts">
import { useRouter } from "vue-router";
import { PhlTabNav, PhlTab } from "@phila/phila-ui-tabs";
const router = useRouter();
</script>
<template>
<PhlTabNav @change="router.push($event)">
<PhlTab id="/overview" label="Overview" />
<PhlTab id="/details" label="Details" />
<PhlTab id="/history" label="History" />
</PhlTabNav>
</template>Props
PhlTabNav
| Prop | Type | Default | Description |
| ------------ | -------------------------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| modelValue | string | — | The active tab id. Use with v-model. |
| variant | "primary" \| "secondary" | "primary" | Visual style of the tab bar. |
| width | "compact" \| "full" | "compact" | "full" stretches the tab bar to fill its container. Only applies to the secondary variant. |
| activation | "auto" \| "manual" | "auto" | Controls how keyboard navigation activates tabs. In "auto" mode, arrow keys move focus and activate simultaneously. In "manual" mode, arrow keys move focus only — press Space or Enter to activate the focused tab. |
PhlTab
| Prop | Type | Default | Description |
| ------- | ---------------- | ------- | --------------------------------------------------------------------------------------------------------------------- |
| id | string | — | Required. Uniquely identifies the tab. Must match the id of its corresponding PhlTabPanel if panels are used. |
| label | string | — | Required. The visible text label. |
| count | number | — | Optional badge count shown on the tab. Renders 0 when explicitly set. |
| icon | IconDefinition | — | Optional FontAwesome icon. Only displayed in the primary variant. |
PhlTabPanel
| Prop | Type | Default | Description |
| ---- | -------- | ------- | ---------------------------------------------------------------- |
| id | string | — | Required. Must match the id of the corresponding PhlTab. |
Events
PhlTabNav
| Event | Payload | Description |
| ------------------- | -------- | --------------------------------------------------------------------- |
| update:modelValue | string | Emitted when the active tab changes. Used by v-model. |
| change | string | Emitted when the active tab changes. Carries the new active tab id. |
Slots
PhlTabNav
| Slot | Description |
| --------- | ---------------------------------------------------------------------------------------------------------- |
| default | Place PhlTab components here. |
| panels | Place PhlTabPanel components here. Optional — omit this slot to use the component as a nav-only control. |
Keyboard Navigation
The tab list follows the ARIA Authoring Practices Guide roving tabindex pattern.
| Key | Action |
| ----------------- | --------------------------------------------------------------------------------- |
| ArrowRight | Move focus to the next tab (wraps around). In auto mode, also activates it. |
| ArrowLeft | Move focus to the previous tab (wraps around). In auto mode, also activates it. |
| Home | Move focus to the first tab. In auto mode, also activates it. |
| End | Move focus to the last tab. In auto mode, also activates it. |
| Space / Enter | Activate the focused tab. Only applies in manual activation mode. |
