@navinc/base-react-components
Version:
Nav's Pattern Library
62 lines (54 loc) • 1.63 kB
JavaScript
import React, { useEffect, useRef, useState } from 'react'
import styled, { keyframes, css } from 'styled-components'
export const ProgressBarSection = styled.div`
height: 8px;
background-color: ${({ theme }) => theme.neutral100};
display: inline-block;
width: 100%;
border-radius: 8px;
`
const advanceProgress = (prevWidth, percent) => keyframes`
from {
width: ${prevWidth}%;
}
to {
width: ${percent}%;
}
`
const animation = ({ prevWidth }) => css`
animation: ${advanceProgress(prevWidth)} 1s forwards;
`
const Progress = styled.div`
background-color: ${({ bgColor, theme }) => bgColor || theme.neutral300};
height: 8px;
width: ${({ percent }) => percent}%;
border-radius: 8px;
${animation};
`
const ProgressBar = ({ bgColor = ({ theme }) => theme.neutral300, percent, className }) => {
const prevWidth = useRef(0)
const nextWidth = useRef(0)
const [progress, setProgress] = useState(0)
/*
Keeps track of previous percentage completion, setting 'to' and 'from' values for animation.
Updates state to set up animation for next time the percent completion changes.
*/
useEffect(() => {
prevWidth.current = progress
}, [progress])
useEffect(() => {
nextWidth.current = percent
setProgress(percent)
}, [percent])
return (
<ProgressBarSection className={className} data-testid="progress-bar:container">
<Progress
data-testid="progress-bar:step-fill"
bgColor={bgColor}
percent={nextWidth.current}
prevWidth={prevWidth.current}
/>
</ProgressBarSection>
)
}
export default styled(ProgressBar)``