1 estrella en GitHub = 1 componente nuevo.

Dar una estrella
Botonesbuttonpremium

Tilt Glow Button

Botón con inclinación interactiva 3D y resplandor dinámico que acompaña al ratón.

Vista Previa en Vivo

Uso

Copia y pega este código directamente en tu componente React:

tsx
import { TiltGlowButton } from 'react-component-kit-ui/buttons';

<TiltGlowButton primaryColor="#b8860b" secondaryColor="#fef3c7">Tilt me</TiltGlowButton>

Instalación Manual

Si no estás usando el paquete npm, crea un archivo nuevo y pega el siguiente código: src/components/TiltGlowButton.tsx + TiltGlowButton.css:

TiltGlowButton.tsx
'use client';

import type { CSSProperties, ElementType, HTMLAttributes, MouseEvent, ReactNode } from 'react';
import './TiltGlowButton.css';

/**
 * TiltGlowButton — An interactive 3D button that tilts towards the cursor with dynamic lighting.
 *
 * @param primaryColor - Optional. Default '#6366f1'.
 * @param secondaryColor - Optional. Default '#c084fc'.
 */
export interface TiltGlowButtonProps extends HTMLAttributes<HTMLElement> {
  href?: string;
  target?: string;
  rel?: string;
  type?: 'button' | 'submit' | 'reset';
  primaryColor?: string;
  secondaryColor?: string;
  size?: 'sm' | 'md' | 'lg';
  disabled?: boolean;
  children?: ReactNode;
}

export function TiltGlowButton({
  href,
  type = 'button',
  primaryColor = '#6366f1',
  secondaryColor = '#c084fc',
  size = 'md',
  disabled = false,
  className,
  style,
  children,
  onMouseMove,
  onMouseLeave,
  ...rest
}: TiltGlowButtonProps) {
  const Tag: ElementType = href ? 'a' : 'button';

  // Written straight to the DOM — no re-render per mouse move.
  const handleMove = (e: MouseEvent<HTMLElement>) => {
    onMouseMove?.(e);
    if (disabled) return;
    const el = e.currentTarget;
    const rect = el.getBoundingClientRect();
    const x = e.clientX - rect.left;
    const y = e.clientY - rect.top;
    el.style.setProperty('--mouse-x', `${(x / rect.width) * 100}%`);
    el.style.setProperty('--mouse-y', `${(y / rect.height) * 100}%`);
    el.style.transform = `rotateY(${(x / rect.width - 0.5) * 25}deg) rotateX(${(y / rect.height - 0.5) * -25}deg)`;
  };

  const handleLeave = (e: MouseEvent<HTMLElement>) => {
    onMouseLeave?.(e);
    const el = e.currentTarget;
    el.style.transform = 'rotateY(0deg) rotateX(0deg)';
    el.style.setProperty('--mouse-x', '50%');
    el.style.setProperty('--mouse-y', '50%');
  };

  return (
    <div className={['tilt-wrapper', `tilt-wrapper--${size}`, className].filter(Boolean).join(' ')}>
      <Tag
        {...rest}
        href={href}
        type={href ? undefined : type}
        disabled={href ? undefined : disabled}
        aria-disabled={href && disabled ? true : undefined}
        className="tilt-card"
        style={{ '--primary-color': primaryColor, '--secondary-color': secondaryColor, ...style } as CSSProperties}
        onMouseMove={handleMove}
        onMouseLeave={handleLeave}
      >
        <span className="tilt-card__glow" aria-hidden="true" />
        <span className="tilt-card__content">{children}</span>
      </Tag>
    </div>
  );
}

export default TiltGlowButton;
TiltGlowButton.css
/* TiltGlowButton — ported from astro-component-kit (buttons/TiltGlowButton.astro) */

.tilt-wrapper {
  perspective: 1000px;
  display: inline-block;
}

.tilt-card {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #0f172a;
  color: #fff;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: var(--r-md, 12px);
  cursor: pointer;
  text-decoration: none;
  overflow: hidden;
  transition: transform 0.15s ease-out, box-shadow 0.3s ease;
  transform-style: preserve-3d;
  user-select: none;
  font-family: var(--font-sans, inherit);
  font-weight: 600;
}

.tilt-card__glow {
  position: absolute;
  inset: 0;
  background: radial-gradient(
    circle at var(--mouse-x, 50%) var(--mouse-y, 50%),
    color-mix(in srgb, var(--primary-color), white 20%) 0%,
    transparent 70%
  );
  opacity: 0;
  transition: opacity 0.3s ease;
  pointer-events: none;
  z-index: 1;
}

.tilt-card__content {
  display: block;
  position: relative;
  z-index: 2;
  transform: translateZ(20px);
  white-space: nowrap;
}

.tilt-card:hover {
  box-shadow: 0 20px 40px -10px rgba(0, 0, 0, 0.5);
  border-color: rgba(255, 255, 255, 0.2);
}

.tilt-card:hover .tilt-card__glow {
  opacity: 0.15;
}

.tilt-card:active {
  transform: scale(0.98) translateZ(0);
}

.tilt-card:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  filter: grayscale(1);
}

/* Sizes */
.tilt-wrapper--sm .tilt-card { padding: 0.5rem 1.4rem; font-size: 0.8rem; }
.tilt-wrapper--md .tilt-card { padding: 0.8rem 2rem; font-size: 0.95rem; }
.tilt-wrapper--lg .tilt-card { padding: 1.1rem 3rem; font-size: 1.1rem; }

Información Rápida

Categoría
Botones
Nombre de archivo
TiltGlowButton.tsx
Dependencias
Ninguna — React + CSS puro
Etiquetas
buttonpremium