Skip to content

ResponsiveGridLayout (width provider) onlayoutChange recalculates weird y values for grid items #1611

@alex254

Description

@alex254

Hi,

To start thank you for this great library. I am retrieving products from the backend and mapping them as grid components in RGL. The usecase is saving new positions of the products as they have been moved. The implementation works although i noticed something strange for ResponsiveGridLayout, this doesnt happen for ReactGridLayout.

Basic component:

import React, { useState } from "react";
import { Responsive, WidthProvider } from "react-grid-layout";
import "../../../../../node_modules/react-grid-layout/css/styles.css";
import "../../../../../node_modules/react-resizable/css/styles.css";

type DraggableProps = {
  children?: React.ReactNode;
  handleLayoutChange?: Function;
  setColumns?: Function;
};

const ResponsiveGridLayout = WidthProvider(Responsive);

const Draggable: React.FC<DraggableProps> = ({
  children, handleLayoutChange, setColumns,
}) => {
  const [rowHeight, setHeight] = useState(350);

  const rowH = {
    lg: 350, md: 350, sm: 350, xs: 350, xxs: 250,
   };

  return (
    <ResponsiveGridLayout
      className="layout"
      breakpoints={{
 lg: 1800, md: 1400, sm: 1200, xs: 1000, xxs: 0,
}}
      cols={{
        lg: 12, md: 10, sm: 6, xs: 4, xxs: 2,
       }}
      margin={[25, 25]}
      isResizable={false}
      autoSize
      rowHeight={rowHeight}
      containerPadding={[0, 0]}
      onLayoutChange={(newLayout: any) => handleLayoutChange(newLayout)}
      onBreakpointChange={(newBreakPoint, newCols) => { setHeight(rowH[newBreakPoint]); setColumns(newCols); }}
    >
      {children}
    </ResponsiveGridLayout>
  );
};

export default Draggable;

on a higher level I have handleLayoutChange:

  const updateProductPositions = useCallback(async (newLayout) => {
    console.log(newLayout);
    const positions = newLayout.map((item: { x: number; y: number; i: string}) => {
        const newPosition = item.y * columns + item.x;
        return { id: parseInt(item.i, 10), position: newPosition };
    });
    console.log(positions);

    updatePositions([positions]);
  }, [columns, updatePositions]);

You can see the console logs. Here you can see them when I open the page:

responsivegrid

to be complete:


              <Draggable handleLayoutChange={updateProductPositions} setColumns={setColumns}>
                {result.value?.map((product, index) => (
                  <div
                    key={product.id}
                    data-grid={{
                        x: index % columns, y: Math.floor(index), w: 1, h: 1,
                        }}
                  >
                    <ProductCard key={product.id} product={product} />
                  </div>
                ))}
              </Draggable>

For me its workable like this because the positions remain in the correct order even though the values are incorrect. But still y should be calculated correctly. Any idea what the reason could be?

Metadata

Metadata

Assignees

No one assigned

    Labels

    staleThe label to apply when a pull request or an issue is stale

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions