Skip to content

Commit a3de04e

Browse files
committed
Allow passing in a custom compaction and collision resolution function to the ReactGridLayout component.
1 parent 2309084 commit a3de04e

File tree

1 file changed

+44
-21
lines changed

1 file changed

+44
-21
lines changed

lib/ReactGridLayout.jsx

Lines changed: 44 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ export type Props = {
5050
draggableCancel: string,
5151
draggableHandle: string,
5252
verticalCompact: boolean,
53-
compactType: ?("horizontal" | "vertical"),
53+
compactType: CompactType,
5454
layout: Layout,
5555
margin: [number, number],
5656
containerPadding: [number, number] | null,
@@ -62,6 +62,9 @@ export type Props = {
6262
preventCollision: boolean,
6363
useCSSTransforms: boolean,
6464

65+
collisonResolver: Function,
66+
compactor: Function,
67+
6568
// Callbacks
6669
onLayoutChange: Layout => void,
6770
onDrag: EventCallback,
@@ -159,6 +162,12 @@ export default class ReactGridLayout extends React.Component<Props, State> {
159162
// Use CSS transforms instead of top/left
160163
useCSSTransforms: PropTypes.bool,
161164

165+
//
166+
// Custom collison resolution and compacting
167+
//
168+
collisonResolver: PropTypes.oneOfType([PropTypes.func]),
169+
compactor: PropTypes.oneOfType([PropTypes.func]),
170+
162171
//
163172
// Callbacks
164173
//
@@ -222,6 +231,8 @@ export default class ReactGridLayout extends React.Component<Props, State> {
222231
verticalCompact: true,
223232
compactType: "vertical",
224233
preventCollision: false,
234+
collisonResolver: moveElement,
235+
compactor: compact,
225236
onLayoutChange: noop,
226237
onDragStart: noop,
227238
onDrag: noop,
@@ -275,12 +286,12 @@ export default class ReactGridLayout extends React.Component<Props, State> {
275286
) {
276287
newLayoutBase = nextProps.layout;
277288
} else if (!isEqual(nextProps.layout, this.state.layout)) {
278-
// When props are out of sync with the state
289+
// When props are out of sync with the state
279290
newLayoutBase = nextProps.layout;
280291
} else if (!childrenEqual(this.props.children, nextProps.children)) {
281-
// If children change, also regenerate the layout. Use our state
282-
// as the base in case because it may be more up to date than
283-
// what is in props.
292+
// If children change, also regenerate the layout. Use our state
293+
// as the base in case because it may be more up to date than
294+
// what is in props.
284295
newLayoutBase = this.state.layout;
285296
}
286297

@@ -353,12 +364,18 @@ export default class ReactGridLayout extends React.Component<Props, State> {
353364
onDrag(i: string, x: number, y: number, { e, node }: GridDragEvent) {
354365
const { oldDragItem } = this.state;
355366
let { layout } = this.state;
356-
const { cols } = this.props;
357-
var l = getLayoutItem(layout, i);
367+
const {
368+
collisonResolver,
369+
preventCollision,
370+
cols,
371+
onDrag,
372+
compactor
373+
} = this.props;
374+
const l = getLayoutItem(layout, i);
358375
if (!l) return;
359376

360377
// Create placeholder (display only)
361-
var placeholder = {
378+
const placeholder = {
362379
w: l.w,
363380
h: l.h,
364381
x: l.x,
@@ -369,21 +386,21 @@ export default class ReactGridLayout extends React.Component<Props, State> {
369386

370387
// Move the element to the dragged location.
371388
const isUserAction = true;
372-
layout = moveElement(
389+
layout = collisonResolver(
373390
layout,
374391
l,
375392
x,
376393
y,
377394
isUserAction,
378-
this.props.preventCollision,
395+
preventCollision,
379396
this.compactType(),
380397
cols
381398
);
382399

383-
this.props.onDrag(layout, oldDragItem, l, placeholder, e, node);
400+
onDrag(layout, oldDragItem, l, placeholder, e, node);
384401

385402
this.setState({
386-
layout: compact(layout, this.compactType(), cols),
403+
layout: compactor(layout, this.compactType(), cols),
387404
activeDrag: placeholder
388405
});
389406
}
@@ -399,13 +416,19 @@ export default class ReactGridLayout extends React.Component<Props, State> {
399416
onDragStop(i: string, x: number, y: number, { e, node }: GridDragEvent) {
400417
const { oldDragItem } = this.state;
401418
let { layout } = this.state;
402-
const { cols, preventCollision } = this.props;
419+
const {
420+
collisonResolver,
421+
cols,
422+
preventCollision,
423+
onDragStop,
424+
compactor
425+
} = this.props;
403426
const l = getLayoutItem(layout, i);
404427
if (!l) return;
405428

406429
// Move the element here
407430
const isUserAction = true;
408-
layout = moveElement(
431+
layout = collisonResolver(
409432
layout,
410433
l,
411434
x,
@@ -416,10 +439,10 @@ export default class ReactGridLayout extends React.Component<Props, State> {
416439
cols
417440
);
418441

419-
this.props.onDragStop(layout, oldDragItem, l, null, e, node);
442+
onDragStop(layout, oldDragItem, l, null, e, node);
420443

421444
// Set state
422-
const newLayout = compact(layout, this.compactType(), cols);
445+
const newLayout = compactor(layout, this.compactType(), cols);
423446
const { oldLayout } = this.state;
424447
this.setState({
425448
activeDrag: null,
@@ -440,7 +463,7 @@ export default class ReactGridLayout extends React.Component<Props, State> {
440463

441464
onResizeStart(i: string, w: number, h: number, { e, node }: GridResizeEvent) {
442465
const { layout } = this.state;
443-
var l = getLayoutItem(layout, i);
466+
const l = getLayoutItem(layout, i);
444467
if (!l) return;
445468

446469
this.setState({
@@ -453,7 +476,7 @@ export default class ReactGridLayout extends React.Component<Props, State> {
453476

454477
onResize(i: string, w: number, h: number, { e, node }: GridResizeEvent) {
455478
const { layout, oldResizeItem } = this.state;
456-
const { cols, preventCollision } = this.props;
479+
const { cols, preventCollision, compactor } = this.props;
457480
const l: ?LayoutItem = getLayoutItem(layout, i);
458481
if (!l) return;
459482

@@ -501,20 +524,20 @@ export default class ReactGridLayout extends React.Component<Props, State> {
501524

502525
// Re-compact the layout and set the drag placeholder.
503526
this.setState({
504-
layout: compact(layout, this.compactType(), cols),
527+
layout: compactor(layout, this.compactType(), cols),
505528
activeDrag: placeholder
506529
});
507530
}
508531

509532
onResizeStop(i: string, w: number, h: number, { e, node }: GridResizeEvent) {
510533
const { layout, oldResizeItem } = this.state;
511-
const { cols } = this.props;
534+
const { cols, compactor } = this.props;
512535
var l = getLayoutItem(layout, i);
513536

514537
this.props.onResizeStop(layout, oldResizeItem, l, null, e, node);
515538

516539
// Set state
517-
const newLayout = compact(layout, this.compactType(), cols);
540+
const newLayout = compactor(layout, this.compactType(), cols);
518541
const { oldLayout } = this.state;
519542
this.setState({
520543
activeDrag: null,

0 commit comments

Comments
 (0)