Skip to content

Commit

Permalink
feat: add skyline color token
Browse files Browse the repository at this point in the history
  • Loading branch information
atanasster committed Sep 30, 2020
1 parent c92732a commit f47ca67
Show file tree
Hide file tree
Showing 7 changed files with 294 additions and 1 deletion.
56 changes: 55 additions & 1 deletion examples/stories/src/tutorial/design/tokens/colors.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import {
PrimerColorPalette,
SeedsColorPalette,
SeekColorPalette,
SkylineColorPalette,
} from '@component-controls/design-tokens';

# Overview
Expand Down Expand Up @@ -1608,4 +1609,57 @@ import { SeekColorPalette } from '@component-controls/design-tokens';
'@sk-pink': '#e60278',
'@sk-green': '#157e00',
}}
/>
/>


## SkylineColor

The [SkylineColor](/api/design-tokens-colors-skylinecolor--overview) component displays the color as a row, with color name, custom columns for contrast checks scss variable name and color block.

Design inspired from [Skyline](https://skyline.benevity.org/design-language/color/#hues).

```
import { SkylineColorPalette } from '@component-controls/design-tokens';
<SkylineColorPalette
palette={{
Green: {
value: '#1a801b',
scss: 'get-hue(green)',
},
'Gray 500': {
value: '#8b8b8b',
scss: 'get-gray(500)',
},
'Gray 600': {
value: '#757575',
scss: 'get-gray(600)',
},
'Gray 700': {
value: '#616161',
scss: 'get-gray(700)',
},
}}
/>
```

<SkylineColorPalette
palette={{
Green: {
value: '#1a801b',
scss: 'get-hue(green)',
},
'Gray 500': {
value: '#8b8b8b',
scss: 'get-gray(500)',
},
'Gray 600': {
value: '#757575',
scss: 'get-gray(600)',
},
'Gray 700': {
value: '#616161',
scss: 'get-gray(700)',
},
}}
/>
61 changes: 61 additions & 0 deletions ui/design-tokens/src/Colors/SkylineColor/SkylineColor.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import React from 'react';
import { ControlTypes } from '@component-controls/core';
import { SkylineColor, SkylineColorPalette } from './SkylineColor';
import { ColorProps } from '../../types';

export default {
title: 'Design Tokens/Colors/SkylineColor',
component: SkylineColor,
};

export const overview = ({ name, color }: ColorProps) => (
<SkylineColor name={name} color={color} />
);

overview.controls = {
name: 'Gray 600',
color: {
type: ControlTypes.OBJECT,
value: {
value: { type: ControlTypes.COLOR, value: '#757575' },
description:
'Dark version of primary blue that is accessible with white. Most commonly used to indicate hover and active states of an item with primary blue background.',
scss: 'get-gray(600)',
},
},
};

export const palette = () => (
<SkylineColorPalette
palette={{
Green: {
value: '#1a801b',
scss: 'get-hue(green)',
},
'Green Light': {
value: '#f4fce3',
scss: 'get-hue(green, light)',
},
Yellow: {
value: '#fcc419',
scss: 'get-hue(yellow)',
},
'Yellow Light': {
value: '#fff9db',
scss: 'get-hue(yellow, light)',
},
'Gray 500': {
value: '#8b8b8b',
scss: 'get-gray(500)',
},
'Gray 600': {
value: '#757575',
scss: 'get-gray(600)',
},
'Gray 700': {
value: '#616161',
scss: 'get-gray(700)',
},
}}
/>
);
171 changes: 171 additions & 0 deletions ui/design-tokens/src/Colors/SkylineColor/SkylineColor.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
/** @jsx jsx */
import { FC } from 'react';
import { jsx } from 'theme-ui';
import { CopyContainer } from '@component-controls/components';
import tinycolor from 'tinycolor2';
import { CheckIcon, XIcon } from '@primer/octicons-react';

import { colorToStr, mostReadable } from '../utils';
import { ColorBlockProps, ColorValue, colorContrast } from '../../types';
import { TableContainerProps, TableContainer } from '../../components';

/**
* Color item displaying as a row, with color name, custom columns for contrast checks scss variable name and color block.
* Design inspired from [Skyline](https://skyline.benevity.org/design-language/color/#hues).
*/

export const SkylineColor: FC<ColorBlockProps> = props => (
<table sx={{ width: '100%' }}>
<tbody>
<BaseSkylineColor {...props} />
</tbody>
</table>
);

const PassTag: FC<{ contrast: number }> = ({ contrast }) => {
const pass = contrast > colorContrast.small.ratio;
return (
<div
sx={{
px: 2,
py: 1,
width: 60,
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
whiteSpace: 'nowrap',
fontSize: 0,
fontWeight: 'thin',
borderRadius: '1rem',
border: `1px solid ${pass ? '#1a801b' : '#ce3232'}`,
}}
>
{pass ? (
<CheckIcon sx={{ color: '#1a801b' }} />
) : (
<XIcon sx={{ color: '#ce3232' }} />
)}
<div sx={{ ml: 2 }}>{pass ? 'Yes' : 'No'}</div>
</div>
);
};

export type ContrastColor = {
name: string;
color: string;
};

export type ContrastColors = ContrastColor[];

export const defaultContrastColors: ContrastColors = [
{ name: 'Use on White', color: '#ffffff' },
{ name: 'Use on Gray 200', color: '#f5f5f5' },
];
export type SkylineColorProps = {
contrastColors?: ContrastColors;
} & ColorBlockProps;

const BaseSkylineColor: FC<SkylineColorProps> = ({
name,
color,
contrastColors = defaultContrastColors,
}) => {
const colorObj: ColorValue =
typeof color === 'string' ? { value: color } : color;
const { value: colorValue, name: colorName = name, scss } = colorObj;
const { hex } = colorToStr(colorValue);
const textColor = mostReadable(hex);
const contrasts = contrastColors.map(contrastColor =>
tinycolor.readability(hex, contrastColor.color),
);
return (
<tr>
<td>
<div sx={{ fontSize: 1 }}>{colorName}</div>
</td>
{contrasts.map((contrastRatio, index) => (
<td key={`contrast_cell_${contrastColors[index].name}`}>
<PassTag contrast={contrastRatio} />
</td>
))}
<td>
{scss && (
<CopyContainer value={scss} name={colorName}>
<code
sx={{
my: 1,
bg: '#deeff8',
border: `1px dashed #106fa4`,
whiteSpace: 'nowrap',
px: 2,
py: 1,
}}
>
{scss}
</code>
</CopyContainer>
)}
</td>
<td>
<CopyContainer value={hex} name={colorName}>
<div
sx={{
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
height: 35,
minWidth: 100,
bg: colorValue,
fontSize: 1,
color: textColor,
}}
>
<div>{hex}</div>
</div>
</CopyContainer>
</td>
</tr>
);
};

/**
*
* palette displayed with SkylineColor items
* using a css flex display direction column
*/
export const SkylineColorPalette: FC<{ contrastColors?: ContrastColors } & Omit<
TableContainerProps,
'children' | 'columns'
>> = ({ contrastColors = defaultContrastColors, ...props }) => (
<TableContainer
columns={[
{ title: 'Name' },
...contrastColors.map(contrastColor => ({ title: contrastColor.name })),
{ title: 'Scss', sx: { width: '30%' } },
{ title: 'Example' },
]}
sx={{
border: 'none',
'& > tbody > tr > td': {
p: 2,
},
'& > thead > tr > th': {
textAlign: 'left',
fontSize: 1,
fontWeight: 'heading',
py: 2,
},
}}
{...props}
>
{({ name, value }) => (
<BaseSkylineColor
key={`color_item_${name}}`}
name={name}
color={value}
contrastColors={contrastColors}
/>
)}
</TableContainer>
);
1 change: 1 addition & 0 deletions ui/design-tokens/src/Colors/SkylineColor/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './SkylineColor';
1 change: 1 addition & 0 deletions ui/design-tokens/src/Colors/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,4 @@ export * from './PhotonColor';
export * from './PrimerColor';
export * from './SeedsColor';
export * from './SeekColor';
export * from './SkylineColor';
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export const TableContainer: FC<TableContainerProps> = ({
sx={{
mx: 1,
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
fontSize: 1,
...column.sx,
}}
Expand Down
4 changes: 4 additions & 0 deletions ui/design-tokens/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ export type ColorValue =
* sass variable name ex: $text-input
*/
sass?: string;
/**
* scss variable name ex: $text-input
*/
scss?: string;
/**
* css class name ex text-input or --pf-global--link--Color
*/
Expand Down

0 comments on commit f47ca67

Please sign in to comment.