Skip to content

ResponsiveGridProps.gap 收 number | string,但渲染只对 number 算 class —— 字符串间距静默丢失(连默认的 gap-4 一起丢) #3988

Description

@yinlianghui

发现于 #3972 的实施(PR #3984),不在该 PR 处理 —— #3972 扫的是 registerLayout() 的声明面(inputs),而这一条的两半都不在声明面上:漂的是 TS prop 类型渲染器之间,#3984 也刻意不动 ResponsiveGrid.tsx 本体。未认领,交 PM triage。

机制

ResponsiveGridProps.gapnumber | string(packages/layout/src/ResponsiveGrid.tsx:42):

/** Gap between grid items */
gap?: number | string;

但渲染只对 number 算 class(:111):

const gapClass = typeof gap === 'number' ? (GAP_CLASSES[gap] || `gap-${gap}`) : '';

于是 gap="4" / gap="1rem" 这类类型允许的写法拿到 gapClass === '' —— 不是"退回默认间距",而是完全没有间距 class:gap = 4 那个默认值只在 gapundefined 时生效,显式传字符串会把默认值一起顶掉(:106)。字符串分支是条死路,而类型签名在邀请人走它。

注册面这次审计判为正确、故未改:{ name: 'gap', type: 'number' } 恰好描述了渲染器真正兑现的唯一类型。所以这不是 #3832 那种"声明面比契约窄"的问题 —— 是 TS 类型比实现宽,#3829 家族(声明了却零实装)落在 props 接口上的一个实例。

三条路线(需要决定,故不顺手改)

  • (a) 收窄类型到 gap?: number —— 与实现一致,对仓外传字符串的调用方是 breaking(编译期红,但那些调用今天本来就没间距);
  • (b) 实装字符串分支 —— 例如字符串走内联 style gap 而非 Tailwind class;要定"字符串是任意 CSS 长度还是 Tailwind 刻度名";
  • (c) 保留类型、在 JSDoc 写明"字符串目前不产生间距" —— 等于承认是 declared-but-inert,应走 ADR-0049 enforce-or-remove。

可达性诚实标注

仓内零消费者:除本包自身外没有任何地方渲染 ResponsiveGrid(plugin-dashboard 里的 ResponsiveGridLayoutreact-grid-layout 的东西,同名不同物),也没有 JSON 元数据把 responsive-grid 当节点写。因此今天没有人被这条打到,按 observation-class 打 finding、不挂 pm:queue,定级请分诊时自行判断。

参考位置

  • packages/layout/src/ResponsiveGrid.tsx:42 —— gap?: number | string
  • packages/layout/src/ResponsiveGrid.tsx:106 / :111 —— 默认值与只认 number 的 class 计算
  • packages/layout/src/index.ts —— responsive-grid{ name: 'gap', type: 'number' }(与实现一致,未改)

关联:#3972(发现于此实施)、#3984(该单的 PR)、#3829(声明了却零读点/零实装)、#3818

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions