|
1 | | -import { Slot } from "@radix-ui/react-slot"; |
2 | | -import { cva, type VariantProps } from "class-variance-authority"; |
3 | | -import * as React from "react"; |
4 | | - |
5 | | -import { cn } from "@/lib/utils"; |
6 | | - |
7 | | -const buttonVariants = cva( |
8 | | - "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50", |
9 | | - { |
10 | | - defaultVariants: { |
11 | | - size: "default", |
12 | | - variant: "default", |
13 | | - }, |
14 | | - variants: { |
15 | | - size: { |
16 | | - default: "h-10 px-4 py-2", |
17 | | - icon: "h-10 w-10", |
18 | | - lg: "h-11 rounded-md px-8", |
19 | | - sm: "h-9 rounded-md px-3", |
20 | | - }, |
21 | | - variant: { |
22 | | - default: "bg-foreground text-background hover:bg-foreground/90", |
23 | | - destructive: |
24 | | - "bg-destructive hover:bg-destructive/90 text-destructive-foreground ", |
25 | | - ghost: "hover:bg-accent hover:text-accent-foreground", |
26 | | - link: "underline-offset-4 hover:underline", |
27 | | - outline: |
28 | | - "border border-input bg-transparent hover:bg-accent hover:text-accent-foreground", |
29 | | - primary: "bg-primary hover:bg-primary/90 text-primary-foreground ", |
30 | | - secondary: |
31 | | - "bg-secondary hover:bg-secondary/80 text-secondary-foreground ", |
32 | | - upsell: |
33 | | - "bg-green-600 text-white hover:bg-green-700 shadow-lg hover:shadow-xl transform hover:-translate-y-0.5 transition-all duration-200", |
34 | | - }, |
35 | | - }, |
36 | | - }, |
37 | | -); |
38 | | - |
39 | | -export interface ButtonProps |
40 | | - extends React.ButtonHTMLAttributes<HTMLButtonElement>, |
41 | | - VariantProps<typeof buttonVariants> { |
42 | | - asChild?: boolean; |
43 | | -} |
44 | | - |
45 | | -const Button = React.forwardRef<HTMLButtonElement, ButtonProps>( |
46 | | - ({ className, variant, size, asChild = false, disabled, ...props }, ref) => { |
47 | | - const Comp = asChild ? Slot : "button"; |
48 | | - |
49 | | - // "button" elements automatically handle the `disabled` attribute. |
50 | | - // For non-button elements rendered via `asChild` (e.g. <a>), we still want |
51 | | - // to visually convey the disabled state and prevent user interaction. |
52 | | - // We do that by conditionally adding the same utility classes that the |
53 | | - // `disabled:` pseudo-variant would normally apply and by setting |
54 | | - // `aria-disabled` for accessibility. |
55 | | - const disabledClass = disabled ? "pointer-events-none opacity-50" : ""; |
56 | | - |
57 | | - const btnOnlyProps = |
58 | | - Comp === "button" |
59 | | - ? { |
60 | | - type: |
61 | | - (props as React.ButtonHTMLAttributes<HTMLButtonElement>).type || |
62 | | - ("button" as const), |
63 | | - } |
64 | | - : undefined; |
65 | | - |
66 | | - return ( |
67 | | - <Comp |
68 | | - aria-disabled={disabled ? true : undefined} |
69 | | - className={cn( |
70 | | - buttonVariants({ className, size, variant }), |
71 | | - disabledClass, |
72 | | - )} |
73 | | - disabled={disabled} |
74 | | - ref={ref} |
75 | | - {...props} |
76 | | - {...btnOnlyProps} |
77 | | - /> |
78 | | - ); |
79 | | - }, |
80 | | -); |
81 | | -Button.displayName = "Button"; |
82 | | - |
83 | | -export { Button, buttonVariants }; |
| 1 | +"use client"; |
| 2 | +export type { ButtonProps } from "@workspace/ui/components/button"; |
| 3 | +export { Button, buttonVariants } from "@workspace/ui/components/button"; |
0 commit comments