跳到主要内容

第二轮修复(设计师反馈)(WEB-377)

Pre-release · 类型: 🐛 缺陷修复

WEB-377 第二轮修复,基于设计师 Vincent 截图新反馈。

WEB-610: Dialog 描述未左对齐 + 按钮描边重影

状态: 已修复

问题

  1. "无关闭按钮" / 受控示例的 description 文字比 title 多缩进一段(视觉未左对齐)
  2. Dialog 内按钮("确认" / "我已了解")出现描边和阴影,与文档站其他位置的 Button 不一致

根因

  1. dialog.mdxcontent 上写了 <div style={{ padding: '0 24px' }}>...</div>,而 Dialog 设计层已经包了一层 px-(--Spacing_24),叠加后变成 48px 内缩
  2. Dialog 通过 Radix Portal 挂到 <body>,跳出了 design-site [class*='playgroundPreview'] 的 reset 范围。design-site 故意没引 Tailwind preflight,导致 user-agent 默认的 <button> 边框/阴影从 portal 中泄漏

改动文件

src/components/Button/styles.ts, src/components/Dialog/Dialog.tsx, packages/design-site/docs/components/patterns/dialog.mdx, packages/design-site/i18n/zh-CN/.../dialog.mdx

改动内容

  1. BUTTON_BASE_CLASS 增加 border-0shadow-none,让 Button 自包含 user-agent reset,不再依赖 design-site 全局 reset;secondary / destructive-outline 变体显式声明的 border border-solid border-(...) 通过 tailwind-merge 自然覆盖
  2. dialog.mdx 中 4 处冗余 content={<div style={{ padding: '0 24px' }}>...</div>} 改为字符串/简单内容,避免与 Dialog 内部 px-(--Spacing_24) 叠加
  3. Dialog 新增 cancelText / okText / onCancel / onOk 配置项,默认渲染的取消/确认按钮通过内部 <DialogClose asChild> wrap,点击后 Dialog 自动关闭。仅在未传 footer 时生效;传了 footer 则关闭逻辑由调用方实现。DialogClose 不对外导出,业务方按"配置"路径使用即可
  4. dialog.mdx 演示改用 cancelText / okText,并补充"自定义 footer"示例说明 footer 模式下的关闭语义

WEB-611: DropdownMenu 分割线两端贴边

状态: 已修复

问题

DropdownMenu 分割线当前从 Content 左右贴边渲染,设计稿要求两端有 16px 内缩,居中展示

改动文件

src/components/DropdownMenu/styles.ts

改动内容

  1. DROPDOWN_SEPARATOR_TOKEN_CLASS 增加 mx-(--Spacing_16),让分割线左右各内缩 16px,与 item 文字左右边对齐

WEB-612: Toast 图标视觉过大 + 与文字未对齐

状态: 已修复

根因

(双重问题)

  1. Toast 中图标视觉过大StatusIcon SVG 自身 viewBox = '0 0 13.333 13.333',但 IconSvg 默认 width/height = 20,相当于把 13.333 的 path 拉伸渲染到 20×20,视觉密度比 Figma vector 大约 50%。但 Icons 在其它组件里使用没问题,不能改 Icons 本身——只能在 Toast 里限制 SVG 渲染尺寸
  2. 垂直对齐策略错:之前用 items-start! + mt-px 强制把图标贴近顶部,与 Figma counterAxisAlignItems: CENTER(即 items-center)的 Message 模式不一致

Figma 实测319:30904 Alert 组件集):

模式外层 frameIcon 区TitleDescription
Message (Description=False)420×44, py=8, items-centericon 20×20 容器(vector 13.333)22px line-height
Alert (Description=True)420×70, py=8, items-startIcon Warp 20×28 (py=4) → 内嵌 20×20 iconH3 28pxBody 22px

改动文件

src/components/Toast/styles.ts

改动内容

  1. status icon:data-icon 容器 20×20 加 p-[3px]!(对应 Figma vector 上下左右各 3.33 留白),内部 SVG 用 size-full! 自适应剩余 14×14 区域 ≈ Figma vector 13.33。不动 src/Icons/index.tsx,Icons 在其它组件里用是正确的
  2. Toast 外层 items-start!items-center!(默认 Message 模式 Figma counterAxisAlignItems: CENTER
  3. Alert 模式(:has([data-description]))单独切到 items-start!,并给 icon 加 my-1(上下各 4px,对齐 Figma Icon Warp 的 py=4)
  4. 关闭按钮:保留 Sonner SVG 默认 12px,padding 由 4px 改为 p-(--Spacing_8)!(8px),按钮总尺寸 12 + 8*2 = 28×28 与 Figma 一致;X 视觉 12px 略大于 Figma vector 8.96,但通过 padding 控制视觉留白,避免引入 flex 居中 / svg size 强制约束
  5. action button:包装 Sonner toast 函数,把配置式 action: { label, onClick } 自动转成 <Button variant="quaternary" size="sm">。业务方继续按 Sonner 配置 API 使用,不需要写 className 也不需要手动塞 Button。Figma 实测节点 21220:3476:76×32,transparent bg + Labels-Primary 文字,对应 Quaternary Small
  6. Message + Action 单行 / Alert + Action 两行 区分(Figma 实测):
    • Message + Action(21220:3470, 420×60):单行 icon → content → action → close
    • Alert + Action(21220:3504, 420×114):上下两行,上行 icon → content → close,下行 action wrapper 单独占行靠右
    • Sonner 默认是 horizontal nowrap,所有元素挤一行 + close 优先级问题需要专门处理
  7. 同时合并 action + cancel:Sonner 把 actioncancel 分别渲染成两个独立 toast 子元素,之前只 transform 了 action,cancel 仍走 Sonner 默认 button 渲染(data-button data-cancel),DOM 里出现两个 Button。修复:transformOptions 同时识别 action 和 cancel 的 { label, onClick } config,合并到单个 <div data-toast-action className="flex justify-end gap-(--Spacing_12)"> 内(cancel 在前 / action 在后,对应 Figma Action 2 / Action 1),并把原 cancel 字段置 undefined 防止 Sonner 重复渲染。注意 wrapper w-full,否则在 Message + Action 单行场景会抢光宽度让 content 收缩到 0px、文字垂直堆叠
  8. dismiss 闭包:cancel 默认行为是关闭 toast(点击后 dismiss)。Sonner 默认 cancel button 自动 dismiss,但我们用 ReactNode 后失去这个能力。wrapToastFn 用闭包延迟读取 toast id(sonnerToast.success(...) 返回的 id 在调用后才确定),onClick 内 sonnerToast.dismiss(toastId) 正确关闭
  9. flex order 控制双形态布局(核心思路):
    • close button base: static! order-99!(默认排到末尾)+ self-start!
    • action wrapper base: order-3!(在 icon/content 之后、close 之前)
    • data-content base: flex-1! min-w-0!(让长文本能收缩、close 不被挤到下一行)
    • 仅当 description + action 同时存在 时(:has([data-description]):has([data-toast-action])),重写为:
      • toast 切 flex-wrap! + gap-y-(--Spacing_12)!
      • close button order-1!(拉到 action 之前)→ 第一行 icon, content, close 排齐
      • action wrapper basis-full! → 单独占第二行
    • 这样 Message + Action 单行、Alert + Action 两行、Alert without action 单行(items-start 让 icon 顶对齐)三个形态共用同一套 base class

WEB-725: Button 缺少 click 点击态(无需代码改动)

状态: 已答复,无需修改

问题

设计师在文档站未看到点击态展示

备注

Click 状态(:active)只在用户真实按下鼠标瞬间生效,无法做静态展示。已在 Linear 评论中向设计师说明,无需代码改动

WEB-725 补充: 全部 Button variant 状态比对 Figma

状态: 已修复

把所有 variant(primary / secondary / tertiary / quaternary / destructive / destructive-outline / link-color / link-gray)的 Default / Hover / Clicked 三态在 Figma Medium 节点逐一比对,列出差异并修复。

Figma 实测结果:

VariantDefaultHoverClicked
primarybg #000bg #333bg #333 + 1px inside stroke #000
secondarybg #fff + stroke Gray-4bg Gray-1 + stroke Gray-4bg Gray-2 + stroke Gray-4
tertiary透明bg Gray-1bg Gray-2
quaternary透明bg #000 op=0.04(Tinted-Default)bg #000 op=0.08(Tinted-Emphasized)
destructivebg Errorbg Error + #fefefe op=0.1 叠加bg Error + #000 op=0.1 叠加
destructive-outlinestroke Errorstroke Error + Background Error op=0.1stroke Error + Background Error op=0.2
link-colortext Linktext Link + 全字符 UNDERLINEtext Link + 全字符 UNDERLINE
link-graytext Tertiarytext Primary + 全字符 UNDERLINEtext Primary + 全字符 UNDERLINE

差异修复:

  1. primary Clicked 缺少 inside stroke #000 → 增加 active:ring-1 active:ring-inset active:ring-(--Labels-Primary),模拟 Figma 1px inside stroke(用 ring inset 不影响盒尺寸,与 base shadow-none 不冲突——ring 用 --tw-ring-shadow 变量)
  2. destructive-outline Clicked 透明度错误bg-(--Labels-Error)/10bg-(--Labels-Error)/20(Figma Background opacity 0.2)

未改动但已验证一致:

  • secondary:bg-Gray-1 hover、bg-Gray-2 active 与 Figma token 一致
  • tertiary:bg-Gray-1 hover、bg-Gray-2 active 一致
  • quaternary:Grays-Tinted-Default hover、Grays-Tinted-Emphasized active 一致
  • destructive:当前 color-mix(in_srgb, var(--Labels-Error) 90%, white/black) 与 Figma 的 90% Error + 10% #fefefe/#000 fill 叠加数学等价(在 sRGB 线性混合下 #fefefe 与 #ffffff 差异 < 1 RGB 单位,肉眼不可见)。维持当前实现
  • link-color / link-gray:Figma hover/clicked 通过 styleOverrideTable + characterStyleOverrides 给整词加 UNDERLINE,当前 hover:underline / active:underline 实现一致

改动文件

src/components/Button/styles.ts

WEB-742: Popover 间距进一步收紧

状态: 已修复

问题

设计师测量当前 Popover 与 trigger 间距 8px(含 arrow 渲染区域),要求收到 4px 视觉效果

改动文件

src/components/Popover/styles.ts, src/components/Popover/Popover.tsx

改动内容

  1. POPOVER_SIDE_OFFSET = 0 与 Radix 默认值相同 → 删除常量、删除 sideOffset = POPOVER_SIDE_OFFSET 的 prop 默认值,使用 Radix 默认即可
  2. 配合 Arrow height=12 渲染后视觉间距更贴近 Figma 4px

WEB-743: Tooltip 间距进一步收紧 + arrow align padding 失效修复

状态: 已修复

问题

问题 1: 设计师反馈第一轮改成 4px 后视觉上仍偏大,要求若已是 4px 则改为 0px,让 Tooltip 与 trigger 更贴近

问题 2: align=start/end 时 arrow 应该靠近对应边(top:12px / bottom:12px / left:12px / right:12px),但实际渲染 arrow 在 trigger 中线(Radix 默认行为),CSS 没生效

根因

TOOLTIP_CONTENT_CLASS 用 [&[data-side=...][data-align=...]>span:last-child] 选 arrow wrapper。Radix 实际 DOM 里 tooltip 子元素顺序是:text → arrow span (含 svg) → role="tooltip" sr-only spanspan:last-child 选到了末尾的 sr-only span,CSS 设到隐藏元素上,arrow 不受影响

改动文件

src/components/Tooltip/styles.ts

改动内容

  1. selector 全部 >span:last-child>span:has(>svg),按 svg 子元素精确定位 arrow wrapper(其它 span 都不含 svg)
  2. (可选)删除 TOOLTIP_SIDE_OFFSET = 0:与 Radix 默认相同,删常量与 prop 默认值,靠 Radix 默认即可

WEB-745: Menu 图标色值偏深

状态: 已修复

问题

设计师标注 Menu 中 chevron 与 group action + 图标色值应为 Tertiary,当前用的是 Placeholder(偏淡)

改动文件

src/components/Menu/styles.ts

改动内容

  1. MENU_ITEM_ICON_CLASStext-(--Labels-Placeholder)text-(--Labels-Tertiary)
  2. MENU_GROUP_ARROW_CLASStext-(--Labels-Placeholder)text-(--Labels-Tertiary)
  3. MENU_GROUP_ACTION_CLASStext-(--Labels-Placeholder)text-(--Labels-Tertiary)

WEB-746: Table 列对齐失效

状态: 已修复

问题

设置 align: 'right' 的 Price 列表头仍然左对齐,body td 通过 inline textAlign 起作用但表头 <TableColumnHeader> 是 flex 容器(flex w-full items-center),默认 justify-start,不响应 td 上的 textAlign

改动文件

src/components/Table/table-column-header.tsx, src/components/Table/table-data-mode.tsx

改动内容

  1. TableColumnHeaderProps 新增 align?: 'left' | 'center' | 'right'
  2. 内部根据 align 映射到 justify-start / justify-center / justify-end 并合并到 TABLE_HEADER_CELL_INNER_CLASS
  3. table-data-mode.tsx 渲染 TableColumnHeader 时透传 col.align