@atlaskit/pragmatic-drag-and-drop 0.17.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/CHANGELOG.md +209 -0
- package/LICENSE.md +13 -0
- package/README.md +43 -0
- package/__perf__/add-example.todo +1 -0
- package/adapter/element/package.json +15 -0
- package/adapter/file/package.json +15 -0
- package/addon/cancel-unhandled/package.json +15 -0
- package/constellation/index/about.mdx +329 -0
- package/constellation/index/props.mdx +3 -0
- package/dist/cjs/adapter/element-adapter.js +151 -0
- package/dist/cjs/adapter/file-adapter.js +98 -0
- package/dist/cjs/addon/cancel-unhandled.js +50 -0
- package/dist/cjs/entry-point/adapter/element.js +24 -0
- package/dist/cjs/entry-point/adapter/file.js +18 -0
- package/dist/cjs/entry-point/addon/cancel-unhandled.js +12 -0
- package/dist/cjs/entry-point/experimental/cross-with-element-adapter.js +30 -0
- package/dist/cjs/entry-point/types.js +5 -0
- package/dist/cjs/entry-point/util/combine.js +12 -0
- package/dist/cjs/entry-point/util/disable-native-drag-preview.js +12 -0
- package/dist/cjs/entry-point/util/once.js +12 -0
- package/dist/cjs/entry-point/util/reorder.js +12 -0
- package/dist/cjs/entry-point/util/scroll-just-enough-into-view.js +12 -0
- package/dist/cjs/entry-point/util/set-custom-native-drag-preview.js +12 -0
- package/dist/cjs/experimental/cross-window-element-adapter.js +131 -0
- package/dist/cjs/index.js +12 -0
- package/dist/cjs/internal-types.js +5 -0
- package/dist/cjs/ledger/dispatch-consumer-event.js +132 -0
- package/dist/cjs/ledger/lifecycle-manager.js +335 -0
- package/dist/cjs/ledger/usage-ledger.js +37 -0
- package/dist/cjs/make-adapter/make-adapter.js +59 -0
- package/dist/cjs/make-adapter/make-drop-target.js +271 -0
- package/dist/cjs/make-adapter/make-monitor.js +100 -0
- package/dist/cjs/util/add-attribute.js +14 -0
- package/dist/cjs/util/combine.js +17 -0
- package/dist/cjs/util/disable-native-drag-preview.js +36 -0
- package/dist/cjs/util/entering-and-leaving-the-window.js +162 -0
- package/dist/cjs/util/fix-post-drag-pointer-bug.js +114 -0
- package/dist/cjs/util/get-input.js +20 -0
- package/dist/cjs/util/once.js +22 -0
- package/dist/cjs/util/reorder.js +26 -0
- package/dist/cjs/util/scroll-just-enough-into-view.js +17 -0
- package/dist/cjs/util/set-custom-native-drag-preview.js +109 -0
- package/dist/cjs/version.json +5 -0
- package/dist/es2019/adapter/element-adapter.js +143 -0
- package/dist/es2019/adapter/file-adapter.js +90 -0
- package/dist/es2019/addon/cancel-unhandled.js +43 -0
- package/dist/es2019/entry-point/adapter/element.js +1 -0
- package/dist/es2019/entry-point/adapter/file.js +1 -0
- package/dist/es2019/entry-point/addon/cancel-unhandled.js +1 -0
- package/dist/es2019/entry-point/experimental/cross-with-element-adapter.js +1 -0
- package/dist/es2019/entry-point/types.js +1 -0
- package/dist/es2019/entry-point/util/combine.js +1 -0
- package/dist/es2019/entry-point/util/disable-native-drag-preview.js +1 -0
- package/dist/es2019/entry-point/util/once.js +1 -0
- package/dist/es2019/entry-point/util/reorder.js +1 -0
- package/dist/es2019/entry-point/util/scroll-just-enough-into-view.js +1 -0
- package/dist/es2019/entry-point/util/set-custom-native-drag-preview.js +1 -0
- package/dist/es2019/experimental/cross-window-element-adapter.js +121 -0
- package/dist/es2019/index.js +7 -0
- package/dist/es2019/internal-types.js +1 -0
- package/dist/es2019/ledger/dispatch-consumer-event.js +128 -0
- package/dist/es2019/ledger/lifecycle-manager.js +333 -0
- package/dist/es2019/ledger/usage-ledger.js +32 -0
- package/dist/es2019/make-adapter/make-adapter.js +55 -0
- package/dist/es2019/make-adapter/make-drop-target.js +233 -0
- package/dist/es2019/make-adapter/make-monitor.js +80 -0
- package/dist/es2019/util/add-attribute.js +7 -0
- package/dist/es2019/util/combine.js +6 -0
- package/dist/es2019/util/disable-native-drag-preview.js +31 -0
- package/dist/es2019/util/entering-and-leaving-the-window.js +159 -0
- package/dist/es2019/util/fix-post-drag-pointer-bug.js +110 -0
- package/dist/es2019/util/get-input.js +14 -0
- package/dist/es2019/util/once.js +13 -0
- package/dist/es2019/util/reorder.js +17 -0
- package/dist/es2019/util/scroll-just-enough-into-view.js +12 -0
- package/dist/es2019/util/set-custom-native-drag-preview.js +106 -0
- package/dist/es2019/version.json +5 -0
- package/dist/esm/adapter/element-adapter.js +142 -0
- package/dist/esm/adapter/file-adapter.js +90 -0
- package/dist/esm/addon/cancel-unhandled.js +43 -0
- package/dist/esm/entry-point/adapter/element.js +1 -0
- package/dist/esm/entry-point/adapter/file.js +1 -0
- package/dist/esm/entry-point/addon/cancel-unhandled.js +1 -0
- package/dist/esm/entry-point/experimental/cross-with-element-adapter.js +1 -0
- package/dist/esm/entry-point/types.js +1 -0
- package/dist/esm/entry-point/util/combine.js +1 -0
- package/dist/esm/entry-point/util/disable-native-drag-preview.js +1 -0
- package/dist/esm/entry-point/util/once.js +1 -0
- package/dist/esm/entry-point/util/reorder.js +1 -0
- package/dist/esm/entry-point/util/scroll-just-enough-into-view.js +1 -0
- package/dist/esm/entry-point/util/set-custom-native-drag-preview.js +1 -0
- package/dist/esm/experimental/cross-window-element-adapter.js +120 -0
- package/dist/esm/index.js +7 -0
- package/dist/esm/internal-types.js +1 -0
- package/dist/esm/ledger/dispatch-consumer-event.js +125 -0
- package/dist/esm/ledger/lifecycle-manager.js +328 -0
- package/dist/esm/ledger/usage-ledger.js +31 -0
- package/dist/esm/make-adapter/make-adapter.js +53 -0
- package/dist/esm/make-adapter/make-drop-target.js +264 -0
- package/dist/esm/make-adapter/make-monitor.js +93 -0
- package/dist/esm/util/add-attribute.js +8 -0
- package/dist/esm/util/combine.js +11 -0
- package/dist/esm/util/disable-native-drag-preview.js +30 -0
- package/dist/esm/util/entering-and-leaving-the-window.js +156 -0
- package/dist/esm/util/fix-post-drag-pointer-bug.js +108 -0
- package/dist/esm/util/get-input.js +14 -0
- package/dist/esm/util/once.js +16 -0
- package/dist/esm/util/reorder.js +19 -0
- package/dist/esm/util/scroll-just-enough-into-view.js +11 -0
- package/dist/esm/util/set-custom-native-drag-preview.js +104 -0
- package/dist/esm/version.json +5 -0
- package/dist/types/adapter/element-adapter.d.ts +42 -0
- package/dist/types/adapter/file-adapter.d.ts +18 -0
- package/dist/types/addon/cancel-unhandled.d.ts +7 -0
- package/dist/types/entry-point/adapter/element.d.ts +2 -0
- package/dist/types/entry-point/adapter/file.d.ts +2 -0
- package/dist/types/entry-point/addon/cancel-unhandled.d.ts +1 -0
- package/dist/types/entry-point/experimental/cross-with-element-adapter.d.ts +1 -0
- package/dist/types/entry-point/types.d.ts +1 -0
- package/dist/types/entry-point/util/combine.d.ts +1 -0
- package/dist/types/entry-point/util/disable-native-drag-preview.d.ts +1 -0
- package/dist/types/entry-point/util/once.d.ts +1 -0
- package/dist/types/entry-point/util/reorder.d.ts +1 -0
- package/dist/types/entry-point/util/scroll-just-enough-into-view.d.ts +1 -0
- package/dist/types/entry-point/util/set-custom-native-drag-preview.d.ts +1 -0
- package/dist/types/experimental/cross-window-element-adapter.d.ts +17 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/internal-types.d.ts +275 -0
- package/dist/types/ledger/dispatch-consumer-event.d.ts +26 -0
- package/dist/types/ledger/lifecycle-manager.d.ts +16 -0
- package/dist/types/ledger/usage-ledger.d.ts +5 -0
- package/dist/types/make-adapter/make-adapter.d.ts +14 -0
- package/dist/types/make-adapter/make-drop-target.d.ts +5 -0
- package/dist/types/make-adapter/make-monitor.d.ts +8 -0
- package/dist/types/util/add-attribute.d.ts +5 -0
- package/dist/types/util/combine.d.ts +3 -0
- package/dist/types/util/disable-native-drag-preview.d.ts +3 -0
- package/dist/types/util/entering-and-leaving-the-window.d.ts +6 -0
- package/dist/types/util/fix-post-drag-pointer-bug.d.ts +14 -0
- package/dist/types/util/get-input.d.ts +2 -0
- package/dist/types/util/once.d.ts +2 -0
- package/dist/types/util/reorder.d.ts +9 -0
- package/dist/types/util/scroll-just-enough-into-view.d.ts +7 -0
- package/dist/types/util/set-custom-native-drag-preview.d.ts +52 -0
- package/experimental/cross-window-element-adapter/package.json +15 -0
- package/package.json +87 -0
- package/report.api.md +35 -0
- package/tmp/api-report-tmp.d.ts +13 -0
- package/types/package.json +15 -0
- package/util/combine/package.json +15 -0
- package/util/disable-native-drag-preview/package.json +15 -0
- package/util/once/package.json +15 -0
- package/util/reorder/package.json +15 -0
- package/util/scroll-just-enough-into-view/package.json +15 -0
- package/util/set-custom-native-drag-preview/package.json +15 -0
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.fixPostDragPointerBug = fixPostDragPointerBug;
|
|
7
|
+
var _bindEventListener = require("bind-event-listener");
|
|
8
|
+
/** Set a `style` property on a `HTMLElement`
|
|
9
|
+
*
|
|
10
|
+
* @returns a `cleanup` function to restore the `style` property to it's original state
|
|
11
|
+
*/
|
|
12
|
+
function setStyle(el, _ref) {
|
|
13
|
+
var property = _ref.property,
|
|
14
|
+
rule = _ref.rule,
|
|
15
|
+
_ref$priority = _ref.priority,
|
|
16
|
+
priority = _ref$priority === void 0 ? '' : _ref$priority;
|
|
17
|
+
var originalValue = el.style.getPropertyValue(property);
|
|
18
|
+
var originalPriority = el.style.getPropertyPriority(property);
|
|
19
|
+
el.style.setProperty(property, rule, priority);
|
|
20
|
+
return function cleanup() {
|
|
21
|
+
el.style.setProperty(property, originalValue, originalPriority);
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Allow the user to continue to interact with the element their pointer is over at the end of the drag.
|
|
27
|
+
* This is important to allow the user to be able to click, drag (etc) after they have finished a drag
|
|
28
|
+
*
|
|
29
|
+
* @returns a `cleanup` function to restore all elements under the users pointer to their original state
|
|
30
|
+
*/
|
|
31
|
+
function allowPointerEventsOnElementUnderPointer(_ref2) {
|
|
32
|
+
var current = _ref2.current;
|
|
33
|
+
var underUsersPointer = document.elementFromPoint(current.input.clientX, current.input.clientY);
|
|
34
|
+
if (!(underUsersPointer instanceof HTMLElement)) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Debug note: change from 'pointer-events: none' to 'background: green'
|
|
39
|
+
// to get a better sense of what is being achieved
|
|
40
|
+
return setStyle(underUsersPointer, {
|
|
41
|
+
property: 'pointer-events',
|
|
42
|
+
rule: 'auto',
|
|
43
|
+
priority: 'important'
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
function blockPointerEventsOnEverything() {
|
|
47
|
+
var _element$sheet;
|
|
48
|
+
var element = document.createElement('style');
|
|
49
|
+
// Adding a data attribute so to make it super clear to consumers
|
|
50
|
+
// (and to our tests) what this temporary style tag is for
|
|
51
|
+
element.setAttribute('pdnd-post-drag-fix', 'true');
|
|
52
|
+
document.head.appendChild(element);
|
|
53
|
+
|
|
54
|
+
// Debug note: change from 'pointer-events: none' to 'background: red'
|
|
55
|
+
// to get a better sense of what is being achieved
|
|
56
|
+
(_element$sheet = element.sheet) === null || _element$sheet === void 0 ? void 0 : _element$sheet.insertRule('* { pointer-events: none !important; }');
|
|
57
|
+
return function cleanup() {
|
|
58
|
+
document.head.removeChild(element);
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** 🔥🤮 Fix (Chrome, Safari and Firefox) bug where the element under where the user started dragging
|
|
63
|
+
* (on the viewport) is entered into by the browser after a drag finishes ("drop" or "dragend")
|
|
64
|
+
*
|
|
65
|
+
* @description
|
|
66
|
+
*
|
|
67
|
+
* Block pointer events on all elements except for the specific element that pointer is currently over
|
|
68
|
+
*
|
|
69
|
+
* - [Visual explanation of bug](https://twitter.com/alexandereardon/status/1633614212873465856)
|
|
70
|
+
* - [Chrome bug](https://bugs.chromium.org/p/chromium/issues/detail?id=410328)
|
|
71
|
+
*/
|
|
72
|
+
function fixPostDragPointerBug(_ref3) {
|
|
73
|
+
var current = _ref3.current;
|
|
74
|
+
// Queuing a microtask to give any opportunity for frameworks to update their UI in a microtask
|
|
75
|
+
// Note: react@18 does standard state updates in a microtask
|
|
76
|
+
// We do this so our `atDestination` gets the _actual_ element that is under the users pointer
|
|
77
|
+
// at the end of the drag.
|
|
78
|
+
queueMicrotask(function () {
|
|
79
|
+
var undoUnderPointer = allowPointerEventsOnElementUnderPointer({
|
|
80
|
+
current: current
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
// This will also block pointer-events on the children of the element under the users pointer.
|
|
84
|
+
// This is what we want. If the user drops on a container element we don't want the children
|
|
85
|
+
// of the container to be incorrectly entered into
|
|
86
|
+
var undoGlobalBlock = blockPointerEventsOnEverything();
|
|
87
|
+
function cleanup() {
|
|
88
|
+
unbindEvents();
|
|
89
|
+
undoUnderPointer === null || undoUnderPointer === void 0 ? void 0 : undoUnderPointer();
|
|
90
|
+
undoGlobalBlock();
|
|
91
|
+
}
|
|
92
|
+
var unbindEvents = (0, _bindEventListener.bindAll)(window, [{
|
|
93
|
+
type: 'pointerdown',
|
|
94
|
+
listener: cleanup
|
|
95
|
+
}, {
|
|
96
|
+
type: 'pointermove',
|
|
97
|
+
listener: cleanup
|
|
98
|
+
}, {
|
|
99
|
+
type: 'focusin',
|
|
100
|
+
listener: cleanup
|
|
101
|
+
}, {
|
|
102
|
+
type: 'focusout',
|
|
103
|
+
listener: cleanup
|
|
104
|
+
},
|
|
105
|
+
// a 'pointerdown' should happen before 'dragstart', but just being super safe
|
|
106
|
+
{
|
|
107
|
+
type: 'dragstart',
|
|
108
|
+
listener: cleanup
|
|
109
|
+
}], {
|
|
110
|
+
// Using `capture` is more likely to not be impacted by consumers stopping events
|
|
111
|
+
capture: true
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.getInput = getInput;
|
|
7
|
+
function getInput(event) {
|
|
8
|
+
return {
|
|
9
|
+
altKey: event.altKey,
|
|
10
|
+
button: event.button,
|
|
11
|
+
buttons: event.buttons,
|
|
12
|
+
ctrlKey: event.ctrlKey,
|
|
13
|
+
metaKey: event.metaKey,
|
|
14
|
+
shiftKey: event.shiftKey,
|
|
15
|
+
clientX: event.clientX,
|
|
16
|
+
clientY: event.clientY,
|
|
17
|
+
pageX: event.pageX,
|
|
18
|
+
pageY: event.pageY
|
|
19
|
+
};
|
|
20
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.once = once;
|
|
7
|
+
/** Provide a function that you only ever want to be called a single time */
|
|
8
|
+
function once(fn) {
|
|
9
|
+
var cache = null;
|
|
10
|
+
return function wrapped() {
|
|
11
|
+
if (!cache) {
|
|
12
|
+
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
13
|
+
args[_key] = arguments[_key];
|
|
14
|
+
}
|
|
15
|
+
var result = fn.apply(this, args);
|
|
16
|
+
cache = {
|
|
17
|
+
result: result
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
return cache.result;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.reorder = reorder;
|
|
8
|
+
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
9
|
+
/**
|
|
10
|
+
* Reorder a provided `list`
|
|
11
|
+
* Returns a new array and does not modify the original array
|
|
12
|
+
*/
|
|
13
|
+
function reorder(_ref) {
|
|
14
|
+
var list = _ref.list,
|
|
15
|
+
startIndex = _ref.startIndex,
|
|
16
|
+
finishIndex = _ref.finishIndex;
|
|
17
|
+
if (startIndex === -1 || finishIndex === -1) {
|
|
18
|
+
return list;
|
|
19
|
+
}
|
|
20
|
+
var result = Array.from(list);
|
|
21
|
+
var _result$splice = result.splice(startIndex, 1),
|
|
22
|
+
_result$splice2 = (0, _slicedToArray2.default)(_result$splice, 1),
|
|
23
|
+
removed = _result$splice2[0];
|
|
24
|
+
result.splice(finishIndex, 0, removed);
|
|
25
|
+
return result;
|
|
26
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.scrollJustEnoughIntoView = scrollJustEnoughIntoView;
|
|
7
|
+
/**
|
|
8
|
+
* Scroll an `element` just enough into view so that the element becomes totally visible.
|
|
9
|
+
* If the element is already totally visible then no scrolling will occur.
|
|
10
|
+
*/
|
|
11
|
+
function scrollJustEnoughIntoView(_ref) {
|
|
12
|
+
var element = _ref.element;
|
|
13
|
+
element.scrollIntoView({
|
|
14
|
+
block: 'nearest',
|
|
15
|
+
inline: 'nearest'
|
|
16
|
+
});
|
|
17
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.setCustomNativeDragPreview = setCustomNativeDragPreview;
|
|
7
|
+
var _elementAdapter = require("../adapter/element-adapter");
|
|
8
|
+
/** A function to remove the element that has been added to the `container`.
|
|
9
|
+
* @example () => ReactDOM.unmountComponentAtNode(container)
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/** A function that will render a preview element into a `container` `HTMLElement` */
|
|
13
|
+
|
|
14
|
+
/** Any valid CSS string value
|
|
15
|
+
* @example `calc(var(--grid) * 2)
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Where to place the custom drag preview
|
|
20
|
+
*
|
|
21
|
+
* `type: 'center'`: Place the center of the drag preview user the users pointer
|
|
22
|
+
*
|
|
23
|
+
* `type: 'offset-from-pointer'`: Shift the drag preview away from the users pointer
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
function setImage(_ref) {
|
|
27
|
+
var container = _ref.container,
|
|
28
|
+
placement = _ref.placement,
|
|
29
|
+
nativeSetDragImage = _ref.nativeSetDragImage;
|
|
30
|
+
if ((placement === null || placement === void 0 ? void 0 : placement.type) === 'center') {
|
|
31
|
+
var box = container.getBoundingClientRect();
|
|
32
|
+
nativeSetDragImage === null || nativeSetDragImage === void 0 ? void 0 : nativeSetDragImage(container, box.width / 2, box.height / 2);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
if ((placement === null || placement === void 0 ? void 0 : placement.type) === 'offset-from-pointer') {
|
|
36
|
+
// Using a transparent border to push the drag preview away
|
|
37
|
+
// from the user's pointer.
|
|
38
|
+
// In Chrome and Safari we could use `padding`:
|
|
39
|
+
// padding: 'var(--grid)',
|
|
40
|
+
// But it does not work in Firefox which trims the padding (or inner margin)
|
|
41
|
+
Object.assign(container.style, {
|
|
42
|
+
borderLeft: "".concat(placement.x, " solid transparent"),
|
|
43
|
+
borderTop: "".concat(placement.y, " solid transparent")
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
nativeSetDragImage === null || nativeSetDragImage === void 0 ? void 0 : nativeSetDragImage(container, 0, 0);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** This function provides the ability to mount an element for it to be used as the native drag preview
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* draggable({
|
|
53
|
+
* onGenerateDragPreview: ({ nativeSetDragImage }) => {
|
|
54
|
+
* setCustomNativeDragPreview({
|
|
55
|
+
* render: ({ container }) => {
|
|
56
|
+
* ReactDOM.render(<Preview item={item} />, container);
|
|
57
|
+
* return () => ReactDOM.unmountComponentAtNode(container);
|
|
58
|
+
* },
|
|
59
|
+
* nativeSetDragImage,
|
|
60
|
+
* });
|
|
61
|
+
* },
|
|
62
|
+
* });
|
|
63
|
+
*/
|
|
64
|
+
function setCustomNativeDragPreview(_ref2) {
|
|
65
|
+
var render = _ref2.render,
|
|
66
|
+
nativeSetDragImage = _ref2.nativeSetDragImage,
|
|
67
|
+
placement = _ref2.placement;
|
|
68
|
+
var container = document.createElement('div');
|
|
69
|
+
Object.assign(container.style, {
|
|
70
|
+
// Ensuring we don't cause reflow when adding the element to the page
|
|
71
|
+
// Using `position:fixed` rather than `position:absolute` so we are
|
|
72
|
+
// positioned on the current viewport.
|
|
73
|
+
// `position:fixed` also creates a new stacking context, so we don't need to do that here
|
|
74
|
+
position: 'fixed',
|
|
75
|
+
top: 0,
|
|
76
|
+
left: 0,
|
|
77
|
+
// Using maximum possible z-index so that this element will always be on top
|
|
78
|
+
// https://stackoverflow.com/questions/491052/minimum-and-maximum-value-of-z-index
|
|
79
|
+
// Did not use `layers` in `@atlaskit/theme` because:
|
|
80
|
+
// 1. This element is not a 'layer' in the conventional sense, as this element
|
|
81
|
+
// is only created for a single frame for the browser to take a photo of it,
|
|
82
|
+
// and then it is destroyed
|
|
83
|
+
// 2. Did not want to add a dependency onto `@atlaskit/theme`
|
|
84
|
+
// 3. Want to always be on top of product UI which might have higher z-index's
|
|
85
|
+
zIndex: 2147483647,
|
|
86
|
+
// Avoiding any additional events caused by the new element (being super safe)
|
|
87
|
+
pointerEvents: 'none'
|
|
88
|
+
});
|
|
89
|
+
document.body.append(container);
|
|
90
|
+
var unmount = render({
|
|
91
|
+
container: container
|
|
92
|
+
});
|
|
93
|
+
setImage({
|
|
94
|
+
container: container,
|
|
95
|
+
placement: placement,
|
|
96
|
+
nativeSetDragImage: nativeSetDragImage
|
|
97
|
+
});
|
|
98
|
+
function cleanup() {
|
|
99
|
+
unbindMonitor();
|
|
100
|
+
unmount === null || unmount === void 0 ? void 0 : unmount();
|
|
101
|
+
document.body.removeChild(container);
|
|
102
|
+
}
|
|
103
|
+
var unbindMonitor = (0, _elementAdapter.monitorForElements)({
|
|
104
|
+
// Remove portal in the dragstart event so that the user will never see it
|
|
105
|
+
onDragStart: cleanup,
|
|
106
|
+
// Backup: remove portal when the drop finishes (this would be an error case)
|
|
107
|
+
onDrop: cleanup
|
|
108
|
+
});
|
|
109
|
+
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { bind } from 'bind-event-listener';
|
|
2
|
+
import { makeAdapter } from '../make-adapter/make-adapter';
|
|
3
|
+
import { addAttribute } from '../util/add-attribute';
|
|
4
|
+
import { combine } from '../util/combine';
|
|
5
|
+
import { getInput } from '../util/get-input';
|
|
6
|
+
const draggableRegistry = new WeakMap();
|
|
7
|
+
function addToRegistry(args) {
|
|
8
|
+
draggableRegistry.set(args.element, args);
|
|
9
|
+
return function cleanup() {
|
|
10
|
+
draggableRegistry.delete(args.element);
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
const adapter = makeAdapter({
|
|
14
|
+
typeKey: 'element',
|
|
15
|
+
defaultDropEffect: 'move',
|
|
16
|
+
mount(api) {
|
|
17
|
+
return bind(window, {
|
|
18
|
+
type: 'dragstart',
|
|
19
|
+
listener(event) {
|
|
20
|
+
var _entry$dragHandle, _entry$dragHandle2, _entry$getInitialData, _entry$getInitialData2;
|
|
21
|
+
if (!api.canStart(event)) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
// the closest parent that is a draggable element will be marked as
|
|
25
|
+
// the `event.target` for the event
|
|
26
|
+
const target = event.target;
|
|
27
|
+
|
|
28
|
+
// this source is only for elements
|
|
29
|
+
// Note: only HTMLElements can have the "draggable" attribute
|
|
30
|
+
if (!(target instanceof HTMLElement)) {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// see if the thing being dragged is owned by us
|
|
35
|
+
const entry = draggableRegistry.get(target);
|
|
36
|
+
|
|
37
|
+
// no matching element found
|
|
38
|
+
// → dragging an element with `draggable="true"` that is not controlled by us
|
|
39
|
+
if (!entry) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
const input = getInput(event);
|
|
43
|
+
const feedback = {
|
|
44
|
+
element: entry.element,
|
|
45
|
+
dragHandle: (_entry$dragHandle = entry.dragHandle) !== null && _entry$dragHandle !== void 0 ? _entry$dragHandle : null,
|
|
46
|
+
input
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
// Check: does the draggable want to allow dragging?
|
|
50
|
+
if (entry.canDrag && !entry.canDrag(feedback)) {
|
|
51
|
+
// cancel drag operation if we cannot drag
|
|
52
|
+
event.preventDefault();
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Check: is there a drag handle and is the user using it?
|
|
57
|
+
if (entry.dragHandle) {
|
|
58
|
+
const over = document.elementFromPoint(input.clientX, input.clientY);
|
|
59
|
+
|
|
60
|
+
// if we are not dragging from the drag handle (or something inside the drag handle)
|
|
61
|
+
// then we will cancel the active drag
|
|
62
|
+
if (!entry.dragHandle.contains(over)) {
|
|
63
|
+
event.preventDefault();
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Must set any media type for iOS15 to work
|
|
69
|
+
// Doing this will fail in firefox though, so we
|
|
70
|
+
// wrap the operation in a try/catch
|
|
71
|
+
try {
|
|
72
|
+
var _event$dataTransfer;
|
|
73
|
+
(_event$dataTransfer = event.dataTransfer) === null || _event$dataTransfer === void 0 ? void 0 : _event$dataTransfer.setData('application/vnd.pdnd', '');
|
|
74
|
+
} catch (e) {}
|
|
75
|
+
const payload = {
|
|
76
|
+
element: entry.element,
|
|
77
|
+
dragHandle: (_entry$dragHandle2 = entry.dragHandle) !== null && _entry$dragHandle2 !== void 0 ? _entry$dragHandle2 : null,
|
|
78
|
+
data: (_entry$getInitialData = (_entry$getInitialData2 = entry.getInitialData) === null || _entry$getInitialData2 === void 0 ? void 0 : _entry$getInitialData2.call(entry, feedback)) !== null && _entry$getInitialData !== void 0 ? _entry$getInitialData : {}
|
|
79
|
+
};
|
|
80
|
+
const makeDragType = {
|
|
81
|
+
key: 'element',
|
|
82
|
+
startedFrom: 'internal',
|
|
83
|
+
payload
|
|
84
|
+
};
|
|
85
|
+
api.start({
|
|
86
|
+
event,
|
|
87
|
+
dragInterface: makeDragType
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
},
|
|
92
|
+
dispatchEventToSource: ({
|
|
93
|
+
eventName,
|
|
94
|
+
payload
|
|
95
|
+
}) => {
|
|
96
|
+
var _draggableRegistry$ge, _draggableRegistry$ge2;
|
|
97
|
+
// During a drag operation, a draggable can be:
|
|
98
|
+
// - remounted with different functions
|
|
99
|
+
// - removed completely
|
|
100
|
+
// So we need to get the latest entry from the registry in order
|
|
101
|
+
// to call the latest event functions
|
|
102
|
+
|
|
103
|
+
(_draggableRegistry$ge = draggableRegistry.get(payload.source.element)) === null || _draggableRegistry$ge === void 0 ? void 0 : (_draggableRegistry$ge2 = _draggableRegistry$ge[eventName]) === null || _draggableRegistry$ge2 === void 0 ? void 0 : _draggableRegistry$ge2.call(_draggableRegistry$ge,
|
|
104
|
+
// I cannot seem to get the types right here.
|
|
105
|
+
// TS doesn't seem to like that one event can need `nativeSetDragImage`
|
|
106
|
+
// @ts-expect-error
|
|
107
|
+
payload);
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
export const dropTargetForElements = adapter.dropTarget;
|
|
111
|
+
export const monitorForElements = adapter.monitor;
|
|
112
|
+
export function draggable(args) {
|
|
113
|
+
// Guardrail: warn if the drag handle is not contained in draggable element
|
|
114
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
115
|
+
if (args.dragHandle && !args.element.contains(args.dragHandle)) {
|
|
116
|
+
// eslint-disable-next-line no-console
|
|
117
|
+
console.warn('Drag handle element must be contained in draggable element', {
|
|
118
|
+
element: args.element,
|
|
119
|
+
dragHandle: args.dragHandle
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
// Guardrail: warn if the draggable element is already registered
|
|
124
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
125
|
+
const existing = draggableRegistry.get(args.element);
|
|
126
|
+
if (existing) {
|
|
127
|
+
// eslint-disable-next-line no-console
|
|
128
|
+
console.warn('You have already registered a `draggable` on the same element', {
|
|
129
|
+
existing,
|
|
130
|
+
proposed: args
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return combine(
|
|
135
|
+
// making the draggable register the adapter rather than drop targets
|
|
136
|
+
// this is because you *must* have a draggable element to start a drag
|
|
137
|
+
// but you _might_ not have any drop targets immediately
|
|
138
|
+
// (You might create drop targets async)
|
|
139
|
+
adapter.registerUsage(), addToRegistry(args), addAttribute(args.element, {
|
|
140
|
+
attribute: 'draggable',
|
|
141
|
+
value: 'true'
|
|
142
|
+
}));
|
|
143
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { bind } from 'bind-event-listener';
|
|
2
|
+
import { makeAdapter } from '../make-adapter/make-adapter';
|
|
3
|
+
import { combine } from '../util/combine';
|
|
4
|
+
import { isEnteringWindow } from '../util/entering-and-leaving-the-window';
|
|
5
|
+
function getFileItems(event) {
|
|
6
|
+
if (event.dataTransfer == null) {
|
|
7
|
+
return null;
|
|
8
|
+
}
|
|
9
|
+
// filtering out anything that is not a file
|
|
10
|
+
const items = event.dataTransfer.items;
|
|
11
|
+
for (let i = 0; i < items.length; i++) {
|
|
12
|
+
const item = items[i];
|
|
13
|
+
if (item.kind !== 'file') {
|
|
14
|
+
items.remove(i);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return items;
|
|
18
|
+
}
|
|
19
|
+
const adapter = makeAdapter({
|
|
20
|
+
typeKey: 'file',
|
|
21
|
+
defaultDropEffect: 'copy',
|
|
22
|
+
mount(api) {
|
|
23
|
+
return bind(window, {
|
|
24
|
+
type: 'dragenter',
|
|
25
|
+
listener(event) {
|
|
26
|
+
if (!api.canStart(event)) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// already cancelled by something else
|
|
31
|
+
if (event.defaultPrevented) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
if (!isEnteringWindow({
|
|
35
|
+
dragEnter: event
|
|
36
|
+
})) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
if (event.dataTransfer == null) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Checking if we are dragging any files
|
|
44
|
+
// This check works in Chrome, Firefox and Chrome
|
|
45
|
+
if (!event.dataTransfer.types.includes('Files')) {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
const dragInterface = {
|
|
49
|
+
key: 'file',
|
|
50
|
+
startedFrom: 'external',
|
|
51
|
+
payload: {
|
|
52
|
+
// Not giving `.items` initially as it cannot be safely and consistently
|
|
53
|
+
// accessed across browsers
|
|
54
|
+
// Not giving `.types` as the consumer already knows a file is being dragged
|
|
55
|
+
items: null
|
|
56
|
+
},
|
|
57
|
+
getDropPayload(event) {
|
|
58
|
+
return {
|
|
59
|
+
items: getFileItems(event)
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
api.start({
|
|
64
|
+
event,
|
|
65
|
+
dragInterface
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// Some events don't make sense for external files
|
|
73
|
+
//
|
|
74
|
+
// onGenerateDragPreview: drag preview is always generated by the browser
|
|
75
|
+
// type WithoutUselessEvents<T> = Omit<T, 'onDragStart' | 'onGenerateDragPreview'>;
|
|
76
|
+
//
|
|
77
|
+
// onDragStart: an external file can never start from inside a drop target
|
|
78
|
+
// (it will always come from outside and we never let a file drag start in a drop target)
|
|
79
|
+
// We remove `onDragStart` from drop targets, but monitors can still listen for a start
|
|
80
|
+
export const dropTargetForFiles = args => {
|
|
81
|
+
return combine(
|
|
82
|
+
// at least one drop target required before we will start listening for file events
|
|
83
|
+
adapter.registerUsage(),
|
|
84
|
+
// note: not removing unsupported events from args; just leaning on the type system
|
|
85
|
+
adapter.dropTarget(args));
|
|
86
|
+
};
|
|
87
|
+
export const monitorForFiles = args => {
|
|
88
|
+
// note: not removing unsupported events from args; just leaning on the type system
|
|
89
|
+
return adapter.monitor(args);
|
|
90
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { bindAll } from 'bind-event-listener';
|
|
2
|
+
function cancel(event) {
|
|
3
|
+
// if `@atlaskit/pragmatic-drag-and-drop` has already prevented the event
|
|
4
|
+
// we don't need to do anything
|
|
5
|
+
if (event.defaultPrevented) {
|
|
6
|
+
return;
|
|
7
|
+
}
|
|
8
|
+
// Using "move" as the drop effect as that uses the standard
|
|
9
|
+
// cursor. Doing this so the user doesn't think they are dropping
|
|
10
|
+
// on the page
|
|
11
|
+
// Note: using "none" will not allow a drop to occur, so we are using "move"
|
|
12
|
+
if (event.dataTransfer) {
|
|
13
|
+
event.dataTransfer.dropEffect = 'move';
|
|
14
|
+
}
|
|
15
|
+
// cancel the default browser behaviour
|
|
16
|
+
// doing this will tell the browser that we have handled the drop
|
|
17
|
+
event.preventDefault();
|
|
18
|
+
}
|
|
19
|
+
let unbindEvents = null;
|
|
20
|
+
/**
|
|
21
|
+
* Block drag operations outside of `@atlaskit/pragmatic-drag-and-drop`
|
|
22
|
+
*/
|
|
23
|
+
export const cancelUnhandled = {
|
|
24
|
+
start() {
|
|
25
|
+
var _unbindEvents;
|
|
26
|
+
(_unbindEvents = unbindEvents) === null || _unbindEvents === void 0 ? void 0 : _unbindEvents();
|
|
27
|
+
unbindEvents = bindAll(window, [{
|
|
28
|
+
type: 'dragover',
|
|
29
|
+
listener: cancel
|
|
30
|
+
}, {
|
|
31
|
+
type: 'dragenter',
|
|
32
|
+
listener: cancel
|
|
33
|
+
}, {
|
|
34
|
+
type: 'drop',
|
|
35
|
+
listener: cancel
|
|
36
|
+
}]);
|
|
37
|
+
},
|
|
38
|
+
stop() {
|
|
39
|
+
var _unbindEvents2;
|
|
40
|
+
(_unbindEvents2 = unbindEvents) === null || _unbindEvents2 === void 0 ? void 0 : _unbindEvents2();
|
|
41
|
+
unbindEvents = null;
|
|
42
|
+
}
|
|
43
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { draggable, dropTargetForElements, monitorForElements } from '../../adapter/element-adapter';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { monitorForFiles, dropTargetForFiles } from '../../adapter/file-adapter';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { cancelUnhandled } from '../../addon/cancel-unhandled';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { setCrossWindowData, extractCrossWindowResult, dropTargetForCrossWindowElements, monitorForCrossWindowElements } from '../../experimental/cross-window-element-adapter';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { combine } from '../../util/combine';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { disableNativeDragPreview } from '../../util/disable-native-drag-preview';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { once } from '../../util/once';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { reorder } from '../../util/reorder';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { scrollJustEnoughIntoView } from '../../util/scroll-just-enough-into-view';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { setCustomNativeDragPreview } from '../../util/set-custom-native-drag-preview';
|