From 50bf25cf19231dda667a2d132636d37aa16f3ec5 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 6 Aug 2026 15:35:33 +0000 Subject: [PATCH 1/2] =?UTF-8?q?docs(spec):=20FieldWidgetPropsSchema=20?= =?UTF-8?q?=E7=9A=84=20required/error=20JSDoc=20=E4=B8=8D=E5=86=8D?= =?UTF-8?q?=E6=95=99=20objectui#3222=20=E8=A3=81=E6=8E=89=E7=9A=84?= =?UTF-8?q?=E5=8F=8C=E4=BB=BD=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `required` 原文教 widget「indicate required state visually」、`error` 原文教 widget「display the error in its UI」——这两件事正是 objectui#3222 裁定反对、 并已在 objectui PR #3289 落地的:必填标记 `*` 归宿主 label,校验消息文案归宿主 `FormMessage`,widget 只把 `error` 当信号驱动 `aria-invalid`,再画一遍就是双份显示。 仅改 JSDoc 散文;`.describe()`、键名与类型一律不动(#5055 的 ADR-0049 决策面不受影响)。 Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_011M7UwH25Unfi73UHim7ajY --- packages/spec/src/ui/widget.zod.ts | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/packages/spec/src/ui/widget.zod.ts b/packages/spec/src/ui/widget.zod.ts index 502d8a5ba0..0d0466a03d 100644 --- a/packages/spec/src/ui/widget.zod.ts +++ b/packages/spec/src/ui/widget.zod.ts @@ -458,13 +458,27 @@ export const FieldWidgetPropsSchema = lazySchema(() => z.object({ /** * Whether the field is required. - * Widget should indicate required state visually and validate accordingly. + * + * The required MARKER (the `*`) is owned by the host's field label, not by + * the widget — a widget that draws its own produces two markers for one + * field (objectui#3222, landed in objectui#3289). Validation is likewise the + * host's: it owns the form state that decides whether the field passes. + * + * A widget reflects the state on the control it renders, via + * `aria-required` — `AriaAttributes` already declares that key, so this + * needs no additional contract key (objectui#3290). */ required: z.boolean().default(false).describe('Required field flag'), /** - * Validation error message to display. - * When present, widget should display the error in its UI. + * The active validation message for this field; `undefined` while the field + * is valid. + * + * Consumed as a SIGNAL, not as content: a widget reads it only to drive + * `aria-invalid` on the control it renders, which is the one element the + * host cannot reach. The message TEXT is rendered by the host's form message + * slot (`FormMessage` in objectui); a widget that renders it too + * double-displays it (objectui#3222, landed in objectui#3289). */ error: z.string().optional().describe('Validation error message'), From f17c27135911e371f733a4026cb3088e69f89ffc Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 6 Aug 2026 23:50:26 +0000 Subject: [PATCH 2/2] =?UTF-8?q?chore:=20=E9=87=8D=E8=A7=A6=E5=8F=91=20CI?= =?UTF-8?q?=20=E2=80=94=E2=80=94=20=E5=B9=B3=E5=8F=B0=E5=86=BB=E7=BB=93?= =?UTF-8?q?=E7=AA=97=E5=8F=A3=E7=9A=84=20rerun=20attempt=20=E5=8D=A1?= =?UTF-8?q?=E6=AD=BB=E9=A2=84=E6=8E=92=E9=98=9F,=E6=8D=A2=20head=20?= =?UTF-8?q?=E9=87=8D=E6=96=B0=E8=B0=83=E5=BA=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_011M7UwH25Unfi73UHim7ajY