๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
Lect & Tip/React by GPT

REACT ๋ชจ๋‹ฌ, ํ† ์ŠคํŠธ, ๋“œ๋กœ์–ด ๋“ฑ ํŒ์—… ์ปดํฌ๋„ŒํŠธ ์„ค๊ณ„ ๋ฐ ๊ตฌํ˜„

by st๊ณต๊ฐ„ 2025. 6. 13.
๋ฐ˜์‘ํ˜•

REACT ๋ชจ๋‹ฌ, ํ† ์ŠคํŠธ, ๋“œ๋กœ์–ด ๋“ฑ ํŒ์—… ์ปดํฌ๋„ŒํŠธ ์„ค๊ณ„ ๋ฐ ๊ตฌํ˜„

์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ํŒ์—… ์š”์†Œ๋Š” ์‚ฌ์šฉ์ž์™€์˜ ์ƒํ˜ธ์ž‘์šฉ์„ ๊ฐœ์„ ํ•˜๊ณ  ์ค‘์š”ํ•œ ์ •๋ณด๋ฅผ ํšจ๊ณผ์ ์œผ๋กœ ์ „๋‹ฌํ•˜๋Š” ๋ฐ ํ•ต์‹ฌ์ ์ธ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋‹ฌ, ํ† ์ŠคํŠธ, ๋“œ๋กœ์–ด ๋“ฑ์˜ ํŒ์—… ์ปดํฌ๋„ŒํŠธ๋Š” ํ™”๋ฉด ๋‚ด์—์„œ ์ฃผ์˜๋ฅผ ์ง‘์ค‘์‹œํ‚ค๊ฑฐ๋‚˜ ๋ถ€๊ฐ€์ ์ธ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•  ๋•Œ ๋งŽ์ด ํ™œ์šฉ๋ฉ๋‹ˆ๋‹ค.

์ด๋ฒˆ ํฌ์ŠคํŒ…์—์„œ๋Š” ํŒ์—… ์ปดํฌ๋„ŒํŠธ์˜ ๋””์ž์ธ ์›์น™๊ณผ ๊ตฌํ˜„ ๋ฐฉ๋ฒ•, ๊ทธ๋ฆฌ๊ณ  ์• ๋‹ˆ๋ฉ”์ด์…˜ ๋ฐ ์ ‘๊ทผ์„ฑ ๊ณ ๋ ค์‚ฌํ•ญ์— ๋Œ€ํ•ด ์ž์„ธํžˆ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.

ํŒ์—… ์ปดํฌ๋„ŒํŠธ์˜ ๊ธฐ๋ณธ ๊ฐœ๋…๊ณผ ์ค‘์š”์„ฑ

ํŒ์—… ์ปดํฌ๋„ŒํŠธ๋Š” ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค(UI)์—์„œ ๋ณ„๋„์˜ ์˜ค๋ฒ„๋ ˆ์ด ์ฐฝ์œผ๋กœ ๋‚˜ํƒ€๋‚˜, ์ค‘์š”ํ•œ ๋ฉ”์‹œ์ง€, ํ”ผ๋“œ๋ฐฑ, ์˜ต์…˜ ๋˜๋Š” ์ถ”๊ฐ€ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•˜๋Š” ์š”์†Œ์ž…๋‹ˆ๋‹ค.

  • ๋ชจ๋‹ฌ(Modal): ์‚ฌ์šฉ์ž๊ฐ€ ๋ชจ๋‹ฌ ์ฐฝ์„ ๋‹ซ๊ธฐ ์ „๊นŒ์ง€ ๋‹ค๋ฅธ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜์ง€ ๋ชปํ•˜๋„๋ก ํ•˜๋Š” ํŒ์—… ์š”์†Œ๋กœ, ์ค‘์š”ํ•œ ๊ฒฝ๊ณ  ๋ฉ”์‹œ์ง€๋‚˜ ํผ ์ž…๋ ฅ ๋“ฑ์— ์ฃผ๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
  • ํ† ์ŠคํŠธ(Toast): ํ™”๋ฉด ํ•˜๋‹จ์ด๋‚˜ ์ƒ๋‹จ์— ์ž ์‹œ ํ‘œ์‹œ๋˜์–ด ๊ฐ„๋‹จํ•œ ์•Œ๋ฆผ์ด๋‚˜ ํ”ผ๋“œ๋ฐฑ์„ ์ œ๊ณตํ•˜๋Š” ์š”์†Œ๋กœ, ์ž๋™์œผ๋กœ ์‚ฌ๋ผ์ง€๋ฉฐ ์‚ฌ์šฉ์ž์˜ ํ๋ฆ„์„ ๋ฐฉํ•ดํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ๋“œ๋กœ์–ด(Drawer): ํ™”๋ฉด ์ธก๋ฉด์—์„œ ์Šฌ๋ผ์ด๋“œ ํ˜•ํƒœ๋กœ ๋‚˜ํƒ€๋‚˜๋Š” ๋ฉ”๋‰ด ๋˜๋Š” ํŒจ๋„๋กœ, ์ถ”๊ฐ€ ์˜ต์…˜์ด๋‚˜ ๋‚ด๋น„๊ฒŒ์ด์…˜์„ ์ œ๊ณตํ•˜๋Š” ๋ฐ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.

์ด๋“ค ํŒ์—… ์ปดํฌ๋„ŒํŠธ๋Š” ์ ์ ˆํ•œ ์• ๋‹ˆ๋ฉ”์ด์…˜ ํšจ๊ณผ์™€ ์ ‘๊ทผ์„ฑ ๊ธฐ๋Šฅ์ด ๊ฒฐํ•ฉ๋  ๊ฒฝ์šฐ, ์‚ฌ์šฉ์ž ๊ฒฝํ—˜(UX)์„ ํฌ๊ฒŒ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋””์ž์ธ ์›์น™๊ณผ UI/UX ๊ณ ๋ ค์‚ฌํ•ญ

ํŒ์—… ์ปดํฌ๋„ŒํŠธ๋ฅผ ์„ค๊ณ„ํ•  ๋•Œ๋Š” ๋ช‡ ๊ฐ€์ง€ ํ•ต์‹ฌ ์›์น™์„ ๊ณ ๋ คํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

1. ์‹œ๊ฐ์  ๊ณ„์ธต ๊ตฌ์กฐ์™€ ์ฃผ์˜ ์ง‘์ค‘

  • ์˜ค๋ฒ„๋ ˆ์ด ํšจ๊ณผ: ๋ชจ๋‹ฌ ์ฐฝ์ด๋‚˜ ๋“œ๋กœ์–ด๋Š” ๋ฐฐ๊ฒฝ์„ ์–ด๋‘ก๊ฒŒ ์ฒ˜๋ฆฌํ•˜์—ฌ ์‚ฌ์šฉ์ž์˜ ์‹œ์„ ์„ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ํŒ์—… ์š”์†Œ๋กœ ์ง‘์ค‘์‹œํ‚ต๋‹ˆ๋‹ค.
  • ๋ช…ํ™•ํ•œ ๊ฒฝ๊ณ„: ํŒ์—… ์ปดํฌ๋„ŒํŠธ๋Š” ์ฃผ๋ณ€ ์ฝ˜ํ…์ธ ์™€ ํ™•์—ฐํžˆ ๊ตฌ๋ถ„๋˜๋Š” ํ…Œ๋‘๋ฆฌ๋‚˜ ๊ทธ๋ฆผ์ž ํšจ๊ณผ๋ฅผ ์ฃผ์–ด, ์‹œ๊ฐ์  ๋ถ„๋ฆฌ๊ฐ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

2. ์• ๋‹ˆ๋ฉ”์ด์…˜๊ณผ ์ „ํ™˜ ํšจ๊ณผ

์• ๋‹ˆ๋ฉ”์ด์…˜์€ ํŒ์—… ์š”์†Œ๊ฐ€ ๋‚˜ํƒ€๋‚˜๊ณ  ์‚ฌ๋ผ์งˆ ๋•Œ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ถ€๋“œ๋Ÿฌ์šด ์ „ํ™˜ ํšจ๊ณผ๋ฅผ ์ œ๊ณตํ•˜์—ฌ, ๊ฐ‘์ž‘์Šค๋Ÿฌ์šด ํ™”๋ฉด ์ „ํ™˜์œผ๋กœ ์ธํ•œ ํ˜ผ๋ž€์„ ์ค„์ž…๋‹ˆ๋‹ค.

  • ํŽ˜์ด๋“œ ์ธ/์•„์›ƒ ํšจ๊ณผ: ๋ชจ๋‹ฌ ์ฐฝ์ด๋‚˜ ํ† ์ŠคํŠธ๊ฐ€ ์„œ์„œํžˆ ๋‚˜ํƒ€๋‚˜๊ณ  ์‚ฌ๋ผ์ง€๋Š” ํšจ๊ณผ๋ฅผ ์ ์šฉํ•˜๋ฉด, ์‹œ๊ฐ์  ์ž์—ฐ์Šค๋Ÿฌ์›€์ด ์ฆ๋Œ€๋ฉ๋‹ˆ๋‹ค.
  • ์Šฌ๋ผ์ด๋“œ ํšจ๊ณผ: ๋“œ๋กœ์–ด์˜ ๊ฒฝ์šฐ, ์ขŒ์ธก ๋˜๋Š” ์šฐ์ธก์—์„œ ๋ถ€๋“œ๋Ÿฝ๊ฒŒ ์Šฌ๋ผ์ด๋“œ๋˜์–ด ๋“ฑ์žฅํ•˜๋ฉด ์‚ฌ์šฉ์ž๊ฐ€ ์ง๊ด€์ ์œผ๋กœ ๋ฉ”๋‰ด์˜ ํ๋ฆ„์„ ์ดํ•ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

3. ์ ‘๊ทผ์„ฑ ๊ณ ๋ ค์‚ฌํ•ญ

ํŒ์—… ์ปดํฌ๋„ŒํŠธ๋Š” ๋ชจ๋“  ์‚ฌ์šฉ์ž์—๊ฒŒ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ ‘๊ทผ์„ฑ์„ ๋†’์ด๊ธฐ ์œ„ํ•œ ๋ช‡ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ํ‚ค๋ณด๋“œ ๋‚ด๋น„๊ฒŒ์ด์…˜: ๋ชจ๋‹ฌ ์ฐฝ์—์„œ๋Š” ํƒญ ํ‚ค๋ฅผ ์ด์šฉํ•ด ํŒ์—… ๋‚ด๋ถ€ ์š”์†Œ ๊ฐ„ ์ด๋™์ด ๊ฐ€๋Šฅํ•˜๋„๋ก ํ•˜๊ณ , ESC ํ‚ค๋ฅผ ๋ˆ„๋ฅด๋ฉด ์ฐฝ์ด ๋‹ซํžˆ๋„๋ก ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.
  • ARIA ์†์„ฑ: aria-modal, aria-labelledby, aria-describedby ๋“ฑ์˜ ์†์„ฑ์„ ์ถ”๊ฐ€ํ•˜์—ฌ, ์Šคํฌ๋ฆฐ ๋ฆฌ๋”๊ฐ€ ํŒ์—…์˜ ์—ญํ• ๊ณผ ๋‚ด์šฉ์„ ๋ช…ํ™•ํ•˜๊ฒŒ ์ธ์‹ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.
  • ํฌ์ปค์Šค ๊ด€๋ฆฌ: ํŒ์—…์ด ์—ด๋ฆด ๋•Œ ํฌ์ปค์Šค๋ฅผ ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ ๋‚ด์˜ ์ฒซ ๋ฒˆ์งธ ํฌ์ปค์Šค ๊ฐ€๋Šฅํ•œ ์š”์†Œ๋กœ ์ด๋™์‹œํ‚ค๊ณ , ๋‹ซํž ๋•Œ ์ด์ „ ํฌ์ปค์Šค ์œ„์น˜๋กœ ๋ณต์›ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์‚ฌ์šฉ์ž ํ˜ผ๋ž€์„ ์ตœ์†Œํ™”ํ•ฉ๋‹ˆ๋‹ค.

๋ชจ๋‹ฌ ์ปดํฌ๋„ŒํŠธ ๊ตฌํ˜„ ๋ฐฉ๋ฒ•

๋ชจ๋‹ฌ์€ ์ค‘์š”ํ•œ ์ •๋ณด๋ฅผ ์‚ฌ์šฉ์ž์—๊ฒŒ ์ „๋‹ฌํ•˜๊ฑฐ๋‚˜, ์ค‘์š”ํ•œ ์ž…๋ ฅ์„ ์š”๊ตฌํ•  ๋•Œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ๋ฆฌ์•กํŠธ์—์„œ ๋ชจ๋‹ฌ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๊ธฐ๋ณธ์ ์ธ ๋ฐฉ๋ฒ•์€ ์ƒํƒœ ๊ด€๋ฆฌ๋ฅผ ํ†ตํ•ด ๋ชจ๋‹ฌ์˜ ์—ด๋ฆผ/๋‹ซํž˜์„ ์ œ์–ดํ•˜๊ณ , ์˜ค๋ฒ„๋ ˆ์ด์™€ ๋‚ด๋ถ€ ์ฝ˜ํ…์ธ ๋ฅผ ๋ณ„๋„์˜ ์ปดํฌ๋„ŒํŠธ๋กœ ๋ถ„๋ฆฌํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋ชจ๋‹ฌ ์ปดํฌ๋„ŒํŠธ ์ฝ”๋“œ ์˜ˆ์ œ

import React, { useEffect, useRef } from 'react';
import styled from 'styled-components';

const Overlay = styled.div`
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  animation: fadeIn 0.3s ease;

  @keyframes fadeIn {
    from { opacity: 0; }
    to { opacity: 1; }
  }
`;

const ModalContent = styled.div`
  background: #fff;
  padding: 20px;
  width: 90%;
  max-width: 500px;
  border-radius: 8px;
  position: relative;
  animation: slideIn 0.3s ease;

  @keyframes slideIn {
    from { transform: translateY(-20px); opacity: 0; }
    to { transform: translateY(0); opacity: 1; }
  }
`;

const CloseButton = styled.button`
  position: absolute;
  top: 10px;
  right: 10px;
  border: none;
  background: transparent;
  font-size: 1.2rem;
  cursor: pointer;
`;

const Modal = ({ isOpen, onClose, children, titleId, descriptionId }) => {
  const modalRef = useRef(null);

  useEffect(() => {
    if (isOpen && modalRef.current) {
      modalRef.current.focus();
    }
  }, [isOpen]);

  if (!isOpen) return null;

  return (
    <Overlay onClick={onClose}>
      <ModalContent
        role="dialog"
        aria-modal="true"
        aria-labelledby={titleId}
        aria-describedby={descriptionId}
        tabIndex={-1}
        ref={modalRef}
        onClick={e => e.stopPropagation()}
      >
        <CloseButton onClick={onClose} aria-label="๋‹ซ๊ธฐ ๋ฒ„ํŠผ">&times;</CloseButton>
        {children}
      </ModalContent>
    </Overlay>
  );
};

export default Modal;

์œ„ ์ฝ”๋“œ๋Š” ๋ชจ๋‹ฌ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ตฌํ˜„ํ•œ ์˜ˆ์ œ์ž…๋‹ˆ๋‹ค.

  • ์˜ค๋ฒ„๋ ˆ์ด: ์ „์ฒด ํ™”๋ฉด์„ ๋ฎ๋Š” ๋ฐ˜ํˆฌ๋ช… ๋ฐฐ๊ฒฝ์„ ์ œ๊ณตํ•˜์—ฌ ๋ชจ๋‹ฌ์— ์ง‘์ค‘ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.
  • ์• ๋‹ˆ๋ฉ”์ด์…˜: fadeIn๊ณผ slideIn ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ์ ์šฉํ•˜์—ฌ ๋ชจ๋‹ฌ์ด ๋ถ€๋“œ๋Ÿฝ๊ฒŒ ๋‚˜ํƒ€๋‚˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.
  • ์ ‘๊ทผ์„ฑ: ์—ญํ• (role), aria ์†์„ฑ, ํฌ์ปค์Šค ๊ด€๋ฆฌ๋ฅผ ํ†ตํ•ด ์Šคํฌ๋ฆฐ ๋ฆฌ๋” ์‚ฌ์šฉ์ž์™€ ํ‚ค๋ณด๋“œ ์‚ฌ์šฉ์ž ๋ชจ๋‘์—๊ฒŒ ์ ‘๊ทผ์„ฑ์„ ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค.

ํ† ์ŠคํŠธ ์ปดํฌ๋„ŒํŠธ ๊ตฌํ˜„ ๋ฐฉ๋ฒ•

ํ† ์ŠคํŠธ๋Š” ๊ฐ„๋‹จํ•œ ์•Œ๋ฆผ ๋ฉ”์‹œ์ง€๋ฅผ ์ œ๊ณตํ•˜๋Š” ํŒ์—… ์š”์†Œ๋กœ, ์งง์€ ์‹œ๊ฐ„ ๋™์•ˆ ํ™”๋ฉด์— ํ‘œ์‹œ๋˜๋ฉฐ ์ž๋™์œผ๋กœ ์‚ฌ๋ผ์ง‘๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž์—๊ฒŒ ์ค‘์š”ํ•œ ์ƒํƒœ ๋ณ€ํ™”๋‚˜ ํ”ผ๋“œ๋ฐฑ์„ ์ œ๊ณตํ•˜๋Š” ๋ฐ ํšจ๊ณผ์ ์ž…๋‹ˆ๋‹ค.

ํ† ์ŠคํŠธ ์ปดํฌ๋„ŒํŠธ ์ฝ”๋“œ ์˜ˆ์ œ

import React, { useEffect } from 'react';
import styled from 'styled-components';

const ToastContainer = styled.div`
  position: fixed;
  bottom: 20px;
  right: 20px;
  background: #333;
  color: #fff;
  padding: 15px 20px;
  border-radius: 4px;
  opacity: 0;
  animation: slideUp 0.5s forwards, fadeOut 0.5s forwards 3s;
  z-index: 1000;

  @keyframes slideUp {
    from { transform: translateY(100%); opacity: 0; }
    to { transform: translateY(0); opacity: 1; }
  }

  @keyframes fadeOut {
    from { opacity: 1; }
    to { opacity: 0; }
  }
`;

const Toast = ({ message, onClose }) => {
  useEffect(() => {
    const timer = setTimeout(() => {
      onClose();
    }, 3500); // 3.5์ดˆ ํ›„ ํ† ์ŠคํŠธ ์ข…๋ฃŒ
    return () => clearTimeout(timer);
  }, [onClose]);

  return <ToastContainer>{message}</ToastContainer>;
};

export default Toast;

ํ† ์ŠคํŠธ ์ปดํฌ๋„ŒํŠธ๋Š”

  • ์• ๋‹ˆ๋ฉ”์ด์…˜: slideUp๊ณผ fadeOut ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ํ†ตํ•ด ๋ถ€๋“œ๋Ÿฝ๊ฒŒ ๋“ฑ์žฅํ•˜๊ณ  ์‚ฌ๋ผ์ง‘๋‹ˆ๋‹ค.
  • ์ž๋™ ์ข…๋ฃŒ: ์ผ์ • ์‹œ๊ฐ„ ํ›„ ์ž๋™์œผ๋กœ onClose ์ฝœ๋ฐฑ์„ ํ˜ธ์ถœํ•˜์—ฌ ํ† ์ŠคํŠธ๋ฅผ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.

๋“œ๋กœ์–ด ์ปดํฌ๋„ŒํŠธ ๊ตฌํ˜„ ๋ฐฉ๋ฒ•

๋“œ๋กœ์–ด๋Š” ํ™”๋ฉด์˜ ์ขŒ์ธก์ด๋‚˜ ์šฐ์ธก์—์„œ ์Šฌ๋ผ์ด๋“œ๋˜์–ด ๋‚˜ํƒ€๋‚˜๋Š” ํŒจ๋„๋กœ, ๋‚ด๋น„๊ฒŒ์ด์…˜ ๋ฉ”๋‰ด, ์ถ”๊ฐ€ ์˜ต์…˜ ๋˜๋Š” ํ•„ํ„ฐ๋ง ๊ธฐ๋Šฅ ๋“ฑ์„ ์ œ๊ณตํ•  ๋•Œ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋“œ๋กœ์–ด๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ํ•„์š”ํ•œ ์‹œ์ ์—๋งŒ ๋‚˜ํƒ€๋‚˜๋ฏ€๋กœ ํ™”๋ฉด ๊ณต๊ฐ„์„ ํšจ์œจ์ ์œผ๋กœ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋“œ๋กœ์–ด ์ปดํฌ๋„ŒํŠธ ์ฝ”๋“œ ์˜ˆ์ œ

import React from 'react';
import styled from 'styled-components';

const DrawerContainer = styled.div`
  position: fixed;
  top: 0;
  ${props => (props.position === 'left' ? 'left: 0;' : 'right: 0;')}
  width: 300px;
  height: 100%;
  background: #fff;
  box-shadow: ${props => (props.position === 'left' ? '2px 0 5px rgba(0,0,0,0.3)' : '-2px 0 5px rgba(0,0,0,0.3)')};
  transform: translateX(${props => (props.open ? '0' : props.position === 'left' ? '-100%' : '100%')});
  transition: transform 0.3s ease;
  z-index: 1000;
`;

const DrawerContent = styled.div`
  padding: 20px;
`;

const Drawer = ({ open, onClose, position = 'left', children }) => {
  return (
    <>
      {open && (
        <div
          onClick={onClose}
          style={{
            position: 'fixed',
            top: 0,
            left: 0,
            right: 0,
            bottom: 0,
            backgroundColor: 'rgba(0,0,0,0.3)',
            zIndex: 900,
          }}
        />
      )}
      <DrawerContainer open={open} position={position}>
        <DrawerContent>
          {children}
        </DrawerContent>
      </DrawerContainer>
    </>
  );
};

export default Drawer;

๋“œ๋กœ์–ด ์ปดํฌ๋„ŒํŠธ๋Š”

  • ์Šฌ๋ผ์ด๋“œ ์• ๋‹ˆ๋ฉ”์ด์…˜: transform๊ณผ transition์„ ์ด์šฉํ•ด ๋ถ€๋“œ๋Ÿฝ๊ฒŒ ์—ด๋ฆฌ๊ณ  ๋‹ซํžˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.
  • ์˜ค๋ฒ„๋ ˆ์ด: ๋“œ๋กœ์–ด๊ฐ€ ์—ด๋ ธ์„ ๋•Œ ๋ฐฐ๊ฒฝ์„ ์–ด๋‘ก๊ฒŒ ์ฒ˜๋ฆฌํ•˜์—ฌ, ์‚ฌ์šฉ์ž๊ฐ€ ๋“œ๋กœ์–ด ์™ธ๋ถ€๋ฅผ ํด๋ฆญํ•˜๋ฉด ๋‹ซํžˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

๊ฒฐ๋ก 

๋ชจ๋‹ฌ, ํ† ์ŠคํŠธ, ๋“œ๋กœ์–ด์™€ ๊ฐ™์€ ํŒ์—… ์ปดํฌ๋„ŒํŠธ๋Š” ์‚ฌ์šฉ์ž์—๊ฒŒ ์ค‘์š”ํ•œ ํ”ผ๋“œ๋ฐฑ๊ณผ ๋ถ€๊ฐ€ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•˜๋Š” ๋™์‹œ์—, ์ „์ฒด UI์˜ ์ผ๊ด€์„ฑ๊ณผ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ํ–ฅ์ƒ์‹œํ‚ค๋Š” ๋ฐ ํ•ต์‹ฌ์ ์ธ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.

  • ๋””์ž์ธ ์ธก๋ฉด์—์„œ๋Š” ์‹œ๊ฐ์  ๊ณ„์ธต ๊ตฌ์กฐ, ์• ๋‹ˆ๋ฉ”์ด์…˜ ์ „ํ™˜, ์ ‘๊ทผ์„ฑ ๊ณ ๋ ค์‚ฌํ•ญ์„ ์ค‘์ ์ ์œผ๋กœ ๋ฐ˜์˜ํ•˜์—ฌ ์‚ฌ์šฉ์ž ์นœํ™”์ ์ธ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌ์ถ•ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • ๊ตฌํ˜„ ์ธก๋ฉด์—์„œ๋Š” ๋ฆฌ์•กํŠธ์˜ ์ƒํƒœ ๊ด€๋ฆฌ์™€ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋ง์„ ํšจ๊ณผ์ ์œผ๋กœ ํ™œ์šฉํ•˜์—ฌ, ๊ฐ ํŒ์—… ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋…๋ฆฝ์ ์œผ๋กœ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ชจ๋“ˆํ™”๋œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.
  • ์ ‘๊ทผ์„ฑ๊ณผ ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ๊ณ ๋ คํ•œ ์„ค๊ณ„๋Š” ์Šคํฌ๋ฆฐ ๋ฆฌ๋”์™€ ํ‚ค๋ณด๋“œ ๋‚ด๋น„๊ฒŒ์ด์…˜์„ ์ง€์›ํ•˜๋ฉฐ, ์‚ฌ์šฉ์ž ํ”ผ๋“œ๋ฐฑ์„ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ์œ ๋„ํ•  ์ˆ˜ ์žˆ๋Š” ์ค‘์š”ํ•œ ์š”์†Œ์ž…๋‹ˆ๋‹ค.

์‹ค์ œ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” ๊ฐ ํŒ์—… ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋””์ž์ธ ์‹œ์Šคํ…œ์˜ ์ผ๋ถ€๋กœ ํ†ตํ•ฉํ•˜์—ฌ, ํŒ€ ๋‚ด์—์„œ ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๊ณ  ์œ ์ง€๋ณด์ˆ˜ํ•˜๊ธฐ ์‰ฌ์šด ํ˜•ํƒœ๋กœ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ, ์‚ฌ์šฉ์ž ํ…Œ์ŠคํŠธ๋ฅผ ํ†ตํ•ด ์• ๋‹ˆ๋ฉ”์ด์…˜ ์†๋„, ์ธํ„ฐ๋ž™์…˜ ํ๋ฆ„, ์ ‘๊ทผ์„ฑ ๊ธฐ๋Šฅ ๋“ฑ์„ ์ง€์†์ ์œผ๋กœ ๊ฐœ์„ ํ•˜๋ฉด, ์ „์ฒด์ ์ธ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ํ’ˆ์งˆ๊ณผ ์‚ฌ์šฉ์ž ๋งŒ์กฑ๋„๋ฅผ ํฌ๊ฒŒ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํŒ์—… ์ปดํฌ๋„ŒํŠธ ์„ค๊ณ„์™€ ๊ตฌํ˜„์€ ๋‹จ์ˆœํ•œ UI ์š”์†Œ๋ฅผ ๋„˜์–ด์„œ, ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ๊ทน๋Œ€ํ™”ํ•˜๊ณ  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์„ฑ๊ณต์ ์ธ ์šด์˜์— ๊ธฐ์—ฌํ•˜๋Š” ํ•ต์‹ฌ ์ „๋žต์ž…๋‹ˆ๋‹ค. ์•ž์œผ๋กœ ๋ชจ๋‹ฌ, ํ† ์ŠคํŠธ, ๋“œ๋กœ์–ด ๋“ฑ์˜ ํŒ์—… ์š”์†Œ๋ฅผ ํ™œ์šฉํ•œ ๋‹ค์–‘ํ•œ UI/UX ๊ฐœ์„  ๋ฐฉ๋ฒ•์„ ์ ์šฉํ•˜์—ฌ, ์‚ฌ์šฉ์ž๊ฐ€ ๋ณด๋‹ค ์ง๊ด€์ ์ด๊ณ  ์พŒ์ ํ•˜๊ฒŒ ์›น ์„œ๋น„์Šค๋ฅผ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์ง€์†์ ์œผ๋กœ ๊ฐœ์„ ํ•ด ๋‚˜๊ฐ€์‹œ๊ธธ ๋ฐ”๋ž๋‹ˆ๋‹ค.

๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€