ldc-ovoteam/resources/ts/front/Components/Theme/Button.tsx
2026-04-15 09:31:53 +02:00

148 lines
3.7 KiB
TypeScript

import { Button as ShadcnButton, ButtonProps } from "@/components/ui/button";
import {
FontName,
fonts,
iconMap,
sidePlacements,
} from "@/front/lib/constants";
import { cn } from "@/lib/utils";
import { CustomButtonVariant, IconConfig } from "@/types/front";
import { Link } from "@inertiajs/react";
type CustomSize = "xs" | "md";
type ThemeButtonProps = Omit<ButtonProps, "variant" | "size"> & {
variant?: ButtonProps["variant"] | CustomButtonVariant;
size?: ButtonProps["size"] | CustomSize;
icon?: IconConfig;
isBold?: boolean;
font?: FontName;
link?: {
href: string;
label: string;
};
};
const customVariantSizes: Record<CustomSize, string> = {
xs: "h-7 px-3 text-sm",
md: "h-10 px-6 py-2 text-md",
};
const customVariantStyles: Record<CustomButtonVariant, string> = {
tertiary:
"bg-primary-foreground text-background hover:bg-primary-foreground/90",
inverted: "bg-background hover:bg-secondary/90",
};
export default function Button({
icon,
isBold = true,
font = fonts.GOTHAM,
size,
variant,
children,
className,
asChild,
link,
...props
}: ThemeButtonProps) {
const Icon = icon ? iconMap[icon.icon] : undefined;
const customVariant =
variant && variant in customVariantStyles
? customVariantStyles[variant as CustomButtonVariant]
: "";
const getSizeClasses = () => {
if (size && size in customVariantSizes) {
return customVariantSizes[size as CustomSize];
}
return "h-9 px-5 text-md";
};
const iconClassName = icon?.className ?? "";
if (link && link.href && link.label) {
return (
<ShadcnButton
variant={variant as ButtonProps["variant"]}
className={cn(
"rounded-full w-fit",
isBold ? "font-bold" : "font-normal",
font,
className,
getSizeClasses(),
customVariant,
)}
asChild
/* eslint-disable react/jsx-props-no-spreading */
{...props}
>
<Link
href={link.href}
className="flex items-center justify-center gap-2"
>
{icon?.placement !== sidePlacements.RIGHT && Icon && (
<Icon className={cn(iconClassName)} />
)}
{link.label}
{icon?.placement === sidePlacements.RIGHT && Icon && (
<Icon className={cn(iconClassName)} />
)}
</Link>
</ShadcnButton>
);
}
if (asChild) {
return (
<ShadcnButton
variant={variant as ButtonProps["variant"]}
className={cn(
"rounded-full w-fit",
isBold ? "font-bold" : "font-normal",
font,
className,
getSizeClasses(),
customVariant,
)}
asChild
/* eslint-disable react/jsx-props-no-spreading */
{...props}
>
<div>
{icon?.placement !== sidePlacements.RIGHT && Icon && (
<Icon className={cn(iconClassName)} />
)}
{children}
{icon?.placement === sidePlacements.RIGHT && Icon && (
<Icon className={cn(iconClassName)} />
)}
</div>
</ShadcnButton>
);
}
return (
<ShadcnButton
variant={variant as ButtonProps["variant"]}
className={cn(
"rounded-full w-fit",
isBold ? "font-bold" : "font-normal",
font,
className,
getSizeClasses(),
customVariant,
)}
/* eslint-disable react/jsx-props-no-spreading */
{...props}
>
{icon?.placement !== sidePlacements.RIGHT && Icon && (
<Icon className={cn(iconClassName)} />
)}
{children}
{icon?.placement === sidePlacements.RIGHT && Icon && (
<Icon className={cn(iconClassName)} />
)}
</ShadcnButton>
);
}