Files
simple-react-app-kit/packages/layout/README.md
T
2026-09-30 01:30:56 +08:00

141 lines
4.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Layout
`@workspace/layout` 提供路由无关的应用级布局。`AppLayout` 以内容区为核心,并按需组合 Header、Navigation Rail、Sidebar、Aside 和 Footer。
## 安装样式源
在应用的全局样式中导入:
```css
@import "@workspace/layout/globals.css";
```
## 布局模型
```text
+-------------------------------------+
| header | headerStart="rail"
+------+---------+---------+----------+
| | header | headerStart="sidebar"
| +---------+---------+----------+
| | | header | headerStart="content"
| | +---------+----------+
| | | | |
| rail | sidebar | content | |
| | +---------+ aside |
| | | footer | | footerStart="content"
| +---------+---------+ |
| | footer | | footerStart="sidebar"
+------+-------------------+----------+
```
图中的多个 Header 和 Footer 表示可选位置,不会同时渲染。`children` 是唯一必需的内容区,其他区域均为可选 slot:
- `rail`:最外侧的一级导航,类似 Activity Bar。
- `sidebar`:当前一级导航下的导航或工作区上下文。
- `aside`:AI、文档、检查器等内容辅助区域。
- `header`:右边界始终包含有效的 `aside`。
- `footer`:始终属于中心工作区,不会延伸到 `rail` 或 `aside` 下方。
## 基本用法
Slot 可以接收已经创建的 React 节点,也可以接收无必需属性的组件定义。组件定义在 `AppLayout` 的 Provider 内创建,因此可以调用 `useLayoutConfig`。
```tsx
import { AppLayout } from "@workspace/layout"
export function Application() {
return (
<AppLayout
header={AppHeader}
rail={ActivityRail}
sidebar={<NavigationSidebar groups={navigationGroups} />}
aside={AssistantPanel}
footer={StatusBar}
defaultLayout={{
asideOpen: true,
footerStart: "sidebar",
headerStart: "sidebar",
}}
>
<RouterOutlet />
</AppLayout>
)
}
```
## LayoutConfig
`LayoutConfig` 是扁平、可序列化的完整快照;`layout` 和 `defaultLayout` 接收 `Partial<LayoutConfig>`。
```ts
interface LayoutConfig {
asideEnabled: boolean
asideOpen: boolean
footerStart: "sidebar" | "content"
headerStart: "rail" | "sidebar" | "content"
sidebarCollapsible: boolean
sidebarOpen: boolean
}
```
默认值:
```ts
const defaultLayoutConfig = {
asideEnabled: true,
asideOpen: false,
footerStart: "content",
headerStart: "rail",
sidebarCollapsible: true,
sidebarOpen: true,
}
```
- 提供 `layout` 时采用受控模式,交互后通过 `onLayoutChange` 返回完整快照。
- 未提供 `layout` 时采用非受控模式,以 `defaultLayout` 或默认配置初始化。
- 区域暂时不可用只影响有效布局,不会覆盖配置中保存的用户偏好。
## useLayoutConfig
区域组件可以读取布局状态并触发布局更新:
```tsx
import { useLayoutConfig } from "@workspace/layout"
export function AppHeader() {
const {
layout,
setAsideOpen,
setSidebarOpen,
toggleAside,
toggleSidebar,
updateLayout,
} = useLayoutConfig()
// Render application controls.
}
```
Hook 必须在 `AppLayout` 子树内调用。`updateLayout` 接收局部配置或根据当前完整配置生成局部配置的函数。
## 自动内移
`headerStart` 和 `footerStart` 表示期望位置。布局会根据当前实际可见的区域计算有效位置,但不会改写原配置:
- `headerStart="rail"` 表示全局 Header;没有 Rail 时从第一个实际存在的区域开始。
- 只有 Rail 与 Sidebar 同时可见时,`headerStart="sidebar"` 和 `footerStart="sidebar"` 才会生效。
- 其他情况下,`"sidebar"` 自动内移为 `"content"`。
- Aside 始终贯穿中心工作区高度,不参与 Footer 范围。
## 尺寸
可以通过 CSS 自定义属性调整三个辅助列:
```css
.application-layout {
--layout-rail-width: 4rem;
--layout-sidebar-width: 18rem;
--layout-aside-width: 22rem;
}
```