@robr0/design-system 0.11.0 → 0.12.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 +4 -4
- package/charts.d.ts +1 -0
- package/charts.js +2 -0
- package/components/AppLayout/AppLayout.d.ts +7 -1
- package/components/AppLayout/AppLayout.js +2 -1
- package/components/AppSidebar/AppSidebar.css +104 -40
- package/components/AppSidebar/AppSidebar.d.ts +14 -1
- package/components/AppSidebar/AppSidebar.js +26 -17
- package/components/Badge/Badge.css +4 -5
- package/components/Chart/AreaChart.d.ts +5 -1
- package/components/Chart/AreaChart.js +5 -4
- package/components/Chart/BarChart.d.ts +3 -1
- package/components/Chart/BarChart.js +3 -3
- package/components/Chart/Chart.css +45 -0
- package/components/Chart/ComboChart.d.ts +40 -0
- package/components/Chart/ComboChart.js +142 -0
- package/components/Chart/LineChart.d.ts +3 -1
- package/components/Chart/LineChart.js +3 -3
- package/components/Chart/PieChart.d.ts +3 -1
- package/components/Chart/PieChart.js +3 -3
- package/components/Chart/RadarChart.d.ts +3 -1
- package/components/Chart/RadarChart.js +3 -3
- package/components/Chart/RadialChart.d.ts +7 -1
- package/components/Chart/RadialChart.js +51 -43
- package/components/Chart/ScatterChart.d.ts +3 -1
- package/components/Chart/ScatterChart.js +3 -3
- package/components/Chart/StackedBarChart.d.ts +3 -1
- package/components/Chart/StackedBarChart.js +3 -3
- package/components/Chart/Treemap.d.ts +3 -1
- package/components/Chart/Treemap.js +3 -3
- package/components/Chart/palette.js +1 -3
- package/components/FunnelChart/FunnelChart.css +41 -0
- package/components/FunnelChart/FunnelChart.d.ts +40 -0
- package/components/FunnelChart/FunnelChart.js +48 -0
- package/components/LegendTile/LegendTile.css +60 -0
- package/components/LegendTile/LegendTile.d.ts +30 -0
- package/components/LegendTile/LegendTile.js +21 -0
- package/components/Panel/Panel.css +26 -0
- package/components/Panel/Panel.d.ts +22 -0
- package/components/Panel/Panel.js +19 -0
- package/components/Stat/Stat.css +35 -2
- package/components/Stat/Stat.d.ts +3 -1
- package/components/Stat/Stat.js +7 -1
- package/components/registry.json +33 -0
- package/components/registry.json.d.ts +33 -0
- package/components/registry.json.js +1 -1
- package/index.d.ts +3 -0
- package/index.js +6 -0
- package/package.json +1 -1
- package/tokens/registry.json +4 -1
- package/tokens/registry.json.d.ts +4 -1
- package/tokens/registry.json.js +1 -1
- package/tokens/tokens-dark.css +3 -0
- package/tokens/tokens-light.css +11 -0
- package/tokens/tokens-primitives.css +2 -0
- package/tokens/tokens-typography.css +12 -5
|
@@ -96,6 +96,51 @@
|
|
|
96
96
|
|
|
97
97
|
.ds-chart__body {
|
|
98
98
|
width: 100%;
|
|
99
|
+
/* Anchors the radial centre label overlay. */
|
|
100
|
+
position: relative;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/* ============================================
|
|
104
|
+
BARE MODE — the chart sits inside another
|
|
105
|
+
panel that supplies the surface, so its own
|
|
106
|
+
card chrome would double-frame it
|
|
107
|
+
============================================ */
|
|
108
|
+
|
|
109
|
+
.ds-chart--bare {
|
|
110
|
+
border: none;
|
|
111
|
+
padding: 0;
|
|
112
|
+
background-color: transparent;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/* ============================================
|
|
116
|
+
RADIAL CENTRE LABEL — the gauge's headline
|
|
117
|
+
in the donut hole
|
|
118
|
+
============================================ */
|
|
119
|
+
|
|
120
|
+
.ds-chart__radial-center {
|
|
121
|
+
position: absolute;
|
|
122
|
+
inset: 0;
|
|
123
|
+
display: grid;
|
|
124
|
+
place-content: center;
|
|
125
|
+
justify-items: center;
|
|
126
|
+
gap: var(--gap-xxs);
|
|
127
|
+
pointer-events: none;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
.ds-chart__radial-center-value {
|
|
131
|
+
font-family: var(--font-sub-display-family);
|
|
132
|
+
font-size: var(--font-sub-display-size);
|
|
133
|
+
font-weight: var(--font-sub-display-weight);
|
|
134
|
+
line-height: var(--font-sub-display-line-height);
|
|
135
|
+
letter-spacing: var(--font-sub-display-letter-spacing);
|
|
136
|
+
color: var(--color-text-primary);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
.ds-chart__radial-center-sub {
|
|
140
|
+
font-family: var(--font-caption-family);
|
|
141
|
+
font-size: var(--font-caption-size);
|
|
142
|
+
line-height: var(--font-caption-line-height);
|
|
143
|
+
color: var(--color-text-secondary);
|
|
99
144
|
}
|
|
100
145
|
|
|
101
146
|
/* ============================================
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { ChartSummaryItem } from './BarChart';
|
|
2
|
+
export interface ComboChartProps {
|
|
3
|
+
/** Array of data objects */
|
|
4
|
+
data: Record<string, unknown>[];
|
|
5
|
+
/** Key in data for x-axis values */
|
|
6
|
+
xKey?: string;
|
|
7
|
+
/** Key in data for the bar series */
|
|
8
|
+
barKey: string;
|
|
9
|
+
/** Display name for the bar series, shown in the tooltip; defaults to the key */
|
|
10
|
+
barLabel?: string;
|
|
11
|
+
/** Key in data for the line series */
|
|
12
|
+
lineKey: string;
|
|
13
|
+
/** Display name for the line series, shown in the tooltip; defaults to the key */
|
|
14
|
+
lineLabel?: string;
|
|
15
|
+
/** Bar fill colour (CSS value or token reference) */
|
|
16
|
+
barColor?: string;
|
|
17
|
+
/** Line stroke colour (CSS value or token reference) */
|
|
18
|
+
lineColor?: string;
|
|
19
|
+
/** Plot the line on its own right-hand y-axis, for series in different units */
|
|
20
|
+
secondaryAxis?: boolean;
|
|
21
|
+
/** Chart title */
|
|
22
|
+
title?: string;
|
|
23
|
+
/** Description text below the title */
|
|
24
|
+
subtitle?: string;
|
|
25
|
+
/** Summary stats displayed in the header */
|
|
26
|
+
summaryItems?: ChartSummaryItem[];
|
|
27
|
+
/** Chart area height in pixels */
|
|
28
|
+
height?: number;
|
|
29
|
+
/** Strip the card chrome (border, padding, fill) when the chart sits inside another panel that supplies the surface */
|
|
30
|
+
bare?: boolean;
|
|
31
|
+
/** Additional CSS classes on the wrapper */
|
|
32
|
+
className?: string;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Combo chart built on Recharts with design-system tokens: one bar series
|
|
36
|
+
* with an overlaid line series, optionally on a second y-axis, for pairs
|
|
37
|
+
* like monthly spend (bars) against ROAS (line). Part of the Chart component
|
|
38
|
+
* family, sharing wrapper, header, tooltip, and summary-stat styles.
|
|
39
|
+
*/
|
|
40
|
+
export declare const ComboChart: ({ data, xKey, barKey, barLabel, lineKey, lineLabel, barColor, lineColor, secondaryAxis, title, subtitle, summaryItems, height, bare, className, }: ComboChartProps) => import("react").JSX.Element;
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback } from "react";
|
|
3
|
+
import { ResponsiveContainer, ComposedChart, CartesianGrid, XAxis, YAxis, Tooltip, Bar, Line } from "recharts";
|
|
4
|
+
import { getChartSeriesColors } from "./palette.js";
|
|
5
|
+
import "./Chart.css";
|
|
6
|
+
function getCSSVar(name, fallback) {
|
|
7
|
+
return `var(${name}, ${fallback})`;
|
|
8
|
+
}
|
|
9
|
+
function ComboTooltip({ active, payload, label }) {
|
|
10
|
+
if (!active || !payload?.length) return null;
|
|
11
|
+
return /* @__PURE__ */ jsxs("div", { className: "ds-chart__tooltip", children: [
|
|
12
|
+
/* @__PURE__ */ jsx("div", { className: "ds-chart__tooltip-label", children: label }),
|
|
13
|
+
payload.map((entry, i) => /* @__PURE__ */ jsxs("div", { className: "ds-chart__tooltip-row", children: [
|
|
14
|
+
/* @__PURE__ */ jsx(
|
|
15
|
+
"span",
|
|
16
|
+
{
|
|
17
|
+
className: "ds-chart__tooltip-dot",
|
|
18
|
+
style: { backgroundColor: entry.color || entry.fill }
|
|
19
|
+
}
|
|
20
|
+
),
|
|
21
|
+
/* @__PURE__ */ jsx("span", { className: "ds-chart__tooltip-name", children: entry.name }),
|
|
22
|
+
/* @__PURE__ */ jsx("span", { className: "ds-chart__tooltip-value", children: entry.value?.toLocaleString() })
|
|
23
|
+
] }, i))
|
|
24
|
+
] });
|
|
25
|
+
}
|
|
26
|
+
const ComboChart = ({
|
|
27
|
+
data,
|
|
28
|
+
xKey = "label",
|
|
29
|
+
barKey,
|
|
30
|
+
barLabel,
|
|
31
|
+
lineKey,
|
|
32
|
+
lineLabel,
|
|
33
|
+
barColor,
|
|
34
|
+
lineColor,
|
|
35
|
+
secondaryAxis = true,
|
|
36
|
+
title,
|
|
37
|
+
subtitle,
|
|
38
|
+
summaryItems,
|
|
39
|
+
height = 350,
|
|
40
|
+
bare = false,
|
|
41
|
+
className = ""
|
|
42
|
+
}) => {
|
|
43
|
+
const baseClass = "ds-chart";
|
|
44
|
+
const classes = [baseClass, bare ? `${baseClass}--bare` : "", className].filter(Boolean).join(" ");
|
|
45
|
+
const seriesColors = getChartSeriesColors();
|
|
46
|
+
const resolvedBarColor = barColor || getCSSVar("--color-action-primary-bg", "#0E6E8F");
|
|
47
|
+
const resolvedLineColor = lineColor || seriesColors[1];
|
|
48
|
+
const textSecondary = getCSSVar("--color-text-secondary", "#A2A2A2");
|
|
49
|
+
const gridColor = getCSSVar("--color-divider", "#232323");
|
|
50
|
+
const cursorColor = getCSSVar("--color-bg-container-secondary", "#303030");
|
|
51
|
+
const resolvedBarLabel = barLabel || barKey;
|
|
52
|
+
const resolvedLineLabel = lineLabel || lineKey;
|
|
53
|
+
const renderTooltip = useCallback(
|
|
54
|
+
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
|
55
|
+
(props) => /* @__PURE__ */ jsx(ComboTooltip, { ...props }),
|
|
56
|
+
[]
|
|
57
|
+
);
|
|
58
|
+
return /* @__PURE__ */ jsxs("div", { className: classes, children: [
|
|
59
|
+
(title || subtitle || summaryItems) && /* @__PURE__ */ jsxs("div", { className: `${baseClass}__header`, children: [
|
|
60
|
+
/* @__PURE__ */ jsxs("div", { className: `${baseClass}__header-text`, children: [
|
|
61
|
+
title && /* @__PURE__ */ jsx("h3", { className: `${baseClass}__title`, children: title }),
|
|
62
|
+
subtitle && /* @__PURE__ */ jsx("p", { className: `${baseClass}__subtitle`, children: subtitle })
|
|
63
|
+
] }),
|
|
64
|
+
summaryItems && summaryItems.length > 0 && /* @__PURE__ */ jsx("div", { className: `${baseClass}__summary`, children: summaryItems.map((item, i) => /* @__PURE__ */ jsxs("div", { className: `${baseClass}__summary-item`, children: [
|
|
65
|
+
/* @__PURE__ */ jsx("span", { className: `${baseClass}__summary-label`, children: item.label }),
|
|
66
|
+
/* @__PURE__ */ jsx("span", { className: `${baseClass}__summary-value`, children: typeof item.value === "number" ? item.value.toLocaleString() : item.value })
|
|
67
|
+
] }, i)) })
|
|
68
|
+
] }),
|
|
69
|
+
/* @__PURE__ */ jsx("div", { className: `${baseClass}__body`, children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height, children: /* @__PURE__ */ jsxs(
|
|
70
|
+
ComposedChart,
|
|
71
|
+
{
|
|
72
|
+
data,
|
|
73
|
+
margin: { top: 8, right: secondaryAxis ? -12 : 4, bottom: 0, left: -12 },
|
|
74
|
+
children: [
|
|
75
|
+
/* @__PURE__ */ jsx(CartesianGrid, { vertical: false, stroke: gridColor }),
|
|
76
|
+
/* @__PURE__ */ jsx(
|
|
77
|
+
XAxis,
|
|
78
|
+
{
|
|
79
|
+
dataKey: xKey,
|
|
80
|
+
tick: { fill: textSecondary, fontSize: 12 },
|
|
81
|
+
tickLine: false,
|
|
82
|
+
axisLine: { stroke: gridColor }
|
|
83
|
+
}
|
|
84
|
+
),
|
|
85
|
+
/* @__PURE__ */ jsx(
|
|
86
|
+
YAxis,
|
|
87
|
+
{
|
|
88
|
+
yAxisId: "bar",
|
|
89
|
+
tick: { fill: textSecondary, fontSize: 12 },
|
|
90
|
+
tickLine: false,
|
|
91
|
+
axisLine: false
|
|
92
|
+
}
|
|
93
|
+
),
|
|
94
|
+
secondaryAxis && /* @__PURE__ */ jsx(
|
|
95
|
+
YAxis,
|
|
96
|
+
{
|
|
97
|
+
yAxisId: "line",
|
|
98
|
+
orientation: "right",
|
|
99
|
+
tick: { fill: textSecondary, fontSize: 12 },
|
|
100
|
+
tickLine: false,
|
|
101
|
+
axisLine: false
|
|
102
|
+
}
|
|
103
|
+
),
|
|
104
|
+
/* @__PURE__ */ jsx(
|
|
105
|
+
Tooltip,
|
|
106
|
+
{
|
|
107
|
+
content: renderTooltip,
|
|
108
|
+
cursor: { fill: cursorColor, opacity: 0.4 }
|
|
109
|
+
}
|
|
110
|
+
),
|
|
111
|
+
/* @__PURE__ */ jsx(
|
|
112
|
+
Bar,
|
|
113
|
+
{
|
|
114
|
+
yAxisId: "bar",
|
|
115
|
+
dataKey: barKey,
|
|
116
|
+
name: resolvedBarLabel,
|
|
117
|
+
fill: resolvedBarColor,
|
|
118
|
+
radius: [3, 3, 0, 0],
|
|
119
|
+
maxBarSize: 32
|
|
120
|
+
}
|
|
121
|
+
),
|
|
122
|
+
/* @__PURE__ */ jsx(
|
|
123
|
+
Line,
|
|
124
|
+
{
|
|
125
|
+
yAxisId: secondaryAxis ? "line" : "bar",
|
|
126
|
+
type: "monotone",
|
|
127
|
+
dataKey: lineKey,
|
|
128
|
+
name: resolvedLineLabel,
|
|
129
|
+
stroke: resolvedLineColor,
|
|
130
|
+
strokeWidth: 2,
|
|
131
|
+
dot: false,
|
|
132
|
+
activeDot: { r: 4, strokeWidth: 0 }
|
|
133
|
+
}
|
|
134
|
+
)
|
|
135
|
+
]
|
|
136
|
+
}
|
|
137
|
+
) }) })
|
|
138
|
+
] });
|
|
139
|
+
};
|
|
140
|
+
export {
|
|
141
|
+
ComboChart
|
|
142
|
+
};
|
|
@@ -24,6 +24,8 @@ export interface LineChartProps {
|
|
|
24
24
|
summaryItems?: ChartSummaryItem[];
|
|
25
25
|
/** Chart area height in pixels */
|
|
26
26
|
height?: number;
|
|
27
|
+
/** Strip the card chrome (border, padding, fill) when the chart sits inside another panel that supplies the surface */
|
|
28
|
+
bare?: boolean;
|
|
27
29
|
/** Additional CSS classes on the wrapper */
|
|
28
30
|
className?: string;
|
|
29
31
|
}
|
|
@@ -31,4 +33,4 @@ export interface LineChartProps {
|
|
|
31
33
|
* Line chart built on Recharts with design-system tokens.
|
|
32
34
|
* Supports multiple series with individual colours.
|
|
33
35
|
*/
|
|
34
|
-
export declare const LineChart: ({ data, xKey, series, title, subtitle, summaryItems, height, className, }: LineChartProps) => import("react").JSX.Element;
|
|
36
|
+
export declare const LineChart: ({ data, xKey, series, title, subtitle, summaryItems, height, bare, className, }: LineChartProps) => import("react").JSX.Element;
|
|
@@ -4,8 +4,7 @@ import { ResponsiveContainer, LineChart as LineChart$1, CartesianGrid, XAxis, YA
|
|
|
4
4
|
import { getChartSeriesColors } from "./palette.js";
|
|
5
5
|
import "./Chart.css";
|
|
6
6
|
function getCSSVar(name, fallback) {
|
|
7
|
-
|
|
8
|
-
return getComputedStyle(document.documentElement).getPropertyValue(name).trim() || fallback;
|
|
7
|
+
return `var(${name}, ${fallback})`;
|
|
9
8
|
}
|
|
10
9
|
function LineChartTooltip({ active, payload, label }) {
|
|
11
10
|
if (!active || !payload?.length) return null;
|
|
@@ -26,10 +25,11 @@ const LineChart = ({
|
|
|
26
25
|
subtitle,
|
|
27
26
|
summaryItems,
|
|
28
27
|
height = 350,
|
|
28
|
+
bare = false,
|
|
29
29
|
className = ""
|
|
30
30
|
}) => {
|
|
31
31
|
const baseClass = "ds-chart";
|
|
32
|
-
const classes = [baseClass, className].filter(Boolean).join(" ");
|
|
32
|
+
const classes = [baseClass, bare ? `${baseClass}--bare` : "", className].filter(Boolean).join(" ");
|
|
33
33
|
const textSecondary = getCSSVar("--color-text-secondary", "#A2A2A2");
|
|
34
34
|
const gridColor = getCSSVar("--color-divider", "#232323");
|
|
35
35
|
const seriesColors = getChartSeriesColors();
|
|
@@ -24,6 +24,8 @@ export interface PieChartProps {
|
|
|
24
24
|
outerRadius?: number;
|
|
25
25
|
/** Show legend */
|
|
26
26
|
showLegend?: boolean;
|
|
27
|
+
/** Strip the card chrome (border, padding, fill) when the chart sits inside another panel that supplies the surface */
|
|
28
|
+
bare?: boolean;
|
|
27
29
|
/** Additional CSS classes on the wrapper */
|
|
28
30
|
className?: string;
|
|
29
31
|
}
|
|
@@ -31,4 +33,4 @@ export interface PieChartProps {
|
|
|
31
33
|
* Pie / donut chart built on Recharts with design-system tokens.
|
|
32
34
|
* Set innerRadius > 0 for a donut variant.
|
|
33
35
|
*/
|
|
34
|
-
export declare const PieChart: ({ data, title, subtitle, summaryItems, height, innerRadius, outerRadius, showLegend, className, }: PieChartProps) => import("react").JSX.Element;
|
|
36
|
+
export declare const PieChart: ({ data, title, subtitle, summaryItems, height, innerRadius, outerRadius, showLegend, bare, className, }: PieChartProps) => import("react").JSX.Element;
|
|
@@ -4,8 +4,7 @@ import { ResponsiveContainer, PieChart as PieChart$1, Pie, Cell, Tooltip, Legend
|
|
|
4
4
|
import { getChartSeriesColors } from "./palette.js";
|
|
5
5
|
import "./Chart.css";
|
|
6
6
|
function getCSSVar(name, fallback) {
|
|
7
|
-
|
|
8
|
-
return getComputedStyle(document.documentElement).getPropertyValue(name).trim() || fallback;
|
|
7
|
+
return `var(${name}, ${fallback})`;
|
|
9
8
|
}
|
|
10
9
|
function PieChartTooltip({ active, payload }) {
|
|
11
10
|
if (!active || !payload?.length) return null;
|
|
@@ -31,10 +30,11 @@ const PieChart = ({
|
|
|
31
30
|
innerRadius = 0,
|
|
32
31
|
outerRadius = 140,
|
|
33
32
|
showLegend = true,
|
|
33
|
+
bare = false,
|
|
34
34
|
className = ""
|
|
35
35
|
}) => {
|
|
36
36
|
const baseClass = "ds-chart";
|
|
37
|
-
const classes = [baseClass, className].filter(Boolean).join(" ");
|
|
37
|
+
const classes = [baseClass, bare ? `${baseClass}--bare` : "", className].filter(Boolean).join(" ");
|
|
38
38
|
const defaultColors = getChartSeriesColors();
|
|
39
39
|
const textSecondary = getCSSVar("--color-text-secondary", "#A2A2A2");
|
|
40
40
|
const renderTooltip = useCallback(
|
|
@@ -24,6 +24,8 @@ export interface RadarChartProps {
|
|
|
24
24
|
summaryItems?: ChartSummaryItem[];
|
|
25
25
|
/** Chart area height in pixels */
|
|
26
26
|
height?: number;
|
|
27
|
+
/** Strip the card chrome (border, padding, fill) when the chart sits inside another panel that supplies the surface */
|
|
28
|
+
bare?: boolean;
|
|
27
29
|
/** Additional CSS classes on the wrapper */
|
|
28
30
|
className?: string;
|
|
29
31
|
}
|
|
@@ -31,4 +33,4 @@ export interface RadarChartProps {
|
|
|
31
33
|
* Radar chart built on Recharts with design-system tokens.
|
|
32
34
|
* Renders one or more data series as filled polygons on a polar grid.
|
|
33
35
|
*/
|
|
34
|
-
export declare const RadarChart: ({ data, categoryKey, series, title, subtitle, summaryItems, height, className, }: RadarChartProps) => import("react").JSX.Element;
|
|
36
|
+
export declare const RadarChart: ({ data, categoryKey, series, title, subtitle, summaryItems, height, bare, className, }: RadarChartProps) => import("react").JSX.Element;
|
|
@@ -4,8 +4,7 @@ import { ResponsiveContainer, RadarChart as RadarChart$1, PolarGrid, PolarAngleA
|
|
|
4
4
|
import { getChartSeriesColors } from "./palette.js";
|
|
5
5
|
import "./Chart.css";
|
|
6
6
|
function getCSSVar(name, fallback) {
|
|
7
|
-
|
|
8
|
-
return getComputedStyle(document.documentElement).getPropertyValue(name).trim() || fallback;
|
|
7
|
+
return `var(${name}, ${fallback})`;
|
|
9
8
|
}
|
|
10
9
|
function RadarTooltip({ active, payload, label }) {
|
|
11
10
|
if (!active || !payload?.length) return null;
|
|
@@ -26,10 +25,11 @@ const RadarChart = ({
|
|
|
26
25
|
subtitle,
|
|
27
26
|
summaryItems,
|
|
28
27
|
height = 350,
|
|
28
|
+
bare = false,
|
|
29
29
|
className = ""
|
|
30
30
|
}) => {
|
|
31
31
|
const baseClass = "ds-chart";
|
|
32
|
-
const classes = [baseClass, className].filter(Boolean).join(" ");
|
|
32
|
+
const classes = [baseClass, bare ? `${baseClass}--bare` : "", className].filter(Boolean).join(" ");
|
|
33
33
|
const textSecondary = getCSSVar("--color-text-secondary", "#A2A2A2");
|
|
34
34
|
const gridColor = getCSSVar("--color-divider", "#232323");
|
|
35
35
|
const seriesColors = getChartSeriesColors();
|
|
@@ -26,6 +26,12 @@ export interface RadialChartProps {
|
|
|
26
26
|
outerRadius?: number;
|
|
27
27
|
/** Show legend */
|
|
28
28
|
showLegend?: boolean;
|
|
29
|
+
/** Headline printed in the donut hole, e.g. "46%"; pairs best with showLegend false, since the legend shifts the rings above centre */
|
|
30
|
+
centerLabel?: string;
|
|
31
|
+
/** Small caption under the centre headline */
|
|
32
|
+
centerSublabel?: string;
|
|
33
|
+
/** Strip the card chrome (border, padding, fill) when the chart sits inside another panel that supplies the surface */
|
|
34
|
+
bare?: boolean;
|
|
29
35
|
/** Additional CSS classes on the wrapper */
|
|
30
36
|
className?: string;
|
|
31
37
|
}
|
|
@@ -34,4 +40,4 @@ export interface RadialChartProps {
|
|
|
34
40
|
* Each data item renders as a concentric ring — great for
|
|
35
41
|
* progress indicators and comparative gauges.
|
|
36
42
|
*/
|
|
37
|
-
export declare const RadialChart: ({ data, maxValue, title, subtitle, summaryItems, height, innerRadius, outerRadius, showLegend, className, }: RadialChartProps) => import("react").JSX.Element;
|
|
43
|
+
export declare const RadialChart: ({ data, maxValue, title, subtitle, summaryItems, height, innerRadius, outerRadius, showLegend, centerLabel, centerSublabel, bare, className, }: RadialChartProps) => import("react").JSX.Element;
|
|
@@ -4,8 +4,7 @@ import { ResponsiveContainer, RadialBarChart, PolarAngleAxis, RadialBar, Tooltip
|
|
|
4
4
|
import { getChartSeriesColors } from "./palette.js";
|
|
5
5
|
import "./Chart.css";
|
|
6
6
|
function getCSSVar(name, fallback) {
|
|
7
|
-
|
|
8
|
-
return getComputedStyle(document.documentElement).getPropertyValue(name).trim() || fallback;
|
|
7
|
+
return `var(${name}, ${fallback})`;
|
|
9
8
|
}
|
|
10
9
|
function RadialTooltip({ active, payload }) {
|
|
11
10
|
if (!active || !payload?.length) return null;
|
|
@@ -32,10 +31,13 @@ const RadialChart = ({
|
|
|
32
31
|
innerRadius = 40,
|
|
33
32
|
outerRadius = 140,
|
|
34
33
|
showLegend = true,
|
|
34
|
+
centerLabel,
|
|
35
|
+
centerSublabel,
|
|
36
|
+
bare = false,
|
|
35
37
|
className = ""
|
|
36
38
|
}) => {
|
|
37
39
|
const baseClass = "ds-chart";
|
|
38
|
-
const classes = [baseClass, className].filter(Boolean).join(" ");
|
|
40
|
+
const classes = [baseClass, bare ? `${baseClass}--bare` : "", className].filter(Boolean).join(" ");
|
|
39
41
|
const defaultColors = getChartSeriesColors();
|
|
40
42
|
const textSecondary = getCSSVar("--color-text-secondary", "#A2A2A2");
|
|
41
43
|
const bgColor = getCSSVar("--color-bg-container-primary", "#0E0E0E");
|
|
@@ -59,46 +61,52 @@ const RadialChart = ({
|
|
|
59
61
|
/* @__PURE__ */ jsx("span", { className: `${baseClass}__summary-value`, children: typeof item.value === "number" ? item.value.toLocaleString() : item.value })
|
|
60
62
|
] }, i)) })
|
|
61
63
|
] }),
|
|
62
|
-
/* @__PURE__ */
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
64
|
+
/* @__PURE__ */ jsxs("div", { className: `${baseClass}__body`, children: [
|
|
65
|
+
/* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height, children: /* @__PURE__ */ jsxs(
|
|
66
|
+
RadialBarChart,
|
|
67
|
+
{
|
|
68
|
+
cx: "50%",
|
|
69
|
+
cy: "50%",
|
|
70
|
+
innerRadius,
|
|
71
|
+
outerRadius,
|
|
72
|
+
data: chartData,
|
|
73
|
+
startAngle: 90,
|
|
74
|
+
endAngle: -270,
|
|
75
|
+
barSize: 16,
|
|
76
|
+
children: [
|
|
77
|
+
/* @__PURE__ */ jsx(PolarAngleAxis, { type: "number", domain: [0, maxValue], tick: false }),
|
|
78
|
+
/* @__PURE__ */ jsx(
|
|
79
|
+
RadialBar,
|
|
80
|
+
{
|
|
81
|
+
background: { fill: bgColor },
|
|
82
|
+
dataKey: "value",
|
|
83
|
+
cornerRadius: 8
|
|
84
|
+
}
|
|
85
|
+
),
|
|
86
|
+
/* @__PURE__ */ jsx(Tooltip, { content: renderTooltip }),
|
|
87
|
+
showLegend && /* @__PURE__ */ jsx(
|
|
88
|
+
Legend,
|
|
89
|
+
{
|
|
90
|
+
verticalAlign: "bottom",
|
|
91
|
+
iconType: "circle",
|
|
92
|
+
iconSize: 8,
|
|
93
|
+
...{ payload: chartData.map((d) => ({
|
|
94
|
+
value: d.name,
|
|
95
|
+
type: "circle",
|
|
96
|
+
color: d.fill
|
|
97
|
+
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
|
98
|
+
})) },
|
|
99
|
+
formatter: (value) => /* @__PURE__ */ jsx("span", { style: { color: textSecondary, fontSize: 12 }, children: value })
|
|
100
|
+
}
|
|
101
|
+
)
|
|
102
|
+
]
|
|
103
|
+
}
|
|
104
|
+
) }),
|
|
105
|
+
centerLabel && /* @__PURE__ */ jsxs("div", { className: `${baseClass}__radial-center`, children: [
|
|
106
|
+
/* @__PURE__ */ jsx("span", { className: `${baseClass}__radial-center-value`, children: centerLabel }),
|
|
107
|
+
centerSublabel && /* @__PURE__ */ jsx("span", { className: `${baseClass}__radial-center-sub`, children: centerSublabel })
|
|
108
|
+
] })
|
|
109
|
+
] })
|
|
102
110
|
] });
|
|
103
111
|
};
|
|
104
112
|
export {
|
|
@@ -26,6 +26,8 @@ export interface ScatterChartProps {
|
|
|
26
26
|
summaryItems?: ChartSummaryItem[];
|
|
27
27
|
/** Chart area height in pixels */
|
|
28
28
|
height?: number;
|
|
29
|
+
/** Strip the card chrome (border, padding, fill) when the chart sits inside another panel that supplies the surface */
|
|
30
|
+
bare?: boolean;
|
|
29
31
|
/** Additional CSS classes on the wrapper */
|
|
30
32
|
className?: string;
|
|
31
33
|
}
|
|
@@ -33,4 +35,4 @@ export interface ScatterChartProps {
|
|
|
33
35
|
* Scatter chart built on Recharts with design-system tokens.
|
|
34
36
|
* Plots one or more datasets as point clouds on an X/Y grid.
|
|
35
37
|
*/
|
|
36
|
-
export declare const ScatterChart: ({ datasets, xKey, yKey, xLabel, yLabel, title, subtitle, summaryItems, height, className, }: ScatterChartProps) => import("react").JSX.Element;
|
|
38
|
+
export declare const ScatterChart: ({ datasets, xKey, yKey, xLabel, yLabel, title, subtitle, summaryItems, height, bare, className, }: ScatterChartProps) => import("react").JSX.Element;
|
|
@@ -4,8 +4,7 @@ import { ResponsiveContainer, ScatterChart as ScatterChart$1, CartesianGrid, XAx
|
|
|
4
4
|
import { getChartSeriesColors } from "./palette.js";
|
|
5
5
|
import "./Chart.css";
|
|
6
6
|
function getCSSVar(name, fallback) {
|
|
7
|
-
|
|
8
|
-
return getComputedStyle(document.documentElement).getPropertyValue(name).trim() || fallback;
|
|
7
|
+
return `var(${name}, ${fallback})`;
|
|
9
8
|
}
|
|
10
9
|
function ScatterTooltip({ active, payload, xLabel, yLabel }) {
|
|
11
10
|
if (!active || !payload?.length) return null;
|
|
@@ -32,10 +31,11 @@ const ScatterChart = ({
|
|
|
32
31
|
subtitle,
|
|
33
32
|
summaryItems,
|
|
34
33
|
height = 350,
|
|
34
|
+
bare = false,
|
|
35
35
|
className = ""
|
|
36
36
|
}) => {
|
|
37
37
|
const baseClass = "ds-chart";
|
|
38
|
-
const classes = [baseClass, className].filter(Boolean).join(" ");
|
|
38
|
+
const classes = [baseClass, bare ? `${baseClass}--bare` : "", className].filter(Boolean).join(" ");
|
|
39
39
|
const seriesColors = getChartSeriesColors();
|
|
40
40
|
const textSecondary = getCSSVar("--color-text-secondary", "#A2A2A2");
|
|
41
41
|
const gridColor = getCSSVar("--color-divider", "#232323");
|
|
@@ -24,6 +24,8 @@ export interface StackedBarChartProps {
|
|
|
24
24
|
height?: number;
|
|
25
25
|
/** Y-axis tick formatter */
|
|
26
26
|
yAxisFormatter?: (value: number) => string;
|
|
27
|
+
/** Strip the card chrome (border, padding, fill) when the chart sits inside another panel that supplies the surface */
|
|
28
|
+
bare?: boolean;
|
|
27
29
|
/** Additional CSS classes on the wrapper */
|
|
28
30
|
className?: string;
|
|
29
31
|
}
|
|
@@ -31,4 +33,4 @@ export interface StackedBarChartProps {
|
|
|
31
33
|
* Stacked bar chart built on Recharts with design-system tokens.
|
|
32
34
|
* Supports multiple series stacked on top of each other.
|
|
33
35
|
*/
|
|
34
|
-
export declare const StackedBarChart: ({ data, xKey, series, title, subtitle, summaryItems, height, yAxisFormatter, className, }: StackedBarChartProps) => import("react").JSX.Element;
|
|
36
|
+
export declare const StackedBarChart: ({ data, xKey, series, title, subtitle, summaryItems, height, yAxisFormatter, bare, className, }: StackedBarChartProps) => import("react").JSX.Element;
|
|
@@ -4,8 +4,7 @@ import { ResponsiveContainer, BarChart, CartesianGrid, XAxis, YAxis, Tooltip, Ba
|
|
|
4
4
|
import { getChartSeriesColors } from "./palette.js";
|
|
5
5
|
import "./Chart.css";
|
|
6
6
|
function getCSSVar(name, fallback) {
|
|
7
|
-
|
|
8
|
-
return getComputedStyle(document.documentElement).getPropertyValue(name).trim() || fallback;
|
|
7
|
+
return `var(${name}, ${fallback})`;
|
|
9
8
|
}
|
|
10
9
|
function StackedTooltip({ active, payload, label }) {
|
|
11
10
|
if (!active || !payload?.length) return null;
|
|
@@ -27,10 +26,11 @@ const StackedBarChart = ({
|
|
|
27
26
|
summaryItems,
|
|
28
27
|
height = 350,
|
|
29
28
|
yAxisFormatter,
|
|
29
|
+
bare = false,
|
|
30
30
|
className = ""
|
|
31
31
|
}) => {
|
|
32
32
|
const baseClass = "ds-chart";
|
|
33
|
-
const classes = [baseClass, className].filter(Boolean).join(" ");
|
|
33
|
+
const classes = [baseClass, bare ? `${baseClass}--bare` : "", className].filter(Boolean).join(" ");
|
|
34
34
|
const textSecondary = getCSSVar("--color-text-secondary", "#A2A2A2");
|
|
35
35
|
const gridColor = getCSSVar("--color-divider", "#232323");
|
|
36
36
|
const cursorColor = getCSSVar("--color-bg-container-secondary", "#303030");
|
|
@@ -23,6 +23,8 @@ export interface TreemapProps {
|
|
|
23
23
|
summaryItems?: ChartSummaryItem[];
|
|
24
24
|
/** Chart area height in pixels */
|
|
25
25
|
height?: number;
|
|
26
|
+
/** Strip the card chrome (border, padding, fill) when the chart sits inside another panel that supplies the surface */
|
|
27
|
+
bare?: boolean;
|
|
26
28
|
/** Additional CSS classes on the wrapper */
|
|
27
29
|
className?: string;
|
|
28
30
|
}
|
|
@@ -30,4 +32,4 @@ export interface TreemapProps {
|
|
|
30
32
|
* Treemap chart built on Recharts with design-system tokens.
|
|
31
33
|
* Displays hierarchical data as nested coloured rectangles sized by value.
|
|
32
34
|
*/
|
|
33
|
-
export declare const Treemap: ({ data, dataKey, title, subtitle, summaryItems, height, className, }: TreemapProps) => import("react").JSX.Element;
|
|
35
|
+
export declare const Treemap: ({ data, dataKey, title, subtitle, summaryItems, height, bare, className, }: TreemapProps) => import("react").JSX.Element;
|
|
@@ -4,8 +4,7 @@ import { ResponsiveContainer, Treemap as Treemap$1, Tooltip } from "recharts";
|
|
|
4
4
|
import { getChartSeriesColors } from "./palette.js";
|
|
5
5
|
import "./Chart.css";
|
|
6
6
|
function getCSSVar(name, fallback) {
|
|
7
|
-
|
|
8
|
-
return getComputedStyle(document.documentElement).getPropertyValue(name).trim() || fallback;
|
|
7
|
+
return `var(${name}, ${fallback})`;
|
|
9
8
|
}
|
|
10
9
|
function TreemapContent(props) {
|
|
11
10
|
const { x, y, width, height, name, index, color } = props;
|
|
@@ -58,10 +57,11 @@ const Treemap = ({
|
|
|
58
57
|
subtitle,
|
|
59
58
|
summaryItems,
|
|
60
59
|
height = 350,
|
|
60
|
+
bare = false,
|
|
61
61
|
className = ""
|
|
62
62
|
}) => {
|
|
63
63
|
const baseClass = "ds-chart";
|
|
64
|
-
const classes = [baseClass, className].filter(Boolean).join(" ");
|
|
64
|
+
const classes = [baseClass, bare ? `${baseClass}--bare` : "", className].filter(Boolean).join(" ");
|
|
65
65
|
const renderTooltip = useCallback(
|
|
66
66
|
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
|
67
67
|
(props) => /* @__PURE__ */ jsx(TreemapTooltip, { ...props }),
|
|
@@ -8,10 +8,8 @@ const SERIES_FALLBACKS = [
|
|
|
8
8
|
"#1E47B0"
|
|
9
9
|
];
|
|
10
10
|
function getChartSeriesColors() {
|
|
11
|
-
if (typeof window === "undefined") return SERIES_FALLBACKS;
|
|
12
|
-
const style = getComputedStyle(document.documentElement);
|
|
13
11
|
return SERIES_FALLBACKS.map(
|
|
14
|
-
(fallback, i) =>
|
|
12
|
+
(fallback, i) => `var(--color-chart-series-${i + 1}, ${fallback})`
|
|
15
13
|
);
|
|
16
14
|
}
|
|
17
15
|
export {
|