# 拟态空态（Empty State）

- 类型 / 材质：`empty-state` / `neumorphic`（新拟态）
- 状态：done ｜ 最后提交：2026-11-01
- 灵感来源：Neumorphism（同色浮起的小图标块）
- 依据标准：`/design#states` ｜ 组件页：`/showcase/component/empty-state/neumorphic` ｜ 条目：`/r/empty-state--neumorphic.json`
- 必缺状态：（无必缺状态）
- 整页场景：尚未接入

## 规格

- 同一份 props（title / description / icon / action）
- 同色底 + 外双阴影的图标砖浮出表面，没有边框与模糊
- 文案与动作规则同玻璃空态

## 参数（CSS 变量）

`--color-accent` `--color-text` `--color-text-muted` `--color-text-subtle` `--neuro-bg` `--neuro-dark` `--neuro-light` `--text-base` `--text-xs`

## Props 契约

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `title` | `string` | 必填 | — |
| `description` | `string` | 可选 | — |
| `icon` | `ReactNode` | 可选 | — |
| `action` | `ReactNode` | 可选 | 一个主操作；多个动作会让空态变成第二个工具栏 |
| `className` | `string` | 可选 | — |

## 提示词（可直接粘给智能体）

```
复现「拟态空态」— Empty State（空态 / Neumorphic）
灵感来源：Neumorphism（同色浮起的小图标块）
规格：
- 同一份 props（title / description / icon / action）
- 同色底 + 外双阴影的图标砖浮出表面，没有边框与模糊
- 文案与动作规则同玻璃空态
参数（CSS 变量）：--color-accent --color-text --color-text-muted --color-text-subtle --neuro-bg --neuro-dark --neuro-light --text-base --text-xs
必缺状态：（无必缺状态）
整页场景：（尚未接进整页场景）
无障碍：焦点环 ≥2px 等效周长（SC 2.4.13）；指针目标 ≥24×24（SC 2.5.8）；动效带 prefers-reduced-motion 降级
参考：本站实样 /showcase/component/empty-state/neumorphic · 标准 states /design#states · 调研笔记 /showcase/component/empty-state/neumorphic#notes
```

## 调研笔记

import { type ReactNode } from 'react';

interface Props {
  title: string;
  description?: string;
  icon?: ReactNode;
  /** 一个主操作；多个动作会让空态变成第二个工具栏 */
  action?: ReactNode;
  className?: string;
}

/** 空态：零数据不是"页面坏了"，要说清是什么空了、下一步做什么 */
export function NeumorphicEmptyState({ title, description, icon, action, className = '' }: Props) {
  return (
    <div className={`flex flex-col items-center justify-center gap-3 px-6 py-14 text-center ${className}`}>
      {icon && (
        <div
          className="
            grid place-items-center size-11 rounded-xl
            bg-[var(--neuro-bg)] border border-transparent
            shadow-[2px_2px_6px_var(--neuro-dark),-2px_-2px_6px_var(--neuro-light)]
            text-[var(--color-text-subtle)]
          "
          aria-hidden="true"
        >
          {icon}
        </div>
      )}
      <p className="text-[length:var(--text-base)] font-medium text-[var(--color-text)]">{title}</p>
      {description && (
        <p className="text-[length:var(--text-xs)] text-[var(--color-text-muted)] max-w-sm leading-relaxed">
          {description}
        </p>
      )}
      {action}
    </div>
  );
}
