Skip to content

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

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 #3298form.tsx 收敛到的正是这个形状。

建议修法

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

明确排除

packages/components/src/renderers/form/{input,textarea,select,checkbox}.tsxbasic/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

Metadata

Metadata

Assignees

No one assigned

    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