|
| 1 | +/** @jsx jsx */ |
| 2 | +import { FC } from 'react'; |
| 3 | +import { jsx, Theme } from 'theme-ui'; |
| 4 | +import { CopyContainer } from '@component-controls/components'; |
| 5 | +import simpleColorConverter from 'simple-color-converter'; |
| 6 | +import { colorToStr } from '../utils'; |
| 7 | +import { ColorBlockProps, ColorValue } from '../../types'; |
| 8 | +import { GridContainerProps, GridContainer } from '../../components'; |
| 9 | + |
| 10 | +/** |
| 11 | + * Color item displaying the color as a cirlce with the variable name, hev, rgb, cmyk and pantone values below. |
| 12 | + * Design inspired from Biteable's Design System [X](https://x.biteable.com/brand/). |
| 13 | + */ |
| 14 | +export const XColor: FC<ColorBlockProps> = ({ name, color }) => { |
| 15 | + const colorObj: ColorValue = |
| 16 | + typeof color === 'string' ? { value: color } : color; |
| 17 | + const { value: colorValue, name: colorName = name } = colorObj; |
| 18 | + |
| 19 | + const { hex, rgba } = colorToStr(colorValue); |
| 20 | + const { color: cmyk } = new simpleColorConverter({ |
| 21 | + rgba, |
| 22 | + to: 'cmyk', |
| 23 | + }); |
| 24 | + const { color: pantone } = new simpleColorConverter({ |
| 25 | + rgba, |
| 26 | + to: 'pantone', |
| 27 | + }); |
| 28 | + return ( |
| 29 | + <div |
| 30 | + sx={{ |
| 31 | + px: 2, |
| 32 | + display: 'flex', |
| 33 | + flexDirection: 'column', |
| 34 | + alignItems: 'center', |
| 35 | + minWidth: 120, |
| 36 | + maxWidth: 320, |
| 37 | + fontSize: 2, |
| 38 | + }} |
| 39 | + > |
| 40 | + <CopyContainer value={hex} name={name} sx={{ px: 2, pt: 2 }}> |
| 41 | + <div |
| 42 | + sx={{ |
| 43 | + border: (t: Theme) => `1px solid ${t.colors?.shadow}`, |
| 44 | + width: 80, |
| 45 | + height: 80, |
| 46 | + bg: colorValue, |
| 47 | + borderRadius: '50%', |
| 48 | + }} |
| 49 | + /> |
| 50 | + </CopyContainer> |
| 51 | + <div sx={{ textAlign: 'center', mt: 1, mb: 2, fontWeight: 'heading' }}> |
| 52 | + {colorName} |
| 53 | + </div> |
| 54 | + <div |
| 55 | + sx={{ |
| 56 | + width: '100%', |
| 57 | + display: 'flex', |
| 58 | + flexDirection: 'row', |
| 59 | + alignItems: 'center', |
| 60 | + justifyContent: 'space-between', |
| 61 | + }} |
| 62 | + > |
| 63 | + <div>HEX</div> |
| 64 | + <div>{hex.split('#')[1].toUpperCase()}</div> |
| 65 | + </div> |
| 66 | + <div |
| 67 | + sx={{ |
| 68 | + width: '100%', |
| 69 | + display: 'flex', |
| 70 | + flexDirection: 'row', |
| 71 | + alignItems: 'center', |
| 72 | + justifyContent: 'space-between', |
| 73 | + }} |
| 74 | + > |
| 75 | + <div>RGB</div> |
| 76 | + <div> |
| 77 | + {`${rgba.r},${rgba.g},${rgba.b}${rgba.a !== 1 ? `,${rgba.a}` : ''}`} |
| 78 | + </div> |
| 79 | + </div> |
| 80 | + <div |
| 81 | + sx={{ |
| 82 | + width: '100%', |
| 83 | + display: 'flex', |
| 84 | + flexDirection: 'row', |
| 85 | + alignItems: 'center', |
| 86 | + justifyContent: 'space-between', |
| 87 | + }} |
| 88 | + > |
| 89 | + <div>CMYK</div> |
| 90 | + <div>{`${cmyk.c},${cmyk.m},${cmyk.y},${cmyk.k}`}</div> |
| 91 | + </div> |
| 92 | + <div |
| 93 | + sx={{ |
| 94 | + width: '100%', |
| 95 | + display: 'flex', |
| 96 | + flexDirection: 'row', |
| 97 | + alignItems: 'center', |
| 98 | + justifyContent: 'space-between', |
| 99 | + }} |
| 100 | + > |
| 101 | + <div>Pantone</div> |
| 102 | + <div>{pantone}</div> |
| 103 | + </div> |
| 104 | + </div> |
| 105 | + ); |
| 106 | +}; |
| 107 | + |
| 108 | +/** |
| 109 | + * |
| 110 | + * palette displayed with XColor items |
| 111 | + * using a css grid for the dsplay |
| 112 | + */ |
| 113 | +export const XColorPalette: FC<Omit< |
| 114 | + GridContainerProps, |
| 115 | + 'children' |
| 116 | +>> = props => ( |
| 117 | + <GridContainer width={180} gap={2} {...props}> |
| 118 | + {({ name, value }) => ( |
| 119 | + <XColor key={`color_item_${name}}`} name={name} color={value} /> |
| 120 | + )} |
| 121 | + </GridContainer> |
| 122 | +); |
0 commit comments