(e: DragEvent)
| 125 | let modalityOnPointerDown = useRef<string>(null); |
| 126 | |
| 127 | let onDragStart = (e: DragEvent) => { |
| 128 | if (e.defaultPrevented) { |
| 129 | return; |
| 130 | } |
| 131 | |
| 132 | // Prevent the drag event from propagating to any parent draggables |
| 133 | e.stopPropagation(); |
| 134 | |
| 135 | // If this drag was initiated by a mobile screen reader (e.g. VoiceOver or TalkBack), enter virtual dragging mode. |
| 136 | if (modalityOnPointerDown.current === 'virtual') { |
| 137 | e.preventDefault(); |
| 138 | startDragging(getEventTarget(e) as HTMLElement); |
| 139 | modalityOnPointerDown.current = null; |
| 140 | return; |
| 141 | } |
| 142 | |
| 143 | if (typeof options.onDragStart === 'function') { |
| 144 | options.onDragStart({ |
| 145 | type: 'dragstart', |
| 146 | x: e.clientX, |
| 147 | y: e.clientY |
| 148 | }); |
| 149 | } |
| 150 | |
| 151 | let items = options.getItems(); |
| 152 | // Clear existing data (e.g. selected text on the page would be included in some browsers) |
| 153 | e.dataTransfer.clearData?.(); |
| 154 | writeToDataTransfer(e.dataTransfer, items); |
| 155 | |
| 156 | let allowed = DROP_OPERATION.all; |
| 157 | if (typeof options.getAllowedDropOperations === 'function') { |
| 158 | let allowedOperations = options.getAllowedDropOperations(); |
| 159 | allowed = DROP_OPERATION.none; |
| 160 | for (let operation of allowedOperations) { |
| 161 | allowed |= DROP_OPERATION[operation] || DROP_OPERATION.none; |
| 162 | } |
| 163 | } |
| 164 | |
| 165 | setGlobalAllowedDropOperations(allowed); |
| 166 | let effectAllowed = EFFECT_ALLOWED[allowed] || 'none'; |
| 167 | e.dataTransfer.effectAllowed = effectAllowed === 'cancel' ? 'none' : effectAllowed; |
| 168 | |
| 169 | // If there is a preview option, use it to render a custom preview image that will |
| 170 | // appear under the pointer while dragging. If not, the element itself is dragged by the browser. |
| 171 | if (typeof options.preview?.current === 'function') { |
| 172 | options.preview.current(items, (node, userX, userY) => { |
| 173 | if (!node) { |
| 174 | return; |
| 175 | } |
| 176 | // Compute the offset that the preview will appear under the mouse. |
| 177 | // If possible, this is based on the point the user clicked on the target. |
| 178 | // If the preview is much smaller, then just use the center point of the preview. |
| 179 | let size = node.getBoundingClientRect(); |
| 180 | let rect = e.currentTarget.getBoundingClientRect(); |
| 181 | let defaultX = e.clientX - rect.x; |
| 182 | let defaultY = e.clientY - rect.y; |
| 183 | if (defaultX > size.width || defaultY > size.height) { |
| 184 | defaultX = size.width / 2; |
no test coverage detected