From c4109f977995ef034fc1ec81ded1d6e0f986489f Mon Sep 17 00:00:00 2001 From: jyswee Date: Thu, 23 Jul 2026 22:12:47 +0000 Subject: [PATCH] Seed: fitness template (17 files) --- src/components/ui/button.tsx | 53 ++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 src/components/ui/button.tsx diff --git a/src/components/ui/button.tsx b/src/components/ui/button.tsx new file mode 100644 index 0000000..476e5b1 --- /dev/null +++ b/src/components/ui/button.tsx @@ -0,0 +1,53 @@ +import * as React from "react"; +import { cn } from "@/lib/utils"; + +const variantClasses: Record = { + default: "bg-indigo-600 text-white hover:bg-indigo-700", + secondary: "bg-slate-100 text-slate-900 hover:bg-slate-200", + outline: "border border-slate-300 bg-transparent hover:bg-slate-50 text-slate-900", + ghost: "bg-transparent hover:bg-slate-100 text-slate-900", + destructive: "bg-red-600 text-white hover:bg-red-700", + link: "bg-transparent underline-offset-4 hover:underline text-indigo-600", +}; + +const sizeClasses: Record = { + default: "h-10 px-4 py-2 text-sm", + sm: "h-8 px-3 text-xs", + lg: "h-12 px-6 text-base", + icon: "h-10 w-10 p-0", +}; + +export interface ButtonProps extends React.ButtonHTMLAttributes { + variant?: keyof typeof variantClasses; + size?: keyof typeof sizeClasses; + asChild?: boolean; +} + +export const Button = React.forwardRef( + ({ className, variant = "default", size = "default", asChild, children, ...props }, ref) => { + const classes = cn( + "inline-flex items-center justify-center gap-2 rounded-md font-medium transition-colors disabled:opacity-50 disabled:pointer-events-none", + variantClasses[variant] || variantClasses.default, + sizeClasses[size] || sizeClasses.default, + className + ); + if (asChild && React.isValidElement(children)) { + return React.cloneElement(children as React.ReactElement, { + className: cn(classes, (children as React.ReactElement).props?.className), + }); + } + return ; + } +); +Button.displayName = "Button"; + +export function buttonVariants(opts?: { variant?: string; size?: string; className?: string }) { + return cn( + "inline-flex items-center justify-center gap-2 rounded-md font-medium transition-colors", + variantClasses[opts?.variant || "default"], + sizeClasses[opts?.size || "default"], + opts?.className + ); +} + +export default Button;