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.

动作 disabled 的「已声明」判定用 != null,disabled: '' 把按钮永久置灰(#3492 同族的另一半 predicate,探针实证) #3842

Closed

Description

@yinlianghui

来源

发现自 #3835 实施(DeclaredActionsBar 的 visible 真值门)的同文件清扫。不在 #3835 的修法面(PM 已裁其范围为 visible 门 + barrel re-export),故独立成单,未认领。

机理

visible 一族已收敛到 hasDeclaredVisibilityGate(!= null && !== '' —— 空谓词不算门),但同一形状的 disabled 判定停在 != null,少了 !== '' 那一半:

  • packages/app-shell/src/views/DeclaredActionsBar.tsx:
    disabled={((action as any).disabled != null ? isDisabledPred : false) || loading}
  • packages/components/src/renderers/action/action-button.tsx:164:
    (schema as any).disabled != null ? isDisabled : schema.enabled != null ? !isEnabled : false

于是 disabled: '' 被判成「声明了 disabled 门」,verdict 交给求值入口 —— 而求值入口对空谓词的语义是「没有条件 → true」:
toPredicateInput('') → undefined → evaluateCondition(undefined) → true。
对 visible 这条链上 true 意味着「显示」(所以 '' 在 visible 侧是良性的、双重保护),对 disabled 则反向:true 意味着禁用。空谓词从「没有门」变成「永久置灰」。

方向对照:visible: '' → 渲染(正确);disabled: '' → 禁用(错误)。同一个「空谓词」,两个 key 得到相反待遇。

实证(origin/main@14c59c0b969c8324160071d447a4b99492dfc35f + #3835 分支,一次性探针,未提交)

DeclaredActionsBar 挂 location: 'record_section' 的声明动作,分别带 disabled: '' / 不带 disabled / disabled: false:

FAIL  PROBE 3835 declared `disabled` > disabled:'' should NOT disable the button (empty predicate is no gate)
Error: expect(element).not.toBeDisabled()

Received element is disabled:
  button
    data-testid="declared-action-approval_approve"
    disabled=""
    type="button"
    variant="outline"
  /

Tests  1 failed | 2 passed (3)

两个对照组(无 disabled、disabled: false)都是 enabled —— 坏的只是「已声明」的判定,不是求值。

action-button.tsx:164 是逐字相同的拼法,未单独探针(推断同形,请实施者自行验证后再改)。

影响

修法(与同族一致,应无新决定)

disabled 的「已声明」判定复用同一处命名定义(hasDeclaredVisibilityGate 的语义,或按 predicate-key 中立地重命名/新增一个 hasDeclaredPredicateGate,同一实现),两处一起改;enabled 那条 legacy 分支同理需要判断。钉子按同族对称性:'' 不置灰 / true 置灰 / false 不置灰 / 未声明不置灰,并区分 disabled 与 enabled 两条腿。

⚠️ 与 #3835 的 PR 同文件同区域(DeclaredActionsBar.tsx 的按钮 props / 门附近):建议等 #3835 落 main 后再派,或在派发时说明合并顺序。命名若要中立化(hasDeclaredVisibilityGate → 通用名),那是一次跨包重命名(components barrel + plugin-grid + app-shell),属于要先裁的小决定。

Related: #3835(发现来源、visible 侧第五处)、#3492(不变量出处)、#3758 / PR #3816、#3812 / PR #3825、#3823 / PR #3836、#1885(disabled 首次接线)。未认领。

Activity

  1. claude commented on Aug 8, 2026

    @claude
    Contributor

    Triage: pm:queue (objectui in-repo — no routing label by protocol).

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  2. self-assigned this
    on Aug 8, 2026
  3. yinlianghui commented on Aug 8, 2026

    @yinlianghui
    ContributorAuthor

    🔒 认领(objectui 分片 PM,session_01GTRjn8xBqp75dk7kFupVRt)

    即将派发 os-dev 实施。


    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