fix(layout): page-header 的 registration inputs 不再宣告 description - #3265
Merged
Conversation
…s an input `registerLayout()` declared `inputs: [title, description]` for the legacy kebab alias, while `@objectstack/spec/ui`'s `PageHeaderProps` — and the canonical `page:header` renderer in `@object-ui/components` — declare `subtitle`. `inputs` is a DECLARATION surface (the designer palette, the framework's `check:react-declaration-parity`), so this did not tolerate a legacy spelling, it published a second dialect and taught authors a non-spec key. Metadata that took the offer renders a subtitle under `page-header` and loses it under `page:header`. The runtime `subtitle ?? description` read in `PageHeader.tsx` stays on purpose: the alias exists for out-of-repo consumer schemas, so zero in-repo hits is not evidence nobody writes it, and dropping the read would silently delete an external page's second line. It is retired with the ADR-0087 D2 conversion entry `page-header-subtitle-alias`, which lives in the framework repo. Narrowing the declaration is unconditional and changes no runtime behaviour. New tests pin both halves: the registration may not declare `description`, must declare `subtitle`, and may declare nothing the spec's own shape does not; the runtime fallback is pinned as a sequencing guard, to be deleted together with the conversion entry. Refs #3226 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NVPjPzmmAJ2Ngtvgg5MSRa
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
Contributor
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
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 #3226
按 issue 上两条 PM 裁定(
#3226的 comment):本单走路线 B(ADR-0087 D2 conversion 条目)而非直接删除,而 conversion 机制在 objectstack 仓,不在这里。因此本 PR 的范围被明确收窄为无条件成立、且跨仓依赖为零的那一半:本 PR 做的:
registerLayout()里page-header的inputs从[title, description]收窄为[title, subtitle]。本 PR 刻意不做的:不删
PageHeader.tsx的subtitle ?? description,不删descriptionprop。这两项被本 PR 的测试主动钉住了(见下),删它们等于走回被否决的删除路线。剩余部分(阻塞在上游):conversion 条目
page-header-subtitle-alias(description→subtitle,加载时改写成 canonical 键)+ 随后删除消费端裸??与descriptionprop。这部分归主 backlog PM,在 objectstack 立单;本单挂Blocked-by。为什么这一半可以现在就做,而且必须现在做
inputs是声明面,不是文档。设计器用它生成属性面板,framework 的check:react-declaration-parity拿它跟 spec schema 对差。所以宣告description不是「容忍一个遗留拼写」,而是对外发布了第二套方言,并且在教作者(尤其是读 registry 学形状的 AI 作者)写一个 spec 里根本不存在的键:@objectstack/spec/ui的PageHeaderProps的 shape 是title / subtitle / icon / breadcrumb / actions / aria—— 没有description(已实测)。page:header(@object-ui/componentscontainers.tsx)声明的是subtitle。description在page-header下渲染出副标题,换到page:header下静默丢失。同一份 JSON,两个结果 —— 这正是「单一契约」要消灭的东西。收窄声明面不改变任何运行时行为(
??还在),因此对仓外消费者零破坏;而把声明面留在错的状态,只会持续生产出将来 conversion 层还得去吸收的错误 metadata。为什么运行时的
??现在不能删这个别名存在的全部理由就是仓外的消费者 schema(佐证:
registerLayout()在本仓没有任何调用点,它纯粹是@object-ui/layout对外的公开导出)。所以「仓内 grep 零命中」(我复核过,确实为零)不构成「没人在写」的证据。按删除路线走,外部写description的页面会静默丢副标题 —— 标题照常渲染,只是第二行没了,是最难被报障的失效形态。预警的门禁冲突:核实过,不存在
PM 预警了
check:react-declaration-parity可能校验「声明的 inputs ↔ 组件实际读取的 props」。查了 framework 侧实现,不会冲突,两个独立理由:inputs),其文件头明确写着「It never looks at a renderer」。组件读不读description完全不在它视野内。description恰恰就是一个 registry-only input,删掉它只会减少 divergence,不可能触发 ratchet。REACT_BLOCKS(ObjectForm/ListView/ObjectChart/Block),baseline 里也只有这三个 block;page-header根本不在其中。测试:两半都钉住
新增
packages/layout/src/__tests__/page-header-authorable-keys.test.tsx(7 个用例):page-header与layout:page-header两个键都不得含description;必须含subtitle;并且 —— 这条是从 spec 自己的 shape 推出来的,不是手写白名单 —— 声明的每一个 input 都必须是PageHeaderProps的键。将来再往这里加一个 spec 没有的 input,会因为和description完全相同的理由变红,不需要谁记得这个 issue。description渲染成副标题、且subtitle在两者都在时胜出 —— 这不是为别名背书,而是钉住顺序:在 conversion 条目落地前删掉这个读取,就是被否决的删除路线。注释里写明:conversion 落地时,同一个 commit 里删掉 fallback 和这两个用例。验证
Changeset
有 ——
patch(@object-ui/layout)。虽然运行时行为不变,但声明面是对外发布的:设计器属性面板会从 "Description" 变成 "Subtitle",生成的sdui.manifest.json也随之改变,对使用设计器的人是可见的。按 AGENTS.md 未标major。顺带发现(未在本 PR 修,已另开 issue)
文档里同样在教
description,而且比inputs教得更直接 —— 但它在content/docs/,超出本单的packages/layout范围,且牵扯到别的 doc drift(breadcrumbs这个 prop 组件根本不读),不适合搭车:content/docs/guide/layout.md「PageHeader Component」的 authored JSON 示例写"type": "page-header"+"description",Schema API 块声明description?: stringcontent/docs/layout/page-header.mdx「Component Props」块列description?: string,且完全没提subtitlehttps://claude.ai/code/session_01NVPjPzmmAJ2Ngtvgg5MSRa
Generated by Claude Code