publ-echo 0.0.1
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 +29 -0
- package/bin/cli.js +8 -0
- package/bitbucket-pipelines.yml +35 -0
- package/package.json +51 -0
- package/public/favicon.ico +0 -0
- package/public/index.html +43 -0
- package/public/logo192.png +0 -0
- package/public/logo512.png +0 -0
- package/public/manifest.json +25 -0
- package/public/robots.txt +3 -0
- package/src/App.tsx +28 -0
- package/src/examples/ReactGridLayout/ReactGridLayoutShowcase01.tsx +80 -0
- package/src/examples/ReactGridLayout/index.ts +1 -0
- package/src/examples/ResponsiveGridLayout/ResponsiveGridLayoutShowcase01.tsx +114 -0
- package/src/examples/ResponsiveGridLayout/index.ts +1 -0
- package/src/examples/index.ts +2 -0
- package/src/examples/utils.ts +15 -0
- package/src/index.tsx +21 -0
- package/src/lib/Draggable/Draggable.tsx +303 -0
- package/src/lib/Draggable/DraggableCore.tsx +352 -0
- package/src/lib/Draggable/constants.ts +12 -0
- package/src/lib/Draggable/index.ts +2 -0
- package/src/lib/Draggable/types.ts +74 -0
- package/src/lib/Draggable/utils/domHelpers.ts +284 -0
- package/src/lib/Draggable/utils/getPrefix.ts +42 -0
- package/src/lib/Draggable/utils/positionHelpers.ts +49 -0
- package/src/lib/Draggable/utils/types.ts +41 -0
- package/src/lib/Draggable/utils/validationHelpers.ts +23 -0
- package/src/lib/GridItem/GridItem.tsx +493 -0
- package/src/lib/GridItem/index.ts +1 -0
- package/src/lib/GridItem/types.ts +121 -0
- package/src/lib/GridItem/utils/calculateUtils.ts +173 -0
- package/src/lib/GridLayoutEditor/ReactGridLayout.tsx +662 -0
- package/src/lib/GridLayoutEditor/ResponsiveGridLayout.tsx +204 -0
- package/src/lib/GridLayoutEditor/index.ts +9 -0
- package/src/lib/GridLayoutEditor/styles/styles.css +133 -0
- package/src/lib/GridLayoutEditor/types.ts +199 -0
- package/src/lib/GridLayoutEditor/utils/renderHelpers.ts +737 -0
- package/src/lib/GridLayoutEditor/utils/responsiveUtils.ts +111 -0
- package/src/lib/PreviewGLE/ReactGridLayoutPreview.tsx +46 -0
- package/src/lib/PreviewGLE/ResponsiveGridLayoutPreview.tsx +54 -0
- package/src/lib/PreviewGLE/index.ts +2 -0
- package/src/lib/Resizable/Resizable.tsx +323 -0
- package/src/lib/Resizable/ResizableBox.tsx +109 -0
- package/src/lib/Resizable/index.ts +1 -0
- package/src/lib/Resizable/styles/styles.css +76 -0
- package/src/lib/Resizable/types.ts +96 -0
- package/src/lib/Resizable/utils/cloneElement.ts +15 -0
- package/src/lib/components/WidthProvider.tsx +71 -0
- package/src/lib/components/index.ts +1 -0
- package/src/lib/components/types.ts +19 -0
- package/src/lib/index.ts +4 -0
- package/src/react-app-env.d.ts +1 -0
- package/src/reportWebVitals.ts +15 -0
- package/src/setupTests.ts +5 -0
- package/src/utils/types.ts +3 -0
- package/tsconfig.json +26 -0
|
@@ -0,0 +1,493 @@
|
|
|
1
|
+
import React, { ReactElement, useRef, useState } from "react";
|
|
2
|
+
import {
|
|
3
|
+
GridItemProps,
|
|
4
|
+
PartialPosition,
|
|
5
|
+
ReactDraggableCallbackData,
|
|
6
|
+
ResizeEventType,
|
|
7
|
+
ResizeHandlerNameType,
|
|
8
|
+
} from "./types";
|
|
9
|
+
import { DraggableCore } from "../Draggable";
|
|
10
|
+
import classNames from "classnames";
|
|
11
|
+
import {
|
|
12
|
+
calcGridColWidth,
|
|
13
|
+
calcGridItemPosition,
|
|
14
|
+
calcGridItemWHPx,
|
|
15
|
+
calcWH,
|
|
16
|
+
calcXY,
|
|
17
|
+
clamp,
|
|
18
|
+
resolveRowHeight,
|
|
19
|
+
} from "./utils/calculateUtils";
|
|
20
|
+
import { Position, PositionParams } from "../GridLayoutEditor/types";
|
|
21
|
+
import {
|
|
22
|
+
perc,
|
|
23
|
+
setTopLeft,
|
|
24
|
+
setTransform,
|
|
25
|
+
} from "../GridLayoutEditor/utils/renderHelpers";
|
|
26
|
+
import { Resizable } from "../Resizable";
|
|
27
|
+
import { PropsWithChildren } from "../../utils/types";
|
|
28
|
+
import { ResizeCallbackData } from "../Resizable/types";
|
|
29
|
+
import { DraggableEvent } from "../Draggable/types";
|
|
30
|
+
|
|
31
|
+
const GridItem = ({ children, ...props }: PropsWithChildren<GridItemProps>) => {
|
|
32
|
+
const {
|
|
33
|
+
resizeHandle,
|
|
34
|
+
cols,
|
|
35
|
+
isDraggable,
|
|
36
|
+
transformScale = 1,
|
|
37
|
+
isResizable,
|
|
38
|
+
useCSSTransforms,
|
|
39
|
+
className,
|
|
40
|
+
cancel = "",
|
|
41
|
+
handle = "",
|
|
42
|
+
x,
|
|
43
|
+
y,
|
|
44
|
+
z,
|
|
45
|
+
w,
|
|
46
|
+
h,
|
|
47
|
+
minH = 1,
|
|
48
|
+
minW = 1,
|
|
49
|
+
maxH = Infinity,
|
|
50
|
+
maxW = Infinity,
|
|
51
|
+
i,
|
|
52
|
+
isHiddenVisibility = false,
|
|
53
|
+
containerWidth,
|
|
54
|
+
} = props;
|
|
55
|
+
|
|
56
|
+
const [resizing, setResizing] = useState<{
|
|
57
|
+
width: number;
|
|
58
|
+
height: number;
|
|
59
|
+
top: number;
|
|
60
|
+
left: number;
|
|
61
|
+
}>();
|
|
62
|
+
const [dragging, setDragging] = useState<{ top: number; left: number }>();
|
|
63
|
+
const [dragStart, setDragStart] = useState<{ x: number; y: number }>();
|
|
64
|
+
|
|
65
|
+
const [isDragging, setIsDragging] = useState(false);
|
|
66
|
+
const [isResizing, setIsResizing] = useState(false);
|
|
67
|
+
|
|
68
|
+
const elementRef = useRef<HTMLDivElement>(null);
|
|
69
|
+
|
|
70
|
+
// const moveDroppingItem = (prevProps: GridItemProps) => {
|
|
71
|
+
// const { droppingPosition } = props;
|
|
72
|
+
// if (!droppingPosition) return;
|
|
73
|
+
// const node = elementRef.current;
|
|
74
|
+
// // Can't find DOM node (are we unmounted?)
|
|
75
|
+
// if (!node) return;
|
|
76
|
+
|
|
77
|
+
// const prevDroppingPosition = prevProps.droppingPosition || {
|
|
78
|
+
// left: 0,
|
|
79
|
+
// top: 0,
|
|
80
|
+
// };
|
|
81
|
+
// const shouldDrag =
|
|
82
|
+
// (dragging && droppingPosition.left !== prevDroppingPosition.left) ||
|
|
83
|
+
// droppingPosition.top !== prevDroppingPosition.top;
|
|
84
|
+
|
|
85
|
+
// if (!dragging) {
|
|
86
|
+
// onDragStart(droppingPosition.e, {
|
|
87
|
+
// node,
|
|
88
|
+
// deltaX: droppingPosition.left,
|
|
89
|
+
// deltaY: droppingPosition.top,
|
|
90
|
+
// });
|
|
91
|
+
// } else if (shouldDrag) {
|
|
92
|
+
// const deltaX = droppingPosition.left - dragging.left;
|
|
93
|
+
// const deltaY = droppingPosition.top - dragging.top;
|
|
94
|
+
|
|
95
|
+
// onDrag(droppingPosition.e, {
|
|
96
|
+
// node,
|
|
97
|
+
// deltaX,
|
|
98
|
+
// deltaY,
|
|
99
|
+
// });
|
|
100
|
+
// }
|
|
101
|
+
// };
|
|
102
|
+
|
|
103
|
+
const getPositionParams = (prop: GridItemProps = props): PositionParams => {
|
|
104
|
+
return {
|
|
105
|
+
cols: prop.cols,
|
|
106
|
+
containerPadding: prop.containerPadding,
|
|
107
|
+
containerWidth: prop.containerWidth,
|
|
108
|
+
margin: prop.margin,
|
|
109
|
+
maxRows: prop.maxRows,
|
|
110
|
+
rowHeight: prop.rowHeight,
|
|
111
|
+
};
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
const createStyle = (
|
|
115
|
+
pos: Position
|
|
116
|
+
): { [key: string]: string | undefined | number } => {
|
|
117
|
+
const { usePercentages, containerWidth, useCSSTransforms } = props;
|
|
118
|
+
let style;
|
|
119
|
+
|
|
120
|
+
if (useCSSTransforms) {
|
|
121
|
+
style = setTransform(pos);
|
|
122
|
+
} else {
|
|
123
|
+
style = setTopLeft(pos);
|
|
124
|
+
|
|
125
|
+
if (usePercentages) {
|
|
126
|
+
if (containerWidth == null) {
|
|
127
|
+
throw new Error("Container width is missing!");
|
|
128
|
+
}
|
|
129
|
+
style.left = perc(pos.left / containerWidth);
|
|
130
|
+
style.width = perc(pos.width / containerWidth);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return style;
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Mix a Draggable instance into a child.
|
|
139
|
+
* @param {Element} child Child element.
|
|
140
|
+
* @return {Element} Child wrapped in Draggable.
|
|
141
|
+
*/
|
|
142
|
+
const mixinDraggable = (child: ReactElement<any>, isDraggable: boolean) => {
|
|
143
|
+
return (
|
|
144
|
+
<DraggableCore
|
|
145
|
+
disabled={!isDraggable}
|
|
146
|
+
onStart={onDragStart}
|
|
147
|
+
onDrag={onDrag}
|
|
148
|
+
onStop={onDragStop}
|
|
149
|
+
handle={handle}
|
|
150
|
+
cancel={".react-resizable-handle" + (cancel ? "," + cancel : "")}
|
|
151
|
+
scale={transformScale}
|
|
152
|
+
nodeRef={elementRef}
|
|
153
|
+
>
|
|
154
|
+
{child}
|
|
155
|
+
</DraggableCore>
|
|
156
|
+
);
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Mix a Resizable instance into a child.
|
|
161
|
+
* @param {Element} child Child element.
|
|
162
|
+
* @param {Object} position Position object (pixel values)
|
|
163
|
+
* @return {Element} Child wrapped in Resizable.
|
|
164
|
+
*/
|
|
165
|
+
const mixinResizable = (
|
|
166
|
+
child: ReactElement<any>,
|
|
167
|
+
position: Position,
|
|
168
|
+
isResizable: boolean
|
|
169
|
+
): ReactElement<any> => {
|
|
170
|
+
const positionParams = getPositionParams();
|
|
171
|
+
|
|
172
|
+
// const maxWidth = calcGridItemPosition(
|
|
173
|
+
// positionParams,
|
|
174
|
+
// x,
|
|
175
|
+
// y,
|
|
176
|
+
// z,
|
|
177
|
+
// cols - x, // TODO - 수정 필요
|
|
178
|
+
// h
|
|
179
|
+
// ).width;
|
|
180
|
+
|
|
181
|
+
const mins = calcGridItemPosition(positionParams, x, y, z, minW, minH);
|
|
182
|
+
const maxes = calcGridItemPosition(positionParams, x, y, z, maxW, maxH);
|
|
183
|
+
const minConstraints = [mins.width, mins.height] as [number, number];
|
|
184
|
+
const maxConstraints = [
|
|
185
|
+
Math.min(maxes.width, containerWidth),
|
|
186
|
+
Math.min(maxes.height, Infinity),
|
|
187
|
+
] as [number, number];
|
|
188
|
+
|
|
189
|
+
return (
|
|
190
|
+
<Resizable
|
|
191
|
+
draggableOpts={{
|
|
192
|
+
disabled: !isResizable,
|
|
193
|
+
}}
|
|
194
|
+
className={isResizable ? undefined : "react-resizable-hide"}
|
|
195
|
+
width={position.width}
|
|
196
|
+
height={position.height}
|
|
197
|
+
top={position.top}
|
|
198
|
+
left={position.left}
|
|
199
|
+
minConstraints={minConstraints}
|
|
200
|
+
maxConstraints={maxConstraints}
|
|
201
|
+
onResizeStop={onResizeStop}
|
|
202
|
+
onResizeStart={onResizeStart}
|
|
203
|
+
onResize={onResize}
|
|
204
|
+
transformScale={transformScale}
|
|
205
|
+
resizeHandles={props.resizeHandles}
|
|
206
|
+
handle={resizeHandle}
|
|
207
|
+
>
|
|
208
|
+
{child}
|
|
209
|
+
</Resizable>
|
|
210
|
+
);
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* onDragStart event handler
|
|
215
|
+
* @param {Event} e event data
|
|
216
|
+
* @param {Object} callbackData an object with node, delta and position information
|
|
217
|
+
*/
|
|
218
|
+
const onDragStart = (
|
|
219
|
+
e: DraggableEvent,
|
|
220
|
+
{ node, deltaX, deltaY }: ReactDraggableCallbackData
|
|
221
|
+
) => {
|
|
222
|
+
const newPosition: PartialPosition = { top: 0, left: 0 };
|
|
223
|
+
|
|
224
|
+
const { offsetParent } = node;
|
|
225
|
+
if (!offsetParent) return;
|
|
226
|
+
|
|
227
|
+
const parentRect = offsetParent.getBoundingClientRect();
|
|
228
|
+
const clientRect = node.getBoundingClientRect();
|
|
229
|
+
const cLeft = clientRect.left / transformScale;
|
|
230
|
+
const pLeft = parentRect.left / transformScale;
|
|
231
|
+
const cTop = clientRect.top / transformScale;
|
|
232
|
+
const pTop = parentRect.top / transformScale;
|
|
233
|
+
|
|
234
|
+
newPosition.left = cLeft - pLeft + offsetParent.scrollLeft;
|
|
235
|
+
newPosition.top = cTop - pTop + offsetParent.scrollTop;
|
|
236
|
+
|
|
237
|
+
setDragging(newPosition);
|
|
238
|
+
|
|
239
|
+
const { x, y } = calcXY(
|
|
240
|
+
getPositionParams(),
|
|
241
|
+
newPosition.top,
|
|
242
|
+
newPosition.left,
|
|
243
|
+
props.w!,
|
|
244
|
+
props.h!
|
|
245
|
+
);
|
|
246
|
+
|
|
247
|
+
setDragStart({ x, y });
|
|
248
|
+
props.onDragStart &&
|
|
249
|
+
props.onDragStart(props.i, x, y, { e, node, newPosition });
|
|
250
|
+
};
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* onDrag event handler
|
|
254
|
+
* @param {Event} e event data
|
|
255
|
+
* @param {Object} callbackData an object with node, delta and position information
|
|
256
|
+
*/
|
|
257
|
+
const onDrag = (
|
|
258
|
+
e: DraggableEvent,
|
|
259
|
+
{ node, deltaX, deltaY }: ReactDraggableCallbackData
|
|
260
|
+
) => {
|
|
261
|
+
if (!dragging) {
|
|
262
|
+
throw new Error("onDrag called before onDragStart.");
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
setIsDragging(true);
|
|
266
|
+
|
|
267
|
+
let top = dragging.top + deltaY;
|
|
268
|
+
let left = dragging.left + deltaX;
|
|
269
|
+
|
|
270
|
+
const { isBounded, i, w, h, containerWidth } = props;
|
|
271
|
+
const positionParams = getPositionParams();
|
|
272
|
+
|
|
273
|
+
if (isBounded) {
|
|
274
|
+
const { offsetParent } = node;
|
|
275
|
+
|
|
276
|
+
if (offsetParent) {
|
|
277
|
+
const { margin, rowHeight } = props;
|
|
278
|
+
const colWidth = calcGridColWidth(positionParams);
|
|
279
|
+
|
|
280
|
+
let rowHeightNumber = resolveRowHeight(rowHeight, colWidth);
|
|
281
|
+
|
|
282
|
+
const bottomBoundary =
|
|
283
|
+
offsetParent.clientHeight -
|
|
284
|
+
calcGridItemWHPx(h, rowHeightNumber, margin[1]);
|
|
285
|
+
top = clamp(top, 0, bottomBoundary);
|
|
286
|
+
|
|
287
|
+
const rightBoundary =
|
|
288
|
+
containerWidth - calcGridItemWHPx(w, colWidth, margin[0]);
|
|
289
|
+
left = clamp(left, 0, rightBoundary);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
const newPosition: PartialPosition = { top, left };
|
|
294
|
+
|
|
295
|
+
setDragging(newPosition);
|
|
296
|
+
|
|
297
|
+
const { x, y } = calcXY(positionParams, top, left, w, h);
|
|
298
|
+
|
|
299
|
+
props.onDrag && props.onDrag(i, x, y, { e, node, newPosition });
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* onDragStop event handler
|
|
304
|
+
* @param {Event} e event data
|
|
305
|
+
* @param {Object} callbackData an object with node, delta and position information
|
|
306
|
+
*/
|
|
307
|
+
const onDragStop = (
|
|
308
|
+
e: DraggableEvent,
|
|
309
|
+
{ node, deltaX, deltaY }: ReactDraggableCallbackData
|
|
310
|
+
) => {
|
|
311
|
+
if (!dragging) {
|
|
312
|
+
throw new Error("onDragEnd called before onDragStart.");
|
|
313
|
+
}
|
|
314
|
+
const { w, h, i } = props;
|
|
315
|
+
const { left, top } = dragging;
|
|
316
|
+
const { x, y } = calcXY(getPositionParams(), top, left, w, h);
|
|
317
|
+
const newPosition: PartialPosition = { top, left };
|
|
318
|
+
|
|
319
|
+
let change = dragStart?.x !== x || dragStart?.y !== y;
|
|
320
|
+
|
|
321
|
+
setDragging(undefined);
|
|
322
|
+
setDragStart(undefined);
|
|
323
|
+
setIsDragging(false);
|
|
324
|
+
|
|
325
|
+
props.onDragStop &&
|
|
326
|
+
props.onDragStop(i, x, y, { e, node, newPosition, change });
|
|
327
|
+
};
|
|
328
|
+
|
|
329
|
+
const getResizableXYPosition = (
|
|
330
|
+
handle: ResizeCallbackData["handle"],
|
|
331
|
+
width: number,
|
|
332
|
+
height: number,
|
|
333
|
+
prevW: number,
|
|
334
|
+
prevH: number
|
|
335
|
+
) => {
|
|
336
|
+
let newX = x;
|
|
337
|
+
let newY = y;
|
|
338
|
+
|
|
339
|
+
if (handle === "nw") {
|
|
340
|
+
// NOTE - nw left(X)와 top(Y) 둘다 변경
|
|
341
|
+
if (width > prevW) {
|
|
342
|
+
newX = x - (width - prevW);
|
|
343
|
+
} else {
|
|
344
|
+
newX = x + (prevW - width);
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
if (height > prevH) {
|
|
348
|
+
newY = y - (height - prevH);
|
|
349
|
+
} else {
|
|
350
|
+
newY = y + (prevH - height);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
if (handle === "n" || handle === "ne") {
|
|
355
|
+
// NOTE - n, ne left(X) 고정 & top(Y) 변경
|
|
356
|
+
if (height > prevH) {
|
|
357
|
+
newY = y - (height - prevH);
|
|
358
|
+
} else {
|
|
359
|
+
newY = y + (prevH - height);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
if (handle === "w" || handle === "sw") {
|
|
364
|
+
// NOTE - s, sw left(X) 변경 top(Y) 고정
|
|
365
|
+
if (width > prevW) {
|
|
366
|
+
newX = x - (width - prevW);
|
|
367
|
+
} else {
|
|
368
|
+
newX = x + (prevW - width);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
return { newX, newY };
|
|
373
|
+
};
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* onResizeStart event handler
|
|
377
|
+
* @param {ResizeEventType} e event data
|
|
378
|
+
* @param {Object} callbackData an object with node and size information
|
|
379
|
+
*/
|
|
380
|
+
const onResizeStart: (
|
|
381
|
+
e: ResizeEventType,
|
|
382
|
+
data: ResizeCallbackData
|
|
383
|
+
) => void = (e, callbackData) => {
|
|
384
|
+
onResizeHandler(e, callbackData, "onResizeStart");
|
|
385
|
+
};
|
|
386
|
+
|
|
387
|
+
/**
|
|
388
|
+
* onResize event handler
|
|
389
|
+
* @param {ResizeEventType} e event data
|
|
390
|
+
* @param {Object} callbackData an object with node and size information
|
|
391
|
+
*/
|
|
392
|
+
const onResize: (e: ResizeEventType, data: ResizeCallbackData) => void = (
|
|
393
|
+
e,
|
|
394
|
+
callbackData
|
|
395
|
+
) => {
|
|
396
|
+
setIsResizing(true);
|
|
397
|
+
onResizeHandler(e, callbackData, "onResize");
|
|
398
|
+
};
|
|
399
|
+
|
|
400
|
+
/**
|
|
401
|
+
* onResizeStop event handler
|
|
402
|
+
* @param {ResizeEventType} e event data
|
|
403
|
+
* @param {Object} callbackData an object with node and size information
|
|
404
|
+
*/
|
|
405
|
+
const onResizeStop: (e: ResizeEventType, data: ResizeCallbackData) => void = (
|
|
406
|
+
e,
|
|
407
|
+
callbackData
|
|
408
|
+
) => {
|
|
409
|
+
setIsResizing(false);
|
|
410
|
+
onResizeHandler(e, callbackData, "onResizeStop");
|
|
411
|
+
};
|
|
412
|
+
|
|
413
|
+
/**
|
|
414
|
+
* Wrapper around drag events to provide more useful data.
|
|
415
|
+
* All drag events call the function with the given handler name,
|
|
416
|
+
* with the signature (index, x, y).
|
|
417
|
+
*
|
|
418
|
+
* @param {String} handlerName Handler name to wrap.
|
|
419
|
+
* @return {Function} Handler function.
|
|
420
|
+
*/
|
|
421
|
+
const onResizeHandler = (
|
|
422
|
+
e: ResizeEventType,
|
|
423
|
+
{ node, size, handle }: ResizeCallbackData,
|
|
424
|
+
handlerName: ResizeHandlerNameType
|
|
425
|
+
): void => {
|
|
426
|
+
const handler = props[handlerName];
|
|
427
|
+
|
|
428
|
+
if (!handler) return;
|
|
429
|
+
|
|
430
|
+
const { w: prevW, h: prevH } = props;
|
|
431
|
+
|
|
432
|
+
// Get new XY
|
|
433
|
+
let { w, h } = calcWH(
|
|
434
|
+
getPositionParams(),
|
|
435
|
+
size,
|
|
436
|
+
x,
|
|
437
|
+
y,
|
|
438
|
+
handle,
|
|
439
|
+
prevW,
|
|
440
|
+
prevH
|
|
441
|
+
);
|
|
442
|
+
|
|
443
|
+
// minW should be at least 1
|
|
444
|
+
// minW = Math.max(minW, 1);
|
|
445
|
+
|
|
446
|
+
// maxW should be at most (cols - x)
|
|
447
|
+
// maxW = Math.min(maxW, cols - x);
|
|
448
|
+
|
|
449
|
+
w = clamp(w, minW, maxW);
|
|
450
|
+
h = clamp(h, minH, maxH);
|
|
451
|
+
|
|
452
|
+
setResizing(handlerName === "onResizeStop" ? undefined : size);
|
|
453
|
+
|
|
454
|
+
const { newX, newY } = getResizableXYPosition(handle, w, h, prevW, prevH);
|
|
455
|
+
|
|
456
|
+
handler(i, w, h, { e, node, size }, newX, newY);
|
|
457
|
+
};
|
|
458
|
+
|
|
459
|
+
const pos = calcGridItemPosition(getPositionParams(), x, y, z, w, h, {
|
|
460
|
+
dragging,
|
|
461
|
+
resizing,
|
|
462
|
+
});
|
|
463
|
+
|
|
464
|
+
const child = React.Children.only(children);
|
|
465
|
+
|
|
466
|
+
let newChild = React.cloneElement(child, {
|
|
467
|
+
ref: elementRef,
|
|
468
|
+
className: classNames("react-grid-item", child.props.className, className, {
|
|
469
|
+
static: props.static,
|
|
470
|
+
isResizing:
|
|
471
|
+
Boolean(resizing) && Boolean(isResizing) && Boolean(isHiddenVisibility),
|
|
472
|
+
resizing: Boolean(resizing),
|
|
473
|
+
"react-draggable": isDraggable,
|
|
474
|
+
isDragging:
|
|
475
|
+
Boolean(isDragging) && Boolean(dragging) && Boolean(isHiddenVisibility),
|
|
476
|
+
"react-draggable-dragging": Boolean(dragging),
|
|
477
|
+
// dropping: Boolean(droppingPosition),
|
|
478
|
+
cssTransforms: useCSSTransforms,
|
|
479
|
+
}),
|
|
480
|
+
style: {
|
|
481
|
+
...props.style,
|
|
482
|
+
...child.props.style,
|
|
483
|
+
...createStyle(pos),
|
|
484
|
+
},
|
|
485
|
+
});
|
|
486
|
+
|
|
487
|
+
newChild = mixinResizable(newChild, pos, isResizable);
|
|
488
|
+
newChild = mixinDraggable(newChild, isDraggable);
|
|
489
|
+
|
|
490
|
+
return newChild;
|
|
491
|
+
};
|
|
492
|
+
|
|
493
|
+
export default GridItem;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as GridItem } from "./GridItem";
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { DragEvent, SyntheticEvent } from "react";
|
|
2
|
+
import { RowHeight } from "../GridLayoutEditor/types";
|
|
3
|
+
import { ResizeHandleAxis, ResizeHandleType } from "../Resizable/types";
|
|
4
|
+
|
|
5
|
+
export type PartialPosition = { top: number; left: number };
|
|
6
|
+
|
|
7
|
+
export type ResizeEventType = SyntheticEvent | MouseEvent | TouchEvent;
|
|
8
|
+
|
|
9
|
+
export type GridResizeEvent = {
|
|
10
|
+
e: ResizeEventType;
|
|
11
|
+
node: HTMLElement;
|
|
12
|
+
size: Size;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export type GridDragEvent = {
|
|
16
|
+
e: ResizeEventType;
|
|
17
|
+
node: HTMLElement;
|
|
18
|
+
newPosition: PartialPosition;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export type GridItemCallback<Data extends GridDragEvent | GridResizeEvent> = (
|
|
22
|
+
i: string,
|
|
23
|
+
x: number,
|
|
24
|
+
y: number,
|
|
25
|
+
data: Data
|
|
26
|
+
) => void;
|
|
27
|
+
|
|
28
|
+
type ResizeGridItemCallback<Data extends GridDragEvent | GridResizeEvent> = (
|
|
29
|
+
i: string,
|
|
30
|
+
w: number,
|
|
31
|
+
h: number,
|
|
32
|
+
data: Data,
|
|
33
|
+
x: number,
|
|
34
|
+
y: number
|
|
35
|
+
) => void;
|
|
36
|
+
|
|
37
|
+
export type GridDragStopEvent = GridDragEvent & { change: boolean };
|
|
38
|
+
|
|
39
|
+
export type Size = { width: number; height: number; top: number; left: number };
|
|
40
|
+
|
|
41
|
+
export type GridItemStateType = {
|
|
42
|
+
resizing?: { width: number; height: number };
|
|
43
|
+
dragging?: { top: number; left: number };
|
|
44
|
+
className: string;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export type GridItemProps = {
|
|
48
|
+
margin: [number, number];
|
|
49
|
+
containerPadding: [number, number];
|
|
50
|
+
rowHeight: RowHeight;
|
|
51
|
+
maxRows: number;
|
|
52
|
+
isDraggable: boolean;
|
|
53
|
+
isResizable: boolean;
|
|
54
|
+
isBounded: boolean;
|
|
55
|
+
static?: boolean;
|
|
56
|
+
useCSSTransforms?: boolean;
|
|
57
|
+
usePercentages?: boolean;
|
|
58
|
+
transformScale?: number;
|
|
59
|
+
droppingPosition?: DroppingPosition;
|
|
60
|
+
cols: number;
|
|
61
|
+
containerWidth: number;
|
|
62
|
+
className?: string;
|
|
63
|
+
style?: Object;
|
|
64
|
+
cancel?: string;
|
|
65
|
+
handle?: string;
|
|
66
|
+
|
|
67
|
+
minW?: number;
|
|
68
|
+
maxW?: number;
|
|
69
|
+
minH?: number;
|
|
70
|
+
maxH?: number;
|
|
71
|
+
|
|
72
|
+
x: number;
|
|
73
|
+
y: number;
|
|
74
|
+
z: number;
|
|
75
|
+
w: number;
|
|
76
|
+
h: number;
|
|
77
|
+
i: string;
|
|
78
|
+
|
|
79
|
+
resizeHandles?: ResizeHandleAxis[];
|
|
80
|
+
resizeHandle?: ResizeHandleType;
|
|
81
|
+
|
|
82
|
+
onDrag?: GridItemCallback<GridDragEvent>;
|
|
83
|
+
onDragStart?: GridItemCallback<GridDragEvent>;
|
|
84
|
+
onDragStop?: GridItemCallback<GridDragStopEvent>;
|
|
85
|
+
onResize?: ResizeGridItemCallback<GridResizeEvent>;
|
|
86
|
+
onResizeStart?: ResizeGridItemCallback<GridResizeEvent>;
|
|
87
|
+
onResizeStop?: ResizeGridItemCallback<GridResizeEvent>;
|
|
88
|
+
isHiddenVisibility?: boolean;
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
export type GridItemDefaultProps = {
|
|
92
|
+
className: string;
|
|
93
|
+
cancel: string;
|
|
94
|
+
handle: string;
|
|
95
|
+
minH: number;
|
|
96
|
+
minW: number;
|
|
97
|
+
maxH: number;
|
|
98
|
+
maxW: number;
|
|
99
|
+
transformScale: number;
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
export type DroppingPosition = {
|
|
103
|
+
left: number;
|
|
104
|
+
top: number;
|
|
105
|
+
e: DragEvent<HTMLDivElement>;
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
export type ReactDraggableCallbackData = {
|
|
109
|
+
node: HTMLElement;
|
|
110
|
+
x: number;
|
|
111
|
+
y: number;
|
|
112
|
+
deltaX: number;
|
|
113
|
+
deltaY: number;
|
|
114
|
+
lastX: number;
|
|
115
|
+
lastY: number;
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
export type ResizeHandlerNameType =
|
|
119
|
+
| "onResizeStart"
|
|
120
|
+
| "onResize"
|
|
121
|
+
| "onResizeStop";
|