@seekalfred/primitives 0.7.3 → 0.8.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/README.md +315 -4
- package/dist/alert/alert.d.ts +2 -2
- package/dist/alert/alert.js +1 -1
- package/dist/alert/alert.js.map +1 -1
- package/dist/alert-dialog/alert-dialog.d.ts +14 -0
- package/dist/alert-dialog/alert-dialog.js +52 -27
- package/dist/alert-dialog/alert-dialog.js.map +1 -1
- package/dist/announcement-bar/announcement-bar.d.ts +15 -4
- package/dist/announcement-bar/announcement-bar.js +31 -6
- package/dist/announcement-bar/announcement-bar.js.map +1 -1
- package/dist/avatar/avatar.d.ts +7 -0
- package/dist/avatar/avatar.js +33 -12
- package/dist/avatar/avatar.js.map +1 -1
- package/dist/badge/badge.d.ts +16 -1
- package/dist/badge/badge.js +12 -5
- package/dist/badge/badge.js.map +1 -1
- package/dist/bar-chart/bar-chart-series.d.ts +75 -0
- package/dist/bar-chart/bar-chart-series.js +401 -0
- package/dist/bar-chart/bar-chart-series.js.map +1 -0
- package/dist/bar-chart/bar-chart.d.ts +25 -1
- package/dist/bar-chart/bar-chart.js +26 -1
- package/dist/bar-chart/bar-chart.js.map +1 -1
- package/dist/bar-chart/index.d.ts +2 -1
- package/dist/button/button.d.ts +24 -2
- package/dist/button/button.js +62 -13
- package/dist/button/button.js.map +1 -1
- package/dist/card/card.js +1 -1
- package/dist/card/card.js.map +1 -1
- package/dist/checkbox/checkbox.d.ts +25 -1
- package/dist/checkbox/checkbox.js +103 -28
- package/dist/checkbox/checkbox.js.map +1 -1
- package/dist/checkbox/index.d.ts +2 -2
- package/dist/checkbox/index.js +2 -2
- package/dist/chip-group/chip-group.d.ts +11 -0
- package/dist/chip-group/chip-group.js +50 -34
- package/dist/chip-group/chip-group.js.map +1 -1
- package/dist/chip-group/index.d.ts +2 -2
- package/dist/code-block/code-block.d.ts +45 -0
- package/dist/code-block/code-block.js +74 -0
- package/dist/code-block/code-block.js.map +1 -0
- package/dist/code-block/index.d.ts +2 -0
- package/dist/code-block/index.js +2 -0
- package/dist/command-palette/command-palette.d.ts +128 -0
- package/dist/command-palette/command-palette.js +371 -0
- package/dist/command-palette/command-palette.js.map +1 -0
- package/dist/command-palette/index.d.ts +2 -0
- package/dist/command-palette/index.js +2 -0
- package/dist/copy-button/copy-button.d.ts +19 -3
- package/dist/copy-button/copy-button.js +7 -4
- package/dist/copy-button/copy-button.js.map +1 -1
- package/dist/dialog/dialog.js +1 -1
- package/dist/dialog/dialog.js.map +1 -1
- package/dist/empty-state/empty-state.d.ts +17 -0
- package/dist/empty-state/empty-state.js +9 -7
- package/dist/empty-state/empty-state.js.map +1 -1
- package/dist/file-drop-zone/file-drop-zone.d.ts +29 -3
- package/dist/file-drop-zone/file-drop-zone.js +26 -8
- package/dist/file-drop-zone/file-drop-zone.js.map +1 -1
- package/dist/gauge/gauge.d.ts +18 -1
- package/dist/gauge/gauge.js +35 -21
- package/dist/gauge/gauge.js.map +1 -1
- package/dist/gauge/index.d.ts +2 -2
- package/dist/index.d.ts +14 -9
- package/dist/index.js +14 -10
- package/dist/info-tooltip/index.d.ts +2 -0
- package/dist/info-tooltip/index.js +2 -0
- package/dist/info-tooltip/info-tooltip.d.ts +35 -0
- package/dist/info-tooltip/info-tooltip.js +49 -0
- package/dist/info-tooltip/info-tooltip.js.map +1 -0
- package/dist/input/input.d.ts +7 -0
- package/dist/input/input.js +4 -2
- package/dist/input/input.js.map +1 -1
- package/dist/lib/field-shell.js +2 -6
- package/dist/lib/field-shell.js.map +1 -1
- package/dist/lib/required-marker.js +20 -0
- package/dist/lib/required-marker.js.map +1 -0
- package/dist/lib/selection-control.js +32 -1
- package/dist/lib/selection-control.js.map +1 -1
- package/dist/line-chart/index.d.ts +2 -2
- package/dist/line-chart/line-chart.d.ts +106 -3
- package/dist/line-chart/line-chart.js +185 -46
- package/dist/line-chart/line-chart.js.map +1 -1
- package/dist/mention-input/mention-input.js +1 -1
- package/dist/money-input/index.d.ts +2 -2
- package/dist/money-input/money-input.d.ts +14 -0
- package/dist/money-input/money-input.js +17 -7
- package/dist/money-input/money-input.js.map +1 -1
- package/dist/morph-select/morph-select.d.ts +8 -1
- package/dist/morph-select/morph-select.js +8 -5
- package/dist/morph-select/morph-select.js.map +1 -1
- package/dist/multi-select/multi-select.d.ts +31 -0
- package/dist/multi-select/multi-select.js +123 -6
- package/dist/multi-select/multi-select.js.map +1 -1
- package/dist/number-field/number-field.js +1 -1
- package/dist/password-field/password-field.js +1 -1
- package/dist/password-strength/password-strength.js +1 -1
- package/dist/phone-input/phone-input.js +1 -1
- package/dist/popover/popover.js +1 -1
- package/dist/popover/popover.js.map +1 -1
- package/dist/progress/index.d.ts +2 -2
- package/dist/progress/index.js +2 -2
- package/dist/progress/progress.d.ts +53 -2
- package/dist/progress/progress.js +146 -36
- package/dist/progress/progress.js.map +1 -1
- package/dist/radio-group/radio-group.d.ts +12 -3
- package/dist/radio-group/radio-group.js +62 -52
- package/dist/radio-group/radio-group.js.map +1 -1
- package/dist/rich-text-editor/rich-text-editor.js +1 -1
- package/dist/scroll-area/scroll-area.d.ts +1 -1
- package/dist/scrub-input/scrub-input.d.ts +11 -1
- package/dist/scrub-input/scrub-input.js +22 -10
- package/dist/scrub-input/scrub-input.js.map +1 -1
- package/dist/search-field/search-field.js +1 -1
- package/dist/select/select.d.ts +10 -1
- package/dist/select/select.js +4 -3
- package/dist/select/select.js.map +1 -1
- package/dist/separator/separator.d.ts +1 -1
- package/dist/shortcut-recorder/shortcut-recorder.js +1 -1
- package/dist/sparkline/sparkline.d.ts +27 -2
- package/dist/sparkline/sparkline.js +115 -18
- package/dist/sparkline/sparkline.js.map +1 -1
- package/dist/stat-card/index.d.ts +2 -2
- package/dist/stat-card/index.js +2 -2
- package/dist/stat-card/stat-card.d.ts +32 -1
- package/dist/stat-card/stat-card.js +52 -9
- package/dist/stat-card/stat-card.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/table/index.d.ts +2 -2
- package/dist/table/index.js +2 -2
- package/dist/table/table.d.ts +211 -3
- package/dist/table/table.js +473 -93
- package/dist/table/table.js.map +1 -1
- package/dist/tabs/tabs.d.ts +4 -2
- package/dist/tabs/tabs.js +7 -5
- package/dist/tabs/tabs.js.map +1 -1
- package/dist/tag-input/tag-input.js +1 -1
- package/dist/text-shimmer/text-shimmer.d.ts +18 -2
- package/dist/text-shimmer/text-shimmer.js +5 -2
- package/dist/text-shimmer/text-shimmer.js.map +1 -1
- package/dist/textarea/textarea.d.ts +7 -0
- package/dist/textarea/textarea.js +4 -2
- package/dist/textarea/textarea.js.map +1 -1
- package/dist/toast/toast.d.ts +2 -2
- package/dist/toggle-button/index.d.ts +2 -0
- package/dist/toggle-button/index.js +2 -0
- package/dist/toggle-button/toggle-button.d.ts +93 -0
- package/dist/toggle-button/toggle-button.js +199 -0
- package/dist/toggle-button/toggle-button.js.map +1 -0
- package/package.json +19 -3
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
//#region src/lib/required-marker.tsx
|
|
3
|
+
/**
|
|
4
|
+
* The required marker after a field's label: one red asterisk, the same in
|
|
5
|
+
* every field (FieldShell's, and Select's own label). Decoration only
|
|
6
|
+
* (aria-hidden): the control's own `required` is what a screen reader
|
|
7
|
+
* announces, so the name stays "Email", not "Email star".
|
|
8
|
+
*/
|
|
9
|
+
function RequiredMarker() {
|
|
10
|
+
return /* @__PURE__ */ jsx("span", {
|
|
11
|
+
"aria-hidden": "true",
|
|
12
|
+
"data-slot": "field-required",
|
|
13
|
+
className: "-ms-1 text-destructive-strong",
|
|
14
|
+
children: "*"
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
//#endregion
|
|
18
|
+
export { RequiredMarker };
|
|
19
|
+
|
|
20
|
+
//# sourceMappingURL=required-marker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"required-marker.js","names":[],"sources":["../../src/lib/required-marker.tsx"],"sourcesContent":["/**\n * The required marker after a field's label: one red asterisk, the same in\n * every field (FieldShell's, and Select's own label). Decoration only\n * (aria-hidden): the control's own `required` is what a screen reader\n * announces, so the name stays \"Email\", not \"Email star\".\n */\nexport function RequiredMarker() {\n return (\n <span aria-hidden=\"true\" data-slot=\"field-required\" className=\"-ms-1 text-destructive-strong\">\n *\n </span>\n );\n}\n"],"mappings":";;;;;;;;AAMA,SAAgB,iBAAiB;CAC/B,OACE,oBAAC,QAAD;EAAM,eAAY;EAAO,aAAU;EAAiB,WAAU;EAAgC,UAAA;CAExF,CAAA;AAEV"}
|
|
@@ -51,7 +51,38 @@ const selectionRingVariants = cva([
|
|
|
51
51
|
"group-data-[focus-visible]:outline-offset-(--focus-ring-offset)",
|
|
52
52
|
"group-data-[focus-visible]:outline-(--color-ring)"
|
|
53
53
|
]);
|
|
54
|
+
/**
|
|
55
|
+
* A selectable card: one choice (Radio) or one option (Checkbox) drawn as a
|
|
56
|
+
* bordered surface the whole of which is the hit target.
|
|
57
|
+
*
|
|
58
|
+
* Selection is shown twice, by the border AND by the mark inside the card (the
|
|
59
|
+
* radio dot, the checkbox tick), so it never rests on colour alone (WCAG 1.4.1).
|
|
60
|
+
* The border reuses StatCard's selected filter pair (`border-primary-strong`,
|
|
61
|
+
* hover darkens an unselected edge).
|
|
62
|
+
*
|
|
63
|
+
* FOCUS is the approved style: the card's own 1px border turns dark, with no
|
|
64
|
+
* ring. React Aria puts the state on the label, which IS the card, so its own
|
|
65
|
+
* `data-[focus-visible]:` is the state (no `group-` hop). The doubled selected
|
|
66
|
+
* rule makes a focused, selected card show it too. Forced colours override a
|
|
67
|
+
* border colour, so only there does the outline come back.
|
|
68
|
+
*/
|
|
69
|
+
const selectionCardVariants = cva([
|
|
70
|
+
"group flex items-start gap-3 p-4",
|
|
71
|
+
"rounded-panel border-(length:--border-width) border-border bg-surface",
|
|
72
|
+
"box-border font-sans text-sm leading-(--leading-normal) text-foreground text-start",
|
|
73
|
+
"cursor-pointer select-none",
|
|
74
|
+
"motion-safe:transition-[border-color] motion-safe:duration-(--duration-quick) motion-safe:ease-settle",
|
|
75
|
+
"data-[hovered]:not-data-[selected]:border-muted-foreground",
|
|
76
|
+
"data-[selected]:border-primary-strong",
|
|
77
|
+
"data-[disabled]:cursor-not-allowed data-[disabled]:opacity-(--opacity-disabled)",
|
|
78
|
+
"outline-none",
|
|
79
|
+
"data-[focus-visible]:border-foreground",
|
|
80
|
+
"data-[focus-visible]:data-[selected]:border-foreground",
|
|
81
|
+
"forced-colors:data-[focus-visible]:outline-solid",
|
|
82
|
+
"forced-colors:data-[focus-visible]:outline-(length:--focus-ring-width)",
|
|
83
|
+
"forced-colors:data-[focus-visible]:outline-offset-(--focus-ring-offset)"
|
|
84
|
+
]);
|
|
54
85
|
//#endregion
|
|
55
|
-
export { selectionLabelVariants, selectionRingVariants };
|
|
86
|
+
export { selectionCardVariants, selectionLabelVariants, selectionRingVariants };
|
|
56
87
|
|
|
57
88
|
//# sourceMappingURL=selection-control.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selection-control.js","names":[],"sources":["../../src/lib/selection-control.ts"],"sourcesContent":["import { cva } from \"class-variance-authority\";\n\n/**\n * The parts every selection control shares: Checkbox, Radio and Switch.\n *\n * Extracted at the Rule of Three, and for the reason this migration keeps\n * running into -- the legacy shipped `input.tsx` and `textarea.tsx` styling\n * one surface twice, and `dialog.tsx` and `alert-dialog.tsx` doing the same,\n * and both pairs had already drifted in ways nobody decided. Three controls\n * with the same label geometry and the same focus ring is where that starts.\n *\n * React Aria renders all three as a `<label>` wrapping a visually-hidden\n * real input, and puts the state on the LABEL -- so the visible box or track\n * has to reach its own state through `group-*`.\n *\n * Every string is a STATIC literal. Tailwind scans source text, so a class\n * assembled at runtime is invisible to it and would never be emitted.\n */\n\n/**\n * The label that wraps the control and its text.\n *\n * `group` is load-bearing: React Aria puts `data-selected`,\n * `data-focus-visible` and the rest on this element, and CSS cannot look\n * upward from the box to them.\n */\nexport const selectionLabelVariants = cva([\n \"group inline-flex items-center gap-2\",\n\n // WCAG 2.2 target-size (2.5.8) wants 24x24 CSS pixels. The controls are\n // 16-20px, which is conventional, so the LABEL carries the target: with\n // text it is large anyway, and without -- a table row selector -- this\n // minimum is the only thing keeping it hittable.\n //\n // Measured, not assumed: axe's target-size rule did NOT fire on a 16px\n // control during the Checkbox sabotage run. Only the explicit assertion\n // caught it.\n \"min-h-6 min-w-6 justify-center\",\n\n // The reset in @seekalfred/styles is OPT-IN, so a consumer may load none.\n // An unstyled <label> inherits the host page's serif; the Accordion\n // shipped its panel exactly that way.\n \"box-border font-sans text-sm leading-(--leading-normal) text-foreground\",\n\n \"cursor-pointer select-none\",\n \"data-[disabled]:cursor-not-allowed data-[disabled]:opacity-(--opacity-disabled)\",\n]);\n\n/**\n * The focus ring, drawn on the VISIBLE control rather than the input.\n *\n * React Aria's input is visually hidden, and an outline on a clipped 1px\n * element is invisible.\n *\n * `outline-solid` is load-bearing, not decoration. `outline-none` sets both\n * `outline-style: none` and `--tw-outline-style: none`, and the width\n * utility resolves its style from that same variable -- so a focus rule can\n * apply a width and a colour while faithfully re-applying none, and paint\n * nothing at all. Button shipped exactly that: keyboard-focusable with no\n * visible ring, and every automated gate stayed green because axe has no\n * focus-indicator rule.\n */\nexport const selectionRingVariants = cva([\n \"outline-none\",\n \"group-data-[focus-visible]:outline-solid\",\n \"group-data-[focus-visible]:outline-(length:--focus-ring-width)\",\n \"group-data-[focus-visible]:outline-offset-(--focus-ring-offset)\",\n \"group-data-[focus-visible]:outline-(--color-ring)\",\n]);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AA0BA,MAAa,yBAAyB,IAAI;CACxC;CAUA;CAKA;CAEA;CACA;AACF,CAAC;;;;;;;;;;;;;;;AAgBD,MAAa,wBAAwB,IAAI;CACvC;CACA;CACA;CACA;CACA;AACF,CAAC"}
|
|
1
|
+
{"version":3,"file":"selection-control.js","names":[],"sources":["../../src/lib/selection-control.ts"],"sourcesContent":["import { cva } from \"class-variance-authority\";\n\n/**\n * The parts every selection control shares: Checkbox, Radio and Switch.\n *\n * Extracted at the Rule of Three, and for the reason this migration keeps\n * running into -- the legacy shipped `input.tsx` and `textarea.tsx` styling\n * one surface twice, and `dialog.tsx` and `alert-dialog.tsx` doing the same,\n * and both pairs had already drifted in ways nobody decided. Three controls\n * with the same label geometry and the same focus ring is where that starts.\n *\n * React Aria renders all three as a `<label>` wrapping a visually-hidden\n * real input, and puts the state on the LABEL -- so the visible box or track\n * has to reach its own state through `group-*`.\n *\n * Every string is a STATIC literal. Tailwind scans source text, so a class\n * assembled at runtime is invisible to it and would never be emitted.\n */\n\n/**\n * The label that wraps the control and its text.\n *\n * `group` is load-bearing: React Aria puts `data-selected`,\n * `data-focus-visible` and the rest on this element, and CSS cannot look\n * upward from the box to them.\n */\nexport const selectionLabelVariants = cva([\n \"group inline-flex items-center gap-2\",\n\n // WCAG 2.2 target-size (2.5.8) wants 24x24 CSS pixels. The controls are\n // 16-20px, which is conventional, so the LABEL carries the target: with\n // text it is large anyway, and without -- a table row selector -- this\n // minimum is the only thing keeping it hittable.\n //\n // Measured, not assumed: axe's target-size rule did NOT fire on a 16px\n // control during the Checkbox sabotage run. Only the explicit assertion\n // caught it.\n \"min-h-6 min-w-6 justify-center\",\n\n // The reset in @seekalfred/styles is OPT-IN, so a consumer may load none.\n // An unstyled <label> inherits the host page's serif; the Accordion\n // shipped its panel exactly that way.\n \"box-border font-sans text-sm leading-(--leading-normal) text-foreground\",\n\n \"cursor-pointer select-none\",\n \"data-[disabled]:cursor-not-allowed data-[disabled]:opacity-(--opacity-disabled)\",\n]);\n\n/**\n * The focus ring, drawn on the VISIBLE control rather than the input.\n *\n * React Aria's input is visually hidden, and an outline on a clipped 1px\n * element is invisible.\n *\n * `outline-solid` is load-bearing, not decoration. `outline-none` sets both\n * `outline-style: none` and `--tw-outline-style: none`, and the width\n * utility resolves its style from that same variable -- so a focus rule can\n * apply a width and a colour while faithfully re-applying none, and paint\n * nothing at all. Button shipped exactly that: keyboard-focusable with no\n * visible ring, and every automated gate stayed green because axe has no\n * focus-indicator rule.\n */\nexport const selectionRingVariants = cva([\n \"outline-none\",\n \"group-data-[focus-visible]:outline-solid\",\n \"group-data-[focus-visible]:outline-(length:--focus-ring-width)\",\n \"group-data-[focus-visible]:outline-offset-(--focus-ring-offset)\",\n \"group-data-[focus-visible]:outline-(--color-ring)\",\n]);\n\n/**\n * A selectable card: one choice (Radio) or one option (Checkbox) drawn as a\n * bordered surface the whole of which is the hit target.\n *\n * Selection is shown twice, by the border AND by the mark inside the card (the\n * radio dot, the checkbox tick), so it never rests on colour alone (WCAG 1.4.1).\n * The border reuses StatCard's selected filter pair (`border-primary-strong`,\n * hover darkens an unselected edge).\n *\n * FOCUS is the approved style: the card's own 1px border turns dark, with no\n * ring. React Aria puts the state on the label, which IS the card, so its own\n * `data-[focus-visible]:` is the state (no `group-` hop). The doubled selected\n * rule makes a focused, selected card show it too. Forced colours override a\n * border colour, so only there does the outline come back.\n */\nexport const selectionCardVariants = cva([\n \"group flex items-start gap-3 p-4\",\n \"rounded-panel border-(length:--border-width) border-border bg-surface\",\n \"box-border font-sans text-sm leading-(--leading-normal) text-foreground text-start\",\n \"cursor-pointer select-none\",\n \"motion-safe:transition-[border-color] motion-safe:duration-(--duration-quick) motion-safe:ease-settle\",\n \"data-[hovered]:not-data-[selected]:border-muted-foreground\",\n \"data-[selected]:border-primary-strong\",\n \"data-[disabled]:cursor-not-allowed data-[disabled]:opacity-(--opacity-disabled)\",\n \"outline-none\",\n \"data-[focus-visible]:border-foreground\",\n \"data-[focus-visible]:data-[selected]:border-foreground\",\n \"forced-colors:data-[focus-visible]:outline-solid\",\n \"forced-colors:data-[focus-visible]:outline-(length:--focus-ring-width)\",\n \"forced-colors:data-[focus-visible]:outline-offset-(--focus-ring-offset)\",\n]);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AA0BA,MAAa,yBAAyB,IAAI;CACxC;CAUA;CAKA;CAEA;CACA;AACF,CAAC;;;;;;;;;;;;;;;AAgBD,MAAa,wBAAwB,IAAI;CACvC;CACA;CACA;CACA;CACA;AACF,CAAC;;;;;;;;;;;;;;;;AAiBD,MAAa,wBAAwB,IAAI;CACvC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { LINE_CHART_DRAW_MS, LineChart, LineChartDatum, LineChartProps, LineChartReference, LineChartSeries } from "./line-chart.js";
|
|
2
|
-
export { LINE_CHART_DRAW_MS, LineChart, type LineChartDatum, type LineChartProps, type LineChartReference, type LineChartSeries };
|
|
1
|
+
import { LINE_CHART_DRAW_MS, LineChart, LineChartBand, LineChartDatum, LineChartMarker, LineChartProps, LineChartReference, LineChartSeries, LineChartTone, LineChartTooltipContext } from "./line-chart.js";
|
|
2
|
+
export { LINE_CHART_DRAW_MS, LineChart, type LineChartBand, type LineChartDatum, type LineChartMarker, type LineChartProps, type LineChartReference, type LineChartSeries, type LineChartTone, type LineChartTooltipContext };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ReactNode } from "react";
|
|
1
2
|
//#region src/line-chart/line-chart.d.ts
|
|
2
3
|
/**
|
|
3
4
|
* LineChart: one or more measures over time, when the shape of the trend
|
|
@@ -26,6 +27,19 @@ export interface LineChartSeries {
|
|
|
26
27
|
dashed?: boolean;
|
|
27
28
|
/** A faint fill under the line. Defaults to true for the first series. */
|
|
28
29
|
area?: boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Prints each value above its point, read with `formatValue` (without `unit`).
|
|
32
|
+
* A missing value (with `missing` `"gap"` or `"connect"`) has no label. For a
|
|
33
|
+
* few points: labels on a dense line collide.
|
|
34
|
+
* @default false
|
|
35
|
+
*/
|
|
36
|
+
pointLabels?: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* A label above the series' last point with a value. `true` prints that value
|
|
39
|
+
* (read with `formatValue`, without `unit`); a string prints the text, such as
|
|
40
|
+
* "Heading for 1,800", and is read in the chart's summary.
|
|
41
|
+
*/
|
|
42
|
+
endLabel?: boolean | string;
|
|
29
43
|
}
|
|
30
44
|
export interface LineChartDatum {
|
|
31
45
|
/** Stable identity, such as an ISO date. */
|
|
@@ -40,6 +54,8 @@ export interface LineChartDatum {
|
|
|
40
54
|
*/
|
|
41
55
|
values: Record<string, number | null | undefined>;
|
|
42
56
|
}
|
|
57
|
+
/** The colour role of a reference line or an event marker. `"neutral"` is the quiet default. */
|
|
58
|
+
export type LineChartTone = "neutral" | "accent" | "success" | "warning" | "danger";
|
|
43
59
|
/**
|
|
44
60
|
* A reference line: a horizontal line at a value (a target, a threshold), or a
|
|
45
61
|
* vertical line at one datum (today, a launch). Drawn dashed and quiet, behind
|
|
@@ -50,6 +66,12 @@ export type LineChartReference = {
|
|
|
50
66
|
key: string;
|
|
51
67
|
/** Short text beside the line, such as "Target" or "Today". Also read to screen readers. */
|
|
52
68
|
label: string;
|
|
69
|
+
/**
|
|
70
|
+
* Colours the line and its label, for a line whose colour carries meaning,
|
|
71
|
+
* such as a "Goal" in warning. Still dashed, still behind the series.
|
|
72
|
+
* @default "neutral"
|
|
73
|
+
*/
|
|
74
|
+
tone?: LineChartTone;
|
|
53
75
|
} & ({
|
|
54
76
|
/**
|
|
55
77
|
* A value on the value axis: a horizontal line. The scale grows to keep it
|
|
@@ -64,6 +86,54 @@ export type LineChartReference = {
|
|
|
64
86
|
at: string;
|
|
65
87
|
value?: never;
|
|
66
88
|
});
|
|
89
|
+
/**
|
|
90
|
+
* An event on the category axis, such as "prompts changed": a short stem up
|
|
91
|
+
* from the baseline at one datum, with a short visible label above it.
|
|
92
|
+
*/
|
|
93
|
+
export interface LineChartMarker {
|
|
94
|
+
/** Stable identity. */
|
|
95
|
+
key: string;
|
|
96
|
+
/** The `key` of a datum. A key not in `data` draws nothing. */
|
|
97
|
+
at: string;
|
|
98
|
+
/** Short visible text, such as "Changed" or "v2". */
|
|
99
|
+
label: string;
|
|
100
|
+
/** What happened, read to screen readers in place of `label`, such as "Prompt set changed". */
|
|
101
|
+
description?: string;
|
|
102
|
+
/** @default "neutral" */
|
|
103
|
+
tone?: LineChartTone;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* A shaded band across the plot between two values, such as "Page 1" for
|
|
107
|
+
* ranks 1 to 10. Drawn behind the gridlines and the series, clipped to the
|
|
108
|
+
* value axis; it never grows the scale.
|
|
109
|
+
*/
|
|
110
|
+
export interface LineChartBand {
|
|
111
|
+
/** Stable identity. */
|
|
112
|
+
key: string;
|
|
113
|
+
/** One edge of the band, on the value axis. Either order. */
|
|
114
|
+
from: number;
|
|
115
|
+
/** The other edge. */
|
|
116
|
+
to: number;
|
|
117
|
+
/** Short text inside the band at its top inline-start corner, such as "Page 1". Hidden when the band is too thin to hold it. */
|
|
118
|
+
label: string;
|
|
119
|
+
/** What the band means, read in the chart's summary in place of `label` and its range, such as "Page 1: ranks 1 to 10". */
|
|
120
|
+
description?: string;
|
|
121
|
+
/** @default "neutral" */
|
|
122
|
+
tone?: LineChartTone;
|
|
123
|
+
}
|
|
124
|
+
/** What `renderTooltip` is given for the point under the crosshair. */
|
|
125
|
+
export interface LineChartTooltipContext {
|
|
126
|
+
datum: LineChartDatum;
|
|
127
|
+
index: number;
|
|
128
|
+
/** The series on show, in order. */
|
|
129
|
+
series: LineChartSeries[];
|
|
130
|
+
/** Each shown series' value at this point; `null` when it is missing (with `missing` `"gap"` or `"connect"`). */
|
|
131
|
+
values: Record<string, number | null>;
|
|
132
|
+
/** Reads a value the way the default tooltip does: `formatValue`, `unit`, and `missingLabel` for `null`. */
|
|
133
|
+
format: (value: number | null, series: LineChartSeries) => string;
|
|
134
|
+
/** The default tooltip content (the date and one row per series), to keep and add to. */
|
|
135
|
+
readout: ReactNode;
|
|
136
|
+
}
|
|
67
137
|
export interface LineChartProps {
|
|
68
138
|
data: LineChartDatum[];
|
|
69
139
|
series: LineChartSeries[];
|
|
@@ -98,14 +168,47 @@ export interface LineChartProps {
|
|
|
98
168
|
* `"zero"` counts it as zero, as before. `"gap"` breaks the line (and its
|
|
99
169
|
* area) there, leaves it out of the scale, hides the crosshair dot on it and
|
|
100
170
|
* reads it as `missingLabel` in the tooltip and the data table. A point with
|
|
101
|
-
* missing neighbours on both sides is drawn as a dot
|
|
171
|
+
* missing neighbours on both sides is drawn as a dot, and so is the only point
|
|
172
|
+
* of a chart with one datum (at the centre, in every mode). `"connect"` is the same,
|
|
173
|
+
* except the line runs on across missing values between two present ones,
|
|
174
|
+
* through the straight line between them (a projection known at a few
|
|
175
|
+
* points); before the first value and after the last, nothing is drawn.
|
|
102
176
|
* @default "zero"
|
|
103
177
|
*/
|
|
104
|
-
missing?: "zero" | "gap";
|
|
105
|
-
/** Read in place of a missing value when `missing` is `"gap"`. @default "No data" */
|
|
178
|
+
missing?: "zero" | "gap" | "connect";
|
|
179
|
+
/** Read in place of a missing value when `missing` is `"gap"` or `"connect"`. @default "No data" */
|
|
106
180
|
missingLabel?: string;
|
|
107
181
|
/** Reference lines: targets at a value, or markers such as "today" at a datum. */
|
|
108
182
|
references?: LineChartReference[];
|
|
183
|
+
/** Events on the category axis, each with a short visible label. Read in the summary and when scrubbed to. */
|
|
184
|
+
markers?: LineChartMarker[];
|
|
185
|
+
/**
|
|
186
|
+
* Flips the value axis: the lowest value at the top, the highest on the
|
|
187
|
+
* baseline. For ranks, where 1 is best. Pair it with `valueDomain`, such as
|
|
188
|
+
* `{ min: 1 }`, so the axis starts at rank 1 rather than 0.
|
|
189
|
+
* @default false
|
|
190
|
+
*/
|
|
191
|
+
reversed?: boolean;
|
|
192
|
+
/**
|
|
193
|
+
* Pins either end of the value axis, such as `{ min: 1, max: 100 }` for ranks
|
|
194
|
+
* #1 to #100. An end left out fits the data as before (from zero at the low
|
|
195
|
+
* end). The pinned values are always ticks. A value past a pinned end is drawn
|
|
196
|
+
* past the edge, so pin a range that covers the data.
|
|
197
|
+
*/
|
|
198
|
+
valueDomain?: {
|
|
199
|
+
min?: number;
|
|
200
|
+
max?: number;
|
|
201
|
+
};
|
|
202
|
+
/** Shaded bands between two values, such as rank pages. Read in the summary. */
|
|
203
|
+
bands?: LineChartBand[];
|
|
204
|
+
/**
|
|
205
|
+
* Replaces the tooltip's content for the point under the crosshair. It is
|
|
206
|
+
* given the point and the default `readout`, to keep and add to (gained and
|
|
207
|
+
* lost counts under a total). Return `null` (or `undefined`, `false`, `0` or `""`) to show no tooltip at that point.
|
|
208
|
+
* The tooltip is visual only: the slider's value text, the summary and the
|
|
209
|
+
* data table still read every value.
|
|
210
|
+
*/
|
|
211
|
+
renderTooltip?: (context: LineChartTooltipContext) => ReactNode;
|
|
109
212
|
/** Extra classes for the root. Merged last. */
|
|
110
213
|
className?: string;
|
|
111
214
|
}
|