1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | exports.Draggable = void 0;
|
4 | const tslib_1 = require("tslib");
|
5 | const React = tslib_1.__importStar(require("react"));
|
6 | const react_styles_1 = require("@patternfly/react-styles");
|
7 | const drag_drop_1 = tslib_1.__importDefault(require("@patternfly/react-styles/css/components/DragDrop/drag-drop"));
|
8 | const DroppableContext_1 = require("./DroppableContext");
|
9 | const DragDrop_1 = require("./DragDrop");
|
10 |
|
11 | function getDefaultBackground() {
|
12 | const div = document.createElement('div');
|
13 | document.head.appendChild(div);
|
14 | const bg = window.getComputedStyle(div).backgroundColor;
|
15 | document.head.removeChild(div);
|
16 | return bg;
|
17 | }
|
18 | function getInheritedBackgroundColor(el) {
|
19 | const defaultStyle = getDefaultBackground();
|
20 | const backgroundColor = window.getComputedStyle(el).backgroundColor;
|
21 | if (backgroundColor !== defaultStyle) {
|
22 | return backgroundColor;
|
23 | }
|
24 | else if (!el.parentElement) {
|
25 | return defaultStyle;
|
26 | }
|
27 | return getInheritedBackgroundColor(el.parentElement);
|
28 | }
|
29 | function removeBlankDiv(node) {
|
30 | if (node.getAttribute('blankDiv') === 'true') {
|
31 |
|
32 | for (let i = 0; i < node.children.length; i++) {
|
33 | const child = node.children[i];
|
34 | if (child.getAttribute('blankDiv') === 'true') {
|
35 | node.removeChild(child);
|
36 | node.setAttribute('blankDiv', 'false');
|
37 | break;
|
38 | }
|
39 | }
|
40 | }
|
41 | }
|
42 |
|
43 | function resetDroppableItem(droppableItem) {
|
44 | removeBlankDiv(droppableItem.node);
|
45 | droppableItem.node.classList.remove(drag_drop_1.default.modifiers.dragging);
|
46 | droppableItem.node.classList.remove(drag_drop_1.default.modifiers.dragOutside);
|
47 | droppableItem.draggableNodes.forEach((n, i) => {
|
48 | n.style.transform = '';
|
49 | n.style.transition = '';
|
50 | droppableItem.draggableNodesRects[i] = n.getBoundingClientRect();
|
51 | });
|
52 | }
|
53 | function overlaps(ev, rect) {
|
54 | return (ev.clientX > rect.x && ev.clientX < rect.x + rect.width && ev.clientY > rect.y && ev.clientY < rect.y + rect.height);
|
55 | }
|
56 | const Draggable = (_a) => {
|
57 | var { className, children, style: styleProp = {}, hasNoWrapper = false } = _a, props = tslib_1.__rest(_a, ["className", "children", "style", "hasNoWrapper"]);
|
58 |
|
59 | let [style, setStyle] = React.useState(styleProp);
|
60 |
|
61 | const [isDragging, setIsDragging] = React.useState(false);
|
62 | const [isValidDrag, setIsValidDrag] = React.useState(true);
|
63 | const { zone, droppableId } = React.useContext(DroppableContext_1.DroppableContext);
|
64 | const { onDrag, onDragMove, onDrop } = React.useContext(DragDrop_1.DragDropContext);
|
65 |
|
66 |
|
67 | let startX = 0;
|
68 | let startY = 0;
|
69 | let index = null;
|
70 | let hoveringDroppable;
|
71 | let hoveringIndex = null;
|
72 | let mouseMoveListener;
|
73 | let mouseUpListener;
|
74 |
|
75 | let startYOffset = 0;
|
76 |
|
77 | const onTransitionEnd = (_ev) => {
|
78 | if (isDragging) {
|
79 | setIsDragging(false);
|
80 | setStyle(styleProp);
|
81 | }
|
82 | };
|
83 | function getSourceAndDest() {
|
84 | const hoveringDroppableId = hoveringDroppable ? hoveringDroppable.getAttribute('data-pf-droppableid') : null;
|
85 | const source = {
|
86 | droppableId,
|
87 | index
|
88 | };
|
89 | const dest = hoveringDroppableId !== null && hoveringIndex !== null
|
90 | ? {
|
91 | droppableId: hoveringDroppableId,
|
92 | index: hoveringIndex
|
93 | }
|
94 | : undefined;
|
95 | return { source, dest, hoveringDroppableId };
|
96 | }
|
97 | const onMouseUpWhileDragging = (droppableItems) => {
|
98 | droppableItems.forEach(resetDroppableItem);
|
99 | document.removeEventListener('mousemove', mouseMoveListener);
|
100 | document.removeEventListener('mouseup', mouseUpListener);
|
101 | document.removeEventListener('contextmenu', mouseUpListener);
|
102 | const { source, dest, hoveringDroppableId } = getSourceAndDest();
|
103 | const consumerReordered = onDrop(source, dest);
|
104 | if (consumerReordered && droppableId === hoveringDroppableId) {
|
105 | setIsDragging(false);
|
106 | setStyle(styleProp);
|
107 | }
|
108 | else if (!consumerReordered) {
|
109 |
|
110 | setStyle(Object.assign(Object.assign({}, style), { transition: 'transform 0.5s cubic-bezier(0.2, 1, 0.1, 1) 0s', transform: '', background: styleProp.background, boxShadow: styleProp.boxShadow }));
|
111 | }
|
112 | };
|
113 |
|
114 | const onMouseMoveWhileDragging = (ev, droppableItems, blankDivRect) => {
|
115 |
|
116 | hoveringDroppable = null;
|
117 | droppableItems.forEach(droppableItem => {
|
118 | const { node, rect, isDraggingHost, draggableNodes, draggableNodesRects } = droppableItem;
|
119 | if (overlaps(ev, rect)) {
|
120 |
|
121 | node.classList.remove(drag_drop_1.default.modifiers.dragOutside);
|
122 | hoveringDroppable = node;
|
123 |
|
124 | if (node.getAttribute('blankDiv') !== 'true' && !isDraggingHost) {
|
125 | const blankDiv = document.createElement('div');
|
126 | blankDiv.setAttribute('blankDiv', 'true');
|
127 | let blankDivPos = -1;
|
128 | for (let i = 0; i < draggableNodes.length; i++) {
|
129 | const childRect = draggableNodesRects[i];
|
130 | const isLast = i === draggableNodes.length - 1;
|
131 | const startOverlaps = childRect.y >= startY - startYOffset;
|
132 | if ((startOverlaps || isLast) && blankDivPos === -1) {
|
133 | if (isLast && !startOverlaps) {
|
134 | draggableNodes[i].after(blankDiv);
|
135 | }
|
136 | else {
|
137 | draggableNodes[i].before(blankDiv);
|
138 | }
|
139 | blankDiv.style.height = `${blankDivRect.height}px`;
|
140 | blankDiv.style.width = `${blankDivRect.width}px`;
|
141 | node.setAttribute('blankDiv', 'true');
|
142 | blankDivPos = i;
|
143 | }
|
144 | if (blankDivPos !== -1) {
|
145 | childRect.y += blankDivRect.height;
|
146 | }
|
147 | }
|
148 |
|
149 | draggableNodes.splice(blankDivPos, 0, blankDiv);
|
150 | draggableNodesRects.splice(blankDivPos, 0, blankDivRect);
|
151 |
|
152 | rect.height += blankDivRect.height;
|
153 | }
|
154 | }
|
155 | else {
|
156 | resetDroppableItem(droppableItem);
|
157 | node.classList.add(drag_drop_1.default.modifiers.dragging);
|
158 | node.classList.add(drag_drop_1.default.modifiers.dragOutside);
|
159 | }
|
160 | });
|
161 |
|
162 | setStyle(Object.assign(Object.assign({}, style), { transform: `translate(${ev.pageX - startX}px, ${ev.pageY - startY}px)` }));
|
163 | setIsValidDrag(Boolean(hoveringDroppable));
|
164 |
|
165 | hoveringIndex = null;
|
166 | if (hoveringDroppable) {
|
167 | const { draggableNodes, draggableNodesRects } = droppableItems.find(item => item.node === hoveringDroppable);
|
168 | let lastTranslate = 0;
|
169 | draggableNodes.forEach((n, i) => {
|
170 | n.style.transition = 'transform 0.5s cubic-bezier(0.2, 1, 0.1, 1) 0s';
|
171 | const rect = draggableNodesRects[i];
|
172 | const halfway = rect.y + rect.height / 2;
|
173 | let translateY = 0;
|
174 |
|
175 | if (startY < halfway && ev.pageY + (blankDivRect.height - startYOffset) > halfway) {
|
176 | translateY -= blankDivRect.height;
|
177 | }
|
178 | else if (startY >= halfway && ev.pageY - startYOffset <= halfway) {
|
179 | translateY += blankDivRect.height;
|
180 | }
|
181 |
|
182 | if ((translateY <= lastTranslate && translateY < 0) || (translateY > lastTranslate && translateY > 0)) {
|
183 | hoveringIndex = i;
|
184 | }
|
185 | n.style.transform = `translate(0, ${translateY}px`;
|
186 | lastTranslate = translateY;
|
187 | });
|
188 | }
|
189 | const { source, dest } = getSourceAndDest();
|
190 | onDragMove(source, dest);
|
191 | };
|
192 | const onDragStart = (ev) => {
|
193 |
|
194 |
|
195 |
|
196 | ev.preventDefault();
|
197 | if (isDragging) {
|
198 |
|
199 | return;
|
200 | }
|
201 |
|
202 | const dragging = ev.target;
|
203 | const rect = dragging.getBoundingClientRect();
|
204 | const droppableNodes = Array.from(document.querySelectorAll(`[data-pf-droppable="${zone}"]`));
|
205 | const droppableItems = droppableNodes.reduce((acc, cur) => {
|
206 | cur.classList.add(drag_drop_1.default.modifiers.dragging);
|
207 | const draggableNodes = Array.from(cur.querySelectorAll(`[data-pf-draggable-zone="${zone}"]`));
|
208 | const isDraggingHost = cur.contains(dragging);
|
209 | if (isDraggingHost) {
|
210 | index = draggableNodes.indexOf(dragging);
|
211 | }
|
212 | const droppableItem = {
|
213 | node: cur,
|
214 | rect: cur.getBoundingClientRect(),
|
215 | isDraggingHost,
|
216 |
|
217 | draggableNodes: draggableNodes.map(node => (node === dragging ? node.cloneNode(false) : node)),
|
218 | draggableNodesRects: draggableNodes.map(node => node.getBoundingClientRect())
|
219 | };
|
220 | acc.push(droppableItem);
|
221 | return acc;
|
222 | }, []);
|
223 | if (!onDrag({ droppableId, index })) {
|
224 |
|
225 | return;
|
226 | }
|
227 |
|
228 | style = Object.assign(Object.assign({}, style), { top: rect.y, left: rect.x, width: rect.width, height: rect.height, '--pf-c-draggable--m-dragging--BackgroundColor': getInheritedBackgroundColor(dragging), position: 'fixed', zIndex: 5000 });
|
229 | setStyle(style);
|
230 |
|
231 | startX = ev.pageX;
|
232 | startY = ev.pageY;
|
233 | startYOffset = startY - rect.y;
|
234 | setIsDragging(true);
|
235 | mouseMoveListener = ev => onMouseMoveWhileDragging(ev, droppableItems, rect);
|
236 | mouseUpListener = () => onMouseUpWhileDragging(droppableItems);
|
237 | document.addEventListener('mousemove', mouseMoveListener);
|
238 | document.addEventListener('mouseup', mouseUpListener);
|
239 |
|
240 |
|
241 | };
|
242 | const childProps = Object.assign({ 'data-pf-draggable-zone': isDragging ? null : zone, draggable: true, className: react_styles_1.css(drag_drop_1.default.draggable, isDragging && drag_drop_1.default.modifiers.dragging, !isValidDrag && drag_drop_1.default.modifiers.dragOutside, className), onDragStart,
|
243 | onTransitionEnd,
|
244 | style }, props);
|
245 | return (React.createElement(React.Fragment, null,
|
246 | isDragging && (React.createElement("div", Object.assign({ draggable: true }, props, { style: Object.assign(Object.assign({}, styleProp), { visibility: 'hidden' }) }), children)),
|
247 | hasNoWrapper ? (React.cloneElement(children, childProps)) : (React.createElement("div", Object.assign({}, childProps), children))));
|
248 | };
|
249 | exports.Draggable = Draggable;
|
250 | exports.Draggable.displayName = 'Draggable';
|
251 |
|
\ | No newline at end of file |