【问题标题】:A resizable `antd` Drawer?一个可调整大小的“antd”抽屉?
【发布时间】:2020-10-25 20:49:18
【问题描述】:

我想提供一种使antd Drawer 可调整大小的方法?

我读了一个很受欢迎的answer,专门针对material-ui/Drawer,但我希望做一些与antd非常相似的事情。

有没有人有类似的antd 示例 - 或者有更好的想法如何处理在抽屉边被切掉的信息。

【问题讨论】:

    标签: reactjs antd


    【解决方案1】:

    您可以通过在 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>
    

    在此处查看工作演示:

    【讨论】:

      【解决方案2】:
      1. 有两种状态用于跟踪抽屉的width 以及抽屉是否正在调整大小 (isResizing)。
      2. 在全局文档上添加两个事件侦听器,它将侦听mousemovemouseup。仅当isResizing 为真时,mousemove 事件才会调整抽屉的大小。 mouseup 事件会将 isResizing 设置为 false。
      3. 在您的抽屉中添加一个 div,作为可拖动边框以使抽屉可调整大小。此 div 将侦听 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"));
      

      这是代码的演示:

      DEMO

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-09-03
        • 2019-08-11
        • 1970-01-01
        • 1970-01-01
        • 2019-09-28
        • 1970-01-01
        相关资源
        最近更新 更多