@skygraph/react 0.4.0 → 0.5.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
@@ -31,7 +31,7 @@ import {
31
31
  buildPrintHtml,
32
32
  printElement,
33
33
  useTable
34
- } from "./chunk-MJAEAFPN.js";
34
+ } from "./chunk-NXB3VAVF.js";
35
35
  import {
36
36
  Button,
37
37
  Input,
@@ -41,13 +41,13 @@ import {
41
41
  Tree,
42
42
  TreeSelect,
43
43
  useTree
44
- } from "./chunk-6SHHUUAE.js";
44
+ } from "./chunk-UO6VJC3C.js";
45
45
  import {
46
46
  DataGrid
47
- } from "./chunk-KCFWFDSP.js";
47
+ } from "./chunk-Z5UGF7EO.js";
48
48
  import {
49
49
  Checkbox
50
- } from "./chunk-DRBAZI46.js";
50
+ } from "./chunk-FSV73JI4.js";
51
51
  import {
52
52
  ConfigProvider,
53
53
  Spin,
@@ -2315,9 +2315,7 @@ function RadioGroup({
2315
2315
  }) {
2316
2316
  const config = useConfig();
2317
2317
  const disabled = disabledProp ?? config.disabled ?? false;
2318
- const [internalValue, setInternalValue] = React3.useState(
2319
- value ?? defaultValue
2320
- );
2318
+ const [internalValue, setInternalValue] = React3.useState(value ?? defaultValue);
2321
2319
  const currentValue = value ?? internalValue;
2322
2320
  const groupClass = unstyled ? className ?? "" : [
2323
2321
  "sg-radio-group",
@@ -2349,6 +2347,7 @@ function RadioGroup({
2349
2347
  }
2350
2348
  }
2351
2349
  ),
2350
+ !unstyled && /* @__PURE__ */ jsx4("span", { className: "sg-radio-box", "aria-hidden": "true" }),
2352
2351
  /* @__PURE__ */ jsx4("span", { className: unstyled ? "" : "sg-radio-label", children: opt.label }),
2353
2352
  loading && currentValue === opt.value && /* @__PURE__ */ jsx4(Spin, { size: "small", unstyled })
2354
2353
  ]
@@ -8020,7 +8019,7 @@ import {
8020
8019
  pointsToPath,
8021
8020
  pointsToRoundedPath,
8022
8021
  getBezierPath,
8023
- nearestSide
8022
+ resolveEdgeEndpoint
8024
8023
  } from "@skygraph/core";
8025
8024
 
8026
8025
  // src/components/complex/Diagram/HoverActions.tsx
@@ -8167,47 +8166,26 @@ function selectionsEqual(a, b) {
8167
8166
 
8168
8167
  // src/components/complex/Diagram/Diagram.tsx
8169
8168
  import { jsx as jsx40, jsxs as jsxs36 } from "react/jsx-runtime";
8170
- function resolveAnchor(graph, nodeId, ref) {
8171
- const anchors = graph.anchorsOf(nodeId);
8172
- let anchor;
8173
- if (typeof ref === "string") {
8174
- anchor = anchors.find((a) => a.id === ref);
8175
- } else {
8176
- let best;
8177
- let bestDiff = Infinity;
8178
- for (const a of anchors) {
8179
- const diff = Math.abs(a.s - ref.s);
8180
- if (diff < bestDiff) {
8181
- bestDiff = diff;
8182
- best = a;
8183
- }
8184
- }
8185
- anchor = best;
8186
- }
8187
- if (!anchor) return null;
8188
- return { point: anchor.point };
8189
- }
8190
- function endpointWorldPoint(graph, ep) {
8191
- const node = graph.getNode(ep.node);
8192
- if (!node) return null;
8193
- const local = resolveAnchor(graph, ep.node, ep.anchor);
8194
- if (!local) return null;
8195
- const bounds = graph.boundsOf(ep.node);
8196
- return [
8197
- bounds.x + (local.point[0] - localOriginOffset(node).x),
8198
- bounds.y + (local.point[1] - localOriginOffset(node).y)
8199
- ];
8200
- }
8201
- function localOriginOffset(node) {
8202
- const o = node.outline;
8203
- if (o.kind === "ellipse") return { x: -o.rx, y: -o.ry };
8204
- return { x: 0, y: 0 };
8205
- }
8206
8169
  function defaultRenderNode(node) {
8207
8170
  return /* @__PURE__ */ jsx40("span", { className: "sg-diagram-node-label", children: node.id });
8208
8171
  }
8209
8172
  var ORTHOGONAL_CORNER_RADIUS = 8;
8210
- function buildEdgePath(edge, start, end, obstacles, sourceBounds, targetBounds, routerOpts) {
8173
+ var ENDPOINT_PADDING = 8;
8174
+ function resolveEdgeEndpoints(sourceBox, targetBox) {
8175
+ const source = resolveEdgeEndpoint(sourceBox, targetBox, ENDPOINT_PADDING);
8176
+ const target = resolveEdgeEndpoint(targetBox, sourceBox, ENDPOINT_PADDING);
8177
+ return { source, target };
8178
+ }
8179
+ function edgeMidpoint(graph, ep) {
8180
+ const sb = graph.boundsOf(ep.from.node);
8181
+ const tb = graph.boundsOf(ep.to.node);
8182
+ if (sb.w === 0 || tb.w === 0) return null;
8183
+ const { source, target } = resolveEdgeEndpoints(sb, tb);
8184
+ return [(source.point[0] + target.point[0]) / 2, (source.point[1] + target.point[1]) / 2];
8185
+ }
8186
+ function buildEdgePath(edge, source, target, obstacles, sourceBounds, targetBounds, routerOpts) {
8187
+ const start = source.point;
8188
+ const end = target.point;
8211
8189
  switch (edge.routing) {
8212
8190
  case "orthogonal": {
8213
8191
  const points = routeOrthogonal(start, end, {
@@ -8216,18 +8194,18 @@ function buildEdgePath(edge, start, end, obstacles, sourceBounds, targetBounds,
8216
8194
  inflate: routerOpts?.inflate,
8217
8195
  maxNodes: routerOpts?.maxNodes,
8218
8196
  sourceBounds,
8219
- targetBounds
8197
+ targetBounds,
8198
+ stepPosition: routerOpts?.stepPosition,
8199
+ stubLength: routerOpts?.stubLength
8220
8200
  });
8221
8201
  return pointsToRoundedPath(points, routerOpts?.cornerRadius ?? ORTHOGONAL_CORNER_RADIUS);
8222
8202
  }
8223
8203
  case "bezier": {
8224
- const sourceSide = sourceBounds ? nearestSide(sourceBounds, end) : "right";
8225
- const targetSide = targetBounds ? nearestSide(targetBounds, start) : "left";
8226
8204
  return getBezierPath({
8227
8205
  source: start,
8228
- sourceSide,
8206
+ sourceSide: source.side,
8229
8207
  target: end,
8230
- targetSide,
8208
+ targetSide: target.side,
8231
8209
  curvature: routerOpts?.curvature
8232
8210
  });
8233
8211
  }
@@ -8696,10 +8674,9 @@ function DiagramInner({
8696
8674
  const hoveredEdgeRecord = hoveredEdge != null ? state.edges.get(hoveredEdge) ?? null : null;
8697
8675
  const hoveredEdgeMid = useMemo11(() => {
8698
8676
  if (!hoveredEdgeRecord) return null;
8699
- const a = endpointWorldPoint(graph, hoveredEdgeRecord.from);
8700
- const b = endpointWorldPoint(graph, hoveredEdgeRecord.to);
8701
- if (!a || !b) return null;
8702
- return { x: (a[0] + b[0]) / 2, y: (a[1] + b[1]) / 2 };
8677
+ const mid = edgeMidpoint(graph, hoveredEdgeRecord);
8678
+ if (!mid) return null;
8679
+ return { x: mid[0], y: mid[1] };
8703
8680
  }, [graph, hoveredEdgeRecord]);
8704
8681
  return /* @__PURE__ */ jsxs36(
8705
8682
  "div",
@@ -8745,53 +8722,33 @@ function DiagramInner({
8745
8722
  },
8746
8723
  "aria-hidden": "true",
8747
8724
  children: [
8748
- edgeArrows && /* @__PURE__ */ jsxs36("defs", { children: [
8749
- /* @__PURE__ */ jsx40(
8750
- "marker",
8751
- {
8752
- id: "sg-diagram-arrow",
8753
- viewBox: "0 0 10 10",
8754
- refX: "9",
8755
- refY: "5",
8756
- markerWidth: "7",
8757
- markerHeight: "7",
8758
- orient: "auto-start-reverse",
8759
- markerUnits: "userSpaceOnUse",
8760
- children: /* @__PURE__ */ jsx40(
8761
- "path",
8762
- {
8763
- d: "M 0 0 L 10 5 L 0 10 Z",
8764
- fill: "context-stroke",
8765
- className: "sg-diagram-arrow-fill"
8766
- }
8767
- )
8768
- }
8769
- ),
8770
- /* @__PURE__ */ jsx40(
8771
- "marker",
8772
- {
8773
- id: "sg-diagram-arrow-hover",
8774
- viewBox: "0 0 10 10",
8775
- refX: "9",
8776
- refY: "5",
8777
- markerWidth: "8",
8778
- markerHeight: "8",
8779
- orient: "auto-start-reverse",
8780
- markerUnits: "userSpaceOnUse",
8781
- children: /* @__PURE__ */ jsx40(
8782
- "path",
8783
- {
8784
- d: "M 0 0 L 10 5 L 0 10 Z",
8785
- fill: "context-stroke",
8786
- className: "sg-diagram-arrow-fill"
8787
- }
8788
- )
8789
- }
8790
- )
8791
- ] }),
8725
+ edgeArrows && /* @__PURE__ */ jsx40("defs", { children: /* @__PURE__ */ jsx40(
8726
+ "marker",
8727
+ {
8728
+ id: "sg-diagram-arrow",
8729
+ viewBox: "-10 -10 20 20",
8730
+ refX: "0",
8731
+ refY: "0",
8732
+ markerWidth: "12",
8733
+ markerHeight: "12",
8734
+ orient: "auto-start-reverse",
8735
+ markerUnits: "strokeWidth",
8736
+ children: /* @__PURE__ */ jsx40(
8737
+ "path",
8738
+ {
8739
+ d: "M -7 -5 L 0 0 L -7 5",
8740
+ fill: "none",
8741
+ stroke: "context-stroke",
8742
+ strokeWidth: "1.5",
8743
+ strokeLinecap: "round",
8744
+ strokeLinejoin: "round",
8745
+ className: "sg-diagram-arrow-fill"
8746
+ }
8747
+ )
8748
+ }
8749
+ ) }),
8792
8750
  edges.map(
8793
8751
  (edge) => renderEdge(
8794
- graph,
8795
8752
  edge,
8796
8753
  boundsById,
8797
8754
  routeAroundNodes,
@@ -8891,10 +8848,11 @@ function DiagramInner({
8891
8848
  }
8892
8849
  );
8893
8850
  }
8894
- function renderEdge(graph, edge, boundsById, routeAroundNodes, routerOpts, interactive, arrows, onContextMenu, onMouseEnter, onMouseLeave) {
8895
- const a = endpointWorldPoint(graph, edge.from);
8896
- const b = endpointWorldPoint(graph, edge.to);
8897
- if (!a || !b) return null;
8851
+ function renderEdge(edge, boundsById, routeAroundNodes, routerOpts, interactive, arrows, onContextMenu, onMouseEnter, onMouseLeave) {
8852
+ const sBox = boundsById.get(edge.from.node);
8853
+ const tBox = boundsById.get(edge.to.node);
8854
+ if (!sBox || !tBox) return null;
8855
+ const { source, target } = resolveEdgeEndpoints(sBox, tBox);
8898
8856
  let obstacles;
8899
8857
  if (routeAroundNodes && edge.routing === "orthogonal") {
8900
8858
  const skip = /* @__PURE__ */ new Set([edge.from.node, edge.to.node]);
@@ -8903,10 +8861,7 @@ function renderEdge(graph, edge, boundsById, routeAroundNodes, routerOpts, inter
8903
8861
  if (!skip.has(id)) obstacles.push(bb);
8904
8862
  }
8905
8863
  }
8906
- const needsBounds = edge.routing === "orthogonal" || edge.routing === "bezier";
8907
- const sourceBounds = needsBounds ? boundsById.get(edge.from.node) : void 0;
8908
- const targetBounds = needsBounds ? boundsById.get(edge.to.node) : void 0;
8909
- const d = buildEdgePath(edge, a, b, obstacles, sourceBounds, targetBounds, routerOpts);
8864
+ const d = buildEdgePath(edge, source, target, obstacles, void 0, void 0, routerOpts);
8910
8865
  const markerEnd = arrows ? "url(#sg-diagram-arrow)" : void 0;
8911
8866
  if (!interactive) {
8912
8867
  return /* @__PURE__ */ jsx40(
@@ -9425,7 +9380,7 @@ import {
9425
9380
  useMemo as useMemo14,
9426
9381
  useRef as useRef21
9427
9382
  } from "react";
9428
- import { routeOrthogonal as routeOrthogonal2, pointsToPath as pointsToPath2 } from "@skygraph/core";
9383
+ import { pointsToPath as pointsToPath2 } from "@skygraph/core";
9429
9384
  import { jsx as jsx43, jsxs as jsxs38 } from "react/jsx-runtime";
9430
9385
  var DAY = 864e5;
9431
9386
  var STEP_MS = {
@@ -9446,11 +9401,18 @@ function alignUp(t, step) {
9446
9401
  function clamp2(v, lo, hi) {
9447
9402
  return Math.max(lo, Math.min(hi, v));
9448
9403
  }
9449
- function formatTick(timeMs, scale) {
9404
+ function formatTick(timeMs, scale, columnWidth) {
9450
9405
  const d = new Date(timeMs);
9451
9406
  switch (scale) {
9452
9407
  case "day": {
9453
9408
  const dd = String(d.getUTCDate()).padStart(2, "0");
9409
+ if (columnWidth < 32) {
9410
+ if (d.getUTCDate() === 1) {
9411
+ const mm2 = String(d.getUTCMonth() + 1).padStart(2, "0");
9412
+ return `${dd}.${mm2}`;
9413
+ }
9414
+ return dd;
9415
+ }
9454
9416
  const mm = String(d.getUTCMonth() + 1).padStart(2, "0");
9455
9417
  return `${dd}.${mm}`;
9456
9418
  }
@@ -9530,12 +9492,12 @@ function Gantt({
9530
9492
  for (let t = resolved.rangeStart; t < resolved.rangeEnd; t += resolved.step) {
9531
9493
  out.push({
9532
9494
  x: (t - resolved.rangeStart) * resolved.pxPerMs,
9533
- label: formatTick(t, scale),
9495
+ label: formatTick(t, scale, columnWidth),
9534
9496
  time: t
9535
9497
  });
9536
9498
  }
9537
9499
  return out;
9538
- }, [resolved, scale]);
9500
+ }, [resolved, scale, columnWidth]);
9539
9501
  const taskRects = useMemo14(() => {
9540
9502
  return tasks.map((task) => {
9541
9503
  const startMs = toMs(task.start);
@@ -9554,17 +9516,38 @@ function Gantt({
9554
9516
  }, [taskRects]);
9555
9517
  const dependencyPaths = useMemo14(() => {
9556
9518
  const out = [];
9519
+ const STUB = 8;
9520
+ const APPROACH = 18;
9557
9521
  for (const r of taskRects) {
9558
9522
  const deps = r.task.dependencies;
9559
9523
  if (!deps || deps.length === 0) continue;
9560
9524
  for (const depId of deps) {
9561
9525
  const src = taskRectById.get(depId);
9562
9526
  if (!src) continue;
9563
- const startPt = [src.x + src.w, src.y + src.h / 2];
9564
- const endPt = [r.x, r.y + r.h / 2];
9565
- const points = routeOrthogonal2(startPt, endPt, {
9566
- preferred: "hv"
9567
- });
9527
+ const sx = src.x + src.w;
9528
+ const sy = src.y + src.h / 2;
9529
+ const tx = r.x;
9530
+ const ey = r.y + r.h / 2;
9531
+ let points;
9532
+ if (tx >= sx + STUB + APPROACH) {
9533
+ const bendX = sx + STUB;
9534
+ points = [
9535
+ [sx, sy],
9536
+ [bendX, sy],
9537
+ [bendX, ey],
9538
+ [tx, ey]
9539
+ ];
9540
+ } else {
9541
+ const detourY = src.y + src.h;
9542
+ points = [
9543
+ [sx, sy],
9544
+ [sx + STUB, sy],
9545
+ [sx + STUB, detourY],
9546
+ [tx - APPROACH, detourY],
9547
+ [tx - APPROACH, ey],
9548
+ [tx, ey]
9549
+ ];
9550
+ }
9568
9551
  out.push({ id: `${depId}->${r.task.id}`, d: pointsToPath2(points) });
9569
9552
  }
9570
9553
  }
@@ -9631,12 +9614,13 @@ function Gantt({
9631
9614
  const wrapperClass = unstyled ? className : ["sg-gantt", className].filter(Boolean).join(" ");
9632
9615
  const headerHeight = rowHeight;
9633
9616
  const gridHeight = resolved.rows.length * rowHeight;
9634
- const totalHeight = gridHeight + headerHeight;
9617
+ const SCROLLBAR_RESERVE = 14;
9618
+ const totalHeight = gridHeight + headerHeight + SCROLLBAR_RESERVE;
9635
9619
  const wrapperStyle = {
9636
9620
  display: "grid",
9637
- gridTemplateColumns: `${sidebarWidth}px 1fr`,
9621
+ gridTemplateColumns: `${sidebarWidth}px minmax(0, 1fr)`,
9638
9622
  width: "100%",
9639
- overflow: "auto",
9623
+ overflow: "hidden",
9640
9624
  height: totalHeight,
9641
9625
  ...style
9642
9626
  };
@@ -9669,12 +9653,12 @@ function Gantt({
9669
9653
  row.key
9670
9654
  ))
9671
9655
  ] }),
9672
- /* @__PURE__ */ jsxs38(
9656
+ /* @__PURE__ */ jsx43(
9673
9657
  "div",
9674
9658
  {
9675
9659
  className: unstyled ? void 0 : "sg-gantt-main",
9676
- style: { position: "relative", width: resolved.totalWidth, minWidth: "100%" },
9677
- children: [
9660
+ style: { position: "relative", overflowX: "auto", overflowY: "hidden", minWidth: 0 },
9661
+ children: /* @__PURE__ */ jsxs38("div", { style: { position: "relative", width: resolved.totalWidth, minWidth: "100%" }, children: [
9678
9662
  /* @__PURE__ */ jsx43(
9679
9663
  "div",
9680
9664
  {
@@ -9723,44 +9707,6 @@ function Gantt({
9723
9707
  },
9724
9708
  row.key
9725
9709
  )),
9726
- dependencyPaths.length > 0 && /* @__PURE__ */ jsxs38(
9727
- "svg",
9728
- {
9729
- className: unstyled ? void 0 : "sg-gantt-deps",
9730
- width: resolved.totalWidth,
9731
- height: gridHeight,
9732
- style: { position: "absolute", inset: 0, pointerEvents: "none", overflow: "visible" },
9733
- "aria-hidden": "true",
9734
- children: [
9735
- /* @__PURE__ */ jsx43("defs", { children: /* @__PURE__ */ jsx43(
9736
- "marker",
9737
- {
9738
- id: "sg-gantt-arrow",
9739
- viewBox: "0 0 10 10",
9740
- refX: "8",
9741
- refY: "5",
9742
- markerWidth: "6",
9743
- markerHeight: "6",
9744
- orient: "auto",
9745
- children: /* @__PURE__ */ jsx43("path", { d: "M 0 0 L 10 5 L 0 10 z", fill: "currentColor" })
9746
- }
9747
- ) }),
9748
- dependencyPaths.map((p) => /* @__PURE__ */ jsx43(
9749
- "path",
9750
- {
9751
- d: p.d,
9752
- className: unstyled ? void 0 : "sg-gantt-dep",
9753
- fill: "none",
9754
- stroke: "currentColor",
9755
- strokeWidth: 1.5,
9756
- markerEnd: "url(#sg-gantt-arrow)",
9757
- "data-dep-id": p.id
9758
- },
9759
- p.id
9760
- ))
9761
- ]
9762
- }
9763
- ),
9764
9710
  taskRects.map(({ task, x, y, w, h }) => {
9765
9711
  const barClass = unstyled ? void 0 : [
9766
9712
  "sg-gantt-bar",
@@ -9834,11 +9780,54 @@ function Gantt({
9834
9780
  },
9835
9781
  task.id
9836
9782
  );
9837
- })
9783
+ }),
9784
+ dependencyPaths.length > 0 && /* @__PURE__ */ jsxs38(
9785
+ "svg",
9786
+ {
9787
+ className: unstyled ? void 0 : "sg-gantt-deps",
9788
+ width: resolved.totalWidth,
9789
+ height: gridHeight,
9790
+ style: {
9791
+ position: "absolute",
9792
+ inset: 0,
9793
+ pointerEvents: "none",
9794
+ overflow: "visible"
9795
+ },
9796
+ "aria-hidden": "true",
9797
+ children: [
9798
+ /* @__PURE__ */ jsx43("defs", { children: /* @__PURE__ */ jsx43(
9799
+ "marker",
9800
+ {
9801
+ id: "sg-gantt-arrow",
9802
+ viewBox: "0 0 10 10",
9803
+ refX: "10",
9804
+ refY: "5",
9805
+ markerWidth: "6",
9806
+ markerHeight: "6",
9807
+ orient: "auto",
9808
+ children: /* @__PURE__ */ jsx43("path", { d: "M 0 0 L 10 5 L 0 10 z", fill: "currentColor" })
9809
+ }
9810
+ ) }),
9811
+ dependencyPaths.map((p) => /* @__PURE__ */ jsx43(
9812
+ "path",
9813
+ {
9814
+ d: p.d,
9815
+ className: unstyled ? void 0 : "sg-gantt-dep",
9816
+ fill: "none",
9817
+ stroke: "currentColor",
9818
+ strokeWidth: 1.5,
9819
+ markerEnd: "url(#sg-gantt-arrow)",
9820
+ "data-dep-id": p.id
9821
+ },
9822
+ p.id
9823
+ ))
9824
+ ]
9825
+ }
9826
+ )
9838
9827
  ]
9839
9828
  }
9840
9829
  )
9841
- ]
9830
+ ] })
9842
9831
  }
9843
9832
  )
9844
9833
  ]
@@ -9890,14 +9879,7 @@ function formatTick2(timeMs, scale) {
9890
9879
  }
9891
9880
  }
9892
9881
  }
9893
- function deriveRange2(assignments, step) {
9894
- if (assignments.length === 0) {
9895
- const now = Date.now();
9896
- return {
9897
- from: new Date(alignDown2(now, step)),
9898
- to: new Date(alignUp2(now + step * 4, step))
9899
- };
9900
- }
9882
+ function resolveRange(assignments, step, range) {
9901
9883
  let lo = Infinity;
9902
9884
  let hi = -Infinity;
9903
9885
  for (const a of assignments) {
@@ -9906,6 +9888,22 @@ function deriveRange2(assignments, step) {
9906
9888
  if (s < lo) lo = s;
9907
9889
  if (e > hi) hi = e;
9908
9890
  }
9891
+ if (range) {
9892
+ const rangeFrom = range.from.getTime();
9893
+ const rangeTo = range.to.getTime();
9894
+ if (assignments.length === 0) return { from: new Date(rangeFrom), to: new Date(rangeTo) };
9895
+ return {
9896
+ from: new Date(alignDown2(Math.min(rangeFrom, lo), step)),
9897
+ to: new Date(alignUp2(Math.max(rangeTo, hi), step))
9898
+ };
9899
+ }
9900
+ if (assignments.length === 0) {
9901
+ const now = Date.now();
9902
+ return {
9903
+ from: new Date(alignDown2(now, step)),
9904
+ to: new Date(alignUp2(now + step * 4, step))
9905
+ };
9906
+ }
9909
9907
  return {
9910
9908
  from: new Date(alignDown2(lo - step, step)),
9911
9909
  to: new Date(alignUp2(hi + step, step))
@@ -9936,7 +9934,7 @@ function ResourceCalendar({
9936
9934
  const [ghost, setGhost] = useState21(null);
9937
9935
  const step = STEP_MS2[scale];
9938
9936
  const resolvedRange = useMemo15(
9939
- () => range ?? deriveRange2(assignments, step),
9937
+ () => resolveRange(assignments, step, range),
9940
9938
  [range, assignments, step]
9941
9939
  );
9942
9940
  const rangeStart = resolvedRange.from.getTime();
@@ -10555,6 +10553,33 @@ function normalizePadding(p) {
10555
10553
  if (typeof p === "number") return [p, p, p, p];
10556
10554
  return [...p];
10557
10555
  }
10556
+ function defaultYTickFormatter(value) {
10557
+ if (Number.isInteger(value)) return String(value);
10558
+ if (Math.abs(value) >= 1e3) return value.toFixed(0);
10559
+ if (Math.abs(value) >= 1) return value.toFixed(2).replace(/\.?0+$/, "");
10560
+ return value.toFixed(2);
10561
+ }
10562
+ function estimateYAxisLabelWidth(min, max, tickCount, formatter) {
10563
+ const fmt = formatter ?? defaultYTickFormatter;
10564
+ const count = Math.max(2, tickCount ?? 5);
10565
+ let maxLen = 0;
10566
+ for (let i = 0; i < count; i++) {
10567
+ const t = i / (count - 1);
10568
+ const value = min + t * (max - min);
10569
+ const s = fmt(value);
10570
+ if (s.length > maxLen) maxLen = s.length;
10571
+ }
10572
+ return maxLen * 7;
10573
+ }
10574
+ function resolveChartPadding(userPadding, yAxis, yMin, yMax) {
10575
+ const base = normalizePadding(userPadding);
10576
+ if (userPadding !== void 0 || !yAxis) return base;
10577
+ const labelW = estimateYAxisLabelWidth(yMin, yMax, yAxis.tickCount, yAxis.tickFormatter);
10578
+ const need = Math.ceil(labelW + 18);
10579
+ if (need > base[3]) base[3] = need;
10580
+ if (yAxis.label) base[3] += 16;
10581
+ return base;
10582
+ }
10558
10583
  function chartBounds(values) {
10559
10584
  let min = Infinity;
10560
10585
  let max = -Infinity;
@@ -11508,7 +11533,11 @@ function LineChartInner({
11508
11533
  const chartsLocale = useConfig().locale?.charts;
11509
11534
  const { rootRef } = useChartPrint(forwardedRef, printable);
11510
11535
  const svgRef = useRef26(null);
11511
- const [pt, pr, pb, pl] = normalizePadding(padding);
11536
+ const { min, max } = useMemo19(() => chartBounds(series.map((s) => s.values)), [series]);
11537
+ const [pt, pr, pb, pl] = useMemo19(
11538
+ () => resolveChartPadding(padding, yAxis, min, max),
11539
+ [padding, yAxis, min, max]
11540
+ );
11512
11541
  const fallbackW = typeof width === "number" && Number.isFinite(width) ? width : 600;
11513
11542
  const fallbackH = typeof height === "number" && Number.isFinite(height) ? height : 200;
11514
11543
  const measured = useChartSize(svgRef, { width: fallbackW, height: fallbackH });
@@ -11516,7 +11545,6 @@ function LineChartInner({
11516
11545
  const viewH = measured.height;
11517
11546
  const plotW = Math.max(0, viewW - pl - pr);
11518
11547
  const plotH = Math.max(0, viewH - pt - pb);
11519
- const { min, max } = useMemo19(() => chartBounds(series.map((s) => s.values)), [series]);
11520
11548
  const range = max - min || 1;
11521
11549
  const xStep = categories.length > 1 ? plotW / (categories.length - 1) : 0;
11522
11550
  function xFor(i) {
@@ -11785,7 +11813,14 @@ function BarChartInner({
11785
11813
  const chartsLocale = useConfig().locale?.charts;
11786
11814
  const { rootRef } = useChartPrint(forwardedRef, printable);
11787
11815
  const svgRef = useRef27(null);
11788
- const [pt, pr, pb, pl] = normalizePadding(padding);
11816
+ const { min, max } = useMemo20(() => chartBounds(series.map((s) => s.values)), [series]);
11817
+ const baseline = Math.min(0, min);
11818
+ const top = Math.max(0, max);
11819
+ const span = top - baseline || 1;
11820
+ const [pt, pr, pb, pl] = useMemo20(
11821
+ () => resolveChartPadding(padding, yAxis, baseline, top),
11822
+ [padding, yAxis, baseline, top]
11823
+ );
11789
11824
  const fallbackW = typeof width === "number" && Number.isFinite(width) ? width : 600;
11790
11825
  const fallbackH = typeof height === "number" && Number.isFinite(height) ? height : 200;
11791
11826
  const measured = useChartSize(svgRef, { width: fallbackW, height: fallbackH });
@@ -11793,10 +11828,6 @@ function BarChartInner({
11793
11828
  const viewH = measured.height;
11794
11829
  const plotW = Math.max(0, viewW - pl - pr);
11795
11830
  const plotH = Math.max(0, viewH - pt - pb);
11796
- const { min, max } = useMemo20(() => chartBounds(series.map((s) => s.values)), [series]);
11797
- const baseline = Math.min(0, min);
11798
- const top = Math.max(0, max);
11799
- const span = top - baseline || 1;
11800
11831
  const yZero = pt + top / span * plotH;
11801
11832
  const groupCount = categories.length;
11802
11833
  const groupWidth = groupCount > 0 ? plotW / groupCount : 0;
@@ -11991,14 +12022,6 @@ function AreaChartInner({
11991
12022
  const chartsLocale = useConfig().locale?.charts;
11992
12023
  const { rootRef } = useChartPrint(forwardedRef, printable);
11993
12024
  const svgRef = useRef28(null);
11994
- const [pt, pr, pb, pl] = normalizePadding(padding);
11995
- const fallbackW = typeof width === "number" && Number.isFinite(width) ? width : 600;
11996
- const fallbackH = typeof height === "number" && Number.isFinite(height) ? height : 200;
11997
- const measured = useChartSize(svgRef, { width: fallbackW, height: fallbackH });
11998
- const viewW = measured.width;
11999
- const viewH = measured.height;
12000
- const plotW = Math.max(0, viewW - pl - pr);
12001
- const plotH = Math.max(0, viewH - pt - pb);
12002
12025
  const stackedValues = useMemo21(() => {
12003
12026
  if (!stacked) return series.map((s) => [...s.values]);
12004
12027
  const totals = new Array(categories.length).fill(0);
@@ -12019,6 +12042,17 @@ function AreaChartInner({
12019
12042
  const baseline = Math.min(0, min);
12020
12043
  const top = Math.max(0, max);
12021
12044
  const span = top - baseline || 1;
12045
+ const [pt, pr, pb, pl] = useMemo21(
12046
+ () => resolveChartPadding(padding, yAxis, baseline, top),
12047
+ [padding, yAxis, baseline, top]
12048
+ );
12049
+ const fallbackW = typeof width === "number" && Number.isFinite(width) ? width : 600;
12050
+ const fallbackH = typeof height === "number" && Number.isFinite(height) ? height : 200;
12051
+ const measured = useChartSize(svgRef, { width: fallbackW, height: fallbackH });
12052
+ const viewW = measured.width;
12053
+ const viewH = measured.height;
12054
+ const plotW = Math.max(0, viewW - pl - pr);
12055
+ const plotH = Math.max(0, viewH - pt - pb);
12022
12056
  const xStep = categories.length > 1 ? plotW / (categories.length - 1) : 0;
12023
12057
  function xFor(i) {
12024
12058
  return pl + i * xStep;
@@ -12481,10 +12515,20 @@ function ListInner({
12481
12515
  setDragIndex(null);
12482
12516
  setDropIndex(null);
12483
12517
  }, []);
12518
+ const scrollRafRef = React22.useRef(null);
12484
12519
  const handleVirtualScroll = React22.useCallback(() => {
12485
- if (virtualRef.current) {
12486
- setScrollTop(virtualRef.current.scrollTop);
12487
- }
12520
+ if (scrollRafRef.current != null) return;
12521
+ scrollRafRef.current = requestAnimationFrame(() => {
12522
+ scrollRafRef.current = null;
12523
+ if (virtualRef.current) {
12524
+ setScrollTop(virtualRef.current.scrollTop);
12525
+ }
12526
+ });
12527
+ }, []);
12528
+ React22.useEffect(() => {
12529
+ return () => {
12530
+ if (scrollRafRef.current != null) cancelAnimationFrame(scrollRafRef.current);
12531
+ };
12488
12532
  }, []);
12489
12533
  const emptyText = locale?.emptyText ?? "No Data";
12490
12534
  const gridStyle = React22.useMemo(() => {