@sanity/ui 2.0.0-alpha.2 → 2.0.0-alpha.21

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.
Files changed (96) hide show
  1. package/dist/index.cjs.mjs +28 -0
  2. package/dist/index.d.ts +476 -12
  3. package/dist/index.esm.js +1326 -524
  4. package/dist/index.esm.js.map +1 -1
  5. package/dist/index.js +1353 -523
  6. package/dist/index.js.map +1 -1
  7. package/package.json +6 -8
  8. package/src/components/autocomplete/autocomplete.tsx +6 -0
  9. package/src/components/dialog/constants.ts +4 -0
  10. package/src/components/dialog/dialog.tsx +79 -15
  11. package/src/components/hotkeys/hotkeys.tsx +2 -0
  12. package/src/components/menu/menu.tsx +2 -0
  13. package/src/components/menu/menuButton.tsx +2 -0
  14. package/src/components/menu/menuGroup.tsx +22 -23
  15. package/src/components/menu/menuItem.tsx +29 -35
  16. package/src/components/tab/tab.tsx +4 -1
  17. package/src/components/toast/toast.tsx +4 -0
  18. package/src/primitives/_selectable/style.ts +2 -1
  19. package/src/primitives/avatar/avatar.tsx +16 -9
  20. package/src/primitives/avatar/avatarCounter.tsx +3 -3
  21. package/src/primitives/avatar/styles.ts +1 -1
  22. package/src/primitives/badge/badge.tsx +7 -3
  23. package/src/primitives/box/box.tsx +3 -0
  24. package/src/primitives/button/__workshop__/sanityUploadButton.tsx +2 -1
  25. package/src/primitives/button/button.tsx +7 -3
  26. package/src/primitives/button/styles.ts +9 -2
  27. package/src/primitives/card/card.tsx +4 -0
  28. package/src/primitives/card/styles.ts +2 -0
  29. package/src/primitives/checkbox/checkbox.tsx +2 -0
  30. package/src/primitives/code/code.tsx +1 -0
  31. package/src/primitives/container/container.tsx +2 -0
  32. package/src/primitives/flex/flex.tsx +2 -0
  33. package/src/primitives/grid/grid.tsx +2 -0
  34. package/src/primitives/heading/heading.tsx +2 -0
  35. package/src/primitives/inline/inline.tsx +3 -0
  36. package/src/primitives/kbd/kbd.tsx +2 -0
  37. package/src/primitives/label/label.tsx +2 -0
  38. package/src/primitives/popover/popover.tsx +6 -1
  39. package/src/primitives/radio/radio.tsx +2 -0
  40. package/src/primitives/select/select.tsx +2 -0
  41. package/src/primitives/select/styles.ts +2 -0
  42. package/src/primitives/spinner/spinner.tsx +2 -0
  43. package/src/primitives/stack/stack.tsx +2 -0
  44. package/src/primitives/switch/switch.tsx +4 -0
  45. package/src/primitives/text/text.tsx +3 -0
  46. package/src/primitives/textArea/textArea.tsx +4 -1
  47. package/src/primitives/textInput/textInput.tsx +10 -1
  48. package/src/primitives/tooltip/__workshop__/customPortal.tsx +99 -0
  49. package/src/primitives/tooltip/__workshop__/index.ts +15 -0
  50. package/src/primitives/tooltip/__workshop__/overflowingBoundary.tsx +73 -0
  51. package/src/primitives/tooltip/__workshop__/resizableBoundary.tsx +85 -0
  52. package/src/primitives/tooltip/constants.ts +1 -0
  53. package/src/primitives/tooltip/tooltip.test.tsx +192 -0
  54. package/src/primitives/tooltip/tooltip.tsx +109 -33
  55. package/src/primitives/types.ts +4 -0
  56. package/src/styles/input/textInputStyle.ts +11 -6
  57. package/src/theme/_internal/__workshop__/build/story.tsx +288 -0
  58. package/src/theme/_internal/__workshop__/build/theme.ts +3 -0
  59. package/src/theme/_internal/__workshop__/index.ts +14 -0
  60. package/src/theme/_internal/build/buildTheme.test.ts +78 -0
  61. package/src/theme/_internal/build/buildTheme.ts +16 -0
  62. package/src/theme/_internal/build/colorTheme/buildColorTheme.test.ts +185 -0
  63. package/src/theme/_internal/build/colorTheme/buildColorTheme.ts +164 -0
  64. package/src/theme/_internal/build/colorTheme/renderColorTheme.ts +242 -0
  65. package/src/theme/_internal/build/colorTheme/resolveColorTokens.ts +121 -0
  66. package/src/theme/_internal/build/defaults/colorPalette.ts +8 -0
  67. package/src/theme/_internal/build/defaults/colorTokens.ts +147 -0
  68. package/src/theme/_internal/build/helpers.ts +65 -0
  69. package/src/theme/_internal/build/index.ts +1 -0
  70. package/src/theme/_internal/config/helpers.ts +47 -0
  71. package/src/theme/_internal/config/index.ts +3 -0
  72. package/src/theme/_internal/config/token/index.ts +2 -0
  73. package/src/theme/_internal/config/token/parseTokenKey.test.ts +72 -0
  74. package/src/theme/_internal/config/token/parseTokenKey.ts +88 -0
  75. package/src/theme/_internal/config/token/parseTokenValue.test.ts +45 -0
  76. package/src/theme/_internal/config/token/parseTokenValue.ts +123 -0
  77. package/src/theme/_internal/config/types.ts +137 -0
  78. package/src/theme/_internal/constants.ts +48 -0
  79. package/src/theme/_internal/helpers.ts +19 -0
  80. package/src/theme/_internal/index.ts +5 -0
  81. package/src/theme/_internal/types.ts +91 -0
  82. package/src/theme/index.ts +1 -0
  83. package/src/theme/lib/color-fns/blend/multiply.ts +2 -2
  84. package/src/theme/lib/color-fns/blend/screen.ts +2 -2
  85. package/src/theme/lib/color-fns/convert.ts +15 -1
  86. package/src/theme/lib/color-fns/parse.ts +7 -3
  87. package/src/theme/lib/color-fns/types.ts +11 -0
  88. package/src/theme/lib/theme/avatar.ts +2 -0
  89. package/src/theme/lib/theme/color/_legacy/createColorTheme.ts +7 -0
  90. package/src/theme/lib/theme/color/_legacy/index.ts +1 -0
  91. package/src/theme/lib/theme/color/_legacy/legacyColor.ts +3997 -0
  92. package/src/theme/studioTheme/color.ts +98 -82
  93. package/src/theme/studioTheme/helpers.ts +15 -1
  94. package/src/theme/studioTheme/theme.ts +5 -5
  95. package/src/theme/studioTheme/tints.ts +244 -84
  96. package/src/types/button.ts +5 -0
@@ -0,0 +1,164 @@
1
+ import {ThemeConfig} from '../../config'
2
+ import {COLOR_BUTTON_MODES, COLOR_STATE_TONES, COLOR_STATES} from '../../constants'
3
+ import {
4
+ ColorBaseTone,
5
+ ColorButtonMode,
6
+ ColorState,
7
+ ColorStateTone,
8
+ TMP_BaseColorTheme,
9
+ TMP_ButtonColorTheme,
10
+ TMP_ButtonModesColorTheme,
11
+ TMP_ButtonStatesColorTheme,
12
+ TMP_ColorTheme,
13
+ TMP_StateColorTheme,
14
+ } from '../../types'
15
+ import {defaultColorTokens} from '../defaults/colorTokens'
16
+ import {ColorTokenContext, resolveColorTokenValue as _color} from '../helpers'
17
+ import {resolveColorTokens} from './resolveColorTokens'
18
+
19
+ export function buildColorTheme(
20
+ options: {scheme: 'light' | 'dark'},
21
+ config?: ThemeConfig,
22
+ ): TMP_ColorTheme {
23
+ const {scheme} = options
24
+
25
+ const resolvedConfig = {
26
+ ...config,
27
+ color: {
28
+ ...config?.color,
29
+ tokens: resolveColorTokens(config?.color?.tokens ?? defaultColorTokens),
30
+ },
31
+ }
32
+
33
+ return {
34
+ transparent: buildBaseColorTheme({scheme, tone: 'transparent'}, resolvedConfig),
35
+ default: buildBaseColorTheme({scheme, tone: 'default'}, resolvedConfig),
36
+ primary: buildBaseColorTheme({scheme, tone: 'primary'}, resolvedConfig),
37
+ positive: buildBaseColorTheme({scheme, tone: 'positive'}, resolvedConfig),
38
+ caution: buildBaseColorTheme({scheme, tone: 'caution'}, resolvedConfig),
39
+ critical: buildBaseColorTheme({scheme, tone: 'critical'}, resolvedConfig),
40
+ }
41
+ }
42
+
43
+ export function buildBaseColorTheme(
44
+ options: {scheme: 'light' | 'dark'; tone: ColorBaseTone},
45
+ config?: ThemeConfig,
46
+ ): TMP_BaseColorTheme {
47
+ const {scheme, tone} = options
48
+ const tokens = config?.color?.tokens?.[tone]
49
+ const hue = tokens?._hue || 'gray'
50
+ const context: ColorTokenContext = {hue, scheme}
51
+ const bg = _color(context, tokens?.bg || ['gray/50', 'black'])
52
+ const blendMode = tokens?._blend || ['screen', 'multiply']
53
+
54
+ return {
55
+ _blend: blendMode[scheme === 'light' ? 0 : 1],
56
+ dark: scheme === 'dark',
57
+ base: {
58
+ bg,
59
+ fg: _color(context, tokens?.fg || ['black', 'white']),
60
+ border: _color(context, tokens?.border || ['black', 'white']),
61
+ focusRing: _color(context, tokens?.focusRing || ['black', 'white']),
62
+ shadow: {
63
+ outline: _color(context, tokens?.shadow?.outline || ['500/0.2', '500/0.2']),
64
+ umbra: _color(context, tokens?.shadow?.umbra || ['500/0.2', '500/0.2']),
65
+ penumbra: _color(context, tokens?.shadow?.penumbra || ['500/0.2', '500/0.2']),
66
+ ambient: _color(context, tokens?.shadow?.ambient || ['500/0.2', '500/0.2']),
67
+ },
68
+ skeleton: {
69
+ from: _color(context, tokens?.skeleton?.from || ['500/0.2', '500/0.2']),
70
+ to: _color(context, tokens?.skeleton?.to || ['500/0.2', '500/0.2']),
71
+ },
72
+ },
73
+ button: buildButtonColorTheme({scheme}, config),
74
+ }
75
+ }
76
+
77
+ function buildButtonColorTheme(
78
+ options: {scheme: 'light' | 'dark'},
79
+ config?: ThemeConfig,
80
+ ): TMP_ButtonColorTheme {
81
+ const {scheme} = options
82
+
83
+ const tones = COLOR_STATE_TONES.map((tone): Partial<TMP_ButtonColorTheme> => {
84
+ return {
85
+ [tone]: buildButtonColorToneTheme({scheme, tone}, config),
86
+ }
87
+ })
88
+
89
+ return Object.assign({}, ...tones) as TMP_ButtonColorTheme
90
+ }
91
+
92
+ function buildButtonColorToneTheme(
93
+ options: {
94
+ scheme: 'light' | 'dark'
95
+ tone: ColorStateTone
96
+ },
97
+ config?: ThemeConfig,
98
+ ): TMP_ButtonModesColorTheme {
99
+ const {scheme, tone} = options
100
+
101
+ const modes = COLOR_BUTTON_MODES.map((mode): Partial<TMP_ButtonModesColorTheme> => {
102
+ return {
103
+ [mode]: buildButtonModeColorTheme({mode, scheme, tone}, config),
104
+ }
105
+ })
106
+
107
+ return Object.assign({}, ...modes) as TMP_ButtonModesColorTheme
108
+ }
109
+
110
+ function buildButtonModeColorTheme(
111
+ options: {
112
+ mode: ColorButtonMode
113
+ scheme: 'light' | 'dark'
114
+ tone: ColorStateTone
115
+ },
116
+ config?: ThemeConfig,
117
+ ): TMP_ButtonStatesColorTheme {
118
+ const {mode, scheme, tone} = options
119
+
120
+ const states = COLOR_STATES.map((state): Partial<TMP_ButtonStatesColorTheme> => {
121
+ return {
122
+ [state]: buildButtonStateColorTheme({mode, tone, scheme, state}, config),
123
+ }
124
+ })
125
+
126
+ return Object.assign({}, ...states) as TMP_ButtonStatesColorTheme
127
+ }
128
+
129
+ function buildButtonStateColorTheme(
130
+ options: {
131
+ mode: ColorButtonMode
132
+ tone: ColorStateTone
133
+ scheme: 'light' | 'dark'
134
+ state: ColorState
135
+ },
136
+ config?: ThemeConfig,
137
+ ): TMP_StateColorTheme {
138
+ const {mode, tone, scheme, state} = options
139
+ const tokens = config?.color?.tokens?.button?.[tone]?.[mode]?.[state]
140
+ const hue = tokens?._hue || 'gray'
141
+ const blendMode = tokens?._blend || ['screen', 'multiply']
142
+ const context: ColorTokenContext = {hue, scheme}
143
+
144
+ return {
145
+ _blend: blendMode[scheme === 'light' ? 0 : 1],
146
+ bg: _color(context, tokens?.bg || ['500', '400']),
147
+ bg2: _color(context, tokens?.bg2 || ['500', '400']),
148
+ fg: _color(context, tokens?.fg || ['white', 'black']),
149
+ border: _color(context, tokens?.border || ['500', '400']),
150
+ muted: {
151
+ fg: _color(context, tokens?.fg || ['500', '400']),
152
+ },
153
+ accent: {
154
+ fg: _color(context, tokens?.fg || ['500', '400']),
155
+ },
156
+ link: {
157
+ fg: _color(context, tokens?.fg || ['500', '400']),
158
+ },
159
+ code: {
160
+ bg: _color(context, tokens?.bg || ['500', '400']),
161
+ fg: _color(context, tokens?.fg || ['500', '400']),
162
+ },
163
+ }
164
+ }
@@ -0,0 +1,242 @@
1
+ import {ColorTint as ColorPaletteValue} from '@sanity/color'
2
+ import {rgba} from '../../../lib/color-fns'
3
+ import {ColorBlendModeValue, parseTokenValue, ThemeConfig, TMP_ColorPalette} from '../../config'
4
+ import {
5
+ TMP_BaseColorTheme,
6
+ TMP_ButtonColorTheme,
7
+ TMP_ButtonModesColorTheme,
8
+ TMP_ButtonStatesColorTheme,
9
+ TMP_ColorTheme,
10
+ TMP_StateColorTheme,
11
+ TMP_Theme,
12
+ } from '../../types'
13
+ import {defaultColorPalette} from '../defaults/colorPalette'
14
+ import {multiply, screen} from '../helpers'
15
+
16
+ export function renderColorTheme(
17
+ value: TMP_Theme['color'],
18
+ config?: ThemeConfig,
19
+ ): TMP_Theme['color'] {
20
+ const colorPalette = config?.color?.palette ?? defaultColorPalette
21
+
22
+ return {
23
+ light: renderColorScheme(colorPalette, value.light),
24
+ dark: renderColorScheme(colorPalette, value.dark),
25
+ }
26
+ }
27
+
28
+ function renderColorScheme(colorPalette: TMP_ColorPalette, value: TMP_ColorTheme): TMP_ColorTheme {
29
+ const toneEntries = Object.entries(value)
30
+ const [, transparentTone] = toneEntries.find(([k]) => k === 'transparent')!
31
+ const [, defaultTone] = toneEntries.find(([k]) => k === 'default')!
32
+
33
+ const renderedTransparentTone = renderColorBase(
34
+ colorPalette,
35
+ transparentTone,
36
+ transparentTone._blend === 'multiply' ? '#ffffff' : '#000000',
37
+ )
38
+
39
+ const renderedDefaultTone = renderColorBase(
40
+ colorPalette,
41
+ defaultTone,
42
+ defaultTone._blend === 'multiply' ? '#ffffff' : '#000000',
43
+ )
44
+
45
+ return Object.fromEntries([
46
+ ['transparent', renderedTransparentTone],
47
+ ['default', renderedDefaultTone],
48
+ ...toneEntries
49
+ .filter(([k]) => k !== 'default' && k !== 'transparent')
50
+ .map(([k, v]) => [k, renderColorBase(colorPalette, v, renderedDefaultTone.base.bg)]),
51
+ ]) as TMP_ColorTheme
52
+ }
53
+
54
+ function renderColorBase(
55
+ colorPalette: TMP_ColorPalette,
56
+ value: TMP_BaseColorTheme,
57
+ bg: string,
58
+ ): TMP_BaseColorTheme {
59
+ const nestedBg = renderColorValue(colorPalette, bg, value._blend, value.base.bg)
60
+
61
+ return {
62
+ _blend: value._blend,
63
+ dark: value.dark,
64
+ base: {
65
+ bg: nestedBg,
66
+ fg: renderColorValue(colorPalette, nestedBg, value._blend, value.base.fg),
67
+ border: renderColorValue(colorPalette, nestedBg, value._blend, value.base.border),
68
+ focusRing: renderColorValue(colorPalette, nestedBg, value._blend, value.base.focusRing),
69
+ shadow: {
70
+ outline: renderColorValue(colorPalette, nestedBg, value._blend, value.base.shadow.outline),
71
+ umbra: renderColorValue(colorPalette, nestedBg, value._blend, value.base.shadow.umbra),
72
+ penumbra: renderColorValue(
73
+ colorPalette,
74
+ nestedBg,
75
+ value._blend,
76
+ value.base.shadow.penumbra,
77
+ ),
78
+ ambient: renderColorValue(colorPalette, nestedBg, value._blend, value.base.shadow.ambient),
79
+ },
80
+ skeleton: {
81
+ from: renderColorValue(colorPalette, nestedBg, value._blend, value.base.skeleton.from),
82
+ to: renderColorValue(colorPalette, nestedBg, value._blend, value.base.skeleton.to),
83
+ },
84
+ },
85
+ button: renderButtonColorTheme(colorPalette, nestedBg, value._blend, value.button),
86
+ }
87
+ }
88
+
89
+ function renderButtonColorTheme(
90
+ colorPalette: TMP_ColorPalette,
91
+ bg: string,
92
+ baseBlendMode: ColorBlendModeValue,
93
+ value: TMP_ButtonColorTheme,
94
+ ): TMP_ButtonColorTheme {
95
+ return {
96
+ default: renderButtonStateColorTheme(colorPalette, bg, baseBlendMode, value.default),
97
+ primary: renderButtonStateColorTheme(colorPalette, bg, baseBlendMode, value.primary),
98
+ positive: renderButtonStateColorTheme(colorPalette, bg, baseBlendMode, value.positive),
99
+ caution: renderButtonStateColorTheme(colorPalette, bg, baseBlendMode, value.caution),
100
+ critical: renderButtonStateColorTheme(colorPalette, bg, baseBlendMode, value.critical),
101
+ }
102
+ }
103
+
104
+ function renderButtonStateColorTheme(
105
+ colorPalette: TMP_ColorPalette,
106
+ bg: string,
107
+ baseBlendMode: ColorBlendModeValue,
108
+ value: TMP_ButtonModesColorTheme,
109
+ ): TMP_ButtonModesColorTheme {
110
+ return {
111
+ default: renderStatesColorTheme(colorPalette, bg, baseBlendMode, value.default),
112
+ ghost: renderStatesColorTheme(colorPalette, bg, baseBlendMode, value.ghost),
113
+ bleed: renderStatesColorTheme(colorPalette, bg, baseBlendMode, value.bleed),
114
+ }
115
+ }
116
+
117
+ function renderStatesColorTheme(
118
+ colorPalette: TMP_ColorPalette,
119
+ bg: string,
120
+ baseBlendMode: ColorBlendModeValue,
121
+ value: TMP_ButtonStatesColorTheme,
122
+ ) {
123
+ return {
124
+ enabled: renderStateColorTheme(colorPalette, bg, baseBlendMode, value.enabled),
125
+ hovered: renderStateColorTheme(colorPalette, bg, baseBlendMode, value.hovered),
126
+ pressed: renderStateColorTheme(colorPalette, bg, baseBlendMode, value.pressed),
127
+ selected: renderStateColorTheme(colorPalette, bg, baseBlendMode, value.selected),
128
+ disabled: renderStateColorTheme(colorPalette, bg, baseBlendMode, value.disabled),
129
+ }
130
+ }
131
+
132
+ function renderStateColorTheme(
133
+ colorPalette: TMP_ColorPalette,
134
+ baseBg: string,
135
+ rootBlendMode: ColorBlendModeValue,
136
+ value: TMP_StateColorTheme,
137
+ ): TMP_StateColorTheme {
138
+ const blendMode = value._blend
139
+
140
+ const bg =
141
+ rootBlendMode === 'multiply' && value.bg === 'white'
142
+ ? '#ffffff'
143
+ : rootBlendMode === 'screen' && value.bg === 'black'
144
+ ? '#000000'
145
+ : renderColorValue(
146
+ colorPalette,
147
+ rootBlendMode === 'multiply' ? '#ffffff' : '#000000',
148
+ rootBlendMode,
149
+ value.bg,
150
+ )
151
+
152
+ const blend = rootBlendMode === 'multiply' ? multiply : screen
153
+
154
+ const unmixed = {
155
+ bg2: renderColorValue(colorPalette, bg, blendMode, value.bg2 || value.bg),
156
+ fg: renderColorValue(colorPalette, bg, blendMode, value.fg),
157
+ border: renderColorValue(colorPalette, bg, blendMode, value.border),
158
+ muted: {
159
+ fg: renderColorValue(colorPalette, bg, blendMode, value.muted.fg),
160
+ },
161
+ accent: {
162
+ fg: renderColorValue(colorPalette, bg, blendMode, value.accent.fg),
163
+ },
164
+ link: {
165
+ fg: renderColorValue(colorPalette, bg, blendMode, value.link.fg),
166
+ },
167
+ code: {
168
+ bg: renderColorValue(colorPalette, bg, blendMode, value.code.bg),
169
+ fg: renderColorValue(colorPalette, bg, blendMode, value.code.fg),
170
+ },
171
+ }
172
+
173
+ return {
174
+ _blend: blendMode,
175
+ bg: blend(baseBg, bg),
176
+ bg2: blend(baseBg, unmixed.bg2),
177
+ fg: blend(baseBg, unmixed.fg),
178
+ border: blend(baseBg, unmixed.border),
179
+ muted: {
180
+ fg: blend(baseBg, unmixed.muted.fg),
181
+ },
182
+ accent: {
183
+ fg: blend(baseBg, unmixed.accent.fg),
184
+ },
185
+ link: {
186
+ fg: blend(baseBg, unmixed.link.fg),
187
+ },
188
+ code: {
189
+ bg: blend(baseBg, unmixed.code.bg),
190
+ fg: blend(baseBg, unmixed.code.fg),
191
+ },
192
+ }
193
+ }
194
+
195
+ function renderColorValue(
196
+ colorPalette: TMP_ColorPalette,
197
+ bg: string,
198
+ blendMode: ColorBlendModeValue,
199
+ str: string,
200
+ ): string {
201
+ const node = parseTokenValue(str)
202
+
203
+ if (!node || node.type !== 'color') {
204
+ throw new Error(`Invalid color token value: ${str}`)
205
+ }
206
+
207
+ let hex = ''
208
+
209
+ if (node.key === 'black') {
210
+ hex = renderColorHex(colorPalette.black)
211
+ }
212
+
213
+ if (node.key === 'white') {
214
+ hex = renderColorHex(colorPalette.white)
215
+ }
216
+
217
+ if (node.hue && node.tint) {
218
+ hex = renderColorHex(colorPalette[node.hue][node.tint])
219
+ }
220
+
221
+ if (!hex) {
222
+ throw new Error(`Invalid color token value: ${str}`)
223
+ }
224
+
225
+ // apply blend mode
226
+ try {
227
+ hex = blendMode === 'multiply' ? multiply(bg, hex) : screen(bg, hex)
228
+ } catch (err) {
229
+ // eslint-disable-next-line no-console
230
+ console.log('could not blend', hex)
231
+ }
232
+
233
+ if (node.opacity !== undefined) {
234
+ hex = rgba(hex, node.opacity)
235
+ }
236
+
237
+ return hex
238
+ }
239
+
240
+ function renderColorHex(color: string | ColorPaletteValue) {
241
+ return typeof color === 'string' ? color : color.hex
242
+ }
@@ -0,0 +1,121 @@
1
+ import {
2
+ BaseColorTokens,
3
+ ButtonColorTokens,
4
+ ButtonModeColorTokens,
5
+ ColorConfigStateTone,
6
+ ColorTokens,
7
+ StateColorTokens,
8
+ } from '../../config'
9
+ import {
10
+ COLOR_BASE_TONES,
11
+ COLOR_BUTTON_MODES,
12
+ COLOR_STATES,
13
+ COLOR_STATE_TONES,
14
+ } from '../../constants'
15
+ import {ColorBaseTone, ColorButtonMode, ColorState, ColorStateTone} from '../../types'
16
+
17
+ /**
18
+ * Convert a tree of color tokens from a sparse format to a dense format.
19
+ */
20
+ export function resolveColorTokens(sparseTokens: ColorTokens): ColorTokens {
21
+ const denseTokens: ColorTokens = {...sparseTokens}
22
+
23
+ // base tones
24
+ for (const tone of COLOR_BASE_TONES) {
25
+ denseTokens[tone] = resolveBaseColorTones(sparseTokens, tone)
26
+ }
27
+
28
+ // button
29
+ denseTokens.button = resolveButtonColorTokens(sparseTokens)
30
+
31
+ return denseTokens
32
+ }
33
+
34
+ function resolveBaseColorTones(sparseTokens: ColorTokens, tone: ColorBaseTone): BaseColorTokens {
35
+ const spec0 = sparseTokens?.[tone]
36
+ const spec1 = sparseTokens?.['*']
37
+
38
+ return {
39
+ ...spec1,
40
+ ...spec0,
41
+ shadow: {...spec1?.shadow, ...spec0?.shadow},
42
+ skeleton: {...spec1?.skeleton, ...spec0?.skeleton},
43
+ }
44
+ }
45
+
46
+ function resolveButtonColorTokens(
47
+ sparseTokens: ColorTokens,
48
+ ): Partial<Record<ColorConfigStateTone, ButtonColorTokens>> {
49
+ const tokens: Partial<Record<ColorConfigStateTone, ButtonColorTokens>> = {}
50
+
51
+ for (const tone of COLOR_STATE_TONES) {
52
+ tokens[tone] = resolveButtonToneColorTokens(sparseTokens, tone)
53
+ }
54
+
55
+ return tokens
56
+ }
57
+
58
+ function resolveButtonToneColorTokens(
59
+ sparseTokens: ColorTokens,
60
+ tone: ColorStateTone,
61
+ ): ButtonColorTokens {
62
+ const tokens: ButtonColorTokens = {
63
+ ...sparseTokens.button?.[tone],
64
+ ...sparseTokens.button?.['*'],
65
+ }
66
+
67
+ for (const mode of COLOR_BUTTON_MODES) {
68
+ tokens[mode] = resolveButtonModeColorTokens(sparseTokens, tone, mode)
69
+ }
70
+
71
+ return tokens
72
+ }
73
+
74
+ function resolveButtonModeColorTokens(
75
+ sparseTokens: ColorTokens,
76
+ tone: ColorStateTone,
77
+ mode: ColorButtonMode,
78
+ ): ButtonModeColorTokens {
79
+ const spec0 = sparseTokens.button?.[tone]?.[mode]
80
+ const spec1 = sparseTokens.button?.['*']?.[mode]
81
+ const tokens = {...spec1, ...spec0}
82
+
83
+ for (const state of COLOR_STATES) {
84
+ tokens[state] = resolveButtonStateColorTokens(sparseTokens, tone, mode, state)
85
+ }
86
+
87
+ return tokens
88
+ }
89
+
90
+ function resolveButtonStateColorTokens(
91
+ tokens: ColorTokens,
92
+ tone: ColorStateTone,
93
+ mode: ColorButtonMode,
94
+ state: ColorState,
95
+ ): StateColorTokens {
96
+ const spec0 = tokens?.button?.[tone]?.[mode]?.[state]
97
+ const spec1 = tokens?.button?.[tone]?.[mode]?.['*']
98
+ const spec2 = tokens?.button?.['*']?.[mode]?.[state]
99
+ const spec3 = tokens?.button?.['*']?.[mode]?.['*']
100
+
101
+ const hue =
102
+ spec0?._hue ||
103
+ spec1?._hue ||
104
+ spec2?._hue ||
105
+ spec3?._hue ||
106
+ tokens?.button?.[tone]?._hue ||
107
+ tokens?.[tone]?._hue
108
+
109
+ return {
110
+ ...spec3,
111
+ ...spec2,
112
+ ...spec1,
113
+ ...spec0,
114
+ _hue: hue,
115
+ muted: {...spec3?.muted, ...spec2?.muted, ...spec1?.muted, ...spec0?.muted},
116
+ accent: {...spec3?.accent, ...spec2?.accent, ...spec1?.accent, ...spec0?.accent},
117
+ link: {...spec3?.link, ...spec2?.link, ...spec1?.link, ...spec0?.link},
118
+ code: {...spec3?.code, ...spec2?.code, ...spec1?.code, ...spec0?.code},
119
+ skeleton: {...spec3?.skeleton, ...spec2?.skeleton, ...spec1?.skeleton, ...spec0?.skeleton},
120
+ }
121
+ }
@@ -0,0 +1,8 @@
1
+ import {color} from '@sanity/color'
2
+
3
+ import {TMP_ColorPalette} from '../../config'
4
+
5
+ export const defaultColorPalette: TMP_ColorPalette = {
6
+ ...color,
7
+ black: '#000000',
8
+ }
@@ -0,0 +1,147 @@
1
+ import {ColorTokens} from '../../config'
2
+
3
+ export const defaultColorTokens: ColorTokens = {
4
+ '*': {
5
+ _blend: ['multiply', 'screen'],
6
+ bg: ['50', '950'],
7
+ fg: ['800', '200'],
8
+ border: ['200', '800'],
9
+ focusRing: ['cyan/500', 'cyan/500'],
10
+ shadow: {
11
+ outline: ['500/0.25', '400/0.3'],
12
+ umbra: ['500/0.1', 'black/0.4'],
13
+ penumbra: ['500/0.07', 'black/0.28'],
14
+ ambient: ['500/0.06', 'black/0.24'],
15
+ },
16
+ skeleton: {
17
+ from: ['100', '900'],
18
+ to: ['100/0.5', '900/0.5'],
19
+ },
20
+ },
21
+ transparent: {
22
+ bg: ['50', 'black'],
23
+ fg: ['600', '400'],
24
+ },
25
+ default: {
26
+ bg: ['white', '950'],
27
+ fg: ['black', '200'],
28
+ },
29
+ primary: {
30
+ _hue: 'cyan',
31
+ },
32
+ positive: {
33
+ _hue: 'cyan',
34
+ },
35
+ caution: {
36
+ _hue: 'yellow',
37
+ },
38
+ critical: {
39
+ _hue: 'red',
40
+ },
41
+ button: {
42
+ '*': {
43
+ default: {
44
+ '*': {
45
+ _blend: ['screen', 'multiply'],
46
+ bg: ['500', '400'],
47
+ bg2: ['950', '50'],
48
+ border: ['500/0', '400/0'],
49
+ muted: {
50
+ fg: ['200', '700'],
51
+ },
52
+ },
53
+ hovered: {
54
+ bg: ['600', '300'],
55
+ border: ['600/0', '300/0'],
56
+ },
57
+ pressed: {
58
+ bg: ['700', '200'],
59
+ },
60
+ selected: {
61
+ bg: ['700', '200'],
62
+ },
63
+ disabled: {
64
+ _hue: 'gray',
65
+ bg: ['200', '900'],
66
+ },
67
+ },
68
+ ghost: {
69
+ '*': {
70
+ _blend: ['multiply', 'screen'],
71
+ bg: ['white', 'black'],
72
+ bg2: ['50', '950'],
73
+ fg: ['600', '400'],
74
+ border: ['200', '800'],
75
+ muted: {
76
+ fg: ['600/0.6', '400/0.6'],
77
+ },
78
+ },
79
+ hovered: {
80
+ bg: ['50', '950'],
81
+ fg: ['700', '300'],
82
+ },
83
+ pressed: {
84
+ bg: ['100', '900'],
85
+ fg: ['800', '200'],
86
+ },
87
+ selected: {
88
+ bg: ['100', '900'],
89
+ fg: ['800', '200'],
90
+ },
91
+ disabled: {
92
+ _hue: 'gray',
93
+ fg: ['200', '900'],
94
+ border: ['100', '950'],
95
+ },
96
+ },
97
+ bleed: {
98
+ '*': {
99
+ _blend: ['multiply', 'screen'],
100
+ bg: ['white', 'black'],
101
+ bg2: ['50', '950'],
102
+ fg: ['600', '400'],
103
+ border: ['white/0', 'black/0'],
104
+ muted: {
105
+ fg: ['600/0.6', '400/0.6'],
106
+ },
107
+ },
108
+ hovered: {
109
+ bg: ['50', '950'],
110
+ fg: ['700', '300'],
111
+ },
112
+ pressed: {
113
+ bg: ['100', '900'],
114
+ fg: ['800', '200'],
115
+ },
116
+ selected: {
117
+ bg: ['100', '900'],
118
+ fg: ['800', '200'],
119
+ },
120
+ disabled: {
121
+ _hue: 'gray',
122
+ fg: ['200', '900'],
123
+ },
124
+ },
125
+ },
126
+ default: {
127
+ default: {
128
+ '*': {
129
+ bg: ['900', '200'],
130
+ },
131
+ hovered: {
132
+ bg: ['black', '100'],
133
+ },
134
+ pressed: {
135
+ bg: ['900', '200'],
136
+ },
137
+ selected: {
138
+ bg: ['black', '200'],
139
+ },
140
+ disabled: {
141
+ _hue: 'gray',
142
+ bg: ['200', '900'],
143
+ },
144
+ },
145
+ },
146
+ },
147
+ }