[React + Typescript + emotion] Badge 컴포넌트 제작
2024. 8. 9. 14:26
이번 프로젝트에서 Badge를 은근 많이 썼었다.
디자인 시스템을 봤을 때 이런 조건들이 있어서 css에서 삼항연산자를 많이 써야 하겠는데..?라는 생각을 했다.
1. disable
- 클릭 불가능
- 색 여러개 사용 가능성 있음
- 사이즈 여러개 사용 가능성 있음
2. clickable
- 기본은 흰색 -> 클릭하면 유색 -> 다시 클릭하면 흰색
3. tag
- 색 여러개 사용 가능성 있음
- 지울 수 있는 close 아이콘 추가
선택가능 여부인 isSelected와 사이즈+컬러로 variant를 설정하고,
모든 Badge에는 label이 필수라 label도 넣어주고, icon도 옵셔널로 넣어줬다.
// Badge.tsx
import React from "react";
import * as S from "./Badge.styled";
interface BadgeProps {
className?: string;
isSelected?: boolean;
variant: "smPink" | "smNavy" | "mdNavy" | "mdWhite";
label: string;
icon?: React.ReactNode;
handleClick?: (e: React.MouseEvent) => void;
}
const Badge = ({
className,
label,
isSelected,
handleClick,
variant,
icon,
}: BadgeProps) => {
return (
<S.Badge
className={className}
isSelected={isSelected}
isClickable={!!handleClick}
onClick={handleClick}
variant={variant}
>
{label}
{icon && icon}
</S.Badge>
);
};
export default Badge;
고려사항이 많다보니 삼항연산자가 좀 늘어난..
추후 추가 개발 시에 혹시나 badge부분의 옵션이 더 늘어난다면...리팩토링할 때 어떻게 해결할지 생각해 봐야겠다.
// Badge.styled.ts
import { css } from "@emotion/react";
import styled from "@emotion/styled";
export const Badge = styled.button<{
isSelected?: boolean;
isClickable: boolean;
variant: "smPink" | "smNavy" | "mdNavy" | "mdWhite";
}>`
${({ isSelected, isClickable, theme, variant }) => css`
${variant === "smPink" || variant === "smNavy"
? theme.fonts.caption_regular_10
: isSelected || variant === "mdNavy"
? theme.fonts.caption_bold_12
: theme.fonts.caption_regular_12};
height: ${variant === "smPink" || variant === "smNavy" ? "18px" : "38px"};
width: fit-content;
display: flex;
align-items: center;
justify-content: center;
border: 1px solid
${variant === "smPink"
? theme.colors.pink900
: (isSelected && isClickable) ||
variant === "smNavy" ||
variant === "mdNavy"
? theme.colors.navy900
: theme.colors.gray600};
border-radius: ${variant === "smPink" || variant === "smNavy"
? "4px"
: "20px"};
padding: ${variant === "smPink" || variant === "smNavy"
? "3px 6px"
: "9px 16px"};
background-color: ${variant === "smPink"
? theme.colors.pink900
: isSelected || variant === "smNavy" || variant === "mdNavy"
? theme.colors.navy900
: theme.colors.white};
color: ${variant === "mdWhite" && !isSelected
? theme.colors.black
: theme.colors.white};
cursor: ${!isClickable && "default"};
&:hover {
background-color: ${isClickable && theme.colors.navy900};
color: ${isClickable && theme.colors.white};
border: ${isClickable && `1px solid ${theme.colors.navy900}`};
}
`}
`;
'FrontEnd > Component' 카테고리의 다른 글
[React + Typescript + emotion] RangeSlider 컴포넌트 제작 (1) | 2024.08.15 |
---|---|
[React + Typescript + emotion] Tag 컴포넌트 제작 (1) | 2024.08.14 |
[React + Typescript + emotion] Dropdown 컴포넌트 제작 (0) | 2024.08.13 |
[React + Typescript + emotion] Toggle 컴포넌트 제작 (0) | 2024.08.08 |
[React + Typescript + emotion] Button 컴포넌트 제작 (0) | 2024.07.19 |