@tamagui/themes 1.101.7 → 1.102.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/src/v3-themes.ts CHANGED
@@ -106,7 +106,7 @@ const color = {
106
106
  ...postfixObjKeys(darkColors, 'Dark'),
107
107
  }
108
108
 
109
- export const palettes = (() => {
109
+ export const defaultPalettes = (() => {
110
110
  const transparent = (hsl: string, opacity = 0) =>
111
111
  hsl.replace(`%)`, `%, ${opacity})`).replace(`hsl(`, `hsla(`)
112
112
 
@@ -233,180 +233,185 @@ export const palettes = (() => {
233
233
  }
234
234
  })()
235
235
 
236
- export const getTemplates = (scheme: 'dark' | 'light') => {
237
- const isLight = scheme === 'light'
238
-
239
- // our palettes have 4 things padding each end until you get to bg/color:
240
- // [accentBg, transparent1, transparent2, transparent3, transparent4, background, ...]
241
- const bgIndex = 5
242
- const lighten = isLight ? -1 : 1
243
- const darken = -lighten
244
- const borderColor = bgIndex + 3
245
-
246
- // templates use the palette and specify index
247
- // negative goes backwards from end so -1 is the last item
248
- const base = {
249
- accentBackground: 0,
250
- accentColor: -0,
251
-
252
- background0: 1,
253
- background025: 2,
254
- background05: 3,
255
- background075: 4,
256
- color1: bgIndex,
257
- color2: bgIndex + 1,
258
- color3: bgIndex + 2,
259
- color4: bgIndex + 3,
260
- color5: bgIndex + 4,
261
- color6: bgIndex + 5,
262
- color7: bgIndex + 6,
263
- color8: bgIndex + 7,
264
- color9: bgIndex + 8,
265
- color10: bgIndex + 9,
266
- color11: bgIndex + 10,
267
- color12: bgIndex + 11,
268
- color0: -1,
269
- color025: -2,
270
- color05: -3,
271
- color075: -4,
272
- // the background, color, etc keys here work like generics - they make it so you
273
- // can publish components for others to use without mandating a specific color scale
274
- // the @tamagui/button Button component looks for `$background`, so you set the
275
- // dark_red_Button theme to have a stronger background than the dark_red theme.
276
- background: bgIndex,
277
- backgroundHover: bgIndex + lighten, // always lighten on hover no matter the scheme
278
- backgroundPress: bgIndex + darken, // always darken on press no matter the theme
279
- backgroundFocus: bgIndex + darken,
280
- borderColor,
281
- borderColorHover: borderColor + lighten,
282
- borderColorPress: borderColor + darken,
283
- borderColorFocus: borderColor,
284
- color: -bgIndex,
285
- colorHover: -bgIndex - 1,
286
- colorPress: -bgIndex,
287
- colorFocus: -bgIndex - 1,
288
- colorTransparent: -1,
289
- placeholderColor: -bgIndex - 3,
290
- outlineColor: -2,
291
- }
236
+ const getTemplates = () => {
237
+ const getBaseTemplates = (scheme: 'dark' | 'light') => {
238
+ const isLight = scheme === 'light'
239
+
240
+ // our palettes have 4 things padding each end until you get to bg/color:
241
+ // [accentBg, transparent1, transparent2, transparent3, transparent4, background, ...]
242
+ const bgIndex = 5
243
+ const lighten = isLight ? -1 : 1
244
+ const darken = -lighten
245
+ const borderColor = bgIndex + 3
246
+
247
+ // templates use the palette and specify index
248
+ // negative goes backwards from end so -1 is the last item
249
+ const base = {
250
+ accentBackground: 0,
251
+ accentColor: -0,
252
+
253
+ background0: 1,
254
+ background025: 2,
255
+ background05: 3,
256
+ background075: 4,
257
+ color1: bgIndex,
258
+ color2: bgIndex + 1,
259
+ color3: bgIndex + 2,
260
+ color4: bgIndex + 3,
261
+ color5: bgIndex + 4,
262
+ color6: bgIndex + 5,
263
+ color7: bgIndex + 6,
264
+ color8: bgIndex + 7,
265
+ color9: bgIndex + 8,
266
+ color10: bgIndex + 9,
267
+ color11: bgIndex + 10,
268
+ color12: bgIndex + 11,
269
+ color0: -1,
270
+ color025: -2,
271
+ color05: -3,
272
+ color075: -4,
273
+ // the background, color, etc keys here work like generics - they make it so you
274
+ // can publish components for others to use without mandating a specific color scale
275
+ // the @tamagui/button Button component looks for `$background`, so you set the
276
+ // dark_red_Button theme to have a stronger background than the dark_red theme.
277
+ background: bgIndex,
278
+ backgroundHover: bgIndex + lighten, // always lighten on hover no matter the scheme
279
+ backgroundPress: bgIndex + darken, // always darken on press no matter the theme
280
+ backgroundFocus: bgIndex + darken,
281
+ borderColor,
282
+ borderColorHover: borderColor + lighten,
283
+ borderColorPress: borderColor + darken,
284
+ borderColorFocus: borderColor,
285
+ color: -bgIndex,
286
+ colorHover: -bgIndex - 1,
287
+ colorPress: -bgIndex,
288
+ colorFocus: -bgIndex - 1,
289
+ colorTransparent: -1,
290
+ placeholderColor: -bgIndex - 3,
291
+ outlineColor: -2,
292
+ }
292
293
 
293
- const surface1 = {
294
- background: base.background + 1,
295
- backgroundHover: base.backgroundHover + 1,
296
- backgroundPress: base.backgroundPress + 1,
297
- backgroundFocus: base.backgroundFocus + 1,
298
- borderColor: base.borderColor + 1,
299
- borderColorHover: base.borderColorHover + 1,
300
- borderColorFocus: base.borderColorFocus + 1,
301
- borderColorPress: base.borderColorPress + 1,
302
- }
294
+ const surface1 = {
295
+ background: base.background + 1,
296
+ backgroundHover: base.backgroundHover + 1,
297
+ backgroundPress: base.backgroundPress + 1,
298
+ backgroundFocus: base.backgroundFocus + 1,
299
+ borderColor: base.borderColor + 1,
300
+ borderColorHover: base.borderColorHover + 1,
301
+ borderColorFocus: base.borderColorFocus + 1,
302
+ borderColorPress: base.borderColorPress + 1,
303
+ }
303
304
 
304
- const surface2 = {
305
- background: base.background + 2,
306
- backgroundHover: base.backgroundHover + 2,
307
- backgroundPress: base.backgroundPress + 2,
308
- backgroundFocus: base.backgroundFocus + 2,
309
- borderColor: base.borderColor + 2,
310
- borderColorHover: base.borderColorHover + 2,
311
- borderColorFocus: base.borderColorFocus + 2,
312
- borderColorPress: base.borderColorPress + 2,
313
- }
305
+ const surface2 = {
306
+ background: base.background + 2,
307
+ backgroundHover: base.backgroundHover + 2,
308
+ backgroundPress: base.backgroundPress + 2,
309
+ backgroundFocus: base.backgroundFocus + 2,
310
+ borderColor: base.borderColor + 2,
311
+ borderColorHover: base.borderColorHover + 2,
312
+ borderColorFocus: base.borderColorFocus + 2,
313
+ borderColorPress: base.borderColorPress + 2,
314
+ }
314
315
 
315
- const surface3 = {
316
- background: base.background + 3,
317
- backgroundHover: base.backgroundHover + 3,
318
- backgroundPress: base.backgroundPress + 3,
319
- backgroundFocus: base.backgroundFocus + 3,
320
- borderColor: base.borderColor + 3,
321
- borderColorHover: base.borderColorHover + 3,
322
- borderColorFocus: base.borderColorFocus + 3,
323
- borderColorPress: base.borderColorPress + 3,
324
- }
316
+ const surface3 = {
317
+ background: base.background + 3,
318
+ backgroundHover: base.backgroundHover + 3,
319
+ backgroundPress: base.backgroundPress + 3,
320
+ backgroundFocus: base.backgroundFocus + 3,
321
+ borderColor: base.borderColor + 3,
322
+ borderColorHover: base.borderColorHover + 3,
323
+ borderColorFocus: base.borderColorFocus + 3,
324
+ borderColorPress: base.borderColorPress + 3,
325
+ }
325
326
 
326
- const surfaceActiveBg = {
327
- background: base.background + 5,
328
- backgroundHover: base.background + 5,
329
- backgroundPress: base.backgroundPress + 5,
330
- backgroundFocus: base.backgroundFocus + 5,
331
- }
327
+ const surfaceActiveBg = {
328
+ background: base.background + 5,
329
+ backgroundHover: base.background + 5,
330
+ backgroundPress: base.backgroundPress + 5,
331
+ backgroundFocus: base.backgroundFocus + 5,
332
+ }
332
333
 
333
- const surfaceActive = {
334
- ...surfaceActiveBg,
335
- // match border to background when active
336
- borderColor: surfaceActiveBg.background,
337
- borderColorHover: surfaceActiveBg.backgroundHover,
338
- borderColorFocus: surfaceActiveBg.backgroundFocus,
339
- borderColorPress: surfaceActiveBg.backgroundPress,
340
- }
334
+ const surfaceActive = {
335
+ ...surfaceActiveBg,
336
+ // match border to background when active
337
+ borderColor: surfaceActiveBg.background,
338
+ borderColorHover: surfaceActiveBg.backgroundHover,
339
+ borderColorFocus: surfaceActiveBg.backgroundFocus,
340
+ borderColorPress: surfaceActiveBg.backgroundPress,
341
+ }
341
342
 
342
- const inverseSurface1 = {
343
- color: surface1.background,
344
- colorHover: surface1.backgroundHover,
345
- colorPress: surface1.backgroundPress,
346
- colorFocus: surface1.backgroundFocus,
347
- background: base.color,
348
- backgroundHover: base.colorHover,
349
- backgroundPress: base.colorPress,
350
- backgroundFocus: base.colorFocus,
351
- borderColor: base.color - 2,
352
- borderColorHover: base.color - 3,
353
- borderColorFocus: base.color - 4,
354
- borderColorPress: base.color - 5,
355
- }
343
+ const inverseSurface1 = {
344
+ color: surface1.background,
345
+ colorHover: surface1.backgroundHover,
346
+ colorPress: surface1.backgroundPress,
347
+ colorFocus: surface1.backgroundFocus,
348
+ background: base.color,
349
+ backgroundHover: base.colorHover,
350
+ backgroundPress: base.colorPress,
351
+ backgroundFocus: base.colorFocus,
352
+ borderColor: base.color - 2,
353
+ borderColorHover: base.color - 3,
354
+ borderColorFocus: base.color - 4,
355
+ borderColorPress: base.color - 5,
356
+ }
356
357
 
357
- const inverseActive = {
358
- ...inverseSurface1,
359
- background: base.color - 2,
360
- backgroundHover: base.colorHover - 2,
361
- backgroundPress: base.colorPress - 2,
362
- backgroundFocus: base.colorFocus - 2,
363
- borderColor: base.color - 2 - 2,
364
- borderColorHover: base.color - 3 - 2,
365
- borderColorFocus: base.color - 4 - 2,
366
- borderColorPress: base.color - 5 - 2,
367
- }
358
+ const inverseActive = {
359
+ ...inverseSurface1,
360
+ background: base.color - 2,
361
+ backgroundHover: base.colorHover - 2,
362
+ backgroundPress: base.colorPress - 2,
363
+ backgroundFocus: base.colorFocus - 2,
364
+ borderColor: base.color - 2 - 2,
365
+ borderColorHover: base.color - 3 - 2,
366
+ borderColorFocus: base.color - 4 - 2,
367
+ borderColorPress: base.color - 5 - 2,
368
+ }
368
369
 
369
- const alt1 = {
370
- color: base.color - 1,
371
- colorHover: base.colorHover - 1,
372
- colorPress: base.colorPress - 1,
373
- colorFocus: base.colorFocus - 1,
374
- }
370
+ const alt1 = {
371
+ color: base.color - 1,
372
+ colorHover: base.colorHover - 1,
373
+ colorPress: base.colorPress - 1,
374
+ colorFocus: base.colorFocus - 1,
375
+ }
376
+
377
+ const alt2 = {
378
+ color: base.color - 2,
379
+ colorHover: base.colorHover - 2,
380
+ colorPress: base.colorPress - 2,
381
+ colorFocus: base.colorFocus - 2,
382
+ }
375
383
 
376
- const alt2 = {
377
- color: base.color - 2,
378
- colorHover: base.colorHover - 2,
379
- colorPress: base.colorPress - 2,
380
- colorFocus: base.colorFocus - 2,
384
+ return {
385
+ base,
386
+ alt1,
387
+ alt2,
388
+ surface1,
389
+ surface2,
390
+ surface3,
391
+ inverseSurface1,
392
+ inverseActive,
393
+ surfaceActive,
394
+ }
381
395
  }
382
396
 
383
- return {
384
- base,
385
- alt1,
386
- alt2,
387
- surface1,
388
- surface2,
389
- surface3,
390
- inverseSurface1,
391
- inverseActive,
392
- surfaceActive,
397
+ const lightTemplates = getBaseTemplates('light')
398
+ const darkTemplates = getBaseTemplates('dark')
399
+ const templates = {
400
+ ...objectFromEntries(
401
+ objectKeys(lightTemplates).map(
402
+ (name) => [`light_${name}`, lightTemplates[name]] as const
403
+ )
404
+ ),
405
+ ...objectFromEntries(
406
+ objectKeys(darkTemplates).map(
407
+ (name) => [`dark_${name}`, darkTemplates[name]] as const
408
+ )
409
+ ),
393
410
  }
411
+ return templates as Record<keyof typeof templates, typeof lightTemplates.base>
394
412
  }
395
413
 
396
- const lightTemplates = getTemplates('light')
397
- const darkTemplates = getTemplates('dark')
398
- const templates = {
399
- ...objectFromEntries(
400
- objectKeys(lightTemplates).map(
401
- (name) => [`light_${name}`, lightTemplates[name]] as const
402
- )
403
- ),
404
- ...objectFromEntries(
405
- objectKeys(darkTemplates).map(
406
- (name) => [`dark_${name}`, darkTemplates[name]] as const
407
- )
408
- ),
409
- }
414
+ export const defaultTemplates = getTemplates()
410
415
 
411
416
  const shadows = {
412
417
  light: {
@@ -493,11 +498,69 @@ const surface3 = [
493
498
  },
494
499
  ] as any
495
500
 
501
+ export const componentThemes = {
502
+ ListItem: {
503
+ template: 'surface1',
504
+ },
505
+ SelectTrigger: surface1,
506
+ Card: surface1,
507
+ Button: surface3,
508
+ Checkbox: surface2,
509
+ Switch: surface2,
510
+ SwitchThumb: inverseSurface1,
511
+ TooltipContent: surface2,
512
+ Progress: {
513
+ template: 'surface1',
514
+ },
515
+ RadioGroupItem: surface2,
516
+ TooltipArrow: {
517
+ template: 'surface1',
518
+ },
519
+ SliderTrackActive: {
520
+ template: 'surface3',
521
+ },
522
+ SliderTrack: {
523
+ template: 'surface1',
524
+ },
525
+ SliderThumb: inverseSurface1,
526
+ Tooltip: inverseSurface1,
527
+ ProgressIndicator: inverseSurface1,
528
+ SheetOverlay: overlayThemeDefinitions,
529
+ DialogOverlay: overlayThemeDefinitions,
530
+ ModalOverlay: overlayThemeDefinitions,
531
+ Input: surface1,
532
+ TextArea: surface1,
533
+ } as const
534
+
535
+ export const defaultSubThemes = {
536
+ alt1: {
537
+ template: 'alt1',
538
+ },
539
+ alt2: {
540
+ template: 'alt2',
541
+ },
542
+ active: {
543
+ template: 'surface3',
544
+ },
545
+ surface1: {
546
+ template: 'surface1',
547
+ },
548
+ surface2: {
549
+ template: 'surface2',
550
+ },
551
+ surface3: {
552
+ template: 'surface3',
553
+ },
554
+ surface4: {
555
+ template: 'surfaceActive',
556
+ },
557
+ } as const
558
+
496
559
  // --- themeBuilder ---
497
560
 
498
561
  const themeBuilder = createThemeBuilder()
499
- .addPalettes(palettes)
500
- .addTemplates(templates)
562
+ .addPalettes(defaultPalettes)
563
+ .addTemplates(defaultTemplates)
501
564
  .addThemes({
502
565
  light: {
503
566
  template: 'base',
@@ -544,81 +607,20 @@ const themeBuilder = createThemeBuilder()
544
607
  template: 'base',
545
608
  },
546
609
  })
547
- .addChildThemes({
548
- alt1: {
549
- template: 'alt1',
550
- },
551
- alt2: {
552
- template: 'alt2',
553
- },
554
- active: {
555
- template: 'surface3',
556
- },
557
- surface1: {
558
- template: 'surface1',
559
- },
560
- surface2: {
561
- template: 'surface2',
562
- },
563
- surface3: {
564
- template: 'surface3',
565
- },
566
- surface4: {
567
- template: 'surfaceActive',
568
- },
610
+ .addChildThemes(defaultSubThemes)
611
+ .addComponentThemes(componentThemes, {
612
+ avoidNestingWithin: ['alt1', 'alt2', 'surface1', 'surface2', 'surface3', 'surface4'],
569
613
  })
570
- .addComponentThemes(
571
- {
572
- ListItem: {
573
- template: 'surface1',
574
- },
575
- SelectTrigger: surface1,
576
- Card: surface1,
577
- Button: surface3,
578
- Checkbox: surface2,
579
- Switch: surface2,
580
- SwitchThumb: inverseSurface1,
581
- TooltipContent: surface2,
582
- Progress: {
583
- template: 'surface1',
584
- },
585
- RadioGroupItem: surface2,
586
- TooltipArrow: {
587
- template: 'surface1',
588
- },
589
- SliderTrackActive: {
590
- template: 'surface3',
591
- },
592
- SliderTrack: {
593
- template: 'surface1',
594
- },
595
- SliderThumb: inverseSurface1,
596
- Tooltip: inverseSurface1,
597
- ProgressIndicator: inverseSurface1,
598
- SheetOverlay: overlayThemeDefinitions,
599
- DialogOverlay: overlayThemeDefinitions,
600
- ModalOverlay: overlayThemeDefinitions,
601
- Input: surface1,
602
- TextArea: surface1,
603
- },
604
- {
605
- avoidNestingWithin: [
606
- 'alt1',
607
- 'alt2',
608
- 'surface1',
609
- 'surface2',
610
- 'surface3',
611
- 'surface4',
612
- ],
613
- }
614
- )
615
614
 
616
615
  // --- themes ---
617
616
 
618
617
  const themesIn = themeBuilder.build()
619
618
 
620
- export type Theme = Record<keyof typeof lightTemplates.base, string> &
621
- typeof nonInherited.light
619
+ type ThemeKeys =
620
+ | keyof typeof defaultTemplates.light_base
621
+ | keyof typeof nonInherited.light
622
+
623
+ export type Theme = Record<ThemeKeys, string>
622
624
 
623
625
  export type ThemesOut = Record<keyof typeof themesIn, Theme>
624
626