Bottom Navigation
A mobile bottom navigation bar with icon tabs, notification badges, four indicator styles, and three label display modes. Supports 3–5 destinations with full light/dark theming.
Import via Components → New component → Import from code → paste YAML
Power Apps Studio rendering note
After importing, the component may appear incomplete in the Studio editor until you press F5 (Preview) or publish. This is standard Power Apps behavior for YAML-imported components — the editor doesn't fully evaluate nested gallery templates until a preview cycle. End users always see the fully rendered component.
Preview
Home
Home
Tab 1 selected
Click tabs to interact
Installation
This component requires Modern controls to be enabled. Settings → Updates → Preview → Modern controls and themes
# In Power Apps Studio:
1. Components tab → New component → Import from code
2. Paste the full YAML definition
3. Add the component to any screen
4. Press F5 (Preview) to see the fully rendered componentUsage
Define navigation items
// Items — each tab needs Icon, Label, and Badge
// Badge: 0 hides the badge, any positive number shows it
cmpBottomNavigation.Items = Table(
{ Icon: "home", Label: "Home", Badge: 0 },
{ Icon: "search", Label: "Explore", Badge: 0 },
{ Icon: "bell", Label: "Alerts", Badge: 3 },
{ Icon: "user", Label: "Profile", Badge: 0 }
)Handle tab selection
// SelectedIndex is 1-based (first tab = 1)
cmpBottomNavigation.SelectedIndex = varActiveTab
// OnSelect — fires when any tab is tapped
// Use SelectedItemIndex output to route navigation
cmpBottomNavigation.OnSelect = Switch(
cmpBottomNavigation.SelectedItemIndex,
1, Navigate(scrHome),
2, Navigate(scrExplore),
3, Navigate(scrAlerts),
4, Navigate(scrProfile)
)
// Or set a variable and use it elsewhere
cmpBottomNavigation.OnSelect = Set(
varActiveTab,
cmpBottomNavigation.SelectedItemIndex
)Dynamic badges from data
// Badge counts update automatically from data sources
// Numbers over 99 display as "99+"
// Badge: 0 hides the badge entirely
cmpBottomNavigation.Items = Table(
{ Icon: "home", Label: "Home", Badge: 0 },
{ Icon: "mail", Label: "Messages",
Badge: CountRows(Filter(colMessages, !IsRead)) },
{ Icon: "bell", Label: "Alerts",
Badge: CountRows(Filter(colNotifications, !IsSeen)) },
{ Icon: "user", Label: "Profile", Badge: 0 }
)Properties
Input
| Property | Type | Default |
|---|---|---|
ItemsNavigation tabs (Icon, Label, Badge) | Table | See default |
SelectedIndexCurrently selected tab (1-based) | Number | 1 |
ShowLabelsLabel display: "always", "selected", or "never" | Text | "always" |
ActiveIndicatorIndicator style: "pill", "dot", "underline", or "bar" | Text | "underline" |
ActiveColorColor for selected tab icon and label | Color | RGBA(59,130,246,1) |
ActiveColorHexHex value for selected icon SVG (without #) | Text | "3B82F6" |
InactiveColorHexHex value for unselected icon SVG (without #) | Text | "6B7280" |
BadgeColorBadge background color | Color | RGBA(220,38,38,1) |
Theme"Light" or "Dark" theme | Text | "Light" |
Output
| Property | Type | Description |
|---|---|---|
SelectedItemIndex | Number | Index of the last clicked tab (1-based). Falls back to SelectedIndex if no tab has been clicked. |
Event
| Event | Description |
|---|---|
OnSelect | Fires when any tab is tapped. Use with SelectedItemIndex to route navigation. |
Implementation Details
Inline SVG icon system
Icons are rendered as inline SVG via data:image/svg+xml URIs. The stroke color is set dynamically using ActiveColorHex and InactiveColorHex properties. Because Power Apps Image controls don't support Color-type values in SVG strings, hex codes are passed as Text without the # prefix.
Four indicator styles
The ActiveIndicator property controls the visual highlight: pill (64×32px rounded background behind icon), dot (8px circle below label), underline (3px line spanning the tab width), and bar (4px full-width line at top of nav). Each uses a GroupContainer with conditional visibility and dynamic positioning.
Label display modes
ShowLabels supports three modes: "always" shows all labels (default), "selected" shows only the active tab's label with icons shifting vertically to compensate, and "never" hides all labels for a compact icon-only layout. The icon Y position adjusts automatically based on label visibility.
Badge system
Badges appear as red pills positioned at the top-right of each icon. Width adapts to content: 16px for single digits, 20px for double digits, 24px for "99+". Badges with a count of 0 are hidden automatically. The badge color is customizable via the BadgeColor property.
Built-in icons
13 built-in icon names: home, search, bell, user, heart, settings, menu, folder, mail, calendar, dashboard, analytics, plus. Unrecognized names fall back to a circle placeholder.
Auto-sizing tabs
Each tab width is calculated as Parent.Width / CountRows(Items), so the bar adapts to 3, 4, or 5 destinations automatically. The component is full-width by default (App.Width) and 64px tall.
Examples
Minimal 3-destination
// Minimal 3-destination navigation
cmpBottomNavigation.Items = Table(
{ Icon: "home", Label: "Home", Badge: 0 },
{ Icon: "search", Label: "Explore", Badge: 0 },
{ Icon: "user", Label: "Profile", Badge: 0 }
)
cmpBottomNavigation.ShowLabels = "always"
cmpBottomNavigation.ActiveIndicator = "dot"5-item with badges and bar indicator
// 5-item with dynamic badges
cmpBottomNavigation.Items = Table(
{ Icon: "home", Label: "Home", Badge: 0 },
{ Icon: "heart", Label: "Favorites", Badge: 0 },
{ Icon: "folder", Label: "Orders", Badge: 2 },
{ Icon: "mail", Label: "Messages", Badge: 5 },
{ Icon: "user", Label: "Account", Badge: 0 }
)
cmpBottomNavigation.ActiveIndicator = "bar"
// Badge widths adapt:
// 1-9 → 16px, 10-99 → 20px, 99+ → 24pxIcons only — dark theme with pill indicator
// Dark theme, icons only, pill indicator
cmpBottomNavigation.Theme = "Dark"
cmpBottomNavigation.ShowLabels = "never"
cmpBottomNavigation.ActiveIndicator = "pill"
// Custom dark-mode colors
cmpBottomNavigation.ActiveColorHex = "60A5FA"
cmpBottomNavigation.InactiveColorHex = "71717A"
// Or match system theme
cmpBottomNavigation.Theme = If(
App.Theme = "Dark", "Dark", "Light"
)Data Schema
Items record
| Field | Type | Notes |
|---|---|---|
| Icon | Text | Built-in icon name (lowercase). Unrecognized names show a circle fallback. |
| Label | Text | Tab label text. Visibility controlled by ShowLabels property. |
| Badge | Number | 0 = hidden. 1-99 shows count. 100+ shows "99+". |
Architecture
7 controls — 1 horizontal gallery with 6 child controls per template.
11 properties — 9 input, 1 output, 1 event.
cmpBottomNavigation (64px tall, full App.Width)
└── galNavItems (Horizontal Gallery — auto-sized tabs)
└── cntNavItem (GroupContainer — one per tab)
├── cntActiveIndicator (pill / dot / underline / bar)
├── imgIcon (24×24 SVG via data URI)
├── lblNavLabel (11px text, conditional visibility)
├── cntBadge (red pill, auto-width)
│ └── lblBadge (9px bold white count)
└── btnNavItem (transparent hit target, full tab size)