@tamagui/themes 1.121.11 → 1.121.12
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/cjs/getThemeSuitePalettes.cjs +81 -0
- package/dist/cjs/getThemeSuitePalettes.js +63 -0
- package/dist/cjs/getThemeSuitePalettes.js.map +6 -0
- package/dist/cjs/getThemeSuitePalettes.native.js +94 -0
- package/dist/cjs/getThemeSuitePalettes.native.js.map +6 -0
- package/dist/cjs/index.cjs +10 -10
- package/dist/cjs/index.js +10 -10
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/index.native.js +10 -10
- package/dist/cjs/index.native.js.map +1 -1
- package/dist/cjs/types.cjs +16 -0
- package/dist/cjs/types.js +14 -0
- package/dist/cjs/types.js.map +6 -0
- package/dist/cjs/types.native.js +15 -0
- package/dist/cjs/types.native.js.map +6 -0
- package/dist/cjs/utils.cjs +40 -0
- package/dist/cjs/utils.js +37 -0
- package/dist/cjs/utils.js.map +6 -0
- package/dist/cjs/utils.native.js +49 -0
- package/dist/cjs/utils.native.js.map +6 -0
- package/dist/cjs/v3-themes.cjs +12 -27
- package/dist/cjs/v3-themes.js +10 -28
- package/dist/cjs/v3-themes.js.map +1 -1
- package/dist/cjs/v3-themes.native.js +8 -34
- package/dist/cjs/v3-themes.native.js.map +2 -2
- package/dist/cjs/v4-createTheme.cjs +257 -0
- package/dist/cjs/v4-createTheme.js +232 -0
- package/dist/cjs/v4-createTheme.js.map +6 -0
- package/dist/cjs/v4-createTheme.native.js +284 -0
- package/dist/cjs/v4-createTheme.native.js.map +6 -0
- package/dist/cjs/v4-default.cjs +102 -0
- package/dist/cjs/v4-default.js +89 -0
- package/dist/cjs/v4-default.js.map +6 -0
- package/dist/cjs/v4-default.native.js +99 -0
- package/dist/cjs/v4-default.native.js.map +6 -0
- package/dist/cjs/v4-defaultTemplates.cjs +158 -0
- package/dist/cjs/v4-defaultTemplates.js +144 -0
- package/dist/cjs/v4-defaultTemplates.js.map +6 -0
- package/dist/cjs/v4-defaultTemplates.native.js +154 -0
- package/dist/cjs/v4-defaultTemplates.native.js.map +6 -0
- package/dist/cjs/v4-tamagui-out.cjs +1217 -0
- package/dist/cjs/v4-tamagui-out.js +1241 -0
- package/dist/cjs/v4-tamagui-out.js.map +6 -0
- package/dist/cjs/v4-tamagui-out.native.js +12662 -0
- package/dist/cjs/v4-tamagui-out.native.js.map +6 -0
- package/dist/cjs/v4-tamagui.cjs +175 -0
- package/dist/cjs/v4-tamagui.js +214 -0
- package/dist/cjs/v4-tamagui.js.map +6 -0
- package/dist/cjs/v4-tamagui.native.js +218 -0
- package/dist/cjs/v4-tamagui.native.js.map +6 -0
- package/dist/cjs/v4.cjs +41 -0
- package/dist/cjs/v4.js +30 -0
- package/dist/cjs/v4.js.map +6 -0
- package/dist/cjs/v4.native.js +37 -0
- package/dist/cjs/v4.native.js.map +6 -0
- package/dist/esm/getThemeSuitePalettes.js +47 -0
- package/dist/esm/getThemeSuitePalettes.js.map +6 -0
- package/dist/esm/getThemeSuitePalettes.mjs +57 -0
- package/dist/esm/getThemeSuitePalettes.mjs.map +1 -0
- package/dist/esm/getThemeSuitePalettes.native.js +73 -0
- package/dist/esm/getThemeSuitePalettes.native.js.map +6 -0
- package/dist/esm/types.js +1 -0
- package/dist/esm/types.js.map +6 -0
- package/dist/esm/types.mjs +2 -0
- package/dist/esm/types.mjs.map +1 -0
- package/dist/esm/types.native.js +1 -0
- package/dist/esm/types.native.js.map +6 -0
- package/dist/esm/utils.js +21 -0
- package/dist/esm/utils.js.map +6 -0
- package/dist/esm/utils.mjs +14 -0
- package/dist/esm/utils.mjs.map +1 -0
- package/dist/esm/utils.native.js +25 -0
- package/dist/esm/utils.native.js.map +6 -0
- package/dist/esm/v3-themes.js +2 -19
- package/dist/esm/v3-themes.js.map +1 -1
- package/dist/esm/v3-themes.mjs +3 -14
- package/dist/esm/v3-themes.mjs.map +1 -1
- package/dist/esm/v3-themes.native.js +2 -23
- package/dist/esm/v3-themes.native.js.map +2 -2
- package/dist/esm/v4-createTheme.js +221 -0
- package/dist/esm/v4-createTheme.js.map +6 -0
- package/dist/esm/v4-createTheme.mjs +226 -0
- package/dist/esm/v4-createTheme.mjs.map +1 -0
- package/dist/esm/v4-createTheme.native.js +261 -0
- package/dist/esm/v4-createTheme.native.js.map +6 -0
- package/dist/esm/v4-default.js +74 -0
- package/dist/esm/v4-default.js.map +6 -0
- package/dist/esm/v4-default.mjs +79 -0
- package/dist/esm/v4-default.mjs.map +1 -0
- package/dist/esm/v4-default.native.js +80 -0
- package/dist/esm/v4-default.native.js.map +6 -0
- package/dist/esm/v4-defaultTemplates.js +128 -0
- package/dist/esm/v4-defaultTemplates.js.map +6 -0
- package/dist/esm/v4-defaultTemplates.mjs +135 -0
- package/dist/esm/v4-defaultTemplates.mjs.map +1 -0
- package/dist/esm/v4-defaultTemplates.native.js +134 -0
- package/dist/esm/v4-defaultTemplates.native.js.map +6 -0
- package/dist/esm/v4-tamagui-out.js +1225 -0
- package/dist/esm/v4-tamagui-out.js.map +6 -0
- package/dist/esm/v4-tamagui-out.mjs +677 -0
- package/dist/esm/v4-tamagui-out.mjs.map +1 -0
- package/dist/esm/v4-tamagui-out.native.js +12124 -0
- package/dist/esm/v4-tamagui-out.native.js.map +6 -0
- package/dist/esm/v4-tamagui.js +216 -0
- package/dist/esm/v4-tamagui.js.map +6 -0
- package/dist/esm/v4-tamagui.mjs +152 -0
- package/dist/esm/v4-tamagui.mjs.map +1 -0
- package/dist/esm/v4-tamagui.native.js +199 -0
- package/dist/esm/v4-tamagui.native.js.map +6 -0
- package/dist/esm/v4.js +8 -0
- package/dist/esm/v4.js.map +6 -0
- package/dist/esm/v4.mjs +5 -0
- package/dist/esm/v4.mjs.map +1 -0
- package/dist/esm/v4.native.js +8 -0
- package/dist/esm/v4.native.js.map +6 -0
- package/package.json +17 -7
- package/src/getThemeSuitePalettes.ts +94 -0
- package/src/types.ts +94 -0
- package/src/utils.ts +51 -0
- package/src/v3-themes.ts +2 -53
- package/src/v4-createTheme.ts +403 -0
- package/src/v4-default.ts +88 -0
- package/src/v4-defaultTemplates.ts +165 -0
- package/src/v4-tamagui-out.ts +1667 -0
- package/src/v4-tamagui.ts +232 -0
- package/src/v4.tsx +4 -0
- package/tsconfig.json +2 -1
- package/types/getThemeSuitePalettes.d.ts +7 -0
- package/types/types.d.ts +72 -0
- package/types/utils.d.ts +21 -0
- package/types/v3-themes.d.ts +0 -20
- package/types/v4-createTheme.d.ts +157 -0
- package/types/v4-default.d.ts +797 -0
- package/types/v4-defaultTemplates.d.ts +44 -0
- package/types/v4-tamagui-out.d.ts +659 -0
- package/types/v4-tamagui.d.ts +15575 -0
- package/types/v4.d.ts +4 -0
- package/v4.d.ts +1 -0
- package/v4.js +1 -0
|
@@ -0,0 +1,403 @@
|
|
|
1
|
+
import { createThemeBuilder, type ThemeBuilder } from '@tamagui/theme-builder'
|
|
2
|
+
import { parseToHsla } from 'color2k'
|
|
3
|
+
import { getThemeSuitePalettes } from './getThemeSuitePalettes'
|
|
4
|
+
import type { BuildPalettes, BuildTemplates, BuildThemeSuiteProps } from './types'
|
|
5
|
+
import { defaultTemplates } from './v4-defaultTemplates'
|
|
6
|
+
|
|
7
|
+
export { getThemeSuitePalettes, PALETTE_BACKGROUND_OFFSET } from './getThemeSuitePalettes'
|
|
8
|
+
export type * from './types'
|
|
9
|
+
export { defaultTemplates } from './v4-defaultTemplates'
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* TODO
|
|
13
|
+
*
|
|
14
|
+
* - we avoidNestingWithin accent, but sometimes want it eg v4-tamagui grandChildren
|
|
15
|
+
* a good default would be to IF palette is set, dont nest, IF only template, nest
|
|
16
|
+
* needs to update both runtime logic and types
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
type ExtraThemeValues = Record<string, string>
|
|
20
|
+
type ExtraThemeValuesByScheme<Values extends ExtraThemeValues = ExtraThemeValues> = {
|
|
21
|
+
dark: Values
|
|
22
|
+
light: Values
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
type SimpleThemeDefinition = { palette?: Palette; template?: string }
|
|
26
|
+
type BaseThemeDefinition<Extra extends ExtraThemeValuesByScheme> = {
|
|
27
|
+
palette: Palette
|
|
28
|
+
template?: string
|
|
29
|
+
extra?: Extra
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
type SimpleThemesDefinition = Record<string, SimpleThemeDefinition>
|
|
33
|
+
type SimplePaletteDefinitions = Record<string, string[]>
|
|
34
|
+
|
|
35
|
+
type SinglePalette = string[]
|
|
36
|
+
type SchemePalette = { light: SinglePalette; dark: SinglePalette }
|
|
37
|
+
type Palette = SinglePalette | SchemePalette
|
|
38
|
+
|
|
39
|
+
const defaultPalettes: SimplePaletteDefinitions = createPalettes(
|
|
40
|
+
getThemesPalettes({
|
|
41
|
+
base: {
|
|
42
|
+
palette: ['#fff', '#000'],
|
|
43
|
+
},
|
|
44
|
+
accent: {
|
|
45
|
+
palette: ['#ff0000', '#ff9999'],
|
|
46
|
+
},
|
|
47
|
+
})
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
export type CreateThemesProps<
|
|
51
|
+
Accent extends BaseThemeDefinition<Extra> | undefined = undefined,
|
|
52
|
+
GrandChildrenThemes extends SimpleThemesDefinition | undefined = undefined,
|
|
53
|
+
Extra extends ExtraThemeValuesByScheme = ExtraThemeValuesByScheme,
|
|
54
|
+
ChildrenThemes extends SimpleThemesDefinition = SimpleThemesDefinition,
|
|
55
|
+
ComponentThemes extends SimpleThemesDefinition = SimpleThemesDefinition,
|
|
56
|
+
Templates extends BuildTemplates = typeof defaultTemplates,
|
|
57
|
+
> = {
|
|
58
|
+
base: BaseThemeDefinition<Extra>
|
|
59
|
+
accent?: Accent
|
|
60
|
+
childrenThemes?: ChildrenThemes
|
|
61
|
+
grandChildrenThemes?: GrandChildrenThemes
|
|
62
|
+
templates?: Templates
|
|
63
|
+
componentThemes?: ComponentThemes
|
|
64
|
+
colorsToTheme?: (props: {
|
|
65
|
+
colors: string[]
|
|
66
|
+
name: string
|
|
67
|
+
scheme?: 'light' | 'dark'
|
|
68
|
+
}) => Record<string, string>
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function createThemeSuite<
|
|
72
|
+
Extra extends ExtraThemeValuesByScheme,
|
|
73
|
+
SubThemes extends SimpleThemesDefinition,
|
|
74
|
+
ComponentThemes extends SimpleThemesDefinition,
|
|
75
|
+
GrandChildrenThemes extends SimpleThemesDefinition | undefined = undefined,
|
|
76
|
+
Accent extends BaseThemeDefinition<Extra> | undefined = undefined,
|
|
77
|
+
>(
|
|
78
|
+
props: CreateThemesProps<Accent, GrandChildrenThemes, Extra, SubThemes, ComponentThemes>
|
|
79
|
+
) {
|
|
80
|
+
const {
|
|
81
|
+
accent,
|
|
82
|
+
childrenThemes,
|
|
83
|
+
grandChildrenThemes,
|
|
84
|
+
templates = defaultTemplates,
|
|
85
|
+
componentThemes = defaultComponentThemes as unknown as any,
|
|
86
|
+
} = props
|
|
87
|
+
|
|
88
|
+
const builder = createSimpleThemeBuilder({
|
|
89
|
+
extra: props.base.extra,
|
|
90
|
+
componentThemes,
|
|
91
|
+
palettes: createPalettes(getThemesPalettes(props)),
|
|
92
|
+
templates: templates as typeof defaultTemplates,
|
|
93
|
+
accentTheme: !!accent as Accent extends undefined ? false : true,
|
|
94
|
+
childrenThemes: normalizeSubThemes(childrenThemes),
|
|
95
|
+
grandChildrenThemes: (grandChildrenThemes
|
|
96
|
+
? normalizeSubThemes(grandChildrenThemes)
|
|
97
|
+
: undefined) as GrandChildrenThemes extends undefined
|
|
98
|
+
? undefined
|
|
99
|
+
: Record<keyof GrandChildrenThemes, any>,
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
return builder.themes
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function normalizeSubThemes<A extends SimpleThemesDefinition>(defs?: A) {
|
|
106
|
+
return Object.fromEntries(
|
|
107
|
+
Object.entries(defs || {}).map(([name, value]) => {
|
|
108
|
+
return [
|
|
109
|
+
name,
|
|
110
|
+
{
|
|
111
|
+
palette: name,
|
|
112
|
+
template: value.template || 'base',
|
|
113
|
+
},
|
|
114
|
+
]
|
|
115
|
+
})
|
|
116
|
+
) as Record<keyof A, any>
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
type NamesWithChildrenNames<ParentNames extends string, ChildNames> =
|
|
120
|
+
| ParentNames
|
|
121
|
+
| (ChildNames extends string ? `${ParentNames}_${ChildNames}` : never)
|
|
122
|
+
|
|
123
|
+
// a simpler API surface
|
|
124
|
+
export function createSimpleThemeBuilder<
|
|
125
|
+
Extra extends ExtraThemeValuesByScheme,
|
|
126
|
+
Templates extends BuildTemplates,
|
|
127
|
+
Palettes extends SimplePaletteDefinitions,
|
|
128
|
+
ChildrenThemes extends Record<
|
|
129
|
+
string,
|
|
130
|
+
{
|
|
131
|
+
template: keyof Templates extends string ? keyof Templates : never
|
|
132
|
+
palette?: string
|
|
133
|
+
}
|
|
134
|
+
>,
|
|
135
|
+
GrandChildrenThemes extends
|
|
136
|
+
| undefined
|
|
137
|
+
| Record<
|
|
138
|
+
string,
|
|
139
|
+
{
|
|
140
|
+
template: keyof Templates extends string ? keyof Templates : never
|
|
141
|
+
palette?: string
|
|
142
|
+
}
|
|
143
|
+
>,
|
|
144
|
+
HasAccent extends boolean,
|
|
145
|
+
ComponentThemes extends SimpleThemesDefinition,
|
|
146
|
+
FullTheme = {
|
|
147
|
+
[ThemeKey in keyof Templates['light_base'] | keyof Extra['dark']]: string
|
|
148
|
+
},
|
|
149
|
+
>(props: {
|
|
150
|
+
palettes?: Palettes
|
|
151
|
+
accentTheme?: HasAccent
|
|
152
|
+
templates?: Templates
|
|
153
|
+
childrenThemes?: ChildrenThemes
|
|
154
|
+
grandChildrenThemes?: GrandChildrenThemes
|
|
155
|
+
componentThemes?: ComponentThemes
|
|
156
|
+
extra?: Extra
|
|
157
|
+
}): {
|
|
158
|
+
themeBuilder: ThemeBuilder<any>
|
|
159
|
+
themes: {
|
|
160
|
+
[Key in
|
|
161
|
+
| 'light'
|
|
162
|
+
| 'dark'
|
|
163
|
+
| (HasAccent extends true ? 'light_accent' | 'dark_accent' : never)
|
|
164
|
+
| (keyof ChildrenThemes extends string
|
|
165
|
+
? `${'light' | 'dark'}_${GrandChildrenThemes extends undefined
|
|
166
|
+
? keyof ChildrenThemes
|
|
167
|
+
: NamesWithChildrenNames<keyof ChildrenThemes, keyof GrandChildrenThemes>}`
|
|
168
|
+
: never)]: FullTheme
|
|
169
|
+
}
|
|
170
|
+
} {
|
|
171
|
+
const {
|
|
172
|
+
extra,
|
|
173
|
+
childrenThemes = null as unknown as ChildrenThemes,
|
|
174
|
+
grandChildrenThemes = null as unknown as GrandChildrenThemes,
|
|
175
|
+
templates = defaultTemplates as unknown as Templates,
|
|
176
|
+
palettes = defaultPalettes as unknown as Palettes,
|
|
177
|
+
componentThemes = templates === (defaultTemplates as any)
|
|
178
|
+
? (defaultComponentThemes as unknown as ComponentThemes)
|
|
179
|
+
: undefined,
|
|
180
|
+
} = props
|
|
181
|
+
|
|
182
|
+
// start theme-builder
|
|
183
|
+
let themeBuilder = createThemeBuilder()
|
|
184
|
+
.addPalettes(palettes)
|
|
185
|
+
.addTemplates(templates)
|
|
186
|
+
.addThemes({
|
|
187
|
+
light: {
|
|
188
|
+
template: 'base',
|
|
189
|
+
palette: 'light',
|
|
190
|
+
nonInheritedValues: extra?.light,
|
|
191
|
+
},
|
|
192
|
+
dark: {
|
|
193
|
+
template: 'base',
|
|
194
|
+
palette: 'dark',
|
|
195
|
+
nonInheritedValues: extra?.dark,
|
|
196
|
+
},
|
|
197
|
+
})
|
|
198
|
+
.addChildThemes(
|
|
199
|
+
palettes.light_accent
|
|
200
|
+
? {
|
|
201
|
+
accent: [
|
|
202
|
+
{
|
|
203
|
+
parent: 'light',
|
|
204
|
+
template: 'base',
|
|
205
|
+
palette: 'light_accent',
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
parent: 'dark',
|
|
209
|
+
template: 'base',
|
|
210
|
+
palette: 'dark_accent',
|
|
211
|
+
},
|
|
212
|
+
],
|
|
213
|
+
}
|
|
214
|
+
: {}
|
|
215
|
+
)
|
|
216
|
+
|
|
217
|
+
if (childrenThemes) {
|
|
218
|
+
themeBuilder = themeBuilder.addChildThemes(childrenThemes, {
|
|
219
|
+
avoidNestingWithin: ['accent'],
|
|
220
|
+
}) as any
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
if (grandChildrenThemes) {
|
|
224
|
+
themeBuilder = themeBuilder.addChildThemes(grandChildrenThemes, {
|
|
225
|
+
avoidNestingWithin: ['accent'],
|
|
226
|
+
}) as any
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
if (componentThemes) {
|
|
230
|
+
themeBuilder = themeBuilder.addComponentThemes(getComponentThemes(componentThemes), {
|
|
231
|
+
avoidNestingWithin: [
|
|
232
|
+
// ...Object.keys(childrenThemes || {}),
|
|
233
|
+
...Object.keys(grandChildrenThemes || {}),
|
|
234
|
+
],
|
|
235
|
+
})
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
return {
|
|
239
|
+
themeBuilder,
|
|
240
|
+
themes: themeBuilder.build() as any,
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// for studio
|
|
245
|
+
// allows more detailed configuration, used by studio
|
|
246
|
+
// eventually we should merge this down into simple and have it handle what we need
|
|
247
|
+
export function createThemes(props: BuildThemeSuiteProps) {
|
|
248
|
+
const palettes = createPalettes(props.palettes)
|
|
249
|
+
return createSimpleThemeBuilder({
|
|
250
|
+
palettes,
|
|
251
|
+
templates: props.templates,
|
|
252
|
+
componentThemes: defaultComponentThemes,
|
|
253
|
+
})
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
function getSchemePalette(colors: SinglePalette): SchemePalette {
|
|
257
|
+
return {
|
|
258
|
+
light: colors,
|
|
259
|
+
dark: colors.toReversed(),
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
function getAnchors(palette: SchemePalette) {
|
|
264
|
+
const maxIndex = 11
|
|
265
|
+
const numItems = palette.light.length
|
|
266
|
+
|
|
267
|
+
const anchors = palette.light.map((lcolor, index) => {
|
|
268
|
+
const dcolor = palette.dark[index]
|
|
269
|
+
const [lhue, lsat, llum] = parseToHsla(lcolor)
|
|
270
|
+
const [dhue, dsat, dlum] = parseToHsla(dcolor)
|
|
271
|
+
return {
|
|
272
|
+
index: spreadIndex(maxIndex, numItems, index),
|
|
273
|
+
hue: { light: lhue, dark: dhue },
|
|
274
|
+
sat: { light: lsat, dark: dsat },
|
|
275
|
+
lum: { light: llum, dark: dlum },
|
|
276
|
+
} as const
|
|
277
|
+
})
|
|
278
|
+
|
|
279
|
+
return anchors
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
function spreadIndex(maxIndex: number, numItems: number, index: number) {
|
|
283
|
+
return Math.round((index / (numItems - 1)) * maxIndex)
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
function coerceSimplePaletteToSchemePalette(def: Palette) {
|
|
287
|
+
return Array.isArray(def) ? getSchemePalette(def) : def
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
function getThemesPalettes(props: CreateThemesProps<any, any>): BuildPalettes {
|
|
291
|
+
const base = coerceSimplePaletteToSchemePalette(props.base.palette)
|
|
292
|
+
const accent = props.accent
|
|
293
|
+
? coerceSimplePaletteToSchemePalette(props.accent.palette)
|
|
294
|
+
: null
|
|
295
|
+
|
|
296
|
+
const baseAnchors = getAnchors(base)
|
|
297
|
+
|
|
298
|
+
function getSubThemesPalettes(defs: SimpleThemesDefinition) {
|
|
299
|
+
return Object.fromEntries(
|
|
300
|
+
Object.entries(defs).map(([key, value]) => {
|
|
301
|
+
return [
|
|
302
|
+
key,
|
|
303
|
+
{
|
|
304
|
+
name: key,
|
|
305
|
+
anchors: value.palette
|
|
306
|
+
? getAnchors(coerceSimplePaletteToSchemePalette(value.palette))
|
|
307
|
+
: baseAnchors,
|
|
308
|
+
},
|
|
309
|
+
]
|
|
310
|
+
})
|
|
311
|
+
)
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
return {
|
|
315
|
+
base: {
|
|
316
|
+
name: 'base',
|
|
317
|
+
anchors: baseAnchors,
|
|
318
|
+
},
|
|
319
|
+
...(accent && {
|
|
320
|
+
accent: {
|
|
321
|
+
name: 'accent',
|
|
322
|
+
anchors: getAnchors(accent),
|
|
323
|
+
},
|
|
324
|
+
}),
|
|
325
|
+
...(props.childrenThemes && getSubThemesPalettes(props.childrenThemes)),
|
|
326
|
+
...(props.grandChildrenThemes && getSubThemesPalettes(props.grandChildrenThemes)),
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
export const getComponentThemes = (components: SimpleThemesDefinition) => {
|
|
331
|
+
return Object.fromEntries(
|
|
332
|
+
Object.entries(components).map(([componentName, { template }]) => {
|
|
333
|
+
return [
|
|
334
|
+
componentName,
|
|
335
|
+
{
|
|
336
|
+
parent: '',
|
|
337
|
+
template: template || 'base',
|
|
338
|
+
},
|
|
339
|
+
]
|
|
340
|
+
})
|
|
341
|
+
)
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
export const defaultComponentThemes = {
|
|
345
|
+
ListItem: { template: 'surface1' },
|
|
346
|
+
SelectTrigger: { template: 'surface1' },
|
|
347
|
+
Card: { template: 'surface1' },
|
|
348
|
+
Button: { template: 'surface3' },
|
|
349
|
+
Checkbox: { template: 'surface2' },
|
|
350
|
+
Switch: { template: 'surface2' },
|
|
351
|
+
SwitchThumb: { template: 'inverse' },
|
|
352
|
+
TooltipContent: { template: 'surface2' },
|
|
353
|
+
Progress: { template: 'surface1' },
|
|
354
|
+
RadioGroupItem: { template: 'surface2' },
|
|
355
|
+
TooltipArrow: { template: 'surface1' },
|
|
356
|
+
SliderTrackActive: { template: 'surface3' },
|
|
357
|
+
SliderTrack: { template: 'surface1' },
|
|
358
|
+
SliderThumb: { template: 'inverse' },
|
|
359
|
+
Tooltip: { template: 'inverse' },
|
|
360
|
+
ProgressIndicator: { template: 'inverse' },
|
|
361
|
+
Input: { template: 'surface1' },
|
|
362
|
+
TextArea: { template: 'surface1' },
|
|
363
|
+
} satisfies SimpleThemesDefinition
|
|
364
|
+
|
|
365
|
+
export function createPalettes(palettes: BuildPalettes): SimplePaletteDefinitions {
|
|
366
|
+
const accentPalettes = palettes.accent ? getThemeSuitePalettes(palettes.accent) : null
|
|
367
|
+
const basePalettes = getThemeSuitePalettes(palettes.base)
|
|
368
|
+
|
|
369
|
+
const next = Object.fromEntries(
|
|
370
|
+
Object.entries(palettes).flatMap(([name, palette]) => {
|
|
371
|
+
const palettes = getThemeSuitePalettes(palette)
|
|
372
|
+
const isAccent = name.startsWith('accent')
|
|
373
|
+
const oppositePalettes = isAccent ? basePalettes : accentPalettes
|
|
374
|
+
const oppositeLight = oppositePalettes!.light
|
|
375
|
+
const oppositeDark = oppositePalettes!.dark
|
|
376
|
+
|
|
377
|
+
const bgOffset = 7
|
|
378
|
+
|
|
379
|
+
const out = [
|
|
380
|
+
[
|
|
381
|
+
name === 'base' ? 'light' : `light_${name}`,
|
|
382
|
+
[
|
|
383
|
+
oppositeLight[bgOffset],
|
|
384
|
+
...palettes.light,
|
|
385
|
+
oppositeLight[oppositeLight.length - bgOffset - 1],
|
|
386
|
+
],
|
|
387
|
+
],
|
|
388
|
+
[
|
|
389
|
+
name === 'base' ? 'dark' : `dark_${name}`,
|
|
390
|
+
[
|
|
391
|
+
oppositeDark[oppositeDark.length - bgOffset - 1],
|
|
392
|
+
...palettes.dark,
|
|
393
|
+
oppositeDark[bgOffset],
|
|
394
|
+
],
|
|
395
|
+
],
|
|
396
|
+
] as const
|
|
397
|
+
|
|
398
|
+
return out
|
|
399
|
+
})
|
|
400
|
+
)
|
|
401
|
+
|
|
402
|
+
return next as any
|
|
403
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { green, greenDark, red, redDark, yellow, yellowDark } from '@tamagui/colors'
|
|
2
|
+
import { createThemeSuite } from './v4-createTheme'
|
|
3
|
+
|
|
4
|
+
const colorTokens = {
|
|
5
|
+
light: {
|
|
6
|
+
green,
|
|
7
|
+
red,
|
|
8
|
+
yellow,
|
|
9
|
+
},
|
|
10
|
+
dark: {
|
|
11
|
+
green: greenDark,
|
|
12
|
+
red: redDark,
|
|
13
|
+
yellow: yellowDark,
|
|
14
|
+
},
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const lightShadowColor = 'rgba(0,0,0,0.04)'
|
|
18
|
+
const lightShadowColorStrong = 'rgba(0,0,0,0.085)'
|
|
19
|
+
const darkShadowColor = 'rgba(0,0,0,0.2)'
|
|
20
|
+
const darkShadowColorStrong = 'rgba(0,0,0,0.3)'
|
|
21
|
+
|
|
22
|
+
const darkPalette = ['#050505', '#fff']
|
|
23
|
+
const lightPalette = ['#fff', 'hsl(0, 0%, 9.0%)']
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Default themes for the tamagui.dev site
|
|
27
|
+
* If you'd like to create your own themes, use `createThemeSuite`
|
|
28
|
+
*/
|
|
29
|
+
export const defaultThemes = createThemeSuite({
|
|
30
|
+
base: {
|
|
31
|
+
palette: {
|
|
32
|
+
dark: darkPalette,
|
|
33
|
+
light: lightPalette,
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
// we set a bunch of colors like $red1 => $red12
|
|
37
|
+
// we only want to set it on the base light/dark theme not all sub-themes
|
|
38
|
+
extra: {
|
|
39
|
+
light: {
|
|
40
|
+
...colorTokens.light.green,
|
|
41
|
+
...colorTokens.light.red,
|
|
42
|
+
...colorTokens.light.yellow,
|
|
43
|
+
shadowColor: lightShadowColorStrong,
|
|
44
|
+
shadowColorHover: lightShadowColorStrong,
|
|
45
|
+
shadowColorPress: lightShadowColor,
|
|
46
|
+
shadowColorFocus: lightShadowColor,
|
|
47
|
+
},
|
|
48
|
+
dark: {
|
|
49
|
+
...colorTokens.dark.green,
|
|
50
|
+
...colorTokens.dark.red,
|
|
51
|
+
...colorTokens.dark.yellow,
|
|
52
|
+
shadowColor: darkShadowColorStrong,
|
|
53
|
+
shadowColorHover: darkShadowColorStrong,
|
|
54
|
+
shadowColorPress: darkShadowColor,
|
|
55
|
+
shadowColorFocus: darkShadowColor,
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
|
|
60
|
+
accent: {
|
|
61
|
+
palette: {
|
|
62
|
+
dark: lightPalette,
|
|
63
|
+
light: darkPalette,
|
|
64
|
+
},
|
|
65
|
+
template: 'inverse',
|
|
66
|
+
},
|
|
67
|
+
|
|
68
|
+
childrenThemes: {
|
|
69
|
+
error: {
|
|
70
|
+
palette: {
|
|
71
|
+
dark: Object.values(colorTokens.dark.red),
|
|
72
|
+
light: Object.values(colorTokens.light.red),
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
warning: {
|
|
76
|
+
palette: {
|
|
77
|
+
dark: Object.values(colorTokens.dark.yellow),
|
|
78
|
+
light: Object.values(colorTokens.light.yellow),
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
success: {
|
|
82
|
+
palette: {
|
|
83
|
+
dark: Object.values(colorTokens.dark.green),
|
|
84
|
+
light: Object.values(colorTokens.light.green),
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
})
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { objectFromEntries, objectKeys } from './helpers'
|
|
2
|
+
import type { BuildTemplates } from './types'
|
|
3
|
+
|
|
4
|
+
const lightShadowColor = 'rgba(0,0,0,0.04)'
|
|
5
|
+
const lightShadowColorStrong = 'rgba(0,0,0,0.085)'
|
|
6
|
+
const darkShadowColor = 'rgba(0,0,0,0.2)'
|
|
7
|
+
const darkShadowColorStrong = 'rgba(0,0,0,0.3)'
|
|
8
|
+
|
|
9
|
+
const shadows = {
|
|
10
|
+
light: {
|
|
11
|
+
shadowColor: lightShadowColorStrong,
|
|
12
|
+
shadowColorHover: lightShadowColorStrong,
|
|
13
|
+
shadowColorPress: lightShadowColor,
|
|
14
|
+
shadowColorFocus: lightShadowColor,
|
|
15
|
+
},
|
|
16
|
+
dark: {
|
|
17
|
+
shadowColor: darkShadowColorStrong,
|
|
18
|
+
shadowColorHover: darkShadowColorStrong,
|
|
19
|
+
shadowColorPress: darkShadowColor,
|
|
20
|
+
shadowColorFocus: darkShadowColor,
|
|
21
|
+
},
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const getTemplates = () => {
|
|
25
|
+
const lightTemplates = getBaseTemplates('light')
|
|
26
|
+
const darkTemplates = getBaseTemplates('dark')
|
|
27
|
+
const templates = {
|
|
28
|
+
...objectFromEntries(
|
|
29
|
+
objectKeys(lightTemplates).map(
|
|
30
|
+
(name) => [`light_${name}`, lightTemplates[name]] as const
|
|
31
|
+
)
|
|
32
|
+
),
|
|
33
|
+
...objectFromEntries(
|
|
34
|
+
objectKeys(darkTemplates).map(
|
|
35
|
+
(name) => [`dark_${name}`, darkTemplates[name]] as const
|
|
36
|
+
)
|
|
37
|
+
),
|
|
38
|
+
}
|
|
39
|
+
return templates as Record<keyof typeof templates, typeof lightTemplates.base>
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const getBaseTemplates = (scheme: 'dark' | 'light') => {
|
|
43
|
+
const isLight = scheme === 'light'
|
|
44
|
+
|
|
45
|
+
// our palettes have 4 things padding each end until you get to bg/color:
|
|
46
|
+
// [accentBg, transparent1, transparent2, transparent3, transparent4, background, ...]
|
|
47
|
+
const bgIndex = 5
|
|
48
|
+
const lighten = isLight ? -1 : 1
|
|
49
|
+
const darken = -lighten
|
|
50
|
+
const borderColor = bgIndex + 3
|
|
51
|
+
|
|
52
|
+
// templates use the palette and specify index
|
|
53
|
+
// negative goes backwards from end so -1 is the last item
|
|
54
|
+
const base = {
|
|
55
|
+
accentBackground: 0,
|
|
56
|
+
accentColor: -0,
|
|
57
|
+
|
|
58
|
+
...(isLight ? shadows.light : shadows.dark),
|
|
59
|
+
|
|
60
|
+
background0: 1,
|
|
61
|
+
background025: 2,
|
|
62
|
+
background05: 3,
|
|
63
|
+
background075: 4,
|
|
64
|
+
color1: bgIndex,
|
|
65
|
+
color2: bgIndex + 1,
|
|
66
|
+
color3: bgIndex + 2,
|
|
67
|
+
color4: bgIndex + 3,
|
|
68
|
+
color5: bgIndex + 4,
|
|
69
|
+
color6: bgIndex + 5,
|
|
70
|
+
color7: bgIndex + 6,
|
|
71
|
+
color8: bgIndex + 7,
|
|
72
|
+
color9: bgIndex + 8,
|
|
73
|
+
color10: bgIndex + 9,
|
|
74
|
+
color11: bgIndex + 10,
|
|
75
|
+
color12: bgIndex + 11,
|
|
76
|
+
color0: -1,
|
|
77
|
+
color025: -2,
|
|
78
|
+
color05: -3,
|
|
79
|
+
color075: -4,
|
|
80
|
+
// the background, color, etc keys here work like generics - they make it so you
|
|
81
|
+
// can publish components for others to use without mandating a specific color scale
|
|
82
|
+
// the @tamagui/button Button component looks for `$background`, so you set the
|
|
83
|
+
// dark_red_Button theme to have a stronger background than the dark_red theme.
|
|
84
|
+
background: bgIndex,
|
|
85
|
+
backgroundHover: bgIndex + lighten, // always lighten on hover no matter the scheme
|
|
86
|
+
backgroundPress: bgIndex + darken, // always darken on press no matter the theme
|
|
87
|
+
backgroundFocus: bgIndex + darken,
|
|
88
|
+
borderColor,
|
|
89
|
+
borderColorHover: borderColor + lighten,
|
|
90
|
+
borderColorPress: borderColor + darken,
|
|
91
|
+
borderColorFocus: borderColor,
|
|
92
|
+
color: -bgIndex,
|
|
93
|
+
colorHover: -bgIndex - 1,
|
|
94
|
+
colorPress: -bgIndex,
|
|
95
|
+
colorFocus: -bgIndex - 1,
|
|
96
|
+
colorTransparent: -1,
|
|
97
|
+
placeholderColor: -bgIndex - 3,
|
|
98
|
+
outlineColor: -2,
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const surface1 = {
|
|
102
|
+
background: base.background + 1,
|
|
103
|
+
backgroundHover: base.backgroundHover + 1,
|
|
104
|
+
backgroundPress: base.backgroundPress + 1,
|
|
105
|
+
backgroundFocus: base.backgroundFocus + 1,
|
|
106
|
+
borderColor: base.borderColor + 1,
|
|
107
|
+
borderColorHover: base.borderColorHover + 1,
|
|
108
|
+
borderColorFocus: base.borderColorFocus + 1,
|
|
109
|
+
borderColorPress: base.borderColorPress + 1,
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const surface2 = {
|
|
113
|
+
background: base.background + 2,
|
|
114
|
+
backgroundHover: base.backgroundHover + 2,
|
|
115
|
+
backgroundPress: base.backgroundPress + 2,
|
|
116
|
+
backgroundFocus: base.backgroundFocus + 2,
|
|
117
|
+
borderColor: base.borderColor + 2,
|
|
118
|
+
borderColorHover: base.borderColorHover + 2,
|
|
119
|
+
borderColorFocus: base.borderColorFocus + 2,
|
|
120
|
+
borderColorPress: base.borderColorPress + 2,
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const surface3 = {
|
|
124
|
+
background: base.background + 3,
|
|
125
|
+
backgroundHover: base.backgroundHover + 3,
|
|
126
|
+
backgroundPress: base.backgroundPress + 3,
|
|
127
|
+
backgroundFocus: base.backgroundFocus + 3,
|
|
128
|
+
borderColor: base.borderColor + 3,
|
|
129
|
+
borderColorHover: base.borderColorHover + 3,
|
|
130
|
+
borderColorFocus: base.borderColorFocus + 3,
|
|
131
|
+
borderColorPress: base.borderColorPress + 3,
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const alt1 = {
|
|
135
|
+
color: base.color - 1,
|
|
136
|
+
colorHover: base.colorHover - 1,
|
|
137
|
+
colorPress: base.colorPress - 1,
|
|
138
|
+
colorFocus: base.colorFocus - 1,
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const alt2 = {
|
|
142
|
+
color: base.color - 2,
|
|
143
|
+
colorHover: base.colorHover - 2,
|
|
144
|
+
colorPress: base.colorPress - 2,
|
|
145
|
+
colorFocus: base.colorFocus - 2,
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const inverse = Object.fromEntries(
|
|
149
|
+
Object.entries(base).map(([key, index]) => {
|
|
150
|
+
return [key, -index]
|
|
151
|
+
})
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
return {
|
|
155
|
+
base,
|
|
156
|
+
surface1,
|
|
157
|
+
surface2,
|
|
158
|
+
surface3,
|
|
159
|
+
alt1,
|
|
160
|
+
alt2,
|
|
161
|
+
inverse,
|
|
162
|
+
} satisfies BuildTemplates
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export const defaultTemplates = getTemplates()
|