NextJS + TailwindCSS + TS + RadixUI의 변형으로 다형성 버튼을 만드는 방법

이것은 전체 TypeScript 지원으로 작업을 수행하는 좋은 방법을 공유하기 위한 빠른 게시물입니다. 다형성을 위해 RadixUI Slot 구성 요소를 사용합니다.

import React, { forwardRef } from 'react';
import { cnMerge } from 'common/cn-merge';
import { Slot } from '@radix-ui/react-slot';

const baseClasses = /*tw:*/ `inline-flex items-center justify-center gap-2 font-bold text-center rounded-md`;

const variantsLookup = {
  solid: /*tw:*/ `text-white bg-primary hover:shadow-button duration-100`,
  outline: /*tw:*/ `text-primary border border-blue-300 hover:bg-blue-600 hover:border-primary`,
  subtle: /*tw:*/ `text-primary hover:bg-blue-600`,
};

const sizesLookup = {
  base: /*tw:*/ `px-5 py-2.5`,
};

type ButtonProps = {
  children: React.ReactNode;
  variant?: 'outline' | 'solid' | 'subtle';
  size?: 'base';
  href?: string;
  className?: string;
  asChild?: boolean;
};

const Button = forwardRef<HTMLButtonElement, ButtonProps>((props, ref) => {
  const { children, variant, size, asChild, className, ...rest } = props;

  const classes = cnMerge([
    baseClasses,
    variantsLookup[variant || 'solid'],
    sizesLookup[size || 'base'],
    className,
  ]);

  const Comp = asChild ? Slot : 'button';

  return (
    <Comp {...rest} className={classes} ref={ref}>
      {children}
    </Comp>
  );
});

export default Button;


용법:

<NextLink href="/extension" passHref>
  <Button asChild>
    <a>
      <ExtensionIcon />
      Install Chrome Extension
    </a>
  </Button>
</NextLink>

/* ---- */

<Button asChild>
  <a href="https://wwww.test.com" target="_blank" rel="noopener noreferrer">
    <ExtensionIcon />
    Install Chrome Extension
  </a>
</Button>

좋은 웹페이지 즐겨찾기