Skip to content

注册路径的全屏长文本编辑器同样绕过 disabled:TextAreaField / RichTextField 的展开按钮与 FullscreenFieldEditor 不认 disabled,禁用字段可经对话框改值写回 #3402

Description

@yinlianghui

在实施 #3400(PR #3401,修内置 form.tsx 全屏路径的 readonly/disabled 绕过)时,做「规则消费半径」扫描发现,未在该 PR 内修改 —— #3400 的文件面被裁定为 packages/components/src/renderers/form/form.tsx,且明确 ⛔ 不碰 FullscreenFieldEditor / TextAreaField。这一条在 packages/fields,是另一条独立缺陷。

现象

#3400 修的是内置分支注册路径的对应实现只守住了 readonly,disabled 一样是漏的:

  • packages/fields/src/widgets/TextAreaField.tsx:40 —— readonly 时提前返回只读展示,showFullscreenButton 根本算不到。readonly 是安全的。
  • packages/fields/src/widgets/RichTextField.tsx:107 —— 同样的提前返回。readonly 也是安全的。
  • disabled 两边都只落到内联控件上:
    • TextAreaField.tsx:68 disabled={readonly || domProps.disabled}
    • RichTextField.tsx:140 disabled={readonly || props.disabled}
  • showFullscreenButton = Boolean(richField?.mobile_fullscreen) 不看 disabled,FullscreenFieldEditor没有收到 disabled(TextAreaField.tsx:85-109 / RichTextField.tsx:144-163 的调用点只传 value / onCommit / label / testIdPrefix / footer / children)。
  • packages/fields/src/widgets/FullscreenFieldEditor.tsx 里 grep readonly|readOnly|disabled —— 零命中(form.tsx 内置 textarea 的全屏路径完全绕过 readonly / disabled:只读长文本可直接编辑,禁用字段可经对话框改值并提交进表单状态 #3400 正文已记录这一点,但当时的结论是「它被 TextAreaField 的提前返回挡在前面」;那个结论只对 readonly 成立,对 disabled 不成立)。

于是禁用的长文本 / 富文本字段:内联控件正确地灰着,但展开按钮仍可点,对话框里可以随便改,提交(onCommit={onChange})把值写回。这与 #3400 的 disabled 那一半是同一个缺陷,只是在另一条渲染路径上,而且同样难被发现,因为控件外观是对的。

可达性

#3400 相同,而且是平台自己造出来的组合:

  • packages/plugin-form/src/ObjectForm.tsx:1076mobile.fullscreenLongText 打开时,给每一个长文本字段无差别盖 mobile_fullscreen,不看该字段是否 readonly/disabled;
  • 表单渲染器的调用点算的是 disabled: disabled || fieldDisabled || isSubmitting || optionGroupGated,而 stripRegisteredFieldProps 不剥离 disabled(已核实:该函数的剥离清单里没有它),所以这个值确实到达注册 widget;
  • 因此同样包含 isSubmitting —— 表单提交进行中,长文本字段仍可通过全屏对话框改值并写回

证据等级

静态证据:读 TextAreaField.tsx / RichTextField.tsx 的提前返回与 FullscreenFieldEditor 调用点、FullscreenFieldEditor.tsx 的 grep 零命中、stripRegisteredFieldProps 的剥离清单(确认 disabled 不在其中)。未做动态探针实测(#3400 的探针只覆盖内置分支);建议 triage 时先跑一次等价探针确认,再定严重度。

修法方向(不预设结论)

  1. 最小修:FullscreenFieldEditor 声明 disabled prop,展开按钮 disabled、对话框输入框跟随、提交不写回;两个 widget 把 disabled 传下去。与 PR fix(components): 内置 textarea 全屏路径遵守 readonly/disabled — 只读不给展开按钮,禁用不可经对话框写回 (#3400) #3401 在内置分支所做的完全对称。
  2. 全屏长文本编辑器有两份实现:form.tsx 的 FullscreenTextarea 与 fields 的 FullscreenFieldEditor(合并受阻于 components ← fields 的依赖方向) #3398(两份实现的合并)最终裁决为「下沉合并」,则在合并后的实现里一次性定义 readonly/disabled —— form.tsx 内置 textarea 的全屏路径完全绕过 readonly / disabled:只读长文本可直接编辑,禁用字段可经对话框改值并提交进表单状态 #3400 已经指出「readonly/disabled 语义要在合并时一并定义,而不是假设搬过去就有」,这一条是那句话的具体清单。

不预设走哪条,取决于 #3398 的裁决节奏。但这一条不依赖 #3398: 方向 1 今天就可独立落地,不需要等合并裁决,所以按独立 issue 归档而非 #3398 的子任务。

关联


Generated by Claude Code

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions