reference page 可以把 source 与实际 renderer output 放在一起。页面本身仍是只读的。live 示例只可暴露所展示 node 本来就有的交互,不能变成 source、manifest 或文档的 editor。
不要把所有渲染对象都当成同一种 component。Markdown directive 会先变成 document target 的 AUP tree;native AUP primitive 另有 target-specific 的支持范围;Web Device 的 .web component 则属于页面 layout,不能靠 generic Markdown directive 直接加载。本页只证明 document-target 上 Markdown → AUP 这条路径。
Sample 合同
| 字段 | 值 |
|---|---|
| 用途 | 未绑定的 document-target input,以及静态 UI 的 view mode tabs |
| 边界 | 无 bind、session patch、AFS 写入、exec、多字段表单或 layout-component API |
| 作者入口 | 内容 Markdown directive(::input、::::view) |
| 表面 | Web Device document target(静态预渲染 + 浏览器表单控件) |
| 公共状态 | 这两个节点在 document 上为 released |
| Fallback / 失败 | 缺 id → DOM id 碰撞风险;未知 tab 子节点仍作为 panel 渲染 |
| 验证 | arc --version = 2.0.0-beta.28;下列路由;窄屏仍可见控件 |
每个公开示例都应在同一位置记录:产生该 node 的 source;所需的 data 或 manifest 边界;实际渲染它的 target;读者应观察到的精确行为,以及有意不提供的行为。
document-target text input
这是一个未绑定的 AUP input node。它没有 bind、event、action、source path 或 write capability。需要时可以在里面输入。field 只作为 browser form control 改变;文档、manifest、AFS record 和 session setting 都不会改变。browser 在重新加载页面时可能恢复 form value,这是 browser 行为,不是 AUP persistence。
为每个 field 写显式 id。content reader 会把该属性提升为 node 顶层 id(arc#3321)。没有它时,同一页上多个 input 可能共用损坏的 DOM id。
Source:
::input{id="docs-live-name" type="text" label="Name" placeholder="Type only in this example" value="Ada"}Rendered:
读取本页的同一个 Web Device document renderer 会渲染此 field。它是真实的 document-target result,但不证明 bound form、AUP session patch 或 persistence。它只作为单个未绑定 field 的证据,不能当成可复制的多字段 live 表单模式。
失败与限制
| 情况 | 预期结果 |
|---|---|
::input 没有 id | field 仍渲染;同页多 field 时 DOM id 不稳定 |
在此 Markdown 中写 bind / session 字段 | 不在本合同内;不要在 docs 页发明 |
| 窄屏 | 标签、控件、placeholder 仍可读;不要求第二套 layout |
document-target 上 mode 为 tabs 的 view
view 是已发布的跨设备 primitive。在 document target 上,mode="tabs" 是静态 UI:radio 与 panel,不是独立 widget session。用 generic container directive 编写 tabs,以便嵌套 panel 正文被保留(arc#2598)。
Source:
::::view{id="docs-live-tabs" mode="tabs" label="Package manager"}
:::view{label="pnpm"}
使用 `pnpm install` 安装。
:::
:::view{label="npm"}
使用 `npm install` 安装。
:::
::::Rendered:
使用 pnpm install 安装。
使用 npm install 安装。
切换 tab 只改变浏览器中哪个 panel 可见。它不会写入内容、打开 AUP session,也不会执行 shell 命令。外层 fence 的冒号数必须多于内层 container,与其他 container directive 相同。
失败与限制
| 情况 | 预期结果 |
|---|---|
无正文的 leaf ::view | 空 panel / 无正文 |
| 外层 fence 冒号过少 | parser 误读结构;panel 可能丢失 |
tabs 容器无 label | tabs 仍渲染;tablist 不带 accessible name |
把 tabs 当成 layout .web component | 错误表面 — layout component 用 layout.aup,不是本 directive |
list 还必须补上什么
afs-list reference 需要独立的合同。source 必须写明 list layout 和 template;data section 必须写明只读 fixture 或已声明的 AFS path;页面还必须指出实际解析它的 renderer/session。static document target 能呈现 literal child node,但它本身不能证明 source-backed list 能读取任意 path。
当前 Showcase 的 list-basic source 是下一片切片的有用证据:它把 afs-list 绑定到 package 中的 data/items,list 本身没有 write action。在它成为 embedded runtime sample 前,应使用独立的最小 demo origin,而不是完整 Showcase;fixture data 保持只读,并验证 frame 没有 bridge、write 或 exec path。本页不声称已验证的 live afs-list sample。
验证证据
| 项 | 值 |
|---|---|
| 基线 | 2026-08-09 · arc --version → 2.0.0-beta.28 |
| 能力行 | docs/aup/capability-matrix.md (internal, non-routed) · input、view、::input |
| 实现 | providers/runtime/web-device/src/content-reader.ts(directive → AUP、id 提升);renderer/primitives/input.ts;renderer/primitives/view.ts(tabs) |
| 测试 | content-reader.test.ts(id 提升、嵌套 tabs);renderer/primitives.test.ts(tabs ARIA / radio) |
| 公开路由 | /zh/docs/aup/live-example-contract/ · /en/docs/aup/live-example-contract/ |
| 本地运行 | arc service start --blocklet blocklets/arcblock --port 4900,打开上述路由(桌面 + 约 390px 宽) |
| 验收 | source fence 与渲染控件一致;输入仅本地;tab 切换不产生网络写入 |
隔离边界见 Frame、bridge 与嵌入 surface;static Web Device 与 interactive AUP session 的区别见 AUP 在 Web Device 中。