Files
stash-ui/site/sections/Composition.tsx
T

168 lines
5.4 KiB
TypeScript

import {
Avatar,
Badge,
Button,
Card,
Grid,
Icon,
IconButton,
Input,
ItemBadge,
Space,
Tag,
} from '../../src'
import { Demo } from '../components/Demo'
import { Section } from '../components/Section'
import { DEMO_APPS, DEMO_COVER, DEMO_POSTERS } from '../data/demo'
import styles from './Composition.module.css'
/**
* 组合示例:把基础组件拼成真实页面里的几块结构。
*
* 这一节不放新组件,只演示「怎么拼」——
* 后期做新页面时,从这里复制结构再改数据即可。
*/
export function Composition() {
return (
<Section
id="composition"
title="组合示例"
api="页面配方"
desc="基础组件只提供外观与行为,页面结构靠组合。下面三块都是 Stash 控制台里真实存在的结构,可以直接当模板用。"
>
<Demo
title="分区卡片(首页)"
desc="Card 提供容器,标题栏由「色条 + 标题 + 角标 + 更多按钮」拼出来,内容区用 Grid 排应用行。角标压在标题右上角,靠绝对定位。"
muted
layout="column"
code={`<Card>
<header className={styles.sectionHead}>
<Space gap="md">
<span className={styles.bar} />
<ItemBadge tone="sticky">置顶</ItemBadge>
<span className={styles.titleWrap}>
<span className={styles.title}>常用站点</span>
<Badge count={18} className={styles.badge} />
</span>
</Space>
<IconButton label="查看全部" icon={<Icon name="more_3_line" />} />
</header>
<Grid columns={4} gap="md">
{apps.map((app) => (
<a className={styles.appRow} key={app.id} href="#">
<Avatar size="lg" fallback={app.icon} />
<span className={styles.appInfo}>
<span className={styles.appName}>{app.name}</span>
<span className={styles.appDesc}>{app.desc}</span>
</span>
</a>
))}
</Grid>
</Card>`}
>
<Card padding="lg">
<header className={styles.sectionHead}>
<div className={styles.headMain}>
<span className={styles.bar} />
<ItemBadge tone="sticky">置顶</ItemBadge>
<span className={styles.titleWrap}>
<span className={styles.title}>常用站点</span>
<Badge count={18} className={styles.badge} />
</span>
</div>
<IconButton label="查看全部" icon={<Icon name="more_3_line" />} />
</header>
<Grid columns={4} gap="md">
{DEMO_APPS.slice(0, 4).map((app) => (
<a
className={styles.appRow}
key={app.id}
href="#composition"
onClick={(event) => event.preventDefault()}
>
<Avatar size="lg" fallback={app.icon} />
<span className={styles.appInfo}>
<span className={styles.appName}>{app.name}</span>
<span className={styles.appDesc}>{app.desc}</span>
</span>
</a>
))}
</Grid>
</Card>
</Demo>
<Demo
title="筛选工具条"
desc="搜索框 + 条件标签 + 操作按钮:左侧输入,右侧动作,中间用 Space 的 justify=between 撑开。"
muted
layout="column"
code={`<Card padding="sm">
<Space justify="between" wrap>
<Space gap="sm">
<Input icon="search_3_line" placeholder="筛选项目…" />
<Tag tone="neutral">全部 42</Tag>
</Space>
<Space gap="sm">
<Button variant="ghost" size="sm">重置</Button>
<Button size="sm">应用</Button>
</Space>
</Space>
</Card>`}
>
<Card padding="sm">
<Space justify="between" wrap>
<Space gap="sm">
<Input icon="search_3_line" placeholder="筛选项目…" style={{ width: 220 }} />
<Tag tone="neutral">全部 42</Tag>
</Space>
<Space gap="sm">
<Button variant="ghost" size="sm">
重置
</Button>
<Button size="sm">应用</Button>
</Space>
</Space>
</Card>
</Demo>
<Demo
title="海报卡(图文列表)"
desc="Card padding=none 承载贴边封面,图片用 aspect-ratio 固定比例,避免加载前后跳动;标题与标签放卡片底部。"
muted
layout="column"
code={`<Grid columns={4} gap="md">
{posters.map((poster) => (
<Card padding="none" className={styles.posterCard} key={poster.id}>
<span className={styles.posterCover}>
<img src={cover} alt="" />
</span>
<span className={styles.posterBody}>
<span className={styles.posterTitle}>{poster.title}</span>
<Tag shape="pill" tone="neutral">{poster.tag}</Tag>
</span>
</Card>
))}
</Grid>`}
>
<Grid columns={4} gap="md">
{DEMO_POSTERS.map((poster) => (
<Card padding="none" className={styles.posterCard} key={poster.id}>
<span className={styles.posterCover}>
<img src={DEMO_COVER} alt="" />
</span>
<span className={styles.posterBody}>
<span className={styles.posterTitle}>{poster.title}</span>
<Tag shape="pill" tone="neutral">
{poster.tag}
</Tag>
</span>
</Card>
))}
</Grid>
</Demo>
</Section>
)
}