index.tsx 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. import type { CSSProperties } from 'react'
  2. import React from 'react'
  3. import { type VariantProps, cva } from 'class-variance-authority'
  4. import Spinner from '../spinner'
  5. import classNames from '@/utils/classnames'
  6. const buttonVariants = cva(
  7. 'btn disabled:btn-disabled',
  8. {
  9. variants: {
  10. variant: {
  11. 'primary': 'btn-primary',
  12. 'warning': 'btn-warning',
  13. 'secondary': 'btn-secondary',
  14. 'secondary-accent': 'btn-secondary-accent',
  15. 'ghost': 'btn-ghost',
  16. 'ghost-accent': 'btn-ghost-accent',
  17. 'tertiary': 'btn-tertiary',
  18. },
  19. size: {
  20. small: 'btn-small',
  21. medium: 'btn-medium',
  22. large: 'btn-large',
  23. },
  24. },
  25. defaultVariants: {
  26. variant: 'secondary',
  27. size: 'medium',
  28. },
  29. },
  30. )
  31. export type ButtonProps = {
  32. destructive?: boolean
  33. loading?: boolean
  34. styleCss?: CSSProperties
  35. } & React.ButtonHTMLAttributes<HTMLButtonElement> & VariantProps<typeof buttonVariants>
  36. const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
  37. ({ className, variant, size, destructive, loading, styleCss, children, ...props }, ref) => {
  38. return (
  39. <button
  40. type='button'
  41. className={classNames(
  42. buttonVariants({ variant, size, className }),
  43. destructive && 'btn-destructive',
  44. )}
  45. ref={ref}
  46. style={styleCss}
  47. {...props}
  48. >
  49. {children}
  50. {loading && <Spinner loading={loading} className='!text-white !h-3 !w-3 !border-2 !ml-1' />}
  51. </button>
  52. )
  53. },
  54. )
  55. Button.displayName = 'Button'
  56. export default Button
  57. export { Button, buttonVariants }