List 컴포넌트 구현

List 컴포넌트는 배열 데이터를 출력하는 역할을 담당하며, items에 배열 데이터를 넘겨주고, renderItem에 렌더링 로직을 주입하는 방식으로 컴포넌트로서 명시적으로 사용할 수 있게 설계했습니다.

interface Props<T> {
  items: T[];
  renderItem: (item: T) => ReactNode;
}

Usage

const list = [
	{
		id: 1,
		title: 'title1',
	},
	{
		id: 2,
		title: 'title2',
	},
]

export default function Example() {
	return (
		<List items={list} renderItem={(item) => (
			<div key={item.id}>{item.title}</div>
		)}/>
	)
}

Image 컴포넌트 구현

Image 컴포넌트는 이미지를 렌더링하는 역할을 담당합니다.

이미지 경로, 크기, 그리고 선택적으로 borderRadius를 받아 사이즈에 맞게 cover 모드로 중앙에 배치되도록 구현했습니다.

type Props = {
  url: string;
  size: {
    width: string;
    height: string;
  };
  borderRadius?: string;
} & HTMLAttributes<HTMLDivElement>;

Usage

import { Image } from '@components/common';

export default function Example() {
  return (
    <Image
      url="<https://kakao.com>"
      borderRadius="8px"
      size={{
        width: '350px',
        height: '275px',
      }}
    />
  );
}

RecruitmentCard 합성 컴포넌트 구현

메인 페이지의 구인/구직 리스트를 표시하는 RecruitmentCard를 합성 패턴을 사용하여 구현했습니다. 합성 패턴을 사용한 이유는 향후 변경사항이 발생할 경우, 유연하게 처리할 수 있도록 하기 위함입니다.

type Props = {
  recruitment: RecruitmentItem;
  children: ReactNode;
};

export default function RecruitmentCard({ recruitment, children }: Props) {
  return (
    <RecruitmentCardContextProvider recruitment={recruitment}>
      <Card
        borderColor="white"
        css={[
          responsiveStyle({
            default: {
              padding: '24px',
              cursor: 'pointer',
            },
            mobile: {
              padding: '16px',
            },
          }),
          bounceAnimation,
        ]}
      >
        {children}
      </Card>
    </RecruitmentCardContextProvider>
  );
}

RecruitmentCard.Title = Title;
RecruitmentCard.Button = Button;
RecruitmentCard.CompanyName = CompanyName;
RecruitmentCard.CompanyImage = CompanyImage;
RecruitmentCard.Detail = Detail;
RecruitmentCard.Salary = Salary;

Usage