Docs
Customizing the layout
Compose the render primitives instead of using the default shell.
DocsShell renders a complete docs page: sidebar, article, table of contents, pager. It emits the whole document, <head> included. Most sites never need more.
use proa_docs::DocsShell;
DocsShell { docs, page }.render(cx)?;
DocsShell writes its own <head> (charset, viewport, title, description)
and has no slot for a stylesheet link, so the default theme only applies when
you compose your own head and render DocsAssets there, as shown in
Styling. DEFAULT_STYLESHEET and
DEFAULT_SCRIPT are the bytes to serve for it.
When you want your own chrome, compose the pieces yourself.
The primitives
| Component | Renders |
|---|---|
DocsShell | The whole page. Start here |
DocsNav | The sidebar tree for a path |
DocsNavItem | One nav entry, if you are building the tree yourself |
DocsSectionMenu | The section switcher, when any folder is a root |
DocsToc | On-this-page headings |
DocsPager | Previous and next links |
TypeTable | An API table from rows your app supplies; the build does not produce them |
nav_icon_svg | An icon by name, for your own chrome |
Apart from TypeTable, each takes data from the compiled Docs registry, so they stay in sync with content without threading state.
Replacing one piece
Keep the primitives, wrap them in your own markup. This is what the Proa site does — its sidebar adds a logo, a search trigger, and a theme toggle around the same DocsNav you would use:
use proa_docs::{DocsNav, DocsSectionMenu};
html_sync! {
<div class="docs-sidebar-inner">
<div class="docs-sidebar-header">
{SearchTrigger { class: Some("docs-sidebar-search") }}
{DocsSectionMenu { docs, active_path: page.route_path }}
</div>
<div class="docs-sidebar-content">
{DocsNav {
items: docs.nav_items_for_path(page.route_path),
active_path: page.route_path,
}}
</div>
</div>
}
proa_marketing/src/components/docs/ in the Proa repository is the full worked example — sidebar, article, and page, each wrapping primitives rather than replacing them.
Reading the registry directly
For chrome the primitives do not cover, walk the model:
| Type | Holds |
|---|---|
Docs | Config, every page, the nav tree, search artifacts |
DocPage | Slug, route, title, description, article HTML, TOC, prev/next |
NavItem | One nav node: page, group, separator, or root |
TocItem | Depth, id, title |
let page = docs.page_for_path(path)?;
let items = docs.nav_items_for_path(page.route_path);
nav_items_for_path returns a root section's children when the path is inside one, and the whole tree otherwise. That single call is what makes the section switcher work.
Styling what you build
The primitives emit stable class and data- hooks, all documented in Styling contract. Your own wrapper markup is yours to style; the parts you compose keep working with the default theme.