@dxos/ui-theme 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/LICENSE +8 -0
  2. package/README.md +25 -0
  3. package/package.json +80 -0
  4. package/src/Tokens.stories.tsx +88 -0
  5. package/src/config/index.ts +6 -0
  6. package/src/config/tailwind.ts +250 -0
  7. package/src/config/tokens/alias-colors.ts +39 -0
  8. package/src/config/tokens/index.ts +92 -0
  9. package/src/config/tokens/lengths.ts +97 -0
  10. package/src/config/tokens/physical-colors.ts +125 -0
  11. package/src/config/tokens/semantic-colors.ts +27 -0
  12. package/src/config/tokens/sememes-calls.ts +17 -0
  13. package/src/config/tokens/sememes-codemirror.ts +50 -0
  14. package/src/config/tokens/sememes-hue.ts +54 -0
  15. package/src/config/tokens/sememes-sheet.ts +62 -0
  16. package/src/config/tokens/sememes-system.ts +302 -0
  17. package/src/config/tokens/sizes.ts +7 -0
  18. package/src/config/tokens/types.ts +9 -0
  19. package/src/docs/theme.drawio.svg +635 -0
  20. package/src/index.ts +19 -0
  21. package/src/plugins/esbuild-plugin.ts +65 -0
  22. package/src/plugins/plugin.ts +130 -0
  23. package/src/plugins/resolveContent.ts +51 -0
  24. package/src/styles/components/README.md +6 -0
  25. package/src/styles/components/anchored-overflow.ts +20 -0
  26. package/src/styles/components/avatar.ts +96 -0
  27. package/src/styles/components/breadcrumb.ts +29 -0
  28. package/src/styles/components/button.ts +48 -0
  29. package/src/styles/components/dialog.ts +36 -0
  30. package/src/styles/components/icon-button.ts +20 -0
  31. package/src/styles/components/icon.ts +19 -0
  32. package/src/styles/components/index.ts +27 -0
  33. package/src/styles/components/input.ts +177 -0
  34. package/src/styles/components/link.ts +26 -0
  35. package/src/styles/components/list.ts +46 -0
  36. package/src/styles/components/main.ts +36 -0
  37. package/src/styles/components/menu.ts +60 -0
  38. package/src/styles/components/message.ts +36 -0
  39. package/src/styles/components/popover.ts +40 -0
  40. package/src/styles/components/scroll-area.ts +43 -0
  41. package/src/styles/components/select.ts +60 -0
  42. package/src/styles/components/separator.ts +24 -0
  43. package/src/styles/components/status.ts +32 -0
  44. package/src/styles/components/tag.ts +23 -0
  45. package/src/styles/components/toast.ts +55 -0
  46. package/src/styles/components/toolbar.ts +29 -0
  47. package/src/styles/components/tooltip.ts +29 -0
  48. package/src/styles/components/treegrid.ts +37 -0
  49. package/src/styles/fragments/density.ts +17 -0
  50. package/src/styles/fragments/dimension.ts +8 -0
  51. package/src/styles/fragments/disabled.ts +6 -0
  52. package/src/styles/fragments/elevation.ts +29 -0
  53. package/src/styles/fragments/focus.ts +16 -0
  54. package/src/styles/fragments/group.ts +12 -0
  55. package/src/styles/fragments/hover.ts +25 -0
  56. package/src/styles/fragments/index.ts +20 -0
  57. package/src/styles/fragments/layout.ts +7 -0
  58. package/src/styles/fragments/motion.ts +6 -0
  59. package/src/styles/fragments/ornament.ts +10 -0
  60. package/src/styles/fragments/selected.ts +45 -0
  61. package/src/styles/fragments/shimmer.ts +9 -0
  62. package/src/styles/fragments/size.ts +117 -0
  63. package/src/styles/fragments/surface.ts +29 -0
  64. package/src/styles/fragments/text.ts +12 -0
  65. package/src/styles/fragments/valence.ts +46 -0
  66. package/src/styles/index.ts +7 -0
  67. package/src/styles/layers/README.md +15 -0
  68. package/src/styles/layers/anchored-overflow.css +9 -0
  69. package/src/styles/layers/animation.css +17 -0
  70. package/src/styles/layers/attention.css +8 -0
  71. package/src/styles/layers/base.css +25 -0
  72. package/src/styles/layers/button.css +76 -0
  73. package/src/styles/layers/can-scroll.css +26 -0
  74. package/src/styles/layers/checkbox.css +50 -0
  75. package/src/styles/layers/dialog.css +42 -0
  76. package/src/styles/layers/drag-preview.css +18 -0
  77. package/src/styles/layers/focus-ring.css +224 -0
  78. package/src/styles/layers/hues.css +110 -0
  79. package/src/styles/layers/index.css +26 -0
  80. package/src/styles/layers/main.css +160 -0
  81. package/src/styles/layers/native.css +20 -0
  82. package/src/styles/layers/positioning.css +23 -0
  83. package/src/styles/layers/size.css +397 -0
  84. package/src/styles/layers/surfaces.css +31 -0
  85. package/src/styles/layers/tag.css +132 -0
  86. package/src/styles/layers/tldraw.css +91 -0
  87. package/src/styles/layers/tokens.css +45 -0
  88. package/src/styles/layers/typography.css +157 -0
  89. package/src/styles/theme.ts +69 -0
  90. package/src/tailwind.ts +5 -0
  91. package/src/theme.css +9 -0
  92. package/src/types.ts +7 -0
  93. package/src/typings.d.ts +8 -0
  94. package/src/util/hash-styles.ts +168 -0
  95. package/src/util/index.ts +6 -0
  96. package/src/util/mx.ts +51 -0
  97. package/src/util/withLogical.ts +114 -0
@@ -0,0 +1,132 @@
1
+ @layer dx-tokens {
2
+ :root {
3
+ --dx-tag-padding-block: 0.125rem;
4
+ }
5
+ }
6
+
7
+ @layer dx-components {
8
+ .dx-tag {
9
+ @apply inline-block text-xs font-semibold m-0.5 pli-1 rounded-sm cursor-default truncate;
10
+ padding-block: var(--dx-tag-padding-block);
11
+ user-select: none;
12
+ }
13
+
14
+ .dx-tag--anchor {
15
+ /* NOTE: Margin offsets padding so that border is flush with text. This should only apply to anchor tags inside of Codemirror. */
16
+ @apply inline cursor-pointer -mli-[4px] pli-[3px] plb-0.5 border border-separator rounded-sm bg-groupSurface transition-colors;
17
+
18
+ &:hover {
19
+ @apply bg-hoverSurface;
20
+ }
21
+ }
22
+
23
+ .dx-tag[data-hue='neutral'],
24
+ .dx-tag--neutral {
25
+ @apply bg-separator text-neutral-700 dark:text-neutral-150;
26
+ }
27
+
28
+ .dx-tag[data-hue='red'],
29
+ .dx-tag--red {
30
+ @apply bg-redSurface text-redSurfaceText;
31
+ }
32
+
33
+ .dx-tag[data-hue='orange'],
34
+ .dx-tag--orange {
35
+ @apply bg-orangeSurface text-orangeSurfaceText;
36
+ }
37
+
38
+ .dx-tag[data-hue='amber'],
39
+ .dx-tag--amber {
40
+ @apply bg-amberSurface text-amberSurfaceText;
41
+ }
42
+
43
+ .dx-tag[data-hue='yellow'],
44
+ .dx-tag--yellow {
45
+ @apply bg-yellowSurface text-yellowSurfaceText;
46
+ }
47
+
48
+ .dx-tag[data-hue='lime'],
49
+ .dx-tag--lime {
50
+ @apply bg-limeSurface text-limeSurfaceText;
51
+ }
52
+
53
+ .dx-tag[data-hue='green'],
54
+ .dx-tag--green {
55
+ @apply bg-greenSurface text-greenSurfaceText;
56
+ }
57
+
58
+ .dx-tag[data-hue='emerald'],
59
+ .dx-tag--emerald {
60
+ @apply bg-emeraldSurface text-emeraldSurfaceText;
61
+ }
62
+
63
+ .dx-tag[data-hue='teal'],
64
+ .dx-tag--teal {
65
+ @apply bg-tealSurface text-tealSurfaceText;
66
+ }
67
+
68
+ .dx-tag[data-hue='cyan'],
69
+ .dx-tag--cyan {
70
+ @apply bg-cyanSurface text-cyanSurfaceText;
71
+ }
72
+
73
+ .dx-tag[data-hue='sky'],
74
+ .dx-tag--sky {
75
+ @apply bg-skySurface text-skySurfaceText;
76
+ }
77
+
78
+ .dx-tag[data-hue='blue'],
79
+ .dx-tag--blue {
80
+ @apply bg-blueSurface text-blueSurfaceText;
81
+ }
82
+
83
+ .dx-tag[data-hue='indigo'],
84
+ .dx-tag--indigo {
85
+ @apply bg-indigoSurface text-indigoSurfaceText;
86
+ }
87
+
88
+ .dx-tag[data-hue='violet'],
89
+ .dx-tag--violet {
90
+ @apply bg-violetSurface text-violetSurfaceText;
91
+ }
92
+
93
+ .dx-tag[data-hue='purple'],
94
+ .dx-tag--purple {
95
+ @apply bg-purpleSurface text-purpleSurfaceText;
96
+ }
97
+
98
+ .dx-tag[data-hue='fuchsia'],
99
+ .dx-tag--fuchsia {
100
+ @apply bg-fuchsiaSurface text-fuchsiaSurfaceText;
101
+ }
102
+
103
+ .dx-tag[data-hue='pink'],
104
+ .dx-tag--pink {
105
+ @apply bg-pinkSurface text-pinkSurfaceText;
106
+ }
107
+
108
+ .dx-tag[data-hue='rose'],
109
+ .dx-tag--rose {
110
+ @apply bg-roseSurface text-roseSurfaceText;
111
+ }
112
+
113
+ .dx-tag[data-hue='info'],
114
+ .dx-tag--info {
115
+ @apply bg-cyanSurface text-cyanSurfaceText;
116
+ }
117
+
118
+ .dx-tag[data-hue='success'],
119
+ .dx-tag--success {
120
+ @apply bg-emeraldSurface text-emeraldSurfaceText;
121
+ }
122
+
123
+ .dx-tag[data-hue='warning'],
124
+ .dx-tag--warning {
125
+ @apply bg-amberSurface text-amberSurfaceText;
126
+ }
127
+
128
+ .dx-tag[data-hue='error'],
129
+ .dx-tag--error {
130
+ @apply bg-roseSurface text-roseSurfaceText;
131
+ }
132
+ }
@@ -0,0 +1,91 @@
1
+ @layer dx-components {
2
+
3
+ .tl-container.tl-theme__light {
4
+ /* Converted */
5
+ /* General */
6
+ --color-accent: var(--color-accent);
7
+ --color-background: var(--surface-bg); /* Main background. */
8
+
9
+ /* Panels *
10
+ --color-panel: theme(colors.neutral.50);
11
+ --color-divider: theme(colors.neutral.75); /* Separator light. */
12
+ --color-panel-contrast: var(--dx-separator);
13
+ --color-panel-overlay: rgba(255, 255, 255, 0.82);
14
+
15
+ /* Unmodified.
16
+ --color-brush-fill: rgba(144, 144, 144, 0.102);
17
+ --color-brush-stroke: rgba(144, 144, 144, 0.251);
18
+ --color-grid: rgba(144, 144, 144, 0.902);
19
+ --color-low: rgb(237, 240, 242);
20
+ --color-culled: rgb(235, 238, 240);
21
+ --color-muted-0: rgba(0, 0, 0, 0.02);
22
+ --color-muted-1: rgba(0, 0, 0, 0.1);
23
+ --color-muted-2: rgba(0, 0, 0, 0.035);
24
+ --color-hint: rgba(0, 0, 0, 0.055);
25
+ --color-overlay: rgba(0, 0, 0, 0.2);
26
+ --color-focus: #004094;
27
+ --color-selected: #2f80ed;
28
+ --color-selected-contrast: #ffffff;
29
+ --color-selection-fill: #1e90ff06;
30
+ --color-selection-stroke: #2f80ed;
31
+ --color-text-0: #1d1d1d;
32
+ --color-text-1: #2d2d2d;
33
+ --color-text-2: #5f6369;
34
+ --color-text-3: #b6b7ba;
35
+ --color-primary: #2f80ed;
36
+ --color-warn: #d10b0b;
37
+ --color-text: #000000;
38
+ --color-laser: #ff0000;
39
+ --shadow-1: 0px 1px 2px rgba(0, 0, 0, 0.22), 0px 1px 3px rgba(0, 0, 0, 0.09);
40
+ --shadow-2: 0px 0px 2px rgba(0, 0, 0, 0.12), 0px 2px 3px rgba(0, 0, 0, 0.24), 0px 2px 6px rgba(0, 0, 0, 0.1),
41
+ inset 0px 0px 0px 1px var(--color-panel-contrast);
42
+ --shadow-3: 0px 1px 2px rgba(0, 0, 0, 0.25), 0px 2px 6px rgba(0, 0, 0, 0.14),
43
+ inset 0px 0px 0px 1px var(--color-panel-contrast);
44
+ --shadow-4: 0px 0px 3px rgba(0, 0, 0, 0.16), 0px 5px 4px rgba(0, 0, 0, 0.16), 0px 2px 16px rgba(0, 0, 0, 0.06),
45
+ inset 0px 0px 0px 1px var(--color-panel-contrast);
46
+ */
47
+ }
48
+
49
+ .tl-container.tl-theme__dark {
50
+ /* Converted */
51
+ /* General */
52
+ --color-accent: var(--color-accent);
53
+ --color-background: var(--surface-bg);
54
+
55
+ /* Panels */
56
+ --color-divider: var(--dx-separator); /* Separator dark. */
57
+ --color-panel: var(--dx-attention);
58
+ --color-panel-contrast: var(--dx-separator);
59
+ --color-panel-overlay: rgba(54, 61, 68, 0.82);
60
+
61
+ /* Unmodified.
62
+ --color-brush-fill: rgba(180, 180, 180, 0.05);
63
+ --color-brush-stroke: rgba(180, 180, 180, 0.25);
64
+ --color-grid: #909090e6;
65
+ --color-low: #2c3136;
66
+ --color-culled: rgb(47, 52, 57);
67
+ --color-muted-0: rgba(255, 255, 255, 0.02);
68
+ --color-muted-1: rgba(255, 255, 255, 0.1);
69
+ --color-muted-2: rgba(255, 255, 255, 0.05);
70
+ --color-hint: rgba(255, 255, 255, 0.1);
71
+ --color-overlay: rgba(0, 0, 0, 0.35);
72
+ --color-focus: #a5c3f3;
73
+ --color-selected: #4285f4;
74
+ --color-selected-contrast: #ffffff;
75
+ --color-selection-fill: rgba(38, 150, 255, 0.05);
76
+ --color-selection-stroke: #2f80ed;
77
+ --color-text-0: #f0eded;
78
+ --color-text-1: #d9d9d9;
79
+ --color-text-2: #8e9094;
80
+ --color-text-3: #515a62;
81
+ --color-primary: #2f80ed;
82
+ --color-warn: #d10b0b;
83
+ --color-text: #f8f9fa;
84
+ --color-laser: #ff0000;
85
+ --shadow-1: 0px 1px 2px #00000029, 0px 1px 3px #00000038, inset 0px 0px 0px 1px var(--color-panel-contrast);
86
+ --shadow-2: 0px 1px 3px #00000077, 0px 2px 6px #00000055, inset 0px 0px 0px 1px var(--color-panel-contrast);
87
+ --shadow-3: 0px 1px 3px #00000077, 0px 2px 12px rgba(0, 0, 0, 0.22), inset 0px 0px 0px 1px var(--color-panel-contrast);
88
+ */
89
+ }
90
+
91
+ }
@@ -0,0 +1,45 @@
1
+ @layer dx-tokens {
2
+ @tokens dx;
3
+
4
+ :root {
5
+ /* Recitations */
6
+ --sticky-top: 0;
7
+
8
+ /* Lengths / sizes */
9
+ --rail-content: 3rem;
10
+ --rail-size: calc(var(--rail-content) + 1px);
11
+ --rail-action: calc(var(--rail-content) - 0.5rem + 1px);
12
+ --rail-item: calc(var(--rail-content) - 1rem);
13
+ --line-height: 32px;
14
+ --topbar-size: var(--rail-size);
15
+ --toolbar-size: var(--rail-content);
16
+ --statusbar-size: theme(spacing.8);
17
+ --nav-sidebar-size: 22.5rem;
18
+ --complementary-sidebar-size: 25rem;
19
+ /* NOTE(thure): 74px (rather than rem) is intentional in order to match the size of macOS windowing controls. */
20
+ --l0-size: 74px;
21
+ --l0-avatar-size: 3rem;
22
+ --l1-size: calc(var(--nav-sidebar-size) - var(--l0-size));
23
+ --r0-size: var(--rail-size);
24
+ --r1-size: calc(var(--complementary-sidebar-size) - var(--r0-size));
25
+ --text-content: calc(50rem - env(safe-area-inset-left) - env(safe-area-inset-right));
26
+ }
27
+
28
+ /* TODO(thure): Support arbitrary values (like for keywords e.g. `auto`, or font families) in @ch-ui/tokens */
29
+ :root {
30
+ --dx-calc-auto: auto;
31
+ --dx-calc-min: min-content;
32
+ --dx-calc-fit: fit-content;
33
+ --dx-calc-max: max-content;
34
+ --dx-calc-content: content;
35
+ }
36
+ @supports (block-size: calc-size(fit-content, size)) {
37
+ :root {
38
+ --dx-calc-auto: calc-size(auto, size);
39
+ --dx-calc-min: calc-size(min-content, size);
40
+ --dx-calc-fit: calc-size(fit-content, size);
41
+ --dx-calc-max: calc-size(max-content, size);
42
+ --dx-calc-content: calc-size(content, size);
43
+ }
44
+ }
45
+ }
@@ -0,0 +1,157 @@
1
+ /**
2
+ * Typography configuration.
3
+ */
4
+
5
+ @import '@fontsource-variable/jetbrains-mono/wght-italic.css';
6
+ @import '@fontsource-variable/jetbrains-mono/wght.css';
7
+ @import '@fontsource-variable/inter/slnt.css';
8
+ @import '@fontsource/poiret-one';
9
+
10
+ @layer utilities {
11
+ /* Font weights & `italic` handling */
12
+ .not-italic {
13
+ font-variation-settings:
14
+ 'wght' 400,
15
+ 'slnt' 0;
16
+ }
17
+ .font-thin,
18
+ .not-italic.font-thin,
19
+ .not-italic .font-thin,
20
+ .font-thin .not-italic {
21
+ font-variation-settings:
22
+ 'wght' 100,
23
+ 'slnt' 0;
24
+ }
25
+ .font-extralight,
26
+ .not-italic.font-extralight,
27
+ .not-italic .font-extralight,
28
+ .font-extralight .not-italic {
29
+ font-variation-settings:
30
+ 'wght' 200,
31
+ 'slnt' 0;
32
+ }
33
+ .font-light,
34
+ .not-italic.font-light,
35
+ .not-italic .font-light,
36
+ .font-light .not-italic {
37
+ font-variation-settings:
38
+ 'wght' 300,
39
+ 'slnt' 0;
40
+ }
41
+ .font-normal,
42
+ .not-italic.font-normal,
43
+ .not-italic .font-normal,
44
+ .font-normal .not-italic {
45
+ font-variation-settings:
46
+ 'wght' 400,
47
+ 'slnt' 0;
48
+ }
49
+ .font-medium,
50
+ .not-italic.font-medium,
51
+ .not-italic .font-medium,
52
+ .font-medium .not-italic {
53
+ font-variation-settings:
54
+ 'wght' 500,
55
+ 'slnt' 0;
56
+ }
57
+ .font-semibold,
58
+ .not-italic.font-semibold,
59
+ .not-italic .font-semibold,
60
+ .font-semibold .not-italic {
61
+ font-variation-settings:
62
+ 'wght' 600,
63
+ 'slnt' 0;
64
+ }
65
+ .font-bold,
66
+ .not-italic.font-bold,
67
+ .not-italic .font-bold,
68
+ .font-bold .not-italic {
69
+ font-variation-settings:
70
+ 'wght' 700,
71
+ 'slnt' 0;
72
+ }
73
+ .font-extrabold,
74
+ .not-italic.font-extrabold,
75
+ .not-italic .font-extrabold,
76
+ .font-extrabold .not-italic {
77
+ font-variation-settings:
78
+ 'wght' 800,
79
+ 'slnt' 0;
80
+ }
81
+ .font-black,
82
+ .not-italic.font-black,
83
+ .not-italic .font-black,
84
+ .font-black .not-italic {
85
+ font-variation-settings:
86
+ 'wght' 900,
87
+ 'slnt' 0;
88
+ }
89
+ .italic {
90
+ font-variation-settings:
91
+ 'wght' 400,
92
+ 'slnt' -10;
93
+ }
94
+ .italic.font-thin,
95
+ .italic .font-thin,
96
+ .font-thin .italic {
97
+ font-variation-settings:
98
+ 'wght' 100,
99
+ 'slnt' -10;
100
+ }
101
+ .italic.font-extralight,
102
+ .italic .font-extralight,
103
+ .font-extralight .italic {
104
+ font-variation-settings:
105
+ 'wght' 200,
106
+ 'slnt' -10;
107
+ }
108
+ .italic.font-light,
109
+ .italic .font-light,
110
+ .font-light .italic {
111
+ font-variation-settings:
112
+ 'wght' 300,
113
+ 'slnt' -10;
114
+ }
115
+ .italic.font-normal,
116
+ .italic .font-normal,
117
+ .font-normal .italic {
118
+ font-variation-settings:
119
+ 'wght' 400,
120
+ 'slnt' -10;
121
+ }
122
+ .italic.font-medium,
123
+ .italic .font-medium,
124
+ .font-medium .italic {
125
+ font-variation-settings:
126
+ 'wght' 500,
127
+ 'slnt' -10;
128
+ }
129
+ .italic.font-semibold,
130
+ .italic .font-semibold,
131
+ .font-semibold .italic {
132
+ font-variation-settings:
133
+ 'wght' 600,
134
+ 'slnt' -10;
135
+ }
136
+ .italic.font-bold,
137
+ .italic .font-bold,
138
+ .font-bold .italic {
139
+ font-variation-settings:
140
+ 'wght' 700,
141
+ 'slnt' -10;
142
+ }
143
+ .italic.font-extrabold,
144
+ .italic .font-extrabold,
145
+ .font-extrabold .italic {
146
+ font-variation-settings:
147
+ 'wght' 800,
148
+ 'slnt' -10;
149
+ }
150
+ .italic.font-black,
151
+ .italic .font-black,
152
+ .font-black .italic {
153
+ font-variation-settings:
154
+ 'wght' 900,
155
+ 'slnt' -10;
156
+ }
157
+ }
@@ -0,0 +1,69 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import { type ComponentFunction, type Theme } from '@dxos/ui-types';
6
+ import { get } from '@dxos/util';
7
+
8
+ import {
9
+ anchoredOverflowTheme,
10
+ avatarTheme,
11
+ breadcrumbTheme,
12
+ buttonTheme,
13
+ dialogTheme,
14
+ iconButtonTheme,
15
+ iconTheme,
16
+ inputTheme,
17
+ linkTheme,
18
+ listTheme,
19
+ mainTheme,
20
+ menuTheme,
21
+ messageTheme,
22
+ popoverTheme,
23
+ scrollAreaTheme,
24
+ selectTheme,
25
+ separatorTheme,
26
+ statusTheme,
27
+ tagTheme,
28
+ toastTheme,
29
+ toolbarTheme,
30
+ tooltipTheme,
31
+ treegridTheme,
32
+ } from './components';
33
+
34
+ export const defaultTheme: Theme<Record<string, any>> = {
35
+ themeName: () => 'default',
36
+
37
+ anchoredOverflow: anchoredOverflowTheme,
38
+ avatar: avatarTheme,
39
+ breadcrumb: breadcrumbTheme,
40
+ button: buttonTheme,
41
+ dialog: dialogTheme,
42
+ icon: iconTheme,
43
+ iconButton: iconButtonTheme,
44
+ input: inputTheme,
45
+ link: linkTheme,
46
+ list: listTheme,
47
+ main: mainTheme,
48
+ message: messageTheme,
49
+ menu: menuTheme,
50
+ popover: popoverTheme,
51
+ select: selectTheme,
52
+ scrollArea: scrollAreaTheme,
53
+ separator: separatorTheme,
54
+ status: statusTheme,
55
+ tag: tagTheme,
56
+ toast: toastTheme,
57
+ toolbar: toolbarTheme,
58
+ tooltip: tooltipTheme,
59
+ treegrid: treegridTheme,
60
+ };
61
+
62
+ export const bindTheme = <P extends Record<string, any>>(theme: Theme<Record<string, any>>) => {
63
+ return (path: string, defaultClassName: string, styleProps: P, ...options: any[]): string => {
64
+ const result: Theme<P> | ComponentFunction<P> = get(theme, path);
65
+ return typeof result === 'function' ? result(styleProps, ...options) : defaultClassName;
66
+ };
67
+ };
68
+
69
+ export const defaultTx = bindTheme(defaultTheme);
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ // Empty for vscode tooling.
package/src/theme.css ADDED
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Main theme.
3
+ */
4
+
5
+ @import 'tailwindcss/base' layer(tw-base);
6
+ @import 'tailwindcss/utilities';
7
+ @import 'tailwindcss/components' layer(tw-components);
8
+
9
+ @import './styles/layers/index.css';
package/src/types.ts ADDED
@@ -0,0 +1,7 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import { type huePalettes } from './config/tokens/physical-colors';
6
+
7
+ export type HuePalette = keyof typeof huePalettes;
@@ -0,0 +1,8 @@
1
+ //
2
+ // Copyright 2022 DXOS.org
3
+ //
4
+
5
+ declare module 'fast-glob';
6
+ declare module 'tailwindcss/stubs/config.full.js';
7
+ declare module 'tailwindcss-radix';
8
+ declare module 'tailwindcss-logical';
@@ -0,0 +1,168 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { type ChromaticPalette } from '@dxos/ui-types';
6
+
7
+ export type Hue = ChromaticPalette | 'neutral';
8
+
9
+ // TODO(burdon): Rename?
10
+ export type ColorStyles = {
11
+ hue: Hue;
12
+ text: string;
13
+ icon: string;
14
+ bg: string;
15
+ surface: string;
16
+ border: string;
17
+ };
18
+
19
+ const neutralColor: ColorStyles = {
20
+ hue: 'neutral',
21
+ text: 'text-neutralFill',
22
+ icon: 'text-neutralSurfaceText',
23
+ bg: 'bg-neutralFill',
24
+ surface: 'bg-neutralSurface',
25
+ border: 'border-neutralFill',
26
+ };
27
+
28
+ // NOTE: Don't include blue/red which are used as system colors.
29
+ // NOTE: Cordinated with `tag.css`.
30
+ // https://github.com/dxos/dxos/blob/main/packages/ui/react-ui-theme/src/styles/layers/tag.css
31
+ export const styles: ColorStyles[] = [
32
+ {
33
+ hue: 'orange',
34
+ text: 'text-orangeFill',
35
+ icon: 'text-orangeSurfaceText',
36
+ bg: 'bg-orangeFill',
37
+ surface: 'bg-orangeSurface',
38
+ border: 'border-orangeFill',
39
+ },
40
+ {
41
+ hue: 'amber',
42
+ text: 'text-amberFill',
43
+ icon: 'text-amberSurfaceText',
44
+ bg: 'bg-amberFill',
45
+ surface: 'bg-amberSurface',
46
+ border: 'border-amberFill',
47
+ },
48
+ {
49
+ hue: 'yellow',
50
+ text: 'text-yellowFill',
51
+ icon: 'text-yellowSurfaceText',
52
+ bg: 'bg-yellowFill',
53
+ surface: 'bg-yellowSurface',
54
+ border: 'border-yellowFill',
55
+ },
56
+ {
57
+ hue: 'lime',
58
+ text: 'text-limeFill',
59
+ icon: 'text-limeSurfaceText',
60
+ bg: 'bg-limeFill',
61
+ surface: 'bg-limeSurface',
62
+ border: 'border-limeFill',
63
+ },
64
+ {
65
+ hue: 'green',
66
+ text: 'text-greenFill',
67
+ icon: 'text-greenSurfaceText',
68
+ bg: 'bg-greenFill',
69
+ surface: 'bg-greenSurface',
70
+ border: 'border-greenFill',
71
+ },
72
+ {
73
+ hue: 'emerald',
74
+ text: 'text-emeraldFill',
75
+ icon: 'text-emeraldSurfaceText',
76
+ bg: 'bg-emeraldFill',
77
+ surface: 'bg-emeraldSurface',
78
+ border: 'border-emeraldFill',
79
+ },
80
+ {
81
+ hue: 'teal',
82
+ text: 'text-tealFill',
83
+ icon: 'text-tealSurfaceText',
84
+ bg: 'bg-tealFill',
85
+ surface: 'bg-tealSurface',
86
+ border: 'border-tealFill',
87
+ },
88
+ {
89
+ hue: 'cyan',
90
+ text: 'text-cyanFill',
91
+ icon: 'text-cyanSurfaceText',
92
+ bg: 'bg-cyanFill',
93
+ surface: 'bg-cyanSurface',
94
+ border: 'border-cyanFill',
95
+ },
96
+ {
97
+ hue: 'sky',
98
+ text: 'text-skyFill',
99
+ icon: 'text-skySurfaceText',
100
+ bg: 'bg-skyFill',
101
+ surface: 'bg-skySurface',
102
+ border: 'border-skyFill',
103
+ },
104
+ {
105
+ hue: 'indigo',
106
+ text: 'text-indigoFill',
107
+ icon: 'text-indigoSurfaceText',
108
+ bg: 'bg-indigoFill',
109
+ surface: 'bg-indigoSurface',
110
+ border: 'border-indigoFill',
111
+ },
112
+ {
113
+ hue: 'violet',
114
+ text: 'text-violetFill',
115
+ icon: 'text-violetSurfaceText',
116
+ bg: 'bg-violetFill',
117
+ surface: 'bg-violetSurface',
118
+ border: 'border-violetFill',
119
+ },
120
+ {
121
+ hue: 'purple',
122
+ text: 'text-purpleFill',
123
+ icon: 'text-purpleSurfaceText',
124
+ bg: 'bg-purpleFill',
125
+ surface: 'bg-purpleSurface',
126
+ border: 'border-purpleFill',
127
+ },
128
+ {
129
+ hue: 'fuchsia',
130
+ text: 'text-fuchsiaFill',
131
+ icon: 'text-fuchsiaSurfaceText',
132
+ bg: 'bg-fuchsiaFill',
133
+ surface: 'bg-fuchsiaSurface',
134
+ border: 'border-fuchsiaFill',
135
+ },
136
+ {
137
+ hue: 'rose',
138
+ text: 'text-roseFill',
139
+ icon: 'text-roseSurfaceText',
140
+ bg: 'bg-roseFill',
141
+ surface: 'bg-roseSurface',
142
+ border: 'border-roseFill',
143
+ },
144
+ {
145
+ hue: 'pink',
146
+ text: 'text-pinkFill',
147
+ icon: 'text-pinkSurfaceText',
148
+ bg: 'bg-pinkFill',
149
+ surface: 'bg-pinkSurface',
150
+ border: 'border-pinkFill',
151
+ },
152
+ ];
153
+
154
+ export const getStyles = (hue: string): ColorStyles => {
155
+ return styles.find((color) => color.hue === hue) || neutralColor;
156
+ };
157
+
158
+ export const getHashHue = (id: string | undefined): Hue => {
159
+ return id ? styles[getHash(id) % styles.length].hue : 'neutral';
160
+ };
161
+
162
+ // TODO(thure): Reconcile with `to-fallback.ts` which exports `toHue` which overlaps a lot.
163
+ export const getHashStyles = (id: string | undefined): ColorStyles => {
164
+ const hue = getHashHue(id);
165
+ return getStyles(hue);
166
+ };
167
+
168
+ const getHash = (id: string): number => id.split('').reduce((acc, char) => acc + char.charCodeAt(0), 0);
@@ -0,0 +1,6 @@
1
+ //
2
+ // Copyright 2022 DXOS.org
3
+ //
4
+
5
+ export * from './hash-styles';
6
+ export * from './mx';