@flesler/cursor-canvas-web 1.4.0 → 1.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.
- package/dist/cursor-canvas-web.css +1 -0
- package/dist/cursor-canvas.cjs +1 -1
- package/dist/cursor-canvas.js +584 -612
- package/dist/pie-donut-DNbA0GeH.cjs +1 -0
- package/dist/pie-donut-qRBFP0tT.js +63 -0
- package/package.json +6 -2
- package/src/runtime/index.tsx +64 -0
- package/src/shim/__tests__/barChart.test.ts +61 -0
- package/src/shim/__tests__/canvas.smoke.test.tsx +209 -0
- package/src/shim/__tests__/category-theme.test.tsx +58 -0
- package/src/shim/__tests__/chartLegendOrder.test.tsx +34 -0
- package/src/shim/__tests__/dag.test.ts +49 -0
- package/src/shim/__tests__/host-tokens.test.ts +106 -0
- package/src/shim/__tests__/lineChart.test.ts +28 -0
- package/src/shim/__tests__/useCanvasState.test.tsx +35 -0
- package/src/shim/__tests__/useHostTheme.test.tsx +43 -0
- package/src/shim/__tests__/valueAxis.test.ts +39 -0
- package/src/shim/bar-chart.tsx +78 -0
- package/src/shim/canvas-hooks.tsx +57 -0
- package/src/shim/canvas-mantine-root.tsx +129 -0
- package/src/shim/chart-shared.tsx +259 -0
- package/src/shim/cursor-canvas.tsx +136 -0
- package/src/shim/dag.ts +179 -0
- package/src/shim/diff.tsx +161 -0
- package/src/shim/host-tokens.ts +614 -0
- package/src/shim/line-chart.tsx +65 -0
- package/src/shim/pie-chart.tsx +127 -0
- package/src/shim/pie-donut.tsx +79 -0
- package/src/shim/theme.ts +77 -0
- package/src/shim/todo.tsx +184 -0
- package/src/shim/ui/actions.tsx +58 -0
- package/src/shim/ui/card-context.tsx +11 -0
- package/src/shim/ui/card.tsx +79 -0
- package/src/shim/ui/chevron.tsx +23 -0
- package/src/shim/ui/display.tsx +83 -0
- package/src/shim/ui/form.tsx +102 -0
- package/src/shim/ui/layout.tsx +67 -0
- package/src/shim/ui/rich.tsx +136 -0
- package/src/shim/ui/table.tsx +71 -0
- package/src/shim/ui/typography.tsx +129 -0
- package/src/shim/use-tokens.ts +13 -0
- package/src/superset/chart-extra.d.ts +11 -11
- package/src/superset/index.d.ts +4 -4
|
@@ -0,0 +1,614 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime mirror of vendored `canvas-tokens.d.ts` + `theme.d.ts` token helpers.
|
|
3
|
+
*/
|
|
4
|
+
import type { CanvasHostThemeBrand, CanvasHostThemeOverrides, CanvasPalette, CanvasTokens, CategoryPalette, Color } from '../vendor/canvas-sdk/canvas-tokens.js'
|
|
5
|
+
import type { CanvasHostTheme } from '../vendor/canvas-sdk/hooks.js'
|
|
6
|
+
import type { CanvasRadius, CanvasTypography } from '../vendor/canvas-sdk/theme.js'
|
|
7
|
+
|
|
8
|
+
export type {
|
|
9
|
+
CanvasHostThemeBrand,
|
|
10
|
+
CanvasHostThemeOverrides,
|
|
11
|
+
CanvasPalette,
|
|
12
|
+
CanvasTokens,
|
|
13
|
+
CategoryPalette,
|
|
14
|
+
Color,
|
|
15
|
+
} from '../vendor/canvas-sdk/canvas-tokens.js'
|
|
16
|
+
|
|
17
|
+
export const canvasPaletteDark: CanvasPalette = {
|
|
18
|
+
foreground: '#E4E4E4EB',
|
|
19
|
+
foregroundSecondary: '#E4E4E48D',
|
|
20
|
+
foregroundTertiary: '#E4E4E45E',
|
|
21
|
+
foregroundQuaternary: '#E4E4E442',
|
|
22
|
+
editor: '#181818',
|
|
23
|
+
chrome: '#141414',
|
|
24
|
+
sidebar: '#141414',
|
|
25
|
+
elevated: '#181818',
|
|
26
|
+
fillPrimary: '#E4E4E430',
|
|
27
|
+
fillSecondary: '#E4E4E41E',
|
|
28
|
+
fillTertiary: '#E4E4E411',
|
|
29
|
+
fillQuaternary: '#E4E4E40A',
|
|
30
|
+
strokePrimary: '#E4E4E433',
|
|
31
|
+
strokeSecondary: '#E4E4E41F',
|
|
32
|
+
strokeTertiary: '#E4E4E414',
|
|
33
|
+
strokeFocused: '#599CE7',
|
|
34
|
+
accent: '#599CE7',
|
|
35
|
+
buttonBackground: '#599CE7',
|
|
36
|
+
buttonForeground: '#191c22',
|
|
37
|
+
buttonHoverBackground: '#6AABE9',
|
|
38
|
+
link: '#87c3ff',
|
|
39
|
+
diffInsertedLine: '#3FA26633',
|
|
40
|
+
diffRemovedLine: '#B8004933',
|
|
41
|
+
diffStripAdded: '#3FA2668F',
|
|
42
|
+
diffStripRemoved: '#FC6B838F',
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export const canvasPaletteLight: CanvasPalette = {
|
|
46
|
+
foreground: '#141414F0',
|
|
47
|
+
foregroundSecondary: '#141414BD',
|
|
48
|
+
foregroundTertiary: '#1414148A',
|
|
49
|
+
foregroundQuaternary: '#1414145C',
|
|
50
|
+
editor: '#FCFCFC',
|
|
51
|
+
chrome: '#F8F8F8',
|
|
52
|
+
sidebar: '#F3F3F3',
|
|
53
|
+
elevated: '#FCFCFC',
|
|
54
|
+
fillPrimary: '#14141433',
|
|
55
|
+
fillSecondary: '#14141424',
|
|
56
|
+
fillTertiary: '#14141414',
|
|
57
|
+
fillQuaternary: '#1414140F',
|
|
58
|
+
strokePrimary: '#14141433',
|
|
59
|
+
strokeSecondary: '#1414141F',
|
|
60
|
+
strokeTertiary: '#14141414',
|
|
61
|
+
strokeFocused: '#3685BF',
|
|
62
|
+
accent: '#3685BF',
|
|
63
|
+
buttonBackground: '#3685BF',
|
|
64
|
+
buttonForeground: '#FCFCFC',
|
|
65
|
+
buttonHoverBackground: '#2E76AB',
|
|
66
|
+
link: '#3685BF',
|
|
67
|
+
diffInsertedLine: '#1F8A651F',
|
|
68
|
+
diffRemovedLine: '#CF2D5614',
|
|
69
|
+
diffStripAdded: '#1F8A65CC',
|
|
70
|
+
diffStripRemoved: '#CF2D56CC',
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const grokAccentDark = {
|
|
74
|
+
accent: '#1084FE',
|
|
75
|
+
buttonBackground: '#1084FE',
|
|
76
|
+
buttonForeground: '#070707',
|
|
77
|
+
buttonHoverBackground: '#459FFE',
|
|
78
|
+
link: '#80BEFE',
|
|
79
|
+
strokeFocused: '#1084FE',
|
|
80
|
+
} as const
|
|
81
|
+
|
|
82
|
+
const grokAccentLight = {
|
|
83
|
+
accent: '#0C64C1',
|
|
84
|
+
buttonBackground: '#0C64C1',
|
|
85
|
+
buttonForeground: '#FAFAFA',
|
|
86
|
+
buttonHoverBackground: '#1084FE',
|
|
87
|
+
link: '#0C64C1',
|
|
88
|
+
strokeFocused: '#0C64C1',
|
|
89
|
+
} as const
|
|
90
|
+
|
|
91
|
+
export const canvasPaletteGrokDark: CanvasPalette = {
|
|
92
|
+
...canvasPaletteDark,
|
|
93
|
+
...grokAccentDark,
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export const canvasPaletteGrokLight: CanvasPalette = {
|
|
97
|
+
...canvasPaletteLight,
|
|
98
|
+
...grokAccentLight,
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/** Chromatic category hues only; `gray` is taken from the active canvas palette. */
|
|
102
|
+
type CategoryChromatic = Readonly<Record<Exclude<Color, 'gray'>, string>>
|
|
103
|
+
|
|
104
|
+
const cursorCategoryChromaticDark: CategoryChromatic = {
|
|
105
|
+
purple: '#7B64B8F0',
|
|
106
|
+
green: '#1F8A65E8',
|
|
107
|
+
yellow: '#E8C030E0',
|
|
108
|
+
cyan: '#2A9A8AE0',
|
|
109
|
+
pink: '#C85898E0',
|
|
110
|
+
blue: '#2E79B5E0',
|
|
111
|
+
orange: '#F0A040E0',
|
|
112
|
+
red: '#C04848E0',
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const cursorCategoryChromaticLight: CategoryChromatic = {
|
|
116
|
+
...cursorCategoryChromaticDark,
|
|
117
|
+
orange: '#F0A088E0',
|
|
118
|
+
red: '#CF2D56E0',
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const grokCategoryChromatic: CategoryChromatic = {
|
|
122
|
+
purple: '#9159FEF0',
|
|
123
|
+
green: '#00C972E8',
|
|
124
|
+
yellow: '#FF9800E0',
|
|
125
|
+
cyan: '#00BCA6E0',
|
|
126
|
+
pink: '#FF309BE0',
|
|
127
|
+
blue: '#1084FEE0',
|
|
128
|
+
orange: '#FF6700E0',
|
|
129
|
+
red: '#FF263CE0',
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function categoryPaletteFor(
|
|
133
|
+
chromatic: CategoryChromatic,
|
|
134
|
+
palette: CanvasPalette,
|
|
135
|
+
): CategoryPalette {
|
|
136
|
+
return {
|
|
137
|
+
gray: palette.foregroundTertiary,
|
|
138
|
+
...chromatic,
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export const categoryPaletteDark = categoryPaletteFor(
|
|
143
|
+
cursorCategoryChromaticDark,
|
|
144
|
+
canvasPaletteDark,
|
|
145
|
+
)
|
|
146
|
+
export const categoryPaletteLight = categoryPaletteFor(
|
|
147
|
+
cursorCategoryChromaticLight,
|
|
148
|
+
canvasPaletteLight,
|
|
149
|
+
)
|
|
150
|
+
export const categoryPaletteGrokDark = categoryPaletteFor(
|
|
151
|
+
grokCategoryChromatic,
|
|
152
|
+
canvasPaletteGrokDark,
|
|
153
|
+
)
|
|
154
|
+
export const categoryPaletteGrokLight = categoryPaletteFor(
|
|
155
|
+
grokCategoryChromatic,
|
|
156
|
+
canvasPaletteGrokLight,
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
export const colorPalette = categoryPaletteDark
|
|
160
|
+
|
|
161
|
+
export const usageColorSequence: readonly Color[] = [
|
|
162
|
+
'blue',
|
|
163
|
+
'purple',
|
|
164
|
+
'green',
|
|
165
|
+
'yellow',
|
|
166
|
+
'cyan',
|
|
167
|
+
'pink',
|
|
168
|
+
'orange',
|
|
169
|
+
'red',
|
|
170
|
+
'gray',
|
|
171
|
+
]
|
|
172
|
+
|
|
173
|
+
export const chartPalette = {
|
|
174
|
+
green: '#1F8A65E8',
|
|
175
|
+
darkGreen: '#0D855AE0',
|
|
176
|
+
lightGreen: '#52B896E0',
|
|
177
|
+
mintGreen: '#7DCAB0E0',
|
|
178
|
+
blue: '#2E79B5E0',
|
|
179
|
+
lightBlue: '#70B0D8E0',
|
|
180
|
+
indigo: '#5A6CC0F0',
|
|
181
|
+
lightIndigo: '#9AAADCE0',
|
|
182
|
+
purple: '#7B64B8F0',
|
|
183
|
+
lightPurple: '#AA98D8E0',
|
|
184
|
+
warmPink: '#C85898E0',
|
|
185
|
+
lightPink: '#E8A0C4E0',
|
|
186
|
+
brightOrange: '#F0A040E0',
|
|
187
|
+
deepOrange: '#C06028E0',
|
|
188
|
+
goldenYellow: '#E8C030E0',
|
|
189
|
+
darkAmber: '#C04848E0',
|
|
190
|
+
warmPeach: '#F0A088E0',
|
|
191
|
+
vibrantTeal: '#2A9A8AE0',
|
|
192
|
+
muted: '#8888A8E0',
|
|
193
|
+
neutralLine: '#888899D0',
|
|
194
|
+
} as const
|
|
195
|
+
|
|
196
|
+
export type ChartPalette = typeof chartPalette
|
|
197
|
+
|
|
198
|
+
export const chartPaletteGrok = {
|
|
199
|
+
green: '#00C972E8',
|
|
200
|
+
darkGreen: '#009957E0',
|
|
201
|
+
lightGreen: '#38D591E0',
|
|
202
|
+
mintGreen: '#78E2B4E0',
|
|
203
|
+
blue: '#1084FEE0',
|
|
204
|
+
lightBlue: '#459FFEE0',
|
|
205
|
+
indigo: '#0C64C1F0',
|
|
206
|
+
lightIndigo: '#80BEFEE0',
|
|
207
|
+
purple: '#9159FEF0',
|
|
208
|
+
lightPurple: '#A97EFEE0',
|
|
209
|
+
warmPink: '#FF309BE0',
|
|
210
|
+
lightPink: '#FF5EB1E0',
|
|
211
|
+
brightOrange: '#FF6700E0',
|
|
212
|
+
deepOrange: '#C24E00E0',
|
|
213
|
+
goldenYellow: '#FF9800E0',
|
|
214
|
+
darkAmber: '#FF263CE0',
|
|
215
|
+
warmPeach: '#FF8838E0',
|
|
216
|
+
vibrantTeal: '#00BCA6E0',
|
|
217
|
+
muted: '#777777E0',
|
|
218
|
+
neutralLine: '#777777D0',
|
|
219
|
+
} as const
|
|
220
|
+
|
|
221
|
+
export const chartColorSequence: readonly string[] = [
|
|
222
|
+
chartPalette.green,
|
|
223
|
+
chartPalette.lightBlue,
|
|
224
|
+
chartPalette.indigo,
|
|
225
|
+
chartPalette.brightOrange,
|
|
226
|
+
chartPalette.deepOrange,
|
|
227
|
+
chartPalette.goldenYellow,
|
|
228
|
+
chartPalette.warmPink,
|
|
229
|
+
chartPalette.warmPeach,
|
|
230
|
+
chartPalette.purple,
|
|
231
|
+
chartPalette.mintGreen,
|
|
232
|
+
chartPalette.muted,
|
|
233
|
+
chartPalette.vibrantTeal,
|
|
234
|
+
]
|
|
235
|
+
|
|
236
|
+
export const chartColorSequenceGrok: readonly string[] = [
|
|
237
|
+
chartPaletteGrok.green,
|
|
238
|
+
chartPaletteGrok.lightBlue,
|
|
239
|
+
chartPaletteGrok.indigo,
|
|
240
|
+
chartPaletteGrok.brightOrange,
|
|
241
|
+
chartPaletteGrok.deepOrange,
|
|
242
|
+
chartPaletteGrok.goldenYellow,
|
|
243
|
+
chartPaletteGrok.warmPink,
|
|
244
|
+
chartPaletteGrok.warmPeach,
|
|
245
|
+
chartPaletteGrok.purple,
|
|
246
|
+
chartPaletteGrok.mintGreen,
|
|
247
|
+
chartPaletteGrok.muted,
|
|
248
|
+
chartPaletteGrok.vibrantTeal,
|
|
249
|
+
]
|
|
250
|
+
|
|
251
|
+
export const canvasTypography = {
|
|
252
|
+
fontFamily: 'inherit' as const,
|
|
253
|
+
h1: { fontSize: '24px', lineHeight: '30px', fontWeight: 590 },
|
|
254
|
+
h2: { fontSize: '18px', lineHeight: '24px', fontWeight: 590 },
|
|
255
|
+
h3: { fontSize: '16px', lineHeight: '22px', fontWeight: 590 },
|
|
256
|
+
body: { fontSize: '14px', lineHeight: '20px', fontWeight: 400 },
|
|
257
|
+
small: { fontSize: '12px', lineHeight: '16px', fontWeight: 400 },
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
export const canvasFontFamilyCursor = 'inherit' as const
|
|
261
|
+
|
|
262
|
+
export const canvasFontFamilyGrok =
|
|
263
|
+
'ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif'
|
|
264
|
+
|
|
265
|
+
export const canvasSpacing = {
|
|
266
|
+
'0.5': 2,
|
|
267
|
+
'1': 4,
|
|
268
|
+
'1.5': 6,
|
|
269
|
+
'2': 8,
|
|
270
|
+
'2.5': 10,
|
|
271
|
+
'3': 12,
|
|
272
|
+
'3.5': 14,
|
|
273
|
+
'4': 16,
|
|
274
|
+
'4.5': 18,
|
|
275
|
+
'5': 20,
|
|
276
|
+
'6': 24,
|
|
277
|
+
'7': 28,
|
|
278
|
+
'8': 32,
|
|
279
|
+
'9': 36,
|
|
280
|
+
'10': 40,
|
|
281
|
+
} as const
|
|
282
|
+
|
|
283
|
+
export const canvasRadius = {
|
|
284
|
+
none: 0,
|
|
285
|
+
xs: 2,
|
|
286
|
+
sm: 4,
|
|
287
|
+
md: 6,
|
|
288
|
+
lg: 8,
|
|
289
|
+
xl: 12,
|
|
290
|
+
full: 9999,
|
|
291
|
+
} as const
|
|
292
|
+
|
|
293
|
+
export const canvasRadiusGrok: CanvasRadius = {
|
|
294
|
+
...canvasRadius,
|
|
295
|
+
md: 8,
|
|
296
|
+
lg: 10,
|
|
297
|
+
xl: 14,
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
export const canvasTypographyGrok: CanvasTypography = {
|
|
301
|
+
...canvasTypography,
|
|
302
|
+
fontFamily: canvasFontFamilyGrok,
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
function tokensFromPalette(
|
|
306
|
+
palette: CanvasPalette,
|
|
307
|
+
category: CategoryPalette,
|
|
308
|
+
): CanvasTokens {
|
|
309
|
+
return {
|
|
310
|
+
bg: {
|
|
311
|
+
editor: palette.editor,
|
|
312
|
+
chrome: palette.chrome,
|
|
313
|
+
elevated: palette.elevated,
|
|
314
|
+
},
|
|
315
|
+
text: {
|
|
316
|
+
primary: palette.foreground,
|
|
317
|
+
secondary: palette.foregroundSecondary,
|
|
318
|
+
tertiary: palette.foregroundTertiary,
|
|
319
|
+
quaternary: palette.foregroundQuaternary,
|
|
320
|
+
link: palette.link,
|
|
321
|
+
onAccent: palette.buttonForeground,
|
|
322
|
+
},
|
|
323
|
+
stroke: {
|
|
324
|
+
primary: palette.strokePrimary,
|
|
325
|
+
secondary: palette.strokeSecondary,
|
|
326
|
+
tertiary: palette.strokeTertiary,
|
|
327
|
+
focused: palette.strokeFocused,
|
|
328
|
+
},
|
|
329
|
+
fill: {
|
|
330
|
+
primary: palette.fillPrimary,
|
|
331
|
+
secondary: palette.fillSecondary,
|
|
332
|
+
tertiary: palette.fillTertiary,
|
|
333
|
+
quaternary: palette.fillQuaternary,
|
|
334
|
+
},
|
|
335
|
+
accent: {
|
|
336
|
+
primary: palette.accent,
|
|
337
|
+
control: palette.buttonBackground,
|
|
338
|
+
controlHover: palette.buttonHoverBackground,
|
|
339
|
+
},
|
|
340
|
+
diff: {
|
|
341
|
+
insertedLine: palette.diffInsertedLine,
|
|
342
|
+
removedLine: palette.diffRemovedLine,
|
|
343
|
+
stripAdded: palette.diffStripAdded,
|
|
344
|
+
stripRemoved: palette.diffStripRemoved,
|
|
345
|
+
},
|
|
346
|
+
category,
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
export const canvasTokens = tokensFromPalette(
|
|
351
|
+
canvasPaletteDark,
|
|
352
|
+
categoryPaletteDark,
|
|
353
|
+
)
|
|
354
|
+
export const canvasTokensLight = tokensFromPalette(
|
|
355
|
+
canvasPaletteLight,
|
|
356
|
+
categoryPaletteLight,
|
|
357
|
+
)
|
|
358
|
+
|
|
359
|
+
export function parseHexColor(value: string): { r: number; g: number; b: number } | undefined {
|
|
360
|
+
const trimmed = value.trim()
|
|
361
|
+
const match = /^#([0-9a-f]{3,8})$/i.exec(trimmed)
|
|
362
|
+
if (!match) {
|
|
363
|
+
return undefined
|
|
364
|
+
}
|
|
365
|
+
const hex = match[1]
|
|
366
|
+
if (hex.length === 3 || hex.length === 4) {
|
|
367
|
+
const expand = (c: string) => c + c
|
|
368
|
+
const r = parseInt(expand(hex[0]), 16)
|
|
369
|
+
const g = parseInt(expand(hex[1]), 16)
|
|
370
|
+
const b = parseInt(expand(hex[2]), 16)
|
|
371
|
+
return { r, g, b }
|
|
372
|
+
}
|
|
373
|
+
if (hex.length === 6 || hex.length === 8) {
|
|
374
|
+
const r = parseInt(hex.slice(0, 2), 16)
|
|
375
|
+
const g = parseInt(hex.slice(2, 4), 16)
|
|
376
|
+
const b = parseInt(hex.slice(4, 6), 16)
|
|
377
|
+
return { r, g, b }
|
|
378
|
+
}
|
|
379
|
+
return undefined
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
function relativeLuminance(rgb: { r: number; g: number; b: number }): number {
|
|
383
|
+
const channel = (c: number) => {
|
|
384
|
+
const s = c / 255
|
|
385
|
+
return s <= 0.03928 ? s / 12.92 : ((s + 0.055) / 1.055) ** 2.4
|
|
386
|
+
}
|
|
387
|
+
return (
|
|
388
|
+
0.2126 * channel(rgb.r) +
|
|
389
|
+
0.7152 * channel(rgb.g) +
|
|
390
|
+
0.0722 * channel(rgb.b)
|
|
391
|
+
)
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
function mixRgb(
|
|
395
|
+
a: { r: number; g: number; b: number },
|
|
396
|
+
b: { r: number; g: number; b: number },
|
|
397
|
+
weightB: number,
|
|
398
|
+
): { r: number; g: number; b: number } {
|
|
399
|
+
const w = Math.min(1, Math.max(0, weightB))
|
|
400
|
+
return {
|
|
401
|
+
r: Math.round(a.r * (1 - w) + b.r * w),
|
|
402
|
+
g: Math.round(a.g * (1 - w) + b.g * w),
|
|
403
|
+
b: Math.round(a.b * (1 - w) + b.b * w),
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
function rgbToHex(rgb: { r: number; g: number; b: number }): string {
|
|
408
|
+
const part = (n: number) => n.toString(16).padStart(2, '0')
|
|
409
|
+
return `#${part(rgb.r)}${part(rgb.g)}${part(rgb.b)}`
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
export function parseCanvasHostThemeBrand(
|
|
413
|
+
value: unknown,
|
|
414
|
+
): CanvasHostThemeBrand {
|
|
415
|
+
return value === 'grok' ? 'grok' : 'cursor'
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
export function applyWorkbenchSurfaces(
|
|
419
|
+
palette: CanvasPalette,
|
|
420
|
+
surfaces: Pick<
|
|
421
|
+
CanvasHostThemeOverrides,
|
|
422
|
+
'editorBackground' | 'editorForeground'
|
|
423
|
+
>,
|
|
424
|
+
): CanvasPalette {
|
|
425
|
+
let next = palette
|
|
426
|
+
if (
|
|
427
|
+
typeof surfaces.editorBackground === 'string' &&
|
|
428
|
+
parseHexColor(surfaces.editorBackground)
|
|
429
|
+
) {
|
|
430
|
+
const bg = surfaces.editorBackground
|
|
431
|
+
next = {
|
|
432
|
+
...next,
|
|
433
|
+
editor: bg,
|
|
434
|
+
chrome: bg,
|
|
435
|
+
sidebar: bg,
|
|
436
|
+
elevated: bg,
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
if (
|
|
440
|
+
typeof surfaces.editorForeground === 'string' &&
|
|
441
|
+
parseHexColor(surfaces.editorForeground)
|
|
442
|
+
) {
|
|
443
|
+
const fg = surfaces.editorForeground
|
|
444
|
+
next = {
|
|
445
|
+
...next,
|
|
446
|
+
foreground: fg,
|
|
447
|
+
foregroundSecondary: fg,
|
|
448
|
+
foregroundTertiary: fg,
|
|
449
|
+
foregroundQuaternary: fg,
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
return next
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
export function applyPrimaryColor(
|
|
456
|
+
palette: CanvasPalette,
|
|
457
|
+
primary: string,
|
|
458
|
+
): CanvasPalette {
|
|
459
|
+
const rgb = parseHexColor(primary)
|
|
460
|
+
if (!rgb) {
|
|
461
|
+
return palette
|
|
462
|
+
}
|
|
463
|
+
const hover = mixRgb(rgb, { r: 255, g: 255, b: 255 }, 0.12)
|
|
464
|
+
const onAccent =
|
|
465
|
+
relativeLuminance(rgb) > 0.45 ? '#141414' : '#FAFAFA'
|
|
466
|
+
return {
|
|
467
|
+
...palette,
|
|
468
|
+
accent: primary,
|
|
469
|
+
buttonBackground: primary,
|
|
470
|
+
buttonHoverBackground: rgbToHex(hover),
|
|
471
|
+
link: primary,
|
|
472
|
+
strokeFocused: primary,
|
|
473
|
+
buttonForeground: onAccent,
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
const LIGHT_KINDS = new Set(['light', 'hc-light'])
|
|
478
|
+
|
|
479
|
+
function isLightKind(kind: string): boolean {
|
|
480
|
+
return LIGHT_KINDS.has(kind)
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
export function buildHostTokens(
|
|
484
|
+
kind: string,
|
|
485
|
+
overrides?: CanvasHostThemeOverrides,
|
|
486
|
+
): {
|
|
487
|
+
tokens: CanvasTokens;
|
|
488
|
+
palette: CanvasPalette;
|
|
489
|
+
brand: CanvasHostThemeBrand
|
|
490
|
+
} {
|
|
491
|
+
const brand = parseCanvasHostThemeBrand(overrides?.brand)
|
|
492
|
+
const light = isLightKind(kind)
|
|
493
|
+
let palette: CanvasPalette
|
|
494
|
+
if (brand === 'grok') {
|
|
495
|
+
palette = light ? canvasPaletteGrokLight : canvasPaletteGrokDark
|
|
496
|
+
} else {
|
|
497
|
+
palette = light ? canvasPaletteLight : canvasPaletteDark
|
|
498
|
+
}
|
|
499
|
+
palette = applyWorkbenchSurfaces(palette, overrides ?? {})
|
|
500
|
+
if (brand !== 'grok' && typeof overrides?.primary === 'string') {
|
|
501
|
+
palette = applyPrimaryColor(palette, overrides.primary)
|
|
502
|
+
}
|
|
503
|
+
const chromatic =
|
|
504
|
+
brand === 'grok'
|
|
505
|
+
? grokCategoryChromatic
|
|
506
|
+
: light
|
|
507
|
+
? cursorCategoryChromaticLight
|
|
508
|
+
: cursorCategoryChromaticDark
|
|
509
|
+
const category = categoryPaletteFor(chromatic, palette)
|
|
510
|
+
const tokens = tokensFromPalette(palette, category)
|
|
511
|
+
return { tokens, palette, brand }
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
export function chartThemeForBrand(brand: CanvasHostThemeBrand): {
|
|
515
|
+
palette: ChartPalette;
|
|
516
|
+
sequence: readonly string[]
|
|
517
|
+
} {
|
|
518
|
+
if (brand === 'grok') {
|
|
519
|
+
return {
|
|
520
|
+
palette: chartPaletteGrok as unknown as ChartPalette,
|
|
521
|
+
sequence: chartColorSequenceGrok,
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
return { palette: chartPalette, sequence: chartColorSequence }
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
export function canvasRadiusForBrand(
|
|
528
|
+
brand: CanvasHostThemeBrand,
|
|
529
|
+
): CanvasRadius {
|
|
530
|
+
return brand === 'grok' ? canvasRadiusGrok : canvasRadius
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
export function canvasTypographyForBrand(
|
|
534
|
+
brand: CanvasHostThemeBrand,
|
|
535
|
+
): CanvasTypography {
|
|
536
|
+
return brand === 'grok' ? canvasTypographyGrok : canvasTypography
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
export type ShimHostTheme = CanvasHostTheme & {
|
|
540
|
+
readonly category: CategoryPalette;
|
|
541
|
+
readonly spacing: typeof canvasSpacing
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
type RawHostThemeState = {
|
|
545
|
+
readonly kind?: unknown;
|
|
546
|
+
readonly brand?: unknown;
|
|
547
|
+
readonly primary?: unknown;
|
|
548
|
+
readonly editorBackground?: unknown;
|
|
549
|
+
readonly editorForeground?: unknown
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
function readHostThemeRaw(): RawHostThemeState | undefined {
|
|
553
|
+
if (typeof window === 'undefined') {
|
|
554
|
+
return undefined
|
|
555
|
+
}
|
|
556
|
+
const bridge = (window as Window & { __cursorCanvas?: { state?: { theme?: RawHostThemeState } } })
|
|
557
|
+
.__cursorCanvas
|
|
558
|
+
return bridge?.state?.theme
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
export function resolveTheme(
|
|
562
|
+
raw: RawHostThemeState | undefined,
|
|
563
|
+
fallbackKind?: 'light' | 'dark',
|
|
564
|
+
): ShimHostTheme {
|
|
565
|
+
let kind =
|
|
566
|
+
typeof raw?.kind === 'string' && raw.kind.length > 0
|
|
567
|
+
? raw.kind
|
|
568
|
+
: undefined
|
|
569
|
+
if (!kind) {
|
|
570
|
+
if (fallbackKind) {
|
|
571
|
+
kind = fallbackKind
|
|
572
|
+
} else if (typeof window !== 'undefined' && window.matchMedia) {
|
|
573
|
+
kind = window.matchMedia('(prefers-color-scheme: dark)').matches
|
|
574
|
+
? 'dark'
|
|
575
|
+
: 'light'
|
|
576
|
+
} else {
|
|
577
|
+
kind = 'dark'
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
const overrides: CanvasHostThemeOverrides = {
|
|
581
|
+
brand: parseCanvasHostThemeBrand(raw?.brand),
|
|
582
|
+
primary:
|
|
583
|
+
typeof raw?.primary === 'string' ? raw.primary : undefined,
|
|
584
|
+
editorBackground:
|
|
585
|
+
typeof raw?.editorBackground === 'string'
|
|
586
|
+
? raw.editorBackground
|
|
587
|
+
: undefined,
|
|
588
|
+
editorForeground:
|
|
589
|
+
typeof raw?.editorForeground === 'string'
|
|
590
|
+
? raw.editorForeground
|
|
591
|
+
: undefined,
|
|
592
|
+
}
|
|
593
|
+
const { tokens, palette, brand } = buildHostTokens(kind, overrides)
|
|
594
|
+
const chart = chartThemeForBrand(brand)
|
|
595
|
+
return {
|
|
596
|
+
...tokens,
|
|
597
|
+
kind,
|
|
598
|
+
brand,
|
|
599
|
+
tokens,
|
|
600
|
+
palette,
|
|
601
|
+
category: tokens.category,
|
|
602
|
+
radius: canvasRadiusForBrand(brand),
|
|
603
|
+
typography: canvasTypographyForBrand(brand),
|
|
604
|
+
chart,
|
|
605
|
+
spacing: canvasSpacing,
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
export function resolveThemeForColorScheme(
|
|
610
|
+
scheme: 'light' | 'dark',
|
|
611
|
+
): ShimHostTheme {
|
|
612
|
+
const host = readHostThemeRaw()
|
|
613
|
+
return resolveTheme(host, scheme)
|
|
614
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { LineChartCurveType } from '@mantine/charts'
|
|
2
|
+
import { AreaChart, LineChart as MantineLineChart } from '@mantine/charts'
|
|
3
|
+
import '@mantine/charts/styles.css'
|
|
4
|
+
import type { LineChartProps } from '../superset/index'
|
|
5
|
+
import { CHART_LEGEND_PROPS, CHART_LEGEND_STYLES, CHART_TOOLTIP_PROPS, reshapeLineChartData, toMantineSeries, useChartColorProps, useSeriesColor, valueAxisChartProps, valueFormatter } from './chart-shared'
|
|
6
|
+
|
|
7
|
+
export function LineChart({
|
|
8
|
+
categories,
|
|
9
|
+
series,
|
|
10
|
+
height = 240,
|
|
11
|
+
fill,
|
|
12
|
+
valueSuffix,
|
|
13
|
+
valuePrefix,
|
|
14
|
+
showValues,
|
|
15
|
+
showHoverGuide = true,
|
|
16
|
+
beginAtZero,
|
|
17
|
+
yMin,
|
|
18
|
+
yMax,
|
|
19
|
+
referenceLines,
|
|
20
|
+
style,
|
|
21
|
+
extra,
|
|
22
|
+
smooth: legacySmooth,
|
|
23
|
+
}: LineChartProps) {
|
|
24
|
+
const smooth = extra?.smooth ?? legacySmooth
|
|
25
|
+
const seriesColor = useSeriesColor()
|
|
26
|
+
const chartColors = useChartColorProps()
|
|
27
|
+
const data = reshapeLineChartData(categories, series)
|
|
28
|
+
const mantineSeries = toMantineSeries(series, seriesColor)
|
|
29
|
+
const stacked = Boolean(fill && extra?.stacked)
|
|
30
|
+
const axis = valueAxisChartProps({
|
|
31
|
+
beginAtZero,
|
|
32
|
+
yMin,
|
|
33
|
+
yMax,
|
|
34
|
+
referenceLines,
|
|
35
|
+
horizontal: false,
|
|
36
|
+
stacked,
|
|
37
|
+
valueAxis: extra?.valueAxis,
|
|
38
|
+
})
|
|
39
|
+
const common = {
|
|
40
|
+
h: height,
|
|
41
|
+
data,
|
|
42
|
+
dataKey: 'category',
|
|
43
|
+
series: mantineSeries,
|
|
44
|
+
curveType: (smooth ? 'monotone' : 'linear') as LineChartCurveType,
|
|
45
|
+
withLegend: series.length > 1,
|
|
46
|
+
legendProps: CHART_LEGEND_PROPS,
|
|
47
|
+
valueFormatter: valueFormatter(valueSuffix, valuePrefix),
|
|
48
|
+
withPointLabels: showValues ?? categories.length <= 20,
|
|
49
|
+
tooltipProps: {
|
|
50
|
+
...CHART_TOOLTIP_PROPS,
|
|
51
|
+
...(!showHoverGuide && { cursor: false }),
|
|
52
|
+
},
|
|
53
|
+
styles: {
|
|
54
|
+
...CHART_LEGEND_STYLES,
|
|
55
|
+
legendItemName: { color: chartColors.textColor },
|
|
56
|
+
},
|
|
57
|
+
...axis,
|
|
58
|
+
style,
|
|
59
|
+
}
|
|
60
|
+
return fill ? (
|
|
61
|
+
<AreaChart {...common} type={stacked ? 'stacked' : 'default'} />
|
|
62
|
+
) : (
|
|
63
|
+
<MantineLineChart {...common} />
|
|
64
|
+
)
|
|
65
|
+
}
|