@hanzogui/theme-builder 2.0.0
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/LICENSE +21 -0
- package/dist/cjs/ThemeBuilder.cjs +184 -0
- package/dist/cjs/ThemeBuilder.native.js +262 -0
- package/dist/cjs/ThemeBuilder.native.js.map +1 -0
- package/dist/cjs/createStudioThemes.cjs +40 -0
- package/dist/cjs/createStudioThemes.native.js +43 -0
- package/dist/cjs/createStudioThemes.native.js.map +1 -0
- package/dist/cjs/createThemes.cjs +345 -0
- package/dist/cjs/createThemes.native.js +366 -0
- package/dist/cjs/createThemes.native.js.map +1 -0
- package/dist/cjs/defaultComponentThemes.cjs +84 -0
- package/dist/cjs/defaultComponentThemes.native.js +87 -0
- package/dist/cjs/defaultComponentThemes.native.js.map +1 -0
- package/dist/cjs/defaultTemplates.cjs +149 -0
- package/dist/cjs/defaultTemplates.native.js +160 -0
- package/dist/cjs/defaultTemplates.native.js.map +1 -0
- package/dist/cjs/defaultTemplatesStronger.cjs +147 -0
- package/dist/cjs/defaultTemplatesStronger.native.js +158 -0
- package/dist/cjs/defaultTemplatesStronger.native.js.map +1 -0
- package/dist/cjs/defaultTemplatesStrongest.cjs +147 -0
- package/dist/cjs/defaultTemplatesStrongest.native.js +158 -0
- package/dist/cjs/defaultTemplatesStrongest.native.js.map +1 -0
- package/dist/cjs/getThemeSuitePalettes.cjs +81 -0
- package/dist/cjs/getThemeSuitePalettes.native.js +93 -0
- package/dist/cjs/getThemeSuitePalettes.native.js.map +1 -0
- package/dist/cjs/helpers.cjs +34 -0
- package/dist/cjs/helpers.native.js +39 -0
- package/dist/cjs/helpers.native.js.map +1 -0
- package/dist/cjs/index.cjs +43 -0
- package/dist/cjs/index.native.js +46 -0
- package/dist/cjs/index.native.js.map +1 -0
- package/dist/cjs/masks.cjs +114 -0
- package/dist/cjs/masks.native.js +118 -0
- package/dist/cjs/masks.native.js.map +1 -0
- package/dist/cjs/types.cjs +16 -0
- package/dist/cjs/types.native.js +19 -0
- package/dist/cjs/types.native.js.map +1 -0
- package/dist/esm/ThemeBuilder.mjs +160 -0
- package/dist/esm/ThemeBuilder.mjs.map +1 -0
- package/dist/esm/ThemeBuilder.native.js +235 -0
- package/dist/esm/ThemeBuilder.native.js.map +1 -0
- package/dist/esm/createStudioThemes.mjs +17 -0
- package/dist/esm/createStudioThemes.mjs.map +1 -0
- package/dist/esm/createStudioThemes.native.js +17 -0
- package/dist/esm/createStudioThemes.native.js.map +1 -0
- package/dist/esm/createThemes.mjs +316 -0
- package/dist/esm/createThemes.mjs.map +1 -0
- package/dist/esm/createThemes.native.js +334 -0
- package/dist/esm/createThemes.native.js.map +1 -0
- package/dist/esm/defaultComponentThemes.mjs +61 -0
- package/dist/esm/defaultComponentThemes.mjs.map +1 -0
- package/dist/esm/defaultComponentThemes.native.js +61 -0
- package/dist/esm/defaultComponentThemes.native.js.map +1 -0
- package/dist/esm/defaultTemplates.mjs +126 -0
- package/dist/esm/defaultTemplates.mjs.map +1 -0
- package/dist/esm/defaultTemplates.native.js +134 -0
- package/dist/esm/defaultTemplates.native.js.map +1 -0
- package/dist/esm/defaultTemplatesStronger.mjs +124 -0
- package/dist/esm/defaultTemplatesStronger.mjs.map +1 -0
- package/dist/esm/defaultTemplatesStronger.native.js +132 -0
- package/dist/esm/defaultTemplatesStronger.native.js.map +1 -0
- package/dist/esm/defaultTemplatesStrongest.mjs +124 -0
- package/dist/esm/defaultTemplatesStrongest.mjs.map +1 -0
- package/dist/esm/defaultTemplatesStrongest.native.js +132 -0
- package/dist/esm/defaultTemplatesStrongest.native.js.map +1 -0
- package/dist/esm/getThemeSuitePalettes.mjs +57 -0
- package/dist/esm/getThemeSuitePalettes.mjs.map +1 -0
- package/dist/esm/getThemeSuitePalettes.native.js +66 -0
- package/dist/esm/getThemeSuitePalettes.native.js.map +1 -0
- package/dist/esm/helpers.mjs +9 -0
- package/dist/esm/helpers.mjs.map +1 -0
- package/dist/esm/helpers.native.js +11 -0
- package/dist/esm/helpers.native.js.map +1 -0
- package/dist/esm/index.js +10 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/index.mjs +10 -0
- package/dist/esm/index.mjs.map +1 -0
- package/dist/esm/index.native.js +10 -0
- package/dist/esm/index.native.js.map +1 -0
- package/dist/esm/masks.mjs +91 -0
- package/dist/esm/masks.mjs.map +1 -0
- package/dist/esm/masks.native.js +92 -0
- package/dist/esm/masks.native.js.map +1 -0
- package/dist/esm/types.mjs +2 -0
- package/dist/esm/types.mjs.map +1 -0
- package/dist/esm/types.native.js +2 -0
- package/dist/esm/types.native.js.map +1 -0
- package/package.json +48 -0
- package/src/ThemeBuilder.ts +514 -0
- package/src/createStudioThemes.ts +28 -0
- package/src/createThemes.ts +794 -0
- package/src/defaultComponentThemes.ts +26 -0
- package/src/defaultTemplates.ts +157 -0
- package/src/defaultTemplatesStronger.ts +152 -0
- package/src/defaultTemplatesStrongest.ts +152 -0
- package/src/getThemeSuitePalettes.ts +101 -0
- package/src/helpers.ts +44 -0
- package/src/index.ts +22 -0
- package/src/masks.tsx +83 -0
- package/src/types.ts +97 -0
- package/types/ThemeBuilder.d.ts +80 -0
- package/types/ThemeBuilder.d.ts.map +1 -0
- package/types/createStudioThemes.d.ts +8 -0
- package/types/createStudioThemes.d.ts.map +1 -0
- package/types/createThemes.d.ts +141 -0
- package/types/createThemes.d.ts.map +1 -0
- package/types/defaultComponentThemes.d.ts +63 -0
- package/types/defaultComponentThemes.d.ts.map +1 -0
- package/types/defaultTemplates.d.ts +42 -0
- package/types/defaultTemplates.d.ts.map +1 -0
- package/types/defaultTemplatesStronger.d.ts +42 -0
- package/types/defaultTemplatesStronger.d.ts.map +1 -0
- package/types/defaultTemplatesStrongest.d.ts +42 -0
- package/types/defaultTemplatesStrongest.d.ts.map +1 -0
- package/types/getThemeSuitePalettes.d.ts +7 -0
- package/types/getThemeSuitePalettes.d.ts.map +1 -0
- package/types/helpers.d.ts +24 -0
- package/types/helpers.d.ts.map +1 -0
- package/types/index.d.ts +11 -0
- package/types/index.d.ts.map +1 -0
- package/types/masks.d.ts +18 -0
- package/types/masks.d.ts.map +1 -0
- package/types/types.d.ts +76 -0
- package/types/types.d.ts.map +1 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { SimpleThemesDefinition } from './createThemes'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @deprecated component themes are no longer recommended - configure component styles directly via themes or component defaultProps instead
|
|
5
|
+
*/
|
|
6
|
+
export const defaultComponentThemes = {
|
|
7
|
+
ListItem: { template: 'surface1' },
|
|
8
|
+
SelectItem: { template: 'surface1' },
|
|
9
|
+
SelectTrigger: { template: 'surface1' },
|
|
10
|
+
Card: { template: 'surface1' },
|
|
11
|
+
Button: { template: 'surface3' },
|
|
12
|
+
Checkbox: { template: 'surface2' },
|
|
13
|
+
Switch: { template: 'surface2' },
|
|
14
|
+
SwitchThumb: { template: 'inverse' },
|
|
15
|
+
TooltipContent: { template: 'surface2' },
|
|
16
|
+
Progress: { template: 'surface1' },
|
|
17
|
+
RadioGroupItem: { template: 'surface2' },
|
|
18
|
+
TooltipArrow: { template: 'surface1' },
|
|
19
|
+
SliderTrackActive: { template: 'surface2' },
|
|
20
|
+
SliderTrack: { template: 'inverse' },
|
|
21
|
+
SliderThumb: { template: 'inverse' },
|
|
22
|
+
Tooltip: { template: 'inverse' },
|
|
23
|
+
ProgressIndicator: { template: 'inverse' },
|
|
24
|
+
Input: { template: 'surface1' },
|
|
25
|
+
TextArea: { template: 'surface1' },
|
|
26
|
+
} satisfies SimpleThemesDefinition
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { objectFromEntries, objectKeys } from './helpers'
|
|
2
|
+
import type { BuildTemplates } from './types'
|
|
3
|
+
|
|
4
|
+
const getTemplates = () => {
|
|
5
|
+
const lightTemplates = getBaseTemplates('light')
|
|
6
|
+
const darkTemplates = getBaseTemplates('dark')
|
|
7
|
+
const templates = {
|
|
8
|
+
...objectFromEntries(
|
|
9
|
+
objectKeys(lightTemplates).map(
|
|
10
|
+
(name) => [`light_${name}`, lightTemplates[name]] as const
|
|
11
|
+
)
|
|
12
|
+
),
|
|
13
|
+
...objectFromEntries(
|
|
14
|
+
objectKeys(darkTemplates).map(
|
|
15
|
+
(name) => [`dark_${name}`, darkTemplates[name]] as const
|
|
16
|
+
)
|
|
17
|
+
),
|
|
18
|
+
}
|
|
19
|
+
return templates as Record<keyof typeof templates, typeof lightTemplates.base>
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const getBaseTemplates = (scheme: 'dark' | 'light') => {
|
|
23
|
+
const isLight = scheme === 'light'
|
|
24
|
+
|
|
25
|
+
// our palettes have 4 things padding each end until you get to bg/color:
|
|
26
|
+
// [accentBg, transparent1, transparent2, transparent3, transparent4, background, ...]
|
|
27
|
+
const bgIndex = 6
|
|
28
|
+
const lighten = isLight ? -1 : 1
|
|
29
|
+
const darken = -lighten
|
|
30
|
+
// always +1 because palette is structured with higher indices = more contrast from background
|
|
31
|
+
const increaseContrast = 1
|
|
32
|
+
const borderColor = bgIndex + 3
|
|
33
|
+
|
|
34
|
+
const baseColors = {
|
|
35
|
+
color: -bgIndex,
|
|
36
|
+
colorHover: -bgIndex - 1,
|
|
37
|
+
colorPress: -bgIndex,
|
|
38
|
+
colorFocus: -bgIndex - 1,
|
|
39
|
+
placeholderColor: -bgIndex - 3,
|
|
40
|
+
outlineColor: -2,
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// templates use the palette and specify index
|
|
44
|
+
// negative goes backwards from end so -1 is the last item
|
|
45
|
+
const base = {
|
|
46
|
+
accentBackground: 0,
|
|
47
|
+
accentColor: -0,
|
|
48
|
+
|
|
49
|
+
background0: 1,
|
|
50
|
+
background02: 2,
|
|
51
|
+
background04: 3,
|
|
52
|
+
background06: 4,
|
|
53
|
+
background08: 5,
|
|
54
|
+
color1: bgIndex,
|
|
55
|
+
color2: bgIndex + 1,
|
|
56
|
+
color3: bgIndex + 2,
|
|
57
|
+
color4: bgIndex + 3,
|
|
58
|
+
color5: bgIndex + 4,
|
|
59
|
+
color6: bgIndex + 5,
|
|
60
|
+
color7: bgIndex + 6,
|
|
61
|
+
color8: bgIndex + 7,
|
|
62
|
+
color9: bgIndex + 8,
|
|
63
|
+
color10: bgIndex + 9,
|
|
64
|
+
color11: bgIndex + 10,
|
|
65
|
+
color12: bgIndex + 11,
|
|
66
|
+
color0: -1,
|
|
67
|
+
color02: -2,
|
|
68
|
+
color04: -3,
|
|
69
|
+
color06: -4,
|
|
70
|
+
color08: -5,
|
|
71
|
+
// the background, color, etc keys here work like generics - they make it so you
|
|
72
|
+
// can publish components for others to use without mandating a specific color scale
|
|
73
|
+
// the @hanzogui/button Button component looks for `$background`, so you set the
|
|
74
|
+
// dark_red_Button theme to have a stronger background than the dark_red theme.
|
|
75
|
+
background: bgIndex,
|
|
76
|
+
backgroundHover: bgIndex + increaseContrast * 2,
|
|
77
|
+
backgroundPress: bgIndex + increaseContrast * 3,
|
|
78
|
+
backgroundFocus: bgIndex + increaseContrast * 2,
|
|
79
|
+
borderColor,
|
|
80
|
+
borderColorHover: borderColor + lighten,
|
|
81
|
+
borderColorPress: borderColor + darken,
|
|
82
|
+
borderColorFocus: borderColor,
|
|
83
|
+
...baseColors,
|
|
84
|
+
colorTransparent: -1,
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const surface1 = {
|
|
88
|
+
...baseColors,
|
|
89
|
+
background: base.background + 1,
|
|
90
|
+
backgroundHover: base.backgroundHover + 1,
|
|
91
|
+
backgroundPress: base.backgroundPress + 1,
|
|
92
|
+
backgroundFocus: base.backgroundFocus + 1,
|
|
93
|
+
backgroundActive: base.background + 1,
|
|
94
|
+
borderColor: base.borderColor + 1,
|
|
95
|
+
borderColorHover: base.borderColorHover + 1,
|
|
96
|
+
borderColorFocus: base.borderColorFocus + 1,
|
|
97
|
+
borderColorPress: base.borderColorPress + 1,
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const surface2 = {
|
|
101
|
+
...baseColors,
|
|
102
|
+
background: base.background + 2,
|
|
103
|
+
backgroundHover: base.backgroundHover + 2,
|
|
104
|
+
backgroundPress: base.backgroundPress + 2,
|
|
105
|
+
backgroundFocus: base.backgroundFocus + 2,
|
|
106
|
+
backgroundActive: base.background + 2,
|
|
107
|
+
borderColor: base.borderColor + 2,
|
|
108
|
+
borderColorHover: base.borderColorHover + 2,
|
|
109
|
+
borderColorFocus: base.borderColorFocus + 2,
|
|
110
|
+
borderColorPress: base.borderColorPress + 2,
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const surface3 = {
|
|
114
|
+
...baseColors,
|
|
115
|
+
background: base.background + 3,
|
|
116
|
+
backgroundHover: base.backgroundHover + 3,
|
|
117
|
+
backgroundPress: base.backgroundPress + 3,
|
|
118
|
+
backgroundFocus: base.backgroundFocus + 3,
|
|
119
|
+
backgroundActive: base.background + 3,
|
|
120
|
+
borderColor: base.borderColor + 3,
|
|
121
|
+
borderColorHover: base.borderColorHover + 3,
|
|
122
|
+
borderColorFocus: base.borderColorFocus + 3,
|
|
123
|
+
borderColorPress: base.borderColorPress + 3,
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const alt1 = {
|
|
127
|
+
color: base.color - 1,
|
|
128
|
+
colorHover: base.colorHover - 1,
|
|
129
|
+
colorPress: base.colorPress - 1,
|
|
130
|
+
colorFocus: base.colorFocus - 1,
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const alt2 = {
|
|
134
|
+
color: base.color - 2,
|
|
135
|
+
colorHover: base.colorHover - 2,
|
|
136
|
+
colorPress: base.colorPress - 2,
|
|
137
|
+
colorFocus: base.colorFocus - 2,
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const inverse = Object.fromEntries(
|
|
141
|
+
Object.entries(base).map(([key, index]) => {
|
|
142
|
+
return [key, -index]
|
|
143
|
+
})
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
return {
|
|
147
|
+
base,
|
|
148
|
+
surface1,
|
|
149
|
+
surface2,
|
|
150
|
+
surface3,
|
|
151
|
+
alt1,
|
|
152
|
+
alt2,
|
|
153
|
+
inverse,
|
|
154
|
+
} satisfies BuildTemplates
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export const defaultTemplates = getTemplates()
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { objectFromEntries, objectKeys } from './helpers'
|
|
2
|
+
import type { BuildTemplates } from './types'
|
|
3
|
+
|
|
4
|
+
const getTemplates = () => {
|
|
5
|
+
const lightTemplates = getBaseTemplates('light')
|
|
6
|
+
const darkTemplates = getBaseTemplates('dark')
|
|
7
|
+
const templates = {
|
|
8
|
+
...objectFromEntries(
|
|
9
|
+
objectKeys(lightTemplates).map(
|
|
10
|
+
(name) => [`light_${name}`, lightTemplates[name]] as const
|
|
11
|
+
)
|
|
12
|
+
),
|
|
13
|
+
...objectFromEntries(
|
|
14
|
+
objectKeys(darkTemplates).map(
|
|
15
|
+
(name) => [`dark_${name}`, darkTemplates[name]] as const
|
|
16
|
+
)
|
|
17
|
+
),
|
|
18
|
+
}
|
|
19
|
+
return templates as Record<keyof typeof templates, typeof lightTemplates.base>
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const getBaseTemplates = (scheme: 'dark' | 'light') => {
|
|
23
|
+
const isLight = scheme === 'light'
|
|
24
|
+
|
|
25
|
+
// our palettes have 4 things padding each end until you get to bg/color:
|
|
26
|
+
// [accentBg, transparent1, transparent2, transparent3, transparent4, background, ...]
|
|
27
|
+
const bgIndex = 6
|
|
28
|
+
const lighten = isLight ? -1 : 1
|
|
29
|
+
const darken = -lighten
|
|
30
|
+
const borderColor = bgIndex + 3
|
|
31
|
+
|
|
32
|
+
const baseColors = {
|
|
33
|
+
color: -bgIndex,
|
|
34
|
+
colorHover: -bgIndex - 1,
|
|
35
|
+
colorPress: -bgIndex,
|
|
36
|
+
colorFocus: -bgIndex - 1,
|
|
37
|
+
placeholderColor: -bgIndex - 3,
|
|
38
|
+
outlineColor: -2,
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// templates use the palette and specify index
|
|
42
|
+
// negative goes backwards from end so -1 is the last item
|
|
43
|
+
const base = {
|
|
44
|
+
accentBackground: 0,
|
|
45
|
+
accentColor: -0,
|
|
46
|
+
|
|
47
|
+
background0: 1,
|
|
48
|
+
background02: 2,
|
|
49
|
+
background04: 3,
|
|
50
|
+
background06: 4,
|
|
51
|
+
background08: 5,
|
|
52
|
+
color1: bgIndex,
|
|
53
|
+
color2: bgIndex + 1,
|
|
54
|
+
color3: bgIndex + 2,
|
|
55
|
+
color4: bgIndex + 3,
|
|
56
|
+
color5: bgIndex + 4,
|
|
57
|
+
color6: bgIndex + 5,
|
|
58
|
+
color7: bgIndex + 6,
|
|
59
|
+
color8: bgIndex + 7,
|
|
60
|
+
color9: bgIndex + 8,
|
|
61
|
+
color10: bgIndex + 9,
|
|
62
|
+
color11: bgIndex + 10,
|
|
63
|
+
color12: bgIndex + 11,
|
|
64
|
+
color0: -1,
|
|
65
|
+
color02: -2,
|
|
66
|
+
color04: -3,
|
|
67
|
+
color06: -4,
|
|
68
|
+
color08: -5,
|
|
69
|
+
// the background, color, etc keys here work like generics - they make it so you
|
|
70
|
+
// can publish components for others to use without mandating a specific color scale
|
|
71
|
+
// the @hanzogui/button Button component looks for `$background`, so you set the
|
|
72
|
+
// dark_red_Button theme to have a stronger background than the dark_red theme.
|
|
73
|
+
background: bgIndex,
|
|
74
|
+
backgroundHover: bgIndex + lighten, // always lighten on hover no matter the scheme
|
|
75
|
+
backgroundPress: bgIndex + darken, // always darken on press no matter the theme
|
|
76
|
+
backgroundFocus: bgIndex + darken,
|
|
77
|
+
borderColor,
|
|
78
|
+
borderColorHover: borderColor + lighten,
|
|
79
|
+
borderColorPress: borderColor + darken,
|
|
80
|
+
borderColorFocus: borderColor,
|
|
81
|
+
...baseColors,
|
|
82
|
+
colorTransparent: -1,
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const surface1 = {
|
|
86
|
+
...baseColors,
|
|
87
|
+
background: base.background + 2,
|
|
88
|
+
backgroundHover: base.backgroundHover + 2,
|
|
89
|
+
backgroundPress: base.backgroundPress + 2,
|
|
90
|
+
backgroundFocus: base.backgroundFocus + 2,
|
|
91
|
+
borderColor: base.borderColor + 2,
|
|
92
|
+
borderColorHover: base.borderColorHover + 2,
|
|
93
|
+
borderColorFocus: base.borderColorFocus + 2,
|
|
94
|
+
borderColorPress: base.borderColorPress + 2,
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const surface2 = {
|
|
98
|
+
...baseColors,
|
|
99
|
+
background: base.background + 3,
|
|
100
|
+
backgroundHover: base.backgroundHover + 3,
|
|
101
|
+
backgroundPress: base.backgroundPress + 3,
|
|
102
|
+
backgroundFocus: base.backgroundFocus + 3,
|
|
103
|
+
borderColor: base.borderColor + 3,
|
|
104
|
+
borderColorHover: base.borderColorHover + 3,
|
|
105
|
+
borderColorFocus: base.borderColorFocus + 3,
|
|
106
|
+
borderColorPress: base.borderColorPress + 3,
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const surface3 = {
|
|
110
|
+
...baseColors,
|
|
111
|
+
background: base.background + 4,
|
|
112
|
+
backgroundHover: base.backgroundHover + 4,
|
|
113
|
+
backgroundPress: base.backgroundPress + 4,
|
|
114
|
+
backgroundFocus: base.backgroundFocus + 4,
|
|
115
|
+
borderColor: base.borderColor + 4,
|
|
116
|
+
borderColorHover: base.borderColorHover + 4,
|
|
117
|
+
borderColorFocus: base.borderColorFocus + 4,
|
|
118
|
+
borderColorPress: base.borderColorPress + 4,
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const alt1 = {
|
|
122
|
+
color: base.color - 1,
|
|
123
|
+
colorHover: base.colorHover - 1,
|
|
124
|
+
colorPress: base.colorPress - 1,
|
|
125
|
+
colorFocus: base.colorFocus - 1,
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const alt2 = {
|
|
129
|
+
color: base.color - 2,
|
|
130
|
+
colorHover: base.colorHover - 2,
|
|
131
|
+
colorPress: base.colorPress - 2,
|
|
132
|
+
colorFocus: base.colorFocus - 2,
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const inverse = Object.fromEntries(
|
|
136
|
+
Object.entries(base).map(([key, index]) => {
|
|
137
|
+
return [key, -index]
|
|
138
|
+
})
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
return {
|
|
142
|
+
base,
|
|
143
|
+
surface1,
|
|
144
|
+
surface2,
|
|
145
|
+
surface3,
|
|
146
|
+
alt1,
|
|
147
|
+
alt2,
|
|
148
|
+
inverse,
|
|
149
|
+
} satisfies BuildTemplates
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export const defaultTemplatesStronger = getTemplates()
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { objectFromEntries, objectKeys } from './helpers'
|
|
2
|
+
import type { BuildTemplates } from './types'
|
|
3
|
+
|
|
4
|
+
const getTemplates = () => {
|
|
5
|
+
const lightTemplates = getBaseTemplates('light')
|
|
6
|
+
const darkTemplates = getBaseTemplates('dark')
|
|
7
|
+
const templates = {
|
|
8
|
+
...objectFromEntries(
|
|
9
|
+
objectKeys(lightTemplates).map(
|
|
10
|
+
(name) => [`light_${name}`, lightTemplates[name]] as const
|
|
11
|
+
)
|
|
12
|
+
),
|
|
13
|
+
...objectFromEntries(
|
|
14
|
+
objectKeys(darkTemplates).map(
|
|
15
|
+
(name) => [`dark_${name}`, darkTemplates[name]] as const
|
|
16
|
+
)
|
|
17
|
+
),
|
|
18
|
+
}
|
|
19
|
+
return templates as Record<keyof typeof templates, typeof lightTemplates.base>
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const getBaseTemplates = (scheme: 'dark' | 'light') => {
|
|
23
|
+
const isLight = scheme === 'light'
|
|
24
|
+
|
|
25
|
+
// our palettes have 4 things padding each end until you get to bg/color:
|
|
26
|
+
// [accentBg, transparent1, transparent2, transparent3, transparent4, background, ...]
|
|
27
|
+
const bgIndex = 6
|
|
28
|
+
const lighten = isLight ? -1 : 1
|
|
29
|
+
const darken = -lighten
|
|
30
|
+
const borderColor = bgIndex + 3
|
|
31
|
+
|
|
32
|
+
const baseColors = {
|
|
33
|
+
color: -bgIndex,
|
|
34
|
+
colorHover: -bgIndex - 1,
|
|
35
|
+
colorPress: -bgIndex,
|
|
36
|
+
colorFocus: -bgIndex - 1,
|
|
37
|
+
placeholderColor: -bgIndex - 3,
|
|
38
|
+
outlineColor: -2,
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// templates use the palette and specify index
|
|
42
|
+
// negative goes backwards from end so -1 is the last item
|
|
43
|
+
const base = {
|
|
44
|
+
accentBackground: 0,
|
|
45
|
+
accentColor: -0,
|
|
46
|
+
|
|
47
|
+
background0: 1,
|
|
48
|
+
background02: 2,
|
|
49
|
+
background04: 3,
|
|
50
|
+
background06: 4,
|
|
51
|
+
background08: 5,
|
|
52
|
+
color1: bgIndex,
|
|
53
|
+
color2: bgIndex + 1,
|
|
54
|
+
color3: bgIndex + 2,
|
|
55
|
+
color4: bgIndex + 3,
|
|
56
|
+
color5: bgIndex + 4,
|
|
57
|
+
color6: bgIndex + 5,
|
|
58
|
+
color7: bgIndex + 6,
|
|
59
|
+
color8: bgIndex + 7,
|
|
60
|
+
color9: bgIndex + 8,
|
|
61
|
+
color10: bgIndex + 9,
|
|
62
|
+
color11: bgIndex + 10,
|
|
63
|
+
color12: bgIndex + 11,
|
|
64
|
+
color0: -1,
|
|
65
|
+
color02: -2,
|
|
66
|
+
color04: -3,
|
|
67
|
+
color06: -4,
|
|
68
|
+
color08: -5,
|
|
69
|
+
// the background, color, etc keys here work like generics - they make it so you
|
|
70
|
+
// can publish components for others to use without mandating a specific color scale
|
|
71
|
+
// the @hanzogui/button Button component looks for `$background`, so you set the
|
|
72
|
+
// dark_red_Button theme to have a stronger background than the dark_red theme.
|
|
73
|
+
background: bgIndex,
|
|
74
|
+
backgroundHover: bgIndex + lighten, // always lighten on hover no matter the scheme
|
|
75
|
+
backgroundPress: bgIndex + darken, // always darken on press no matter the theme
|
|
76
|
+
backgroundFocus: bgIndex + darken,
|
|
77
|
+
borderColor,
|
|
78
|
+
borderColorHover: borderColor + lighten,
|
|
79
|
+
borderColorPress: borderColor + darken,
|
|
80
|
+
borderColorFocus: borderColor,
|
|
81
|
+
...baseColors,
|
|
82
|
+
colorTransparent: -1,
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const surface1 = {
|
|
86
|
+
...baseColors,
|
|
87
|
+
background: base.background + 3,
|
|
88
|
+
backgroundHover: base.backgroundHover + 3,
|
|
89
|
+
backgroundPress: base.backgroundPress + 3,
|
|
90
|
+
backgroundFocus: base.backgroundFocus + 3,
|
|
91
|
+
borderColor: base.borderColor + 3,
|
|
92
|
+
borderColorHover: base.borderColorHover + 3,
|
|
93
|
+
borderColorFocus: base.borderColorFocus + 3,
|
|
94
|
+
borderColorPress: base.borderColorPress + 3,
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const surface2 = {
|
|
98
|
+
...baseColors,
|
|
99
|
+
background: base.background + 4,
|
|
100
|
+
backgroundHover: base.backgroundHover + 4,
|
|
101
|
+
backgroundPress: base.backgroundPress + 4,
|
|
102
|
+
backgroundFocus: base.backgroundFocus + 4,
|
|
103
|
+
borderColor: base.borderColor + 4,
|
|
104
|
+
borderColorHover: base.borderColorHover + 4,
|
|
105
|
+
borderColorFocus: base.borderColorFocus + 4,
|
|
106
|
+
borderColorPress: base.borderColorPress + 4,
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const surface3 = {
|
|
110
|
+
...baseColors,
|
|
111
|
+
background: base.background + 5,
|
|
112
|
+
backgroundHover: base.backgroundHover + 5,
|
|
113
|
+
backgroundPress: base.backgroundPress + 5,
|
|
114
|
+
backgroundFocus: base.backgroundFocus + 5,
|
|
115
|
+
borderColor: base.borderColor + 5,
|
|
116
|
+
borderColorHover: base.borderColorHover + 5,
|
|
117
|
+
borderColorFocus: base.borderColorFocus + 5,
|
|
118
|
+
borderColorPress: base.borderColorPress + 5,
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const alt1 = {
|
|
122
|
+
color: base.color - 1,
|
|
123
|
+
colorHover: base.colorHover - 1,
|
|
124
|
+
colorPress: base.colorPress - 1,
|
|
125
|
+
colorFocus: base.colorFocus - 1,
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const alt2 = {
|
|
129
|
+
color: base.color - 2,
|
|
130
|
+
colorHover: base.colorHover - 2,
|
|
131
|
+
colorPress: base.colorPress - 2,
|
|
132
|
+
colorFocus: base.colorFocus - 2,
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const inverse = Object.fromEntries(
|
|
136
|
+
Object.entries(base).map(([key, index]) => {
|
|
137
|
+
return [key, -index]
|
|
138
|
+
})
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
return {
|
|
142
|
+
base,
|
|
143
|
+
surface1,
|
|
144
|
+
surface2,
|
|
145
|
+
surface3,
|
|
146
|
+
alt1,
|
|
147
|
+
alt2,
|
|
148
|
+
inverse,
|
|
149
|
+
} satisfies BuildTemplates
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export const defaultTemplatesStrongest = getTemplates()
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { hsla, parseToHsla } from 'color2k'
|
|
2
|
+
import type { BuildPalette } from './types'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* palette generally is:
|
|
6
|
+
*
|
|
7
|
+
* [constrastBackground, accent, backgroundTransparent, ...background, ...foreground, foregroundTransparent, accentForeground]
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const paletteSize = 12
|
|
11
|
+
|
|
12
|
+
// how many things come before the actual bg color (transparencies etc)
|
|
13
|
+
// 👋 SYNC WITH gui.hanzo.ai/features/studio/constants
|
|
14
|
+
export const PALETTE_BACKGROUND_OFFSET = 6
|
|
15
|
+
|
|
16
|
+
const generateColorPalette = ({
|
|
17
|
+
palette: buildPalette,
|
|
18
|
+
scheme,
|
|
19
|
+
}: {
|
|
20
|
+
palette: BuildPalette
|
|
21
|
+
scheme: 'light' | 'dark'
|
|
22
|
+
}) => {
|
|
23
|
+
if (!buildPalette) {
|
|
24
|
+
return [] as string[]
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const { anchors } = buildPalette
|
|
28
|
+
|
|
29
|
+
let palette: string[] = []
|
|
30
|
+
|
|
31
|
+
const add = (h: number, s: number, l: number, a?: number) => {
|
|
32
|
+
palette.push(hsla(h, s, l, a ?? 1))
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const numAnchors = Object.keys(anchors).length
|
|
36
|
+
|
|
37
|
+
for (const [anchorIndex, anchor] of anchors.entries()) {
|
|
38
|
+
const [h, s, l, a] = [
|
|
39
|
+
anchor.hue[scheme],
|
|
40
|
+
anchor.sat[scheme],
|
|
41
|
+
anchor.lum[scheme],
|
|
42
|
+
anchor.alpha?.[scheme] ?? 1,
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
if (anchorIndex !== 0) {
|
|
46
|
+
const lastAnchor = anchors[anchorIndex - 1]
|
|
47
|
+
const steps = anchor.index - lastAnchor.index
|
|
48
|
+
|
|
49
|
+
const lastHue = lastAnchor.hue[scheme]
|
|
50
|
+
const lastSat = lastAnchor.sat[scheme]
|
|
51
|
+
const lastLum = lastAnchor.lum[scheme]
|
|
52
|
+
|
|
53
|
+
const stepHue = (lastHue - h) / steps
|
|
54
|
+
const stepSat = (lastSat - s) / steps
|
|
55
|
+
const stepLum = (lastLum - l) / steps
|
|
56
|
+
|
|
57
|
+
// backfill:
|
|
58
|
+
for (let step = lastAnchor.index + 1; step < anchor.index; step++) {
|
|
59
|
+
const str = anchor.index - step
|
|
60
|
+
add(h + stepHue * str, s + stepSat * str, l + stepLum * str)
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
add(h, s, l, a)
|
|
65
|
+
|
|
66
|
+
const isLastAnchor = anchorIndex === numAnchors - 1
|
|
67
|
+
if (isLastAnchor && palette.length < paletteSize) {
|
|
68
|
+
// forwardfill:
|
|
69
|
+
for (let step = anchor.index + 1; step < paletteSize; step++) {
|
|
70
|
+
add(h, s, l)
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// add transparent values
|
|
76
|
+
const background = palette[0]
|
|
77
|
+
const foreground = palette[palette.length - 1]
|
|
78
|
+
|
|
79
|
+
const transparentValues = [background, foreground].map((color) => {
|
|
80
|
+
const [h, s, l] = parseToHsla(color)
|
|
81
|
+
// fully transparent to partially
|
|
82
|
+
return [
|
|
83
|
+
hsla(h, s, l, 0),
|
|
84
|
+
hsla(h, s, l, 0.2),
|
|
85
|
+
hsla(h, s, l, 0.4),
|
|
86
|
+
hsla(h, s, l, 0.6),
|
|
87
|
+
hsla(h, s, l, 0.8),
|
|
88
|
+
] as const
|
|
89
|
+
})
|
|
90
|
+
const reverseForeground = [...transparentValues[1]].reverse()
|
|
91
|
+
palette = [...transparentValues[0], ...palette, ...reverseForeground]
|
|
92
|
+
|
|
93
|
+
return palette
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export function getThemeSuitePalettes(palette: BuildPalette) {
|
|
97
|
+
return {
|
|
98
|
+
light: generateColorPalette({ palette, scheme: 'light' }),
|
|
99
|
+
dark: generateColorPalette({ palette, scheme: 'dark' }),
|
|
100
|
+
}
|
|
101
|
+
}
|
package/src/helpers.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
type ObjectType = Record<PropertyKey, unknown>
|
|
2
|
+
|
|
3
|
+
type PickByValue<OBJ_T, VALUE_T> = // From https://stackoverflow.com/a/55153000
|
|
4
|
+
Pick<OBJ_T, { [K in keyof OBJ_T]: OBJ_T[K] extends VALUE_T ? K : never }[keyof OBJ_T]>
|
|
5
|
+
|
|
6
|
+
type ObjectEntries<OBJ_T> = // From https://stackoverflow.com/a/60142095
|
|
7
|
+
{ [K in keyof OBJ_T]: [keyof PickByValue<OBJ_T, OBJ_T[K]>, OBJ_T[K]] }[keyof OBJ_T][]
|
|
8
|
+
|
|
9
|
+
export const objectKeys = <O extends object>(obj: O) => Object.keys(obj) as Array<keyof O>
|
|
10
|
+
|
|
11
|
+
export function objectEntries<OBJ_T extends ObjectType>(
|
|
12
|
+
obj: OBJ_T
|
|
13
|
+
): ObjectEntries<OBJ_T> {
|
|
14
|
+
return Object.entries(obj) as ObjectEntries<OBJ_T>
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
type EntriesType =
|
|
18
|
+
| [PropertyKey, unknown][]
|
|
19
|
+
| ReadonlyArray<readonly [PropertyKey, unknown]>
|
|
20
|
+
|
|
21
|
+
// Existing Utils
|
|
22
|
+
type DeepWritable<OBJ_T> = { -readonly [P in keyof OBJ_T]: DeepWritable<OBJ_T[P]> }
|
|
23
|
+
type UnionToIntersection<UNION_T> = // From https://stackoverflow.com/a/50375286
|
|
24
|
+
(UNION_T extends any ? (k: UNION_T) => void : never) extends (k: infer I) => void
|
|
25
|
+
? I
|
|
26
|
+
: never
|
|
27
|
+
|
|
28
|
+
// New Utils
|
|
29
|
+
type UnionObjectFromArrayOfPairs<ARR_T extends EntriesType> =
|
|
30
|
+
DeepWritable<ARR_T> extends (infer R)[]
|
|
31
|
+
? R extends [infer key, infer val]
|
|
32
|
+
? { [prop in key & PropertyKey]: val }
|
|
33
|
+
: never
|
|
34
|
+
: never
|
|
35
|
+
type MergeIntersectingObjects<ObjT> = { [key in keyof ObjT]: ObjT[key] }
|
|
36
|
+
type EntriesToObject<ARR_T extends EntriesType> = MergeIntersectingObjects<
|
|
37
|
+
UnionToIntersection<UnionObjectFromArrayOfPairs<ARR_T>>
|
|
38
|
+
>
|
|
39
|
+
|
|
40
|
+
export function objectFromEntries<ARR_T extends EntriesType>(
|
|
41
|
+
arr: ARR_T
|
|
42
|
+
): EntriesToObject<ARR_T> {
|
|
43
|
+
return Object.fromEntries(arr) as EntriesToObject<ARR_T>
|
|
44
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export * from './ThemeBuilder'
|
|
2
|
+
export * from '@hanzogui/create-theme'
|
|
3
|
+
|
|
4
|
+
export { createStudioThemes } from './createStudioThemes'
|
|
5
|
+
export {
|
|
6
|
+
createThemes,
|
|
7
|
+
createV4Themes,
|
|
8
|
+
createPalettes,
|
|
9
|
+
createV4ThemeBuilder,
|
|
10
|
+
type CreateThemesProps,
|
|
11
|
+
} from './createThemes'
|
|
12
|
+
|
|
13
|
+
export { defaultTemplates } from './defaultTemplates'
|
|
14
|
+
/** @deprecated component themes are no longer recommended */
|
|
15
|
+
export { defaultComponentThemes } from './defaultComponentThemes'
|
|
16
|
+
|
|
17
|
+
export { PALETTE_BACKGROUND_OFFSET, getThemeSuitePalettes } from './getThemeSuitePalettes'
|
|
18
|
+
|
|
19
|
+
// copied from themes to avoid cyclic dep
|
|
20
|
+
export { masks } from './masks'
|
|
21
|
+
|
|
22
|
+
export type * from './types'
|