{
  "slug": "document-form",
  "schemaVersion": 2,
  "sourceKind": "structured-spec",
  "confidence": "high",
  "intent": "分组单据表单",
  "implementation": "workbench.css",
  "behavior": "workbench.js",
  "preview": "examples/object-page.html",
  "reference": "examples/object-page.html",
  "specification": "WORKBENCH.md",
  "api": {
    "initObjectPage": "initObjectPage(root, { edit, footer, messages, validate, onSave, saved }) → { enter, save, cancel, isDirty, destroy }"
  },
  "variantDimensions": [
    {
      "axis": "mode",
      "values": [
        "read",
        "edit"
      ]
    },
    {
      "axis": "layout",
      "values": [
        "single",
        "pair",
        "side"
      ]
    }
  ],
  "anatomy": {
    "parts": [
      "card",
      "card-title",
      "group",
      "group-title",
      "label",
      "colon",
      "required-mark",
      "value",
      "source-mark",
      "control",
      "value-state",
      "edit-footer",
      "message-button",
      "message-list"
    ],
    "required": [
      "card",
      "label",
      "value"
    ]
  },
  "markup": {
    "card": "<section class=\"wb-doc-card\" aria-labelledby=\"c-basic\"><div class=\"wb-doc-card-head\"><h2 id=\"c-basic\">基本信息</h2></div><div class=\"wb-doc-group\"><h3 class=\"wb-doc-group-title\">项目</h3><div class=\"wb-form-col\">…</div></div></section>",
    "row": "<div class=\"wb-form-row\"><div class=\"wb-form-label\" id=\"l-name\">项目名称<span class=\"wb-colon\" aria-hidden=\"true\">：</span><span class=\"wb-form-required\" aria-hidden=\"true\">*</span></div><div class=\"wb-form-value\" tabindex=\"0\" aria-labelledby=\"l-name\"><span class=\"wb-read wb-form-text\"><span class=\"wb-value is-editable\">华东仓储改造</span></span><span class=\"wb-edit\"><input class=\"wb-edit-input\" name=\"name\" aria-labelledby=\"l-name\" required></span></div></div>",
    "groups": "<span class=\"wb-edit is-groups\"><span class=\"wb-edit-group\"><input class=\"wb-edit-input is-number\" aria-label=\"账期 天数\" size=\"4\"><span>天，</span></span><span class=\"wb-edit-group\"><select class=\"wb-edit-input\" aria-label=\"账期 起算点\">…</select><span>起算</span></span></span>",
    "footer": "<div class=\"wb-edit-footer\" role=\"toolbar\" aria-label=\"编辑\"><button type=\"button\" class=\"wb-msg-btn\"></button><span class=\"wb-spacer\"></span><button type=\"button\" class=\"wb-btn primary\" data-action=\"save\">保存</button><button type=\"button\" class=\"wb-btn\" data-action=\"cancel\">取消</button></div>"
  },
  "rules": [
    "正文 .wb-document.is-capped 最宽 documentMaxWidth 1328px 加卡片和小节的内边距，窗口更宽时右边留白",
    "分区是 1px 描边的卡片 .wb-doc-card；卡片里只套一层次级底色的小节 .wb-doc-group，小节标题前 3px 蓝色竖条",
    "表单一列 480～640px；两个都短的小节并排（.wb-doc-pair），表单加表格并排（.wb-doc-side），容器宽于 1008px 才并排",
    "标签按表单列宽度定位置：宽于 480px 时在左、148px、左对齐、后跟全角冒号；窄于 480px 时在上、不加冒号",
    "显示态和编辑态用同一套行；页眉其他操作加 data-edit-hide 只隐藏不移除，进出编辑态时页面不移动",
    "进入编辑态：「编辑」、E、双击能改的值、在聚焦的值上按 Enter 或 F2；焦点落在双击的那一项或第一个必填空框",
    "保存先校验全部字段；有错误不存并打开消息列表；服务端确认后才回到显示态；失败留在编辑态、输入不丢",
    "有改动时取消先问，按钮「继续编辑」和红字「放弃改动」；回到显示态后焦点落在「编辑」",
    "能改的值下面虚线；要核对的值只在文字底下浅黄 warning-mark；必填没写红字浅红底 danger-bg；整行不上底色",
    "一个值一个框时框占满值的格子；几段的值拆成「文字 + 框 + 单位」的组，组内不折行；自由文字用自动加高的多行框；下拉空选项写「–」",
    "框只有下边线，高 hitMin 32px、上下各用 -4px 外边距收回，进出编辑态时行高不变"
  ],
  "states": [
    "read",
    "edit",
    "dirty",
    "invalid",
    "warning",
    "saving",
    "save-failed",
    "conflict",
    "focus-visible",
    "readonly",
    "empty"
  ],
  "keyboard": [
    "E 进入编辑态（单字母键，可在设置里关闭）",
    "在聚焦的值上按 Enter 或 F2 进入编辑态，焦点落在这一项",
    "⌘ / Ctrl + Enter 保存编辑态",
    "消息列表里的每一条是按钮，Enter 跳到那一个框"
  ],
  "accessibility": [
    "所有输入有标签；反馈文本可被读屏读取",
    "触摸目标至少 44px；键盘焦点可见",
    "不靠色彩表达状态；不把原生表格声明为未实现键盘导航的 ARIA grid",
    "编辑态的框用 aria-labelledby 指向标签，几段的值每个框有自己的 aria-label",
    "值状态的说明错误用 role=alert、提醒用 role=status；消息按钮有可访问名「消息 N 条」",
    "冒号和必填星号 aria-hidden，读屏只读标签"
  ],
  "doNotInvent": [
    "彩色状态胶囊",
    "蓝色整行选中",
    "卡片阴影",
    "通过缩小字号到 12px 以下提高密度",
    "给要核对或缺失的值整行上底色",
    "编辑时另开弹窗或另一套版式",
    "编辑态移除页眉按钮让页面上移",
    "标签右对齐或宽度随文字变化",
    "把破坏性的「放弃改动」做成蓝色主按钮"
  ]
}
