ss-feedback

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

UX Feedback States Generator

UX反馈状态生成器

When NOT to use

不适用场景

  • For only the words inside a state → use
    /ss-copy
  • For accessibility issues in existing states → use
    /ss-a11y
  • For brand-new component creation → use
    /ss-component
  • For analytics or error-logging plumbing — UI presentation only
Target: $ARGUMENTS
  • 仅需状态内文字内容 → 使用
    /ss-copy
  • 现有状态的无障碍访问问题 → 使用
    /ss-a11y
  • 创建全新组件 → 使用
    /ss-component
  • 仅处理分析或错误日志相关逻辑 — 本工具仅负责UI呈现
目标对象:$ARGUMENTS

Instructions

操作步骤

  1. Read the target file and identify all data-dependent areas.
  2. Read the design language reference:
    • DESIGN-LANGUAGE.md
      sections on Loading States (Skeleton), Empty States, Error States
  3. For each data-dependent area, implement ALL 4 states:
  1. 读取目标文件,识别所有依赖数据的区域。
  2. 查阅设计语言参考文档:
    • DESIGN-LANGUAGE.md
      中关于加载状态(骨架屏)、空状态、错误状态的章节
  3. 为每个依赖数据的区域,实现全部4种状态:

State 1: Loading (Skeleton)

状态1:加载中(骨架屏)

tsx
// Skeleton must match the final layout shape
<div className="bg-card rounded-2xl p-6 shadow-[var(--shadow-card)]">
  <div className="flex items-center gap-2 mb-3">
    <div className="size-7 bg-surface-muted rounded-lg animate-pulse" />
    <div className="h-3 w-16 bg-surface-muted rounded animate-pulse" />
  </div>
  <div className="h-9 w-24 bg-surface-muted rounded-lg animate-pulse mb-3" />
  <div className="h-3 w-12 bg-surface-muted rounded animate-pulse" />
</div>
Rules:
  • Show skeleton for 300ms minimum (prevent flash)
  • Delay skeleton display by 300ms (fast loads skip skeleton entirely)
  • Use
    animate-pulse
    (1.5s cycle)
  • Match skeleton shapes to real content dimensions
  • Never use spinners inside cards
tsx
// Skeleton must match the final layout shape
<div className="bg-card rounded-2xl p-6 shadow-[var(--shadow-card)]">
  <div className="flex items-center gap-2 mb-3">
    <div className="size-7 bg-surface-muted rounded-lg animate-pulse" />
    <div className="h-3 w-16 bg-surface-muted rounded animate-pulse" />
  </div>
  <div className="h-9 w-24 bg-surface-muted rounded-lg animate-pulse mb-3" />
  <div className="h-3 w-12 bg-surface-muted rounded animate-pulse" />
</div>
规则:
  • 骨架屏最少显示300毫秒(防止闪烁)
  • 延迟300毫秒显示骨架屏(加载速度快时跳过骨架屏)
  • 使用
    animate-pulse
    动画(1.5秒周期)
  • 骨架屏形状需匹配真实内容尺寸
  • 卡片内禁止使用加载 spinner

State 2: Empty (Zero Data)

状态2:空状态(无数据)

tsx
<EmptyState
  icon={PackageIcon}
  title="No activity yet"
  description="Create your first project to get started."
  action={<Button>Create Project</Button>}
/>
Rules:
  • Center-aligned in the card
  • Icon: 32px,
    text-text-tertiary
  • Title: 14px,
    text-text-secondary
  • Always suggest a next action
  • Zero values show as "0" (don't hide or dash)
tsx
<EmptyState
  icon={PackageIcon}
  title="No activity yet"
  description="Create your first project to get started."
  action={<Button>Create Project</Button>}
/>
规则:
  • 在卡片内居中对齐
  • 图标:32px,
    text-text-tertiary
    样式
  • 标题:14px,
    text-text-secondary
    样式
  • 必须提供下一步操作建议
  • 零值需显示为"0"(不可隐藏或用短横线代替)

State 3: Error (Load Failed)

状态3:错误状态(加载失败)

tsx
<div className="flex flex-col items-center justify-center py-8 text-center">
  <AlertCircle className="size-8 text-destructive mb-3" />
  <p className="text-[14px] text-text-secondary mb-4">Couldn't load the data</p>
  <Button variant="brandGhost" size="sm" onClick={retry}>Try again</Button>
</div>
Rules:
  • Partial failure: only affected card shows error, rest loads normally
  • Full page failure: full-screen EmptyState with retry
  • Error message: plain language, blame the system
  • Always provide retry button
tsx
<div className="flex flex-col items-center justify-center py-8 text-center">
  <AlertCircle className="size-8 text-destructive mb-3" />
  <p className="text-[14px] text-text-secondary mb-4">Couldn't load the data</p>
  <Button variant="brandGhost" size="sm" onClick={retry}>Try again</Button>
</div>
规则:
  • 部分加载失败:仅受影响的卡片显示错误状态,其余正常加载
  • 整页加载失败:全屏显示EmptyState并提供重试按钮
  • 错误提示:使用通俗易懂的语言,将问题归因于系统
  • 必须提供重试按钮

State 4: Success (Action Feedback)

状态4:成功状态(操作反馈)

tsx
// Toast notification for action confirmations
toast("Changes saved")

// With undo for destructive actions
toast("Item deleted", { action: { label: "Undo", onClick: handleUndo } })
Rules:
  • Info toast: 3s display
  • Action toast (with undo): 5s display
  • Toast position: above BottomNav
  • One toast at a time (new replaces old)
  1. Implementation pattern:
tsx
function DataCard({ data, isLoading, error }) {
  if (isLoading) return <DataCardSkeleton />
  if (error) return <DataCardError onRetry={refetch} />
  if (!data || data.length === 0) return <DataCardEmpty />
  return <DataCardContent data={data} />
}
  1. Check
    prefers-reduced-motion
    — disable
    animate-pulse
    when reduced motion is preferred.
tsx
// Toast notification for action confirmations
toast("Changes saved")

// With undo for destructive actions
toast("Item deleted", { action: { label: "Undo", onClick: handleUndo } })
规则:
  • 信息类Toast:显示3秒
  • 带撤销操作的Toast:显示5秒
  • Toast位置:BottomNav上方
  • 同一时间仅显示一个Toast(新Toast替换旧Toast)
  1. 实现模式:
tsx
function DataCard({ data, isLoading, error }) {
  if (isLoading) return <DataCardSkeleton />
  if (error) return <DataCardError onRetry={refetch} />
  if (!data || data.length === 0) return <DataCardEmpty />
  return <DataCardContent data={data} />
}
  1. 检查
    prefers-reduced-motion
    设置 — 当用户偏好减少动画时,禁用
    animate-pulse
    动画。