import React from 'react' ; import classnames from 'classnames' ; import { MDCTextFieldIconAdapter } from '@material/textfield/icon/adapter' ; import { MDCTextFieldIconFoundation } from '@material/textfield/icon/foundation' ; export interface IconProps extends React . HTMLProps < HTMLOrSVGElement > { disabled ? : boolean ; children : React . ReactElement < React . HTMLProps < HTMLOrSVGElement > > ; onSelect ? : ( ) => void ; } interface IconState { tabindex ? : number ; role ? : string ; } export default class Icon extends React . Component < IconProps , IconState > { foundation ! : MDCTextFieldIconFoundation ; static defaultProps : Partial < IconProps > = { disabled : false , } ; constructor ( props ) { super ( props ) ; const { role } = props . children . props ; this . state = { tabindex : this . tabindex , role , } ; } componentDidMount ( ) { this . foundation = new MDCTextFieldIconFoundation ( this . adapter ) ; this . foundation . init ( ) ; if ( this . props . disabled ) { this . foundation . setDisabled ( true ) ; } } componentDidUpdate ( prevProps ) { if ( this . props . disabled !== prevProps . disabled ) { this . foundation . setDisabled ( ! ! this . props . disabled ) ; } if ( this . props . onSelect !== prevProps . onSelect ) { this . setState ( { tabindex : this . tabindex } ) ; } } componentWillUnmount ( ) { this . foundation . destroy ( ) ; } get tabindex ( ) { if ( typeof this . props . children . props . tabIndex === 'number' ) { return this . props . children . props . tabIndex ; } return this . props . onSelect ? 0 : - 1 ; } get adapter ( ) : MDCTextFieldIconAdapter { return { getAttr : ( attr ) => { const attr_ = this . state [ attr ] ; if ( attr_ || ( typeof attr_ === 'number' && ! isNaN ( attr_ ) ) ) { return attr_ . toString ( ) ; } return '' ; } , setAttr : ( attr , value ) => this . setState ( ( prevState ) => { return { ... prevState , [ attr ] : attr === 'tabindex' ? Number ( value ) : value , } ; } ) , removeAttr : ( attr ) => this . setState ( ( prevState ) => ( { ... prevState , [ attr ] : null } ) ) , notifyIconAction : ( ) => this . props . onSelect && this . props . onSelect ( ) , setContent : ( ) => undefined , registerInteractionHandler : ( ) => undefined , deregisterInteractionHandler : ( ) => undefined , } ; } handleClick = ( e ) => this . foundation . handleInteraction ( e . nativeEvent ) ; handleKeyDown = ( e ) => this . foundation . handleInteraction ( e . nativeEvent ) ; addIconAttrsToChildren = ( ) => { const { tabindex : tabIndex , role } = this . state ; const child = React . Children . only ( this . props . children ) ; const className = classnames ( 'mdc-text-field__icon' , child . props . className ) ; const props = Object . assign ( { } , child . props , { className , onClick : this . handleClick , onKeyDown : this . handleKeyDown , tabIndex , role , } ) ; return React . cloneElement ( child , props ) ; } ; render ( ) { return this . addIconAttrsToChildren ( ) ; } }