[mui]재사용 가능한 Button 정의

hansoom·2023년 7월 5일
0

design system

목록 보기
2/4
post-thumbnail

재사용가능한 Button 정의

따로 정의한 palette와 typography의 mui theme를 활용해 mui Button을 커스텀하여 재사용이 가능하도록 기능을 구현할 것이다.

  • 버튼의 크기에 따라 패딩을 달리하여 사이즈를 조절
// 패딩 사이즈 표
const PADDING = {
  xl: '14px 17.5px',
  lg: '12px 14px',
  md: '10px 12px',
  sm: '8px 12px',
};
  • 버튼의 props의 타입을 지정
import { ButtonProps } from '@mui/material';
// 버튼 타입들
export type Color = 'primary' | 'secondary';

export type Variant = 'text' | 'outlined' | 'contained';

export type Size = 'xl' | 'lg' | 'md' | 'sm';

interface BoxButtonProps extends ButtonProps {
  // 버튼명
  title: string;
  // 버튼 배경 색상
  color?: Color;
  // 버튼 모양
  variant?: Variant;
  // 버튼 사이즈
  padding?: Size;
}
  • 버튼 컴포넌트의 props color 값에 따라 색상을 팔레트에서 지정
import { useTheme } from '@mui/material';
const BoxButton = ({
  title,
  variant,
  color, // secondary가 오거나 primary가 오거나
  padding,
  disabled,
  ...others
}: BoxButtonProps) => {
  const theme = useTheme(); // 팔레트 색상을 활용하기 위해

  // 버튼 색상 분기 처리
  let backgroundColor = color as string;
  if (color === 'secondary') {
    backgroundColor = theme.palette.grey[900] as string;
  }
  if (disabled) {
    backgroundColor = theme.palette.grey[200] as string;
  }
  • mui Button 커스텀
interface StyleProps {
  padding: string;
  backgroundColor: string;
}

const MuiButton = styled(Button, {
  shouldForwardProp: (prop) => prop !== 'padding' && prop !== 'backgroundColor',
})(({ padding, backgroundColor }: StyleProps) => ({
  backgroundColor,
  padding: padding as string,
  margin: 5,
}));

styled(Button, { shouldForwardProp }):
styled 함수는 Button 컴포넌트를 커스터마이즈하기 위한 스타일을 생성하는 함수입니다.

  • 첫 번째 인자로 커스터마이즈할 대상 컴포넌트인 Button을 전달합니다.
  • 두 번째 인자로 shouldForwardProp을 전달합니다. shouldForwardProp 함수는 스타일 컴포넌트로 전달되는 속성 중 padding과 backgroundColor을 제외한 속성들을 Button 컴포넌트에 전달할 것인지를 결정하는 함수입니다.

이 함수는 전달된 prop이 'padding'이거나 'backgroundColor'가 아닌 경우에만 true를 반환합니다. 즉, 'padding'과 'backgroundColor' 속성은 스타일 컴포넌트에 전달되지 않고, 나머지 속성들은 실제 Button 컴포넌트로 전달됩니다.

  • Button return 할 버튼 구현
return (
    <MuiButton
      theme={theme}
      variant={variant}
      backgroundColor={backgroundColor as string}
      padding={PADDING[padding as Size]}
      disabled={disabled}
      {...others}
    >
      <Typography
        variant="h5"
        color={!disabled && variant === 'outlined' ? color : 'white'}
      >
        {title}
      </Typography>
    </MuiButton>
  );
  • 사용자에게 props를 받지 않는 경우 default 값을 지정하기 위해 defaultProps 정의
BoxButton.defaultProps = {
  color: 'primary',
  variant: 'contained',
  padding: 'lg',
};

실제 활용

		  <BoxButton
            title="버튼"
            color="primary"
            padding="xl"
            onClick={handleClick}
          />
          <BoxButton
            title="버튼"
            color="primary"
            padding="lg"
            onClick={handleClick}
          />
          <BoxButton
            title="버튼"
            color="primary"
            padding="md"
            onClick={handleClick}
          />
          <BoxButton
            title="버튼"
            color="primary"
            padding="sm"
            onClick={handleClick}
          />

0개의 댓글