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
+120
View File
@@ -0,0 +1,120 @@
import { useState } from 'react'
import { Button, Modal, Notice, Space } from '../../src'
import { Demo } from '../components/Demo'
import { PropsTable } from '../components/PropsTable'
import { Section } from '../components/Section'
export function Modals() {
const [confirmOpen, setConfirmOpen] = useState(false)
const [infoOpen, setInfoOpen] = useState(false)
const [deleted, setDeleted] = useState(false)
return (
<Section
id="modal"
title="弹窗"
api="Modal"
desc="基于原生 <dialog>:焦点陷阱、Esc 关闭、背景 inert 由浏览器提供,组件补样式、滚动锁和受控开关。对应参考站的 .nice-tips(遮罩 60% 黑、内容 12px 圆角、上滑淡入)。"
>
<Demo
title="确认弹窗"
desc="危险操作要二次确认;确认后由调用方关闭并把结果反馈给页面(这里用 Notice 示意)。"
layout="column"
code={`const [open, setOpen] = useState(false)
<Modal
open={open}
onClose={() => setOpen(false)}
title="删除这篇内容?"
footer={
<>
<Button variant="ghost" onClick={() => setOpen(false)}>取消</Button>
<Button variant="danger" onClick={handleDelete}>删除</Button>
</>
}
>
删除后不可恢复,占位数据会被一起清掉。
</Modal>`}
>
<Space gap="md" wrap>
<Button variant="danger" onClick={() => setConfirmOpen(true)}>
删除内容
</Button>
<Button variant="secondary" onClick={() => setInfoOpen(true)}>
打开说明弹窗
</Button>
</Space>
{deleted && (
<Notice title="示例:已删除" action={{ label: '撤销', onClick: () => setDeleted(false) }}>
这里只是演示确认流程,没有真的删数据。
</Notice>
)}
</Demo>
<Demo
title="尺寸与长内容"
desc="sm 300 / md 460 / lg 640;内容多时弹窗内部不滚动、由页面决定(这里演示 lg 的排版)。"
layout="column"
code={`<Modal size="lg" title="关于这套组件" open={open} onClose={close}>…</Modal>`}
>
<Button variant="secondary" onClick={() => setInfoOpen(true)}>
打开 lg 弹窗
</Button>
</Demo>
<PropsTable
rows={[
{ name: 'open', type: 'boolean', required: true, desc: '受控开关' },
{ name: 'onClose', type: '() => void', required: true, desc: 'Esc / 遮罩 / 关闭按钮都会调用' },
{ name: 'title', type: 'ReactNode', required: true, desc: '标题,同时作为 aria-labelledby' },
{ name: 'children', type: 'ReactNode', desc: '正文' },
{ name: 'footer', type: 'ReactNode', desc: '底部操作区(通常放按钮)' },
{ name: 'size', type: "'sm' | 'md' | 'lg'", defaultValue: "'md'", desc: '300 / 460 / 640' },
{ name: 'closeOnOverlay', type: 'boolean', defaultValue: 'true', desc: '点遮罩是否关闭' },
]}
/>
<Modal
open={confirmOpen}
onClose={() => setConfirmOpen(false)}
title="删除这篇内容?"
footer={
<>
<Button variant="ghost" onClick={() => setConfirmOpen(false)}>
取消
</Button>
<Button
variant="danger"
onClick={() => {
setConfirmOpen(false)
setDeleted(true)
}}
>
删除
</Button>
</>
}
>
删除后不可恢复,占位数据会被一起清掉。
</Modal>
<Modal
open={infoOpen}
onClose={() => setInfoOpen(false)}
title="关于这套组件"
size="lg"
footer={
<Button onClick={() => setInfoOpen(false)}>知道了</Button>
}
>
<p>
组件只依赖令牌,不依赖任何业务数据;页面用 Card / Grid / Space 组合,弹窗只负责「打断」。
</p>
<p style={{ marginTop: 12 }}>
关闭方式有三种:右上角按钮、Esc、点击遮罩。打开时背景滚动会被锁住,关闭后恢复。
</p>
</Modal>
</Section>
)
}