@kjaniec-dev/ui 0.9.3 → 1.0.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/dist/index.cjs CHANGED
@@ -550,9 +550,18 @@ var CheckboxField = React52__namespace.forwardRef(
550
550
  );
551
551
  CheckboxField.displayName = "CheckboxField";
552
552
  var Switch = React52__namespace.forwardRef(
553
- ({ className, label, id, ...props }, ref) => {
553
+ ({ className, label, id, checked, defaultChecked, onChange, ...props }, ref) => {
554
554
  const autoId = React52__namespace.useId();
555
555
  const inputId = id ?? autoId;
556
+ const isControlled = checked !== void 0;
557
+ const [internalChecked, setInternalChecked] = React52__namespace.useState(Boolean(defaultChecked));
558
+ const isChecked = isControlled ? Boolean(checked) : internalChecked;
559
+ const handleChange = (e) => {
560
+ if (!isControlled) {
561
+ setInternalChecked(e.target.checked);
562
+ }
563
+ onChange?.(e);
564
+ };
556
565
  return /* @__PURE__ */ jsxRuntime.jsxs(
557
566
  "label",
558
567
  {
@@ -569,6 +578,10 @@ var Switch = React52__namespace.forwardRef(
569
578
  id: inputId,
570
579
  type: "checkbox",
571
580
  role: "switch",
581
+ "aria-checked": isChecked,
582
+ checked: isControlled ? checked : void 0,
583
+ defaultChecked: !isControlled ? defaultChecked : void 0,
584
+ onChange: handleChange,
572
585
  className: "peer sr-only",
573
586
  ...props
574
587
  }
@@ -1675,16 +1688,44 @@ function ToastProvider({ children }) {
1675
1688
  "div",
1676
1689
  {
1677
1690
  role: "status",
1678
- onClick: () => remove(t.id),
1679
1691
  className: cn(
1680
- "flex items-center gap-2.5 min-w-[280px] px-4 py-3 cursor-pointer",
1692
+ "flex items-center justify-between gap-3 min-w-[280px] px-4 py-3",
1681
1693
  "bg-surface border border-border border-l-[3px] rounded-kj-md shadow-kj-lg text-[0.85rem] font-medium",
1682
1694
  toneBorder[t.tone],
1683
1695
  t.leaving ? "animate-[kjtoastout_.25s_ease_forwards]" : "animate-[kjtoastin_.25s_ease]"
1684
1696
  ),
1685
1697
  children: [
1686
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "grid place-items-center", children: icons[t.tone] }),
1687
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: t.message })
1698
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2.5", children: [
1699
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "grid place-items-center", children: icons[t.tone] }),
1700
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: t.message })
1701
+ ] }),
1702
+ /* @__PURE__ */ jsxRuntime.jsx(
1703
+ "button",
1704
+ {
1705
+ type: "button",
1706
+ "aria-label": "Dismiss notification",
1707
+ onClick: () => remove(t.id),
1708
+ className: "ml-auto text-muted-foreground hover:text-foreground p-1 -mr-1 rounded-kj-sm transition-colors cursor-pointer",
1709
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
1710
+ "svg",
1711
+ {
1712
+ width: 14,
1713
+ height: 14,
1714
+ viewBox: "0 0 24 24",
1715
+ fill: "none",
1716
+ stroke: "currentColor",
1717
+ strokeWidth: 2,
1718
+ strokeLinecap: "round",
1719
+ strokeLinejoin: "round",
1720
+ "aria-hidden": "true",
1721
+ children: [
1722
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
1723
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
1724
+ ]
1725
+ }
1726
+ )
1727
+ }
1728
+ )
1688
1729
  ]
1689
1730
  },
1690
1731
  t.id
@@ -1910,7 +1951,7 @@ function DataTable({
1910
1951
  onSelectionChange(next);
1911
1952
  };
1912
1953
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col gap-4 w-full", className), children: [
1913
- toolbar && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col sm:flex-row items-stretch sm:items-center justify-between gap-3", children: toolbar }),
1954
+ toolbar && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full min-w-0", children: toolbar }),
1914
1955
  /* @__PURE__ */ jsxRuntime.jsxs(
1915
1956
  TableWrap,
1916
1957
  {
@@ -2383,12 +2424,12 @@ var TableToolbar = React52__namespace.forwardRef(
2383
2424
  {
2384
2425
  ref,
2385
2426
  className: cn(
2386
- "flex flex-col sm:flex-row items-stretch sm:items-center justify-between gap-3 w-full pb-1",
2427
+ "flex flex-col sm:flex-row flex-wrap items-stretch sm:items-center justify-between gap-3 w-full pb-1",
2387
2428
  className
2388
2429
  ),
2389
2430
  ...props,
2390
2431
  children: [
2391
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 flex-col sm:flex-row items-stretch sm:items-center gap-2 max-w-xl", children: [
2432
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 flex-col sm:flex-row sm:flex-wrap items-stretch sm:items-center gap-2 min-w-0 max-w-xl", children: [
2392
2433
  onSearchChange && /* @__PURE__ */ jsxRuntime.jsx(
2393
2434
  Input,
2394
2435
  {
@@ -2396,7 +2437,7 @@ var TableToolbar = React52__namespace.forwardRef(
2396
2437
  placeholder: searchPlaceholder,
2397
2438
  value: searchQuery,
2398
2439
  onChange: (e) => onSearchChange(e.target.value),
2399
- className: "sm:w-64",
2440
+ className: "w-full sm:w-64 max-w-full",
2400
2441
  leadingIcon: /* @__PURE__ */ jsxRuntime.jsx(
2401
2442
  "svg",
2402
2443
  {
@@ -2417,9 +2458,9 @@ var TableToolbar = React52__namespace.forwardRef(
2417
2458
  )
2418
2459
  }
2419
2460
  ),
2420
- filters && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2", children: filters })
2461
+ filters && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap items-center gap-2 min-w-0", children: filters })
2421
2462
  ] }),
2422
- actions && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2 shrink-0 justify-end", children: actions })
2463
+ actions && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap items-center gap-2 shrink-0 justify-end sm:ml-auto", children: actions })
2423
2464
  ]
2424
2465
  }
2425
2466
  );
@@ -3005,7 +3046,6 @@ function BottomSheet({
3005
3046
  return /* @__PURE__ */ jsxRuntime.jsx(BottomSheetContext.Provider, { value: { titleId, descId }, children: /* @__PURE__ */ jsxRuntime.jsx(
3006
3047
  "div",
3007
3048
  {
3008
- role: "presentation",
3009
3049
  onClick: (e) => e.target === e.currentTarget && onClose(),
3010
3050
  className: cn(
3011
3051
  "fixed inset-0 z-[100] grid items-end sm:place-items-center p-0 sm:p-6 backdrop-blur-[3px] transition-all duration-200",
@@ -7305,6 +7345,2077 @@ var InPostGeowidgetModal = ({
7305
7345
  ] });
7306
7346
  };
7307
7347
 
7348
+ // src/components/chart-math.ts
7349
+ function formatCoordinate(val) {
7350
+ if (!Number.isFinite(val)) return "0";
7351
+ return Number.isInteger(val) ? val.toString() : Number(val.toFixed(2)).toString();
7352
+ }
7353
+ function niceNum(range2, round) {
7354
+ if (range2 <= 0 || !Number.isFinite(range2)) return 1;
7355
+ const exponent = Math.floor(Math.log10(range2));
7356
+ const fraction = range2 / 10 ** exponent;
7357
+ let niceFraction;
7358
+ {
7359
+ if (fraction < 1.5) niceFraction = 1;
7360
+ else if (fraction < 3) niceFraction = 2;
7361
+ else if (fraction < 7) niceFraction = 5;
7362
+ else niceFraction = 10;
7363
+ }
7364
+ return niceFraction * 10 ** exponent;
7365
+ }
7366
+ function getNiceScale(minInput, maxInput, tickCount = 5) {
7367
+ let min = Number.isFinite(minInput) ? minInput : 0;
7368
+ let max = Number.isFinite(maxInput) ? maxInput : 1;
7369
+ if (min > max) {
7370
+ const temp = min;
7371
+ min = max;
7372
+ max = temp;
7373
+ }
7374
+ if (min === max) {
7375
+ if (min === 0) {
7376
+ min = 0;
7377
+ max = 1;
7378
+ } else {
7379
+ const delta = Math.abs(min) * 0.2 || 1;
7380
+ min = min - delta;
7381
+ max = max + delta;
7382
+ }
7383
+ }
7384
+ const rawRange = max - min;
7385
+ const count = Math.max(2, tickCount);
7386
+ const step = niceNum(rawRange / count);
7387
+ const niceMin = Math.floor(min / step) * step;
7388
+ const niceMax = Math.ceil(max / step) * step;
7389
+ const ticks = [];
7390
+ const totalTicks = Math.round((niceMax - niceMin) / step);
7391
+ for (let i = 0; i <= totalTicks; i++) {
7392
+ const val = niceMin + i * step;
7393
+ ticks.push(Number(parseFloat(val.toPrecision(12))));
7394
+ }
7395
+ return {
7396
+ min: Number(parseFloat(niceMin.toPrecision(12))),
7397
+ max: Number(parseFloat(niceMax.toPrecision(12))),
7398
+ ticks
7399
+ };
7400
+ }
7401
+ function linearScale(val, domain, range2) {
7402
+ if (!Number.isFinite(val)) return range2[0];
7403
+ const [d0, d1] = domain;
7404
+ const [r0, r1] = range2;
7405
+ const domainDelta = d1 - d0;
7406
+ if (domainDelta === 0) {
7407
+ return r0;
7408
+ }
7409
+ const ratio = (val - d0) / domainDelta;
7410
+ return r0 + ratio * (r1 - r0);
7411
+ }
7412
+ function generateLinePath(points, curve = "linear") {
7413
+ const n = points.length;
7414
+ if (n === 0) return "";
7415
+ if (n === 1) return `M ${formatCoordinate(points[0].x)} ${formatCoordinate(points[0].y)}`;
7416
+ if (curve === "step") {
7417
+ const commands2 = [
7418
+ `M ${formatCoordinate(points[0].x)} ${formatCoordinate(points[0].y)}`
7419
+ ];
7420
+ for (let i = 1; i < n; i++) {
7421
+ const p = points[i];
7422
+ commands2.push(`H ${formatCoordinate(p.x)} V ${formatCoordinate(p.y)}`);
7423
+ }
7424
+ return commands2.join(" ");
7425
+ }
7426
+ if (curve === "smooth") {
7427
+ const commands2 = [
7428
+ `M ${formatCoordinate(points[0].x)} ${formatCoordinate(points[0].y)}`
7429
+ ];
7430
+ for (let i = 0; i < n - 1; i++) {
7431
+ const p0 = i > 0 ? points[i - 1] : {
7432
+ x: 2 * points[0].x - points[1].x,
7433
+ y: 2 * points[0].y - points[1].y
7434
+ };
7435
+ const p1 = points[i];
7436
+ const p2 = points[i + 1];
7437
+ const p3 = i + 2 < n ? points[i + 2] : {
7438
+ x: 2 * points[n - 1].x - points[n - 2].x,
7439
+ y: 2 * points[n - 1].y - points[n - 2].y
7440
+ };
7441
+ const cp1x = p1.x + (p2.x - p0.x) / 6;
7442
+ const cp1y = p1.y + (p2.y - p0.y) / 6;
7443
+ const cp2x = p2.x - (p3.x - p1.x) / 6;
7444
+ const cp2y = p2.y - (p3.y - p1.y) / 6;
7445
+ commands2.push(
7446
+ `C ${formatCoordinate(cp1x)} ${formatCoordinate(cp1y)}, ${formatCoordinate(cp2x)} ${formatCoordinate(cp2y)}, ${formatCoordinate(p2.x)} ${formatCoordinate(p2.y)}`
7447
+ );
7448
+ }
7449
+ return commands2.join(" ");
7450
+ }
7451
+ const commands = points.map(
7452
+ (p, i) => i === 0 ? `M ${formatCoordinate(p.x)} ${formatCoordinate(p.y)}` : `L ${formatCoordinate(p.x)} ${formatCoordinate(p.y)}`
7453
+ );
7454
+ return commands.join(" ");
7455
+ }
7456
+ function generateAreaPath(points, baselineY, curve = "linear") {
7457
+ if (points.length === 0) return "";
7458
+ if (points.length === 1) {
7459
+ const p = points[0];
7460
+ return `M ${formatCoordinate(p.x)} ${formatCoordinate(p.y)} L ${formatCoordinate(p.x)} ${formatCoordinate(baselineY)} Z`;
7461
+ }
7462
+ const linePath = generateLinePath(points, curve);
7463
+ const first = points[0];
7464
+ const last = points[points.length - 1];
7465
+ return `${linePath} L ${formatCoordinate(last.x)} ${formatCoordinate(baselineY)} L ${formatCoordinate(first.x)} ${formatCoordinate(baselineY)} Z`;
7466
+ }
7467
+ function calculateBarLayout(options) {
7468
+ const {
7469
+ dataCount,
7470
+ seriesCount,
7471
+ plotWidth,
7472
+ plotHeight,
7473
+ yDomain,
7474
+ data,
7475
+ mode = "grouped",
7476
+ layout = "vertical",
7477
+ barMaxWidth,
7478
+ groupPadding = 0.2,
7479
+ barPadding = 2
7480
+ } = options;
7481
+ if (data.length === 0 || dataCount <= 0 || seriesCount <= 0) {
7482
+ return [];
7483
+ }
7484
+ const domainSpan = yDomain[1] - yDomain[0];
7485
+ const safeDomainSpan = domainSpan !== 0 ? domainSpan : 1;
7486
+ const isVertical = layout === "vertical";
7487
+ const slotSize = isVertical ? plotWidth / dataCount : plotHeight / dataCount;
7488
+ if (isVertical) {
7489
+ if (mode === "grouped") {
7490
+ const groupWidth = slotSize * (1 - groupPadding);
7491
+ const totalGaps = Math.max(0, seriesCount - 1) * barPadding;
7492
+ let rawBarWidth2 = (groupWidth - totalGaps) / seriesCount;
7493
+ if (rawBarWidth2 < 1) rawBarWidth2 = Math.max(1, groupWidth / seriesCount);
7494
+ const barWidth2 = barMaxWidth ? Math.min(rawBarWidth2, barMaxWidth) : rawBarWidth2;
7495
+ const actualGroupBarsWidth = seriesCount * barWidth2 + (seriesCount - 1) * barPadding;
7496
+ return data.map((item) => {
7497
+ const groupStart = item.group * slotSize + (slotSize - actualGroupBarsWidth) / 2;
7498
+ const x = groupStart + item.seriesIndex * (barWidth2 + barPadding);
7499
+ const height = Math.abs(item.value) / safeDomainSpan * plotHeight;
7500
+ const y = plotHeight - height;
7501
+ return {
7502
+ ...item,
7503
+ x: Number(parseFloat(x.toPrecision(10))),
7504
+ y: Number(parseFloat(y.toPrecision(10))),
7505
+ width: Number(parseFloat(barWidth2.toPrecision(10))),
7506
+ height: Number(parseFloat(height.toPrecision(10)))
7507
+ };
7508
+ });
7509
+ }
7510
+ const rawBarWidth = slotSize * (1 - groupPadding);
7511
+ const barWidth = barMaxWidth ? Math.min(rawBarWidth, barMaxWidth) : rawBarWidth;
7512
+ const currentStackTops = /* @__PURE__ */ new Map();
7513
+ return data.map((item) => {
7514
+ const groupCenter = item.group * slotSize + slotSize / 2;
7515
+ const x = groupCenter - barWidth / 2;
7516
+ const height = Math.abs(item.value) / safeDomainSpan * plotHeight;
7517
+ const currentY = currentStackTops.get(item.group) ?? plotHeight;
7518
+ const y = currentY - height;
7519
+ currentStackTops.set(item.group, y);
7520
+ return {
7521
+ ...item,
7522
+ x: Number(parseFloat(x.toPrecision(10))),
7523
+ y: Number(parseFloat(y.toPrecision(10))),
7524
+ width: Number(parseFloat(barWidth.toPrecision(10))),
7525
+ height: Number(parseFloat(height.toPrecision(10)))
7526
+ };
7527
+ });
7528
+ }
7529
+ if (mode === "grouped") {
7530
+ const groupHeight = slotSize * (1 - groupPadding);
7531
+ const totalGaps = Math.max(0, seriesCount - 1) * barPadding;
7532
+ let rawBarHeight2 = (groupHeight - totalGaps) / seriesCount;
7533
+ if (rawBarHeight2 < 1) rawBarHeight2 = Math.max(1, groupHeight / seriesCount);
7534
+ const barHeight2 = barMaxWidth ? Math.min(rawBarHeight2, barMaxWidth) : rawBarHeight2;
7535
+ const actualGroupBarsHeight = seriesCount * barHeight2 + (seriesCount - 1) * barPadding;
7536
+ return data.map((item) => {
7537
+ const groupStart = item.group * slotSize + (slotSize - actualGroupBarsHeight) / 2;
7538
+ const y = groupStart + item.seriesIndex * (barHeight2 + barPadding);
7539
+ const width = Math.abs(item.value) / safeDomainSpan * plotWidth;
7540
+ const x = 0;
7541
+ return {
7542
+ ...item,
7543
+ x: Number(parseFloat(x.toPrecision(10))),
7544
+ y: Number(parseFloat(y.toPrecision(10))),
7545
+ width: Number(parseFloat(width.toPrecision(10))),
7546
+ height: Number(parseFloat(barHeight2.toPrecision(10)))
7547
+ };
7548
+ });
7549
+ }
7550
+ const rawBarHeight = slotSize * (1 - groupPadding);
7551
+ const barHeight = barMaxWidth ? Math.min(rawBarHeight, barMaxWidth) : rawBarHeight;
7552
+ const currentStackRights = /* @__PURE__ */ new Map();
7553
+ return data.map((item) => {
7554
+ const groupCenter = item.group * slotSize + slotSize / 2;
7555
+ const y = groupCenter - barHeight / 2;
7556
+ const width = Math.abs(item.value) / safeDomainSpan * plotWidth;
7557
+ const currentX = currentStackRights.get(item.group) ?? 0;
7558
+ const x = currentX;
7559
+ currentStackRights.set(item.group, currentX + width);
7560
+ return {
7561
+ ...item,
7562
+ x: Number(parseFloat(x.toPrecision(10))),
7563
+ y: Number(parseFloat(y.toPrecision(10))),
7564
+ width: Number(parseFloat(width.toPrecision(10))),
7565
+ height: Number(parseFloat(barHeight.toPrecision(10)))
7566
+ };
7567
+ });
7568
+ }
7569
+ function calculateDonutSegments(slices, options) {
7570
+ const { cx, cy, innerRadius, outerRadius, startAngle = -90 } = options;
7571
+ if (slices.length === 0) {
7572
+ return [];
7573
+ }
7574
+ const total = slices.reduce((sum, s) => sum + (s.value > 0 ? s.value : 0), 0);
7575
+ if (total === 0) {
7576
+ return slices.map((slice) => ({
7577
+ ...slice,
7578
+ percentage: 0,
7579
+ path: "",
7580
+ startAngle: 0,
7581
+ endAngle: 0,
7582
+ middleAngle: 0
7583
+ }));
7584
+ }
7585
+ let currentAngleRad = startAngle * Math.PI / 180;
7586
+ const segments = [];
7587
+ for (const slice of slices) {
7588
+ if (slice.value <= 0) {
7589
+ segments.push({
7590
+ ...slice,
7591
+ percentage: 0,
7592
+ path: "",
7593
+ startAngle: Number(parseFloat((currentAngleRad * (180 / Math.PI)).toPrecision(8))),
7594
+ endAngle: Number(parseFloat((currentAngleRad * (180 / Math.PI)).toPrecision(8))),
7595
+ middleAngle: Number(parseFloat((currentAngleRad * (180 / Math.PI)).toPrecision(8)))
7596
+ });
7597
+ continue;
7598
+ }
7599
+ const ratio = slice.value / total;
7600
+ const percentage = Math.round(ratio * 1e4) / 100;
7601
+ const angleSpanRad = ratio * 2 * Math.PI;
7602
+ const startA = currentAngleRad;
7603
+ const endA = currentAngleRad + angleSpanRad;
7604
+ const middleA = currentAngleRad + angleSpanRad / 2;
7605
+ currentAngleRad = endA;
7606
+ const startDeg = Number(parseFloat((startA * (180 / Math.PI)).toPrecision(8)));
7607
+ const endDeg = Number(parseFloat((endA * (180 / Math.PI)).toPrecision(8)));
7608
+ const middleDeg = Number(parseFloat((middleA * (180 / Math.PI)).toPrecision(8)));
7609
+ if (ratio >= 0.99999) {
7610
+ let fullPath = "";
7611
+ if (innerRadius > 0) {
7612
+ fullPath = `M ${formatCoordinate(cx)} ${formatCoordinate(cy - outerRadius)} A ${formatCoordinate(outerRadius)} ${formatCoordinate(outerRadius)} 0 1 1 ${formatCoordinate(cx)} ${formatCoordinate(cy + outerRadius)} A ${formatCoordinate(outerRadius)} ${formatCoordinate(outerRadius)} 0 1 1 ${formatCoordinate(cx)} ${formatCoordinate(cy - outerRadius)} L ${formatCoordinate(cx)} ${formatCoordinate(cy - innerRadius)} A ${formatCoordinate(innerRadius)} ${formatCoordinate(innerRadius)} 0 1 0 ${formatCoordinate(cx)} ${formatCoordinate(cy + innerRadius)} A ${formatCoordinate(innerRadius)} ${formatCoordinate(innerRadius)} 0 1 0 ${formatCoordinate(cx)} ${formatCoordinate(cy - innerRadius)} Z`;
7613
+ } else {
7614
+ fullPath = `M ${formatCoordinate(cx)} ${formatCoordinate(cy - outerRadius)} A ${formatCoordinate(outerRadius)} ${formatCoordinate(outerRadius)} 0 1 1 ${formatCoordinate(cx)} ${formatCoordinate(cy + outerRadius)} A ${formatCoordinate(outerRadius)} ${formatCoordinate(outerRadius)} 0 1 1 ${formatCoordinate(cx)} ${formatCoordinate(cy - outerRadius)} Z`;
7615
+ }
7616
+ segments.push({
7617
+ ...slice,
7618
+ percentage,
7619
+ path: fullPath,
7620
+ startAngle: startDeg,
7621
+ endAngle: endDeg,
7622
+ middleAngle: middleDeg
7623
+ });
7624
+ continue;
7625
+ }
7626
+ const x1 = cx + outerRadius * Math.cos(startA);
7627
+ const y1 = cy + outerRadius * Math.sin(startA);
7628
+ const x2 = cx + outerRadius * Math.cos(endA);
7629
+ const y2 = cy + outerRadius * Math.sin(endA);
7630
+ const largeArcFlag = angleSpanRad > Math.PI ? 1 : 0;
7631
+ let path = "";
7632
+ if (innerRadius > 0) {
7633
+ const x3 = cx + innerRadius * Math.cos(endA);
7634
+ const y3 = cy + innerRadius * Math.sin(endA);
7635
+ const x4 = cx + innerRadius * Math.cos(startA);
7636
+ const y4 = cy + innerRadius * Math.sin(startA);
7637
+ path = `M ${formatCoordinate(x1)} ${formatCoordinate(y1)} A ${formatCoordinate(outerRadius)} ${formatCoordinate(outerRadius)} 0 ${largeArcFlag} 1 ${formatCoordinate(x2)} ${formatCoordinate(y2)} L ${formatCoordinate(x3)} ${formatCoordinate(y3)} A ${formatCoordinate(innerRadius)} ${formatCoordinate(innerRadius)} 0 ${largeArcFlag} 0 ${formatCoordinate(x4)} ${formatCoordinate(y4)} Z`;
7638
+ } else {
7639
+ path = `M ${formatCoordinate(x1)} ${formatCoordinate(y1)} A ${formatCoordinate(outerRadius)} ${formatCoordinate(outerRadius)} 0 ${largeArcFlag} 1 ${formatCoordinate(x2)} ${formatCoordinate(y2)} L ${formatCoordinate(cx)} ${formatCoordinate(cy)} Z`;
7640
+ }
7641
+ segments.push({
7642
+ ...slice,
7643
+ percentage,
7644
+ path,
7645
+ startAngle: startDeg,
7646
+ endAngle: endDeg,
7647
+ middleAngle: middleDeg
7648
+ });
7649
+ }
7650
+ return segments;
7651
+ }
7652
+ var CHART_COLOR_VARS = {
7653
+ chart1: "var(--kj-chart1, #a84f08)",
7654
+ chart2: "var(--kj-chart2, #0f746d)",
7655
+ chart3: "var(--kj-chart3, #0284c7)",
7656
+ chart4: "var(--kj-chart4, #7c3aed)",
7657
+ chart5: "var(--kj-chart5, #e11d48)",
7658
+ chart6: "var(--kj-chart6, #65a30d)"
7659
+ };
7660
+ var DEFAULT_CHART_COLORS = [
7661
+ "chart1",
7662
+ "chart2",
7663
+ "chart3",
7664
+ "chart4",
7665
+ "chart5",
7666
+ "chart6"
7667
+ ];
7668
+ function getChartColor(color, fallbackIndex = 0) {
7669
+ if (!color) {
7670
+ const defaultKey = DEFAULT_CHART_COLORS[fallbackIndex % DEFAULT_CHART_COLORS.length];
7671
+ return CHART_COLOR_VARS[defaultKey] || defaultKey;
7672
+ }
7673
+ return CHART_COLOR_VARS[color] ?? color;
7674
+ }
7675
+ var SVG_TAGS = /* @__PURE__ */ new Set([
7676
+ "path",
7677
+ "rect",
7678
+ "circle",
7679
+ "ellipse",
7680
+ "line",
7681
+ "polyline",
7682
+ "polygon",
7683
+ "text",
7684
+ "tspan",
7685
+ "g",
7686
+ "defs",
7687
+ "linearGradient",
7688
+ "radialGradient",
7689
+ "stop",
7690
+ "pattern",
7691
+ "clipPath",
7692
+ "mask",
7693
+ "image",
7694
+ "use",
7695
+ "symbol",
7696
+ "animate",
7697
+ "animateTransform",
7698
+ "foreignObject"
7699
+ ]);
7700
+ function isSvgChild(child) {
7701
+ if (!React52__namespace.isValidElement(child)) return false;
7702
+ if (typeof child.type === "string") {
7703
+ return SVG_TAGS.has(child.type);
7704
+ }
7705
+ const comp = child.type;
7706
+ if (comp.isSvg) return true;
7707
+ const name = comp.displayName || comp.name || "";
7708
+ if (name.includes("Grid") || name.includes("Axis")) {
7709
+ return true;
7710
+ }
7711
+ return false;
7712
+ }
7713
+ function isOverlayChild(child) {
7714
+ if (!React52__namespace.isValidElement(child)) return false;
7715
+ const comp = child.type;
7716
+ const name = comp?.displayName || comp?.name || "";
7717
+ if (name.includes("Tooltip")) return true;
7718
+ const className = child.props?.className;
7719
+ if (typeof className === "string") {
7720
+ if (className.includes("chart-tooltip") || className.includes("chart-donut-center") || className.includes("chart-empty-message") || className.includes("absolute")) {
7721
+ return true;
7722
+ }
7723
+ }
7724
+ return false;
7725
+ }
7726
+ function partitionChildren(children) {
7727
+ const svgChildren = [];
7728
+ const overlayChildren = [];
7729
+ const flowChildren = [];
7730
+ const categorize = (child) => {
7731
+ if (child === null || child === void 0 || typeof child === "boolean") {
7732
+ return;
7733
+ }
7734
+ if (React52__namespace.isValidElement(child) && child.type === React52__namespace.Fragment) {
7735
+ const inner = partitionChildren(child.props.children);
7736
+ svgChildren.push(...inner.svgChildren);
7737
+ overlayChildren.push(...inner.overlayChildren);
7738
+ flowChildren.push(...inner.flowChildren);
7739
+ return;
7740
+ }
7741
+ if (isSvgChild(child)) {
7742
+ svgChildren.push(child);
7743
+ return;
7744
+ }
7745
+ if (isOverlayChild(child)) {
7746
+ overlayChildren.push(child);
7747
+ return;
7748
+ }
7749
+ flowChildren.push(child);
7750
+ };
7751
+ React52__namespace.Children.forEach(children, categorize);
7752
+ return { svgChildren, overlayChildren, flowChildren };
7753
+ }
7754
+ function useChartWidth(containerRef, defaultWidth = 600) {
7755
+ const [width, setWidth] = React52__namespace.useState(defaultWidth);
7756
+ React52__namespace.useEffect(() => {
7757
+ const el = containerRef.current;
7758
+ if (!el) return;
7759
+ const measure = () => {
7760
+ const rect = el.getBoundingClientRect();
7761
+ if (rect.width > 0) {
7762
+ setWidth(Math.round(rect.width));
7763
+ }
7764
+ };
7765
+ measure();
7766
+ if (typeof ResizeObserver === "undefined") {
7767
+ return;
7768
+ }
7769
+ const observer = new ResizeObserver((entries) => {
7770
+ for (const entry of entries) {
7771
+ const w = entry.contentRect.width;
7772
+ if (w > 0) {
7773
+ setWidth(Math.round(w));
7774
+ }
7775
+ }
7776
+ });
7777
+ observer.observe(el);
7778
+ return () => {
7779
+ observer.disconnect();
7780
+ };
7781
+ }, [containerRef]);
7782
+ return width;
7783
+ }
7784
+ var ChartContainer = React52__namespace.forwardRef(
7785
+ ({
7786
+ width,
7787
+ height,
7788
+ viewBox,
7789
+ "aria-label": ariaLabelProp,
7790
+ ariaLabel,
7791
+ overlay,
7792
+ svgClassName,
7793
+ svgRef,
7794
+ plotWrapperClassName,
7795
+ plotWrapperStyle,
7796
+ children,
7797
+ className,
7798
+ style,
7799
+ ...props
7800
+ }, ref) => {
7801
+ const label = ariaLabelProp || ariaLabel;
7802
+ const { svgChildren, overlayChildren, flowChildren } = partitionChildren(children);
7803
+ const heightNum = typeof height === "number" ? height : void 0;
7804
+ const computedViewBox = viewBox || (width !== void 0 && heightNum !== void 0 ? `0 0 ${width} ${heightNum}` : void 0);
7805
+ const plotHeightStyle = typeof height === "number" ? `${height}px` : height ?? void 0;
7806
+ return /* @__PURE__ */ jsxRuntime.jsxs(
7807
+ "div",
7808
+ {
7809
+ ref,
7810
+ className: cn("chart-container relative w-full flex flex-col", className),
7811
+ style,
7812
+ ...props,
7813
+ children: [
7814
+ /* @__PURE__ */ jsxRuntime.jsxs(
7815
+ "div",
7816
+ {
7817
+ className: cn("chart-plot-wrapper relative w-full", plotWrapperClassName),
7818
+ style: {
7819
+ height: plotHeightStyle,
7820
+ width: typeof width === "number" ? `${width}px` : void 0,
7821
+ ...plotWrapperStyle
7822
+ },
7823
+ children: [
7824
+ svgChildren.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
7825
+ "svg",
7826
+ {
7827
+ ref: svgRef,
7828
+ role: "img",
7829
+ "aria-label": label,
7830
+ viewBox: computedViewBox,
7831
+ width,
7832
+ height: heightNum,
7833
+ className: cn(
7834
+ "chart-svg block w-full overflow-visible",
7835
+ height !== void 0 ? "h-full" : "h-auto",
7836
+ svgClassName
7837
+ ),
7838
+ children: svgChildren
7839
+ }
7840
+ ),
7841
+ overlayChildren,
7842
+ overlay
7843
+ ]
7844
+ }
7845
+ ),
7846
+ flowChildren
7847
+ ]
7848
+ }
7849
+ );
7850
+ }
7851
+ );
7852
+ ChartContainer.displayName = "ChartContainer";
7853
+ var ChartGrid = ({
7854
+ width = 0,
7855
+ height = 0,
7856
+ yTicks,
7857
+ xTicks,
7858
+ scaleY,
7859
+ scaleX,
7860
+ yDomain,
7861
+ yRange,
7862
+ xDomain,
7863
+ xRange,
7864
+ stroke = "var(--kj-border-subtle, #e5e7eb)",
7865
+ strokeDasharray = "3 3",
7866
+ strokeWidth = 1,
7867
+ strokeOpacity = 1,
7868
+ horizontal = true,
7869
+ vertical,
7870
+ className,
7871
+ ...props
7872
+ }) => {
7873
+ const shouldDrawHorizontal = horizontal && Boolean(yTicks && yTicks.length > 0);
7874
+ const shouldDrawVertical = (vertical ?? Boolean(xTicks && xTicks.length > 0)) && Boolean(xTicks && xTicks.length > 0);
7875
+ const getY = scaleY ?? (yDomain && yRange ? (val) => linearScale(val, yDomain, yRange) : (val) => val);
7876
+ const getX = scaleX ?? (xDomain && xRange ? (val) => linearScale(val, xDomain, xRange) : (val) => val);
7877
+ return /* @__PURE__ */ jsxRuntime.jsxs("g", { className: cn("chart-grid pointer-events-none", className), ...props, children: [
7878
+ shouldDrawHorizontal && yTicks?.map((tick, idx) => {
7879
+ const yPos = getY(tick);
7880
+ return /* @__PURE__ */ jsxRuntime.jsx(
7881
+ "line",
7882
+ {
7883
+ x1: 0,
7884
+ y1: yPos,
7885
+ x2: width,
7886
+ y2: yPos,
7887
+ stroke,
7888
+ strokeDasharray,
7889
+ strokeWidth,
7890
+ strokeOpacity,
7891
+ className: "chart-grid-line chart-grid-line-y"
7892
+ },
7893
+ `grid-y-${idx}-${tick}`
7894
+ );
7895
+ }),
7896
+ shouldDrawVertical && xTicks?.map((tick, idx) => {
7897
+ const xPos = getX(tick);
7898
+ return /* @__PURE__ */ jsxRuntime.jsx(
7899
+ "line",
7900
+ {
7901
+ x1: xPos,
7902
+ y1: 0,
7903
+ x2: xPos,
7904
+ y2: height,
7905
+ stroke,
7906
+ strokeDasharray,
7907
+ strokeWidth,
7908
+ strokeOpacity,
7909
+ className: "chart-grid-line chart-grid-line-x"
7910
+ },
7911
+ `grid-x-${idx}-${tick}`
7912
+ );
7913
+ })
7914
+ ] });
7915
+ };
7916
+ ChartGrid.displayName = "ChartGrid";
7917
+ var ChartXAxis = ({
7918
+ ticks,
7919
+ y,
7920
+ formatter,
7921
+ valueFormatter,
7922
+ textAnchor = "middle",
7923
+ dy = "1.2em",
7924
+ className,
7925
+ tickClassName,
7926
+ ...props
7927
+ }) => {
7928
+ const format = formatter ?? valueFormatter ?? ((v) => String(v));
7929
+ return /* @__PURE__ */ jsxRuntime.jsx("g", { className: cn("chart-x-axis", className), ...props, children: ticks.map((tick, idx) => /* @__PURE__ */ jsxRuntime.jsx(
7930
+ "text",
7931
+ {
7932
+ x: tick.x,
7933
+ y,
7934
+ dy,
7935
+ textAnchor,
7936
+ fill: "currentColor",
7937
+ className: cn("chart-x-tick text-xs fill-muted-foreground select-none", tickClassName),
7938
+ children: format(tick.value)
7939
+ },
7940
+ `x-tick-${idx}-${tick.value}`
7941
+ )) });
7942
+ };
7943
+ ChartXAxis.displayName = "ChartXAxis";
7944
+ var ChartYAxis = ({
7945
+ ticks,
7946
+ x,
7947
+ formatter,
7948
+ valueFormatter,
7949
+ textAnchor = "end",
7950
+ dx = "-0.5em",
7951
+ dominantBaseline = "middle",
7952
+ className,
7953
+ tickClassName,
7954
+ ...props
7955
+ }) => {
7956
+ const format = formatter ?? valueFormatter ?? ((v) => String(v));
7957
+ return /* @__PURE__ */ jsxRuntime.jsx("g", { className: cn("chart-y-axis", className), ...props, children: ticks.map((tick, idx) => /* @__PURE__ */ jsxRuntime.jsx(
7958
+ "text",
7959
+ {
7960
+ x,
7961
+ y: tick.y,
7962
+ dx,
7963
+ textAnchor,
7964
+ dominantBaseline,
7965
+ fill: "currentColor",
7966
+ className: cn("chart-y-tick text-xs fill-muted-foreground select-none", tickClassName),
7967
+ children: format(tick.value)
7968
+ },
7969
+ `y-tick-${idx}-${tick.value}`
7970
+ )) });
7971
+ };
7972
+ ChartYAxis.displayName = "ChartYAxis";
7973
+ var ChartTooltip = React52__namespace.forwardRef(
7974
+ ({
7975
+ title,
7976
+ items,
7977
+ x,
7978
+ y,
7979
+ open = true,
7980
+ crosshairX,
7981
+ crosshairHeight,
7982
+ showCrosshair = false,
7983
+ valueFormatter,
7984
+ content,
7985
+ className,
7986
+ style,
7987
+ ...props
7988
+ }, ref) => {
7989
+ if (!open) {
7990
+ return null;
7991
+ }
7992
+ const hasCoordinates = x !== void 0 && y !== void 0;
7993
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
7994
+ showCrosshair && crosshairX !== void 0 && /* @__PURE__ */ jsxRuntime.jsx(
7995
+ "div",
7996
+ {
7997
+ className: "chart-crosshair pointer-events-none absolute top-0 w-px border-l border-dashed border-border/80",
7998
+ style: {
7999
+ left: `${crosshairX}px`,
8000
+ height: crosshairHeight !== void 0 ? `${crosshairHeight}px` : "100%"
8001
+ },
8002
+ "aria-hidden": "true"
8003
+ }
8004
+ ),
8005
+ /* @__PURE__ */ jsxRuntime.jsx(
8006
+ "div",
8007
+ {
8008
+ ref,
8009
+ className: cn(
8010
+ "chart-tooltip pointer-events-none absolute z-50 min-w-[120px] rounded-lg border border-border bg-popover/95 p-2.5 text-xs text-popover-foreground shadow-md backdrop-blur-sm transition-opacity duration-150",
8011
+ className
8012
+ ),
8013
+ style: {
8014
+ left: x !== void 0 ? `${x}px` : void 0,
8015
+ top: y !== void 0 ? `${y}px` : void 0,
8016
+ transform: hasCoordinates ? "translate(-50%, -100%) translateY(-8px)" : void 0,
8017
+ ...style
8018
+ },
8019
+ ...props,
8020
+ children: content ? content : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
8021
+ title && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "chart-tooltip-title font-medium text-foreground mb-1.5 pb-1 border-b border-border/50", children: title }),
8022
+ items && items.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "chart-tooltip-items space-y-1", children: items.map((item, idx) => {
8023
+ const itemVal = item.formattedValue ?? (typeof item.value === "number" && valueFormatter ? valueFormatter(item.value) : item.value);
8024
+ return /* @__PURE__ */ jsxRuntime.jsxs(
8025
+ "div",
8026
+ {
8027
+ className: "chart-tooltip-item flex items-center justify-between gap-3",
8028
+ children: [
8029
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 min-w-0", children: [
8030
+ /* @__PURE__ */ jsxRuntime.jsx(
8031
+ "span",
8032
+ {
8033
+ className: "chart-tooltip-dot h-2 w-2 rounded-full shrink-0",
8034
+ style: { backgroundColor: getChartColor(item.color, idx) },
8035
+ "aria-hidden": "true"
8036
+ }
8037
+ ),
8038
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-muted-foreground", children: item.label })
8039
+ ] }),
8040
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-semibold text-foreground shrink-0", children: itemVal })
8041
+ ]
8042
+ },
8043
+ item.key ?? idx
8044
+ );
8045
+ }) })
8046
+ ] })
8047
+ }
8048
+ )
8049
+ ] });
8050
+ }
8051
+ );
8052
+ ChartTooltip.displayName = "ChartTooltip";
8053
+ ChartTooltip.isHtml = true;
8054
+ var ChartLegend = ({
8055
+ series,
8056
+ activeSeries,
8057
+ disabledSeries,
8058
+ onToggle,
8059
+ orientation = "horizontal",
8060
+ className,
8061
+ itemClassName,
8062
+ ...props
8063
+ }) => {
8064
+ const isInteractive = Boolean(onToggle);
8065
+ return /* @__PURE__ */ jsxRuntime.jsx(
8066
+ "div",
8067
+ {
8068
+ className: cn(
8069
+ "chart-legend flex flex-wrap items-center justify-center gap-4 py-2",
8070
+ orientation === "vertical" && "flex-col items-start gap-2",
8071
+ className
8072
+ ),
8073
+ ...props,
8074
+ children: series.map((item, idx) => {
8075
+ const isDisabled = disabledSeries?.includes(item.key) || activeSeries !== void 0 && !activeSeries.includes(item.key);
8076
+ const content = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
8077
+ /* @__PURE__ */ jsxRuntime.jsx(
8078
+ "span",
8079
+ {
8080
+ className: "chart-legend-dot h-2.5 w-2.5 rounded-full shrink-0",
8081
+ style: { backgroundColor: getChartColor(item.color, idx) },
8082
+ "aria-hidden": "true"
8083
+ }
8084
+ ),
8085
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "chart-legend-label", children: item.label })
8086
+ ] });
8087
+ if (isInteractive) {
8088
+ return /* @__PURE__ */ jsxRuntime.jsx(
8089
+ "button",
8090
+ {
8091
+ type: "button",
8092
+ onClick: () => onToggle?.(item.key),
8093
+ onKeyDown: (e) => {
8094
+ if (e.key === "Enter" || e.key === " ") {
8095
+ e.preventDefault();
8096
+ onToggle?.(item.key);
8097
+ }
8098
+ },
8099
+ "aria-pressed": !isDisabled,
8100
+ className: cn(
8101
+ "chart-legend-item inline-flex items-center gap-1.5 text-xs font-medium transition-opacity cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 rounded px-1 py-0.5",
8102
+ isDisabled ? "opacity-40 line-through text-muted-foreground" : "text-foreground hover:opacity-80",
8103
+ itemClassName
8104
+ ),
8105
+ children: content
8106
+ },
8107
+ item.key
8108
+ );
8109
+ }
8110
+ return /* @__PURE__ */ jsxRuntime.jsx(
8111
+ "div",
8112
+ {
8113
+ className: cn(
8114
+ "chart-legend-item inline-flex items-center gap-1.5 text-xs font-medium",
8115
+ isDisabled ? "opacity-40 text-muted-foreground" : "text-foreground",
8116
+ itemClassName
8117
+ ),
8118
+ children: content
8119
+ },
8120
+ item.key
8121
+ );
8122
+ })
8123
+ }
8124
+ );
8125
+ };
8126
+ ChartLegend.displayName = "ChartLegend";
8127
+ ChartLegend.isHtml = true;
8128
+ var ChartA11yTable = ({
8129
+ caption,
8130
+ categories,
8131
+ series,
8132
+ data,
8133
+ indexKey,
8134
+ index,
8135
+ valueFormatter,
8136
+ className
8137
+ }) => {
8138
+ const categoryKey = indexKey ?? index;
8139
+ return /* @__PURE__ */ jsxRuntime.jsxs("table", { className: cn("sr-only", className), children: [
8140
+ caption && /* @__PURE__ */ jsxRuntime.jsx("caption", { children: caption }),
8141
+ /* @__PURE__ */ jsxRuntime.jsx("thead", { children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
8142
+ /* @__PURE__ */ jsxRuntime.jsx("th", { scope: "col", children: categoryKey || "Category" }),
8143
+ series.map((s) => /* @__PURE__ */ jsxRuntime.jsx("th", { scope: "col", children: s.label }, s.key))
8144
+ ] }) }),
8145
+ /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: data.map((row, rowIdx) => {
8146
+ let categoryLabel = "";
8147
+ if (typeof row === "object" && row !== null && categoryKey && row[categoryKey] !== void 0) {
8148
+ categoryLabel = String(row[categoryKey]);
8149
+ } else if (categories && categories[rowIdx] !== void 0) {
8150
+ categoryLabel = String(categories[rowIdx]);
8151
+ } else {
8152
+ categoryLabel = `Item ${rowIdx + 1}`;
8153
+ }
8154
+ return /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
8155
+ /* @__PURE__ */ jsxRuntime.jsx("th", { scope: "row", children: categoryLabel }),
8156
+ series.map((s) => {
8157
+ let rawVal;
8158
+ if (typeof row === "number") {
8159
+ rawVal = row;
8160
+ } else if (typeof row === "object" && row !== null) {
8161
+ rawVal = row[s.key];
8162
+ }
8163
+ const displayVal = valueFormatter && typeof rawVal === "number" ? valueFormatter(rawVal) : rawVal !== void 0 && rawVal !== null ? String(rawVal) : "-";
8164
+ return /* @__PURE__ */ jsxRuntime.jsx("td", { children: displayVal }, s.key);
8165
+ })
8166
+ ] }, `a11y-row-${rowIdx}`);
8167
+ }) })
8168
+ ] });
8169
+ };
8170
+ ChartA11yTable.displayName = "ChartA11yTable";
8171
+ ChartA11yTable.isHtml = true;
8172
+ var Sparkline = React52__namespace.forwardRef(
8173
+ ({
8174
+ data,
8175
+ dataKey,
8176
+ variant = "line",
8177
+ curve = "smooth",
8178
+ color = "chart1",
8179
+ strokeWidth = 2,
8180
+ showEndDot = false,
8181
+ showGradient = true,
8182
+ height = 36,
8183
+ width = "100%",
8184
+ barRadius = 2,
8185
+ barPadding = 2,
8186
+ ariaLabel,
8187
+ className,
8188
+ style,
8189
+ preserveAspectRatio = "none",
8190
+ ...props
8191
+ }, ref) => {
8192
+ const rawId = React52__namespace.useId();
8193
+ const gradientId = `sparkline-grad-${rawId.replace(/[^a-zA-Z0-9_-]/g, "")}`;
8194
+ const values = React52__namespace.useMemo(() => {
8195
+ if (!data || !Array.isArray(data) || data.length === 0) return [];
8196
+ return data.map((item) => {
8197
+ if (typeof item === "number") return item;
8198
+ if (typeof item === "object" && item !== null) {
8199
+ if (dataKey && item[dataKey] !== void 0) {
8200
+ const num = Number(item[dataKey]);
8201
+ return Number.isFinite(num) ? num : 0;
8202
+ }
8203
+ if ("value" in item && item.value !== void 0) {
8204
+ const num = Number(item.value);
8205
+ return Number.isFinite(num) ? num : 0;
8206
+ }
8207
+ for (const key of Object.keys(item)) {
8208
+ const val = item[key];
8209
+ if (typeof val === "number") return val;
8210
+ const num = Number(val);
8211
+ if (Number.isFinite(num)) return num;
8212
+ }
8213
+ }
8214
+ const parsed = Number(item);
8215
+ return Number.isFinite(parsed) ? parsed : 0;
8216
+ }).filter((v) => Number.isFinite(v));
8217
+ }, [data, dataKey]);
8218
+ const resolvedColor = getChartColor(color, 0);
8219
+ const computedAriaLabel = props["aria-label"] ?? ariaLabel ?? "Sparkline";
8220
+ const viewBoxWidth = typeof width === "number" && width > 0 ? width : 120;
8221
+ const isHidden = props["aria-hidden"] === true || props["aria-hidden"] === "true";
8222
+ if (values.length === 0) {
8223
+ return /* @__PURE__ */ jsxRuntime.jsx(
8224
+ "svg",
8225
+ {
8226
+ ref,
8227
+ role: isHidden ? void 0 : "img",
8228
+ "aria-label": isHidden ? void 0 : computedAriaLabel,
8229
+ viewBox: `0 0 ${viewBoxWidth} ${height}`,
8230
+ width,
8231
+ height,
8232
+ className: cn("chart-sparkline chart-sparkline-empty overflow-visible", className),
8233
+ style: {
8234
+ height: typeof height === "number" ? `${height}px` : height,
8235
+ width: typeof width === "number" ? `${width}px` : width,
8236
+ ...style
8237
+ },
8238
+ preserveAspectRatio,
8239
+ ...props,
8240
+ children: /* @__PURE__ */ jsxRuntime.jsx(
8241
+ "line",
8242
+ {
8243
+ x1: 0,
8244
+ y1: height / 2,
8245
+ x2: viewBoxWidth,
8246
+ y2: height / 2,
8247
+ stroke: "currentColor",
8248
+ strokeDasharray: "2 2",
8249
+ strokeWidth: 1,
8250
+ className: "text-muted-foreground/30 stroke-current"
8251
+ }
8252
+ )
8253
+ }
8254
+ );
8255
+ }
8256
+ if (variant === "bar") {
8257
+ const minVal2 = Math.min(0, ...values);
8258
+ const maxVal2 = Math.max(0, ...values) || 1;
8259
+ const barData = values.map((val, idx) => ({
8260
+ group: idx,
8261
+ seriesIndex: 0,
8262
+ value: val
8263
+ }));
8264
+ const barRects = calculateBarLayout({
8265
+ dataCount: values.length,
8266
+ seriesCount: 1,
8267
+ plotWidth: viewBoxWidth,
8268
+ plotHeight: height,
8269
+ yDomain: [minVal2, maxVal2],
8270
+ data: barData,
8271
+ mode: "grouped",
8272
+ layout: "vertical",
8273
+ groupPadding: 0.2,
8274
+ barPadding
8275
+ });
8276
+ const lastBar = barRects.length > 0 ? barRects[barRects.length - 1] : void 0;
8277
+ return /* @__PURE__ */ jsxRuntime.jsxs(
8278
+ "svg",
8279
+ {
8280
+ ref,
8281
+ role: isHidden ? void 0 : "img",
8282
+ "aria-label": isHidden ? void 0 : computedAriaLabel,
8283
+ viewBox: `0 0 ${viewBoxWidth} ${height}`,
8284
+ width,
8285
+ height,
8286
+ className: cn("chart-sparkline chart-sparkline-bars overflow-visible", className),
8287
+ style: {
8288
+ height: typeof height === "number" ? `${height}px` : height,
8289
+ width: typeof width === "number" ? `${width}px` : width,
8290
+ ...style
8291
+ },
8292
+ preserveAspectRatio,
8293
+ ...props,
8294
+ children: [
8295
+ barRects.map((bar, idx) => /* @__PURE__ */ jsxRuntime.jsx(
8296
+ "rect",
8297
+ {
8298
+ x: bar.x,
8299
+ y: bar.y,
8300
+ width: bar.width,
8301
+ height: Math.max(bar.height, bar.value === 0 ? 0 : 1),
8302
+ rx: barRadius,
8303
+ fill: resolvedColor,
8304
+ className: "chart-sparkline-bar"
8305
+ },
8306
+ `sparkline-bar-${idx}-${bar.x}`
8307
+ )),
8308
+ showEndDot && lastBar && /* @__PURE__ */ jsxRuntime.jsx(
8309
+ "circle",
8310
+ {
8311
+ cx: lastBar.x + lastBar.width / 2,
8312
+ cy: lastBar.y,
8313
+ r: 3,
8314
+ fill: resolvedColor,
8315
+ className: "chart-sparkline-dot"
8316
+ }
8317
+ )
8318
+ ]
8319
+ }
8320
+ );
8321
+ }
8322
+ const paddingTop = 4;
8323
+ const paddingBottom = 4;
8324
+ const paddingLeft = showEndDot ? 4 : 2;
8325
+ const paddingRight = showEndDot ? 4 : 2;
8326
+ const minVal = Math.min(...values);
8327
+ const maxVal = Math.max(...values);
8328
+ const points = values.map((val, idx) => {
8329
+ const x = values.length === 1 ? viewBoxWidth / 2 : linearScale(idx, [0, values.length - 1], [paddingLeft, viewBoxWidth - paddingRight]);
8330
+ const y = minVal === maxVal ? height / 2 : linearScale(val, [minVal, maxVal], [height - paddingBottom, paddingTop]);
8331
+ return { x, y };
8332
+ });
8333
+ const linePath = generateLinePath(points, curve);
8334
+ const areaPath = variant === "area" ? generateAreaPath(points, height, curve) : "";
8335
+ const lastPoint = points[points.length - 1];
8336
+ return /* @__PURE__ */ jsxRuntime.jsxs(
8337
+ "svg",
8338
+ {
8339
+ ref,
8340
+ role: isHidden ? void 0 : "img",
8341
+ "aria-label": isHidden ? void 0 : computedAriaLabel,
8342
+ viewBox: `0 0 ${viewBoxWidth} ${height}`,
8343
+ width,
8344
+ height,
8345
+ className: cn(
8346
+ "chart-sparkline overflow-visible",
8347
+ variant === "area" ? "chart-sparkline-area-container" : "chart-sparkline-line-container",
8348
+ className
8349
+ ),
8350
+ style: {
8351
+ height: typeof height === "number" ? `${height}px` : height,
8352
+ width: typeof width === "number" ? `${width}px` : width,
8353
+ ...style
8354
+ },
8355
+ preserveAspectRatio,
8356
+ ...props,
8357
+ children: [
8358
+ variant === "area" && showGradient && /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsxs("linearGradient", { id: gradientId, x1: "0", y1: "0", x2: "0", y2: "1", children: [
8359
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "0%", stopColor: resolvedColor, stopOpacity: "0.28" }),
8360
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "100%", stopColor: resolvedColor, stopOpacity: "0.0" })
8361
+ ] }) }),
8362
+ variant === "area" && areaPath && /* @__PURE__ */ jsxRuntime.jsx(
8363
+ "path",
8364
+ {
8365
+ d: areaPath,
8366
+ fill: showGradient ? `url(#${gradientId})` : resolvedColor,
8367
+ fillOpacity: showGradient ? void 0 : 0.15,
8368
+ stroke: "none",
8369
+ className: "chart-sparkline-area"
8370
+ }
8371
+ ),
8372
+ linePath && /* @__PURE__ */ jsxRuntime.jsx(
8373
+ "path",
8374
+ {
8375
+ d: linePath,
8376
+ fill: "none",
8377
+ stroke: resolvedColor,
8378
+ strokeWidth,
8379
+ strokeLinecap: "round",
8380
+ strokeLinejoin: "round",
8381
+ vectorEffect: "non-scaling-stroke",
8382
+ className: "chart-sparkline-line"
8383
+ }
8384
+ ),
8385
+ showEndDot && lastPoint && /* @__PURE__ */ jsxRuntime.jsx(
8386
+ "circle",
8387
+ {
8388
+ cx: lastPoint.x,
8389
+ cy: lastPoint.y,
8390
+ r: 3,
8391
+ fill: resolvedColor,
8392
+ stroke: "var(--kj-background, #ffffff)",
8393
+ strokeWidth: 1.5,
8394
+ vectorEffect: "non-scaling-stroke",
8395
+ className: "chart-sparkline-dot"
8396
+ }
8397
+ )
8398
+ ]
8399
+ }
8400
+ );
8401
+ }
8402
+ );
8403
+ Sparkline.displayName = "Sparkline";
8404
+ var LineChart = React52__namespace.forwardRef(
8405
+ ({
8406
+ data,
8407
+ index,
8408
+ series,
8409
+ variant = "line",
8410
+ curve = "linear",
8411
+ showGrid = true,
8412
+ showXAxis = true,
8413
+ showYAxis = true,
8414
+ showLegend,
8415
+ showTooltip = true,
8416
+ showDots = false,
8417
+ showGradient = true,
8418
+ showA11yTable,
8419
+ valueFormatter,
8420
+ indexFormatter,
8421
+ emptyMessage = "Brak danych do wy\u015Bwietlenia",
8422
+ height = 280,
8423
+ width = "100%",
8424
+ margin: marginProp,
8425
+ ariaLabel,
8426
+ caption,
8427
+ strokeWidth = 2,
8428
+ activeSeries: activeSeriesProp,
8429
+ onSeriesToggle,
8430
+ yTicksCount = 5,
8431
+ yDomain: yDomainProp,
8432
+ autoScale = false,
8433
+ className,
8434
+ style,
8435
+ ...props
8436
+ }, ref) => {
8437
+ const rawId = React52__namespace.useId();
8438
+ const idPrefix = `kj-chart-${rawId.replace(/[^a-zA-Z0-9_-]/g, "")}`;
8439
+ const containerRef = React52__namespace.useRef(null);
8440
+ const combinedRef = (node) => {
8441
+ containerRef.current = node;
8442
+ if (typeof ref === "function") {
8443
+ ref(node);
8444
+ } else if (ref) {
8445
+ ref.current = node;
8446
+ }
8447
+ };
8448
+ const [internalDisabledSeries, setInternalDisabledSeries] = React52__namespace.useState([]);
8449
+ const disabledSeries = activeSeriesProp ? series.filter((s) => !activeSeriesProp.includes(s.key)).map((s) => s.key) : internalDisabledSeries;
8450
+ const handleSeriesToggle = (key) => {
8451
+ onSeriesToggle?.(key);
8452
+ setInternalDisabledSeries(
8453
+ (prev) => prev.includes(key) ? prev.filter((k) => k !== key) : [...prev, key]
8454
+ );
8455
+ };
8456
+ const activeSeriesList = React52__namespace.useMemo(
8457
+ () => series.filter((s) => !disabledSeries.includes(s.key)),
8458
+ [series, disabledSeries]
8459
+ );
8460
+ const [activeIndex, setActiveIndex] = React52__namespace.useState(null);
8461
+ const [tooltipPos, setTooltipPos] = React52__namespace.useState(null);
8462
+ const computedAriaLabel = props["aria-label"] ?? ariaLabel ?? (variant === "area" ? "Wykres warstwowy" : "Wykres liniowy");
8463
+ if (!data || data.length === 0) {
8464
+ return /* @__PURE__ */ jsxRuntime.jsx(
8465
+ ChartContainer,
8466
+ {
8467
+ ref: combinedRef,
8468
+ width: typeof width === "number" ? width : void 0,
8469
+ height,
8470
+ "aria-label": computedAriaLabel,
8471
+ className: cn("chart-line-empty", className),
8472
+ style,
8473
+ ...props,
8474
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "chart-empty-message flex h-full min-h-[160px] w-full items-center justify-center text-sm text-muted-foreground select-none", children: emptyMessage })
8475
+ }
8476
+ );
8477
+ }
8478
+ const measuredWidth = useChartWidth(
8479
+ containerRef,
8480
+ typeof width === "number" && width > 0 ? width : 600
8481
+ );
8482
+ const viewBoxWidth = typeof width === "number" && width > 0 ? width : measuredWidth > 0 ? measuredWidth : 600;
8483
+ const viewBoxHeight = typeof height === "number" && height > 0 ? height : 280;
8484
+ const margin = {
8485
+ top: 16,
8486
+ right: 20,
8487
+ bottom: showXAxis ? 32 : 16,
8488
+ left: showYAxis ? 48 : 16,
8489
+ ...marginProp
8490
+ };
8491
+ const plotLeft = margin.left;
8492
+ const plotRight = viewBoxWidth - margin.right;
8493
+ const plotTop = margin.top;
8494
+ const plotBottom = viewBoxHeight - margin.bottom;
8495
+ const plotWidth = Math.max(0, plotRight - plotLeft);
8496
+ const plotHeight = Math.max(0, plotBottom - plotTop);
8497
+ const allValues = [];
8498
+ for (const row of data) {
8499
+ for (const s of activeSeriesList) {
8500
+ const val = row[s.key];
8501
+ if (typeof val === "number" && Number.isFinite(val)) {
8502
+ allValues.push(val);
8503
+ }
8504
+ }
8505
+ }
8506
+ let dataMin = allValues.length > 0 ? Math.min(...allValues) : 0;
8507
+ const dataMax = allValues.length > 0 ? Math.max(...allValues) : 100;
8508
+ if (!autoScale && dataMin > 0) {
8509
+ dataMin = 0;
8510
+ }
8511
+ const niceScale = getNiceScale(dataMin, dataMax, yTicksCount);
8512
+ const domainMin = yDomainProp ? yDomainProp[0] : niceScale.min;
8513
+ const domainMax = yDomainProp ? yDomainProp[1] : niceScale.max;
8514
+ const getY = (val) => {
8515
+ return linearScale(val, [domainMin, domainMax], [plotBottom, plotTop]);
8516
+ };
8517
+ const getX = (idx) => {
8518
+ if (data.length <= 1) {
8519
+ return plotLeft + plotWidth / 2;
8520
+ }
8521
+ return linearScale(idx, [0, data.length - 1], [plotLeft, plotRight]);
8522
+ };
8523
+ const yTicks = (yDomainProp ? getNiceScale(yDomainProp[0], yDomainProp[1], yTicksCount).ticks : niceScale.ticks).map((val) => ({
8524
+ value: val,
8525
+ y: getY(val)
8526
+ }));
8527
+ const maxXTicks = Math.max(2, Math.floor(plotWidth / 60));
8528
+ const xStep = data.length > maxXTicks ? Math.ceil(data.length / maxXTicks) : 1;
8529
+ const xTicks = data.map((row, idx) => ({
8530
+ value: row[index] ?? "",
8531
+ x: getX(idx),
8532
+ idx
8533
+ })).filter((_, i) => i % xStep === 0 || i === data.length - 1);
8534
+ const handlePointerMove = (clientX, clientY, target) => {
8535
+ const rect = target.getBoundingClientRect();
8536
+ let relativeX;
8537
+ if (rect.width > 0) {
8538
+ relativeX = (clientX - rect.left) / rect.width * plotWidth + plotLeft;
8539
+ } else {
8540
+ relativeX = clientX;
8541
+ }
8542
+ let closestIdx = 0;
8543
+ let minDiff = Infinity;
8544
+ for (let i = 0; i < data.length; i++) {
8545
+ const ptX = getX(i);
8546
+ const diff = Math.abs(ptX - relativeX);
8547
+ if (diff < minDiff) {
8548
+ minDiff = diff;
8549
+ closestIdx = i;
8550
+ }
8551
+ }
8552
+ setActiveIndex(closestIdx);
8553
+ if (containerRef.current) {
8554
+ const containerRect = containerRef.current.getBoundingClientRect();
8555
+ if (containerRect.width > 0) {
8556
+ const scaleX = containerRect.width / viewBoxWidth;
8557
+ const pixelX = getX(closestIdx) * scaleX;
8558
+ const pixelY = clientY - containerRect.top;
8559
+ setTooltipPos({ x: pixelX, y: Math.max(20, pixelY) });
8560
+ return;
8561
+ }
8562
+ }
8563
+ setTooltipPos({ x: getX(closestIdx), y: clientY });
8564
+ };
8565
+ const handleMouseMove = (e) => {
8566
+ handlePointerMove(e.clientX, e.clientY, e.currentTarget);
8567
+ };
8568
+ const handleTouch = (e) => {
8569
+ if (e.touches.length > 0) {
8570
+ const touch = e.touches[0];
8571
+ handlePointerMove(touch.clientX, touch.clientY, e.currentTarget);
8572
+ }
8573
+ };
8574
+ const handleMouseLeave = () => {
8575
+ setActiveIndex(null);
8576
+ setTooltipPos(null);
8577
+ };
8578
+ const activeRow = activeIndex !== null && data[activeIndex] ? data[activeIndex] : null;
8579
+ const tooltipTitle = activeRow !== null ? indexFormatter ? indexFormatter(activeRow[index]) : String(activeRow[index] ?? "") : "";
8580
+ const tooltipItems = activeRow !== null ? activeSeriesList.map((s, sIdx) => {
8581
+ const origIdx = series.findIndex((orig) => orig.key === s.key);
8582
+ const seriesColorIndex = origIdx >= 0 ? origIdx : sIdx;
8583
+ const raw = activeRow[s.key];
8584
+ const num = typeof raw === "number" ? raw : Number(raw) || 0;
8585
+ return {
8586
+ key: s.key,
8587
+ label: s.label,
8588
+ value: num,
8589
+ color: s.color ?? `chart${seriesColorIndex % 6 + 1}`,
8590
+ formattedValue: valueFormatter ? valueFormatter(num) : void 0
8591
+ };
8592
+ }) : [];
8593
+ const baselineY = getY(Math.max(0, domainMin));
8594
+ const shouldShowLegend = showLegend ?? series.length > 1;
8595
+ const shouldShowA11yTable = showA11yTable ?? Boolean(caption);
8596
+ return /* @__PURE__ */ jsxRuntime.jsxs(
8597
+ ChartContainer,
8598
+ {
8599
+ ref: combinedRef,
8600
+ width: typeof width === "number" ? width : void 0,
8601
+ height,
8602
+ viewBox: `0 0 ${viewBoxWidth} ${viewBoxHeight}`,
8603
+ "aria-label": computedAriaLabel,
8604
+ className: cn(
8605
+ "chart-line-root flex flex-col",
8606
+ variant === "area" ? "chart-area-root" : "chart-line-root",
8607
+ className
8608
+ ),
8609
+ style,
8610
+ ...props,
8611
+ children: [
8612
+ /* @__PURE__ */ jsxRuntime.jsx("defs", { children: variant === "area" && showGradient && series.map((s, idx) => {
8613
+ const gradColor = getChartColor(s.color, idx);
8614
+ return /* @__PURE__ */ jsxRuntime.jsxs(
8615
+ "linearGradient",
8616
+ {
8617
+ id: `${idPrefix}-grad-${s.key}`,
8618
+ x1: "0",
8619
+ y1: "0",
8620
+ x2: "0",
8621
+ y2: "1",
8622
+ children: [
8623
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "0%", stopColor: gradColor, stopOpacity: "0.28" }),
8624
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "100%", stopColor: gradColor, stopOpacity: "0.0" })
8625
+ ]
8626
+ },
8627
+ `grad-${s.key}`
8628
+ );
8629
+ }) }),
8630
+ showGrid && /* @__PURE__ */ jsxRuntime.jsx("g", { transform: `translate(${plotLeft}, 0)`, children: /* @__PURE__ */ jsxRuntime.jsx(
8631
+ ChartGrid,
8632
+ {
8633
+ horizontal: true,
8634
+ yTicks: yTicks.map((t) => t.value),
8635
+ scaleY: getY,
8636
+ width: plotWidth
8637
+ }
8638
+ ) }),
8639
+ activeSeriesList.map((s, sIdx) => {
8640
+ const origIdx = series.findIndex((orig) => orig.key === s.key);
8641
+ const seriesColorIndex = origIdx >= 0 ? origIdx : sIdx;
8642
+ const sColor = getChartColor(s.color, seriesColorIndex);
8643
+ const points = [];
8644
+ for (let i = 0; i < data.length; i++) {
8645
+ const rawVal = data[i][s.key];
8646
+ if (rawVal !== void 0 && rawVal !== null && Number.isFinite(Number(rawVal))) {
8647
+ points.push({ x: getX(i), y: getY(Number(rawVal)) });
8648
+ }
8649
+ }
8650
+ if (points.length === 0) return null;
8651
+ const linePath = generateLinePath(points, curve);
8652
+ const areaPath = variant === "area" ? generateAreaPath(points, baselineY, curve) : "";
8653
+ return /* @__PURE__ */ jsxRuntime.jsxs("g", { className: `chart-series chart-series-${s.key}`, children: [
8654
+ variant === "area" && areaPath && /* @__PURE__ */ jsxRuntime.jsx(
8655
+ "path",
8656
+ {
8657
+ d: areaPath,
8658
+ fill: showGradient ? `url(#${idPrefix}-grad-${s.key})` : sColor,
8659
+ fillOpacity: showGradient ? void 0 : 0.15,
8660
+ stroke: "none",
8661
+ className: "chart-area pointer-events-none transition-opacity duration-200"
8662
+ }
8663
+ ),
8664
+ linePath && /* @__PURE__ */ jsxRuntime.jsx(
8665
+ "path",
8666
+ {
8667
+ d: linePath,
8668
+ fill: "none",
8669
+ stroke: sColor,
8670
+ strokeWidth,
8671
+ strokeLinecap: "round",
8672
+ strokeLinejoin: "round",
8673
+ vectorEffect: "non-scaling-stroke",
8674
+ className: "chart-line pointer-events-none transition-opacity duration-200"
8675
+ }
8676
+ ),
8677
+ showDots && points.map((pt, ptIdx) => /* @__PURE__ */ jsxRuntime.jsx(
8678
+ "circle",
8679
+ {
8680
+ cx: pt.x,
8681
+ cy: pt.y,
8682
+ r: 3,
8683
+ fill: sColor,
8684
+ stroke: "var(--kj-background, #ffffff)",
8685
+ strokeWidth: 1.5,
8686
+ className: "chart-dot pointer-events-none"
8687
+ },
8688
+ `dot-${s.key}-${ptIdx}`
8689
+ )),
8690
+ activeIndex !== null && activeRow && activeRow[s.key] !== void 0 && activeRow[s.key] !== null && Number.isFinite(Number(activeRow[s.key])) && /* @__PURE__ */ jsxRuntime.jsx(
8691
+ "circle",
8692
+ {
8693
+ cx: getX(activeIndex),
8694
+ cy: getY(Number(activeRow[s.key])),
8695
+ r: 4.5,
8696
+ fill: sColor,
8697
+ stroke: "var(--kj-background, #ffffff)",
8698
+ strokeWidth: 2,
8699
+ className: "chart-active-dot pointer-events-none"
8700
+ }
8701
+ )
8702
+ ] }, `series-${s.key}`);
8703
+ }),
8704
+ showXAxis && /* @__PURE__ */ jsxRuntime.jsx(ChartXAxis, { ticks: xTicks, y: plotBottom + 16, formatter: indexFormatter }),
8705
+ showYAxis && /* @__PURE__ */ jsxRuntime.jsx(
8706
+ ChartYAxis,
8707
+ {
8708
+ ticks: yTicks,
8709
+ x: plotLeft - 8,
8710
+ formatter: valueFormatter
8711
+ }
8712
+ ),
8713
+ showTooltip && /* biome-ignore lint/a11y/noStaticElementInteractions: transparent SVG overlay tracks pointer for chart tooltip */
8714
+ /* @__PURE__ */ jsxRuntime.jsx(
8715
+ "rect",
8716
+ {
8717
+ className: "chart-interactive-overlay cursor-crosshair",
8718
+ x: plotLeft,
8719
+ y: plotTop,
8720
+ width: plotWidth,
8721
+ height: plotHeight,
8722
+ fill: "transparent",
8723
+ pointerEvents: "all",
8724
+ onMouseMove: handleMouseMove,
8725
+ onMouseLeave: handleMouseLeave,
8726
+ onTouchStart: handleTouch,
8727
+ onTouchMove: handleTouch,
8728
+ onTouchEnd: handleMouseLeave
8729
+ }
8730
+ ),
8731
+ showTooltip && activeIndex !== null && tooltipPos && /* @__PURE__ */ jsxRuntime.jsx(
8732
+ ChartTooltip,
8733
+ {
8734
+ open: activeIndex !== null,
8735
+ title: tooltipTitle,
8736
+ items: tooltipItems,
8737
+ x: tooltipPos.x,
8738
+ y: tooltipPos.y,
8739
+ showCrosshair: true,
8740
+ crosshairX: tooltipPos.x,
8741
+ crosshairHeight: plotBottom,
8742
+ valueFormatter
8743
+ }
8744
+ ),
8745
+ shouldShowLegend && /* @__PURE__ */ jsxRuntime.jsx(
8746
+ ChartLegend,
8747
+ {
8748
+ series,
8749
+ disabledSeries,
8750
+ onToggle: handleSeriesToggle
8751
+ }
8752
+ ),
8753
+ shouldShowA11yTable && /* @__PURE__ */ jsxRuntime.jsx(
8754
+ ChartA11yTable,
8755
+ {
8756
+ caption: caption ?? computedAriaLabel,
8757
+ series,
8758
+ data,
8759
+ indexKey: index,
8760
+ valueFormatter
8761
+ }
8762
+ )
8763
+ ]
8764
+ }
8765
+ );
8766
+ }
8767
+ );
8768
+ LineChart.displayName = "LineChart";
8769
+ var AreaChart = React52__namespace.forwardRef((props, ref) => /* @__PURE__ */ jsxRuntime.jsx(LineChart, { ref, variant: "area", ...props }));
8770
+ AreaChart.displayName = "AreaChart";
8771
+ var BarChart = React52__namespace.forwardRef(
8772
+ ({
8773
+ data,
8774
+ index,
8775
+ series,
8776
+ type = "grouped",
8777
+ layout = "vertical",
8778
+ radius = 4,
8779
+ showGrid = true,
8780
+ showXAxis = true,
8781
+ showYAxis = true,
8782
+ showLegend,
8783
+ showTooltip = true,
8784
+ showA11yTable,
8785
+ valueFormatter,
8786
+ indexFormatter,
8787
+ emptyMessage = "Brak danych do wy\u015Bwietlenia",
8788
+ height = 280,
8789
+ width = "100%",
8790
+ margin: marginProp,
8791
+ ariaLabel,
8792
+ caption,
8793
+ activeSeries: activeSeriesProp,
8794
+ onSeriesToggle,
8795
+ yTicksCount = 5,
8796
+ yDomain: yDomainProp,
8797
+ autoScale = false,
8798
+ barMaxWidth,
8799
+ groupPadding = 0.2,
8800
+ barPadding = 2,
8801
+ barClassName,
8802
+ className,
8803
+ style,
8804
+ ...props
8805
+ }, ref) => {
8806
+ const containerRef = React52__namespace.useRef(null);
8807
+ const combinedRef = (node) => {
8808
+ containerRef.current = node;
8809
+ if (typeof ref === "function") {
8810
+ ref(node);
8811
+ } else if (ref) {
8812
+ ref.current = node;
8813
+ }
8814
+ };
8815
+ const [internalDisabledSeries, setInternalDisabledSeries] = React52__namespace.useState([]);
8816
+ const disabledSeries = activeSeriesProp ? series.filter((s) => !activeSeriesProp.includes(s.key)).map((s) => s.key) : internalDisabledSeries;
8817
+ const handleSeriesToggle = (key) => {
8818
+ onSeriesToggle?.(key);
8819
+ setInternalDisabledSeries(
8820
+ (prev) => prev.includes(key) ? prev.filter((k) => k !== key) : [...prev, key]
8821
+ );
8822
+ };
8823
+ const activeSeriesList = React52__namespace.useMemo(
8824
+ () => series.filter((s) => !disabledSeries.includes(s.key)),
8825
+ [series, disabledSeries]
8826
+ );
8827
+ const [activeGroup, setActiveGroup] = React52__namespace.useState(null);
8828
+ const [activeSeriesKey, setActiveSeriesKey] = React52__namespace.useState(null);
8829
+ const [tooltipPos, setTooltipPos] = React52__namespace.useState(null);
8830
+ const computedAriaLabel = props["aria-label"] ?? ariaLabel ?? (type === "stacked" ? "Wykres s\u0142upkowy skumulowany" : "Wykres s\u0142upkowy");
8831
+ if (!data || data.length === 0) {
8832
+ return /* @__PURE__ */ jsxRuntime.jsx(
8833
+ ChartContainer,
8834
+ {
8835
+ ref: combinedRef,
8836
+ width: typeof width === "number" ? width : void 0,
8837
+ height,
8838
+ "aria-label": computedAriaLabel,
8839
+ className: cn("chart-bar-empty", className),
8840
+ style,
8841
+ ...props,
8842
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "chart-empty-message flex h-full min-h-[160px] w-full items-center justify-center text-sm text-muted-foreground select-none", children: emptyMessage })
8843
+ }
8844
+ );
8845
+ }
8846
+ const measuredWidth = useChartWidth(
8847
+ containerRef,
8848
+ typeof width === "number" && width > 0 ? width : 600
8849
+ );
8850
+ const viewBoxWidth = typeof width === "number" && width > 0 ? width : measuredWidth > 0 ? measuredWidth : 600;
8851
+ const viewBoxHeight = typeof height === "number" && height > 0 ? height : 280;
8852
+ const margin = {
8853
+ top: 16,
8854
+ right: 20,
8855
+ bottom: showXAxis ? 32 : 16,
8856
+ left: showYAxis ? layout === "horizontal" ? 64 : 48 : 16,
8857
+ ...marginProp
8858
+ };
8859
+ const plotLeft = margin.left;
8860
+ const plotRight = viewBoxWidth - margin.right;
8861
+ const plotTop = margin.top;
8862
+ const plotBottom = viewBoxHeight - margin.bottom;
8863
+ const plotWidth = Math.max(0, plotRight - plotLeft);
8864
+ const plotHeight = Math.max(0, plotBottom - plotTop);
8865
+ let dataMin = 0;
8866
+ let dataMax = 100;
8867
+ if (type === "stacked") {
8868
+ const stackSums = [];
8869
+ for (const row of data) {
8870
+ let sum = 0;
8871
+ for (const s of activeSeriesList) {
8872
+ const val = row[s.key];
8873
+ if (typeof val === "number" && Number.isFinite(val)) {
8874
+ sum += Math.max(0, val);
8875
+ }
8876
+ }
8877
+ stackSums.push(sum);
8878
+ }
8879
+ dataMax = stackSums.length > 0 ? Math.max(...stackSums, 0) : 100;
8880
+ if (dataMax === 0) dataMax = 100;
8881
+ } else {
8882
+ const allValues = [];
8883
+ for (const row of data) {
8884
+ for (const s of activeSeriesList) {
8885
+ const val = row[s.key];
8886
+ if (typeof val === "number" && Number.isFinite(val)) {
8887
+ allValues.push(val);
8888
+ }
8889
+ }
8890
+ }
8891
+ dataMax = allValues.length > 0 ? Math.max(...allValues, 0) : 100;
8892
+ if (allValues.length > 0 && autoScale) {
8893
+ dataMin = Math.min(...allValues, 0);
8894
+ }
8895
+ if (dataMax === 0) dataMax = 100;
8896
+ }
8897
+ const niceScale = getNiceScale(dataMin, dataMax, yTicksCount);
8898
+ const domainMin = yDomainProp ? yDomainProp[0] : niceScale.min;
8899
+ const domainMax = yDomainProp ? yDomainProp[1] : niceScale.max;
8900
+ const yDomain = [domainMin, domainMax];
8901
+ const barDataPoints = [];
8902
+ for (let group = 0; group < data.length; group++) {
8903
+ const row = data[group];
8904
+ for (let sIdx = 0; sIdx < activeSeriesList.length; sIdx++) {
8905
+ const s = activeSeriesList[sIdx];
8906
+ const rawVal = row[s.key];
8907
+ const num = typeof rawVal === "number" && Number.isFinite(rawVal) ? rawVal : Number(rawVal) || 0;
8908
+ barDataPoints.push({
8909
+ group,
8910
+ seriesIndex: sIdx,
8911
+ value: num,
8912
+ seriesKey: s.key,
8913
+ seriesLabel: s.label,
8914
+ categoryValue: row[index]
8915
+ });
8916
+ }
8917
+ }
8918
+ const barRects = calculateBarLayout({
8919
+ dataCount: data.length,
8920
+ seriesCount: activeSeriesList.length,
8921
+ plotWidth,
8922
+ plotHeight,
8923
+ yDomain,
8924
+ data: barDataPoints,
8925
+ mode: type,
8926
+ layout,
8927
+ barMaxWidth,
8928
+ groupPadding,
8929
+ barPadding
8930
+ });
8931
+ const isVertical = layout === "vertical";
8932
+ const slotSize = data.length > 0 ? isVertical ? plotWidth / data.length : plotHeight / data.length : 0;
8933
+ const categoryTicks = data.map((row, idx) => ({
8934
+ value: row[index] ?? "",
8935
+ coord: isVertical ? plotLeft + (idx + 0.5) * slotSize : plotTop + (idx + 0.5) * slotSize
8936
+ }));
8937
+ const valueTicks = (yDomainProp ? getNiceScale(yDomainProp[0], yDomainProp[1], yTicksCount).ticks : niceScale.ticks).map((val) => ({
8938
+ value: val,
8939
+ coord: isVertical ? linearScale(val, yDomain, [plotBottom, plotTop]) : linearScale(val, yDomain, [plotLeft, plotRight])
8940
+ }));
8941
+ const updateTooltipPosition = (bar) => {
8942
+ let targetX;
8943
+ let targetY;
8944
+ if (layout === "horizontal") {
8945
+ targetX = plotLeft + bar.x + bar.width;
8946
+ targetY = plotTop + bar.y + bar.height / 2;
8947
+ } else {
8948
+ targetX = plotLeft + bar.x + bar.width / 2;
8949
+ targetY = plotTop + bar.y;
8950
+ }
8951
+ if (containerRef.current) {
8952
+ const containerRect = containerRef.current.getBoundingClientRect();
8953
+ if (containerRect.width > 0 && containerRect.height > 0) {
8954
+ const scaleX = containerRect.width / viewBoxWidth;
8955
+ const scaleY = containerRect.height / viewBoxHeight;
8956
+ setTooltipPos({ x: targetX * scaleX, y: targetY * scaleY });
8957
+ return;
8958
+ }
8959
+ }
8960
+ setTooltipPos({ x: targetX, y: targetY });
8961
+ };
8962
+ const handleBarMouseEnter = (bar) => {
8963
+ if (!showTooltip) return;
8964
+ setActiveGroup(bar.group);
8965
+ setActiveSeriesKey(bar.seriesKey);
8966
+ updateTooltipPosition(bar);
8967
+ };
8968
+ const handleBarMouseLeave = () => {
8969
+ setActiveGroup(null);
8970
+ setActiveSeriesKey(null);
8971
+ setTooltipPos(null);
8972
+ };
8973
+ const handleBarTouchStart = (bar) => {
8974
+ if (!showTooltip) return;
8975
+ setActiveGroup(bar.group);
8976
+ setActiveSeriesKey(bar.seriesKey);
8977
+ updateTooltipPosition(bar);
8978
+ };
8979
+ const handleBarTouchEnd = () => {
8980
+ setActiveGroup(null);
8981
+ setActiveSeriesKey(null);
8982
+ setTooltipPos(null);
8983
+ };
8984
+ const activeRow = activeGroup !== null && data[activeGroup] ? data[activeGroup] : null;
8985
+ const tooltipTitle = activeRow !== null ? indexFormatter ? indexFormatter(activeRow[index]) : String(activeRow[index] ?? "") : "";
8986
+ const tooltipItems = activeRow !== null ? activeSeriesList.map((s, sIdx) => {
8987
+ const origIdx = series.findIndex((orig) => orig.key === s.key);
8988
+ const seriesColorIndex = origIdx >= 0 ? origIdx : sIdx;
8989
+ const raw = activeRow[s.key];
8990
+ const num = typeof raw === "number" ? raw : Number(raw) || 0;
8991
+ return {
8992
+ key: s.key,
8993
+ label: s.label,
8994
+ value: num,
8995
+ color: s.color ?? `chart${seriesColorIndex % 6 + 1}`,
8996
+ formattedValue: valueFormatter ? valueFormatter(num) : void 0
8997
+ };
8998
+ }) : [];
8999
+ const shouldShowLegend = showLegend ?? series.length > 1;
9000
+ const shouldShowA11yTable = showA11yTable ?? Boolean(caption);
9001
+ return /* @__PURE__ */ jsxRuntime.jsxs(
9002
+ ChartContainer,
9003
+ {
9004
+ ref: combinedRef,
9005
+ width: typeof width === "number" ? width : void 0,
9006
+ height,
9007
+ viewBox: `0 0 ${viewBoxWidth} ${viewBoxHeight}`,
9008
+ "aria-label": computedAriaLabel,
9009
+ className: cn(
9010
+ "chart-bar-root flex flex-col",
9011
+ type === "stacked" ? "chart-bar-stacked" : "chart-bar-grouped",
9012
+ layout === "horizontal" ? "chart-bar-horizontal" : "chart-bar-vertical",
9013
+ className
9014
+ ),
9015
+ style,
9016
+ ...props,
9017
+ children: [
9018
+ showGrid && (isVertical ? /* @__PURE__ */ jsxRuntime.jsx("g", { transform: `translate(${plotLeft}, 0)`, children: /* @__PURE__ */ jsxRuntime.jsx(
9019
+ ChartGrid,
9020
+ {
9021
+ horizontal: true,
9022
+ yTicks: valueTicks.map((t) => t.value),
9023
+ scaleY: (val) => linearScale(val, yDomain, [plotBottom, plotTop]),
9024
+ width: plotWidth
9025
+ }
9026
+ ) }) : /* @__PURE__ */ jsxRuntime.jsx("g", { transform: `translate(0, ${plotTop})`, children: /* @__PURE__ */ jsxRuntime.jsx(
9027
+ ChartGrid,
9028
+ {
9029
+ vertical: true,
9030
+ horizontal: false,
9031
+ xTicks: valueTicks.map((t) => t.value),
9032
+ scaleX: (val) => linearScale(val, yDomain, [plotLeft, plotRight]),
9033
+ height: plotHeight
9034
+ }
9035
+ ) })),
9036
+ /* @__PURE__ */ jsxRuntime.jsx("g", { transform: `translate(${plotLeft}, ${plotTop})`, className: "chart-bars-group", children: barRects.map((bar) => {
9037
+ const origIdx = series.findIndex((orig) => orig.key === bar.seriesKey);
9038
+ const seriesColorIndex = origIdx >= 0 ? origIdx : bar.seriesIndex;
9039
+ const matchingSeries = series[origIdx] ?? activeSeriesList[bar.seriesIndex];
9040
+ const sColor = getChartColor(matchingSeries?.color, seriesColorIndex);
9041
+ const barW = Math.max(0, bar.width);
9042
+ const barH = Math.max(0, bar.height);
9043
+ const safeRadius = radius > 0 ? Math.min(radius, Math.max(0, barW / 2), Math.max(0, barH / 2)) : 0;
9044
+ const isDimmed = activeGroup !== null && (bar.group !== activeGroup || type === "grouped" && activeSeriesKey !== null && bar.seriesKey !== activeSeriesKey);
9045
+ return /* @__PURE__ */ jsxRuntime.jsx(
9046
+ "rect",
9047
+ {
9048
+ className: cn(
9049
+ "chart-bar transition-opacity duration-150 cursor-pointer",
9050
+ barClassName
9051
+ ),
9052
+ x: bar.x,
9053
+ y: bar.y,
9054
+ width: barW,
9055
+ height: barH,
9056
+ rx: safeRadius,
9057
+ ry: safeRadius,
9058
+ fill: sColor,
9059
+ opacity: isDimmed ? 0.45 : 1,
9060
+ tabIndex: 0,
9061
+ role: "graphics-symbol",
9062
+ "aria-label": `${bar.seriesLabel ?? bar.seriesKey}: ${valueFormatter ? valueFormatter(bar.value) : bar.value}, ${bar.categoryValue}`,
9063
+ onMouseEnter: () => handleBarMouseEnter(bar),
9064
+ onMouseMove: () => handleBarMouseEnter(bar),
9065
+ onMouseLeave: handleBarMouseLeave,
9066
+ onTouchStart: () => handleBarTouchStart(bar),
9067
+ onTouchEnd: handleBarTouchEnd,
9068
+ onFocus: () => handleBarMouseEnter(bar),
9069
+ onBlur: handleBarMouseLeave
9070
+ },
9071
+ `bar-${bar.group}-${bar.seriesKey}`
9072
+ );
9073
+ }) }),
9074
+ showXAxis && /* @__PURE__ */ jsxRuntime.jsx(
9075
+ ChartXAxis,
9076
+ {
9077
+ ticks: isVertical ? categoryTicks.map((t) => ({ value: t.value, x: t.coord })) : valueTicks.map((t) => ({ value: t.value, x: t.coord })),
9078
+ y: plotBottom + 16,
9079
+ formatter: isVertical ? indexFormatter : valueFormatter
9080
+ }
9081
+ ),
9082
+ showYAxis && /* @__PURE__ */ jsxRuntime.jsx(
9083
+ ChartYAxis,
9084
+ {
9085
+ ticks: isVertical ? valueTicks.map((t) => ({ value: t.value, y: t.coord })) : categoryTicks.map((t) => ({ value: t.value, y: t.coord })),
9086
+ x: plotLeft - 8,
9087
+ formatter: isVertical ? valueFormatter : indexFormatter
9088
+ }
9089
+ ),
9090
+ showTooltip && activeGroup !== null && tooltipPos && /* @__PURE__ */ jsxRuntime.jsx(
9091
+ ChartTooltip,
9092
+ {
9093
+ open: activeGroup !== null,
9094
+ title: tooltipTitle,
9095
+ items: tooltipItems,
9096
+ x: tooltipPos.x,
9097
+ y: tooltipPos.y,
9098
+ valueFormatter
9099
+ }
9100
+ ),
9101
+ shouldShowLegend && /* @__PURE__ */ jsxRuntime.jsx(
9102
+ ChartLegend,
9103
+ {
9104
+ series,
9105
+ disabledSeries,
9106
+ onToggle: handleSeriesToggle
9107
+ }
9108
+ ),
9109
+ shouldShowA11yTable && /* @__PURE__ */ jsxRuntime.jsx(
9110
+ ChartA11yTable,
9111
+ {
9112
+ caption: caption ?? computedAriaLabel,
9113
+ series,
9114
+ data,
9115
+ indexKey: index,
9116
+ valueFormatter
9117
+ }
9118
+ )
9119
+ ]
9120
+ }
9121
+ );
9122
+ }
9123
+ );
9124
+ BarChart.displayName = "BarChart";
9125
+ var SIZE_MAP = {
9126
+ sm: 160,
9127
+ md: 220,
9128
+ lg: 280
9129
+ };
9130
+ function getDimension(size = "md") {
9131
+ if (typeof size === "number") {
9132
+ return size > 0 ? size : 220;
9133
+ }
9134
+ return SIZE_MAP[size] ?? 220;
9135
+ }
9136
+ var DonutChart = React52__namespace.forwardRef(
9137
+ ({
9138
+ data,
9139
+ category,
9140
+ value,
9141
+ centerLabel,
9142
+ size = "md",
9143
+ innerRadius: innerRadiusProp,
9144
+ colors,
9145
+ showLegend = true,
9146
+ showTooltip = true,
9147
+ showA11yTable,
9148
+ valueFormatter,
9149
+ emptyMessage = "Brak danych do wy\u015Bwietlenia",
9150
+ ariaLabel,
9151
+ caption,
9152
+ valueLabel = "Warto\u015B\u0107",
9153
+ activeCategories: activeCategoriesProp,
9154
+ onCategoryToggle,
9155
+ sliceClassName,
9156
+ className,
9157
+ style,
9158
+ ...props
9159
+ }, ref) => {
9160
+ const containerRef = React52__namespace.useRef(null);
9161
+ const combinedRef = (node) => {
9162
+ containerRef.current = node;
9163
+ if (typeof ref === "function") {
9164
+ ref(node);
9165
+ } else if (ref) {
9166
+ ref.current = node;
9167
+ }
9168
+ };
9169
+ const [internalDisabled, setInternalDisabled] = React52__namespace.useState([]);
9170
+ const [activeIdx, setActiveIdx] = React52__namespace.useState(null);
9171
+ const [tooltipPos, setTooltipPos] = React52__namespace.useState(null);
9172
+ const safeData = data || [];
9173
+ const dimension = getDimension(size);
9174
+ const cx = dimension / 2;
9175
+ const cy = dimension / 2;
9176
+ const padding = 8;
9177
+ const outerRadius = Math.max(10, dimension / 2 - padding);
9178
+ let computedInnerRadius;
9179
+ if (innerRadiusProp !== void 0) {
9180
+ if (innerRadiusProp >= 0 && innerRadiusProp <= 1) {
9181
+ computedInnerRadius = outerRadius * innerRadiusProp;
9182
+ } else {
9183
+ computedInnerRadius = Math.min(innerRadiusProp, Math.max(0, outerRadius - 4));
9184
+ }
9185
+ } else {
9186
+ computedInnerRadius = outerRadius * 0.65;
9187
+ }
9188
+ const legendSeries = React52__namespace.useMemo(() => {
9189
+ return safeData.map((item, idx) => {
9190
+ const cat = String(item[category] ?? `Item ${idx + 1}`);
9191
+ const rawColor = item.color ?? (colors ? colors[idx % colors.length] : DEFAULT_CHART_COLORS[idx % DEFAULT_CHART_COLORS.length]);
9192
+ return {
9193
+ key: cat,
9194
+ label: cat,
9195
+ color: rawColor
9196
+ };
9197
+ });
9198
+ }, [safeData, category, colors]);
9199
+ const disabledCategories = activeCategoriesProp ? legendSeries.filter((s) => !activeCategoriesProp.includes(s.key)).map((s) => s.key) : internalDisabled;
9200
+ const handleLegendToggle = (catKey) => {
9201
+ onCategoryToggle?.(catKey);
9202
+ setInternalDisabled(
9203
+ (prev) => prev.includes(catKey) ? prev.filter((k) => k !== catKey) : [...prev, catKey]
9204
+ );
9205
+ };
9206
+ const sliceInputs = React52__namespace.useMemo(() => {
9207
+ return safeData.map((item, idx) => {
9208
+ const cat = String(item[category] ?? `Item ${idx + 1}`);
9209
+ const isDisabled = disabledCategories.includes(cat);
9210
+ const rawVal = item[value];
9211
+ const numVal = typeof rawVal === "number" && Number.isFinite(rawVal) ? rawVal : Number(rawVal) || 0;
9212
+ const rawColor = item.color ?? (colors ? colors[idx % colors.length] : DEFAULT_CHART_COLORS[idx % DEFAULT_CHART_COLORS.length]);
9213
+ return {
9214
+ label: cat,
9215
+ value: isDisabled ? 0 : Math.max(0, numVal),
9216
+ color: getChartColor(rawColor, idx),
9217
+ originalValue: numVal,
9218
+ originalIndex: idx
9219
+ };
9220
+ });
9221
+ }, [safeData, category, value, colors, disabledCategories]);
9222
+ const segments = React52__namespace.useMemo(() => {
9223
+ return calculateDonutSegments(sliceInputs, {
9224
+ cx,
9225
+ cy,
9226
+ innerRadius: computedInnerRadius,
9227
+ outerRadius,
9228
+ startAngle: -90
9229
+ });
9230
+ }, [sliceInputs, cx, cy, computedInnerRadius, outerRadius]);
9231
+ const computedAriaLabel = props["aria-label"] ?? ariaLabel ?? "Wykres pier\u015Bcieniowy";
9232
+ if (!data || data.length === 0) {
9233
+ return /* @__PURE__ */ jsxRuntime.jsx(
9234
+ ChartContainer,
9235
+ {
9236
+ ref: combinedRef,
9237
+ "aria-label": computedAriaLabel,
9238
+ className: cn("chart-donut-empty flex flex-col items-center justify-center", className),
9239
+ style,
9240
+ ...props,
9241
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "chart-empty-message flex min-h-[160px] w-full items-center justify-center text-sm text-muted-foreground select-none", children: emptyMessage })
9242
+ }
9243
+ );
9244
+ }
9245
+ const updateTooltipPosition = (segment, clientX, clientY) => {
9246
+ const midRad = segment.middleAngle * Math.PI / 180;
9247
+ const midRadius = (computedInnerRadius + outerRadius) / 2;
9248
+ const targetX = cx + midRadius * Math.cos(midRad);
9249
+ const targetY = cy + midRadius * Math.sin(midRad);
9250
+ if (containerRef.current) {
9251
+ const containerRect = containerRef.current.getBoundingClientRect();
9252
+ if (containerRect.width > 0 && containerRect.height > 0 && clientX !== void 0 && clientY !== void 0) {
9253
+ setTooltipPos({
9254
+ x: clientX - containerRect.left,
9255
+ y: clientY - containerRect.top
9256
+ });
9257
+ return;
9258
+ }
9259
+ }
9260
+ setTooltipPos({ x: targetX, y: targetY });
9261
+ };
9262
+ const handleSliceMouseEnter = (idx, segment, e) => {
9263
+ if (!showTooltip) return;
9264
+ setActiveIdx(idx);
9265
+ updateTooltipPosition(segment, e.clientX, e.clientY);
9266
+ };
9267
+ const handleSliceMouseMove = (_idx, segment, e) => {
9268
+ if (!showTooltip) return;
9269
+ updateTooltipPosition(segment, e.clientX, e.clientY);
9270
+ };
9271
+ const handleSliceMouseLeave = () => {
9272
+ setActiveIdx(null);
9273
+ setTooltipPos(null);
9274
+ };
9275
+ const handleSliceTouchStart = (idx, segment, e) => {
9276
+ if (!showTooltip) return;
9277
+ setActiveIdx(idx);
9278
+ if (e.touches.length > 0) {
9279
+ const touch = e.touches[0];
9280
+ updateTooltipPosition(segment, touch.clientX, touch.clientY);
9281
+ } else {
9282
+ updateTooltipPosition(segment);
9283
+ }
9284
+ };
9285
+ const handleSliceTouchEnd = () => {
9286
+ setActiveIdx(null);
9287
+ setTooltipPos(null);
9288
+ };
9289
+ const activeSegment = activeIdx !== null && segments[activeIdx] ? segments[activeIdx] : null;
9290
+ const shouldShowA11yTable = showA11yTable ?? Boolean(caption);
9291
+ const a11ySeries = [
9292
+ { key: value, label: valueLabel },
9293
+ { key: "__percentage__", label: "Udzia\u0142 (%)" }
9294
+ ];
9295
+ const a11yData = data.map((row) => {
9296
+ const cat = String(row[category] ?? "");
9297
+ const seg = segments.find((s) => s.label === cat);
9298
+ return {
9299
+ ...row,
9300
+ __percentage__: seg ? `${seg.percentage}%` : "0%"
9301
+ };
9302
+ });
9303
+ const sizeClass = typeof size === "number" ? void 0 : size === "sm" ? "max-w-[160px] max-h-[160px]" : size === "lg" ? "max-w-[280px] max-h-[280px]" : "max-w-[220px] max-h-[220px]";
9304
+ return /* @__PURE__ */ jsxRuntime.jsxs(
9305
+ ChartContainer,
9306
+ {
9307
+ ref: combinedRef,
9308
+ width: dimension,
9309
+ height: dimension,
9310
+ viewBox: `0 0 ${dimension} ${dimension}`,
9311
+ "aria-label": computedAriaLabel,
9312
+ className: cn(
9313
+ "chart-donut-root relative flex flex-col items-center justify-start mx-auto w-full",
9314
+ className
9315
+ ),
9316
+ svgClassName: cn("chart-donut-svg mx-auto shrink-0", sizeClass),
9317
+ style: {
9318
+ "--donut-dim": `${dimension}px`,
9319
+ ...style
9320
+ },
9321
+ ...props,
9322
+ children: [
9323
+ /* @__PURE__ */ jsxRuntime.jsx("g", { className: "chart-donut-slices", children: segments.map((segment, idx) => {
9324
+ const isHovered = activeIdx === idx;
9325
+ const isDimmed = activeIdx !== null && !isHovered;
9326
+ const origVal = segment.originalValue ?? segment.value;
9327
+ const displayVal = valueFormatter ? valueFormatter(origVal) : String(origVal);
9328
+ const hasPath = Boolean(segment.path);
9329
+ return /* @__PURE__ */ jsxRuntime.jsx(
9330
+ "path",
9331
+ {
9332
+ className: cn(
9333
+ "chart-donut-slice transition-all duration-150 cursor-pointer outline-none",
9334
+ sliceClassName
9335
+ ),
9336
+ d: segment.path || "",
9337
+ fill: segment.color,
9338
+ opacity: !hasPath ? 0 : isDimmed ? 0.4 : 1,
9339
+ style: {
9340
+ transformOrigin: `${cx}px ${cy}px`,
9341
+ transform: isHovered && hasPath ? "scale(1.03)" : "scale(1)",
9342
+ filter: isHovered && hasPath ? "brightness(1.1)" : void 0,
9343
+ pointerEvents: hasPath ? void 0 : "none"
9344
+ },
9345
+ tabIndex: hasPath ? 0 : -1,
9346
+ role: "graphics-symbol",
9347
+ "aria-label": `${segment.label}: ${displayVal} (${segment.percentage}%)`,
9348
+ onMouseEnter: hasPath ? (e) => handleSliceMouseEnter(idx, segment, e) : void 0,
9349
+ onMouseMove: hasPath ? (e) => handleSliceMouseMove(idx, segment, e) : void 0,
9350
+ onMouseLeave: hasPath ? handleSliceMouseLeave : void 0,
9351
+ onTouchStart: hasPath ? (e) => handleSliceTouchStart(idx, segment, e) : void 0,
9352
+ onTouchEnd: hasPath ? handleSliceTouchEnd : void 0,
9353
+ onFocus: hasPath ? (e) => handleSliceMouseEnter(
9354
+ idx,
9355
+ segment,
9356
+ e
9357
+ ) : void 0,
9358
+ onBlur: hasPath ? handleSliceMouseLeave : void 0
9359
+ },
9360
+ `slice-${idx}-${segment.label}`
9361
+ );
9362
+ }) }),
9363
+ centerLabel && /* @__PURE__ */ jsxRuntime.jsx(
9364
+ "div",
9365
+ {
9366
+ className: "chart-donut-center pointer-events-none absolute flex flex-col items-center justify-center text-center select-none",
9367
+ style: {
9368
+ width: `${Math.max(20, Math.floor(computedInnerRadius * 1.8))}px`,
9369
+ height: `${Math.max(20, Math.floor(computedInnerRadius * 1.8))}px`,
9370
+ left: "50%",
9371
+ top: `${dimension / 2}px`,
9372
+ transform: "translate(-50%, -50%)"
9373
+ },
9374
+ children: centerLabel
9375
+ }
9376
+ ),
9377
+ showTooltip && activeSegment && tooltipPos && activeSegment.path && /* @__PURE__ */ jsxRuntime.jsx(
9378
+ ChartTooltip,
9379
+ {
9380
+ open: Boolean(activeSegment),
9381
+ x: tooltipPos.x,
9382
+ y: tooltipPos.y,
9383
+ items: [
9384
+ {
9385
+ key: activeSegment.label,
9386
+ label: activeSegment.label,
9387
+ value: activeSegment.originalValue ?? activeSegment.value,
9388
+ formattedValue: `${valueFormatter ? valueFormatter(activeSegment.originalValue ?? activeSegment.value) : activeSegment.originalValue ?? activeSegment.value} (${activeSegment.percentage}%)`,
9389
+ color: activeSegment.color
9390
+ }
9391
+ ]
9392
+ }
9393
+ ),
9394
+ showLegend && /* @__PURE__ */ jsxRuntime.jsx(
9395
+ ChartLegend,
9396
+ {
9397
+ series: legendSeries,
9398
+ disabledSeries: disabledCategories,
9399
+ onToggle: handleLegendToggle
9400
+ }
9401
+ ),
9402
+ shouldShowA11yTable && /* @__PURE__ */ jsxRuntime.jsx(
9403
+ ChartA11yTable,
9404
+ {
9405
+ caption: caption ?? computedAriaLabel,
9406
+ series: a11ySeries,
9407
+ data: a11yData,
9408
+ indexKey: category,
9409
+ valueFormatter: (v) => typeof v === "number" && valueFormatter ? valueFormatter(v) : String(v)
9410
+ }
9411
+ )
9412
+ ]
9413
+ }
9414
+ );
9415
+ }
9416
+ );
9417
+ DonutChart.displayName = "DonutChart";
9418
+
7308
9419
  exports.Accordion = Accordion;
7309
9420
  exports.AccordionContent = AccordionContent;
7310
9421
  exports.AccordionItem = AccordionItem;
@@ -7315,9 +9426,11 @@ exports.AppShellBanner = AppShellBanner;
7315
9426
  exports.AppShellFooter = AppShellFooter;
7316
9427
  exports.AppShellHeader = AppShellHeader;
7317
9428
  exports.AppShellMain = AppShellMain;
9429
+ exports.AreaChart = AreaChart;
7318
9430
  exports.Avatar = Avatar;
7319
9431
  exports.AvatarGroup = AvatarGroup;
7320
9432
  exports.Badge = Badge;
9433
+ exports.BarChart = BarChart;
7321
9434
  exports.BlogCard = BlogCard;
7322
9435
  exports.BottomNavigation = BottomNavigation;
7323
9436
  exports.BottomSheet = BottomSheet;
@@ -7330,6 +9443,7 @@ exports.Breadcrumb = Breadcrumb;
7330
9443
  exports.BreadcrumbItem = BreadcrumbItem;
7331
9444
  exports.BreadcrumbSeparator = BreadcrumbSeparator;
7332
9445
  exports.Button = Button;
9446
+ exports.CHART_COLOR_VARS = CHART_COLOR_VARS;
7333
9447
  exports.Calendar = Calendar;
7334
9448
  exports.Card = Card;
7335
9449
  exports.CardContent = CardContent;
@@ -7337,6 +9451,13 @@ exports.CardDescription = CardDescription;
7337
9451
  exports.CardFooter = CardFooter;
7338
9452
  exports.CardHeader = CardHeader;
7339
9453
  exports.CardTitle = CardTitle;
9454
+ exports.ChartA11yTable = ChartA11yTable;
9455
+ exports.ChartContainer = ChartContainer;
9456
+ exports.ChartGrid = ChartGrid;
9457
+ exports.ChartLegend = ChartLegend;
9458
+ exports.ChartTooltip = ChartTooltip;
9459
+ exports.ChartXAxis = ChartXAxis;
9460
+ exports.ChartYAxis = ChartYAxis;
7340
9461
  exports.Checkbox = Checkbox;
7341
9462
  exports.CheckboxField = CheckboxField;
7342
9463
  exports.CodeBlock = CodeBlock;
@@ -7347,6 +9468,7 @@ exports.Combobox = Combobox;
7347
9468
  exports.ComboboxField = ComboboxField;
7348
9469
  exports.CommandPalette = CommandPalette;
7349
9470
  exports.ConfirmDialog = ConfirmDialog;
9471
+ exports.DEFAULT_CHART_COLORS = DEFAULT_CHART_COLORS;
7350
9472
  exports.DEFAULT_COLOR_SWATCHES = DEFAULT_COLOR_SWATCHES;
7351
9473
  exports.DashboardShell = DashboardShell;
7352
9474
  exports.DataTable = DataTable;
@@ -7355,6 +9477,7 @@ exports.DatePickerField = DatePickerField;
7355
9477
  exports.DateRangePicker = DateRangePicker;
7356
9478
  exports.DateRangePickerField = DateRangePickerField;
7357
9479
  exports.DetailPageLayout = DetailPageLayout;
9480
+ exports.DonutChart = DonutChart;
7358
9481
  exports.Drawer = Drawer;
7359
9482
  exports.DropdownMenu = DropdownMenu;
7360
9483
  exports.DropdownMenuContent = DropdownMenuContent;
@@ -7379,6 +9502,7 @@ exports.InboxTrigger = InboxTrigger;
7379
9502
  exports.Input = Input;
7380
9503
  exports.Kbd = Kbd;
7381
9504
  exports.Label = Label;
9505
+ exports.LineChart = LineChart;
7382
9506
  exports.MetricCard = MetricCard;
7383
9507
  exports.Modal = Modal;
7384
9508
  exports.ModalActions = ModalActions;
@@ -7409,6 +9533,7 @@ exports.SettingsLayout = SettingsLayout;
7409
9533
  exports.SidebarNav = SidebarNav;
7410
9534
  exports.Skeleton = Skeleton;
7411
9535
  exports.Slider = Slider;
9536
+ exports.Sparkline = Sparkline;
7412
9537
  exports.Spinner = Spinner;
7413
9538
  exports.Stat = Stat;
7414
9539
  exports.Stepper = Stepper;
@@ -7449,12 +9574,15 @@ exports.Tooltip = Tooltip;
7449
9574
  exports.badgeVariants = badgeVariants;
7450
9575
  exports.buttonVariants = buttonVariants;
7451
9576
  exports.cn = cn;
9577
+ exports.fabVariants = fabVariants;
7452
9578
  exports.formatRelativeTime = formatRelativeTime;
9579
+ exports.getChartColor = getChartColor;
7453
9580
  exports.hexToHsl = hexToHsl;
7454
9581
  exports.hslToHex = hslToHex;
7455
9582
  exports.isValidHex = isValidHex;
7456
9583
  exports.normalizeHex = normalizeHex;
7457
9584
  exports.sliderThumbCSS = sliderThumbCSS;
9585
+ exports.useChartWidth = useChartWidth;
7458
9586
  exports.useInPostScript = useInPostScript;
7459
9587
  exports.useInboxState = useInboxState;
7460
9588
  exports.useStepper = useStepper;