nextuiq
Version:
NextUIQ is a modern, lightweight, and developer-friendly UI component library for React and Next.js. Built with TypeScript and Tailwind CSS, it offers customizable, accessible, and performance-optimized components with built-in dark mode, theme customizat
79 lines (76 loc) • 3.67 kB
JavaScript
import { j as jsxRuntimeExports } from './index46.mjs';
const Button = ({
children,
className = "",
variant = "primary",
size = "md",
startIcon,
endIcon,
disabled = false,
// Default to false
tag = "button",
href,
loading = false,
loadingText = "Loading...",
target,
rel,
ariaLabel,
ariaDescribedBy,
...props
}) => {
const variantClasses = {
primary: "bg-[oklch(var(--theme-primary))] text-white hover:bg-[oklch(var(--theme-primary-dark))] focus:ring-[oklch(var(--theme-primary)/50)]",
destructive: "bg-[oklch(var(--theme-error))] text-white hover:bg-[oklch(var(--theme-error)/90)] focus:ring-[oklch(var(--theme-error)/50)]",
outline: "border border-[oklch(var(--theme-border))] bg-[oklch(var(--theme-background))] text-[oklch(var(--theme-foreground))] hover:bg-[oklch(var(--theme-muted))]",
secondary: "bg-[oklch(var(--theme-secondary))] text-white hover:bg-[oklch(var(--theme-secondary-dark))]",
ghost: "text-[oklch(var(--theme-foreground))] hover:bg-[oklch(var(--theme-muted))]",
link: 'underline-offset-4 hover:underline p-0 h-auto font-normal [&:not([class*="text-"])]:text-[oklch(var(--theme-primary))]'
};
const sizeClasses = {
sm: "text-[var(--text-sm)] px-[var(--spacing)] py-[calc(var(--spacing)*0.5)]",
md: "text-[var(--text-base)] px-[calc(var(--spacing)*1.5)] py-[var(--spacing)]"
};
const baseClasses = `inline-flex items-center justify-center font-[var(--font-weight-semibold)] gap-[var(--spacing)] rounded-[var(--radius-md)] transition-all duration-[var(--ease-in-out)] whitespace-nowrap ${sizeClasses[size]} ${variantClasses[variant]} ${disabled || loading ? "cursor-not-allowed opacity-50" : "cursor-pointer"} ${className}`;
const content = /* @__PURE__ */ jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: loading ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "animate-[var(--animate-spin)] mr-[var(--spacing)]", "aria-hidden": "true", children: "⚪" }),
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "sr-only", children: "Loading" }),
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: loadingText })
] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "inline-flex items-center gap-[var(--spacing)]", children: [
startIcon && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex items-center", "aria-hidden": "true", children: startIcon }),
typeof children === "string" ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "inline-flex items-center gap-3", children }),
endIcon && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex items-center", "aria-hidden": "true", children: endIcon })
] }) });
const commonProps = {
className: baseClasses,
"aria-label": ariaLabel,
"aria-describedby": ariaDescribedBy,
"aria-disabled": disabled || loading,
"aria-busy": loading
};
if (tag === "a" && href) {
return /* @__PURE__ */ jsxRuntimeExports.jsx(
"a",
{
href,
target,
rel: target === "_blank" ? `${rel || ""} noopener noreferrer`.trim() : rel,
role: "button",
tabIndex: disabled || loading ? -1 : 0,
...commonProps,
...props,
children: content
}
);
}
return /* @__PURE__ */ jsxRuntimeExports.jsx(
"button",
{
type: props.type || "button",
disabled: disabled || loading,
...commonProps,
...props,
children: content
}
);
};
export { Button };