@stealthscale/component-charts 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +1862 -0
- package/dist/cyclonedx/bom.json +1 -0
- package/dist/index.d.ts +4332 -0
- package/dist/index.js +14711 -0
- package/dist/recipe-ZKqGhtpf.js +1054 -0
- package/dist/rolldown-runtime-D7D4PA-g.js +13 -0
- package/dist/theme.d.ts +11 -0
- package/dist/theme.js +22 -0
- package/package.json +84 -0
|
@@ -0,0 +1,1054 @@
|
|
|
1
|
+
import { below, defineRecipe, defineSlotRecipe, dense, onSlots, ratioVariants, sizeVariants } from "@stealthscale/theme/authoring";
|
|
2
|
+
//#region src/chart/placed.ts
|
|
3
|
+
/**
|
|
4
|
+
* Styles the lines, words and marks a chart places over its plot: a quadrant chart's dividing lines
|
|
5
|
+
* and names, the words beside a scatter's points, a timeline's markers, an annotation's words and
|
|
6
|
+
* the crosshair, and sizes a plot by its rows.
|
|
7
|
+
*
|
|
8
|
+
* @remarks
|
|
9
|
+
* The chart recipe spreads `PLACED` into its plot's styles and takes `ROWS_TALL` as its `rows`
|
|
10
|
+
* ratio. Each selector names the class its part renders with, so no rule applies to another
|
|
11
|
+
* chart's marks. The dividing lines are in the emphasized border ink and the quadrants' names in
|
|
12
|
+
* the label ink. A point's words are the ink inside a halo in the panel's color, and a marker's
|
|
13
|
+
* count is the black or white `contrast-color()` finds against the marker's color. An
|
|
14
|
+
* annotation's words are the label ink inside the same halo, and the crosshair takes the
|
|
15
|
+
* cursor's border ink.
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* Class a quadrant chart's two dividing lines take.
|
|
19
|
+
*/
|
|
20
|
+
const DIVISION = "chart-division";
|
|
21
|
+
/**
|
|
22
|
+
* Selects the line of each of a quadrant chart's dividing lines.
|
|
23
|
+
*/
|
|
24
|
+
const DIVISIONS = "& .chart-division .recharts-reference-line-line";
|
|
25
|
+
/**
|
|
26
|
+
* Class the name of a quadrant takes, written in its corner of the plot.
|
|
27
|
+
*/
|
|
28
|
+
const QUADRANT = "chart-quadrant";
|
|
29
|
+
/**
|
|
30
|
+
* Selects the names of a quadrant chart's quadrants.
|
|
31
|
+
*/
|
|
32
|
+
const QUADRANT_NAMES = "& .recharts-text.chart-quadrant";
|
|
33
|
+
/**
|
|
34
|
+
* Class the words beside a point take, such as a vendor's name on a quadrant chart.
|
|
35
|
+
*/
|
|
36
|
+
const POINT_LABEL = "chart-point-label";
|
|
37
|
+
/**
|
|
38
|
+
* Selects the words beside the points of a scatter.
|
|
39
|
+
*/
|
|
40
|
+
const POINT_LABELS = "& .recharts-text.chart-point-label";
|
|
41
|
+
/**
|
|
42
|
+
* Class a timeline's marker takes: a dot for one moment, or a pill with the count of a cluster.
|
|
43
|
+
*/
|
|
44
|
+
const MARKER = "chart-marker";
|
|
45
|
+
/**
|
|
46
|
+
* Custom property of a timeline marker's color, which fills the dot or the pill and which the
|
|
47
|
+
* count's ink contrasts with.
|
|
48
|
+
*/
|
|
49
|
+
const MARKER_FILL = "--chart-marker";
|
|
50
|
+
/**
|
|
51
|
+
* Selects the dot or the pill of every timeline marker.
|
|
52
|
+
*/
|
|
53
|
+
const MARKER_SHAPES = "& .chart-marker > :is(circle, rect)";
|
|
54
|
+
/**
|
|
55
|
+
* Selects the count a timeline marker writes on its pill.
|
|
56
|
+
*/
|
|
57
|
+
const MARKER_COUNTS = "& .chart-marker > text";
|
|
58
|
+
/**
|
|
59
|
+
* Selects a timeline marker the chart selects on a press.
|
|
60
|
+
*/
|
|
61
|
+
const MARKER_PRESSES = "& .chart-marker[data-press]";
|
|
62
|
+
/**
|
|
63
|
+
* Class an annotation's mark takes: a moment's rule, a period's wash or a point's ring.
|
|
64
|
+
*/
|
|
65
|
+
const ANNOTATION = "chart-annotation";
|
|
66
|
+
/**
|
|
67
|
+
* Class the words of an annotation take.
|
|
68
|
+
*/
|
|
69
|
+
const ANNOTATION_LABEL = "chart-annotation-label";
|
|
70
|
+
/**
|
|
71
|
+
* Selects the words of every annotation.
|
|
72
|
+
*/
|
|
73
|
+
const ANNOTATION_LABELS = "& .recharts-text.chart-annotation-label";
|
|
74
|
+
/**
|
|
75
|
+
* Class the crosshair's guide takes.
|
|
76
|
+
*/
|
|
77
|
+
const CROSSHAIR = "chart-crosshair";
|
|
78
|
+
/**
|
|
79
|
+
* Selects the line of the crosshair's guide.
|
|
80
|
+
*/
|
|
81
|
+
const CROSSHAIR_LINE = "& .chart-crosshair .recharts-reference-line-line";
|
|
82
|
+
/**
|
|
83
|
+
* Custom property of the number of rows a plot at the `rows` ratio is tall, such as a timeline's
|
|
84
|
+
* lanes.
|
|
85
|
+
*/
|
|
86
|
+
const ROWS = "--chart-rows";
|
|
87
|
+
/**
|
|
88
|
+
* Sizes a plot by its rows: a row of `sizes.10` per row and `sizes.12` for the axis under them.
|
|
89
|
+
*/
|
|
90
|
+
const ROWS_TALL = {
|
|
91
|
+
aspectRatio: "auto",
|
|
92
|
+
blockSize: "calc(var(--chart-rows, 1) * {sizes.10} + {sizes.12})"
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* Styles of the lines, words and marks a chart places over its plot, which the plot spreads.
|
|
96
|
+
*/
|
|
97
|
+
const PLACED = {
|
|
98
|
+
[ANNOTATION_LABELS]: {
|
|
99
|
+
_highContrast: {
|
|
100
|
+
fill: "CanvasText",
|
|
101
|
+
stroke: "Canvas"
|
|
102
|
+
},
|
|
103
|
+
fill: "fg.muted",
|
|
104
|
+
paintOrder: "stroke",
|
|
105
|
+
pointerEvents: "none",
|
|
106
|
+
stroke: "bg.panel",
|
|
107
|
+
strokeLinejoin: "round",
|
|
108
|
+
strokeWidth: "ring",
|
|
109
|
+
textStyle: "body.xs"
|
|
110
|
+
},
|
|
111
|
+
[CROSSHAIR_LINE]: {
|
|
112
|
+
_highContrast: { stroke: "CanvasText" },
|
|
113
|
+
stroke: "border"
|
|
114
|
+
},
|
|
115
|
+
[DIVISIONS]: {
|
|
116
|
+
_highContrast: { stroke: "CanvasText" },
|
|
117
|
+
stroke: "border.emphasized"
|
|
118
|
+
},
|
|
119
|
+
[MARKER_COUNTS]: {
|
|
120
|
+
fill: "contrast-color(var(--chart-marker))",
|
|
121
|
+
fontWeight: "semibold",
|
|
122
|
+
pointerEvents: "none",
|
|
123
|
+
textStyle: "body.xs"
|
|
124
|
+
},
|
|
125
|
+
[MARKER_PRESSES]: { cursor: "button" },
|
|
126
|
+
[MARKER_SHAPES]: {
|
|
127
|
+
_highContrast: { stroke: "Canvas" },
|
|
128
|
+
fill: "var(--chart-marker)",
|
|
129
|
+
stroke: "bg.panel",
|
|
130
|
+
strokeWidth: "ring"
|
|
131
|
+
},
|
|
132
|
+
[POINT_LABELS]: {
|
|
133
|
+
_highContrast: {
|
|
134
|
+
fill: "CanvasText",
|
|
135
|
+
stroke: "Canvas"
|
|
136
|
+
},
|
|
137
|
+
fill: "fg",
|
|
138
|
+
paintOrder: "stroke",
|
|
139
|
+
pointerEvents: "none",
|
|
140
|
+
stroke: "bg.panel",
|
|
141
|
+
strokeLinejoin: "round",
|
|
142
|
+
strokeWidth: "ring",
|
|
143
|
+
textStyle: "body.xs"
|
|
144
|
+
},
|
|
145
|
+
[QUADRANT_NAMES]: {
|
|
146
|
+
_highContrast: { fill: "CanvasText" },
|
|
147
|
+
fill: "fg.muted",
|
|
148
|
+
fontWeight: "medium",
|
|
149
|
+
pointerEvents: "none",
|
|
150
|
+
textStyle: "body.xs"
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
//#endregion
|
|
154
|
+
//#region src/chart/recipe.ts
|
|
155
|
+
/**
|
|
156
|
+
* Styles a chart's figure and parts, and restyles the classes recharts writes on its SVG with the
|
|
157
|
+
* theme's tokens.
|
|
158
|
+
*
|
|
159
|
+
* @remarks
|
|
160
|
+
* Recharts writes its inks as presentation attributes: `#666` on tick labels, axis lines and tick
|
|
161
|
+
* marks, `#ccc` on grid lines, a polar radius axis and the cursor, `#fff` on dots, sectors and a
|
|
162
|
+
* funnel's trapezoids, `#808080` on a `Label`'s text. A CSS property applies over a presentation
|
|
163
|
+
* attribute, so the plot sets each from a role, and a `fill` or `stroke` a caller passes to an
|
|
164
|
+
* axis or a `Label` loses to it. Under forced colors neither Firefox nor Chromium replaces an SVG
|
|
165
|
+
* `fill` or `stroke`, so the series keep their colors, and the plot sets the ticks, the labels
|
|
166
|
+
* and the axis lines in `CanvasText` and the grid in `GrayText`. A bar's hairline edge in the
|
|
167
|
+
* panel's color parts the segments of a stack. A series the legend does not point at fades to the
|
|
168
|
+
* plot's `--chart-faded`. The band under the pointer and a hovered legend button fill with the
|
|
169
|
+
* neutral palette's `subtle`, which steps towards the ink in both modes, where a well such as
|
|
170
|
+
* `bg.muted` sinks below a dark panel. A pie's shares and a funnel's counts render in `fg` inside
|
|
171
|
+
* a halo in the panel's color, so they read on a mark of any color, and the pointer passes
|
|
172
|
+
* through them to the mark under them, which opens the tooltip. A treemap's tile hides a line of
|
|
173
|
+
* words it marks as wider than the tile, and a sunburst's gap takes no pointer and no edge. A
|
|
174
|
+
* flow, a sankey's band or a chord diagram's ribbon, rests at the backdrop opacity, lifts to the
|
|
175
|
+
* muted opacity while the tooltip is at the flow or at one of its nodes, and fades while the
|
|
176
|
+
* tooltip is at another mark, and so does the bar or the arc of a node the tooltip is not at. The
|
|
177
|
+
* tooltip's panel is transparent while it is empty, so a readout outside recharts' wrapper, such
|
|
178
|
+
* as a chord diagram's, shows only while it is at a mark and remains in the accessibility tree as
|
|
179
|
+
* a live region before it fills. A bar's target tick is the ink inside a halo in the panel's
|
|
180
|
+
* color, and the part of a bar's zones no zone covers fills like a track. A quadrant chart's
|
|
181
|
+
* dividing lines are in the emphasized border ink and its quadrants' names in the label ink. A
|
|
182
|
+
* point's words are the ink inside a halo in the panel's color, and a timeline marker's count is
|
|
183
|
+
* the black or white `contrast-color()` finds against the marker's color. The `rows` ratio sizes
|
|
184
|
+
* a plot by its rows, such as a timeline's lanes. The recipe has no `palette` or `effect` axis,
|
|
185
|
+
* because each series takes its own color and a chart is not a control.
|
|
186
|
+
*/
|
|
187
|
+
/**
|
|
188
|
+
* Selects the tick labels of every cartesian and polar axis.
|
|
189
|
+
*/
|
|
190
|
+
const TICKS = "& .recharts-text:is(.recharts-cartesian-axis-tick-value, .recharts-polar-angle-axis-tick-value, .recharts-polar-radius-axis-tick-value)";
|
|
191
|
+
/**
|
|
192
|
+
* Selects the tick labels of a polar radius axis, which recharts writes on the ring they label,
|
|
193
|
+
* over the rings and the polygons.
|
|
194
|
+
*/
|
|
195
|
+
const RADII = "& .recharts-text.recharts-polar-radius-axis-tick-value";
|
|
196
|
+
/**
|
|
197
|
+
* Class a sector takes as a track: the rest of a gauge's dial past the reading, and the part of
|
|
198
|
+
* its range no zone covers.
|
|
199
|
+
*/
|
|
200
|
+
const TRACK = "chart-track";
|
|
201
|
+
/**
|
|
202
|
+
* Selects a track: the rest of a radial bar's full turn behind its ring, and a gauge's track.
|
|
203
|
+
*
|
|
204
|
+
* @remarks
|
|
205
|
+
* The selector names the sector's class and the track's class. Its specificity of three classes
|
|
206
|
+
* applies its forced edge over the panel-colored edge of every sector, whose `:is()` counts a
|
|
207
|
+
* class and a type.
|
|
208
|
+
*/
|
|
209
|
+
const TRACKS = "& .recharts-sector:is(.recharts-radial-bar-background-sector, .chart-track)";
|
|
210
|
+
/**
|
|
211
|
+
* Selects the line of every cartesian and polar axis and the tick marks along it.
|
|
212
|
+
*/
|
|
213
|
+
const AXES = "& :is(.recharts-cartesian-axis-line, .recharts-cartesian-axis-tick-line, .recharts-polar-angle-axis-line, .recharts-polar-angle-axis-tick-line, .recharts-polar-radius-axis-line)";
|
|
214
|
+
/**
|
|
215
|
+
* Selects the text of recharts' `Label`, which a reference line or an axis renders.
|
|
216
|
+
*/
|
|
217
|
+
const LABELS = "& .recharts-text.recharts-label";
|
|
218
|
+
/**
|
|
219
|
+
* Selects the lines of a cartesian grid, and the spokes and the ring paths of a polar one.
|
|
220
|
+
*/
|
|
221
|
+
const GRID = "& :is(.recharts-cartesian-grid line, .recharts-polar-grid line, .recharts-polar-grid path)";
|
|
222
|
+
/**
|
|
223
|
+
* Selects the band a bar chart renders behind the hovered category.
|
|
224
|
+
*/
|
|
225
|
+
const BAND = "& .recharts-rectangle.recharts-tooltip-cursor";
|
|
226
|
+
/**
|
|
227
|
+
* Selects the cursor line a line or area chart renders at the hovered category, and the cross a
|
|
228
|
+
* scatter renders at the hovered point.
|
|
229
|
+
*/
|
|
230
|
+
const CURSOR = "& :is(.recharts-curve, .recharts-cross).recharts-tooltip-cursor";
|
|
231
|
+
/**
|
|
232
|
+
* Selects the white edges recharts renders around a dot, between a pie's sectors and between a
|
|
233
|
+
* funnel's stages, and a scatter's points, whose edge keeps overlapping points apart.
|
|
234
|
+
*
|
|
235
|
+
* @remarks
|
|
236
|
+
* A reference dot is left out, because recharts edges it in its own `stroke`, such as an
|
|
237
|
+
* annotation's ring in its palette's chart color. The exclusion is inside `:where()`, so the rule
|
|
238
|
+
* keeps the specificity the chart's other edge rules are written against.
|
|
239
|
+
*/
|
|
240
|
+
const SEPARATED = "& :is(.recharts-active-dot circle, .recharts-dot:not(:where(.recharts-reference-dot-dot)), .recharts-sector, .recharts-symbols, .recharts-trapezoid)";
|
|
241
|
+
/**
|
|
242
|
+
* Selects every bar, whose edge parts the segments of a stack.
|
|
243
|
+
*/
|
|
244
|
+
const BARS = "& .recharts-bar-rectangle path";
|
|
245
|
+
/**
|
|
246
|
+
* Class a trend line takes, whose line fades with the series it summarises.
|
|
247
|
+
*/
|
|
248
|
+
const TREND = "chart-trend";
|
|
249
|
+
/**
|
|
250
|
+
* Class a treemap's tile takes, whose group takes its family's opacity.
|
|
251
|
+
*/
|
|
252
|
+
const TILE = "chart-tile";
|
|
253
|
+
/**
|
|
254
|
+
* Class a sunburst's gap takes: the arc a ring leaves where a leaf ends above it.
|
|
255
|
+
*/
|
|
256
|
+
const GAP = "chart-gap";
|
|
257
|
+
/**
|
|
258
|
+
* Selects a sunburst's gap, whose specificity applies over the panel-colored edge of every sector.
|
|
259
|
+
*/
|
|
260
|
+
const GAPS = "& .recharts-sector.chart-gap";
|
|
261
|
+
/**
|
|
262
|
+
* Class a flow takes at the backdrop opacity: a sankey's band, a stroke without a fill, or a chord
|
|
263
|
+
* diagram's ribbon, a fill without a stroke.
|
|
264
|
+
*/
|
|
265
|
+
const FLOW = "chart-flow";
|
|
266
|
+
/**
|
|
267
|
+
* Class a node takes: a sankey's bar or a chord diagram's arc, with its words.
|
|
268
|
+
*/
|
|
269
|
+
const NODE = "chart-node";
|
|
270
|
+
/**
|
|
271
|
+
* Selects every flow of a sankey or a chord diagram.
|
|
272
|
+
*/
|
|
273
|
+
const FLOWS = "& .chart-flow";
|
|
274
|
+
/**
|
|
275
|
+
* Selects the flow the tooltip is at, and every flow of the node it is at.
|
|
276
|
+
*/
|
|
277
|
+
const LIT$1 = "& .chart-flow[data-trace=lit]";
|
|
278
|
+
/**
|
|
279
|
+
* Selects every other flow while the tooltip is at a mark.
|
|
280
|
+
*/
|
|
281
|
+
const DIMMED = "& .chart-flow[data-trace=dimmed]";
|
|
282
|
+
/**
|
|
283
|
+
* Selects the bar of every node of a sankey.
|
|
284
|
+
*/
|
|
285
|
+
const BARS_OF_NODES = "& .chart-node .recharts-rectangle";
|
|
286
|
+
/**
|
|
287
|
+
* Selects the bar or the arc of every node the tooltip is not at while it is at a mark.
|
|
288
|
+
*/
|
|
289
|
+
const IDLE = "& .chart-node[data-trace=dimmed] :is(.recharts-rectangle, .recharts-sector)";
|
|
290
|
+
/**
|
|
291
|
+
* Attribute a treemap's tile writes on a line of words wider than the tile, and a node on a line
|
|
292
|
+
* of words that meets another node's, which the plot hides.
|
|
293
|
+
*/
|
|
294
|
+
const OVERFLOW$1 = "data-overflow";
|
|
295
|
+
/**
|
|
296
|
+
* Selects a line of words a treemap's tile or a node marks as not fitting.
|
|
297
|
+
*/
|
|
298
|
+
const OVERFLOWED = "& :is(.chart-tile, .chart-node) [data-overflow]";
|
|
299
|
+
/**
|
|
300
|
+
* Selects the painted paths of every line, area, bar, sector, polygon, point and trend line, and
|
|
301
|
+
* every treemap tile, which take a series' opacity.
|
|
302
|
+
*/
|
|
303
|
+
const MARKS = "& :is(.recharts-line-curve, .recharts-area-area, .recharts-area-curve, .recharts-bar-rectangle path, .recharts-sector, .recharts-polygon, .recharts-symbols, .chart-trend .recharts-reference-line-line, .chart-tile)";
|
|
304
|
+
/**
|
|
305
|
+
* Class a `LabelList` gives each value it writes on a mark, a pie's share or a funnel's count,
|
|
306
|
+
* which recharts writes on the `text` in place of `recharts-label`.
|
|
307
|
+
*/
|
|
308
|
+
const SHARE = "chart-share";
|
|
309
|
+
/**
|
|
310
|
+
* Selects the shares a pie writes on its slices and the counts a funnel writes on its stages.
|
|
311
|
+
*/
|
|
312
|
+
const SHARES = "& .recharts-text.chart-share";
|
|
313
|
+
/**
|
|
314
|
+
* Class a waterfall's connectors take: the dashed lines from each bar to the next at the running
|
|
315
|
+
* total.
|
|
316
|
+
*/
|
|
317
|
+
const CONNECTOR = "chart-connector";
|
|
318
|
+
/**
|
|
319
|
+
* Selects the line of every connector.
|
|
320
|
+
*/
|
|
321
|
+
const CONNECTORS = "& .chart-connector .recharts-reference-line-line";
|
|
322
|
+
/**
|
|
323
|
+
* Class a box's whiskers and their caps take, in the chart and in its key.
|
|
324
|
+
*/
|
|
325
|
+
const WHISKER = "chart-whisker";
|
|
326
|
+
/**
|
|
327
|
+
* Class a box's median line and a violin's median point take, in the chart and in its key.
|
|
328
|
+
*/
|
|
329
|
+
const MEDIAN = "chart-median";
|
|
330
|
+
/**
|
|
331
|
+
* Class a violin's quartile bar takes, in the chart and in its key.
|
|
332
|
+
*/
|
|
333
|
+
const QUARTILES = "chart-quartiles";
|
|
334
|
+
/**
|
|
335
|
+
* Class an outlier's point takes, in the chart and in its key.
|
|
336
|
+
*/
|
|
337
|
+
const OUTLIER = "chart-outlier";
|
|
338
|
+
/**
|
|
339
|
+
* Class a bar's target tick takes, in the chart and in its key.
|
|
340
|
+
*/
|
|
341
|
+
const TARGET = "chart-target";
|
|
342
|
+
/**
|
|
343
|
+
* Selects the part of a bar's zones no zone covers, a rectangle with the track's class.
|
|
344
|
+
*/
|
|
345
|
+
const BAND_TRACKS = "& rect.chart-track";
|
|
346
|
+
/**
|
|
347
|
+
* Custom property of the opacity a series' marks take while the legend points at another series.
|
|
348
|
+
*/
|
|
349
|
+
const FADED = "--chart-faded";
|
|
350
|
+
/**
|
|
351
|
+
* Defines the chart recipe: a figure whose plot is as wide as the figure and as tall as its ratio,
|
|
352
|
+
* by default the video ratio.
|
|
353
|
+
*/
|
|
354
|
+
const recipe$2 = defineSlotRecipe({
|
|
355
|
+
base: {
|
|
356
|
+
caption: {
|
|
357
|
+
color: "fg.muted",
|
|
358
|
+
textStyle: "body.sm"
|
|
359
|
+
},
|
|
360
|
+
center: {
|
|
361
|
+
alignItems: "center",
|
|
362
|
+
display: "flex",
|
|
363
|
+
flexDirection: "column",
|
|
364
|
+
inset: "0",
|
|
365
|
+
justifyContent: "center",
|
|
366
|
+
pointerEvents: "none",
|
|
367
|
+
position: "absolute",
|
|
368
|
+
textAlign: "center"
|
|
369
|
+
},
|
|
370
|
+
centerLabel: {
|
|
371
|
+
color: "fg.muted",
|
|
372
|
+
textStyle: "body.xs"
|
|
373
|
+
},
|
|
374
|
+
centerValue: {
|
|
375
|
+
color: "fg",
|
|
376
|
+
fontVariantNumeric: "tabular-nums",
|
|
377
|
+
fontWeight: "semibold",
|
|
378
|
+
textStyle: "heading.md"
|
|
379
|
+
},
|
|
380
|
+
empty: {
|
|
381
|
+
alignItems: "center",
|
|
382
|
+
borderColor: "border",
|
|
383
|
+
borderRadius: "l2",
|
|
384
|
+
borderStyle: "dashed",
|
|
385
|
+
borderWidth: "hairline",
|
|
386
|
+
color: "fg.muted",
|
|
387
|
+
display: "flex",
|
|
388
|
+
inlineSize: "full",
|
|
389
|
+
justifyContent: "center",
|
|
390
|
+
padding: dense("{spacing.inset.md}"),
|
|
391
|
+
textAlign: "center",
|
|
392
|
+
textStyle: "body.sm"
|
|
393
|
+
},
|
|
394
|
+
glyph: {
|
|
395
|
+
"& > svg": {
|
|
396
|
+
blockSize: "full",
|
|
397
|
+
inlineSize: "full",
|
|
398
|
+
overflow: "visible"
|
|
399
|
+
},
|
|
400
|
+
boxSize: "icon.xs",
|
|
401
|
+
display: "inline-flex",
|
|
402
|
+
flexShrink: "0"
|
|
403
|
+
},
|
|
404
|
+
heading: {
|
|
405
|
+
color: "fg",
|
|
406
|
+
fontWeight: "medium"
|
|
407
|
+
},
|
|
408
|
+
item: {
|
|
409
|
+
_highContrast: { _hover: {
|
|
410
|
+
outlineColor: "CanvasText",
|
|
411
|
+
outlineStyle: "solid"
|
|
412
|
+
} },
|
|
413
|
+
_hover: { background: "neutral.subtle" },
|
|
414
|
+
"&[aria-pressed=false]": {
|
|
415
|
+
color: "fg.muted",
|
|
416
|
+
textDecorationLine: "line-through"
|
|
417
|
+
},
|
|
418
|
+
alignItems: "center",
|
|
419
|
+
background: "transparent",
|
|
420
|
+
borderRadius: "l1",
|
|
421
|
+
color: "fg",
|
|
422
|
+
cursor: "button",
|
|
423
|
+
display: "inline-flex",
|
|
424
|
+
focusRingColor: "border.focus",
|
|
425
|
+
focusVisibleRing: "outside",
|
|
426
|
+
gap: dense("{spacing.gap.sm}"),
|
|
427
|
+
["&[aria-pressed=false] .color-swatch"]: { opacity: "0.4" },
|
|
428
|
+
minBlockSize: "6",
|
|
429
|
+
paddingInline: dense("{spacing.inset.xs}"),
|
|
430
|
+
textStyle: "body.sm"
|
|
431
|
+
},
|
|
432
|
+
key: {
|
|
433
|
+
alignItems: "center",
|
|
434
|
+
color: "fg.muted",
|
|
435
|
+
columnGap: dense("{spacing.gap.md}"),
|
|
436
|
+
display: "flex",
|
|
437
|
+
flexWrap: "wrap",
|
|
438
|
+
listStyle: "none",
|
|
439
|
+
margin: "0",
|
|
440
|
+
padding: "0",
|
|
441
|
+
rowGap: dense("{spacing.gap.xs}"),
|
|
442
|
+
textStyle: "body.sm"
|
|
443
|
+
},
|
|
444
|
+
keyItem: {
|
|
445
|
+
alignItems: "center",
|
|
446
|
+
display: "inline-flex",
|
|
447
|
+
gap: dense("{spacing.gap.sm}")
|
|
448
|
+
},
|
|
449
|
+
legend: {
|
|
450
|
+
alignItems: "center",
|
|
451
|
+
borderWidth: "0",
|
|
452
|
+
columnGap: dense("{spacing.gap.md}"),
|
|
453
|
+
display: "flex",
|
|
454
|
+
flexWrap: "wrap",
|
|
455
|
+
margin: "0",
|
|
456
|
+
minInlineSize: "0",
|
|
457
|
+
padding: "0",
|
|
458
|
+
rowGap: dense("{spacing.gap.xs}")
|
|
459
|
+
},
|
|
460
|
+
name: {
|
|
461
|
+
color: "fg.muted",
|
|
462
|
+
flex: "1"
|
|
463
|
+
},
|
|
464
|
+
plot: {
|
|
465
|
+
...PLACED,
|
|
466
|
+
"& .recharts-surface": {
|
|
467
|
+
focusRingColor: "border.focus",
|
|
468
|
+
focusVisibleRing: "outside",
|
|
469
|
+
overflow: "visible"
|
|
470
|
+
},
|
|
471
|
+
[AXES]: {
|
|
472
|
+
_highContrast: { stroke: "CanvasText" },
|
|
473
|
+
stroke: "border"
|
|
474
|
+
},
|
|
475
|
+
[BAND]: { fill: "neutral.subtle" },
|
|
476
|
+
[BAND_TRACKS]: {
|
|
477
|
+
_highContrast: {
|
|
478
|
+
fill: "Canvas",
|
|
479
|
+
stroke: "GrayText"
|
|
480
|
+
},
|
|
481
|
+
fill: "neutral.subtle"
|
|
482
|
+
},
|
|
483
|
+
[BARS]: {
|
|
484
|
+
stroke: "bg.panel",
|
|
485
|
+
strokeWidth: "hairline"
|
|
486
|
+
},
|
|
487
|
+
[BARS_OF_NODES]: { transition: "opacity {durations.fast} {easings.out}" },
|
|
488
|
+
[CONNECTORS]: {
|
|
489
|
+
_highContrast: { stroke: "GrayText" },
|
|
490
|
+
stroke: "border.emphasized"
|
|
491
|
+
},
|
|
492
|
+
[CURSOR]: { stroke: "border" },
|
|
493
|
+
[DIMMED]: { opacity: "backdrop" },
|
|
494
|
+
[FADED]: "{opacity.backdrop}",
|
|
495
|
+
[FLOWS]: {
|
|
496
|
+
fillOpacity: "{opacity.backdrop}",
|
|
497
|
+
strokeOpacity: "{opacity.backdrop}",
|
|
498
|
+
transition: "fill-opacity {durations.fast} {easings.out}, stroke-opacity {durations.fast} {easings.out}, opacity {durations.fast} {easings.out}"
|
|
499
|
+
},
|
|
500
|
+
[GAPS]: {
|
|
501
|
+
pointerEvents: "none",
|
|
502
|
+
stroke: "none"
|
|
503
|
+
},
|
|
504
|
+
[GRID]: {
|
|
505
|
+
_highContrast: { stroke: "GrayText" },
|
|
506
|
+
stroke: "border.muted"
|
|
507
|
+
},
|
|
508
|
+
[IDLE]: { opacity: "muted" },
|
|
509
|
+
inlineSize: "full",
|
|
510
|
+
[LABELS]: {
|
|
511
|
+
_highContrast: { fill: "CanvasText" },
|
|
512
|
+
fill: "fg.muted",
|
|
513
|
+
textStyle: "body.xs"
|
|
514
|
+
},
|
|
515
|
+
[LIT$1]: {
|
|
516
|
+
fillOpacity: "{opacity.muted}",
|
|
517
|
+
strokeOpacity: "{opacity.muted}"
|
|
518
|
+
},
|
|
519
|
+
[MARKS]: { transition: "opacity {durations.fast} {easings.out}" },
|
|
520
|
+
minInlineSize: "0",
|
|
521
|
+
[OVERFLOWED]: { visibility: "hidden" },
|
|
522
|
+
position: "relative",
|
|
523
|
+
[RADII]: {
|
|
524
|
+
_highContrast: { stroke: "Canvas" },
|
|
525
|
+
dominantBaseline: "text-before-edge",
|
|
526
|
+
paintOrder: "stroke",
|
|
527
|
+
stroke: "bg.panel",
|
|
528
|
+
strokeLinejoin: "round",
|
|
529
|
+
strokeWidth: "ring"
|
|
530
|
+
},
|
|
531
|
+
[SEPARATED]: { stroke: "bg.panel" },
|
|
532
|
+
[SHARES]: {
|
|
533
|
+
_highContrast: {
|
|
534
|
+
fill: "CanvasText",
|
|
535
|
+
stroke: "Canvas"
|
|
536
|
+
},
|
|
537
|
+
fill: "fg",
|
|
538
|
+
fontWeight: "semibold",
|
|
539
|
+
paintOrder: "stroke",
|
|
540
|
+
pointerEvents: "none",
|
|
541
|
+
stroke: "bg.panel",
|
|
542
|
+
strokeLinejoin: "round",
|
|
543
|
+
strokeWidth: "ring",
|
|
544
|
+
textStyle: "body.xs"
|
|
545
|
+
},
|
|
546
|
+
[TICKS]: {
|
|
547
|
+
_highContrast: { fill: "CanvasText" },
|
|
548
|
+
fill: "fg.muted",
|
|
549
|
+
textStyle: "body.xs"
|
|
550
|
+
},
|
|
551
|
+
[TRACKS]: {
|
|
552
|
+
_highContrast: {
|
|
553
|
+
fill: "Canvas",
|
|
554
|
+
stroke: "GrayText"
|
|
555
|
+
},
|
|
556
|
+
fill: "neutral.subtle"
|
|
557
|
+
}
|
|
558
|
+
},
|
|
559
|
+
root: {
|
|
560
|
+
"& .chart-median": {
|
|
561
|
+
_highContrast: {
|
|
562
|
+
fill: "Canvas",
|
|
563
|
+
stroke: "CanvasText"
|
|
564
|
+
},
|
|
565
|
+
fill: "bg.panel",
|
|
566
|
+
stroke: "fg"
|
|
567
|
+
},
|
|
568
|
+
"& .chart-outlier": {
|
|
569
|
+
_highContrast: { fill: "Canvas" },
|
|
570
|
+
fill: "bg.panel"
|
|
571
|
+
},
|
|
572
|
+
"& .chart-quartiles": {
|
|
573
|
+
_highContrast: { fill: "CanvasText" },
|
|
574
|
+
fill: "fg"
|
|
575
|
+
},
|
|
576
|
+
"& .chart-target": {
|
|
577
|
+
_highContrast: {
|
|
578
|
+
fill: "CanvasText",
|
|
579
|
+
stroke: "Canvas"
|
|
580
|
+
},
|
|
581
|
+
fill: "fg",
|
|
582
|
+
paintOrder: "stroke",
|
|
583
|
+
stroke: "bg.panel",
|
|
584
|
+
strokeWidth: "ring"
|
|
585
|
+
},
|
|
586
|
+
"& .chart-whisker": {
|
|
587
|
+
_highContrast: { stroke: "CanvasText" },
|
|
588
|
+
stroke: "fg.muted"
|
|
589
|
+
},
|
|
590
|
+
display: "flex",
|
|
591
|
+
flexDirection: "column",
|
|
592
|
+
gap: dense("{spacing.gap.md}"),
|
|
593
|
+
inlineSize: "full",
|
|
594
|
+
minInlineSize: "0"
|
|
595
|
+
},
|
|
596
|
+
row: {
|
|
597
|
+
alignItems: "center",
|
|
598
|
+
display: "flex",
|
|
599
|
+
gap: dense("{spacing.gap.sm}")
|
|
600
|
+
},
|
|
601
|
+
tooltip: {
|
|
602
|
+
_empty: { opacity: "0" },
|
|
603
|
+
background: "bg.popover",
|
|
604
|
+
borderColor: "border",
|
|
605
|
+
borderRadius: "l2",
|
|
606
|
+
borderStyle: "solid",
|
|
607
|
+
borderWidth: "hairline",
|
|
608
|
+
boxShadow: "lg",
|
|
609
|
+
color: "fg",
|
|
610
|
+
display: "grid",
|
|
611
|
+
gap: dense("{spacing.gap.xs}"),
|
|
612
|
+
minInlineSize: "40",
|
|
613
|
+
padding: dense("{spacing.inset.sm}"),
|
|
614
|
+
textAlign: "start",
|
|
615
|
+
textStyle: "body.sm"
|
|
616
|
+
},
|
|
617
|
+
value: {
|
|
618
|
+
color: "fg",
|
|
619
|
+
fontVariantNumeric: "tabular-nums",
|
|
620
|
+
fontWeight: "medium"
|
|
621
|
+
}
|
|
622
|
+
},
|
|
623
|
+
className: "chart",
|
|
624
|
+
defaultVariants: { ratio: "video" },
|
|
625
|
+
jsx: [/^Chart(\.\w+)?$/u],
|
|
626
|
+
slots: [
|
|
627
|
+
"root",
|
|
628
|
+
"plot",
|
|
629
|
+
"center",
|
|
630
|
+
"centerValue",
|
|
631
|
+
"centerLabel",
|
|
632
|
+
"empty",
|
|
633
|
+
"caption",
|
|
634
|
+
"legend",
|
|
635
|
+
"item",
|
|
636
|
+
"key",
|
|
637
|
+
"keyItem",
|
|
638
|
+
"glyph",
|
|
639
|
+
"tooltip",
|
|
640
|
+
"heading",
|
|
641
|
+
"row",
|
|
642
|
+
"name",
|
|
643
|
+
"value"
|
|
644
|
+
],
|
|
645
|
+
variants: {
|
|
646
|
+
/**
|
|
647
|
+
* Aspect ratio of the plot and of the empty state in its place, one of the theme's ratios, or
|
|
648
|
+
* `rows` for a plot as tall as its rows.
|
|
649
|
+
*
|
|
650
|
+
* @remarks
|
|
651
|
+
* Recharts measures the plot's box after the first render and renders nothing in a box 0
|
|
652
|
+
* pixels high. The ratio gives the box its height before that measurement. At `rows` the box
|
|
653
|
+
* is a row of `sizes.10` per row of `--chart-rows`, one unless stated, and `sizes.12` for the
|
|
654
|
+
* axis, so a timeline of four lanes is 208px tall at any width.
|
|
655
|
+
*/
|
|
656
|
+
ratio: onSlots({
|
|
657
|
+
empty: {
|
|
658
|
+
...ratioVariants(),
|
|
659
|
+
rows: ROWS_TALL
|
|
660
|
+
},
|
|
661
|
+
plot: {
|
|
662
|
+
...ratioVariants(),
|
|
663
|
+
rows: ROWS_TALL
|
|
664
|
+
}
|
|
665
|
+
}) }
|
|
666
|
+
});
|
|
667
|
+
//#endregion
|
|
668
|
+
//#region src/heat/recipe.ts
|
|
669
|
+
/**
|
|
670
|
+
* Styles a heat grid, a table whose cells take a color from their values: the frame, the grid, its
|
|
671
|
+
* headings and cells, the readout over a cell, and the key under the grid.
|
|
672
|
+
*
|
|
673
|
+
* @remarks
|
|
674
|
+
* The cells are 2px apart on the panel, so each reads as one block of color. A cell takes its
|
|
675
|
+
* fill from `--heat-fill`, which the component sets from the value, and keeps it under forced
|
|
676
|
+
* colors, where neither engine would otherwise keep a background color. A value printed in a
|
|
677
|
+
* cell is black or white, whichever `contrast-color()` picks against the fill, which measured at
|
|
678
|
+
* least 4.56:1 on every fill of the ten themes in both modes and both engines. A cell without a
|
|
679
|
+
* value has no fill and a dashed edge, and a cell without a reading in a sparse grid has neither.
|
|
680
|
+
* The cell the readout shows takes an outline in the ink, inside its edge, and a cell with focus
|
|
681
|
+
* takes the focus ring outside it, over the gap. The headings of the row and the column the
|
|
682
|
+
* readout shows fill with the neutral palette's `subtle`. The row headings are sticky at the
|
|
683
|
+
* grid's start while it scrolls sideways, and their words and the corner's align to their end,
|
|
684
|
+
* beside the cells. Next to squares the row headings take no height of their own, so the rows are
|
|
685
|
+
* as far apart as the columns. A group's words start at its first column and are placed out of
|
|
686
|
+
* the table's layout, so a group never widens its columns, and they are transparent with
|
|
687
|
+
* `data-overflow`. The readout is placed above its cell at `--heat-x` and `--heat-y`, or below it
|
|
688
|
+
* with `data-side="bottom"`, and takes no pointer. The key aligns to the grid's end, and its bar
|
|
689
|
+
* runs the scale's colors from `--heat-ramp` from the reading start. The recipe has no `palette`
|
|
690
|
+
* or `effect` axis, because the values set the colors and a grid is not a control.
|
|
691
|
+
*/
|
|
692
|
+
/**
|
|
693
|
+
* Sizes the grid offers.
|
|
694
|
+
*/
|
|
695
|
+
const SIZES = [
|
|
696
|
+
"sm",
|
|
697
|
+
"md",
|
|
698
|
+
"lg"
|
|
699
|
+
];
|
|
700
|
+
/**
|
|
701
|
+
* Attribute the cell the readout shows writes, which the recipe outlines.
|
|
702
|
+
*/
|
|
703
|
+
const SHOWN = "data-readout";
|
|
704
|
+
/**
|
|
705
|
+
* Custom property of a cell's fill.
|
|
706
|
+
*/
|
|
707
|
+
const FILL = "--heat-fill";
|
|
708
|
+
/**
|
|
709
|
+
* Custom property of the colors of the key's bar, from its start to its end.
|
|
710
|
+
*/
|
|
711
|
+
const RAMP = "--heat-ramp";
|
|
712
|
+
/**
|
|
713
|
+
* Custom property of the readout's horizontal middle, from the frame's start.
|
|
714
|
+
*/
|
|
715
|
+
const READOUT_X = "--heat-x";
|
|
716
|
+
/**
|
|
717
|
+
* Custom property of the edge of the cell the readout is placed against, from the frame's top.
|
|
718
|
+
*/
|
|
719
|
+
const READOUT_Y = "--heat-y";
|
|
720
|
+
/**
|
|
721
|
+
* Attribute a heading writes while the readout shows a cell in its row or its column.
|
|
722
|
+
*/
|
|
723
|
+
const LIT = "data-lit";
|
|
724
|
+
/**
|
|
725
|
+
* Attribute the readout writes while its cell is out of the scroll area's view, which hides it.
|
|
726
|
+
*/
|
|
727
|
+
const CLIPPED = "data-clipped";
|
|
728
|
+
/**
|
|
729
|
+
* Attribute a group's words write while they are wider than the group, which hides them from sight.
|
|
730
|
+
*/
|
|
731
|
+
const OVERFLOW = "data-overflow";
|
|
732
|
+
/**
|
|
733
|
+
* Room between two cells, which the table also leaves around its outer cells.
|
|
734
|
+
*/
|
|
735
|
+
const SPACING = "{spacing.0.5}";
|
|
736
|
+
/**
|
|
737
|
+
* Custom property of a block cell's height and least width, which the size sets.
|
|
738
|
+
*/
|
|
739
|
+
const BLOCK = "--heat-block";
|
|
740
|
+
/**
|
|
741
|
+
* Custom property of a square cell's side, which the size sets.
|
|
742
|
+
*/
|
|
743
|
+
const SQUARE = "--heat-square";
|
|
744
|
+
/**
|
|
745
|
+
* Maps each size to the grid step of a block cell's height and least width.
|
|
746
|
+
*/
|
|
747
|
+
const BLOCKS = {
|
|
748
|
+
lg: "11",
|
|
749
|
+
md: "8",
|
|
750
|
+
sm: "6"
|
|
751
|
+
};
|
|
752
|
+
/**
|
|
753
|
+
* Maps each size to the grid step of a square cell's side.
|
|
754
|
+
*/
|
|
755
|
+
const SQUARES = {
|
|
756
|
+
lg: "6",
|
|
757
|
+
md: "3.5",
|
|
758
|
+
sm: "2.5"
|
|
759
|
+
};
|
|
760
|
+
/**
|
|
761
|
+
* Styles every cell: a fill from the value, a transparent edge a missing value dashes, the outline
|
|
762
|
+
* of the cell the readout shows and the focus ring.
|
|
763
|
+
*/
|
|
764
|
+
const CELL = {
|
|
765
|
+
_focusVisible: { outlineOffset: "0" },
|
|
766
|
+
_highContrast: {
|
|
767
|
+
"&[data-state=missing]": { borderColor: "GrayText" },
|
|
768
|
+
[`&[${SHOWN}]`]: { outlineColor: "CanvasText" },
|
|
769
|
+
focusRingColor: "Highlight"
|
|
770
|
+
},
|
|
771
|
+
"&[data-state=missing]": {
|
|
772
|
+
borderColor: "border",
|
|
773
|
+
borderStyle: "dashed"
|
|
774
|
+
},
|
|
775
|
+
[`&[${SHOWN}]:not(:focus-visible)`]: {
|
|
776
|
+
outlineColor: "fg",
|
|
777
|
+
outlineOffset: "calc({borderWidths.indicator} * -1)",
|
|
778
|
+
outlineStyle: "solid",
|
|
779
|
+
outlineWidth: "indicator"
|
|
780
|
+
},
|
|
781
|
+
backgroundColor: `var(${FILL}, transparent)`,
|
|
782
|
+
borderColor: "transparent",
|
|
783
|
+
borderStyle: "solid",
|
|
784
|
+
borderWidth: "hairline",
|
|
785
|
+
focusRingColor: "border.focus",
|
|
786
|
+
focusVisibleRing: "outside",
|
|
787
|
+
forcedColorAdjust: "none",
|
|
788
|
+
padding: "0"
|
|
789
|
+
};
|
|
790
|
+
/**
|
|
791
|
+
* Styles a heading the readout lights: the neutral palette's `subtle` fill and the full ink.
|
|
792
|
+
*/
|
|
793
|
+
const LIGHT = { [`&[${LIT}]`]: {
|
|
794
|
+
_highContrast: {
|
|
795
|
+
background: "Highlight",
|
|
796
|
+
color: "HighlightText",
|
|
797
|
+
forcedColorAdjust: "none"
|
|
798
|
+
},
|
|
799
|
+
background: "neutral.subtle",
|
|
800
|
+
color: "fg"
|
|
801
|
+
} };
|
|
802
|
+
/**
|
|
803
|
+
* Defines the heat recipe: a grid of block cells 2px apart at size `md` by default.
|
|
804
|
+
*/
|
|
805
|
+
const recipe$1 = defineSlotRecipe({
|
|
806
|
+
base: {
|
|
807
|
+
bar: {
|
|
808
|
+
_rtl: { backgroundImage: `linear-gradient(to left, var(${RAMP}))` },
|
|
809
|
+
backgroundImage: `linear-gradient(to right, var(${RAMP}))`,
|
|
810
|
+
blockSize: "2",
|
|
811
|
+
borderColor: "border",
|
|
812
|
+
borderRadius: "l1",
|
|
813
|
+
borderStyle: "solid",
|
|
814
|
+
borderWidth: "hairline",
|
|
815
|
+
forcedColorAdjust: "none"
|
|
816
|
+
},
|
|
817
|
+
cell: {
|
|
818
|
+
...CELL,
|
|
819
|
+
textAlign: "center",
|
|
820
|
+
verticalAlign: "middle",
|
|
821
|
+
whiteSpace: "nowrap"
|
|
822
|
+
},
|
|
823
|
+
columnHeading: {
|
|
824
|
+
...LIGHT,
|
|
825
|
+
"&:first-child": {
|
|
826
|
+
background: "bg.panel",
|
|
827
|
+
insetInlineStart: "0",
|
|
828
|
+
position: "sticky",
|
|
829
|
+
textAlign: "end",
|
|
830
|
+
zIndex: "1"
|
|
831
|
+
},
|
|
832
|
+
color: "fg.muted",
|
|
833
|
+
fontWeight: "normal",
|
|
834
|
+
paddingBlock: "0",
|
|
835
|
+
paddingInline: dense("{spacing.gap.xs}"),
|
|
836
|
+
textAlign: "center",
|
|
837
|
+
verticalAlign: "bottom",
|
|
838
|
+
whiteSpace: "nowrap"
|
|
839
|
+
},
|
|
840
|
+
frame: {
|
|
841
|
+
display: "flex",
|
|
842
|
+
flexDirection: "column",
|
|
843
|
+
gap: dense("{spacing.gap.sm}"),
|
|
844
|
+
inlineSize: "fit",
|
|
845
|
+
maxInlineSize: "full",
|
|
846
|
+
minInlineSize: "0",
|
|
847
|
+
position: "relative"
|
|
848
|
+
},
|
|
849
|
+
grid: {
|
|
850
|
+
borderCollapse: "separate",
|
|
851
|
+
borderSpacing: SPACING
|
|
852
|
+
},
|
|
853
|
+
group: {
|
|
854
|
+
blockSize: "1lh",
|
|
855
|
+
color: "fg.muted",
|
|
856
|
+
fontWeight: "normal",
|
|
857
|
+
padding: "0",
|
|
858
|
+
position: "relative",
|
|
859
|
+
verticalAlign: "bottom"
|
|
860
|
+
},
|
|
861
|
+
groupLabel: {
|
|
862
|
+
[`&[${OVERFLOW}]`]: { opacity: "0" },
|
|
863
|
+
insetBlockEnd: "0",
|
|
864
|
+
insetInlineStart: "0",
|
|
865
|
+
pointerEvents: "none",
|
|
866
|
+
position: "absolute",
|
|
867
|
+
whiteSpace: "nowrap"
|
|
868
|
+
},
|
|
869
|
+
key: {
|
|
870
|
+
alignItems: "center",
|
|
871
|
+
alignSelf: "end",
|
|
872
|
+
color: "fg.muted",
|
|
873
|
+
columnGap: dense("{spacing.gap.sm}"),
|
|
874
|
+
display: "grid",
|
|
875
|
+
fontVariantNumeric: "tabular-nums",
|
|
876
|
+
gridTemplateColumns: "auto auto {sizes.40} auto",
|
|
877
|
+
inlineSize: "fit",
|
|
878
|
+
marginInlineEnd: SPACING,
|
|
879
|
+
rowGap: dense("{spacing.gap.xs}"),
|
|
880
|
+
textStyle: "body.xs"
|
|
881
|
+
},
|
|
882
|
+
keyLabel: {
|
|
883
|
+
color: "fg",
|
|
884
|
+
paddingInlineEnd: dense("{spacing.gap.xs}")
|
|
885
|
+
},
|
|
886
|
+
midpoint: {
|
|
887
|
+
gridColumn: "3",
|
|
888
|
+
gridRow: "2",
|
|
889
|
+
justifySelf: "center"
|
|
890
|
+
},
|
|
891
|
+
name: { srOnly: true },
|
|
892
|
+
readout: {
|
|
893
|
+
"&[data-side=bottom]": { translate: "-50% {spacing.gap.xs}" },
|
|
894
|
+
[`&[${CLIPPED}]`]: { visibility: "hidden" },
|
|
895
|
+
left: `var(${READOUT_X})`,
|
|
896
|
+
maxInlineSize: "full",
|
|
897
|
+
pointerEvents: "none",
|
|
898
|
+
position: "absolute",
|
|
899
|
+
top: `var(${READOUT_Y})`,
|
|
900
|
+
translate: "-50% calc(-100% - {spacing.gap.xs})",
|
|
901
|
+
zIndex: "docked"
|
|
902
|
+
},
|
|
903
|
+
rowHeading: {
|
|
904
|
+
...LIGHT,
|
|
905
|
+
background: "bg.panel",
|
|
906
|
+
color: "fg.muted",
|
|
907
|
+
fontWeight: "normal",
|
|
908
|
+
insetInlineStart: "0",
|
|
909
|
+
paddingBlock: "0",
|
|
910
|
+
paddingInline: dense("{spacing.gap.xs}"),
|
|
911
|
+
position: "sticky",
|
|
912
|
+
textAlign: "end",
|
|
913
|
+
whiteSpace: "nowrap",
|
|
914
|
+
zIndex: "1"
|
|
915
|
+
},
|
|
916
|
+
value: {
|
|
917
|
+
color: `contrast-color(var(${FILL}))`,
|
|
918
|
+
fontVariantNumeric: "tabular-nums",
|
|
919
|
+
paddingInline: dense("{spacing.gap.xs}")
|
|
920
|
+
}
|
|
921
|
+
},
|
|
922
|
+
className: "heat",
|
|
923
|
+
compoundVariants: [{
|
|
924
|
+
css: { rowHeading: { lineHeight: "0" } },
|
|
925
|
+
name: "squared",
|
|
926
|
+
shape: "square"
|
|
927
|
+
}],
|
|
928
|
+
defaultVariants: {
|
|
929
|
+
shape: "block",
|
|
930
|
+
size: "md"
|
|
931
|
+
},
|
|
932
|
+
jsx: [/^Heatmap$/u],
|
|
933
|
+
slots: [
|
|
934
|
+
"frame",
|
|
935
|
+
"grid",
|
|
936
|
+
"group",
|
|
937
|
+
"groupLabel",
|
|
938
|
+
"columnHeading",
|
|
939
|
+
"rowHeading",
|
|
940
|
+
"cell",
|
|
941
|
+
"value",
|
|
942
|
+
"name",
|
|
943
|
+
"readout",
|
|
944
|
+
"key",
|
|
945
|
+
"keyLabel",
|
|
946
|
+
"bar",
|
|
947
|
+
"midpoint"
|
|
948
|
+
],
|
|
949
|
+
variants: {
|
|
950
|
+
/**
|
|
951
|
+
* Shape of the cells: a block at least as wide as it is tall, which widens to a printed value,
|
|
952
|
+
* or a square with a 2px corner in every theme.
|
|
953
|
+
*/
|
|
954
|
+
shape: {
|
|
955
|
+
block: { cell: {
|
|
956
|
+
blockSize: `var(${BLOCK})`,
|
|
957
|
+
minInlineSize: `var(${BLOCK})`
|
|
958
|
+
} },
|
|
959
|
+
square: { cell: {
|
|
960
|
+
borderRadius: "xs",
|
|
961
|
+
boxSize: `var(${SQUARE})`,
|
|
962
|
+
minInlineSize: `var(${SQUARE})`
|
|
963
|
+
} }
|
|
964
|
+
},
|
|
965
|
+
/**
|
|
966
|
+
* Size of the cells and of the words in the grid: a block 24, 32 or 44px tall, a square 10, 14
|
|
967
|
+
* or 24px, and the headings and values one text size smaller than the size. A large square is a
|
|
968
|
+
* pointer target of the 24px WCAG 2.5.8 asks for.
|
|
969
|
+
*/
|
|
970
|
+
size: onSlots({
|
|
971
|
+
cell: sizeVariants((size) => ({
|
|
972
|
+
[BLOCK]: dense(`{sizes.${BLOCKS[size]}}`),
|
|
973
|
+
[SQUARE]: dense(`{sizes.${SQUARES[size]}}`)
|
|
974
|
+
}), SIZES),
|
|
975
|
+
columnHeading: sizeVariants((size) => ({ textStyle: `label.${below(size)}` }), SIZES),
|
|
976
|
+
group: sizeVariants((size) => ({ textStyle: `label.${below(size)}` }), SIZES),
|
|
977
|
+
rowHeading: sizeVariants((size) => ({ textStyle: `label.${below(size)}` }), SIZES),
|
|
978
|
+
value: sizeVariants((size) => ({ textStyle: `body.${below(size)}` }), SIZES)
|
|
979
|
+
})
|
|
980
|
+
}
|
|
981
|
+
});
|
|
982
|
+
//#endregion
|
|
983
|
+
//#region src/spark/recipe.ts
|
|
984
|
+
/**
|
|
985
|
+
* Styles a spark, a run of values the size of a word: the box recharts renders the run in, and the
|
|
986
|
+
* baseline across it.
|
|
987
|
+
*
|
|
988
|
+
* @remarks
|
|
989
|
+
* The box takes its size from the grid, four times as wide as it is tall: 64 by 16 pixels at
|
|
990
|
+
* `sm`, 96 by 24 at `md` and 128 by 32 at `lg`, times the density. `stretch` fills the
|
|
991
|
+
* container's width at the size's height. A baseline renders in the subtle ink, and in
|
|
992
|
+
* `CanvasText` under forced colors, where the run keeps its color because neither Firefox nor
|
|
993
|
+
* Chromium replaces an SVG `fill` or `stroke`. The recipe has no `palette` axis, because the run
|
|
994
|
+
* takes a palette through the component's `color`.
|
|
995
|
+
*/
|
|
996
|
+
/**
|
|
997
|
+
* Selects the line of a baseline recharts renders across the run.
|
|
998
|
+
*/
|
|
999
|
+
const BASELINE = "& .recharts-reference-line line";
|
|
1000
|
+
/**
|
|
1001
|
+
* Maps each size to the grid step of its height.
|
|
1002
|
+
*/
|
|
1003
|
+
const HEIGHTS = {
|
|
1004
|
+
lg: "8",
|
|
1005
|
+
md: "6",
|
|
1006
|
+
sm: "4"
|
|
1007
|
+
};
|
|
1008
|
+
/**
|
|
1009
|
+
* Maps each size to the grid step of its width.
|
|
1010
|
+
*/
|
|
1011
|
+
const WIDTHS = {
|
|
1012
|
+
lg: "32",
|
|
1013
|
+
md: "24",
|
|
1014
|
+
sm: "16"
|
|
1015
|
+
};
|
|
1016
|
+
/**
|
|
1017
|
+
* Defines the spark recipe: an inline box at the middle size.
|
|
1018
|
+
*/
|
|
1019
|
+
const recipe = defineRecipe({
|
|
1020
|
+
base: {
|
|
1021
|
+
[BASELINE]: {
|
|
1022
|
+
_highContrast: { stroke: "CanvasText" },
|
|
1023
|
+
stroke: "fg.subtle"
|
|
1024
|
+
},
|
|
1025
|
+
display: "inline-flex",
|
|
1026
|
+
flexShrink: "0",
|
|
1027
|
+
verticalAlign: "middle"
|
|
1028
|
+
},
|
|
1029
|
+
className: "spark",
|
|
1030
|
+
defaultVariants: { size: "md" },
|
|
1031
|
+
jsx: [/^Spark(bar|line)$/u],
|
|
1032
|
+
variants: {
|
|
1033
|
+
/**
|
|
1034
|
+
* Box on the grid, four times as wide as it is tall.
|
|
1035
|
+
*/
|
|
1036
|
+
size: sizeVariants((size) => ({
|
|
1037
|
+
blockSize: dense(`{sizes.${HEIGHTS[size]}}`),
|
|
1038
|
+
inlineSize: dense(`{sizes.${WIDTHS[size]}}`)
|
|
1039
|
+
}), [
|
|
1040
|
+
"sm",
|
|
1041
|
+
"md",
|
|
1042
|
+
"lg"
|
|
1043
|
+
]),
|
|
1044
|
+
/**
|
|
1045
|
+
* Whether the box fills its container's width at the size's height.
|
|
1046
|
+
*/
|
|
1047
|
+
stretch: { true: {
|
|
1048
|
+
display: "flex",
|
|
1049
|
+
inlineSize: "full"
|
|
1050
|
+
} }
|
|
1051
|
+
}
|
|
1052
|
+
});
|
|
1053
|
+
//#endregion
|
|
1054
|
+
export { DIVISION as A, TRACK as C, ANNOTATION as D, recipe$2 as E, ROWS as F, MARKER_FILL as M, POINT_LABEL as N, ANNOTATION_LABEL as O, QUADRANT as P, TILE as S, WHISKER as T, OUTLIER as _, OVERFLOW as a, SHARE as b, READOUT_Y as c, CONNECTOR as d, FADED as f, NODE as g, MEDIAN as h, LIT as i, MARKER as j, CROSSHAIR as k, SHOWN as l, GAP as m, CLIPPED as n, RAMP as o, FLOW as p, FILL as r, READOUT_X as s, recipe as t, recipe$1 as u, OVERFLOW$1 as v, TREND as w, TARGET as x, QUARTILES as y };
|