suiss/ui · Component
Tab Bar
A floating bottom navigation bar whose overflow and extra sections expand from a More button.
Tab Bar is an open-source component from suiss/ui for React, React Native, SwiftUI and Jetpack Compose. The @esuiss/ui CLI copies its source into your project, so you own the code.
TabBar renders a fixed nav centered at the bottom of the screen. TabBarList holds the primary TabBarItem buttons. TabBarTrigger is the More button: pressing it expands TabBarContent above the list, with a spring animation, to show TabBarSection columns. Each section has a TabBarSectionTitle and a set of TabBarLink entries.
The list measures itself and moves items that don't fit into the expanded content, where they appear as links. When every item fits and there are no sections, the More button is hidden. Use TabBar for top-level navigation on any screen size; for in-page panels, use Tabs, and for an app's side navigation, use Sidebar.
Installation
CLI
Works in any project with a components.json. See Installation for the one-line registry setup. Or use the suiss/ui CLI:
Manual
- Install the dependencies and add the
cnhelper:
-
Add the pieces it builds on: Button.
-
Copy the source into
components/ui/tab-bar.tsx:
- Update the import paths to match your project.
Usage
Use defaultOpen on TabBar for an uncontrolled bar, or open with onOpenChange to control it. Give the nav a name with aria-label.
Mark the current destination with isActive on a TabBarItem or TabBarLink. A TabBarItem can render as a link or router link. Choosing a TabBarLink or an overflowed item closes the bar. Child components can read the bar's state with the useTabBar hook.
Use the render prop to render a TabBarItem as a link or router link.
Set asChild on a TabBarItem and pass a link or router link as the child.
Pass a render function to a TabBarItem that returns a link or router link with the props it receives.
Examples
Open
Renders with the sections expanded on mount; an outside click closes them.
Fits without more
Hides the More button because every item fits and there are no sections.
Overflow into more
Holds more items than fit, so the extra items move behind More.
Links
Renders each item as a link, with the active one marked as the current page.
Disabled item
Disables one item in the list.
API Reference
TabBar
The floating nav container that holds the open state.
| Prop | Type | Default | Description |
|---|---|---|---|
open | boolean | - | Whether the More panel is open, for controlled use. |
defaultOpen | boolean | false | Whether the More panel starts open when uncontrolled. |
onOpenChange | (open: boolean) => void | - | Called when the More panel opens or closes. |
Also accepts the props of React.ComponentProps<"nav">, TabBarProps.
TabBarList
The row of primary items; items that don't fit move into the content.
Also accepts the props of React.ComponentProps<"div">.
TabBarItem
A primary destination in the list, rendered as a button by default.
| Prop | Type | Default | Description |
|---|---|---|---|
isActive | boolean | false | Marks the item as the current page with aria-current="page". |
Also accepts the props of useRender.ComponentProps<"button">, React.ComponentProps<"button">.
TabBarTrigger
The More button that expands and collapses the content.
Also accepts the props of React.ComponentProps<typeof Button>.
TabBarContent
The expandable area above the list that holds overflowed items and sections.
Also accepts the props of React.ComponentProps<"div">.
TabBarSection
A column of related links in the content.
Also accepts the props of React.ComponentProps<"div">.
TabBarSectionTitle
The heading of a section, marked with a small dot.
Also accepts the props of React.ComponentProps<"div">.
TabBarLink
A link inside a section that closes the bar when chosen.
| Prop | Type | Default | Description |
|---|---|---|---|
isActive | boolean | false | Marks the link as the current page with aria-current="page". |
Also accepts the props of useRender.ComponentProps<"a">, React.ComponentProps<"a">.
Accessibility
TabBaris anavigationlandmark; name it witharia-label.- Active items and links set
aria-current="page". - The More button sets
aria-expandedandaria-controlsto point to the content. Escapecloses the open bar and returns focus to the More button. A pointer press outside the bar also closes it.- While open, the list is
inert. Items moved into the overflow are hidden from assistive technologies and removed from the tab order in the list, and appear as links in the content instead. - When the More button isn't needed, it's hidden and removed from the tab order.
Notes
TabBarsetsdata-open,data-overflowinganddata-sectionsfor styling. The trigger setsdata-idlewhen it's hidden, and items and links setdata-active.- Parts carry
data-slotattributes such astab-bar,tab-bar-list,tab-bar-item,tab-bar-triggerandtab-bar-content. - The bar sits above the safe-area inset at the bottom of the screen and uses a
cardbackground with a thin border and a shadow. The active item gets asecondaryfill andprimarytext. - Animations are removed when reduced motion is preferred.
useTabBarthrows if it's used outside aTabBar.
TabBar is built on the tabs primitive and sits at the bottom of a screen. TabBarList is a rounded capsule with a shadow, inset from the screen edges, so the bar floats above the page. The root adds bottom padding for the safe area, minus any inset an enclosing Screen already handles, and never less than 12 points. TabBarItem stacks an icon over a short label; the active tab sits on a bg-secondary pill and uses text-primary and a filled icon weight.
Use it for switching between the top-level sections of an app. For switching views within a screen, use Tabs.







