xlibs-components
Version:
Modern React component library with Aceternity, MagicUI, and ShadCN components for building beautiful web applications
74 lines (73 loc) • 3.27 kB
JavaScript
"use client";
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { cn } from '../../lib/utils.js';
import { motion, useAnimate } from "framer-motion";
export const Button = ({ className, children, ...props }) => {
const [scope, animate] = useAnimate();
const animateLoading = async () => {
await animate(".loader", {
width: "20px",
scale: 1,
display: "block",
}, {
duration: 0.2,
});
};
const animateSuccess = async () => {
await animate(".loader", {
width: "0px",
scale: 0,
display: "none",
}, {
duration: 0.2,
});
await animate(".check", {
width: "20px",
scale: 1,
display: "block",
}, {
duration: 0.2,
});
await animate(".check", {
width: "0px",
scale: 0,
display: "none",
}, {
delay: 2,
duration: 0.2,
});
};
const handleClick = async (event) => {
await animateLoading();
await props.onClick?.(event);
await animateSuccess();
};
const { onClick, onDrag, onDragStart, onDragEnd, onAnimationStart, onAnimationEnd, ...buttonProps } = props;
return (_jsx(motion.button, { layout: true, layoutId: "button", ref: scope, className: cn("flex min-w-[120px] cursor-pointer items-center justify-center gap-2 rounded-full bg-green-500 px-4 py-2 font-medium text-white ring-offset-2 transition duration-200 hover:ring-2 hover:ring-green-500 dark:ring-offset-black", className), ...buttonProps, onClick: handleClick, children: _jsxs(motion.div, { layout: true, className: "flex items-center gap-2", children: [_jsx(Loader, {}), _jsx(CheckIcon, {}), _jsx(motion.span, { layout: true, children: children })] }) }));
};
const Loader = () => {
return (_jsxs(motion.svg, { animate: {
rotate: [0, 360],
}, initial: {
scale: 0,
width: 0,
display: "none",
}, style: {
scale: 0.5,
display: "none",
}, transition: {
duration: 0.3,
repeat: Infinity,
ease: "linear",
}, xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: "loader text-white", children: [_jsx("path", { stroke: "none", d: "M0 0h24v24H0z", fill: "none" }), _jsx("path", { d: "M12 3a9 9 0 1 0 9 9" })] }));
};
const CheckIcon = () => {
return (_jsxs(motion.svg, { initial: {
scale: 0,
width: 0,
display: "none",
}, style: {
scale: 0.5,
display: "none",
}, xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: "check text-white", children: [_jsx("path", { stroke: "none", d: "M0 0h24v24H0z", fill: "none" }), _jsx("path", { d: "M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0" }), _jsx("path", { d: "M9 12l2 2l4 -4" })] }));
};