Uh oh!
There was an error while loading. Please reload this page.
fix(app-shell): metadata 详情抽屉的 SchemaForm 按实例作用域取 id (#5092) - #5105
Conversation
… instance (#5092) MetadataDetailDrawer is a Radix Sheet, so opening it leaves the page's own SchemaForm mounted underneath. Top-level field ids were spelled `mdf-{field}` with no instance dimension, so every field name the two forms share (name, label, description) appeared twice in one document — and a `label[for]` resolves to the FIRST match in document order, i.e. the page form. The drawer's labels focused, and assistive tech announced, the controls of the form the drawer covers. Both drawer-side mount points now pass an id scope segment as their form's `idPath` (the ancestor path objectui#5062 already threads): the embedded MetadataResourceEditPage and EmbeddedItemEditor. The page form passes nothing, so its top-level ids are byte-for-byte unchanged — #5062's "top level does not move" ruling is untouched. Scoping per mount point relies on every host remembering to pass a segment, so dev builds now report any duplicate `mdf-` host id in the document. A future second-form mount point that forgets one fails loudly instead of silently re-crossing the wires. Production is untouched: the check is behind a NODE_ENV gate and the outermost form of a subtree runs it, not every nested one. Co-authored-by: Claude <noreply@anthropic.com>
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
yinlianghui
commented
Aug 18, 2026
PM 验收:ACCEPT(session_01GTRjn8xBqp75dk7kFupVRt,objectui 分片) 实物核验:merge-base CI 亲读(jobs 端点,步级时间戳):19/20 终态全绿零失败(4 个 Test shard、Type Check、Lint、Live E2E、Bundle Analysis 等全 success,2 skipped 为 path-filter);唯一未终态是 Build & E2E,停在 Playwright 系统依赖安装步、无任何报错,且本单两次实证该端点有读数滞后(shards 实际 00:36-37 完成、端点报 in_progress 半小时)—— auto-merge 的语义即「绿才合、红不合」,把最后一格终态交给它,若意外转红 PM 下一跳处置。 验收要点:
三件套照常:本评论 → undraft → auto-merge(SQUASH)。#5091/#5097 家族裁定(是否走方向 1 的 useId 命名空间)不受本单阻塞,维护者可随时在 #5092 否决方向 3 —— 方向 1 覆盖方向 3,现落地不构成障碍。 Generated by Claude Code |
Uh oh!
There was an error while loading. Please reload this page.
Fixes#5092
按 PM 裁定评论 #5092 (comment) 取方向 3(= 方向 2「宿主显式传作用域」+ 开发期重复 id 断言)。方向 1(
useId()实例命名空间)是顶层 id 契约变更,属维护者题,裁定里留了否决窗 —— 本 PR 落的 3 对既有面是纯加法,不构成 1 的障碍。基线
fc1511152(已含 PR #5096 的idPath贯穿,本卡直接复用)。前提复测(在含 #5096 的新基线上逐条重测,卡面读数全部成立)
ResourceEditPage.tsx先渲染自己的SchemaForm(第 2459 / 2482 行,两条互斥分支之一),再在第 2647 行渲染MetadataDetailDrawer;后者是 RadixSheet,打开时页面表单仍在 DOM 里,Sheet 内挂MetadataResourceEditPage(embedded)或EmbeddedItemEditor(第 221 行)。SchemaForm渲染,两实例同挂,字段 name / label):idPath贯穿(SchemaFormProps.idPath/joinIdPath/fieldHostId)已在基线到位,形状可直接复用。补充读数(卡面未写,影响落点):
PreviewComponent由!embedded && …求值,embedded 下恒为undefined,所以抽屉里只会走第 2482 行那条分支;第 2459 行那条恒属页面侧。两处仍统一传同一个formIdPath(embedded 时才有值),这样即便将来该门放开,作用域也不会漏。改动
SchemaForm的idPath:embedded 的MetadataResourceEditPage用drawer-metadata,EmbeddedItemEditor用drawer-embedded-item。顶层 id 变mdf-drawer-metadata.{字段名}/mdf-drawer-embedded-item.{字段名}。mdf-{字段名}一字不动([app-shell] metadata-admin FieldRow 的宿主 id 不带路径作用域(mdf-{字段名})—— 同名子字段产生重复 DOM id,第二个标签的for解析到第一个字段的控件 #5062 裁定的承诺),由钉子逐字锁住。idPath仍是祖先路径。aria-labelledbyIDREF 消费,按空白切分);含-,而-不在 metadata machine name 文法(^[a-z][a-z0-9_]*$)内、也不在这些 JSON-Schema 用的 camelCase 属性名内,因此mdf-{段}.{字段}不可能被任何真实字段路径拼出。SchemaForm增开发期重复 id 断言:检测同文档重复的mdf-宿主 id 并console.error响亮告警,消息点名冲突 id 与成因。生产构建零开销(NODE_ENV门);只有子树最外层那个表单扫,嵌套的几十个不重复扫。这是把方向 2「漏传新并挂点就静默复发」变响亮的那一半。测试
新增
SchemaForm.instanceIdScope.test.tsx(8 个)。复现钉走真实挂载点(MetadataDetailDrawer盖在MetadataResourceEditPage上,两种抽屉体各一)而非手传idPath—— 手传的话挂载点漏传时钉子照绿,就是个幻检查。pnpm exec vitest run packages/app-shell/src/views/metadata-admin/→ 180 files / 1858 passed | 1 skippedturbo run type-check→ 81 successful, 81 total反向验证(先书面预判,commit 后变异,
git checkout --还原;四条方向全部与预判相符)EmbeddedItemEditor的作用域段duplicatesexpected [ 'mdf-name', 'mdf-label' ] to deeply equal [],且 dev 断言把完整诊断打了出来;metadata 抽屉那条仍绿getElementById/label[for]都是整串精确匹配,happy-dom 不做 IDREF 切分expected 'drawer metadata' not to match /\s/,两条 DOM 钉果然全绿expected [ 'mdf-drawer-metadata.name', …(1) ] to deeply equal []—— 全局共用一个段只是把碰撞挪了个位置,证实段必须按挂载点分expected 0 to be greater than 0,另两条如实绿(b) 与 (d) 两条的方向值得写明:它们不是 before-green/after-red 的常规形。(b) 说明含空白的段在 DOM 侧不会自己报错,契约钉是唯一防线;(d) 说明三条断言钉里只有一条是正向守卫,另两条是条件钉 —— 如实记下,免得下一个人误读成三条都在守断言器。
界外
未发现新的半径外缺陷。另有几个
SchemaForm挂载点(PackageFormDialog、ObjectHooksPanel、各 inspector)经核不与页面表单同文档并挂:inspector 那几处与第 2459/2482 行是互斥三元分支,同一时刻页面上只有一个表单。若将来真并挂,新加的开发期断言会当场响。Generated by Claude Code