@sanity/ui 2.0.0-alpha.13 → 2.0.0-alpha.14

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 (32) hide show
  1. package/dist/index.cjs.mjs +27 -0
  2. package/dist/index.d.ts +337 -7
  3. package/dist/index.esm.js +745 -58
  4. package/dist/index.esm.js.map +1 -1
  5. package/dist/index.js +772 -58
  6. package/dist/index.js.map +1 -1
  7. package/package.json +2 -2
  8. package/src/theme/_internal/__workshop__/build/story.tsx +178 -0
  9. package/src/theme/_internal/__workshop__/build/theme.ts +3 -0
  10. package/src/theme/_internal/__workshop__/index.ts +14 -0
  11. package/src/theme/_internal/build/buildTheme.test.ts +78 -0
  12. package/src/theme/_internal/build/buildTheme.ts +15 -0
  13. package/src/theme/_internal/build/colorTheme/buildColorTheme.test.ts +185 -0
  14. package/src/theme/_internal/build/colorTheme/buildColorTheme.ts +222 -0
  15. package/src/theme/_internal/build/colorTheme/renderColorTheme.ts +226 -0
  16. package/src/theme/_internal/build/defaults/colorPalette.ts +8 -0
  17. package/src/theme/_internal/build/defaults/colorTokens.ts +124 -0
  18. package/src/theme/_internal/build/helpers.ts +64 -0
  19. package/src/theme/_internal/build/index.ts +1 -0
  20. package/src/theme/_internal/config/helpers.ts +47 -0
  21. package/src/theme/_internal/config/index.ts +3 -0
  22. package/src/theme/_internal/config/token/index.ts +2 -0
  23. package/src/theme/_internal/config/token/parseTokenKey.test.ts +72 -0
  24. package/src/theme/_internal/config/token/parseTokenKey.ts +88 -0
  25. package/src/theme/_internal/config/token/parseTokenValue.test.ts +45 -0
  26. package/src/theme/_internal/config/token/parseTokenValue.ts +123 -0
  27. package/src/theme/_internal/config/types.ts +126 -0
  28. package/src/theme/_internal/constants.ts +48 -0
  29. package/src/theme/_internal/helpers.ts +19 -0
  30. package/src/theme/_internal/index.ts +5 -0
  31. package/src/theme/_internal/types.ts +72 -0
  32. package/src/theme/index.ts +1 -0
@@ -0,0 +1,72 @@
1
+ import {parseTokenKey} from './parseTokenKey'
2
+
3
+ test('parse token key', () => {
4
+ expect(parseTokenKey('*/_blend')).toEqual({
5
+ type: 'base',
6
+ tone: '*',
7
+ key: '_blend',
8
+ })
9
+
10
+ expect(parseTokenKey('*/_hue')).toEqual({
11
+ type: 'base',
12
+ tone: '*',
13
+ key: '_hue',
14
+ })
15
+
16
+ expect(parseTokenKey('primary/_hue')).toEqual({
17
+ type: 'base',
18
+ tone: 'primary',
19
+ key: '_hue',
20
+ })
21
+
22
+ // ['primary/_hue', 'purple'],
23
+ // ['positive/_hue', 'cyan'],
24
+ // ['caution/_hue', 'yellow'],
25
+ // ['critical/_hue', 'red'],
26
+
27
+ expect(parseTokenKey('*/bg')).toEqual({
28
+ type: 'base',
29
+ tone: '*',
30
+ key: 'bg',
31
+ })
32
+
33
+ expect(parseTokenKey('*/focusRing')).toEqual({
34
+ type: 'base',
35
+ tone: '*',
36
+ key: 'focusRing',
37
+ })
38
+
39
+ expect(parseTokenKey('*/muted/fg')).toEqual({
40
+ type: 'base',
41
+ tone: '*',
42
+ key: 'muted/fg',
43
+ })
44
+
45
+ expect(parseTokenKey('*/link/fg')).toEqual({
46
+ type: 'base',
47
+ tone: '*',
48
+ key: 'link/fg',
49
+ })
50
+
51
+ expect(parseTokenKey('*/code/fg')).toEqual({
52
+ type: 'base',
53
+ tone: '*',
54
+ key: 'code/fg',
55
+ })
56
+
57
+ expect(parseTokenKey('default/_blend')).toEqual({
58
+ type: 'base',
59
+ tone: 'default',
60
+ key: '_blend',
61
+ })
62
+
63
+ // ['default/bg', 'white', '900'],
64
+ // ['default/fg', 'black', '100'],
65
+
66
+ expect(parseTokenKey('button/*/default/_blend')).toEqual({
67
+ type: 'button',
68
+ tone: '*',
69
+ mode: 'default',
70
+ key: '_blend',
71
+ })
72
+ })
@@ -0,0 +1,88 @@
1
+ import {isColorButtonMode} from '../../helpers'
2
+ import {ColorButtonMode} from '../../types'
3
+ import {
4
+ isColorConfigBaseKey,
5
+ isColorConfigBaseTone,
6
+ isColorConfigBlendKey,
7
+ isColorConfigStateKey,
8
+ isColorConfigStateTone,
9
+ } from '../helpers'
10
+ import {
11
+ ColorConfigBaseKey,
12
+ ColorConfigBaseTone,
13
+ ColorConfigBlendKey,
14
+ ColorConfigStateKey,
15
+ ColorConfigStateTone,
16
+ } from '../types'
17
+
18
+ export interface TokenBaseKeyNode {
19
+ type: 'base'
20
+ tone: ColorConfigBaseTone
21
+ key: ColorConfigBaseKey | ColorConfigBlendKey
22
+ }
23
+
24
+ export interface TokenButtonKeyNode {
25
+ type: 'button'
26
+ tone: ColorConfigStateTone
27
+ mode: ColorButtonMode
28
+ key: ColorConfigStateKey | ColorConfigBlendKey
29
+ }
30
+
31
+ export type TokenKeyNode = TokenBaseKeyNode | TokenButtonKeyNode
32
+
33
+ export function parseTokenKey(str: string): TokenKeyNode | undefined {
34
+ const segments = str.split('/')
35
+ const segment0 = segments.shift() || ''
36
+
37
+ if (isColorConfigBaseTone(segment0)) {
38
+ const key = segments.join('/')
39
+
40
+ if (isColorConfigBaseKey(key)) {
41
+ return {
42
+ type: 'base',
43
+ tone: segment0,
44
+ key,
45
+ }
46
+ }
47
+
48
+ if (isColorConfigBlendKey(key)) {
49
+ return {
50
+ type: 'base',
51
+ tone: segment0,
52
+ key,
53
+ }
54
+ }
55
+ }
56
+
57
+ if (segment0 === 'button') {
58
+ const segment1 = segments.shift() || ''
59
+
60
+ if (isColorConfigStateTone(segment1)) {
61
+ const segment2 = segments.shift() || ''
62
+
63
+ if (isColorButtonMode(segment2)) {
64
+ const key = segments.join('/')
65
+
66
+ if (isColorConfigStateKey(key)) {
67
+ return {
68
+ type: 'button',
69
+ tone: segment1,
70
+ mode: segment2,
71
+ key,
72
+ }
73
+ }
74
+
75
+ if (isColorConfigBlendKey(key)) {
76
+ return {
77
+ type: 'button',
78
+ tone: segment1,
79
+ mode: segment2,
80
+ key,
81
+ }
82
+ }
83
+ }
84
+ }
85
+ }
86
+
87
+ return undefined
88
+ }
@@ -0,0 +1,45 @@
1
+ import {parseTokenValue} from './parseTokenValue'
2
+
3
+ test('parse color value', () => {
4
+ expect(parseTokenValue('cyan')).toEqual({
5
+ type: 'hue',
6
+ value: 'cyan',
7
+ })
8
+
9
+ expect(parseTokenValue('50')).toEqual({
10
+ type: 'color',
11
+ tint: '50',
12
+ })
13
+
14
+ expect(parseTokenValue('cyan/500')).toEqual({
15
+ type: 'color',
16
+ key: 'cyan/500',
17
+ hue: 'cyan',
18
+ tint: '500',
19
+ })
20
+
21
+ expect(parseTokenValue('screen')).toEqual({
22
+ type: 'blendMode',
23
+ value: 'screen',
24
+ })
25
+
26
+ expect(parseTokenValue('multiply')).toEqual({
27
+ type: 'blendMode',
28
+ value: 'multiply',
29
+ })
30
+
31
+ expect(parseTokenValue('0')).toEqual({
32
+ type: 'color',
33
+ opacity: 0,
34
+ })
35
+
36
+ expect(parseTokenValue('0.1')).toEqual({
37
+ type: 'color',
38
+ opacity: 0.1,
39
+ })
40
+
41
+ expect(parseTokenValue('1')).toEqual({
42
+ type: 'color',
43
+ opacity: 1,
44
+ })
45
+ })
@@ -0,0 +1,123 @@
1
+ import {isColorBlendModeValue, isColorHueValue, isColorTintValue} from '../../helpers'
2
+ import {ColorHueValue, ColorTintValue} from '../../types'
3
+ import {isColorOpacityValue, isColorValue} from '../helpers'
4
+ import {ColorBlendModeValue} from '../types'
5
+
6
+ export interface TokenColorValueNode {
7
+ type: 'color'
8
+ key?: 'black' | 'white' | `${ColorHueValue}/${ColorTintValue}` | ColorTintValue
9
+ hue?: ColorHueValue
10
+ tint?: ColorTintValue
11
+ opacity?: number
12
+ }
13
+
14
+ export interface TokenHueValueNode {
15
+ type: 'hue'
16
+ value?: ColorHueValue
17
+ }
18
+
19
+ export interface TokenBlendModeValueNode {
20
+ type: 'blendMode'
21
+ value?: ColorBlendModeValue
22
+ }
23
+
24
+ export type TokenValueNode = TokenColorValueNode | TokenHueValueNode | TokenBlendModeValueNode
25
+
26
+ export function parseTokenValue(str: string): TokenValueNode | undefined {
27
+ const segments = str.split('/')
28
+ const segment0 = segments.shift() || ''
29
+
30
+ if (isColorTintValue(segment0)) {
31
+ const tint = segment0
32
+ const segment1 = segments.shift() || ''
33
+
34
+ if (isColorOpacityValue(segment1)) {
35
+ const opacity = Number(segment1)
36
+
37
+ return {
38
+ type: 'color',
39
+ tint,
40
+ opacity,
41
+ }
42
+ }
43
+
44
+ return {
45
+ type: 'color',
46
+ tint,
47
+ }
48
+ }
49
+
50
+ if (isColorValue(segment0)) {
51
+ const key = segment0 as 'black' | 'white'
52
+ const segment1 = segments.shift() || ''
53
+
54
+ if (isColorOpacityValue(segment1)) {
55
+ const opacity = Number(segment1)
56
+
57
+ return {
58
+ type: 'color',
59
+ key,
60
+ opacity,
61
+ }
62
+ }
63
+
64
+ return {
65
+ type: 'color',
66
+ key,
67
+ }
68
+ }
69
+
70
+ if (isColorHueValue(segment0)) {
71
+ const hue = segment0
72
+ const segment1 = segments.shift() || ''
73
+
74
+ if (isColorTintValue(segment1)) {
75
+ const tint = segment1
76
+ const segment2 = segments.shift() || ''
77
+
78
+ if (isColorOpacityValue(segment2)) {
79
+ const opacity = Number(segment2)
80
+
81
+ return {
82
+ type: 'color',
83
+ key: `${hue}/${tint}`,
84
+ hue,
85
+ tint,
86
+ opacity,
87
+ }
88
+ }
89
+
90
+ return {
91
+ type: 'color',
92
+ key: `${hue}/${tint}`,
93
+ hue,
94
+ tint,
95
+ }
96
+ }
97
+
98
+ return {
99
+ type: 'hue',
100
+ value: `${hue}`,
101
+ }
102
+ }
103
+
104
+ if (isColorOpacityValue(segment0)) {
105
+ const opacity = Number(segment0)
106
+
107
+ return {
108
+ type: 'color',
109
+ opacity,
110
+ }
111
+ }
112
+
113
+ if (isColorBlendModeValue(segment0)) {
114
+ const value = segment0
115
+
116
+ return {
117
+ type: 'blendMode',
118
+ value,
119
+ }
120
+ }
121
+
122
+ return undefined
123
+ }
@@ -0,0 +1,126 @@
1
+ import {ColorTint as ColorPaletteValue} from '@sanity/color'
2
+
3
+ import {COLOR_BASE_TONES, COLOR_BLEND_MODES, COLOR_STATE_TONES} from '../constants'
4
+ import {ColorButtonMode, ColorHueValue, ColorState, ColorTintValue} from '../types'
5
+
6
+ export type ColorBlendModeValue = (typeof COLOR_BLEND_MODES)[number]
7
+
8
+ export type ColorTokenValue = [ColorConfigValue, ColorConfigValue]
9
+
10
+ export type ColorBlendModeTokenValue = [ColorBlendModeValue, ColorBlendModeValue]
11
+
12
+ export const COLOR_CONFIG_BASE_TONES = ['*', ...COLOR_BASE_TONES] as const
13
+ export type ColorConfigBaseTone = (typeof COLOR_CONFIG_BASE_TONES)[number]
14
+
15
+ export const COLOR_CONFIG_STATE_TONES = ['*', ...COLOR_STATE_TONES] as const
16
+ export type ColorConfigStateTone = (typeof COLOR_CONFIG_STATE_TONES)[number]
17
+
18
+ export interface BaseColorTokens {
19
+ _blend?: ColorBlendModeTokenValue
20
+ _hue?: ColorHueValue
21
+ bg?: ColorTokenValue
22
+ fg?: ColorTokenValue
23
+ border?: ColorTokenValue
24
+ }
25
+
26
+ export interface StateColorTokens {
27
+ _blend?: ColorBlendModeTokenValue
28
+ _hue?: ColorHueValue
29
+ bg?: ColorTokenValue
30
+ bg2?: ColorTokenValue
31
+ fg?: ColorTokenValue
32
+ border?: ColorTokenValue
33
+ muted?: {
34
+ fg?: ColorTokenValue
35
+ }
36
+ accent?: {
37
+ fg?: ColorTokenValue
38
+ }
39
+ link?: {
40
+ fg?: ColorTokenValue
41
+ }
42
+ code?: {
43
+ bg?: ColorTokenValue
44
+ fg?: ColorTokenValue
45
+ }
46
+ skeleton?: {
47
+ from?: ColorTokenValue
48
+ to?: ColorTokenValue
49
+ }
50
+ }
51
+
52
+ export type ButtonModeColorTokens = Partial<Record<'*' | ColorState, StateColorTokens>>
53
+
54
+ export interface ButtonColorTokens extends Partial<Record<ColorButtonMode, ButtonModeColorTokens>> {
55
+ _hue?: ColorHueValue
56
+ }
57
+
58
+ export interface ColorTokens extends Partial<Record<ColorConfigBaseTone, BaseColorTokens>> {
59
+ button?: Partial<Record<ColorConfigStateTone, ButtonColorTokens>>
60
+ }
61
+
62
+ export type TMP_ColorPalette = {
63
+ black: string | ColorPaletteValue
64
+ white: string | ColorPaletteValue
65
+ } & Record<ColorHueValue, Record<ColorTintValue, string | ColorPaletteValue>>
66
+
67
+ export interface ColorThemeConfig {
68
+ // eslint-disable-next-line
69
+ palette?: TMP_ColorPalette
70
+ tokens?: ColorTokens
71
+ }
72
+
73
+ export interface ThemeConfig {
74
+ color?: ColorThemeConfig
75
+ }
76
+
77
+ export const COLOR_CONFIG_BASE_KEYS = [
78
+ '_hue',
79
+ 'bg',
80
+ 'fg',
81
+ 'border',
82
+ 'focusRing',
83
+ 'muted/fg',
84
+ 'link/fg',
85
+ 'code/bg',
86
+ 'code/fg',
87
+ 'shadow/outline',
88
+ 'shadow/umbra',
89
+ 'shadow/penumbra',
90
+ 'shadow/ambient',
91
+ 'skeleton/from',
92
+ 'skeleton/to',
93
+ ] as const
94
+ export type ColorConfigBaseKey = (typeof COLOR_CONFIG_BASE_KEYS)[number]
95
+
96
+ export const COLOR_CONFIG_STATE_KEYS = [
97
+ '_hue',
98
+ 'bg',
99
+ 'fg',
100
+ 'border',
101
+ 'focusRing',
102
+ 'muted/fg',
103
+ 'link/fg',
104
+ 'code/bg',
105
+ 'code/fg',
106
+ 'skeleton/from',
107
+ 'skeleton/to',
108
+ ] as const
109
+ export type ColorConfigStateKey = (typeof COLOR_CONFIG_STATE_KEYS)[number]
110
+
111
+ export const COLOR_CONFIG_BLEND_KEYS = ['_blend'] as const
112
+ export type ColorConfigBlendKey = (typeof COLOR_CONFIG_BLEND_KEYS)[number]
113
+
114
+ export type ColorConfigOpacityValue = `0` | `0.${number}` | `1`
115
+
116
+ export type ColorConfigValue =
117
+ | `black`
118
+ | `white`
119
+ | `black/${ColorConfigOpacityValue}`
120
+ | `white/${ColorConfigOpacityValue}`
121
+ | `${ColorHueValue}`
122
+ | `${ColorHueValue}/${ColorTintValue}`
123
+ | `${ColorHueValue}/${ColorTintValue}/${ColorConfigOpacityValue}`
124
+ | `${ColorTintValue}`
125
+ | `${ColorTintValue}/${ColorConfigOpacityValue}`
126
+ | ColorBlendModeValue
@@ -0,0 +1,48 @@
1
+ export const COLOR_HUES = [
2
+ 'gray',
3
+ 'cyan',
4
+ 'blue',
5
+ 'purple',
6
+ 'magenta',
7
+ 'red',
8
+ 'orange',
9
+ 'yellow',
10
+ 'green',
11
+ ] as const
12
+
13
+ export const COLOR_TINTS = [
14
+ '50',
15
+ '100',
16
+ '200',
17
+ '300',
18
+ '400',
19
+ '500',
20
+ '600',
21
+ '700',
22
+ '800',
23
+ '900',
24
+ '950',
25
+ ] as const
26
+
27
+ export const COLOR_BASE_TONES = [
28
+ 'transparent',
29
+ 'default',
30
+ 'primary', // todo: rename to `accent`
31
+ 'positive',
32
+ 'caution',
33
+ 'critical',
34
+ ] as const
35
+
36
+ export const COLOR_STATE_TONES = [
37
+ 'default',
38
+ 'primary', // todo: rename to `accent`
39
+ 'positive',
40
+ 'caution',
41
+ 'critical',
42
+ ] as const
43
+
44
+ export const COLOR_STATES = ['enabled', 'hovered', 'pressed', 'selected', 'disabled'] as const
45
+
46
+ export const COLOR_BUTTON_MODES = ['default', 'ghost', 'bleed'] as const
47
+
48
+ export const COLOR_BLEND_MODES = ['multiply', 'screen'] as const
@@ -0,0 +1,19 @@
1
+ import {ColorBlendModeValue} from './config'
2
+ import {COLOR_BLEND_MODES, COLOR_BUTTON_MODES, COLOR_HUES, COLOR_TINTS} from './constants'
3
+ import {ColorButtonMode, ColorHueValue, ColorTintValue} from './types'
4
+
5
+ export function isColorBlendModeValue(str: string): str is ColorBlendModeValue {
6
+ return COLOR_BLEND_MODES.includes(str as ColorBlendModeValue)
7
+ }
8
+
9
+ export function isColorHueValue(str: string): str is ColorHueValue {
10
+ return COLOR_HUES.includes(str as ColorHueValue)
11
+ }
12
+
13
+ export function isColorTintValue(str: string): str is ColorTintValue {
14
+ return COLOR_TINTS.includes(str as ColorTintValue)
15
+ }
16
+
17
+ export function isColorButtonMode(str: string): str is ColorButtonMode {
18
+ return COLOR_BUTTON_MODES.includes(str as ColorButtonMode)
19
+ }
@@ -0,0 +1,5 @@
1
+ export * from './build'
2
+ export * from './config'
3
+ export * from './constants'
4
+ export * from './helpers'
5
+ export * from './types'
@@ -0,0 +1,72 @@
1
+ import {ColorBlendModeValue} from './config'
2
+ import {
3
+ COLOR_BASE_TONES,
4
+ COLOR_BUTTON_MODES,
5
+ COLOR_HUES,
6
+ COLOR_STATE_TONES,
7
+ COLOR_STATES,
8
+ COLOR_TINTS,
9
+ } from './constants'
10
+
11
+ export type ColorHueValue = (typeof COLOR_HUES)[number]
12
+
13
+ export type ColorTintValue = (typeof COLOR_TINTS)[number]
14
+
15
+ export type ColorBaseTone = (typeof COLOR_BASE_TONES)[number]
16
+
17
+ export type ColorButtonMode = (typeof COLOR_BUTTON_MODES)[number]
18
+
19
+ export type ColorState = (typeof COLOR_STATES)[number]
20
+
21
+ export type ColorStateTone = (typeof COLOR_STATE_TONES)[number]
22
+
23
+ export interface TMP_StateColorTheme {
24
+ _blend: ColorBlendModeValue
25
+ bg: string
26
+ bg2?: string
27
+ fg: string
28
+ border: string
29
+ muted: {
30
+ fg: string
31
+ }
32
+ accent: {
33
+ fg: string
34
+ }
35
+ link: {
36
+ fg: string
37
+ }
38
+ code: {
39
+ bg: string
40
+ fg: string
41
+ }
42
+ skeleton?: {
43
+ from: string
44
+ to: string
45
+ }
46
+ }
47
+
48
+ export type TMP_ButtonStatesColorTheme = Record<ColorState, TMP_StateColorTheme>
49
+
50
+ export type TMP_ButtonModesColorTheme = Record<ColorButtonMode, TMP_ButtonStatesColorTheme>
51
+
52
+ export type TMP_ButtonColorTheme = Record<ColorStateTone, TMP_ButtonModesColorTheme>
53
+
54
+ export interface TMP_BaseColorTheme {
55
+ _blend: ColorBlendModeValue
56
+ dark: boolean
57
+ base: {
58
+ bg: string
59
+ fg: string
60
+ border: string
61
+ }
62
+ button: TMP_ButtonColorTheme
63
+ }
64
+
65
+ export type TMP_ColorTheme = Record<ColorBaseTone, TMP_BaseColorTheme>
66
+
67
+ export interface TMP_Theme {
68
+ color: {
69
+ light: TMP_ColorTheme
70
+ dark: TMP_ColorTheme
71
+ }
72
+ }
@@ -1,3 +1,4 @@
1
+ export * from './_internal'
1
2
  export * from './lib/color-fns'
2
3
  export * from './lib/theme'
3
4
  export * from './studioTheme'