import { useState , useRef , useEffect } from 'react' ; import { useFoundation } from '@rmwc/base' ; import { EventType , SpecificEventListener } from '@material/base/types' ; import { MDCTextFieldFoundation } from '@material/textfield' ; import { TextFieldProps , TextFieldCharacterCountApi , TextFieldIconApi } from '.' ; import { FloatingLabelApi } from '@rmwc/floating-label' ; export const useTextFieldFoundation = ( props ) => { const [ lineRippleActive , setLineRippleActive ] = useState ( false ) ; const [ lineRippleCenter , setLineRippleCenter ] = useState ( 0 ) ; const [ notchWidth , setNotchWidth ] = useState < number > ( ) ; const [ shakeLabel , setShakeLabel ] = useState ( false ) ; const [ floatLabel , setFloatlabel ] = useState ( false ) ; const characterCounter = useRef < TextFieldCharacterCountApi | null > ( ) ; const setCharacterCounter = ( api ) => ( characterCounter . current = api ) ; const leadingIcon = useRef < TextFieldIconApi | null > ( ) ; const setLeadingIcon = ( api ) => ( leadingIcon . current = api ) ; const trailingIcon = useRef < TextFieldIconApi | null > ( ) ; const setTrailingIcon = ( api ) => ( trailingIcon . current = api ) ; const floatingLabel = useRef < FloatingLabelApi | null > ( ) ; const setFloatingLabel = ( api ) => ( floatingLabel . current = api ) ; const { foundation , ... elements } = useFoundation ( { props , elements : { rootEl : true , inputEl : true } , foundation : ( { rootEl , inputEl , getProps } ) => { const getLabelAdapterMethods = ( ) => { return { shakeLabel : ( shouldShake ) => setShakeLabel ( shouldShake ) , floatLabel : ( shouldFloat ) => { setFloatlabel ( getProps ( ) . floatLabel ?? shouldFloat ) ; } , hasLabel : ( ) => { return ! ! getProps ( ) . label ; } , getLabelWidth : ( ) => floatingLabel . current ?. getWidth ( ) || 0 } ; } ; const getLineRippleAdapterMethods = ( ) => { return { activateLineRipple : ( ) => { setLineRippleActive ( true ) ; } , deactivateLineRipple : ( ) => { setLineRippleActive ( false ) ; } , setLineRippleTransformOrigin : ( normalizedX ) => { setLineRippleCenter ( normalizedX ) ; } } ; } ; const getOutlineAdapterMethods = ( ) => { return { notchOutline : ( labelWidth ) => { setNotchWidth ( labelWidth ) ; } , closeOutline : ( ) => { getProps ( ) . floatLabel ?? setNotchWidth ( undefined ) ; } , hasOutline : ( ) => { return ! ! getProps ( ) . outlined ; } } ; } ; const getInputAdapterMethods = ( ) => { return { registerInputInteractionHandler : < K extends EventType > ( evtType , handler ) : void => inputEl . addEventListener ( evtType , handler ) , deregisterInputInteractionHandler : < K extends EventType > ( evtType , handler ) : void => inputEl . removeEventListener ( evtType , handler ) , getNativeInput : ( ) => inputEl . ref as any } ; } ; const getFoundationMap = ( ) => { return { characterCounter : characterCounter . current ? characterCounter . current . getFoundation ( ) : undefined , helperText : undefined , leadingIcon : leadingIcon . current ? leadingIcon . current . getFoundation ( ) : undefined , trailingIcon : trailingIcon . current ? trailingIcon . current . getFoundation ( ) : undefined } ; } ; return new MDCTextFieldFoundation ( { addClass : ( className ) => rootEl . addClass ( className ) , removeClass : ( className ) => rootEl . removeClass ( className ) , hasClass : ( className ) => rootEl . hasClass ( className ) , registerTextFieldInteractionHandler : < K extends EventType > ( evtType , handler ) : void => rootEl . addEventListener ( evtType , handler ) , deregisterTextFieldInteractionHandler : < K extends EventType > ( evtType , handler ) : void => rootEl . removeEventListener ( evtType , handler ) , registerValidationAttributeChangeHandler : ( handler ) : MutationObserver => { const getAttributesList = ( mutationsList ) => mutationsList . map ( ( mutation ) => mutation . attributeName ) ; if ( inputEl . ref ) { const observer = new MutationObserver ( ( mutationsList ) => handler ( getAttributesList ( mutationsList ) as string [ ] ) ) ; const targetNode = inputEl . ref ; const config = { attributes : true } ; targetNode && observer . observe ( targetNode , config ) ; return observer ; } return { } as MutationObserver ; } , deregisterValidationAttributeChangeHandler : ( observer ) => { observer && observer . disconnect ( ) ; } , isFocused : ( ) => { return document . activeElement === inputEl . ref ; } , ... getInputAdapterMethods ( ) , ... getLabelAdapterMethods ( ) , ... getLineRippleAdapterMethods ( ) , ... getOutlineAdapterMethods ( ) } , getFoundationMap ( ) ) ; } } ) ; const foundationValue = foundation . getValue ( ) ; useEffect ( ( ) => { if ( props . value !== undefined && props . value !== foundationValue ) { foundation . setValue ( String ( props . value ) ) ; } } , [ props . value , foundation , foundationValue ] ) ; useEffect ( ( ) => { if ( props . floatLabel !== undefined ) { foundation . notchOutline ( props . floatLabel ) ; foundation . adapter_ . floatLabel ( props . floatLabel ) ; } } , [ foundation , props . floatLabel ] ) ; return { shakeLabel , floatLabel , notchWidth , lineRippleActive , lineRippleCenter , setCharacterCounter , setLeadingIcon , setTrailingIcon , setFloatingLabel , ... elements } ; } ;