# All files / src/ProgressBar ProgressBar.tsx

96.66% Statements 29/30
63.63% Branches 7/11
75% Functions 3/4
95.65% Lines 22/23

Press n or j to go to the next uncovered block, b, p or k for the previous block.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    775x
    5x
    5x

    5x

    5x
    18x
    18x
    18x
    18x

    18x

    18x
    6x
    6x

    6x
    6x

    6x
    6x

    6x
    5x

    18x

    18x

    5x
     import React from 'react'
    import { clamp, maxProgressValue, minProgressValue } from '../Loader/Loader'
    import {
      StyledProgressBar,
      StyledProgressBarLoader,
    } from './ProgressBar.styles'
    import { ProgressBarProps } from './ProgressBar.types'

    const finalAnimationDuration = 900

    /**

     Progress bars visually show system loading progress, such as uploading a file
     or loading a page, as well as user progress, like filling out a form.

     @since 10.19.0

     @see [Storybook](https://procore.github.io/core/core-react/latest/?path=/story/demos-progressbar--demo)

     @see [Design Guidelines](https://design.procore.com/progress-bar)

     */
    export const ProgressBar = React.forwardRef<HTMLDivElement, ProgressBarProps>(
      function ProgressBar({ animated = false, value, ...props }, ref) {
        const isProgressValueComplete = value >= maxProgressValue
        const [isFinalized, setFinalized] = React.useState(false)
        const [isProgressComplete, setProgressComplete] = React.useState(
          isProgressValueComplete
        )
        const didMountRef = React.useRef(false)

        React.useEffect(() => {
          const isFinalized = didMountRef.current && isProgressValueComplete
          const timerId: number | null = isFinalized
            ? window.setTimeout(() => {
                setFinalized(false)
              }, finalAnimationDuration)
            : null

          setProgressComplete(isProgressValueComplete)
          setFinalized(isFinalized)

          if (!didMountRef.current) {
            didMountRef.current = true
          }

          return () => {
            timerId && clearTimeout(timerId)
          }
        }, [isProgressValueComplete])

        const clampedValue = clamp(value)

        return (
          <StyledProgressBar
            $complete={isProgressComplete}
            $finalized={isFinalized}
            ref={ref}
            role="progressbar"
            aria-valuenow={clampedValue}
            aria-valuemin={minProgressValue}
            aria-valuemax={maxProgressValue}
            {...props}
            aria-valuetext={
              typeof props['aria-valuetext'] === 'function'
                ? props['aria-valuetext']({ value: clampedValue })
                : props['aria-valuetext']
            }
          >
            <StyledProgressBarLoader value={value} animated={animated} />
          </StyledProgressBar>
        )
      }
    )

    ProgressBar.displayName = 'ProgressBar'