Skip to content
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
This repository was archived by the owner on Nov 4, 2026. It is now read-only.

对象表单之外的一批渲染器仍把必填状态画成星号而不送进 a11y 树(#3290 的同类缺陷,另外五处) #3299

Closed

Description

@xuyushun441-sys

实施 objectui#3290(PR #3298,给对象表单渲染器 packages/components/src/renderers/form/form.tsx 的控件送 aria-required)时顺带扫到的:同一个缺陷在别的渲染器里还有五处,#3290 的范围栅栏只钉了 form.tsx 一处,所以单独立此单,不在那个 PR 里修。

缺陷形状(与 #3290 完全同型)

组件算出了 required,只用它画一颗红星,而控件本身没有任何必填状态——既没有 aria-required,也没有原生 required。屏幕阅读器要么完全不知道该字段必填,要么只能从可访问名里读到一个孤零零的 "asterisk / star"。

清单(已逐处核对,非 grep 猜测)

位置 星号写法 控件上的必填状态
packages/app-shell/src/views/ActionParamDialog.tsx:243,260 < Label htmlFor > 内的裸 < span >*< /span >(无 aria-hidden) 无
packages/components/src/custom/action-param-dialog.tsx:117,137,173,202,223 同上,五处 无
packages/app-shell/src/views/CreateViewDialog.tsx:510,557,579 < label htmlFor > 内裸 < span >*< /span > 无
packages/plugin-detail/src/InlineCreateRelated.tsx:211 裸 < span >*< /span > 无
packages/components/src/custom/field.tsx:58 CSS 伪元素 after:content-['*'] 无——FieldContainer 往子 Slot 注入了 id / aria-describedby / aria-invalid,唯独漏了 aria-required

裸 < span >*< /span > 那四处比 form.tsx 原来的情况更糟一点:老的 form.tsx 至少有 aria-label="required" 让可访问名读作 "Title required";这些只有一个 * 字符落进可访问名,被读成 "Title asterisk"。

已经做对的参照实现

packages/plugin-form/src/EmbeddableForm.tsx:481,489 早就是正确形状,可以直接照抄:

aria-required={consentRequired || undefined}
…
< span aria-hidden="true" className="text-destructive ml-0.5" >*< /span >

PR #3298 让 form.tsx 收敛到的正是这个形状。

建议修法

对每一处:控件加 aria-required={required || undefined}(不是原生 required——理由见 #3290 裁决:会和应用自己的校验双轨),星号加 aria-hidden="true"。custom/field.tsx 的 FieldContainer 只需在已有的 Slot 注入里补一个 aria-required,一处就覆盖它的所有使用方。

明确排除

packages/components/src/renderers/form/{input,textarea,select,checkbox}.tsx 和 basic/text-input.tsx 不在本单内:它们设了原生 required={schema.required},浏览器会自动把它映射成必填状态,a11y 上是通的。那几个是独立 SDUI 控件、不走 react-hook-form,所以原生 required 在那里也不构成 #3290 说的双轨问题。

边界

不动 packages/spec,不动任何 field widget 的 props 契约(aria-required 已经在 FieldWidgetComponentProps & AriaAttributes 里,无需新键)。每处一到两行 + 测试。

关联:objectui#3290、PR #3298。

Activity

  1. xuyushun441-sys commented on Aug 4, 2026

    @xuyushun441-sys
    ContributorAuthor

    认领 — session session_01NVPjPzmmAJ2Ngtvgg5MSRa,分支 claude/issue-3299-required-a11y-five-sites。

    PM 裁决:按 issue 清单五处逐一收敛到 EmbeddableForm.tsx:481,489 的参照形状——控件 aria-required={required || undefined}(不用原生 required,#3290 裁决的双轨理由),星号 aria-hidden="true"。custom/field.tsx 的 FieldContainer 走 Slot 注入补 aria-required 一处覆盖所有使用方。明确排除段照单全收(原生 required 的 SDUI 控件不动)。不动 spec、不动 widget props 契约。每处配测试并做破坏验证。


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

bugSomething isn't workingpm:queue

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions