@toptal/picasso-modal 100.0.1 → 100.1.1

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.
@@ -22,6 +22,8 @@ export interface Props extends BaseProps, HTMLAttributes<HTMLDivElement> {
22
22
  container?: ContainerValue;
23
23
  /** If `true`, the backdrop is not rendered */
24
24
  hideBackdrop?: boolean;
25
+ /** If `true`, the backdrop is rendered even when nested in another dialog */
26
+ forceRenderBackdrop?: boolean;
25
27
  /** Position of the modal relative to the browser's viewport */
26
28
  align?: Alignment;
27
29
  /** Animation lifecycle callbacks. Backed by [react-transition-group/Transition](https://reactcommunity.org/react-transition-group/transition#Transition-props) */
@@ -1 +1 @@
1
- {"version":3,"file":"Modal.d.ts","sourceRoot":"","sources":["../../../src/Modal/Modal.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,OAAO,CAAA;AAEtD,OAAO,KAAoD,MAAM,OAAO,CAAA;AACxE,OAAO,KAAK,EACV,SAAS,EACT,QAAQ,EACR,eAAe,EAChB,MAAM,wBAAwB,CAAA;AAc/B,KAAK,cAAc,GAAG,WAAW,GAAG,CAAC,MAAM,WAAW,CAAC,CAAA;AACvD,KAAK,SAAS,GAAG,KAAK,GAAG,UAAU,CAAA;AAEnC,MAAM,WAAW,KAAM,SAAQ,SAAS,EAAE,cAAc,CAAC,cAAc,CAAC;IACtE,iCAAiC;IACjC,QAAQ,EAAE,SAAS,CAAA;IACnB,wCAAwC;IACxC,IAAI,EAAE,OAAO,CAAA;IACb,qBAAqB;IACrB,IAAI,CAAC,EACD,QAAQ,CAAC,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAC,GAC5D,aAAa,CAAA;IACjB,kDAAkD;IAClD,eAAe,CAAC,EAAE,MAAM,IAAI,CAAA;IAC5B,oFAAoF;IACpF,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAC9B,uDAAuD;IACvD,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB,mDAAmD;IACnD,MAAM,CAAC,EAAE,MAAM,IAAI,CAAA;IACnB,2GAA2G;IAC3G,SAAS,CAAC,EAAE,cAAc,CAAA;IAC1B,8CAA8C;IAC9C,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,+DAA+D;IAC/D,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB,kKAAkK;IAClK,eAAe,CAAC,EAAE,eAAe,CAAA;IACjC,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,gFAAgF;IAChF,UAAU,CAAC,EAAE,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,CAAA;IACjD,OAAO,CAAC,EAAE;QACR,WAAW,CAAC,EAAE,MAAM,CAAA;KACrB,CAAA;IACD,OAAO,CAAC,EAAE;QACR,WAAW,CAAC,EAAE,MAAM,CAAA;KACrB,CAAA;CACF;AAyDD,eAAO,MAAM,KAAK,8EA4KhB,CAAA;AAIF,eAAe,KAAK,CAAA"}
1
+ {"version":3,"file":"Modal.d.ts","sourceRoot":"","sources":["../../../src/Modal/Modal.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,OAAO,CAAA;AAEtD,OAAO,KAAoD,MAAM,OAAO,CAAA;AACxE,OAAO,KAAK,EACV,SAAS,EACT,QAAQ,EACR,eAAe,EAChB,MAAM,wBAAwB,CAAA;AAc/B,KAAK,cAAc,GAAG,WAAW,GAAG,CAAC,MAAM,WAAW,CAAC,CAAA;AACvD,KAAK,SAAS,GAAG,KAAK,GAAG,UAAU,CAAA;AAEnC,MAAM,WAAW,KAAM,SAAQ,SAAS,EAAE,cAAc,CAAC,cAAc,CAAC;IACtE,iCAAiC;IACjC,QAAQ,EAAE,SAAS,CAAA;IACnB,wCAAwC;IACxC,IAAI,EAAE,OAAO,CAAA;IACb,qBAAqB;IACrB,IAAI,CAAC,EACD,QAAQ,CAAC,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAC,GAC5D,aAAa,CAAA;IACjB,kDAAkD;IAClD,eAAe,CAAC,EAAE,MAAM,IAAI,CAAA;IAC5B,oFAAoF;IACpF,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAC9B,uDAAuD;IACvD,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB,mDAAmD;IACnD,MAAM,CAAC,EAAE,MAAM,IAAI,CAAA;IACnB,2GAA2G;IAC3G,SAAS,CAAC,EAAE,cAAc,CAAA;IAC1B,8CAA8C;IAC9C,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,6EAA6E;IAC7E,mBAAmB,CAAC,EAAE,OAAO,CAAA;IAC7B,+DAA+D;IAC/D,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB,kKAAkK;IAClK,eAAe,CAAC,EAAE,eAAe,CAAA;IACjC,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,gFAAgF;IAChF,UAAU,CAAC,EAAE,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,CAAA;IACjD,OAAO,CAAC,EAAE;QACR,WAAW,CAAC,EAAE,MAAM,CAAA;KACrB,CAAA;IACD,OAAO,CAAC,EAAE;QACR,WAAW,CAAC,EAAE,MAAM,CAAA;KACrB,CAAA;CACF;AAyDD,eAAO,MAAM,KAAK,8EAuMhB,CAAA;AAIF,eAAe,KAAK,CAAA"}
@@ -57,12 +57,14 @@ const generateKey = (() => {
57
57
  })();
58
58
  // eslint-disable-next-line react/display-name
59
59
  export const Modal = forwardRef(function Modal(_a, ref) {
60
- var { hideBackdrop = false, disableBackdropClick = false, size = 'medium', transitionDuration = 300, align = 'centered' } = _a, props = __rest(_a, ["hideBackdrop", "disableBackdropClick", "size", "transitionDuration", "align"]);
61
- const { children, open, onBackdropClick, onClose, onOpen, onClick, className, style, container, paperProps, testIds, transitionProps, classes } = props, rest = __rest(props, ["children", "open", "onBackdropClick", "onClose", "onOpen", "onClick", "className", "style", "container", "paperProps", "testIds", "transitionProps", "classes"]);
60
+ var { hideBackdrop = false, forceRenderBackdrop = true, disableBackdropClick = false, size = 'medium', transitionDuration = 300, align = 'centered' } = _a, props = __rest(_a, ["hideBackdrop", "forceRenderBackdrop", "disableBackdropClick", "size", "transitionDuration", "align"]);
61
+ const { children, open, onBackdropClick, onClose, onOpen, onClick, onMouseDown, onMouseUp, className, style, container, paperProps, testIds, transitionProps, classes } = props, rest = __rest(props, ["children", "open", "onBackdropClick", "onClose", "onOpen", "onClick", "onMouseDown", "onMouseUp", "className", "style", "container", "paperProps", "testIds", "transitionProps", "classes"]);
62
62
  const picassoRootContainer = usePicassoRoot();
63
63
  const modalRef = useCombinedRefs(ref, useRef(null));
64
64
  const modalId = useRef(generateKey());
65
65
  const wasOpen = useRef(false);
66
+ const mouseDownOnPopupRef = useRef(false);
67
+ const mouseUpOnPopupRef = useRef(false);
66
68
  const { rootRef } = useContext(RootContext);
67
69
  useEffect(() => {
68
70
  const handleDocumentFocus = () => {
@@ -111,8 +113,21 @@ export const Modal = forwardRef(function Modal(_a, ref) {
111
113
  const durationStyle = { transitionDuration: `${duration}ms` };
112
114
  const resolvedContainer = (typeof container === 'function' ? container() : container) ||
113
115
  picassoRootContainer;
116
+ const handlePopupMouseDown = (event) => {
117
+ mouseDownOnPopupRef.current = event.target === event.currentTarget;
118
+ onMouseDown === null || onMouseDown === void 0 ? void 0 : onMouseDown(event);
119
+ };
120
+ const handlePopupMouseUp = (event) => {
121
+ mouseUpOnPopupRef.current = event.target === event.currentTarget;
122
+ onMouseUp === null || onMouseUp === void 0 ? void 0 : onMouseUp(event);
123
+ };
114
124
  const handlePopupClick = (event) => {
115
- if (event.target === event.currentTarget && !disableBackdropClick) {
125
+ // a drag between the backdrop and the content dispatches its click on the
126
+ // common ancestor — this popup — so both ends must have been on it
127
+ if (mouseDownOnPopupRef.current &&
128
+ mouseUpOnPopupRef.current &&
129
+ event.target === event.currentTarget &&
130
+ !disableBackdropClick) {
116
131
  onBackdropClick === null || onBackdropClick === void 0 ? void 0 : onBackdropClick();
117
132
  onClose === null || onClose === void 0 ? void 0 : onClose();
118
133
  }
@@ -129,13 +144,13 @@ export const Modal = forwardRef(function Modal(_a, ref) {
129
144
  }
130
145
  } },
131
146
  React.createElement(BaseUIDialog.Portal, { container: resolvedContainer },
132
- !hideBackdrop && (React.createElement(BaseUIDialog.Backdrop, { className: 'fixed z-modal inset-0 bg-black/50 transition-opacity data-starting-style:opacity-0 data-ending-style:opacity-0', style: durationStyle })),
147
+ !hideBackdrop && (React.createElement(BaseUIDialog.Backdrop, { forceRender: forceRenderBackdrop, className: 'fixed z-modal inset-0 bg-black/50 transition-opacity data-starting-style:opacity-0 data-ending-style:opacity-0', style: durationStyle })),
133
148
  React.createElement(BaseUIDialog.Popup, Object.assign({}, rest, { ref: modalRef, initialFocus: () => {
134
149
  var _a;
135
150
  return ((_a = modalRef.current) === null || _a === void 0 ? void 0 : _a.contains(document.activeElement))
136
151
  ? undefined
137
152
  : modalRef.current;
138
- }, className: twMerge('fixed z-modal inset-0 flex flex-col text-lg leading-[normal] justify-center items-center transition-opacity data-starting-style:opacity-0 data-ending-style:opacity-0', className), style: Object.assign(Object.assign({}, style), durationStyle), onClick: handlePopupClick }),
153
+ }, className: twMerge('fixed z-modal inset-0 flex flex-col text-lg leading-[normal] justify-center items-center transition-opacity data-starting-style:opacity-0 data-ending-style:opacity-0', className), style: Object.assign(Object.assign({}, style), durationStyle), onClick: handlePopupClick, onMouseDown: handlePopupMouseDown, onMouseUp: handlePopupMouseUp }),
139
154
  React.createElement(ModalPaper, Object.assign({ size: size, align: align, tabIndex: -1 }, paperProps),
140
155
  React.createElement(ModalContext.Provider, { value: true },
141
156
  children,
@@ -1 +1 @@
1
- {"version":3,"file":"Modal.js","sourceRoot":"","sources":["../../../src/Modal/Modal.tsx"],"names":[],"mappings":";;;;;;;;;;;AACA,OAAO,EAAE,MAAM,IAAI,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAC9D,OAAO,KAAK,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,OAAO,CAAA;AAMxE,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AACpD,OAAO,EACL,eAAe,EACf,YAAY,EACZ,iBAAiB,GAClB,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AACvD,OAAO,YAAY,MAAM,+BAA+B,CAAA;AACxD,OAAO,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAA;AAExD,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAyC1C,MAAM,cAAc,GAAG,IAAI,YAAY,EAAE,CAAA;AAEzC,kHAAkH;AAClH,6FAA6F;AAC7F,MAAM,uBAAuB,GAC3B,gLAAgL,CAAA;AAClL,2EAA2E;AAC3E,iFAAiF;AACjF,MAAM,0BAA0B,GAAG,uCAAuC,CAAA;AAE1E,MAAM,0BAA0B,GAAG,CAAC,IAAa,EAAE,EAAE;IACnD,MAAM,QAAQ,GAAG,IAAI,CAAC,gBAAgB,CAAC,uBAAuB,CAAC,CAAA;IAC/D,4BAA4B;IAC5B,MAAM,iBAAiB,GAAG,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;IAE9D,IAAI,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACjC,iBAAiB,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAA;IAC9B,CAAC;AACH,CAAC,CAAA;AAED,MAAM,kBAAkB,GAAG,CAAC,SAAkB,EAAE,EAAE;IAChD,MAAM,2BAA2B,GAAG,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAA;IAE9E,IAAI,2BAA2B,EAAE,CAAC;QAChC,OAAO,IAAI,CAAA;IACb,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC,CAAA;AAED,MAAM,wBAAwB,GAAG,GAAG,EAAE;IACpC,MAAM,eAAe,GAAG,QAAQ,CAAC,gBAAgB,CAAC,0BAA0B,CAAC,CAAA;IAE7E,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjC,OAAO,KAAK,CAAA;IACd,CAAC;IAED,MAAM,2BAA2B,GAAG,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,IAAI,CAClE,SAAS,CAAC,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,aAAa,CAAC,CACxD,CAAA;IAED,IAAI,2BAA2B,EAAE,CAAC;QAChC,OAAO,IAAI,CAAA;IACb,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC,CAAA;AAED,MAAM,WAAW,GAAG,CAAC,GAAG,EAAE;IACxB,IAAI,KAAK,GAAG,CAAC,CAAA;IAEb,OAAO,GAAG,EAAE,CAAC,EAAE,KAAK,CAAA;AACtB,CAAC,CAAC,EAAE,CAAA;AAEJ,8CAA8C;AAC9C,MAAM,CAAC,MAAM,KAAK,GAAG,UAAU,CAAwB,SAAS,KAAK,CACnE,EAOC,EACD,GAAG;QARH,EACE,YAAY,GAAG,KAAK,EACpB,oBAAoB,GAAG,KAAK,EAC5B,IAAI,GAAG,QAAQ,EACf,kBAAkB,GAAG,GAAG,EACxB,KAAK,GAAG,UAAU,OAEnB,EADI,KAAK,cANV,+EAOC,CADS;IAIV,MAAM,EACJ,QAAQ,EACR,IAAI,EACJ,eAAe,EACf,OAAO,EACP,MAAM,EACN,OAAO,EACP,SAAS,EACT,KAAK,EACL,SAAS,EACT,UAAU,EACV,OAAO,EACP,eAAe,EACf,OAAO,KAEL,KAAK,EADJ,IAAI,UACL,KAAK,EAfH,iKAeL,CAAQ,CAAA;IACT,MAAM,oBAAoB,GAAG,cAAc,EAAE,CAAA;IAC7C,MAAM,QAAQ,GAAG,eAAe,CAC9B,GAAG,EACH,MAAM,CAAiB,IAAI,CAAC,CAC7B,CAAA;IACD,MAAM,OAAO,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC,CAAA;IACrC,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,CAAA;IAC7B,MAAM,EAAE,OAAO,EAAE,GAAG,UAAU,CAAC,WAAW,CAAC,CAAA;IAE3C,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,mBAAmB,GAAG,GAAG,EAAE;YAC/B,IAAI,CAAC,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,OAAO,CAAA,EAAE,CAAC;gBACtB,OAAO,CAAC,IAAI,CACV,mIAAmI,CACpI,CAAA;YACH,CAAC;YAED,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;gBAChD,OAAM;YACR,CAAC;YAED,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;gBACnC,OAAM;YACR,CAAC;YAED,IAAI,kBAAkB,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;gBACzC,OAAM;YACR,CAAC;YAED,IAAI,wBAAwB,EAAE,EAAE,CAAC;gBAC/B,OAAM;YACR,CAAC;YAED,0BAA0B,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;QAC9C,CAAC,CAAA;QAED,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAM;QACR,CAAC;QAED,QAAQ,CAAC,gBAAgB,CAAC,OAAO,EAAE,mBAAmB,EAAE,IAAI,CAAC,CAAA;QAE7D,OAAO,GAAG,EAAE;YACV,QAAQ,CAAC,mBAAmB,CAAC,OAAO,EAAE,mBAAmB,EAAE,IAAI,CAAC,CAAA;QAClE,CAAC,CAAA;IACH,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAA;IAE7B,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,cAAc,GAAG,OAAO,CAAC,OAAO,CAAA;QAEtC,IAAI,IAAI,EAAE,CAAC;YACT,cAAc,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;QACpC,CAAC;QAED,OAAO,GAAG,EAAE;YACV,cAAc,CAAC,MAAM,CAAC,cAAc,CAAC,CAAA;QACvC,CAAC,CAAA;IACH,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAA;IAEV,iBAAiB,CAAC,IAAI,CAAC,CAAA;IAEvB,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YAC7B,MAAM,aAAN,MAAM,uBAAN,MAAM,EAAI,CAAA;QACZ,CAAC;QACD,OAAO,CAAC,OAAO,GAAG,IAAI,CAAA;IACxB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAA;IAElB,MAAM,QAAQ,GAAG,CAAA,eAAe,aAAf,eAAe,uBAAf,eAAe,CAAE,OAAO,KAAI,kBAAkB,CAAA;IAC/D,MAAM,aAAa,GAAG,EAAE,kBAAkB,EAAE,GAAG,QAAQ,IAAI,EAAE,CAAA;IAE7D,MAAM,iBAAiB,GACrB,CAAC,OAAO,SAAS,KAAK,UAAU,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QAC3D,oBAAoB,CAAA;IAEtB,MAAM,gBAAgB,GAAG,CAAC,KAAuC,EAAE,EAAE;QACnE,IAAI,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,aAAa,IAAI,CAAC,oBAAoB,EAAE,CAAC;YAClE,eAAe,aAAf,eAAe,uBAAf,eAAe,EAAI,CAAA;YACnB,OAAO,aAAP,OAAO,uBAAP,OAAO,EAAI,CAAA;QACb,CAAC;QAED,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAG,KAAK,CAAC,CAAA;IAClB,CAAC,CAAA;IAED,OAAO,CACL,oBAAC,YAAY,CAAC,IAAI,IAChB,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,KAAK,EACZ,uBAAuB,QACvB,YAAY,EAAE,MAAM,CAAC,EAAE;YACrB,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,OAAO,aAAP,OAAO,uBAAP,OAAO,EAAI,CAAA;YACb,CAAC;QACH,CAAC,EACD,oBAAoB,EAAE,MAAM,CAAC,EAAE;;YAC7B,IAAI,CAAC,MAAM,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;gBAChC,MAAA,eAAe,aAAf,eAAe,uBAAf,eAAe,CAAE,QAAQ,gEAAG,QAAQ,CAAC,OAAO,CAAC,CAAA;YAC/C,CAAC;QACH,CAAC;QAED,oBAAC,YAAY,CAAC,MAAM,IAAC,SAAS,EAAE,iBAAiB;YAC9C,CAAC,YAAY,IAAI,CAChB,oBAAC,YAAY,CAAC,QAAQ,IACpB,SAAS,EAAC,gHAAgH,EAC1H,KAAK,EAAE,aAAa,GACpB,CACH;YACD,oBAAC,YAAY,CAAC,KAAK,oBACb,IAAI,IACR,GAAG,EAAE,QAAQ,EACb,YAAY,EAAE,GAAG,EAAE;;oBACjB,OAAA,CAAA,MAAA,QAAQ,CAAC,OAAO,0CAAE,QAAQ,CAAC,QAAQ,CAAC,aAAa,CAAC;wBAChD,CAAC,CAAC,SAAS;wBACX,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAA;iBAAA,EAEtB,SAAS,EAAE,OAAO,CAChB,uKAAuK,EACvK,SAAS,CACV,EACD,KAAK,kCAAO,KAAK,GAAK,aAAa,GACnC,OAAO,EAAE,gBAAgB;gBAEzB,oBAAC,UAAU,kBAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,IAAM,UAAU;oBAChE,oBAAC,YAAY,CAAC,QAAQ,IAAC,KAAK;wBACzB,QAAQ;wBACR,OAAO,IAAI,CACV,oBAAC,cAAc,kBACF,OAAO,EAClB,OAAO,EAAC,MAAM,EACd,SAAS,EAAE,OAAO,CAChB,wBAAwB,EACxB,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,WAAW,CACrB,EACD,OAAO,EAAE,OAAO,iBACH,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,WAAW;4BAEjC,oBAAC,YAAY,OAAG,CACD,CAClB,CACqB,CACb,CACM,CACD,CACJ,CACrB,CAAA;AACH,CAAC,CAAC,CAAA;AAEF,KAAK,CAAC,WAAW,GAAG,OAAO,CAAA;AAE3B,eAAe,KAAK,CAAA"}
1
+ {"version":3,"file":"Modal.js","sourceRoot":"","sources":["../../../src/Modal/Modal.tsx"],"names":[],"mappings":";;;;;;;;;;;AACA,OAAO,EAAE,MAAM,IAAI,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAC9D,OAAO,KAAK,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,OAAO,CAAA;AAMxE,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AACpD,OAAO,EACL,eAAe,EACf,YAAY,EACZ,iBAAiB,GAClB,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AACvD,OAAO,YAAY,MAAM,+BAA+B,CAAA;AACxD,OAAO,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAA;AAExD,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AA2C1C,MAAM,cAAc,GAAG,IAAI,YAAY,EAAE,CAAA;AAEzC,kHAAkH;AAClH,6FAA6F;AAC7F,MAAM,uBAAuB,GAC3B,gLAAgL,CAAA;AAClL,2EAA2E;AAC3E,iFAAiF;AACjF,MAAM,0BAA0B,GAAG,uCAAuC,CAAA;AAE1E,MAAM,0BAA0B,GAAG,CAAC,IAAa,EAAE,EAAE;IACnD,MAAM,QAAQ,GAAG,IAAI,CAAC,gBAAgB,CAAC,uBAAuB,CAAC,CAAA;IAC/D,4BAA4B;IAC5B,MAAM,iBAAiB,GAAG,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;IAE9D,IAAI,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACjC,iBAAiB,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAA;IAC9B,CAAC;AACH,CAAC,CAAA;AAED,MAAM,kBAAkB,GAAG,CAAC,SAAkB,EAAE,EAAE;IAChD,MAAM,2BAA2B,GAAG,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAA;IAE9E,IAAI,2BAA2B,EAAE,CAAC;QAChC,OAAO,IAAI,CAAA;IACb,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC,CAAA;AAED,MAAM,wBAAwB,GAAG,GAAG,EAAE;IACpC,MAAM,eAAe,GAAG,QAAQ,CAAC,gBAAgB,CAAC,0BAA0B,CAAC,CAAA;IAE7E,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjC,OAAO,KAAK,CAAA;IACd,CAAC;IAED,MAAM,2BAA2B,GAAG,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,IAAI,CAClE,SAAS,CAAC,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,aAAa,CAAC,CACxD,CAAA;IAED,IAAI,2BAA2B,EAAE,CAAC;QAChC,OAAO,IAAI,CAAA;IACb,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC,CAAA;AAED,MAAM,WAAW,GAAG,CAAC,GAAG,EAAE;IACxB,IAAI,KAAK,GAAG,CAAC,CAAA;IAEb,OAAO,GAAG,EAAE,CAAC,EAAE,KAAK,CAAA;AACtB,CAAC,CAAC,EAAE,CAAA;AAEJ,8CAA8C;AAC9C,MAAM,CAAC,MAAM,KAAK,GAAG,UAAU,CAAwB,SAAS,KAAK,CACnE,EAQC,EACD,GAAG;QATH,EACE,YAAY,GAAG,KAAK,EACpB,mBAAmB,GAAG,IAAI,EAC1B,oBAAoB,GAAG,KAAK,EAC5B,IAAI,GAAG,QAAQ,EACf,kBAAkB,GAAG,GAAG,EACxB,KAAK,GAAG,UAAU,OAEnB,EADI,KAAK,cAPV,sGAQC,CADS;IAIV,MAAM,EACJ,QAAQ,EACR,IAAI,EACJ,eAAe,EACf,OAAO,EACP,MAAM,EACN,OAAO,EACP,WAAW,EACX,SAAS,EACT,SAAS,EACT,KAAK,EACL,SAAS,EACT,UAAU,EACV,OAAO,EACP,eAAe,EACf,OAAO,KAEL,KAAK,EADJ,IAAI,UACL,KAAK,EAjBH,6LAiBL,CAAQ,CAAA;IACT,MAAM,oBAAoB,GAAG,cAAc,EAAE,CAAA;IAC7C,MAAM,QAAQ,GAAG,eAAe,CAC9B,GAAG,EACH,MAAM,CAAiB,IAAI,CAAC,CAC7B,CAAA;IACD,MAAM,OAAO,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC,CAAA;IACrC,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,CAAA;IAC7B,MAAM,mBAAmB,GAAG,MAAM,CAAC,KAAK,CAAC,CAAA;IACzC,MAAM,iBAAiB,GAAG,MAAM,CAAC,KAAK,CAAC,CAAA;IACvC,MAAM,EAAE,OAAO,EAAE,GAAG,UAAU,CAAC,WAAW,CAAC,CAAA;IAE3C,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,mBAAmB,GAAG,GAAG,EAAE;YAC/B,IAAI,CAAC,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,OAAO,CAAA,EAAE,CAAC;gBACtB,OAAO,CAAC,IAAI,CACV,mIAAmI,CACpI,CAAA;YACH,CAAC;YAED,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;gBAChD,OAAM;YACR,CAAC;YAED,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;gBACnC,OAAM;YACR,CAAC;YAED,IAAI,kBAAkB,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;gBACzC,OAAM;YACR,CAAC;YAED,IAAI,wBAAwB,EAAE,EAAE,CAAC;gBAC/B,OAAM;YACR,CAAC;YAED,0BAA0B,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;QAC9C,CAAC,CAAA;QAED,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAM;QACR,CAAC;QAED,QAAQ,CAAC,gBAAgB,CAAC,OAAO,EAAE,mBAAmB,EAAE,IAAI,CAAC,CAAA;QAE7D,OAAO,GAAG,EAAE;YACV,QAAQ,CAAC,mBAAmB,CAAC,OAAO,EAAE,mBAAmB,EAAE,IAAI,CAAC,CAAA;QAClE,CAAC,CAAA;IACH,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAA;IAE7B,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,cAAc,GAAG,OAAO,CAAC,OAAO,CAAA;QAEtC,IAAI,IAAI,EAAE,CAAC;YACT,cAAc,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;QACpC,CAAC;QAED,OAAO,GAAG,EAAE;YACV,cAAc,CAAC,MAAM,CAAC,cAAc,CAAC,CAAA;QACvC,CAAC,CAAA;IACH,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAA;IAEV,iBAAiB,CAAC,IAAI,CAAC,CAAA;IAEvB,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YAC7B,MAAM,aAAN,MAAM,uBAAN,MAAM,EAAI,CAAA;QACZ,CAAC;QACD,OAAO,CAAC,OAAO,GAAG,IAAI,CAAA;IACxB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAA;IAElB,MAAM,QAAQ,GAAG,CAAA,eAAe,aAAf,eAAe,uBAAf,eAAe,CAAE,OAAO,KAAI,kBAAkB,CAAA;IAC/D,MAAM,aAAa,GAAG,EAAE,kBAAkB,EAAE,GAAG,QAAQ,IAAI,EAAE,CAAA;IAE7D,MAAM,iBAAiB,GACrB,CAAC,OAAO,SAAS,KAAK,UAAU,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QAC3D,oBAAoB,CAAA;IAEtB,MAAM,oBAAoB,GAAG,CAAC,KAAuC,EAAE,EAAE;QACvE,mBAAmB,CAAC,OAAO,GAAG,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,aAAa,CAAA;QAElE,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAG,KAAK,CAAC,CAAA;IACtB,CAAC,CAAA;IAED,MAAM,kBAAkB,GAAG,CAAC,KAAuC,EAAE,EAAE;QACrE,iBAAiB,CAAC,OAAO,GAAG,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,aAAa,CAAA;QAEhE,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAG,KAAK,CAAC,CAAA;IACpB,CAAC,CAAA;IAED,MAAM,gBAAgB,GAAG,CAAC,KAAuC,EAAE,EAAE;QACnE,0EAA0E;QAC1E,mEAAmE;QACnE,IACE,mBAAmB,CAAC,OAAO;YAC3B,iBAAiB,CAAC,OAAO;YACzB,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,aAAa;YACpC,CAAC,oBAAoB,EACrB,CAAC;YACD,eAAe,aAAf,eAAe,uBAAf,eAAe,EAAI,CAAA;YACnB,OAAO,aAAP,OAAO,uBAAP,OAAO,EAAI,CAAA;QACb,CAAC;QAED,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAG,KAAK,CAAC,CAAA;IAClB,CAAC,CAAA;IAED,OAAO,CACL,oBAAC,YAAY,CAAC,IAAI,IAChB,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,KAAK,EACZ,uBAAuB,QACvB,YAAY,EAAE,MAAM,CAAC,EAAE;YACrB,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,OAAO,aAAP,OAAO,uBAAP,OAAO,EAAI,CAAA;YACb,CAAC;QACH,CAAC,EACD,oBAAoB,EAAE,MAAM,CAAC,EAAE;;YAC7B,IAAI,CAAC,MAAM,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;gBAChC,MAAA,eAAe,aAAf,eAAe,uBAAf,eAAe,CAAE,QAAQ,gEAAG,QAAQ,CAAC,OAAO,CAAC,CAAA;YAC/C,CAAC;QACH,CAAC;QAED,oBAAC,YAAY,CAAC,MAAM,IAAC,SAAS,EAAE,iBAAiB;YAC9C,CAAC,YAAY,IAAI,CAChB,oBAAC,YAAY,CAAC,QAAQ,IACpB,WAAW,EAAE,mBAAmB,EAChC,SAAS,EAAC,gHAAgH,EAC1H,KAAK,EAAE,aAAa,GACpB,CACH;YACD,oBAAC,YAAY,CAAC,KAAK,oBACb,IAAI,IACR,GAAG,EAAE,QAAQ,EACb,YAAY,EAAE,GAAG,EAAE;;oBACjB,OAAA,CAAA,MAAA,QAAQ,CAAC,OAAO,0CAAE,QAAQ,CAAC,QAAQ,CAAC,aAAa,CAAC;wBAChD,CAAC,CAAC,SAAS;wBACX,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAA;iBAAA,EAEtB,SAAS,EAAE,OAAO,CAChB,uKAAuK,EACvK,SAAS,CACV,EACD,KAAK,kCAAO,KAAK,GAAK,aAAa,GACnC,OAAO,EAAE,gBAAgB,EACzB,WAAW,EAAE,oBAAoB,EACjC,SAAS,EAAE,kBAAkB;gBAE7B,oBAAC,UAAU,kBAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,IAAM,UAAU;oBAChE,oBAAC,YAAY,CAAC,QAAQ,IAAC,KAAK;wBACzB,QAAQ;wBACR,OAAO,IAAI,CACV,oBAAC,cAAc,kBACF,OAAO,EAClB,OAAO,EAAC,MAAM,EACd,SAAS,EAAE,OAAO,CAChB,wBAAwB,EACxB,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,WAAW,CACrB,EACD,OAAO,EAAE,OAAO,iBACH,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,WAAW;4BAEjC,oBAAC,YAAY,OAAG,CACD,CAClB,CACqB,CACb,CACM,CACD,CACJ,CACrB,CAAA;AACH,CAAC,CAAC,CAAA;AAEF,KAAK,CAAC,WAAW,GAAG,OAAO,CAAA;AAE3B,eAAe,KAAK,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@toptal/picasso-modal",
3
- "version": "100.0.1",
3
+ "version": "100.1.1",
4
4
  "description": "Toptal UI components library - Modal",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -20,13 +20,13 @@
20
20
  "dependencies": {
21
21
  "@base-ui/react": "^1.6.0",
22
22
  "debounce": "^1.2.1",
23
- "@toptal/picasso-button": "100.0.1",
24
- "@toptal/picasso-shared": "100.0.0",
25
23
  "@toptal/picasso-paper": "100.0.0",
26
- "@toptal/picasso-icons": "100.0.0",
24
+ "@toptal/picasso-shared": "100.0.0",
25
+ "@toptal/picasso-button": "100.0.1",
27
26
  "@toptal/picasso-typography": "100.0.0",
28
27
  "@toptal/picasso-utils": "100.0.0",
29
- "@toptal/picasso-modal-context": "100.0.0"
28
+ "@toptal/picasso-modal-context": "100.0.0",
29
+ "@toptal/picasso-icons": "100.0.0"
30
30
  },
31
31
  "sideEffects": [
32
32
  "**/styles.ts",
@@ -42,9 +42,9 @@
42
42
  ".": "./dist-package/src/index.js"
43
43
  },
44
44
  "devDependencies": {
45
- "@toptal/picasso-test-utils": "100.0.0",
46
45
  "@toptal/picasso-provider": "100.0.0",
47
- "@toptal/picasso-tailwind-merge": "100.0.0"
46
+ "@toptal/picasso-tailwind-merge": "100.0.0",
47
+ "@toptal/picasso-test-utils": "100.0.0"
48
48
  },
49
49
  "files": [
50
50
  "dist-package/**",
@@ -43,6 +43,8 @@ export interface Props extends BaseProps, HTMLAttributes<HTMLDivElement> {
43
43
  container?: ContainerValue
44
44
  /** If `true`, the backdrop is not rendered */
45
45
  hideBackdrop?: boolean
46
+ /** If `true`, the backdrop is rendered even when nested in another dialog */
47
+ forceRenderBackdrop?: boolean
46
48
  /** Position of the modal relative to the browser's viewport */
47
49
  align?: Alignment
48
50
  /** Animation lifecycle callbacks. Backed by [react-transition-group/Transition](https://reactcommunity.org/react-transition-group/transition#Transition-props) */
@@ -116,6 +118,7 @@ const generateKey = (() => {
116
118
  export const Modal = forwardRef<HTMLDivElement, Props>(function Modal(
117
119
  {
118
120
  hideBackdrop = false,
121
+ forceRenderBackdrop = true,
119
122
  disableBackdropClick = false,
120
123
  size = 'medium',
121
124
  transitionDuration = 300,
@@ -131,6 +134,8 @@ export const Modal = forwardRef<HTMLDivElement, Props>(function Modal(
131
134
  onClose,
132
135
  onOpen,
133
136
  onClick,
137
+ onMouseDown,
138
+ onMouseUp,
134
139
  className,
135
140
  style,
136
141
  container,
@@ -147,6 +152,8 @@ export const Modal = forwardRef<HTMLDivElement, Props>(function Modal(
147
152
  )
148
153
  const modalId = useRef(generateKey())
149
154
  const wasOpen = useRef(false)
155
+ const mouseDownOnPopupRef = useRef(false)
156
+ const mouseUpOnPopupRef = useRef(false)
150
157
  const { rootRef } = useContext(RootContext)
151
158
 
152
159
  useEffect(() => {
@@ -215,8 +222,27 @@ export const Modal = forwardRef<HTMLDivElement, Props>(function Modal(
215
222
  (typeof container === 'function' ? container() : container) ||
216
223
  picassoRootContainer
217
224
 
225
+ const handlePopupMouseDown = (event: React.MouseEvent<HTMLDivElement>) => {
226
+ mouseDownOnPopupRef.current = event.target === event.currentTarget
227
+
228
+ onMouseDown?.(event)
229
+ }
230
+
231
+ const handlePopupMouseUp = (event: React.MouseEvent<HTMLDivElement>) => {
232
+ mouseUpOnPopupRef.current = event.target === event.currentTarget
233
+
234
+ onMouseUp?.(event)
235
+ }
236
+
218
237
  const handlePopupClick = (event: React.MouseEvent<HTMLDivElement>) => {
219
- if (event.target === event.currentTarget && !disableBackdropClick) {
238
+ // a drag between the backdrop and the content dispatches its click on the
239
+ // common ancestor — this popup — so both ends must have been on it
240
+ if (
241
+ mouseDownOnPopupRef.current &&
242
+ mouseUpOnPopupRef.current &&
243
+ event.target === event.currentTarget &&
244
+ !disableBackdropClick
245
+ ) {
220
246
  onBackdropClick?.()
221
247
  onClose?.()
222
248
  }
@@ -243,6 +269,7 @@ export const Modal = forwardRef<HTMLDivElement, Props>(function Modal(
243
269
  <BaseUIDialog.Portal container={resolvedContainer}>
244
270
  {!hideBackdrop && (
245
271
  <BaseUIDialog.Backdrop
272
+ forceRender={forceRenderBackdrop}
246
273
  className='fixed z-modal inset-0 bg-black/50 transition-opacity data-starting-style:opacity-0 data-ending-style:opacity-0'
247
274
  style={durationStyle}
248
275
  />
@@ -261,6 +288,8 @@ export const Modal = forwardRef<HTMLDivElement, Props>(function Modal(
261
288
  )}
262
289
  style={{ ...style, ...durationStyle }}
263
290
  onClick={handlePopupClick}
291
+ onMouseDown={handlePopupMouseDown}
292
+ onMouseUp={handlePopupMouseUp}
264
293
  >
265
294
  <ModalPaper size={size} align={align} tabIndex={-1} {...paperProps}>
266
295
  <ModalContext.Provider value>
@@ -207,6 +207,146 @@ describe('Modal', () => {
207
207
  expect(baseElement).toMatchSnapshot()
208
208
  })
209
209
 
210
+ describe('backdrop', () => {
211
+ const getBackdrops = (element: HTMLElement) =>
212
+ element.querySelectorAll('[role="presentation"]')
213
+
214
+ it('renders a backdrop for a nested modal by default', () => {
215
+ const { baseElement } = render(
216
+ <Modal open>
217
+ <p>Outer modal content</p>
218
+ <Modal open>
219
+ <p>Nested modal content</p>
220
+ </Modal>
221
+ </Modal>
222
+ )
223
+
224
+ expect(getBackdrops(baseElement)).toHaveLength(2)
225
+ })
226
+
227
+ it('given forceRenderBackdrop is false, does not render a backdrop for a nested modal', () => {
228
+ const { baseElement } = render(
229
+ <Modal open>
230
+ <p>Outer modal content</p>
231
+ <Modal open forceRenderBackdrop={false}>
232
+ <p>Nested modal content</p>
233
+ </Modal>
234
+ </Modal>
235
+ )
236
+
237
+ expect(getBackdrops(baseElement)).toHaveLength(1)
238
+ })
239
+
240
+ it('given hideBackdrop is true, does not render a backdrop', () => {
241
+ const { baseElement } = render(
242
+ <Modal open hideBackdrop>
243
+ <p>Modal content</p>
244
+ </Modal>
245
+ )
246
+
247
+ expect(getBackdrops(baseElement)).toHaveLength(0)
248
+ })
249
+ })
250
+
251
+ describe('backdrop click', () => {
252
+ const renderModal = (props?: Partial<ModalProps>) => {
253
+ const onClose = jest.fn()
254
+ const onBackdropClick = jest.fn()
255
+
256
+ const { baseElement } = render(
257
+ <Modal
258
+ open
259
+ onClose={onClose}
260
+ onBackdropClick={onBackdropClick}
261
+ {...props}
262
+ >
263
+ <Modal.Content>
264
+ <input />
265
+ </Modal.Content>
266
+ </Modal>
267
+ )
268
+
269
+ return {
270
+ onClose,
271
+ onBackdropClick,
272
+ // the popup is the transparent full-screen element over the backdrop
273
+ popup: baseElement.querySelector('[role="dialog"]') as HTMLElement,
274
+ }
275
+ }
276
+
277
+ // a pointer interaction fires mousedown → mouseup → click, and the browser
278
+ // dispatches the click on the nearest common ancestor of the press and the
279
+ // release target — the popup itself whenever the two differ
280
+ const press = ({
281
+ from,
282
+ to,
283
+ popup,
284
+ }: {
285
+ from: HTMLElement
286
+ to: HTMLElement
287
+ popup: HTMLElement
288
+ }) => {
289
+ fireEvent.mouseDown(from)
290
+ fireEvent.mouseUp(to)
291
+ fireEvent.click(from === to ? from : popup)
292
+ }
293
+
294
+ it('closes when pressing and releasing on the backdrop', () => {
295
+ const { popup, onClose, onBackdropClick } = renderModal()
296
+
297
+ press({ from: popup, to: popup, popup })
298
+
299
+ expect(onBackdropClick).toHaveBeenCalled()
300
+ expect(onClose).toHaveBeenCalled()
301
+ })
302
+
303
+ it('given the press started inside the content, does not close', () => {
304
+ const { popup, onClose, onBackdropClick } = renderModal()
305
+
306
+ // selecting text in a field and releasing outside the paper
307
+ press({ from: screen.getByRole('textbox'), to: popup, popup })
308
+
309
+ expect(onBackdropClick).not.toHaveBeenCalled()
310
+ expect(onClose).not.toHaveBeenCalled()
311
+ })
312
+
313
+ it('given the press ended inside the content, does not close', () => {
314
+ const { popup, onClose, onBackdropClick } = renderModal()
315
+
316
+ // selecting from outside the paper into a field
317
+ press({ from: popup, to: screen.getByRole('textbox'), popup })
318
+
319
+ expect(onBackdropClick).not.toHaveBeenCalled()
320
+ expect(onClose).not.toHaveBeenCalled()
321
+ })
322
+
323
+ it('given disableBackdropClick, does not close on a backdrop click', () => {
324
+ const { popup, onClose } = renderModal({ disableBackdropClick: true })
325
+
326
+ press({ from: popup, to: popup, popup })
327
+
328
+ expect(onClose).not.toHaveBeenCalled()
329
+ })
330
+
331
+ it('forwards onMouseUp', () => {
332
+ const onMouseUp = jest.fn()
333
+ const { popup } = renderModal({ onMouseUp })
334
+
335
+ fireEvent.mouseUp(popup)
336
+
337
+ expect(onMouseUp).toHaveBeenCalled()
338
+ })
339
+
340
+ it('forwards onMouseDown', () => {
341
+ const onMouseDown = jest.fn()
342
+ const { popup } = renderModal({ onMouseDown })
343
+
344
+ fireEvent.mouseDown(popup)
345
+
346
+ expect(onMouseDown).toHaveBeenCalled()
347
+ })
348
+ })
349
+
210
350
  describe('page scroll lock', () => {
211
351
  afterEach(() => {
212
352
  cleanup()