Skip to content

Commit 0b7eae4

Browse files
authored
Merge pull request #13099 from TylerAPfledderer/feat/color-scheme-stories
feat: Create stories for DS color scheme
2 parents 288ba62 + 84ea229 commit 0b7eae4

File tree

2 files changed

+187
-1
lines changed

2 files changed

+187
-1
lines changed

.storybook/main.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ import type { StorybookConfig } from "@storybook/nextjs"
1616

1717
const config: StorybookConfig = {
1818
stories: [
19-
"../src/components/**/*.stories.tsx",
19+
"../src/components/**/*.stories.{ts,tsx}",
20+
"../src/@chakra-ui/stories/*.stories.tsx",
2021
"../src/layouts/stories/*.stories.tsx",
2122
],
2223
addons: [
Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
import { type ReactNode } from "react"
2+
import capitalize from "lodash/capitalize"
3+
import { Box, Flex, HStack, Square, Stack, Text } from "@chakra-ui/react"
4+
import type { Meta, StoryObj } from "@storybook/react"
5+
6+
import colors from "@/@chakra-ui/foundations/colors"
7+
import semanticTokens from "@/@chakra-ui/semanticTokens"
8+
9+
const semanticTokenColors = semanticTokens["colors"]
10+
11+
import Heading from "@/components/Heading"
12+
13+
const meta = {
14+
title: "Design System/Colors",
15+
parameters: {
16+
// Do not create snapshots for any stories in the file.
17+
chromatic: { disableSnapshot: true },
18+
},
19+
} satisfies Meta
20+
21+
export default meta
22+
23+
const primitiveColorKeys = ["gray", "blue", "orange"]
24+
export const Primitives: StoryObj = {
25+
render: () => {
26+
const primitiveColorsMap = Object.entries(colors)
27+
.filter((obj) => primitiveColorKeys.includes(obj[0]))
28+
.reduce<{ [tokenKey: string]: [string, string][] }>(
29+
(acc, [key, value]) => {
30+
const tokenMap = Object.entries(value)
31+
return {
32+
...acc,
33+
[key]: tokenMap,
34+
}
35+
},
36+
{}
37+
)
38+
39+
return (
40+
<Stack direction="column" gap="16">
41+
{primitiveColorKeys.map((color) => (
42+
<ColorGroupWrapper key={color} color={color}>
43+
<HStack>
44+
{primitiveColorsMap[color].map(([tokenKey, value]) => (
45+
<Stack key={`${color}${tokenKey}`} direction="column">
46+
<Box>
47+
<Square size="20" bg={`${color}.${tokenKey}`}></Square>
48+
</Box>
49+
<Stack direction="column">
50+
<Text size="sm">{value}</Text>
51+
<Text size="sm">
52+
{color}.{tokenKey}
53+
</Text>
54+
</Stack>
55+
</Stack>
56+
))}
57+
</HStack>
58+
</ColorGroupWrapper>
59+
))}
60+
</Stack>
61+
)
62+
},
63+
}
64+
65+
const ColorGroupWrapper = ({
66+
color,
67+
children,
68+
}: {
69+
color: string
70+
children: ReactNode
71+
}) => {
72+
return (
73+
<Box
74+
key={color}
75+
color={color === "orange" ? "white" : undefined}
76+
px="8"
77+
py="8"
78+
bg={
79+
color === "gray"
80+
? `linear-gradient(180deg, #1b1b1b 35%, #fff 35%)`
81+
: color === "orange"
82+
? "gray.800"
83+
: undefined
84+
}
85+
>
86+
{children}
87+
</Box>
88+
)
89+
}
90+
91+
export const SemanticScheme: StoryObj = {
92+
parameters: {
93+
chromatic: {
94+
modes: {
95+
darkMode: {
96+
colorMode: "dark",
97+
},
98+
lightMode: {
99+
colorMode: "light",
100+
},
101+
},
102+
},
103+
},
104+
render: () => {
105+
const tokenNames = [
106+
"primary",
107+
"body",
108+
"background",
109+
"disabled",
110+
"success",
111+
"attention",
112+
"error",
113+
] as const
114+
const deprecatedTokens: Record<(typeof tokenNames)[number], string[]> = {
115+
primary: ["light", "dark", "pressed"],
116+
body: ["inverted"],
117+
background: [],
118+
disabled: [],
119+
success: ["neutral", "outline"],
120+
attention: ["neutral", "outline"],
121+
error: ["neutral", "outline"],
122+
}
123+
124+
return (
125+
<Flex direction="column" gap="16">
126+
{tokenNames.map((tokenName) => {
127+
const currentDeprecatedTokens = deprecatedTokens[
128+
tokenName
129+
] as string[]
130+
131+
const tokenObj = semanticTokenColors[tokenName]
132+
133+
const filteredTokenObj =
134+
"base" in tokenObj
135+
? Object.keys(semanticTokens["colors"][tokenName]).filter(
136+
(key) => !currentDeprecatedTokens.includes(key)
137+
)
138+
: undefined
139+
140+
return (
141+
<Flex key={tokenName} direction="column" gap="4">
142+
<Heading>{capitalize(tokenName)}</Heading>
143+
<HStack gap="8">
144+
{!filteredTokenObj ? (
145+
<SemanticColorBlock
146+
nestedKey={tokenName}
147+
tokenName={tokenName}
148+
/>
149+
) : (
150+
<>
151+
{filteredTokenObj.map((nestedKey) => (
152+
<SemanticColorBlock
153+
key={nestedKey}
154+
nestedKey={nestedKey}
155+
tokenName={tokenName}
156+
/>
157+
))}
158+
</>
159+
)}
160+
</HStack>
161+
</Flex>
162+
)
163+
})}
164+
</Flex>
165+
)
166+
},
167+
}
168+
169+
const SemanticColorBlock = ({
170+
nestedKey,
171+
tokenName,
172+
}: Record<"nestedKey" | "tokenName", string>) => (
173+
<Flex key={nestedKey} direction="column" gap="2">
174+
<Square
175+
border={
176+
tokenName === "background" && nestedKey === "base"
177+
? "1px solid"
178+
: undefined
179+
}
180+
size="20"
181+
bg={tokenName === nestedKey ? tokenName : `${tokenName}.${nestedKey}`}
182+
/>
183+
<Text>{tokenName}.{nestedKey}</Text>
184+
</Flex>
185+
)

0 commit comments

Comments
 (0)