/**
* 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' ) }
}
>
);
};