React: Prevent MUI Draggable Dialog From Going Off Screen

Viewed 317

I am working with the MUI library, specifically with the Draggable Dialog component seen here.

My question is how do I stop the dialog from being dragged off the screen?

I have tried this inside the Paper Component, but its not working:

import * as React from 'react';
import Paper, { PaperProps } from '@mui/material/Paper';
import Draggable, { DraggableEvent, DraggableData } from 'react-draggable';
export const PaperComponent = (props: PaperProps) => {
  const widgetContainerRef = React.useRef<HTMLInputElement>(null);
  const [widgetState, setWidgetState] = React.useState({
    visible: false,
    disabled: true,
    bounds: { left: 0, top: 0, bottom: 0, right: 0 },
  });
  // const draggleRef = useRef<HTMLInputElement>(null);
  const onStart = (event: DraggableEvent, uiData: DraggableData) => {
    const { clientWidth, clientHeight } = window?.document?.documentElement;
    const targetRect = widgetContainerRef?.current?.getBoundingClientRect();
    if (targetRect) {
      setWidgetState((prevState) => ({
        ...prevState,
        bounds: {
          left: -targetRect?.left + uiData?.x,
          right: clientWidth - (targetRect?.right - uiData?.x),
          top: -targetRect?.top + uiData?.y,
          bottom: clientHeight - (targetRect?.bottom - uiData?.y),
        },
      }));
    }
  };
  return (
    <Draggable
      handle="#draggable-dialog-title"
      cancel={'[class*="MuiDialogContent-root"]'}
      nodeRef={widgetContainerRef}
      onStart={(event, uiData) => onStart(event, uiData)}
    >
      {/* <Resizable height={scaler.height} width={scaler.width} onResize={onResize}> */}
      <div ref={widgetContainerRef}>
        <Paper {...props} />
      </div>
    </Draggable>
  );
};

Would anyone know how to prevent my user from dragging the dialog off the screen?

2 Answers

Looks like I overlooked a little thing here. It works if you add :

<Draggable
...
bounds={widgetState.bounds}
>
<div ref={widgetContainerRef}>
  <Paper {...props} />
 </div>
</Draggable>

Use onDrag Prop to prevent from being dragged, just return false on a specific scenario

      onDrag={(e: any) => {
        const from = e.relatedTarget || e.toElement;
        if (!from || from.nodeName === EVENT_NODE_NAME.HTML) {
          // stop your drag event here
          return false;
        }
      }}
      handle='#event-max-dialog'
      cancel={'[class*="MuiDialogContent-root"]'}>```
Related