react-resizable-panels
用于可调整大小的面板组/布局的 React 组件。
支持的输入方法包括鼠标、触摸和键盘(通过窗口分割器)。
如果你喜欢这个项目,🎉 成为赞助者 或 ☕ 给我买杯咖啡
常见问题
面板大小可以用像素指定吗?
不可以。基于像素的约束增加了初始化和验证逻辑的复杂性,所以我决定不支持它们。你可以尝试按照这种模式自己实现一个版本,但这个库并不官方支持。
如何解决条件渲染面板的布局/大小问题?
Panel
API 不要求 id
和 order
属性,因为它们对静态布局不是必需的。但是当面板被条件渲染时,最好提供这些值。
<PanelGroup direction="horizontal">
{renderSideBar && (
<>
<Panel id="sidebar" minSize={25} order={1}>
<Sidebar />
</Panel>
<PanelResizeHandle />
</>
)}
<Panel minSize={25} order={2}>
<Main />
</Panel>
</PanelGroup>
可以为 DOM 元素附加 ref 吗?
不可以。我认为暴露两个 ref(一个用于组件的命令式 API,一个用于 DOM 元素)会很尴尬。不过,这个库确实导出了几个用于访问底层 DOM 元素的实用方法。例如:
import {
getPanelElement,
getPanelGroupElement,
getResizeHandleElement,
Panel,
PanelGroup,
PanelResizeHandle,
} from "react-resizable-panels";
export function Example() {
const refs = useRef();
useEffect(() => {
const groupElement = getPanelGroupElement("group");
const leftPanelElement = getPanelElement("left-panel");
const rightPanelElement = getPanelElement("right-panel");
const resizeHandleElement = getResizeHandleElement("resize-handle");
// 如果你想的话,可以将它们存储在 ref 中以便传递
refs.current = {
groupElement,
leftPanelElement,
rightPanelElement,
resizeHandleElement,
};
}, []);
return (
<PanelGroup direction="horizontal" id="group">
<Panel id="left-panel">{/* ... */}</Panel>
<PanelResizeHandle id="resize-handle" />
<Panel id="right-panel">{/* ... */}</Panel>
</PanelGroup>
);
}
为什么我看不到任何调整大小的 UI?
这可能意味着你还没有应用任何 CSS 来样式化调整大小的句柄。默认情况下,调整大小的句柄只是一个空的 DOM 元素。要添加样式,请使用 className
或 style
属性:
// Tailwind 示例
<PanelResizeHandle className="w-2 bg-blue-800" />
如何在 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>
);
}
[!注意] 请确保为每个
Panel
组件指定defaultSize
属性,以避免布局闪烁。
这个演示的代码可以在这里找到。
如何设置 CSP "nonce"
属性?
import { setNonce } from "react-resizable-panels";
setNonce("your-nonce-value-here");
如何禁用全局光标样式?
import { disableGlobalCursorStyles } from "react-resizable-panels";
disableGlobalCursorStyles();