Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/components/chip/Chip.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { Meta, StoryObj } from '@storybook/react';
import Chip from './Chip';

const meta = {
title: 'Components/Chip',
title: 'Components/Chip/Base',
component: Chip,
parameters: {
layout: 'centered',
Expand All @@ -29,7 +29,7 @@ export const RoundedLight: Story = {
export const SquareOutlined: Story = {
args: {
text: '오프라인',
variant: 'square-light',
variant: 'square-outlined',
},
};

Expand All @@ -54,13 +54,13 @@ export const AllStates: Story = {
<div className="flex gap-2">
<Chip text="모집중" variant="rounded-filled" />
<Chip text="1월 7일" variant="rounded-light" />
<Chip text="오프라인" variant="square-light" />
<Chip text="오프라인" variant="square-outlined" />
<Chip text="마감" variant="square-filled" />
</div>
<div className="flex gap-2">
<Chip text="자유책" variant="rounded-filled" isPast={true} />
<Chip text="1월 7일" variant="rounded-light" isPast={true} />
<Chip text="오프라인" variant="square-light" isPast={true} />
<Chip text="오프라인" variant="square-outlined" isPast={true} />
<Chip text="마감" variant="square-filled" isPast={true} />
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/components/chip/Chip.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import Chip from '@/components/chip/Chip';
import '@testing-library/jest-dom';
import { render, screen } from '@testing-library/react';

describe('TextChip', () => {
describe('Chip', () => {
it('텍스트가 올바르게 렌더링되어야 한다', () => {
render(<Chip text="테스트" />);
const chip = screen.getByText('테스트');
Expand Down
14 changes: 8 additions & 6 deletions src/components/chip/Chip.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { twMerge } from 'tailwind-merge';

const CHIP_VARIANTS = {
'rounded-filled': 'rounded-full bg-green-light-02 text-green-dark-01',
'rounded-light': 'rounded-full bg-green-normal-01 text-gray-white',
'square-light':
'rounded border border-gray-normal-02 bg-gray-light-01 text-gray-dark-01',
'square-filled': 'rounded bg-green-dark-01 text-gray-dark-01',
'rounded-filled':
'rounded-full bg-green-light-02 text-green-dark-01 font-semibold',
'rounded-light':
'rounded-full bg-green-normal-01 text-gray-white font-semibold',
'square-outlined':
'rounded-md border border-green-normal-01 bg-gray-white text-green-normal-01',
'square-filled': 'rounded-md bg-green-normal-01 text-gray-white px-2',
} as const;

type ChipVariant = keyof typeof CHIP_VARIANTS;
Expand All @@ -24,7 +26,7 @@ function Chip({
className,
}: ChipProps) {
const baseStyles =
'inline-flex items-center justify-center px-2.5 py-1 text-sm font-semibold';
'inline-flex items-center justify-center px-2.5 py-1 text-sm font-medium';

const combinedClassName = twMerge(
baseStyles,
Expand Down
48 changes: 48 additions & 0 deletions src/components/chip/club-chip/ClubChip.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import type { Meta, StoryObj } from '@storybook/react';
import ClubChip from './ClubChip';

const meta = {
title: 'Components/Chip/ClubChip',
component: ClubChip,
parameters: {
layout: 'centered',
},
} satisfies Meta<typeof ClubChip>;

export default meta;
type Story = StoryObj<typeof ClubChip>;

export const Completed: Story = {
args: {
variant: 'completed',
},
};

export const Scheduled: Story = {
args: {
variant: 'scheduled',
},
};

export const Pending: Story = {
args: {
variant: 'pending',
},
};

export const Confirmed: Story = {
args: {
variant: 'confirmed',
},
};

export const AllStates: Story = {
render: () => (
<div className="flex gap-2">
<ClubChip variant="completed" />
<ClubChip variant="scheduled" />
<ClubChip variant="pending" />
<ClubChip variant="confirmed" />
</div>
),
};
29 changes: 29 additions & 0 deletions src/components/chip/club-chip/ClubChip.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import ClubChip from './ClubChip';
import '@testing-library/jest-dom';
import { render, screen } from '@testing-library/react';

describe('ClubChip', () => {
it('variant에 따라 올바른 텍스트가 렌더링되어야 한다', () => {
render(<ClubChip variant="completed" />);
expect(screen.getByText('참여완료')).toBeInTheDocument();
});

it('모든 variant가 올바르게 렌더링되어야 한다', () => {
const { rerender } = render(<ClubChip variant="completed" />);
expect(screen.getByText('참여완료')).toBeInTheDocument();

rerender(<ClubChip variant="scheduled" />);
expect(screen.getByText('참여예정')).toBeInTheDocument();

rerender(<ClubChip variant="pending" />);
expect(screen.getByText('개설대기')).toBeInTheDocument();

rerender(<ClubChip variant="confirmed" />);
expect(screen.getByText('개설확정')).toBeInTheDocument();
});

it('className prop으로 스타일을 오버라이드할 수 있어야 한다', () => {
render(<ClubChip variant="completed" className="custom-class" />);
expect(screen.getByText('참여완료')).toHaveClass('custom-class');
});
});
54 changes: 54 additions & 0 deletions src/components/chip/club-chip/ClubChip.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import Chip from '../Chip';
import { twMerge } from 'tailwind-merge';

type ClubChipVariant = 'completed' | 'scheduled' | 'pending' | 'confirmed';

const CLUB_CHIP_TEXT = {
completed: '참여완료',
scheduled: '참여예정',
pending: '개설대기',
confirmed: '개설확정',
} as const;

interface ClubChipProps {
variant: ClubChipVariant;
className?: string;
}

function ClubChip({ variant, className }: ClubChipProps) {
const getChipVariant = () => {
switch (variant) {
case 'completed':
return 'square-filled';
case 'scheduled':
return 'square-filled';
case 'pending':
return 'square-outlined';
case 'confirmed':
return 'square-filled';
}
};

const getCustomClassName = () => {
switch (variant) {
case 'completed':
return 'bg-gray-normal-01 text-gray-dark-02';
case 'scheduled':
return 'bg-green-normal-01 text-gray-white';
case 'pending':
return 'border-blue-normal-01 text-blue-normal-01';
case 'confirmed':
return 'bg-blue-normal-01 text-gray-white';
}
Comment on lines +19 to +42
Copy link
Contributor

Choose a reason for hiding this comment

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

큰 차이는 없을 거 같긴한데 통일성 있게 객체화 시키는 방법은 어떤가요??
객체화 시켜서 사용하는 방법과 switch case 문을 같이 사용한 이유가 있으실까요?

const CLUB_CHIP_VARIANTS = {
  completed: 'square-filled',
  scheduled: 'square-filled',
  pending: 'square-outlined',
  confirmed: 'square-filled',
} as const;

const CLUB_CHIP_CLASSES = {
  completed: 'bg-gray-normal-01 text-gray-dark-02',
  scheduled: 'bg-green-normal-01 text-gray-white',
  pending: 'border-blue-normal-01 text-blue-normal-01',
  confirmed: 'bg-blue-normal-01 text-gray-white',
} as const;

};

return (
<Chip
text={CLUB_CHIP_TEXT[variant]}
variant={getChipVariant()}
className={twMerge(getCustomClassName(), className)}
Comment on lines +48 to +49
Copy link
Contributor

Choose a reason for hiding this comment

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

variant={CHIP_VARIANTS[variant]}
className={twMerge(CHIP_CLASSES[variant], className)}

/>
);
}

export default ClubChip;
3 changes: 3 additions & 0 deletions tailwind.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ const config: Config = {
'dark-03': '#004c41',
darker: '#003b33',
},
blue: {
'normal-01': '#007AFF',
},
},
},
},
Expand Down