Skip to content

Instantly share code, notes, and snippets.

@H-ymt
Last active March 23, 2025 11:08
Show Gist options
  • Save H-ymt/bd73f11aae14ea471c43c19c939dca08 to your computer and use it in GitHub Desktop.
Save H-ymt/bd73f11aae14ea471c43c19c939dca08 to your computer and use it in GitHub Desktop.
React x CSS Modulesでつくる汎用性の高いボタンコンポーネント
import clsx from "clsx";
import styles from "./index.module.css";
import Link from "next/link";

type ButtonProps = {
  children: React.ReactNode;
  className?: string;
  visual?: "primary" | "secondary";
  size?: "sm" | "md" | "lg";
  href?: string;
  type?: "button" | "submit" | "reset";
  target?: "_blank" | "_self" | "_parent" | "_top";
};

export default function Button({
  children,
  className,
  visual = "primary",
  size = "md",
  href,
  type = "button",
  ...props
}: ButtonProps) {
  const classNames = clsx(styles.button, styles[visual], styles[size], className);

  if (href) {
    return (
      <Link href={href} className={classNames} {...props}>
        {children}
      </Link>
    );
  }

  return (
    <button className={classNames} type={type} {...props}>
      {children}
    </button>
  );
}
.button {
    display: inline-grid;
    align-items: center;
    justify-content: center;
}

/* Visual */
.primary {
    color: var(--btn-fgc-primary);
    background-color: var(--btn-bgc-primary);
    border: 0.125rem solid var(--btn-bgc-primary);
    border-radius: var(--radius-24);
}

.secondary {
    color: var(--btn-fgc-secondary);
    background-color: var(--btn-bgc-secondary);
}

/* Size */
.sm {
    padding: var(--space-8) var(--space-16);
    font-size: 0.875rem;
}

.md {
    padding: var(--space-10) var(--space-20);
    font-size: 0.875rem;
}

.lg {
    padding: var(--space-12) var(--space-24) var(--space-10);
    font-size: 0.875rem;
    line-height: 1;
}

.lg:focus-visible {
    outline-offset: 0.2rem;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment