@tamagui/themes 1.121.10 → 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.
Files changed (139) hide show
  1. package/dist/cjs/getThemeSuitePalettes.cjs +81 -0
  2. package/dist/cjs/getThemeSuitePalettes.js +63 -0
  3. package/dist/cjs/getThemeSuitePalettes.js.map +6 -0
  4. package/dist/cjs/getThemeSuitePalettes.native.js +94 -0
  5. package/dist/cjs/getThemeSuitePalettes.native.js.map +6 -0
  6. package/dist/cjs/index.cjs +10 -10
  7. package/dist/cjs/index.js +10 -10
  8. package/dist/cjs/index.js.map +1 -1
  9. package/dist/cjs/index.native.js +10 -10
  10. package/dist/cjs/index.native.js.map +1 -1
  11. package/dist/cjs/types.cjs +16 -0
  12. package/dist/cjs/types.js +14 -0
  13. package/dist/cjs/types.js.map +6 -0
  14. package/dist/cjs/types.native.js +15 -0
  15. package/dist/cjs/types.native.js.map +6 -0
  16. package/dist/cjs/utils.cjs +40 -0
  17. package/dist/cjs/utils.js +37 -0
  18. package/dist/cjs/utils.js.map +6 -0
  19. package/dist/cjs/utils.native.js +49 -0
  20. package/dist/cjs/utils.native.js.map +6 -0
  21. package/dist/cjs/v3-themes.cjs +12 -27
  22. package/dist/cjs/v3-themes.js +10 -28
  23. package/dist/cjs/v3-themes.js.map +1 -1
  24. package/dist/cjs/v3-themes.native.js +8 -34
  25. package/dist/cjs/v3-themes.native.js.map +2 -2
  26. package/dist/cjs/v4-createTheme.cjs +257 -0
  27. package/dist/cjs/v4-createTheme.js +232 -0
  28. package/dist/cjs/v4-createTheme.js.map +6 -0
  29. package/dist/cjs/v4-createTheme.native.js +284 -0
  30. package/dist/cjs/v4-createTheme.native.js.map +6 -0
  31. package/dist/cjs/v4-default.cjs +102 -0
  32. package/dist/cjs/v4-default.js +89 -0
  33. package/dist/cjs/v4-default.js.map +6 -0
  34. package/dist/cjs/v4-default.native.js +99 -0
  35. package/dist/cjs/v4-default.native.js.map +6 -0
  36. package/dist/cjs/v4-defaultTemplates.cjs +158 -0
  37. package/dist/cjs/v4-defaultTemplates.js +144 -0
  38. package/dist/cjs/v4-defaultTemplates.js.map +6 -0
  39. package/dist/cjs/v4-defaultTemplates.native.js +154 -0
  40. package/dist/cjs/v4-defaultTemplates.native.js.map +6 -0
  41. package/dist/cjs/v4-tamagui-out.cjs +1217 -0
  42. package/dist/cjs/v4-tamagui-out.js +1241 -0
  43. package/dist/cjs/v4-tamagui-out.js.map +6 -0
  44. package/dist/cjs/v4-tamagui-out.native.js +12662 -0
  45. package/dist/cjs/v4-tamagui-out.native.js.map +6 -0
  46. package/dist/cjs/v4-tamagui.cjs +175 -0
  47. package/dist/cjs/v4-tamagui.js +214 -0
  48. package/dist/cjs/v4-tamagui.js.map +6 -0
  49. package/dist/cjs/v4-tamagui.native.js +218 -0
  50. package/dist/cjs/v4-tamagui.native.js.map +6 -0
  51. package/dist/cjs/v4.cjs +41 -0
  52. package/dist/cjs/v4.js +30 -0
  53. package/dist/cjs/v4.js.map +6 -0
  54. package/dist/cjs/v4.native.js +37 -0
  55. package/dist/cjs/v4.native.js.map +6 -0
  56. package/dist/esm/getThemeSuitePalettes.js +47 -0
  57. package/dist/esm/getThemeSuitePalettes.js.map +6 -0
  58. package/dist/esm/getThemeSuitePalettes.mjs +57 -0
  59. package/dist/esm/getThemeSuitePalettes.mjs.map +1 -0
  60. package/dist/esm/getThemeSuitePalettes.native.js +73 -0
  61. package/dist/esm/getThemeSuitePalettes.native.js.map +6 -0
  62. package/dist/esm/types.js +1 -0
  63. package/dist/esm/types.js.map +6 -0
  64. package/dist/esm/types.mjs +2 -0
  65. package/dist/esm/types.mjs.map +1 -0
  66. package/dist/esm/types.native.js +1 -0
  67. package/dist/esm/types.native.js.map +6 -0
  68. package/dist/esm/utils.js +21 -0
  69. package/dist/esm/utils.js.map +6 -0
  70. package/dist/esm/utils.mjs +14 -0
  71. package/dist/esm/utils.mjs.map +1 -0
  72. package/dist/esm/utils.native.js +25 -0
  73. package/dist/esm/utils.native.js.map +6 -0
  74. package/dist/esm/v3-themes.js +2 -19
  75. package/dist/esm/v3-themes.js.map +1 -1
  76. package/dist/esm/v3-themes.mjs +3 -14
  77. package/dist/esm/v3-themes.mjs.map +1 -1
  78. package/dist/esm/v3-themes.native.js +2 -23
  79. package/dist/esm/v3-themes.native.js.map +2 -2
  80. package/dist/esm/v4-createTheme.js +221 -0
  81. package/dist/esm/v4-createTheme.js.map +6 -0
  82. package/dist/esm/v4-createTheme.mjs +226 -0
  83. package/dist/esm/v4-createTheme.mjs.map +1 -0
  84. package/dist/esm/v4-createTheme.native.js +261 -0
  85. package/dist/esm/v4-createTheme.native.js.map +6 -0
  86. package/dist/esm/v4-default.js +74 -0
  87. package/dist/esm/v4-default.js.map +6 -0
  88. package/dist/esm/v4-default.mjs +79 -0
  89. package/dist/esm/v4-default.mjs.map +1 -0
  90. package/dist/esm/v4-default.native.js +80 -0
  91. package/dist/esm/v4-default.native.js.map +6 -0
  92. package/dist/esm/v4-defaultTemplates.js +128 -0
  93. package/dist/esm/v4-defaultTemplates.js.map +6 -0
  94. package/dist/esm/v4-defaultTemplates.mjs +135 -0
  95. package/dist/esm/v4-defaultTemplates.mjs.map +1 -0
  96. package/dist/esm/v4-defaultTemplates.native.js +134 -0
  97. package/dist/esm/v4-defaultTemplates.native.js.map +6 -0
  98. package/dist/esm/v4-tamagui-out.js +1225 -0
  99. package/dist/esm/v4-tamagui-out.js.map +6 -0
  100. package/dist/esm/v4-tamagui-out.mjs +677 -0
  101. package/dist/esm/v4-tamagui-out.mjs.map +1 -0
  102. package/dist/esm/v4-tamagui-out.native.js +12124 -0
  103. package/dist/esm/v4-tamagui-out.native.js.map +6 -0
  104. package/dist/esm/v4-tamagui.js +216 -0
  105. package/dist/esm/v4-tamagui.js.map +6 -0
  106. package/dist/esm/v4-tamagui.mjs +152 -0
  107. package/dist/esm/v4-tamagui.mjs.map +1 -0
  108. package/dist/esm/v4-tamagui.native.js +199 -0
  109. package/dist/esm/v4-tamagui.native.js.map +6 -0
  110. package/dist/esm/v4.js +8 -0
  111. package/dist/esm/v4.js.map +6 -0
  112. package/dist/esm/v4.mjs +5 -0
  113. package/dist/esm/v4.mjs.map +1 -0
  114. package/dist/esm/v4.native.js +8 -0
  115. package/dist/esm/v4.native.js.map +6 -0
  116. package/package.json +17 -7
  117. package/src/getThemeSuitePalettes.ts +94 -0
  118. package/src/types.ts +94 -0
  119. package/src/utils.ts +51 -0
  120. package/src/v3-themes.ts +2 -53
  121. package/src/v4-createTheme.ts +403 -0
  122. package/src/v4-default.ts +88 -0
  123. package/src/v4-defaultTemplates.ts +165 -0
  124. package/src/v4-tamagui-out.ts +1667 -0
  125. package/src/v4-tamagui.ts +232 -0
  126. package/src/v4.tsx +4 -0
  127. package/tsconfig.json +2 -1
  128. package/types/getThemeSuitePalettes.d.ts +7 -0
  129. package/types/types.d.ts +72 -0
  130. package/types/utils.d.ts +21 -0
  131. package/types/v3-themes.d.ts +0 -20
  132. package/types/v4-createTheme.d.ts +157 -0
  133. package/types/v4-default.d.ts +797 -0
  134. package/types/v4-defaultTemplates.d.ts +44 -0
  135. package/types/v4-tamagui-out.d.ts +659 -0
  136. package/types/v4-tamagui.d.ts +15575 -0
  137. package/types/v4.d.ts +4 -0
  138. package/v4.d.ts +1 -0
  139. 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()