REACT LIBRARY/Styled-Component

Styled-Components Dialog 만들기

두비_ 2022. 6. 29. 23:01
반응형

Dialog란 화면을 가리면서 어떤 작업을 선택할지 나오게 되는 컴포넌트 박스입니다

Components 폴더에 Dialog.js 생성

기존에 만든 버튼을 활용할 예정이기에 버튼도 같이 불러옵니다

import React from "react";
import styled from "styled-components";
import Button from "./Button";

function Dialog() {
  return <div></div>;
}

export default Dialog;

어두운 배경 설정

const DarkBackground = styled.div`
  position: fixed;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.8);
`;

내부에 흰색 박스 생성

const DialogBlock = styled.div`
  width: 320px;
  padding: 1.5rem;
  background: white;
  border-radius: 2px;
`;

제목과 내용 삽입

nesting 기능을 활용하여 안쪽에서 만들어줍니다

const DialogBlock = styled.div`
  width: 320px;
  padding: 1.5rem;
  background: white;
  border-radius: 2px;

  h3 {
    margin: 0;
    font-size: 1.5rem;
  }

  p {
    font-size: 1.125rem;
  }
`;

버튼그룹 생성, 여백 및 정렬

const ButtonGroup = styled.div`
  margin-top: 3rem;
  display: flex;
  justify-content: flex-end;
`;

이제 Dialog 컴포넌트에서 받아올 props를 설정해줍니다

function Dialog({ title, children, confirmText, cancelText })

return에선 DarkBackground를 랜더링 합니다

return <DarkBackground></DarkBackground>;

제목과 내용을 넣습니다

<DarkBackground>
      <DialogBlock>
        <h3>{title}</h3>
        <p>{children}</p>
      </DialogBlock>
    </DarkBackground>

확인, 취소 버튼 컬러 지정

<DialogBlock>
        <h3>{title}</h3>
        <p>{children}</p>
        <ButtonGroup>
          <Button color="pink">{cancelText}</Button>
          <Button color="violet">{confirmText}</Button>
        </ButtonGroup>
      </DialogBlock>

cancelText와 confirmText 기본값 설정

Dialog.defaultProps = {
  cancelText: "취소",
  confirmText: "확인",
};

App.js에서 랜더링

<Dialog
          title="정말로 삭제하시겠습니까?"
          confirmText="삭제"
          cancelText="취소"
        >
          데이터를 정말 삭제하시겠습니까?
        </Dialog>

 

ThemeProvider 안에는 하나의 엘리먼트만 있어야하기 때문에 AppBlock 밖에 지정하면 오류가 뜨게됩니다

해결방법은 프래그먼트를 줘서 AppBLock를 감싸면 됩니다

function App() {
  return (
    <ThemeProvider theme={{ palette }}>
      <>
        <AppBlock>
          <ButtonGroup>
            <Button color="pink" size="large">
              BUTTON
            </Button>
            <Button>BUTTON</Button>
            <Button color="violet" size="small">
              BUTTON
            </Button>
          </ButtonGroup>

          <ButtonGroup>
            <Button color="pink" size="large" outline>
              BUTTON
            </Button>
            <Button outline>BUTTON</Button>
            <Button color="violet" size="small" outline>
              BUTTON
            </Button>
          </ButtonGroup>

          <ButtonGroup>
            <Button color="pink" size="large" fullWidth>
              BUTTON
            </Button>
            <Button fullWidth size="large">
              BUTTON
            </Button>
            <Button color="violet" size="large" fullWidth>
              BUTTON
            </Button>
          </ButtonGroup>
        </AppBlock>
        <Dialog
          title="정말로 삭제하시겠습니까?"
          confirmText="삭제"
          cancelText="취소"
        >
          데이터를 정말 삭제하시겠습니까?
        </Dialog>
      </>
    </ThemeProvider>
  );
}

만약 버튼에 여백을 좀 주고 싶다면 기존에 만든 버튼에 상속받아서 만들 수 있습니다

Dialog.js에서 작성합니다

const ShortMarginButton = styled(Button)`
  & + & {
    margin-left: 0%.5rem;
  }
`;

이렇게 지정한 후에 태그를 Button 대신 ShortMarginButton을 사용하면됩니다

<ButtonGroup>
          <ShortMarginButton color="pink">{cancelText}</ShortMarginButton>
          <ShortMarginButton color="violet">{confirmText}</ShortMarginButton>
        </ButtonGroup>

이제 기능 구현을 하겠습니다

App.js에서 useState를 불러옵니다

import React, { useState } from "react";

Diglog 상태를 만들어줍니다

function App() {
  const [dialog, setDialog] = useState(false);
  const onClick = () => {
    setDialog(true); //버튼 열어주기
  }

버튼이 많으니 삭제해주고 하나의 버튼만 만들어서 진행합니다

<AppBlock>
          <Button color="pink" size="large" onClick={onClick}>
            삭제
          </Button>
        </AppBlock>

visible도 만들어줍니다

title="정말로 삭제하시겠습니까?"
          confirmText="삭제"
          cancelText="취소"
          visible={dialog} //가시성, 보이는 속성

각 버튼도 만들어줍니다

function App() {
  const [dialog, setDialog] = useState(false); //기본적으로 닫혀있음
  const onClick = () => {
    setDialog(true); //dialog 열어주기
  };
  const onConfirm = () => {
    console.log('확인')
    setDialog(false);
  };
  const onCancel = () => {
    console.log('취소')
    setDialog(false);
  };

onConfirm과 onCancel을 dialog에 넣어주겠습니다

<Dialog
          title="정말로 삭제하시겠습니까?"
          confirmText="삭제"
          cancelText="취소"
          onConfirm={onConfirm}
          onCancel={onCancel}
          visible={dialog} //가시성, 보이는 속성
        >
          데이터를 정말 삭제하시겠습니까?
        </Dialog>

Dialog.js 열어서 visible, onConfirm, onCancel 값을 받아오겠습니다

function Dialog({
  title,
  children,
  confirmText,
  cancelText,
  visible,
  onConfirm,
  onCancel,
})

visible를 false로 처리하면 false일 때 아무것도 안보이게 됩니다

onCancel,
}) {
    if (!visible) return null

버튼 값을 넣어주겠습니다

<ButtonGroup>
          <ShortMarginButton color="pink" onClick={onCancel}>
            {cancelText}
          </ShortMarginButton>
          <ShortMarginButton color="violet" onClick={onConfirm}>
            {confirmText}
          </ShortMarginButton>
        </ButtonGroup>