Navigation Bar
Material 3 Expressive Navigation Bar component for bottom navigation on mobile devices.
Overview
The Navigation Bar is a horizontal navigation component that provides quick access to top-level destinations in your app. It adapts its layout based on window size, showing vertical items in compact windows and horizontal items in medium windows.
m3-navigation-bar
Main container that holds navigation items and manages layout (vertical/horizontal).
m3-navigation-bar-item
Individual navigation items with icons, labels, and badge support.
Live Examples
Basic Navigation Bar
A simple navigation bar with three items. Click on items to see the active state change.
💡 Try it: Click on any navigation item to see it become active. The active indicator and colors will change.
In compact windows (<600px), items are arranged vertically and dynamically resize. In medium windows (≥600px), items have fixed widths.
Current selection:Home
<m3-navigation-bar>
<m3-navigation-bar-item label="Home" active>
<span slot="icon" class="material-symbols-outlined">home</span>
</m3-navigation-bar-item>
</m3-navigation-bar>Navigation Bar with Badges
Badges can display notification counts or status indicators on navigation items.
📊 Badge Types:
- Number badges: Display counts (e.g., "5", "12", "3")
- Dot badges: Show presence without counts (empty string)
- No badge: Standard item without indicators
<m3-navigation-bar-item label="Messages" badge="12">
<span slot="icon" class="material-symbols-outlined">mail</span>
</m3-navigation-bar-item>Horizontal Layout (Medium Windows)
In medium windows (≥600px), the navigation bar automatically switches to horizontal item layout with fixed widths.
🔄 Horizontal Layout: Items have fixed widths (min 80px, max 168px) and extra space is added to the ends of the navigation bar.
This layout is perfect for medium-sized windows where you want consistent item sizes.
<m3-navigation-bar layout="horizontal">
<m3-navigation-bar-item label="Home" active>...</m3-navigation-bar-item>
</m3-navigation-bar>Auto Layout (Responsive)
Enable automatic layout switching based on window size using the auto-layout attribute.
📱 Responsive: The navigation bar automatically switches between vertical and horizontal layouts based on window width.
- Compact windows (<600px): Vertical layout with dynamic item widths
- Medium windows (≥600px): Horizontal layout with fixed item widths
Try it: Resize your browser window to see the layout change!
<m3-navigation-bar auto-layout>
<m3-navigation-bar-item label="Home" active>...</m3-navigation-bar-item>
</m3-navigation-bar>Basic Usage
<m3-navigation-bar>
<m3-navigation-bar-item label="Home" active>
<span slot="icon" class="material-symbols-outlined">home</span>
</m3-navigation-bar-item>
<m3-navigation-bar-item label="Music">
<span slot="icon" class="material-symbols-outlined">music_note</span>
</m3-navigation-bar-item>
<m3-navigation-bar-item label="Podcasts">
<span slot="icon" class="material-symbols-outlined">podcasts</span>
</m3-navigation-bar-item>
</m3-navigation-bar>API Reference
m3-navigation-bar
Main container component for the navigation bar.
Properties
| Property | Type | Default | Description |
|---|---|---|---|
layout | 'vertical' | 'horizontal' | 'vertical' | Layout mode for navigation items |
auto-layout | boolean | false | Automatically switch between vertical/horizontal based on window width (≥600px = horizontal) |
Events
| Event | Detail | Description |
|---|---|---|
item-click | { label: string } | Fired when a navigation item is clicked (bubbles from items) |
Slots
| Slot | Description |
|---|---|
| (default) | Navigation bar items |
m3-navigation-bar-item
Individual navigation item with icon and label.
Properties
| Property | Type | Default | Description |
|---|---|---|---|
active | boolean | false | Whether the item is currently active/selected |
label | string | '' | Text label for the navigation item |
badge | string | '' | Badge text to display (empty string shows a dot badge) |
largeBadge | string | '' | Large badge text (displays larger badge) |
layout | 'vertical' | 'horizontal' | 'vertical' | Layout mode (automatically set by parent bar) |
Events
| Event | Detail | Description |
|---|---|---|
item-click | { label: string } | Fired when the item is clicked |
Slots
| Slot | Description |
|---|---|
icon | SVG or icon element (24x24px recommended) |
Framework Integration
Angular
// navigation-bar.component.ts
import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import '@banegasn/m3-navigation-bar';
@Component({
selector: 'app-navigation',
template: `
<m3-navigation-bar [auto-layout]="true">
<m3-navigation-bar-item
label="Home"
[active]="true"
(item-click)="onItemClick($event)"
>
<span slot="icon" class="material-symbols-outlined">home</span>
</m3-navigation-bar-item>
</m3-navigation-bar>
`,
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class NavigationComponent {
onItemClick(event: CustomEvent) {
console.log('Clicked:', event.detail.label);
}
}React
import '@banegasn/m3-navigation-bar';
function App() {
const handleItemClick = (e) => {
console.log('Clicked:', e.detail.label);
};
return (
<m3-navigation-bar auto-layout>
<m3-navigation-bar-item
label="Home"
active
onitem-click={handleItemClick}
>
<span slot="icon" class="material-symbols-outlined">home</span>
</m3-navigation-bar-item>
</m3-navigation-bar>
);
}Vue
<template>
<m3-navigation-bar :auto-layout="true">
<m3-navigation-bar-item
label="Home"
:active="true"
@item-click="handleItemClick"
>
<span slot="icon" class="material-symbols-outlined">home</span>
</m3-navigation-bar-item>
</m3-navigation-bar>
</template>
<script setup>
import '@banegasn/m3-navigation-bar';
const handleItemClick = (event) => {
console.log('Clicked:', event.detail.label);
};
</script>Design Tokens
The navigation bar follows Material Design 3 specifications and uses the following design tokens:
Color Tokens
- Container:
md.sys.color.surface-container - Elevation:
md.sys.elevation.level2 - Active Indicator:
md.sys.color.secondary-container - Active Label:
md.sys.color.secondary - Active Icon:
md.sys.color.on-secondary-container - Inactive Label/Icon:
md.sys.color.on-surface-variant
State Layers
- Hover: 8% state layer opacity
- Focus: 10% state layer opacity
- Pressed: 10% state layer opacity