日本語

Navigation

Links between the pages of an application: a list of its sections, a breadcrumb trail, and the pages of a long list.

Result

navigation.rs
use hypersig::html::div;
use hypersig::style::Style;
use hypersig::style::pattern::stack;
use hypersig::style::value::{Display, raw, rem};
use hypersig::{Page, Rest, Signals};
use hypersig_ui::{Breadcrumb, NavList, PaginationText, pagination};
use serde::{Deserialize, Serialize};

use crate::doc::{Component, Doc};
use crate::{PAGE, Site};

#[derive(Signals, Serialize, Deserialize)]
pub struct Docs {
    title: String,
}

/// The component pages the pagination steps through.
const PAGES: [Component; 6] = [
    Component::Tabs,
    Component::Accordion,
    Component::Card,
    Component::Separator,
    Component::Navigation,
    Component::DataTable,
];

/// The path of `doc` inside this site, as `PAGE` takes it.
fn at(site: Site, doc: Doc) -> Rest {
    Rest::new(doc.url(site).trim_start_matches('/'))
}

pub fn page() -> Page<Docs> {
    let here = Doc::Components(Component::Navigation);
    let sections = NavList::new(
        "Sections",
        PAGE.url(at(site, here)),
    )
    .item(
        "Installation",
        PAGE,
        at(site, Doc::Components(Component::Installation)),
    )
    .item(
        "Navigation",
        PAGE,
        at(site, here),
    )
    .item(
        "Dialog",
        PAGE,
        at(site, Doc::Components(Component::Dialog)),
    );
    let trail = Breadcrumb::new("Breadcrumb")
    .link(
        "Components",
        PAGE.link_with(&at(site, Doc::ComponentsHome)),
    )
    .current("Navigation");
    let text = PaginationText {
        label: "Pagination"
            .into(),
        previous: "Previous"
            .into(),
        next: "Next"
            .into(),
    };
    let pager = pagination(
        5,
        6,
        |page| PAGE.link_with(&at(site, Doc::Components(PAGES[page as usize - 1]))),
        &text,
    );
    let initial = Docs {
        title: here.title(site).into(),
    };
    Page::new(
        "Docs",
        initial,
    )
    .child(
        div()
            .css(
                Style::new()
                    .display(Display::Grid)
                    .grid_template_columns(raw("9rem 1fr"))
                    .gap(rem(1.5)),
            )
            .child(sections)
            .child(div().css(stack(rem(1.5))).child(trail).child(pager)),
    )
}

Accessibility

Each is a <nav> named by the label it takes, holding a list of links, so a screen reader lists it among the page's landmarks. The links are typed Link values from routes, and the one to the page the visitor is on has aria-current="page".

NavList decides the mark on the server, from the page's own Url that Route::url writes. A link to the same path has aria-current="page", and a link to a path that the page's path continues has aria-current="true". Breadcrumb::current ends the trail with the current page as text and returns the element, so no link can follow it. pagination shows the first and the last page and the pages next to the current one, and marks the link to the page before or after aria-disabled where there is none. The links in the demo lead to pages of this site.

API

ItemSummary
NavList::newAn empty list whose <nav> is named label, on the page at current.
itemAdds a link to route with the arguments args, as Route::url takes them.
Breadcrumb::newAn empty trail whose <nav> is named label, such as "Breadcrumb".
linkAdds a link to a page above the current one, after the links before it.
currentThe trail, ending at the current page text.
paginationLinks to the pages of a list of count pages, on page current.
PaginationTextThe words pagination names its parts with.