Layout
layout整页布局 · 复合 Header/Sider/Content/Footer + Sider 可折叠(受控/断点/trigger) + 宽度过渡(零依赖·尽量 RSC·复用 ScrollArea)
用法
经典中后台外壳
左侧 Sider + 右侧 Header / Content / Footer,含侧栏时自动横向布局。
页面内容
第 1 段占位内容 —— Content 区 flex-auto 占满并独立滚动,Header 可吸顶、Footer 沉底。
第 2 段占位内容 —— Content 区 flex-auto 占满并独立滚动,Header 可吸顶、Footer 沉底。
第 3 段占位内容 —— Content 区 flex-auto 占满并独立滚动,Header 可吸顶、Footer 沉底。
第 4 段占位内容 —— Content 区 flex-auto 占满并独立滚动,Header 可吸顶、Footer 沉底。
第 5 段占位内容 —— Content 区 flex-auto 占满并独立滚动,Header 可吸顶、Footer 沉底。
第 6 段占位内容 —— Content 区 flex-auto 占满并独立滚动,Header 可吸顶、Footer 沉底。
第 7 段占位内容 —— Content 区 flex-auto 占满并独立滚动,Header 可吸顶、Footer 沉底。
第 8 段占位内容 —— Content 区 flex-auto 占满并独立滚动,Header 可吸顶、Footer 沉底。
<Layout className="h-full">
<Layout.Sider collapsible>
<NavMenu items={items} selectedKeys={["dashboard"]} />
</Layout.Sider>
<Layout>
<Layout.Header sticky>
<span className="font-medium">中后台外壳</span>
<span className="ml-auto text-sm text-muted">user@hulian</span>
</Layout.Header>
<Layout.Content>{/* 页面内容 */}</Layout.Content>
<Layout.Footer>瑚琏 Layout · © 2026</Layout.Footer>
</Layout>
</Layout>通栏头部在上
Header 横跨全宽,下方再分 Sider + Content,最外层为纵向布局。
页面内容
第 1 段占位内容 —— Content 区 flex-auto 占满并独立滚动,Header 可吸顶、Footer 沉底。
第 2 段占位内容 —— Content 区 flex-auto 占满并独立滚动,Header 可吸顶、Footer 沉底。
第 3 段占位内容 —— Content 区 flex-auto 占满并独立滚动,Header 可吸顶、Footer 沉底。
第 4 段占位内容 —— Content 区 flex-auto 占满并独立滚动,Header 可吸顶、Footer 沉底。
第 5 段占位内容 —— Content 区 flex-auto 占满并独立滚动,Header 可吸顶、Footer 沉底。
第 6 段占位内容 —— Content 区 flex-auto 占满并独立滚动,Header 可吸顶、Footer 沉底。
第 7 段占位内容 —— Content 区 flex-auto 占满并独立滚动,Header 可吸顶、Footer 沉底。
第 8 段占位内容 —— Content 区 flex-auto 占满并独立滚动,Header 可吸顶、Footer 沉底。
<Layout className="h-full">
<Layout.Header>
<span className="font-medium">通栏头部</span>
</Layout.Header>
<Layout>
<Layout.Sider collapsible>
<NavMenu items={items} />
</Layout.Sider>
<Layout.Content>{/* 页面内容 */}</Layout.Content>
</Layout>
<Layout.Footer>底部通栏 · © 2026</Layout.Footer>
</Layout>默认收起侧栏
defaultCollapsed 让侧栏初始收起,NavMenu 切到 collapsed 图标轨。
页面内容
第 1 段占位内容 —— Content 区 flex-auto 占满并独立滚动,Header 可吸顶、Footer 沉底。
第 2 段占位内容 —— Content 区 flex-auto 占满并独立滚动,Header 可吸顶、Footer 沉底。
第 3 段占位内容 —— Content 区 flex-auto 占满并独立滚动,Header 可吸顶、Footer 沉底。
第 4 段占位内容 —— Content 区 flex-auto 占满并独立滚动,Header 可吸顶、Footer 沉底。
第 5 段占位内容 —— Content 区 flex-auto 占满并独立滚动,Header 可吸顶、Footer 沉底。
第 6 段占位内容 —— Content 区 flex-auto 占满并独立滚动,Header 可吸顶、Footer 沉底。
第 7 段占位内容 —— Content 区 flex-auto 占满并独立滚动,Header 可吸顶、Footer 沉底。
第 8 段占位内容 —— Content 区 flex-auto 占满并独立滚动,Header 可吸顶、Footer 沉底。
<Layout.Sider collapsible defaultCollapsed>
<NavMenu items={items} mode="collapsed" />
</Layout.Sider>何时用
需要 Header/Sider/Content/Footer 这种通用页面骨架、且自己掌控菜单与页签逻辑时用 Layout(更原子、更自由)。若要开箱即用的中后台外壳(品牌 + NavMenu + 多页签 keep-alive 已内置),直接用 AdminLayout,它就是基于本组件的成品装配。
导入
import { Layout, LayoutHeader, LayoutSider, LayoutContent, LayoutFooter } from "@hulianui/ui"Props
Layout(也可用 Layout.Sider 等点访问)
| 名称 | 类型 | 默认 | 说明 |
|---|---|---|---|
| hasSider | boolean | 自动探测 | 强制横向(含侧栏)布局。缺省按直接子元素是否含 Layout.Sider 判定:含则横向 row,否则纵向 col。异步/条件渲染 Sider 时用它兜底。 |
继承 HTMLAttributes<HTMLDivElement>。
LayoutHeader
| 名称 | 类型 | 默认 | 说明 |
|---|---|---|---|
| sticky | boolean | false | 吸顶(sticky top-0)。 |
LayoutSider
| 名称 | 类型 | 默认 | 说明 |
|---|---|---|---|
| width | number | 240 | 展开态宽度(px)。 |
| collapsedWidth | number | 64 | 收起态宽度(px),留出 icon-only 菜单。 |
| collapsible | boolean | false | 是否可折叠(显示底部 trigger 折叠按钮)。 |
| collapsed | boolean | — | 受控收起态。传入即受控,须配合 onCollapse 回写。 |
| defaultCollapsed | boolean | false | 非受控初始收起态。 |
| breakpoint | "sm" | "md" | "lg" | "xl" | "2xl" | number | — | 响应式断点:视口 ≤ 该宽度自动收起,> 时展开。 |
LayoutContent / LayoutFooter
纯 HTMLAttributes<HTMLElement>,无专属 prop。
Events
LayoutSider
| 事件 | 类型 | 说明 |
|---|---|---|
| onCollapse | (collapsed: boolean, type: "clickTrigger" | "responsive") => void | 收起态变化回调(点 trigger 或命中断点时触发)。 |
Slots
LayoutSider
| 插槽 | 类型 | 说明 |
|---|---|---|
| trigger | ReactNode | 底部折叠触发器内容。undefined=默认 chevron;null=不渲染触发器(即便 collapsible);传节点=自定义触发器内容(仍由本件包裹为可点按钮)。 |
禁忌 / 坑
- 受控/非受控二选一:
Layout.Sider传了collapsed即进入受控,必须配onCollapse回写,否则 trigger/断点点了不动;只想非受控用defaultCollapsed。 - 横/纵布局靠子元素探测:嵌套子
Layout是否横排取决于其直接子是否含Layout.Sider。Sider 异步/条件渲染、或被包装进自定义组件(如<AppSider/>内部才渲染Layout.Sider)时探测会落空,须显式给hasSider。 - 收起态切窄宽用菜单的
mode="collapsed"(dogfood NavMenu 自带 icon-only 轨),不要手搓「窄宽裁切 label」。
相关
AdminLayout · ScrollArea · Viewport · Resizable · AspectRatio · FitScreen
Playground
页面内容
第 1 段占位内容 —— Content 区 flex-auto 占满并独立滚动,Header 可吸顶、Footer 沉底。
第 2 段占位内容 —— Content 区 flex-auto 占满并独立滚动,Header 可吸顶、Footer 沉底。
第 3 段占位内容 —— Content 区 flex-auto 占满并独立滚动,Header 可吸顶、Footer 沉底。
第 4 段占位内容 —— Content 区 flex-auto 占满并独立滚动,Header 可吸顶、Footer 沉底。
第 5 段占位内容 —— Content 区 flex-auto 占满并独立滚动,Header 可吸顶、Footer 沉底。
第 6 段占位内容 —— Content 区 flex-auto 占满并独立滚动,Header 可吸顶、Footer 沉底。
第 7 段占位内容 —— Content 区 flex-auto 占满并独立滚动,Header 可吸顶、Footer 沉底。
第 8 段占位内容 —— Content 区 flex-auto 占满并独立滚动,Header 可吸顶、Footer 沉底。
<Layout>
<Layout.Sider collapsible>
{/* dogfood NavMenu:收起态自动切图标轨 */}
<NavMenu items={items} mode={"inline"} />
</Layout.Sider>
<Layout>
<Layout.Header sticky>顶栏</Layout.Header>
<Layout.Content>内容</Layout.Content>
<Layout.Footer>底栏</Layout.Footer>
</Layout>
</Layout>