【发布时间】:2020-10-25 20:49:18
【问题描述】:
我想提供一种使antd Drawer 可调整大小的方法?
我读了一个很受欢迎的answer,专门针对material-ui/Drawer,但我希望做一些与antd非常相似的事情。
有没有人有类似的antd 示例 - 或者有更好的想法如何处理在抽屉边被切掉的信息。
【问题讨论】:
我想提供一种使antd Drawer 可调整大小的方法?
我读了一个很受欢迎的answer,专门针对material-ui/Drawer,但我希望做一些与antd非常相似的事情。
有没有人有类似的antd 示例 - 或者有更好的想法如何处理在抽屉边被切掉的信息。
【问题讨论】:
您可以通过在 width 属性上指定 Drawer 的宽度来扩展它。如果您不想扩展它但又希望内容仍然适合,您可以在bodyStyle 属性上设置宽度并使用overflow: "auto":
<Drawer
title="Basic Drawer"
placement="right"
closable={false}
visible={isDrawerVisible}
bodyStyle={{
width: 400,
overflow: "auto"
}}
onClose={toggleDrawerVisible}
>
我还根据您在 antd 版本(react hooks 版本答案)中提供的link 制作了一个可调整大小的抽屉。
ResizableDrawer.jsx
import React, { useState, useEffect } from "react";
import { Drawer } from "antd";
let isResizing = null;
const ResizableDrawer = ({ children, ...props }) => {
const [drawerWidth, setDrawerWidth] = useState(undefined);
const cbHandleMouseMove = React.useCallback(handleMousemove, []);
const cbHandleMouseUp = React.useCallback(handleMouseup, []);
useEffect(() => {
setDrawerWidth(props.width);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [props.visible]);
function handleMouseup(e) {
if (!isResizing) {
return;
}
isResizing = false;
document.removeEventListener("mousemove", cbHandleMouseMove);
document.removeEventListener("mouseup", cbHandleMouseUp);
}
function handleMousedown(e) {
e.stopPropagation();
e.preventDefault();
// we will only add listeners when needed, and remove them afterward
document.addEventListener("mousemove", cbHandleMouseMove);
document.addEventListener("mouseup", cbHandleMouseUp);
isResizing = true;
}
function handleMousemove(e) {
let offsetRight =
document.body.offsetWidth - (e.clientX - document.body.offsetLeft);
let minWidth = 256;
let maxWidth = 600;
if (offsetRight > minWidth && offsetRight < maxWidth) {
setDrawerWidth(offsetRight);
}
}
return (
<Drawer {...props} width={drawerWidth}>
<div className="sidebar-dragger" onMouseDown={handleMousedown} />
{children}
</Drawer>
);
};
export default ResizableDrawer;
并使用它:
import ResizableDrawer from "./ResizableDrawer";
<ResizableDrawer
title="Resizable Drawer"
placement="right"
closable={false}
visible={isResizableDrawerVisible}
onClose={toggleResizableDrawerVisible}
>
...
</ResizableDrawer>
在此处查看工作演示:
【讨论】:
width 以及抽屉是否正在调整大小 (isResizing)。mousemove 和mouseup。仅当isResizing 为真时,mousemove 事件才会调整抽屉的大小。 mouseup 事件会将 isResizing 设置为 false。mousedown 事件,该事件会将 isResizing 的状态设置为 true。这是从 antd 网站的基本抽屉演示中改进的代码。
import React, { useState, useEffect } from "react";
import ReactDOM from "react-dom";
import "antd/dist/antd.css";
import "./index.css";
import { Drawer, Button } from "antd";
const App = () => {
const [visible, setVisible] = useState(false);
const [isResizing, setIsResizing] = useState(false);
const [width, setWidth] = useState(256);
const showDrawer = () => {
setVisible(true);
};
const onClose = () => {
setVisible(false);
};
const onMouseDown = e => {
setIsResizing(true);
};
const onMouseUp = e => {
setIsResizing(false);
};
const onMouseMove = e => {
if (isResizing) {
let offsetRight =
document.body.offsetWidth - (e.clientX - document.body.offsetLeft);
const minWidth = 50;
const maxWidth = 600;
if (offsetRight > minWidth && offsetRight < maxWidth) {
setWidth(offsetRight);
}
}
};
useEffect(() => {
document.addEventListener("mousemove", onMouseMove);
document.addEventListener("mouseup", onMouseUp);
return () => {
document.removeEventListener("mousemove", onMouseMove);
document.removeEventListener("mouseup", onMouseUp);
};
});
return (
<>
<Button type="primary" onClick={showDrawer}>
Open
</Button>
<Drawer
title="Basic Drawer"
placement="right"
closable={false}
onClose={onClose}
visible={visible}
width={width}
>
<div
style={{
position: "absolute",
width: "5px",
padding: "4px 0 0",
top: 0,
left: 0,
bottom: 0,
zIndex: 100,
cursor: "ew-resize",
backgroundColor: "#f4f7f9"
}}
onMouseDown={onMouseDown}
/>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
</Drawer>
</>
);
};
ReactDOM.render(<App />, document.getElementById("container"));
这是代码的演示:
【讨论】: