Skip to content

BottomNav

BottomNav provides a mobile-style fixed bottom navigation bar with touch-friendly items.

Quick Start

from faststrap import BottomNav, BottomNavItem

BottomNav(
    BottomNavItem("Home", href="/", icon="house", active=True),
    BottomNavItem("Search", href="/search", icon="search"),
    BottomNavItem("Profile", href="/profile", icon="person"),
)

Common Usage

BottomNav(
    BottomNavItem("Feed", href="/feed", icon="newspaper"),
    BottomNavItem("Saved", href="/saved", icon="bookmark"),
    BottomNavItem("Settings", href="/settings", icon="gear"),
    variant="light",
    fixed=True,
)

Parameters

BottomNav

Parameter Type Default Description
*children Any Required BottomNavItem children
variant str \| None None Color scheme (light, dark, or custom)
fixed bool \| None True Fixed to viewport bottom
labels bool True Reserved for label visibility behavior
**kwargs Any - Additional HTML attributes

BottomNavItem

Parameter Type Default Description
label str Required Item text
href str "#" Link destination
icon str \| None None Bootstrap icon name
active bool False Active route styling
cls str \| None None Extra classes
**kwargs Any - Additional attributes

faststrap.components.navigation.bottom_nav.BottomNav(*children, variant=None, fixed=True, labels=True, **kwargs)

Bottom Navigation Bar for mobile applications.

Parameters:

Name Type Description Default
*children Any

BottomNavItem components

()
variant str | None

Color scheme (light, dark, or custom class)

None
fixed bool | None

Fix to bottom of viewport (default: True)

True
labels bool

Show labels (True) or icons only (False)

True
**kwargs Any

Additional attributes

{}
Source code in src/faststrap/components/navigation/bottom_nav.py
@register(category="navigation")
def BottomNav(
    *children: Any,
    variant: str | None = None,
    fixed: bool | None = True,  # Default to fixed-bottom which is standard for apps
    labels: bool = True,
    **kwargs: Any,
) -> Nav:
    """Bottom Navigation Bar for mobile applications.

    Args:
        *children: BottomNavItem components
        variant: Color scheme (light, dark, or custom class)
        fixed: Fix to bottom of viewport (default: True)
        labels: Show labels (True) or icons only (False)
        **kwargs: Additional attributes
    """
    cfg = resolve_defaults("BottomNav", variant=variant)
    c_variant = cfg.get("variant", "light")

    classes = ["navbar", "navbar-bottom", "w-100"]

    if fixed:
        classes.append("fixed-bottom")

    if c_variant == "dark":
        classes.append("bg-dark")
        classes.append("navbar-dark")
    elif c_variant == "light":
        classes.append("bg-white")  # Stronger than bg-light for bottom nav
        classes.append("navbar-light")
    else:
        classes.append(f"bg-{c_variant}")

    # Add border top for separation
    classes.append("border-top")

    # Merge user classes
    user_cls = kwargs.pop("cls", "")
    all_classes = merge_classes(" ".join(classes), user_cls)

    # Custom styles to ensure equal width items
    style = kwargs.pop("style", {})
    if isinstance(style, str):
        # Determine if it's string style, if so prepend
        style = f"padding-bottom: env(safe-area-inset-bottom); {style}"
    else:
        style["padding-bottom"] = "env(safe-area-inset-bottom)"  # iPhone Home Bar support

    attrs = {"cls": all_classes, "style": style}
    attrs.update(convert_attrs(kwargs))

    # Pass configuration down to children if needed context existed
    # For now, children (BottomNavItem) are independent

    content = Div(
        *children,
        cls="container-fluid d-flex flex-nowrap justify-content-around align-items-center h-100 px-0",
    )

    return Nav(content, **attrs)

faststrap.components.navigation.bottom_nav.BottomNavItem(label, href='#', icon=None, active=False, cls=None, **kwargs)

Individual item for BottomNav.

Parameters:

Name Type Description Default
label str

Text label

required
href str

Link URL

'#'
icon str | None

Bootstrap icon name (e.g., "house", "person")

None
active bool

Active state

False
cls str | None

Custom classes

None
**kwargs Any

Additional attributes

{}
Source code in src/faststrap/components/navigation/bottom_nav.py
@register(category="navigation")
def BottomNavItem(
    label: str,
    href: str = "#",
    icon: str | None = None,
    active: bool = False,
    cls: str | None = None,
    **kwargs: Any,
) -> A:
    """Individual item for BottomNav.

    Args:
        label: Text label
        href: Link URL
        icon: Bootstrap icon name (e.g., "house", "person")
        active: Active state
        cls: Custom classes
        **kwargs: Additional attributes
    """
    classes = [
        "nav-link",
        "d-flex",
        "flex-column",
        "align-items-center",
        "justify-content-center",
        "w-100",
        "flex-grow-1",
        "py-2",
    ]

    if active:
        classes.append("active")
        kwargs["aria-current"] = "page"

    # Merge user classes
    all_classes = merge_classes(" ".join(classes), cls)

    parts = []
    if icon:
        # Icon size should be slightly larger for touch targets
        parts.append(Icon(name=icon, size="1.25em", cls="mb-1" if label else ""))

    if label:
        parts.append(Small(label, cls="d-block", style="font-size: 0.75rem; line-height: 1;"))

    return A(*parts, href=href, cls=all_classes, **convert_attrs(kwargs))