Reputation: 3680
According to React-Grid-Layout doc
resizeHandle?: ReactElement<any> | ((resizeHandleAxis: ResizeHandleAxis, ref: ReactRef<HTMLElement>) => ReactElement<any>)
can be used to implement custom resize handle for the grid items.
In my case this is not working. It's not even throwing any errors.
Code: https://codesandbox.io/s/react-playground-forked-jwfn3?file=/index.js
Note: If I remove resizeHandle={<BottomRightHandle />}
grid items will get default resize handler, Which is working fine.
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"));
Upvotes: 3
Views: 12333
Reputation: 336
Please try to import the below react-grid-layout css files. Then you will see the handles.
import "react-grid-layout/css/styles.css";
import "react-resizable/css/styles.css";
Upvotes: 7
Reputation: 917
According to the doc, you have to have the react-resizable-handle
and react-resizable-handle-${handleAxis}
in your custom handle component, and pass the handleAxis
and ref
in from the ReactGridLayout
's resizeHandle
prop.
What worked for me was:
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>
Then you can do extra stuff in this new component. But you'll have to use css classes to erase the default styling and customizing the new styles
Erasing default 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;
}
You can also use other classes instead of having to clear the default styling as per the doc, but then it's not super clear and I didn't get to it.
Upvotes: 3
Reputation: 2968
Well, it seems that this feature is not yet implemented in react-grid-layout
although it's been described in the documentation!! And it causes lots of confusion. Any way, I found a workaround to apply customized icon for resizing. First, we need to create our customized component with an absolute position in our desired place (as you have done it by creating BottomRightHandle
component). Then, pass your BottomRightHandle
inside ResponsiveGridLayout
component as below:
<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>
and then, create a css file in order to remove and disappear the default resize arrow by these styles:
.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;
}
Please check the sandbox here
Please keep in mind that the resizeHandles
position (in this case se
) should be the same as the BottomRightHandle
component's absolute position.
Upvotes: 0