loading-spinner.tsx 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. import { useTranslation } from 'react-i18next'
  2. import { useEffect, useState } from 'react'
  3. import OLSpinner, {
  4. OLSpinnerSize,
  5. } from '@/features/ui/components/ol/ol-spinner'
  6. import { isBootstrap5 } from '@/features/utils/bootstrap-5'
  7. import { setTimeout } from '@/utils/window'
  8. import classNames from 'classnames'
  9. function LoadingSpinner({
  10. align,
  11. delay = 0,
  12. loadingText,
  13. size = 'sm',
  14. className,
  15. }: {
  16. align?: 'left' | 'center'
  17. delay?: 0 | 500 // 500 is our standard delay
  18. loadingText?: string
  19. size?: OLSpinnerSize
  20. className?: string
  21. }) {
  22. const { t } = useTranslation()
  23. const [show, setShow] = useState(false)
  24. useEffect(() => {
  25. const timer = setTimeout(() => {
  26. setShow(true)
  27. }, delay)
  28. return () => {
  29. window.clearTimeout(timer)
  30. }
  31. }, [delay])
  32. if (!show) {
  33. return null
  34. }
  35. const extraClasses = isBootstrap5()
  36. ? [align === 'left' ? 'align-items-start' : 'align-items-center']
  37. : null
  38. return (
  39. <div className={classNames('loading', className, extraClasses)}>
  40. <OLSpinner size={size} />
  41. &nbsp;
  42. {loadingText || `${t('loading')}…`}
  43. </div>
  44. )
  45. }
  46. export default LoadingSpinner
  47. export function FullSizeLoadingSpinner({
  48. delay = 0,
  49. minHeight,
  50. loadingText,
  51. size = 'sm',
  52. }: {
  53. delay?: 0 | 500
  54. minHeight?: string
  55. loadingText?: string
  56. size?: OLSpinnerSize
  57. }) {
  58. return (
  59. <div className="full-size-loading-spinner-container" style={{ minHeight }}>
  60. <LoadingSpinner size={size} loadingText={loadingText} delay={delay} />
  61. </div>
  62. )
  63. }