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.

TextAreaField 的字数统计 aria-label 是英文字面量 Character count: {n} of {max},非英文会话的读屏用户听到英文 #3406

Closed

Description

@yinlianghui

实施 #3404(PR #3405,给注册路径的 FullscreenFieldEditor 接 i18n)时在同包邻近文件发现,未并入该 PR —— #3404 的文件面裁定只含 FullscreenFieldEditor.tsx,明确不碰 TextAreaField.tsx。

现象

packages/fields/src/widgets/TextAreaField.tsx:84(对当前 origin/main ≥ 7d08c3f 复核):

aria-label={`Character count: ${(value || '').length} of ${maxLength}`}

这是内联 textarea 右下角字数统计块的可访问名。渲染出来的数字本身({(value || '').length}/{maxLength})是纯数字、与语言无关,但它的 aria-label 是硬编码英文句子。

可达性

不是死代码,但比 #3404 窄两层:

  1. 仅当字段元数据声明了 maxLength 时才渲染这个块({maxLength && (...)});
  2. 仅读屏用户能感知 —— 该元素带 aria-live="polite",所以非英文会话下,每次输入变化都会朗读一句英文。

视觉用户看到的只是数字,不受影响。因此我把它当作比 #3404 严重度低的一条,但它确实运行期有人读(与 #3394 那种设计器 defaultProps、运行期无人读的情况不同)。

与 #3404 的关系

同族但不重叠:#3404 是「键早已存在、这条路径没消费」;这一条是键根本不存在 —— 十个语言包里没有任何 characterCount / charCount 键(已 grep 确认)。所以修它需要新增一个键并翻译十个包,而 #3404 明确是零新增键。这也是它没有被顺手并进 PR #3405 的实质原因,而不只是文件面裁定。

修的时候要先回答的问题

aria-live="polite" + 每次按键重算的 aria-label 是否本身就该重新设计(每敲一个字就朗读一次完整句子是相当吵的),还是只把句子搬进语言包就行。这决定了新键是一句话(fields.textarea.characterCount,带 {{count}} / {{max}} 插值)还是需要拆分。建议 triage 时一并裁定,别只做机械替换。

同 FullscreenFieldEditor 的字符计数 footer({draft.length}/{maxLength})没有 aria-label,不在此列。


Generated by Claude Code

Activity

  1. self-assigned this
    on Aug 5, 2026
  2. yinlianghui commented on Aug 5, 2026

    @yinlianghui
    ContributorAuthor

    认领:objectui 分片 PM 滚动补位第 17 单(#3404/PR #3405 落地后同包释放)
    会话:session_01GTRjn8xBqp75dk7kFupVRt
    分支:claude/issue-3406-charcount-aria-i18n
    Worktree:objectui-issue-3406
    域:objectui 分片(fields + i18n locales)
    文件面:packages/fields/src/widgets/TextAreaField.tsx、packages/i18n/src/locales/*.ts(新键 fields.textarea.characterCount,{{count}}/{{max}} 插值,十包齐)+ useFieldTranslation.ts 的 FIELD_DEFAULTS 英文兜底 + 相应测试 + .changeset/*.md(patch)。当前在飞 0。

    范围裁定(PM,否决窗口):本单只做键化(机械替换,行为不变);正文提出的「aria-live + 每击键重算 label 是否本身该重设计」是独立的行为问题 —— dev 测量后按 finding 立单(含实测吵闹程度与候选模式),⛔ 不在本单顺手改行为,防止 i18n 小单变成无边界的 a11y 重设计。


    Generated by Claude Code

  3. yinlianghui commented on Aug 5, 2026

    @yinlianghui
    ContributorAuthor

    PM 验收:ACCEPT → PR #3409 已转 ready + auto-merge(报告时 7 项完成全绿、全仓作业在跑零失败),跟到 MERGED。

    落地内容:新键 fields.textarea.characterCount 十包齐 + FIELD_DEFAULTS 逐字节英文兜底,走 #3405 验证过的 useFieldTranslation() 形制;单句键化的实证理由被钉进断言 —— ja/ko 的插值语序是上限在前、计数在后,任何代码侧拼接都产不出;hook 上移过 readonly 提前返回(rules-of-hooks)且该分支渲染不变有 pin;TS 契约红时改写用例为类型合法等价而非 cast 绕过。两肢反向验证方向均预判命中(en 与 no-provider 文件在 A 肢保持绿正是「逐字节同英文」主张的证据,非缺口)。行为零改动,符合范围裁定。

    衍生分诊:#3408(aria-live 每击键重读整句 —— 实测 52 击键 52 次播报、52 字符句子播报 979 字符;四候选模式已列且未自裁,a11y 契约形状留 triage)已复核入队 bug + pm:queue,派发时 PM 出方向裁定。

    objectui 分片 PM session_01GTRjn8xBqp75dk7kFupVRt


    Generated by Claude Code

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions