Nav bar
● Stable · v0.1A floating bottom navigation bar — a rounded, translucent, shadowed pill that hovers above the screen. Two to five destinations, each an icon over a label, with the active one lifted onto a neutral pill and its icon filled.
In context
The bar floats above the content; on the web it frosts what's behind it.
Try it
States & variants
Purpose
The nav bar is the app's top-level switch between destinations — Home, Record, Insights, Profile. Floating it (rather than pinning a full-width bar to the very bottom) keeps it reachable with a thumb, frames the content, and feels modern without shouting.
The floating look
- A rounded pill centred above the bottom edge, inset from the sides.
- A translucent surface (
surface.glass) over a backdrop blur on web; on native it falls back to the same translucent surface plus a soft shadow (no blur dependency). - A shadow (
elevation.lg) so it reads as hovering above the page, not stuck to it. - The active destination sits on a quiet neutral pill (no brand colour), its icon filled and its label in the strongest text colour; the rest stay outlined and secondary.
Anatomy
- Bar — the floating container. Positions itself absolutely at the bottom of its parent (which must be
flex:1/ relative); setfloating={false}to dock it inline. - Item — an equal-width slot (icon over a short label, ≥48dp) that fills with a neutral pill (
background.tertiary) when active. - Icon — passed per item as a render function that receives
active, so you show a filled glyph when active and an outline when not (and the colour follows the state). The package stays icon-free. - Badge — an optional dot (
badge: true) or count (badge: 5) on an item for unseen activity.
Code
import { NavBar } from '@daytwo/components'// Use an icon set with filled + outline pairs (e.g. Ionicons):import { IoHome, IoHomeOutline, IoPieChart, IoPieChartOutline } from 'react-icons/io5'const [tab, setTab] = useState('home')// Each item shows the FILLED glyph when active, the OUTLINE when not.<View style={{ flex: 1 }}><YourScreen /><NavBarvalue={tab}onChange={setTab}items={[{ value: 'home', label: 'Home',icon: ({ color, size, active }) =>active ? <IoHome color={color} size={size} /> : <IoHomeOutline color={color} size={size} /> },{ value: 'insights', label: 'Insights', badge: 3,icon: ({ color, size, active }) =>active ? <IoPieChart color={color} size={size} /> : <IoPieChartOutline color={color} size={size} /> },]}/></View>
The component passes active to each item's icon, so you swap between the
filled and outline glyph. Add bottom padding to the scrolling content so the last
items clear the floating bar, and raise bottomInset to sit above a device's
home indicator.
When to use
- For the app's 2–5 top-level destinations, reachable from anywhere.
- When a thumb-friendly, modern bottom bar fits the product.
When NOT to use
- To section one screen's content (Sales / Customers) — that's Tabs.
- To toggle one value (Today / This week) — that's a segmented control.
- For more than five destinations — they get cramped; group some under a "More" or rethink the IA.
Anti-patterns
A nav bar switches where you are; it never performs an action. "Record a sale" belongs on the screen as a button (or as a destination that opens the record flow) — not mixed in as a fifth tab that behaves differently from the rest.
Edge cases
badge: true) or count on the itemshowLabels={false} for a compact barbottomInset so the bar clears it