@skygraph/react 0.4.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -2465,6 +2465,7 @@ function Checkbox({
2465
2465
  onChange: (e) => onChange?.(e.target.checked)
2466
2466
  }
2467
2467
  ),
2468
+ !unstyled && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "sg-checkbox-box", "aria-hidden": true }),
2468
2469
  children && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: unstyled ? "" : "sg-checkbox-label", children }),
2469
2470
  loading && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Spin, { size: "small", unstyled })
2470
2471
  ] });
@@ -2999,7 +3000,7 @@ function AdvancedFilterPanel({ col, t, state, actions, filterRef }) {
2999
3000
  value: draftOp,
3000
3001
  onChange: (v) => setDraftOp(v),
3001
3002
  options: ops.map((op) => ({ label: operatorLabel(op, t), value: op })),
3002
- "aria-label": "Filter operator"
3003
+ "aria-label": t.filterOperatorAriaLabel
3003
3004
  }
3004
3005
  ) }),
3005
3006
  showValueInput && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "sg-table-filter-advanced-row", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
@@ -3255,7 +3256,7 @@ function TableHeader(props) {
3255
3256
  className: ["sg-table-th-content", sCls.headerCellContent].filter(Boolean).join(" "),
3256
3257
  style: sSty.headerCellContent,
3257
3258
  children: [
3258
- cell.col.title,
3259
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "sg-table-th-title", children: cell.col.title }),
3259
3260
  isLeaf && cell.col.tooltip && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ColumnTooltip, { content: cell.col.tooltip }),
3260
3261
  isLeaf && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(SortIndicator, { col: cell.col, ...sortProps })
3261
3262
  ]
@@ -3324,7 +3325,7 @@ function TableHeader(props) {
3324
3325
  className: ["sg-table-th-content", sCls.headerCellContent].filter(Boolean).join(" "),
3325
3326
  style: sSty.headerCellContent,
3326
3327
  children: [
3327
- col.title,
3328
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "sg-table-th-title", children: col.title }),
3328
3329
  col.tooltip && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ColumnTooltip, { content: col.tooltip }),
3329
3330
  /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(SortIndicator, { col, ...sortProps })
3330
3331
  ]
@@ -3829,7 +3830,9 @@ function VirtualTableBody(props) {
3829
3830
  if (!el) return;
3830
3831
  setViewportHeight(el.clientHeight);
3831
3832
  setScrollTop(el.scrollTop);
3832
- const onScroll = () => setScrollTop(el.scrollTop);
3833
+ const onScroll = () => {
3834
+ setScrollTop(el.scrollTop);
3835
+ };
3833
3836
  el.addEventListener("scroll", onScroll, { passive: true });
3834
3837
  let ro = null;
3835
3838
  if (typeof ResizeObserver !== "undefined") {
@@ -4520,7 +4523,8 @@ var DEFAULT_LOCALE = {
4520
4523
  filterOpStartsWith: "starts with",
4521
4524
  filterOpEndsWith: "ends with",
4522
4525
  filterOpIsEmpty: "is empty",
4523
- filterOpIsNotEmpty: "is not empty"
4526
+ filterOpIsNotEmpty: "is not empty",
4527
+ filterOperatorAriaLabel: "Filter operator"
4524
4528
  };
4525
4529
  var DEFAULT_COL_WIDTH = 150;
4526
4530
  var MIN_COL_WIDTH = 50;
@@ -8919,9 +8923,7 @@ function RadioGroup({
8919
8923
  }) {
8920
8924
  const config = useConfig();
8921
8925
  const disabled = disabledProp ?? config.disabled ?? false;
8922
- const [internalValue, setInternalValue] = import_react33.default.useState(
8923
- value ?? defaultValue
8924
- );
8926
+ const [internalValue, setInternalValue] = import_react33.default.useState(value ?? defaultValue);
8925
8927
  const currentValue = value ?? internalValue;
8926
8928
  const groupClass = unstyled ? className ?? "" : [
8927
8929
  "sg-radio-group",
@@ -8953,6 +8955,7 @@ function RadioGroup({
8953
8955
  }
8954
8956
  }
8955
8957
  ),
8958
+ !unstyled && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "sg-radio-box", "aria-hidden": "true" }),
8956
8959
  /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: unstyled ? "" : "sg-radio-label", children: opt.label }),
8957
8960
  loading && currentValue === opt.value && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Spin, { size: "small", unstyled })
8958
8961
  ]
@@ -15685,47 +15688,26 @@ function selectionsEqual(a, b) {
15685
15688
 
15686
15689
  // src/components/complex/Diagram/Diagram.tsx
15687
15690
  var import_jsx_runtime69 = require("react/jsx-runtime");
15688
- function resolveAnchor(graph, nodeId, ref) {
15689
- const anchors = graph.anchorsOf(nodeId);
15690
- let anchor;
15691
- if (typeof ref === "string") {
15692
- anchor = anchors.find((a) => a.id === ref);
15693
- } else {
15694
- let best;
15695
- let bestDiff = Infinity;
15696
- for (const a of anchors) {
15697
- const diff = Math.abs(a.s - ref.s);
15698
- if (diff < bestDiff) {
15699
- bestDiff = diff;
15700
- best = a;
15701
- }
15702
- }
15703
- anchor = best;
15704
- }
15705
- if (!anchor) return null;
15706
- return { point: anchor.point };
15707
- }
15708
- function endpointWorldPoint(graph, ep) {
15709
- const node = graph.getNode(ep.node);
15710
- if (!node) return null;
15711
- const local = resolveAnchor(graph, ep.node, ep.anchor);
15712
- if (!local) return null;
15713
- const bounds = graph.boundsOf(ep.node);
15714
- return [
15715
- bounds.x + (local.point[0] - localOriginOffset(node).x),
15716
- bounds.y + (local.point[1] - localOriginOffset(node).y)
15717
- ];
15718
- }
15719
- function localOriginOffset(node) {
15720
- const o = node.outline;
15721
- if (o.kind === "ellipse") return { x: -o.rx, y: -o.ry };
15722
- return { x: 0, y: 0 };
15723
- }
15724
15691
  function defaultRenderNode(node) {
15725
15692
  return /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("span", { className: "sg-diagram-node-label", children: node.id });
15726
15693
  }
15727
15694
  var ORTHOGONAL_CORNER_RADIUS = 8;
15728
- function buildEdgePath(edge, start, end, obstacles, sourceBounds, targetBounds, routerOpts) {
15695
+ var ENDPOINT_PADDING = 8;
15696
+ function resolveEdgeEndpoints(sourceBox, targetBox) {
15697
+ const source = (0, import_core9.resolveEdgeEndpoint)(sourceBox, targetBox, ENDPOINT_PADDING);
15698
+ const target = (0, import_core9.resolveEdgeEndpoint)(targetBox, sourceBox, ENDPOINT_PADDING);
15699
+ return { source, target };
15700
+ }
15701
+ function edgeMidpoint(graph, ep) {
15702
+ const sb = graph.boundsOf(ep.from.node);
15703
+ const tb = graph.boundsOf(ep.to.node);
15704
+ if (sb.w === 0 || tb.w === 0) return null;
15705
+ const { source, target } = resolveEdgeEndpoints(sb, tb);
15706
+ return [(source.point[0] + target.point[0]) / 2, (source.point[1] + target.point[1]) / 2];
15707
+ }
15708
+ function buildEdgePath(edge, source, target, obstacles, sourceBounds, targetBounds, routerOpts) {
15709
+ const start = source.point;
15710
+ const end = target.point;
15729
15711
  switch (edge.routing) {
15730
15712
  case "orthogonal": {
15731
15713
  const points = (0, import_core9.routeOrthogonal)(start, end, {
@@ -15734,18 +15716,18 @@ function buildEdgePath(edge, start, end, obstacles, sourceBounds, targetBounds,
15734
15716
  inflate: routerOpts?.inflate,
15735
15717
  maxNodes: routerOpts?.maxNodes,
15736
15718
  sourceBounds,
15737
- targetBounds
15719
+ targetBounds,
15720
+ stepPosition: routerOpts?.stepPosition,
15721
+ stubLength: routerOpts?.stubLength
15738
15722
  });
15739
15723
  return (0, import_core9.pointsToRoundedPath)(points, routerOpts?.cornerRadius ?? ORTHOGONAL_CORNER_RADIUS);
15740
15724
  }
15741
15725
  case "bezier": {
15742
- const sourceSide = sourceBounds ? (0, import_core9.nearestSide)(sourceBounds, end) : "right";
15743
- const targetSide = targetBounds ? (0, import_core9.nearestSide)(targetBounds, start) : "left";
15744
15726
  return (0, import_core9.getBezierPath)({
15745
15727
  source: start,
15746
- sourceSide,
15728
+ sourceSide: source.side,
15747
15729
  target: end,
15748
- targetSide,
15730
+ targetSide: target.side,
15749
15731
  curvature: routerOpts?.curvature
15750
15732
  });
15751
15733
  }
@@ -16214,10 +16196,9 @@ function DiagramInner({
16214
16196
  const hoveredEdgeRecord = hoveredEdge != null ? state.edges.get(hoveredEdge) ?? null : null;
16215
16197
  const hoveredEdgeMid = (0, import_react66.useMemo)(() => {
16216
16198
  if (!hoveredEdgeRecord) return null;
16217
- const a = endpointWorldPoint(graph, hoveredEdgeRecord.from);
16218
- const b = endpointWorldPoint(graph, hoveredEdgeRecord.to);
16219
- if (!a || !b) return null;
16220
- return { x: (a[0] + b[0]) / 2, y: (a[1] + b[1]) / 2 };
16199
+ const mid = edgeMidpoint(graph, hoveredEdgeRecord);
16200
+ if (!mid) return null;
16201
+ return { x: mid[0], y: mid[1] };
16221
16202
  }, [graph, hoveredEdgeRecord]);
16222
16203
  return /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(
16223
16204
  "div",
@@ -16263,53 +16244,33 @@ function DiagramInner({
16263
16244
  },
16264
16245
  "aria-hidden": "true",
16265
16246
  children: [
16266
- edgeArrows && /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("defs", { children: [
16267
- /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
16268
- "marker",
16269
- {
16270
- id: "sg-diagram-arrow",
16271
- viewBox: "0 0 10 10",
16272
- refX: "9",
16273
- refY: "5",
16274
- markerWidth: "7",
16275
- markerHeight: "7",
16276
- orient: "auto-start-reverse",
16277
- markerUnits: "userSpaceOnUse",
16278
- children: /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
16279
- "path",
16280
- {
16281
- d: "M 0 0 L 10 5 L 0 10 Z",
16282
- fill: "context-stroke",
16283
- className: "sg-diagram-arrow-fill"
16284
- }
16285
- )
16286
- }
16287
- ),
16288
- /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
16289
- "marker",
16290
- {
16291
- id: "sg-diagram-arrow-hover",
16292
- viewBox: "0 0 10 10",
16293
- refX: "9",
16294
- refY: "5",
16295
- markerWidth: "8",
16296
- markerHeight: "8",
16297
- orient: "auto-start-reverse",
16298
- markerUnits: "userSpaceOnUse",
16299
- children: /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
16300
- "path",
16301
- {
16302
- d: "M 0 0 L 10 5 L 0 10 Z",
16303
- fill: "context-stroke",
16304
- className: "sg-diagram-arrow-fill"
16305
- }
16306
- )
16307
- }
16308
- )
16309
- ] }),
16247
+ edgeArrows && /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
16248
+ "marker",
16249
+ {
16250
+ id: "sg-diagram-arrow",
16251
+ viewBox: "-10 -10 20 20",
16252
+ refX: "0",
16253
+ refY: "0",
16254
+ markerWidth: "12",
16255
+ markerHeight: "12",
16256
+ orient: "auto-start-reverse",
16257
+ markerUnits: "strokeWidth",
16258
+ children: /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
16259
+ "path",
16260
+ {
16261
+ d: "M -7 -5 L 0 0 L -7 5",
16262
+ fill: "none",
16263
+ stroke: "context-stroke",
16264
+ strokeWidth: "1.5",
16265
+ strokeLinecap: "round",
16266
+ strokeLinejoin: "round",
16267
+ className: "sg-diagram-arrow-fill"
16268
+ }
16269
+ )
16270
+ }
16271
+ ) }),
16310
16272
  edges.map(
16311
16273
  (edge) => renderEdge(
16312
- graph,
16313
16274
  edge,
16314
16275
  boundsById,
16315
16276
  routeAroundNodes,
@@ -16409,10 +16370,11 @@ function DiagramInner({
16409
16370
  }
16410
16371
  );
16411
16372
  }
16412
- function renderEdge(graph, edge, boundsById, routeAroundNodes, routerOpts, interactive, arrows, onContextMenu, onMouseEnter, onMouseLeave) {
16413
- const a = endpointWorldPoint(graph, edge.from);
16414
- const b = endpointWorldPoint(graph, edge.to);
16415
- if (!a || !b) return null;
16373
+ function renderEdge(edge, boundsById, routeAroundNodes, routerOpts, interactive, arrows, onContextMenu, onMouseEnter, onMouseLeave) {
16374
+ const sBox = boundsById.get(edge.from.node);
16375
+ const tBox = boundsById.get(edge.to.node);
16376
+ if (!sBox || !tBox) return null;
16377
+ const { source, target } = resolveEdgeEndpoints(sBox, tBox);
16416
16378
  let obstacles;
16417
16379
  if (routeAroundNodes && edge.routing === "orthogonal") {
16418
16380
  const skip = /* @__PURE__ */ new Set([edge.from.node, edge.to.node]);
@@ -16421,10 +16383,7 @@ function renderEdge(graph, edge, boundsById, routeAroundNodes, routerOpts, inter
16421
16383
  if (!skip.has(id)) obstacles.push(bb);
16422
16384
  }
16423
16385
  }
16424
- const needsBounds = edge.routing === "orthogonal" || edge.routing === "bezier";
16425
- const sourceBounds = needsBounds ? boundsById.get(edge.from.node) : void 0;
16426
- const targetBounds = needsBounds ? boundsById.get(edge.to.node) : void 0;
16427
- const d = buildEdgePath(edge, a, b, obstacles, sourceBounds, targetBounds, routerOpts);
16386
+ const d = buildEdgePath(edge, source, target, obstacles, void 0, void 0, routerOpts);
16428
16387
  const markerEnd = arrows ? "url(#sg-diagram-arrow)" : void 0;
16429
16388
  if (!interactive) {
16430
16389
  return /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
@@ -16950,11 +16909,18 @@ function alignUp(t, step) {
16950
16909
  function clamp2(v, lo, hi) {
16951
16910
  return Math.max(lo, Math.min(hi, v));
16952
16911
  }
16953
- function formatTick(timeMs, scale) {
16912
+ function formatTick(timeMs, scale, columnWidth) {
16954
16913
  const d = new Date(timeMs);
16955
16914
  switch (scale) {
16956
16915
  case "day": {
16957
16916
  const dd = String(d.getUTCDate()).padStart(2, "0");
16917
+ if (columnWidth < 32) {
16918
+ if (d.getUTCDate() === 1) {
16919
+ const mm2 = String(d.getUTCMonth() + 1).padStart(2, "0");
16920
+ return `${dd}.${mm2}`;
16921
+ }
16922
+ return dd;
16923
+ }
16958
16924
  const mm = String(d.getUTCMonth() + 1).padStart(2, "0");
16959
16925
  return `${dd}.${mm}`;
16960
16926
  }
@@ -17034,12 +17000,12 @@ function Gantt({
17034
17000
  for (let t = resolved.rangeStart; t < resolved.rangeEnd; t += resolved.step) {
17035
17001
  out.push({
17036
17002
  x: (t - resolved.rangeStart) * resolved.pxPerMs,
17037
- label: formatTick(t, scale),
17003
+ label: formatTick(t, scale, columnWidth),
17038
17004
  time: t
17039
17005
  });
17040
17006
  }
17041
17007
  return out;
17042
- }, [resolved, scale]);
17008
+ }, [resolved, scale, columnWidth]);
17043
17009
  const taskRects = (0, import_react69.useMemo)(() => {
17044
17010
  return tasks.map((task) => {
17045
17011
  const startMs = toMs(task.start);
@@ -17058,17 +17024,38 @@ function Gantt({
17058
17024
  }, [taskRects]);
17059
17025
  const dependencyPaths = (0, import_react69.useMemo)(() => {
17060
17026
  const out = [];
17027
+ const STUB = 8;
17028
+ const APPROACH = 18;
17061
17029
  for (const r of taskRects) {
17062
17030
  const deps = r.task.dependencies;
17063
17031
  if (!deps || deps.length === 0) continue;
17064
17032
  for (const depId of deps) {
17065
17033
  const src = taskRectById.get(depId);
17066
17034
  if (!src) continue;
17067
- const startPt = [src.x + src.w, src.y + src.h / 2];
17068
- const endPt = [r.x, r.y + r.h / 2];
17069
- const points = (0, import_core10.routeOrthogonal)(startPt, endPt, {
17070
- preferred: "hv"
17071
- });
17035
+ const sx = src.x + src.w;
17036
+ const sy = src.y + src.h / 2;
17037
+ const tx = r.x;
17038
+ const ey = r.y + r.h / 2;
17039
+ let points;
17040
+ if (tx >= sx + STUB + APPROACH) {
17041
+ const bendX = sx + STUB;
17042
+ points = [
17043
+ [sx, sy],
17044
+ [bendX, sy],
17045
+ [bendX, ey],
17046
+ [tx, ey]
17047
+ ];
17048
+ } else {
17049
+ const detourY = src.y + src.h;
17050
+ points = [
17051
+ [sx, sy],
17052
+ [sx + STUB, sy],
17053
+ [sx + STUB, detourY],
17054
+ [tx - APPROACH, detourY],
17055
+ [tx - APPROACH, ey],
17056
+ [tx, ey]
17057
+ ];
17058
+ }
17072
17059
  out.push({ id: `${depId}->${r.task.id}`, d: (0, import_core10.pointsToPath)(points) });
17073
17060
  }
17074
17061
  }
@@ -17135,12 +17122,13 @@ function Gantt({
17135
17122
  const wrapperClass = unstyled ? className : ["sg-gantt", className].filter(Boolean).join(" ");
17136
17123
  const headerHeight = rowHeight;
17137
17124
  const gridHeight = resolved.rows.length * rowHeight;
17138
- const totalHeight = gridHeight + headerHeight;
17125
+ const SCROLLBAR_RESERVE = 14;
17126
+ const totalHeight = gridHeight + headerHeight + SCROLLBAR_RESERVE;
17139
17127
  const wrapperStyle = {
17140
17128
  display: "grid",
17141
- gridTemplateColumns: `${sidebarWidth}px 1fr`,
17129
+ gridTemplateColumns: `${sidebarWidth}px minmax(0, 1fr)`,
17142
17130
  width: "100%",
17143
- overflow: "auto",
17131
+ overflow: "hidden",
17144
17132
  height: totalHeight,
17145
17133
  ...style
17146
17134
  };
@@ -17173,12 +17161,12 @@ function Gantt({
17173
17161
  row.key
17174
17162
  ))
17175
17163
  ] }),
17176
- /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)(
17164
+ /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
17177
17165
  "div",
17178
17166
  {
17179
17167
  className: unstyled ? void 0 : "sg-gantt-main",
17180
- style: { position: "relative", width: resolved.totalWidth, minWidth: "100%" },
17181
- children: [
17168
+ style: { position: "relative", overflowX: "auto", overflowY: "hidden", minWidth: 0 },
17169
+ children: /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)("div", { style: { position: "relative", width: resolved.totalWidth, minWidth: "100%" }, children: [
17182
17170
  /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
17183
17171
  "div",
17184
17172
  {
@@ -17227,44 +17215,6 @@ function Gantt({
17227
17215
  },
17228
17216
  row.key
17229
17217
  )),
17230
- dependencyPaths.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)(
17231
- "svg",
17232
- {
17233
- className: unstyled ? void 0 : "sg-gantt-deps",
17234
- width: resolved.totalWidth,
17235
- height: gridHeight,
17236
- style: { position: "absolute", inset: 0, pointerEvents: "none", overflow: "visible" },
17237
- "aria-hidden": "true",
17238
- children: [
17239
- /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
17240
- "marker",
17241
- {
17242
- id: "sg-gantt-arrow",
17243
- viewBox: "0 0 10 10",
17244
- refX: "8",
17245
- refY: "5",
17246
- markerWidth: "6",
17247
- markerHeight: "6",
17248
- orient: "auto",
17249
- children: /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("path", { d: "M 0 0 L 10 5 L 0 10 z", fill: "currentColor" })
17250
- }
17251
- ) }),
17252
- dependencyPaths.map((p) => /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
17253
- "path",
17254
- {
17255
- d: p.d,
17256
- className: unstyled ? void 0 : "sg-gantt-dep",
17257
- fill: "none",
17258
- stroke: "currentColor",
17259
- strokeWidth: 1.5,
17260
- markerEnd: "url(#sg-gantt-arrow)",
17261
- "data-dep-id": p.id
17262
- },
17263
- p.id
17264
- ))
17265
- ]
17266
- }
17267
- ),
17268
17218
  taskRects.map(({ task, x, y, w, h }) => {
17269
17219
  const barClass = unstyled ? void 0 : [
17270
17220
  "sg-gantt-bar",
@@ -17338,11 +17288,54 @@ function Gantt({
17338
17288
  },
17339
17289
  task.id
17340
17290
  );
17341
- })
17291
+ }),
17292
+ dependencyPaths.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)(
17293
+ "svg",
17294
+ {
17295
+ className: unstyled ? void 0 : "sg-gantt-deps",
17296
+ width: resolved.totalWidth,
17297
+ height: gridHeight,
17298
+ style: {
17299
+ position: "absolute",
17300
+ inset: 0,
17301
+ pointerEvents: "none",
17302
+ overflow: "visible"
17303
+ },
17304
+ "aria-hidden": "true",
17305
+ children: [
17306
+ /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
17307
+ "marker",
17308
+ {
17309
+ id: "sg-gantt-arrow",
17310
+ viewBox: "0 0 10 10",
17311
+ refX: "10",
17312
+ refY: "5",
17313
+ markerWidth: "6",
17314
+ markerHeight: "6",
17315
+ orient: "auto",
17316
+ children: /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("path", { d: "M 0 0 L 10 5 L 0 10 z", fill: "currentColor" })
17317
+ }
17318
+ ) }),
17319
+ dependencyPaths.map((p) => /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
17320
+ "path",
17321
+ {
17322
+ d: p.d,
17323
+ className: unstyled ? void 0 : "sg-gantt-dep",
17324
+ fill: "none",
17325
+ stroke: "currentColor",
17326
+ strokeWidth: 1.5,
17327
+ markerEnd: "url(#sg-gantt-arrow)",
17328
+ "data-dep-id": p.id
17329
+ },
17330
+ p.id
17331
+ ))
17332
+ ]
17333
+ }
17334
+ )
17342
17335
  ]
17343
17336
  }
17344
17337
  )
17345
- ]
17338
+ ] })
17346
17339
  }
17347
17340
  )
17348
17341
  ]
@@ -17388,14 +17381,7 @@ function formatTick2(timeMs, scale) {
17388
17381
  }
17389
17382
  }
17390
17383
  }
17391
- function deriveRange2(assignments, step) {
17392
- if (assignments.length === 0) {
17393
- const now = Date.now();
17394
- return {
17395
- from: new Date(alignDown2(now, step)),
17396
- to: new Date(alignUp2(now + step * 4, step))
17397
- };
17398
- }
17384
+ function resolveRange(assignments, step, range) {
17399
17385
  let lo = Infinity;
17400
17386
  let hi = -Infinity;
17401
17387
  for (const a of assignments) {
@@ -17404,6 +17390,22 @@ function deriveRange2(assignments, step) {
17404
17390
  if (s < lo) lo = s;
17405
17391
  if (e > hi) hi = e;
17406
17392
  }
17393
+ if (range) {
17394
+ const rangeFrom = range.from.getTime();
17395
+ const rangeTo = range.to.getTime();
17396
+ if (assignments.length === 0) return { from: new Date(rangeFrom), to: new Date(rangeTo) };
17397
+ return {
17398
+ from: new Date(alignDown2(Math.min(rangeFrom, lo), step)),
17399
+ to: new Date(alignUp2(Math.max(rangeTo, hi), step))
17400
+ };
17401
+ }
17402
+ if (assignments.length === 0) {
17403
+ const now = Date.now();
17404
+ return {
17405
+ from: new Date(alignDown2(now, step)),
17406
+ to: new Date(alignUp2(now + step * 4, step))
17407
+ };
17408
+ }
17407
17409
  return {
17408
17410
  from: new Date(alignDown2(lo - step, step)),
17409
17411
  to: new Date(alignUp2(hi + step, step))
@@ -17434,7 +17436,7 @@ function ResourceCalendar({
17434
17436
  const [ghost, setGhost] = (0, import_react70.useState)(null);
17435
17437
  const step = STEP_MS2[scale];
17436
17438
  const resolvedRange = (0, import_react70.useMemo)(
17437
- () => range ?? deriveRange2(assignments, step),
17439
+ () => resolveRange(assignments, step, range),
17438
17440
  [range, assignments, step]
17439
17441
  );
17440
17442
  const rangeStart = resolvedRange.from.getTime();
@@ -18053,6 +18055,33 @@ function normalizePadding(p) {
18053
18055
  if (typeof p === "number") return [p, p, p, p];
18054
18056
  return [...p];
18055
18057
  }
18058
+ function defaultYTickFormatter(value) {
18059
+ if (Number.isInteger(value)) return String(value);
18060
+ if (Math.abs(value) >= 1e3) return value.toFixed(0);
18061
+ if (Math.abs(value) >= 1) return value.toFixed(2).replace(/\.?0+$/, "");
18062
+ return value.toFixed(2);
18063
+ }
18064
+ function estimateYAxisLabelWidth(min, max, tickCount, formatter) {
18065
+ const fmt = formatter ?? defaultYTickFormatter;
18066
+ const count = Math.max(2, tickCount ?? 5);
18067
+ let maxLen = 0;
18068
+ for (let i = 0; i < count; i++) {
18069
+ const t = i / (count - 1);
18070
+ const value = min + t * (max - min);
18071
+ const s = fmt(value);
18072
+ if (s.length > maxLen) maxLen = s.length;
18073
+ }
18074
+ return maxLen * 7;
18075
+ }
18076
+ function resolveChartPadding(userPadding, yAxis, yMin, yMax) {
18077
+ const base = normalizePadding(userPadding);
18078
+ if (userPadding !== void 0 || !yAxis) return base;
18079
+ const labelW = estimateYAxisLabelWidth(yMin, yMax, yAxis.tickCount, yAxis.tickFormatter);
18080
+ const need = Math.ceil(labelW + 18);
18081
+ if (need > base[3]) base[3] = need;
18082
+ if (yAxis.label) base[3] += 16;
18083
+ return base;
18084
+ }
18056
18085
  function chartBounds(values) {
18057
18086
  let min = Infinity;
18058
18087
  let max = -Infinity;
@@ -19006,7 +19035,11 @@ function LineChartInner({
19006
19035
  const chartsLocale = useConfig().locale?.charts;
19007
19036
  const { rootRef } = useChartPrint(forwardedRef, printable);
19008
19037
  const svgRef = (0, import_react77.useRef)(null);
19009
- const [pt, pr, pb, pl] = normalizePadding(padding);
19038
+ const { min, max } = (0, import_react77.useMemo)(() => chartBounds(series.map((s) => s.values)), [series]);
19039
+ const [pt, pr, pb, pl] = (0, import_react77.useMemo)(
19040
+ () => resolveChartPadding(padding, yAxis, min, max),
19041
+ [padding, yAxis, min, max]
19042
+ );
19010
19043
  const fallbackW = typeof width === "number" && Number.isFinite(width) ? width : 600;
19011
19044
  const fallbackH = typeof height === "number" && Number.isFinite(height) ? height : 200;
19012
19045
  const measured = useChartSize(svgRef, { width: fallbackW, height: fallbackH });
@@ -19014,7 +19047,6 @@ function LineChartInner({
19014
19047
  const viewH = measured.height;
19015
19048
  const plotW = Math.max(0, viewW - pl - pr);
19016
19049
  const plotH = Math.max(0, viewH - pt - pb);
19017
- const { min, max } = (0, import_react77.useMemo)(() => chartBounds(series.map((s) => s.values)), [series]);
19018
19050
  const range = max - min || 1;
19019
19051
  const xStep = categories.length > 1 ? plotW / (categories.length - 1) : 0;
19020
19052
  function xFor(i) {
@@ -19283,7 +19315,14 @@ function BarChartInner({
19283
19315
  const chartsLocale = useConfig().locale?.charts;
19284
19316
  const { rootRef } = useChartPrint(forwardedRef, printable);
19285
19317
  const svgRef = (0, import_react78.useRef)(null);
19286
- const [pt, pr, pb, pl] = normalizePadding(padding);
19318
+ const { min, max } = (0, import_react78.useMemo)(() => chartBounds(series.map((s) => s.values)), [series]);
19319
+ const baseline = Math.min(0, min);
19320
+ const top = Math.max(0, max);
19321
+ const span = top - baseline || 1;
19322
+ const [pt, pr, pb, pl] = (0, import_react78.useMemo)(
19323
+ () => resolveChartPadding(padding, yAxis, baseline, top),
19324
+ [padding, yAxis, baseline, top]
19325
+ );
19287
19326
  const fallbackW = typeof width === "number" && Number.isFinite(width) ? width : 600;
19288
19327
  const fallbackH = typeof height === "number" && Number.isFinite(height) ? height : 200;
19289
19328
  const measured = useChartSize(svgRef, { width: fallbackW, height: fallbackH });
@@ -19291,10 +19330,6 @@ function BarChartInner({
19291
19330
  const viewH = measured.height;
19292
19331
  const plotW = Math.max(0, viewW - pl - pr);
19293
19332
  const plotH = Math.max(0, viewH - pt - pb);
19294
- const { min, max } = (0, import_react78.useMemo)(() => chartBounds(series.map((s) => s.values)), [series]);
19295
- const baseline = Math.min(0, min);
19296
- const top = Math.max(0, max);
19297
- const span = top - baseline || 1;
19298
19333
  const yZero = pt + top / span * plotH;
19299
19334
  const groupCount = categories.length;
19300
19335
  const groupWidth = groupCount > 0 ? plotW / groupCount : 0;
@@ -19489,14 +19524,6 @@ function AreaChartInner({
19489
19524
  const chartsLocale = useConfig().locale?.charts;
19490
19525
  const { rootRef } = useChartPrint(forwardedRef, printable);
19491
19526
  const svgRef = (0, import_react79.useRef)(null);
19492
- const [pt, pr, pb, pl] = normalizePadding(padding);
19493
- const fallbackW = typeof width === "number" && Number.isFinite(width) ? width : 600;
19494
- const fallbackH = typeof height === "number" && Number.isFinite(height) ? height : 200;
19495
- const measured = useChartSize(svgRef, { width: fallbackW, height: fallbackH });
19496
- const viewW = measured.width;
19497
- const viewH = measured.height;
19498
- const plotW = Math.max(0, viewW - pl - pr);
19499
- const plotH = Math.max(0, viewH - pt - pb);
19500
19527
  const stackedValues = (0, import_react79.useMemo)(() => {
19501
19528
  if (!stacked) return series.map((s) => [...s.values]);
19502
19529
  const totals = new Array(categories.length).fill(0);
@@ -19517,6 +19544,17 @@ function AreaChartInner({
19517
19544
  const baseline = Math.min(0, min);
19518
19545
  const top = Math.max(0, max);
19519
19546
  const span = top - baseline || 1;
19547
+ const [pt, pr, pb, pl] = (0, import_react79.useMemo)(
19548
+ () => resolveChartPadding(padding, yAxis, baseline, top),
19549
+ [padding, yAxis, baseline, top]
19550
+ );
19551
+ const fallbackW = typeof width === "number" && Number.isFinite(width) ? width : 600;
19552
+ const fallbackH = typeof height === "number" && Number.isFinite(height) ? height : 200;
19553
+ const measured = useChartSize(svgRef, { width: fallbackW, height: fallbackH });
19554
+ const viewW = measured.width;
19555
+ const viewH = measured.height;
19556
+ const plotW = Math.max(0, viewW - pl - pr);
19557
+ const plotH = Math.max(0, viewH - pt - pb);
19520
19558
  const xStep = categories.length > 1 ? plotW / (categories.length - 1) : 0;
19521
19559
  function xFor(i) {
19522
19560
  return pl + i * xStep;
@@ -20812,10 +20850,20 @@ function ListInner({
20812
20850
  setDragIndex(null);
20813
20851
  setDropIndex(null);
20814
20852
  }, []);
20853
+ const scrollRafRef = import_react83.default.useRef(null);
20815
20854
  const handleVirtualScroll = import_react83.default.useCallback(() => {
20816
- if (virtualRef.current) {
20817
- setScrollTop(virtualRef.current.scrollTop);
20818
- }
20855
+ if (scrollRafRef.current != null) return;
20856
+ scrollRafRef.current = requestAnimationFrame(() => {
20857
+ scrollRafRef.current = null;
20858
+ if (virtualRef.current) {
20859
+ setScrollTop(virtualRef.current.scrollTop);
20860
+ }
20861
+ });
20862
+ }, []);
20863
+ import_react83.default.useEffect(() => {
20864
+ return () => {
20865
+ if (scrollRafRef.current != null) cancelAnimationFrame(scrollRafRef.current);
20866
+ };
20819
20867
  }, []);
20820
20868
  const emptyText = locale?.emptyText ?? "No Data";
20821
20869
  const gridStyle = import_react83.default.useMemo(() => {