`. Each update re-parses and patches the host; already-initialized custom elements skip their setup, and scroll position is preserved. The RPML language and primitives below are identical regardless of which renderer you use. Full guide: `spec/react.md`.
ARIA note: component states (checked / expanded / selected / disabled / current / pressed) follow the structure that the W3C ARIA Authoring Practices expect, so annotations can describe accessibility intent precisely. RPUI is static and does not emit runtime `role` / `aria-*` attributes — treat ARIA as a reference for which states to expose and document, not as runtime behavior.
## Core model
RPUI has two layers:
1. Canvas layer: page shell, main snapshot view, numbered pins, annotations, nested annotations, and state enums.
2. Snapshot Primitive layer: static UI building blocks for product UI snapshots and annotation slices.
RPML is the authoring language. Its tags are clean single words (`page`, `view`, `button`, `navigator`); the runtime maps them onto Web Component tag names. Write the language tags below — do not write the underlying component tags.
## Canvas tags
```html
...
```
Tags:
- `
` — root document canvas. Default (`snapshot`) keeps the title/main snapshot on the left and moves top-level annotations to the right-side scroll pane. `mode="doc"` switches to a single top-to-bottom document column with no `route` badge (see "Document mode" below).
- `` — scaled main snapshot frame. Device presets are fixed width with auto height unless a numeric `height` is provided.
- `` — snapshot viewport. Use the same `device` as the view for clarity.
- `` — top-level annotation linked to `data-pin="1"`; rendered in the right annotation pane.
- `` — nested annotation; no `id` required.
- `` — page-level, pin-less annotation for cross-cutting notes (permission matrix, glossary, global empty/error policy, conventions). Rendered at the **top** of the annotation pane, above the numbered annotations. Has no `id` and no pin. Use this instead of a numbered annotation for anything that doesn't map to one snapshot region.
- `` — horizontal state/variant container.
- `` — one explicit state/variant card with optional short description.
- `` — cross-page link to another prototype screen in the file set. `section` is optional and deep-links a specific annotation on the target page. Works in the gallery (playground / `serve` / compiled single-file) and degrades to a `?rpml=` reload in the standalone viewer.
- `` — renders Mermaid text (flowchart / state / sequence / class / ER) to inline SVG. Place inside an annotation to specify a flow or state machine. Put the diagram header on its own line. Theme is automatically selected based on the current light/dark mode (github-light / github-dark).
## Document mode
Set `mode="doc"` on `` to render a single top-to-bottom reading column instead of the snapshot canvas — like Markdown built from RPML elements. There is no scaled ``, no `data-pin` overlays, no right-hand annotation pane, and no `route` badge (documents don't map to one screen). Every child flows in source order. Use this for linear prose (release notes, specs, requirements). For interaction states, permission variants, and hidden UI, keep the default snapshot mode.
```html
RPUI 0.9 发布说明
文档模式把页面渲染成单栏可读文档,每一块都是 RPML 原语。
新增 doc-* 排版原语。
页面级 mode="doc" 切换文档流。
文档模式用来排布说明,而非绘制 UI。
```
Document typography primitives (only meaningful inside `mode="doc"`):
- `` — heading; `level` defaults to `1`, and `level="2"` and up get a bottom border.
- `` — paragraph; may contain inline `strong` / `em` / `code` / `a`.
- `` + `` — ordered/unordered list.
- `` — blockquote; `cite` renders as a `— 来源` line below the quote.
Ordinary snapshot primitives (e.g. ``, ``, ``) can also appear in the document flow as inline examples; they render in source order. The validator skips `view`/pin/annotation requirements in doc mode and only checks for `title`.
## Pin rule
Inside ``, add `data-pin="N"` to meaningful regions. Number pins from 1 without gaps. Pin as many regions as the page actually has — there is no target count, and none should be padded in or dropped to hit one.
Pin↔annotation parity is strict and bidirectional. Every `data-pin="N"` has exactly one matching top-level ``, and every numbered `` has exactly one matching `data-pin="N"`:
```html
...
...
```
A numbered annotation with no pin is a defect. For cross-cutting notes that don't map to one region (permission matrix, glossary, global policy), use `` — it is pin-less by design and renders at the top of the pane.
RPUI renders water-drop pins automatically. Never write pin DOM manually.
## Section addressing, deep links, and enum numbering
The runtime makes the canvas navigable. Authors do not write any of these attributes — they are generated:
- Every annotation gets a `data-rp-section` path. Top-level annotations use their `id` (e.g. `3`); nested annotations use the parent path plus their 1-based position among annotation siblings (e.g. `3-2`, `3-2-1`). This supports up to 3–5 levels of nesting.
- Every annotation renders a marker showing its **local index** (the last path segment): top-level = blue water-drop with the id; nested depth 1 = purple circle; nested depth ≥2 = green triangle. A nested annotation at `3-2` is marked `2`, at `3-2-1` is marked `1` — local to its parent, not the full path.
- To explain a UI slice that is rendered inside an annotation, nest another `` around/after it. The nested annotation gets its own numbered circle/triangle marker and its body indents one level: `view → ⬤ annotation 3 → UI slice → ① nested annotation → detail`.
- Clicking a pin in the main snapshot, or clicking an annotation title, updates the URL to `?section=` and scrolls/focuses the matching annotation with a dashed-outline highlight.
- Loading a URL with `?section=3-2-1` focuses that nested annotation on load (reverse deep link).
- Each `` is auto-numbered with a black square index badge (1, 2, 3…), so annotation prose can reference "state 2" unambiguously.
Keep annotation and enum-item sibling order intentional and stable: the generated addresses depend on DOM order.
## Layout and state rules
- RPUI is static. Do not create interactions.
- Do not use `onclick`, hover behavior, runtime focus, timers, API calls, or framework state.
- Do not use external images; use ``.
- Do not use `position:absolute` or `position:fixed` in snapshot content. RPUI owns pin positioning.
- Do not use raw `div`, `button`, `input`, or `table` to represent product UI. Use RPML primitives.
- Basic text and simple inline HTML are allowed inside annotations.
- Top-level annotations render automatically in the right-side annotation pane. Do not manually create annotation pane wrappers.
- The title/route/description and main snapshot stay visible on the left while the annotation pane scrolls independently on both axes.
- Keep annotations compact and document-flow oriented. Do not stretch annotation content to full width.
- Choose a device preset for new prototypes: `web` (1440px), `ipad` (834px), or `mobile` (390px). Presets use fixed width and auto height unless a numeric height is provided.
- In the main snapshot, keep selects collapsed; show their expanded list in an annotation enum.
- Overlays and transient feedback — `modal`, `drawer`, `dropdown`, `popover`, `tooltip`, `toast` — are interaction results, not page regions. Do not place them in the main snapshot. Instead: pin the trigger element (button/row/field), state the trigger condition in the annotation, and render the overlay inside that annotation (usually in an ``). Never stack mutually exclusive overlays/states side by side in the snapshot. A permanently docked side panel may stay open in the snapshot, but document its open/close trigger anyway.
- Use `` for state families, permission variants, hidden interaction results, and validation branches. Use `enum-item description="..."` for a short clarification of a state.
## Snapshot primitives
### Containers
- `` — fixed-width snapshot viewport; presets default to auto height.
- `` — CSS grid container.
- `` — white panel/card shell.
- `` — content card.
- `` — static opened modal.
- `` — static opened drawer.
- `` — static opened dropdown.
- `` — static opened popover.
- `` — visible tooltip bubble.
- `…children…` — custom-styled scrollable container.
- `…children…` — expand/collapse section.
- `…children…` — container maintaining width/height ratio.
### Navigation
- `` — top navigation container.
- `` — side navigation container.
- `` — logo placeholder.
- `` — generated list when no children are provided.
- ``.
- `` with ``; `active` can be index or label.
- ``.
- ``.
- ``.
### Data and content display
- `