publ-echo 0.0.4 → 0.0.6
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/dist/App.d.ts +2 -0
- package/dist/App.js +18 -0
- package/dist/examples/ReactGridLayout/ReactGridLayoutShowcase01.d.ts +2 -0
- package/dist/examples/ReactGridLayout/ReactGridLayoutShowcase01.js +57 -0
- package/dist/examples/ReactGridLayout/index.js +1 -0
- package/dist/examples/ResponsiveGridLayout/ResponsiveGridLayoutShowcase01.d.ts +2 -0
- package/dist/examples/ResponsiveGridLayout/ResponsiveGridLayoutShowcase01.js +69 -0
- package/dist/examples/ResponsiveGridLayout/index.js +1 -0
- package/dist/examples/index.js +2 -0
- package/dist/examples/utils.d.ts +8 -0
- package/dist/examples/utils.js +14 -0
- package/dist/index.d.ts +1 -0
- package/{src/index.tsx → dist/index.js} +3 -12
- package/dist/lib/Draggable/Draggable.d.ts +17 -0
- package/dist/lib/Draggable/Draggable.js +192 -0
- package/dist/lib/Draggable/DraggableCore.d.ts +5 -0
- package/dist/lib/Draggable/DraggableCore.js +266 -0
- package/dist/lib/Draggable/constants.d.ts +12 -0
- package/dist/lib/Draggable/constants.js +12 -0
- package/dist/lib/Draggable/index.js +2 -0
- package/dist/lib/Draggable/types.d.ts +55 -0
- package/dist/lib/Draggable/types.js +1 -0
- package/dist/lib/Draggable/utils/domHelpers.d.ts +22 -0
- package/dist/lib/Draggable/utils/domHelpers.js +222 -0
- package/dist/lib/Draggable/utils/getPrefix.d.ts +5 -0
- package/dist/lib/Draggable/utils/getPrefix.js +41 -0
- package/dist/lib/Draggable/utils/positionHelpers.d.ts +7 -0
- package/dist/lib/Draggable/utils/positionHelpers.js +32 -0
- package/dist/lib/Draggable/utils/types.d.ts +30 -0
- package/dist/lib/Draggable/utils/types.js +1 -0
- package/dist/lib/Draggable/utils/validationHelpers.d.ts +4 -0
- package/dist/lib/Draggable/utils/validationHelpers.js +16 -0
- package/dist/lib/GridItem/GridItem.d.ts +5 -0
- package/dist/lib/GridItem/GridItem.js +324 -0
- package/dist/lib/GridItem/index.js +1 -0
- package/dist/lib/GridItem/types.d.ts +105 -0
- package/dist/lib/GridItem/types.js +1 -0
- package/dist/lib/GridItem/utils/calculateUtils.d.ts +30 -0
- package/dist/lib/GridItem/utils/calculateUtils.js +108 -0
- package/dist/lib/GridLayoutEditor/ReactGridLayout.d.ts +5 -0
- package/dist/lib/GridLayoutEditor/ReactGridLayout.js +423 -0
- package/dist/lib/GridLayoutEditor/ResponsiveGridLayout.d.ts +4 -0
- package/dist/lib/GridLayoutEditor/ResponsiveGridLayout.js +117 -0
- package/dist/lib/GridLayoutEditor/index.d.ts +3 -0
- package/dist/lib/GridLayoutEditor/index.js +2 -0
- package/dist/lib/GridLayoutEditor/types.d.ts +129 -0
- package/dist/lib/GridLayoutEditor/types.js +1 -0
- package/dist/lib/GridLayoutEditor/utils/renderHelpers.d.ts +164 -0
- package/dist/lib/GridLayoutEditor/utils/renderHelpers.js +591 -0
- package/dist/lib/GridLayoutEditor/utils/responsiveUtils.d.ts +26 -0
- package/dist/lib/GridLayoutEditor/utils/responsiveUtils.js +77 -0
- package/dist/lib/PreviewGLE/ReactGridLayoutPreview.d.ts +7 -0
- package/dist/lib/PreviewGLE/ReactGridLayoutPreview.js +35 -0
- package/dist/lib/PreviewGLE/ResponsiveGridLayoutPreview.d.ts +9 -0
- package/dist/lib/PreviewGLE/ResponsiveGridLayoutPreview.js +38 -0
- package/dist/lib/PreviewGLE/index.js +2 -0
- package/dist/lib/Resizable/Resizable.d.ts +7 -0
- package/dist/lib/Resizable/Resizable.js +216 -0
- package/dist/lib/Resizable/ResizableBox.d.ts +7 -0
- package/dist/lib/Resizable/ResizableBox.js +57 -0
- package/dist/lib/Resizable/index.js +1 -0
- package/dist/lib/Resizable/types.d.ts +63 -0
- package/dist/lib/Resizable/types.js +1 -0
- package/dist/lib/Resizable/utils/cloneElement.d.ts +2 -0
- package/dist/lib/Resizable/utils/cloneElement.js +21 -0
- package/dist/lib/components/WidthProvider.d.ts +9 -0
- package/dist/lib/components/WidthProvider.js +55 -0
- package/dist/lib/components/index.js +1 -0
- package/dist/lib/components/types.d.ts +13 -0
- package/dist/lib/components/types.js +1 -0
- package/dist/lib/index.js +5 -0
- package/dist/reportWebVitals.d.ts +3 -0
- package/dist/reportWebVitals.js +13 -0
- package/dist/setupTests.d.ts +1 -0
- package/dist/utils/types.d.ts +4 -0
- package/dist/utils/types.js +1 -0
- package/package.json +5 -5
- package/bin/cli.js +0 -8
- package/bitbucket-pipelines.yml +0 -35
- package/public/favicon.ico +0 -0
- package/public/index.html +0 -43
- package/public/logo192.png +0 -0
- package/public/logo512.png +0 -0
- package/public/manifest.json +0 -25
- package/public/robots.txt +0 -3
- package/src/App.tsx +0 -28
- package/src/examples/ReactGridLayout/ReactGridLayoutShowcase01.tsx +0 -80
- package/src/examples/ResponsiveGridLayout/ResponsiveGridLayoutShowcase01.tsx +0 -114
- package/src/examples/utils.ts +0 -15
- package/src/lib/Draggable/Draggable.tsx +0 -303
- package/src/lib/Draggable/DraggableCore.tsx +0 -352
- package/src/lib/Draggable/constants.ts +0 -12
- package/src/lib/Draggable/types.ts +0 -74
- package/src/lib/Draggable/utils/domHelpers.ts +0 -284
- package/src/lib/Draggable/utils/getPrefix.ts +0 -42
- package/src/lib/Draggable/utils/positionHelpers.ts +0 -49
- package/src/lib/Draggable/utils/types.ts +0 -41
- package/src/lib/Draggable/utils/validationHelpers.ts +0 -23
- package/src/lib/GridItem/GridItem.tsx +0 -493
- package/src/lib/GridItem/types.ts +0 -121
- package/src/lib/GridItem/utils/calculateUtils.ts +0 -173
- package/src/lib/GridLayoutEditor/ReactGridLayout.tsx +0 -662
- package/src/lib/GridLayoutEditor/ResponsiveGridLayout.tsx +0 -204
- package/src/lib/GridLayoutEditor/index.ts +0 -11
- package/src/lib/GridLayoutEditor/styles/styles.css +0 -133
- package/src/lib/GridLayoutEditor/types.ts +0 -199
- package/src/lib/GridLayoutEditor/utils/renderHelpers.ts +0 -737
- package/src/lib/GridLayoutEditor/utils/responsiveUtils.ts +0 -111
- package/src/lib/PreviewGLE/ReactGridLayoutPreview.tsx +0 -46
- package/src/lib/PreviewGLE/ResponsiveGridLayoutPreview.tsx +0 -54
- package/src/lib/Resizable/Resizable.tsx +0 -323
- package/src/lib/Resizable/ResizableBox.tsx +0 -109
- package/src/lib/Resizable/styles/styles.css +0 -76
- package/src/lib/Resizable/types.ts +0 -96
- package/src/lib/Resizable/utils/cloneElement.ts +0 -15
- package/src/lib/components/WidthProvider.tsx +0 -71
- package/src/lib/components/types.ts +0 -19
- package/src/react-app-env.d.ts +0 -1
- package/src/reportWebVitals.ts +0 -15
- package/src/utils/types.ts +0 -3
- package/tsconfig.json +0 -22
- /package/{src/examples/ReactGridLayout/index.ts → dist/examples/ReactGridLayout/index.d.ts} +0 -0
- /package/{src/examples/ResponsiveGridLayout/index.ts → dist/examples/ResponsiveGridLayout/index.d.ts} +0 -0
- /package/{src/examples/index.ts → dist/examples/index.d.ts} +0 -0
- /package/{src/lib/Draggable/index.ts → dist/lib/Draggable/index.d.ts} +0 -0
- /package/{src/lib/GridItem/index.ts → dist/lib/GridItem/index.d.ts} +0 -0
- /package/{src/lib/PreviewGLE/index.ts → dist/lib/PreviewGLE/index.d.ts} +0 -0
- /package/{src/lib/Resizable/index.ts → dist/lib/Resizable/index.d.ts} +0 -0
- /package/{src/lib/components/index.ts → dist/lib/components/index.d.ts} +0 -0
- /package/{src/lib/index.ts → dist/lib/index.d.ts} +0 -0
- /package/{src/setupTests.ts → dist/setupTests.js} +0 -0
|
@@ -1,352 +0,0 @@
|
|
|
1
|
-
import React, { useEffect, useRef, useState } from "react";
|
|
2
|
-
import type {
|
|
3
|
-
ControlPosition,
|
|
4
|
-
EventHandler,
|
|
5
|
-
MouseTouchEvent,
|
|
6
|
-
} from "./utils/types";
|
|
7
|
-
import {
|
|
8
|
-
DraggableCoreDefaultProps,
|
|
9
|
-
DraggableCoreState,
|
|
10
|
-
DraggableData,
|
|
11
|
-
PropsWithChildren,
|
|
12
|
-
} from "./types";
|
|
13
|
-
import {
|
|
14
|
-
addEvent,
|
|
15
|
-
addUserSelectStyles,
|
|
16
|
-
getTouch,
|
|
17
|
-
getTouchIdentifier,
|
|
18
|
-
matchSelectorAndParentsTo,
|
|
19
|
-
offsetXYFromParent,
|
|
20
|
-
removeEvent,
|
|
21
|
-
removeUserSelectStyles,
|
|
22
|
-
} from "./utils/domHelpers";
|
|
23
|
-
import { isNum } from "./utils/validationHelpers";
|
|
24
|
-
import { snapToGrid } from "./utils/positionHelpers";
|
|
25
|
-
import { EVENTS } from "./constants";
|
|
26
|
-
|
|
27
|
-
type Props = DraggableCoreDefaultProps;
|
|
28
|
-
|
|
29
|
-
const DraggableCore = ({
|
|
30
|
-
allowAnyClick = false,
|
|
31
|
-
disabled = false,
|
|
32
|
-
enableUserSelectHack = true,
|
|
33
|
-
onStart = function () {},
|
|
34
|
-
onDrag = function () {},
|
|
35
|
-
onStop = function () {},
|
|
36
|
-
onMouseDown = function () {},
|
|
37
|
-
scale = 1,
|
|
38
|
-
children,
|
|
39
|
-
...props
|
|
40
|
-
}: PropsWithChildren<Props>) => {
|
|
41
|
-
const draggableCoreRef = useRef<HTMLElement>(null);
|
|
42
|
-
const isMounted = useRef(false);
|
|
43
|
-
|
|
44
|
-
const [draggableCoreState, setDraggableCoreState] =
|
|
45
|
-
useState<DraggableCoreState>({
|
|
46
|
-
dragging: false,
|
|
47
|
-
lastX: NaN,
|
|
48
|
-
lastY: NaN,
|
|
49
|
-
touchIdentifier: null,
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* @when DraggableCore가 랜더링 했을 때
|
|
54
|
-
* @expected 해당 DOMNode에서 Drag가 동작할 수 있도록 event를 추가합니다.
|
|
55
|
-
* @clear 등록된 모든 EventListener들을 remove합니다.
|
|
56
|
-
*/
|
|
57
|
-
useEffect(() => {
|
|
58
|
-
const thisNode = findDOMNode();
|
|
59
|
-
|
|
60
|
-
if (thisNode) {
|
|
61
|
-
addEvent(thisNode, EVENTS.TOUCH.START, handleTouchStart, {
|
|
62
|
-
passive: false,
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
if (draggableCoreState.dragging) {
|
|
66
|
-
addEvent(thisNode.ownerDocument, dragEventFor.MOVE, handleDrag);
|
|
67
|
-
addEvent(thisNode.ownerDocument, dragEventFor.STOP, handleDragStop);
|
|
68
|
-
} else {
|
|
69
|
-
removeEvent(thisNode.ownerDocument, dragEventFor.MOVE, handleDrag);
|
|
70
|
-
removeEvent(thisNode.ownerDocument, dragEventFor.STOP, handleDragStop);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
return () => {
|
|
75
|
-
if (thisNode) {
|
|
76
|
-
const { ownerDocument } = thisNode;
|
|
77
|
-
|
|
78
|
-
removeEvent(ownerDocument, EVENTS.MOUSE.MOVE, handleDrag);
|
|
79
|
-
removeEvent(ownerDocument, EVENTS.MOUSE.STOP, handleDragStop);
|
|
80
|
-
removeEvent(ownerDocument, EVENTS.TOUCH.MOVE, handleDrag);
|
|
81
|
-
removeEvent(ownerDocument, EVENTS.TOUCH.STOP, handleDragStop);
|
|
82
|
-
removeEvent(thisNode, EVENTS.TOUCH.START, handleTouchStart, {
|
|
83
|
-
passive: false,
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
};
|
|
87
|
-
}, [handleDragStart, handleDrag, handleDragStop]);
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* @when DraggableCore가 랜더링 했을 때
|
|
91
|
-
* @expected mount된 상태를 true로 변경합니다.
|
|
92
|
-
* @clear mount된 상태를 false로 변경하고, 등록된 styles을 제거합니다.
|
|
93
|
-
*/
|
|
94
|
-
useEffect(() => {
|
|
95
|
-
isMounted.current = true;
|
|
96
|
-
|
|
97
|
-
return () => {
|
|
98
|
-
isMounted.current = false;
|
|
99
|
-
|
|
100
|
-
const thisNode = findDOMNode();
|
|
101
|
-
|
|
102
|
-
if (thisNode) {
|
|
103
|
-
const { ownerDocument } = thisNode;
|
|
104
|
-
|
|
105
|
-
if (enableUserSelectHack) removeUserSelectStyles(ownerDocument);
|
|
106
|
-
}
|
|
107
|
-
};
|
|
108
|
-
// NOTE - react-draggable과 동일하게 동작하게 하기 위해서 dependency를 제거하였습니다.
|
|
109
|
-
}, []);
|
|
110
|
-
|
|
111
|
-
let dragEventFor = EVENTS.MOUSE;
|
|
112
|
-
|
|
113
|
-
// NOTE - draggable할 node element를 찾는 함수
|
|
114
|
-
const findDOMNode = (): HTMLElement | null => {
|
|
115
|
-
return props?.nodeRef?.current ?? draggableCoreRef?.current;
|
|
116
|
-
};
|
|
117
|
-
|
|
118
|
-
// NOTE - event 발생 시 {x, y} position을 가져오는 함수
|
|
119
|
-
const getControlPosition = (
|
|
120
|
-
e: MouseTouchEvent,
|
|
121
|
-
touchIdentifier?: number | null
|
|
122
|
-
): ControlPosition | null => {
|
|
123
|
-
const touchObj =
|
|
124
|
-
typeof touchIdentifier === "number" ? getTouch(e, touchIdentifier) : null;
|
|
125
|
-
|
|
126
|
-
// NOTE - 올바르게 touch를 하지 않은 경우
|
|
127
|
-
if (typeof touchIdentifier === "number" && !touchObj) return null;
|
|
128
|
-
|
|
129
|
-
const thisNode = findDOMNode();
|
|
130
|
-
|
|
131
|
-
const offsetParent =
|
|
132
|
-
props?.offsetParent ||
|
|
133
|
-
thisNode?.offsetParent ||
|
|
134
|
-
thisNode?.ownerDocument?.body;
|
|
135
|
-
|
|
136
|
-
if (!offsetParent) return null;
|
|
137
|
-
|
|
138
|
-
return offsetXYFromParent(touchObj || e, offsetParent, scale);
|
|
139
|
-
};
|
|
140
|
-
|
|
141
|
-
const createCoreData = (x: number, y: number): DraggableData | void => {
|
|
142
|
-
const isStart = !isNum(draggableCoreState.lastX);
|
|
143
|
-
const node = findDOMNode();
|
|
144
|
-
|
|
145
|
-
if (!node) return;
|
|
146
|
-
|
|
147
|
-
if (isStart) {
|
|
148
|
-
return {
|
|
149
|
-
node,
|
|
150
|
-
deltaX: 0,
|
|
151
|
-
deltaY: 0,
|
|
152
|
-
lastX: x,
|
|
153
|
-
lastY: y,
|
|
154
|
-
x,
|
|
155
|
-
y,
|
|
156
|
-
};
|
|
157
|
-
} else {
|
|
158
|
-
return {
|
|
159
|
-
node,
|
|
160
|
-
deltaX: x - draggableCoreState.lastX,
|
|
161
|
-
deltaY: y - draggableCoreState.lastY,
|
|
162
|
-
lastX: draggableCoreState.lastX,
|
|
163
|
-
lastY: draggableCoreState.lastY,
|
|
164
|
-
x,
|
|
165
|
-
y,
|
|
166
|
-
};
|
|
167
|
-
}
|
|
168
|
-
};
|
|
169
|
-
|
|
170
|
-
function handleDragStart(e: MouseTouchEvent): void | false {
|
|
171
|
-
onMouseDown && onMouseDown(e);
|
|
172
|
-
|
|
173
|
-
// NOTE - left clicks만 가능
|
|
174
|
-
if (!allowAnyClick && typeof e.button === "number" && e.button !== 0) {
|
|
175
|
-
return false;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
const thisNode = findDOMNode();
|
|
179
|
-
|
|
180
|
-
if (!thisNode || !thisNode.ownerDocument || !thisNode.ownerDocument.body) {
|
|
181
|
-
throw new Error("<DraggableCore> not mounted on DragStart!");
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
const { ownerDocument } = thisNode;
|
|
185
|
-
|
|
186
|
-
// NOTE - handle || cancel prop이 제공되었을 때 selector와 match되는지를 확인
|
|
187
|
-
// handle prop이 존재할 때, matchSelectorAndParentsTo 메소드를 통해 thisNode와 일치하는 element만 Drag 가능
|
|
188
|
-
// cancel prop이 존재할 때, matchSelectorAndParentsTo 메소드를 통해 thisNode와 일치하는 element는 Drag 불가능
|
|
189
|
-
if (
|
|
190
|
-
disabled ||
|
|
191
|
-
!(
|
|
192
|
-
ownerDocument.defaultView &&
|
|
193
|
-
e.target instanceof ownerDocument.defaultView.Node
|
|
194
|
-
) ||
|
|
195
|
-
(props.handle &&
|
|
196
|
-
!matchSelectorAndParentsTo(e.target, props.handle, thisNode)) ||
|
|
197
|
-
(props.cancel &&
|
|
198
|
-
matchSelectorAndParentsTo(e.target, props.cancel, thisNode))
|
|
199
|
-
) {
|
|
200
|
-
return;
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
// NOTE - ipad || iphone과 같은 mobile 기기에서 scroll 방지
|
|
204
|
-
if (e.type === "touchstart") e.preventDefault();
|
|
205
|
-
|
|
206
|
-
// NOTE - touch event가 발생했을 때 multi touch 상황에서 각각의 터치를 구분하고 다른 처리를 할 수 있게 하기 위함입니다.
|
|
207
|
-
const touchIdentifier = getTouchIdentifier(e);
|
|
208
|
-
|
|
209
|
-
if (touchIdentifier) {
|
|
210
|
-
setDraggableCoreState({ ...draggableCoreState, touchIdentifier });
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
const position = getControlPosition(e, touchIdentifier);
|
|
214
|
-
|
|
215
|
-
if (!position) return;
|
|
216
|
-
|
|
217
|
-
const { x, y } = position;
|
|
218
|
-
|
|
219
|
-
const coreEvent = createCoreData(x, y);
|
|
220
|
-
|
|
221
|
-
if (!coreEvent) return;
|
|
222
|
-
|
|
223
|
-
const shouldUpdate = onStart(e, coreEvent);
|
|
224
|
-
|
|
225
|
-
if (shouldUpdate === false || isMounted.current === false) return;
|
|
226
|
-
|
|
227
|
-
if (enableUserSelectHack) addUserSelectStyles(ownerDocument);
|
|
228
|
-
|
|
229
|
-
setDraggableCoreState((prev) => ({
|
|
230
|
-
...prev,
|
|
231
|
-
dragging: true,
|
|
232
|
-
lastX: x,
|
|
233
|
-
lastY: y,
|
|
234
|
-
}));
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
function handleDrag(e: MouseTouchEvent): void | false {
|
|
238
|
-
const position = getControlPosition(e, draggableCoreState.touchIdentifier);
|
|
239
|
-
|
|
240
|
-
if (!position) return;
|
|
241
|
-
|
|
242
|
-
let { x, y } = position;
|
|
243
|
-
|
|
244
|
-
if (Array.isArray(props.grid)) {
|
|
245
|
-
let deltaX = x - draggableCoreState.lastX;
|
|
246
|
-
let deltaY = y - draggableCoreState.lastY;
|
|
247
|
-
|
|
248
|
-
[deltaX, deltaY] = snapToGrid(props.grid, deltaX, deltaY);
|
|
249
|
-
|
|
250
|
-
if (!deltaX && !deltaY) return;
|
|
251
|
-
|
|
252
|
-
x = draggableCoreState.lastX + deltaX;
|
|
253
|
-
y = draggableCoreState.lastY + deltaY;
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
const coreEvent = createCoreData(x, y);
|
|
257
|
-
const thisNode = findDOMNode();
|
|
258
|
-
|
|
259
|
-
if (!coreEvent || !thisNode) return;
|
|
260
|
-
|
|
261
|
-
const shouldUpdate = onDrag(e, coreEvent, thisNode);
|
|
262
|
-
|
|
263
|
-
if (shouldUpdate === false || isMounted.current === false) {
|
|
264
|
-
handleDragStop(e);
|
|
265
|
-
|
|
266
|
-
return;
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
setDraggableCoreState((prevState) => ({
|
|
270
|
-
...prevState,
|
|
271
|
-
lastX: x,
|
|
272
|
-
lastY: y,
|
|
273
|
-
}));
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
function handleDragStop(e: MouseTouchEvent): void | false {
|
|
277
|
-
if (!draggableCoreState.dragging) return;
|
|
278
|
-
|
|
279
|
-
const position = getControlPosition(e, draggableCoreState.touchIdentifier);
|
|
280
|
-
|
|
281
|
-
if (!position) return;
|
|
282
|
-
|
|
283
|
-
let { x, y } = position;
|
|
284
|
-
|
|
285
|
-
if (Array.isArray(props?.grid)) {
|
|
286
|
-
let deltaX = x - draggableCoreState.lastX || 0;
|
|
287
|
-
let deltaY = y - draggableCoreState.lastY || 0;
|
|
288
|
-
[deltaX, deltaY] = snapToGrid(props?.grid, deltaX, deltaY);
|
|
289
|
-
x = draggableCoreState.lastX + deltaX;
|
|
290
|
-
y = draggableCoreState.lastY + deltaY;
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
const coreEvent = createCoreData(x, y);
|
|
294
|
-
|
|
295
|
-
if (!coreEvent) return;
|
|
296
|
-
|
|
297
|
-
const shouldContinue = onStop(e, coreEvent);
|
|
298
|
-
|
|
299
|
-
if (shouldContinue === false || isMounted.current === false) return false;
|
|
300
|
-
|
|
301
|
-
const thisNode = findDOMNode();
|
|
302
|
-
|
|
303
|
-
if (thisNode) {
|
|
304
|
-
if (enableUserSelectHack) removeUserSelectStyles(thisNode.ownerDocument);
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
setDraggableCoreState((prev) => ({
|
|
308
|
-
...prev,
|
|
309
|
-
dragging: false,
|
|
310
|
-
lastX: NaN,
|
|
311
|
-
lastY: NaN,
|
|
312
|
-
}));
|
|
313
|
-
|
|
314
|
-
if (thisNode) {
|
|
315
|
-
removeEvent(thisNode.ownerDocument, dragEventFor.MOVE, handleDrag);
|
|
316
|
-
removeEvent(thisNode.ownerDocument, dragEventFor.STOP, handleDragStop);
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
const handleMouseDown: EventHandler<MouseTouchEvent> = (e) => {
|
|
321
|
-
dragEventFor = EVENTS.MOUSE;
|
|
322
|
-
|
|
323
|
-
return handleDragStart(e);
|
|
324
|
-
};
|
|
325
|
-
|
|
326
|
-
const handleMouseUp: EventHandler<MouseTouchEvent> = (e) => {
|
|
327
|
-
dragEventFor = EVENTS.MOUSE;
|
|
328
|
-
|
|
329
|
-
return handleDragStop(e);
|
|
330
|
-
};
|
|
331
|
-
|
|
332
|
-
// NOTE - handleMouseDown(start drag)과 동일하지만 touch device에 대응
|
|
333
|
-
const handleTouchStart: EventHandler<MouseTouchEvent> = (e) => {
|
|
334
|
-
dragEventFor = EVENTS.TOUCH;
|
|
335
|
-
|
|
336
|
-
return handleDragStart(e);
|
|
337
|
-
};
|
|
338
|
-
const handleTouchEnd: EventHandler<MouseTouchEvent> = (e) => {
|
|
339
|
-
dragEventFor = EVENTS.TOUCH;
|
|
340
|
-
|
|
341
|
-
return handleDragStop(e);
|
|
342
|
-
};
|
|
343
|
-
|
|
344
|
-
return React.cloneElement(children, {
|
|
345
|
-
onMouseDown: handleMouseDown,
|
|
346
|
-
onMouseUp: handleMouseUp,
|
|
347
|
-
onTouchEnd: handleTouchEnd,
|
|
348
|
-
ref: props.nodeRef ?? draggableCoreRef,
|
|
349
|
-
});
|
|
350
|
-
};
|
|
351
|
-
|
|
352
|
-
export default DraggableCore;
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import { ReactElement, RefObject } from "react";
|
|
2
|
-
import {
|
|
3
|
-
ControlPosition,
|
|
4
|
-
DraggableEventHandler,
|
|
5
|
-
PositionOffsetControlPosition,
|
|
6
|
-
} from "./utils/types";
|
|
7
|
-
|
|
8
|
-
// draggableCore
|
|
9
|
-
export type DraggableCoreState = {
|
|
10
|
-
dragging: boolean;
|
|
11
|
-
lastX: number;
|
|
12
|
-
lastY: number;
|
|
13
|
-
touchIdentifier?: number | null;
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
export type DraggableData = {
|
|
17
|
-
node: HTMLElement;
|
|
18
|
-
x: number;
|
|
19
|
-
y: number;
|
|
20
|
-
deltaX: number;
|
|
21
|
-
deltaY: number;
|
|
22
|
-
lastX: number;
|
|
23
|
-
lastY: number;
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
export type DraggableCoreDefaultProps = {
|
|
27
|
-
allowAnyClick?: boolean;
|
|
28
|
-
disabled?: boolean;
|
|
29
|
-
enableUserSelectHack?: boolean;
|
|
30
|
-
onStart?: DraggableEventHandler | Function;
|
|
31
|
-
onDrag?: DraggableEventHandler | Function;
|
|
32
|
-
onStop?: DraggableEventHandler | Function;
|
|
33
|
-
onMouseDown?: (e: MouseEvent) => void;
|
|
34
|
-
scale?: number;
|
|
35
|
-
cancel?: string;
|
|
36
|
-
children: ReactElement<any>;
|
|
37
|
-
offsetParent?: HTMLElement;
|
|
38
|
-
grid?: [number, number];
|
|
39
|
-
handle?: string;
|
|
40
|
-
nodeRef?: RefObject<HTMLElement>;
|
|
41
|
-
className?: string;
|
|
42
|
-
style?: Object;
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
// draggable type
|
|
46
|
-
export type DraggableState = {
|
|
47
|
-
dragging: boolean;
|
|
48
|
-
dragged: boolean;
|
|
49
|
-
x: number;
|
|
50
|
-
y: number;
|
|
51
|
-
slackX: number;
|
|
52
|
-
slackY: number;
|
|
53
|
-
isElementSVG: boolean;
|
|
54
|
-
prevPropsPosition?: ControlPosition;
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
export type DraggablePositionType = {
|
|
58
|
-
positionOffset?: PositionOffsetControlPosition;
|
|
59
|
-
position?: ControlPosition;
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
export type DraggableProps = DraggablePositionType & DraggableCoreDefaultProps;
|
|
63
|
-
|
|
64
|
-
export type PropsWithChildren<P> = P & {
|
|
65
|
-
children: ReactElement<any>;
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
export type AxisType = "both" | "x" | "y" | "none";
|
|
69
|
-
|
|
70
|
-
export type DraggableEvent =
|
|
71
|
-
| React.MouseEvent<HTMLElement | SVGElement>
|
|
72
|
-
| React.TouchEvent<HTMLElement | SVGElement>
|
|
73
|
-
| MouseEvent
|
|
74
|
-
| TouchEvent;
|
|
@@ -1,284 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
2
|
-
import browserPrefix, { browserPrefixToKey } from "./getPrefix";
|
|
3
|
-
import type {
|
|
4
|
-
ControlPosition,
|
|
5
|
-
PositionOffsetControlPosition,
|
|
6
|
-
MouseTouchEvent,
|
|
7
|
-
EventWithOffset,
|
|
8
|
-
EventHandler,
|
|
9
|
-
} from "./types";
|
|
10
|
-
import { findInArray, int, isFunction } from "./validationHelpers";
|
|
11
|
-
|
|
12
|
-
export const matchSelector = (el: Node, selector: string): boolean => {
|
|
13
|
-
let matchedSelector = "";
|
|
14
|
-
const selectors = [
|
|
15
|
-
"matches",
|
|
16
|
-
"webkitMatchesSelector",
|
|
17
|
-
// "mozMatchesSelector",
|
|
18
|
-
// "msMatchesSelector",
|
|
19
|
-
// "oMatchesSelector",
|
|
20
|
-
];
|
|
21
|
-
const callback = (method: keyof Element) => {
|
|
22
|
-
return isFunction((el as Element)[method]);
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
if (!matchedSelector) {
|
|
26
|
-
matchedSelector = findInArray(selectors, callback);
|
|
27
|
-
|
|
28
|
-
if (
|
|
29
|
-
matchedSelector === "matches" ||
|
|
30
|
-
matchedSelector === "webkitMatchesSelector"
|
|
31
|
-
) {
|
|
32
|
-
return (el as Element)[matchedSelector](selector);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
return false;
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
export const matchSelectorAndParentsTo = (
|
|
40
|
-
el: Node,
|
|
41
|
-
selector: string,
|
|
42
|
-
baseNode: Node
|
|
43
|
-
): boolean => {
|
|
44
|
-
let node = el;
|
|
45
|
-
|
|
46
|
-
do {
|
|
47
|
-
if (matchSelector(node, selector)) return true;
|
|
48
|
-
if (node === baseNode) return false;
|
|
49
|
-
if (node.parentNode) node = node.parentNode;
|
|
50
|
-
} while (node);
|
|
51
|
-
|
|
52
|
-
return false;
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
export const addEvent = (
|
|
56
|
-
el: Node,
|
|
57
|
-
eventType: string,
|
|
58
|
-
handler: EventHandler<any>,
|
|
59
|
-
inputOptions?: Object
|
|
60
|
-
): void => {
|
|
61
|
-
if (!el) return;
|
|
62
|
-
|
|
63
|
-
const options = { capture: true, ...inputOptions };
|
|
64
|
-
|
|
65
|
-
if (el.addEventListener) {
|
|
66
|
-
el.addEventListener(eventType, handler, options);
|
|
67
|
-
}
|
|
68
|
-
// if (el.addEventListener) {
|
|
69
|
-
// el.addEventListener(eventType, handler, options);
|
|
70
|
-
// } else {
|
|
71
|
-
// (el as { [key: string]: any })['on' + eventType] = handler;
|
|
72
|
-
// }
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
export const removeEvent = (
|
|
76
|
-
el: Node,
|
|
77
|
-
eventType: string,
|
|
78
|
-
handler: EventHandler<any>,
|
|
79
|
-
inputOptions?: Object
|
|
80
|
-
): void => {
|
|
81
|
-
if (!el) return;
|
|
82
|
-
|
|
83
|
-
const options = { capture: true, ...inputOptions };
|
|
84
|
-
|
|
85
|
-
if (el.removeEventListener) {
|
|
86
|
-
el.removeEventListener(eventType, handler, options);
|
|
87
|
-
}
|
|
88
|
-
// if (el.removeEventListener) {
|
|
89
|
-
// el.removeEventListener(eventType, handler, options);
|
|
90
|
-
// } else {
|
|
91
|
-
// (el as { [key: string]: any })['on' + eventType] = null;
|
|
92
|
-
// }
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
export const outerHeight = (node: HTMLElement): number => {
|
|
96
|
-
let height = node.clientHeight;
|
|
97
|
-
const computedStyle = node.ownerDocument.defaultView?.getComputedStyle(node);
|
|
98
|
-
|
|
99
|
-
if (computedStyle) {
|
|
100
|
-
height += int(computedStyle.borderTopWidth);
|
|
101
|
-
height += int(computedStyle.borderBottomWidth);
|
|
102
|
-
return height;
|
|
103
|
-
} else {
|
|
104
|
-
return height;
|
|
105
|
-
}
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
export const outerWidth = (node: HTMLElement): number => {
|
|
109
|
-
let width = node.clientWidth;
|
|
110
|
-
const computedStyle = node.ownerDocument.defaultView?.getComputedStyle(node);
|
|
111
|
-
|
|
112
|
-
if (computedStyle) {
|
|
113
|
-
width += int(computedStyle.borderLeftWidth);
|
|
114
|
-
width += int(computedStyle.borderRightWidth);
|
|
115
|
-
return width;
|
|
116
|
-
} else {
|
|
117
|
-
return width;
|
|
118
|
-
}
|
|
119
|
-
};
|
|
120
|
-
export const innerHeight = (node: HTMLElement): number => {
|
|
121
|
-
let height = node.clientHeight;
|
|
122
|
-
const computedStyle = node.ownerDocument.defaultView?.getComputedStyle(node);
|
|
123
|
-
|
|
124
|
-
if (computedStyle) {
|
|
125
|
-
height -= int(computedStyle.paddingTop);
|
|
126
|
-
height -= int(computedStyle.paddingBottom);
|
|
127
|
-
return height;
|
|
128
|
-
} else {
|
|
129
|
-
return height;
|
|
130
|
-
}
|
|
131
|
-
};
|
|
132
|
-
|
|
133
|
-
export const innerWidth = (node: HTMLElement): number => {
|
|
134
|
-
let width = node.clientWidth;
|
|
135
|
-
|
|
136
|
-
const computedStyle = node.ownerDocument.defaultView?.getComputedStyle(node);
|
|
137
|
-
|
|
138
|
-
if (computedStyle) {
|
|
139
|
-
width -= int(computedStyle.paddingLeft);
|
|
140
|
-
width -= int(computedStyle.paddingRight);
|
|
141
|
-
|
|
142
|
-
return width;
|
|
143
|
-
} else {
|
|
144
|
-
return width;
|
|
145
|
-
}
|
|
146
|
-
};
|
|
147
|
-
|
|
148
|
-
export const offsetXYFromParent = (
|
|
149
|
-
evt: EventWithOffset,
|
|
150
|
-
offsetParent: Element,
|
|
151
|
-
scale: number
|
|
152
|
-
): ControlPosition => {
|
|
153
|
-
const isBody = offsetParent.ownerDocument.body;
|
|
154
|
-
const offsetParentRect = isBody
|
|
155
|
-
? { left: 0, top: 0 }
|
|
156
|
-
: offsetParent.getBoundingClientRect();
|
|
157
|
-
|
|
158
|
-
const x =
|
|
159
|
-
(evt.clientX + offsetParent.scrollLeft - offsetParentRect.left) / scale;
|
|
160
|
-
const y =
|
|
161
|
-
(evt.clientY + offsetParent.scrollTop - offsetParentRect.top) / scale;
|
|
162
|
-
|
|
163
|
-
return { x, y };
|
|
164
|
-
};
|
|
165
|
-
|
|
166
|
-
export const createCSSTransform = (
|
|
167
|
-
controlPos: ControlPosition,
|
|
168
|
-
positionOffset?: PositionOffsetControlPosition
|
|
169
|
-
): Object => {
|
|
170
|
-
const translation = getTranslation(controlPos, "px", positionOffset);
|
|
171
|
-
return { [browserPrefixToKey("transform", browserPrefix)]: translation };
|
|
172
|
-
};
|
|
173
|
-
|
|
174
|
-
export const createSVGTransform = (
|
|
175
|
-
controlPos: ControlPosition,
|
|
176
|
-
positionOffset?: PositionOffsetControlPosition
|
|
177
|
-
): string => {
|
|
178
|
-
const translation = getTranslation(controlPos, "", positionOffset);
|
|
179
|
-
|
|
180
|
-
return translation;
|
|
181
|
-
};
|
|
182
|
-
|
|
183
|
-
export const getTranslation = (
|
|
184
|
-
{ x, y }: ControlPosition,
|
|
185
|
-
unitSuffix: string,
|
|
186
|
-
positionOffset?: PositionOffsetControlPosition
|
|
187
|
-
): string => {
|
|
188
|
-
let translation = `translate(${x}${unitSuffix},${y}${unitSuffix})`;
|
|
189
|
-
|
|
190
|
-
if (positionOffset) {
|
|
191
|
-
const defaultX = `${
|
|
192
|
-
typeof positionOffset.x === "string"
|
|
193
|
-
? positionOffset.x
|
|
194
|
-
: positionOffset.x + unitSuffix
|
|
195
|
-
}`;
|
|
196
|
-
const defaultY = `${
|
|
197
|
-
typeof positionOffset.y === "string"
|
|
198
|
-
? positionOffset.y
|
|
199
|
-
: positionOffset.y + unitSuffix
|
|
200
|
-
}`;
|
|
201
|
-
|
|
202
|
-
translation = `translate(${defaultX}, ${defaultY})` + translation;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
return translation;
|
|
206
|
-
};
|
|
207
|
-
|
|
208
|
-
export const getTouch = (
|
|
209
|
-
e: MouseTouchEvent,
|
|
210
|
-
identifier: number
|
|
211
|
-
): { clientX: number; clientY: number } => {
|
|
212
|
-
return (
|
|
213
|
-
(e.targetTouches &&
|
|
214
|
-
findInArray(e.targetTouches, (t: any) => identifier === t.identifier)) ||
|
|
215
|
-
(e.changedTouches &&
|
|
216
|
-
findInArray(e.changedTouches, (t: any) => identifier === t.identifier))
|
|
217
|
-
);
|
|
218
|
-
};
|
|
219
|
-
|
|
220
|
-
export const getTouchIdentifier = (e: MouseTouchEvent): number | undefined => {
|
|
221
|
-
if (e.targetTouches && e.targetTouches[0]) {
|
|
222
|
-
return e.targetTouches[0].identifier;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
if (e.changedTouches && e.changedTouches[0]) {
|
|
226
|
-
return e.changedTouches[0].identifier;
|
|
227
|
-
}
|
|
228
|
-
};
|
|
229
|
-
|
|
230
|
-
export const addUserSelectStyles = (doc?: Document) => {
|
|
231
|
-
if (!doc) return;
|
|
232
|
-
|
|
233
|
-
let styleEl = doc.getElementById("react-draggable-style-el");
|
|
234
|
-
|
|
235
|
-
if (!styleEl) {
|
|
236
|
-
styleEl = doc.createElement("style");
|
|
237
|
-
styleEl.id = "react-draggable-style-el";
|
|
238
|
-
styleEl.innerHTML =
|
|
239
|
-
".react-draggable-transparent-selection *::-moz-selection {all: inherit;}\n";
|
|
240
|
-
styleEl.innerHTML +=
|
|
241
|
-
".react-draggable-transparent-selection *::selection {all: inherit;}\n";
|
|
242
|
-
doc.getElementsByTagName("head")[0].appendChild(styleEl);
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
if (doc.body) addClassName(doc.body, "react-draggable-transparent-selection");
|
|
246
|
-
};
|
|
247
|
-
|
|
248
|
-
export const removeUserSelectStyles = (doc?: Document) => {
|
|
249
|
-
if (!doc) return;
|
|
250
|
-
|
|
251
|
-
if (doc.body) {
|
|
252
|
-
removeClassName(doc.body, "react-draggable-transparent-selection");
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
if (doc.getSelection()) {
|
|
256
|
-
doc.getSelection()?.empty();
|
|
257
|
-
} else {
|
|
258
|
-
const selection = (doc.defaultView || window).getSelection();
|
|
259
|
-
if (selection && selection.type !== "Caret") {
|
|
260
|
-
selection.removeAllRanges();
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
};
|
|
264
|
-
|
|
265
|
-
export const addClassName = (el: HTMLElement, className: string) => {
|
|
266
|
-
if (el.classList) {
|
|
267
|
-
el.classList.add(className);
|
|
268
|
-
} else {
|
|
269
|
-
if (!el.className.match(new RegExp(`(?:^|\\s)${className}(?!\\S)`))) {
|
|
270
|
-
el.className += ` ${className}`;
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
};
|
|
274
|
-
|
|
275
|
-
export const removeClassName = (el: HTMLElement, className: string) => {
|
|
276
|
-
if (el.classList) {
|
|
277
|
-
el.classList.remove(className);
|
|
278
|
-
} else {
|
|
279
|
-
el.className = el.className.replace(
|
|
280
|
-
new RegExp(`(?:^|\\s)${className}(?!\\S)`, "g"),
|
|
281
|
-
""
|
|
282
|
-
);
|
|
283
|
-
}
|
|
284
|
-
};
|