Actions

ButtonLink

Enlace con estilo de botón

Preview

size
variant
children

Code

import css from "./ButtonLink.module.css";

type Size = "xs" | "sm" | "md" | "lg";

interface ResponsiveSize {
  base: Size;
  mobile?: Size;
  tablet?: Size;
  desktop?: Size;
  wide?: Size;
}

interface ButtonLinkProps {
  size: Size | ResponsiveSize;
  variant: "solid" | "soft" | "outline" | "ghost";
  href: string;
  target?: string;
  children: React.ReactNode;
}

function getSizeClasses(size: Size | ResponsiveSize): string {
  if (typeof size === "string") {
    return css[size];
  }

  const classes = [css[`${size.base}_base`]];

  if (size.mobile) classes.push(css[`${size.mobile}_mobile`]);
  if (size.tablet) classes.push(css[`${size.tablet}_tablet`]);
  if (size.desktop) classes.push(css[`${size.desktop}_desktop`]);
  if (size.wide) classes.push(css[`${size.wide}_wide`]);

  return classes.join(" ");
}

export default function ButtonLink({
  size,
  variant,
  href,
  target,
  children,
}: ButtonLinkProps) {
  return (
    <a
      className={`
        ${css.button}
        ${getSizeClasses(size)}
        ${css[variant]}
      `}
      href={href}
      target={target}
      rel={target === "_blank" ? "noopener noreferrer" : undefined}
    >
      <span className={css.button_content}>{children}</span>
    </a>
  );
}

Props

PropTypeRequiredDescription
size"xs" | "sm" | "md" | "lg" | ResponsiveSizerequiredTamaño del enlace (altura, padding y tipografía). Fijo o responsive.
variant"solid" | "soft" | "outline" | "ghost"requiredDe más a menos peso. solid va relleno, soft lleva un fondo suave de acento, outline es un contorno que se rellena al pasar el ratón y ghost va sin borde ni fondo y se tiñe con el hover.
hrefstringrequiredDestino del enlace.
targetstring—Destino de apertura. Con "_blank" añade rel="noopener noreferrer".
childrenReact.ReactNoderequiredContenido del enlace (texto, o icono + texto).