button.tsx 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. import { Button as B5Button, Spinner } from 'react-bootstrap-5'
  2. import type { ButtonProps } from '@/features/ui/components/types/button-props'
  3. import classNames from 'classnames'
  4. import { useTranslation } from 'react-i18next'
  5. const sizeClasses = new Map<ButtonProps['size'], string>([
  6. ['small', 'btn-sm'],
  7. ['default', ''],
  8. ['large', 'btn-lg'],
  9. ])
  10. export default function Button({
  11. children,
  12. className,
  13. isLoading = false,
  14. size = 'default',
  15. ...props
  16. }: ButtonProps) {
  17. const { t } = useTranslation()
  18. const sizeClass = sizeClasses.get(size)
  19. const buttonClassName = classNames('d-inline-grid', sizeClass, className, {
  20. 'button-loading': isLoading,
  21. })
  22. const loadingSpinnerClassName =
  23. size === 'large' ? 'loading-spinner-large' : 'loading-spinner-small'
  24. return (
  25. <B5Button className={buttonClassName} {...props}>
  26. {isLoading && (
  27. <span className="spinner-container">
  28. <Spinner
  29. animation="border"
  30. aria-hidden="true"
  31. as="span"
  32. className={loadingSpinnerClassName}
  33. role="status"
  34. />
  35. <span className="sr-only">{t('loading')}</span>
  36. </span>
  37. )}
  38. <span className="button-content" aria-hidden={isLoading}>
  39. {children}
  40. </span>
  41. </B5Button>
  42. )
  43. }