Bottom Nav
Mobile-first bottom tab bar with icons, labels, badges, safe-area padding, and an optional floating action button. Pair with Sidebar for responsive app layouts.
Installation
dotnet add package Lumeo
One-time app setup (AddLumeo(), CSS & JS) is covered in the
installation guide.
Usage
@using Lumeo <BottomNav />
52 tests across 8 files. Auto-generated from the test suite.
When to Use
- Mobile or touch-first apps that need 3–5 top-level destinations always reachable
- As the small-screen half of a responsive pair:
Sidebaron desktop,BottomNavon mobile - Thumb-zone primary actions (center FAB for "Create", "Compose", "Scan")
Not for: deep navigation hierarchies, admin panels, or more than ~5 items. Use Sidebar, Tabs, or Navigation Menu for those.
Responsive: Sidebar ↔ BottomNav
The standard mobile pattern: show the full <Sidebar> on
md and up, and a 4-item <BottomNav> below it.
Pick the 4 most-used items — do not mirror the full sidebar tree;
bury the rest behind a "More" item or a Sheet.
Two simple rules: the Sidebar is hidden md:flex,
the BottomNav is md:hidden.
Add pb-16 md:pb-0 to your scroll container so content
isn't hidden behind the fixed bar on mobile.
API Reference
BottomNav
| Prop | Type | Default | Description |
|---|---|---|---|
| ChildContent | RenderFragment? | — | The BottomNavItem (and optionally BottomNavFab) elements rendered inside the nav bar. |
| AriaLabel | string? | — | Accessible label for the nav landmark. Defaults to "Bottom navigation". |
| Fixed | bool | true | When true (default), pins to the bottom of the viewport with position: fixed. Set false to render inline. |
| ReserveSpace | bool | false | When true (and Fixed is on), also renders an in-flow, aria-hidden spacer equal to the nav's height plus the bottom safe-area inset, so the fixed bar never overlaps the end of the page content — no consumer padding-bottom hack needed. The height is driven by the --lumeo-bottom-nav-height CSS variable (default 3.5rem); override it if your nav is taller (e.g. the Pill variant or two-line labels). Place BottomNav at the end of the scrolling content so the spacer reserves room there. Default false. |
| Variant | BottomNavVariant | BottomNavVariant.Default | Visual variant. Default is a solid bar with a top border; Pill is a floating centered pill. |
| AnimatedIndicator | bool | false | When true, each BottomNavItem gets smooth background-color and color transitions, and the small active pill transitions its transform with a spring easing. Default is false. |
| Class | string? | — | Additional CSS classes merged onto the root nav element. |
| AdditionalAttributes | Dictionary<string, object>? | — | Unmatched attributes are splatted onto the root nav element. |
BottomNavItem
| Prop | Type | Default | Description |
|---|---|---|---|
| Href | string? | — | Destination URL. When set, item renders as an <a>; otherwise as a <button>. |
| Label | string? | — | Text label shown under the icon. Also used as the accessible name. |
| IconContent | RenderFragment? | — | Icon slot (use Icon or <SvgGlyph>). The Content suffix avoids colliding with the <Icon> component. |
| Badge | RenderFragment? | — | Optional badge (count, dot, or any content) shown on the icon. Int, string, or RenderFragment. |
| IconSize | string | "h-5 w-5" | Size class applied to the icon container. Defaults to h-5 w-5 to match the original visual. Override to fit larger content like avatars (e.g. "h-7 w-7"). |
| IsActive | bool? | — | Manual active-state override. When null, active is inferred from the current route matching Href. |
| PressEffect | Button.ButtonPressEffect | Button.ButtonPressEffect.None | Visual feedback when the item is pressed. Default is None. Scale is recommended for a tactile feel on mobile. |
| Class | string? | — | Additional CSS classes merged onto the root button/anchor element. |
| AdditionalAttributes | Dictionary<string, object>? | — | Unmatched attributes are splatted onto the root button/anchor element. |
Events
| OnClick | EventCallback | Click handler — fires for both <a> and <button> renderings (link navigation still proceeds). |
BottomNavFab
| Prop | Type | Default | Description |
|---|---|---|---|
| Href | string? | — | Optional destination URL. When set, renders as an anchor; otherwise a button. |
| AriaLabel* | string? | — | Accessible label. Required because FABs are usually icon-only. Defaults to "Primary action". |
| ChildContent | RenderFragment? | — | The icon (or other content) rendered inside the floating action button. |
| Class | string? | — | Additional CSS classes merged onto the root button/anchor element. |
| AdditionalAttributes | Dictionary<string, object>? | — | Unmatched attributes are splatted onto the root button/anchor element. |
Events
| OnClick | EventCallback | Invoked when the FAB is activated. Ignored when Href is set (the anchor navigates instead). |
Related Components
- Sidebar — Use on desktop in the responsive pair
- Tabs — For switching views within a page (not top-level nav)
- Speed Dial — Alternative quick-action surface
- Sheet — Bottom sheet for "More" destinations that don't fit in 4 tabs