import SketchPicker from 'react-color/lib/Sketch' ; import { isFunction } from '@utils/lang' ; import React , { useState , useRef , useEffect } from 'react' ; import type { ColorChangeHandler } from 'react-color' ; import TextInput , { TextInputProps , TextInputAddon } from '@components/TextInput' ; import { ColorIndicator , PickerContainer , ColorInputWrapper , PickerOverlay } from '@components/ColorInput/styles' ; export interface ColorChangeEvent { name : string ; value : string ; } export interface ColorInputProps extends TextInputProps { onChange ? : ( e : React . ChangeEvent < HTMLInputElement > | ColorChangeEvent ) => void ; } export const ColorInput = ( { value , name , onFocus , onChange , ... rest } ) => { const [ isActive , setActive ] = useState ( false ) ; const inputRef = useRef < HTMLInputElement > ( null ) ; const pickerRef = useRef ( null ) ; const clickAwayHandler = useRef ( ( e ) => { if ( ! pickerRef . current . base . contains ( e . target ) ) { setActive ( false ) ; document . removeEventListener ( 'click' , clickAwayHandler . current ) ; } } ) ; useEffect ( ( ) => { if ( isActive ) { document . addEventListener ( 'click' , clickAwayHandler . current ) ; } } , [ isActive ] ) ; const activateOnClick = ( ) => { inputRef . current ?. focus ( ) ; setActive ( true ) ; } ; const onPickerChange = ( color ) => { const { hex , rgb } = color ; if ( isFunction ( onChange ) ) { if ( rgb . a !== 1 ) { const { r , b , g , a } = rgb ; onChange ( { name , value : `rgba(${ r }, ${ g }, ${ b }, ${ a })` } ) ; } else { onChange ( { name , value : hex } ) ; } } } ; const indicator = ( < TextInputAddon > < ColorIndicator color = { value } onClick = { activateOnClick } / > < /TextInputAddon>); return ( < ColorInputWrapper > < TextInput { ... rest } ref = { inputRef } onKeyDown = { ( e ) => { if ( e . key === 'Enter' ) { activateOnClick ( ) ; } } } onClick = { activateOnClick } name = { name } value = { value } prepend = { indicator } onChange = { onChange } / > { isActive && < PickerContainer > < SketchPicker presetColors = { [ ] } ref = { pickerRef } color = { value } onChange = { onPickerChange } / > < /PickerContainer>} < /ColorInputWrapper>); } ;