feat: stash-ui 0.1.0(40 个组件 + 文档站 + 主题机制)

This commit is contained in:
stash
2026-10-28 20:44:18 +08:00
commit 52296b3368
153 changed files with 17129 additions and 0 deletions
+153
View File
@@ -0,0 +1,153 @@
import { useState } from 'react'
import { Button, Icon, IconButton, Space } from '../../src'
import { Demo } from '../components/Demo'
import { PropsTable } from '../components/PropsTable'
import { Section } from '../components/Section'
export function Buttons() {
const [loading, setLoading] = useState(false)
const loadOnce = () => {
setLoading(true)
window.setTimeout(() => setLoading(false), 1200)
}
return (
<Section
id="buttons"
title="按钮"
api="Button / IconButton"
desc="五种语义、两种尺寸、两种形状;图标按钮是圆形的,只放一个图标,所以无障碍名称必填。交互对齐参考站:hover 用 opacity .8(主色/危险),过渡 .3s ease-in-out。"
>
<Demo
title="语义变体"
desc="一个页面里主要操作只出现一次 primary,其余用 secondary / outline / ghost。"
code={`<Button>保存</Button>
<Button variant="secondary">取消</Button>
<Button variant="outline">更多</Button>
<Button variant="ghost">详情</Button>
<Button variant="danger">删除</Button>`}
>
<Button>保存</Button>
<Button variant="secondary">取消</Button>
<Button variant="outline">更多</Button>
<Button variant="ghost">详情</Button>
<Button variant="danger">删除</Button>
</Demo>
<Demo
title="形状"
desc="rounded(默认,6px 圆角)用于工具型操作;pill 用于登录、筛选这类主操作——参考站的全部分类筛选和登录按钮都是胶囊。"
code={`<Button shape="pill">登录</Button>
<Button shape="pill" variant="secondary">全部</Button>
<Button shape="pill" variant="ghost">重置</Button>`}
>
<Button shape="pill">登录</Button>
<Button shape="pill" variant="secondary">
全部
</Button>
<Button shape="pill" variant="ghost">
重置
</Button>
</Demo>
<Demo
title="尺寸"
desc="sm 用于卡片内的次级操作,md 用于页面级操作;两档高度分别是 32 / 36。"
code={`<Button size="sm">小号</Button>
<Button size="md">中号</Button>`}
>
<Button size="sm">小号按钮</Button>
<Button size="md">中号按钮</Button>
</Demo>
<Demo
title="状态"
desc="loading 会自动禁用点击;disabled 换成浅底弱文字(参考站的做法),不做整体降透明度。"
code={`<Button loading={loading} onClick={loadOnce}>提交</Button>
<Button disabled>不可用</Button>`}
>
<Button loading={loading} onClick={loadOnce}>
点我加载
</Button>
<Button disabled>不可用</Button>
<Button variant="secondary" disabled>
不可用(次要)
</Button>
</Demo>
<Demo
title="带图标与整行"
desc="图标放在文字左侧;block 让按钮占满容器宽度(表单底部常用)。"
layout="column"
code={`<Button icon={<Icon name="refresh_3_line" />}>重新扫描</Button>
<Button shape="pill" icon={<Icon name="arrow_right_up_line" />}>打开接口</Button>`}
>
<Space gap="md" wrap>
<Button icon={<Icon name="refresh_3_line" />}>重新扫描</Button>
<Button shape="pill" variant="secondary" icon={<Icon name="arrow_right_up_line" />}>
打开接口
</Button>
</Space>
<Button block icon={<Icon name="link_line" />}>
占满一行的按钮
</Button>
</Demo>
<Demo
title="图标按钮"
desc="xs / sm / md 是 28 / 36 / 44 的圆形,图标字号 16 / 20 / 24;ghost 用于顶栏,soft 用于需要一点底色的场景。"
code={`<IconButton label="搜索" icon={<Icon name="search_3_line" />} />
<IconButton label="更多" icon={<Icon name="more_3_line" />} variant="soft" />
<IconButton label="关闭" icon={<Icon name="close_line" />} size="xs" />
<IconButton label="刷新中" icon={<Icon name="refresh_3_line" />} spinning variant="soft" />`}
>
<IconButton label="搜索" icon={<Icon name="search_3_line" />} />
<IconButton label="用户" icon={<Icon name="user_3_line" />} />
<IconButton label="更多" icon={<Icon name="more_3_line" />} variant="soft" />
<IconButton label="小号" icon={<Icon name="close_line" />} size="xs" />
<IconButton label="大号" icon={<Icon name="share_3_line" />} size="md" variant="soft" />
<IconButton label="刷新中" icon={<Icon name="refresh_3_line" />} spinning variant="soft" />
</Demo>
<Demo
title="尺寸与进行中"
desc="sm 32 / md 36 / lg 44;spinning 让图标原地旋转(刷新类动作),loading 则换成转圈。"
code={`<Button size="lg">大按钮</Button>
<Button spinning icon={<Icon name="refresh_3_line" />}>重新扫描</Button>`}
>
<Space gap="md" wrap>
<Button size="sm">小号 32</Button>
<Button size="md">默认 36</Button>
<Button size="lg">大号 44</Button>
<Button variant="secondary" spinning icon={<Icon name="refresh_3_line" />}>
重新扫描
</Button>
</Space>
</Demo>
<PropsTable
rows={[
{ name: 'variant', type: "'primary' | 'secondary' | 'outline' | 'ghost' | 'danger'", defaultValue: "'primary'", desc: '语义变体' },
{ name: 'size', type: "'sm' | 'md' | 'lg'", defaultValue: "'md'", desc: '32 / 36 / 44px 高' },
{ name: 'spinning', type: 'boolean', defaultValue: 'false', desc: '图标原地旋转(不换转圈)' },
{ name: 'shape', type: "'rounded' | 'pill'", defaultValue: "'rounded'", desc: '6px 圆角 / 胶囊' },
{ name: 'block', type: 'boolean', defaultValue: 'false', desc: '占满一行' },
{ name: 'loading', type: 'boolean', defaultValue: 'false', desc: '加载中,自动禁用' },
{ name: 'icon', type: 'ReactNode', desc: '文字左侧图标' },
{ name: '…rest', type: 'ButtonHTMLAttributes', desc: '透传原生属性(type 默认 button)' },
]}
/>
<PropsTable
rows={[
{ name: 'label', type: 'string', required: true, desc: '无障碍名称,同时作为 title' },
{ name: 'icon', type: 'ReactNode', required: true, desc: '按钮里的图标' },
{ name: 'variant', type: "'ghost' | 'soft'", defaultValue: "'ghost'", desc: '是否有底色' },
{ name: 'size', type: "'xs' | 'sm' | 'md'", defaultValue: "'sm'", desc: '28 / 36 / 44px 圆形' },
{ name: 'spinning', type: 'boolean', defaultValue: 'false', desc: '图标旋转' },
]}
/>
</Section>
)
}