Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
schedule.cancel();
unbindWindowEventsRef.current();
isDraggingRef.current = false;
onCaptureEnd();
}, [getIsDragging, onCaptureEnd, schedule]);
const cancel = useCallback(() => {
const wasDragging: boolean = isDraggingRef.current;
stop();
if (wasDragging) {
callbacks.onCancel();
}
}, [callbacks, stop]);
const windowBindings: EventBinding[] = useMemo(() => {
invariant(
!getIsDragging(),
'Should not recreate window bindings when dragging',
);
return [
// any mouse actions kills a drag
{
eventName: 'mousedown',
fn: cancel,
},
{
eventName: 'mouseup',
fn: cancel,
},
{
eventName: 'click',
export default function useRegistry(): Registry {
const registry: Registry = useMemo(createRegistry, []);
useEffect(() => {
return function unmount() {
// clean up the registry to avoid any leaks
// doing it after an animation frame so that other things unmounting
// can continue to interact with the registry
requestAnimationFrame(registry.clean);
};
}, [registry]);
return registry;
}
export default function useLiftInstruction(
contextId: ContextId,
liftInstruction: string,
): ElementId {
const id: string = useMemo(() => getId(contextId), [contextId]);
useEffect(
function mount() {
const el: HTMLElement = document.createElement('div');
// identifier
el.id = id;
// add the description text
el.textContent = liftInstruction;
// Using `display: none` prevent screen readers from reading this element in the document flow
// This element is used as a `aria-labelledby` reference for *other elements* and will be read out for those
Object.assign(el.style, { display: 'none' });
// Add to body
export default function useMouseSensor(api: SensorAPI) {
const phaseRef = useRef(idle);
const unbindEventsRef = useRef<() => void>(noop);
const startCaptureBinding: EventBinding = useMemo(
() => ({
eventName: 'mousedown',
fn: function onMouseDown(event: MouseEvent) {
// Event already used
if (event.defaultPrevented) {
return;
}
// only starting a drag if dragging with the primary mouse button
if (event.button !== primaryButton) {
return;
}
// Do not start a drag if any modifier key is pressed
if (event.ctrlKey || event.metaKey || event.shiftKey || event.altKey) {
return;
}
);
callbacks.onCancel();
}
}
// Handle aborting
// No longer dragging but still capturing: need to abort
// Using a layout effect to ensure that there is a flip from isDragging => !isDragging
// When there is a pending drag !isDragging will always be true
useLayoutEffect(() => {
if (!isDragging && capturingRef.current) {
abortCapture();
}
}, [abortCapture, isDragging]);
const props: ?DragHandleProps = useMemo(() => {
if (!isEnabled) {
return null;
}
return {
onMouseDown,
onKeyDown,
onTouchStart,
onFocus,
onBlur,
tabIndex: 0,
'data-react-beautiful-dnd-drag-handle': styleContext,
// English default. Consumers are welcome to add their own start instruction
'aria-roledescription': 'Draggable item. Press space bar to lift',
// Opting out of html5 drag and drops
draggable: false,
onDragStart: preventHtml5Dnd,
y: event.clientY,
};
// unbind this listener
unbindEventsRef.current();
// using this function before it is defined as their is a circular usage pattern
// eslint-disable-next-line no-use-before-define
startPendingDrag(actions, point);
},
}),
// not including startPendingDrag as it is not defined initially
// eslint-disable-next-line react-hooks/exhaustive-deps
[api],
);
const preventForcePressBinding: EventBinding = useMemo(
() => ({
eventName: 'webkitmouseforcewillbegin',
fn: (event: Event) => {
if (event.defaultPrevented) {
return;
}
const id: ?DraggableId = api.findClosestDraggableId(event);
if (!id) {
return;
}
const options: ?DraggableOptions = api.findOptionsForDraggable(id);
if (!options) {
export default function useAnnouncer(contextId: ContextId): Announce {
const id: string = useMemo(() => getId(contextId), [contextId]);
const ref = useRef(null);
useEffect(
function setup() {
const el: HTMLElement = document.createElement('div');
// storing reference for usage in announce
ref.current = el;
// identifier
el.id = id;
// Aria live region
// will force itself to be read
el.setAttribute('aria-live', 'assertive');
el.setAttribute('role', 'log');
export default function useMouseSensor(api: SensorAPI) {
const phaseRef = useRef(idle);
const unbindEventsRef = useRef<() => void>(noop);
const getPhase = useCallback(function getPhase(): Phase {
return phaseRef.current;
}, []);
const setPhase = useCallback(function setPhase(phase: Phase) {
phaseRef.current = phase;
}, []);
const startCaptureBinding: EventBinding = useMemo(
() => ({
eventName: 'touchstart',
fn: function onTouchStart(event: TouchEvent) {
// Event already used by something else
if (event.defaultPrevented) {
return;
}
// We need to NOT call event.preventDefault() so as to maintain as much standard
// browser interactions as possible.
// This includes navigation on anchors which we want to preserve
const draggableId: ?DraggableId = api.findClosestDraggableId(event);
if (!draggableId) {
return;
onCaptureEnd,
getShouldRespectForcePress,
}),
[
callbacks,
getDraggableRef,
getWindow,
canStartCapturing,
onCaptureStart,
onCaptureEnd,
getShouldRespectForcePress,
],
);
const onMouseDown = useMouseSensor(mouseArgs);
const keyboardArgs: KeyboardSensorArgs = useMemo(
() => ({
callbacks,
getDraggableRef,
getWindow,
canStartCapturing,
onCaptureStart,
onCaptureEnd,
}),
[
callbacks,
canStartCapturing,
getDraggableRef,
getWindow,
onCaptureEnd,
onCaptureStart,
],
return;
}
recordRef.current = id;
}, []);
useLayoutEffect(() => {
return function clearFrameOnUnmount() {
const frameId: ?AnimationFrameID = restoreFocusFrameRef.current;
if (frameId) {
cancelAnimationFrame(frameId);
}
};
}, []);
const marshal: FocusMarshal = useMemo(
() => ({
register,
tryRecordFocus,
tryRestoreFocusRecorded,
tryShiftRecord,
}),
[register, tryRecordFocus, tryRestoreFocusRecorded, tryShiftRecord],
);
return marshal;
}