gridsmith-ui 0.17.2 → 0.17.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/charts.js CHANGED
@@ -1,9 +1,10 @@
1
1
  import { Skeleton } from './chunk-Z63OSN64.js';
2
2
  import { mergeRefs } from './chunk-7Q46JXSK.js';
3
3
  import { cn, GLASS_SURFACE } from './chunk-4KVFH5KC.js';
4
- import { createContext, forwardRef, useRef, useId, useContext, useMemo, useState, useEffect, useSyncExternalStore, useLayoutEffect } from 'react';
5
- import { ResponsiveContainer, BarChart as BarChart$1, CartesianGrid, XAxis, YAxis, Tooltip, Legend, Bar, LineChart as LineChart$1, Line, AreaChart as AreaChart$1, Area, PieChart as PieChart$1, Pie, Cell, ComposedChart, ScatterChart as ScatterChart$1, ZAxis, Scatter, RadarChart as RadarChart$1, PolarGrid, PolarAngleAxis, PolarRadiusAxis, Radar, RadialBarChart as RadialBarChart$1, RadialBar, FunnelChart as FunnelChart$1, Funnel, LabelList, Treemap, Sankey, Text, Rectangle } from 'recharts';
6
- import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
+ import { createContext, forwardRef, useContext, useRef, useState, useMemo, useLayoutEffect, useEffect, useId, useSyncExternalStore, Children, isValidElement } from 'react';
5
+ import { ResponsiveContainer, BarChart as BarChart$1, CartesianGrid, XAxis, YAxis, Tooltip, Bar, LineChart as LineChart$1, Line, AreaChart as AreaChart$1, Area, PieChart as PieChart$1, Pie, Cell, ComposedChart, ScatterChart as ScatterChart$1, ZAxis, Scatter, RadarChart as RadarChart$1, PolarGrid, PolarAngleAxis, PolarRadiusAxis, Radar, RadialBarChart as RadialBarChart$1, RadialBar, FunnelChart as FunnelChart$1, Funnel, LabelList, Treemap, Sankey, Text, Legend, Rectangle } from 'recharts';
6
+ import { createPortal } from 'react-dom';
7
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
7
8
 
8
9
  var CHART_TOKENS = [
9
10
  "--ds-chart-1",
@@ -129,14 +130,415 @@ var useChartAnimation = (animated) => {
129
130
  const reduced = useReducedMotion();
130
131
  return animated !== false && !reduced;
131
132
  };
133
+
134
+ // ../../showcase/src/lib/chart-categories.ts
135
+ var ENGLISH_MONTHS = [
136
+ "january",
137
+ "february",
138
+ "march",
139
+ "april",
140
+ "may",
141
+ "june",
142
+ "july",
143
+ "august",
144
+ "september",
145
+ "october",
146
+ "november",
147
+ "december",
148
+ "jan",
149
+ "feb",
150
+ "mar",
151
+ "apr",
152
+ "jun",
153
+ "jul",
154
+ "aug",
155
+ "sep",
156
+ "sept",
157
+ "oct",
158
+ "nov",
159
+ "dec"
160
+ ];
161
+ var ENGLISH_WEEKDAYS = [
162
+ "monday",
163
+ "tuesday",
164
+ "wednesday",
165
+ "thursday",
166
+ "friday",
167
+ "saturday",
168
+ "sunday",
169
+ "mon",
170
+ "tue",
171
+ "tues",
172
+ "wed",
173
+ "thu",
174
+ "thur",
175
+ "thurs",
176
+ "fri",
177
+ "sat",
178
+ "sun"
179
+ ];
180
+ var escape = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
181
+ var clean = (s) => s.trim().toLowerCase().replace(/\.$/, "");
182
+ function intlNames(locale, kind) {
183
+ const out = [];
184
+ try {
185
+ for (const width of ["short", "long"]) {
186
+ const fmt = new Intl.DateTimeFormat(locale, kind === "month" ? { month: width, timeZone: "UTC" } : { weekday: width, timeZone: "UTC" });
187
+ const count = kind === "month" ? 12 : 7;
188
+ for (let i = 0; i < count; i++) {
189
+ const date = kind === "month" ? new Date(Date.UTC(2026, i, 15)) : new Date(Date.UTC(2026, 0, 5 + i));
190
+ out.push(clean(fmt.format(date)));
191
+ }
192
+ }
193
+ } catch {
194
+ }
195
+ return out;
196
+ }
197
+ function locales() {
198
+ const out = /* @__PURE__ */ new Set(["en"]);
199
+ try {
200
+ out.add(new Intl.DateTimeFormat().resolvedOptions().locale);
201
+ } catch {
202
+ }
203
+ if (typeof navigator !== "undefined" && navigator.language) out.add(navigator.language);
204
+ if (typeof document !== "undefined" && document.documentElement?.lang) out.add(document.documentElement.lang);
205
+ return [...out];
206
+ }
207
+ var cached = null;
208
+ function patterns() {
209
+ const tags = locales();
210
+ const key = tags.join("|");
211
+ if (cached?.key === key) return cached;
212
+ const months = new Set(ENGLISH_MONTHS);
213
+ const weekdays = new Set(ENGLISH_WEEKDAYS);
214
+ for (const tag of tags) {
215
+ for (const m of intlNames(tag, "month")) if (m) months.add(m);
216
+ for (const d of intlNames(tag, "weekday")) if (d) weekdays.add(d);
217
+ }
218
+ const alt = (set) => [...set].sort((a, b) => b.length - a.length).map(escape).join("|");
219
+ const M = `(?:${alt(months)})\\.?`;
220
+ const D = `(?:${alt(weekdays)})\\.?`;
221
+ const day = String.raw`\d{1,2}(?:st|nd|rd|th|\.)?`;
222
+ const year = String.raw`'?\d{2,4}`;
223
+ const list = [
224
+ // dates in digits: 2026-09-21, 21/09, 09/21/2026, 21.09.2026, an ISO date-time
225
+ /^\d{4}[-/.]\d{1,2}(?:[-/.]\d{1,2})?$/,
226
+ /^\d{1,2}[-/.]\d{1,2}(?:[-/.]\d{2,4})?$/,
227
+ /^\d{4}-\d{2}-\d{2}[T ]\d{1,2}:\d{2}(?::\d{2}(?:\.\d+)?)?(?:Z|[+-]\d{2}:?\d{2})?$/,
228
+ // a day and a month in either order, and a month alone or with its year: 16 Sep, 21. Sept., Sept 21, March 2026
229
+ new RegExp(`^${day}\\s*${M}(?:,?\\s+${year})?$`, "iu"),
230
+ new RegExp(`^${M}\\s*${day}(?:,?\\s+${year})?$`, "iu"),
231
+ new RegExp(`^${M}(?:\\s*${year})?$`, "iu"),
232
+ // CJK dates: 9月21日, 2026年9月, 9월 21일
233
+ /^(?:\d{4}年)?\d{1,2}月(?:\d{1,2}日)?$/u,
234
+ /^\d{4}年(?:\d{1,2}月)?$/u,
235
+ /^(?:\d{4}년\s?)?\d{1,2}월(?:\s?\d{1,2}일)?$/u,
236
+ // a quarter or a half: Q3, Q3 2026, Q3 FY26, 2026 Q3, 3Q26, H1 2026
237
+ /^Q[1-4](?:\s*[-/']?\s*(?:FY\s?)?'?\d{2,4})?$/i,
238
+ /^[1-4]Q\s*'?\d{0,4}$/i,
239
+ /^(?:FY\s?)?'?\d{2,4}\s*[-/]?\s*Q[1-4]$/i,
240
+ /^H[12](?:\s*'?\d{2,4})?$/i,
241
+ // a year or a fiscal year: 2026, FY26, FY 2025/26, 2025/26, 2025-2026
242
+ /^(?:19|20)\d{2}$/,
243
+ /^FY\s?'?\d{2,4}(?:\s?[-/]\s?'?\d{2,4})?$/i,
244
+ /^(?:19|20)\d{2}\s?[-/–]\s?(?:(?:19|20)?\d{2})$/,
245
+ // a week: W12, Wk 3, Week 12, Week 12 2026, 2026-W12
246
+ /^(?:W|Wk|Week)\.?\s?\d{1,2}(?:\s*[,/-]?\s*\d{4})?$/i,
247
+ /^\d{4}-?W\d{1,2}(?:-?\d)?$/i,
248
+ // a weekday: Mon, Tuesday, and the runtime and page locales' own
249
+ new RegExp(`^${D}$`, "iu"),
250
+ // a time: 09:00, 9:30 pm, 9am, 14h
251
+ /^\d{1,2}:\d{2}(?::\d{2})?\s?(?:[ap]\.?m\.?)?$/i,
252
+ /^\d{1,2}\s?[ap]\.?m\.?$/i,
253
+ /^\d{1,2}h(?:\d{2})?$/i,
254
+ // a number, a percentage or an amount: 12, -3.5, 1,200, 12%, $5k, €1.2m, 5 €, a bin (10–20, <10, 50+)
255
+ /^[<>≤≥~]?\s?[+\-−]?\s?[$€£¥₹]?\s?\d[\d,. \u00a0\u202f]*(?:\s?(?:k|m|mn|bn|b|t))?\s?(?:%|[$€£¥₹])?\+?$/iu,
256
+ /^[$€£¥₹]?\d[\d,.]*\s?[-–]\s?[$€£¥₹]?\d[\d,.]*\s?(?:k|m|bn|%)?$/iu
257
+ ];
258
+ cached = { key, list };
259
+ return cached;
260
+ }
261
+ function categoryKind(labels) {
262
+ const { list } = patterns();
263
+ for (const raw of labels) {
264
+ if (raw == null) continue;
265
+ if (typeof raw === "number") {
266
+ if (Number.isFinite(raw)) continue;
267
+ return "names";
268
+ }
269
+ if (raw instanceof Date) continue;
270
+ const text = String(raw).trim();
271
+ if (!text) continue;
272
+ if (!list.some((re) => re.test(text))) return "names";
273
+ }
274
+ return "scale";
275
+ }
276
+ function resolvedAxisFont(el) {
277
+ const doc = el.ownerDocument;
278
+ const view = doc.defaultView;
279
+ let probe = el.querySelector("[data-chart-probe]");
280
+ let temporary = false;
281
+ if (!probe) {
282
+ probe = doc.createElement("span");
283
+ probe.setAttribute("aria-hidden", "true");
284
+ probe.style.cssText = "position:absolute;visibility:hidden;pointer-events:none;white-space:nowrap;font-size:var(--ds-font-size-xs);font-family:var(--ds-font-sans)";
285
+ el.appendChild(probe);
286
+ temporary = true;
287
+ }
288
+ const cs = view?.getComputedStyle(probe);
289
+ const px = parseFloat(cs?.fontSize ?? "") || 12;
290
+ const family = (cs?.fontFamily ?? "").trim() || "sans-serif";
291
+ const style = cs?.fontStyle && cs.fontStyle !== "normal" ? `${cs.fontStyle} ` : "";
292
+ const weight = cs?.fontWeight && cs.fontWeight !== "400" && cs.fontWeight !== "normal" ? `${cs.fontWeight} ` : "";
293
+ if (temporary) probe.remove();
294
+ return { font: `${style}${weight}${px}px ${family}`, px };
295
+ }
296
+ var shared = null;
297
+ function canvasContext() {
298
+ if (typeof document === "undefined") return null;
299
+ const getContext = globalThis.HTMLCanvasElement?.prototype.getContext;
300
+ if (shared && shared.getContext === getContext) return shared.ctx;
301
+ let ctx = null;
302
+ try {
303
+ ctx = document.createElement("canvas").getContext?.("2d") ?? null;
304
+ } catch {
305
+ ctx = null;
306
+ }
307
+ shared = { getContext, ctx };
308
+ return ctx;
309
+ }
310
+ function createAxisMeasurer(el) {
311
+ const ctx = canvasContext();
312
+ if (!ctx) return null;
313
+ const { font, px } = resolvedAxisFont(el);
314
+ ctx.font = font;
315
+ const widths = /* @__PURE__ */ new Map();
316
+ const measure = (text) => {
317
+ let w = widths.get(text);
318
+ if (w === void 0) {
319
+ ctx.font = font;
320
+ w = ctx.measureText(text).width;
321
+ widths.set(text, w);
322
+ }
323
+ return w;
324
+ };
325
+ return { measure, px, font };
326
+ }
327
+ var ELLIPSIS = "\u2026";
328
+ var letters = (s) => s.replace(/\s+/g, "").replace(/…/g, "").length;
329
+ function prefixThatFits(text, width, measure, suffix = "") {
330
+ let lo = 1;
331
+ let hi = text.length;
332
+ let best = 0;
333
+ while (lo <= hi) {
334
+ const mid = lo + hi >> 1;
335
+ if (measure(text.slice(0, mid).trimEnd() + suffix) <= width) {
336
+ best = mid;
337
+ lo = mid + 1;
338
+ } else hi = mid - 1;
339
+ }
340
+ return best;
341
+ }
342
+ function fitLabel(name, width, measure) {
343
+ const text = name.replace(/\s+/g, " ").trim();
344
+ if (!measure || !text || width <= 0 || measure(text) <= width) return { lines: [text], cut: false, shown: letters(text) };
345
+ const words = text.split(" ");
346
+ let first = "";
347
+ let firstShown = "";
348
+ let rest = "";
349
+ for (let i = words.length - 1; i >= 1; i--) {
350
+ const candidate = words.slice(0, i).join(" ");
351
+ if (measure(candidate) <= width) {
352
+ first = firstShown = candidate;
353
+ rest = words.slice(i).join(" ");
354
+ break;
355
+ }
356
+ }
357
+ if (!first) {
358
+ const k2 = Math.max(1, prefixThatFits(text, width, measure, "-"));
359
+ firstShown = text.slice(0, k2).trimEnd();
360
+ rest = text.slice(k2).trimStart();
361
+ first = rest && !text.slice(k2 - 1, k2 + 1).includes(" ") ? `${firstShown}-` : firstShown;
362
+ }
363
+ if (!rest) return { lines: [first], cut: false, shown: letters(firstShown) };
364
+ if (measure(rest) <= width) return { lines: [first, rest], cut: false, shown: letters(firstShown) + letters(rest) };
365
+ const k = prefixThatFits(rest, width, measure, ELLIPSIS);
366
+ const kept = k > 0 ? rest.slice(0, k).trimEnd() : "";
367
+ return { lines: [first, kept + ELLIPSIS], cut: true, shown: letters(firstShown) + letters(kept) };
368
+ }
369
+ var MIN_NAME_CHARS = 6;
370
+ function namesCutShort(names, width, measure) {
371
+ return names.some((n) => {
372
+ const fit = fitLabel(n, width, measure);
373
+ return fit.cut && fit.shown < MIN_NAME_CHARS;
374
+ });
375
+ }
376
+ var CHART_HEIGHTS = {
377
+ sm: "var(--ds-chart-height-sm)",
378
+ md: "var(--ds-chart-height-md)",
379
+ lg: "var(--ds-chart-height-lg)"
380
+ };
381
+ var CHART_ROW = "var(--ds-chart-row, 2rem)";
382
+ function fixedChartHeight(height) {
383
+ if (typeof height === "number") return `${height}px`;
384
+ if (height === "sm" || height === "md" || height === "lg") return CHART_HEIGHTS[height];
385
+ return void 0;
386
+ }
387
+ var SM = CHART_HEIGHTS.sm;
388
+ var LG = CHART_HEIGHTS.lg;
389
+ function plotBoxStyle(size, fixed) {
390
+ if (size.model === "square") {
391
+ return { height: fixed ?? `clamp(${SM}, 100cqi, ${LG})`, flex: "0 0 auto" };
392
+ }
393
+ if (size.model === "rows") {
394
+ const lines = size.lines ? ` + ${size.lines} * 1.25 * var(--ds-font-size-xs)` : "";
395
+ const height = fixed ?? `max(${SM}, calc(${size.units} * ${CHART_ROW}${lines} + ${size.axis ?? CHART_ROW}))`;
396
+ return { height, maxHeight: `calc(2 * ${height})`, flex: "1 0 auto" };
397
+ }
398
+ return { height: fixed ?? `clamp(${SM}, 50cqi, ${LG})`, maxHeight: `max(${fixed ?? LG}, 100cqi)`, flex: "1 0 auto" };
399
+ }
400
+ var CHART_MARK = /* @__PURE__ */ Symbol.for("gridsmith.Chart");
401
+ function markChart(component) {
402
+ Object.assign(component, { [CHART_MARK]: true });
403
+ return component;
404
+ }
405
+ function isLibraryChart(children) {
406
+ const kids = Children.toArray(children);
407
+ if (kids.length !== 1) return false;
408
+ const only = kids[0];
409
+ if (!isValidElement(only)) return false;
410
+ const type = only.type;
411
+ return !!type && typeof type !== "string" && type[CHART_MARK] === true;
412
+ }
413
+ var ChartContainerContext = createContext(null);
414
+ function useInsideChartContainer() {
415
+ return useContext(ChartContainerContext) !== null;
416
+ }
417
+ var ChartFrameContext = createContext({ legend: null, live: null });
418
+ var REMAPPED = /* @__PURE__ */ new WeakSet();
419
+ function remapRowKeys(e) {
420
+ if (REMAPPED.has(e.nativeEvent)) return;
421
+ const next = e.key === "ArrowDown" || e.key === "ArrowRight";
422
+ const previous = e.key === "ArrowUp" || e.key === "ArrowLeft";
423
+ if (!next && !previous) return;
424
+ const target = e.target;
425
+ if (!target.closest?.(".recharts-wrapper")) return;
426
+ e.preventDefault();
427
+ e.stopPropagation();
428
+ const View = target.ownerDocument.defaultView ?? window;
429
+ const event = new View.KeyboardEvent("keydown", { key: next ? "ArrowLeft" : "ArrowRight", bubbles: true, cancelable: true });
430
+ REMAPPED.add(event);
431
+ target.dispatchEvent(event);
432
+ }
433
+ var ChartWrapper = forwardRef(function ChartWrapper2({
434
+ height = "auto",
435
+ size,
436
+ chart,
437
+ categoryKind: categoryKind2,
438
+ categories,
439
+ categoryAxis,
440
+ sideways = false,
441
+ axisTitle,
442
+ className,
443
+ children,
444
+ "aria-label": ariaLabel
445
+ }, ref) {
446
+ const container = useContext(ChartContainerContext);
447
+ const rootRef = useRef(null);
448
+ const plotRef = useRef(null);
449
+ const [legend, setLegend] = useState(null);
450
+ const [live, setLive] = useState(null);
451
+ const frame = useMemo(() => ({ legend, live }), [legend, live]);
452
+ const [drawn, setDrawn] = useState(null);
453
+ useLayoutEffect(() => {
454
+ const plot = plotRef.current;
455
+ if (!plot || typeof ResizeObserver === "undefined") return;
456
+ const observer = new ResizeObserver((entries) => {
457
+ const box = entries[entries.length - 1]?.contentRect;
458
+ if (!box || box.width <= 0 || box.height <= 0) return;
459
+ setDrawn((prev) => prev && Math.abs(prev.width - box.width) < 0.5 && Math.abs(prev.height - box.height) < 0.5 ? prev : { width: box.width, height: box.height });
460
+ });
461
+ observer.observe(plot);
462
+ return () => observer.disconnect();
463
+ }, []);
464
+ const fill = container?.fillArea === true;
465
+ const fixed = container?.height ?? fixedChartHeight(height);
466
+ const plotStyle = fill ? { flex: "1 1 0%", minHeight: 0 } : plotBoxStyle(size, fixed);
467
+ const named = ariaLabel ? { role: "img", "aria-label": ariaLabel } : container?.titleId ? { role: "img", "aria-labelledby": container.titleId } : {};
468
+ useEffect(() => {
469
+ const root = rootRef.current;
470
+ const plot = plotRef.current;
471
+ if (!root || !plot || !categoryAxis || typeof MutationObserver === "undefined") return;
472
+ const selector = `.recharts-${categoryAxis}Axis-tick-labels .recharts-cartesian-axis-tick-value`;
473
+ const count = () => {
474
+ const labels = Array.from(plot.querySelectorAll(selector)).filter((el) => (el.textContent ?? "").trim() !== "");
475
+ const shown = String(labels.length);
476
+ const cut = String(labels.filter((el) => el.hasAttribute("data-cut")).length);
477
+ if (root.getAttribute("data-labels-shown") !== shown) root.setAttribute("data-labels-shown", shown);
478
+ if (root.getAttribute("data-labels-cut") !== cut) root.setAttribute("data-labels-cut", cut);
479
+ };
480
+ count();
481
+ const observer = new MutationObserver(count);
482
+ observer.observe(plot, { subtree: true, childList: true, characterData: true, attributes: true, attributeFilter: ["data-cut"] });
483
+ return () => observer.disconnect();
484
+ }, [categoryAxis]);
485
+ return /* @__PURE__ */ jsxs(
486
+ "div",
487
+ {
488
+ ref: mergeRefs(ref, rootRef),
489
+ "data-gs-chart": chart,
490
+ "data-category-kind": categoryKind2,
491
+ "data-categories": categories,
492
+ className: cn("relative flex w-full flex-col", fill && "h-full", className),
493
+ style: { containerType: "inline-size", minInlineSize: "min(100%, 16rem)", ...fill ? {} : { flex: "1 0 auto" } },
494
+ children: [
495
+ /* @__PURE__ */ jsxs(
496
+ "div",
497
+ {
498
+ ref: plotRef,
499
+ "data-chart-plot": "",
500
+ className: "relative w-full",
501
+ style: plotStyle,
502
+ onKeyDownCapture: sideways ? remapRowKeys : void 0,
503
+ ...named,
504
+ children: [
505
+ axisTitle && /* @__PURE__ */ jsx("span", { "data-chart-axis-title": "", className: "absolute left-0 top-0 whitespace-nowrap text-xs text-[var(--ds-text-muted)] font-[family-name:var(--ds-font-sans)] leading-normal", children: axisTitle }),
506
+ /* @__PURE__ */ jsx("div", { className: "absolute inset-0", style: drawn ? { minWidth: drawn.width, minHeight: drawn.height } : void 0, children: /* @__PURE__ */ jsx(ChartFrameContext.Provider, { value: frame, children }) })
507
+ ]
508
+ }
509
+ ),
510
+ /* @__PURE__ */ jsx("div", { ref: setLegend, "data-chart-legend": "" }),
511
+ /* @__PURE__ */ jsx("div", { ref: setLive, role: "status", "aria-live": "polite", className: "sr-only" }),
512
+ /* @__PURE__ */ jsx(
513
+ "span",
514
+ {
515
+ "data-chart-probe": "",
516
+ "aria-hidden": "true",
517
+ className: "pointer-events-none invisible absolute left-0 top-0",
518
+ style: { fontSize: "var(--ds-font-size-xs)", fontFamily: "var(--ds-font-sans)", height: CHART_ROW, width: 0 }
519
+ }
520
+ )
521
+ ]
522
+ }
523
+ );
524
+ });
525
+ var hasLabel = (label) => label != null && label !== "" && typeof label !== "number";
526
+ var entryName = (entry, label) => !hasLabel(label) && typeof entry.payload?.name === "string" && entry.payload.name || entry.name;
527
+ var entryValue = (entry) => typeof entry.value === "number" ? entry.value.toLocaleString() : entry.value;
528
+ function tooltipAnnouncement(label, payload) {
529
+ if (!payload?.length) return "";
530
+ const values = payload.map((entry) => `${entryName(entry, label)} ${entryValue(entry)}`).join(", ");
531
+ return hasLabel(label) ? `${String(label)}: ${values}` : values;
532
+ }
132
533
  function ChartTooltipContent({ active, payload, label }) {
133
534
  const bgSurface = useResolvedToken("--ds-bg-surface");
134
535
  const borderSubtle = useResolvedToken("--ds-border-subtle");
135
536
  const textPrimary = useResolvedToken("--ds-text-primary");
136
537
  const textSecondary = useResolvedToken("--ds-text-secondary");
137
- if (!active || !payload?.length) return null;
138
- const showLabel = label != null && label !== "" && typeof label !== "number";
139
- return /* @__PURE__ */ jsxs(
538
+ const { live } = useContext(ChartFrameContext);
539
+ const on = !!active && !!payload?.length;
540
+ const showLabel = hasLabel(label);
541
+ const box = on ? /* @__PURE__ */ jsxs(
140
542
  "div",
141
543
  {
142
544
  className: "rounded-[var(--ds-radius-md)] shadow-[var(--ds-shadow-popover)] font-[family-name:var(--ds-font-sans)] text-sm",
@@ -149,7 +551,6 @@ function ChartTooltipContent({ active, payload, label }) {
149
551
  showLabel && /* @__PURE__ */ jsx("p", { className: "font-medium mb-ds-1", style: { color: textPrimary }, children: label }),
150
552
  payload.map((entry, i) => {
151
553
  const dotColor = entry.payload?.fill || entry.color || textSecondary;
152
- const displayName = typeof entry.payload?.name === "string" && entry.payload.name || entry.name;
153
554
  return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-ds-2", style: { marginTop: i > 0 ? 2 : 0 }, children: [
154
555
  /* @__PURE__ */ jsx(
155
556
  "span",
@@ -159,15 +560,22 @@ function ChartTooltipContent({ active, payload, label }) {
159
560
  }
160
561
  ),
161
562
  /* @__PURE__ */ jsxs("span", { style: { color: textSecondary }, children: [
162
- displayName,
563
+ entryName(entry, label),
163
564
  ":"
164
565
  ] }),
165
- /* @__PURE__ */ jsx("span", { className: "tabular-nums", style: { color: textPrimary }, children: typeof entry.value === "number" ? entry.value.toLocaleString() : entry.value })
566
+ /* @__PURE__ */ jsx("span", { className: "tabular-nums", style: { color: textPrimary }, children: entryValue(entry) })
166
567
  ] }, i);
167
568
  })
168
569
  ]
169
570
  }
170
- );
571
+ ) : null;
572
+ if (live) {
573
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
574
+ box,
575
+ createPortal(on ? tooltipAnnouncement(label, payload) : "", live)
576
+ ] });
577
+ }
578
+ return /* @__PURE__ */ jsx("div", { role: "status", "aria-live": "polite", children: box });
171
579
  }
172
580
  function swatchEdge(entry) {
173
581
  const stroke = entry.payload?.stroke;
@@ -187,6 +595,20 @@ function ChartLegendContent({ payload }) {
187
595
  /* @__PURE__ */ jsx("span", { style: { color: textSecondary }, children: entry.value })
188
596
  ] }, i)) });
189
597
  }
598
+ function seriesSorter(order, by = "dataKey") {
599
+ return (item) => {
600
+ const key = by === "dataKey" ? item.dataKey : item.value;
601
+ const i = order.indexOf(String(key));
602
+ return i < 0 ? order.length : i;
603
+ };
604
+ }
605
+ function ChartLegend({ order, by = "dataKey" }) {
606
+ const { legend } = useContext(ChartFrameContext);
607
+ const orderKey = order.join("");
608
+ const sorter = useMemo(() => seriesSorter(order, by), [orderKey, by]);
609
+ if (!legend) return null;
610
+ return /* @__PURE__ */ jsx(Legend, { portal: legend, content: /* @__PURE__ */ jsx(ChartLegendContent, {}), itemSorter: sorter, wrapperStyle: { paddingTop: "var(--ds-space-3)" } });
611
+ }
190
612
  function useGridStroke() {
191
613
  return useResolvedToken("--ds-border-subtle");
192
614
  }
@@ -196,7 +618,11 @@ function useAxisStyle() {
196
618
  tick: {
197
619
  fontSize: "var(--ds-font-size-xs)",
198
620
  fontFamily: "var(--ds-font-sans)",
199
- fill: textMuted
621
+ fill: textMuted,
622
+ // Sprint 25.9: Recharts paints a default tick's text with the axis stroke (#666 unless set), not with fill, so the
623
+ // value axes drew their numbers at about 2.6:1 on dark cards (WCAG 1.4.3 asks 4.5:1). Every axis that spreads this
624
+ // hides its axis and tick lines, so the stroke only colours the text.
625
+ stroke: textMuted
200
626
  }
201
627
  };
202
628
  }
@@ -209,41 +635,113 @@ function xAxisTick(props) {
209
635
  const { x, y, payload, width: _width, visibleTicksCount: _count, ...rest } = props;
210
636
  return /* @__PURE__ */ jsx(Text, { ...rest, x, y, textAnchor: "middle", verticalAnchor: "start", children: payload.value });
211
637
  }
212
- function yAxisTick(props) {
213
- const { x, y, payload, ...rest } = props;
214
- return /* @__PURE__ */ jsx(Text, { ...rest, x, y, textAnchor: "end", verticalAnchor: "middle", width: 200, maxLines: 2, children: payload.value });
638
+ var LINE_EM = 1.2;
639
+ var NAME_GAP = 8;
640
+ var NAME_COLUMN_INSET = 12;
641
+ function namesTick(measure, orientation, column) {
642
+ return function NamesTick(props) {
643
+ const { x, y, payload, width, visibleTicksCount, className, fill, fontSize, fontFamily } = props;
644
+ const name = String(payload?.value ?? "");
645
+ const room = orientation === "x" ? (Number(width) || 0) / Math.max(1, Number(visibleTicksCount) || 1) - NAME_GAP : (column ?? (Number(width) || 0)) - NAME_COLUMN_INSET;
646
+ const fit = fitLabel(name, room, measure);
647
+ const text = { fill, fontSize, fontFamily, stroke: "none" };
648
+ const firstDy = orientation === "x" ? 0.71 : 0.355 - (fit.lines.length - 1) * LINE_EM / 2;
649
+ return /* @__PURE__ */ jsxs("g", { className, "data-cut": fit.cut ? "" : void 0, "data-lines": fit.lines.length, children: [
650
+ /* @__PURE__ */ jsx("title", { children: name }),
651
+ fit.lines.map((line, i) => /* @__PURE__ */ jsx("text", { x, y, dy: `${firstDy + i * LINE_EM}em`, textAnchor: orientation === "x" ? "middle" : "end", ...text, children: line }, i))
652
+ ] });
653
+ };
654
+ }
655
+ function useAxisMeasure(ref, enabled = true) {
656
+ const [state, setState] = useState({ measure: null, px: 12, rowPx: 32, width: 0 });
657
+ useLayoutEffect(() => {
658
+ const el = ref.current;
659
+ if (!enabled || !el) return;
660
+ let live = true;
661
+ let font = "";
662
+ const update = (fresh = false) => {
663
+ if (!live) return;
664
+ const measured = el.clientWidth;
665
+ const probe = el.querySelector("[data-chart-probe]");
666
+ const row = probe?.getBoundingClientRect().height ?? 0;
667
+ const next = createAxisMeasurer(el);
668
+ setState((prev) => {
669
+ const width = measured > 0 ? measured : prev.width;
670
+ const rowPx = row > 0 ? row : prev.rowPx;
671
+ if (!next) return prev.width === width ? prev : { ...prev, width };
672
+ if (!fresh && next.font === font && prev.measure && prev.width === width && prev.rowPx === rowPx) return prev;
673
+ const keep = !fresh && next.font === font && prev.measure;
674
+ font = next.font;
675
+ return { measure: keep ? prev.measure : next.measure, px: next.px, rowPx, width };
676
+ });
677
+ };
678
+ update(true);
679
+ const ro = typeof ResizeObserver !== "undefined" ? new ResizeObserver(() => update()) : null;
680
+ ro?.observe(el);
681
+ const fonts = typeof document !== "undefined" ? document.fonts : void 0;
682
+ const landed = () => update(true);
683
+ fonts?.ready.then(landed, () => {
684
+ });
685
+ fonts?.addEventListener?.("loadingdone", landed);
686
+ return () => {
687
+ live = false;
688
+ ro?.disconnect();
689
+ fonts?.removeEventListener?.("loadingdone", landed);
690
+ };
691
+ }, [ref, enabled]);
692
+ return state;
693
+ }
694
+ function valueAxisWidth(values, measure) {
695
+ const finite = values.filter(Number.isFinite);
696
+ const max = finite.length ? Math.max(...finite.map(Math.abs)) : 0;
697
+ const magnitude = max > 0 ? 10 ** Math.floor(Math.log10(max)) : 1;
698
+ const top = Math.ceil(max / magnitude) * magnitude;
699
+ const negative = finite.some((v) => v < 0) ? "-" : "";
700
+ return Math.ceil(measure(`${negative}${top}`)) + 8;
701
+ }
702
+ var SWITCH_HYSTERESIS = 32;
703
+ function useSidewaysSwitch(enabled, names, m, axisWidth, sideMargins) {
704
+ const [turned, setTurned] = useState(false);
705
+ const key = names.join("");
706
+ const cut = useMemo(() => {
707
+ if (!enabled || !m.measure || m.width <= 0 || names.length === 0) return { here: false, narrower: false };
708
+ const cutAt = (width) => namesCutShort(names, (width - sideMargins - axisWidth) / names.length - NAME_GAP, m.measure);
709
+ return { here: cutAt(m.width), narrower: cutAt(m.width - SWITCH_HYSTERESIS) };
710
+ }, [enabled, key, m.measure, m.width, axisWidth, sideMargins]);
711
+ const decision = turned ? cut.here || cut.narrower : cut.here;
712
+ if (decision !== turned) setTurned(decision);
713
+ return decision;
714
+ }
715
+ function nameColumn(names, m) {
716
+ if (!m.measure || m.width <= 0) return void 0;
717
+ const widest = names.reduce((w, n) => Math.max(w, m.measure(n.replace(/\s+/g, " ").trim())), 0);
718
+ return Math.max(24, Math.min(Math.ceil(widest) + NAME_COLUMN_INSET, Math.floor(m.width / 3)));
215
719
  }
216
- function lengthPx(value, el) {
217
- const v = value.trim();
218
- if (v.endsWith("rem")) return parseFloat(v) * (parseFloat(getComputedStyle(el.ownerDocument.documentElement).fontSize) || 16);
219
- if (v.endsWith("px")) return parseFloat(v);
220
- const n = parseFloat(v);
221
- return Number.isFinite(n) ? n : NaN;
720
+ function twoLineNames(names, column, m) {
721
+ if (!m.measure || column === void 0) return 0;
722
+ return names.filter((n) => fitLabel(n, column - NAME_COLUMN_INSET, m.measure).lines.length > 1).length;
222
723
  }
223
724
  function widestLabel(el, labels) {
224
- if (typeof document === "undefined") return null;
225
- const ctx = document.createElement("canvas").getContext?.("2d");
226
- if (!ctx) return null;
227
- const cs = getComputedStyle(el);
228
- const size = lengthPx(cs.getPropertyValue("--ds-font-size-xs"), el) || 12;
229
- const family = cs.getPropertyValue("--ds-font-sans").trim() || cs.fontFamily || "sans-serif";
230
- ctx.font = `${size}px ${family}`;
231
- return labels.reduce((w, l) => Math.max(w, ctx.measureText(l).width), 0);
725
+ const measurer = createAxisMeasurer(el);
726
+ if (!measurer) return null;
727
+ return labels.reduce((w, l) => Math.max(w, measurer.measure(l)), 0);
232
728
  }
233
729
  var TICK_GAP = 12;
234
730
  var AXIS_RESERVE = 48;
235
- function useCategoryTicks(data, xAxisKey, ref, override) {
731
+ function useCategoryTicks(data, xAxisKey, ref, override, kind = "scale") {
236
732
  const labels = useMemo(() => (data ?? []).map((d) => String(d[xAxisKey] ?? "")), [data, xAxisKey]);
237
733
  const labelsKey = labels.join("");
238
734
  const [ticks, setTicks] = useState(void 0);
239
735
  const [endMargin, setEndMargin] = useState(4);
240
736
  const numeric = typeof override === "number" ? override : void 0;
737
+ const names = kind === "names";
241
738
  useEffect(() => {
242
739
  const el = ref.current;
243
- if (numeric !== void 0 || !el || labels.length === 0) return;
740
+ if (names || numeric !== void 0 || !el || labels.length === 0) return;
244
741
  let live = true;
245
742
  const compute = () => {
246
743
  if (!live) return;
744
+ if (el.clientWidth <= 0) return;
247
745
  const widest = widestLabel(el, labels);
248
746
  const plot = el.clientWidth - AXIS_RESERVE;
249
747
  if (widest == null || plot <= 0) {
@@ -265,33 +763,20 @@ function useCategoryTicks(data, xAxisKey, ref, override) {
265
763
  live = false;
266
764
  ro.disconnect();
267
765
  };
268
- }, [labelsKey, numeric, ref]);
766
+ }, [labelsKey, numeric, names, ref]);
767
+ if (names) return { interval: 0, endMargin: 4 };
269
768
  if (numeric !== void 0) return { interval: numeric, endMargin: 4 };
270
769
  return ticks ? { ticks, interval: 0, endMargin } : { interval: "preserveStartEnd", endMargin: 4 };
271
770
  }
272
- var ChartContainerContext = createContext(false);
273
- function useInsideChartContainer() {
274
- return useContext(ChartContainerContext);
275
- }
276
- var HEIGHT_MAP = {
277
- sm: "var(--ds-chart-height-sm)",
278
- md: "var(--ds-chart-height-md)",
279
- lg: "var(--ds-chart-height-lg)"
280
- };
281
- var ChartWrapper = forwardRef(function ChartWrapper2({ height = "md", className, children, "aria-label": ariaLabel }, ref) {
282
- const insideContainer = useInsideChartContainer();
283
- if (insideContainer) {
284
- return /* @__PURE__ */ jsx("div", { ref, className: cn("h-full w-full", className), ...ariaLabel ? { role: "img", "aria-label": ariaLabel } : {}, children });
285
- }
286
- const heightValue = typeof height === "number" ? `${height}px` : HEIGHT_MAP[height];
287
- return /* @__PURE__ */ jsx("div", { ref, className: cn("w-full", className), style: { height: heightValue }, ...ariaLabel ? { role: "img", "aria-label": ariaLabel } : {}, children });
288
- });
289
771
  function barStackOf(bar, stacked) {
290
772
  return bar.stackId ?? (stacked ? "stack" : void 0);
291
773
  }
292
774
  function anyStack(bars, stacked) {
293
775
  return bars.some((bar) => barStackOf(bar, stacked) != null);
294
776
  }
777
+ function barGroups(bars, stacked) {
778
+ return Math.max(1, new Set(bars.map((bar, i) => barStackOf(bar, stacked) ?? `\0${i}`)).size);
779
+ }
295
780
  function barShape(bars, index, stacked, radius, horizontal = false) {
296
781
  const round = horizontal ? [0, radius, radius, 0] : [radius, radius, 0, 0];
297
782
  const square = [0, 0, 0, 0];
@@ -309,14 +794,31 @@ function barShape(bars, index, stacked, radius, horizontal = false) {
309
794
  };
310
795
  return Shape;
311
796
  }
312
- var BarChart = forwardRef(function BarChart2({
797
+ function valueExtent(data, bars, stacked) {
798
+ return data.flatMap((row) => {
799
+ const own = [];
800
+ const stacks = /* @__PURE__ */ new Map();
801
+ for (const bar of bars) {
802
+ const v = Number(row[bar.dataKey]);
803
+ if (!Number.isFinite(v)) continue;
804
+ const stack = barStackOf(bar, stacked);
805
+ if (stack == null) own.push(v);
806
+ else stacks.set(stack, (stacks.get(stack) ?? 0) + v);
807
+ }
808
+ return [...own, ...stacks.values()];
809
+ });
810
+ }
811
+ var titleLine = (px) => Math.ceil(px * 1.5) + 4;
812
+ var TITLE_LINE_CSS = "calc(1.5 * var(--ds-font-size-xs) + 4px)";
813
+ var BarChart = markChart(forwardRef(function BarChart2({
313
814
  data,
314
815
  bars,
315
816
  xAxisKey,
316
817
  xAxisInterval,
317
- height = "md",
818
+ height = "auto",
318
819
  stacked = false,
319
- horizontal = false,
820
+ horizontal,
821
+ categoryKind: categoryKind2,
320
822
  showGrid = true,
321
823
  showTooltip = true,
322
824
  showLegend,
@@ -327,7 +829,20 @@ var BarChart = forwardRef(function BarChart2({
327
829
  className
328
830
  }, ref) {
329
831
  const wrapperRef = useRef(null);
330
- const xTicks = useCategoryTicks(data, xAxisKey, wrapperRef, horizontal ? xAxisInterval ?? "preserveStartEnd" : xAxisInterval);
832
+ const labels = useMemo(() => (data ?? []).map((d) => String(d[xAxisKey] ?? "")), [data, xAxisKey]);
833
+ const kind = categoryKind2 ?? categoryKind((data ?? []).map((d) => d[xAxisKey]));
834
+ const names = kind === "names";
835
+ const measured = useAxisMeasure(wrapperRef, (data?.length ?? 0) > 0);
836
+ const axisWidth = useMemo(
837
+ () => measured.measure ? valueAxisWidth(valueExtent(data ?? [], bars, stacked), measured.measure) : 0,
838
+ [measured.measure, data, bars, stacked]
839
+ );
840
+ const turned = useSidewaysSwitch(horizontal === void 0 && names, labels, measured, axisWidth, 8);
841
+ const sideways = horizontal ?? turned;
842
+ const xTicks = useCategoryTicks(data, xAxisKey, wrapperRef, xAxisInterval, sideways || names ? "names" : "scale");
843
+ const column = sideways ? nameColumn(labels, measured) : void 0;
844
+ const upright = useMemo(() => namesTick(measured.measure, "x"), [measured.measure]);
845
+ const rows = useMemo(() => namesTick(measured.measure, "y", column), [measured.measure, column]);
331
846
  const solidColors = useChartColors(bars.length, false);
332
847
  const softColors = useChartColors(bars.length, true);
333
848
  const gridStroke = useGridStroke();
@@ -335,94 +850,108 @@ var BarChart = forwardRef(function BarChart2({
335
850
  const isAnimated = useChartAnimation(animated);
336
851
  const radius = useRadius();
337
852
  const legendVisible = showLegend ?? bars.length >= 2;
338
- const layout = horizontal ? "vertical" : "horizontal";
853
+ const valueTitle = horizontal === true ? xAxisLabel : yAxisLabel;
854
+ const categoryTitle = horizontal === true ? yAxisLabel : xAxisLabel;
855
+ const topTitle = sideways ? categoryTitle : valueTitle;
856
+ const bottomTitle = sideways ? valueTitle : categoryTitle;
339
857
  const axisLabelStyle = { fontSize: "var(--ds-font-size-xs)", fontFamily: "var(--ds-font-sans)", fill: axisStyle.tick.fill };
858
+ const bottomLabel = bottomTitle ? { value: bottomTitle, position: "insideBottom", offset: -2, style: axisLabelStyle } : void 0;
859
+ const groups = barGroups(bars, stacked);
860
+ const perCategory = 1 + 0.5 * (groups - 1);
861
+ const titles = [topTitle, bottomTitle].filter(Boolean).length;
862
+ const size = sideways ? {
863
+ model: "rows",
864
+ units: labels.length * perCategory,
865
+ lines: twoLineNames(labels, column, measured),
866
+ axis: titles ? `calc(${CHART_ROW} + ${titles} * ${TITLE_LINE_CSS})` : CHART_ROW
867
+ } : { model: "ratio" };
868
+ const maxBarSize = sideways ? Math.max(4, Math.round(measured.rowPx * perCategory * 0.7 / groups)) : void 0;
340
869
  if (!data?.length) return null;
341
- return /* @__PURE__ */ jsx(ChartWrapper, { ref: mergeRefs(ref, wrapperRef), height, className, "aria-label": ariaLabel, children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(
342
- BarChart$1,
870
+ return /* @__PURE__ */ jsx(
871
+ ChartWrapper,
343
872
  {
344
- data,
345
- layout,
346
- stackOffset: anyStack(bars, stacked) ? "sign" : void 0,
347
- margin: { top: 4, right: xTicks.endMargin, bottom: 4, left: 4 },
348
- accessibilityLayer: true,
349
- children: [
350
- showGrid && /* @__PURE__ */ jsx(CartesianGrid, { strokeDasharray: "3 3", stroke: gridStroke, vertical: !horizontal, horizontal: true }),
351
- horizontal ? /* @__PURE__ */ jsxs(Fragment, { children: [
352
- /* @__PURE__ */ jsx(
353
- XAxis,
354
- {
355
- type: "number",
356
- ...axisStyle.tick,
357
- axisLine: false,
358
- tickLine: false,
359
- label: xAxisLabel ? { value: xAxisLabel, position: "insideBottom", offset: -2, style: axisLabelStyle } : void 0
360
- }
361
- ),
362
- /* @__PURE__ */ jsx(
363
- YAxis,
364
- {
365
- dataKey: xAxisKey,
366
- type: "category",
367
- width: "auto",
368
- ...axisStyle.tick,
369
- axisLine: false,
370
- tickLine: false,
371
- tick: yAxisTick
372
- }
373
- )
374
- ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
375
- /* @__PURE__ */ jsx(
376
- XAxis,
377
- {
378
- dataKey: xAxisKey,
379
- ...axisStyle.tick,
380
- axisLine: false,
381
- tickLine: false,
382
- tick: xAxisTick,
383
- interval: xTicks.interval,
384
- ticks: xTicks.ticks,
385
- height: "auto",
386
- label: xAxisLabel ? { value: xAxisLabel, position: "insideBottom", offset: -2, style: axisLabelStyle } : void 0
387
- }
388
- ),
389
- /* @__PURE__ */ jsx(
390
- YAxis,
391
- {
392
- width: "auto",
393
- ...axisStyle.tick,
394
- axisLine: false,
395
- tickLine: false,
396
- label: yAxisLabel ? { value: yAxisLabel, angle: -90, position: "insideLeft", style: axisLabelStyle } : void 0
397
- }
398
- )
399
- ] }),
400
- showTooltip && /* @__PURE__ */ jsx(Tooltip, { content: /* @__PURE__ */ jsx(ChartTooltipContent, {}), cursor: { fill: "var(--ds-bg-muted)", opacity: 0.5 } }),
401
- legendVisible && /* @__PURE__ */ jsx(Legend, { content: /* @__PURE__ */ jsx(ChartLegendContent, {}), wrapperStyle: { paddingTop: "var(--ds-space-3)" } }),
402
- bars.map((bar, i) => /* @__PURE__ */ jsx(
403
- Bar,
404
- {
405
- dataKey: bar.dataKey,
406
- name: bar.label ?? bar.dataKey,
407
- fill: bar.soft ? softColors[i] : solidColors[i],
408
- stroke: bar.soft ? solidColors[i] : void 0,
409
- strokeWidth: bar.soft ? 1 : void 0,
410
- shape: barShape(bars, i, stacked, radius, horizontal),
411
- stackId: barStackOf(bar, stacked),
412
- isAnimationActive: isAnimated
413
- },
414
- bar.dataKey
415
- ))
416
- ]
873
+ ref: mergeRefs(ref, wrapperRef),
874
+ height,
875
+ size,
876
+ chart: "bar",
877
+ categoryKind: kind,
878
+ categories: data.length,
879
+ categoryAxis: sideways ? "y" : "x",
880
+ sideways,
881
+ axisTitle: topTitle,
882
+ className,
883
+ "aria-label": ariaLabel,
884
+ children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(
885
+ BarChart$1,
886
+ {
887
+ data,
888
+ layout: sideways ? "vertical" : "horizontal",
889
+ stackOffset: anyStack(bars, stacked) ? "sign" : void 0,
890
+ margin: { top: 4 + (topTitle ? titleLine(measured.px) : 0), right: sideways || names ? 4 : xTicks.endMargin, bottom: 4, left: 4 },
891
+ accessibilityLayer: true,
892
+ children: [
893
+ showGrid && /* @__PURE__ */ jsx(CartesianGrid, { strokeDasharray: "3 3", stroke: gridStroke, vertical: !sideways, horizontal: true }),
894
+ sideways ? /* @__PURE__ */ jsxs(Fragment, { children: [
895
+ /* @__PURE__ */ jsx(XAxis, { type: "number", ...axisStyle.tick, axisLine: false, tickLine: false, height: "auto", label: bottomLabel }),
896
+ /* @__PURE__ */ jsx(
897
+ YAxis,
898
+ {
899
+ dataKey: xAxisKey,
900
+ type: "category",
901
+ width: column ?? "auto",
902
+ ...axisStyle.tick,
903
+ axisLine: false,
904
+ tickLine: false,
905
+ interval: 0,
906
+ tick: rows
907
+ }
908
+ )
909
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
910
+ /* @__PURE__ */ jsx(
911
+ XAxis,
912
+ {
913
+ dataKey: xAxisKey,
914
+ ...axisStyle.tick,
915
+ axisLine: false,
916
+ tickLine: false,
917
+ tick: names ? upright : xAxisTick,
918
+ interval: xTicks.interval,
919
+ ticks: xTicks.ticks,
920
+ height: "auto",
921
+ label: bottomLabel
922
+ }
923
+ ),
924
+ /* @__PURE__ */ jsx(YAxis, { width: "auto", ...axisStyle.tick, axisLine: false, tickLine: false })
925
+ ] }),
926
+ showTooltip && /* @__PURE__ */ jsx(Tooltip, { content: /* @__PURE__ */ jsx(ChartTooltipContent, {}), cursor: { fill: "var(--ds-bg-muted)", opacity: 0.5 } }),
927
+ legendVisible && /* @__PURE__ */ jsx(ChartLegend, { order: bars.map((b) => b.dataKey) }),
928
+ bars.map((bar, i) => /* @__PURE__ */ jsx(
929
+ Bar,
930
+ {
931
+ dataKey: bar.dataKey,
932
+ name: bar.label ?? bar.dataKey,
933
+ fill: bar.soft ? softColors[i] : solidColors[i],
934
+ stroke: bar.soft ? solidColors[i] : void 0,
935
+ strokeWidth: bar.soft ? 1 : void 0,
936
+ shape: barShape(bars, i, stacked, radius, sideways),
937
+ stackId: barStackOf(bar, stacked),
938
+ maxBarSize,
939
+ isAnimationActive: isAnimated
940
+ },
941
+ bar.dataKey
942
+ ))
943
+ ]
944
+ }
945
+ ) })
417
946
  }
418
- ) }) });
419
- });
420
- var LineChart = forwardRef(function LineChart2({
947
+ );
948
+ }));
949
+ var LineChart = markChart(forwardRef(function LineChart2({
421
950
  data,
422
951
  lines,
423
952
  xAxisKey,
424
953
  xAxisInterval,
425
- height = "md",
954
+ height = "auto",
426
955
  curved = true,
427
956
  showDots = false,
428
957
  showGrid = true,
@@ -435,65 +964,73 @@ var LineChart = forwardRef(function LineChart2({
435
964
  className
436
965
  }, ref) {
437
966
  const wrapperRef = useRef(null);
438
- const xTicks = useCategoryTicks(data, xAxisKey, wrapperRef, xAxisInterval);
967
+ const xTicks = useCategoryTicks(data, xAxisKey, wrapperRef, xAxisInterval, "scale");
968
+ const measured = useAxisMeasure(wrapperRef, !!yAxisLabel && (data?.length ?? 0) > 0);
439
969
  const colors = useChartColors(lines.length, false);
440
970
  const gridStroke = useGridStroke();
441
971
  const axisStyle = useAxisStyle();
442
972
  const isAnimated = useChartAnimation(animated);
443
973
  const legendVisible = showLegend ?? lines.length >= 2;
444
974
  const axisLabelStyle = { fontSize: "var(--ds-font-size-xs)", fontFamily: "var(--ds-font-sans)", fill: axisStyle.tick.fill };
975
+ const top = 4 + (yAxisLabel ? Math.ceil(measured.px * 1.5) + 4 : 0);
445
976
  if (!data?.length) return null;
446
- return /* @__PURE__ */ jsx(ChartWrapper, { ref: mergeRefs(ref, wrapperRef), height, className, "aria-label": ariaLabel, children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(LineChart$1, { data, margin: { top: 4, right: xTicks.endMargin, bottom: 4, left: 4 }, accessibilityLayer: true, children: [
447
- showGrid && /* @__PURE__ */ jsx(CartesianGrid, { strokeDasharray: "3 3", stroke: gridStroke }),
448
- /* @__PURE__ */ jsx(
449
- XAxis,
450
- {
451
- dataKey: xAxisKey,
452
- ...axisStyle.tick,
453
- axisLine: false,
454
- tickLine: false,
455
- tick: xAxisTick,
456
- interval: xTicks.interval,
457
- ticks: xTicks.ticks,
458
- height: "auto",
459
- label: xAxisLabel ? { value: xAxisLabel, position: "insideBottom", offset: -2, style: axisLabelStyle } : void 0
460
- }
461
- ),
462
- /* @__PURE__ */ jsx(
463
- YAxis,
464
- {
465
- width: "auto",
466
- ...axisStyle.tick,
467
- axisLine: false,
468
- tickLine: false,
469
- label: yAxisLabel ? { value: yAxisLabel, angle: -90, position: "insideLeft", style: axisLabelStyle } : void 0
470
- }
471
- ),
472
- showTooltip && /* @__PURE__ */ jsx(Tooltip, { content: /* @__PURE__ */ jsx(ChartTooltipContent, {}) }),
473
- legendVisible && /* @__PURE__ */ jsx(Legend, { content: /* @__PURE__ */ jsx(ChartLegendContent, {}), wrapperStyle: { paddingTop: "var(--ds-space-3)" } }),
474
- lines.map((line, i) => /* @__PURE__ */ jsx(
475
- Line,
476
- {
477
- type: curved ? "monotone" : "linear",
478
- dataKey: line.dataKey,
479
- name: line.label ?? line.dataKey,
480
- stroke: colors[i],
481
- strokeWidth: 2,
482
- strokeDasharray: line.dashed ? "5 5" : void 0,
483
- dot: showDots,
484
- activeDot: { r: 5, strokeWidth: 2 },
485
- isAnimationActive: isAnimated
486
- },
487
- line.dataKey
488
- ))
489
- ] }) }) });
490
- });
491
- var AreaChart = forwardRef(function AreaChart2({
977
+ return /* @__PURE__ */ jsx(
978
+ ChartWrapper,
979
+ {
980
+ ref: mergeRefs(ref, wrapperRef),
981
+ height,
982
+ size: { model: "ratio" },
983
+ chart: "line",
984
+ categoryKind: "scale",
985
+ categories: data.length,
986
+ categoryAxis: "x",
987
+ axisTitle: yAxisLabel,
988
+ className,
989
+ "aria-label": ariaLabel,
990
+ children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(LineChart$1, { data, margin: { top, right: xTicks.endMargin, bottom: 4, left: 4 }, accessibilityLayer: true, children: [
991
+ showGrid && /* @__PURE__ */ jsx(CartesianGrid, { strokeDasharray: "3 3", stroke: gridStroke }),
992
+ /* @__PURE__ */ jsx(
993
+ XAxis,
994
+ {
995
+ dataKey: xAxisKey,
996
+ ...axisStyle.tick,
997
+ axisLine: false,
998
+ tickLine: false,
999
+ tick: xAxisTick,
1000
+ interval: xTicks.interval,
1001
+ ticks: xTicks.ticks,
1002
+ height: "auto",
1003
+ label: xAxisLabel ? { value: xAxisLabel, position: "insideBottom", offset: -2, style: axisLabelStyle } : void 0
1004
+ }
1005
+ ),
1006
+ /* @__PURE__ */ jsx(YAxis, { width: "auto", ...axisStyle.tick, axisLine: false, tickLine: false }),
1007
+ showTooltip && /* @__PURE__ */ jsx(Tooltip, { content: /* @__PURE__ */ jsx(ChartTooltipContent, {}) }),
1008
+ legendVisible && /* @__PURE__ */ jsx(ChartLegend, { order: lines.map((l) => l.dataKey) }),
1009
+ lines.map((line, i) => /* @__PURE__ */ jsx(
1010
+ Line,
1011
+ {
1012
+ type: curved ? "monotone" : "linear",
1013
+ dataKey: line.dataKey,
1014
+ name: line.label ?? line.dataKey,
1015
+ stroke: colors[i],
1016
+ strokeWidth: 2,
1017
+ strokeDasharray: line.dashed ? "5 5" : void 0,
1018
+ dot: showDots,
1019
+ activeDot: { r: 5, strokeWidth: 2 },
1020
+ isAnimationActive: isAnimated
1021
+ },
1022
+ line.dataKey
1023
+ ))
1024
+ ] }) })
1025
+ }
1026
+ );
1027
+ }));
1028
+ var AreaChart = markChart(forwardRef(function AreaChart2({
492
1029
  data,
493
1030
  areas,
494
1031
  xAxisKey,
495
1032
  xAxisInterval,
496
- height = "md",
1033
+ height = "auto",
497
1034
  stacked = false,
498
1035
  curved = true,
499
1036
  showGrid = true,
@@ -507,7 +1044,8 @@ var AreaChart = forwardRef(function AreaChart2({
507
1044
  className
508
1045
  }, ref) {
509
1046
  const wrapperRef = useRef(null);
510
- const xTicks = useCategoryTicks(data, xAxisKey, wrapperRef, xAxisInterval);
1047
+ const xTicks = useCategoryTicks(data, xAxisKey, wrapperRef, xAxisInterval, "scale");
1048
+ const measured = useAxisMeasure(wrapperRef, !!yAxisLabel && (data?.length ?? 0) > 0);
511
1049
  const instanceId = useId();
512
1050
  const solidColors = useChartColors(areas.length, false);
513
1051
  const softColors = useChartColors(areas.length, true);
@@ -516,58 +1054,65 @@ var AreaChart = forwardRef(function AreaChart2({
516
1054
  const isAnimated = useChartAnimation(animated);
517
1055
  const legendVisible = showLegend ?? areas.length >= 2;
518
1056
  const axisLabelStyle = { fontSize: "var(--ds-font-size-xs)", fontFamily: "var(--ds-font-sans)", fill: axisStyle.tick.fill };
1057
+ const top = 4 + (yAxisLabel ? Math.ceil(measured.px * 1.5) + 4 : 0);
519
1058
  if (!data?.length) return null;
520
- return /* @__PURE__ */ jsx(ChartWrapper, { ref: mergeRefs(ref, wrapperRef), height, className, "aria-label": ariaLabel, children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(AreaChart$1, { data, margin: { top: 4, right: xTicks.endMargin, bottom: 4, left: 4 }, accessibilityLayer: true, children: [
521
- /* @__PURE__ */ jsx("defs", { children: areas.map((area, i) => /* @__PURE__ */ jsxs("linearGradient", { id: `gradient-${instanceId}-${area.dataKey}`, x1: "0", y1: "0", x2: "0", y2: "1", children: [
522
- /* @__PURE__ */ jsx("stop", { offset: "0%", stopColor: softColors[i], stopOpacity: 1 }),
523
- /* @__PURE__ */ jsx("stop", { offset: "95%", stopColor: softColors[i], stopOpacity: 0.1 })
524
- ] }, area.dataKey)) }),
525
- showGrid && /* @__PURE__ */ jsx(CartesianGrid, { strokeDasharray: "3 3", stroke: gridStroke }),
526
- /* @__PURE__ */ jsx(
527
- XAxis,
528
- {
529
- dataKey: xAxisKey,
530
- ...axisStyle.tick,
531
- axisLine: false,
532
- tickLine: false,
533
- tick: xAxisTick,
534
- interval: xTicks.interval,
535
- ticks: xTicks.ticks,
536
- height: "auto",
537
- label: xAxisLabel ? { value: xAxisLabel, position: "insideBottom", offset: -2, style: axisLabelStyle } : void 0
538
- }
539
- ),
540
- /* @__PURE__ */ jsx(
541
- YAxis,
542
- {
543
- width: "auto",
544
- ...axisStyle.tick,
545
- axisLine: false,
546
- tickLine: false,
547
- label: yAxisLabel ? { value: yAxisLabel, angle: -90, position: "insideLeft", style: axisLabelStyle } : void 0
548
- }
549
- ),
550
- showTooltip && /* @__PURE__ */ jsx(Tooltip, { content: /* @__PURE__ */ jsx(ChartTooltipContent, {}) }),
551
- legendVisible && /* @__PURE__ */ jsx(Legend, { content: /* @__PURE__ */ jsx(ChartLegendContent, {}), wrapperStyle: { paddingTop: "var(--ds-space-3)" } }),
552
- areas.map((area, i) => /* @__PURE__ */ jsx(
553
- Area,
554
- {
555
- type: curved ? "monotone" : "linear",
556
- dataKey: area.dataKey,
557
- name: area.label ?? area.dataKey,
558
- stroke: solidColors[i],
559
- strokeWidth: 2,
560
- fill: gradient ? `url(#gradient-${instanceId}-${area.dataKey})` : softColors[i],
561
- stackId: stacked ? "stack" : void 0,
562
- isAnimationActive: isAnimated
563
- },
564
- area.dataKey
565
- ))
566
- ] }) }) });
567
- });
568
- var PieChart = forwardRef(function PieChart2({
1059
+ return /* @__PURE__ */ jsx(
1060
+ ChartWrapper,
1061
+ {
1062
+ ref: mergeRefs(ref, wrapperRef),
1063
+ height,
1064
+ size: { model: "ratio" },
1065
+ chart: "area",
1066
+ categoryKind: "scale",
1067
+ categories: data.length,
1068
+ categoryAxis: "x",
1069
+ axisTitle: yAxisLabel,
1070
+ className,
1071
+ "aria-label": ariaLabel,
1072
+ children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(AreaChart$1, { data, margin: { top, right: xTicks.endMargin, bottom: 4, left: 4 }, accessibilityLayer: true, children: [
1073
+ /* @__PURE__ */ jsx("defs", { children: areas.map((area, i) => /* @__PURE__ */ jsxs("linearGradient", { id: `gradient-${instanceId}-${area.dataKey}`, x1: "0", y1: "0", x2: "0", y2: "1", children: [
1074
+ /* @__PURE__ */ jsx("stop", { offset: "0%", stopColor: softColors[i], stopOpacity: 1 }),
1075
+ /* @__PURE__ */ jsx("stop", { offset: "95%", stopColor: softColors[i], stopOpacity: 0.1 })
1076
+ ] }, area.dataKey)) }),
1077
+ showGrid && /* @__PURE__ */ jsx(CartesianGrid, { strokeDasharray: "3 3", stroke: gridStroke }),
1078
+ /* @__PURE__ */ jsx(
1079
+ XAxis,
1080
+ {
1081
+ dataKey: xAxisKey,
1082
+ ...axisStyle.tick,
1083
+ axisLine: false,
1084
+ tickLine: false,
1085
+ tick: xAxisTick,
1086
+ interval: xTicks.interval,
1087
+ ticks: xTicks.ticks,
1088
+ height: "auto",
1089
+ label: xAxisLabel ? { value: xAxisLabel, position: "insideBottom", offset: -2, style: axisLabelStyle } : void 0
1090
+ }
1091
+ ),
1092
+ /* @__PURE__ */ jsx(YAxis, { width: "auto", ...axisStyle.tick, axisLine: false, tickLine: false }),
1093
+ showTooltip && /* @__PURE__ */ jsx(Tooltip, { content: /* @__PURE__ */ jsx(ChartTooltipContent, {}) }),
1094
+ legendVisible && /* @__PURE__ */ jsx(ChartLegend, { order: areas.map((a) => a.dataKey) }),
1095
+ areas.map((area, i) => /* @__PURE__ */ jsx(
1096
+ Area,
1097
+ {
1098
+ type: curved ? "monotone" : "linear",
1099
+ dataKey: area.dataKey,
1100
+ name: area.label ?? area.dataKey,
1101
+ stroke: solidColors[i],
1102
+ strokeWidth: 2,
1103
+ fill: gradient ? `url(#gradient-${instanceId}-${area.dataKey})` : softColors[i],
1104
+ stackId: stacked ? "stack" : void 0,
1105
+ isAnimationActive: isAnimated
1106
+ },
1107
+ area.dataKey
1108
+ ))
1109
+ ] }) })
1110
+ }
1111
+ );
1112
+ }));
1113
+ var PieChart = markChart(forwardRef(function PieChart2({
569
1114
  data,
570
- height = "md",
1115
+ height = "auto",
571
1116
  donut = false,
572
1117
  showTooltip = true,
573
1118
  showLegend = true,
@@ -580,7 +1125,7 @@ var PieChart = forwardRef(function PieChart2({
580
1125
  const isAnimated = useChartAnimation(animated);
581
1126
  const renderLabel = showLabels ? ({ percent }) => `${((percent ?? 0) * 100).toFixed(0)}%` : false;
582
1127
  if (!data?.length) return null;
583
- return /* @__PURE__ */ jsx(ChartWrapper, { ref, height, className, "aria-label": ariaLabel, children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(PieChart$1, { accessibilityLayer: true, children: [
1128
+ return /* @__PURE__ */ jsx(ChartWrapper, { ref, height, size: { model: "square" }, chart: "pie", className, "aria-label": ariaLabel, children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(PieChart$1, { accessibilityLayer: true, children: [
584
1129
  /* @__PURE__ */ jsx(
585
1130
  Pie,
586
1131
  {
@@ -600,18 +1145,20 @@ var PieChart = forwardRef(function PieChart2({
600
1145
  }
601
1146
  ),
602
1147
  showTooltip && /* @__PURE__ */ jsx(Tooltip, { content: /* @__PURE__ */ jsx(ChartTooltipContent, {}) }),
603
- showLegend && /* @__PURE__ */ jsx(Legend, { content: /* @__PURE__ */ jsx(ChartLegendContent, {}), wrapperStyle: { paddingTop: "var(--ds-space-3)" } })
1148
+ showLegend && /* @__PURE__ */ jsx(ChartLegend, { order: data.map((d) => d.name), by: "value" })
604
1149
  ] }) }) });
605
- });
606
- var CompositeChart = forwardRef(function CompositeChart2({
1150
+ }));
1151
+ var CompositeChart = markChart(forwardRef(function CompositeChart2({
607
1152
  data,
608
1153
  bars,
609
1154
  lines,
610
1155
  xAxisKey,
611
1156
  xAxisInterval,
612
- height = "md",
1157
+ height = "auto",
613
1158
  stacked = false,
614
1159
  dualAxis = !anyStack(bars, stacked),
1160
+ categoryKind: categoryKind2,
1161
+ horizontal,
615
1162
  showGrid = true,
616
1163
  showTooltip = true,
617
1164
  showLegend = true,
@@ -622,7 +1169,33 @@ var CompositeChart = forwardRef(function CompositeChart2({
622
1169
  className
623
1170
  }, ref) {
624
1171
  const wrapperRef = useRef(null);
625
- const xTicks = useCategoryTicks(data, xAxisKey, wrapperRef, xAxisInterval);
1172
+ const labels = useMemo(() => (data ?? []).map((d) => String(d[xAxisKey] ?? "")), [data, xAxisKey]);
1173
+ const kind = categoryKind2 ?? categoryKind((data ?? []).map((d) => d[xAxisKey]));
1174
+ const names = kind === "names";
1175
+ const measured = useAxisMeasure(wrapperRef, (data?.length ?? 0) > 0);
1176
+ const axisWidth = useMemo(() => {
1177
+ if (!measured.measure) return 0;
1178
+ const values = (data ?? []).flatMap((row) => {
1179
+ const stacks = /* @__PURE__ */ new Map();
1180
+ const own = [];
1181
+ for (const bar of bars) {
1182
+ const v = Number(row[bar.dataKey]);
1183
+ if (!Number.isFinite(v)) continue;
1184
+ const stack = barStackOf(bar, stacked);
1185
+ if (stack == null) own.push(v);
1186
+ else stacks.set(stack, (stacks.get(stack) ?? 0) + v);
1187
+ }
1188
+ return [...own, ...stacks.values(), ...dualAxis ? [] : lines.map((l) => Number(row[l.dataKey]))];
1189
+ });
1190
+ const lineValues = (data ?? []).flatMap((row) => lines.map((l) => Number(row[l.dataKey])));
1191
+ return valueAxisWidth(values, measured.measure) + (dualAxis ? valueAxisWidth(lineValues, measured.measure) : 0);
1192
+ }, [measured.measure, data, bars, lines, stacked, dualAxis]);
1193
+ const turned = useSidewaysSwitch(horizontal === void 0 && names, labels, measured, axisWidth, 8);
1194
+ const sideways = horizontal ?? turned;
1195
+ const xTicks = useCategoryTicks(data, xAxisKey, wrapperRef, xAxisInterval, sideways ? "names" : kind);
1196
+ const column = sideways ? nameColumn(labels, measured) : void 0;
1197
+ const tick = useMemo(() => names ? namesTick(measured.measure, "x") : xAxisTick, [names, measured.measure]);
1198
+ const rows = useMemo(() => namesTick(measured.measure, "y", column), [measured.measure, column]);
626
1199
  const barSoftColors = useChartColors(bars.length, true);
627
1200
  const barSolidColors = useChartColors(bars.length, false);
628
1201
  const lineColors = useChartColors(lines.length, false);
@@ -631,74 +1204,125 @@ var CompositeChart = forwardRef(function CompositeChart2({
631
1204
  const isAnimated = useChartAnimation(animated);
632
1205
  const radius = useRadius();
633
1206
  const axisLabelStyle = { fontSize: "var(--ds-font-size-xs)", fontFamily: "var(--ds-font-sans)", fill: axisStyle.tick.fill };
1207
+ const topTitle = sideways ? xAxisLabel : yAxisLabel;
1208
+ const bottomTitle = sideways ? yAxisLabel : xAxisLabel;
1209
+ const bottomLabel = bottomTitle ? { value: bottomTitle, position: "insideBottom", offset: -2, style: axisLabelStyle } : void 0;
1210
+ const top = 4 + (topTitle ? Math.ceil(measured.px * 1.5) + 4 : 0);
1211
+ const groups = barGroups(bars, stacked);
1212
+ const perCategory = 1 + 0.5 * (groups - 1);
1213
+ const titles = [topTitle, bottomTitle].filter(Boolean).length + (sideways && dualAxis ? 1 : 0);
1214
+ const size = sideways ? {
1215
+ model: "rows",
1216
+ units: labels.length * perCategory,
1217
+ lines: twoLineNames(labels, column, measured),
1218
+ axis: titles ? `calc(${CHART_ROW} + ${titles} * calc(1.5 * var(--ds-font-size-xs) + 4px))` : CHART_ROW
1219
+ } : { model: "ratio" };
1220
+ const maxBarSize = sideways ? Math.max(4, Math.round(measured.rowPx * perCategory * 0.7 / groups)) : void 0;
1221
+ const barAxis = sideways ? { xAxisId: "left" } : { yAxisId: "left" };
1222
+ const lineAxis = sideways ? { xAxisId: dualAxis ? "right" : "left" } : { yAxisId: dualAxis ? "right" : "left" };
634
1223
  if (!data?.length) return null;
635
- return /* @__PURE__ */ jsx(ChartWrapper, { ref: mergeRefs(ref, wrapperRef), height, className, "aria-label": ariaLabel, children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(ComposedChart, { data, stackOffset: anyStack(bars, stacked) ? "sign" : void 0, margin: { top: 4, right: xTicks.endMargin, bottom: 4, left: 4 }, accessibilityLayer: true, children: [
636
- showGrid && /* @__PURE__ */ jsx(CartesianGrid, { strokeDasharray: "3 3", stroke: gridStroke }),
637
- /* @__PURE__ */ jsx(
638
- XAxis,
639
- {
640
- dataKey: xAxisKey,
641
- ...axisStyle.tick,
642
- axisLine: false,
643
- tickLine: false,
644
- tick: xAxisTick,
645
- interval: xTicks.interval,
646
- ticks: xTicks.ticks,
647
- height: "auto",
648
- label: xAxisLabel ? { value: xAxisLabel, position: "insideBottom", offset: -2, style: axisLabelStyle } : void 0
649
- }
650
- ),
651
- /* @__PURE__ */ jsx(
652
- YAxis,
653
- {
654
- yAxisId: "left",
655
- width: "auto",
656
- ...axisStyle.tick,
657
- axisLine: false,
658
- tickLine: false,
659
- label: yAxisLabel ? { value: yAxisLabel, angle: -90, position: "insideLeft", style: axisLabelStyle } : void 0
660
- }
661
- ),
662
- dualAxis && /* @__PURE__ */ jsx(YAxis, { yAxisId: "right", orientation: "right", width: "auto", ...axisStyle.tick, axisLine: false, tickLine: false }),
663
- showTooltip && /* @__PURE__ */ jsx(Tooltip, { content: /* @__PURE__ */ jsx(ChartTooltipContent, {}) }),
664
- showLegend && /* @__PURE__ */ jsx(Legend, { content: /* @__PURE__ */ jsx(ChartLegendContent, {}), wrapperStyle: { paddingTop: "var(--ds-space-3)" } }),
665
- bars.map((bar, i) => /* @__PURE__ */ jsx(
666
- Bar,
667
- {
668
- dataKey: bar.dataKey,
669
- name: bar.label ?? bar.dataKey,
670
- fill: barSoftColors[i],
671
- stroke: barSolidColors[i],
672
- strokeWidth: 1,
673
- shape: barShape(bars, i, stacked, radius),
674
- stackId: barStackOf(bar, stacked),
675
- yAxisId: "left",
676
- isAnimationActive: isAnimated
677
- },
678
- bar.dataKey
679
- )),
680
- lines.map((line, i) => /* @__PURE__ */ jsx(
681
- Line,
682
- {
683
- type: "monotone",
684
- dataKey: line.dataKey,
685
- name: line.label ?? line.dataKey,
686
- stroke: lineColors[i],
687
- strokeWidth: 2,
688
- strokeDasharray: line.dashed ? "5 5" : void 0,
689
- dot: false,
690
- yAxisId: dualAxis ? "right" : "left",
691
- isAnimationActive: isAnimated
692
- },
693
- line.dataKey
694
- ))
695
- ] }) }) });
696
- });
697
- var ScatterChart = forwardRef(function ScatterChart2({
1224
+ return /* @__PURE__ */ jsx(
1225
+ ChartWrapper,
1226
+ {
1227
+ ref: mergeRefs(ref, wrapperRef),
1228
+ height,
1229
+ size,
1230
+ chart: "composite",
1231
+ categoryKind: kind,
1232
+ categories: data.length,
1233
+ categoryAxis: sideways ? "y" : "x",
1234
+ sideways,
1235
+ axisTitle: topTitle,
1236
+ className,
1237
+ "aria-label": ariaLabel,
1238
+ children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(
1239
+ ComposedChart,
1240
+ {
1241
+ data,
1242
+ layout: sideways ? "vertical" : "horizontal",
1243
+ stackOffset: anyStack(bars, stacked) ? "sign" : void 0,
1244
+ margin: { top, right: sideways || names ? 4 : xTicks.endMargin, bottom: 4, left: 4 },
1245
+ accessibilityLayer: true,
1246
+ children: [
1247
+ showGrid && /* @__PURE__ */ jsx(CartesianGrid, { strokeDasharray: "3 3", stroke: gridStroke, vertical: !sideways, horizontal: true }),
1248
+ sideways ? /* @__PURE__ */ jsxs(Fragment, { children: [
1249
+ /* @__PURE__ */ jsx(XAxis, { xAxisId: "left", type: "number", ...axisStyle.tick, axisLine: false, tickLine: false, height: "auto", label: bottomLabel }),
1250
+ dualAxis && /* @__PURE__ */ jsx(XAxis, { xAxisId: "right", type: "number", orientation: "top", ...axisStyle.tick, axisLine: false, tickLine: false, height: "auto" }),
1251
+ /* @__PURE__ */ jsx(
1252
+ YAxis,
1253
+ {
1254
+ dataKey: xAxisKey,
1255
+ type: "category",
1256
+ width: column ?? "auto",
1257
+ ...axisStyle.tick,
1258
+ axisLine: false,
1259
+ tickLine: false,
1260
+ interval: 0,
1261
+ tick: rows
1262
+ }
1263
+ )
1264
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
1265
+ /* @__PURE__ */ jsx(
1266
+ XAxis,
1267
+ {
1268
+ dataKey: xAxisKey,
1269
+ ...axisStyle.tick,
1270
+ axisLine: false,
1271
+ tickLine: false,
1272
+ tick,
1273
+ interval: xTicks.interval,
1274
+ ticks: xTicks.ticks,
1275
+ height: "auto",
1276
+ label: bottomLabel
1277
+ }
1278
+ ),
1279
+ /* @__PURE__ */ jsx(YAxis, { yAxisId: "left", width: "auto", ...axisStyle.tick, axisLine: false, tickLine: false }),
1280
+ dualAxis && /* @__PURE__ */ jsx(YAxis, { yAxisId: "right", orientation: "right", width: "auto", ...axisStyle.tick, axisLine: false, tickLine: false })
1281
+ ] }),
1282
+ showTooltip && /* @__PURE__ */ jsx(Tooltip, { content: /* @__PURE__ */ jsx(ChartTooltipContent, {}) }),
1283
+ showLegend && /* @__PURE__ */ jsx(ChartLegend, { order: [...bars.map((b) => b.dataKey), ...lines.map((l) => l.dataKey)] }),
1284
+ bars.map((bar, i) => /* @__PURE__ */ jsx(
1285
+ Bar,
1286
+ {
1287
+ dataKey: bar.dataKey,
1288
+ name: bar.label ?? bar.dataKey,
1289
+ fill: barSoftColors[i],
1290
+ stroke: barSolidColors[i],
1291
+ strokeWidth: 1,
1292
+ shape: barShape(bars, i, stacked, radius, sideways),
1293
+ stackId: barStackOf(bar, stacked),
1294
+ maxBarSize,
1295
+ ...barAxis,
1296
+ isAnimationActive: isAnimated
1297
+ },
1298
+ bar.dataKey
1299
+ )),
1300
+ lines.map((line, i) => /* @__PURE__ */ jsx(
1301
+ Line,
1302
+ {
1303
+ type: "monotone",
1304
+ dataKey: line.dataKey,
1305
+ name: line.label ?? line.dataKey,
1306
+ stroke: lineColors[i],
1307
+ strokeWidth: 2,
1308
+ strokeDasharray: line.dashed ? "5 5" : void 0,
1309
+ dot: false,
1310
+ ...lineAxis,
1311
+ isAnimationActive: isAnimated
1312
+ },
1313
+ line.dataKey
1314
+ ))
1315
+ ]
1316
+ }
1317
+ ) })
1318
+ }
1319
+ );
1320
+ }));
1321
+ var ScatterChart = markChart(forwardRef(function ScatterChart2({
698
1322
  data,
699
1323
  xLabel,
700
1324
  yLabel,
701
- height = "md",
1325
+ height = "auto",
702
1326
  showGrid = true,
703
1327
  showTooltip = true,
704
1328
  showLegend,
@@ -706,6 +1330,8 @@ var ScatterChart = forwardRef(function ScatterChart2({
706
1330
  "aria-label": ariaLabel,
707
1331
  className
708
1332
  }, ref) {
1333
+ const wrapperRef = useRef(null);
1334
+ const measured = useAxisMeasure(wrapperRef, !!yLabel && (data?.length ?? 0) > 0);
709
1335
  const colors = useChartColors(data.length, false);
710
1336
  const gridStroke = useGridStroke();
711
1337
  const axisStyle = useAxisStyle();
@@ -713,60 +1339,71 @@ var ScatterChart = forwardRef(function ScatterChart2({
713
1339
  const legendVisible = showLegend ?? data.length >= 2;
714
1340
  const axisLabelStyle = { fontSize: "var(--ds-font-size-xs)", fontFamily: "var(--ds-font-sans)", fill: axisStyle.tick.fill };
715
1341
  if (!data?.length) return null;
716
- return /* @__PURE__ */ jsx(ChartWrapper, { ref, height, className, "aria-label": ariaLabel, children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(
717
- ScatterChart$1,
1342
+ return /* @__PURE__ */ jsx(
1343
+ ChartWrapper,
718
1344
  {
719
- margin: { top: 8, right: 8, bottom: xLabel ? 20 : 4, left: yLabel ? 20 : 4 },
720
- accessibilityLayer: true,
721
- children: [
722
- showGrid && /* @__PURE__ */ jsx(CartesianGrid, { strokeDasharray: "3 3", stroke: gridStroke }),
723
- /* @__PURE__ */ jsx(
724
- XAxis,
725
- {
726
- type: "number",
727
- dataKey: "x",
728
- name: xLabel ?? "x",
729
- ...axisStyle.tick,
730
- axisLine: false,
731
- tickLine: false,
732
- label: xLabel ? { value: xLabel, position: "bottom", offset: 0, style: { ...axisLabelStyle, textAnchor: "middle" } } : void 0
733
- }
734
- ),
735
- /* @__PURE__ */ jsx(
736
- YAxis,
737
- {
738
- type: "number",
739
- dataKey: "y",
740
- name: yLabel ?? "y",
741
- width: "auto",
742
- ...axisStyle.tick,
743
- axisLine: false,
744
- tickLine: false,
745
- label: yLabel ? { value: yLabel, angle: -90, position: "left", offset: 0, style: { ...axisLabelStyle, textAnchor: "middle" } } : void 0
746
- }
747
- ),
748
- /* @__PURE__ */ jsx(ZAxis, { type: "number", dataKey: "z", range: [40, 400] }),
749
- showTooltip && /* @__PURE__ */ jsx(Tooltip, { content: /* @__PURE__ */ jsx(ChartTooltipContent, {}) }),
750
- legendVisible && /* @__PURE__ */ jsx(Legend, { content: /* @__PURE__ */ jsx(ChartLegendContent, {}), wrapperStyle: { paddingTop: "var(--ds-space-3)" } }),
751
- data.map((series, i) => /* @__PURE__ */ jsx(
752
- Scatter,
753
- {
754
- name: series.name,
755
- data: series.points,
756
- fill: colors[i],
757
- isAnimationActive: isAnimated
758
- },
759
- series.name
760
- ))
761
- ]
1345
+ ref: mergeRefs(ref, wrapperRef),
1346
+ height,
1347
+ size: { model: "ratio" },
1348
+ chart: "scatter",
1349
+ axisTitle: yLabel,
1350
+ className,
1351
+ "aria-label": ariaLabel,
1352
+ children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(
1353
+ ScatterChart$1,
1354
+ {
1355
+ margin: { top: 8 + (yLabel ? Math.ceil(measured.px * 1.5) + 4 : 0), right: 8, bottom: xLabel ? 20 : 4, left: 4 },
1356
+ accessibilityLayer: true,
1357
+ children: [
1358
+ showGrid && /* @__PURE__ */ jsx(CartesianGrid, { strokeDasharray: "3 3", stroke: gridStroke }),
1359
+ /* @__PURE__ */ jsx(
1360
+ XAxis,
1361
+ {
1362
+ type: "number",
1363
+ dataKey: "x",
1364
+ name: xLabel ?? "x",
1365
+ ...axisStyle.tick,
1366
+ axisLine: false,
1367
+ tickLine: false,
1368
+ label: xLabel ? { value: xLabel, position: "bottom", offset: 0, style: { ...axisLabelStyle, textAnchor: "middle" } } : void 0
1369
+ }
1370
+ ),
1371
+ /* @__PURE__ */ jsx(
1372
+ YAxis,
1373
+ {
1374
+ type: "number",
1375
+ dataKey: "y",
1376
+ name: yLabel ?? "y",
1377
+ width: "auto",
1378
+ ...axisStyle.tick,
1379
+ axisLine: false,
1380
+ tickLine: false
1381
+ }
1382
+ ),
1383
+ /* @__PURE__ */ jsx(ZAxis, { type: "number", dataKey: "z", range: [40, 400] }),
1384
+ showTooltip && /* @__PURE__ */ jsx(Tooltip, { content: /* @__PURE__ */ jsx(ChartTooltipContent, {}) }),
1385
+ legendVisible && /* @__PURE__ */ jsx(ChartLegend, { order: data.map((s) => s.name), by: "value" }),
1386
+ data.map((series, i) => /* @__PURE__ */ jsx(
1387
+ Scatter,
1388
+ {
1389
+ name: series.name,
1390
+ data: series.points,
1391
+ fill: colors[i],
1392
+ isAnimationActive: isAnimated
1393
+ },
1394
+ series.name
1395
+ ))
1396
+ ]
1397
+ }
1398
+ ) })
762
1399
  }
763
- ) }) });
764
- });
765
- var RadarChart = forwardRef(function RadarChart2({
1400
+ );
1401
+ }));
1402
+ var RadarChart = markChart(forwardRef(function RadarChart2({
766
1403
  data,
767
1404
  dataKeys,
768
1405
  axisKey,
769
- height = "md",
1406
+ height = "auto",
770
1407
  filled = true,
771
1408
  showDots = true,
772
1409
  showTooltip = true,
@@ -780,7 +1417,7 @@ var RadarChart = forwardRef(function RadarChart2({
780
1417
  const isAnimated = useChartAnimation(animated);
781
1418
  const legendVisible = showLegend ?? dataKeys.length >= 2;
782
1419
  if (!data?.length) return null;
783
- return /* @__PURE__ */ jsx(ChartWrapper, { ref, height, className, "aria-label": ariaLabel, children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(RadarChart$1, { data, cx: "50%", cy: "50%", outerRadius: "75%", accessibilityLayer: true, children: [
1420
+ return /* @__PURE__ */ jsx(ChartWrapper, { ref, height, size: { model: "square" }, chart: "radar", className, "aria-label": ariaLabel, children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(RadarChart$1, { data, cx: "50%", cy: "50%", outerRadius: "75%", accessibilityLayer: true, children: [
784
1421
  /* @__PURE__ */ jsx(PolarGrid, { stroke: "var(--ds-border-subtle)" }),
785
1422
  /* @__PURE__ */ jsx(
786
1423
  PolarAngleAxis,
@@ -797,7 +1434,7 @@ var RadarChart = forwardRef(function RadarChart2({
797
1434
  }
798
1435
  ),
799
1436
  showTooltip && /* @__PURE__ */ jsx(Tooltip, { content: /* @__PURE__ */ jsx(ChartTooltipContent, {}) }),
800
- legendVisible && /* @__PURE__ */ jsx(Legend, { content: /* @__PURE__ */ jsx(ChartLegendContent, {}), wrapperStyle: { paddingTop: "var(--ds-space-3)" } }),
1437
+ legendVisible && /* @__PURE__ */ jsx(ChartLegend, { order: dataKeys.map((dk) => dk.key) }),
801
1438
  dataKeys.map((dk, i) => /* @__PURE__ */ jsx(
802
1439
  Radar,
803
1440
  {
@@ -812,10 +1449,10 @@ var RadarChart = forwardRef(function RadarChart2({
812
1449
  dk.key
813
1450
  ))
814
1451
  ] }) }) });
815
- });
816
- var RadialBarChart = forwardRef(function RadialBarChart2({
1452
+ }));
1453
+ var RadialBarChart = markChart(forwardRef(function RadialBarChart2({
817
1454
  data,
818
- height = "md",
1455
+ height = "auto",
819
1456
  showTooltip = true,
820
1457
  showLegend = true,
821
1458
  showLabels = false,
@@ -832,7 +1469,7 @@ var RadialBarChart = forwardRef(function RadialBarChart2({
832
1469
  fill: colors[i % colors.length]
833
1470
  }));
834
1471
  if (!data?.length) return null;
835
- return /* @__PURE__ */ jsx(ChartWrapper, { ref, height, className, "aria-label": ariaLabel, children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(
1472
+ return /* @__PURE__ */ jsx(ChartWrapper, { ref, height, size: { model: "square" }, chart: "radial-bar", className, "aria-label": ariaLabel, children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(
836
1473
  RadialBarChart$1,
837
1474
  {
838
1475
  data: chartData,
@@ -854,16 +1491,16 @@ var RadialBarChart = forwardRef(function RadialBarChart2({
854
1491
  }
855
1492
  ),
856
1493
  showTooltip && /* @__PURE__ */ jsx(Tooltip, { content: /* @__PURE__ */ jsx(ChartTooltipContent, {}) }),
857
- showLegend && /* @__PURE__ */ jsx(Legend, { content: /* @__PURE__ */ jsx(ChartLegendContent, {}), wrapperStyle: { paddingTop: "var(--ds-space-3)" } })
1494
+ showLegend && /* @__PURE__ */ jsx(ChartLegend, { order: data.map((d) => d.name), by: "value" })
858
1495
  ]
859
1496
  }
860
1497
  ) }) });
861
- });
862
- var FunnelChart = forwardRef(function FunnelChart2({
1498
+ }));
1499
+ var STAGE_ROWS = 1.5;
1500
+ var FunnelChart = markChart(forwardRef(function FunnelChart2({
863
1501
  data,
864
- height = "md",
1502
+ height = "auto",
865
1503
  showTooltip = true,
866
- showLegend = true,
867
1504
  showLabels = true,
868
1505
  animated,
869
1506
  "aria-label": ariaLabel,
@@ -876,7 +1513,7 @@ var FunnelChart = forwardRef(function FunnelChart2({
876
1513
  fill: colors[i % colors.length]
877
1514
  }));
878
1515
  if (!data?.length) return null;
879
- return /* @__PURE__ */ jsx(ChartWrapper, { ref, height, className, "aria-label": ariaLabel, children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(FunnelChart$1, { accessibilityLayer: true, children: [
1516
+ return /* @__PURE__ */ jsx(ChartWrapper, { ref, height, size: { model: "rows", units: data.length * STAGE_ROWS, axis: "16px" }, chart: "funnel", className, "aria-label": ariaLabel, children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(FunnelChart$1, { accessibilityLayer: true, children: [
880
1517
  /* @__PURE__ */ jsx(Funnel, { dataKey: "value", data: chartData, isAnimationActive: isAnimated, children: showLabels && /* @__PURE__ */ jsx(
881
1518
  LabelList,
882
1519
  {
@@ -887,10 +1524,9 @@ var FunnelChart = forwardRef(function FunnelChart2({
887
1524
  fontFamily: "var(--ds-font-sans)"
888
1525
  }
889
1526
  ) }),
890
- showTooltip && /* @__PURE__ */ jsx(Tooltip, { content: /* @__PURE__ */ jsx(ChartTooltipContent, {}) }),
891
- showLegend && /* @__PURE__ */ jsx(Legend, { content: /* @__PURE__ */ jsx(ChartLegendContent, {}), wrapperStyle: { paddingTop: "var(--ds-space-3)" } })
1527
+ showTooltip && /* @__PURE__ */ jsx(Tooltip, { content: /* @__PURE__ */ jsx(ChartTooltipContent, {}) })
892
1528
  ] }) }) });
893
- });
1529
+ }));
894
1530
  function contrastColor(hex) {
895
1531
  const c = hex.replace("#", "");
896
1532
  if (c.length < 6) return "#ffffff";
@@ -946,9 +1582,9 @@ function addFillToNodes(nodes, colors, counter = { i: 0 }) {
946
1582
  return { ...node, fill };
947
1583
  });
948
1584
  }
949
- var TreemapChart = forwardRef(function TreemapChart2({
1585
+ var TreemapChart = markChart(forwardRef(function TreemapChart2({
950
1586
  data,
951
- height = "md",
1587
+ height = "auto",
952
1588
  showTooltip = true,
953
1589
  animated,
954
1590
  "aria-label": ariaLabel,
@@ -959,7 +1595,7 @@ var TreemapChart = forwardRef(function TreemapChart2({
959
1595
  const radius = useRadius();
960
1596
  const chartData = addFillToNodes(data, colors);
961
1597
  if (!data?.length) return null;
962
- return /* @__PURE__ */ jsx(ChartWrapper, { ref, height, className, "aria-label": ariaLabel, children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsx(
1598
+ return /* @__PURE__ */ jsx(ChartWrapper, { ref, height, size: { model: "ratio" }, chart: "treemap", className, "aria-label": ariaLabel, children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsx(
963
1599
  Treemap,
964
1600
  {
965
1601
  data: chartData,
@@ -972,10 +1608,10 @@ var TreemapChart = forwardRef(function TreemapChart2({
972
1608
  children: showTooltip && /* @__PURE__ */ jsx(Tooltip, { content: /* @__PURE__ */ jsx(ChartTooltipContent, {}) })
973
1609
  }
974
1610
  ) }) });
975
- });
976
- var SankeyChart = forwardRef(function SankeyChart2({
1611
+ }));
1612
+ var SankeyChart = markChart(forwardRef(function SankeyChart2({
977
1613
  data,
978
- height = "md",
1614
+ height = "auto",
979
1615
  showTooltip = true,
980
1616
  "aria-label": ariaLabel,
981
1617
  className
@@ -991,7 +1627,7 @@ var SankeyChart = forwardRef(function SankeyChart2({
991
1627
  links: data.links
992
1628
  };
993
1629
  if (!data?.nodes?.length) return null;
994
- return /* @__PURE__ */ jsx(ChartWrapper, { ref, height, className, "aria-label": ariaLabel, children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsx(
1630
+ return /* @__PURE__ */ jsx(ChartWrapper, { ref, height, size: { model: "ratio" }, chart: "sankey", className, "aria-label": ariaLabel, children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsx(
995
1631
  Sankey,
996
1632
  {
997
1633
  data: sankeyData,
@@ -1002,7 +1638,7 @@ var SankeyChart = forwardRef(function SankeyChart2({
1002
1638
  children: showTooltip && /* @__PURE__ */ jsx(Tooltip, { content: /* @__PURE__ */ jsx(ChartTooltipContent, {}) })
1003
1639
  }
1004
1640
  ) }) });
1005
- });
1641
+ }));
1006
1642
  var Sparkline = forwardRef(function Sparkline2({
1007
1643
  data,
1008
1644
  variant = "line",
@@ -1084,13 +1720,9 @@ var Sparkline = forwardRef(function Sparkline2({
1084
1720
  )
1085
1721
  ] }) }) });
1086
1722
  });
1087
- var HEIGHT_MAP2 = {
1088
- sm: "var(--ds-chart-height-sm)",
1089
- md: "var(--ds-chart-height-md)",
1090
- lg: "var(--ds-chart-height-lg)"
1091
- };
1723
+ var CHART_TITLE_CLASSES = "font-[family-name:var(--ds-font-display)] text-lg font-[var(--ds-weight-heading)] text-[var(--ds-text-primary)]";
1092
1724
  function ChartContainer({
1093
- height = "md",
1725
+ height = "auto",
1094
1726
  title,
1095
1727
  loading = false,
1096
1728
  emptyState,
@@ -1098,39 +1730,52 @@ function ChartContainer({
1098
1730
  children,
1099
1731
  className
1100
1732
  }) {
1101
- const fill = height === "fill";
1733
+ const titleId = useId();
1734
+ const fixed = fixedChartHeight(height);
1735
+ const sizesItself = !loading && !!children && isLibraryChart(children);
1736
+ const area = fixed ?? CHART_HEIGHTS.md;
1737
+ const context = useMemo(
1738
+ () => ({ height: fixed, titleId: title ? titleId : void 0, fillArea: !sizesItself }),
1739
+ [fixed, title, titleId, sizesItself]
1740
+ );
1741
+ let body = null;
1742
+ if (loading) {
1743
+ body = /* @__PURE__ */ jsxs("div", { className: "absolute inset-0 flex flex-col justify-end gap-ds-2 px-ds-2", children: [
1744
+ /* @__PURE__ */ jsx("div", { className: "flex items-end h-full gap-ds-1", children: [65, 40, 80, 55, 72, 45, 60].map((h, i) => /* @__PURE__ */ jsx(Skeleton, { variant: "custom", className: "flex-1", height: `${h}%` }, i)) }),
1745
+ /* @__PURE__ */ jsx(Skeleton, { variant: "text", lines: 1, className: "w-full" })
1746
+ ] });
1747
+ } else if (children) {
1748
+ body = /* @__PURE__ */ jsx(ChartContainerContext.Provider, { value: context, children: sizesItself ? children : (
1749
+ // the area is absolute, so a child that fills 100% has a definite height to fill
1750
+ /* @__PURE__ */ jsx("div", { className: "absolute inset-0", children: /* @__PURE__ */ jsx("div", { className: "h-full w-full", children }) })
1751
+ ) });
1752
+ } else if (emptyState) {
1753
+ body = /* @__PURE__ */ jsx("div", { className: "flex flex-1 items-center justify-center", children: emptyState });
1754
+ }
1102
1755
  return /* @__PURE__ */ jsxs(
1103
1756
  "div",
1104
1757
  {
1105
1758
  "data-card": "",
1759
+ "data-gs": "chart",
1106
1760
  className: cn(
1107
- fill && "h-full flex flex-col",
1761
+ "flex flex-col",
1108
1762
  variant === "ghost" ? "bg-transparent" : cn(
1109
- "rounded-[var(--ds-radius-md)] p-ds-4",
1763
+ // CardHeader's inset, so titles inside frames line up in a row (A1)
1764
+ "rounded-[var(--ds-radius-md)] px-ds-5 py-ds-4",
1110
1765
  "bg-[var(--ds-bg-surface)] border-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]",
1111
1766
  GLASS_SURFACE
1112
1767
  ),
1113
1768
  className
1114
1769
  ),
1115
1770
  children: [
1116
- title && /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-[var(--ds-text-primary)] mb-ds-4", children: title }),
1771
+ title && /* @__PURE__ */ jsx("h3", { id: titleId, className: cn(CHART_TITLE_CLASSES, "mb-ds-4"), children: title }),
1117
1772
  /* @__PURE__ */ jsx(
1118
1773
  "div",
1119
1774
  {
1120
- style: fill ? { minHeight: HEIGHT_MAP2.sm } : { height: HEIGHT_MAP2[height] },
1121
- className: cn("relative", fill && "flex-1"),
1122
- children: /* @__PURE__ */ jsx("div", { className: fill ? "absolute inset-0" : "h-full", children: loading ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col justify-end h-full gap-ds-2 px-ds-2", children: [
1123
- /* @__PURE__ */ jsx("div", { className: "flex items-end h-full gap-ds-1", children: [65, 40, 80, 55, 72, 45, 60].map((h, i) => /* @__PURE__ */ jsx(
1124
- Skeleton,
1125
- {
1126
- variant: "custom",
1127
- className: "flex-1",
1128
- height: `${h}%`
1129
- },
1130
- i
1131
- )) }),
1132
- /* @__PURE__ */ jsx(Skeleton, { variant: "text", lines: 1, className: "w-full" })
1133
- ] }) : children ? /* @__PURE__ */ jsx(ChartContainerContext.Provider, { value: true, children: /* @__PURE__ */ jsx("div", { className: "h-full w-full", children }) }) : emptyState ? /* @__PURE__ */ jsx("div", { className: "h-full w-full flex items-center justify-center", children: emptyState }) : null })
1775
+ "data-chart-body": "",
1776
+ className: "relative flex min-w-0 flex-col",
1777
+ style: { flex: "1 1 0%", minHeight: sizesItself ? void 0 : area },
1778
+ children: body
1134
1779
  }
1135
1780
  )
1136
1781
  ]
@@ -1138,6 +1783,6 @@ function ChartContainer({
1138
1783
  );
1139
1784
  }
1140
1785
 
1141
- export { AreaChart, BarChart, ChartContainer, CompositeChart, FunnelChart, LineChart, PieChart, RadarChart, RadialBarChart, SankeyChart, ScatterChart, Sparkline, TreemapChart, useChartColors };
1786
+ export { AreaChart, BarChart, ChartContainer, CompositeChart, FunnelChart, LineChart, PieChart, RadarChart, RadialBarChart, SankeyChart, ScatterChart, Sparkline, TreemapChart, categoryKind, useChartColors };
1142
1787
  //# sourceMappingURL=charts.js.map
1143
1788
  //# sourceMappingURL=charts.js.map