Skip to content
Pinky UI

mobile

Floating Tab Bar

A compact mobile navigation bar that lets the active destination expand without losing the surrounding destinations.

  • mobile
  • navigation
  • tabs
  • active state
  • safe area
Related pattern

The canonical compact mobile navigation pattern: active context grows in place while the bar remains reachable.

Live preview

Quick usage

usage
import { FloatingTabBar } from "@pinky-ui/systems";

<FloatingTabBar items={items} value={activeId} onValueChange={setActiveId} />

Install

Add @pinky-ui/systems as a dependency, or use the CLI to copy this component's source directly into your project — no dependency to manage, fully editable.

shell
npm install @pinky-ui/systems

Prefer to run the whole repository locally instead?

repository
git clone https://github.com/florash/Pinky-UI.git
cd Pinky-UI
npm install
npm run dev

Accessibility

  • Pointer and keyboard paths expose the same state change.
  • Status and focus remain meaningful when motion is disabled.

Performance

  • Uses local state and transforms; no per-frame React pointer loop.

Reduced motion

Resolves state changes without layout animation while preserving semantics.

When to use

  • Product workflows with a clear reversible or inspectable state.

When not to use

  • Decorative motion without a user task.

Skill

Purpose

Use a floating tab bar when the active mobile destination needs a little more context without turning the navigation into a full-width desktop header.

Interaction anatomy

  • One active destination expands in place.
  • Neighbouring destinations remain visible and reachable.
  • The lower edge reserves safe-area space for the device gesture region.

Good for

Small product shells with three to five peer destinations.

Avoid

Deep navigation, more than five peers or a desktop navigation bar compressed into a phone.

Live example

Activate Search, Saved or Profile and watch the active destination take more room.

Usage

tsx
<FloatingTabBar items={items} value={activeId} onValueChange={setActiveId} />

Tune

Keep labels short, use stable order and let the active label carry the context. Preserve a minimum 44px target.

Accessibility and reduced motion

Use aria-current for the active destination and keep every item a real button. Reduced motion keeps the active state and resolves width changes immediately.

Open this skill on its own page