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.