@x-plat/design-system 0.5.37 → 0.5.38

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
@@ -6380,28 +6380,11 @@ var useChartTooltip = (enabled) => {
6380
6380
  if (!rect) return;
6381
6381
  setTooltip({ visible: true, x: e.clientX - rect.left, y: e.clientY - rect.top, content });
6382
6382
  }, [enabled]);
6383
- const showAt = React6.useCallback((svgX, svgY, content, svgEl) => {
6384
- if (!enabled) return;
6385
- const container = containerRef.current;
6386
- if (!container) return;
6387
- let x = svgX;
6388
- let y = svgY;
6389
- if (svgEl) {
6390
- const svgRect = svgEl.getBoundingClientRect();
6391
- const containerRect = container.getBoundingClientRect();
6392
- const vb = svgEl.viewBox.baseVal;
6393
- const scaleX = svgRect.width / (vb.width || 1);
6394
- const scaleY = svgRect.height / (vb.height || 1);
6395
- x = svgX * scaleX + (svgRect.left - containerRect.left);
6396
- y = svgY * scaleY + (svgRect.top - containerRect.top);
6397
- }
6398
- setTooltip({ visible: true, x, y, content });
6399
- }, [enabled]);
6400
6383
  const hide = React6.useCallback(() => {
6401
6384
  cancelAnimationFrame(rafRef.current);
6402
6385
  setTooltip((prev) => ({ ...prev, visible: false }));
6403
6386
  }, []);
6404
- return { tooltip, show, showAt, hide, move, containerRef };
6387
+ return { tooltip, show, hide, move, containerRef };
6405
6388
  };
6406
6389
  var GridLines = React6.memo(({ width, height, chartH, maxVal }) => /* @__PURE__ */ jsx307(Fragment2, { children: [0, 0.25, 0.5, 0.75, 1].map((ratio) => {
6407
6390
  const y = PADDING.top + (1 - ratio) * chartH;
@@ -6466,7 +6449,7 @@ var useCrosshair = (seriesPoints, entries, labels, chartH) => {
6466
6449
  }, [entries, seriesPoints]);
6467
6450
  return { activeIndex, handleMouseMove, handleMouseLeave, tooltipContent, getTooltipAt };
6468
6451
  };
6469
- var LineChart = React6.memo(({ data, labels, width, height, animate, onHover, onShowAt, onMove, onLeave }) => {
6452
+ var LineChart = React6.memo(({ data, labels, width, height, animate, onHover, onMove, onLeave }) => {
6470
6453
  const entries = React6.useMemo(() => Object.entries(data), [data]);
6471
6454
  const maxVal = React6.useMemo(() => {
6472
6455
  const allValues = entries.flatMap(([, v]) => v);
@@ -6486,7 +6469,6 @@ var LineChart = React6.memo(({ data, labels, width, height, animate, onHover, on
6486
6469
  [entries, count, chartW, chartH, maxVal]
6487
6470
  );
6488
6471
  const clipRef = React6.useRef(null);
6489
- const svgRef = React6.useRef(null);
6490
6472
  const { activeIndex, handleMouseMove, handleMouseLeave, getTooltipAt } = useCrosshair(seriesPoints, entries, labels, chartH);
6491
6473
  React6.useEffect(() => {
6492
6474
  if (!animate || !clipRef.current) return;
@@ -6503,14 +6485,12 @@ var LineChart = React6.memo(({ data, labels, width, height, animate, onHover, on
6503
6485
  return /* @__PURE__ */ jsxs197(
6504
6486
  "svg",
6505
6487
  {
6506
- ref: svgRef,
6507
6488
  viewBox: `0 0 ${width} ${height}`,
6508
6489
  className: "chart-svg",
6509
6490
  onMouseMove: (e) => {
6510
6491
  handleMouseMove(e);
6511
- if (activeIndex !== null && seriesPoints[0]?.[activeIndex]) {
6512
- const p = seriesPoints[0][activeIndex];
6513
- onShowAt(p.x, p.y, `${labels[activeIndex]} \u2014 ${getTooltipAt(activeIndex)}`, svgRef.current);
6492
+ if (activeIndex !== null) {
6493
+ onHover(e, `${labels[activeIndex]} \u2014 ${getTooltipAt(activeIndex)}`);
6514
6494
  } else {
6515
6495
  onLeave();
6516
6496
  }
@@ -6578,7 +6558,7 @@ var LineChart = React6.memo(({ data, labels, width, height, animate, onHover, on
6578
6558
  );
6579
6559
  });
6580
6560
  LineChart.displayName = "LineChart";
6581
- var CurveChart = React6.memo(({ data, labels, width, height, animate, onHover, onShowAt, onMove, onLeave }) => {
6561
+ var CurveChart = React6.memo(({ data, labels, width, height, animate, onHover, onMove, onLeave }) => {
6582
6562
  const entries = React6.useMemo(() => Object.entries(data), [data]);
6583
6563
  const maxVal = React6.useMemo(() => {
6584
6564
  const allValues = entries.flatMap(([, v]) => v);
@@ -6598,7 +6578,6 @@ var CurveChart = React6.memo(({ data, labels, width, height, animate, onHover, o
6598
6578
  [entries, count, chartW, chartH, maxVal]
6599
6579
  );
6600
6580
  const curveClipRef = React6.useRef(null);
6601
- const curveSvgRef = React6.useRef(null);
6602
6581
  const { activeIndex, handleMouseMove, handleMouseLeave, getTooltipAt } = useCrosshair(seriesPoints, entries, labels, chartH);
6603
6582
  React6.useEffect(() => {
6604
6583
  if (!animate || !curveClipRef.current) return;
@@ -6615,14 +6594,13 @@ var CurveChart = React6.memo(({ data, labels, width, height, animate, onHover, o
6615
6594
  return /* @__PURE__ */ jsxs197(
6616
6595
  "svg",
6617
6596
  {
6618
- ref: curveSvgRef,
6619
6597
  viewBox: `0 0 ${width} ${height}`,
6620
6598
  className: "chart-svg",
6621
6599
  onMouseMove: (e) => {
6622
6600
  handleMouseMove(e);
6623
6601
  if (activeIndex !== null && seriesPoints[0]?.[activeIndex]) {
6624
6602
  const p = seriesPoints[0][activeIndex];
6625
- onShowAt(p.x, p.y, `${labels[activeIndex]} \u2014 ${getTooltipAt(activeIndex)}`, curveSvgRef.current);
6603
+ onHover(e, `${labels[activeIndex]} \u2014 ${getTooltipAt(activeIndex)}`);
6626
6604
  } else {
6627
6605
  onLeave();
6628
6606
  }
@@ -6690,8 +6668,7 @@ var CurveChart = React6.memo(({ data, labels, width, height, animate, onHover, o
6690
6668
  );
6691
6669
  });
6692
6670
  CurveChart.displayName = "CurveChart";
6693
- var BarChart = React6.memo(({ data, labels, width, height, animate, onHover, onShowAt, onMove, onLeave }) => {
6694
- const barSvgRef = React6.useRef(null);
6671
+ var BarChart = React6.memo(({ data, labels, width, height, animate, onHover, onMove, onLeave }) => {
6695
6672
  const entries = React6.useMemo(() => Object.entries(data), [data]);
6696
6673
  const maxVal = React6.useMemo(() => {
6697
6674
  const allValues = entries.flatMap(([, v]) => v);
@@ -6718,7 +6695,7 @@ var BarChart = React6.memo(({ data, labels, width, height, animate, onHover, onS
6718
6695
  [entries, maxVal, chartH, groupW, barW, barGap, groupCount]
6719
6696
  );
6720
6697
  const barLabelStep = getLabelStep(count, chartW);
6721
- return /* @__PURE__ */ jsxs197("svg", { ref: barSvgRef, viewBox: `0 0 ${width} ${height}`, className: "chart-svg", children: [
6698
+ return /* @__PURE__ */ jsxs197("svg", { viewBox: `0 0 ${width} ${height}`, className: "chart-svg", children: [
6722
6699
  /* @__PURE__ */ jsx307(GridLines, { width, height, chartH, maxVal }),
6723
6700
  labels.map((label, i) => {
6724
6701
  if (i % barLabelStep !== 0) return null;
@@ -6741,7 +6718,8 @@ var BarChart = React6.memo(({ data, labels, width, height, animate, onHover, onS
6741
6718
  transformOrigin: `${b.x + b.w / 2}px ${baseline}px`,
6742
6719
  animationDelay: `${delay}ms`
6743
6720
  } : void 0,
6744
- onMouseEnter: () => onShowAt(b.x + b.w / 2, b.y, `${key}: ${labels[i]} \u2014 ${b.v}`, barSvgRef.current),
6721
+ onMouseEnter: (e) => onHover(e, `${key}: ${labels[i]} \u2014 ${b.v}`),
6722
+ onMouseMove: onMove,
6745
6723
  onMouseLeave: onLeave
6746
6724
  },
6747
6725
  `${di}-${i}`
@@ -6829,14 +6807,17 @@ var PieDonutChart = React6.memo(
6829
6807
  {
6830
6808
  d: s.d,
6831
6809
  fill: PIE_COLORS[(i + colorOffset) % PIE_COLORS.length],
6832
- className: "chart-slice"
6810
+ className: "chart-slice",
6811
+ onMouseEnter: (e) => onHover(e, `${s.label} \u2014 ${s.v.toLocaleString()} (${s.pct}%)`),
6812
+ onMouseMove: onMove,
6813
+ onMouseLeave: onLeave
6833
6814
  }
6834
6815
  ) }, i)) })
6835
6816
  ] });
6836
6817
  }
6837
6818
  );
6838
6819
  PieDonutChart.displayName = "PieDonutChart";
6839
- var ChartTooltip = ({ x, y, containerWidth, containerHeight, children }) => {
6820
+ var ChartTooltip = ({ x, y, containerWidth, containerHeight, tooltipType, children }) => {
6840
6821
  const ref = React6.useRef(null);
6841
6822
  const [pos, setPos] = React6.useState({ left: 0, top: 0 });
6842
6823
  React6.useLayoutEffect(() => {
@@ -6851,13 +6832,20 @@ var ChartTooltip = ({ x, y, containerWidth, containerHeight, children }) => {
6851
6832
  if (left < 0) left = 0;
6852
6833
  setPos({ left, top });
6853
6834
  }, [x, y, containerWidth, containerHeight]);
6854
- return /* @__PURE__ */ jsx307(
6835
+ const content = typeof children === "string" ? children : "";
6836
+ const sepIdx = content.indexOf(" \u2014 ");
6837
+ const title = sepIdx >= 0 ? content.slice(0, sepIdx) : content;
6838
+ const desc = sepIdx >= 0 ? content.slice(sepIdx + 3) : "";
6839
+ return /* @__PURE__ */ jsxs197(
6855
6840
  "div",
6856
6841
  {
6857
6842
  ref,
6858
- className: "chart-tooltip chart-tooltip-show",
6843
+ className: `chart-tooltip chart-tooltip-show chart-tooltip-${tooltipType}`,
6859
6844
  style: { left: pos.left, top: pos.top },
6860
- children
6845
+ children: [
6846
+ title && /* @__PURE__ */ jsx307("div", { className: "chart-tooltip-title", children: title }),
6847
+ desc && /* @__PURE__ */ jsx307("div", { className: "chart-tooltip-desc", children: desc })
6848
+ ]
6861
6849
  }
6862
6850
  );
6863
6851
  };
@@ -6900,8 +6888,8 @@ var ChartLegend = ({ data, labels, type }) => {
6900
6888
  }) });
6901
6889
  };
6902
6890
  var Chart = React6.memo((props) => {
6903
- const { type, data, labels, tooltip: showTooltip = true } = props;
6904
- const { tooltip, show, showAt, hide, move, containerRef } = useChartTooltip(showTooltip);
6891
+ const { type, data, labels, tooltip: showTooltip = true, tooltipType = "dark" } = props;
6892
+ const { tooltip, show, hide, move, containerRef } = useChartTooltip(showTooltip);
6905
6893
  const { width, height } = useChartSize(containerRef);
6906
6894
  const stableData = React6.useMemo(() => data, [JSON.stringify(data)]);
6907
6895
  const stableLabels = React6.useMemo(() => labels, [JSON.stringify(labels)]);
@@ -6909,13 +6897,13 @@ var Chart = React6.memo((props) => {
6909
6897
  const animate = useChartAnimation(containerRef, dataKey);
6910
6898
  const ready = width > 0 && height > 0;
6911
6899
  return /* @__PURE__ */ jsxs197("div", { className: "lib-xplat-chart", ref: containerRef, children: [
6912
- ready && type === "line" && /* @__PURE__ */ jsx307(LineChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onShowAt: showAt, onMove: move, onLeave: hide }),
6913
- ready && type === "curve" && /* @__PURE__ */ jsx307(CurveChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onShowAt: showAt, onMove: move, onLeave: hide }),
6914
- ready && type === "bar" && /* @__PURE__ */ jsx307(BarChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onShowAt: showAt, onMove: move, onLeave: hide }),
6915
- ready && type === "pie" && /* @__PURE__ */ jsx307(PieDonutChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onShowAt: showAt, onMove: move, onLeave: hide }),
6916
- ready && type === "doughnut" && /* @__PURE__ */ jsx307(PieDonutChart, { data: stableData, labels: stableLabels, width, height, animate, isDoughnut: true, onHover: show, onShowAt: showAt, onMove: move, onLeave: hide }),
6900
+ ready && type === "line" && /* @__PURE__ */ jsx307(LineChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onMove: move, onLeave: hide }),
6901
+ ready && type === "curve" && /* @__PURE__ */ jsx307(CurveChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onMove: move, onLeave: hide }),
6902
+ ready && type === "bar" && /* @__PURE__ */ jsx307(BarChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onMove: move, onLeave: hide }),
6903
+ ready && type === "pie" && /* @__PURE__ */ jsx307(PieDonutChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onMove: move, onLeave: hide }),
6904
+ ready && type === "doughnut" && /* @__PURE__ */ jsx307(PieDonutChart, { data: stableData, labels: stableLabels, width, height, animate, isDoughnut: true, onHover: show, onMove: move, onLeave: hide }),
6917
6905
  ready && (type === "pie" || type === "doughnut") && /* @__PURE__ */ jsx307(ChartLegend, { data: stableData, labels: stableLabels, type }),
6918
- tooltip.visible && tooltip.content && /* @__PURE__ */ jsx307(ChartTooltip, { x: tooltip.x, y: tooltip.y, containerWidth: width, containerHeight: height, children: tooltip.content })
6906
+ tooltip.visible && tooltip.content && /* @__PURE__ */ jsx307(ChartTooltip, { x: tooltip.x, y: tooltip.y, containerWidth: width, containerHeight: height, tooltipType, children: tooltip.content })
6919
6907
  ] });
6920
6908
  });
6921
6909
  Chart.displayName = "Chart";
@@ -9435,18 +9423,94 @@ ToastProvider.displayName = "ToastProvider";
9435
9423
 
9436
9424
  // src/components/Tooltip/Tooltip.tsx
9437
9425
  import React39 from "react";
9438
- import { jsx as jsx348, jsxs as jsxs221 } from "react/jsx-runtime";
9426
+ import { Fragment as Fragment5, jsx as jsx348, jsxs as jsxs221 } from "react/jsx-runtime";
9427
+ var OFFSET = 12;
9428
+ var SHOW_DELAY = 300;
9439
9429
  var Tooltip = (props) => {
9440
9430
  const {
9441
- type = "primary",
9431
+ type = "dark",
9432
+ title,
9442
9433
  description,
9443
- children
9434
+ children,
9435
+ disabled = false
9444
9436
  } = props;
9445
- const iconRef = React39.useRef(null);
9446
- return /* @__PURE__ */ jsxs221("div", { className: "lib-xplat-tooltip", children: [
9447
- /* @__PURE__ */ jsx348("div", { className: "tooltip-content", ref: iconRef, children: children || "Tooltip" }),
9448
- /* @__PURE__ */ jsx348("div", { className: clsx_default("tooltip-wrapper", type), children: description })
9449
- ] });
9437
+ const triggerRef = React39.useRef(null);
9438
+ const tooltipRef = React39.useRef(null);
9439
+ const [visible, setVisible] = React39.useState(false);
9440
+ const [pos, setPos] = React39.useState({ left: 0, top: 0 });
9441
+ const delayTimer = React39.useRef(0);
9442
+ const calculatePos = React39.useCallback((clientX, clientY) => {
9443
+ const el = tooltipRef.current;
9444
+ if (!el) return;
9445
+ const w = el.offsetWidth;
9446
+ const h = el.offsetHeight;
9447
+ const vw = window.innerWidth;
9448
+ let left = clientX + OFFSET;
9449
+ let top = clientY - h - OFFSET;
9450
+ if (left + w > vw - 8) left = clientX - w - OFFSET;
9451
+ if (top < 8) top = clientY + OFFSET;
9452
+ if (left < 8) left = 8;
9453
+ setPos({ left, top });
9454
+ }, []);
9455
+ const handleMouseEnter = React39.useCallback(() => {
9456
+ if (disabled) return;
9457
+ delayTimer.current = window.setTimeout(() => {
9458
+ setVisible(true);
9459
+ }, SHOW_DELAY);
9460
+ }, [disabled]);
9461
+ const handleMouseMove = React39.useCallback((e) => {
9462
+ if (!visible) return;
9463
+ calculatePos(e.clientX, e.clientY);
9464
+ }, [visible, calculatePos]);
9465
+ const handleMouseLeave = React39.useCallback(() => {
9466
+ window.clearTimeout(delayTimer.current);
9467
+ setVisible(false);
9468
+ }, []);
9469
+ const handleClick = React39.useCallback(() => {
9470
+ window.clearTimeout(delayTimer.current);
9471
+ setVisible(false);
9472
+ }, []);
9473
+ const handleFocus = React39.useCallback(() => {
9474
+ if (disabled) return;
9475
+ setVisible(true);
9476
+ }, [disabled]);
9477
+ const handleBlur = React39.useCallback(() => {
9478
+ setVisible(false);
9479
+ }, []);
9480
+ React39.useLayoutEffect(() => {
9481
+ if (!visible || !triggerRef.current) return;
9482
+ const rect = triggerRef.current.getBoundingClientRect();
9483
+ calculatePos(rect.right, rect.top);
9484
+ }, [visible, calculatePos]);
9485
+ if (!title && !description) return /* @__PURE__ */ jsx348(Fragment5, { children });
9486
+ return /* @__PURE__ */ jsxs221(
9487
+ "div",
9488
+ {
9489
+ ref: triggerRef,
9490
+ className: "lib-xplat-tooltip-trigger",
9491
+ onMouseEnter: handleMouseEnter,
9492
+ onMouseMove: handleMouseMove,
9493
+ onMouseLeave: handleMouseLeave,
9494
+ onClick: handleClick,
9495
+ onFocus: handleFocus,
9496
+ onBlur: handleBlur,
9497
+ children: [
9498
+ children,
9499
+ visible && /* @__PURE__ */ jsx348(Portal_default, { children: /* @__PURE__ */ jsxs221(
9500
+ "div",
9501
+ {
9502
+ ref: tooltipRef,
9503
+ className: clsx_default("lib-xplat-tooltip", type),
9504
+ style: { position: "fixed", left: pos.left, top: pos.top },
9505
+ children: [
9506
+ title && /* @__PURE__ */ jsx348("div", { className: "tooltip-title", children: title }),
9507
+ description && /* @__PURE__ */ jsx348("div", { className: "tooltip-desc", children: description })
9508
+ ]
9509
+ }
9510
+ ) })
9511
+ ]
9512
+ }
9513
+ );
9450
9514
  };
9451
9515
  Tooltip.displayName = "Tooltip";
9452
9516
  var Tooltip_default = Tooltip;
@@ -9891,11 +9955,11 @@ Header.displayName = "Header";
9891
9955
  var Header_default = Header;
9892
9956
 
9893
9957
  // src/layout/Layout/Layout.tsx
9894
- import { Fragment as Fragment5, jsx as jsx354, jsxs as jsxs224 } from "react/jsx-runtime";
9958
+ import { Fragment as Fragment6, jsx as jsx354, jsxs as jsxs224 } from "react/jsx-runtime";
9895
9959
  var Layout = (props) => {
9896
9960
  const { header, sideBar, children } = props;
9897
9961
  return /* @__PURE__ */ jsx354("div", { className: "lib-xplat-layout", children: /* @__PURE__ */ jsxs224("div", { className: "lib-xplat-layout-content-wrapper", children: [
9898
- sideBar && /* @__PURE__ */ jsx354(Fragment5, { children: sideBar }),
9962
+ sideBar && /* @__PURE__ */ jsx354(Fragment6, { children: sideBar }),
9899
9963
  /* @__PURE__ */ jsxs224("div", { className: "lib-xplat-layout-content", children: [
9900
9964
  header && /* @__PURE__ */ jsx354("div", { className: "lib-xplat-layout-conent-header", children: header }),
9901
9965
  children
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@x-plat/design-system",
3
- "version": "0.5.37",
3
+ "version": "0.5.38",
4
4
  "description": "XPLAT UI Design System",
5
5
  "author": "XPLAT WOONG",
6
6
  "main": "dist/index.cjs",