mirror of
https://github.com/Sea-Haven-Industries/shoc-frontend-new.git
synced 2026-09-30 12:43:13 +00:00
70 lines
1.9 KiB
TypeScript
70 lines
1.9 KiB
TypeScript
import type { ButtonProps } from "@mui/material";
|
|
import { Button as MuiButton, CircularProgress } from "@mui/material";
|
|
|
|
import { cn } from "@/lib/utils";
|
|
|
|
type ButtonVariant = "default" | "destructive" | "outline" | "ghost" | "link";
|
|
type ButtonSize = "default" | "lg";
|
|
|
|
export type UiButtonProps = Omit<ButtonProps, "variant" | "color" | "size"> & {
|
|
variant?: ButtonVariant;
|
|
size?: ButtonSize;
|
|
loading?: boolean;
|
|
loadingText?: string;
|
|
};
|
|
|
|
const variantMap: Record<
|
|
ButtonVariant,
|
|
Pick<ButtonProps, "variant" | "color"> & { className?: string }
|
|
> = {
|
|
default: { variant: "contained", color: "primary" },
|
|
destructive: { variant: "contained", color: "error" },
|
|
outline: { variant: "outlined", color: "primary", className: "border-border" },
|
|
ghost: { variant: "text", color: "inherit", className: "text-foreground" },
|
|
link: { variant: "text", color: "primary", className: "underline-offset-4 hover:underline" },
|
|
};
|
|
|
|
const sizeSx: Record<ButtonSize, ButtonProps["sx"]> = {
|
|
default: undefined,
|
|
lg: {
|
|
height: 42,
|
|
fontFamily: "var(--font-display)",
|
|
fontSize: "var(--text-base)",
|
|
fontWeight: 600,
|
|
},
|
|
};
|
|
|
|
export function Button({
|
|
variant = "default",
|
|
size = "default",
|
|
loading = false,
|
|
loadingText = "Loading…",
|
|
className,
|
|
disabled,
|
|
children,
|
|
sx,
|
|
...props
|
|
}: UiButtonProps) {
|
|
const mapped = variantMap[variant];
|
|
|
|
return (
|
|
<MuiButton
|
|
{...mapped}
|
|
disabled={disabled || loading}
|
|
aria-busy={loading || undefined}
|
|
aria-disabled={disabled || loading || undefined}
|
|
sx={[sizeSx[size], ...(Array.isArray(sx) ? sx : sx ? [sx] : [])]}
|
|
className={cn(mapped.className, className)}
|
|
{...props}
|
|
>
|
|
{loading ? (
|
|
<>
|
|
<CircularProgress size={16} color="inherit" sx={{ mr: 1 }} aria-hidden />
|
|
{loadingText}
|
|
</>
|
|
) : (
|
|
children
|
|
)}
|
|
</MuiButton>
|
|
);
|
|
}
|