import classnames from 'classnames' ; import React from 'react' ; import { MDCLinearProgressFoundation } from '@material/linear-progress/foundation' ; import { MDCLinearProgressAdapter } from '@material/linear-progress/adapter' ; export interface LinearProgressProps < T > extends React . HTMLProps < T > { buffer ? : number ; bufferingDots ? : boolean ; className ? : string ; closed ? : boolean ; indeterminate ? : boolean ; progress ? : number ; reversed ? : boolean ; tag ? : string ; } interface LinearProgressState { classList : Set < string > ; } class LinearProgress < T extends { } = HTMLDivElement > extends React . Component < LinearProgressProps < T > , LinearProgressState > { isComponentMounted : boolean = false ; bufferElement : React . RefObject < HTMLDivElement > = React . createRef ( ) ; primaryBarElement : React . RefObject < HTMLDivElement > = React . createRef ( ) ; foundation : MDCLinearProgressFoundation ; constructor ( props ) { super ( props ) ; this . foundation = new MDCLinearProgressFoundation ( this . adapter ) ; this . state = { classList : new Set ( ) , } ; } static defaultProps : LinearProgressProps < HTMLDivElement > = { buffer : 0 , bufferingDots : true , className : '' , closed : false , indeterminate : false , progress : 0 , reversed : false , tag : 'div' , } ; componentDidMount ( ) { const { buffer , closed , indeterminate , progress , reversed } = this . props ; this . isComponentMounted = true ; this . foundation . init ( ) ; this . foundation . setBuffer ( buffer ! ) ; this . foundation . setDeterminate ( ! indeterminate ) ; this . foundation . setProgress ( progress ! ) ; this . foundation . setReverse ( reversed ! ) ; if ( closed ) { this . foundation . close ( ) ; } } componentDidUpdate ( prevProps ) { const { buffer : prevBuffer , closed : prevClosed , indeterminate : prevIndeterminate , progress : prevProgress , reversed : prevReversed , } = prevProps ; const { buffer , closed , indeterminate , progress , reversed } = this . props ; if ( buffer !== prevBuffer ) { this . foundation . setBuffer ( buffer ! ) ; } if ( closed && ! prevClosed ) { this . foundation . close ( ) ; } if ( ! closed && prevClosed ) { this . foundation . open ( ) ; } if ( indeterminate !== prevIndeterminate ) { this . foundation . setDeterminate ( ! indeterminate ) ; } if ( progress !== prevProgress ) { this . foundation . setProgress ( progress ! ) ; } if ( reversed !== prevReversed ) { this . foundation . setReverse ( reversed ! ) ; } } componentWillUnmount ( ) { this . isComponentMounted = false ; this . foundation . destroy ( ) ; } get adapter ( ) : MDCLinearProgressAdapter { return { addClass : ( className ) => { if ( this . isComponentMounted ) { const { classList } = this . state ; classList . add ( className ) ; this . setState ( { classList } ) ; } } , getBuffer : ( ) => { return this . bufferElement . current ; } , getPrimaryBar : ( ) => { return this . primaryBarElement . current ; } , hasClass : ( className ) => { return this . state . classList . has ( className ) ; } , removeClass : ( className ) => { if ( this . isComponentMounted ) { const { classList } = this . state ; classList . delete ( className ) ; this . setState ( { classList } ) ; } } , setStyle : ( element , propertyName , value ) => { if ( this . isComponentMounted ) { element . style . setProperty ( propertyName , value ) ; } } , } ; } get classes ( ) { const { className , indeterminate , reversed } = this . props ; const { classList } = this . state ; return classnames ( 'mdc-linear-progress' , Array . from ( classList ) , className , { 'mdc-linear-progress--indeterminate' : indeterminate , 'mdc-linear-progress--reversed' : reversed , } ) ; } render ( ) { const { buffer , bufferingDots , className , closed , indeterminate , progress , reversed , tag : Tag , ... otherProps } = this . props ; return ( < Tag className = { this . classes } role = 'progressbar' { ... otherProps } > { bufferingDots && ( < div className = 'mdc-linear-progress__buffering-dots' / > ) } < div className = 'mdc-linear-progress__buffer' ref = { this . bufferElement } / > < div className = 'mdc-linear-progress__bar mdc-linear-progress__primary-bar' ref = { this . primaryBarElement } > < span className = 'mdc-linear-progress__bar-inner' / > < /div> < div className = 'mdc-linear-progress__bar mdc-linear-progress__secondary-bar' > < span className = 'mdc-linear-progress__bar-inner' / > < /div> < /Tag>); } } export default LinearProgress ;