Skip to content

Commit

Permalink
Create Storybook stories for Penumbra colors
Browse files Browse the repository at this point in the history
  • Loading branch information
jessepinho committed Jul 17, 2024
1 parent 170e172 commit ae32dbb
Show file tree
Hide file tree
Showing 2 changed files with 118 additions and 0 deletions.
10 changes: 10 additions & 0 deletions packages/ui/src/Colors.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Meta, Canvas } from '@storybook/blocks';
import * as ColorsStories from './Colors.stories';

<Meta title='Colors' />

# Colors

Below are the colors we use at Penumbra. We deliberately do not include RGB/hex values for our colors, as they should be used via tokens — e.g., `text.primary`, `neutral.light`, `destructive.main`, etc. — to ensure consistency.

<Canvas of={ColorsStories.ColorGrid} />
108 changes: 108 additions & 0 deletions packages/ui/src/Colors.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import type { Meta, StoryObj } from '@storybook/react';
import { Grid } from './Grid';
import { Technical } from './Typography';
import styled from 'styled-components';
import {
type ColorVariant,
type Color as TColor,
type TextColorVariant,
} from './ThemeProvider/theme';
import { Fragment } from 'react';
import { media } from './utils/media';

const meta: Meta = {};
export default meta;

const Label = styled.div`
display: flex;
height: 100%;
${media.tablet`
align-items: center;
`}
`;

const Variants = styled.div`
display: grid;
gap: ${props => props.theme.spacing(4)};
grid-template-columns: 1fr;
${media.tablet`
grid-template-columns: repeat(4, 1fr);
`}
`;

type VariantProps =
| {
$color: 'text';
$colorVariant: TextColorVariant;
}
| {
$color: Exclude<TColor, 'text' | 'action' | 'other'>;
$colorVariant: ColorVariant;
};

const Variant = styled.div<VariantProps>`
background-color: ${props =>
props.$color === 'text' ? 'transparent' : props.theme.color[props.$color][props.$colorVariant]};
border-radius: ${props => props.theme.borderRadius.xl};
color: ${props =>
props.$color === 'text'
? props.theme.color.text[props.$colorVariant]
: props.$colorVariant === 'contrast' || props.$colorVariant === 'light'
? props.theme.color[props.$color].dark
: props.theme.color.text.primary};
padding: ${props => props.theme.spacing(2)};
`;

const BASE_COLORS: Exclude<TColor, 'text' | 'action' | 'other'>[] = [
'neutral',
'primary',
'secondary',
'unshield',
'destructive',
'caution',
'success',
];

const Color = <T extends Exclude<TColor, 'action' | 'other'>>({ color }: { color: T }) => (
<Fragment key={color}>
<Grid mobile={6} tablet={2}>
<Label>
<Technical>{color}</Technical>
</Label>
</Grid>
<Grid mobile={6} tablet={10}>
<Variants>
{color === 'text'
? (['primary', 'secondary', 'disabled', 'special'] as const).map(variant => (
<Variant key={variant} $color={color} $colorVariant={variant}>
<Technical>{variant}</Technical>
</Variant>
))
: (['main', 'light', 'dark', 'contrast'] as const).map(variant => (
<Variant key={variant} $color={color} $colorVariant={variant}>
<Technical>{variant}</Technical>
</Variant>
))}
</Variants>
</Grid>
</Fragment>
);

export const ColorGrid: StoryObj = {
tags: ['!dev'],
render: function Render() {
return (
<>
<Grid container as='section'>
<Color color='text' />

{BASE_COLORS.map(color => (
<Color key={color} color={color} />
))}
</Grid>
</>
);
},
};

0 comments on commit ae32dbb

Please sign in to comment.