import * as React from 'react' ; import { createComponent , StyledType , expandHex , GrowthBehavior , ErrorType , styled , Themeable , ContentDirection , } from '@workday/canvas-kit-react/common' ; import { colors , space , type , inputColors } from '@workday/canvas-kit-react/tokens' ; import { TextInput , TextInputProps } from '@workday/canvas-kit-react/text-input' ; import { ColorSwatch } from './parts/ColorSwatch' ; export interface ColorInputProps extends Themeable , TextInputProps , GrowthBehavior { default value ? : string ; default showCheck ? : boolean ; default placeholder ? : string ; /**
     * The type of error associated with the ColorInput (if applicable).
     */ error ? : ErrorType ; default disabled ? : boolean ; /**
     * The function called when the ColorInput state changes.
     */ onChange ? : ( event : React . ChangeEvent < HTMLInputElement > ) => void ; /**
     * The function called when a valid hex value is entered in the ColorInput. The `color` argument passed to the callback function is prefixed with a hash and expanded if necessary (e.g., `03F` is converted to `#0033FF`).
     */ onValidColorChange ? : ( color : string ) => void ; } const colorInputWidth = 116 ; const CustomHexInput = styled ( TextInput ) < Pick < ColorInputProps , 'disabled' | 'grow' > & StyledType > ( { boxSizing : 'border-box' , minWidth : colorInputWidth , width : colorInputWidth , fontFamily : type . properties . fontFamilies . monospace , '&:focus::placeholder' : { color : 'transparent' , } , } , ( { grow } ) => grow && { minWidth : '100%' , width : '100%' , } , ( { disabled } ) => ( { backgroundColor : disabled ? colors . soap200 : '' , } ) , ( { theme } ) => ( { paddingLeft : theme . canvas . direction === ContentDirection . LTR ? '46px' : 'calc(100% - 86px) /* @noflip */' , } ) ) ; const ColorInputContainer = styled ( 'div' ) < Pick < ColorInputProps , 'grow' > > ( { position : 'relative' , width : colorInputWidth , } , ( { grow } ) => grow && { minWidth : '100%' , width : '100%' , } ) ; const PoundSignPrefix = styled ( 'span' ) < Pick < ColorInputProps , 'disabled' > > ( { position : 'absolute' , top : 10 , ... type . levels . subtext . large , fontFamily : type . properties . fontFamilies . monospace , } , ( { disabled } ) => ( { color : disabled ? inputColors . disabled . text : undefined , } ) , ( { theme } ) => ( { left : theme . canvas . direction === ContentDirection . LTR ? '36px' : '88px' , } ) ) ; const SwatchTile = styled ( ColorSwatch ) ( { position : 'absolute' , top : 0 , left : space . xxs , marginTop : '10px' , boxShadow : 'inset 0 0 0 1px rgba(0,0,0,0.25)' , pointerEvents : 'none' , } ) ; const isValidHex = ( value ) => { return /(^#?[0-9A-F]{3}$)|(^#?[0-9A-F]{6}$)/i . test ( value ) ; } ; const formatValue = ( value ) => { return value . replace ( /#/g , '' ) . substring ( 0 , 6 ) ; } ; export const ColorInput = createComponent ( 'input' ) ( { displayName : 'ColorInput' , Component : ( { placeholder = 'FFFFFF' , value = '' , showCheck , onChange , onValidColorChange , disabled , error , grow , ... elemProps } , ref , Element ) => { const formattedValue = formatValue ( value ) ; const handleChange = ( e ) => { const value = formatValue ( e . currentTarget . value ) ; if ( onChange ) { onChange ( e ) ; } if ( isValidHex ( value ) && onValidColorChange ) { onValidColorChange ( `#${ expandHex ( value ) }` ) ; } } ; return ( < ColorInputContainer grow = { grow } > < CustomHexInput dir = "ltr" ref = { ref } as = { Element } onChange = { handleChange } type = "text" placeholder = { value ? undefined : placeholder } value = { formattedValue } error = { error } spellCheck = { false } disabled = { disabled } grow = { grow } maxLength = { 7 } { ... elemProps } / > < SwatchTile showCheck = { showCheck } color = { isValidHex ( formattedValue ) ? `#${ formattedValue }` : '' } /> < PoundSignPrefix aria - hidden = { true } disabled = { disabled } > # < /PoundSignPrefix> < /ColorInputContainer>); } , } ) ; export default ColorInput ;