HapplyUI

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.

  • tv
  • happly-ui-utils
  • polymorphic
  • recursive-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.

Business overview section
Financial overview section
Sale details section
<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.

PropTypeDefaultDescription
variant'neutral' | 'primary''neutral'Color scheme for the selected tab and underline indicator
scrollMarginnumber16Extra 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.

PropTypeDefaultDescription
selectedbooleanfalseWhether this tab is currently selected
disabledboolean-Disables the tab
scrollTostring-Element ID to smooth-scroll to when clicked

MenuTabBar.Icon

Polymorphic 16px icon inside a tab item.

PropTypeDefaultDescription
asReact.ElementType'div'The element or component to render as

MenuTabBar.Composed

Shorthand controlled tab bar. Accepts all Root props.

PropTypeDefaultDescription
valuestring-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

Previous
Dot Stepper