Preciso de uma janela modal em meu sistema ou site e agora o que fazer? Desenvolver o meu próprio componente ou instalar uma biblioteca inteira só para usar um simples modal?
Muitos escolhem a segunda opção, as vezes pela facilidade de estar pronto, outros por falta de conhecimento para desenvolver o próprio componente. Então decidi compartilhar com vocês um simples exemplo em ReactJS.
import React, { useState, useEffect } from 'react'
import ReactFrom from 'react-dom'
import './modal.css'
import React, { useState, useEffect } from 'react'
import ReactDom from 'react-dom'
import './modal.css'
interface ModalProps {
isShowing: boolean;
toggle: () => void;
}
const Modal: React.FC<ModalProps> = ({ isShowing, toggle, children }) => {
useEffect(() => {
const listner = function (e: KeyboardEvent ) {
if (e.key === 'Escape' || e.key === 'Esc' || e.keyCode === 27) {
e.preventDefault();
e.stopPropagation();
isShowing && toggle();
}
}
window.addEventListener('keyup', listner)
return (() => {
window.removeEventListener('keyup', listner)
})
}, [isShowing, toggle])
return (
isShowing ? ReactDom.createPortal(
<div className="modal-overlay">
<div className="modal-wrapper">
<div className="modal">
{children}
</div>
</div>
</div>, document.body
) : null
)
}
interface ModalHeaderProps {
toggle: () => void;
}
export const ModalHeader: React.FC<ModalHeaderProps> = ({ toggle, children }) => (
<div className="modal-header">
{children || 'Title'}
<button
className="modal-button-close"
data-dismiss="modal"
aria-label="Close"
onClick={toggle}
>
×
</button>
</div>
)
export const ModalBody: React.FC = ({ children }) => (
<div className="modal-body">
{children}
</div>
)
export const ModalFooter: React.FC = ({ children }) => (
<div className="modal-footer">
{children}
</div>
)
export const useModal = () => {
const [isShowing, setIsShowing] = useState(false);
function toggle() {
setIsShowing(!isShowing);
}
return {
isShowing,
toggle,
}
}
export default Modal;
.modal-overlay {
position: fixed;
top: 0;
left: 0;
z-index: 1040;
width: 100vw;
height: 100vh;
background-color: rgba(0,0,0,0.5);
}
.modal-wrapper {
position: fixed;
top: 0;
left: 0;
z-index: 1050;
width: 100%;
height: 100%;
overflow-x: hidden;
overflow-y: auto;
outline: 0;
}
.modal {
z-index: 100;
background: white;
position: relative;
margin:20px auto;
border-radius: 3px;
max-width: 800px;
padding: 8px;
border-radius: 4px;
}
.modal-header {
display: flex;
justify-content: space-between;
border-bottom: 1px solid #ddd;
padding: 8px 0;
font-weight: bold;
}
.modal-button-close {
background: transparent;
border: none;
cursor: pointer;
font-size: 16px;
}
.modal-body {
padding: 8px 0;
}
.modal-footer {
display: flex;
flex-direction: row;
justify-content: flex-end;
padding: 8px 0;
}
Agora para usar o componente criado é simples
import React from 'react';
import Modal, {
ModalHeader,
ModalBody,
ModalFooter,
useModal
} from './components/Modal'
function App() {
const { isShowing, toggle } = useModal();
return (
<div>
<button onClick={toggle}>
Modal
</button>
<Modal {...{isShowing, toggle}}>
<ModalHeader {...{toggle}}>
My Title
</ModalHeader>
<ModalBody>
Hello World!
</ModalBody>
<ModalFooter>
<button onClick={toggle}>
Cancel
</button>
</ModalFooter>
</Modal>
</div>
);
}
export default App;
Link do github https://github.com/renatoosaka/useModal
Top comments (1)
Gostei muito do seu modelo utilizei ele e na minha página tive várias modais, só que quando clico nela aparece todas de uma vez, como faço para deixar apenas 1 por vez? Obrigada