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
+42
View File
@@ -0,0 +1,42 @@
import type { ReactNode } from 'react'
/**
* 一个用法示例:标题 + 说明 + 预览区 + 可选代码。
*
* 预览区默认横向排列,需要纵向(表单、长文)时传 `layout="column"`。
*/
type DemoProps = {
title: string
desc?: ReactNode
/** 展示给使用方的代码片段 */
code?: string
layout?: 'row' | 'column'
/** 灰底预览,用于白色组件(卡片)看得清边界 */
muted?: boolean
children: ReactNode
}
export function Demo({ title, desc, code, layout = 'row', muted = false, children }: DemoProps) {
const previewClasses = [
'demo-preview',
layout === 'column' ? 'demo-preview--column' : undefined,
muted ? 'demo-preview--muted' : undefined,
]
.filter(Boolean)
.join(' ')
return (
<article className="demo">
<h3 className="demo-title">{title}</h3>
{desc !== undefined && <p className="demo-desc">{desc}</p>}
<div className={previewClasses}>{children}</div>
{code !== undefined && (
<pre className="demo-code">
<code>{code}</code>
</pre>
)}
</article>
)
}
+44
View File
@@ -0,0 +1,44 @@
/**
* Props 表:手写维护,保持和组件定义同步。
*
* 只列对外承诺的 props;内部实现用的字段不写进来。
*/
export type PropRow = {
name: string
type: string
required?: boolean
defaultValue?: string
desc: string
}
export function PropsTable({ rows }: { rows: PropRow[] }) {
return (
<div className="props-table-wrap">
<table className="props-table">
<thead>
<tr>
<th>属性</th>
<th>类型</th>
<th>默认值</th>
<th>说明</th>
</tr>
</thead>
<tbody>
{rows.map((row) => (
<tr key={row.name}>
<td>
<code>{row.name}</code>
{row.required === true && ' *'}
</td>
<td className="props-type">
<code>{row.type}</code>
</td>
<td className="props-type">{row.defaultValue ?? '—'}</td>
<td>{row.desc}</td>
</tr>
))}
</tbody>
</table>
</div>
)
}
+29
View File
@@ -0,0 +1,29 @@
import type { ReactNode } from 'react'
/**
* 文档的一节:锚点 + 标题 + 说明。
*
* 每个组件一节,节内再用 Demo 摆具体用法,方便直接翻着找。
*/
type SectionProps = {
/** 锚点 id,与左侧目录一致 */
id: string
title: string
/** 右侧灰字,通常写组件名或导出路径 */
api?: string
desc?: ReactNode
children: ReactNode
}
export function Section({ id, title, api, desc, children }: SectionProps) {
return (
<section id={id} className="doc-section">
<div className="doc-section-title">
<h2>{title}</h2>
{api !== undefined && <code>{api}</code>}
</div>
{desc !== undefined && <p className="doc-section-desc">{desc}</p>}
{children}
</section>
)
}