Bottom Nav
Mobile bottom bar with icon + label items. Active item gets accent-primary glow underline with surface-overlay background and backdrop blur.
<arc-bottom-nav> Overview
>
BottomNav is a fixed-position navigation bar anchored to the bottom of the viewport, purpose-built for mobile and touch-first interfaces. It renders a row of icon-and-label items where the active selection is highlighted with an accent-primary glow underline and a frosted surface-overlay background with backdrop blur, making the current section immediately obvious even at a glance.
The component follows the well-established mobile navigation pattern used by native apps: three to five top-level destinations, each represented by an icon above a short label. Tapping an item dispatches an `arc-change` event so your application can update the active route. The `value` prop controls which item is currently selected, enabling both controlled and uncontrolled usage patterns.
BottomNav is designed to complement TopBar — use TopBar for desktop viewports and swap in BottomNav at mobile breakpoints. The backdrop blur effect ensures the bar remains legible even when content scrolls beneath it. For deeper hierarchical navigation on mobile, pair BottomNav with a Drawer or Sheet for secondary menu levels.Guidelines
When to use
- Limit to three to five items — more will crowd the bar on small screens
- Use recognizable icons with short labels (one to two words)
- Show BottomNav only on mobile breakpoints — use TopBar or Sidebar on desktop
- Set the value prop to match the current route for correct highlighting
- Pair with a Drawer or Sheet for deeper navigation within a section
When not to use
- Do not display BottomNav and TopBar navigation simultaneously on the same viewport
- Do not use labels longer than two words — they will truncate on narrow screens
- Do not add more than five items — prioritize the most important destinations
- Do not use BottomNav for actions (like "Create" or "Delete") — it is for navigation only
- Do not forget to provide icons — label-only items break the expected mobile pattern
Features
- Fixed bottom positioning for mobile-first navigation
- Icon + label items for scannable touch targets
- Accent-primary glow underline on the active item
- Surface-overlay background with backdrop blur
- `arc-change` event on item selection
- Controlled value prop for external state management
- Supports three to five navigation destinations
- Keyboard accessible with arrow key navigation
- Token-driven theming via CSS custom properties
Preview
Usage
This component requires JavaScript. No pure HTML/CSS version is available — use the Web Component directly or a framework wrapper.
<script type="module" src="@arclux/arc-ui"></script>
<arc-bottom-nav
value="home"
items='[
{ "label": "Home", "icon": "house", "value": "home" },
{ "label": "Search", "icon": "magnifying-glass", "value": "search" },
{ "label": "Profile", "icon": "user", "value": "profile" },
{ "label": "Settings", "icon": "gear", "value": "settings" }
]'
id="nav"
></arc-bottom-nav>
<script>
document.querySelector('#nav').addEventListener('arc-change', (e) => {
console.log('navigate:', e.detail.value);
});
</script> import { BottomNav } from '@arclux/arc-ui-react';
const items = [
{ label: 'Home', icon: 'home', value: 'home' },
{ label: 'Search', icon: 'search', value: 'search' },
{ label: 'Profile', icon: 'user', value: 'profile' },
{ label: 'Settings', icon: 'settings', value: 'settings' },
];
export function MobileNav() {
return (
<BottomNav
items={items}
value="home"
onArcChange={(e) => console.log('navigate:', e.detail.value)}
/>
);
} <script setup>
import { BottomNav } from '@arclux/arc-ui-vue';
const items = [
{ label: 'Home', icon: 'home', value: 'home' },
{ label: 'Search', icon: 'search', value: 'search' },
{ label: 'Profile', icon: 'user', value: 'profile' },
{ label: 'Settings', icon: 'settings', value: 'settings' },
];
function onChange(e) {
console.log('navigate:', e.detail.value);
}
</script>
<template>
<BottomNav :items="items" value="home" @arc-change="onChange" />
</template> <script>
import { BottomNav } from '@arclux/arc-ui-svelte';
const items = [
{ label: 'Home', icon: 'home', value: 'home' },
{ label: 'Search', icon: 'search', value: 'search' },
{ label: 'Profile', icon: 'user', value: 'profile' },
{ label: 'Settings', icon: 'settings', value: 'settings' },
];
</script>
<BottomNav
{items}
value="home"
on:arc-change={(e) => console.log('navigate:', e.detail.value)}
/> import { Component } from '@angular/core';
import { BottomNav } from '@arclux/arc-ui-angular';
@Component({
imports: [BottomNav],
template: `
<arc-bottom-nav
[items]="items"
value="home"
(arc-change)="onChange($event)"
/>
`,
})
export class MobileNavComponent {
items = [
{ label: 'Home', icon: 'home', value: 'home' },
{ label: 'Search', icon: 'search', value: 'search' },
{ label: 'Profile', icon: 'user', value: 'profile' },
{ label: 'Settings', icon: 'settings', value: 'settings' },
];
onChange(e: CustomEvent) {
console.log('navigate:', e.detail.value);
}
} import { BottomNav } from '@arclux/arc-ui-solid';
const items = [
{ label: 'Home', icon: 'home', value: 'home' },
{ label: 'Search', icon: 'search', value: 'search' },
{ label: 'Profile', icon: 'user', value: 'profile' },
{ label: 'Settings', icon: 'settings', value: 'settings' },
];
export function MobileNav() {
return (
<BottomNav
items={items}
value="home"
onArcChange={(e) => console.log('navigate:', e.detail.value)}
/>
);
} import { BottomNav } from '@arclux/arc-ui-preact';
const items = [
{ label: 'Home', icon: 'home', value: 'home' },
{ label: 'Search', icon: 'search', value: 'search' },
{ label: 'Profile', icon: 'user', value: 'profile' },
{ label: 'Settings', icon: 'settings', value: 'settings' },
];
export function MobileNav() {
return (
<BottomNav
items={items}
value="home"
onArcChange={(e) => console.log('navigate:', e.detail.value)}
/>
);
} API
-
itemsArray<{label: string, icon?: string, value: string}>[] - Array of navigation items, each with a label, icon name, and value identifier.
-
valuestring'' - The value of the currently active item. Controls which item is highlighted.
Events
-
arc-changedetail: { value: string } - Fired when an item is tapped with detail: { value }.
See Also
- Top Bar Fixed header bar that anchors every page with a brand slot on the left, an optional center navigation area, and a right-aligned actions region for user controls, search, and settings.
- Tabs Tabbed content navigation with keyboard support and ARIA roles.
- Navigation Menu Horizontal navigation bar with hover-triggered dropdown sub-menus and full keyboard accessibility. Designed for marketing sites, documentation hubs, and product landing pages where top-level sections expand into categorised link lists.