diff --git a/packages/ui/src/Colors.mdx b/packages/ui/src/Colors.mdx new file mode 100644 index 0000000000..316f688d59 --- /dev/null +++ b/packages/ui/src/Colors.mdx @@ -0,0 +1,10 @@ +import { Meta, Canvas } from '@storybook/blocks'; +import * as ColorsStories from './Colors.stories'; + + + +# 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. + + diff --git a/packages/ui/src/Colors.stories.tsx b/packages/ui/src/Colors.stories.tsx new file mode 100644 index 0000000000..6c196f59ec --- /dev/null +++ b/packages/ui/src/Colors.stories.tsx @@ -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; + $colorVariant: ColorVariant; + }; + +const Variant = styled.div` + 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[] = [ + 'neutral', + 'primary', + 'secondary', + 'unshield', + 'destructive', + 'caution', + 'success', +]; + +const Color = >({ color }: { color: T }) => ( + + + + + + + {color === 'text' + ? (['primary', 'secondary', 'disabled', 'special'] as const).map(variant => ( + + {variant} + + )) + : (['main', 'light', 'dark', 'contrast'] as const).map(variant => ( + + {variant} + + ))} + + + +); + +export const ColorGrid: StoryObj = { + tags: ['!dev'], + render: function Render() { + return ( + <> + + + + {BASE_COLORS.map(color => ( + + ))} + + + ); + }, +};