@carto/ps-react-ui 6.4.0 → 6.5.1

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 (93) hide show
  1. package/dist/{actions-DyWNwvLu.js → actions-D_PVFZaM.js} +4 -4
  2. package/dist/{actions-DyWNwvLu.js.map → actions-D_PVFZaM.js.map} +1 -1
  3. package/dist/{category-BHBd5Pcc.js → category-UIGvFN3D.js} +4 -4
  4. package/dist/{category-BHBd5Pcc.js.map → category-UIGvFN3D.js.map} +1 -1
  5. package/dist/chat.js +472 -470
  6. package/dist/chat.js.map +1 -1
  7. package/dist/{components-CTUpdQuj.js → components-DDJU4m0t.js} +8 -8
  8. package/dist/components-DDJU4m0t.js.map +1 -0
  9. package/dist/components.js +2 -2
  10. package/dist/{download-B4sykOFm.js → download-DIj1Iz0t.js} +2 -2
  11. package/dist/{download-B4sykOFm.js.map → download-DIj1Iz0t.js.map} +1 -1
  12. package/dist/{formula-DJS-JLpk.js → formula-CSHhAoyW.js} +4 -4
  13. package/dist/{formula-DJS-JLpk.js.map → formula-CSHhAoyW.js.map} +1 -1
  14. package/dist/{item-color-B7xkIpDZ.js → item-color-7o7pFBR2.js} +26 -18
  15. package/dist/item-color-7o7pFBR2.js.map +1 -0
  16. package/dist/markdown-B8lLR-NY.js +106 -0
  17. package/dist/markdown-B8lLR-NY.js.map +1 -0
  18. package/dist/{spread-CQwFIwuz.js → spread-BRfPPIep.js} +3 -3
  19. package/dist/{spread-CQwFIwuz.js.map → spread-BRfPPIep.js.map} +1 -1
  20. package/dist/style-DTLuIo84.js +87 -0
  21. package/dist/style-DTLuIo84.js.map +1 -0
  22. package/dist/{styles-BCEBm7xh.js → styles-yKcpfyNV.js} +5 -5
  23. package/dist/styles-yKcpfyNV.js.map +1 -0
  24. package/dist/{table-DEdW_fDj.js → table-Col_FRvb.js} +2 -2
  25. package/dist/{table-DEdW_fDj.js.map → table-Col_FRvb.js.map} +1 -1
  26. package/dist/theme/tailwind.css +373 -0
  27. package/dist/theme.js +123 -0
  28. package/dist/theme.js.map +1 -0
  29. package/dist/types/components/lasso-tool/styles.d.ts +4 -4
  30. package/dist/types/theme/create-carto-theme.d.ts +7 -0
  31. package/dist/types/theme/deep-merge.d.ts +6 -0
  32. package/dist/types/theme/generate-tailwind-css.d.ts +8 -0
  33. package/dist/types/theme/index.d.ts +2 -0
  34. package/dist/types/widgets/markdown/style.d.ts +74 -0
  35. package/dist/types/widgets/utils/spacing-px.d.ts +13 -0
  36. package/dist/types/widgets/wrapper/collapsed-context.d.ts +7 -0
  37. package/dist/{utils-C-eWwOhE.js → utils-Dw4y8tiq.js} +2 -2
  38. package/dist/{utils-C-eWwOhE.js.map → utils-Dw4y8tiq.js.map} +1 -1
  39. package/dist/widgets/actions.js +3 -3
  40. package/dist/widgets/bar.js +54 -54
  41. package/dist/widgets/bar.js.map +1 -1
  42. package/dist/widgets/category.js +1 -1
  43. package/dist/widgets/formula.js +1 -1
  44. package/dist/widgets/histogram.js +70 -70
  45. package/dist/widgets/histogram.js.map +1 -1
  46. package/dist/widgets/markdown.js +1 -1
  47. package/dist/widgets/pie.js +78 -78
  48. package/dist/widgets/pie.js.map +1 -1
  49. package/dist/widgets/scatterplot.js +82 -82
  50. package/dist/widgets/scatterplot.js.map +1 -1
  51. package/dist/widgets/spread.js +1 -1
  52. package/dist/widgets/table.js +1 -1
  53. package/dist/widgets/timeseries.js +62 -62
  54. package/dist/widgets/timeseries.js.map +1 -1
  55. package/dist/widgets/utils.js +1 -1
  56. package/dist/widgets.js +309 -299
  57. package/dist/widgets.js.map +1 -1
  58. package/dist/{zoom-toggle-MmLjMTEw.js → zoom-toggle-DqrV_0Ji.js} +2 -2
  59. package/dist/{zoom-toggle-MmLjMTEw.js.map → zoom-toggle-DqrV_0Ji.js.map} +1 -1
  60. package/package.json +10 -3
  61. package/src/chat/bubbles/styles.ts +2 -0
  62. package/src/components/lasso-tool/lasso-tool-inline.test.tsx +4 -4
  63. package/src/components/lasso-tool/lasso-tool-inline.tsx +6 -6
  64. package/src/components/lasso-tool/styles.ts +4 -4
  65. package/src/theme/create-carto-theme.test.ts +53 -0
  66. package/src/theme/create-carto-theme.ts +21 -0
  67. package/src/theme/deep-merge.test.ts +25 -0
  68. package/src/theme/deep-merge.ts +22 -0
  69. package/src/theme/generate-tailwind-css.test.ts +87 -0
  70. package/src/theme/generate-tailwind-css.ts +178 -0
  71. package/src/theme/index.ts +2 -0
  72. package/src/theme/tailwind-compile.test.ts +71 -0
  73. package/src/theme/tailwind.css +373 -0
  74. package/src/widgets/bar/options.ts +7 -6
  75. package/src/widgets/histogram/options.ts +7 -6
  76. package/src/widgets/markdown/style.ts +40 -0
  77. package/src/widgets/note/widget-note.tsx +4 -1
  78. package/src/widgets/pie/options.ts +5 -4
  79. package/src/widgets/scatterplot/options.ts +7 -6
  80. package/src/widgets/timeseries/options.ts +7 -6
  81. package/src/widgets/toolbox/toolbox.test.tsx +28 -0
  82. package/src/widgets/toolbox/toolbox.tsx +9 -0
  83. package/src/widgets/utils/css-variables-theme.test.ts +32 -0
  84. package/src/widgets/utils/option-builders.ts +4 -6
  85. package/src/widgets/utils/spacing-px.test.ts +42 -0
  86. package/src/widgets/utils/spacing-px.ts +24 -0
  87. package/src/widgets/wrapper/collapsed-context.ts +12 -0
  88. package/src/widgets/wrapper/widget-wrapper.tsx +6 -1
  89. package/dist/components-CTUpdQuj.js.map +0 -1
  90. package/dist/item-color-B7xkIpDZ.js.map +0 -1
  91. package/dist/markdown-DmvLi3vx.js +0 -159
  92. package/dist/markdown-DmvLi3vx.js.map +0 -1
  93. package/dist/styles-BCEBm7xh.js.map +0 -1
@@ -0,0 +1,71 @@
1
+ import { readFile } from 'node:fs/promises'
2
+ import { createRequire } from 'node:module'
3
+ import path from 'node:path'
4
+ import { fileURLToPath } from 'node:url'
5
+ import { compile } from 'tailwindcss'
6
+ import { beforeAll, describe, expect, it } from 'vitest'
7
+
8
+ const require = createRequire(import.meta.url)
9
+ const tailwindDir = path.dirname(require.resolve('tailwindcss/package.json'))
10
+ const themeDir = path.dirname(fileURLToPath(import.meta.url))
11
+
12
+ // Same order the docs tell consumers to use.
13
+ const ENTRY = `@layer theme, base, mui, components, utilities;
14
+ @import 'tailwindcss';
15
+ @import './tailwind.css';`
16
+
17
+ let build: (candidates: string[]) => string
18
+
19
+ beforeAll(async () => {
20
+ const compiler = await compile(ENTRY, {
21
+ base: themeDir,
22
+ loadStylesheet: async (id, base) => {
23
+ const file =
24
+ id === 'tailwindcss'
25
+ ? path.join(tailwindDir, 'index.css')
26
+ : path.resolve(base, id)
27
+ return {
28
+ path: file,
29
+ base: path.dirname(file),
30
+ content: await readFile(file, 'utf8'),
31
+ }
32
+ },
33
+ })
34
+ build = (candidates) => compiler.build(candidates)
35
+ })
36
+
37
+ describe('tailwind.css under Tailwind v4', () => {
38
+ it('compiles colour, shadow and radius utilities to MUI variables', () => {
39
+ const out = build([
40
+ 'bg-primary',
41
+ 'text-brand-navy-blue',
42
+ 'shadow-2',
43
+ 'rounded-theme',
44
+ ])
45
+ expect(out).toContain('background-color: var(--mui-palette-primary-main)')
46
+ expect(out).toContain('color: var(--mui-palette-brand-navyBlue)')
47
+ expect(out).toContain('--tw-shadow: var(--mui-shadows-2)')
48
+ expect(out).toContain('border-radius: var(--mui-shape-borderRadius)')
49
+ })
50
+
51
+ it('uses CARTO breakpoints over Tailwind defaults and drops 2xl', () => {
52
+ const out = build(['sm:bg-primary', 'md:bg-primary', '2xl:bg-primary'])
53
+ expect(out).toContain('@media (width >= 600px)')
54
+ expect(out).toContain('@media (width >= 960px)')
55
+ expect(out).not.toContain('40rem')
56
+ expect(out).not.toContain('2xl\\:bg-primary')
57
+ })
58
+
59
+ it('compiles responsive typography utilities', () => {
60
+ const out = build(['typography-h1'])
61
+ expect(out).toContain('font-size: 3.5rem')
62
+ expect(out).toContain('font-size: 6rem')
63
+ expect(out).toContain('letter-spacing: -1.5px')
64
+ })
65
+
66
+ it('derives the spacing unit from the theme', () => {
67
+ const out = build(['p-4'])
68
+ expect(out).toContain('padding: calc(var(--spacing) * 4)')
69
+ expect(out).toContain('--spacing: calc(var(--mui-spacing) / 2)')
70
+ })
71
+ })
@@ -0,0 +1,373 @@
1
+ /*
2
+ * Generated by generateTailwindCss() from @carto/ps-react-ui/theme.
3
+ * Do not edit by hand: regenerate it whenever the theme changes.
4
+ *
5
+ * Import after `tailwindcss`. Declare the cascade layer order yourself first:
6
+ * theme, base, mui, components, utilities (in that order).
7
+ */
8
+
9
+ @theme inline {
10
+ --color-primary: var(--mui-palette-primary-main);
11
+ --color-primary-light: var(--mui-palette-primary-light);
12
+ --color-primary-dark: var(--mui-palette-primary-dark);
13
+ --color-primary-contrast: var(--mui-palette-primary-contrastText);
14
+ --color-primary-related-light: var(--mui-palette-primary-relatedLight);
15
+ --color-primary-related-dark: var(--mui-palette-primary-relatedDark);
16
+ --color-primary-background: var(--mui-palette-primary-background);
17
+ --color-secondary: var(--mui-palette-secondary-main);
18
+ --color-secondary-light: var(--mui-palette-secondary-light);
19
+ --color-secondary-dark: var(--mui-palette-secondary-dark);
20
+ --color-secondary-contrast: var(--mui-palette-secondary-contrastText);
21
+ --color-secondary-related-light: var(--mui-palette-secondary-relatedLight);
22
+ --color-secondary-related-dark: var(--mui-palette-secondary-relatedDark);
23
+ --color-secondary-background: var(--mui-palette-secondary-background);
24
+ --color-tertiary: var(--mui-palette-tertiary-main);
25
+ --color-tertiary-light: var(--mui-palette-tertiary-light);
26
+ --color-tertiary-dark: var(--mui-palette-tertiary-dark);
27
+ --color-tertiary-contrast: var(--mui-palette-tertiary-contrastText);
28
+ --color-tertiary-related-light: var(--mui-palette-tertiary-relatedLight);
29
+ --color-tertiary-related-dark: var(--mui-palette-tertiary-relatedDark);
30
+ --color-tertiary-background: var(--mui-palette-tertiary-background);
31
+ --color-error: var(--mui-palette-error-main);
32
+ --color-error-light: var(--mui-palette-error-light);
33
+ --color-error-dark: var(--mui-palette-error-dark);
34
+ --color-error-contrast: var(--mui-palette-error-contrastText);
35
+ --color-error-related-light: var(--mui-palette-error-relatedLight);
36
+ --color-error-related-dark: var(--mui-palette-error-relatedDark);
37
+ --color-error-background: var(--mui-palette-error-background);
38
+ --color-warning: var(--mui-palette-warning-main);
39
+ --color-warning-light: var(--mui-palette-warning-light);
40
+ --color-warning-dark: var(--mui-palette-warning-dark);
41
+ --color-warning-contrast: var(--mui-palette-warning-contrastText);
42
+ --color-warning-related-light: var(--mui-palette-warning-relatedLight);
43
+ --color-warning-related-dark: var(--mui-palette-warning-relatedDark);
44
+ --color-warning-background: var(--mui-palette-warning-background);
45
+ --color-info: var(--mui-palette-info-main);
46
+ --color-info-light: var(--mui-palette-info-light);
47
+ --color-info-dark: var(--mui-palette-info-dark);
48
+ --color-info-contrast: var(--mui-palette-info-contrastText);
49
+ --color-info-related-light: var(--mui-palette-info-relatedLight);
50
+ --color-info-related-dark: var(--mui-palette-info-relatedDark);
51
+ --color-info-background: var(--mui-palette-info-background);
52
+ --color-success: var(--mui-palette-success-main);
53
+ --color-success-light: var(--mui-palette-success-light);
54
+ --color-success-dark: var(--mui-palette-success-dark);
55
+ --color-success-contrast: var(--mui-palette-success-contrastText);
56
+ --color-success-related-light: var(--mui-palette-success-relatedLight);
57
+ --color-success-related-dark: var(--mui-palette-success-relatedDark);
58
+ --color-success-background: var(--mui-palette-success-background);
59
+ --color-neutral: var(--mui-palette-neutral-main);
60
+ --color-neutral-light: var(--mui-palette-neutral-light);
61
+ --color-neutral-dark: var(--mui-palette-neutral-dark);
62
+ --color-neutral-contrast: var(--mui-palette-neutral-contrastText);
63
+ --color-neutral-related-light: var(--mui-palette-neutral-relatedLight);
64
+ --color-neutral-related-dark: var(--mui-palette-neutral-relatedDark);
65
+ --color-neutral-background: var(--mui-palette-neutral-background);
66
+ --color-default: var(--mui-palette-default-main);
67
+ --color-default-light: var(--mui-palette-default-light);
68
+ --color-default-dark: var(--mui-palette-default-dark);
69
+ --color-default-contrast: var(--mui-palette-default-contrastText);
70
+ --color-default-related-light: var(--mui-palette-default-relatedLight);
71
+ --color-default-related-dark: var(--mui-palette-default-relatedDark);
72
+ --color-default-background: var(--mui-palette-default-background);
73
+ --color-text-primary: var(--mui-palette-text-primary);
74
+ --color-text-secondary: var(--mui-palette-text-secondary);
75
+ --color-text-disabled: var(--mui-palette-text-disabled);
76
+ --color-background: var(--mui-palette-background-default);
77
+ --color-paper: var(--mui-palette-background-paper);
78
+ --color-divider: var(--mui-palette-divider);
79
+ --color-action-active: var(--mui-palette-action-active);
80
+ --color-action-hover: var(--mui-palette-action-hover);
81
+ --color-action-disabled-background: var(--mui-palette-action-disabledBackground);
82
+ --color-action-disabled: var(--mui-palette-action-disabled);
83
+ --color-action-selected: var(--mui-palette-action-selected);
84
+ --color-action-focus: var(--mui-palette-action-focus);
85
+ --color-common-white: var(--mui-palette-common-white);
86
+ --color-common-black: var(--mui-palette-common-black);
87
+ --color-grey-50: var(--mui-palette-grey-50);
88
+ --color-grey-100: var(--mui-palette-grey-100);
89
+ --color-grey-200: var(--mui-palette-grey-200);
90
+ --color-grey-300: var(--mui-palette-grey-300);
91
+ --color-grey-400: var(--mui-palette-grey-400);
92
+ --color-grey-500: var(--mui-palette-grey-500);
93
+ --color-grey-600: var(--mui-palette-grey-600);
94
+ --color-grey-700: var(--mui-palette-grey-700);
95
+ --color-grey-800: var(--mui-palette-grey-800);
96
+ --color-grey-900: var(--mui-palette-grey-900);
97
+ --color-grey-A100: var(--mui-palette-grey-A100);
98
+ --color-grey-A200: var(--mui-palette-grey-A200);
99
+ --color-grey-A400: var(--mui-palette-grey-A400);
100
+ --color-grey-A700: var(--mui-palette-grey-A700);
101
+ --color-brand-navy-blue: var(--mui-palette-brand-navyBlue);
102
+ --color-brand-location-red: var(--mui-palette-brand-locationRed);
103
+ --color-brand-prediction-blue: var(--mui-palette-brand-predictionBlue);
104
+ --color-brand-soft-blue: var(--mui-palette-brand-softBlue);
105
+ --color-brand-app-bar-main: var(--mui-palette-brand-appBarMain);
106
+ --color-brand-app-bar-contrast-text: var(--mui-palette-brand-appBarContrastText);
107
+ --color-white-4: var(--mui-palette-white-4);
108
+ --color-white-8: var(--mui-palette-white-8);
109
+ --color-white-12: var(--mui-palette-white-12);
110
+ --color-white-25: var(--mui-palette-white-25);
111
+ --color-white-40: var(--mui-palette-white-40);
112
+ --color-white-60: var(--mui-palette-white-60);
113
+ --color-white-90: var(--mui-palette-white-90);
114
+ --color-black-4: var(--mui-palette-black-4);
115
+ --color-black-8: var(--mui-palette-black-8);
116
+ --color-black-12: var(--mui-palette-black-12);
117
+ --color-black-25: var(--mui-palette-black-25);
118
+ --color-black-40: var(--mui-palette-black-40);
119
+ --color-black-60: var(--mui-palette-black-60);
120
+ --color-black-90: var(--mui-palette-black-90);
121
+ --color-qualitative-0: var(--mui-palette-qualitative-bold-0);
122
+ --color-qualitative-1: var(--mui-palette-qualitative-bold-1);
123
+ --color-qualitative-2: var(--mui-palette-qualitative-bold-2);
124
+ --color-qualitative-3: var(--mui-palette-qualitative-bold-3);
125
+ --color-qualitative-4: var(--mui-palette-qualitative-bold-4);
126
+ --color-qualitative-5: var(--mui-palette-qualitative-bold-5);
127
+ --color-qualitative-6: var(--mui-palette-qualitative-bold-6);
128
+ --color-qualitative-7: var(--mui-palette-qualitative-bold-7);
129
+ --color-qualitative-8: var(--mui-palette-qualitative-bold-8);
130
+ --color-qualitative-9: var(--mui-palette-qualitative-bold-9);
131
+ --color-qualitative-10: var(--mui-palette-qualitative-bold-10);
132
+ --color-qualitative-11: var(--mui-palette-qualitative-bold-11);
133
+ --shadow-1: var(--mui-shadows-1);
134
+ --shadow-2: var(--mui-shadows-2);
135
+ --shadow-3: var(--mui-shadows-3);
136
+ --shadow-4: var(--mui-shadows-4);
137
+ --shadow-5: var(--mui-shadows-5);
138
+ --shadow-6: var(--mui-shadows-6);
139
+ --shadow-7: var(--mui-shadows-7);
140
+ --shadow-8: var(--mui-shadows-8);
141
+ --shadow-9: var(--mui-shadows-9);
142
+ --shadow-10: var(--mui-shadows-10);
143
+ --shadow-11: var(--mui-shadows-11);
144
+ --shadow-12: var(--mui-shadows-12);
145
+ --shadow-13: var(--mui-shadows-13);
146
+ --shadow-14: var(--mui-shadows-14);
147
+ --shadow-15: var(--mui-shadows-15);
148
+ --shadow-16: var(--mui-shadows-16);
149
+ --shadow-17: var(--mui-shadows-17);
150
+ --shadow-18: var(--mui-shadows-18);
151
+ --shadow-19: var(--mui-shadows-19);
152
+ --shadow-20: var(--mui-shadows-20);
153
+ --shadow-21: var(--mui-shadows-21);
154
+ --shadow-22: var(--mui-shadows-22);
155
+ --shadow-23: var(--mui-shadows-23);
156
+ --shadow-24: var(--mui-shadows-24);
157
+ --radius-theme: var(--mui-shape-borderRadius);
158
+ --radius-theme-half: calc(var(--mui-shape-borderRadius) * 0.5);
159
+ --radius-theme-2: calc(var(--mui-shape-borderRadius) * 2);
160
+ --radius-theme-3: calc(var(--mui-shape-borderRadius) * 3);
161
+ --radius-theme-4: calc(var(--mui-shape-borderRadius) * 4);
162
+ --breakpoint-xs: 320px;
163
+ --breakpoint-sm: 600px;
164
+ --breakpoint-md: 960px;
165
+ --breakpoint-lg: 1280px;
166
+ --breakpoint-xl: 1600px;
167
+ --breakpoint-2xl: initial;
168
+ }
169
+
170
+ @theme {
171
+ --spacing: calc(var(--mui-spacing) / 2);
172
+ }
173
+
174
+ @utility typography-h1 {
175
+ font-family: Inter, sans-serif;
176
+ font-weight: 600;
177
+ font-size: 3.5rem;
178
+ line-height: 1.167;
179
+ letter-spacing: -1.5px;
180
+ @media (min-width:600px) {
181
+ font-size: 4.7129rem;
182
+ }
183
+ @media (min-width:960px) {
184
+ font-size: 5.3556rem;
185
+ }
186
+ @media (min-width:1280px) {
187
+ font-size: 6rem;
188
+ }
189
+ }
190
+
191
+ @utility typography-h2 {
192
+ font-family: Inter, sans-serif;
193
+ font-weight: 600;
194
+ font-size: 2.375rem;
195
+ line-height: 1.2;
196
+ letter-spacing: -0.5px;
197
+ @media (min-width:600px) {
198
+ font-size: 2.9167rem;
199
+ }
200
+ @media (min-width:960px) {
201
+ font-size: 3.3333rem;
202
+ }
203
+ @media (min-width:1280px) {
204
+ font-size: 3.75rem;
205
+ }
206
+ }
207
+
208
+ @utility typography-h3 {
209
+ font-family: Inter, sans-serif;
210
+ font-weight: 600;
211
+ font-size: 2rem;
212
+ line-height: 1.167;
213
+ letter-spacing: 0;
214
+ @media (min-width:600px) {
215
+ font-size: 2.5707rem;
216
+ }
217
+ @media (min-width:960px) {
218
+ font-size: 2.7849rem;
219
+ }
220
+ @media (min-width:1280px) {
221
+ font-size: 3rem;
222
+ }
223
+ }
224
+
225
+ @utility typography-h4 {
226
+ font-family: Inter, sans-serif;
227
+ font-weight: 600;
228
+ font-size: 1.5rem;
229
+ line-height: 1.25;
230
+ letter-spacing: 0;
231
+ @media (min-width:600px) {
232
+ font-size: 1.8rem;
233
+ }
234
+ @media (min-width:960px) {
235
+ font-size: 1.8rem;
236
+ }
237
+ @media (min-width:1280px) {
238
+ font-size: 2rem;
239
+ }
240
+ }
241
+
242
+ @utility typography-h5 {
243
+ font-family: Inter, sans-serif;
244
+ font-weight: 600;
245
+ font-size: 1.25rem;
246
+ line-height: 1.167;
247
+ letter-spacing: 0;
248
+ @media (min-width:600px) {
249
+ font-size: 1.2853rem;
250
+ }
251
+ @media (min-width:960px) {
252
+ font-size: 1.4996rem;
253
+ }
254
+ @media (min-width:1280px) {
255
+ font-size: 1.5rem;
256
+ }
257
+ }
258
+
259
+ @utility typography-h6 {
260
+ font-family: Inter, sans-serif;
261
+ font-weight: 500;
262
+ font-size: 1.0625rem;
263
+ line-height: 1.333;
264
+ letter-spacing: 0;
265
+ @media (min-width:600px) {
266
+ font-size: 1.1253rem;
267
+ }
268
+ @media (min-width:960px) {
269
+ font-size: 1.1253rem;
270
+ }
271
+ @media (min-width:1280px) {
272
+ font-size: 1.125rem;
273
+ }
274
+ }
275
+
276
+ @utility typography-subtitle1 {
277
+ font-family: Inter, sans-serif;
278
+ font-weight: 500;
279
+ font-size: 1rem;
280
+ line-height: 1.5;
281
+ letter-spacing: 0;
282
+ }
283
+
284
+ @utility typography-subtitle2 {
285
+ font-family: Inter, sans-serif;
286
+ font-weight: 600;
287
+ font-size: 0.8125rem;
288
+ line-height: 1.538;
289
+ letter-spacing: 0;
290
+ }
291
+
292
+ @utility typography-body1 {
293
+ font-family: Inter, sans-serif;
294
+ font-weight: 400;
295
+ font-size: 1rem;
296
+ line-height: 1.5;
297
+ letter-spacing: 0;
298
+ }
299
+
300
+ @utility typography-body2 {
301
+ font-family: Inter, sans-serif;
302
+ font-weight: 400;
303
+ font-size: 0.8125rem;
304
+ line-height: 1.538;
305
+ letter-spacing: 0;
306
+ }
307
+
308
+ @utility typography-button {
309
+ font-family: Inter, sans-serif;
310
+ font-weight: 500;
311
+ font-size: 0.8125rem;
312
+ line-height: 1.538;
313
+ letter-spacing: 0;
314
+ text-transform: inherit;
315
+ }
316
+
317
+ @utility typography-caption {
318
+ font-family: Inter, sans-serif;
319
+ font-weight: 400;
320
+ font-size: 0.6875rem;
321
+ line-height: 1.454;
322
+ letter-spacing: 0;
323
+ }
324
+
325
+ @utility typography-overline {
326
+ font-family: Inter, sans-serif;
327
+ font-weight: 500;
328
+ font-size: 0.625rem;
329
+ line-height: 1.2;
330
+ letter-spacing: 1.2px;
331
+ text-transform: uppercase;
332
+ }
333
+
334
+ @utility typography-caption-medium {
335
+ font-family: Inter, sans-serif;
336
+ font-weight: 500;
337
+ font-size: 0.6875rem;
338
+ line-height: 1.454;
339
+ letter-spacing: 0;
340
+ }
341
+
342
+ @utility typography-overline-delicate {
343
+ font-family: Inter, sans-serif;
344
+ font-weight: 400;
345
+ font-size: 0.625rem;
346
+ line-height: 1.2;
347
+ letter-spacing: 1.2px;
348
+ text-transform: uppercase;
349
+ }
350
+
351
+ @utility typography-code1 {
352
+ font-family: "Overpass Mono", monospace;
353
+ font-weight: 400;
354
+ font-size: 1rem;
355
+ line-height: 1.5;
356
+ letter-spacing: 0;
357
+ }
358
+
359
+ @utility typography-code2 {
360
+ font-family: "Overpass Mono", monospace;
361
+ font-weight: 400;
362
+ font-size: 0.875rem;
363
+ line-height: 1.428;
364
+ letter-spacing: 0;
365
+ }
366
+
367
+ @utility typography-code3 {
368
+ font-family: "Overpass Mono", monospace;
369
+ font-weight: 400;
370
+ font-size: 0.75rem;
371
+ line-height: 1.333;
372
+ letter-spacing: 0;
373
+ }
@@ -12,6 +12,7 @@ import {
12
12
  import { ZOOM_LAYOUT } from '../actions/zoom-toggle'
13
13
  import type { OptionFactory } from '../echart'
14
14
  import { mergeOptions, resolveThemeColor } from '../utils'
15
+ import { spacingPx } from '../utils/spacing-px'
15
16
  import { createItemColorResolver } from '../utils/item-color'
16
17
  import { positionDataZoomForLegend } from '../utils/data-zoom-layout'
17
18
  import type {
@@ -50,9 +51,9 @@ export function barOptions({
50
51
 
51
52
  return {
52
53
  grid: {
53
- left: parseInt(theme.spacing(1)),
54
- top: parseInt(theme.spacing(3)),
55
- right: parseInt(theme.spacing(1)),
54
+ left: spacingPx(theme, 1),
55
+ top: spacingPx(theme, 3),
56
+ right: spacingPx(theme, 1),
56
57
  // Default: no legend. Merger bumps this when there are >1 series.
57
58
  ...buildGridConfig(false, theme),
58
59
  containLabel: true,
@@ -61,7 +62,7 @@ export function barOptions({
61
62
  trigger: 'axis',
62
63
  backgroundColor: theme.palette.grey[900],
63
64
  borderWidth: 0,
64
- padding: [parseInt(theme.spacing(1)), parseInt(theme.spacing(1))],
65
+ padding: [spacingPx(theme, 1), spacingPx(theme, 1)],
65
66
  textStyle: {
66
67
  color: theme.palette.common.white,
67
68
  fontSize: 11,
@@ -90,7 +91,7 @@ export function barOptions({
90
91
  axisTick: { show: false },
91
92
  axisLabel: {
92
93
  ...buildAxisLabelStyle(theme),
93
- padding: [parseInt(theme.spacing(0.5)), 0, 0, 0],
94
+ padding: [spacingPx(theme, 0.5), 0, 0, 0],
94
95
  margin: 0,
95
96
  // `interval: 0` makes every category label a candidate so `hideOverlap`
96
97
  // can pack the maximum number that physically fit; the category-axis
@@ -120,7 +121,7 @@ export function barOptions({
120
121
  },
121
122
  axisLabel: {
122
123
  ...buildAxisLabelStyle(theme),
123
- margin: parseInt(theme.spacing(1)),
124
+ margin: spacingPx(theme, 1),
124
125
  show: true,
125
126
  showMaxLabel: true,
126
127
  showMinLabel: true,
@@ -12,6 +12,7 @@ import {
12
12
  import { ZOOM_LAYOUT } from '../actions/zoom-toggle'
13
13
  import type { OptionFactory } from '../echart'
14
14
  import { mergeOptions, resolveThemeColor } from '../utils'
15
+ import { spacingPx } from '../utils/spacing-px'
15
16
  import { createItemColorResolver } from '../utils/item-color'
16
17
  import { getHistogramBinValue } from './bins'
17
18
  import { positionDataZoomForLegend } from '../utils/data-zoom-layout'
@@ -56,9 +57,9 @@ export function histogramOptions({
56
57
 
57
58
  return {
58
59
  grid: {
59
- left: parseInt(theme.spacing(1)),
60
- top: parseInt(theme.spacing(3)),
61
- right: parseInt(theme.spacing(1)),
60
+ left: spacingPx(theme, 1),
61
+ top: spacingPx(theme, 3),
62
+ right: spacingPx(theme, 1),
62
63
  // Default: no legend. Merger bumps this when there are >1 series.
63
64
  ...buildGridConfig(false, theme),
64
65
  containLabel: true,
@@ -67,7 +68,7 @@ export function histogramOptions({
67
68
  trigger: 'axis',
68
69
  backgroundColor: theme.palette.grey[900],
69
70
  borderWidth: 0,
70
- padding: [parseInt(theme.spacing(1)), parseInt(theme.spacing(1))],
71
+ padding: [spacingPx(theme, 1), spacingPx(theme, 1)],
71
72
  textStyle: {
72
73
  color: theme.palette.common.white,
73
74
  fontSize: 11,
@@ -98,7 +99,7 @@ export function histogramOptions({
98
99
  axisTick: { show: false },
99
100
  axisLabel: {
100
101
  ...buildAxisLabelStyle(theme),
101
- padding: [parseInt(theme.spacing(0.5)), 0, 0, 0],
102
+ padding: [spacingPx(theme, 0.5), 0, 0, 0],
102
103
  margin: 0,
103
104
  // `interval: 0` makes every bin label a candidate so `hideOverlap`
104
105
  // can pack the maximum number that physically fit. The category-axis
@@ -126,7 +127,7 @@ export function histogramOptions({
126
127
  },
127
128
  axisLabel: {
128
129
  ...buildAxisLabelStyle(theme),
129
- margin: parseInt(theme.spacing(1)),
130
+ margin: spacingPx(theme, 1),
130
131
  show: true,
131
132
  showMaxLabel: true,
132
133
  showMinLabel: true,
@@ -1,7 +1,47 @@
1
1
  import type { SxProps, Theme } from '@mui/material'
2
+ import type { CSSObject } from '@mui/material/styles'
3
+
4
+ /**
5
+ * Browser defaults that rendered Markdown relies on, restated with `revert`
6
+ * so a CSS reset in the app (Tailwind's preflight, for one) cannot strip
7
+ * them: list bullets and indent, link underline, blockquote margins, inline
8
+ * images, monospace fonts, `pre` margins, `sub`/`sup` placement. `revert`
9
+ * rolls back to the browser's own value, so pages without a reset render
10
+ * exactly as before.
11
+ *
12
+ * Wrapped in `:where()` so any element rule a consumer sets on top wins.
13
+ */
14
+ export const markdownElementDefaults = {
15
+ '& :where(ul, ol)': {
16
+ listStyle: 'revert',
17
+ margin: 'revert',
18
+ padding: 'revert',
19
+ },
20
+ '& :where(a)': { textDecoration: 'revert' },
21
+ '& :where(blockquote)': { margin: 'revert' },
22
+ '& :where(code, kbd, samp)': { fontFamily: 'revert' },
23
+ '& :where(img)': {
24
+ display: 'revert',
25
+ verticalAlign: 'revert',
26
+ maxWidth: 'revert',
27
+ height: 'revert',
28
+ },
29
+ '& :where(pre)': {
30
+ margin: 'revert',
31
+ fontFamily: 'revert',
32
+ fontSize: 'revert',
33
+ },
34
+ '& :where(sub, sup)': {
35
+ fontSize: 'revert',
36
+ lineHeight: 'revert',
37
+ position: 'revert',
38
+ verticalAlign: 'revert',
39
+ },
40
+ } satisfies CSSObject
2
41
 
3
42
  export const styles = {
4
43
  root: {
44
+ ...markdownElementDefaults,
5
45
  color: 'text.primary',
6
46
  '& a': { color: 'primary.main' },
7
47
  '& code': {
@@ -2,6 +2,7 @@ import { useCallback, useEffect, useRef, useState, type ReactNode } from 'react'
2
2
  import { Box, Link, Typography } from '@mui/material'
3
3
  import type { Components } from 'react-markdown'
4
4
  import { MarkdownContent } from '../markdown/markdown-content'
5
+ import { markdownElementDefaults } from '../markdown/style'
5
6
  import { observeResize } from '../echart/shared-resize-observer'
6
7
  import { DEFAULT_NOTE_LABELS, type NoteLabels } from './labels'
7
8
  import { styles } from './style'
@@ -107,7 +108,9 @@ function NoteBase({ lineClamp = 3, labels, children }: NoteProps) {
107
108
  function NoteMarkdown({ content, lineClamp = 3, labels }: NoteMarkdownProps) {
108
109
  return (
109
110
  <NoteShell lineClamp={lineClamp} labels={labels} dependency={content}>
110
- <MarkdownContent content={content} components={NOTE_COMPONENTS} />
111
+ <Box sx={markdownElementDefaults}>
112
+ <MarkdownContent content={content} components={NOTE_COMPONENTS} />
113
+ </Box>
111
114
  </NoteShell>
112
115
  )
113
116
  }
@@ -12,6 +12,7 @@ import {
12
12
  } from '../utils/option-builders'
13
13
  import type { OptionFactory, OptionFactoryContext } from '../echart'
14
14
  import { mergeOptions, resolveThemeColor } from '../utils'
15
+ import { spacingPx } from '../utils/spacing-px'
15
16
  import { createItemColorResolver } from '../utils/item-color'
16
17
  import type { WidgetSeries } from '../types'
17
18
  import type {
@@ -67,7 +68,7 @@ export function pieOptions({
67
68
  trigger: 'item',
68
69
  backgroundColor: theme.palette.grey[900],
69
70
  borderWidth: 0,
70
- padding: [parseInt(theme.spacing(1)), parseInt(theme.spacing(1))],
71
+ padding: [spacingPx(theme, 1), spacingPx(theme, 1)],
71
72
  textStyle: {
72
73
  color: theme.palette.common.white,
73
74
  fontSize: 11,
@@ -466,7 +467,7 @@ function buildMultiSeriesBarFusion(
466
467
  grid: {
467
468
  ...baseGrid,
468
469
  ...buildGridConfig(true, theme),
469
- right: parseInt(theme.spacing(4)),
470
+ right: spacingPx(theme, 4),
470
471
  containLabel: true,
471
472
  },
472
473
  // Drop pie-specific structural keys that shouldn't render in the
@@ -511,7 +512,7 @@ function buildMultiSeriesBarFusion(
511
512
  axisLabel: {
512
513
  fontSize: theme.typography.overlineDelicate?.fontSize,
513
514
  fontFamily: theme.typography.overlineDelicate?.fontFamily,
514
- margin: parseInt(theme.spacing(1)),
515
+ margin: spacingPx(theme, 1),
515
516
  showMaxLabel: true,
516
517
  showMinLabel: true,
517
518
  formatter: (value: number) => {
@@ -526,7 +527,7 @@ function buildMultiSeriesBarFusion(
526
527
  axisLine: { show: false },
527
528
  axisTick: { show: false },
528
529
  axisLabel: {
529
- padding: [parseInt(theme.spacing(0.5)), 0, 0, 0],
530
+ padding: [spacingPx(theme, 0.5), 0, 0, 0],
530
531
  ...(labelFormatter && {
531
532
  formatter: (value: string | number) => String(labelFormatter(value)),
532
533
  }),