Skip to content

Commit cfc37bc

Browse files
authored
Generate less gaps on drag when verticalCompact: false (#646)
* fix: make verticalCompact: false more elastic (generate less gaps) * feat: add restoreOnDrag prop * fix: fix behavior when verticalCompact: false and restoreOnDrag: false
1 parent 124327e commit cfc37bc

File tree

4 files changed

+45
-5
lines changed

4 files changed

+45
-5
lines changed

src/App.vue

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
:is-mirrored="mirrored"
4848
:prevent-collision="preventCollision"
4949
:vertical-compact="compact"
50+
:restore-on-drag="restoreOnDrag"
5051
:use-css-transforms="true"
5152
:responsive="responsive"
5253
@layout-created="layoutCreatedEvent"
@@ -167,6 +168,7 @@
167168
responsive: true,
168169
preventCollision: false,
169170
compact: true,
171+
restoreOnDrag: true,
170172
rowHeight: 30,
171173
colNum: 12,
172174
index: 0,

src/components/GridLayout.vue

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@
8282
type: Boolean,
8383
default: true
8484
},
85+
restoreOnDrag: {
86+
type: Boolean,
87+
default: false
88+
},
8589
layout: {
8690
type: Array,
8791
required: true,
@@ -315,6 +319,13 @@
315319
l = {x:0, y:0}
316320
}
317321
322+
if (eventName === "dragstart" && !this.verticalCompact) {
323+
this.positionsBeforeDrag = this.layout.reduce((result, {i, x, y}) => ({
324+
...result,
325+
[i]: {x, y}
326+
}), {});
327+
}
328+
318329
if (eventName === "dragmove" || eventName === "dragstart") {
319330
this.placeholder.i = id;
320331
this.placeholder.x = l.x;
@@ -334,11 +345,24 @@
334345
335346
// Move the element to the dragged location.
336347
this.layout = moveElement(this.layout, l, x, y, true, this.preventCollision);
337-
compact(this.layout, this.verticalCompact);
348+
349+
if (this.restoreOnDrag) {
350+
// Do not compact items more than in layout before drag
351+
// Set moved item as static to avoid to compact it
352+
l.static = true;
353+
compact(this.layout, this.verticalCompact, this.positionsBeforeDrag);
354+
l.static = false;
355+
} else {
356+
compact(this.layout, this.verticalCompact);
357+
}
358+
338359
// needed because vue can't detect changes on array element properties
339360
this.eventBus.$emit("compact");
340361
this.updateHeight();
341-
if (eventName === 'dragend') this.$emit('layout-updated', this.layout);
362+
if (eventName === 'dragend') {
363+
delete this.positionsBeforeDrag;
364+
this.$emit('layout-updated', this.layout);
365+
}
342366
},
343367
resizeEvent: function (eventName, id, x, y, h, w) {
344368
let l = getLayoutItem(this.layout, id);

src/helpers/utils.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,10 @@ export function collides(l1: LayoutItem, l2: LayoutItem): boolean {
7575
* @param {Array} layout Layout.
7676
* @param {Boolean} verticalCompact Whether or not to compact the layout
7777
* vertically.
78+
* @param {Object} minPositions
7879
* @return {Array} Compacted Layout.
7980
*/
80-
export function compact(layout: Layout, verticalCompact: Boolean): Layout {
81+
export function compact(layout: Layout, verticalCompact: Boolean, minPositions): Layout {
8182
// Statics go in the compareWith array right away so items flow around them.
8283
const compareWith = getStatics(layout);
8384
// We go through the items by row and column.
@@ -90,7 +91,7 @@ export function compact(layout: Layout, verticalCompact: Boolean): Layout {
9091

9192
// Don't move static elements
9293
if (!l.static) {
93-
l = compactItem(compareWith, l, verticalCompact);
94+
l = compactItem(compareWith, l, verticalCompact, minPositions);
9495

9596
// Add to comparison array. We only collide with items before this one.
9697
// Statics are already in this array.
@@ -110,12 +111,17 @@ export function compact(layout: Layout, verticalCompact: Boolean): Layout {
110111
/**
111112
* Compact an item in the layout.
112113
*/
113-
export function compactItem(compareWith: Layout, l: LayoutItem, verticalCompact: boolean): LayoutItem {
114+
export function compactItem(compareWith: Layout, l: LayoutItem, verticalCompact: boolean, minPositions): LayoutItem {
114115
if (verticalCompact) {
115116
// Move the element up as far as it can go without colliding.
116117
while (l.y > 0 && !getFirstCollision(compareWith, l)) {
117118
l.y--;
118119
}
120+
} else if (minPositions) {
121+
const minY = minPositions[l.i].y;
122+
while (l.y > minY && !getFirstCollision(compareWith, l)) {
123+
l.y--;
124+
}
119125
}
120126

121127
// Move it down, and keep moving it down if it's colliding.

website/docs/guide/properties.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,14 @@ Says if the container height should swells and contracts to fit contents.
100100

101101
Says if the layout should be compact vertically.
102102

103+
### restoreOnDrag
104+
105+
* type: `Boolean`
106+
* required: `false`
107+
* default: `false`
108+
109+
Says if the moved grid items should be restored after an item has been dragged over.
110+
103111
### preventCollision
104112

105113
* type: `Boolean`

0 commit comments

Comments
 (0)