본문으로 바로가기

Typography 컴포넌트 구현하기

Typography 컴포넌트는 텍스트를 보여주기 위한 컴포넌트입니다.
일반적으로 HTML에서 텍스트를 표시할 때는 span 또는 p 태그를 사용합니다.
제가 구현한 Typography 컴포넌트는 기본적으로 span 태그를 사용하지만, 사용자가 필요에 따라 p 태그로 변경할 수 있도록 유연하게 설계되었습니다.

Typography 구현하기

props

interface TypographyProps {
  color?: TypographyColor;
  align?: "inherit" | "center" | "right" | "left";
  variant?: TypographyVariant;
  noWrap?: boolean;
  component?: ElementType;
  children?: React.ReactNode;
  style?: React.CSSProperties;
}

모든 props를 일일이 작성할 필요는 없습니다.
실제로 사용할 속성만 정의하여 관리의 복잡성을 줄이는 것이 더 효율적입니다.
또한, 추가적인 CSS 작업이 필요한 경우를 대비해 style props도 함께 제공하여 유연한 스타일링이 가능하도록 구현했습니다.

색상, Variant 처리

const getColor = (theme: Theme, color?: TypographyColor) => {
  if (!color) return undefined;
  if (color === "textDisabled") {
    return theme.palette.text.disabled;
  }
  if (color === "textPrimary") {
    return theme.palette.text.primary;
  }
  if (color === "textSecondary") {
    return theme.palette.text.secondary;
  }
  return theme.palette[color].main;
};

const getVariant = (theme: Theme, variant?: TypographyVariant) => {
  if (!variant) return {};
  return theme.typography[variant];
};

위 코드를 보면 theme의 장점을 확인할 수 있습니다.
미리 정의해둔 theme을 사용하여 설정된 값을 손쉽게 적용할 수 있어, 일관성 있는 스타일링과 유지 보수가 용이합니다.

Typography 컴포넌트

const StyledTypography = styled("span")<TypographyProps>(
  ({
    theme,
    color: _color,
    variant: _variant,
    align: textAlign,
    noWrap,
    style
  }) => {
    const color = getColor(theme, _color);
    const variant = getVariant(theme, _variant);
    return {
      textAlign,
      whiteSpace: noWrap ? "nowrap" : "normal",
      color,
      ...variant,
      ...style
    };
  }
);

기본적으로 span 엘리먼트를 사용하고 있으며, colorvariant 값에 따라 적절한 CSS가 적용됩니다.
이를 통해 다양한 스타일을 유연하게 설정할 수 있습니다.

const Typography = forwardRef<HTMLElement, TypographyProps>(function Typography(
  {
    children,
    color = "textPrimary",
    align = "inherit",
    variant = "body1",
    noWrap = false,
    component: Component = "span",
    ...props
  }: TypographyProps,
  ref: Ref<HTMLElement>
) {
  return (
    <StyledTypography
      as={Component}
      color={color}
      align={align}
      noWrap={noWrap}
      variant={variant}
      ref={ref}
      {...props}
    >
      {children}
    </StyledTypography>
  );
});

as props를 사용하면 기본적으로 span이 아닌, 원하는 태그로 컴포넌트를 변경할 수 있습니다.
예를 들어, as="p" 값을 주면 p 태그로 렌더링됩니다.

결론

이번에는 간단한 Typography 컴포넌트를 살펴보았습니다.
다음 게시글에서는 이 Typography 컴포넌트를 더 직관적으로 확인할 수 있도록 Storybook을 셋팅하는 방법을 알아보겠습니다.

링크

- Typography 구현
- 해당 게시글 최종 코드

반응형