@channel.io/bezier-react 3.6.4 → 3.6.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/packages/bezier-tokens/dist/beta/esm/darkTheme.js +60 -0
- package/dist/cjs/packages/bezier-tokens/dist/beta/esm/darkTheme.js.map +1 -1
- package/dist/cjs/packages/bezier-tokens/dist/beta/esm/lightTheme.js +60 -0
- package/dist/cjs/packages/bezier-tokens/dist/beta/esm/lightTheme.js.map +1 -1
- package/dist/cjs/styles.css +1 -1
- package/dist/esm/packages/bezier-tokens/dist/beta/esm/darkTheme.mjs +60 -0
- package/dist/esm/packages/bezier-tokens/dist/beta/esm/darkTheme.mjs.map +1 -1
- package/dist/esm/packages/bezier-tokens/dist/beta/esm/lightTheme.mjs +60 -0
- package/dist/esm/packages/bezier-tokens/dist/beta/esm/lightTheme.mjs.map +1 -1
- package/dist/esm/styles.css +1 -1
- package/package.json +2 -2
- package/src/stories/color.mdx +259 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@channel.io/bezier-react",
|
|
3
|
-
"version": "3.6.
|
|
3
|
+
"version": "3.6.5",
|
|
4
4
|
"description": "React components library that implements Bezier design system.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -131,7 +131,7 @@
|
|
|
131
131
|
}
|
|
132
132
|
},
|
|
133
133
|
"dependencies": {
|
|
134
|
-
"@channel.io/bezier-tokens": "0.
|
|
134
|
+
"@channel.io/bezier-tokens": "0.5.0",
|
|
135
135
|
"@radix-ui/react-checkbox": "^1.1.3",
|
|
136
136
|
"@radix-ui/react-dialog": "^1.1.3",
|
|
137
137
|
"@radix-ui/react-radio-group": "^1.2.2",
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
import { Meta } from '@storybook/blocks'
|
|
2
|
+
import { tokens } from '@channel.io/bezier-tokens/beta'
|
|
3
|
+
import { useState } from 'react'
|
|
4
|
+
|
|
5
|
+
import globalColor from '../../../bezier-tokens/src/beta/global/color.json'
|
|
6
|
+
import lightThemeColor from '../../../bezier-tokens/src/beta/semantic/light-theme/color.json'
|
|
7
|
+
import darkThemeColor from '../../../bezier-tokens/src/beta/semantic/dark-theme/color.json'
|
|
8
|
+
|
|
9
|
+
import {
|
|
10
|
+
LightThemeProvider,
|
|
11
|
+
DarkThemeProvider,
|
|
12
|
+
} from '~/src/components/ThemeProvider'
|
|
13
|
+
import { HStack, VStack } from '~/src/components/Stack'
|
|
14
|
+
|
|
15
|
+
<Meta title="foundation/Color" />
|
|
16
|
+
|
|
17
|
+
export const formatTitle = (title) =>
|
|
18
|
+
title
|
|
19
|
+
.split('-')
|
|
20
|
+
.map((word) => (word ? word[0].toUpperCase() + word.slice(1) : word))
|
|
21
|
+
.join(' ')
|
|
22
|
+
|
|
23
|
+
export const isTokenLeaf = (value) =>
|
|
24
|
+
Boolean(value && typeof value.value === 'string')
|
|
25
|
+
|
|
26
|
+
export const normalizeTokenName = (name) =>
|
|
27
|
+
name.endsWith('-normal') ? name.slice(0, -'-normal'.length) : name
|
|
28
|
+
|
|
29
|
+
export const getTokenName = (path) =>
|
|
30
|
+
normalizeTokenName(`color-${path.join('-')}`)
|
|
31
|
+
|
|
32
|
+
export const sortNumericLeafEntries = (entries) => {
|
|
33
|
+
const allNumericKeys = entries.every(([key]) => /^\d+$/.test(key))
|
|
34
|
+
|
|
35
|
+
if (!allNumericKeys) {
|
|
36
|
+
return entries
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return [...entries].sort((a, b) => Number(a[0]) - Number(b[0]))
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export const ColorSwatch = ({ name, value, reference }) => {
|
|
43
|
+
const [isHovered, setIsHovered] = useState(false)
|
|
44
|
+
const cssVar = `--${name}`
|
|
45
|
+
const color = isHovered
|
|
46
|
+
? `var(${cssVar}-hovered, var(${cssVar}))`
|
|
47
|
+
: `var(${cssVar})`
|
|
48
|
+
const displayValue = reference || value
|
|
49
|
+
const isReferenced = Boolean(reference)
|
|
50
|
+
|
|
51
|
+
return (
|
|
52
|
+
<VStack spacing={6} style={{ width: 160 }}>
|
|
53
|
+
<div
|
|
54
|
+
style={{
|
|
55
|
+
width: '100%',
|
|
56
|
+
height: 24,
|
|
57
|
+
borderRadius: 6,
|
|
58
|
+
backgroundColor: color,
|
|
59
|
+
border: '1px solid var(--color-border-neutral, #e5e5e5)',
|
|
60
|
+
}}
|
|
61
|
+
onMouseEnter={() => {
|
|
62
|
+
setIsHovered(true)
|
|
63
|
+
}}
|
|
64
|
+
onMouseLeave={() => {
|
|
65
|
+
setIsHovered(false)
|
|
66
|
+
}}
|
|
67
|
+
/>
|
|
68
|
+
<div style={{ fontSize: 11, color: 'var(--color-text-neutral, #1a1a1a)' }}>
|
|
69
|
+
{name}
|
|
70
|
+
</div>
|
|
71
|
+
<div
|
|
72
|
+
style={{
|
|
73
|
+
display: 'flex',
|
|
74
|
+
alignItems: 'center',
|
|
75
|
+
gap: 4,
|
|
76
|
+
fontSize: 10,
|
|
77
|
+
color: 'var(--color-text-neutral-light, #666)',
|
|
78
|
+
}}
|
|
79
|
+
>
|
|
80
|
+
{isReferenced ? 'var' : ''}
|
|
81
|
+
<span
|
|
82
|
+
style={{
|
|
83
|
+
display: 'inline-flex',
|
|
84
|
+
fontSize: 'inherit',
|
|
85
|
+
lineHeight: 'inherit',
|
|
86
|
+
padding: '1px 2px',
|
|
87
|
+
backgroundColor: 'var(--color-fill-neutral-light, #f2f2f2)',
|
|
88
|
+
borderRadius: 3,
|
|
89
|
+
border: '1px solid var(--color-border-neutral, #e5e5e5)',
|
|
90
|
+
}}
|
|
91
|
+
>
|
|
92
|
+
{displayValue}
|
|
93
|
+
</span>
|
|
94
|
+
</div>
|
|
95
|
+
</VStack>
|
|
96
|
+
)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export const TokenGroup = ({
|
|
100
|
+
title,
|
|
101
|
+
data,
|
|
102
|
+
path,
|
|
103
|
+
source,
|
|
104
|
+
depth,
|
|
105
|
+
columns,
|
|
106
|
+
}) => {
|
|
107
|
+
const entries = Object.entries(data)
|
|
108
|
+
const leafEntries = sortNumericLeafEntries(
|
|
109
|
+
entries.filter(([, value]) => isTokenLeaf(value))
|
|
110
|
+
)
|
|
111
|
+
const groupEntries = entries.filter(([, value]) => !isTokenLeaf(value))
|
|
112
|
+
const headingSize = depth === 0 ? 20 : depth === 1 ? 16 : 14
|
|
113
|
+
|
|
114
|
+
return (
|
|
115
|
+
<VStack spacing={10} style={{ marginTop: depth === 0 ? 8 : 16 }}>
|
|
116
|
+
<div
|
|
117
|
+
style={{
|
|
118
|
+
fontSize: headingSize,
|
|
119
|
+
fontWeight: 600,
|
|
120
|
+
color: 'var(--color-text-neutral, #1a1a1a)',
|
|
121
|
+
}}
|
|
122
|
+
>
|
|
123
|
+
{formatTitle(title)}
|
|
124
|
+
</div>
|
|
125
|
+
{leafEntries.length > 0 && (
|
|
126
|
+
<div
|
|
127
|
+
style={
|
|
128
|
+
columns
|
|
129
|
+
? {
|
|
130
|
+
display: 'grid',
|
|
131
|
+
gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))`,
|
|
132
|
+
gap: 12,
|
|
133
|
+
}
|
|
134
|
+
: { display: 'flex', flexWrap: 'wrap', gap: 12 }
|
|
135
|
+
}
|
|
136
|
+
>
|
|
137
|
+
{leafEntries.map(([key, value]) => {
|
|
138
|
+
const tokenName = getTokenName([...path, key])
|
|
139
|
+
const token =
|
|
140
|
+
source[tokenName] ||
|
|
141
|
+
source[`${tokenName}-normal`] ||
|
|
142
|
+
{}
|
|
143
|
+
|
|
144
|
+
return (
|
|
145
|
+
<ColorSwatch
|
|
146
|
+
key={tokenName}
|
|
147
|
+
name={tokenName}
|
|
148
|
+
value={token.value || value.value}
|
|
149
|
+
reference={token.ref}
|
|
150
|
+
/>
|
|
151
|
+
)
|
|
152
|
+
})}
|
|
153
|
+
</div>
|
|
154
|
+
)}
|
|
155
|
+
{groupEntries.map(([key, value]) => (
|
|
156
|
+
<TokenGroup
|
|
157
|
+
key={key}
|
|
158
|
+
title={key}
|
|
159
|
+
data={value}
|
|
160
|
+
path={[...path, key]}
|
|
161
|
+
source={source}
|
|
162
|
+
depth={depth + 1}
|
|
163
|
+
columns={columns}
|
|
164
|
+
/>
|
|
165
|
+
))}
|
|
166
|
+
</VStack>
|
|
167
|
+
)
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export const GlobalSection = () => (
|
|
171
|
+
<VStack spacing={16}>
|
|
172
|
+
<div style={{ fontSize: 24, fontWeight: 700 }}>Global</div>
|
|
173
|
+
{Object.entries(globalColor.color).map(([key, value]) => (
|
|
174
|
+
<TokenGroup
|
|
175
|
+
key={key}
|
|
176
|
+
title={key}
|
|
177
|
+
data={value}
|
|
178
|
+
path={[key]}
|
|
179
|
+
source={tokens.global.color}
|
|
180
|
+
depth={0}
|
|
181
|
+
columns={6}
|
|
182
|
+
/>
|
|
183
|
+
))}
|
|
184
|
+
</VStack>
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
export const SemanticSection = ({
|
|
188
|
+
title,
|
|
189
|
+
colorData,
|
|
190
|
+
source,
|
|
191
|
+
titleColor,
|
|
192
|
+
columns,
|
|
193
|
+
}) => (
|
|
194
|
+
<VStack spacing={16} style={{ flex: 1 }}>
|
|
195
|
+
<div
|
|
196
|
+
style={{
|
|
197
|
+
fontSize: 24,
|
|
198
|
+
fontWeight: 700,
|
|
199
|
+
color: titleColor || 'var(--color-text-neutral, #1a1a1a)',
|
|
200
|
+
}}
|
|
201
|
+
>
|
|
202
|
+
{title}
|
|
203
|
+
</div>
|
|
204
|
+
{Object.entries(colorData.color).map(([key, value]) => (
|
|
205
|
+
<TokenGroup
|
|
206
|
+
key={key}
|
|
207
|
+
title={key}
|
|
208
|
+
data={value}
|
|
209
|
+
path={[key]}
|
|
210
|
+
source={source}
|
|
211
|
+
depth={0}
|
|
212
|
+
columns={columns}
|
|
213
|
+
/>
|
|
214
|
+
))}
|
|
215
|
+
</VStack>
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
export const Primary = () => (
|
|
219
|
+
<VStack spacing={32}>
|
|
220
|
+
<GlobalSection />
|
|
221
|
+
|
|
222
|
+
<HStack spacing={40} align="flex-start">
|
|
223
|
+
<LightThemeProvider>
|
|
224
|
+
<div style={{ flex: 1, padding: 16 }}>
|
|
225
|
+
<SemanticSection
|
|
226
|
+
title="Light"
|
|
227
|
+
colorData={lightThemeColor}
|
|
228
|
+
source={tokens.lightTheme.color}
|
|
229
|
+
columns={1}
|
|
230
|
+
/>
|
|
231
|
+
</div>
|
|
232
|
+
</LightThemeProvider>
|
|
233
|
+
|
|
234
|
+
<DarkThemeProvider>
|
|
235
|
+
<div
|
|
236
|
+
style={{
|
|
237
|
+
flex: 1,
|
|
238
|
+
padding: 16,
|
|
239
|
+
backgroundColor: 'var(--color-surface, #1d1d20)',
|
|
240
|
+
borderRadius: 12,
|
|
241
|
+
}}
|
|
242
|
+
>
|
|
243
|
+
<SemanticSection
|
|
244
|
+
title="Dark"
|
|
245
|
+
titleColor="var(--color-text-neutral, #ffffcc)"
|
|
246
|
+
colorData={darkThemeColor}
|
|
247
|
+
source={tokens.darkTheme.color}
|
|
248
|
+
columns={1}
|
|
249
|
+
/>
|
|
250
|
+
</div>
|
|
251
|
+
</DarkThemeProvider>
|
|
252
|
+
</HStack>
|
|
253
|
+
</VStack>
|
|
254
|
+
)
|
|
255
|
+
|
|
256
|
+
# Color
|
|
257
|
+
|
|
258
|
+
<Primary />
|
|
259
|
+
|