@marcoschwartz/lite-ui 0.15.0 → 0.17.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.js CHANGED
@@ -610,11 +610,23 @@ var Navbar = ({
610
610
  logo,
611
611
  children,
612
612
  className = "",
613
- sticky = false
613
+ sticky = false,
614
+ variant = "solid"
614
615
  }) => {
615
616
  const { theme } = useTheme();
616
617
  const baseClasses = sticky ? "sticky top-0 z-40" : "";
617
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("nav", { className: `bg-white dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700 ${baseClasses} ${className}`, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex justify-between items-center h-16", children: [
618
+ const getVariantClasses = () => {
619
+ switch (variant) {
620
+ case "glass":
621
+ return "bg-transparent backdrop-blur-xl";
622
+ case "transparent":
623
+ return "bg-transparent";
624
+ case "solid":
625
+ default:
626
+ return "bg-white dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700";
627
+ }
628
+ };
629
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("nav", { className: `${getVariantClasses()} ${baseClasses} ${className}`, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex justify-between items-center h-16", children: [
618
630
  logo && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "flex items-center", children: logo }),
619
631
  children && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "flex items-center gap-6", children })
620
632
  ] }) }) });
@@ -5300,14 +5312,32 @@ var LineChart = ({
5300
5312
  strokeWidth = 2,
5301
5313
  className = "",
5302
5314
  xAxisLabel,
5303
- yAxisLabel
5315
+ yAxisLabel,
5316
+ baseFontSize = 14
5304
5317
  }) => {
5305
- const height = providedHeight ?? 400;
5306
- const width = providedWidth ?? (responsive ? 600 : 600);
5318
+ const viewBoxWidth = 1e3;
5319
+ const viewBoxHeight = 600;
5320
+ const containerRef = import_react26.default.useRef(null);
5321
+ const svgRef = import_react26.default.useRef(null);
5322
+ const [tooltipPosition, setTooltipPosition] = import_react26.default.useState(null);
5307
5323
  const [hoveredPoint, setHoveredPoint] = import_react26.default.useState(null);
5308
- const padding = { top: 20, right: 20, bottom: showXAxis ? 60 : 20, left: showYAxis ? 60 : 20 };
5309
- const chartWidth = width - padding.left - padding.right;
5310
- const chartHeight = height - padding.top - padding.bottom;
5324
+ const chartId = import_react26.default.useId();
5325
+ const wrapperClass = `chart-svg-wrapper-${chartId.replace(/:/g, "-")}`;
5326
+ const gridLabelClass = `chart-grid-label-${chartId.replace(/:/g, "-")}`;
5327
+ const axisLabelClass = `chart-axis-label-${chartId.replace(/:/g, "-")}`;
5328
+ const lineClass = `chart-line-${chartId.replace(/:/g, "-")}`;
5329
+ const pointClass = `chart-point-${chartId.replace(/:/g, "-")}`;
5330
+ const padding = {
5331
+ top: 50,
5332
+ right: 50,
5333
+ bottom: showXAxis ? 120 : 50,
5334
+ left: showYAxis ? 130 : 50
5335
+ };
5336
+ const chartWidth = viewBoxWidth - padding.left - padding.right;
5337
+ const chartHeight = viewBoxHeight - padding.top - padding.bottom;
5338
+ const gridLabelFontSize = viewBoxWidth * 0.045;
5339
+ const axisLabelFontSize = viewBoxWidth * 0.05;
5340
+ const titleFontSize = viewBoxWidth * 0.055;
5311
5341
  const allPoints = data.flatMap((series) => series.data);
5312
5342
  const allYValues = allPoints.map((p) => p.y);
5313
5343
  const firstXValue = data[0]?.data[0]?.x;
@@ -5320,7 +5350,7 @@ var LineChart = ({
5320
5350
  const minY = Math.min(0, ...allYValues);
5321
5351
  const maxY = Math.max(...allYValues);
5322
5352
  const yRange = maxY - minY;
5323
- const yMin = minY - yRange * 0.1;
5353
+ const yMin = Math.max(0, minY - yRange * 0.1);
5324
5354
  const yMax = maxY + yRange * 0.1;
5325
5355
  const scaleX = (x, index) => {
5326
5356
  const numX = isStringX ? index : x;
@@ -5367,29 +5397,32 @@ var LineChart = ({
5367
5397
  x2: chartWidth,
5368
5398
  y2: y,
5369
5399
  stroke: "currentColor",
5370
- strokeWidth: "1",
5400
+ strokeWidth: "0.5",
5371
5401
  className: "text-gray-200 dark:text-gray-700",
5372
- strokeDasharray: "2,2"
5402
+ strokeDasharray: "4,4"
5373
5403
  }
5374
5404
  ),
5375
5405
  showYAxis && /* @__PURE__ */ (0, import_jsx_runtime108.jsx)(
5376
5406
  "text",
5377
5407
  {
5378
- x: -10,
5379
- y: y + 4,
5408
+ x: -25,
5409
+ y,
5380
5410
  textAnchor: "end",
5381
- fontSize: "16",
5382
- className: "fill-gray-600 dark:fill-gray-400",
5411
+ dominantBaseline: "middle",
5412
+ fontSize: gridLabelFontSize,
5413
+ className: `fill-gray-600 dark:fill-gray-400 ${gridLabelClass}`,
5383
5414
  children: yValue.toFixed(1)
5384
5415
  }
5385
5416
  )
5386
5417
  ] }, `grid-h-${i}`)
5387
5418
  );
5388
5419
  }
5389
- const numXGridLines = Math.min(allPoints.length, 6);
5420
+ const numXGridLines = Math.max(2, Math.min(allPoints.length, 6));
5421
+ const xGridStep = numXGridLines > 1 ? 1 / (numXGridLines - 1) : 0;
5390
5422
  for (let i = 0; i < numXGridLines; i++) {
5391
- const x = chartWidth / (numXGridLines - 1) * i;
5392
- const xValue = data[0]?.data[Math.floor((data[0].data.length - 1) * (i / (numXGridLines - 1)))]?.x || "";
5423
+ const x = chartWidth * (i * xGridStep);
5424
+ const dataIndex = Math.floor((data[0]?.data.length - 1) * (i * xGridStep));
5425
+ const xValue = data[0]?.data[Math.max(0, Math.min(dataIndex, data[0].data.length - 1))]?.x || "";
5393
5426
  gridLines.push(
5394
5427
  /* @__PURE__ */ (0, import_jsx_runtime108.jsxs)("g", { children: [
5395
5428
  /* @__PURE__ */ (0, import_jsx_runtime108.jsx)(
@@ -5400,19 +5433,20 @@ var LineChart = ({
5400
5433
  x2: x,
5401
5434
  y2: chartHeight,
5402
5435
  stroke: "currentColor",
5403
- strokeWidth: "1",
5436
+ strokeWidth: "0.5",
5404
5437
  className: "text-gray-200 dark:text-gray-700",
5405
- strokeDasharray: "2,2"
5438
+ strokeDasharray: "4,4"
5406
5439
  }
5407
5440
  ),
5408
5441
  showXAxis && /* @__PURE__ */ (0, import_jsx_runtime108.jsx)(
5409
5442
  "text",
5410
5443
  {
5411
5444
  x,
5412
- y: chartHeight + 20,
5445
+ y: chartHeight + 35,
5413
5446
  textAnchor: "middle",
5414
- fontSize: "14",
5415
- className: "fill-gray-600 dark:fill-gray-400",
5447
+ dominantBaseline: "hanging",
5448
+ fontSize: gridLabelFontSize,
5449
+ className: `fill-gray-600 dark:fill-gray-400 ${gridLabelClass}`,
5416
5450
  children: xValue
5417
5451
  }
5418
5452
  )
@@ -5420,21 +5454,74 @@ var LineChart = ({
5420
5454
  );
5421
5455
  }
5422
5456
  }
5457
+ const getTooltipPosition = import_react26.default.useCallback((x, y) => {
5458
+ if (!containerRef.current) return { x, y };
5459
+ const rect = containerRef.current.getBoundingClientRect();
5460
+ const tooltipWidth = 120;
5461
+ const tooltipHeight = 80;
5462
+ let tooltipX = x + 10;
5463
+ let tooltipY = y - 30;
5464
+ if (tooltipX + tooltipWidth > rect.width) {
5465
+ tooltipX = x - tooltipWidth - 10;
5466
+ }
5467
+ if (tooltipY + tooltipHeight > rect.height) {
5468
+ tooltipY = y + 30;
5469
+ }
5470
+ return { x: tooltipX, y: tooltipY };
5471
+ }, []);
5472
+ const containerStyle = {
5473
+ "--font-size-base": `${baseFontSize}px`,
5474
+ "--font-size-lg": `calc(var(--font-size-base) * 1.125)`,
5475
+ "--font-size-sm": `calc(var(--font-size-base) * 0.875)`,
5476
+ "--font-size-xs": `calc(var(--font-size-base) * 0.75)`
5477
+ };
5423
5478
  return /* @__PURE__ */ (0, import_jsx_runtime108.jsxs)(
5424
5479
  "div",
5425
5480
  {
5426
- className: `relative ${responsive ? "w-full" : "inline-block"} ${className}`,
5427
- style: responsive ? { aspectRatio: `${width} / ${height}` } : void 0,
5481
+ ref: containerRef,
5482
+ className: `relative flex flex-col gap-4 ${responsive ? "w-full" : "inline-block"} ${className}`,
5483
+ style: {
5484
+ ...containerStyle
5485
+ },
5428
5486
  children: [
5487
+ /* @__PURE__ */ (0, import_jsx_runtime108.jsx)("style", { children: `
5488
+ /* Mobile: Large fonts, hidden axis titles, thicker lines (default) */
5489
+ .${gridLabelClass} { font-size: ${gridLabelFontSize}px !important; }
5490
+ .${axisLabelClass} { display: none; }
5491
+ .${lineClass} { stroke-width: ${strokeWidth * 2.5} !important; }
5492
+ .${pointClass} { r: 6 !important; stroke-width: 3 !important; }
5493
+
5494
+ /* Tablet: Medium fonts, show axis titles, medium lines */
5495
+ @media (min-width: 640px) {
5496
+ .${gridLabelClass} { font-size: ${gridLabelFontSize * 0.7}px !important; }
5497
+ .${axisLabelClass} {
5498
+ font-size: ${axisLabelFontSize * 0.7}px !important;
5499
+ display: block;
5500
+ }
5501
+ .${lineClass} { stroke-width: ${strokeWidth * 1.5} !important; }
5502
+ .${pointClass} { r: 4 !important; stroke-width: 2 !important; }
5503
+ }
5504
+
5505
+ /* Desktop: Small fonts, show axis titles, normal lines */
5506
+ @media (min-width: 1024px) {
5507
+ .${gridLabelClass} { font-size: ${gridLabelFontSize * 0.4}px !important; }
5508
+ .${axisLabelClass} {
5509
+ font-size: ${axisLabelFontSize * 0.4}px !important;
5510
+ display: block;
5511
+ }
5512
+ .${lineClass} { stroke-width: ${strokeWidth} !important; }
5513
+ .${pointClass} { r: 3 !important; stroke-width: 1.5 !important; }
5514
+ }
5515
+ ` }),
5429
5516
  /* @__PURE__ */ (0, import_jsx_runtime108.jsx)(
5430
5517
  "svg",
5431
5518
  {
5519
+ ref: svgRef,
5432
5520
  width: "100%",
5433
- height: "100%",
5434
- viewBox: `0 0 ${width} ${height}`,
5521
+ viewBox: `0 0 ${viewBoxWidth} ${viewBoxHeight}`,
5435
5522
  preserveAspectRatio: "xMidYMid meet",
5436
- className: "bg-white dark:bg-gray-800 block",
5437
- style: { overflow: "visible" },
5523
+ className: "bg-white dark:bg-gray-800 block w-full",
5524
+ style: { height: "auto", overflow: "visible" },
5438
5525
  children: /* @__PURE__ */ (0, import_jsx_runtime108.jsxs)("g", { transform: `translate(${padding.left}, ${padding.top})`, children: [
5439
5526
  gridLines,
5440
5527
  data.map((series, seriesIndex) => /* @__PURE__ */ (0, import_jsx_runtime108.jsx)(
@@ -5445,7 +5532,8 @@ var LineChart = ({
5445
5532
  stroke: series.color || defaultColors[seriesIndex % defaultColors.length],
5446
5533
  strokeWidth,
5447
5534
  strokeLinecap: "round",
5448
- strokeLinejoin: "round"
5535
+ strokeLinejoin: "round",
5536
+ className: lineClass
5449
5537
  },
5450
5538
  `line-${seriesIndex}`
5451
5539
  )),
@@ -5459,13 +5547,32 @@ var LineChart = ({
5459
5547
  {
5460
5548
  cx: x,
5461
5549
  cy: y,
5462
- r: isHovered ? 6 : 4,
5550
+ r: isHovered ? 5 : 3,
5463
5551
  fill: series.color || defaultColors[seriesIndex % defaultColors.length],
5464
5552
  stroke: "white",
5465
- strokeWidth: "2",
5466
- className: "cursor-pointer transition-all",
5467
- onMouseEnter: () => showTooltip && setHoveredPoint({ seriesIndex, pointIndex, x, y }),
5468
- onMouseLeave: () => setHoveredPoint(null)
5553
+ strokeWidth: "1.5",
5554
+ className: `cursor-pointer transition-all ${pointClass}`,
5555
+ onMouseEnter: (e) => {
5556
+ if (showTooltip && containerRef.current) {
5557
+ setHoveredPoint({ seriesIndex, pointIndex, x, y });
5558
+ const containerRect = containerRef.current.getBoundingClientRect();
5559
+ const mouseX = e.clientX - containerRect.left;
5560
+ const mouseY = e.clientY - containerRect.top;
5561
+ setTooltipPosition(getTooltipPosition(mouseX, mouseY));
5562
+ }
5563
+ },
5564
+ onMouseMove: (e) => {
5565
+ if (showTooltip && hoveredPoint?.seriesIndex === seriesIndex && hoveredPoint?.pointIndex === pointIndex && containerRef.current) {
5566
+ const containerRect = containerRef.current.getBoundingClientRect();
5567
+ const mouseX = e.clientX - containerRect.left;
5568
+ const mouseY = e.clientY - containerRect.top;
5569
+ setTooltipPosition(getTooltipPosition(mouseX, mouseY));
5570
+ }
5571
+ },
5572
+ onMouseLeave: () => {
5573
+ setHoveredPoint(null);
5574
+ setTooltipPosition(null);
5575
+ }
5469
5576
  },
5470
5577
  `point-${seriesIndex}-${pointIndex}`
5471
5578
  );
@@ -5475,11 +5582,12 @@ var LineChart = ({
5475
5582
  "text",
5476
5583
  {
5477
5584
  x: chartWidth / 2,
5478
- y: chartHeight + 50,
5585
+ y: chartHeight + 80,
5479
5586
  textAnchor: "middle",
5480
- fontSize: "16",
5481
- fontWeight: "500",
5482
- className: "fill-gray-700 dark:fill-gray-300",
5587
+ dominantBaseline: "hanging",
5588
+ fontSize: axisLabelFontSize,
5589
+ fontWeight: "600",
5590
+ className: `fill-gray-700 dark:fill-gray-300 ${axisLabelClass}`,
5483
5591
  children: xAxisLabel
5484
5592
  }
5485
5593
  ),
@@ -5487,45 +5595,47 @@ var LineChart = ({
5487
5595
  "text",
5488
5596
  {
5489
5597
  x: -chartHeight / 2,
5490
- y: -45,
5598
+ y: -100,
5491
5599
  textAnchor: "middle",
5492
- fontSize: "16",
5493
- fontWeight: "500",
5494
- transform: `rotate(-90, 0, 0)`,
5495
- className: "fill-gray-700 dark:fill-gray-300",
5600
+ dominantBaseline: "middle",
5601
+ fontSize: axisLabelFontSize,
5602
+ fontWeight: "600",
5603
+ transform: "rotate(-90)",
5604
+ className: `fill-gray-700 dark:fill-gray-300 ${axisLabelClass}`,
5496
5605
  children: yAxisLabel
5497
5606
  }
5498
5607
  )
5499
5608
  ] })
5500
5609
  }
5501
5610
  ),
5502
- showLegend && /* @__PURE__ */ (0, import_jsx_runtime108.jsx)("div", { className: "flex flex-wrap gap-4 mt-4 justify-center", children: data.map((series, index) => /* @__PURE__ */ (0, import_jsx_runtime108.jsxs)("div", { className: "flex items-center gap-2", children: [
5611
+ showLegend && /* @__PURE__ */ (0, import_jsx_runtime108.jsx)("div", { className: "flex flex-wrap gap-3 justify-center px-4", children: data.map((series, index) => /* @__PURE__ */ (0, import_jsx_runtime108.jsxs)("div", { className: "flex items-center gap-2 text-sm", children: [
5503
5612
  /* @__PURE__ */ (0, import_jsx_runtime108.jsx)(
5504
5613
  "div",
5505
5614
  {
5506
- className: "w-4 h-4 rounded-sm",
5615
+ className: "w-3 h-3 rounded-sm flex-shrink-0",
5507
5616
  style: {
5508
5617
  backgroundColor: series.color || defaultColors[index % defaultColors.length]
5509
5618
  }
5510
5619
  }
5511
5620
  ),
5512
- /* @__PURE__ */ (0, import_jsx_runtime108.jsx)("span", { className: "text-sm text-gray-700 dark:text-gray-300", children: series.name })
5621
+ /* @__PURE__ */ (0, import_jsx_runtime108.jsx)("span", { className: "text-gray-700 dark:text-gray-300", children: series.name })
5513
5622
  ] }, `legend-${index}`)) }),
5514
- showTooltip && hoveredPoint && /* @__PURE__ */ (0, import_jsx_runtime108.jsxs)(
5623
+ showTooltip && hoveredPoint && tooltipPosition && /* @__PURE__ */ (0, import_jsx_runtime108.jsxs)(
5515
5624
  "div",
5516
5625
  {
5517
- className: "absolute bg-gray-900 dark:bg-gray-700 text-white px-3 py-2 rounded shadow-lg text-sm pointer-events-none z-50",
5626
+ className: "absolute bg-gray-900 dark:bg-gray-700 text-white px-3 py-2 rounded shadow-lg pointer-events-none z-50 text-sm whitespace-nowrap",
5518
5627
  style: {
5519
- left: `${padding.left + hoveredPoint.x + 10}px`,
5520
- top: `${padding.top + hoveredPoint.y - 30}px`
5628
+ left: `${tooltipPosition.x}px`,
5629
+ top: `${tooltipPosition.y}px`,
5630
+ transform: "translateZ(0)"
5521
5631
  },
5522
5632
  children: [
5523
5633
  /* @__PURE__ */ (0, import_jsx_runtime108.jsx)("div", { className: "font-semibold", children: data[hoveredPoint.seriesIndex].name }),
5524
- /* @__PURE__ */ (0, import_jsx_runtime108.jsxs)("div", { children: [
5634
+ /* @__PURE__ */ (0, import_jsx_runtime108.jsxs)("div", { className: "text-xs opacity-90", children: [
5525
5635
  "x: ",
5526
5636
  data[hoveredPoint.seriesIndex].data[hoveredPoint.pointIndex].x
5527
5637
  ] }),
5528
- /* @__PURE__ */ (0, import_jsx_runtime108.jsxs)("div", { children: [
5638
+ /* @__PURE__ */ (0, import_jsx_runtime108.jsxs)("div", { className: "text-xs opacity-90", children: [
5529
5639
  "y: ",
5530
5640
  data[hoveredPoint.seriesIndex].data[hoveredPoint.pointIndex].y
5531
5641
  ] })
@@ -5571,26 +5681,38 @@ var BarChart = ({
5571
5681
  barWidth = 0.8,
5572
5682
  className = "",
5573
5683
  xAxisLabel,
5574
- yAxisLabel
5684
+ yAxisLabel,
5685
+ baseFontSize = 14,
5686
+ colors = defaultColors2
5575
5687
  }) => {
5576
- const height = providedHeight ?? 400;
5577
- const width = providedWidth ?? (responsive ? 800 : 600);
5688
+ const viewBoxWidth = 1e3;
5689
+ const viewBoxHeight = 600;
5690
+ const containerRef = import_react27.default.useRef(null);
5691
+ const [tooltipPosition, setTooltipPosition] = import_react27.default.useState(null);
5578
5692
  const [hoveredBar, setHoveredBar] = import_react27.default.useState(null);
5693
+ const chartId = import_react27.default.useId();
5694
+ const wrapperClass = `chart-svg-wrapper-${chartId.replace(/:/g, "-")}`;
5695
+ const gridLabelClass = `chart-grid-label-${chartId.replace(/:/g, "-")}`;
5696
+ const axisLabelClass = `chart-axis-label-${chartId.replace(/:/g, "-")}`;
5697
+ const barClass = `chart-bar-${chartId.replace(/:/g, "-")}`;
5579
5698
  const padding = {
5580
- top: 20,
5581
- right: 20,
5582
- bottom: showXAxis ? horizontal ? 60 : 80 : 20,
5583
- left: showYAxis ? horizontal ? 80 : 60 : 20
5699
+ top: 50,
5700
+ right: 50,
5701
+ bottom: showXAxis ? horizontal ? 120 : 140 : 50,
5702
+ left: showYAxis ? horizontal ? 140 : 130 : 50
5584
5703
  };
5585
- const chartWidth = width - padding.left - padding.right;
5586
- const chartHeight = height - padding.top - padding.bottom;
5704
+ const chartWidth = viewBoxWidth - padding.left - padding.right;
5705
+ const chartHeight = viewBoxHeight - padding.top - padding.bottom;
5706
+ const gridLabelFontSize = viewBoxWidth * 0.045;
5707
+ const axisLabelFontSize = viewBoxWidth * 0.05;
5708
+ const titleFontSize = viewBoxWidth * 0.055;
5587
5709
  const allYValues = stacked ? data[0]?.data.map(
5588
5710
  (_, i) => data.reduce((sum, series) => sum + (series.data[i]?.y || 0), 0)
5589
5711
  ) || [] : data.flatMap((series) => series.data.map((p) => p.y));
5590
5712
  const minY = Math.min(0, ...allYValues);
5591
5713
  const maxY = Math.max(...allYValues);
5592
5714
  const yRange = maxY - minY;
5593
- const yMin = minY - yRange * 0.1;
5715
+ const yMin = Math.max(0, minY - yRange * 0.1);
5594
5716
  const yMax = maxY + yRange * 0.1;
5595
5717
  const numBars = data[0]?.data.length || 0;
5596
5718
  const numSeries = data.length;
@@ -5617,19 +5739,20 @@ var BarChart = ({
5617
5739
  x2: chartWidth,
5618
5740
  y2: y,
5619
5741
  stroke: "currentColor",
5620
- strokeWidth: "1",
5742
+ strokeWidth: "0.5",
5621
5743
  className: "text-gray-200 dark:text-gray-700",
5622
- strokeDasharray: "2,2"
5744
+ strokeDasharray: "4,4"
5623
5745
  }
5624
5746
  ),
5625
5747
  showYAxis && !horizontal && /* @__PURE__ */ (0, import_jsx_runtime109.jsx)(
5626
5748
  "text",
5627
5749
  {
5628
- x: -10,
5629
- y: y + 4,
5750
+ x: -25,
5751
+ y,
5630
5752
  textAnchor: "end",
5631
- fontSize: "14",
5632
- className: "fill-gray-600 dark:fill-gray-400",
5753
+ dominantBaseline: "middle",
5754
+ fontSize: gridLabelFontSize,
5755
+ className: `fill-gray-600 dark:fill-gray-400 ${gridLabelClass}`,
5633
5756
  children: yValue.toFixed(0)
5634
5757
  }
5635
5758
  )
@@ -5678,12 +5801,20 @@ var BarChart = ({
5678
5801
  x: xPos,
5679
5802
  y: yPos,
5680
5803
  width: barW,
5681
- height: barHeight,
5682
- fill: data[seriesIndex].color || defaultColors2[seriesIndex % defaultColors2.length],
5683
- className: "cursor-pointer transition-opacity",
5804
+ height: Math.abs(scaleY(0) - yPos),
5805
+ fill: data[seriesIndex].color || colors[seriesIndex % colors.length],
5806
+ className: `cursor-pointer transition-opacity ${barClass}`,
5684
5807
  opacity: isHovered ? 0.8 : 1,
5685
- onMouseEnter: () => showTooltip && setHoveredBar({ seriesIndex, barIndex, x: xPos + barW / 2, y: yPos }),
5686
- onMouseLeave: () => setHoveredBar(null)
5808
+ onMouseEnter: () => {
5809
+ if (showTooltip) {
5810
+ setHoveredBar({ seriesIndex, barIndex, x: xPos + barW / 2, y: yPos });
5811
+ setTooltipPosition(getTooltipPosition(padding.left + xPos + barW / 2, padding.top + yPos));
5812
+ }
5813
+ },
5814
+ onMouseLeave: () => {
5815
+ setHoveredBar(null);
5816
+ setTooltipPosition(null);
5817
+ }
5687
5818
  },
5688
5819
  `bar-${seriesIndex}-${barIndex}`
5689
5820
  )
@@ -5708,8 +5839,8 @@ var BarChart = ({
5708
5839
  y: yPos,
5709
5840
  width: actualBarWidth,
5710
5841
  height: barHeight,
5711
- fill: data[seriesIndex].color || defaultColors2[seriesIndex % defaultColors2.length],
5712
- className: "cursor-pointer transition-opacity",
5842
+ fill: data[seriesIndex].color || colors[seriesIndex % colors.length],
5843
+ className: `cursor-pointer transition-opacity ${barClass}`,
5713
5844
  opacity: isHovered ? 0.8 : 1,
5714
5845
  onMouseEnter: () => showTooltip && setHoveredBar({ seriesIndex, barIndex, x: xPos + actualBarWidth / 2, y: yPos }),
5715
5846
  onMouseLeave: () => setHoveredBar(null)
@@ -5723,10 +5854,11 @@ var BarChart = ({
5723
5854
  "text",
5724
5855
  {
5725
5856
  x: xPos + actualBarWidth / 2,
5726
- y: yPos - 5,
5857
+ y: yPos - 10,
5727
5858
  textAnchor: "middle",
5728
- fontSize: "14",
5729
- fontWeight: "500",
5859
+ dominantBaseline: "middle",
5860
+ fontSize: "11",
5861
+ fontWeight: "600",
5730
5862
  className: "fill-gray-700 dark:fill-gray-300",
5731
5863
  children: point.y
5732
5864
  },
@@ -5745,30 +5877,77 @@ var BarChart = ({
5745
5877
  "text",
5746
5878
  {
5747
5879
  x: xPos,
5748
- y: chartHeight + 20,
5880
+ y: chartHeight + 35,
5749
5881
  textAnchor: "middle",
5750
- fontSize: "14",
5751
- className: "fill-gray-600 dark:fill-gray-400",
5882
+ dominantBaseline: "hanging",
5883
+ fontSize: gridLabelFontSize,
5884
+ className: `fill-gray-600 dark:fill-gray-400 ${gridLabelClass}`,
5752
5885
  children: point.x
5753
5886
  },
5754
5887
  `x-label-${i}`
5755
5888
  );
5756
5889
  });
5890
+ const getTooltipPosition = import_react27.default.useCallback((x, y) => {
5891
+ if (!containerRef.current) return { x, y };
5892
+ const rect = containerRef.current.getBoundingClientRect();
5893
+ const tooltipWidth = 140;
5894
+ const tooltipHeight = 80;
5895
+ let tooltipX = x + 10;
5896
+ let tooltipY = y - 30;
5897
+ if (tooltipX + tooltipWidth > rect.width) {
5898
+ tooltipX = x - tooltipWidth - 10;
5899
+ }
5900
+ if (tooltipY + tooltipHeight > rect.height) {
5901
+ tooltipY = y + 30;
5902
+ }
5903
+ return { x: tooltipX, y: tooltipY };
5904
+ }, []);
5905
+ const containerStyle = {
5906
+ "--font-size-base": `${baseFontSize}px`,
5907
+ "--font-size-lg": `calc(var(--font-size-base) * 1.125)`,
5908
+ "--font-size-sm": `calc(var(--font-size-base) * 0.875)`,
5909
+ "--font-size-xs": `calc(var(--font-size-base) * 0.75)`
5910
+ };
5757
5911
  return /* @__PURE__ */ (0, import_jsx_runtime109.jsxs)(
5758
5912
  "div",
5759
5913
  {
5760
- className: `relative ${responsive ? "w-full" : "inline-block"} ${className}`,
5761
- style: responsive ? { aspectRatio: `${width} / ${height}` } : void 0,
5914
+ ref: containerRef,
5915
+ className: `relative flex flex-col gap-4 ${responsive ? "w-full" : "inline-block"} ${className}`,
5916
+ style: {
5917
+ ...containerStyle
5918
+ },
5762
5919
  children: [
5920
+ /* @__PURE__ */ (0, import_jsx_runtime109.jsx)("style", { children: `
5921
+ /* Mobile: Large fonts, hidden axis titles, thicker bars (default) */
5922
+ .${gridLabelClass} { font-size: ${gridLabelFontSize}px !important; }
5923
+ .${axisLabelClass} { display: none; }
5924
+
5925
+ /* Tablet: Medium fonts, show axis titles */
5926
+ @media (min-width: 640px) {
5927
+ .${gridLabelClass} { font-size: ${gridLabelFontSize * 0.7}px !important; }
5928
+ .${axisLabelClass} {
5929
+ font-size: ${axisLabelFontSize * 0.7}px !important;
5930
+ display: block;
5931
+ }
5932
+ }
5933
+
5934
+ /* Desktop: Small fonts, show axis titles */
5935
+ @media (min-width: 1024px) {
5936
+ .${gridLabelClass} { font-size: ${gridLabelFontSize * 0.4}px !important; }
5937
+ .${axisLabelClass} {
5938
+ font-size: ${axisLabelFontSize * 0.4}px !important;
5939
+ display: block;
5940
+ }
5941
+ }
5942
+ ` }),
5763
5943
  /* @__PURE__ */ (0, import_jsx_runtime109.jsx)(
5764
5944
  "svg",
5765
5945
  {
5766
5946
  width: "100%",
5767
- height: "100%",
5768
- viewBox: `0 0 ${width} ${height}`,
5947
+ viewBox: `0 0 ${viewBoxWidth} ${viewBoxHeight}`,
5769
5948
  preserveAspectRatio: "xMidYMid meet",
5770
- className: "bg-white dark:bg-gray-800 block",
5771
- style: { overflow: "visible" },
5949
+ className: "bg-white dark:bg-gray-800 block w-full",
5950
+ style: { height: "auto", overflow: "visible" },
5772
5951
  children: /* @__PURE__ */ (0, import_jsx_runtime109.jsxs)("g", { transform: `translate(${padding.left}, ${padding.top})`, children: [
5773
5952
  gridLines,
5774
5953
  renderBars(),
@@ -5777,11 +5956,12 @@ var BarChart = ({
5777
5956
  "text",
5778
5957
  {
5779
5958
  x: chartWidth / 2,
5780
- y: chartHeight + 50,
5959
+ y: chartHeight + 80,
5781
5960
  textAnchor: "middle",
5782
- fontSize: "16",
5783
- fontWeight: "500",
5784
- className: "fill-gray-700 dark:fill-gray-300",
5961
+ dominantBaseline: "hanging",
5962
+ fontSize: axisLabelFontSize,
5963
+ fontWeight: "600",
5964
+ className: `fill-gray-700 dark:fill-gray-300 ${axisLabelClass}`,
5785
5965
  children: xAxisLabel
5786
5966
  }
5787
5967
  ),
@@ -5789,41 +5969,43 @@ var BarChart = ({
5789
5969
  "text",
5790
5970
  {
5791
5971
  x: -chartHeight / 2,
5792
- y: -45,
5972
+ y: -100,
5793
5973
  textAnchor: "middle",
5794
- fontSize: "16",
5795
- fontWeight: "500",
5796
- transform: `rotate(-90, 0, 0)`,
5797
- className: "fill-gray-700 dark:fill-gray-300",
5974
+ dominantBaseline: "middle",
5975
+ fontSize: axisLabelFontSize,
5976
+ fontWeight: "600",
5977
+ transform: "rotate(-90)",
5978
+ className: `fill-gray-700 dark:fill-gray-300 ${axisLabelClass}`,
5798
5979
  children: yAxisLabel
5799
5980
  }
5800
5981
  )
5801
5982
  ] })
5802
5983
  }
5803
5984
  ),
5804
- showLegend && /* @__PURE__ */ (0, import_jsx_runtime109.jsx)("div", { className: "flex flex-wrap gap-4 mt-4 justify-center", children: data.map((series, index) => /* @__PURE__ */ (0, import_jsx_runtime109.jsxs)("div", { className: "flex items-center gap-2", children: [
5985
+ showLegend && /* @__PURE__ */ (0, import_jsx_runtime109.jsx)("div", { className: "flex flex-wrap gap-3 justify-center px-4", children: data.map((series, index) => /* @__PURE__ */ (0, import_jsx_runtime109.jsxs)("div", { className: "flex items-center gap-2 text-sm", children: [
5805
5986
  /* @__PURE__ */ (0, import_jsx_runtime109.jsx)(
5806
5987
  "div",
5807
5988
  {
5808
- className: "w-4 h-4 rounded-sm",
5989
+ className: "w-3 h-3 rounded-sm flex-shrink-0",
5809
5990
  style: {
5810
- backgroundColor: series.color || defaultColors2[index % defaultColors2.length]
5991
+ backgroundColor: series.color || colors[index % colors.length]
5811
5992
  }
5812
5993
  }
5813
5994
  ),
5814
- /* @__PURE__ */ (0, import_jsx_runtime109.jsx)("span", { className: "text-sm text-gray-700 dark:text-gray-300", children: series.name })
5995
+ /* @__PURE__ */ (0, import_jsx_runtime109.jsx)("span", { className: "text-gray-700 dark:text-gray-300", children: series.name })
5815
5996
  ] }, `legend-${index}`)) }),
5816
- showTooltip && hoveredBar && /* @__PURE__ */ (0, import_jsx_runtime109.jsxs)(
5997
+ showTooltip && hoveredBar && tooltipPosition && /* @__PURE__ */ (0, import_jsx_runtime109.jsxs)(
5817
5998
  "div",
5818
5999
  {
5819
- className: "absolute bg-gray-900 dark:bg-gray-700 text-white px-3 py-2 rounded shadow-lg text-sm pointer-events-none z-50",
6000
+ className: "absolute bg-gray-900 dark:bg-gray-700 text-white px-3 py-2 rounded shadow-lg pointer-events-none z-50 text-sm whitespace-nowrap",
5820
6001
  style: {
5821
- left: `${padding.left + hoveredBar.x + 10}px`,
5822
- top: `${padding.top + hoveredBar.y - 30}px`
6002
+ left: `${tooltipPosition.x}px`,
6003
+ top: `${tooltipPosition.y}px`,
6004
+ transform: "translateZ(0)"
5823
6005
  },
5824
6006
  children: [
5825
6007
  /* @__PURE__ */ (0, import_jsx_runtime109.jsx)("div", { className: "font-semibold", children: data[hoveredBar.seriesIndex].name }),
5826
- /* @__PURE__ */ (0, import_jsx_runtime109.jsxs)("div", { children: [
6008
+ /* @__PURE__ */ (0, import_jsx_runtime109.jsxs)("div", { className: "text-xs opacity-90", children: [
5827
6009
  data[hoveredBar.seriesIndex].data[hoveredBar.barIndex].x,
5828
6010
  ": ",
5829
6011
  data[hoveredBar.seriesIndex].data[hoveredBar.barIndex].y
@@ -5871,14 +6053,32 @@ var AreaChart = ({
5871
6053
  strokeWidth = 2,
5872
6054
  className = "",
5873
6055
  xAxisLabel,
5874
- yAxisLabel
6056
+ yAxisLabel,
6057
+ baseFontSize = 14
5875
6058
  }) => {
5876
- const height = providedHeight ?? 400;
5877
- const width = providedWidth ?? 800;
6059
+ const viewBoxWidth = 1e3;
6060
+ const viewBoxHeight = 600;
6061
+ const containerRef = import_react28.default.useRef(null);
6062
+ const svgRef = import_react28.default.useRef(null);
6063
+ const [tooltipPosition, setTooltipPosition] = import_react28.default.useState(null);
5878
6064
  const [hoveredPoint, setHoveredPoint] = import_react28.default.useState(null);
5879
- const padding = { top: 20, right: 20, bottom: showXAxis ? 60 : 20, left: showYAxis ? 60 : 20 };
5880
- const chartWidth = width - padding.left - padding.right;
5881
- const chartHeight = height - padding.top - padding.bottom;
6065
+ const chartId = import_react28.default.useId();
6066
+ const wrapperClass = `chart-svg-wrapper-${chartId.replace(/:/g, "-")}`;
6067
+ const gridLabelClass = `chart-grid-label-${chartId.replace(/:/g, "-")}`;
6068
+ const axisLabelClass = `chart-axis-label-${chartId.replace(/:/g, "-")}`;
6069
+ const lineClass = `chart-line-${chartId.replace(/:/g, "-")}`;
6070
+ const pointClass = `chart-point-${chartId.replace(/:/g, "-")}`;
6071
+ const padding = {
6072
+ top: 50,
6073
+ right: 50,
6074
+ bottom: showXAxis ? 120 : 50,
6075
+ left: showYAxis ? 130 : 50
6076
+ };
6077
+ const chartWidth = viewBoxWidth - padding.left - padding.right;
6078
+ const chartHeight = viewBoxHeight - padding.top - padding.bottom;
6079
+ const gridLabelFontSize = viewBoxWidth * 0.045;
6080
+ const axisLabelFontSize = viewBoxWidth * 0.05;
6081
+ const titleFontSize = viewBoxWidth * 0.055;
5882
6082
  const allPoints = data.flatMap((series) => series.data);
5883
6083
  const allYValues = stacked ? data[0]?.data.map(
5884
6084
  (_, i) => data.reduce((sum, series) => sum + (series.data[i]?.y || 0), 0)
@@ -5892,7 +6092,7 @@ var AreaChart = ({
5892
6092
  const minY = Math.min(0, ...allYValues);
5893
6093
  const maxY = Math.max(...allYValues);
5894
6094
  const yRange = maxY - minY;
5895
- const yMin = minY - yRange * 0.1;
6095
+ const yMin = Math.max(0, minY - yRange * 0.1);
5896
6096
  const yMax = maxY + yRange * 0.1;
5897
6097
  const scaleX = (x, index) => {
5898
6098
  const numX = isStringX ? index : x;
@@ -5973,20 +6173,21 @@ var AreaChart = ({
5973
6173
  x2: chartWidth,
5974
6174
  y2: y,
5975
6175
  stroke: "currentColor",
5976
- strokeWidth: "1",
6176
+ strokeWidth: "0.5",
5977
6177
  className: "text-gray-200 dark:text-gray-700",
5978
- strokeDasharray: "2,2"
6178
+ strokeDasharray: "4,4"
5979
6179
  }
5980
6180
  ),
5981
6181
  showYAxis && /* @__PURE__ */ (0, import_jsx_runtime110.jsx)(
5982
6182
  "text",
5983
6183
  {
5984
- x: -10,
5985
- y: y + 4,
6184
+ x: -25,
6185
+ y,
5986
6186
  textAnchor: "end",
5987
- fontSize: "12",
5988
- className: "fill-gray-600 dark:fill-gray-400",
5989
- children: yValue.toFixed(0)
6187
+ dominantBaseline: "middle",
6188
+ fontSize: gridLabelFontSize,
6189
+ className: `fill-gray-600 dark:fill-gray-400 ${gridLabelClass}`,
6190
+ children: yValue.toFixed(1)
5990
6191
  }
5991
6192
  )
5992
6193
  ] }, `grid-h-${i}`)
@@ -6006,19 +6207,20 @@ var AreaChart = ({
6006
6207
  x2: x,
6007
6208
  y2: chartHeight,
6008
6209
  stroke: "currentColor",
6009
- strokeWidth: "1",
6210
+ strokeWidth: "0.5",
6010
6211
  className: "text-gray-200 dark:text-gray-700",
6011
- strokeDasharray: "2,2"
6212
+ strokeDasharray: "4,4"
6012
6213
  }
6013
6214
  ),
6014
6215
  showXAxis && /* @__PURE__ */ (0, import_jsx_runtime110.jsx)(
6015
6216
  "text",
6016
6217
  {
6017
6218
  x,
6018
- y: chartHeight + 20,
6219
+ y: chartHeight + 35,
6019
6220
  textAnchor: "middle",
6020
- fontSize: "12",
6021
- className: "fill-gray-600 dark:fill-gray-400",
6221
+ dominantBaseline: "hanging",
6222
+ fontSize: gridLabelFontSize,
6223
+ className: `fill-gray-600 dark:fill-gray-400 ${gridLabelClass}`,
6022
6224
  children: xValue
6023
6225
  }
6024
6226
  )
@@ -6030,20 +6232,72 @@ var AreaChart = ({
6030
6232
  if (stacked) {
6031
6233
  cumulativeValues = Array(data[0]?.data.length || 0).fill(0);
6032
6234
  }
6235
+ const getTooltipPosition = import_react28.default.useCallback((x, y) => {
6236
+ if (!containerRef.current) return { x, y };
6237
+ const rect = containerRef.current.getBoundingClientRect();
6238
+ const tooltipWidth = 120;
6239
+ const tooltipHeight = 80;
6240
+ let tooltipX = x + 10;
6241
+ let tooltipY = y - 30;
6242
+ if (tooltipX + tooltipWidth > rect.width) {
6243
+ tooltipX = x - tooltipWidth - 10;
6244
+ }
6245
+ if (tooltipY + tooltipHeight > rect.height) {
6246
+ tooltipY = y + 30;
6247
+ }
6248
+ return { x: tooltipX, y: tooltipY };
6249
+ }, []);
6250
+ const containerStyle = {
6251
+ "--font-size-base": `${baseFontSize}px`,
6252
+ "--font-size-lg": `calc(var(--font-size-base) * 1.125)`,
6253
+ "--font-size-sm": `calc(var(--font-size-base) * 0.875)`,
6254
+ "--font-size-xs": `calc(var(--font-size-base) * 0.75)`
6255
+ };
6033
6256
  return /* @__PURE__ */ (0, import_jsx_runtime110.jsxs)(
6034
6257
  "div",
6035
6258
  {
6036
- className: `relative ${responsive ? "w-full" : "inline-block"} ${className}`,
6037
- style: responsive ? { width: "100%", aspectRatio: `${width} / ${height}` } : void 0,
6259
+ ref: containerRef,
6260
+ className: `relative flex flex-col gap-4 ${responsive ? "w-full" : "inline-block"} ${className}`,
6261
+ style: containerStyle,
6038
6262
  children: [
6263
+ /* @__PURE__ */ (0, import_jsx_runtime110.jsx)("style", { children: `
6264
+ /* Mobile: Large fonts, hidden axis titles, thicker lines (default) */
6265
+ .${gridLabelClass} { font-size: ${gridLabelFontSize}px !important; }
6266
+ .${axisLabelClass} { display: none; }
6267
+ .${lineClass} { stroke-width: ${strokeWidth * 2.5} !important; }
6268
+ .${pointClass} { r: 6 !important; stroke-width: 3 !important; }
6269
+
6270
+ /* Tablet: Medium fonts, show axis titles, medium lines */
6271
+ @media (min-width: 640px) {
6272
+ .${gridLabelClass} { font-size: ${gridLabelFontSize * 0.7}px !important; }
6273
+ .${axisLabelClass} {
6274
+ font-size: ${axisLabelFontSize * 0.7}px !important;
6275
+ display: block;
6276
+ }
6277
+ .${lineClass} { stroke-width: ${strokeWidth * 1.5} !important; }
6278
+ .${pointClass} { r: 4 !important; stroke-width: 2 !important; }
6279
+ }
6280
+
6281
+ /* Desktop: Small fonts, show axis titles, normal lines */
6282
+ @media (min-width: 1024px) {
6283
+ .${gridLabelClass} { font-size: ${gridLabelFontSize * 0.4}px !important; }
6284
+ .${axisLabelClass} {
6285
+ font-size: ${axisLabelFontSize * 0.4}px !important;
6286
+ display: block;
6287
+ }
6288
+ .${lineClass} { stroke-width: ${strokeWidth} !important; }
6289
+ .${pointClass} { r: 3 !important; stroke-width: 1.5 !important; }
6290
+ }
6291
+ ` }),
6039
6292
  /* @__PURE__ */ (0, import_jsx_runtime110.jsx)(
6040
6293
  "svg",
6041
6294
  {
6295
+ ref: svgRef,
6042
6296
  width: "100%",
6043
- height: "100%",
6044
- viewBox: `0 0 ${width} ${height}`,
6297
+ viewBox: `0 0 ${viewBoxWidth} ${viewBoxHeight}`,
6045
6298
  preserveAspectRatio: "xMidYMid meet",
6046
- className: "bg-white dark:bg-gray-800 block",
6299
+ className: "bg-white dark:bg-gray-800 block w-full",
6300
+ style: { height: "auto", overflow: "visible" },
6047
6301
  children: /* @__PURE__ */ (0, import_jsx_runtime110.jsxs)("g", { transform: `translate(${padding.left}, ${padding.top})`, children: [
6048
6302
  gridLines,
6049
6303
  data.map((series, seriesIndex) => {
@@ -6072,7 +6326,8 @@ var AreaChart = ({
6072
6326
  stroke: series.color || defaultColors3[seriesIndex % defaultColors3.length],
6073
6327
  strokeWidth,
6074
6328
  strokeLinecap: "round",
6075
- strokeLinejoin: "round"
6329
+ strokeLinejoin: "round",
6330
+ className: lineClass
6076
6331
  }
6077
6332
  )
6078
6333
  ] }, `area-${seriesIndex}`);
@@ -6094,9 +6349,28 @@ var AreaChart = ({
6094
6349
  fill: series.color || defaultColors3[seriesIndex % defaultColors3.length],
6095
6350
  stroke: "white",
6096
6351
  strokeWidth: "2",
6097
- className: "cursor-pointer transition-all",
6098
- onMouseEnter: () => showTooltip && setHoveredPoint({ seriesIndex, pointIndex, x, y }),
6099
- onMouseLeave: () => setHoveredPoint(null)
6352
+ className: `cursor-pointer transition-all ${pointClass}`,
6353
+ onMouseEnter: (e) => {
6354
+ if (showTooltip && containerRef.current) {
6355
+ setHoveredPoint({ seriesIndex, pointIndex, x, y });
6356
+ const containerRect = containerRef.current.getBoundingClientRect();
6357
+ const mouseX = e.clientX - containerRect.left;
6358
+ const mouseY = e.clientY - containerRect.top;
6359
+ setTooltipPosition(getTooltipPosition(mouseX, mouseY));
6360
+ }
6361
+ },
6362
+ onMouseMove: (e) => {
6363
+ if (showTooltip && hoveredPoint?.seriesIndex === seriesIndex && hoveredPoint?.pointIndex === pointIndex && containerRef.current) {
6364
+ const containerRect = containerRef.current.getBoundingClientRect();
6365
+ const mouseX = e.clientX - containerRect.left;
6366
+ const mouseY = e.clientY - containerRect.top;
6367
+ setTooltipPosition(getTooltipPosition(mouseX, mouseY));
6368
+ }
6369
+ },
6370
+ onMouseLeave: () => {
6371
+ setHoveredPoint(null);
6372
+ setTooltipPosition(null);
6373
+ }
6100
6374
  },
6101
6375
  `point-${seriesIndex}-${pointIndex}`
6102
6376
  );
@@ -6106,11 +6380,12 @@ var AreaChart = ({
6106
6380
  "text",
6107
6381
  {
6108
6382
  x: chartWidth / 2,
6109
- y: chartHeight + 50,
6383
+ y: chartHeight + 80,
6110
6384
  textAnchor: "middle",
6111
- fontSize: "14",
6112
- fontWeight: "500",
6113
- className: "fill-gray-700 dark:fill-gray-300",
6385
+ dominantBaseline: "hanging",
6386
+ fontSize: axisLabelFontSize,
6387
+ fontWeight: "600",
6388
+ className: `fill-gray-700 dark:fill-gray-300 ${axisLabelClass}`,
6114
6389
  children: xAxisLabel
6115
6390
  }
6116
6391
  ),
@@ -6118,45 +6393,47 @@ var AreaChart = ({
6118
6393
  "text",
6119
6394
  {
6120
6395
  x: -chartHeight / 2,
6121
- y: -45,
6396
+ y: -100,
6122
6397
  textAnchor: "middle",
6123
- fontSize: "14",
6124
- fontWeight: "500",
6125
- transform: "rotate(-90, 0, 0)",
6126
- className: "fill-gray-700 dark:fill-gray-300",
6398
+ dominantBaseline: "middle",
6399
+ fontSize: axisLabelFontSize,
6400
+ fontWeight: "600",
6401
+ transform: "rotate(-90)",
6402
+ className: `fill-gray-700 dark:fill-gray-300 ${axisLabelClass}`,
6127
6403
  children: yAxisLabel
6128
6404
  }
6129
6405
  )
6130
6406
  ] })
6131
6407
  }
6132
6408
  ),
6133
- showLegend && /* @__PURE__ */ (0, import_jsx_runtime110.jsx)("div", { className: "flex flex-wrap gap-4 mt-4 justify-center", children: data.map((series, index) => /* @__PURE__ */ (0, import_jsx_runtime110.jsxs)("div", { className: "flex items-center gap-2", children: [
6409
+ showLegend && /* @__PURE__ */ (0, import_jsx_runtime110.jsx)("div", { className: "flex flex-wrap gap-3 justify-center px-4", children: data.map((series, index) => /* @__PURE__ */ (0, import_jsx_runtime110.jsxs)("div", { className: "flex items-center gap-2 text-sm", children: [
6134
6410
  /* @__PURE__ */ (0, import_jsx_runtime110.jsx)(
6135
6411
  "div",
6136
6412
  {
6137
- className: "w-4 h-4 rounded-sm",
6413
+ className: "w-3 h-3 rounded-sm flex-shrink-0",
6138
6414
  style: {
6139
6415
  backgroundColor: series.color || defaultColors3[index % defaultColors3.length]
6140
6416
  }
6141
6417
  }
6142
6418
  ),
6143
- /* @__PURE__ */ (0, import_jsx_runtime110.jsx)("span", { className: "text-sm text-gray-700 dark:text-gray-300", children: series.name })
6419
+ /* @__PURE__ */ (0, import_jsx_runtime110.jsx)("span", { className: "text-gray-700 dark:text-gray-300", children: series.name })
6144
6420
  ] }, `legend-${index}`)) }),
6145
- showTooltip && hoveredPoint && /* @__PURE__ */ (0, import_jsx_runtime110.jsxs)(
6421
+ showTooltip && hoveredPoint && tooltipPosition && /* @__PURE__ */ (0, import_jsx_runtime110.jsxs)(
6146
6422
  "div",
6147
6423
  {
6148
- className: "absolute bg-gray-900 dark:bg-gray-700 text-white px-3 py-2 rounded shadow-lg text-sm pointer-events-none z-50",
6424
+ className: "absolute bg-gray-900 dark:bg-gray-700 text-white px-3 py-2 rounded shadow-lg pointer-events-none z-50 text-sm whitespace-nowrap",
6149
6425
  style: {
6150
- left: `${padding.left + hoveredPoint.x + 10}px`,
6151
- top: `${padding.top + hoveredPoint.y - 30}px`
6426
+ left: `${tooltipPosition.x}px`,
6427
+ top: `${tooltipPosition.y}px`,
6428
+ transform: "translateZ(0)"
6152
6429
  },
6153
6430
  children: [
6154
6431
  /* @__PURE__ */ (0, import_jsx_runtime110.jsx)("div", { className: "font-semibold", children: data[hoveredPoint.seriesIndex].name }),
6155
- /* @__PURE__ */ (0, import_jsx_runtime110.jsxs)("div", { children: [
6432
+ /* @__PURE__ */ (0, import_jsx_runtime110.jsxs)("div", { className: "text-xs opacity-90", children: [
6156
6433
  "x: ",
6157
6434
  data[hoveredPoint.seriesIndex].data[hoveredPoint.pointIndex].x
6158
6435
  ] }),
6159
- /* @__PURE__ */ (0, import_jsx_runtime110.jsxs)("div", { children: [
6436
+ /* @__PURE__ */ (0, import_jsx_runtime110.jsxs)("div", { className: "text-xs opacity-90", children: [
6160
6437
  "y: ",
6161
6438
  data[hoveredPoint.seriesIndex].data[hoveredPoint.pointIndex].y
6162
6439
  ] })
@@ -6201,16 +6478,27 @@ var PieChart = ({
6201
6478
  showPercentages = false,
6202
6479
  donut = false,
6203
6480
  donutWidth = 60,
6204
- className = ""
6481
+ className = "",
6482
+ baseFontSize = 14
6205
6483
  }) => {
6206
- const height = providedHeight ?? 400;
6207
- const width = providedWidth ?? 400;
6484
+ const viewBoxWidth = 600;
6485
+ const viewBoxHeight = 600;
6486
+ const containerRef = import_react29.default.useRef(null);
6487
+ const [tooltipPosition, setTooltipPosition] = import_react29.default.useState(null);
6208
6488
  const [hoveredSlice, setHoveredSlice] = import_react29.default.useState(null);
6489
+ const chartId = import_react29.default.useId();
6490
+ const wrapperClass = `chart-svg-wrapper-${chartId.replace(/:/g, "-")}`;
6491
+ const gridLabelClass = `chart-grid-label-${chartId.replace(/:/g, "-")}`;
6492
+ const axisLabelClass = `chart-axis-label-${chartId.replace(/:/g, "-")}`;
6493
+ const sliceClass = `chart-slice-${chartId.replace(/:/g, "-")}`;
6209
6494
  const total = data.reduce((sum, item) => sum + item.value, 0);
6210
- const centerX = width / 2;
6211
- const centerY = height / 2;
6212
- const radius = Math.min(width, height) / 2 - 40;
6495
+ const centerX = viewBoxWidth / 2;
6496
+ const centerY = viewBoxHeight / 2;
6497
+ const radius = Math.min(viewBoxWidth, viewBoxHeight) / 2 - 40;
6213
6498
  const innerRadius = donut ? radius - donutWidth : 0;
6499
+ const gridLabelFontSize = viewBoxWidth * 0.045;
6500
+ const axisLabelFontSize = viewBoxWidth * 0.05;
6501
+ const titleFontSize = viewBoxWidth * 0.055;
6214
6502
  let currentAngle = -90;
6215
6503
  const slices = data.map((item, index) => {
6216
6504
  const percentage = item.value / total * 100;
@@ -6262,20 +6550,64 @@ var PieChart = ({
6262
6550
  index
6263
6551
  };
6264
6552
  });
6553
+ const getTooltipPosition = import_react29.default.useCallback((x, y) => {
6554
+ if (!containerRef.current) return { x, y };
6555
+ const rect = containerRef.current.getBoundingClientRect();
6556
+ const tooltipWidth = 120;
6557
+ const tooltipHeight = 80;
6558
+ let tooltipX = x + 10;
6559
+ let tooltipY = y - 30;
6560
+ if (tooltipX + tooltipWidth > rect.width) {
6561
+ tooltipX = x - tooltipWidth - 10;
6562
+ }
6563
+ if (tooltipY + tooltipHeight > rect.height) {
6564
+ tooltipY = y + 30;
6565
+ }
6566
+ return { x: tooltipX, y: tooltipY };
6567
+ }, []);
6568
+ const containerStyle = {
6569
+ "--font-size-base": `${baseFontSize}px`,
6570
+ "--font-size-lg": `calc(var(--font-size-base) * 1.125)`,
6571
+ "--font-size-sm": `calc(var(--font-size-base) * 0.875)`,
6572
+ "--font-size-xs": `calc(var(--font-size-base) * 0.75)`,
6573
+ "--font-size-xl": `calc(var(--font-size-base) * 1.5)`,
6574
+ "--font-size-2xl": `calc(var(--font-size-base) * 2)`
6575
+ };
6576
+ if (responsive) {
6577
+ containerStyle["--font-size-base"] = `clamp(${baseFontSize * 0.8}px, 4vw, ${baseFontSize}px)`;
6578
+ }
6265
6579
  return /* @__PURE__ */ (0, import_jsx_runtime111.jsxs)(
6266
6580
  "div",
6267
6581
  {
6268
- className: `relative ${responsive ? "w-full flex justify-center" : "inline-block"} ${className}`,
6269
- style: responsive ? { aspectRatio: `${width} / ${height}` } : void 0,
6582
+ ref: containerRef,
6583
+ className: `relative flex flex-col gap-4 ${responsive ? "w-full" : "inline-block"} ${className}`,
6584
+ style: containerStyle,
6270
6585
  children: [
6586
+ /* @__PURE__ */ (0, import_jsx_runtime111.jsx)("style", { children: `
6587
+ /* Mobile: Large fonts (default) */
6588
+ .${gridLabelClass} { font-size: ${gridLabelFontSize}px !important; }
6589
+ .${axisLabelClass} { font-size: ${titleFontSize}px !important; }
6590
+
6591
+ /* Tablet: Medium fonts */
6592
+ @media (min-width: 640px) {
6593
+ .${gridLabelClass} { font-size: ${gridLabelFontSize * 0.7}px !important; }
6594
+ .${axisLabelClass} { font-size: ${titleFontSize * 0.7}px !important; }
6595
+ }
6596
+
6597
+ /* Desktop: Small fonts */
6598
+ @media (min-width: 1024px) {
6599
+ .${gridLabelClass} { font-size: ${gridLabelFontSize * 0.4}px !important; }
6600
+ .${axisLabelClass} { font-size: ${titleFontSize * 0.4}px !important; }
6601
+ }
6602
+ ` }),
6271
6603
  /* @__PURE__ */ (0, import_jsx_runtime111.jsxs)(
6272
6604
  "svg",
6273
6605
  {
6274
6606
  width: "100%",
6275
- height: "100%",
6276
- viewBox: `0 0 ${width} ${height}`,
6607
+ viewBox: `0 0 ${viewBoxWidth} ${viewBoxHeight}`,
6277
6608
  preserveAspectRatio: "xMidYMid meet",
6278
- className: "bg-white dark:bg-gray-800 block",
6609
+ className: "bg-white dark:bg-gray-800 block w-full",
6610
+ style: { height: "auto", overflow: "visible" },
6279
6611
  children: [
6280
6612
  slices.map((slice) => {
6281
6613
  const isHovered = hoveredSlice === slice.index;
@@ -6289,8 +6621,19 @@ var PieChart = ({
6289
6621
  strokeWidth: "2",
6290
6622
  className: "cursor-pointer transition-opacity",
6291
6623
  opacity: isHovered ? 0.8 : 1,
6292
- onMouseEnter: () => setHoveredSlice(slice.index),
6293
- onMouseLeave: () => setHoveredSlice(null)
6624
+ onMouseEnter: (e) => {
6625
+ setHoveredSlice(slice.index);
6626
+ if (containerRef.current) {
6627
+ const rect = containerRef.current.getBoundingClientRect();
6628
+ const svgX = e.clientX - rect.left;
6629
+ const svgY = e.clientY - rect.top;
6630
+ setTooltipPosition(getTooltipPosition(svgX, svgY));
6631
+ }
6632
+ },
6633
+ onMouseLeave: () => {
6634
+ setHoveredSlice(null);
6635
+ setTooltipPosition(null);
6636
+ }
6294
6637
  }
6295
6638
  ),
6296
6639
  showLabels && slice.percentage > 5 && /* @__PURE__ */ (0, import_jsx_runtime111.jsxs)(
@@ -6300,9 +6643,9 @@ var PieChart = ({
6300
6643
  y: slice.labelY,
6301
6644
  textAnchor: "middle",
6302
6645
  dominantBaseline: "middle",
6303
- fontSize: "14",
6646
+ fontSize: gridLabelFontSize,
6304
6647
  fontWeight: "600",
6305
- className: "fill-gray-700 dark:fill-gray-200 pointer-events-none",
6648
+ className: `fill-gray-700 dark:fill-gray-200 pointer-events-none ${gridLabelClass}`,
6306
6649
  children: [
6307
6650
  showPercentages && `${slice.percentage.toFixed(1)}%`,
6308
6651
  showPercentages && showValues && " ",
@@ -6320,9 +6663,10 @@ var PieChart = ({
6320
6663
  x: centerX,
6321
6664
  y: centerY - 10,
6322
6665
  textAnchor: "middle",
6323
- fontSize: "32",
6666
+ dominantBaseline: "middle",
6667
+ fontSize: titleFontSize,
6324
6668
  fontWeight: "700",
6325
- className: "fill-gray-900 dark:fill-gray-100",
6669
+ className: `fill-gray-900 dark:fill-gray-100 ${axisLabelClass}`,
6326
6670
  children: total
6327
6671
  }
6328
6672
  ),
@@ -6332,8 +6676,9 @@ var PieChart = ({
6332
6676
  x: centerX,
6333
6677
  y: centerY + 15,
6334
6678
  textAnchor: "middle",
6335
- fontSize: "16",
6336
- className: "fill-gray-600 dark:fill-gray-400",
6679
+ dominantBaseline: "middle",
6680
+ fontSize: axisLabelFontSize,
6681
+ className: `fill-gray-600 dark:fill-gray-400 ${gridLabelClass}`,
6337
6682
  children: "Total"
6338
6683
  }
6339
6684
  )
@@ -6341,23 +6686,23 @@ var PieChart = ({
6341
6686
  ]
6342
6687
  }
6343
6688
  ),
6344
- showLegend && /* @__PURE__ */ (0, import_jsx_runtime111.jsx)("div", { className: "flex flex-wrap gap-4 mt-4 justify-center", children: data.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime111.jsxs)(
6689
+ showLegend && /* @__PURE__ */ (0, import_jsx_runtime111.jsx)("div", { className: "flex flex-wrap gap-3 justify-center px-4", children: data.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime111.jsxs)(
6345
6690
  "div",
6346
6691
  {
6347
- className: "flex items-center gap-2 cursor-pointer",
6692
+ className: "flex items-center gap-2 text-sm cursor-pointer",
6348
6693
  onMouseEnter: () => setHoveredSlice(index),
6349
6694
  onMouseLeave: () => setHoveredSlice(null),
6350
6695
  children: [
6351
6696
  /* @__PURE__ */ (0, import_jsx_runtime111.jsx)(
6352
6697
  "div",
6353
6698
  {
6354
- className: "w-4 h-4 rounded-sm",
6699
+ className: "w-3 h-3 rounded-sm flex-shrink-0",
6355
6700
  style: {
6356
6701
  backgroundColor: item.color || defaultColors4[index % defaultColors4.length]
6357
6702
  }
6358
6703
  }
6359
6704
  ),
6360
- /* @__PURE__ */ (0, import_jsx_runtime111.jsxs)("span", { className: "text-sm text-gray-700 dark:text-gray-300", children: [
6705
+ /* @__PURE__ */ (0, import_jsx_runtime111.jsxs)("span", { className: "text-gray-700 dark:text-gray-300", children: [
6361
6706
  item.label,
6362
6707
  ": ",
6363
6708
  item.value,
@@ -6367,18 +6712,29 @@ var PieChart = ({
6367
6712
  },
6368
6713
  `legend-${index}`
6369
6714
  )) }),
6370
- hoveredSlice !== null && /* @__PURE__ */ (0, import_jsx_runtime111.jsxs)("div", { className: "absolute top-2 right-2 bg-gray-900 dark:bg-gray-700 text-white px-3 py-2 rounded shadow-lg text-sm pointer-events-none z-50", children: [
6371
- /* @__PURE__ */ (0, import_jsx_runtime111.jsx)("div", { className: "font-semibold", children: data[hoveredSlice].label }),
6372
- /* @__PURE__ */ (0, import_jsx_runtime111.jsxs)("div", { children: [
6373
- "Value: ",
6374
- data[hoveredSlice].value
6375
- ] }),
6376
- /* @__PURE__ */ (0, import_jsx_runtime111.jsxs)("div", { children: [
6377
- "Percentage: ",
6378
- (data[hoveredSlice].value / total * 100).toFixed(1),
6379
- "%"
6380
- ] })
6381
- ] })
6715
+ hoveredSlice !== null && tooltipPosition && /* @__PURE__ */ (0, import_jsx_runtime111.jsxs)(
6716
+ "div",
6717
+ {
6718
+ className: "absolute bg-gray-900 dark:bg-gray-700 text-white px-3 py-2 rounded shadow-lg pointer-events-none z-50 text-sm whitespace-nowrap",
6719
+ style: {
6720
+ left: `${tooltipPosition.x}px`,
6721
+ top: `${tooltipPosition.y}px`,
6722
+ transform: "translateZ(0)"
6723
+ },
6724
+ children: [
6725
+ /* @__PURE__ */ (0, import_jsx_runtime111.jsx)("div", { className: "font-semibold", children: data[hoveredSlice].label }),
6726
+ /* @__PURE__ */ (0, import_jsx_runtime111.jsxs)("div", { className: "text-xs opacity-90", children: [
6727
+ "Value: ",
6728
+ data[hoveredSlice].value
6729
+ ] }),
6730
+ /* @__PURE__ */ (0, import_jsx_runtime111.jsxs)("div", { className: "text-xs opacity-90", children: [
6731
+ "Percentage: ",
6732
+ (data[hoveredSlice].value / total * 100).toFixed(1),
6733
+ "%"
6734
+ ] })
6735
+ ]
6736
+ }
6737
+ )
6382
6738
  ]
6383
6739
  }
6384
6740
  );