@a-type/ui 1.8.9 → 1.8.10

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 (37) hide show
  1. package/dist/cjs/colorMode.d.ts +1 -0
  2. package/dist/cjs/colorMode.js +10 -0
  3. package/dist/cjs/colorMode.js.map +1 -1
  4. package/dist/cjs/components/card/Card.d.ts +1 -1
  5. package/dist/cjs/hooks/index.d.ts +1 -0
  6. package/dist/cjs/hooks/index.js +1 -0
  7. package/dist/cjs/hooks/index.js.map +1 -1
  8. package/dist/cjs/hooks/useOverrideTheme.d.ts +2 -0
  9. package/dist/cjs/hooks/useOverrideTheme.js +17 -0
  10. package/dist/cjs/hooks/useOverrideTheme.js.map +1 -0
  11. package/dist/cjs/themes.stories.d.ts +2 -0
  12. package/dist/cjs/themes.stories.js +16 -2
  13. package/dist/cjs/themes.stories.js.map +1 -1
  14. package/dist/cjs/uno.preset.js +148 -127
  15. package/dist/cjs/uno.preset.js.map +1 -1
  16. package/dist/css/main.css +591 -126
  17. package/dist/esm/colorMode.d.ts +1 -0
  18. package/dist/esm/colorMode.js +9 -0
  19. package/dist/esm/colorMode.js.map +1 -1
  20. package/dist/esm/components/card/Card.d.ts +1 -1
  21. package/dist/esm/hooks/index.d.ts +1 -0
  22. package/dist/esm/hooks/index.js +1 -0
  23. package/dist/esm/hooks/index.js.map +1 -1
  24. package/dist/esm/hooks/useOverrideTheme.d.ts +2 -0
  25. package/dist/esm/hooks/useOverrideTheme.js +14 -0
  26. package/dist/esm/hooks/useOverrideTheme.js.map +1 -0
  27. package/dist/esm/themes.stories.d.ts +2 -0
  28. package/dist/esm/themes.stories.js +16 -2
  29. package/dist/esm/themes.stories.js.map +1 -1
  30. package/dist/esm/uno.preset.js +148 -127
  31. package/dist/esm/uno.preset.js.map +1 -1
  32. package/package.json +1 -1
  33. package/src/colorMode.ts +10 -0
  34. package/src/hooks/index.ts +1 -0
  35. package/src/hooks/useOverrideTheme.ts +14 -0
  36. package/src/themes.stories.tsx +36 -2
  37. package/src/uno.preset.ts +178 -127
package/src/colorMode.ts CHANGED
@@ -57,6 +57,16 @@ export function getColorMode(): 'system' | 'light' | 'dark' {
57
57
  return (window.localStorage.getItem('colorMode') as any) || 'system';
58
58
  }
59
59
 
60
+ export function getResolvedColorMode(): 'light' | 'dark' {
61
+ const mode = getColorMode();
62
+ if (mode === 'system') {
63
+ return window.matchMedia('(prefers-color-scheme: dark)').matches
64
+ ? 'dark'
65
+ : 'light';
66
+ }
67
+ return mode;
68
+ }
69
+
60
70
  export function subscribeToColorModeChange(
61
71
  callback: (mode: 'system' | 'light' | 'dark') => void,
62
72
  ) {
@@ -2,6 +2,7 @@ export * from './useAnimationFrame.js';
2
2
  export * from './useLongPress.js';
3
3
  export * from './useMergedRef.js';
4
4
  export * from './useOnUnmount.js';
5
+ export * from './useOverrideTheme.js';
5
6
  export * from './useSize.js';
6
7
  export * from './useStableCallback.js';
7
8
  export * from './useTitleBarColor.js';
@@ -0,0 +1,14 @@
1
+ import { useLayoutEffect } from 'react';
2
+ import { ThemeName } from '../components/index.js';
3
+
4
+ export function useOverrideTheme(theme: ThemeName | null | undefined) {
5
+ useLayoutEffect(() => {
6
+ if (!theme) {
7
+ return;
8
+ }
9
+ document.body.classList.add(`theme-override-${theme}`);
10
+ return () => {
11
+ document.body.classList.remove(`theme-override-${theme}`);
12
+ };
13
+ }, [theme]);
14
+ }
@@ -1,5 +1,6 @@
1
1
  import type { Meta, StoryObj } from '@storybook/react';
2
2
  import clsx from 'clsx';
3
+ import { useState } from 'react';
3
4
  import { ActionBar, ActionButton } from './components/actions/index.js';
4
5
  import { Button } from './components/button/index.js';
5
6
  import { Card } from './components/card/index.js';
@@ -8,6 +9,7 @@ import {
8
9
  AvatarList,
9
10
  Box,
10
11
  Checkbox,
12
+ ColorPicker,
11
13
  ContextMenu,
12
14
  DateRangePicker,
13
15
  Dialog,
@@ -30,13 +32,16 @@ import {
30
32
  PageNav,
31
33
  PageRoot,
32
34
  Progress,
35
+ Provider,
33
36
  TextSkeleton,
37
+ ThemeName,
34
38
  ToggleGroup,
35
39
  Tooltip,
36
40
  } from './components/index.js';
37
41
  import { Input } from './components/input/index.js';
38
42
  import { Tabs } from './components/tabs/tabs.js';
39
43
  import { TextArea } from './components/textArea/index.js';
44
+ import { useOverrideTheme } from './hooks/useOverrideTheme.js';
40
45
 
41
46
  const meta = {
42
47
  title: 'themes',
@@ -55,9 +60,9 @@ function DemoUI({ className }: { className?: string }) {
55
60
  const nextWeek = new Date();
56
61
  nextWeek.setDate(nextWeek.getDate() + 7);
57
62
  return (
58
- <PageRoot>
63
+ <PageRoot className={clsx('flex-1', className)}>
59
64
  <PageContent>
60
- <div className={clsx('grid gap-2 grid-cols-2', className)}>
65
+ <div className={clsx('grid gap-2 grid-cols-2')}>
61
66
  <Box gap wrap p>
62
67
  <Button color="primary">Primary</Button>
63
68
  <Button color="accent">Accent</Button>
@@ -159,6 +164,7 @@ function DemoUI({ className }: { className?: string }) {
159
164
  <Dialog.Description>Im a dialog</Dialog.Description>
160
165
  <Dialog.Actions>
161
166
  <Dialog.Close>Close</Dialog.Close>
167
+ <Button color="primary">Action</Button>
162
168
  </Dialog.Actions>
163
169
  </Dialog.Content>
164
170
  </Dialog>
@@ -247,3 +253,31 @@ export const Default: Story = {
247
253
  return <DemoUI />;
248
254
  },
249
255
  };
256
+
257
+ export const Nesting: Story = {
258
+ render() {
259
+ return (
260
+ <Box d="col" p gap>
261
+ <Box d="row" gap surface="primary">
262
+ <Button color="primary">Root theme</Button>
263
+ </Box>
264
+ <DemoUI className="theme-eggplant override-dark flex-1" />
265
+ </Box>
266
+ );
267
+ },
268
+ };
269
+
270
+ export const Override: Story = {
271
+ render() {
272
+ const [theme, setTheme] = useState<ThemeName | null>(null);
273
+ useOverrideTheme(theme);
274
+ return (
275
+ <Provider>
276
+ <Box d="col" p gap>
277
+ <ColorPicker value={theme} onChange={setTheme} />
278
+ <DemoUI />
279
+ </Box>
280
+ </Provider>
281
+ );
282
+ },
283
+ };
package/src/uno.preset.ts CHANGED
@@ -603,6 +603,69 @@ export default function presetAglio({
603
603
  --color-shadow-2: var(--palette-shadow-3);
604
604
  --color-overlay: var(--palette-black-overlay);
605
605
  `;
606
+
607
+ const lemon = themeVars({
608
+ primary: 'yellow',
609
+ accent: 'green',
610
+ grayTweak: -20,
611
+ });
612
+ const leek = themeVars({
613
+ primary: 'green',
614
+ accent: 'blue',
615
+ grayTweak: 20,
616
+ });
617
+ const tomato = themeVars({
618
+ primary: 'magenta',
619
+ accent: 'green',
620
+ grayTweak: -20,
621
+ });
622
+ const blueberry = themeVars({
623
+ primary: 'blue',
624
+ accent: 'green',
625
+ grayTweak: 20,
626
+ });
627
+ const eggplant = themeVars({
628
+ primary: 'purple',
629
+ accent: 'green',
630
+ grayTweak: -20,
631
+ });
632
+ const salt = themeVars({
633
+ primary: 'true-gray',
634
+ accent: {
635
+ default: 'true-gray-light',
636
+ wash: 'white',
637
+ light: 'true-gray-wash',
638
+ dark: 'true-gray',
639
+ },
640
+ globalSaturation: 0,
641
+ });
642
+
643
+ const computedVars = `
644
+ --palette-gray-wash: hsl(from var(--color-primary-wash) calc(h + var(--gray-hue-tweak, 0)) calc(s * var(--wash-saturation-tweak, 1) * var(--global-saturation, 1)) calc(l * pow(1.025, var(--mode-mult,1))));
645
+ --palette-gray: hsl(from var(--color-primary) calc(h + var(--gray-hue-tweak, 0)) calc(s * var(--global-saturation, 1)) calc(l * 1.125));
646
+ --palette-gray-dark: hsl(from var(--color-primary-dark) calc(h + var(--gray-hue-tweak, 0)) calc(s * 0.75 * var(--global-saturation, 1)) calc(l * pow(1.125, var(--mode-mult,1))));
647
+ --palette-gray-light: hsl(from var(--color-primary-light) calc(h + var(--gray-hue-tweak, 0) * pow(2, var(--mode-mult, 1))) calc(s * 0.5 * var(--global-saturation, 1)) calc(l * pow(1.25, var(--mode-mult,1))));
648
+ --color-wash: var(--color-gray-wash);
649
+ --color-gray-wash: var(--palette-gray-wash);
650
+ --color-gray: var(--palette-gray);
651
+ --color-gray-dark: var(--palette-gray-dark);
652
+ --color-gray-light: var(--palette-gray-light);
653
+ --palette-gray-1: var(--color-gray-wash);
654
+ --palette-gray-2: var(--color-gray-light);
655
+ --palette-gray-3: var(--color-gray-light);
656
+ --palette-gray-4: var(--color-gray);
657
+ --palette-gray-5: var(--color-gray);
658
+ --palette-gray-6: var(--color-gray);
659
+ --palette-gray-7: var(--color-gray-dark);
660
+ --palette-gray-8: var(--color-gray-dark);
661
+ --palette-gray-9: var(--color-black);
662
+ --palette-gray-0: var(--color-black);
663
+ --palette-gray-ex-1: var(--color-black);
664
+ --palette-gray-ex-2: var(--color-black);
665
+ --palette-white: hsl(from var(--color-wash) calc(h + 0) calc(s * 0.3 * var(--global-saturation, 1)) calc(min(100, l + 1 / var(--global-saturation, 1))));
666
+ --palette-black: hsl(from var(--color-gray-dark) calc(h + 0) calc(s * 0.1 * var(--global-saturation, 1)) calc(min(100, l / (var(--mode-mult,1) * -5 + pow(1 + var(--global-saturation, 1), 1.5)))));
667
+ `;
668
+
606
669
  return `
607
670
  @layer preflightBase, preflightVariant, components, responsive, variants, utilities;
608
671
 
@@ -617,6 +680,17 @@ export default function presetAglio({
617
680
  --palette-red-20: #804020;
618
681
  --palette-red-10: #702604;
619
682
  --palette-red-00:rgb(37, 28, 25);
683
+ /* TODO: define these */
684
+ --palette-magenta-90: hsl(from rgb(255, 244, 240) calc(h - 20) s l);
685
+ --palette-magenta-80: hsl(from #ffdbcf calc(h - 20) s l);
686
+ --palette-magenta-70: hsl(from #ffbea6 calc(h - 20) s l);
687
+ --palette-magenta-60: hsl(from #fdad8e calc(h - 20) s l);
688
+ --palette-magenta-50: hsl(from #ff8e61 calc(h - 20) s l);
689
+ --palette-magenta-40: hsl(from #d56f46 calc(h - 20) s l);
690
+ --palette-magenta-30: hsl(from #ae562d calc(h - 20) s l);
691
+ --palette-magenta-20: hsl(from #804020 calc(h - 20) s l);
692
+ --palette-magenta-10: hsl(from #702604 calc(h - 20) s l);
693
+ --palette-magenta-00: hsl(from rgb(37, 28, 25) calc(h - 20) s l);
620
694
  --palette-green-90:rgb(242, 251, 247);
621
695
  --palette-green-80: #c2ffe9;
622
696
  --palette-green-70: #92f2d1;
@@ -637,7 +711,7 @@ export default function presetAglio({
637
711
  --palette-yellow-20:rgb(111, 83, 23);
638
712
  --palette-yellow-10:rgb(84, 62, 12);
639
713
  --palette-yellow-00:rgb(37, 33, 22);
640
- --palette-blue-90: rgb(239, 249, 256);
714
+ --palette-blue-90: rgb(238, 248, 255);
641
715
  --palette-blue-80: #c4e7ff;
642
716
  --palette-blue-70: #87d3fc;
643
717
  --palette-blue-60: #5fcefe;
@@ -681,40 +755,15 @@ export default function presetAglio({
681
755
  --palette-true-gray-20: #4f4f4f;
682
756
  --palette-true-gray-10: #383838;
683
757
  --palette-true-gray-00: #1f1f1f;
758
+ --palette-true-white: #ffffff;
759
+ --palette-true-black: #303030;
684
760
 
685
761
  --global-saturation: ${saturationScale};
686
762
  --global-corner-scale: ${cornerScale};
687
763
  --global-border-scale: ${borderScale};
688
764
  --global-spacing-scale: ${spacingScale};
689
765
 
690
- --palette-gray-wash: hsl(from var(--color-primary-wash) calc(h + var(--gray-hue-tweak, 0)) calc(s * var(--wash-saturation-tweak, 1) * var(--global-saturation, 1)) calc(l * pow(1.025, var(--mode-mult,1))));
691
- --palette-gray: hsl(from var(--color-primary) calc(h + var(--gray-hue-tweak, 0)) calc(s * var(--global-saturation, 1)) calc(l * 1.125));
692
- --palette-gray-dark: hsl(from var(--color-primary-dark) calc(h + var(--gray-hue-tweak, 0)) calc(s * 0.75 * var(--global-saturation, 1)) calc(l * pow(1.125, var(--mode-mult,1))));
693
- --palette-gray-light: hsl(from var(--color-primary-light) calc(h + var(--gray-hue-tweak, 0) * pow(2, var(--mode-mult, 1))) calc(s * 0.5 * var(--global-saturation, 1)) calc(l * pow(1.25, var(--mode-mult,1))));
694
- --color-wash: var(--color-gray-wash);
695
-
696
- --color-gray-wash: var(--palette-gray-wash);
697
- --color-gray: var(--palette-gray);
698
- --color-gray-dark: var(--palette-gray-dark);
699
- --color-gray-light: var(--palette-gray-light);
700
-
701
- --palette-gray-1: var(--color-gray-wash);
702
- --palette-gray-2: var(--color-gray-light);
703
- --palette-gray-3: var(--color-gray-light);
704
- --palette-gray-4: var(--color-gray);
705
- --palette-gray-5: var(--color-gray);
706
- --palette-gray-6: var(--color-gray);
707
- --palette-gray-7: var(--color-gray-dark);
708
- --palette-gray-8: var(--color-gray-dark);
709
- --palette-gray-9: var(--color-black);
710
- --palette-gray-0: var(--color-black);
711
- --palette-gray-ex-1: var(--color-black);
712
- --palette-gray-ex-2: var(--color-black);
713
-
714
- --palette-true-white: #ffffff;
715
- --palette-true-black: #303030;
716
- --palette-white: hsl(from var(--color-wash) calc(h + 0) calc(s * 0.3 * var(--global-saturation, 1)) calc(min(100, l + 1 / var(--global-saturation, 1))));
717
- --palette-black: hsl(from var(--color-gray-dark) calc(h + 0) calc(s * 0.1 * var(--global-saturation, 1)) calc(min(100, l / (var(--mode-mult,1) * -5 + pow(1 + var(--global-saturation, 1), 1.5)))));
766
+ ${computedVars}
718
767
 
719
768
  --z-nowPlaying: 40;
720
769
  --z-nav: 50;
@@ -732,19 +781,7 @@ export default function presetAglio({
732
781
  ${lightMode}
733
782
 
734
783
  /* DEFAULT THEME (LEMON) */
735
- --color-attention-light: var(--color-red-light);
736
- --color-attention: var(--color-red);
737
- --color-attention-dark: var(--color-red-dark);
738
- --color-attention-wash: var(--color-red-wash);
739
- --color-accent: var(--color-green);
740
- --color-accent-wash: var(--color-green-wash);
741
- --color-accent-light: var(--color-green-light);
742
- --color-accent-dark: var(--color-green-dark);
743
- --color-primary: var(--color-yellow);
744
- --color-primary-light: var(--color-yellow-light);
745
- --color-primary-dark: var(--color-yellow-dark);
746
- --color-primary-wash: var(--color-yellow-wash);
747
- --gray-hue-tweak: -30;
784
+ ${lemon}
748
785
  }
749
786
 
750
787
  /* INTRINSIC DARK THEME */
@@ -755,20 +792,8 @@ export default function presetAglio({
755
792
  }
756
793
 
757
794
  .theme-lemon {
758
- --color-attention-light: var(--color-red-light);
759
- --color-attention: var(--color-red);
760
- --color-attention-dark: var(--color-red-dark);
761
- --color-attention-wash: var(--color-red-wash);
762
- --color-accent: var(--color-green);
763
- --color-accent-wash: var(--color-green-wash);
764
- --color-accent-light: var(--color-green-light);
765
- --color-accent-dark: var(--color-green-dark);
766
- --color-primary: var(--color-yellow);
767
- --color-primary-light: var(--color-yellow-light);
768
- --color-primary-dark: var(--color-yellow-dark);
769
- --color-primary-wash: var(--color-yellow-wash);
770
-
771
- --gray-hue-tweak: -20;
795
+ ${lemon}
796
+ ${computedVars}
772
797
  }
773
798
 
774
799
  /* fix yellow hue in dark mode */
@@ -787,88 +812,28 @@ export default function presetAglio({
787
812
  }
788
813
 
789
814
  .theme-blueberry {
790
- --color-attention-light: var(--color-red-light);
791
- --color-attention: var(--color-red);
792
- --color-attention-dark: var(--color-red-dark);
793
- --color-attention-wash: var(--color-red-wash);
794
- --color-accent: var(--color-green);
795
- --color-accent-wash: var(--color-green-wash);
796
- --color-accent-light: var(--color-green-light);
797
- --color-accent-dark: var(--color-green-dark);
798
- --color-primary: var(--color-blue);
799
- --color-primary-light: var(--color-blue-light);
800
- --color-primary-dark: var(--color-blue-dark);
801
- --color-primary-wash: var(--color-blue-wash);
802
-
803
- --gray-hue-tweak: 20;
815
+ ${blueberry}
816
+ ${computedVars}
804
817
  }
805
818
 
806
819
  .theme-eggplant {
807
- --color-attention-light: var(--color-red-light);
808
- --color-attention: var(--color-red);
809
- --color-attention-dark: var(--color-red-dark);
810
- --color-attention-wash: var(--color-red-wash);
811
- --color-accent: var(--color-green);
812
- --color-accent-wash: var(--color-green-wash);
813
- --color-accent-light: var(--color-green-light);
814
- --color-accent-dark: var(--color-green-dark);
815
- --color-primary: var(--color-purple);
816
- --color-primary-light: var(--color-purple-light);
817
- --color-primary-dark: var(--color-purple-dark);
818
- --color-primary-wash: var(--color-purple-wash);
819
-
820
- --gray-hue-tweak: -20;
820
+ ${eggplant}
821
+ ${computedVars}
821
822
  }
822
823
 
823
824
  .theme-leek {
824
- --color-attention-light: var(--color-red-light);
825
- --color-attention: var(--color-red);
826
- --color-attention-dark: var(--color-red-dark);
827
- --color-attention-wash: var(--color-red-wash);
828
- --color-accent: var(--color-blue);
829
- --color-accent-wash: var(--color-blue-wash);
830
- --color-accent-light: var(--color-blue-light);
831
- --color-accent-dark: var(--color-blue-dark);
832
- --color-primary: var(--color-green);
833
- --color-primary-light: var(--color-green-light);
834
- --color-primary-dark: var(--color-green-dark);
835
- --color-primary-wash: var(--color-green-wash);
836
-
837
- --gray-hue-tweak: 20;
825
+ ${leek}
826
+ ${computedVars}
838
827
  }
839
828
 
840
829
  .theme-tomato {
841
- --color-attention-light: var(--color-red-light);
842
- --color-attention: var(--color-red);
843
- --color-attention-dark: var(--color-red-dark);
844
- --color-attention-wash: var(--color-red-wash);
845
- --color-accent: var(--color-green);
846
- --color-accent-wash: var(--color-green-wash);
847
- --color-accent-light: var(--color-green-light);
848
- --color-accent-dark: var(--color-green-dark);
849
- --color-primary: hsl(from var(--color-red) calc(h - 20) s l);
850
- --color-primary-light: hsl(from var(--color-red-light) calc(h - 20) s l);
851
- --color-primary-dark: hsl(from var(--color-red-dark) calc(h - 20) s l);
852
- --color-primary-wash: hsl(from var(--color-red-wash) calc(h - 20) s l);
853
-
854
- --gray-hue-tweak: -20;
830
+ ${tomato}
831
+ ${computedVars}
855
832
  }
856
833
 
857
834
  .theme-salt {
858
- --color-attention-light: var(--color-red-light);
859
- --color-attention: var(--color-red);
860
- --color-attention-dark: var(--color-red-dark);
861
- --color-attention-wash: var(--color-red-wash);
862
- --color-primary: var(--color-true-gray);
863
- --color-primary-wash: var(--color-true-gray-wash);
864
- --color-primary-light: var(--color-true-gray-light);
865
- --color-primary-dark: var(--color-true-gray-dark);
866
- --color-accent: var(--color-true-gray-light);
867
- --color-accent-light: var(--color-true-gray-wash);
868
- --color-accent-dark: var(--color-true-gray);
869
- --color-accent-wash: var(--color-white);
870
-
871
- --global-saturation: 0;
835
+ ${salt}
836
+ ${computedVars}
872
837
  }
873
838
 
874
839
  html, body {
@@ -902,10 +867,37 @@ export default function presetAglio({
902
867
  /** SYSTEM OVERRIDES **/
903
868
  .override-light {
904
869
  ${lightMode}
870
+ color: var(--color-black);
905
871
  }
906
872
 
907
873
  .override-dark {
908
874
  ${darkMode}
875
+ color: var(--color-black);
876
+ }
877
+
878
+ .theme-override-lemon {
879
+ ${lemon}
880
+ ${computedVars}
881
+ }
882
+ .theme-override-blueberry {
883
+ ${blueberry}
884
+ ${computedVars}
885
+ }
886
+ .theme-override-eggplant {
887
+ ${eggplant}
888
+ ${computedVars}
889
+ }
890
+ .theme-override-leek {
891
+ ${leek}
892
+ ${computedVars}
893
+ }
894
+ .theme-override-tomato {
895
+ ${tomato}
896
+ ${computedVars}
897
+ }
898
+ .theme-override-salt {
899
+ ${salt}
900
+ ${computedVars}
909
901
  }
910
902
  }
911
903
 
@@ -955,7 +947,15 @@ export default function presetAglio({
955
947
  };
956
948
  }
957
949
 
958
- const themeColors = ['red', 'green', 'yellow', 'blue', 'purple', 'true-gray'];
950
+ const themeColors = [
951
+ 'red',
952
+ 'magenta',
953
+ 'green',
954
+ 'yellow',
955
+ 'blue',
956
+ 'purple',
957
+ 'true-gray',
958
+ ];
959
959
  function roundTens(num: number) {
960
960
  return Math.round(num / 10) * 10;
961
961
  }
@@ -1054,3 +1054,54 @@ function darken(base: string, level: string) {
1054
1054
  const levelNum = parseFloat(level);
1055
1055
  return lighten(base, (levelNum / -15).toString());
1056
1056
  }
1057
+
1058
+ function themeVars({
1059
+ primary,
1060
+ accent,
1061
+ grayTweak,
1062
+ globalSaturation,
1063
+ }: {
1064
+ primary: string | ExplicitColorRange;
1065
+ accent: string | ExplicitColorRange;
1066
+ grayTweak?: number;
1067
+ globalSaturation?: number;
1068
+ }) {
1069
+ return `
1070
+ ${themeVarRange({ name: 'attention', range: 'red' })}
1071
+ ${themeVarRange({ name: 'accent', range: accent })}
1072
+ ${themeVarRange({ name: 'primary', range: primary })}
1073
+
1074
+ --gray-hue-tweak: ${grayTweak ?? 0};
1075
+ ${
1076
+ globalSaturation !== undefined
1077
+ ? `--global-saturation: ${globalSaturation};`
1078
+ : ''
1079
+ }
1080
+ `;
1081
+ }
1082
+
1083
+ type ExplicitColorRange = {
1084
+ default: string;
1085
+ wash: string;
1086
+ light: string;
1087
+ dark: string;
1088
+ };
1089
+ function themeVarRange({
1090
+ name,
1091
+ range,
1092
+ }: {
1093
+ name: string;
1094
+ range: string | ExplicitColorRange;
1095
+ }) {
1096
+ if (typeof range === 'string') {
1097
+ return `--color-${name}: var(--color-${range});
1098
+ --color-${name}-wash: var(--color-${range}-wash);
1099
+ --color-${name}-light: var(--color-${range}-light);
1100
+ --color-${name}-dark: var(--color-${range}-dark);`;
1101
+ }
1102
+
1103
+ return `--color-${name}: var(--color-${range.default});
1104
+ --color-${name}-wash: var(--color-${range.wash});
1105
+ --color-${name}-light: var(--color-${range.light});
1106
+ --color-${name}-dark: var(--color-${range.dark});`;
1107
+ }