import React , { useState , useEffect , useCallback } from "react" ; import { useEventCallback } from "../../hooks/useEventCallback" ; import { ColorInputBaseProps } from "../../types" ; interface Props extends ColorInputBaseProps { /** Blocks typing invalid characters and limits string length */ escape : ( value : string ) => string ; /** Checks that value is valid color string */ validate : ( value : string ) => boolean ; /** Processes value before displaying it in the input */ format ? : ( value : string ) => string ; /** Processes value before sending it in `onChange` */ process ? : ( value : string ) => string ; } export const ColorInput = ( props ) : JSX . Element => { const { color = "" , onChange , onBlur , escape , validate , format , process , ... rest } = props ; const [ value , setValue ] = useState ( ( ) => escape ( color ) ) ; const onChangeCallback = useEventCallback < string > ( onChange ) ; const onBlurCallback = useEventCallback < React . FocusEvent < HTMLInputElement > > ( onBlur ) ; const handleChange = useCallback ( ( e ) => { const inputValue = escape ( e . target . value ) ; setValue ( inputValue ) ; if ( validate ( inputValue ) ) onChangeCallback ( process ? process ( inputValue ) : inputValue ) ; } , [ escape , process , validate , onChangeCallback ] ) ; const handleBlur = useCallback ( ( e ) => { if ( ! validate ( e . target . value ) ) setValue ( escape ( color ) ) ; onBlurCallback ( e ) ; } , [ color , escape , validate , onBlurCallback ] ) ; useEffect ( ( ) => { setValue ( escape ( color ) ) ; } , [ color , escape ] ) ; return ( < input { ... rest } value = { format ? format ( value ) : value } spellCheck = "false" onChange = { handleChange } onBlur = { handleBlur } / > ) ; } ;