Phi
Tabs
@dicehub/phiv1.0.0-beta.1

Tabs

A set of layered sections of content, known as tab panels, displayed one at a time.

<script setup>
import { Tabs } from "@dicehub/phi/components/tabs";

const tabs = [
  { value: "tab1", label: "Tab 1" },
  { value: "tab2", label: "Tab 2" },
  { value: "tab3", label: "Tab 3" },
];
</script>

<template>
  <div class="tabs-demo__stack">
    <div>
      <p class="tabs-demo__label">Segmented (default)</p>
      <Tabs :tabs="tabs" selected-value="tab1" variant="segmented" />
    </div>
    <div>
      <p class="tabs-demo__label">Underline</p>
      <Tabs :tabs="tabs" selected-value="tab1" variant="underline" />
    </div>
  </div>
</template>

Installation

Barrel

import { Tabs } from "@dicehub/phi";

Granular

import { Tabs } from "@dicehub/phi/components/tabs";

Usage

<script setup>
import { Tabs } from "@dicehub/phi/components/tabs";

const tabs = [
  { value: "overview", label: "Overview" },
  { value: "settings", label: "Settings" },
];
</script>

<template>
  <Tabs :tabs="tabs" selected-value="overview" />
</template>

Examples

Variants

Segmented (Default)

A pill-shaped indicator slides between tabs on a subtle background.

<script setup>
import { Tabs } from "@dicehub/phi/components/tabs";

const tabs = [
  { value: "tab1", label: "Tab 1" },
  { value: "tab2", label: "Tab 2" },
  { value: "tab3", label: "Tab 3" },
];
</script>

<template>
  <Tabs :tabs="tabs" selected-value="tab1" variant="segmented" />
</template>

Underline

A bottom border with a primary-colored indicator. The active tab has bolder text for emphasis.

<script setup>
import { Tabs } from "@dicehub/phi/components/tabs";

const tabs = [
  { value: "tab1", label: "Tab 1" },
  { value: "tab2", label: "Tab 2" },
  { value: "tab3", label: "Tab 3" },
];
</script>

<template>
  <Tabs :tabs="tabs" selected-value="tab1" variant="underline" />
</template>

Small Size

Use size="sm" for a compact tab bar that matches input size="sm" height (h-6.5 / 26px). Useful inside toolbars and filter rows.

<script setup>
import { Tabs } from "@dicehub/phi/components/tabs";

const tabs = [
  { value: "tab1", label: "Tab 1" },
  { value: "tab2", label: "Tab 2" },
  { value: "tab3", label: "Tab 3" },
];
</script>

<template>
  <div class="tabs-demo__stack">
    <div>
      <p class="tabs-demo__label">Segmented sm</p>
      <Tabs :tabs="tabs" selected-value="tab1" size="sm" />
    </div>
    <div>
      <p class="tabs-demo__label">Underline sm</p>
      <Tabs :tabs="tabs" selected-value="tab1" variant="underline" size="sm" />
    </div>
  </div>
</template>

Controlled

Use v-model:value or value with @value-change for controlled state.

<script setup>
import { ref } from "vue";
import { Tabs } from "@dicehub/phi/components/tabs";

const tabs = [
  { value: "tab1", label: "Tab 1" },
  { value: "tab2", label: "Tab 2" },
  { value: "tab3", label: "Tab 3" },
];

const activeTab = ref("tab1");
</script>

<template>
  <div class="tabs-demo__stack">
    <Tabs v-model:value="activeTab" :tabs="tabs" />
    <p class="tabs-demo__status">Active tab: <code>{{ activeTab }}</code></p>
  </div>
</template>

Horizontal Overflow

When segmented tabs overflow their container, flat scroll controls appear at the clipped edge. Use them, horizontal scrolling, or mouse drag to reveal off-screen tabs. Underline tabs keep native horizontal scrolling without controls.

<script setup>
import { Tabs } from "@dicehub/phi/components/tabs";

const tabs = [
  { value: "overview", label: "Overview" },
  { value: "analytics", label: "Analytics" },
  { value: "reports", label: "Reports" },
  { value: "notifications", label: "Notifications" },
  { value: "settings", label: "Settings" },
  { value: "billing", label: "Billing" },
  { value: "security", label: "Security" },
  { value: "integrations", label: "Integrations" },
];
</script>

<template>
  <div class="tabs-demo__overflow">
    <Tabs :tabs="tabs" selected-value="overview" />
  </div>
</template>

API Reference

Tabs

Closed tab-list component with controlled and uncontrolled selection.

Prop / EventTypeDefaultDescription
tabsTabsItem[][]Items rendered in the tab list. No root is rendered when this array is empty.
valuestring-Controlled selected tab value.
modelValuestring-v-model alias for controlled selected value.
selectedValuestringfirst tabInitial selected value for uncontrolled usage.
onValueChange(value: string) => void-Selection callback. Vue consumers can also use @value-change.
activateOnFocusbooleanfalseWhen true, arrow-key focus also activates the focused tab.
variant"segmented" | "underline""segmented"Visual variant.
size"base" | "sm""base"Tab control size.
labelsTabsLabelsEnglish labelsOverrides accessible labels for the overflow scroll buttons.
classNamestring-Additional classes applied to the root.
listClassNamestring-Additional classes applied to the tab list.
indicatorClassNamestring-Additional classes applied to the active indicator.
$attrsHTMLAttributes-Native attributes are forwarded to the Ark TabsRoot element.
@value-change(value: string, details: TabsValueChangeDetails) => void-Emitted when the selected value changes.
@update:value(value: string) => void-v-model:value update event.
@update:model-value(value: string) => void-v-model update event.

TabsItem

Item descriptor passed through the tabs prop.

Prop / EventTypeDefaultDescription
valuestringrequiredUnique value used by Ark UI for selection.
labelstringrequiredVisible text label for the tab.
classNamestring-Additional classes applied to this tab trigger.
asstring | Component-Custom element or Vue component for the trigger.
hrefstring-Shortcut for rendering an anchor tab trigger.
targetstring-Anchor target when href is provided.
relstring-Anchor rel attribute. Defaults to noopener noreferrer for _blank targets.

TabsLabels

Accessible labels for horizontal overflow controls.

Prop / EventTypeDefaultDescription
scrollStartstring"Scroll tabs left"Label for the control that reveals earlier tabs.
scrollEndstring"Scroll tabs right"Label for the control that reveals later tabs.