This commit is contained in:
sunzhongyi
2026-05-20 01:30:49 +08:00
parent 7dded89537
commit 610805a374
42 changed files with 3451 additions and 0 deletions
@@ -0,0 +1,219 @@
'use client';
import {
Layout,
Section,
Article,
Layer,
Headline,
Subhead,
BodyText,
} from '@newspaperui/components';
import { Demo } from '@/components/Demo';
import { PropsTable } from '@/components/PropsTable';
export default function ArticlePage() {
return (
<Layout columns={24} maxWidth="900px" padding="2rem">
<Section columns={24}>
<Article span={24}>
<Headline weight="Medium" as="h1">
Article + Layer
</Headline>
<Subhead weight="Medium">
Article 是栅格内的文章块,通过 grid-column span 跨栏。Layer 是脱离文档流的浮动层。
</Subhead>
<Headline weight="Low" as="h2">
Article API
</Headline>
<PropsTable
data={[
{
name: 'span',
type: 'number',
description: '跨多少列(≤ Section.columns)。缺省时占满全宽。',
},
{
name: 'breakable',
type: 'boolean',
default: 'true',
description: '允许打印时跨页断开。',
},
{
name: 'className',
type: 'string',
description: '自定义 CSS 类名。',
},
{
name: 'style',
type: 'CSSProperties',
description: '自定义内联样式。',
},
{
name: 'children',
type: 'ReactNode',
required: true,
description: '文章内容。',
},
]}
/>
<Headline weight="Low" as="h2">
跨栏 Demo
</Headline>
<Demo
title="8 + 16 跨栏"
description="左侧 8 列 + 右侧 16 列,模拟短讯 + 主稿布局。"
code={`<Layout columns={24}>
<Section columns={24}>
<Article span={8}>
<Headline weight="Low">短讯</Headline>
<BodyText>...</BodyText>
</Article>
<Article span={16}>
<Headline weight="Medium">主稿</Headline>
<BodyText columns={2}>...</BodyText>
</Article>
</Section>
</Layout>`}
>
<Layout columns={24} padding="0">
<Section columns={24}>
<Article span={8}>
<Headline weight="Low" as="h3">
短讯
</Headline>
<BodyText weight="Low">
<p>
Markets responded cautiously through the morning session. The pound
traded sideways against the dollar, gilts firmed by three basis points.
</p>
</BodyText>
</Article>
<Article span={16}>
<Headline weight="Medium" as="h3">
主稿
</Headline>
<BodyText columns={2}>
<p>
Whitehall officials confirmed late Tuesday that the long-anticipated
review of national infrastructure funding will be tabled before the
recess. The 248-page document, drafted across three departments,
recommends a recalibration of regional priorities and a measured shift
toward rail electrification.
</p>
<p>
Critics inside the cabinet caution that the timing risks overshadowing
the chancellor&rsquo;s autumn statement, while supporters describe the
proposals as the most coherent strategic blueprint in a generation.
</p>
</BodyText>
</Article>
</Section>
</Layout>
</Demo>
<Headline weight="Low" as="h2" style={{ marginTop: '2rem' }}>
Layer API
</Headline>
<BodyText weight="Low">
<p>
Layer 脱离栅格流,使用 CSS position 定位。适合浮动拉引、浮动广告、sticky 导航等场景。
</p>
</BodyText>
<PropsTable
data={[
{
name: 'position',
type: "'absolute' | 'fixed' | 'sticky'",
default: "'absolute'",
description: 'CSS position 属性。',
},
{
name: 'top',
type: 'string | number',
description: '距离顶部的距离。',
},
{
name: 'left',
type: 'string | number',
description: '距离左侧的距离。',
},
{
name: 'right',
type: 'string | number',
description: '距离右侧的距离。',
},
{
name: 'bottom',
type: 'string | number',
description: '距离底部的距离。',
},
{
name: 'zIndex',
type: 'number',
description: 'z-index 层级。',
},
{
name: 'children',
type: 'ReactNode',
required: true,
description: '浮动层内容。',
},
]}
/>
<Demo
title="Layer 浮动拉引"
description="在文章旁边添加浮动的拉引文字。父容器需要 position: relative。"
code={`<div style={{ position: 'relative', minHeight: '200px' }}>
<Article span={16}>
<Headline weight="Low">主要文章</Headline>
<BodyText>...</BodyText>
</Article>
<Layer position="absolute" top="0" right="0">
<aside>浮动内容</aside>
</Layer>
</div>`}
>
<Layout columns={24} padding="0">
<Section columns={24}>
<div style={{ position: 'relative', minHeight: '200px', gridColumn: 'span 24' }}>
<Article span={16}>
<Headline weight="Low" as="h3">
主要文章
</Headline>
<BodyText>
<p>
In Manchester, regional officials greeted the announcement with
measured optimism. The mayor&rsquo;s office is expected to issue a
formal response by week&rsquo;s end.
</p>
</BodyText>
</Article>
<Layer position="absolute" top="0" right="0">
<aside
style={{
width: '180px',
padding: '1rem',
borderTop: '1px solid var(--nui-rule-hairline)',
borderBottom: '1px solid var(--nui-rule-hairline)',
fontFamily: 'var(--font-family-display)',
fontSize: '18px',
lineHeight: 1.3,
color: 'var(--nui-text-primary)',
}}
>
&ldquo;We have lobbied for this kind of clarity for the better part of
a decade.&rdquo;
</aside>
</Layer>
</div>
</Section>
</Layout>
</Demo>
</Article>
</Section>
</Layout>
);
}
@@ -0,0 +1,148 @@
'use client';
import {
Layout,
Section,
Article,
Headline,
Subhead,
BodyText,
Masthead,
} from '@newspaperui/components';
import { Demo } from '@/components/Demo';
import { PropsTable } from '@/components/PropsTable';
export default function MastheadPage() {
return (
<Layout columns={24} maxWidth="900px" padding="2rem">
<Section columns={24}>
<Article span={24}>
<Headline weight="Medium" as="h1">
Masthead 报头
</Headline>
<Subhead weight="Medium">
报头是报纸的门面。三个 variant 覆盖经典双线居中、哥特体、现代左对齐三种风格。
</Subhead>
<Headline weight="Low" as="h2">
API
</Headline>
<PropsTable
data={[
{
name: 'title',
type: 'string',
required: true,
description: '报名文字。',
},
{
name: 'variant',
type: "'classic' | 'blackletter' | 'modern'",
default: "'classic'",
description: '视觉风格。',
},
{
name: 'kicker',
type: 'string',
description: '报名上方的小标(如 "All the News That\'s Fit to Print")。',
},
{
name: 'edition',
type: 'string',
description: '版次(如 "Vol. CLXXII No. 59,678")。',
},
{
name: 'date',
type: 'string',
description: '日期(如 "Monday, May 19, 2026")。',
},
{
name: 'price',
type: 'string',
description: '售价(如 "$3.00")。',
},
]}
/>
<Headline weight="Low" as="h2">
Classic
</Headline>
<Demo
title="classic variant"
description="双线居中,Cormorant Garamond 衬线。"
code={`<Masthead
variant="classic"
title="The Daily Chronicle"
kicker="All the News That's Fit to Print"
edition="Vol. CLXXII No. 59,678"
date="Monday, May 19, 2026"
price="$3.00"
/>`}
>
<Masthead
variant="classic"
title="The Daily Chronicle"
kicker="All the News That's Fit to Print"
edition="Vol. CLXXII No. 59,678"
date="Monday, May 19, 2026"
price="$3.00"
/>
</Demo>
<Headline weight="Low" as="h2">
Blackletter
</Headline>
<Demo
title="blackletter variant"
description="UnifrakturMaguntia 哥特体,The Times 风格。"
code={`<Masthead
variant="blackletter"
title="The Evening Standard"
edition="Late Final Edition"
date="Monday, May 19, 2026"
price="£2.50"
/>`}
>
<Masthead
variant="blackletter"
title="The Evening Standard"
edition="Late Final Edition"
date="Monday, May 19, 2026"
price="£2.50"
/>
</Demo>
<Headline weight="Low" as="h2">
Modern
</Headline>
<Demo
title="modern variant"
description="左对齐 + accent 强调色,适合数字优先的出版物。"
code={`<Masthead
variant="modern"
title="The Observer"
kicker="Sunday Edition"
date="May 19, 2026"
/>`}
>
<Masthead
variant="modern"
title="The Observer"
kicker="Sunday Edition"
date="May 19, 2026"
/>
</Demo>
<Headline weight="Low" as="h2">
使用建议
</Headline>
<BodyText weight="Low">
<p>
Masthead 默认 <code>gridColumn: 1 / -1</code>,在 Section 内自动全宽。
通常放在 Layout 的第一个 Section 中,后接 Rule 分隔线。
</p>
</BodyText>
</Article>
</Section>
</Layout>
);
}
@@ -0,0 +1,166 @@
'use client';
import {
Layout,
Section,
Article,
Headline,
Subhead,
BodyText,
Figure,
PullQuote,
} from '@newspaperui/components';
import { Demo } from '@/components/Demo';
import { PropsTable } from '@/components/PropsTable';
export default function MediaPage() {
return (
<Layout columns={24} maxWidth="900px" padding="2rem">
<Section columns={24}>
<Article span={24}>
<Headline weight="Medium" as="h1">
媒体组件
</Headline>
<Subhead weight="Medium">
Image、Figure、Video、PullQuote — 报纸版面中的视觉元素。
</Subhead>
<Headline weight="Low" as="h2">
Image
</Headline>
<BodyText weight="Low">
<p>
基础图片组件。<code>display: block; width: 100%</code>,在 Section 栅格内通过
span 跨栏。
</p>
</BodyText>
<PropsTable
data={[
{ name: 'src', type: 'string', required: true, description: '图片 URL。' },
{ name: 'alt', type: 'string', required: true, description: '替代文本。' },
{ name: 'span', type: 'number', description: '跨栏数。' },
]}
/>
<Headline weight="Low" as="h2">
Figure
</Headline>
<BodyText weight="Low">
<p>
组合 Image + Caption + Credit 的语义容器。自动渲染 figcaption。
</p>
</BodyText>
<PropsTable
data={[
{ name: 'src', type: 'string', required: true, description: '图片 URL。' },
{ name: 'alt', type: 'string', required: true, description: '替代文本。' },
{ name: 'caption', type: 'string', description: '图片说明。' },
{ name: 'credit', type: 'string', description: '摄影师/来源(small-caps 渲染)。' },
{ name: 'span', type: 'number', description: '跨栏数。' },
]}
/>
<Demo
title="Figure 带 caption 和 credit"
description="使用 Unsplash 占位图演示完整效果。"
code={`<Figure
src="https://images.unsplash.com/photo-1495020689067-958852a7765e?w=800&h=400&fit=crop"
alt="Newspapers on a wooden table"
caption="A view of the morning editions, arranged on the newsroom table."
credit="Photograph by Roman Kraft / Unsplash"
/>`}
>
<Figure
src="https://images.unsplash.com/photo-1495020689067-958852a7765e?w=800&h=400&fit=crop"
alt="Newspapers on a wooden table"
caption="A view of the morning editions, arranged on the newsroom table."
credit="Photograph by Roman Kraft / Unsplash"
/>
</Demo>
<Headline weight="Low" as="h2">
Video
</Headline>
<PropsTable
data={[
{ name: 'src', type: 'string', required: true, description: '视频 URL。' },
{ name: 'poster', type: 'string', description: '封面图 URL。' },
{ name: 'caption', type: 'string', description: '视频说明。' },
{ name: 'credit', type: 'string', description: '来源。' },
{ name: 'controls', type: 'boolean', default: 'true', description: '显示播放控件。' },
{ name: 'span', type: 'number', description: '跨栏数。' },
]}
/>
<BodyText weight="Low">
<p>
Video 组件与 Figure 结构类似,包裹 <code>&lt;video&gt;</code> 标签并附带
caption/credit。
</p>
</BodyText>
<Headline weight="Low" as="h2">
PullQuote
</Headline>
<BodyText weight="Low">
<p>
上下双 hairline + Display 字体的拉引组件。在多栏 BodyText 内设置
<code>spanAllColumns</code> 可跨所有栏(通过 <code>column-span: all</code>)。
</p>
</BodyText>
<PropsTable
data={[
{ name: 'weight', type: "'High' | 'Medium'", default: "'High'", description: '视觉权重。' },
{ name: 'span', type: 'number', description: '在 Section 栅格内跨栏。' },
{ name: 'spanAllColumns', type: 'boolean', default: 'false', description: '在多栏 BodyText 内跨所有栏。' },
{ name: 'author', type: 'string', description: '引用来源。' },
{ name: 'align', type: "'left' | 'center'", default: "'left'", description: '文本对齐。' },
]}
/>
<Demo
title="PullQuote 独立使用"
code={`<PullQuote author="Senior Cabinet Official">
We have lobbied for this kind of clarity for the better part of a decade.
</PullQuote>`}
>
<PullQuote author="Senior Cabinet Official">
We have lobbied for this kind of clarity for the better part of a decade.
</PullQuote>
</Demo>
<Demo
title="PullQuote 在多栏 BodyText 内跨栏"
description="spanAllColumns 使 PullQuote 通过 column-span: all 跨越所有文字栏。"
code={`<BodyText columns={3}>
<p>...</p>
<PullQuote spanAllColumns author="...">...</PullQuote>
<p>...</p>
</BodyText>`}
>
<BodyText columns={3}>
<p>
Whitehall officials confirmed late Tuesday that the long-anticipated review
of national infrastructure funding will be tabled before the recess. The
248-page document, drafted across three departments, recommends a
recalibration of regional priorities and a measured shift toward rail
electrification.
</p>
<PullQuote spanAllColumns author="Senior Cabinet Official">
The most coherent strategic blueprint in a generation.
</PullQuote>
<p>
Markets responded cautiously through the morning session. The pound traded
sideways against the dollar, gilts firmed by three basis points, and the
FTSE 100 closed marginally lower as defensive sectors absorbed the
day&rsquo;s modest outflows.
</p>
<p>
In Manchester, regional officials greeted the announcement with measured
optimism. The mayor&rsquo;s office is expected to issue a formal response by
week&rsquo;s end, focusing on commitments to the trans-Pennine corridor.
</p>
</BodyText>
</Demo>
</Article>
</Section>
</Layout>
);
}
@@ -0,0 +1,134 @@
'use client';
import {
Layout,
Section,
Article,
Headline,
Subhead,
BodyText,
Rule,
} from '@newspaperui/components';
import { Demo } from '@/components/Demo';
import { PropsTable } from '@/components/PropsTable';
export default function RulePage() {
return (
<Layout columns={24} maxWidth="900px" padding="2rem">
<Section columns={24}>
<Article span={24}>
<Headline weight="Medium" as="h1">
Rule 分隔线
</Headline>
<Subhead weight="Medium">
显式分隔线组件。三个 variant 覆盖 hairline、double、thick,支持水平和垂直方向。
</Subhead>
<Headline weight="Low" as="h2">
API
</Headline>
<PropsTable
data={[
{
name: 'variant',
type: "'hairline' | 'double' | 'thick'",
default: "'hairline'",
description: '线型。',
},
{
name: 'orientation',
type: "'horizontal' | 'vertical'",
default: "'horizontal'",
description: '方向。',
},
{
name: 'span',
type: 'number',
description: '横向时占多少列。缺省时 1 / -1 全跨。',
},
{
name: 'className',
type: 'string',
description: '自定义 CSS 类名。',
},
{
name: 'style',
type: 'CSSProperties',
description: '自定义内联样式。',
},
]}
/>
<Headline weight="Low" as="h2">
水平方向三种 variant
</Headline>
<Demo title="hairline / double / thick" description="水平分隔线对照。">
<div style={{ display: 'flex', flexDirection: 'column', gap: '2rem' }}>
<div>
<BodyText weight="Low">
<p>hairline</p>
</BodyText>
<Rule variant="hairline" />
</div>
<div>
<BodyText weight="Low">
<p>double</p>
</BodyText>
<Rule variant="double" />
</div>
<div>
<BodyText weight="Low">
<p>thick</p>
</BodyText>
<Rule variant="thick" />
</div>
</div>
</Demo>
<Headline weight="Low" as="h2">
垂直方向
</Headline>
<Demo
title="垂直分隔线"
description="在两栏之间放置垂直 Rule。"
code={`<div style={{ display: 'flex', gap: '1.5rem', height: '120px' }}>
<div>左栏内容</div>
<Rule variant="hairline" orientation="vertical" />
<div>右栏内容</div>
</div>`}
>
<div style={{ display: 'flex', gap: '1.5rem', height: '120px', alignItems: 'stretch' }}>
<div style={{ flex: 1 }}>
<BodyText weight="Low">
<p>
Markets responded cautiously through the morning session. The pound
traded sideways against the dollar.
</p>
</BodyText>
</div>
<Rule variant="hairline" orientation="vertical" />
<div style={{ flex: 1 }}>
<BodyText weight="Low">
<p>
Analysts at three of the City&rsquo;s largest houses framed the move as
a holding pattern.
</p>
</BodyText>
</div>
</div>
</Demo>
<Headline weight="Low" as="h2">
使用建议
</Headline>
<BodyText weight="Low">
<p>
Rule 在 Section 栅格内默认 <code>gridColumn: 1 / -1</code> 全跨。
如果只需要跨部分列,传入 <code>span</code> prop。垂直 Rule 适合放在
flex 容器中作为栏间分隔。
</p>
</BodyText>
</Article>
</Section>
</Layout>
);
}