Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
.DS_Store
node_modules
dist
dist/*
!dist/react-grid-layout.min*
!dist/*.html
Comment on lines +3 to 6
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

πŸ’‘ Verification agent

❓ Verification inconclusive

dist entry shadows the later negate rules – minified bundles & HTML will now be ignored

Adding the bare dist pattern ignores the directory itself, so Git stops traversing its contents.
The subsequent negations (!dist/react-grid-layout.min*, !dist/*.html) therefore no longer take effect, meaning the artefacts you explicitly wanted to keep tracked will be excluded from commits and npm publishes.

Remove the new line or restructure the rules as follows:

-# Ignore entire dist directory (breaks negate rules below)
-dist
+# Keep specific build artefacts, ignore everything else inside dist
+dist/*
+!dist/react-grid-layout.min*
+!dist/*.html

Failing to fix this will drop your distributable assets from the repo and packaged tarball.
Please verify npm pack output after the change.


Restructure .gitignore to preserve specific dist artefacts

The bare dist entry prevents Git from descending into that directory, so your negations never take effect. Remove it and ignore everything inside dist/ first, then re-include the files you need.

β€’ File: .gitignore
β€’ Lines: 3–6

- dist
+# Keep only our minified bundle & HTML, ignore all other files under dist
+ dist/*
  !dist/react-grid-layout.min*
  !dist/*.html

After updating, confirm your changes with git check-ignore -v dist/react-grid-layout.min.js or by running npm pack to ensure the artefacts are included.

Committable suggestion skipped: line range outside the PR's diff.

πŸ€– Prompt for AI Agents
In the .gitignore file at lines 3 to 6, remove the bare "dist" entry because it
prevents Git from checking inside the dist directory, making the negation rules
ineffective. Instead, ignore all files inside dist/ with "dist/*" first, then
explicitly re-include the needed files like "dist/react-grid-layout.min*" and
"dist/*.html" using negation patterns. After making these changes, verify with
"git check-ignore -v dist/react-grid-layout.min.js" or by running "npm pack" to
confirm the correct files are included.

Expand Down
2 changes: 0 additions & 2 deletions dist/react-grid-layout.min.js

This file was deleted.

1 change: 0 additions & 1 deletion dist/react-grid-layout.min.js.map

This file was deleted.

6 changes: 3 additions & 3 deletions lib/GridItem.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -510,15 +510,15 @@ export default class GridItem extends React.Component<Props, State> {
const { offsetParent } = node;

if (offsetParent) {
const { margin, rowHeight, containerPadding } = this.props;
const { margin, rowHeight } = this.props;
const bottomBoundary =
offsetParent.clientHeight - calcGridItemWHPx(h, rowHeight, margin[1]);
top = clamp(top - containerPadding[1], 0, bottomBoundary);
top = clamp(top, 0, bottomBoundary);

const colWidth = calcGridColWidth(positionParams);
const rightBoundary =
containerWidth - calcGridItemWHPx(w, colWidth, margin[0]);
left = clamp(left - containerPadding[0], 0, rightBoundary);
left = clamp(left, 0, rightBoundary);
}
}

Expand Down
6 changes: 3 additions & 3 deletions lib/ResponsiveReactGridLayout.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -161,9 +161,9 @@ export default class ResponsiveReactGridLayout extends React.Component<
};

static defaultProps: DefaultProps = {
breakpoints: { lg: 1200, md: 996, sm: 768 },
cols: { lg: 12, md: 10, sm: 6 },
containerPadding: { lg: null, md: null, sm: null },
breakpoints: { lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0 },
cols: { lg: 12, md: 10, sm: 6, xs: 4, xxs: 2 },
containerPadding: { lg: null, md: null, sm: null, xs: null, xxs: null },
layouts: {},
margin: [10, 10],
allowOverlap: false,
Expand Down
2 changes: 1 addition & 1 deletion lib/responsiveUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { cloneLayout, compact, correctBounds } from "./utils";
import type { CompactType, Layout } from "./utils";

export type Breakpoint = string;
export type DefaultBreakpoints = "lg" | "md" | "sm";
export type DefaultBreakpoints = "lg" | "md" | "sm" | "xs" | "xxs";

// + indicates read-only
export type ResponsiveLayout<T: Breakpoint> = {
Expand Down
10 changes: 7 additions & 3 deletions lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,8 @@ export function compact(
): Layout {
// Statics go in the compareWith array right away so items flow around them.
const compareWith = getStatics(layout);
// We keep track of the bottom position.
let b = bottom(compareWith);
// We go through the items by row and column.
const sorted = sortLayoutItems(layout, compactType);
// Holding for new items.
Expand All @@ -249,7 +251,8 @@ export function compact(

// Don't move static elements
if (!l.static) {
l = compactItem(compareWith, l, compactType, cols, sorted, allowOverlap);
l = compactItem(compareWith, l, compactType, cols, sorted, allowOverlap, b);
b = Math.max(b, l.y + l.h);

// Add to comparison array. We only collide with items before this one.
// Statics are already in this array.
Expand Down Expand Up @@ -319,15 +322,16 @@ export function compactItem(
compactType: CompactType,
cols: number,
fullLayout: Layout,
allowOverlap: ?boolean
allowOverlap: ?boolean,
b: number
): LayoutItem {
const compactV = compactType === "vertical";
const compactH = compactType === "horizontal";
if (compactV) {
// Bottom 'y' possible is the bottom of the layout.
// This allows you to do nice stuff like specify {y: Infinity}
// This is here because the layout must be sorted in order to get the correct bottom `y`.
l.y = Math.min(bottom(compareWith), l.y);
l.y = Math.min(b, l.y);
// Move the element up as far as it can go without colliding.
while (l.y > 0 && !getFirstCollision(compareWith, l)) {
l.y--;
Expand Down
2 changes: 1 addition & 1 deletion test/examples/00-showcase.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export default class ShowcaseLayout extends React.Component<Props, State> {
className: "layout",
rowHeight: 30,
onLayoutChange: function() {},
cols: { lg: 12, md: 10, sm: 6 },
cols: { lg: 12, md: 10, sm: 6, xs: 4, xxs: 2 },
};

state: State = {
Expand Down
2 changes: 1 addition & 1 deletion test/examples/06-dynamic-add-remove.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const ResponsiveReactGridLayout = WidthProvider(Responsive);
export default class AddRemoveLayout extends React.PureComponent {
static defaultProps = {
className: "layout",
cols: { lg: 12, md: 10, sm: 6 },
cols: { lg: 12, md: 10, sm: 6, xs: 4, xxs: 2 },
rowHeight: 100
};

Expand Down
4 changes: 2 additions & 2 deletions test/examples/08-localstorage-responsive.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export default class ResponsiveLocalStorageLayout extends React.PureComponent {
static get defaultProps() {
return {
className: "layout",
cols: { lg: 12, md: 10, sm: 6 },
cols: { lg: 12, md: 10, sm: 6, xs: 4, xxs: 2 },
rowHeight: 30
};
}
Expand All @@ -39,7 +39,7 @@ export default class ResponsiveLocalStorageLayout extends React.PureComponent {
<button onClick={() => this.resetLayout()}>Reset Layout</button>
<ResponsiveReactGridLayout
className="layout"
cols={{ lg: 12, md: 10, sm: 6 }}
cols={{ lg: 12, md: 10, sm: 6, xs: 4, xxs: 2 }}
rowHeight={30}
layouts={this.state.layouts}
onLayoutChange={(layout, layouts) =>
Expand Down
2 changes: 1 addition & 1 deletion test/examples/14-toolbox.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export default class ToolboxLayout extends React.Component {
className: "layout",
rowHeight: 30,
onLayoutChange: function() {},
cols: { lg: 12, md: 10, sm: 6 },
cols: { lg: 12, md: 10, sm: 6, xs: 4, xxs: 2 },
initialLayout: generateLayout()
};

Expand Down
2 changes: 1 addition & 1 deletion test/examples/15-drag-from-outside.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export default class DragFromOutsideLayout extends React.Component {
className: "layout",
rowHeight: 30,
onLayoutChange: function() {},
cols: { lg: 12, md: 10, sm: 6 },
cols: { lg: 12, md: 10, sm: 6, xs: 4, xxs: 2 },
};

state = {
Expand Down
4 changes: 2 additions & 2 deletions test/examples/17-responsive-bootstrap-style.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export default class BootstrapStyleLayout extends React.PureComponent {
items: 20,
rowHeight: 30,
onLayoutChange: function() {},
cols: {lg: 12, md: 12, sm: 12}
cols: {lg: 12, md: 12, sm: 12, xs: 12, xxs: 12}
};

state = {
Expand All @@ -36,7 +36,7 @@ export default class BootstrapStyleLayout extends React.PureComponent {
// the viewport shrinks
generateLayouts() {
const times = [...Array(this.props.items)];
const widths = {lg: 3, md: 4, sm: 6};
const widths = {lg: 3, md: 4, sm: 6, xs: 12, xxs: 12};
return Object.keys(widths).reduce((memo, breakpoint) => {
const width = widths[breakpoint];
const cols = this.props.cols[breakpoint];
Expand Down
25 changes: 25 additions & 0 deletions test/examples/test_demo.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from 'react';
import RGL, { WidthProvider } from 'react-grid-layout';

const ReactGridLayout = WidthProvider(RGL);


export const IsBounded = ({ onDragStop }) => {

const layout = [
{ i: '0', x: 0, y: 0, w: 1, h: 1 },
{ i: '1', x: 1, y: 0, w: 1, h: 1 },
]

return (
<ReactGridLayout
layout={layout}
isBounded={true}
onDragStop={onDragStop}
>
{
layout.map(ele => <div key={ele.i}>{ele.i}</div>)
}
</ReactGridLayout>
);
};
50 changes: 50 additions & 0 deletions test/spec/lifecycle-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,40 @@ import DroppableLayout from "../examples/15-drag-from-outside";
import ResizableLayout from "../examples/20-resizable-handles";
import deepFreeze from "../util/deepFreeze";
import { mount } from "enzyme";
import { IsBounded } from "../examples/test_demo.jsx";

function mouseMove(x, y, node) {
const doc = node ? node.ownerDocument : document;
const evt = doc.createEvent("MouseEvents");
// $FlowIgnore
evt.initMouseEvent(
"mousemove",
true,
true,
window,
0,
0,
0,
x,
y,
false,
false,
false,
false,
0,
null
);
doc.dispatchEvent(evt);
return evt;
}
function simulateMovementFromTo(drag, fromX, fromY, toX, toY) {
TestUtils.Simulate.mouseDown(drag, {
clientX: fromX,
clientY: fromY
});
mouseMove(toX, toY, drag);
TestUtils.Simulate.mouseUp(drag);
}

describe("Lifecycle tests", function () {
// Example layouts use randomness
Expand Down Expand Up @@ -429,6 +463,22 @@ describe("Lifecycle tests", function () {
});
});

it("should transform output correctly when isBounded is true", () => {
let transform = "transform";

const wrapper = mount(
<IsBounded
onDragStop={(_, __, ___, ____, _____, element) => {
transform = element.style.transform;
}}
/>
);
const Item = wrapper.find("GridItem").at(1);

simulateMovementFromTo(Item.getDOMNode(), 0, 0, 10, 0);
expect(transform).toBe("translate(10px,0px)");
});

it("Allows customizing the droppable placeholder", function () {
const wrapper = mount(
<DroppableLayout onDropDragOver={() => ({ w: 2, h: 2 })} />
Expand Down
8 changes: 5 additions & 3 deletions test/test-hook.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from "react";
import { createRoot } from "react-dom/client";
import ReactDOM from "react-dom";
import "style-loader!css-loader!../css/styles.css";
import "style-loader!css-loader!../examples/util/example-styles.css";
typeof window !== "undefined" && (window.React = React); // for devtools
Expand Down Expand Up @@ -44,8 +44,10 @@ export default function makeLayout(Layout) {
function run() {
const contentDiv = document.getElementById("content");
const gridProps = window.gridProps || {};
const root = createRoot(contentDiv);
root.render(React.createElement(ListeningLayout, gridProps));
ReactDOM.render(
React.createElement(ListeningLayout, gridProps),
contentDiv
);
Comment on lines +47 to +50
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Update rendering logic to use modern React 18 API.

Correspondingly, the rendering logic should use the modern createRoot API instead of the deprecated ReactDOM.render.

-    ReactDOM.render(
-      React.createElement(ListeningLayout, gridProps),
-      contentDiv
-    );
+    const root = createRoot(contentDiv);
+    root.render(React.createElement(ListeningLayout, gridProps));

Committable suggestion skipped: line range outside the PR's diff.

πŸ€– Prompt for AI Agents
In test/test-hook.jsx around lines 47 to 50, replace the deprecated
ReactDOM.render call with the modern React 18 createRoot API. Import createRoot
from 'react-dom/client', create a root using createRoot(contentDiv), and then
call root.render with the React element. This updates the rendering logic to
conform to React 18 standards.

}
if (!document.getElementById("content")) {
document.addEventListener("DOMContentLoaded", run);
Expand Down
Loading