布局与卡片
布局组件负责宽度、排列与间距,卡片和面板负责内容表面及分区。PageContainer 限制页面宽度,Stack 纵向排列,Cluster 横向排列并换行;Panel 可组合标题、正文与页脚。卡片家族提供标题、链接、统计和分享等结构,页面业务与响应式网格仍由宿主组织。间距与容器宽度使用像素数值,链接接入宿主路由,标题层级需要与页面结构保持一致。
参考资料
效果展示
页面布局
| 组件 | 主要属性 | 行为 |
|---|---|---|
PageContainer | children、width | 居中限制内容宽度,默认最大 1120 px |
SiteHeader | brand、navigation、actions | 网站顶部栏与响应式排列 |
Stack | children、gap | 纵向排列,默认间距 16 px |
Cluster | children、gap | 横向排列并换行,默认间距 12 px |
PageHeader | children、aside | 标题区域与附加内容 |
PageTitle | title、description | 页面标题与说明 |
PageContent | children、as、className | 页面正文容器,可选择元素类型 |
PageContainer、Stack 和 Cluster 支持原生 div 属性。width、gap 是像素数值,例如 width={960}、gap={16}。
import { PageContainer, Panel, PanelBody, PanelFooter, PanelHeader, Stack } from '@lailai0916/ui';
export function ProjectPanel() {
return (
<PageContainer width={960}>
<Stack gap={24}>
<Panel>
<PanelHeader>
<h2>项目概览</h2>
</PanelHeader>
<PanelBody>应用自己的内容。</PanelBody>
<PanelFooter>最近更新于 2026 年 9 月。</PanelFooter>
</Panel>
</Stack>
</PageContainer>
);
}
PageTitle.title 保留 HTML 字符串接口,只能使用应用自己编写的可信内容。来自用户或远程数据的标题应使用普通 React 文本元素;文章标题可以选择接受 ReactNode 的 MDTitle。
网站顶部栏
SiteHeader 统一顶部栏的高度、颜色、间距、页面容器和触摸区域。品牌、导航和操作由应用传入,搜索、通知、登录状态与路由仍由应用管理。
| 属性 | 行为 |
|---|---|
brand | 品牌区域,通常传入路由链接和 Brand |
navigation | 桌面导航或当前位置,在宽度不超过 900 px 时隐藏 |
mobileAction | 宽度不超过 900 px 时显示,通常传入打开应用菜单的按钮 |
actions | 语言、主题、搜索、通知和账号等操作 |
position | 默认 sticky,也可选择 fixed 或 static |
width | 内部容器的最大宽度,单位为像素,默认 1120 px |
fullWidth | 忽略 width,覆盖可用宽度并保留共享页面留白 |
不超过 520 px 时,顶部栏中的 Brand 隐藏名称,品牌链接应提供 aria-label。触摸设备或不超过 600 px 时,操作按钮至少保留 44 px 点击区域。导航包含必要入口时,应用应通过 mobileAction 提供菜单,并处理展开状态、关闭、焦点返回和页面切换。
import { Brand, ButtonLink, SiteHeader, SkipLink } from '@lailai0916/ui';
export function ProjectLayout() {
return (
<>
<SkipLink>跳到主要内容</SkipLink>
<SiteHeader
brand={
<a href="/" aria-label="项目首页">
<Brand logoSrc="/logo.svg" name="项目名称" />
</a>
}
actions={<ButtonLink to="/settings">设置</ButtonLink>}
/>
<main id="main-content" tabIndex={-1}>
应用内容
</main>
</>
);
}
SkipLink 默认指向 #main-content,获得焦点时显示,文案由应用本地化。主区域应使用对应的 id 和 tabIndex={-1}。position="fixed" 时,应用需要为主区域预留 --lk-header-height 的空间。
应用侧栏可通过 --lk-header-brand-width 对齐桌面品牌列,窄屏时会自动恢复紧凑排列。支持的钩子包括 site-header、header-inner、header-start、header-brand、header-navigation、header-mobile-action、header-actions 和 skip-link。
面板
Panel 使用 tone="default" 或 tone="muted" 控制表面,feature 可强调面板。PanelHeader、PanelBody、PanelFooter 按需组合,均支持原生 div 属性。
面板不会代替语义标题,应在 PanelHeader 中使用符合页面层级的 h2、h3 等元素。只需一层内容表面时,也可以使用 Card。
卡片
| 组件 | 必要属性 | 可选属性 |
|---|---|---|
Card | children | as、padding、className、wrapperClassName、style;to 或 href |
TitleCard | title、children | icon、description、count、padding、bodyAlign、size |
LinkCard | title,以及 to 或 href | description、image、fallbackIcon、imageVariant |
DataCard | value、label、icon | format、description |
ShareCard | url、title | description、image |
Card、LinkCard 的 to 与 href 二选一;站内导航使用 to,并通过 LaikitProvider 接入路由。链接卡片内不要再放按钮或其他链接,以免嵌套交互元素。
TitleCard.size 为 md、sm 或 plain,bodyAlign 为 top 或 bottom。卡片保留外部焦点环,铺满卡片的图片如需裁剪,应由自己的图片容器设置溢出裁剪。
import { DataCard, LaikitProvider, LinkCard, Stack } from '@lailai0916/ui';
export function ProjectCards() {
return (
<LaikitProvider locale="zh-Hans">
<Stack>
<DataCard value={42} label="组件" icon="lucide:boxes" />
<LinkCard
title="快速开始"
description="安装组件库并接入应用。"
to="/docs/project/ui/getting-started"
/>
</Stack>
</LaikitProvider>
);
}
DataCard.label 支持按语言选择单复数。英文使用 'Component|Components',中文使用单一形式 '组件',详见 框架接入。
Card.as 默认为 div,也可选择 article 或 section,用于保持应用的内容语义。DataCard.value 接受数字或已格式化的字符串,例如 "82%";数字继续使用原有格式化方式,description 可提供补充说明。