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.

```tsx demo="layouts/docs-layout-preview"
```

## Usage

```tsx
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:

```tsx demo="layouts/docs-layout-two-column"
```

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:

```tsx
import { AsheeUIProvider } from "@asheeui/web";

<AsheeUIProvider
  config={{
    components: {
      docslayout: {
        navigationLabel: "Guides",
        tocLabel: "Sections",
        skipLinkLabel: "Skip to the article",
      },
    },
  }}
>
  <App />
</AsheeUIProvider>;
```

## Props

```props DocsLayout
```

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 `main` landmark, carrying `mainId` and `tabIndex={-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 <kbd>Tab</kbd> reaches.
- The navigation column is a complementary landmark named by `navigationLabel`, and the contents are
  a second one named by `tocLabel`, rendered only when `toc` is 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 `xl` the 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](/concepts/layout-and-spacing) vocabulary; which shell a product should start
from is the argument in [Page compositions](/guides/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](/platforms/native).

## Related

```related sidebar, link, navbar
```
