/** * External dependencies */ import { colord, extend, Colord } from 'colord'; /** * GeChiUI dependencies */ import { useCopyToClipboard } from '@gechiui/compose'; import { useState, useEffect, useRef } from '@gechiui/element'; import { __ } from '@gechiui/i18n'; /** * Internal dependencies */ import { Text } from '../text'; import { Flex, FlexItem } from '../flex'; import { Tooltip } from '../ui/tooltip'; import type { ColorType } from './types'; import { space } from '../ui/utils/space'; interface ColorDisplayProps { color: Colord; colorType: ColorType; enableAlpha: boolean; } interface DisplayProps { color: Colord; enableAlpha: boolean; } type Values = [ number, string ][]; interface ValueDisplayProps { values: Values; } const ValueDisplay = ( { values }: ValueDisplayProps ) => ( <> { values.map( ( [ value, abbreviation ] ) => { return ( { abbreviation } { value } ); } ) } ); const HslDisplay = ( { color, enableAlpha }: DisplayProps ) => { const { h, s, l, a } = color.toHsl(); const values: Values = [ [ Math.floor( h ), 'H' ], [ Math.round( s * 100 ), 'S' ], [ Math.round( l * 100 ), 'L' ], ]; if ( enableAlpha ) { values.push( [ Math.round( a * 100 ), 'A' ] ); } return ; }; const RgbDisplay = ( { color, enableAlpha }: DisplayProps ) => { const { r, g, b, a } = color.toRgb(); const values: Values = [ [ r, 'R' ], [ g, 'G' ], [ b, 'B' ], ]; if ( enableAlpha ) { values.push( [ Math.round( a * 100 ), 'A' ] ); } return ; }; const HexDisplay = ( { color }: DisplayProps ) => { const colorWithoutHash = color.toHex().slice( 1 ).toUpperCase(); return ( # { colorWithoutHash } ); }; const getComponent = ( colorType: ColorType ) => { switch ( colorType ) { case 'hsl': return HslDisplay; case 'rgb': return RgbDisplay; default: case 'hex': return HexDisplay; } }; export const ColorDisplay = ( { color, colorType, enableAlpha, }: ColorDisplayProps ) => { const [ copiedColor, setCopiedColor ] = useState< string | null >( null ); const copyTimer = useRef< ReturnType< typeof setTimeout > | undefined >(); const props = { color, enableAlpha }; const Component = getComponent( colorType ); const copyRef = useCopyToClipboard< HTMLDivElement >( () => { switch ( colorType ) { case 'hsl': { return color.toHslString(); } case 'rgb': { return color.toRgbString(); } default: case 'hex': { return color.toHex(); } } }, () => { if ( copyTimer.current ) { clearTimeout( copyTimer.current ); } setCopiedColor( color.toHex() ); copyTimer.current = setTimeout( () => { setCopiedColor( null ); copyTimer.current = undefined; }, 3000 ); } ); useEffect( () => { // clear copyTimer on component unmount. return () => { if ( copyTimer.current ) { clearTimeout( copyTimer.current ); } }; }, [] ); return ( { copiedColor === color.toHex() ? __( 'Copied!' ) : __( 'Copy' ) } } > ); };