Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

Problema ao Fechar o Modal

Meu modal esta estilizado e funciona quase tudo certo, o problema esta na hora que eu fecho a imagem, quando eu clico para fechar, a imagem some mas a tela fica presa com o overlay, tenho que recarregar a pagina, alguém sabe onde esta o problema?

ModalZoom

import React from 'react'
import Card from '../Card';
import styled from 'styled-components';

const Overlay = styled.div`
    background-color: rgba(0, 0, 0, 0.7);
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
`

const DialogEstilizado = styled.dialog`
    position: absolute;
    top: 294px;
    padding: 0;
    background: transparent;
    border: transparent;
`

const ButtonEstilizado = styled.button`
    background: rgba(0, 0, 0, 0.7);
    border-radius: 20px;
    border: transparent;
    position: absolute;
    top: 0;
    right: 0;
    img {
        width: 32px;
        height: 32px;
    }
`


function ModalZoom({ foto }) {
    return (
        <>
            {foto && <>
                <Overlay />
                <DialogEstilizado open={!!foto}>
                    <Card foto={foto} expandida={true} />
                    <form method="dialog">
                        <ButtonEstilizado>
                            <img src="/icones/fechar.png"/>
                        </ButtonEstilizado>
                    </form>
                </DialogEstilizado>
            </>}
        </>
    )
}

export default ModalZoom;

Card (o componente imagem do professor)

import styled from "styled-components";

const CardEstilizado = styled.figure`
    display: flex;
    flex-direction: column;
    margin: 0;
`

const ImgEstilizado = styled.img`
    width: ${props => props.$expandida ? "1156px" : "448px"};
    border-radius: 20px 20px 0 0;
`

const FigcaptionEstilizado = styled.figcaption`
    background-color: #001634;
    border-radius: 0 0 20px 20px;
`

const H2Estilizado = styled.h2`
    color: #FFF;
    font-size: 20px;
    font-weight: 700;
    font-style: normal;
    line-height: normal;
    margin-top: 16px;
    margin-left: 21px;
    margin-bottom: 2px;
`

const CardInfoEstilizado = styled.div`
    display: flex;
    justify-content: space-between;
    align-items: center;
    width: ${props => props.$expandida ? "1156" : "448"};
`

const H4Estilizado = styled.h4`
    color: #FFF;
    font-size: 16px;
    font-weight: 400;
    font-style: normal;
    line-height: normal;
    margin-left: 21px;
    margin-bottom: 16px;
    margin-top: 2px;
`

const DivIconesEstilizado = styled.div`
    display: flex;
    gap: 24px;
    margin-right: 16px;
    margin-bottom: 16px;
`

const ButtonEstilizado = styled.button`
    background: transparent;
    border: transparent;
`

const IconeEstilizado = styled.img`
    height: 24px;
    width: 24px;
`

const Card = ({ foto, expandida = false, aoZoomSolicitado }) => {
    return (
        <CardEstilizado>
            <ImgEstilizado $expandida={expandida} src={foto.path} />
            <FigcaptionEstilizado>
                <H2Estilizado>{foto.titulo}</H2Estilizado>
                <CardInfoEstilizado $expandida={expandida}>
                    <H4Estilizado>{foto.fonte}</H4Estilizado>
                    <DivIconesEstilizado>
                        <ButtonEstilizado>
                            <IconeEstilizado src="/icones/favorito.png" alt="" />
                        </ButtonEstilizado>
                        {!expandida && <ButtonEstilizado aria-hidden={expandida} onClick={() => aoZoomSolicitado(foto)}>
                            <IconeEstilizado src="/icones/expandir.png" alt="" />
                        </ButtonEstilizado>}
                    </DivIconesEstilizado>
                </CardInfoEstilizado>
            </FigcaptionEstilizado>
        </CardEstilizado>
    )
}

export default Card;

Galeria

import styled from "styled-components";
import Titulo from "../Titulo";
import Tags from "./Tags";
import Populares from "./Populares";
import Card from "../Card";

const GaleriaContainer = styled.div`
    display: flex;
`

const SecaoFluida = styled.section`
    flex-grow: 1;
`

const FigureContainer = styled.figure`
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
    margin: 0;
`

const Galeria = ({fotos = [], aoFotoSelecionada}) => {
    return (
        <>
            <Tags />
            <GaleriaContainer>
                <SecaoFluida>
                    <Titulo>Navegue pela galeria</Titulo>
                    <FigureContainer>
                        {fotos.map(foto => <Card aoZoomSolicitado={aoFotoSelecionada} key={foto.id} foto={foto}/>)}
                    </FigureContainer>
                </SecaoFluida>
                <Populares />
            </GaleriaContainer>
        </>
    )
}

export default Galeria;
2 respostas

App

import { styled } from 'styled-components'
import EstilosGlobais from './componentes/EstilosGlobais'
import Cabecalho from './componentes/Cabecalho'
import BarraLateral from './componentes/BarraLateral'
import Banner from './componentes/Banner'
import Galeria from './componentes/Galeria'
import fotos from './fotos.json'
import { useState } from 'react'
import ModalZoom from './componentes/ModalZoom'

const FundoGradiente = styled.div`
  background: linear-gradient(174.61deg, #041833 4.16%, #04244F 48%, #154580 96.76%);
  width: 100%;
  min-height: 100vh;
`
const AppContainer = styled.div`
  width: 1440px;
  max-width: 100%;
  margin: 0 auto;
`

const MainContainer = styled.main`
  display: flex;
  gap: 24px;
`
const ConteudoGaleria = styled.section`
  display: flex;
  flex-direction: column;
  flex-grow: 1;
`

const App = () => {
  const [fotosGaleria, setFotosGaleria] = useState(fotos);
  const [fotoSelecionada, setFotoSelecionada] = useState(null);
  return (
    <FundoGradiente>
      <EstilosGlobais />
      <AppContainer>
        <Cabecalho />
        <MainContainer>
          <BarraLateral />
          <ConteudoGaleria>
            <Banner texto="A galeria mais completa de fotos do espaço!" backgroundImage="/imagens/banner.png"/>
            <Galeria aoFotoSelecionada={foto => setFotoSelecionada(foto)} fotos={fotosGaleria}/>
          </ConteudoGaleria>
        </MainContainer>
      </AppContainer>
      <ModalZoom foto={fotoSelecionada}/>
    </FundoGradiente>
  )
}

export default App
solução!

Oii, Plinio, tudo certo?

O problema está na falta de uma função para fechar o modal quando o botão de fechar é clicado. No código que você compartilhou, não há uma função que altere o estado do componente para fechar o modal.

Você poderia adicionar uma função para lidar com o fechamento do modal e passá-la como propriedade para o componente ModalZoom.

Vou deixar abaixo um exemplo pra te ajudar:


const [fotoModal, setFotoModal] = useState(null);

const fecharModal = () => {
  setFotoModal(null);
};

<ModalZoom foto={fotoModal} aoFechar={fecharModal} />

E no seu componente ModalZoom, você pode chamar essa função quando o botão de fechar for clicado:

function ModalZoom({ foto, aoFechar }) {
    return (
        <>
            {foto && <>
                <Overlay />
                <DialogEstilizado open={!!foto}>
                    <Card foto={foto} expandida={true} />
                    <form method="dialog">
                        <ButtonEstilizado onClick={aoFechar}>
                            <img src="/icones/fechar.png"/>
                        </ButtonEstilizado>
                    </form>
                </DialogEstilizado>
            </>}
        </>
    )
}

Dessa forma, quando o botão de fechar for clicado, a função aoFechar será executada. Isso vai alterar o estado do componente pai e fechar o modal.

Se outra dúvida surgir, estamos aqui!

Abraços e bons estudos!

Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓.