diff --git a/src/assets/icons/check.svg b/src/assets/icons/check.svg new file mode 100644 index 0000000..3adb08a --- /dev/null +++ b/src/assets/icons/check.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/components/ui/Chip/ColorChip.tsx b/src/components/ui/Chip/ColorChip.tsx new file mode 100644 index 0000000..f813ceb --- /dev/null +++ b/src/components/ui/Chip/ColorChip.tsx @@ -0,0 +1,15 @@ +import { HexColor } from '@/constants/colors'; +import { cn } from '@/utils/helper'; +import { HTMLAttributes } from 'react'; + +interface ColorChipProps extends HTMLAttributes { + color: HexColor; +} + +export default function ColorChip({ color, className, ...props }: ColorChipProps) { + return ( + + {color} + + ); +} diff --git a/src/components/ui/Chip/ColorPicker.tsx b/src/components/ui/Chip/ColorPicker.tsx new file mode 100644 index 0000000..30c8a6d --- /dev/null +++ b/src/components/ui/Chip/ColorPicker.tsx @@ -0,0 +1,45 @@ +import Image from 'next/image'; +import { DEFAULT_COLORS } from '@/constants/colors'; +import check_icon from '@/assets/icons/check.svg'; +import ColorChip from './ColorChip'; +import { cn } from '@/utils/helper'; + +/** + * input name을 통한 radio group으로 구성된 컬러 피커 입니다. + * Controller를 사용하여 `react-hook-form`과 `ColorPicker` 컴포넌트를 연결하시면 됩니다. + * (name은 zod schema key값을 내려주면 됩니다.) + * + * @example + * ( + * field.onChange(value)} + * /> + * )} + * /> + */ + +interface ColorPickerProps { + name: string; + selected: string; + onChange: (value: string) => void; + className?: string; +} + +export default function ColorPicker({ name = 'color', selected, onChange, className }: ColorPickerProps) { + return ( +
+ {DEFAULT_COLORS.map((color) => ( + + ))} +
+ ); +} diff --git a/src/components/ui/Chip/NumberChip.tsx b/src/components/ui/Chip/NumberChip.tsx new file mode 100644 index 0000000..8df8dd4 --- /dev/null +++ b/src/components/ui/Chip/NumberChip.tsx @@ -0,0 +1,19 @@ +import { cn } from '@/utils/helper'; +import { HTMLAttributes } from 'react'; + +interface NumberChipProps extends HTMLAttributes { + label: number; + max?: number; +} + +const DEFAULT_MAX_NUMBER = 99; + +export default function NumberChip({ label, max = DEFAULT_MAX_NUMBER, className, ...props }: NumberChipProps) { + const safeParseMaxNumber = max <= 0 || !Number.isInteger(max) ? DEFAULT_MAX_NUMBER : max; + + return ( + + {label > safeParseMaxNumber ? `${safeParseMaxNumber}+` : label} + + ); +} diff --git a/src/components/ui/Chip/RoundChip.tsx b/src/components/ui/Chip/RoundChip.tsx new file mode 100644 index 0000000..5eb718d --- /dev/null +++ b/src/components/ui/Chip/RoundChip.tsx @@ -0,0 +1,21 @@ +import { cn } from '@/utils/helper'; +import { HTMLAttributes } from 'react'; + +interface RoundChipProps extends HTMLAttributes { + label: string; +} + +export default function RoundChip({ label, className, ...props }: RoundChipProps) { + return ( + + {label} + + ); +} diff --git a/src/components/ui/Chip/TagChip.tsx b/src/components/ui/Chip/TagChip.tsx new file mode 100644 index 0000000..083e413 --- /dev/null +++ b/src/components/ui/Chip/TagChip.tsx @@ -0,0 +1,32 @@ +import { HTMLAttributes } from 'react'; +import { DEFAULT_COLORS } from '@/constants/colors'; +import { cn, getColorByString } from '@/utils/helper'; + +/** + * 하나의 color 값으로 배경색과 폰트색상에 적용합니다. + * + * 받은 color가 #FFCC00일경우 + * + * font color => #FFCCOO + * background color => #FFCCOO30 (30% opacity) + */ + +const BACKGROUND_ALPHA = 30; + +interface TagChipProps extends HTMLAttributes { + label: string; +} + +export default function TagChip({ label, className, ...props }: TagChipProps) { + const colorCode = getColorByString(label, DEFAULT_COLORS); + + return ( + + {label} + + ); +} diff --git a/src/constants/colors.ts b/src/constants/colors.ts index 7abcc32..ce2d01a 100644 --- a/src/constants/colors.ts +++ b/src/constants/colors.ts @@ -1,3 +1,3 @@ -type HexColor = `#${string}`; +export type HexColor = `#${string}`; export const DEFAULT_COLORS: HexColor[] = ['#7AC555', '#760DDE', '#FFA500', '#76A5EA', '#E876EA'];