@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.mjs CHANGED
@@ -459,11 +459,23 @@ var Navbar = ({
459
459
  logo,
460
460
  children,
461
461
  className = "",
462
- sticky = false
462
+ sticky = false,
463
+ variant = "solid"
463
464
  }) => {
464
465
  const { theme } = useTheme();
465
466
  const baseClasses = sticky ? "sticky top-0 z-40" : "";
466
- return /* @__PURE__ */ jsx5("nav", { className: `bg-white dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700 ${baseClasses} ${className}`, children: /* @__PURE__ */ jsx5("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: /* @__PURE__ */ jsxs4("div", { className: "flex justify-between items-center h-16", children: [
467
+ const getVariantClasses = () => {
468
+ switch (variant) {
469
+ case "glass":
470
+ return "bg-transparent backdrop-blur-xl";
471
+ case "transparent":
472
+ return "bg-transparent";
473
+ case "solid":
474
+ default:
475
+ return "bg-white dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700";
476
+ }
477
+ };
478
+ return /* @__PURE__ */ jsx5("nav", { className: `${getVariantClasses()} ${baseClasses} ${className}`, children: /* @__PURE__ */ jsx5("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: /* @__PURE__ */ jsxs4("div", { className: "flex justify-between items-center h-16", children: [
467
479
  logo && /* @__PURE__ */ jsx5("div", { className: "flex items-center", children: logo }),
468
480
  children && /* @__PURE__ */ jsx5("div", { className: "flex items-center gap-6", children })
469
481
  ] }) }) });
@@ -5149,14 +5161,32 @@ var LineChart = ({
5149
5161
  strokeWidth = 2,
5150
5162
  className = "",
5151
5163
  xAxisLabel,
5152
- yAxisLabel
5164
+ yAxisLabel,
5165
+ baseFontSize = 14
5153
5166
  }) => {
5154
- const height = providedHeight ?? 400;
5155
- const width = providedWidth ?? (responsive ? 600 : 600);
5167
+ const viewBoxWidth = 1e3;
5168
+ const viewBoxHeight = 600;
5169
+ const containerRef = React26.useRef(null);
5170
+ const svgRef = React26.useRef(null);
5171
+ const [tooltipPosition, setTooltipPosition] = React26.useState(null);
5156
5172
  const [hoveredPoint, setHoveredPoint] = React26.useState(null);
5157
- const padding = { top: 20, right: 20, bottom: showXAxis ? 60 : 20, left: showYAxis ? 60 : 20 };
5158
- const chartWidth = width - padding.left - padding.right;
5159
- const chartHeight = height - padding.top - padding.bottom;
5173
+ const chartId = React26.useId();
5174
+ const wrapperClass = `chart-svg-wrapper-${chartId.replace(/:/g, "-")}`;
5175
+ const gridLabelClass = `chart-grid-label-${chartId.replace(/:/g, "-")}`;
5176
+ const axisLabelClass = `chart-axis-label-${chartId.replace(/:/g, "-")}`;
5177
+ const lineClass = `chart-line-${chartId.replace(/:/g, "-")}`;
5178
+ const pointClass = `chart-point-${chartId.replace(/:/g, "-")}`;
5179
+ const padding = {
5180
+ top: 50,
5181
+ right: 50,
5182
+ bottom: showXAxis ? 120 : 50,
5183
+ left: showYAxis ? 130 : 50
5184
+ };
5185
+ const chartWidth = viewBoxWidth - padding.left - padding.right;
5186
+ const chartHeight = viewBoxHeight - padding.top - padding.bottom;
5187
+ const gridLabelFontSize = viewBoxWidth * 0.045;
5188
+ const axisLabelFontSize = viewBoxWidth * 0.05;
5189
+ const titleFontSize = viewBoxWidth * 0.055;
5160
5190
  const allPoints = data.flatMap((series) => series.data);
5161
5191
  const allYValues = allPoints.map((p) => p.y);
5162
5192
  const firstXValue = data[0]?.data[0]?.x;
@@ -5169,7 +5199,7 @@ var LineChart = ({
5169
5199
  const minY = Math.min(0, ...allYValues);
5170
5200
  const maxY = Math.max(...allYValues);
5171
5201
  const yRange = maxY - minY;
5172
- const yMin = minY - yRange * 0.1;
5202
+ const yMin = Math.max(0, minY - yRange * 0.1);
5173
5203
  const yMax = maxY + yRange * 0.1;
5174
5204
  const scaleX = (x, index) => {
5175
5205
  const numX = isStringX ? index : x;
@@ -5216,29 +5246,32 @@ var LineChart = ({
5216
5246
  x2: chartWidth,
5217
5247
  y2: y,
5218
5248
  stroke: "currentColor",
5219
- strokeWidth: "1",
5249
+ strokeWidth: "0.5",
5220
5250
  className: "text-gray-200 dark:text-gray-700",
5221
- strokeDasharray: "2,2"
5251
+ strokeDasharray: "4,4"
5222
5252
  }
5223
5253
  ),
5224
5254
  showYAxis && /* @__PURE__ */ jsx108(
5225
5255
  "text",
5226
5256
  {
5227
- x: -10,
5228
- y: y + 4,
5257
+ x: -25,
5258
+ y,
5229
5259
  textAnchor: "end",
5230
- fontSize: "16",
5231
- className: "fill-gray-600 dark:fill-gray-400",
5260
+ dominantBaseline: "middle",
5261
+ fontSize: gridLabelFontSize,
5262
+ className: `fill-gray-600 dark:fill-gray-400 ${gridLabelClass}`,
5232
5263
  children: yValue.toFixed(1)
5233
5264
  }
5234
5265
  )
5235
5266
  ] }, `grid-h-${i}`)
5236
5267
  );
5237
5268
  }
5238
- const numXGridLines = Math.min(allPoints.length, 6);
5269
+ const numXGridLines = Math.max(2, Math.min(allPoints.length, 6));
5270
+ const xGridStep = numXGridLines > 1 ? 1 / (numXGridLines - 1) : 0;
5239
5271
  for (let i = 0; i < numXGridLines; i++) {
5240
- const x = chartWidth / (numXGridLines - 1) * i;
5241
- const xValue = data[0]?.data[Math.floor((data[0].data.length - 1) * (i / (numXGridLines - 1)))]?.x || "";
5272
+ const x = chartWidth * (i * xGridStep);
5273
+ const dataIndex = Math.floor((data[0]?.data.length - 1) * (i * xGridStep));
5274
+ const xValue = data[0]?.data[Math.max(0, Math.min(dataIndex, data[0].data.length - 1))]?.x || "";
5242
5275
  gridLines.push(
5243
5276
  /* @__PURE__ */ jsxs35("g", { children: [
5244
5277
  /* @__PURE__ */ jsx108(
@@ -5249,19 +5282,20 @@ var LineChart = ({
5249
5282
  x2: x,
5250
5283
  y2: chartHeight,
5251
5284
  stroke: "currentColor",
5252
- strokeWidth: "1",
5285
+ strokeWidth: "0.5",
5253
5286
  className: "text-gray-200 dark:text-gray-700",
5254
- strokeDasharray: "2,2"
5287
+ strokeDasharray: "4,4"
5255
5288
  }
5256
5289
  ),
5257
5290
  showXAxis && /* @__PURE__ */ jsx108(
5258
5291
  "text",
5259
5292
  {
5260
5293
  x,
5261
- y: chartHeight + 20,
5294
+ y: chartHeight + 35,
5262
5295
  textAnchor: "middle",
5263
- fontSize: "14",
5264
- className: "fill-gray-600 dark:fill-gray-400",
5296
+ dominantBaseline: "hanging",
5297
+ fontSize: gridLabelFontSize,
5298
+ className: `fill-gray-600 dark:fill-gray-400 ${gridLabelClass}`,
5265
5299
  children: xValue
5266
5300
  }
5267
5301
  )
@@ -5269,21 +5303,74 @@ var LineChart = ({
5269
5303
  );
5270
5304
  }
5271
5305
  }
5306
+ const getTooltipPosition = React26.useCallback((x, y) => {
5307
+ if (!containerRef.current) return { x, y };
5308
+ const rect = containerRef.current.getBoundingClientRect();
5309
+ const tooltipWidth = 120;
5310
+ const tooltipHeight = 80;
5311
+ let tooltipX = x + 10;
5312
+ let tooltipY = y - 30;
5313
+ if (tooltipX + tooltipWidth > rect.width) {
5314
+ tooltipX = x - tooltipWidth - 10;
5315
+ }
5316
+ if (tooltipY + tooltipHeight > rect.height) {
5317
+ tooltipY = y + 30;
5318
+ }
5319
+ return { x: tooltipX, y: tooltipY };
5320
+ }, []);
5321
+ const containerStyle = {
5322
+ "--font-size-base": `${baseFontSize}px`,
5323
+ "--font-size-lg": `calc(var(--font-size-base) * 1.125)`,
5324
+ "--font-size-sm": `calc(var(--font-size-base) * 0.875)`,
5325
+ "--font-size-xs": `calc(var(--font-size-base) * 0.75)`
5326
+ };
5272
5327
  return /* @__PURE__ */ jsxs35(
5273
5328
  "div",
5274
5329
  {
5275
- className: `relative ${responsive ? "w-full" : "inline-block"} ${className}`,
5276
- style: responsive ? { aspectRatio: `${width} / ${height}` } : void 0,
5330
+ ref: containerRef,
5331
+ className: `relative flex flex-col gap-4 ${responsive ? "w-full" : "inline-block"} ${className}`,
5332
+ style: {
5333
+ ...containerStyle
5334
+ },
5277
5335
  children: [
5336
+ /* @__PURE__ */ jsx108("style", { children: `
5337
+ /* Mobile: Large fonts, hidden axis titles, thicker lines (default) */
5338
+ .${gridLabelClass} { font-size: ${gridLabelFontSize}px !important; }
5339
+ .${axisLabelClass} { display: none; }
5340
+ .${lineClass} { stroke-width: ${strokeWidth * 2.5} !important; }
5341
+ .${pointClass} { r: 6 !important; stroke-width: 3 !important; }
5342
+
5343
+ /* Tablet: Medium fonts, show axis titles, medium lines */
5344
+ @media (min-width: 640px) {
5345
+ .${gridLabelClass} { font-size: ${gridLabelFontSize * 0.7}px !important; }
5346
+ .${axisLabelClass} {
5347
+ font-size: ${axisLabelFontSize * 0.7}px !important;
5348
+ display: block;
5349
+ }
5350
+ .${lineClass} { stroke-width: ${strokeWidth * 1.5} !important; }
5351
+ .${pointClass} { r: 4 !important; stroke-width: 2 !important; }
5352
+ }
5353
+
5354
+ /* Desktop: Small fonts, show axis titles, normal lines */
5355
+ @media (min-width: 1024px) {
5356
+ .${gridLabelClass} { font-size: ${gridLabelFontSize * 0.4}px !important; }
5357
+ .${axisLabelClass} {
5358
+ font-size: ${axisLabelFontSize * 0.4}px !important;
5359
+ display: block;
5360
+ }
5361
+ .${lineClass} { stroke-width: ${strokeWidth} !important; }
5362
+ .${pointClass} { r: 3 !important; stroke-width: 1.5 !important; }
5363
+ }
5364
+ ` }),
5278
5365
  /* @__PURE__ */ jsx108(
5279
5366
  "svg",
5280
5367
  {
5368
+ ref: svgRef,
5281
5369
  width: "100%",
5282
- height: "100%",
5283
- viewBox: `0 0 ${width} ${height}`,
5370
+ viewBox: `0 0 ${viewBoxWidth} ${viewBoxHeight}`,
5284
5371
  preserveAspectRatio: "xMidYMid meet",
5285
- className: "bg-white dark:bg-gray-800 block",
5286
- style: { overflow: "visible" },
5372
+ className: "bg-white dark:bg-gray-800 block w-full",
5373
+ style: { height: "auto", overflow: "visible" },
5287
5374
  children: /* @__PURE__ */ jsxs35("g", { transform: `translate(${padding.left}, ${padding.top})`, children: [
5288
5375
  gridLines,
5289
5376
  data.map((series, seriesIndex) => /* @__PURE__ */ jsx108(
@@ -5294,7 +5381,8 @@ var LineChart = ({
5294
5381
  stroke: series.color || defaultColors[seriesIndex % defaultColors.length],
5295
5382
  strokeWidth,
5296
5383
  strokeLinecap: "round",
5297
- strokeLinejoin: "round"
5384
+ strokeLinejoin: "round",
5385
+ className: lineClass
5298
5386
  },
5299
5387
  `line-${seriesIndex}`
5300
5388
  )),
@@ -5308,13 +5396,32 @@ var LineChart = ({
5308
5396
  {
5309
5397
  cx: x,
5310
5398
  cy: y,
5311
- r: isHovered ? 6 : 4,
5399
+ r: isHovered ? 5 : 3,
5312
5400
  fill: series.color || defaultColors[seriesIndex % defaultColors.length],
5313
5401
  stroke: "white",
5314
- strokeWidth: "2",
5315
- className: "cursor-pointer transition-all",
5316
- onMouseEnter: () => showTooltip && setHoveredPoint({ seriesIndex, pointIndex, x, y }),
5317
- onMouseLeave: () => setHoveredPoint(null)
5402
+ strokeWidth: "1.5",
5403
+ className: `cursor-pointer transition-all ${pointClass}`,
5404
+ onMouseEnter: (e) => {
5405
+ if (showTooltip && containerRef.current) {
5406
+ setHoveredPoint({ seriesIndex, pointIndex, x, y });
5407
+ const containerRect = containerRef.current.getBoundingClientRect();
5408
+ const mouseX = e.clientX - containerRect.left;
5409
+ const mouseY = e.clientY - containerRect.top;
5410
+ setTooltipPosition(getTooltipPosition(mouseX, mouseY));
5411
+ }
5412
+ },
5413
+ onMouseMove: (e) => {
5414
+ if (showTooltip && hoveredPoint?.seriesIndex === seriesIndex && hoveredPoint?.pointIndex === pointIndex && containerRef.current) {
5415
+ const containerRect = containerRef.current.getBoundingClientRect();
5416
+ const mouseX = e.clientX - containerRect.left;
5417
+ const mouseY = e.clientY - containerRect.top;
5418
+ setTooltipPosition(getTooltipPosition(mouseX, mouseY));
5419
+ }
5420
+ },
5421
+ onMouseLeave: () => {
5422
+ setHoveredPoint(null);
5423
+ setTooltipPosition(null);
5424
+ }
5318
5425
  },
5319
5426
  `point-${seriesIndex}-${pointIndex}`
5320
5427
  );
@@ -5324,11 +5431,12 @@ var LineChart = ({
5324
5431
  "text",
5325
5432
  {
5326
5433
  x: chartWidth / 2,
5327
- y: chartHeight + 50,
5434
+ y: chartHeight + 80,
5328
5435
  textAnchor: "middle",
5329
- fontSize: "16",
5330
- fontWeight: "500",
5331
- className: "fill-gray-700 dark:fill-gray-300",
5436
+ dominantBaseline: "hanging",
5437
+ fontSize: axisLabelFontSize,
5438
+ fontWeight: "600",
5439
+ className: `fill-gray-700 dark:fill-gray-300 ${axisLabelClass}`,
5332
5440
  children: xAxisLabel
5333
5441
  }
5334
5442
  ),
@@ -5336,45 +5444,47 @@ var LineChart = ({
5336
5444
  "text",
5337
5445
  {
5338
5446
  x: -chartHeight / 2,
5339
- y: -45,
5447
+ y: -100,
5340
5448
  textAnchor: "middle",
5341
- fontSize: "16",
5342
- fontWeight: "500",
5343
- transform: `rotate(-90, 0, 0)`,
5344
- className: "fill-gray-700 dark:fill-gray-300",
5449
+ dominantBaseline: "middle",
5450
+ fontSize: axisLabelFontSize,
5451
+ fontWeight: "600",
5452
+ transform: "rotate(-90)",
5453
+ className: `fill-gray-700 dark:fill-gray-300 ${axisLabelClass}`,
5345
5454
  children: yAxisLabel
5346
5455
  }
5347
5456
  )
5348
5457
  ] })
5349
5458
  }
5350
5459
  ),
5351
- showLegend && /* @__PURE__ */ jsx108("div", { className: "flex flex-wrap gap-4 mt-4 justify-center", children: data.map((series, index) => /* @__PURE__ */ jsxs35("div", { className: "flex items-center gap-2", children: [
5460
+ showLegend && /* @__PURE__ */ jsx108("div", { className: "flex flex-wrap gap-3 justify-center px-4", children: data.map((series, index) => /* @__PURE__ */ jsxs35("div", { className: "flex items-center gap-2 text-sm", children: [
5352
5461
  /* @__PURE__ */ jsx108(
5353
5462
  "div",
5354
5463
  {
5355
- className: "w-4 h-4 rounded-sm",
5464
+ className: "w-3 h-3 rounded-sm flex-shrink-0",
5356
5465
  style: {
5357
5466
  backgroundColor: series.color || defaultColors[index % defaultColors.length]
5358
5467
  }
5359
5468
  }
5360
5469
  ),
5361
- /* @__PURE__ */ jsx108("span", { className: "text-sm text-gray-700 dark:text-gray-300", children: series.name })
5470
+ /* @__PURE__ */ jsx108("span", { className: "text-gray-700 dark:text-gray-300", children: series.name })
5362
5471
  ] }, `legend-${index}`)) }),
5363
- showTooltip && hoveredPoint && /* @__PURE__ */ jsxs35(
5472
+ showTooltip && hoveredPoint && tooltipPosition && /* @__PURE__ */ jsxs35(
5364
5473
  "div",
5365
5474
  {
5366
- 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",
5475
+ 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",
5367
5476
  style: {
5368
- left: `${padding.left + hoveredPoint.x + 10}px`,
5369
- top: `${padding.top + hoveredPoint.y - 30}px`
5477
+ left: `${tooltipPosition.x}px`,
5478
+ top: `${tooltipPosition.y}px`,
5479
+ transform: "translateZ(0)"
5370
5480
  },
5371
5481
  children: [
5372
5482
  /* @__PURE__ */ jsx108("div", { className: "font-semibold", children: data[hoveredPoint.seriesIndex].name }),
5373
- /* @__PURE__ */ jsxs35("div", { children: [
5483
+ /* @__PURE__ */ jsxs35("div", { className: "text-xs opacity-90", children: [
5374
5484
  "x: ",
5375
5485
  data[hoveredPoint.seriesIndex].data[hoveredPoint.pointIndex].x
5376
5486
  ] }),
5377
- /* @__PURE__ */ jsxs35("div", { children: [
5487
+ /* @__PURE__ */ jsxs35("div", { className: "text-xs opacity-90", children: [
5378
5488
  "y: ",
5379
5489
  data[hoveredPoint.seriesIndex].data[hoveredPoint.pointIndex].y
5380
5490
  ] })
@@ -5420,26 +5530,38 @@ var BarChart = ({
5420
5530
  barWidth = 0.8,
5421
5531
  className = "",
5422
5532
  xAxisLabel,
5423
- yAxisLabel
5533
+ yAxisLabel,
5534
+ baseFontSize = 14,
5535
+ colors = defaultColors2
5424
5536
  }) => {
5425
- const height = providedHeight ?? 400;
5426
- const width = providedWidth ?? (responsive ? 800 : 600);
5537
+ const viewBoxWidth = 1e3;
5538
+ const viewBoxHeight = 600;
5539
+ const containerRef = React27.useRef(null);
5540
+ const [tooltipPosition, setTooltipPosition] = React27.useState(null);
5427
5541
  const [hoveredBar, setHoveredBar] = React27.useState(null);
5542
+ const chartId = React27.useId();
5543
+ const wrapperClass = `chart-svg-wrapper-${chartId.replace(/:/g, "-")}`;
5544
+ const gridLabelClass = `chart-grid-label-${chartId.replace(/:/g, "-")}`;
5545
+ const axisLabelClass = `chart-axis-label-${chartId.replace(/:/g, "-")}`;
5546
+ const barClass = `chart-bar-${chartId.replace(/:/g, "-")}`;
5428
5547
  const padding = {
5429
- top: 20,
5430
- right: 20,
5431
- bottom: showXAxis ? horizontal ? 60 : 80 : 20,
5432
- left: showYAxis ? horizontal ? 80 : 60 : 20
5548
+ top: 50,
5549
+ right: 50,
5550
+ bottom: showXAxis ? horizontal ? 120 : 140 : 50,
5551
+ left: showYAxis ? horizontal ? 140 : 130 : 50
5433
5552
  };
5434
- const chartWidth = width - padding.left - padding.right;
5435
- const chartHeight = height - padding.top - padding.bottom;
5553
+ const chartWidth = viewBoxWidth - padding.left - padding.right;
5554
+ const chartHeight = viewBoxHeight - padding.top - padding.bottom;
5555
+ const gridLabelFontSize = viewBoxWidth * 0.045;
5556
+ const axisLabelFontSize = viewBoxWidth * 0.05;
5557
+ const titleFontSize = viewBoxWidth * 0.055;
5436
5558
  const allYValues = stacked ? data[0]?.data.map(
5437
5559
  (_, i) => data.reduce((sum, series) => sum + (series.data[i]?.y || 0), 0)
5438
5560
  ) || [] : data.flatMap((series) => series.data.map((p) => p.y));
5439
5561
  const minY = Math.min(0, ...allYValues);
5440
5562
  const maxY = Math.max(...allYValues);
5441
5563
  const yRange = maxY - minY;
5442
- const yMin = minY - yRange * 0.1;
5564
+ const yMin = Math.max(0, minY - yRange * 0.1);
5443
5565
  const yMax = maxY + yRange * 0.1;
5444
5566
  const numBars = data[0]?.data.length || 0;
5445
5567
  const numSeries = data.length;
@@ -5466,19 +5588,20 @@ var BarChart = ({
5466
5588
  x2: chartWidth,
5467
5589
  y2: y,
5468
5590
  stroke: "currentColor",
5469
- strokeWidth: "1",
5591
+ strokeWidth: "0.5",
5470
5592
  className: "text-gray-200 dark:text-gray-700",
5471
- strokeDasharray: "2,2"
5593
+ strokeDasharray: "4,4"
5472
5594
  }
5473
5595
  ),
5474
5596
  showYAxis && !horizontal && /* @__PURE__ */ jsx109(
5475
5597
  "text",
5476
5598
  {
5477
- x: -10,
5478
- y: y + 4,
5599
+ x: -25,
5600
+ y,
5479
5601
  textAnchor: "end",
5480
- fontSize: "14",
5481
- className: "fill-gray-600 dark:fill-gray-400",
5602
+ dominantBaseline: "middle",
5603
+ fontSize: gridLabelFontSize,
5604
+ className: `fill-gray-600 dark:fill-gray-400 ${gridLabelClass}`,
5482
5605
  children: yValue.toFixed(0)
5483
5606
  }
5484
5607
  )
@@ -5527,12 +5650,20 @@ var BarChart = ({
5527
5650
  x: xPos,
5528
5651
  y: yPos,
5529
5652
  width: barW,
5530
- height: barHeight,
5531
- fill: data[seriesIndex].color || defaultColors2[seriesIndex % defaultColors2.length],
5532
- className: "cursor-pointer transition-opacity",
5653
+ height: Math.abs(scaleY(0) - yPos),
5654
+ fill: data[seriesIndex].color || colors[seriesIndex % colors.length],
5655
+ className: `cursor-pointer transition-opacity ${barClass}`,
5533
5656
  opacity: isHovered ? 0.8 : 1,
5534
- onMouseEnter: () => showTooltip && setHoveredBar({ seriesIndex, barIndex, x: xPos + barW / 2, y: yPos }),
5535
- onMouseLeave: () => setHoveredBar(null)
5657
+ onMouseEnter: () => {
5658
+ if (showTooltip) {
5659
+ setHoveredBar({ seriesIndex, barIndex, x: xPos + barW / 2, y: yPos });
5660
+ setTooltipPosition(getTooltipPosition(padding.left + xPos + barW / 2, padding.top + yPos));
5661
+ }
5662
+ },
5663
+ onMouseLeave: () => {
5664
+ setHoveredBar(null);
5665
+ setTooltipPosition(null);
5666
+ }
5536
5667
  },
5537
5668
  `bar-${seriesIndex}-${barIndex}`
5538
5669
  )
@@ -5557,8 +5688,8 @@ var BarChart = ({
5557
5688
  y: yPos,
5558
5689
  width: actualBarWidth,
5559
5690
  height: barHeight,
5560
- fill: data[seriesIndex].color || defaultColors2[seriesIndex % defaultColors2.length],
5561
- className: "cursor-pointer transition-opacity",
5691
+ fill: data[seriesIndex].color || colors[seriesIndex % colors.length],
5692
+ className: `cursor-pointer transition-opacity ${barClass}`,
5562
5693
  opacity: isHovered ? 0.8 : 1,
5563
5694
  onMouseEnter: () => showTooltip && setHoveredBar({ seriesIndex, barIndex, x: xPos + actualBarWidth / 2, y: yPos }),
5564
5695
  onMouseLeave: () => setHoveredBar(null)
@@ -5572,10 +5703,11 @@ var BarChart = ({
5572
5703
  "text",
5573
5704
  {
5574
5705
  x: xPos + actualBarWidth / 2,
5575
- y: yPos - 5,
5706
+ y: yPos - 10,
5576
5707
  textAnchor: "middle",
5577
- fontSize: "14",
5578
- fontWeight: "500",
5708
+ dominantBaseline: "middle",
5709
+ fontSize: "11",
5710
+ fontWeight: "600",
5579
5711
  className: "fill-gray-700 dark:fill-gray-300",
5580
5712
  children: point.y
5581
5713
  },
@@ -5594,30 +5726,77 @@ var BarChart = ({
5594
5726
  "text",
5595
5727
  {
5596
5728
  x: xPos,
5597
- y: chartHeight + 20,
5729
+ y: chartHeight + 35,
5598
5730
  textAnchor: "middle",
5599
- fontSize: "14",
5600
- className: "fill-gray-600 dark:fill-gray-400",
5731
+ dominantBaseline: "hanging",
5732
+ fontSize: gridLabelFontSize,
5733
+ className: `fill-gray-600 dark:fill-gray-400 ${gridLabelClass}`,
5601
5734
  children: point.x
5602
5735
  },
5603
5736
  `x-label-${i}`
5604
5737
  );
5605
5738
  });
5739
+ const getTooltipPosition = React27.useCallback((x, y) => {
5740
+ if (!containerRef.current) return { x, y };
5741
+ const rect = containerRef.current.getBoundingClientRect();
5742
+ const tooltipWidth = 140;
5743
+ const tooltipHeight = 80;
5744
+ let tooltipX = x + 10;
5745
+ let tooltipY = y - 30;
5746
+ if (tooltipX + tooltipWidth > rect.width) {
5747
+ tooltipX = x - tooltipWidth - 10;
5748
+ }
5749
+ if (tooltipY + tooltipHeight > rect.height) {
5750
+ tooltipY = y + 30;
5751
+ }
5752
+ return { x: tooltipX, y: tooltipY };
5753
+ }, []);
5754
+ const containerStyle = {
5755
+ "--font-size-base": `${baseFontSize}px`,
5756
+ "--font-size-lg": `calc(var(--font-size-base) * 1.125)`,
5757
+ "--font-size-sm": `calc(var(--font-size-base) * 0.875)`,
5758
+ "--font-size-xs": `calc(var(--font-size-base) * 0.75)`
5759
+ };
5606
5760
  return /* @__PURE__ */ jsxs36(
5607
5761
  "div",
5608
5762
  {
5609
- className: `relative ${responsive ? "w-full" : "inline-block"} ${className}`,
5610
- style: responsive ? { aspectRatio: `${width} / ${height}` } : void 0,
5763
+ ref: containerRef,
5764
+ className: `relative flex flex-col gap-4 ${responsive ? "w-full" : "inline-block"} ${className}`,
5765
+ style: {
5766
+ ...containerStyle
5767
+ },
5611
5768
  children: [
5769
+ /* @__PURE__ */ jsx109("style", { children: `
5770
+ /* Mobile: Large fonts, hidden axis titles, thicker bars (default) */
5771
+ .${gridLabelClass} { font-size: ${gridLabelFontSize}px !important; }
5772
+ .${axisLabelClass} { display: none; }
5773
+
5774
+ /* Tablet: Medium fonts, show axis titles */
5775
+ @media (min-width: 640px) {
5776
+ .${gridLabelClass} { font-size: ${gridLabelFontSize * 0.7}px !important; }
5777
+ .${axisLabelClass} {
5778
+ font-size: ${axisLabelFontSize * 0.7}px !important;
5779
+ display: block;
5780
+ }
5781
+ }
5782
+
5783
+ /* Desktop: Small fonts, show axis titles */
5784
+ @media (min-width: 1024px) {
5785
+ .${gridLabelClass} { font-size: ${gridLabelFontSize * 0.4}px !important; }
5786
+ .${axisLabelClass} {
5787
+ font-size: ${axisLabelFontSize * 0.4}px !important;
5788
+ display: block;
5789
+ }
5790
+ }
5791
+ ` }),
5612
5792
  /* @__PURE__ */ jsx109(
5613
5793
  "svg",
5614
5794
  {
5615
5795
  width: "100%",
5616
- height: "100%",
5617
- viewBox: `0 0 ${width} ${height}`,
5796
+ viewBox: `0 0 ${viewBoxWidth} ${viewBoxHeight}`,
5618
5797
  preserveAspectRatio: "xMidYMid meet",
5619
- className: "bg-white dark:bg-gray-800 block",
5620
- style: { overflow: "visible" },
5798
+ className: "bg-white dark:bg-gray-800 block w-full",
5799
+ style: { height: "auto", overflow: "visible" },
5621
5800
  children: /* @__PURE__ */ jsxs36("g", { transform: `translate(${padding.left}, ${padding.top})`, children: [
5622
5801
  gridLines,
5623
5802
  renderBars(),
@@ -5626,11 +5805,12 @@ var BarChart = ({
5626
5805
  "text",
5627
5806
  {
5628
5807
  x: chartWidth / 2,
5629
- y: chartHeight + 50,
5808
+ y: chartHeight + 80,
5630
5809
  textAnchor: "middle",
5631
- fontSize: "16",
5632
- fontWeight: "500",
5633
- className: "fill-gray-700 dark:fill-gray-300",
5810
+ dominantBaseline: "hanging",
5811
+ fontSize: axisLabelFontSize,
5812
+ fontWeight: "600",
5813
+ className: `fill-gray-700 dark:fill-gray-300 ${axisLabelClass}`,
5634
5814
  children: xAxisLabel
5635
5815
  }
5636
5816
  ),
@@ -5638,41 +5818,43 @@ var BarChart = ({
5638
5818
  "text",
5639
5819
  {
5640
5820
  x: -chartHeight / 2,
5641
- y: -45,
5821
+ y: -100,
5642
5822
  textAnchor: "middle",
5643
- fontSize: "16",
5644
- fontWeight: "500",
5645
- transform: `rotate(-90, 0, 0)`,
5646
- className: "fill-gray-700 dark:fill-gray-300",
5823
+ dominantBaseline: "middle",
5824
+ fontSize: axisLabelFontSize,
5825
+ fontWeight: "600",
5826
+ transform: "rotate(-90)",
5827
+ className: `fill-gray-700 dark:fill-gray-300 ${axisLabelClass}`,
5647
5828
  children: yAxisLabel
5648
5829
  }
5649
5830
  )
5650
5831
  ] })
5651
5832
  }
5652
5833
  ),
5653
- showLegend && /* @__PURE__ */ jsx109("div", { className: "flex flex-wrap gap-4 mt-4 justify-center", children: data.map((series, index) => /* @__PURE__ */ jsxs36("div", { className: "flex items-center gap-2", children: [
5834
+ showLegend && /* @__PURE__ */ jsx109("div", { className: "flex flex-wrap gap-3 justify-center px-4", children: data.map((series, index) => /* @__PURE__ */ jsxs36("div", { className: "flex items-center gap-2 text-sm", children: [
5654
5835
  /* @__PURE__ */ jsx109(
5655
5836
  "div",
5656
5837
  {
5657
- className: "w-4 h-4 rounded-sm",
5838
+ className: "w-3 h-3 rounded-sm flex-shrink-0",
5658
5839
  style: {
5659
- backgroundColor: series.color || defaultColors2[index % defaultColors2.length]
5840
+ backgroundColor: series.color || colors[index % colors.length]
5660
5841
  }
5661
5842
  }
5662
5843
  ),
5663
- /* @__PURE__ */ jsx109("span", { className: "text-sm text-gray-700 dark:text-gray-300", children: series.name })
5844
+ /* @__PURE__ */ jsx109("span", { className: "text-gray-700 dark:text-gray-300", children: series.name })
5664
5845
  ] }, `legend-${index}`)) }),
5665
- showTooltip && hoveredBar && /* @__PURE__ */ jsxs36(
5846
+ showTooltip && hoveredBar && tooltipPosition && /* @__PURE__ */ jsxs36(
5666
5847
  "div",
5667
5848
  {
5668
- 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",
5849
+ 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",
5669
5850
  style: {
5670
- left: `${padding.left + hoveredBar.x + 10}px`,
5671
- top: `${padding.top + hoveredBar.y - 30}px`
5851
+ left: `${tooltipPosition.x}px`,
5852
+ top: `${tooltipPosition.y}px`,
5853
+ transform: "translateZ(0)"
5672
5854
  },
5673
5855
  children: [
5674
5856
  /* @__PURE__ */ jsx109("div", { className: "font-semibold", children: data[hoveredBar.seriesIndex].name }),
5675
- /* @__PURE__ */ jsxs36("div", { children: [
5857
+ /* @__PURE__ */ jsxs36("div", { className: "text-xs opacity-90", children: [
5676
5858
  data[hoveredBar.seriesIndex].data[hoveredBar.barIndex].x,
5677
5859
  ": ",
5678
5860
  data[hoveredBar.seriesIndex].data[hoveredBar.barIndex].y
@@ -5720,14 +5902,32 @@ var AreaChart = ({
5720
5902
  strokeWidth = 2,
5721
5903
  className = "",
5722
5904
  xAxisLabel,
5723
- yAxisLabel
5905
+ yAxisLabel,
5906
+ baseFontSize = 14
5724
5907
  }) => {
5725
- const height = providedHeight ?? 400;
5726
- const width = providedWidth ?? 800;
5908
+ const viewBoxWidth = 1e3;
5909
+ const viewBoxHeight = 600;
5910
+ const containerRef = React28.useRef(null);
5911
+ const svgRef = React28.useRef(null);
5912
+ const [tooltipPosition, setTooltipPosition] = React28.useState(null);
5727
5913
  const [hoveredPoint, setHoveredPoint] = React28.useState(null);
5728
- const padding = { top: 20, right: 20, bottom: showXAxis ? 60 : 20, left: showYAxis ? 60 : 20 };
5729
- const chartWidth = width - padding.left - padding.right;
5730
- const chartHeight = height - padding.top - padding.bottom;
5914
+ const chartId = React28.useId();
5915
+ const wrapperClass = `chart-svg-wrapper-${chartId.replace(/:/g, "-")}`;
5916
+ const gridLabelClass = `chart-grid-label-${chartId.replace(/:/g, "-")}`;
5917
+ const axisLabelClass = `chart-axis-label-${chartId.replace(/:/g, "-")}`;
5918
+ const lineClass = `chart-line-${chartId.replace(/:/g, "-")}`;
5919
+ const pointClass = `chart-point-${chartId.replace(/:/g, "-")}`;
5920
+ const padding = {
5921
+ top: 50,
5922
+ right: 50,
5923
+ bottom: showXAxis ? 120 : 50,
5924
+ left: showYAxis ? 130 : 50
5925
+ };
5926
+ const chartWidth = viewBoxWidth - padding.left - padding.right;
5927
+ const chartHeight = viewBoxHeight - padding.top - padding.bottom;
5928
+ const gridLabelFontSize = viewBoxWidth * 0.045;
5929
+ const axisLabelFontSize = viewBoxWidth * 0.05;
5930
+ const titleFontSize = viewBoxWidth * 0.055;
5731
5931
  const allPoints = data.flatMap((series) => series.data);
5732
5932
  const allYValues = stacked ? data[0]?.data.map(
5733
5933
  (_, i) => data.reduce((sum, series) => sum + (series.data[i]?.y || 0), 0)
@@ -5741,7 +5941,7 @@ var AreaChart = ({
5741
5941
  const minY = Math.min(0, ...allYValues);
5742
5942
  const maxY = Math.max(...allYValues);
5743
5943
  const yRange = maxY - minY;
5744
- const yMin = minY - yRange * 0.1;
5944
+ const yMin = Math.max(0, minY - yRange * 0.1);
5745
5945
  const yMax = maxY + yRange * 0.1;
5746
5946
  const scaleX = (x, index) => {
5747
5947
  const numX = isStringX ? index : x;
@@ -5822,20 +6022,21 @@ var AreaChart = ({
5822
6022
  x2: chartWidth,
5823
6023
  y2: y,
5824
6024
  stroke: "currentColor",
5825
- strokeWidth: "1",
6025
+ strokeWidth: "0.5",
5826
6026
  className: "text-gray-200 dark:text-gray-700",
5827
- strokeDasharray: "2,2"
6027
+ strokeDasharray: "4,4"
5828
6028
  }
5829
6029
  ),
5830
6030
  showYAxis && /* @__PURE__ */ jsx110(
5831
6031
  "text",
5832
6032
  {
5833
- x: -10,
5834
- y: y + 4,
6033
+ x: -25,
6034
+ y,
5835
6035
  textAnchor: "end",
5836
- fontSize: "12",
5837
- className: "fill-gray-600 dark:fill-gray-400",
5838
- children: yValue.toFixed(0)
6036
+ dominantBaseline: "middle",
6037
+ fontSize: gridLabelFontSize,
6038
+ className: `fill-gray-600 dark:fill-gray-400 ${gridLabelClass}`,
6039
+ children: yValue.toFixed(1)
5839
6040
  }
5840
6041
  )
5841
6042
  ] }, `grid-h-${i}`)
@@ -5855,19 +6056,20 @@ var AreaChart = ({
5855
6056
  x2: x,
5856
6057
  y2: chartHeight,
5857
6058
  stroke: "currentColor",
5858
- strokeWidth: "1",
6059
+ strokeWidth: "0.5",
5859
6060
  className: "text-gray-200 dark:text-gray-700",
5860
- strokeDasharray: "2,2"
6061
+ strokeDasharray: "4,4"
5861
6062
  }
5862
6063
  ),
5863
6064
  showXAxis && /* @__PURE__ */ jsx110(
5864
6065
  "text",
5865
6066
  {
5866
6067
  x,
5867
- y: chartHeight + 20,
6068
+ y: chartHeight + 35,
5868
6069
  textAnchor: "middle",
5869
- fontSize: "12",
5870
- className: "fill-gray-600 dark:fill-gray-400",
6070
+ dominantBaseline: "hanging",
6071
+ fontSize: gridLabelFontSize,
6072
+ className: `fill-gray-600 dark:fill-gray-400 ${gridLabelClass}`,
5871
6073
  children: xValue
5872
6074
  }
5873
6075
  )
@@ -5879,20 +6081,72 @@ var AreaChart = ({
5879
6081
  if (stacked) {
5880
6082
  cumulativeValues = Array(data[0]?.data.length || 0).fill(0);
5881
6083
  }
6084
+ const getTooltipPosition = React28.useCallback((x, y) => {
6085
+ if (!containerRef.current) return { x, y };
6086
+ const rect = containerRef.current.getBoundingClientRect();
6087
+ const tooltipWidth = 120;
6088
+ const tooltipHeight = 80;
6089
+ let tooltipX = x + 10;
6090
+ let tooltipY = y - 30;
6091
+ if (tooltipX + tooltipWidth > rect.width) {
6092
+ tooltipX = x - tooltipWidth - 10;
6093
+ }
6094
+ if (tooltipY + tooltipHeight > rect.height) {
6095
+ tooltipY = y + 30;
6096
+ }
6097
+ return { x: tooltipX, y: tooltipY };
6098
+ }, []);
6099
+ const containerStyle = {
6100
+ "--font-size-base": `${baseFontSize}px`,
6101
+ "--font-size-lg": `calc(var(--font-size-base) * 1.125)`,
6102
+ "--font-size-sm": `calc(var(--font-size-base) * 0.875)`,
6103
+ "--font-size-xs": `calc(var(--font-size-base) * 0.75)`
6104
+ };
5882
6105
  return /* @__PURE__ */ jsxs37(
5883
6106
  "div",
5884
6107
  {
5885
- className: `relative ${responsive ? "w-full" : "inline-block"} ${className}`,
5886
- style: responsive ? { width: "100%", aspectRatio: `${width} / ${height}` } : void 0,
6108
+ ref: containerRef,
6109
+ className: `relative flex flex-col gap-4 ${responsive ? "w-full" : "inline-block"} ${className}`,
6110
+ style: containerStyle,
5887
6111
  children: [
6112
+ /* @__PURE__ */ jsx110("style", { children: `
6113
+ /* Mobile: Large fonts, hidden axis titles, thicker lines (default) */
6114
+ .${gridLabelClass} { font-size: ${gridLabelFontSize}px !important; }
6115
+ .${axisLabelClass} { display: none; }
6116
+ .${lineClass} { stroke-width: ${strokeWidth * 2.5} !important; }
6117
+ .${pointClass} { r: 6 !important; stroke-width: 3 !important; }
6118
+
6119
+ /* Tablet: Medium fonts, show axis titles, medium lines */
6120
+ @media (min-width: 640px) {
6121
+ .${gridLabelClass} { font-size: ${gridLabelFontSize * 0.7}px !important; }
6122
+ .${axisLabelClass} {
6123
+ font-size: ${axisLabelFontSize * 0.7}px !important;
6124
+ display: block;
6125
+ }
6126
+ .${lineClass} { stroke-width: ${strokeWidth * 1.5} !important; }
6127
+ .${pointClass} { r: 4 !important; stroke-width: 2 !important; }
6128
+ }
6129
+
6130
+ /* Desktop: Small fonts, show axis titles, normal lines */
6131
+ @media (min-width: 1024px) {
6132
+ .${gridLabelClass} { font-size: ${gridLabelFontSize * 0.4}px !important; }
6133
+ .${axisLabelClass} {
6134
+ font-size: ${axisLabelFontSize * 0.4}px !important;
6135
+ display: block;
6136
+ }
6137
+ .${lineClass} { stroke-width: ${strokeWidth} !important; }
6138
+ .${pointClass} { r: 3 !important; stroke-width: 1.5 !important; }
6139
+ }
6140
+ ` }),
5888
6141
  /* @__PURE__ */ jsx110(
5889
6142
  "svg",
5890
6143
  {
6144
+ ref: svgRef,
5891
6145
  width: "100%",
5892
- height: "100%",
5893
- viewBox: `0 0 ${width} ${height}`,
6146
+ viewBox: `0 0 ${viewBoxWidth} ${viewBoxHeight}`,
5894
6147
  preserveAspectRatio: "xMidYMid meet",
5895
- className: "bg-white dark:bg-gray-800 block",
6148
+ className: "bg-white dark:bg-gray-800 block w-full",
6149
+ style: { height: "auto", overflow: "visible" },
5896
6150
  children: /* @__PURE__ */ jsxs37("g", { transform: `translate(${padding.left}, ${padding.top})`, children: [
5897
6151
  gridLines,
5898
6152
  data.map((series, seriesIndex) => {
@@ -5921,7 +6175,8 @@ var AreaChart = ({
5921
6175
  stroke: series.color || defaultColors3[seriesIndex % defaultColors3.length],
5922
6176
  strokeWidth,
5923
6177
  strokeLinecap: "round",
5924
- strokeLinejoin: "round"
6178
+ strokeLinejoin: "round",
6179
+ className: lineClass
5925
6180
  }
5926
6181
  )
5927
6182
  ] }, `area-${seriesIndex}`);
@@ -5943,9 +6198,28 @@ var AreaChart = ({
5943
6198
  fill: series.color || defaultColors3[seriesIndex % defaultColors3.length],
5944
6199
  stroke: "white",
5945
6200
  strokeWidth: "2",
5946
- className: "cursor-pointer transition-all",
5947
- onMouseEnter: () => showTooltip && setHoveredPoint({ seriesIndex, pointIndex, x, y }),
5948
- onMouseLeave: () => setHoveredPoint(null)
6201
+ className: `cursor-pointer transition-all ${pointClass}`,
6202
+ onMouseEnter: (e) => {
6203
+ if (showTooltip && containerRef.current) {
6204
+ setHoveredPoint({ seriesIndex, pointIndex, x, y });
6205
+ const containerRect = containerRef.current.getBoundingClientRect();
6206
+ const mouseX = e.clientX - containerRect.left;
6207
+ const mouseY = e.clientY - containerRect.top;
6208
+ setTooltipPosition(getTooltipPosition(mouseX, mouseY));
6209
+ }
6210
+ },
6211
+ onMouseMove: (e) => {
6212
+ if (showTooltip && hoveredPoint?.seriesIndex === seriesIndex && hoveredPoint?.pointIndex === pointIndex && containerRef.current) {
6213
+ const containerRect = containerRef.current.getBoundingClientRect();
6214
+ const mouseX = e.clientX - containerRect.left;
6215
+ const mouseY = e.clientY - containerRect.top;
6216
+ setTooltipPosition(getTooltipPosition(mouseX, mouseY));
6217
+ }
6218
+ },
6219
+ onMouseLeave: () => {
6220
+ setHoveredPoint(null);
6221
+ setTooltipPosition(null);
6222
+ }
5949
6223
  },
5950
6224
  `point-${seriesIndex}-${pointIndex}`
5951
6225
  );
@@ -5955,11 +6229,12 @@ var AreaChart = ({
5955
6229
  "text",
5956
6230
  {
5957
6231
  x: chartWidth / 2,
5958
- y: chartHeight + 50,
6232
+ y: chartHeight + 80,
5959
6233
  textAnchor: "middle",
5960
- fontSize: "14",
5961
- fontWeight: "500",
5962
- className: "fill-gray-700 dark:fill-gray-300",
6234
+ dominantBaseline: "hanging",
6235
+ fontSize: axisLabelFontSize,
6236
+ fontWeight: "600",
6237
+ className: `fill-gray-700 dark:fill-gray-300 ${axisLabelClass}`,
5963
6238
  children: xAxisLabel
5964
6239
  }
5965
6240
  ),
@@ -5967,45 +6242,47 @@ var AreaChart = ({
5967
6242
  "text",
5968
6243
  {
5969
6244
  x: -chartHeight / 2,
5970
- y: -45,
6245
+ y: -100,
5971
6246
  textAnchor: "middle",
5972
- fontSize: "14",
5973
- fontWeight: "500",
5974
- transform: "rotate(-90, 0, 0)",
5975
- className: "fill-gray-700 dark:fill-gray-300",
6247
+ dominantBaseline: "middle",
6248
+ fontSize: axisLabelFontSize,
6249
+ fontWeight: "600",
6250
+ transform: "rotate(-90)",
6251
+ className: `fill-gray-700 dark:fill-gray-300 ${axisLabelClass}`,
5976
6252
  children: yAxisLabel
5977
6253
  }
5978
6254
  )
5979
6255
  ] })
5980
6256
  }
5981
6257
  ),
5982
- showLegend && /* @__PURE__ */ jsx110("div", { className: "flex flex-wrap gap-4 mt-4 justify-center", children: data.map((series, index) => /* @__PURE__ */ jsxs37("div", { className: "flex items-center gap-2", children: [
6258
+ showLegend && /* @__PURE__ */ jsx110("div", { className: "flex flex-wrap gap-3 justify-center px-4", children: data.map((series, index) => /* @__PURE__ */ jsxs37("div", { className: "flex items-center gap-2 text-sm", children: [
5983
6259
  /* @__PURE__ */ jsx110(
5984
6260
  "div",
5985
6261
  {
5986
- className: "w-4 h-4 rounded-sm",
6262
+ className: "w-3 h-3 rounded-sm flex-shrink-0",
5987
6263
  style: {
5988
6264
  backgroundColor: series.color || defaultColors3[index % defaultColors3.length]
5989
6265
  }
5990
6266
  }
5991
6267
  ),
5992
- /* @__PURE__ */ jsx110("span", { className: "text-sm text-gray-700 dark:text-gray-300", children: series.name })
6268
+ /* @__PURE__ */ jsx110("span", { className: "text-gray-700 dark:text-gray-300", children: series.name })
5993
6269
  ] }, `legend-${index}`)) }),
5994
- showTooltip && hoveredPoint && /* @__PURE__ */ jsxs37(
6270
+ showTooltip && hoveredPoint && tooltipPosition && /* @__PURE__ */ jsxs37(
5995
6271
  "div",
5996
6272
  {
5997
- 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",
6273
+ 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",
5998
6274
  style: {
5999
- left: `${padding.left + hoveredPoint.x + 10}px`,
6000
- top: `${padding.top + hoveredPoint.y - 30}px`
6275
+ left: `${tooltipPosition.x}px`,
6276
+ top: `${tooltipPosition.y}px`,
6277
+ transform: "translateZ(0)"
6001
6278
  },
6002
6279
  children: [
6003
6280
  /* @__PURE__ */ jsx110("div", { className: "font-semibold", children: data[hoveredPoint.seriesIndex].name }),
6004
- /* @__PURE__ */ jsxs37("div", { children: [
6281
+ /* @__PURE__ */ jsxs37("div", { className: "text-xs opacity-90", children: [
6005
6282
  "x: ",
6006
6283
  data[hoveredPoint.seriesIndex].data[hoveredPoint.pointIndex].x
6007
6284
  ] }),
6008
- /* @__PURE__ */ jsxs37("div", { children: [
6285
+ /* @__PURE__ */ jsxs37("div", { className: "text-xs opacity-90", children: [
6009
6286
  "y: ",
6010
6287
  data[hoveredPoint.seriesIndex].data[hoveredPoint.pointIndex].y
6011
6288
  ] })
@@ -6050,16 +6327,27 @@ var PieChart = ({
6050
6327
  showPercentages = false,
6051
6328
  donut = false,
6052
6329
  donutWidth = 60,
6053
- className = ""
6330
+ className = "",
6331
+ baseFontSize = 14
6054
6332
  }) => {
6055
- const height = providedHeight ?? 400;
6056
- const width = providedWidth ?? 400;
6333
+ const viewBoxWidth = 600;
6334
+ const viewBoxHeight = 600;
6335
+ const containerRef = React29.useRef(null);
6336
+ const [tooltipPosition, setTooltipPosition] = React29.useState(null);
6057
6337
  const [hoveredSlice, setHoveredSlice] = React29.useState(null);
6338
+ const chartId = React29.useId();
6339
+ const wrapperClass = `chart-svg-wrapper-${chartId.replace(/:/g, "-")}`;
6340
+ const gridLabelClass = `chart-grid-label-${chartId.replace(/:/g, "-")}`;
6341
+ const axisLabelClass = `chart-axis-label-${chartId.replace(/:/g, "-")}`;
6342
+ const sliceClass = `chart-slice-${chartId.replace(/:/g, "-")}`;
6058
6343
  const total = data.reduce((sum, item) => sum + item.value, 0);
6059
- const centerX = width / 2;
6060
- const centerY = height / 2;
6061
- const radius = Math.min(width, height) / 2 - 40;
6344
+ const centerX = viewBoxWidth / 2;
6345
+ const centerY = viewBoxHeight / 2;
6346
+ const radius = Math.min(viewBoxWidth, viewBoxHeight) / 2 - 40;
6062
6347
  const innerRadius = donut ? radius - donutWidth : 0;
6348
+ const gridLabelFontSize = viewBoxWidth * 0.045;
6349
+ const axisLabelFontSize = viewBoxWidth * 0.05;
6350
+ const titleFontSize = viewBoxWidth * 0.055;
6063
6351
  let currentAngle = -90;
6064
6352
  const slices = data.map((item, index) => {
6065
6353
  const percentage = item.value / total * 100;
@@ -6111,20 +6399,64 @@ var PieChart = ({
6111
6399
  index
6112
6400
  };
6113
6401
  });
6402
+ const getTooltipPosition = React29.useCallback((x, y) => {
6403
+ if (!containerRef.current) return { x, y };
6404
+ const rect = containerRef.current.getBoundingClientRect();
6405
+ const tooltipWidth = 120;
6406
+ const tooltipHeight = 80;
6407
+ let tooltipX = x + 10;
6408
+ let tooltipY = y - 30;
6409
+ if (tooltipX + tooltipWidth > rect.width) {
6410
+ tooltipX = x - tooltipWidth - 10;
6411
+ }
6412
+ if (tooltipY + tooltipHeight > rect.height) {
6413
+ tooltipY = y + 30;
6414
+ }
6415
+ return { x: tooltipX, y: tooltipY };
6416
+ }, []);
6417
+ const containerStyle = {
6418
+ "--font-size-base": `${baseFontSize}px`,
6419
+ "--font-size-lg": `calc(var(--font-size-base) * 1.125)`,
6420
+ "--font-size-sm": `calc(var(--font-size-base) * 0.875)`,
6421
+ "--font-size-xs": `calc(var(--font-size-base) * 0.75)`,
6422
+ "--font-size-xl": `calc(var(--font-size-base) * 1.5)`,
6423
+ "--font-size-2xl": `calc(var(--font-size-base) * 2)`
6424
+ };
6425
+ if (responsive) {
6426
+ containerStyle["--font-size-base"] = `clamp(${baseFontSize * 0.8}px, 4vw, ${baseFontSize}px)`;
6427
+ }
6114
6428
  return /* @__PURE__ */ jsxs38(
6115
6429
  "div",
6116
6430
  {
6117
- className: `relative ${responsive ? "w-full flex justify-center" : "inline-block"} ${className}`,
6118
- style: responsive ? { aspectRatio: `${width} / ${height}` } : void 0,
6431
+ ref: containerRef,
6432
+ className: `relative flex flex-col gap-4 ${responsive ? "w-full" : "inline-block"} ${className}`,
6433
+ style: containerStyle,
6119
6434
  children: [
6435
+ /* @__PURE__ */ jsx111("style", { children: `
6436
+ /* Mobile: Large fonts (default) */
6437
+ .${gridLabelClass} { font-size: ${gridLabelFontSize}px !important; }
6438
+ .${axisLabelClass} { font-size: ${titleFontSize}px !important; }
6439
+
6440
+ /* Tablet: Medium fonts */
6441
+ @media (min-width: 640px) {
6442
+ .${gridLabelClass} { font-size: ${gridLabelFontSize * 0.7}px !important; }
6443
+ .${axisLabelClass} { font-size: ${titleFontSize * 0.7}px !important; }
6444
+ }
6445
+
6446
+ /* Desktop: Small fonts */
6447
+ @media (min-width: 1024px) {
6448
+ .${gridLabelClass} { font-size: ${gridLabelFontSize * 0.4}px !important; }
6449
+ .${axisLabelClass} { font-size: ${titleFontSize * 0.4}px !important; }
6450
+ }
6451
+ ` }),
6120
6452
  /* @__PURE__ */ jsxs38(
6121
6453
  "svg",
6122
6454
  {
6123
6455
  width: "100%",
6124
- height: "100%",
6125
- viewBox: `0 0 ${width} ${height}`,
6456
+ viewBox: `0 0 ${viewBoxWidth} ${viewBoxHeight}`,
6126
6457
  preserveAspectRatio: "xMidYMid meet",
6127
- className: "bg-white dark:bg-gray-800 block",
6458
+ className: "bg-white dark:bg-gray-800 block w-full",
6459
+ style: { height: "auto", overflow: "visible" },
6128
6460
  children: [
6129
6461
  slices.map((slice) => {
6130
6462
  const isHovered = hoveredSlice === slice.index;
@@ -6138,8 +6470,19 @@ var PieChart = ({
6138
6470
  strokeWidth: "2",
6139
6471
  className: "cursor-pointer transition-opacity",
6140
6472
  opacity: isHovered ? 0.8 : 1,
6141
- onMouseEnter: () => setHoveredSlice(slice.index),
6142
- onMouseLeave: () => setHoveredSlice(null)
6473
+ onMouseEnter: (e) => {
6474
+ setHoveredSlice(slice.index);
6475
+ if (containerRef.current) {
6476
+ const rect = containerRef.current.getBoundingClientRect();
6477
+ const svgX = e.clientX - rect.left;
6478
+ const svgY = e.clientY - rect.top;
6479
+ setTooltipPosition(getTooltipPosition(svgX, svgY));
6480
+ }
6481
+ },
6482
+ onMouseLeave: () => {
6483
+ setHoveredSlice(null);
6484
+ setTooltipPosition(null);
6485
+ }
6143
6486
  }
6144
6487
  ),
6145
6488
  showLabels && slice.percentage > 5 && /* @__PURE__ */ jsxs38(
@@ -6149,9 +6492,9 @@ var PieChart = ({
6149
6492
  y: slice.labelY,
6150
6493
  textAnchor: "middle",
6151
6494
  dominantBaseline: "middle",
6152
- fontSize: "14",
6495
+ fontSize: gridLabelFontSize,
6153
6496
  fontWeight: "600",
6154
- className: "fill-gray-700 dark:fill-gray-200 pointer-events-none",
6497
+ className: `fill-gray-700 dark:fill-gray-200 pointer-events-none ${gridLabelClass}`,
6155
6498
  children: [
6156
6499
  showPercentages && `${slice.percentage.toFixed(1)}%`,
6157
6500
  showPercentages && showValues && " ",
@@ -6169,9 +6512,10 @@ var PieChart = ({
6169
6512
  x: centerX,
6170
6513
  y: centerY - 10,
6171
6514
  textAnchor: "middle",
6172
- fontSize: "32",
6515
+ dominantBaseline: "middle",
6516
+ fontSize: titleFontSize,
6173
6517
  fontWeight: "700",
6174
- className: "fill-gray-900 dark:fill-gray-100",
6518
+ className: `fill-gray-900 dark:fill-gray-100 ${axisLabelClass}`,
6175
6519
  children: total
6176
6520
  }
6177
6521
  ),
@@ -6181,8 +6525,9 @@ var PieChart = ({
6181
6525
  x: centerX,
6182
6526
  y: centerY + 15,
6183
6527
  textAnchor: "middle",
6184
- fontSize: "16",
6185
- className: "fill-gray-600 dark:fill-gray-400",
6528
+ dominantBaseline: "middle",
6529
+ fontSize: axisLabelFontSize,
6530
+ className: `fill-gray-600 dark:fill-gray-400 ${gridLabelClass}`,
6186
6531
  children: "Total"
6187
6532
  }
6188
6533
  )
@@ -6190,23 +6535,23 @@ var PieChart = ({
6190
6535
  ]
6191
6536
  }
6192
6537
  ),
6193
- showLegend && /* @__PURE__ */ jsx111("div", { className: "flex flex-wrap gap-4 mt-4 justify-center", children: data.map((item, index) => /* @__PURE__ */ jsxs38(
6538
+ showLegend && /* @__PURE__ */ jsx111("div", { className: "flex flex-wrap gap-3 justify-center px-4", children: data.map((item, index) => /* @__PURE__ */ jsxs38(
6194
6539
  "div",
6195
6540
  {
6196
- className: "flex items-center gap-2 cursor-pointer",
6541
+ className: "flex items-center gap-2 text-sm cursor-pointer",
6197
6542
  onMouseEnter: () => setHoveredSlice(index),
6198
6543
  onMouseLeave: () => setHoveredSlice(null),
6199
6544
  children: [
6200
6545
  /* @__PURE__ */ jsx111(
6201
6546
  "div",
6202
6547
  {
6203
- className: "w-4 h-4 rounded-sm",
6548
+ className: "w-3 h-3 rounded-sm flex-shrink-0",
6204
6549
  style: {
6205
6550
  backgroundColor: item.color || defaultColors4[index % defaultColors4.length]
6206
6551
  }
6207
6552
  }
6208
6553
  ),
6209
- /* @__PURE__ */ jsxs38("span", { className: "text-sm text-gray-700 dark:text-gray-300", children: [
6554
+ /* @__PURE__ */ jsxs38("span", { className: "text-gray-700 dark:text-gray-300", children: [
6210
6555
  item.label,
6211
6556
  ": ",
6212
6557
  item.value,
@@ -6216,18 +6561,29 @@ var PieChart = ({
6216
6561
  },
6217
6562
  `legend-${index}`
6218
6563
  )) }),
6219
- hoveredSlice !== null && /* @__PURE__ */ jsxs38("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: [
6220
- /* @__PURE__ */ jsx111("div", { className: "font-semibold", children: data[hoveredSlice].label }),
6221
- /* @__PURE__ */ jsxs38("div", { children: [
6222
- "Value: ",
6223
- data[hoveredSlice].value
6224
- ] }),
6225
- /* @__PURE__ */ jsxs38("div", { children: [
6226
- "Percentage: ",
6227
- (data[hoveredSlice].value / total * 100).toFixed(1),
6228
- "%"
6229
- ] })
6230
- ] })
6564
+ hoveredSlice !== null && tooltipPosition && /* @__PURE__ */ jsxs38(
6565
+ "div",
6566
+ {
6567
+ 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",
6568
+ style: {
6569
+ left: `${tooltipPosition.x}px`,
6570
+ top: `${tooltipPosition.y}px`,
6571
+ transform: "translateZ(0)"
6572
+ },
6573
+ children: [
6574
+ /* @__PURE__ */ jsx111("div", { className: "font-semibold", children: data[hoveredSlice].label }),
6575
+ /* @__PURE__ */ jsxs38("div", { className: "text-xs opacity-90", children: [
6576
+ "Value: ",
6577
+ data[hoveredSlice].value
6578
+ ] }),
6579
+ /* @__PURE__ */ jsxs38("div", { className: "text-xs opacity-90", children: [
6580
+ "Percentage: ",
6581
+ (data[hoveredSlice].value / total * 100).toFixed(1),
6582
+ "%"
6583
+ ] })
6584
+ ]
6585
+ }
6586
+ )
6231
6587
  ]
6232
6588
  }
6233
6589
  );