button.md
组件 · COMPONENT

按钮 Btn

光从正上方来——每个按钮都是一枚真实的键:凸面渐变、顶部反光、贴地投影、反光光晕、按压内陷。文字按钮一律圆角矩形,禁胶囊。

试验台

三条轴自由组合:五种键面 × 三档高度 × 三种状态。下方同时给出对应的 JSX 和类名。

<Btn variant="primary">墨键</Btn><button class="zzm-btn zzm-btn--primary">

五种键面

纸键是默认;墨键给一屏里最主要的操作;朱键只给品牌强调、播放或破坏性确认;幽灵键静默时是文字,悬停才「长成键」,用于工具条;暗面键只在深色面上用。

纸 · 墨 · 朱 · 幽灵
import { Btn, btnClass } from './components/v4/Button.jsx'

export function Variants() {
  return (
    <>
      <Btn>纸键(默认)</Btn>
      <Btn variant="primary">墨键 · 主操作</Btn>
      <Btn variant="accent">朱键 · 强调</Btn>
      <Btn variant="ghost">幽灵键</Btn>
    </>
  )
}
暗面键付款页 / 播放器锁罩 / 海报态
import { Btn, btnClass } from './components/v4/Button.jsx'

export function OnDark() {
  return (
    <>
      <Btn variant="ondark">暗面键</Btn>
      <Btn variant="accent">朱键在暗面同样成立</Btn>
      <Btn variant="ondark" disabled>禁用</Btn>
    </>
  )
}

三档高度

高度落在 4pt 网格上:sm 28(工具条)、md 36(表单与一般操作)、lg 44(主操作,圆角升到 12)。icon 把键变成正方形。

28 · 36 · 44 · 图标键
import { Btn, btnClass } from './components/v4/Button.jsx'

export function Sizes() {
  return (
    <>
      <Btn size="sm">小 · 28</Btn>
      <Btn>中 · 36</Btn>
      <Btn size="lg" variant="primary">大 · 44 · 圆角 12</Btn>
      <Btn icon title="图标键"></Btn>
      <Btn icon size="sm" variant="ghost" title="小图标键"></Btn>
    </>
  )
}

等待与禁用:两种语义两张脸

busy 是「正在做」:出旋转环、一道反光扫过、饱和度略降、不可点,但保留变体本色disabled 是「不能做」:灰面灰字。禁用永远不用 opacity 淡化——白字 × 半透明 × 灰面会让字直接消失。任何点击后要等的按钮都用 busy

busy 与 disabled
import { Btn, btnClass } from './components/v4/Button.jsx'

export function States() {
  return (
    <>
      <Btn busy>Saving…</Btn>
      <Btn busy variant="primary">保存中…</Btn>
      <Btn busy variant="accent">提交中…</Btn>
      <Btn disabled>禁用</Btn>
      <Btn variant="primary" disabled>禁用 · 灰面灰字</Btn>
    </>
  )
}

链接长成键

<a><label> 这类非 button 元素用 btnClass() 取同一套类名,质感完全一致。

btnClass()
import { Btn, btnClass } from './components/v4/Button.jsx'

export function AsLink() {
  return (
    <>
      <a href="#pricing" className={btnClass({ variant: 'primary' })}>查看定价</a>
      <a href="#docs" className={btnClass({ size: 'sm' })}>阅读文档</a>
    </>
  )
}

属性

属性取值默认说明
variantpaper · primary · accent · ghost · ondarkpaper五种键面
sizesm · md · lgmd高 28 / 36 / 44;lg 圆角 12
iconbooleanfalse正方形图标键,宽=高
blockbooleanfalse撑满容器宽度
busybooleanfalse等待态:旋转环 + 反光 + 本色 + 自动禁用
disabledbooleanfalse不能做:灰面灰字
classNamestring''追加类名;style 只放布局,不放背景和阴影

铁律

✓ 要圆角矩形:sm/md 圆角 8,lg 圆角 12
✗ 不要把文字按钮做成 999 胶囊——胶囊只留给不可点的徽章
✓ 要光影只从 .zzm-btn 取,调用方 style 只写 margin / flex / width
✗ 不要style 里散写 box-shadow、渐变或 border-radius 盖掉质感
✓ 要点击后要等待的操作用 busy
✗ 不要opacity 淡化来表示禁用
✓ 要一屏只有一个墨键或朱键做主操作
✗ 不要朱键当装饰色——它只标「下一步」或危险动作