Components
Menu Tab Bar
An underline-style horizontal tab bar with optional leading icons and a smoothly animated underline indicator. Supports neutral and primary variants.
Installation
bunx @happlyui/cli@latest add menu-tab-bar
Dependencies
Registry dependencies
These are automatically installed when you add this component.
tvhapply-ui-utilspolymorphicrecursive-clone-children
Usage
import * as MenuTabBar from "@/components/ui/menu-tab-bar"
<MenuTabBar.Root>
<MenuTabBar.Item selected>
<MenuTabBar.Icon as={RiBriefcaseLine} />
<span>Overview</span>
</MenuTabBar.Item>
<MenuTabBar.Item>
<span>Details</span>
</MenuTabBar.Item>
</MenuTabBar.Root>
Examples
Default
Underline tab bar with icons matching the Figma design.
<MenuTabBar.Root>
<MenuTabBar.Item selected>
<MenuTabBar.Icon as={RiBriefcaseLine} />
<span>Business overview</span>
</MenuTabBar.Item>
<MenuTabBar.Item>
<MenuTabBar.Icon as={RiBarChartBoxLine} />
<span>Financial overview</span>
</MenuTabBar.Item>
</MenuTabBar.Root>
Primary
Primary variant with brand-colored underline and selected text.
<MenuTabBar.Root variant="primary">
<MenuTabBar.Item selected>
<MenuTabBar.Icon as={RiBriefcaseLine} />
<span>Business overview</span>
</MenuTabBar.Item>
</MenuTabBar.Root>
Without Icons
Text-only tabs without leading icons.
<MenuTabBar.Root>
<MenuTabBar.Item selected>
<span>Overview</span>
</MenuTabBar.Item>
<MenuTabBar.Item>
<span>Details</span>
</MenuTabBar.Item>
</MenuTabBar.Root>
Composed
Shorthand composed version with controlled value.
<MenuTabBar.Composed
value={value}
onValueChange={setValue}
items={[
{ label: 'Home', value: 'home', icon: RiHome5Line },
{ label: 'Profile', value: 'profile', icon: RiUserLine },
]}
/>
Scroll To Section
Clicking a tab smooth-scrolls to the corresponding section by ID.
<MenuTabBar.Item scrollTo="business" selected>
<span>Business overview</span>
</MenuTabBar.Item>
<div id="business">...</div>
Disabled
Individual tabs can be disabled.
<MenuTabBar.Item disabled>
<span>Disabled</span>
</MenuTabBar.Item>
API Reference
MenuTabBar.Root
Container for tab items with bottom border, tablist role, and animated underline indicator.
| Prop | Type | Default | Description |
|---|---|---|---|
variant | 'neutral' | 'primary' | 'neutral' | Color scheme for the selected tab and underline indicator |
scrollMargin | number | 16 | Extra pixels below the auto-detected offset. The component already accounts for sticky headers by measuring its own bottom edge. |
MenuTabBar.Item
Individual tab button with underline indicator when selected.
| Prop | Type | Default | Description |
|---|---|---|---|
selected | boolean | false | Whether this tab is currently selected |
disabled | boolean | - | Disables the tab |
scrollTo | string | - | Element ID to smooth-scroll to when clicked |
MenuTabBar.Icon
Polymorphic 16px icon inside a tab item.
| Prop | Type | Default | Description |
|---|---|---|---|
as | React.ElementType | 'div' | The element or component to render as |
MenuTabBar.Composed
Shorthand controlled tab bar. Accepts all Root props.
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | - | The currently selected tab value |
onValueChange | (value: string) => void | - | Callback when a tab is clicked |
items | { label: string; value: string; disabled?: boolean; icon?: React.ElementType }[] | - | Array of tab definitions |