第二轮修复(设计师反馈)(WEB-377)
Pre-release · 类型: 🐛 缺陷修复
WEB-377 第二轮修复,基于设计师 Vincent 截图新反馈。
WEB-610: Dialog 描述未左对齐 + 按钮描边重影
状态: 已修复
问题
- "无关闭按钮" / 受控示例的 description 文字比 title 多缩进一段(视觉未左对齐)
- Dialog 内按钮("确认" / "我已了解")出现描边和阴影,与文档站其他位置的 Button 不一致
根因
dialog.mdx在content上写了<div style={{ padding: '0 24px' }}>...</div>,而 Dialog 设计层已经包了一层px-(--Spacing_24),叠加后变成 48px 内缩- 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
改动内容
BUTTON_BASE_CLASS增加border-0和shadow-none,让 Button 自包含 user-agent reset,不再依赖 design-site 全局 reset;secondary/destructive-outline变体显式声明的border border-solid border-(...)通过 tailwind-merge 自然覆盖- dialog.mdx 中 4 处冗余
content={<div style={{ padding: '0 24px' }}>...</div>}改为字符串/简单内容,避免与 Dialog 内部px-(--Spacing_24)叠加 - Dialog 新增
cancelText/okText/onCancel/onOk配置项,默认渲染的取消/确认按钮通过内部<DialogClose asChild>wrap,点击后 Dialog 自动关闭。仅在未传footer时生效;传了footer则关闭逻辑由调用方实现。DialogClose不对外导出,业务方按"配置"路径使用即可 - dialog.mdx 演示改用
cancelText/okText,并补充"自定义 footer"示例说明 footer 模式下的关闭语义
WEB-611: DropdownMenu 分割线两端贴边
状态: 已修复
问题
DropdownMenu 分割线当前从 Content 左右贴边渲染,设计稿要求两端有 16px 内缩,居中展示
改动文件
src/components/DropdownMenu/styles.ts
改动内容
DROPDOWN_SEPARATOR_TOKEN_CLASS增加mx-(--Spacing_16),让分割线左右各内缩 16px,与 item 文字左右边对齐
WEB-612: Toast 图标视觉过大 + 与文字未对齐
状态: 已修复
根因
(双重问题)
- Toast 中图标视觉过大:
StatusIconSVG 自身viewBox = '0 0 13.333 13.333',但 IconSvg 默认 width/height = 20,相当于把 13.333 的 path 拉伸渲染到 20×20,视觉密度比 Figma vector 大约 50%。但 Icons 在其它组件里使用没问题,不能改 Icons 本身——只能在 Toast 里限制 SVG 渲染尺寸 - 垂直对齐策略错:之前用
items-start!+mt-px强制把图标贴近顶部,与 FigmacounterAxisAlignItems: CENTER(即 items-center)的 Message 模式不一致
Figma 实测(319:30904 Alert 组件集):
| 模式 | 外层 frame | Icon 区 | Title | Description |
|---|---|---|---|---|
| Message (Description=False) | 420×44, py=8, items-center | icon 20×20 容器(vector 13.333) | 22px line-height | — |
| Alert (Description=True) | 420×70, py=8, items-start | Icon Warp 20×28 (py=4) → 内嵌 20×20 icon | H3 28px | Body 22px |
改动文件
src/components/Toast/styles.ts
改动内容
- 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 在其它组件里用是正确的 - Toast 外层
items-start!→items-center!(默认 Message 模式 FigmacounterAxisAlignItems: CENTER) - Alert 模式(
:has([data-description]))单独切到items-start!,并给 icon 加my-1(上下各 4px,对齐 Figma Icon Warp 的 py=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 强制约束 - 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 - 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 优先级问题需要专门处理
- Message + Action(21220:3470, 420×60):单行
- 同时合并 action + cancel:Sonner 把
action和cancel分别渲染成两个独立 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、文字垂直堆叠 - dismiss 闭包:cancel 默认行为是关闭 toast(点击后 dismiss)。Sonner 默认 cancel button 自动 dismiss,但我们用 ReactNode 后失去这个能力。
wrapToastFn用闭包延迟读取 toast id(sonnerToast.success(...)返回的 id 在调用后才确定),onClick 内sonnerToast.dismiss(toastId)正确关闭 - 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!→ 单独占第二行
- toast 切
- 这样 Message + Action 单行、Alert + Action 两行、Alert without action 单行(items-start 让 icon 顶对齐)三个形态共用同一套 base class
- close button base:
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 实测结果:
| Variant | Default | Hover | Clicked |
|---|---|---|---|
| primary | bg #000 | bg #333 | bg #333 + 1px inside stroke #000 |
| secondary | bg #fff + stroke Gray-4 | bg Gray-1 + stroke Gray-4 | bg Gray-2 + stroke Gray-4 |
| tertiary | 透明 | bg Gray-1 | bg Gray-2 |
| quaternary | 透明 | bg #000 op=0.04(Tinted-Default) | bg #000 op=0.08(Tinted-Emphasized) |
| destructive | bg Error | bg Error + #fefefe op=0.1 叠加 | bg Error + #000 op=0.1 叠加 |
| destructive-outline | stroke Error | stroke Error + Background Error op=0.1 | stroke Error + Background Error op=0.2 |
| link-color | text Link | text Link + 全字符 UNDERLINE | text Link + 全字符 UNDERLINE |
| link-gray | text Tertiary | text Primary + 全字符 UNDERLINE | text Primary + 全字符 UNDERLINE |
差异修复:
- primary Clicked 缺少 inside stroke #000 → 增加
active:ring-1 active:ring-inset active:ring-(--Labels-Primary),模拟 Figma 1px inside stroke(用 ring inset 不影响盒尺寸,与 baseshadow-none不冲突——ring 用--tw-ring-shadow变量) - destructive-outline Clicked 透明度错误 →
bg-(--Labels-Error)/10→bg-(--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
改动内容
POPOVER_SIDE_OFFSET = 0与 Radix 默认值相同 → 删除常量、删除sideOffset = POPOVER_SIDE_OFFSET的 prop 默认值,使用 Radix 默认即可- 配合
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 span,span:last-child 选到了末尾的 sr-only span,CSS 设到隐藏元素上,arrow 不受影响
改动文件
src/components/Tooltip/styles.ts
改动内容
- selector 全部
>span:last-child→>span:has(>svg),按 svg 子元素精确定位 arrow wrapper(其它 span 都不含 svg) - (可选)删除
TOOLTIP_SIDE_OFFSET = 0:与 Radix 默认相同,删常量与 prop 默认值,靠 Radix 默认即可
WEB-745: Menu 图标色值偏深
状态: 已修复
问题
设计师标注 Menu 中 chevron 与 group action + 图标色值应为 Tertiary,当前用的是 Placeholder(偏淡)
改动文件
src/components/Menu/styles.ts
改动内容
MENU_ITEM_ICON_CLASS:text-(--Labels-Placeholder)→text-(--Labels-Tertiary)MENU_GROUP_ARROW_CLASS:text-(--Labels-Placeholder)→text-(--Labels-Tertiary)MENU_GROUP_ACTION_CLASS:text-(--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
改动内容
TableColumnHeaderProps新增align?: 'left' | 'center' | 'right'- 内部根据 align 映射到
justify-start / justify-center / justify-end并合并到TABLE_HEADER_CELL_INNER_CLASS table-data-mode.tsx渲染TableColumnHeader时透传col.align