@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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@channel.io/bezier-react",
3
- "version": "3.6.4",
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.4.1",
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
+