xlibs-components
Version:
Modern React component library with Aceternity, MagicUI, and ShadCN components for building beautiful web applications
60 lines (59 loc) • 3.97 kB
JavaScript
"use client";
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import * as React from "react";
import { Slot } from "@radix-ui/react-slot";
import { cva } from "class-variance-authority";
import { cn } from '../../lib/utils.js';
const magicButtonVariants = cva("inline-flex items-center justify-center whitespace-nowrap rounded-lg text-sm font-medium transition-all duration-300 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 relative overflow-hidden group", {
variants: {
variant: {
default: "btn-primary shadow-lg hover:shadow-xl transform hover:-translate-y-0.5",
destructive: "btn-destructive shadow-lg hover:shadow-xl transform hover:-translate-y-0.5",
outline: "btn-outline shadow-sm hover:shadow-md transform hover:-translate-y-0.5",
secondary: "btn-secondary shadow-lg hover:shadow-xl transform hover:-translate-y-0.5",
ghost: "text-foreground hover:bg-accent hover:text-accent-foreground",
link: "text-primary underline-offset-4 hover:underline",
success: "btn-success shadow-lg hover:shadow-xl transform hover:-translate-y-0.5",
warning: "btn-warning shadow-lg hover:shadow-xl transform hover:-translate-y-0.5",
info: "btn-info shadow-lg hover:shadow-xl transform hover:-translate-y-0.5",
magic: "bg-gradient-to-r from-primary via-chart-2 to-chart-3 text-primary-foreground shadow-lg hover:shadow-xl transform hover:-translate-y-0.5 hover:scale-105",
glass: "backdrop-blur-sm border border-border bg-card/50 hover:bg-card/80 shadow-lg hover:shadow-xl transform hover:-translate-y-0.5",
neon: "bg-primary text-primary-foreground shadow-lg hover:shadow-xl transform hover:-translate-y-0.5 border border-primary/50 hover:border-primary shadow-[0_0_20px_rgba(var(--primary),0.3)] hover:shadow-[0_0_30px_rgba(var(--primary),0.5)]",
},
size: {
default: "h-10 px-4 py-2",
sm: "h-9 rounded-md px-3",
lg: "h-11 rounded-md px-8",
icon: "h-10 w-10",
magic: "h-12 px-6 py-3 text-base",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
});
const MagicButton = React.forwardRef(({ className, variant, size, asChild = false, loading = false, ripple = true, children, ...props }, ref) => {
const Comp = asChild ? Slot : "button";
const [ripples, setRipples] = React.useState([]);
const handleClick = (event) => {
if (ripple) {
const rect = event.currentTarget.getBoundingClientRect();
const x = event.clientX - rect.left;
const y = event.clientY - rect.top;
const id = Date.now();
setRipples(prev => [...prev, { id, x, y }]);
setTimeout(() => {
setRipples(prev => prev.filter(ripple => ripple.id !== id));
}, 600);
}
};
return (_jsxs(Comp, { className: cn(magicButtonVariants({ variant, size, className })), ref: ref, onClick: handleClick, disabled: loading || props.disabled, ...props, children: [loading && (_jsx("div", { className: "mr-2 h-4 w-4 animate-spin rounded-full border-2 border-current border-t-transparent" })), children, ripple && ripples.map((ripple) => (_jsx("span", { className: "absolute rounded-full bg-white/30 animate-ping", style: {
left: ripple.x - 10,
top: ripple.y - 10,
width: 20,
height: 20,
} }, ripple.id))), variant === "magic" && (_jsx("div", { className: "absolute inset-0 rounded-lg bg-gradient-to-r from-primary/20 via-chart-2/20 to-chart-3/20 opacity-0 group-hover:opacity-100 transition-opacity duration-300" }))] }));
});
MagicButton.displayName = "MagicButton";
export { MagicButton, magicButtonVariants };