objectui#3222 已按**方向 1(objectui 跟随 spec)**落地(objectui PR #3289):packages/spec 一个字未改——契约本来就是对的,是 objectui 从来没实现它。现在 objectui 侧实现了,content/docs/protocol/objectui/widget-contract.mdx 有两处需要跟着收口。
这份协议页本身是排除方向 3 的关键证据(:48 的「the source of truth is FieldWidgetPropsSchema」),所以它的正确性直接关系到那次裁定的价值。
1. 示例教 widget 自己渲染文案 —— 落地后会双份显示
:83-100 的 CustomRatingField 示例:
function CustomRatingField({ value, onChange, readonly, required, error }: FieldWidgetProps) {
return (
< div className="rating-field" aria-invalid={!!error} >
…
{error && < span className="error" >{error}< /span >} ← 这一行
objectui 的表单渲染器已经用独立的 < FormMessage / > 在控件下方渲染这条消息。在 #3222 之前 widget 拿不到 error,所以这行永远不执行,问题是隐性的;现在 widget 真的会拿到了,照这份文档写出来的第三方 widget 会把同一句话显示两遍。
职责划分(objectui#3222 的裁定,已在 objectui 侧的实现与文档中落地):
| 关注点 |
归属 |
aria-invalid(必须落在 input 元素上) |
widget |
| 校验消息文案 |
宿主(< FormMessage / >) |
必填标记 * |
宿主(< FormLabel >) |
建议:删掉那一行,并在示例旁写明 error 是布尔信号,不是待渲染的文案。
2. required 的措辞需要限定
:62-63 现在写「Indicate the required state visually and validate accordingly」。但在 objectui 里必填标记由外层 FieldContainer / < FormLabel > 画,widget 再画一个就是同样的双份显示——objectui#3222 正是因此决定不把 required 下沉到 widget props(见 objectui#3290 的分析:真正需要的是输入控件上的 aria-required,而那不需要新增契约键)。
required 留在 spec 的 schema 里没有问题(它描述的是契约,宿主是否传由宿主定),但文档里的这句祈使需要改成「不要自己画必填标记;宿主拥有它。你可以用它设 aria-required」之类的表述,否则同一份文档同时教出两个双份显示。
边界
纯 docs:content/docs/protocol/objectui/widget-contract.mdx。不改 packages/spec/src/ui/widget.zod.ts——契约是对的,只有教法要收口。
关联:objectui#3222、objectui PR #3289、objectui#3290、objectstack#4115。
objectui#3222 已按**方向 1(objectui 跟随 spec)**落地(objectui PR #3289):
packages/spec一个字未改——契约本来就是对的,是 objectui 从来没实现它。现在 objectui 侧实现了,content/docs/protocol/objectui/widget-contract.mdx有两处需要跟着收口。这份协议页本身是排除方向 3 的关键证据(
:48的「the source of truth isFieldWidgetPropsSchema」),所以它的正确性直接关系到那次裁定的价值。1. 示例教 widget 自己渲染文案 —— 落地后会双份显示
:83-100的CustomRatingField示例:objectui 的表单渲染器已经用独立的
< FormMessage / >在控件下方渲染这条消息。在 #3222 之前 widget 拿不到error,所以这行永远不执行,问题是隐性的;现在 widget 真的会拿到了,照这份文档写出来的第三方 widget 会把同一句话显示两遍。职责划分(objectui#3222 的裁定,已在 objectui 侧的实现与文档中落地):
aria-invalid(必须落在 input 元素上)< FormMessage / >)*< FormLabel >)建议:删掉那一行,并在示例旁写明
error是布尔信号,不是待渲染的文案。2.
required的措辞需要限定:62-63现在写「Indicate the required state visually and validate accordingly」。但在 objectui 里必填标记由外层FieldContainer/< FormLabel >画,widget 再画一个就是同样的双份显示——objectui#3222 正是因此决定不把required下沉到 widget props(见 objectui#3290 的分析:真正需要的是输入控件上的aria-required,而那不需要新增契约键)。required留在 spec 的 schema 里没有问题(它描述的是契约,宿主是否传由宿主定),但文档里的这句祈使需要改成「不要自己画必填标记;宿主拥有它。你可以用它设aria-required」之类的表述,否则同一份文档同时教出两个双份显示。边界
纯 docs:
content/docs/protocol/objectui/widget-contract.mdx。不改packages/spec/src/ui/widget.zod.ts——契约是对的,只有教法要收口。关联:objectui#3222、objectui PR #3289、objectui#3290、objectstack#4115。