UNPKG

@navinc/base-react-components

Version:
62 lines (54 loc) 1.63 kB
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)``