DocsLayout
The documentation composition, a navigation column, an article, and an optional table of contents beside it.
DocsLayout is the arrangement a documentation page is built in: the site's navigation column, the article, and, when the article is long enough to need one, a table of contents. It composes the application shell and the split layout instead of restating them, so the sticky navigation, the stacked narrow screen and the responsive columns are the behaviour those primitives already provide.
What it adds is the page's structure: a main the skip link leads to, a named navigation column, a
named contents region, and the skip link itself as the first focusable element.
Usage
import {
DocsLayout,
Link,
Navbar,
Sidebar,
Typography,
VStack,
} from "@asheeui/web";
<DocsLayout
header={<Navbar brand="AsheeUI" links={links} />}
navigation={<Sidebar items={sections} activeKey="layout" />}
toc={
<VStack gap="xs">
<Link href="#grid" variant="muted" size="sm">
The grid
</Link>
</VStack>
}
>
<Typography role="display">Layouts</Typography>
<Typography role="body-md">A page is composed from the layout layer.</Typography>
</DocsLayout>;
navigation is the only required slot. children is the article, header and footer sit around
everything, and toc decides whether the page has two columns or three.
Two columns, or three
toc is what decides. Left out, the page is a navigation column and the article:
A changelog, a migration note or a reference page that is read from top to bottom rarely needs an
outline of itself, and stating no toc is how the page says so. Supplied, the contents take a third
column from the xl breakpoint (1280 pixels), 16rem wide and placed after the article; below it
they are hidden, because they repeat headings that are still in the article. That is why the same
page is complete at every width without a drawer, a disclosure or a second copy of the article's
outline.
stickyToc keeps the contents in view while the article scrolls, top: 0, position: sticky,
from the same xl breakpoint. Turn it off for a contents list shorter than the viewport that reads
better in the flow. stickyNavigation does the same for the navigation column from lg: it is
passed through to the shell's stickySidebar, so a documentation page whose navigation is a short
list can let the column leave with the article rather than pinning it.
The skip link and the region names
A documentation page leads with navigation, so the composition renders a skip link as its first
focusable element: an anchor to the article's identifier, visually hidden until it is focused. The
article is a main with that identifier and tabIndex={-1}, so following the link moves focus into
the content rather than only scrolling to it. mainId names the identifier, main-content by
default, and skipLink={false} removes the link for a page whose navigation is already short
enough to walk through.
Both region names are configuration rather than markup, and so is the wording of the link:
import { AsheeUIProvider } from "@asheeui/web";
<AsheeUIProvider
config={{
components: {
docslayout: {
navigationLabel: "Guides",
tocLabel: "Sections",
skipLinkLabel: "Skip to the article",
},
},
}}
>
<App />
</AsheeUIProvider>;
Props
Seven options are registered by the component, so each resolves from the instance, then from
components.docslayout, then from the registration: navigationLabel Documentation, tocLabel
On this page, navigationWidth md, stickyNavigation true, stickyToc true, skipLink
true and skipLinkLabel Skip to content. navigationWidth takes the same sm/md/lg column
widths SidebarLayout does, 14rem, 16rem and 20rem from lg. mainId is instance-only and
defaults to main-content: an identifier belongs to the page, and a page with more than one
composition on it gives each one its own. The four slots and as are instance-only too.
Accessibility
- The article is the
mainlandmark, carryingmainIdandtabIndex={-1}, so the skip link both scrolls to it and moves the reader into it. - The skip link is the first focusable element of the page. It is visually hidden until focused, so it does not appear to a pointer reader, and it is the first thing Tab reaches.
- The navigation column is a complementary landmark named by
navigationLabel, and the contents are a second one named bytocLabel, rendered only whentocis supplied, so a landmark list names both regions rather than offering two asides of which one is unnamed. - The shell supplies no heading at all. The article's first heading is the page's
<h1>, and the contents list you pass is markup rather than an outline, so give its visible title the treatment the rest of the page uses for a label rather than a second heading level. - Below
xlthe contents column is hidden, not moved: nothing in it is reachable at that width, which is the point, because the article's own headings stay where they were written.
The widths and the spacing between the columns are the Layout and spacing vocabulary; which shell a product should start from is the argument in Page compositions.
Native
@asheeui/native ships the same contract as its own DocsLayout: one column, with the navigation,
the article and the contents stacked in the order the web's narrow layout gives them, and the whole
screen a scroller because three stacked regions do not fit a phone at once. The platform has no
landmark vocabulary, so navigationLabel and tocLabel become the titles that head the two
sections, and navigationWidth, stickyNavigation, skipLink and stickyToc resolve through the
contract without changing the rendering: the platform stacks and scrolls the whole screen, so there
is nothing to pin. See React Native.