主角:react-resizable-panels
简介:来之Ant Design官方文档社区精选组件
1、效果
2、环境
react-resizable-panels
: ^2.0.16next
: 14.1.3react
: ^18
3、安装
# npm
npm install react-resizable-panels
# yarn
yarn add react-resizable-panels
# pnpm
pnpm add react-resizable-panels
# bun
bun add react-resizable-panels
4、组件概述
PanelGroup
: 布局容器PanelResizeHandle
: 分割线控件,无自带样式,使用className
或style
属性自定义Panel
: 面板容器,其下可嵌套任何元素
5、基础用法
// file: app/test/page.tsx
"use client"
import { Card } from "antd"
// 引入基础组件
import {
Panel,
PanelGroup,
PanelResizeHandle
} from "react-resizable-panels";
// 给边线来点小样式
const PanelResizeHandleStyle = {
outline: 'none',
flex: '0 0 .25rem',
justifyContent: 'stretch',
alignItems: 'stretch',
transition: 'background-color .2s linear',
display: 'flex'
}
const TestView = function () {
return (
<>
<PanelGroup direction="horizontal">
<Panel>
<Card>Card Panel 1</Card>
</Panel>
<PanelResizeHandle style={PanelResizeHandleStyle} />
<Panel>
<Card>Card Panel 1</Card>
</Panel>
</PanelGroup>;
</>
)
}
export default TestView;
6、组件Props
6.1、PanelGroup Props
属性 | 类型 | 描述 |
---|---|---|
autoSaveId | ?string | 用于自动保存组排列的唯一 ID localStorage |
children | ReactNode | 任意 React 元素 |
className | ?string | 附加到根元素的类名 |
direction | “horizontal” | “vertical” |
id | ?string | 组ID;回落到useId未提供时 |
onLayout | ?(sizes: number[]) => void | 当组布局更改时调用 |
storage | ?PanelGroupStorage | 自定义存储API;默认为localStorage ① |
style | ?CSSProperties | 附加到根元素的 CSS 样式 |
tagName | ?string = “div” | 根元素的 HTML 元素标签名称 |
①:存储API必须定义以下同步方法:
getItem: (name:string) => string
setItem: (name: string, value: string) => void
用于手动调整大小的命令式 API:
方法 | 描述 |
---|---|
getId(): string | 获取面板组的 ID |
getLayout(): number[] | 获取面板组的当前布局( [1 - 100, ...] )。 |
setLayout(layout: number[]) | 将面板组大小调整为指定布局( [1 - 100, ...] ) |
6.2、Panel Props
属性 | 类型 | 描述 |
---|---|---|
children | ReactNode | 任意 React 元素 |
className | ?string | 附加到根元素的类名 |
collapsedSize | ?number=0 | 面板应折叠至此尺寸 |
collapsible | ?boolean=false | 当调整大小超出其范围时,面板应该折叠minSize |
defaultSize | ?number | 面板的初始大小(1-100之间的数值) |
id | ?string | 面板 ID(组内唯一);回落到useId未提供时 |
maxSize | ?number = 100 | 面板最大允许尺寸(1-100之间的数值);默认为100 |
minSize | ?number = 10 | 面板最小允许尺寸(1-100之间的数值);默认为10 |
onCollapse | ?() => void | 面板折叠时调用 |
onExpand | ?() => void | 面板展开时调用 |
onResize | ?(size: number) => void | 调整面板大小时调用;size参数是 1-100 之间的数值。1 |
order | ?number | 小组内小组的顺序;对于具有条件渲染面板的组来说是必需的 |
style | ?CSSProperties | 附加到根元素的 CSS 样式 |
tagName | ?string = “div” | 根元素的 HTML 元素标签名称 |
6.3、PanelResizeHandle Props
属性 | 类型 | 描述 |
---|---|---|
children | ?ReactNode | 自定义拖动UI;可以是任意 React 元素 |
className | ?string | 附加到根元素的类名 |
hitAreaMargins | ?{ coarse: number = 15; fine: number = 5; } | 在确定可调整大小的手柄点击检测时允许这么多余量 |
disabled | ?boolean | 禁用拖动手柄 |
id | ?string | 调整句柄 ID 的大小(组内唯一);回落到useId未提供时 |
onDragging | ?(isDragging: boolean) => void | 当组布局更改时调用 |
style | ?CSSProperties | 附加到根元素的 CSS 样式 |
tagName | ?string = “div” | 根元素的 HTML 元素标签名称 |
7、持久布局与 SSR 结合使用
默认情况下,该库用于
localStorage
保留布局。对于服务器渲染,当默认布局(在服务器上渲染)替换为持久布局(在 中localStorage
)时,这可能会导致闪烁。
避免这种闪烁的方法是使用cookie
来持久化布局,如下所示:
服务器组件
import ResizablePanels from "@/app/ResizablePanels";
import { cookies } from "next/headers";
export function ServerComponent() {
const layout = cookies().get("react-resizable-panels:layout");
let defaultLayout;
if (layout) {
defaultLayout = JSON.parse(layout.value);
}
return <ClientComponent defaultLayout={defaultLayout} />;
}
客户端组件
"use client";
import { Panel, PanelGroup, PanelResizeHandle } from "react-resizable-panels";
export function ClientComponent({
defaultLayout = [33, 67],
}: {
defaultLayout: number[] | undefined;
}) {
const onLayout = (sizes: number[]) => {
document.cookie = `react-resizable-panels:layout=${JSON.stringify(sizes)}`;
};
return (
<PanelGroup direction="horizontal" onLayout={onLayout}>
<Panel defaultSize={defaultLayout[0]}>{/* ... */}</Panel>
<PanelResizeHandle className="w-2 bg-blue-800" />
<Panel defaultSize={defaultLayout[1]}>{/* ... */}</Panel>
</PanelGroup>
);
}