139 lines
4.7 KiB
TypeScript
139 lines
4.7 KiB
TypeScript
import { Divider, Grid, Space, Tag } from '../../src'
|
||
import { Demo } from '../components/Demo'
|
||
import { PropsTable } from '../components/PropsTable'
|
||
import { Section } from '../components/Section'
|
||
import { DEMO_POSTERS } from '../data/demo'
|
||
|
||
const BLOCKS = [1, 2, 3, 4, 5, 6, 7, 8]
|
||
|
||
function Block({ index, tall = false }: { index: number; tall?: boolean }) {
|
||
return (
|
||
<div
|
||
style={{
|
||
display: 'grid',
|
||
placeItems: 'center',
|
||
height: tall ? 96 : 56,
|
||
borderRadius: 'var(--su-radius-sm)',
|
||
background: 'var(--su-gray-2)',
|
||
color: 'var(--su-text-muted)',
|
||
fontSize: 12,
|
||
}}
|
||
>
|
||
{index}
|
||
</div>
|
||
)
|
||
}
|
||
|
||
export function Layouts() {
|
||
return (
|
||
<Section
|
||
id="layouts"
|
||
title="网格与间距"
|
||
api="Grid / Space / Divider"
|
||
desc="页面布局只保留三件套:给卡片列表用的 Grid(列数与断点收在组件里),给元素间距用的 Space,以及分隔内容块的 Divider。"
|
||
>
|
||
<Demo
|
||
title="网格列数"
|
||
desc="窄屏自动退化:≤1100px 取一半(至少 2 列),≤720px 收成一列;也可以显式指定 tabletColumns / mobileColumns。"
|
||
layout="column"
|
||
code={`<Grid columns={4} gap="md">…</Grid>
|
||
<Grid columns={6} tabletColumns={3} mobileColumns={2} gap="sm">…</Grid>`}
|
||
>
|
||
<Grid columns={4} gap="md">
|
||
{BLOCKS.slice(0, 4).map((index) => (
|
||
<Block key={index} index={index} />
|
||
))}
|
||
</Grid>
|
||
<Grid columns={6} tabletColumns={3} mobileColumns={2} gap="sm">
|
||
{BLOCKS.map((index) => (
|
||
<Block key={index} index={index} />
|
||
))}
|
||
</Grid>
|
||
</Demo>
|
||
|
||
<Demo
|
||
title="列表语义"
|
||
desc="传 as='ul' 时用 li 做列表项,屏幕阅读器能读出条目数;纯展示容器用默认的 div。"
|
||
layout="column"
|
||
code={`<Grid as="ul" role="list" columns={4} gap="md">
|
||
{items.map((item) => <li key={item.id}>…</li>)}
|
||
</Grid>`}
|
||
>
|
||
<Grid as="ul" role="list" columns={4} gap="md">
|
||
{DEMO_POSTERS.map((poster) => (
|
||
<li key={poster.id} style={{ listStyle: 'none' }}>
|
||
<div
|
||
style={{
|
||
display: 'flex',
|
||
flexDirection: 'column',
|
||
alignItems: 'flex-start',
|
||
gap: 'var(--su-space-2)',
|
||
padding: 'var(--su-space-3)',
|
||
border: '1px solid var(--su-border)',
|
||
borderRadius: 'var(--su-radius-md)',
|
||
}}
|
||
>
|
||
<span style={{ fontWeight: 500 }}>{poster.title}</span>
|
||
<Tag shape="pill" tone="neutral">
|
||
{poster.tag}
|
||
</Tag>
|
||
</div>
|
||
</li>
|
||
))}
|
||
</Grid>
|
||
</Demo>
|
||
|
||
<Demo
|
||
title="间距"
|
||
desc="Space 只是 flex + gap 的封装,方向、间距、对齐都用语义化的档位表达,避免每个页面各写一套像素值。"
|
||
layout="column"
|
||
code={`<Space gap="md">
|
||
<Tag>本地</Tag>
|
||
<span>docs</span>
|
||
</Space>
|
||
|
||
<Space direction="column" gap="sm" align="start">…</Space>`}
|
||
>
|
||
<Space gap="md">
|
||
<Tag>本地</Tag>
|
||
<span>docs</span>
|
||
<Tag tone="success" dot>
|
||
已连接
|
||
</Tag>
|
||
</Space>
|
||
<Space direction="column" gap="sm" align="start">
|
||
<span style={{ fontWeight: 500 }}>竖向排列</span>
|
||
<span style={{ color: 'var(--su-text-muted)' }}>适合标题 + 描述这类两行结构</span>
|
||
</Space>
|
||
</Demo>
|
||
|
||
<Demo
|
||
title="分隔线"
|
||
desc="横向分隔内容块,纵向分隔并排元素;虚线用于「弱分隔」,和实线区分层级。"
|
||
layout="column"
|
||
code={`<Divider />
|
||
<Divider variant="dashed" spacing="sm" />
|
||
<Space gap="sm"><span>左</span><Divider orientation="vertical" /><span>右</span></Space>`}
|
||
>
|
||
<Divider />
|
||
<Divider variant="dashed" spacing="sm" />
|
||
<Space gap="sm">
|
||
<span>左</span>
|
||
<Divider orientation="vertical" />
|
||
<span>右</span>
|
||
</Space>
|
||
</Demo>
|
||
|
||
<PropsTable
|
||
rows={[
|
||
{ name: 'columns', type: 'number', defaultValue: '4', desc: '宽屏列数' },
|
||
{ name: 'tabletColumns', type: 'number', defaultValue: 'columns / 2(至少 2)', desc: '≤1100px 列数' },
|
||
{ name: 'mobileColumns', type: 'number', defaultValue: '1', desc: '≤720px 列数' },
|
||
{ name: 'gap', type: "'sm' | 'md' | 'lg'", defaultValue: "'md'", desc: '间距档位' },
|
||
{ name: 'as', type: "'div' | 'ul'", defaultValue: "'div'", desc: '列表语义' },
|
||
]}
|
||
/>
|
||
</Section>
|
||
)
|
||
}
|