168 lines
5.4 KiB
TypeScript
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>
|
|
)
|
|
}
|