DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

Cover image for Criando um Modal em ReactJS
Renato Hideki Osaka
Renato Hideki Osaka

Posted on

Criando um Modal em ReactJS

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}
    >
      &times;
    </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;
Enter fullscreen mode Exit fullscreen mode
.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;  
}
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

Exemplo

Link do github https://github.com/renatoosaka/useModal

Top comments (1)

Collapse
 
naiaraborges profile image
Naiara Borges

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

16 Libraries You Should Know as a React Developer

Being a modern React developer is not about knowing just React itself. To stay competitive, it is highly recommended to explore the whole ecosystem. This article contains some of the most useful React component libraries to speed up your developer workflow.