Breadcrumb

Rust UI component that displays the path to the current resource using a hierarchy of links.

navigation
  • Rust UI Icons - CopyCopy Demo
use leptos::prelude::*;

use crate::components::ui::breadcrumb::{
    Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator,
};

#[component]
pub fn DemoBreadcrumb() -> impl IntoView {
    view! {
        <Breadcrumb>
            <BreadcrumbList>
                <BreadcrumbItem>
                    <BreadcrumbLink href="/">Home</BreadcrumbLink>
                </BreadcrumbItem>

                <BreadcrumbSeparator />

                <BreadcrumbItem>
                    <BreadcrumbEllipsis />
                </BreadcrumbItem>

                <BreadcrumbSeparator />

                <BreadcrumbItem>
                    <BreadcrumbLink href="/demo-components/button">Button</BreadcrumbLink>
                </BreadcrumbItem>

                <BreadcrumbSeparator />

                <BreadcrumbItem>
                    <BreadcrumbPage>"Breadcrumb"</BreadcrumbPage>
                </BreadcrumbItem>
            </BreadcrumbList>
        </Breadcrumb>
    }
}

Installation

You can run either of the following commands:

# cargo install ui-cli --force
ui add demo_breadcrumb
ui add breadcrumb

Update the imports to match your project setup.

Copy and paste the following code into your project:

components/ui/breadcrumb.rs

use icons::{ChevronRight, Ellipsis};
use leptos::prelude::*;
use leptos_ui::{a, clx};

mod components {
    use super::*;
    clx! {Breadcrumb, nav, ""}
    clx! {BreadcrumbList, ol, "flex flex-wrap gap-1 items-center text-sm break-words sm:gap-2 text-muted-foreground"}
    clx! {BreadcrumbItem, li, "inline-flex gap-1 items-center [&_svg:not([class*='size-'])]:size-4"}
    a! {BreadcrumbLink, "transition-colors hover:text-foreground"}
    clx! {RootSeparator, li, "[&>svg]:size-3.5 [&_svg:not([class*='size-'])]:size-4"}
    clx! {RootPage, span, "font-normal text-foreground"}
    clx! {RootEllipsisBtn, button, "flex items-center gap-1"}
    clx! {RootEllipsis, span, "flex items-center justify-center size-4"}
}

pub use components::*;

/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/*                     ✨ FUNCTIONS ✨                        */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

#[component]
pub fn BreadcrumbSeparator(#[prop(into, optional)] class: Signal<String>) -> impl IntoView {
    view! {
        <RootSeparator class=class role="presentation" aria_hidden="true">
            <ChevronRight />
        </RootSeparator>
    }
}

#[component]
pub fn BreadcrumbPage(#[prop(into, optional)] class: Signal<String>, children: Children) -> impl IntoView {
    // TODO. aria_disabled
    view! {
        <RootPage class=class role="link" aria_disabled="true" aria_current="page">
            {children()}
        </RootPage>
    }
}

#[component]
pub fn BreadcrumbEllipsis(#[prop(into, optional)] class: Signal<String>) -> impl IntoView {
    // TODO. data_state
    view! {
        <RootEllipsisBtn aria_haspopup="menu" aria_expanded="false" data_state="closed">
            <RootEllipsis role="presentation" aria_hidden="true">
                <Ellipsis class=class />
                <span class="sr-only">More</span>
            </RootEllipsis>
            <span class="sr-only">Toggle menu</span>
        </RootEllipsisBtn>
    }
}

Update the imports to match your project setup.

Usage

use crate::components::ui::breadcrumb::{
    Breadcrumb,
    BreadcrumbEllipsis,
    BreadcrumbItem,
    BreadcrumbLink,
    BreadcrumbList,
    BreadcrumbPage,
    BreadcrumbSeparator,
};
<Breadcrumb>
    <BreadcrumbList>
        <BreadcrumbItem>
            <BreadcrumbLink href="/">"Home"</BreadcrumbLink>
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
            <BreadcrumbPage>"Current Page"</BreadcrumbPage>
        </BreadcrumbItem>
    </BreadcrumbList>
</Breadcrumb>