button.tsx 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. import * as React from "react"
  2. import { Slot } from "@radix-ui/react-slot"
  3. import { cva, type VariantProps } from "class-variance-authority"
  4. import { cn } from "@/lib/utils"
  5. const buttonVariants = cva(
  6. "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
  7. {
  8. variants: {
  9. variant: {
  10. default:
  11. "bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",
  12. destructive:
  13. "bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
  14. outline:
  15. "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
  16. secondary:
  17. "bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80",
  18. ghost:
  19. "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
  20. link: "text-primary underline-offset-4 hover:underline",
  21. },
  22. size: {
  23. default: "h-9 px-4 py-2 has-[>svg]:px-3",
  24. sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
  25. lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
  26. icon: "size-9",
  27. },
  28. },
  29. defaultVariants: {
  30. variant: "default",
  31. size: "default",
  32. },
  33. }
  34. )
  35. function Button({
  36. className,
  37. variant,
  38. size,
  39. asChild = false,
  40. ...props
  41. }: React.ComponentProps<"button"> &
  42. VariantProps<typeof buttonVariants> & {
  43. asChild?: boolean
  44. }) {
  45. const Comp = asChild ? Slot : "button"
  46. return (
  47. <Comp
  48. data-slot="button"
  49. className={cn(buttonVariants({ variant, size, className }))}
  50. {...props}
  51. />
  52. )
  53. }
  54. export { Button, buttonVariants }