Vize

Bottom Navigation

Mobile tab bar: a labelled navigation landmark whose active destination carries aria-current="page".

Package @vizejs/ui/bottom-navigation
Maturity stable
Own the source vize lib pull bottom-navigation
Requires context, controllable-state
Aliases tab bar, bottom tabs, bottom nav, app navigation bar
Covers HTML nav landmark, aria-current=page, Material bottom navigation

Usage

import { BottomNavigation, TabBar, BottomNavigationItem, TabBarItem } from "@vizejs/ui/bottom-navigation";

Or copy the source into your project with vize lib pull bottom-navigation (see Source Distribution).

API

BottomNavigation<Value extends string>

Source: src/families/navigation/bottom-navigation/bottom-navigation.vue

Props

Prop Type Default Description
destinations (required) readonly Value[] required Destination values in order; their literal union types v-model and select.
modelValue Value undefined Controlled active destination. undefined selects uncontrolled behavior.
defaultValue Value undefined Initial uncontrolled destination.
ariaLabel string "Primary" Accessible name of the navigation landmark.
ariaLabelledby string undefined Ids that label the navigation landmark (overrides ariaLabel).

Events

Event Payload Description
update:modelValue [value: Value] Fired when an item requests to become the active destination.
select [value: Value, nativeEvent: MouseEvent] Fired after an item is activated, with its value and the native click.

Slots

Slot Slot props Description
default { readonly active: Value | undefined } Renders BottomNavigationItem destinations with the active value.

TabBar<Value extends string>

Source: src/families/navigation/bottom-navigation/bottom-navigation.vue

Props

Prop Type Default Description
destinations (required) readonly Value[] required Destination values in order; their literal union types v-model and select.
modelValue Value undefined Controlled active destination. undefined selects uncontrolled behavior.
defaultValue Value undefined Initial uncontrolled destination.
ariaLabel string "Primary" Accessible name of the navigation landmark.
ariaLabelledby string undefined Ids that label the navigation landmark (overrides ariaLabel).

Events

Event Payload Description
update:modelValue [value: Value] Fired when an item requests to become the active destination.
select [value: Value, nativeEvent: MouseEvent] Fired after an item is activated, with its value and the native click.

Slots

Slot Slot props Description
default { readonly active: Value | undefined } Renders BottomNavigationItem destinations with the active value.

BottomNavigationItem

Source: src/families/navigation/bottom-navigation/bottom-navigation-item.vue

Props

Prop Type Default Description
value (required) string required Destination value; must be one of the root destinations.
href string undefined Link target. With href the item renders an <a>, otherwise a <button>.
disabled boolean false Disable the destination.
badge string | number undefined Badge text announced with the label (for example an unread count).

Slots

Slot Slot props Description
default { readonly active: boolean } Icon and label contents with the active state.
badge { readonly badge: string | number } Visual badge; its text is also announced through aria-describedby via badge.

TabBarItem

Source: src/families/navigation/bottom-navigation/bottom-navigation-item.vue

Props

Prop Type Default Description
value (required) string required Destination value; must be one of the root destinations.
href string undefined Link target. With href the item renders an <a>, otherwise a <button>.
disabled boolean false Disable the destination.
badge string | number undefined Badge text announced with the label (for example an unread count).

Slots

Slot Slot props Description
default { readonly active: boolean } Icon and label contents with the active state.
badge { readonly badge: string | number } Visual badge; its text is also announced through aria-describedby via badge.

Behavior

Normative state x input -> outcome table for bottom-navigation.vue and bottom-navigation-item.vue (@vizejs/ui/bottom-navigation, also exported as TabBar/TabBarItem). A bottom tab bar is navigation, not an APG tablist: it renders a labelled <nav> landmark and marks the current destination with aria-current="page". Every row is proven by the named test in bottom-navigation.test.ts or bottom-navigation-ssr.test.ts.

# State Input Outcome Proven by
BN1 seeded render <nav aria-label="Primary">; items with href render links, others type="button"; badges render; current item has aria-current="page" renders a labelled navigation landmark with links, buttons, and badges
BN2 uncontrolled click the item becomes current (aria-current, data-state="active") and emits update:modelValue then select activating an item moves aria-current and emits typed selections
BN3 controlled / disabled / unknown click controlled values win; disabled buttons are native-disabled, disabled links drop href with aria-disabled; unknown values never emit controlled values win, and disabled or unknown items do not activate
BN4 no provider setup items throw VIZE_UI_CONTEXT_MISSING: BottomNavigation items require a BottomNavigation provider
BN5 SSR / hydration isolated requests byte-identical markup and hydration without diagnostics renders byte-identical tab bar markup and hydrates without mismatches

Pair with SafeArea (edges: ["bottom"]) to clear home indicators. The subpath ships no CSS.