Yes! yet another modal tutorial but there's a catch! This one attaches an event listener on a div container rather than the document or window. Let's see how:
- We first create the basic Modal Functional component
import React, { useRef } from "react";
const Modal = ({ open, onClose, children }) => {
const modalRef = useRef(null);
return (
open && (
<div className="modal-overlay" ref={modalRef}>
<div className="modal-content">{children}</div>
<button className="close-btn" onClick={onClose}>
Close
</button>
</div>
)
);
};
export default Modal;
- We then attach our event listeners not to the
document
, or thewindow
but to thediv
container for our Modal.
import React, { useCallback, useEffect, useRef } from "react";
const Modal = ({ open, onClose, children }) => {
const modalRef = useRef(null);
const handleKeyPress = useCallback(
({ keyCode }) => keyCode === 27 && onClose(),
[onClose]
);
useEffect(() => {
let target = modalRef && modalRef.current;
if (target) {
target.addEventListener("click", onClose);
target.addEventListener("keydown", handleKeyPress);
}
return () => {
if (target) {
target.removeEventListener("click", onClose);
target.removeEventListener("keydown", handleKeyPress);
}
};
}, [modalRef, onClose, handleKeyPress]);
return (
open && (
<div className="modal-overlay" ref={modalRef}>
<div className="modal-content">{children}</div>
<button className="close-btn" onClick={onClose}>
Close
</button>
</div>
)
);
};
export default Modal;
- We make sure to attach
tabIndex="0"
property on the container and focus on it as we attach the listeners. These are the two important steps to make the Modal close by pressingÈsc
button.
import React, { useCallback, useEffect, useRef } from "react";
const Modal = ({ open, onClose, children }) => {
const modalRef = useRef(null);
const handleKeyPress = useCallback(
({ keyCode }) => keyCode === 27 && onClose(),
[onClose]
);
useEffect(() => {
let target = modalRef && modalRef.current;
if (target) {
modalRef.current.focus(); // important
target.addEventListener("click", onClose);
target.addEventListener("keydown", handleKeyPress);
}
return () => {
if (target) {
target.removeEventListener("click", onClose);
target.removeEventListener("keydown", handleKeyPress);
}
};
}, [modalRef, onClose, handleKeyPress]);
// tabIndex on our div tag
return (
open && (
<div tabIndex="0" className="modal-overlay" ref={modalRef}>
<div className="modal-content">{children}</div>
<button className="close-btn" onClick={onClose}>
Close
</button>
</div>
)
);
};
export default Modal;
Top comments (0)