@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.
- package/dist/index.cjs.mjs +28 -0
- package/dist/index.d.ts +476 -12
- package/dist/index.esm.js +1326 -524
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +1353 -523
- package/dist/index.js.map +1 -1
- package/package.json +6 -8
- package/src/components/autocomplete/autocomplete.tsx +6 -0
- package/src/components/dialog/constants.ts +4 -0
- package/src/components/dialog/dialog.tsx +79 -15
- package/src/components/hotkeys/hotkeys.tsx +2 -0
- package/src/components/menu/menu.tsx +2 -0
- package/src/components/menu/menuButton.tsx +2 -0
- package/src/components/menu/menuGroup.tsx +22 -23
- package/src/components/menu/menuItem.tsx +29 -35
- package/src/components/tab/tab.tsx +4 -1
- package/src/components/toast/toast.tsx +4 -0
- package/src/primitives/_selectable/style.ts +2 -1
- package/src/primitives/avatar/avatar.tsx +16 -9
- package/src/primitives/avatar/avatarCounter.tsx +3 -3
- package/src/primitives/avatar/styles.ts +1 -1
- package/src/primitives/badge/badge.tsx +7 -3
- package/src/primitives/box/box.tsx +3 -0
- package/src/primitives/button/__workshop__/sanityUploadButton.tsx +2 -1
- package/src/primitives/button/button.tsx +7 -3
- package/src/primitives/button/styles.ts +9 -2
- package/src/primitives/card/card.tsx +4 -0
- package/src/primitives/card/styles.ts +2 -0
- package/src/primitives/checkbox/checkbox.tsx +2 -0
- package/src/primitives/code/code.tsx +1 -0
- package/src/primitives/container/container.tsx +2 -0
- package/src/primitives/flex/flex.tsx +2 -0
- package/src/primitives/grid/grid.tsx +2 -0
- package/src/primitives/heading/heading.tsx +2 -0
- package/src/primitives/inline/inline.tsx +3 -0
- package/src/primitives/kbd/kbd.tsx +2 -0
- package/src/primitives/label/label.tsx +2 -0
- package/src/primitives/popover/popover.tsx +6 -1
- package/src/primitives/radio/radio.tsx +2 -0
- package/src/primitives/select/select.tsx +2 -0
- package/src/primitives/select/styles.ts +2 -0
- package/src/primitives/spinner/spinner.tsx +2 -0
- package/src/primitives/stack/stack.tsx +2 -0
- package/src/primitives/switch/switch.tsx +4 -0
- package/src/primitives/text/text.tsx +3 -0
- package/src/primitives/textArea/textArea.tsx +4 -1
- package/src/primitives/textInput/textInput.tsx +10 -1
- package/src/primitives/tooltip/__workshop__/customPortal.tsx +99 -0
- package/src/primitives/tooltip/__workshop__/index.ts +15 -0
- package/src/primitives/tooltip/__workshop__/overflowingBoundary.tsx +73 -0
- package/src/primitives/tooltip/__workshop__/resizableBoundary.tsx +85 -0
- package/src/primitives/tooltip/constants.ts +1 -0
- package/src/primitives/tooltip/tooltip.test.tsx +192 -0
- package/src/primitives/tooltip/tooltip.tsx +109 -33
- package/src/primitives/types.ts +4 -0
- package/src/styles/input/textInputStyle.ts +11 -6
- package/src/theme/_internal/__workshop__/build/story.tsx +288 -0
- package/src/theme/_internal/__workshop__/build/theme.ts +3 -0
- package/src/theme/_internal/__workshop__/index.ts +14 -0
- package/src/theme/_internal/build/buildTheme.test.ts +78 -0
- package/src/theme/_internal/build/buildTheme.ts +16 -0
- package/src/theme/_internal/build/colorTheme/buildColorTheme.test.ts +185 -0
- package/src/theme/_internal/build/colorTheme/buildColorTheme.ts +164 -0
- package/src/theme/_internal/build/colorTheme/renderColorTheme.ts +242 -0
- package/src/theme/_internal/build/colorTheme/resolveColorTokens.ts +121 -0
- package/src/theme/_internal/build/defaults/colorPalette.ts +8 -0
- package/src/theme/_internal/build/defaults/colorTokens.ts +147 -0
- package/src/theme/_internal/build/helpers.ts +65 -0
- package/src/theme/_internal/build/index.ts +1 -0
- package/src/theme/_internal/config/helpers.ts +47 -0
- package/src/theme/_internal/config/index.ts +3 -0
- package/src/theme/_internal/config/token/index.ts +2 -0
- package/src/theme/_internal/config/token/parseTokenKey.test.ts +72 -0
- package/src/theme/_internal/config/token/parseTokenKey.ts +88 -0
- package/src/theme/_internal/config/token/parseTokenValue.test.ts +45 -0
- package/src/theme/_internal/config/token/parseTokenValue.ts +123 -0
- package/src/theme/_internal/config/types.ts +137 -0
- package/src/theme/_internal/constants.ts +48 -0
- package/src/theme/_internal/helpers.ts +19 -0
- package/src/theme/_internal/index.ts +5 -0
- package/src/theme/_internal/types.ts +91 -0
- package/src/theme/index.ts +1 -0
- package/src/theme/lib/color-fns/blend/multiply.ts +2 -2
- package/src/theme/lib/color-fns/blend/screen.ts +2 -2
- package/src/theme/lib/color-fns/convert.ts +15 -1
- package/src/theme/lib/color-fns/parse.ts +7 -3
- package/src/theme/lib/color-fns/types.ts +11 -0
- package/src/theme/lib/theme/avatar.ts +2 -0
- package/src/theme/lib/theme/color/_legacy/createColorTheme.ts +7 -0
- package/src/theme/lib/theme/color/_legacy/index.ts +1 -0
- package/src/theme/lib/theme/color/_legacy/legacyColor.ts +3997 -0
- package/src/theme/studioTheme/color.ts +98 -82
- package/src/theme/studioTheme/helpers.ts +15 -1
- package/src/theme/studioTheme/theme.ts +5 -5
- package/src/theme/studioTheme/tints.ts +244 -84
- package/src/types/button.ts +5 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import {
|
|
2
|
+
parseColor,
|
|
3
|
+
rgbToHex,
|
|
4
|
+
screen as _screen,
|
|
5
|
+
multiply as _multiply,
|
|
6
|
+
rgba,
|
|
7
|
+
} from '../../lib/color-fns'
|
|
8
|
+
import {ColorTokenValue, parseTokenValue, TokenColorValueNode} from '../config'
|
|
9
|
+
import {ColorHueValue} from '../types'
|
|
10
|
+
|
|
11
|
+
export interface ColorTokenContext {
|
|
12
|
+
hue: ColorHueValue
|
|
13
|
+
scheme: 'light' | 'dark'
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function resolveColorTokenValue(context: ColorTokenContext, value: ColorTokenValue): string {
|
|
17
|
+
const {hue, scheme} = context
|
|
18
|
+
const node = parseTokenValue(value[scheme === 'light' ? 0 : 1])
|
|
19
|
+
|
|
20
|
+
if (!node || node.type !== 'color') {
|
|
21
|
+
throw new Error(`Invalid color token: ${value[0]}`)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return compileColorTokenValue({...node, hue: node.hue || hue})
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function compileColorTokenValue(node: TokenColorValueNode): string {
|
|
28
|
+
let key = ''
|
|
29
|
+
|
|
30
|
+
if (node.key === 'black' || node.key === 'white') {
|
|
31
|
+
key = node.key
|
|
32
|
+
} else {
|
|
33
|
+
key = `${node.hue}/${node.tint}`
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (node.opacity !== undefined) {
|
|
37
|
+
key += `/${node.opacity}`
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return key
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function multiply(bg: string, fg: string): string {
|
|
44
|
+
const b = parseColor(bg)
|
|
45
|
+
const s = parseColor(fg)
|
|
46
|
+
const hex = rgbToHex(_multiply(b, s))
|
|
47
|
+
|
|
48
|
+
if (s.a !== undefined) {
|
|
49
|
+
return rgba(hex, s.a)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return hex
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function screen(bg: string, fg: string): string {
|
|
56
|
+
const b = parseColor(bg)
|
|
57
|
+
const s = parseColor(fg)
|
|
58
|
+
const hex = rgbToHex(_screen(b, s))
|
|
59
|
+
|
|
60
|
+
if (s.a !== undefined) {
|
|
61
|
+
return rgba(hex, s.a)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return hex
|
|
65
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './buildTheme'
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import {parseTokenValue} from './token'
|
|
2
|
+
import {
|
|
3
|
+
COLOR_CONFIG_BASE_KEYS,
|
|
4
|
+
COLOR_CONFIG_BASE_TONES,
|
|
5
|
+
COLOR_CONFIG_BLEND_KEYS,
|
|
6
|
+
COLOR_CONFIG_STATE_KEYS,
|
|
7
|
+
COLOR_CONFIG_STATE_TONES,
|
|
8
|
+
ColorConfigBaseKey,
|
|
9
|
+
ColorConfigBaseTone,
|
|
10
|
+
ColorConfigBlendKey,
|
|
11
|
+
ColorConfigOpacityValue,
|
|
12
|
+
ColorConfigStateKey,
|
|
13
|
+
ColorConfigStateTone,
|
|
14
|
+
ColorConfigValue,
|
|
15
|
+
} from './types'
|
|
16
|
+
|
|
17
|
+
export function isColorConfigBaseTone(str: string): str is ColorConfigBaseTone {
|
|
18
|
+
return COLOR_CONFIG_BASE_TONES.includes(str as ColorConfigBaseTone)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function isColorConfigBaseKey(str: string): str is ColorConfigBaseKey {
|
|
22
|
+
return COLOR_CONFIG_BASE_KEYS.includes(str as ColorConfigBaseKey)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function isColorConfigStateKey(str: string): str is ColorConfigStateKey {
|
|
26
|
+
return COLOR_CONFIG_STATE_KEYS.includes(str as ColorConfigStateKey)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function isColorConfigStateTone(str: string): str is ColorConfigStateTone {
|
|
30
|
+
return COLOR_CONFIG_STATE_TONES.includes(str as ColorConfigStateTone)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function isColorConfigBlendKey(str: string): str is ColorConfigBlendKey {
|
|
34
|
+
return COLOR_CONFIG_BLEND_KEYS.includes(str as ColorConfigBlendKey)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function isColorTokenValue(str: string): str is ColorConfigValue {
|
|
38
|
+
return parseTokenValue(str)?.type === 'color' || parseTokenValue(str)?.type === 'hue'
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function isColorValue(str: string): str is 'black' | 'white' {
|
|
42
|
+
return str === 'black' || str === 'white'
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function isColorOpacityValue(str: string): str is ColorConfigOpacityValue {
|
|
46
|
+
return str === '0' || /^0\.[0-9]+$/.test(str) || str === '1'
|
|
47
|
+
}
|
|
@@ -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,137 @@
|
|
|
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
|
+
focusRing?: ColorTokenValue
|
|
25
|
+
shadow?: {
|
|
26
|
+
outline?: ColorTokenValue
|
|
27
|
+
umbra?: ColorTokenValue
|
|
28
|
+
penumbra?: ColorTokenValue
|
|
29
|
+
ambient?: ColorTokenValue
|
|
30
|
+
}
|
|
31
|
+
skeleton?: {
|
|
32
|
+
from?: ColorTokenValue
|
|
33
|
+
to?: ColorTokenValue
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface StateColorTokens {
|
|
38
|
+
_blend?: ColorBlendModeTokenValue
|
|
39
|
+
_hue?: ColorHueValue
|
|
40
|
+
bg?: ColorTokenValue
|
|
41
|
+
bg2?: ColorTokenValue
|
|
42
|
+
fg?: ColorTokenValue
|
|
43
|
+
border?: ColorTokenValue
|
|
44
|
+
muted?: {
|
|
45
|
+
fg?: ColorTokenValue
|
|
46
|
+
}
|
|
47
|
+
accent?: {
|
|
48
|
+
fg?: ColorTokenValue
|
|
49
|
+
}
|
|
50
|
+
link?: {
|
|
51
|
+
fg?: ColorTokenValue
|
|
52
|
+
}
|
|
53
|
+
code?: {
|
|
54
|
+
bg?: ColorTokenValue
|
|
55
|
+
fg?: ColorTokenValue
|
|
56
|
+
}
|
|
57
|
+
skeleton?: {
|
|
58
|
+
from?: ColorTokenValue
|
|
59
|
+
to?: ColorTokenValue
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export type ButtonModeColorTokens = Partial<Record<'*' | ColorState, StateColorTokens>>
|
|
64
|
+
|
|
65
|
+
export interface ButtonColorTokens extends Partial<Record<ColorButtonMode, ButtonModeColorTokens>> {
|
|
66
|
+
_hue?: ColorHueValue
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export interface ColorTokens extends Partial<Record<ColorConfigBaseTone, BaseColorTokens>> {
|
|
70
|
+
button?: Partial<Record<ColorConfigStateTone, ButtonColorTokens>>
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export type TMP_ColorPalette = {
|
|
74
|
+
black: string | ColorPaletteValue
|
|
75
|
+
white: string | ColorPaletteValue
|
|
76
|
+
} & Record<ColorHueValue, Record<ColorTintValue, string | ColorPaletteValue>>
|
|
77
|
+
|
|
78
|
+
export interface ColorThemeConfig {
|
|
79
|
+
// eslint-disable-next-line
|
|
80
|
+
palette?: TMP_ColorPalette
|
|
81
|
+
tokens?: ColorTokens
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export interface ThemeConfig {
|
|
85
|
+
color?: ColorThemeConfig
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export const COLOR_CONFIG_BASE_KEYS = [
|
|
89
|
+
'_hue',
|
|
90
|
+
'bg',
|
|
91
|
+
'fg',
|
|
92
|
+
'border',
|
|
93
|
+
'focusRing',
|
|
94
|
+
'muted/fg',
|
|
95
|
+
'link/fg',
|
|
96
|
+
'code/bg',
|
|
97
|
+
'code/fg',
|
|
98
|
+
'shadow/outline',
|
|
99
|
+
'shadow/umbra',
|
|
100
|
+
'shadow/penumbra',
|
|
101
|
+
'shadow/ambient',
|
|
102
|
+
'skeleton/from',
|
|
103
|
+
'skeleton/to',
|
|
104
|
+
] as const
|
|
105
|
+
export type ColorConfigBaseKey = (typeof COLOR_CONFIG_BASE_KEYS)[number]
|
|
106
|
+
|
|
107
|
+
export const COLOR_CONFIG_STATE_KEYS = [
|
|
108
|
+
'_hue',
|
|
109
|
+
'bg',
|
|
110
|
+
'fg',
|
|
111
|
+
'border',
|
|
112
|
+
'focusRing',
|
|
113
|
+
'muted/fg',
|
|
114
|
+
'link/fg',
|
|
115
|
+
'code/bg',
|
|
116
|
+
'code/fg',
|
|
117
|
+
'skeleton/from',
|
|
118
|
+
'skeleton/to',
|
|
119
|
+
] as const
|
|
120
|
+
export type ColorConfigStateKey = (typeof COLOR_CONFIG_STATE_KEYS)[number]
|
|
121
|
+
|
|
122
|
+
export const COLOR_CONFIG_BLEND_KEYS = ['_blend'] as const
|
|
123
|
+
export type ColorConfigBlendKey = (typeof COLOR_CONFIG_BLEND_KEYS)[number]
|
|
124
|
+
|
|
125
|
+
export type ColorConfigOpacityValue = `0` | `0.${number}` | `1`
|
|
126
|
+
|
|
127
|
+
export type ColorConfigValue =
|
|
128
|
+
| `black`
|
|
129
|
+
| `white`
|
|
130
|
+
| `black/${ColorConfigOpacityValue}`
|
|
131
|
+
| `white/${ColorConfigOpacityValue}`
|
|
132
|
+
| `${ColorHueValue}`
|
|
133
|
+
| `${ColorHueValue}/${ColorTintValue}`
|
|
134
|
+
| `${ColorHueValue}/${ColorTintValue}/${ColorConfigOpacityValue}`
|
|
135
|
+
| `${ColorTintValue}`
|
|
136
|
+
| `${ColorTintValue}/${ColorConfigOpacityValue}`
|
|
137
|
+
| 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
|
+
}
|