React网格布局自定义调整大小手柄无法工作。

3
根据 React-Grid-Layout 文档resizeHandle?: ReactElement<any> | ((resizeHandleAxis: ResizeHandleAxis, ref: ReactRef<HTMLElement>) => ReactElement<any>) 可用于为网格项实现自定义的调整大小句柄。
但在我的情况下,这并没有起作用。它甚至没有抛出任何错误。
代码示例: https://codesandbox.io/s/react-playground-forked-jwfn3?file=/index.js 注意: 如果我删除 resizeHandle={<BottomRightHandle />},则网格项将获得默认的调整大小处理程序,这是有效的。
CustomResizeHandle.js
import React from "react";

const SouthEastArrow = () => (
  <svg
    width="20px"
    height="20px"
    version="1.1"
    viewBox="0 0 100 100"
    xmlns="http://www.w3.org/2000/svg"
  >
    <path d="m70.129 67.086l1.75-36.367c-0.035156-2.6523-2.9414-3.6523-4.8164-1.7773l-8.4531 8.4531-17.578-17.574c-2.3438-2.3438-5.7188-1.5625-8.0586 0.78125l-13.078 13.078c-2.3438 2.3438-2.4141 5.0117-0.074219 7.3516l17.574 17.574-8.4531 8.4531c-1.875 1.875-0.83594 4.8203 1.8164 4.8555l36.258-1.8594c1.6836 0.019531 3.1328-1.2812 3.1133-2.9688z" />
  </svg>
);

const CustomHandle = (props) => (
  <div
    style={{
      background: "#fff",
      borderRadius: "2px",
      border: "1px solid #ddd",
      position: "absolute",
      bottom: 0,
      right: 0,
      padding: 0,
      cursor: "se-resize"
    }}
    {...props}
  />
);

const BottomRightHandle = () => (
  <CustomHandle>
    <SouthEastArrow />
  </CustomHandle>
);

export default BottomRightHandle;

index.js

import React from "react";
import ReactDOM from "react-dom";
import { Grid, Row, Col } from "react-flexbox-grid";

import { Responsive, WidthProvider } from "react-grid-layout";

import "../../node_modules/react-grid-layout/css/styles.css";
import "../../node_modules/react-resizable/css/styles.css";

import BottomRightHandle from "./CustomResizeHandle";

const ResponsiveGridLayout = WidthProvider(Responsive);

const Layout = (props) => {
  const [items, setItems] = React.useState([
    { i: "a", x: 0, y: 0, w: 2, h: 1 },
    { i: "b", x: 2, y: 0, w: 2, h: 1 }
  ]);

  return (
    <ResponsiveGridLayout
      className="layout"
      layouts={{ lg: items }}
      breakpoints={{ lg: 1200, md: 996, sm: 768 }}
      cols={{ lg: 12, md: 10, sm: 6 }}
      resizeHandles={["se"]}
      resizeHandle={<BottomRightHandle />}
    >
      {items.map((item) => {
        return (
          <div
            key={item.i}
            style={{ backgroundColor: "#ccc" }}
            data-grid={{ x: item.x, y: item.y }}
          >
            {item.i}
          </div>
        );
      })}
    </ResponsiveGridLayout>
  );
};

class App extends React.Component {
  render() {
    return (
      <Grid>
        <Row>
          <Col>
            <Layout />
          </Col>
        </Row>
      </Grid>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("container"));
3个回答

5
请尝试导入下面的react-grid-layout CSS文件。然后您就会看到操作柄。
import "react-grid-layout/css/styles.css";
import "react-resizable/css/styles.css";

你真是太厉害了!这两个导入功能真是节省了我很多工作时间。 - undefined

3
根据文档,你需要在自定义的句柄组件中包含"react-resizable-handle"和"react-resizable-handle-${handleAxis}",并从"ReactGridLayout"的"resizeHandle"属性中传递"handleAxis"和"ref"。
对我有效的方法是:
type ResizeHandleAxis = 's' | 'w' | 'e' | 'n' | 'sw' | 'nw' | 'se' | 'ne';

type ResizeHandleProps = {
  handleAxis: ResizeHandleAxis;
}
const MyHandle = React.forwardRef<HTMLDivElement, ResizeHandleProps>(({ handleAxis }, ref) => {
  return (
    <div ref={ref}
      className={`react-resizable-handle react-resizable-handle-${handleAxis}`}
    >
    </div>
  );
});

    <ReactGridLayout {...}
      resizeHandles={[ "n", "e", "s", "w", "ne", "se", "nw", "sw" ]}
      resizeHandle={(handleAxis: ResizeHandleAxis, ref: React.Ref<HTMLDivElement>) =>
        <MyHandle ref={ref} handleAxis={handleAxis} />
      }
    >
      { children }
    </ReactGridLayout>

然后您可以在这个新组件中进行额外的操作。但是您将需要使用CSS类来擦除默认样式并自定义新样式。

擦除默认CSS

.react-resizable-handle {
  background-image: none;
  padding: 0;
  background-color: yellow;
}
.react-grid-item > .react-resizable-handle.react-resizable-handle-n,
.react-grid-item > .react-resizable-handle.react-resizable-handle-e,
.react-grid-item > .react-resizable-handle.react-resizable-handle-s,
.react-grid-item > .react-resizable-handle.react-resizable-handle-w,
.react-grid-item > .react-resizable-handle.react-resizable-handle-ne,
.react-grid-item > .react-resizable-handle.react-resizable-handle-nw,
.react-grid-item > .react-resizable-handle.react-resizable-handle-se,
.react-grid-item > .react-resizable-handle.react-resizable-handle-sw
{
  transform: none;
  margin: 0;
}
.react-grid-item > .react-resizable-handle::after {
  border: none;
  content: none;
}

除了按照文档中清除默认样式的方法之外,您还可以使用其他类,但这样并不是非常清晰,我也没有深入研究。


0

好吧,看起来这个功能在react-grid-layout中尚未实现,虽然它已经在文档中描述了!这造成了很多混乱。无论如何,我找到了一个解决办法,可以应用于自定义图标进行调整大小。首先,我们需要创建一个具有绝对位置的自定义组件,放置在我们想要的位置(就像您创建BottomRightHandle组件一样)。然后,将您的BottomRightHandle传递给ResponsiveGridLayout组件,如下所示:

 <ResponsiveGridLayout
      className="layout"
      layouts={{ lg: items }}
      breakpoints={{ lg: 1200, md: 996, sm: 768 }}
      cols={{ lg: 12, md: 10, sm: 6 }}
      resizeHandles={["se"]}
      // resizeHandle={<BottomRightHandle />}
    >
      {items.map((item) => {
        return (
          <div
            key={item.i}
            style={{ backgroundColor: "#ccc" }}
            data-grid={{ x: item.x, y: item.y }}
          >
            {item.i}
            <BottomRightHandle />
          </div>
        );
      })}
    </ResponsiveGridLayout>

然后,创建一个CSS文件,通过以下样式来删除和隐藏默认的调整大小箭头:

.react-grid-item > .react-resizable-handle::after {
  border-right: 2px solid rgba(0, 0, 0, 0);
  border-bottom: 2px solid rgba(0, 0, 0, 0);
}

.react-resizable-handle {
  background: transparent;
}

请检查此处的沙盒
请记住,resizeHandles位置(在本例中为se)应与BottomRightHandle组件的绝对位置相同。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接