fix(layout): registerLayout 的 inputs 声明面对齐渲染器读点 —— page-header 补 icon/actions,navigation-renderer 的 items 改为 array (#3972) - #3984
Merged
Conversation
page-header 补声明 icon 与 actions(渲染器真读 + spec 声明 + ManifestInputType 表达得了),navigation-renderer 的 items 由 type:'object' 改为 'array' (NavigationRendererProps.items 是 NavigationItem[])。 声明面即作者面:sdui-parser 拿节点顶层属性比对 comp.inputs,漏声明的键报 unknown-prop、类型写错的报 type-mismatch —— 两处都是对着正确写法报假诊断, 其中 icon 那条今天就落在 content/docs/layout/page-header.mdx 唯一的 live demo 上。 渲染输出不变(渲染路径不读 inputs)。 两方向都钉住:文档 demo 过 manifest 门无 unknown-prop、数组 items 无 type-mismatch;对照侧 description(#3226 刻意不声明)仍报 unknown-prop、 items 写成对象仍报 type-mismatch 且消息已变为 expected an array。 breadcrumb / showBack / action / aria 的刻意不声明也各自钉了理由。 Claude-Session: https://claude.ai/code/session_01GTRjn8xBqp75dk7kFupVRt Co-authored-by: Claude <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
Contributor
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
Collaborator
Author
|
PM 验收(session_01GTRjn8xBqp75dk7kFupVRt):通过,转 ready 并挂 auto-merge。#3972 落地。 核验记录(head
out-of-scope 三条:#3985(mobileNavMode 词表未定,finding 持有)、#3987(items required 缺口 —— 收紧决定有 blast radius,PM 另评分诊)、#3988(gap 字符串死支,finding 持有)—— 划界全部正确,#3987 刻意不夹带(新增 error 级诊断属收紧决定)的判断尤其对。 Generated by Claude Code |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #3972
前提复核(基
cdc0e44c8,git merge-base --is-ancestor 82f8dfffd HEAD通过 —— PR #3973 在基内)正文两处锚点与"实测"全部成立,逐条复核:
packages/layout/src/index.ts的page-header只声明title/subtitle;PageHeader.tsx:117取参、:224-226渲染icon(字符串走LazyIcon,也接受 React node);@objectstack/spec/ui的PageHeaderProps.shape实测为title, subtitle, icon, breadcrumb, actions, aria,icon是 optional string。examples/schema-catalog/src/schemas/layout-page-header/pageheader-with-actions.json已经带"icon": "users"(无需为造钉子改 JSON),而它是content/docs/layout/page-header.mdx唯一的 live demo。items是type: 'object',NavigationRendererProps.items是NavigationItem[](NavigationRenderer.tsx:108);checkType对两者互斥判定(sdui-parser/src/validate.ts:124-129),ManifestInputType有'array'(types.ts:51-62)—— 确实不是ComponentInput.type无法表达 spec 的联合类型,于是发布面永远比契约窄一个 arm ——page:header.title的内联翻译映射今天就会被 manifest 门报type-mismatch#3832 的表达力问题。改了什么(
packages/layout/src/index.ts,三个键)正文要求的是"一次按渲染器实际读点的审计",所以
page-header这一块是整块过的,结果比派发单摘要多出一个键:icon:117/:224-226type: 'string'actions:119/:192-196(委派record:quick_actions)type: 'array'items(navigation-renderer)NavigationItem[],:108'object'改'array'actions与icon是同一个判据下的同一类缺陷(渲染器真读 × spec 声明 × 类型可表达),content/docs/layout/page-header.mdx的 Component Props 段落把两者一起写成公开契约,而它今天同样吃unknown-prop。只修icon会让这次审计留下一个已知未修的同族实例,所以一并修了 —— 类型与 canonicalpage:header的actions逐字一致(containers.tsx:1585,type: 'array'),不新开方言。若维护者认为该键应单开一单,删掉那一条 input 与对应的两条断言即可,其余不受影响。刻意不声明的也一并钉住(照抄 spec shape 是这条修复最容易滑进的反向缺陷):
breadcrumb(spec 有、这个渲染器零读点 → 声明它就是 #3829 的方向)、showBack/action/description(渲染器读、spec 无 → 声明即第二套方言,#3226 收窄要防的正是这个)、aria(全仓一致的可访问性逃逸口)。顺带一处值得记下的对称:
page:header.icon在apps/console/src/__tests__/registry-inputs-spec-parity.test.ts的UNPUBLISHED_EXEMPTIONS里(canonical 渲染器零读点,#3829),而同名键在这里被声明 —— 两个不同渲染器、相反的读点事实,不矛盾。该门只判ComponentPropsMap里的键(page:header),kebab 的 legacypage-header不在其覆盖内,所以本 PR 不动它的任何期望值。渲染输出逐字节不变:渲染路径从不读
inputs。钉子(两方向,沿 PR #3973 的形态)
注册级(
packages/layout/src/__tests__/):page-header-authorable-keys.test.tsx新增一个 describe:icon/actions在裸键与 namespace 两处都声明且类型正确、且"合法的理由"(spec 拥有该键)一起断言;反面钉breadcrumb未声明(spec 有、零读点)与showBack/action/description未声明(spec 无)。navigation-renderer-items-declaration.test.tsx(新):运行期钉items声明为array;另有一半是编译期的 ——NavigationRendererProps的items必须仍可赋给数组,由pnpm type-check兜住(tsconfig.test.json覆盖测试文件),这样 prop 被改形状时是 type-check 红,而不是声明面悄悄漂回去。端到端(
examples/schema-catalog/test/pageheader-with-actions.test.tsx,复用 PR #3973 建的diagnose(),即按getJsxManifest()同法构建 manifest):icon)无unknown-prop(附可达性前置:demo 必须仍写icon、无unknown-component);actions: ['export']与数组items均无诊断。description(page-header与page:header对外声明了两套 authorable 键:descriptionvssubtitle,消费端用??兜底 #3226 刻意不声明、渲染器却仍读的那个 legacy alias)仍报unknown-prop;actions写成对象报type-mismatch;items写成对象报type-mismatch且消息断言为 expected an array —— 光断 code 会在"声明根本没动"时照绿。PR #3973 留在该文件里的两处注释(说
icon的unknown-prop尚在、说items: []会另报type-mismatch)已随之更新 —— 它们描述的是修复前的状态。反向验证(先预判,后跑;变异未提交)
预判写在跑之前:把
icon/actions删掉、items改回'object'(即 #3972 前的声明状态),预计 7 条红、两条必须仍绿。实测Tests 7 failed | 21 passed (28),与预判逐条一致:declares icon…/declares actions…/declares type: array(两个 namespace)/ 端到端draws no unknown-prop on the demo/accepts the actions array/accepts an array-valued items。still draws unknown-prop for a key the declaration deliberately withholds(description对照与本改动无关,这正是它作为对照的意义)、以及 PR fix(layout): page-header 注册补 isContainer: true,校验器不再对文档承诺的 children 写法报 not-a-container (#3900) #3973 的全部not-a-container/ docs/examples: PageHeader 文档页的唯一 live demo(layout-page-header/pageheader-with-actions)手搓 div,完全不用page-header#3787 / docs:page-header.mdx的 Styling/Container 两条数值与 PageHeader.tsx 不符(pb-8 on desktop、gap-4) #3786 断言。navigation-renderer-items-declaration里and the prop it describes is still an array在变异下仍绿,这是设计如此 —— 它钉的是 TS prop 类型,变异只动声明,不动 prop。它只在items被改形状时才红。items的对象形状在改动前是唯一能过的写法,改动后才是被报的那个;toContain('type-mismatch')在两个方向都成立,所以真正区分前后的是数组侧的toEqual([])与那条消息断言。审计的其余两个 inputs 块:界内无改动,界外三条已另开单
responsive-grid/app-schema-renderer逐键过了,没有发现"对正确写法报假诊断"这一类缺陷,故本 PR 不动它们。审计顺带看到的三件事都落在本单完成范围之外,已按 Prime Directive #10 另开(未认领),不夹带:app-schema-renderer.mobileNavMode声明成自由文本string,实现是三值联合,且'hamburger'在渲染器里零读点 —— 改成enum前得先定"词表里还有几个值是真的",属契约决定,不猜。navigation-renderer.items是 TS 必填、声明面可选,省略它时渲染器直接抛(collectPinnedItems的 for-of 与sorted.slice()都吃 undefined),而校验器一言不发。加required: true会新增 error 级诊断,是收紧决定,不在本单"三面对齐"的范围里。responsive-grid.gap的 TS 类型收number | string,但ResponsiveGrid.tsx:111只对 number 算 class,字符串静默无间距(连默认的 4 也丢)。验证
pnpm exec vitest run packages/layout packages/sdui-parser examples/schema-catalog --maxWorkers=2(仓根,shared lock 内):16 files / 1216 tests 全绿。--reporter=verbose:28 条全绿,新增钉子逐条可见(反可达性:确认它们真的跑了)。pnpm exec turbo run type-check --concurrency=2(仓根):78/78 successful。node scripts/check-control-bytes.mjs:OK(3882 文件);另对本 PR 五个文件跑了grep -naP的越界自查,无控制字节。changeset
.changeset/layout-inputs-declaration-3972.md,@object-ui/layoutpatch(声明面修正,渲染输出不变)。Generated by Claude Code