¿Un cajón `antd` de tamaño variable?

Oct 26 2020

Me gustaría proporcionar una forma de antdcambiar el tamaño de un cajón.

Leí una respuesta popular específicamente para, material-ui/Drawerpero estoy buscando hacer algo muy similar con antd.

¿Alguien tiene un antdejemplo similar , o tiene una mejor idea de cómo manejar la información que se corta en el costado del cajón?

Respuestas

2 Chanandrei Oct 26 2020 at 11:19

Puede ampliar el ancho de Drawerespecificándolo en los widthaccesorios. Si no desea extenderlo pero desea que el contenido aún se ajuste, puede establecer el ancho en bodyStyleprop y usar overflow: "auto":

<Drawer
    title="Basic Drawer"
    placement="right"
    closable={false}
    visible={isDrawerVisible}
    bodyStyle={{
      width: 400,
      overflow: "auto"
    }}
    onClose={toggleDrawerVisible}
>

También hice un cajón de tamaño variable basado en el enlace que proporcionaste en la versión antd (respuesta de la versión de react hooks).

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;

y para usarlo:

import ResizableDrawer from "./ResizableDrawer";

<ResizableDrawer
    title="Resizable Drawer"
    placement="right"
    closable={false}
    visible={isResizableDrawerVisible}
    onClose={toggleResizableDrawerVisible}
>
    ...
</ResizableDrawer>

Vea la demostración funcional aquí:

1 Scratch'N'Purr Oct 26 2020 at 12:21
  1. Tiene dos estados para rastrear el widthdel cajón y si el cajón se está redimensionando o no ( isResizing).
  2. Agregue dos detectores de eventos en el documento global donde escuchará mousemovey mouseup. El mousemoveevento cambiará el tamaño del cajón, solo si isResizinges verdadero. Y el mouseupevento se establecerá isResizingen falso.
  3. Agregue un div en su cajón que actúa como el borde arrastrable para hacer que el cajón sea de tamaño variable. Este div escuchará un mousedownevento, que establecerá el estado de isResizingen verdadero.

Aquí está el código que se ha mejorado de la demostración básica del cajón del sitio web de 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"));

Y aquí está la demostración del código:

MANIFESTACIÓN