0.5.0 • Published 3 years ago

@cutehammond/modal v0.5.0

Weekly downloads
-
License
MIT
Repository
-
Last release
3 years ago

cutehammond-modal

이 라이브러리는 커뮤니티 Pill에서 사용하고 있는 커스텀 모달 라이브러리입니다.

이 Readme는 v0.5.0를 기준으로 작성되었습니다.

npm version

시작하기

이 라이브러리에 사용된 기술 스택

*CRA (create-react-app)*TypescriptRedux-ToolkitRedux-Saga*Emotion

'*' 표시된 스택은 이 라이브러리를 사용하는 프로젝트에서 반드시 사용해야 합니다.

라이브러리 설치하기

npm 명령어

$ npm install @cutehammond/modal --save

yarn 명령어

$ yarn add @cutehammond/modal

튜토리얼

1. GlobalModalProvider 등록하기

이 React app이 모달을 받을 수 있도록 <App /> 바깥을 감싸도록 합니다.

단, GlobalStyles과 같이 전역 스타일 설정이 존재하는 경우 이 설정이 먼저 적용되도록 합니다.

index.tsx

import React from "react";
import ReactDOM from "react-dom/client";
import GlobalStyles from "./styles";

import { GlobalModalProvider } from "@cutehammond/modal";
import { App } from "./App";

const root = ReactDOM.createRoot(
  document.getElementById("root") as HTMLElement
);

root.render(
  <>
    <GlobalStyles />
    <GlobalModalProvider>
      <App />
    </GlobalModalProvider>
  </>
);

2. 모달 만들기

이제 초기 설정은 끝났습니다. 예시로 간단한 정보를 전달하는 모달을 만들어 보겠습니다.

이 예시는 이 레포지토리의 demo 폴더에 포함되어 있습니다.

이 이외에도 무궁무진한 기능이 포함되어 있습니다! 이후 API 문서를 통해 자세한 방법이 추가될 예정입니다.


2-1. 모달 레이아웃 정의

모달의 레이아웃을 정의하는 데 emotion 라이브러리의 css 함수가 필요합니다.

위의 과정을 통해 만들어진 css 객체는 <ModalBase /> 컴포넌트의 layout prop에 들어갑니다.

레이아웃 내의 스타일은 scss, styled-components, css 등 다른 방법으로도 스타일을 정의할 수 있습니다. 여기서는 styled-components의 방식으로 예시를 들었습니다.

info.styled.tsx

/** @jsxImportSource '@emotion/react' */
import { css } from "@emotion/react";
import styled from "@emotion/styled";

export const Modal = css`
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  box-sizing: border-box;

  font-family: "Inter", "Noto Sans KR", sans-serif !important;
  background: black;
  border-radius: 20px;
  box-shadow: 0px 0px 10px var(--shadow);

  user-select: none;

  // 모바일 레이아웃
  @media screen and (max-width: 768px) {
    margin-left: 36px;
    margin-right: 36px;

    width: calc(100% - 72px);
  }

  // 데스크톱, 태블릿 레이아웃
  @media screen and (min-width: 768px) {
    margin-left: calc(50% - 348px);
    margin-right: calc(50% - 348px);

    width: 696px;
  }
`;

export const Container = styled.div`
  position: relative;
  padding: 30px;

  display: grid;
  grid-template-rows: 1fr 3fr 1fr;
  row-gap: 10px;

  ::-webkit-scrollbar {
    display: none;
  }

  // 모바일 레이아웃
  @media screen and (max-width: 768px) {
    max-height: 80%;
  }

  // 데스크톱, 태블릿 레이아웃
  @media screen and (min-width: 768px) {
    max-height: 700px;
  }
`;

export const Title = styled.div`
  font-weight: 700;
  color: white;

  font-size: 1.75rem;
  line-height: 100%;
`;

export const Content = styled.div`
  font-weight: 500;
  color: white;

  font-size: 1.25rem;
`;

export const ConfirmButton = styled.div`
  width: auto;
  height: auto;
  border-radius: 15px;
  padding: 10px;

  font-weight: 700;
  background-color: blue;
  color: white;

  font-size: 1.25rem;
  line-height: 100%;
  text-align: center;

  cursor: pointer;

  :hover {
    filter: brightness(0.75);
  }

  transition: filter 500ms;
`;

2-2. 모달 컴포넌트 정의

<ModalBase /> 컴포넌트를 이용하여 모달을 정의합니다.

  • 모달의 고유 이름 INFO_MODAL을 생성합니다.
  • layout prop에 위에서 정의한 css 객체를 대입합니다.
  • createModal 함수를 통해 모달을 등록합니다.

이때, 컴포넌트의 props는 무조건 ModalProps여야 합니다.

FAQ: 별도의 props를 전달하고 싶습니다. 이럴 땐 어떻게 해야 할까요?

useModal Hook에서 모달을 생성할 때 prop을 전달합니다.

(이후 API 문서를 통해 자세한 방법이 추가될 예정입니다.)

info.modal.tsx

import * as React from "react";
import { ModalProps, Modal, createModal } from "@cutehammond/modal";

import * as Styled from "./info.styled";

export const INFO_MODAL = "INFO_MODAL";

const InfoModal = (props: ModalProps) => {
  return (
    <ModalBase layout={Styled.Modal} {...props}>
      <Styled.Container>
        <Styled.Title>정보</Styled.Title>
        <Styled.Content>햄찌는 귀엽습니다.</Styled.Content>
        <Styled.ConfirmButton onClick={props.onClose}>
          확인
        </Styled.ConfirmButton>
      </Styled.Container>
    </ModalBase>
  );
};

createModal(INFO_MODAL, InfoModal);

2-3. useModal를 이용하여 create 함수 생성

useModal Hook은 모달 생성 함수를 반환합니다. 이 함수를 적절한 시기에 호출하면 됩니다.

  • useModal Hook의 매개 변수에 모달의 고유 이름을 대입합니다.

App.tsx

import React from "react";
import { useModal } from "@cutehammond/modal";

import { INFO_MODAL } from "./demo/modal/info";

export const App = () => {
  const { create: createInfoModal } = useModal(INFO_MODAL);

  return (
    <div>
      <button onClick={createInfoModal}>정보 모달 열기</button>
    </div>
  );
};

라이선스

Copyright (c) 2022 Jungheon Lee.

Licensed under The MIT License (MIT).