Skip to content

Commit d0c4c92

Browse files
committed
feature: allow modal to be resized in width
1 parent f196b47 commit d0c4c92

File tree

2 files changed

+62
-2
lines changed

2 files changed

+62
-2
lines changed

src/components/Modal/Modal.react.js

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import Position from 'lib/Position';
1313
import React from 'react';
1414
import PropTypes from 'lib/PropTypes';
1515
import styles from 'components/Modal/Modal.scss';
16+
import { useState, useEffect, useRef } from 'react';
1617

1718
const origin = new Position(0, 0);
1819
const buttonColors = {
@@ -38,12 +39,55 @@ const Modal = ({
3839
progress = false,
3940
customFooter,
4041
textModal = false,
41-
width,
42+
width: initialWidth = 500,
4243
continueText,
4344
onContinue,
4445
showContinue,
4546
buttonsInCenter = React.Children.count(children) === 0,
4647
}) => {
48+
49+
const modalRef = useRef(null);
50+
51+
const [currentWidth, setCurrentWidth] = useState(initialWidth);
52+
const resizing = useRef(false);
53+
54+
const handleMouseDown = (e) => {
55+
e.preventDefault();
56+
resizing.current = true;
57+
if (modalRef.current) {
58+
modalRef.current.classList.add(styles.noTransition);
59+
}
60+
};
61+
62+
const handleMouseMove = (e) => {
63+
if (!resizing.current || !modalRef.current) {
64+
return;
65+
}
66+
67+
const modalLeft = modalRef.current.getBoundingClientRect().left;
68+
const newWidth = e.clientX - modalLeft;
69+
70+
const clampedWidth = Math.min(window.innerWidth, Math.max(initialWidth, newWidth));
71+
setCurrentWidth(clampedWidth);
72+
};
73+
74+
const handleMouseUp = () => {
75+
resizing.current = false;
76+
if (modalRef.current) {
77+
modalRef.current.classList.remove(styles.noTransition);
78+
}
79+
};
80+
81+
useEffect(() => {
82+
document.addEventListener('mousemove', handleMouseMove);
83+
document.addEventListener('mouseup', handleMouseUp);
84+
85+
return () => {
86+
document.removeEventListener('mousemove', handleMouseMove);
87+
document.removeEventListener('mouseup', handleMouseUp);
88+
};
89+
}, []);
90+
4791
if (children) {
4892
children = React.Children.map(children, c => {
4993
if (c && c.type === Field && c.props.label) {
@@ -81,7 +125,7 @@ const Modal = ({
81125

82126
return (
83127
<Popover fadeIn={true} fixed={true} position={origin} modal={true} color="rgba(17,13,17,0.8)">
84-
<div className={[styles.modal, styles[type]].join(' ')} style={{ width }}>
128+
<div ref={modalRef} className={[styles.modal, styles[type]].join(' ')} style={{ width: currentWidth }}>
85129
<div className={styles.header}>
86130
<div
87131
style={{
@@ -100,6 +144,7 @@ const Modal = ({
100144
</div>
101145
{wrappedChildren}
102146
{footer}
147+
<div className={styles.resizeHandle} onMouseDown={handleMouseDown} />
103148
</div>
104149
</Popover>
105150
);

src/components/Modal/Modal.scss

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,3 +99,18 @@
9999
}
100100

101101
@include modalKeyframes();
102+
103+
.resizeHandle {
104+
width: 16px;
105+
height: 16px;
106+
position: absolute;
107+
bottom: 0;
108+
right: 0;
109+
cursor: se-resize;
110+
background: rgba(255, 255, 255, 0.5);
111+
z-index: 10;
112+
}
113+
114+
.noTransition {
115+
transition: none !important;
116+
}

0 commit comments

Comments
 (0)