Skip to content

Conversation

@nunoria
Copy link
Collaborator

@nunoria nunoria commented Apr 19, 2025

1주차 과제 - TeamMemberCard 만들기

개요

팀원들의 카드리스트를 만들고 클릭시 상세 정보를 보여준다.

구현 내용

1. 기본과제

  • TeamMemberCard 컴포넌트 생성

2. 선택과제

  • 입사연차 표시
  • 부서별 카드 배경색 분리
  • 클릭시 모달로 상세정보 표현

3. 기타

  • tailwind spacing UC(utilitycase) extend

    • p-20pxr1.25rem 으로 자동 적용
  • cn util ( tailwind-merge, clsx 사용)

    • tailwind className 적용시, 조건부 또는 오류 문법, 중복 UC 제거
    const isActive = true;
    const isError = false;
    cn("btn px-4", isActive && "btn-active", isError && "text-red-500", "px-2" );
    // 결과: "btn bg-blue-500 px-2"

추가 Library

  • clsx
  • tailwind-merge
  • lucide-react (아이콘)

주요 학습내용

1. radix ui 스타일의 컴포넌트 구현

  • 재사용과 확장성 극대화 및 일관된 컴포넌트 사용패턴 목표로 함
  • Modal 컴포넌트 사용예시
    /* Anatomy */
    // 각 항목은 className 을 통해서 커스텀 가능
    <Modal> {/* 오버레이 */}
      <ModalTrigger></ModalTrigger> {/* 트리거 */ }
      <ModalContent> {/* 컨텐츠 */}
        <ModalClose></ModalClose> {/* 클로즈 버튼(optional) */}
      </ModalContent>
    </Modal>
    
    // EX 1, default 디자인,close 버튼 사용
    <Modal> {/* 오버레이 */}
      <ModalTrigger> <button>{"모달열기"}</button></ModalTrigger> {/* 기본 트리거사용 */ }
      <ModalContent> {/* 컨텐츠 */}
    	<p> 모달 내용</p>
      </ModalContent>
    </Modal>
    
    // EX 2, 스타일 확장
    <Modal classNmae="bg-red-100" onClick={null}> {/* 오버레이 색상 변경, 오버레이 클릭시 닫힘 방지 */}
      <ModalTrigger> <button>{"모달열기"}</button></ModalTrigger> {/* 기본 트리거사용 */ }
      <ModalContent className="data-[state=open]:animate-fadeIn"> {/* 컨텐츠 에니메이션 적용 */}
    	<p> 모달 내용</p>
    	<ModalClose className="relative right-0 w-full text-center">{"닫힘"}</ModalClose> {/* 클로즈 버튼 하단에 적용 */}
      </ModalContent>
    </Modal>
    
    // EX3 외부 state 로 제어
    <Modal open={modalOpen} onOpenChange={setModalOpen}>  {/* 오버레이 */}
      <ModalContent> {/* 컨텐츠 */}
    	<p> 모달 내용</p>
      </ModalContent>
    </Modal>
    <button onClick={()=>setModalOpen(true)}>{"모달열기"}</button> {/* 트리거 버튼 */}

2. 사용 기술

  • Context API (createContext, useContext)
    • 모달의 상태(openModal, closeModal, open)를 하위 컴포넌트에 공유하기 위해 사용
  • Portals (createPortal)
    • 모달을 부모 컴포넌트가 아닌 document.body에 렌더링하여 레이어 분리, z-index 문제 방지.
  • Children Utilities (Children, isValidElement)
    • 모달 콘텐츠 내부에 커스텀 닫기 버튼이 있는지 확인하기 위해 사용.
    • JSX로 들어온 children을 검사 및 조건 분기 처리

UI/UX 특징

1. 반응형

  • screen break point 4단계 : 480px, 760px, 976px, 1440px
  • flexible container

RoyKimDeveloper and others added 10 commits April 5, 2025 22:08
- CSS reset
- tailwind spacing에 "pxr" suffix 추가
- screen 사이즈 조정

Signed-off-by: kibum.lee <kissyou7@gmail.com>
- TeamMemberCard 컴포넌트 구현
- lucide-react 라이브러리 설치

Signed-off-by: kibum.lee <kissyou7@gmail.com>
- Modal 컴포넌트 구현
- TeamMemberCard 컴포넌트에 Modal 컴포넌트 적용

Signed-off-by: kibum.lee <kissyou7@gmail.com>
- 조건부 tailwind uc 처리
- 중복 tailwind uc 제거

Signed-off-by: kibum.lee <kissyou7@gmail.com>
Signed-off-by: kibum.lee <kissyou7@gmail.com>
- onOpenChange, open prop을 사용하여 외부에서 상태 관리 가능하도록함
- ModalClose 추가 하여, Close 커스텀 가능하도록함
- aria 속성 추가

Signed-off-by: kibum.lee <kissyou7@gmail.com>
- Card 컴포넌트는 공통 적용부분만 분리
- TeamMemberCard의 모달 state 직접관리
- 기타 코드 정리

Signed-off-by: kibum.lee <kissyou7@gmail.com>
- mount, visible 상태 추가

Signed-off-by: kibum.lee(t14) <kissyou7@gmail.com>
const { visible, closeModal } = useModalContext();

useEffect(() => {
const handleEsc = (e) => {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이렇게 하면 모든 domtree에 Modal 이 활성화 되어있을경우에 esc 이벤트가 다 closeModal로 되었던 경험이 있어서
useRef()로 사용해서 해당 node에 event 걸면 어떨까요??

const isOpen = open ? open : _open;

const openModal = useCallback(() => {
onOpenChange && onOpenChange(true);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

현재는 context provider를 사용하고 있으신데 onOpenChange,setOpen을 하나로 통합 할 수 있을거같은데 제가 contextValue는 사용해보지 않아서 ㅠㅠ 혹시 방법이 없을까욤

제 경우,

전역상태라이브러리 관리를 썼을경우에는 부모 컴포넌트에서 전역상태를 수정하면 자식에서도 수정되는 형식으로

const Modal = ({ children }: Props) => {
  const { toggleModal } = useModalStore();
  return (
    <div>
      <div className={styles['modal-overlay']} onClick={toggleModal}></div>
      <div className={styles['modal-content-container']}>
        <div className={styles['modal-content']}>
          <h1>모달테스트</h1>
          {children}
          <button
            onClick={toggleModal}
            className={styles['modal-close-button']}
            type='button'
          >
            닫기
          </button>
        </div>
      </div>
    </div>
  );
};

export default Modal;

이런식으로

useModalStore 상태를 바꿔줬던것 같습니다. !

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • mount, open의 역할이 궁금합니다!

nunoria added 2 commits April 22, 2025 13:18
- mount 상태에 따른 content 렌더링 버그 수정
- ModalTrigger 버그수정

Signed-off-by: kibum.lee <kissyou7@gmail.com>
- ModalClose 존재하지 않는경우 Default 스타일로 ModalClose 스타일 적용

Signed-off-by: kibum.lee <kissyou7@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants