import React from 'react' ; import classnames from 'classnames' ; import { MDCLineRippleFoundation } from '@material/line-ripple/foundation' ; import { MDCLineRippleAdapter } from '@material/line-ripple/adapter' ; export interface LineRippleProps extends React . HTMLProps < HTMLDivElement > { className ? : string ; active ? : boolean ; rippleCenter ? : number ; } interface LineRippleState { classList : Set < string > ; style : React . CSSProperties ; } export default class LineRipple extends React . Component < LineRippleProps , LineRippleState > { static defaultProps = { className : '' , style : { } , active : false , rippleCenter : 0 , } ; foundation_ ! : MDCLineRippleFoundation ; state : LineRippleState = { classList : new Set ( ) , style : { } , } ; componentDidMount ( ) { this . foundation_ = new MDCLineRippleFoundation ( this . adapter ) ; this . foundation_ . init ( ) ; if ( this . props . active ) { this . foundation_ . activate ( ) ; } } componentDidUpdate ( prevProps ) { if ( this . props . active !== prevProps . active ) { if ( this . props . active ) { this . foundation_ . activate ( ) ; } else { this . foundation_ . deactivate ( ) ; } } const { rippleCenter } = this . props ; if ( rippleCenter && rippleCenter !== prevProps . rippleCenter && ! isNaN ( rippleCenter ) ) { this . foundation_ . setRippleCenter ( rippleCenter ) ; } } componentWillUnmount ( ) { this . foundation_ . destroy ( ) ; } get adapter ( ) : MDCLineRippleAdapter { return { addClass : ( className ) => this . setState ( { classList : this . state . classList . add ( className ) } ) , removeClass : ( className ) => { const { classList } = this . state ; classList . delete ( className ) ; this . setState ( { classList } ) ; } , hasClass : ( className ) => this . state . classList . has ( className ) , setStyle : this . setStyle , registerEventHandler : ( ) => null , deregisterEventHandler : ( ) => null , } ; } get classes ( ) { const { className } = this . props ; const { classList } = this . state ; return classnames ( 'mdc-line-ripple' , Array . from ( classList ) , className ) ; } setStyle = ( varName , value ) => { const styleName = varName . replace ( /-(\w)/g , ( _ , v ) => v . toUpperCase ( ) ) ; const updatedStyle = Object . assign ( { } , this . state . style ) ; updatedStyle [ styleName ] = value ; this . setState ( { style : updatedStyle } ) ; } ; getMergedStyles = ( ) => { const { style : wrappedStyle } = this . props ; const { style } = this . state ; return Object . assign ( { } , style , wrappedStyle ) ; } ; onTransitionEnd = ( evt ) => this . foundation_ . handleTransitionEnd ( evt . nativeEvent ) ; render ( ) { const { style , className , active , rippleCenter , ... otherProps } = this . props ; return ( < div className = { this . classes } style = { this . getMergedStyles ( ) } onTransitionEnd = { this . onTransitionEnd } { ... otherProps } />); } }