react-grid-layout 1.5.2 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1075 -432
- package/css/styles.css +6 -4
- package/dist/ResponsiveGridLayout-CH4s0tKj.d.ts +124 -0
- package/dist/ResponsiveGridLayout-D6lFRE3f.d.mts +124 -0
- package/dist/calculate-CwYDW8na.d.mts +168 -0
- package/dist/calculate-mgLpNJ5O.d.ts +168 -0
- package/dist/chunk-2KUHNJXF.mjs +90 -0
- package/dist/chunk-2KUHNJXF.mjs.map +1 -0
- package/dist/chunk-3WO4SAYB.js +868 -0
- package/dist/chunk-3WO4SAYB.js.map +1 -0
- package/dist/chunk-4HNUMWQK.mjs +822 -0
- package/dist/chunk-4HNUMWQK.mjs.map +1 -0
- package/dist/chunk-BFTKGAP3.js +1309 -0
- package/dist/chunk-BFTKGAP3.js.map +1 -0
- package/dist/chunk-F6NQPYKT.js +98 -0
- package/dist/chunk-F6NQPYKT.js.map +1 -0
- package/dist/chunk-H5KMDLY3.js +434 -0
- package/dist/chunk-H5KMDLY3.js.map +1 -0
- package/dist/chunk-PBQSHIID.js +4 -0
- package/dist/chunk-PBQSHIID.js.map +1 -0
- package/dist/chunk-R35HZZTA.mjs +1300 -0
- package/dist/chunk-R35HZZTA.mjs.map +1 -0
- package/dist/chunk-ZCXE6SR5.mjs +428 -0
- package/dist/chunk-ZCXE6SR5.mjs.map +1 -0
- package/dist/chunk-ZWN22PS2.mjs +3 -0
- package/dist/chunk-ZWN22PS2.mjs.map +1 -0
- package/dist/core.d.mts +33 -0
- package/dist/core.d.ts +33 -0
- package/dist/core.js +218 -0
- package/dist/core.js.map +1 -0
- package/dist/core.mjs +5 -0
- package/dist/core.mjs.map +1 -0
- package/dist/extras.d.mts +78 -0
- package/dist/extras.d.ts +78 -0
- package/dist/extras.js +91 -0
- package/dist/extras.js.map +1 -0
- package/dist/extras.mjs +89 -0
- package/dist/extras.mjs.map +1 -0
- package/dist/index.d.mts +7 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +154 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +7 -0
- package/dist/index.mjs.map +1 -0
- package/dist/legacy.d.mts +163 -0
- package/dist/legacy.d.ts +163 -0
- package/dist/legacy.js +319 -0
- package/dist/legacy.js.map +1 -0
- package/dist/legacy.mjs +307 -0
- package/dist/legacy.mjs.map +1 -0
- package/dist/position-BmN1z36J.d.mts +319 -0
- package/dist/position-Dk2b4ZMS.d.ts +319 -0
- package/dist/react.d.mts +351 -0
- package/dist/react.d.ts +351 -0
- package/dist/react.js +96 -0
- package/dist/react.js.map +1 -0
- package/dist/react.mjs +7 -0
- package/dist/react.mjs.map +1 -0
- package/dist/responsive-C4L1ESlm.d.ts +145 -0
- package/dist/responsive-CJxefsYw.d.mts +145 -0
- package/dist/types-Cxf4nHNr.d.mts +375 -0
- package/dist/types-Cxf4nHNr.d.ts +375 -0
- package/index-dev.js +8 -0
- package/package.json +132 -39
- package/.babelrc.js +0 -22
- package/.browserslistrc +0 -3
- package/.eslintignore +0 -4
- package/.flowconfig +0 -20
- package/.prettierignore +0 -4
- package/.prettierrc +0 -17
- package/CHANGELOG.md +0 -985
- package/build/GridItem.js +0 -640
- package/build/ReactGridLayout.js +0 -744
- package/build/ReactGridLayoutPropTypes.js +0 -210
- package/build/ResponsiveReactGridLayout.js +0 -294
- package/build/calculateUtils.js +0 -165
- package/build/components/WidthProvider.js +0 -111
- package/build/fastRGLPropsEqual.js +0 -5
- package/build/responsiveUtils.js +0 -101
- package/build/utils.js +0 -834
- package/dist/react-grid-layout.min.js +0 -2
- package/dist/react-grid-layout.min.js.map +0 -1
- package/index.js.flow +0 -8
- package/ip_fetcher +0 -0
- package/ip_fetcher.c +0 -47
- package/lib/GridItem.jsx +0 -689
- package/lib/ReactGridLayout.jsx +0 -855
- package/lib/ReactGridLayoutPropTypes.js +0 -241
- package/lib/ResponsiveReactGridLayout.jsx +0 -349
- package/lib/calculateUtils.js +0 -169
- package/lib/components/WidthProvider.jsx +0 -110
- package/lib/fastRGLPropsEqual.js +0 -46
- package/lib/responsiveUtils.js +0 -118
- package/lib/utils.js +0 -979
package/lib/GridItem.jsx
DELETED
|
@@ -1,689 +0,0 @@
|
|
|
1
|
-
// @flow
|
|
2
|
-
import React from "react";
|
|
3
|
-
import { flushSync } from "react-dom";
|
|
4
|
-
import PropTypes from "prop-types";
|
|
5
|
-
import { DraggableCore } from "react-draggable";
|
|
6
|
-
import { Resizable } from "react-resizable";
|
|
7
|
-
import {
|
|
8
|
-
fastPositionEqual,
|
|
9
|
-
perc,
|
|
10
|
-
resizeItemInDirection,
|
|
11
|
-
setTopLeft,
|
|
12
|
-
setTransform
|
|
13
|
-
} from "./utils";
|
|
14
|
-
import {
|
|
15
|
-
calcGridItemPosition,
|
|
16
|
-
calcGridItemWHPx,
|
|
17
|
-
calcGridColWidth,
|
|
18
|
-
calcXY,
|
|
19
|
-
calcWH,
|
|
20
|
-
clamp
|
|
21
|
-
} from "./calculateUtils";
|
|
22
|
-
import {
|
|
23
|
-
resizeHandleAxesType,
|
|
24
|
-
resizeHandleType
|
|
25
|
-
} from "./ReactGridLayoutPropTypes";
|
|
26
|
-
import clsx from "clsx";
|
|
27
|
-
import type { Element as ReactElement, Node as ReactNode } from "react";
|
|
28
|
-
|
|
29
|
-
import type {
|
|
30
|
-
ReactDraggableCallbackData,
|
|
31
|
-
GridDragEvent,
|
|
32
|
-
GridResizeEvent,
|
|
33
|
-
DroppingPosition,
|
|
34
|
-
Position,
|
|
35
|
-
ResizeHandleAxis
|
|
36
|
-
} from "./utils";
|
|
37
|
-
|
|
38
|
-
import type { PositionParams } from "./calculateUtils";
|
|
39
|
-
import type { ResizeHandle, ReactRef } from "./ReactGridLayoutPropTypes";
|
|
40
|
-
|
|
41
|
-
type PartialPosition = { top: number, left: number };
|
|
42
|
-
type GridItemCallback<Data: GridDragEvent | GridResizeEvent> = (
|
|
43
|
-
i: string,
|
|
44
|
-
w: number,
|
|
45
|
-
h: number,
|
|
46
|
-
Data
|
|
47
|
-
) => void;
|
|
48
|
-
|
|
49
|
-
type ResizeCallbackData = {
|
|
50
|
-
node: HTMLElement,
|
|
51
|
-
size: Position,
|
|
52
|
-
handle: ResizeHandleAxis
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
type GridItemResizeCallback = (
|
|
56
|
-
e: Event,
|
|
57
|
-
data: ResizeCallbackData,
|
|
58
|
-
position: Position
|
|
59
|
-
) => void;
|
|
60
|
-
|
|
61
|
-
type State = {
|
|
62
|
-
resizing: ?{ top: number, left: number, width: number, height: number },
|
|
63
|
-
dragging: ?{ top: number, left: number },
|
|
64
|
-
className: string
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
type Props = {
|
|
68
|
-
children: ReactElement<any>,
|
|
69
|
-
cols: number,
|
|
70
|
-
containerWidth: number,
|
|
71
|
-
margin: [number, number],
|
|
72
|
-
containerPadding: [number, number],
|
|
73
|
-
rowHeight: number,
|
|
74
|
-
maxRows: number,
|
|
75
|
-
isDraggable: boolean,
|
|
76
|
-
isResizable: boolean,
|
|
77
|
-
isBounded: boolean,
|
|
78
|
-
static?: boolean,
|
|
79
|
-
useCSSTransforms?: boolean,
|
|
80
|
-
usePercentages?: boolean,
|
|
81
|
-
transformScale: number,
|
|
82
|
-
droppingPosition?: DroppingPosition,
|
|
83
|
-
|
|
84
|
-
className: string,
|
|
85
|
-
style?: Object,
|
|
86
|
-
// Draggability
|
|
87
|
-
cancel: string,
|
|
88
|
-
handle: string,
|
|
89
|
-
|
|
90
|
-
x: number,
|
|
91
|
-
y: number,
|
|
92
|
-
w: number,
|
|
93
|
-
h: number,
|
|
94
|
-
|
|
95
|
-
minW: number,
|
|
96
|
-
maxW: number,
|
|
97
|
-
minH: number,
|
|
98
|
-
maxH: number,
|
|
99
|
-
i: string,
|
|
100
|
-
|
|
101
|
-
resizeHandles?: ResizeHandleAxis[],
|
|
102
|
-
resizeHandle?: ResizeHandle,
|
|
103
|
-
|
|
104
|
-
onDrag?: GridItemCallback<GridDragEvent>,
|
|
105
|
-
onDragStart?: GridItemCallback<GridDragEvent>,
|
|
106
|
-
onDragStop?: GridItemCallback<GridDragEvent>,
|
|
107
|
-
onResize?: GridItemCallback<GridResizeEvent>,
|
|
108
|
-
onResizeStart?: GridItemCallback<GridResizeEvent>,
|
|
109
|
-
onResizeStop?: GridItemCallback<GridResizeEvent>
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
type DefaultProps = {
|
|
113
|
-
className: string,
|
|
114
|
-
cancel: string,
|
|
115
|
-
handle: string,
|
|
116
|
-
minH: number,
|
|
117
|
-
minW: number,
|
|
118
|
-
maxH: number,
|
|
119
|
-
maxW: number,
|
|
120
|
-
transformScale: number
|
|
121
|
-
};
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* An individual item within a ReactGridLayout.
|
|
125
|
-
*/
|
|
126
|
-
export default class GridItem extends React.Component<Props, State> {
|
|
127
|
-
static propTypes = {
|
|
128
|
-
// Children must be only a single element
|
|
129
|
-
children: PropTypes.element,
|
|
130
|
-
|
|
131
|
-
// General grid attributes
|
|
132
|
-
cols: PropTypes.number.isRequired,
|
|
133
|
-
containerWidth: PropTypes.number.isRequired,
|
|
134
|
-
rowHeight: PropTypes.number.isRequired,
|
|
135
|
-
margin: PropTypes.array.isRequired,
|
|
136
|
-
maxRows: PropTypes.number.isRequired,
|
|
137
|
-
containerPadding: PropTypes.array.isRequired,
|
|
138
|
-
|
|
139
|
-
// These are all in grid units
|
|
140
|
-
x: PropTypes.number.isRequired,
|
|
141
|
-
y: PropTypes.number.isRequired,
|
|
142
|
-
w: PropTypes.number.isRequired,
|
|
143
|
-
h: PropTypes.number.isRequired,
|
|
144
|
-
|
|
145
|
-
// All optional
|
|
146
|
-
minW: function (props: Props, propName: string) {
|
|
147
|
-
const value = props[propName];
|
|
148
|
-
if (typeof value !== "number") return new Error("minWidth not Number");
|
|
149
|
-
if (value > props.w || value > props.maxW)
|
|
150
|
-
return new Error("minWidth larger than item width/maxWidth");
|
|
151
|
-
},
|
|
152
|
-
|
|
153
|
-
maxW: function (props: Props, propName: string) {
|
|
154
|
-
const value = props[propName];
|
|
155
|
-
if (typeof value !== "number") return new Error("maxWidth not Number");
|
|
156
|
-
if (value < props.w || value < props.minW)
|
|
157
|
-
return new Error("maxWidth smaller than item width/minWidth");
|
|
158
|
-
},
|
|
159
|
-
|
|
160
|
-
minH: function (props: Props, propName: string) {
|
|
161
|
-
const value = props[propName];
|
|
162
|
-
if (typeof value !== "number") return new Error("minHeight not Number");
|
|
163
|
-
if (value > props.h || value > props.maxH)
|
|
164
|
-
return new Error("minHeight larger than item height/maxHeight");
|
|
165
|
-
},
|
|
166
|
-
|
|
167
|
-
maxH: function (props: Props, propName: string) {
|
|
168
|
-
const value = props[propName];
|
|
169
|
-
if (typeof value !== "number") return new Error("maxHeight not Number");
|
|
170
|
-
if (value < props.h || value < props.minH)
|
|
171
|
-
return new Error("maxHeight smaller than item height/minHeight");
|
|
172
|
-
},
|
|
173
|
-
|
|
174
|
-
// ID is nice to have for callbacks
|
|
175
|
-
i: PropTypes.string.isRequired,
|
|
176
|
-
|
|
177
|
-
// Resize handle options
|
|
178
|
-
resizeHandles: resizeHandleAxesType,
|
|
179
|
-
resizeHandle: resizeHandleType,
|
|
180
|
-
|
|
181
|
-
// Functions
|
|
182
|
-
onDragStop: PropTypes.func,
|
|
183
|
-
onDragStart: PropTypes.func,
|
|
184
|
-
onDrag: PropTypes.func,
|
|
185
|
-
onResizeStop: PropTypes.func,
|
|
186
|
-
onResizeStart: PropTypes.func,
|
|
187
|
-
onResize: PropTypes.func,
|
|
188
|
-
|
|
189
|
-
// Flags
|
|
190
|
-
isDraggable: PropTypes.bool.isRequired,
|
|
191
|
-
isResizable: PropTypes.bool.isRequired,
|
|
192
|
-
isBounded: PropTypes.bool.isRequired,
|
|
193
|
-
static: PropTypes.bool,
|
|
194
|
-
|
|
195
|
-
// Use CSS transforms instead of top/left
|
|
196
|
-
useCSSTransforms: PropTypes.bool.isRequired,
|
|
197
|
-
transformScale: PropTypes.number,
|
|
198
|
-
|
|
199
|
-
// Others
|
|
200
|
-
className: PropTypes.string,
|
|
201
|
-
// Selector for draggable handle
|
|
202
|
-
handle: PropTypes.string,
|
|
203
|
-
// Selector for draggable cancel (see react-draggable)
|
|
204
|
-
cancel: PropTypes.string,
|
|
205
|
-
// Current position of a dropping element
|
|
206
|
-
droppingPosition: PropTypes.shape({
|
|
207
|
-
e: PropTypes.object.isRequired,
|
|
208
|
-
left: PropTypes.number.isRequired,
|
|
209
|
-
top: PropTypes.number.isRequired
|
|
210
|
-
})
|
|
211
|
-
};
|
|
212
|
-
|
|
213
|
-
static defaultProps: DefaultProps = {
|
|
214
|
-
className: "",
|
|
215
|
-
cancel: "",
|
|
216
|
-
handle: "",
|
|
217
|
-
minH: 1,
|
|
218
|
-
minW: 1,
|
|
219
|
-
maxH: Infinity,
|
|
220
|
-
maxW: Infinity,
|
|
221
|
-
transformScale: 1
|
|
222
|
-
};
|
|
223
|
-
|
|
224
|
-
state: State = {
|
|
225
|
-
resizing: null,
|
|
226
|
-
dragging: null,
|
|
227
|
-
className: ""
|
|
228
|
-
};
|
|
229
|
-
|
|
230
|
-
elementRef: ReactRef<HTMLDivElement> = React.createRef();
|
|
231
|
-
|
|
232
|
-
shouldComponentUpdate(nextProps: Props, nextState: State): boolean {
|
|
233
|
-
// We can't deeply compare children. If the developer memoizes them, we can
|
|
234
|
-
// use this optimization.
|
|
235
|
-
if (this.props.children !== nextProps.children) return true;
|
|
236
|
-
if (this.props.droppingPosition !== nextProps.droppingPosition) return true;
|
|
237
|
-
// TODO memoize these calculations so they don't take so long?
|
|
238
|
-
const oldPosition = calcGridItemPosition(
|
|
239
|
-
this.getPositionParams(this.props),
|
|
240
|
-
this.props.x,
|
|
241
|
-
this.props.y,
|
|
242
|
-
this.props.w,
|
|
243
|
-
this.props.h,
|
|
244
|
-
this.state
|
|
245
|
-
);
|
|
246
|
-
const newPosition = calcGridItemPosition(
|
|
247
|
-
this.getPositionParams(nextProps),
|
|
248
|
-
nextProps.x,
|
|
249
|
-
nextProps.y,
|
|
250
|
-
nextProps.w,
|
|
251
|
-
nextProps.h,
|
|
252
|
-
nextState
|
|
253
|
-
);
|
|
254
|
-
return (
|
|
255
|
-
!fastPositionEqual(oldPosition, newPosition) ||
|
|
256
|
-
this.props.useCSSTransforms !== nextProps.useCSSTransforms
|
|
257
|
-
);
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
componentDidMount() {
|
|
261
|
-
this.moveDroppingItem({});
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
componentDidUpdate(prevProps: Props) {
|
|
265
|
-
this.moveDroppingItem(prevProps);
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
// When a droppingPosition is present, this means we should fire a move event, as if we had moved
|
|
269
|
-
// this element by `x, y` pixels.
|
|
270
|
-
moveDroppingItem(prevProps: Props) {
|
|
271
|
-
const { droppingPosition } = this.props;
|
|
272
|
-
if (!droppingPosition) return;
|
|
273
|
-
const node = this.elementRef.current;
|
|
274
|
-
// Can't find DOM node (are we unmounted?)
|
|
275
|
-
if (!node) return;
|
|
276
|
-
|
|
277
|
-
const prevDroppingPosition = prevProps.droppingPosition || {
|
|
278
|
-
left: 0,
|
|
279
|
-
top: 0
|
|
280
|
-
};
|
|
281
|
-
const { dragging } = this.state;
|
|
282
|
-
|
|
283
|
-
const shouldDrag =
|
|
284
|
-
(dragging && droppingPosition.left !== prevDroppingPosition.left) ||
|
|
285
|
-
droppingPosition.top !== prevDroppingPosition.top;
|
|
286
|
-
|
|
287
|
-
if (!dragging) {
|
|
288
|
-
this.onDragStart(droppingPosition.e, {
|
|
289
|
-
node,
|
|
290
|
-
deltaX: droppingPosition.left,
|
|
291
|
-
deltaY: droppingPosition.top
|
|
292
|
-
});
|
|
293
|
-
} else if (shouldDrag) {
|
|
294
|
-
const deltaX = droppingPosition.left - dragging.left;
|
|
295
|
-
const deltaY = droppingPosition.top - dragging.top;
|
|
296
|
-
|
|
297
|
-
this.onDrag(
|
|
298
|
-
droppingPosition.e,
|
|
299
|
-
{
|
|
300
|
-
node,
|
|
301
|
-
deltaX,
|
|
302
|
-
deltaY
|
|
303
|
-
},
|
|
304
|
-
true // dontFLush: avoid flushSync to temper warnings
|
|
305
|
-
);
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
getPositionParams(props: Props = this.props): PositionParams {
|
|
310
|
-
return {
|
|
311
|
-
cols: props.cols,
|
|
312
|
-
containerPadding: props.containerPadding,
|
|
313
|
-
containerWidth: props.containerWidth,
|
|
314
|
-
margin: props.margin,
|
|
315
|
-
maxRows: props.maxRows,
|
|
316
|
-
rowHeight: props.rowHeight
|
|
317
|
-
};
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
/**
|
|
321
|
-
* This is where we set the grid item's absolute placement. It gets a little tricky because we want to do it
|
|
322
|
-
* well when server rendering, and the only way to do that properly is to use percentage width/left because
|
|
323
|
-
* we don't know exactly what the browser viewport is.
|
|
324
|
-
* Unfortunately, CSS Transforms, which are great for performance, break in this instance because a percentage
|
|
325
|
-
* left is relative to the item itself, not its container! So we cannot use them on the server rendering pass.
|
|
326
|
-
*
|
|
327
|
-
* @param {Object} pos Position object with width, height, left, top.
|
|
328
|
-
* @return {Object} Style object.
|
|
329
|
-
*/
|
|
330
|
-
createStyle(pos: Position): { [key: string]: ?string } {
|
|
331
|
-
const { usePercentages, containerWidth, useCSSTransforms } = this.props;
|
|
332
|
-
|
|
333
|
-
let style;
|
|
334
|
-
// CSS Transforms support (default)
|
|
335
|
-
if (useCSSTransforms) {
|
|
336
|
-
style = setTransform(pos);
|
|
337
|
-
} else {
|
|
338
|
-
// top,left (slow)
|
|
339
|
-
style = setTopLeft(pos);
|
|
340
|
-
|
|
341
|
-
// This is used for server rendering.
|
|
342
|
-
if (usePercentages) {
|
|
343
|
-
style.left = perc(pos.left / containerWidth);
|
|
344
|
-
style.width = perc(pos.width / containerWidth);
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
return style;
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
/**
|
|
352
|
-
* Mix a Draggable instance into a child.
|
|
353
|
-
* @param {Element} child Child element.
|
|
354
|
-
* @return {Element} Child wrapped in Draggable.
|
|
355
|
-
*/
|
|
356
|
-
mixinDraggable(
|
|
357
|
-
child: ReactElement<any>,
|
|
358
|
-
isDraggable: boolean
|
|
359
|
-
): ReactElement<any> {
|
|
360
|
-
return (
|
|
361
|
-
<DraggableCore
|
|
362
|
-
disabled={!isDraggable}
|
|
363
|
-
onStart={this.onDragStart}
|
|
364
|
-
onDrag={this.onDrag}
|
|
365
|
-
onStop={this.onDragStop}
|
|
366
|
-
handle={this.props.handle}
|
|
367
|
-
cancel={
|
|
368
|
-
".react-resizable-handle" +
|
|
369
|
-
(this.props.cancel ? "," + this.props.cancel : "")
|
|
370
|
-
}
|
|
371
|
-
scale={this.props.transformScale}
|
|
372
|
-
nodeRef={this.elementRef}
|
|
373
|
-
>
|
|
374
|
-
{child}
|
|
375
|
-
</DraggableCore>
|
|
376
|
-
);
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
/**
|
|
380
|
-
* Utility function to setup callback handler definitions for
|
|
381
|
-
* similarily structured resize events.
|
|
382
|
-
*/
|
|
383
|
-
curryResizeHandler(position: Position, handler: Function): Function {
|
|
384
|
-
return (e: Event, data: ResizeCallbackData): Function =>
|
|
385
|
-
handler(e, data, position);
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
/**
|
|
389
|
-
* Mix a Resizable instance into a child.
|
|
390
|
-
* @param {Element} child Child element.
|
|
391
|
-
* @param {Object} position Position object (pixel values)
|
|
392
|
-
* @return {Element} Child wrapped in Resizable.
|
|
393
|
-
*/
|
|
394
|
-
mixinResizable(
|
|
395
|
-
child: ReactElement<any>,
|
|
396
|
-
position: Position,
|
|
397
|
-
isResizable: boolean
|
|
398
|
-
): ReactElement<any> {
|
|
399
|
-
const {
|
|
400
|
-
cols,
|
|
401
|
-
minW,
|
|
402
|
-
minH,
|
|
403
|
-
maxW,
|
|
404
|
-
maxH,
|
|
405
|
-
transformScale,
|
|
406
|
-
resizeHandles,
|
|
407
|
-
resizeHandle
|
|
408
|
-
} = this.props;
|
|
409
|
-
const positionParams = this.getPositionParams();
|
|
410
|
-
|
|
411
|
-
// This is the max possible width - doesn't go to infinity because of the width of the window
|
|
412
|
-
const maxWidth = calcGridItemPosition(positionParams, 0, 0, cols, 0).width;
|
|
413
|
-
|
|
414
|
-
// Calculate min/max constraints using our min & maxes
|
|
415
|
-
const mins = calcGridItemPosition(positionParams, 0, 0, minW, minH);
|
|
416
|
-
const maxes = calcGridItemPosition(positionParams, 0, 0, maxW, maxH);
|
|
417
|
-
const minConstraints = [mins.width, mins.height];
|
|
418
|
-
const maxConstraints = [
|
|
419
|
-
Math.min(maxes.width, maxWidth),
|
|
420
|
-
Math.min(maxes.height, Infinity)
|
|
421
|
-
];
|
|
422
|
-
return (
|
|
423
|
-
<Resizable
|
|
424
|
-
// These are opts for the resize handle itself
|
|
425
|
-
draggableOpts={{
|
|
426
|
-
disabled: !isResizable
|
|
427
|
-
}}
|
|
428
|
-
className={isResizable ? undefined : "react-resizable-hide"}
|
|
429
|
-
width={position.width}
|
|
430
|
-
height={position.height}
|
|
431
|
-
minConstraints={minConstraints}
|
|
432
|
-
maxConstraints={maxConstraints}
|
|
433
|
-
onResizeStop={this.curryResizeHandler(position, this.onResizeStop)}
|
|
434
|
-
onResizeStart={this.curryResizeHandler(position, this.onResizeStart)}
|
|
435
|
-
onResize={this.curryResizeHandler(position, this.onResize)}
|
|
436
|
-
transformScale={transformScale}
|
|
437
|
-
resizeHandles={resizeHandles}
|
|
438
|
-
handle={resizeHandle}
|
|
439
|
-
>
|
|
440
|
-
{child}
|
|
441
|
-
</Resizable>
|
|
442
|
-
);
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
/**
|
|
446
|
-
* onDragStart event handler
|
|
447
|
-
* @param {Event} e event data
|
|
448
|
-
* @param {Object} callbackData an object with node, delta and position information
|
|
449
|
-
*/
|
|
450
|
-
onDragStart: (Event, ReactDraggableCallbackData) => void = (e, { node }) => {
|
|
451
|
-
const { onDragStart, transformScale } = this.props;
|
|
452
|
-
if (!onDragStart) return;
|
|
453
|
-
|
|
454
|
-
const newPosition: PartialPosition = { top: 0, left: 0 };
|
|
455
|
-
|
|
456
|
-
// TODO: this wont work on nested parents
|
|
457
|
-
const { offsetParent } = node;
|
|
458
|
-
if (!offsetParent) return;
|
|
459
|
-
const parentRect = offsetParent.getBoundingClientRect();
|
|
460
|
-
const clientRect = node.getBoundingClientRect();
|
|
461
|
-
const cLeft = clientRect.left / transformScale;
|
|
462
|
-
const pLeft = parentRect.left / transformScale;
|
|
463
|
-
const cTop = clientRect.top / transformScale;
|
|
464
|
-
const pTop = parentRect.top / transformScale;
|
|
465
|
-
newPosition.left = cLeft - pLeft + offsetParent.scrollLeft;
|
|
466
|
-
newPosition.top = cTop - pTop + offsetParent.scrollTop;
|
|
467
|
-
this.setState({ dragging: newPosition });
|
|
468
|
-
|
|
469
|
-
// Call callback with this data
|
|
470
|
-
const { x, y } = calcXY(
|
|
471
|
-
this.getPositionParams(),
|
|
472
|
-
newPosition.top,
|
|
473
|
-
newPosition.left,
|
|
474
|
-
this.props.w,
|
|
475
|
-
this.props.h
|
|
476
|
-
);
|
|
477
|
-
|
|
478
|
-
return onDragStart.call(this, this.props.i, x, y, {
|
|
479
|
-
e,
|
|
480
|
-
node,
|
|
481
|
-
newPosition
|
|
482
|
-
});
|
|
483
|
-
};
|
|
484
|
-
|
|
485
|
-
/**
|
|
486
|
-
* onDrag event handler
|
|
487
|
-
* @param {Event} e event data
|
|
488
|
-
* @param {Object} callbackData an object with node, delta and position information
|
|
489
|
-
* @param {boolean} dontFlush if true, will not call flushSync
|
|
490
|
-
*/
|
|
491
|
-
onDrag: (Event, ReactDraggableCallbackData, boolean) => void = (
|
|
492
|
-
e,
|
|
493
|
-
{ node, deltaX, deltaY },
|
|
494
|
-
dontFlush
|
|
495
|
-
) => {
|
|
496
|
-
const { onDrag } = this.props;
|
|
497
|
-
if (!onDrag) return;
|
|
498
|
-
|
|
499
|
-
if (!this.state.dragging) {
|
|
500
|
-
throw new Error("onDrag called before onDragStart.");
|
|
501
|
-
}
|
|
502
|
-
let top = this.state.dragging.top + deltaY;
|
|
503
|
-
let left = this.state.dragging.left + deltaX;
|
|
504
|
-
|
|
505
|
-
const { isBounded, i, w, h, containerWidth } = this.props;
|
|
506
|
-
const positionParams = this.getPositionParams();
|
|
507
|
-
|
|
508
|
-
// Boundary calculations; keeps items within the grid
|
|
509
|
-
if (isBounded) {
|
|
510
|
-
const { offsetParent } = node;
|
|
511
|
-
|
|
512
|
-
if (offsetParent) {
|
|
513
|
-
const { margin, rowHeight } = this.props;
|
|
514
|
-
const bottomBoundary =
|
|
515
|
-
offsetParent.clientHeight - calcGridItemWHPx(h, rowHeight, margin[1]);
|
|
516
|
-
top = clamp(top, 0, bottomBoundary);
|
|
517
|
-
|
|
518
|
-
const colWidth = calcGridColWidth(positionParams);
|
|
519
|
-
const rightBoundary =
|
|
520
|
-
containerWidth - calcGridItemWHPx(w, colWidth, margin[0]);
|
|
521
|
-
left = clamp(left, 0, rightBoundary);
|
|
522
|
-
}
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
const newPosition: PartialPosition = { top, left };
|
|
526
|
-
|
|
527
|
-
// dontFlush is set if we're calling from inside
|
|
528
|
-
if (dontFlush) {
|
|
529
|
-
this.setState({ dragging: newPosition });
|
|
530
|
-
} else {
|
|
531
|
-
flushSync(() => {
|
|
532
|
-
this.setState({ dragging: newPosition });
|
|
533
|
-
});
|
|
534
|
-
}
|
|
535
|
-
|
|
536
|
-
// Call callback with this data
|
|
537
|
-
const { x, y } = calcXY(positionParams, top, left, w, h);
|
|
538
|
-
return onDrag.call(this, i, x, y, {
|
|
539
|
-
e,
|
|
540
|
-
node,
|
|
541
|
-
newPosition
|
|
542
|
-
});
|
|
543
|
-
};
|
|
544
|
-
|
|
545
|
-
/**
|
|
546
|
-
* onDragStop event handler
|
|
547
|
-
* @param {Event} e event data
|
|
548
|
-
* @param {Object} callbackData an object with node, delta and position information
|
|
549
|
-
*/
|
|
550
|
-
onDragStop: (Event, ReactDraggableCallbackData) => void = (e, { node }) => {
|
|
551
|
-
const { onDragStop } = this.props;
|
|
552
|
-
if (!onDragStop) return;
|
|
553
|
-
|
|
554
|
-
if (!this.state.dragging) {
|
|
555
|
-
throw new Error("onDragEnd called before onDragStart.");
|
|
556
|
-
}
|
|
557
|
-
const { w, h, i } = this.props;
|
|
558
|
-
const { left, top } = this.state.dragging;
|
|
559
|
-
const newPosition: PartialPosition = { top, left };
|
|
560
|
-
this.setState({ dragging: null });
|
|
561
|
-
|
|
562
|
-
const { x, y } = calcXY(this.getPositionParams(), top, left, w, h);
|
|
563
|
-
|
|
564
|
-
return onDragStop.call(this, i, x, y, {
|
|
565
|
-
e,
|
|
566
|
-
node,
|
|
567
|
-
newPosition
|
|
568
|
-
});
|
|
569
|
-
};
|
|
570
|
-
|
|
571
|
-
/**
|
|
572
|
-
* onResizeStop event handler
|
|
573
|
-
* @param {Event} e event data
|
|
574
|
-
* @param {Object} callbackData an object with node and size information
|
|
575
|
-
*/
|
|
576
|
-
onResizeStop: GridItemResizeCallback = (e, callbackData, position) =>
|
|
577
|
-
this.onResizeHandler(e, callbackData, position, "onResizeStop");
|
|
578
|
-
|
|
579
|
-
// onResizeStart event handler
|
|
580
|
-
onResizeStart: GridItemResizeCallback = (e, callbackData, position) =>
|
|
581
|
-
this.onResizeHandler(e, callbackData, position, "onResizeStart");
|
|
582
|
-
|
|
583
|
-
// onResize event handler
|
|
584
|
-
onResize: GridItemResizeCallback = (e, callbackData, position) =>
|
|
585
|
-
this.onResizeHandler(e, callbackData, position, "onResize");
|
|
586
|
-
|
|
587
|
-
/**
|
|
588
|
-
* Wrapper around resize events to provide more useful data.
|
|
589
|
-
*/
|
|
590
|
-
onResizeHandler(
|
|
591
|
-
e: Event,
|
|
592
|
-
{ node, size, handle }: ResizeCallbackData, // 'size' is updated position
|
|
593
|
-
position: Position, // existing position
|
|
594
|
-
handlerName: string
|
|
595
|
-
): void {
|
|
596
|
-
const handler = this.props[handlerName];
|
|
597
|
-
if (!handler) return;
|
|
598
|
-
const { x, y, i, maxH, minH, containerWidth } = this.props;
|
|
599
|
-
const { minW, maxW } = this.props;
|
|
600
|
-
|
|
601
|
-
// Clamping of dimensions based on resize direction
|
|
602
|
-
let updatedSize = size;
|
|
603
|
-
if (node) {
|
|
604
|
-
updatedSize = resizeItemInDirection(
|
|
605
|
-
handle,
|
|
606
|
-
position,
|
|
607
|
-
size,
|
|
608
|
-
containerWidth
|
|
609
|
-
);
|
|
610
|
-
flushSync(() => {
|
|
611
|
-
this.setState({
|
|
612
|
-
resizing: handlerName === "onResizeStop" ? null : updatedSize
|
|
613
|
-
});
|
|
614
|
-
});
|
|
615
|
-
}
|
|
616
|
-
|
|
617
|
-
// Get new XY based on pixel size
|
|
618
|
-
let { w, h } = calcWH(
|
|
619
|
-
this.getPositionParams(),
|
|
620
|
-
updatedSize.width,
|
|
621
|
-
updatedSize.height,
|
|
622
|
-
x,
|
|
623
|
-
y,
|
|
624
|
-
handle
|
|
625
|
-
);
|
|
626
|
-
|
|
627
|
-
// Min/max capping.
|
|
628
|
-
// minW should be at least 1 (TODO propTypes validation?)
|
|
629
|
-
w = clamp(w, Math.max(minW, 1), maxW);
|
|
630
|
-
h = clamp(h, minH, maxH);
|
|
631
|
-
|
|
632
|
-
handler.call(this, i, w, h, { e, node, size: updatedSize, handle });
|
|
633
|
-
}
|
|
634
|
-
|
|
635
|
-
render(): ReactNode {
|
|
636
|
-
const {
|
|
637
|
-
x,
|
|
638
|
-
y,
|
|
639
|
-
w,
|
|
640
|
-
h,
|
|
641
|
-
isDraggable,
|
|
642
|
-
isResizable,
|
|
643
|
-
droppingPosition,
|
|
644
|
-
useCSSTransforms
|
|
645
|
-
} = this.props;
|
|
646
|
-
|
|
647
|
-
const pos = calcGridItemPosition(
|
|
648
|
-
this.getPositionParams(),
|
|
649
|
-
x,
|
|
650
|
-
y,
|
|
651
|
-
w,
|
|
652
|
-
h,
|
|
653
|
-
this.state
|
|
654
|
-
);
|
|
655
|
-
const child = React.Children.only(this.props.children);
|
|
656
|
-
|
|
657
|
-
// Create the child element. We clone the existing element but modify its className and style.
|
|
658
|
-
let newChild = React.cloneElement(child, {
|
|
659
|
-
ref: this.elementRef,
|
|
660
|
-
className: clsx(
|
|
661
|
-
"react-grid-item",
|
|
662
|
-
child.props.className,
|
|
663
|
-
this.props.className,
|
|
664
|
-
{
|
|
665
|
-
static: this.props.static,
|
|
666
|
-
resizing: Boolean(this.state.resizing),
|
|
667
|
-
"react-draggable": isDraggable,
|
|
668
|
-
"react-draggable-dragging": Boolean(this.state.dragging),
|
|
669
|
-
dropping: Boolean(droppingPosition),
|
|
670
|
-
cssTransforms: useCSSTransforms
|
|
671
|
-
}
|
|
672
|
-
),
|
|
673
|
-
// We can set the width and height on the child, but unfortunately we can't set the position.
|
|
674
|
-
style: {
|
|
675
|
-
...this.props.style,
|
|
676
|
-
...child.props.style,
|
|
677
|
-
...this.createStyle(pos)
|
|
678
|
-
}
|
|
679
|
-
});
|
|
680
|
-
|
|
681
|
-
// Resizable support. This is usually on but the user can toggle it off.
|
|
682
|
-
newChild = this.mixinResizable(newChild, pos, isResizable);
|
|
683
|
-
|
|
684
|
-
// Draggable support. This is always on, except for with placeholders.
|
|
685
|
-
newChild = this.mixinDraggable(newChild, isDraggable);
|
|
686
|
-
|
|
687
|
-
return newChild;
|
|
688
|
-
}
|
|
689
|
-
}
|