@easy-shadcn/react
Version:
Use shadcn/ui easy&enhance like component library
182 lines (176 loc) • 5.58 kB
JavaScript
;
var chunkHKTXE4L5_js = require('./chunk-HKTXE4L5.js');
var React = require('react');
var utils = require('@easy-shadcn/utils');
var react = require('motion/react');
var jsxRuntime = require('react/jsx-runtime');
function _interopNamespace(e) {
if (e && e.__esModule) return e;
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}
var React__namespace = /*#__PURE__*/_interopNamespace(React);
var Ripple = ({
color = "rgb(255 255 255 / 0.5)",
rippleRef
}) => {
const [ripples, setRipples] = React__namespace.useState([]);
const showRipple = React__namespace.useCallback((event) => {
const container = event.currentTarget;
if (!container) return;
const rect = container.getBoundingClientRect();
const x = event.clientX - rect.left;
const y = event.clientY - rect.top;
const size = Math.max(rect.width, rect.height) * 2;
setRipples((prev) => [
...prev,
{
x,
y,
size,
id: Date.now()
}
]);
}, []);
React__namespace.useImperativeHandle(rippleRef, () => ({
showRipple
}));
React__namespace.useEffect(() => {
const timeouts = ripples.map((ripple) => {
return setTimeout(() => {
setRipples((prev) => prev.filter((r) => r.id !== ripple.id));
}, 1e3);
});
return () => {
timeouts.forEach(clearTimeout);
};
}, [ripples]);
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: utils.cn("absolute inset-0 pointer-events-none z-10"), role: "presentation", children: /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { mode: "sync", children: ripples.map((ripple) => /* @__PURE__ */ jsxRuntime.jsx(
react.motion.span,
{
className: "absolute rounded-full",
style: {
left: ripple.x - ripple.size / 2,
top: ripple.y - ripple.size / 2,
width: `${ripple.size}px`,
height: `${ripple.size}px`,
backgroundColor: color
},
initial: { scale: 0, opacity: 0.5 },
animate: { scale: 1, opacity: 0 },
transition: {
duration: 0.75,
ease: [0.4, 0, 0.2, 1]
},
exit: { opacity: 0 }
},
ripple.id
)) }) });
};
Ripple.displayName = "Ripple";
var BlackRipple = "rgb(0 0 0 / 0.3)";
var WhiteRipple = "rgb(255 255 255 / 0.3)";
var getRippleColor = (variant) => {
if (["outline", "ghost", "secondary"].includes(variant || "")) {
return BlackRipple;
}
return WhiteRipple;
};
var RippleButton = React__namespace.forwardRef(
({ className, children, onMouseDown, variant, ...props }, ref) => {
const rippleRef = React__namespace.useRef(null);
return /* @__PURE__ */ jsxRuntime.jsxs(
chunkHKTXE4L5_js.Button,
{
ref,
className: utils.cn("relative overflow-hidden", className),
onMouseDown: (e) => {
onMouseDown?.(e);
rippleRef.current?.showRipple(e);
},
variant,
...props,
children: [
/* @__PURE__ */ jsxRuntime.jsx(Ripple, { color: getRippleColor(variant), rippleRef }),
children
]
}
);
}
);
RippleButton.displayName = "RippleButton";
var LoadingIcon = (props) => /* @__PURE__ */ jsxRuntime.jsx(
"svg",
{
xmlns: "http://www.w3.org/2000/svg",
width: "1em",
height: "1em",
viewBox: "0 0 24 24",
fill: "none",
stroke: "currentColor",
strokeWidth: "2",
strokeLinecap: "round",
strokeLinejoin: "round",
...props,
children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M21 12a9 9 0 1 1-6.219-8.56" })
}
);
var Button2 = React__namespace.default.forwardRef(
({ icon, iconPosition, loading, disabled, onClick, children, size, className, ...resetProps }, ref) => {
const [isLoading, setIsLoading] = React.useState(false);
const handleClick = (e) => {
if (onClick) {
const clickPromise = onClick(e);
if (clickPromise instanceof Promise) {
setIsLoading(true);
clickPromise.catch(() => {
}).finally(() => {
setIsLoading(false);
});
}
}
};
const innerLoading = loading || isLoading;
let iconNode = null;
let content = null;
if (size === "icon") {
iconNode = innerLoading ? /* @__PURE__ */ jsxRuntime.jsx(LoadingIcon, { className: "animate-spin" }) : children;
} else {
iconNode = innerLoading ? /* @__PURE__ */ jsxRuntime.jsx(LoadingIcon, { className: "animate-spin" }) : icon;
content = children;
}
return /* @__PURE__ */ jsxRuntime.jsxs(
RippleButton,
{
ref,
...resetProps,
size,
disabled: innerLoading || disabled,
onClick: handleClick,
className: utils.cn(
iconPosition === "end" && "flex-row-reverse",
"[&_svg]:size-[1em]",
className
),
children: [
iconNode ? /* @__PURE__ */ jsxRuntime.jsx("span", { children: /* @__PURE__ */ jsxRuntime.jsx("span", { role: "img", className: "inline-flex items-center align-[-0.125em]", children: iconNode }) }) : null,
content ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: content }) : null
]
}
);
}
);
Button2.displayName = "Button";
exports.Button = Button2;