@railtownai/railtracks-visualizer 0.0.37 → 0.0.39

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/cjs/index.js CHANGED
@@ -6006,7 +6006,7 @@ function createPanZoomEndHandler({ zoomPanValues, panOnDrag, panOnScroll, onDrag
6006
6006
  return (!event.ctrlKey || isWheelEvent) && buttonAllowed;
6007
6007
  };
6008
6008
  }
6009
- function XYPanZoom({ domNode, minZoom, maxZoom, paneClickDistance, translateExtent, viewport, onPanZoom, onPanZoomStart, onPanZoomEnd, onDraggingChange }) {
6009
+ function XYPanZoom({ domNode, minZoom, maxZoom, translateExtent, viewport, onPanZoom, onPanZoomStart, onPanZoomEnd, onDraggingChange }) {
6010
6010
  const zoomPanValues = {
6011
6011
  isZoomingOrPanning: false,
6012
6012
  usedRightMouseButton: false,
@@ -6018,7 +6018,7 @@ function XYPanZoom({ domNode, minZoom, maxZoom, paneClickDistance, translateExte
6018
6018
  isPanScrolling: false
6019
6019
  };
6020
6020
  const bbox = domNode.getBoundingClientRect();
6021
- const d3ZoomInstance = zoom().clickDistance(!isNumeric(paneClickDistance) || paneClickDistance < 0 ? 0 : paneClickDistance).scaleExtent([
6021
+ const d3ZoomInstance = zoom().scaleExtent([
6022
6022
  minZoom,
6023
6023
  maxZoom
6024
6024
  ]).translateExtent(translateExtent);
@@ -6049,11 +6049,12 @@ function XYPanZoom({ domNode, minZoom, maxZoom, paneClickDistance, translateExte
6049
6049
  return Promise.resolve(false);
6050
6050
  }
6051
6051
  // public functions
6052
- function update({ noWheelClassName, noPanClassName, onPaneContextMenu, userSelectionActive, panOnScroll, panOnDrag, panOnScrollMode, panOnScrollSpeed, preventScrolling, zoomOnPinch, zoomOnScroll, zoomOnDoubleClick, zoomActivationKeyPressed, lib, onTransformChange, connectionInProgress }) {
6052
+ function update({ noWheelClassName, noPanClassName, onPaneContextMenu, userSelectionActive, panOnScroll, panOnDrag, panOnScrollMode, panOnScrollSpeed, preventScrolling, zoomOnPinch, zoomOnScroll, zoomOnDoubleClick, zoomActivationKeyPressed, lib, onTransformChange, connectionInProgress, paneClickDistance, selectionOnDrag }) {
6053
6053
  if (userSelectionActive && !zoomPanValues.isZoomingOrPanning) {
6054
6054
  destroy();
6055
6055
  }
6056
6056
  const isPanOnScroll = panOnScroll && !zoomActivationKeyPressed && !userSelectionActive;
6057
+ d3ZoomInstance.clickDistance(selectionOnDrag ? Infinity : !isNumeric(paneClickDistance) || paneClickDistance < 0 ? 0 : paneClickDistance);
6057
6058
  const wheelHandler = isPanOnScroll ? createPanOnScrollHandler({
6058
6059
  zoomPanValues,
6059
6060
  noWheelClassName,
@@ -7335,7 +7336,6 @@ const reactFlowFieldsToTrack = [
7335
7336
  'onBeforeDelete',
7336
7337
  'debug',
7337
7338
  'autoPanSpeed',
7338
- 'paneClickDistance',
7339
7339
  'ariaLabelConfig'
7340
7340
  ];
7341
7341
  // rfId doesn't exist in ReactFlowProps, but it's one of the fields we want to update
@@ -7351,8 +7351,7 @@ const selector$l = (s)=>({
7351
7351
  setTranslateExtent: s.setTranslateExtent,
7352
7352
  setNodeExtent: s.setNodeExtent,
7353
7353
  reset: s.reset,
7354
- setDefaultNodesAndEdges: s.setDefaultNodesAndEdges,
7355
- setPaneClickDistance: s.setPaneClickDistance
7354
+ setDefaultNodesAndEdges: s.setDefaultNodesAndEdges
7356
7355
  });
7357
7356
  const initPrevValues = {
7358
7357
  /*
@@ -7365,11 +7364,10 @@ const initPrevValues = {
7365
7364
  maxZoom: 2,
7366
7365
  elementsSelectable: true,
7367
7366
  noPanClassName: 'nopan',
7368
- rfId: '1',
7369
- paneClickDistance: 0
7367
+ rfId: '1'
7370
7368
  };
7371
7369
  function StoreUpdater(props) {
7372
- const { setNodes, setEdges, setMinZoom, setMaxZoom, setTranslateExtent, setNodeExtent, reset, setDefaultNodesAndEdges, setPaneClickDistance } = useStore(selector$l, shallow$1);
7370
+ const { setNodes, setEdges, setMinZoom, setMaxZoom, setTranslateExtent, setNodeExtent, reset, setDefaultNodesAndEdges } = useStore(selector$l, shallow$1);
7373
7371
  const store = useStoreApi();
7374
7372
  React.useEffect(()=>{
7375
7373
  setDefaultNodesAndEdges(props.defaultNodes, props.defaultEdges);
@@ -7393,7 +7391,6 @@ function StoreUpdater(props) {
7393
7391
  else if (fieldName === 'maxZoom') setMaxZoom(fieldValue);
7394
7392
  else if (fieldName === 'translateExtent') setTranslateExtent(fieldValue);
7395
7393
  else if (fieldName === 'nodeExtent') setNodeExtent(fieldValue);
7396
- else if (fieldName === 'paneClickDistance') setPaneClickDistance(fieldValue);
7397
7394
  else if (fieldName === 'ariaLabelConfig') store.setState({
7398
7395
  ariaLabelConfig: mergeAriaLabelConfig(fieldValue)
7399
7396
  });
@@ -8455,7 +8452,7 @@ const selector$j = (s)=>({
8455
8452
  lib: s.lib,
8456
8453
  connectionInProgress: s.connection.inProgress
8457
8454
  });
8458
- function ZoomPane({ onPaneContextMenu, zoomOnScroll = true, zoomOnPinch = true, panOnScroll = false, panOnScrollSpeed = 0.5, panOnScrollMode = PanOnScrollMode.Free, zoomOnDoubleClick = true, panOnDrag = true, defaultViewport, translateExtent, minZoom, maxZoom, zoomActivationKeyCode, preventScrolling = true, children, noWheelClassName, noPanClassName, onViewportChange, isControlledViewport, paneClickDistance }) {
8455
+ function ZoomPane({ onPaneContextMenu, zoomOnScroll = true, zoomOnPinch = true, panOnScroll = false, panOnScrollSpeed = 0.5, panOnScrollMode = PanOnScrollMode.Free, zoomOnDoubleClick = true, panOnDrag = true, defaultViewport, translateExtent, minZoom, maxZoom, zoomActivationKeyCode, preventScrolling = true, children, noWheelClassName, noPanClassName, onViewportChange, isControlledViewport, paneClickDistance, selectionOnDrag }) {
8459
8456
  const store = useStoreApi();
8460
8457
  const zoomPane = React.useRef(null);
8461
8458
  const { userSelectionActive, lib, connectionInProgress } = useStore(selector$j, shallow$1);
@@ -8485,7 +8482,6 @@ function ZoomPane({ onPaneContextMenu, zoomOnScroll = true, zoomOnPinch = true,
8485
8482
  maxZoom,
8486
8483
  translateExtent,
8487
8484
  viewport: defaultViewport,
8488
- paneClickDistance,
8489
8485
  onDraggingChange: (paneDragging)=>store.setState({
8490
8486
  paneDragging
8491
8487
  }),
@@ -8537,7 +8533,9 @@ function ZoomPane({ onPaneContextMenu, zoomOnScroll = true, zoomOnPinch = true,
8537
8533
  noWheelClassName,
8538
8534
  lib,
8539
8535
  onTransformChange,
8540
- connectionInProgress
8536
+ connectionInProgress,
8537
+ selectionOnDrag,
8538
+ paneClickDistance
8541
8539
  });
8542
8540
  }, [
8543
8541
  onPaneContextMenu,
@@ -8555,7 +8553,9 @@ function ZoomPane({ onPaneContextMenu, zoomOnScroll = true, zoomOnPinch = true,
8555
8553
  noWheelClassName,
8556
8554
  lib,
8557
8555
  onTransformChange,
8558
- connectionInProgress
8556
+ connectionInProgress,
8557
+ selectionOnDrag,
8558
+ paneClickDistance
8559
8559
  ]);
8560
8560
  return jsxRuntime.jsx("div", {
8561
8561
  className: "react-flow__renderer",
@@ -8597,17 +8597,16 @@ const selector$h = (s)=>({
8597
8597
  connectionInProgress: s.connection.inProgress,
8598
8598
  dragging: s.paneDragging
8599
8599
  });
8600
- function Pane({ isSelecting, selectionKeyPressed, selectionMode = SelectionMode.Full, panOnDrag, selectionOnDrag, onSelectionStart, onSelectionEnd, onPaneClick, onPaneContextMenu, onPaneScroll, onPaneMouseEnter, onPaneMouseMove, onPaneMouseLeave, children }) {
8600
+ function Pane({ isSelecting, selectionKeyPressed, selectionMode = SelectionMode.Full, panOnDrag, paneClickDistance, selectionOnDrag, onSelectionStart, onSelectionEnd, onPaneClick, onPaneContextMenu, onPaneScroll, onPaneMouseEnter, onPaneMouseMove, onPaneMouseLeave, children }) {
8601
8601
  const store = useStoreApi();
8602
8602
  const { userSelectionActive, elementsSelectable, dragging, connectionInProgress } = useStore(selector$h, shallow$1);
8603
- const hasActiveSelection = elementsSelectable && (isSelecting || userSelectionActive);
8603
+ const isSelectionEnabled = elementsSelectable && (isSelecting || userSelectionActive);
8604
8604
  const container = React.useRef(null);
8605
8605
  const containerBounds = React.useRef();
8606
8606
  const selectedNodeIds = React.useRef(new Set());
8607
8607
  const selectedEdgeIds = React.useRef(new Set());
8608
8608
  // Used to prevent click events when the user lets go of the selectionKey during a selection
8609
8609
  const selectionInProgress = React.useRef(false);
8610
- const selectionStarted = React.useRef(false);
8611
8610
  const onClick = (event)=>{
8612
8611
  // We prevent click events when the user let go of the selectionKey during a selection
8613
8612
  // We also prevent click events when a connection is in progress
@@ -8630,29 +8629,27 @@ function Pane({ isSelecting, selectionKeyPressed, selectionMode = SelectionMode.
8630
8629
  };
8631
8630
  const onWheel = onPaneScroll ? (event)=>onPaneScroll(event) : undefined;
8632
8631
  const onClickCapture = (event)=>{
8633
- const isSelectionOnDragActive = selectionOnDrag && container.current === event.target || !selectionOnDrag || selectionKeyPressed;
8634
- if (!isSelectionOnDragActive) {
8635
- return;
8632
+ if (selectionInProgress.current) {
8633
+ event.stopPropagation();
8634
+ selectionInProgress.current = false;
8636
8635
  }
8637
- event.stopPropagation();
8638
8636
  };
8639
8637
  // We are using capture here in order to prevent other pointer events
8640
8638
  // to be able to create a selection above a node or an edge
8641
8639
  const onPointerDownCapture = (event)=>{
8642
- const { resetSelectedElements, domNode } = store.getState();
8640
+ const { domNode } = store.getState();
8643
8641
  containerBounds.current = domNode?.getBoundingClientRect();
8644
- const isNoKeyEvent = event.target !== container.current && !!event.target.closest('.nokey');
8645
- const isSelectionActive = selectionOnDrag && container.current === event.target || !selectionOnDrag || selectionKeyPressed;
8646
- if (!elementsSelectable || !isSelecting || event.button !== 0 || !containerBounds.current || isNoKeyEvent || !isSelectionActive || !event.isPrimary) {
8642
+ if (!containerBounds.current) return;
8643
+ const eventTargetIsContainer = event.target === container.current;
8644
+ // if a child element has the 'nokey' class, we don't want to swallow the event and don't start a selection
8645
+ const isNoKeyEvent = !eventTargetIsContainer && !!event.target.closest('.nokey');
8646
+ const isSelectionActive = selectionOnDrag && eventTargetIsContainer || selectionKeyPressed;
8647
+ if (isNoKeyEvent || !isSelecting || !isSelectionActive || event.button !== 0 || !event.isPrimary) {
8647
8648
  return;
8648
8649
  }
8649
- event.stopPropagation();
8650
- event.preventDefault();
8651
8650
  event.target?.setPointerCapture?.(event.pointerId);
8652
- selectionStarted.current = true;
8653
8651
  selectionInProgress.current = false;
8654
8652
  const { x, y } = getEventPosition(event.nativeEvent, containerBounds.current);
8655
- resetSelectedElements();
8656
8653
  store.setState({
8657
8654
  userSelectionRect: {
8658
8655
  width: 0,
@@ -8663,16 +8660,28 @@ function Pane({ isSelecting, selectionKeyPressed, selectionMode = SelectionMode.
8663
8660
  y
8664
8661
  }
8665
8662
  });
8666
- onSelectionStart?.(event);
8663
+ if (!eventTargetIsContainer) {
8664
+ event.stopPropagation();
8665
+ event.preventDefault();
8666
+ }
8667
8667
  };
8668
8668
  const onPointerMove = (event)=>{
8669
- const { userSelectionRect, transform, nodeLookup, edgeLookup, connectionLookup, triggerNodeChanges, triggerEdgeChanges, defaultEdgeOptions } = store.getState();
8669
+ const { userSelectionRect, transform, nodeLookup, edgeLookup, connectionLookup, triggerNodeChanges, triggerEdgeChanges, defaultEdgeOptions, resetSelectedElements } = store.getState();
8670
8670
  if (!containerBounds.current || !userSelectionRect) {
8671
8671
  return;
8672
8672
  }
8673
- selectionInProgress.current = true;
8674
8673
  const { x: mouseX, y: mouseY } = getEventPosition(event.nativeEvent, containerBounds.current);
8675
8674
  const { startX, startY } = userSelectionRect;
8675
+ if (!selectionInProgress.current) {
8676
+ const requiredDistance = selectionKeyPressed ? 0 : paneClickDistance;
8677
+ const distance = Math.hypot(mouseX - startX, mouseY - startY);
8678
+ if (distance <= requiredDistance) {
8679
+ return;
8680
+ }
8681
+ resetSelectedElements();
8682
+ onSelectionStart?.(event);
8683
+ }
8684
+ selectionInProgress.current = true;
8676
8685
  const nextUserSelectRect = {
8677
8686
  startX,
8678
8687
  startY,
@@ -8712,30 +8721,26 @@ function Pane({ isSelecting, selectionKeyPressed, selectionMode = SelectionMode.
8712
8721
  });
8713
8722
  };
8714
8723
  const onPointerUp = (event)=>{
8715
- if (event.button !== 0 || !selectionStarted.current) {
8724
+ if (event.button !== 0) {
8716
8725
  return;
8717
8726
  }
8718
8727
  event.target?.releasePointerCapture?.(event.pointerId);
8719
- const { userSelectionRect } = store.getState();
8720
8728
  /*
8721
8729
  * We only want to trigger click functions when in selection mode if
8722
8730
  * the user did not move the mouse.
8723
- */ if (!userSelectionActive && userSelectionRect && event.target === container.current) {
8731
+ */ if (!userSelectionActive && event.target === container.current && store.getState().userSelectionRect) {
8724
8732
  onClick?.(event);
8725
8733
  }
8726
8734
  store.setState({
8727
8735
  userSelectionActive: false,
8728
- userSelectionRect: null,
8729
- nodesSelectionActive: selectedNodeIds.current.size > 0
8736
+ userSelectionRect: null
8730
8737
  });
8731
- onSelectionEnd?.(event);
8732
- /*
8733
- * If the user kept holding the selectionKey during the selection,
8734
- * we need to reset the selectionInProgress, so the next click event is not prevented
8735
- */ if (selectionKeyPressed || selectionOnDrag) {
8736
- selectionInProgress.current = false;
8738
+ if (selectionInProgress.current) {
8739
+ onSelectionEnd?.(event);
8740
+ store.setState({
8741
+ nodesSelectionActive: selectedNodeIds.current.size > 0
8742
+ });
8737
8743
  }
8738
- selectionStarted.current = false;
8739
8744
  };
8740
8745
  const draggable = panOnDrag === true || Array.isArray(panOnDrag) && panOnDrag.includes(0);
8741
8746
  return jsxRuntime.jsxs("div", {
@@ -8747,14 +8752,14 @@ function Pane({ isSelecting, selectionKeyPressed, selectionMode = SelectionMode.
8747
8752
  selection: isSelecting
8748
8753
  }
8749
8754
  ]),
8750
- onClick: hasActiveSelection ? undefined : wrapHandler(onClick, container),
8755
+ onClick: isSelectionEnabled ? undefined : wrapHandler(onClick, container),
8751
8756
  onContextMenu: wrapHandler(onContextMenu, container),
8752
8757
  onWheel: wrapHandler(onWheel, container),
8753
- onPointerEnter: hasActiveSelection ? undefined : onPaneMouseEnter,
8754
- onPointerMove: hasActiveSelection ? onPointerMove : onPaneMouseMove,
8755
- onPointerUp: hasActiveSelection ? onPointerUp : undefined,
8756
- onPointerDownCapture: hasActiveSelection ? onPointerDownCapture : undefined,
8757
- onClickCapture: hasActiveSelection ? onClickCapture : undefined,
8758
+ onPointerEnter: isSelectionEnabled ? undefined : onPaneMouseEnter,
8759
+ onPointerMove: isSelectionEnabled ? onPointerMove : onPaneMouseMove,
8760
+ onPointerUp: isSelectionEnabled ? onPointerUp : undefined,
8761
+ onPointerDownCapture: isSelectionEnabled ? onPointerDownCapture : undefined,
8762
+ onClickCapture: isSelectionEnabled ? onClickCapture : undefined,
8758
8763
  onPointerLeave: onPaneMouseLeave,
8759
8764
  ref: container,
8760
8765
  style: containerStyle,
@@ -9304,6 +9309,7 @@ function FlowRendererComponent({ children, onPaneClick, onPaneMouseEnter, onPane
9304
9309
  onViewportChange: onViewportChange,
9305
9310
  isControlledViewport: isControlledViewport,
9306
9311
  paneClickDistance: paneClickDistance,
9312
+ selectionOnDrag: _selectionOnDrag,
9307
9313
  children: jsxRuntime.jsxs(Pane, {
9308
9314
  onSelectionStart: onSelectionStart,
9309
9315
  onSelectionEnd: onSelectionEnd,
@@ -9317,6 +9323,7 @@ function FlowRendererComponent({ children, onPaneClick, onPaneMouseEnter, onPane
9317
9323
  isSelecting: !!isSelecting,
9318
9324
  selectionMode: selectionMode,
9319
9325
  selectionKeyPressed: selectionKeyPressed,
9326
+ paneClickDistance: paneClickDistance,
9320
9327
  selectionOnDrag: _selectionOnDrag,
9321
9328
  children: [
9322
9329
  children,
@@ -11399,9 +11406,6 @@ const createStore = ({ nodes, edges, defaultNodes, defaultEdges, width, height,
11399
11406
  translateExtent
11400
11407
  });
11401
11408
  },
11402
- setPaneClickDistance: (clickDistance)=>{
11403
- get().panZoom?.setClickDistance(clickDistance);
11404
- },
11405
11409
  resetSelectedElements: ()=>{
11406
11410
  const { edges, nodes, triggerNodeChanges, triggerEdgeChanges, elementsSelectable } = get();
11407
11411
  if (!elementsSelectable) {
@@ -11730,7 +11734,6 @@ function ReactFlow({ nodes, edges, defaultNodes, defaultEdges, className, nodeTy
11730
11734
  nodeDragThreshold: nodeDragThreshold,
11731
11735
  connectionDragThreshold: connectionDragThreshold,
11732
11736
  onBeforeDelete: onBeforeDelete,
11733
- paneClickDistance: paneClickDistance,
11734
11737
  debug: debug,
11735
11738
  ariaLabelConfig: ariaLabelConfig
11736
11739
  }),
@@ -12696,7 +12699,7 @@ var css_248z = "/* this gets exported as style.css and can be used for the defau
12696
12699
  styleInject(css_248z);
12697
12700
 
12698
12701
  /**
12699
- * @license lucide-react v0.546.0 - ISC
12702
+ * @license lucide-react v0.553.0 - ISC
12700
12703
  *
12701
12704
  * This source code is licensed under the ISC license.
12702
12705
  * See the LICENSE file in the root directory of this source tree.
@@ -12718,7 +12721,7 @@ const hasA11yProp = (props)=>{
12718
12721
  };
12719
12722
 
12720
12723
  /**
12721
- * @license lucide-react v0.546.0 - ISC
12724
+ * @license lucide-react v0.553.0 - ISC
12722
12725
  *
12723
12726
  * This source code is licensed under the ISC license.
12724
12727
  * See the LICENSE file in the root directory of this source tree.
@@ -14485,24 +14488,16 @@ const Edge = ({ id, sourceX, sourceY, targetX, targetY, sourcePosition, targetPo
14485
14488
  const [isHovered, setIsHovered] = React.useState(false);
14486
14489
  const { theme } = useTheme();
14487
14490
  const themeColors = theme.colors;
14488
- // Function to determine stroke color based on edge state and theme
14491
+ // Function to determine stroke color based on edge status and theme
14489
14492
  const getStrokeColor = ()=>{
14490
- const state = data?.details?.state;
14491
14493
  const status = data?.details?.status;
14492
- const output = data?.details?.output;
14494
+ data?.details?.output;
14493
14495
  // Check for error indicators
14494
- const hasError = state === "Error" || status === "Error" || typeof output === "string" && output.includes("ERROR:");
14496
+ const hasError = status === "Failed";
14495
14497
  if (hasError) {
14496
14498
  return themeColors.destructive;
14497
14499
  }
14498
- switch(state){
14499
- case "Open":
14500
- return themeColors.mutedForeground;
14501
- case "Completed":
14502
- return themeColors.mutedForeground;
14503
- default:
14504
- return themeColors.mutedForeground;
14505
- }
14500
+ return themeColors.mutedForeground;
14506
14501
  };
14507
14502
  const [edgePath] = React.useMemo(()=>{
14508
14503
  return getSmoothStepPath({
@@ -15801,6 +15796,8 @@ const Label$1 = styled.span`
15801
15796
  `;
15802
15797
  const Value$1 = styled.span`
15803
15798
  font-size: 0.75rem;
15799
+ overflow-wrap: break-word;
15800
+ word-wrap: break-word;
15804
15801
  color: ${(props)=>props.themeColors.primary};
15805
15802
  `;
15806
15803
  const EmptyIndicator = styled.span`
@@ -15820,8 +15817,8 @@ const TreeContainer = styled.div`
15820
15817
  `;
15821
15818
  const TreeScrollContainer = styled.div`
15822
15819
  width: 100%;
15823
- max-height: 16rem;
15824
15820
  overflow-y: auto;
15821
+ max-height: 16rem;
15825
15822
  padding: 0.5rem;
15826
15823
  `;
15827
15824
  const NoDataMessage = styled.div`
@@ -15842,7 +15839,8 @@ const SimpleValueContainer = styled.div`
15842
15839
  border: 1px solid ${(props)=>props.themeColors.border};
15843
15840
  font-size: 0.75rem;
15844
15841
  color: ${(props)=>props.themeColors.foreground};
15845
- word-break: break-all;
15842
+ overflow-wrap: break-word;
15843
+ word-wrap: break-word;
15846
15844
  `;
15847
15845
  styled.div`
15848
15846
  width: 100%;
@@ -15862,6 +15860,8 @@ const SimpleValueLabel = styled.span`
15862
15860
  `;
15863
15861
  const SimpleValueText = styled.span`
15864
15862
  color: ${(props)=>props.themeColors.foreground};
15863
+ word-wrap: break-word;
15864
+ overflow-wrap: break-word;
15865
15865
  font-size: 0.875rem;
15866
15866
  `;
15867
15867
  const EmptyStateContainer = styled.div`
@@ -16031,6 +16031,8 @@ const JsonTreeViewer = ({ data, maxDepth = 4, initialExpanded = false, expanded
16031
16031
  })()));
16032
16032
  };
16033
16033
 
16034
+ const NODE_MAX_WIDTH = 500;
16035
+
16034
16036
  const OutputRenderer = ({ data })=>{
16035
16037
  const [isExpanded, setIsExpanded] = React.useState(false);
16036
16038
  const contentType = detectContentType(data);
@@ -16039,20 +16041,26 @@ const OutputRenderer = ({ data })=>{
16039
16041
  };
16040
16042
  switch(contentType){
16041
16043
  case "string":
16042
- return /*#__PURE__*/ React.createElement(OutputScrollableContent, null, /*#__PURE__*/ React.createElement(ExpandableTextarea, {
16044
+ return /*#__PURE__*/ React.createElement(OutputScrollableContent, {
16045
+ className: "agent-node-scrollable"
16046
+ }, /*#__PURE__*/ React.createElement(ExpandableTextarea, {
16043
16047
  label: "Output",
16044
16048
  content: data.content,
16045
16049
  isExpanded: isExpanded,
16046
16050
  onToggle: handleToggle
16047
16051
  }));
16048
16052
  case "toolResponse":
16049
- return /*#__PURE__*/ React.createElement(OutputScrollableContent, null, /*#__PURE__*/ React.createElement(NodeSubHeader, null, "Output - Tool Response"), /*#__PURE__*/ React.createElement(JsonTreeViewer, {
16053
+ return /*#__PURE__*/ React.createElement(OutputScrollableContent, {
16054
+ className: "agent-node-scrollable"
16055
+ }, /*#__PURE__*/ React.createElement(NodeSubHeader, null, "Output - Tool Response"), /*#__PURE__*/ React.createElement(JsonTreeViewer, {
16050
16056
  data: data,
16051
16057
  expanded: true
16052
16058
  }));
16053
16059
  case "toolCallList":
16054
16060
  const formattedCode = formatToolCalls(data.content);
16055
- return /*#__PURE__*/ React.createElement(React.Fragment, null, /*#__PURE__*/ React.createElement(OutputScrollableContent, null, /*#__PURE__*/ React.createElement(NodeSubHeader, null, /*#__PURE__*/ React.createElement("span", null, "Output - Tool Calls"), /*#__PURE__*/ React.createElement("span", {
16061
+ return /*#__PURE__*/ React.createElement(React.Fragment, null, /*#__PURE__*/ React.createElement(OutputScrollableContent, {
16062
+ className: "agent-node-scrollable"
16063
+ }, /*#__PURE__*/ React.createElement(NodeSubHeader, null, /*#__PURE__*/ React.createElement("span", null, "Output - Tool Calls"), /*#__PURE__*/ React.createElement("span", {
16056
16064
  style: {
16057
16065
  display: "flex",
16058
16066
  alignItems: "center",
@@ -16067,7 +16075,7 @@ const OutputRenderer = ({ data })=>{
16067
16075
  })));
16068
16076
  case "other":
16069
16077
  default:
16070
- return /*#__PURE__*/ React.createElement(React.Fragment, null, /*#__PURE__*/ React.createElement(OutputScrollableContent, null, /*#__PURE__*/ React.createElement(NodeSubHeader, null, "Output"), /*#__PURE__*/ React.createElement(JsonTreeViewer, {
16078
+ return /*#__PURE__*/ React.createElement(React.Fragment, null, /*#__PURE__*/ React.createElement(OutputScrollableContent, null, /*#__PURE__*/ React.createElement(NodeSubHeader, null, "Output - JSON"), /*#__PURE__*/ React.createElement(JsonTreeViewer, {
16071
16079
  data: data,
16072
16080
  expanded: true
16073
16081
  })));
@@ -16090,12 +16098,13 @@ const NodeSubHeader = styled.span`
16090
16098
  `;
16091
16099
  const OutputScrollableContent = styled.div`
16092
16100
  width: 100%;
16101
+ max-width: ${NODE_MAX_WIDTH}px;
16093
16102
  display: flex;
16094
16103
  flex-direction: column;
16104
+ align-items: stretch;
16095
16105
  padding-bottom: 0.5rem;
16106
+ padding-right: 2px;
16096
16107
  gap: 0.5rem;
16097
- max-height: 200px;
16098
- overflow-y: auto;
16099
16108
  `;
16100
16109
 
16101
16110
  function _objectWithoutPropertiesLoose(r, e) {
@@ -16407,7 +16416,9 @@ const InputArrayRenderer = ({ input })=>{
16407
16416
  }
16408
16417
  }, /*#__PURE__*/ React.createElement(MessageSquare, {
16409
16418
  size: 12
16410
- }), input.length)), /*#__PURE__*/ React.createElement(InputArrayScrollableContent, null, input.map((item, index)=>/*#__PURE__*/ React.createElement(InputItem, {
16419
+ }), input.length)), /*#__PURE__*/ React.createElement(InputArrayScrollableContent, {
16420
+ className: "agent-node-scrollable"
16421
+ }, input.map((item, index)=>/*#__PURE__*/ React.createElement(InputItem, {
16411
16422
  key: index
16412
16423
  }, /*#__PURE__*/ React.createElement(InputItemHeader, null, /*#__PURE__*/ React.createElement(InputItemLabel, null, getRoleEmoji(item.role), " ", getRoleDisplayName(item.role))), /*#__PURE__*/ React.createElement(InputItemTextarea, {
16413
16424
  onClick: (e)=>{
@@ -16419,7 +16430,8 @@ const InputArrayRenderer = ({ input })=>{
16419
16430
  border: `1px solid ${themeColors.border}`,
16420
16431
  backgroundColor: themeColors.muted,
16421
16432
  color: themeColors.foreground
16422
- }
16433
+ },
16434
+ className: "agent-node-scrollable"
16423
16435
  })))));
16424
16436
  };
16425
16437
  // Styled components
@@ -16434,6 +16446,7 @@ const InputArrayScrollableContent = styled.div`
16434
16446
  display: flex;
16435
16447
  flex-direction: column;
16436
16448
  padding-bottom: 0.5rem;
16449
+ padding-right: 2px;
16437
16450
  gap: 0.5rem;
16438
16451
  max-height: 200px;
16439
16452
  overflow-y: auto;
@@ -16563,12 +16576,7 @@ const getNodeIcon$1 = (nodeType, modelProvider)=>{
16563
16576
  }
16564
16577
  return "🤖";
16565
16578
  };
16566
- const NodeDetailsPopover = ({ isVisible, onClose, nodeData, triggerRef })=>{
16567
- const [position, setPosition] = React.useState({
16568
- top: 0,
16569
- left: 0,
16570
- arrowPosition: "right"
16571
- });
16579
+ const NodeDetailsPopover = ({ isVisible, onClose, nodeData })=>{
16572
16580
  const [selectedRowIndex, setSelectedRowIndex] = React.useState(null);
16573
16581
  const [selectedLlmDetails, setSelectedLlmDetails] = React.useState(null);
16574
16582
  // Default to last row (total/aggregate) when popover opens (only on first open)
@@ -16593,54 +16601,6 @@ const NodeDetailsPopover = ({ isVisible, onClose, nodeData, triggerRef })=>{
16593
16601
  setSelectedLlmDetails(nodeData.details.internals.llm_details[nodeData.details.internals.llm_details.length]);
16594
16602
  }
16595
16603
  };
16596
- // Calculate popover position based on trigger element
16597
- React.useEffect(()=>{
16598
- if (isVisible && triggerRef.current) {
16599
- const rect = triggerRef.current.getBoundingClientRect();
16600
- const viewportWidth = window.innerWidth;
16601
- const viewportHeight = window.innerHeight;
16602
- const popoverWidth = DEFAULT_POPOVER_WIDTH; // Match the width from styled component
16603
- const popoverHeight = DEFAULT_POPOVER_HEIGHT; // Approximate max height
16604
- const gap = 12; // Gap between node and popover
16605
- // Check if the rect is valid (has non-zero dimensions and is in viewport)
16606
- const isValidRect = rect.width > 0 && rect.height > 0 && rect.top >= 0 && rect.left >= 0;
16607
- if (isValidRect) {
16608
- // Normal positioning logic for ReactFlow
16609
- let left = rect.right + gap;
16610
- let top = rect.top;
16611
- let arrowPosition = "right"; // Arrow points right (popover is to the right)
16612
- // If popover would go off-screen, position it to the left of the node
16613
- if (left + popoverWidth > viewportWidth) {
16614
- left = rect.left - popoverWidth - gap;
16615
- arrowPosition = "left"; // Arrow points left (popover is to the left)
16616
- }
16617
- // Ensure popover doesn't go off the top or bottom of the viewport
16618
- if (top < 0) {
16619
- top = 20; // Small margin from top
16620
- } else if (top + popoverHeight > viewportHeight) {
16621
- top = viewportHeight - popoverHeight - 20; // Small margin from bottom
16622
- }
16623
- setPosition({
16624
- top,
16625
- left,
16626
- arrowPosition
16627
- });
16628
- } else {
16629
- // Fallback positioning for isolated environments (like Storybook)
16630
- // Center the popover in the viewport
16631
- const centerLeft = Math.max(20, (viewportWidth - popoverWidth) / 2);
16632
- const centerTop = Math.max(20, (viewportHeight - popoverHeight) / 2);
16633
- setPosition({
16634
- top: centerTop,
16635
- left: centerLeft,
16636
- arrowPosition: "none" // No arrow in fallback mode
16637
- });
16638
- }
16639
- }
16640
- }, [
16641
- isVisible,
16642
- triggerRef
16643
- ]);
16644
16604
  // Handle ESC key to close popover
16645
16605
  React.useEffect(()=>{
16646
16606
  const handleEscKey = (event)=>{
@@ -16666,7 +16626,7 @@ const NodeDetailsPopover = ({ isVisible, onClose, nodeData, triggerRef })=>{
16666
16626
  // Handle click outside to close popover
16667
16627
  React.useEffect(()=>{
16668
16628
  const handleClickOutside = (event)=>{
16669
- if (isVisible && triggerRef.current && !triggerRef.current.contains(event.target) && !event.target.closest("[data-popover-content]")) {
16629
+ if (isVisible && !event.target.closest("[data-popover-content]") && !event.target.closest(".react-flow__node")) {
16670
16630
  onClose();
16671
16631
  }
16672
16632
  };
@@ -16676,8 +16636,7 @@ const NodeDetailsPopover = ({ isVisible, onClose, nodeData, triggerRef })=>{
16676
16636
  }
16677
16637
  }, [
16678
16638
  isVisible,
16679
- onClose,
16680
- triggerRef
16639
+ onClose
16681
16640
  ]);
16682
16641
  if (!isVisible) return null;
16683
16642
  const llOverviewDetails = getOverviewLlmDetails(nodeData.details?.internals?.llm_details || []);
@@ -16685,16 +16644,14 @@ const NodeDetailsPopover = ({ isVisible, onClose, nodeData, triggerRef })=>{
16685
16644
  const totalInputTokens = sumTotalInputTokens(nodeData.details?.internals?.llm_details || []);
16686
16645
  const totalOutputTokens = sumTotalOutputTokens(nodeData.details?.internals?.llm_details || []);
16687
16646
  const totalLatency = sumTotalLatency(nodeData.details?.internals?.llm_details || []);
16688
- const popoverContent = /*#__PURE__*/ React.createElement(PopoverPortal, {
16689
- style: {
16690
- top: position.top,
16691
- left: position.left
16692
- }
16693
- }, /*#__PURE__*/ React.createElement(PopoverContent, {
16647
+ const popoverContent = /*#__PURE__*/ React.createElement(PopoverPortal, null, /*#__PURE__*/ React.createElement(PopoverContent, {
16694
16648
  "data-popover-content": true,
16695
- $arrowPosition: position.arrowPosition
16649
+ $arrowPosition: "left"
16696
16650
  }, /*#__PURE__*/ React.createElement(PopoverHeader, null, /*#__PURE__*/ React.createElement(PopoverTitle, null, /*#__PURE__*/ React.createElement(NodeIcon$3, null, getNodeIcon$1(nodeData.nodeType || "Agent", llOverviewDetails?.model_provider)), /*#__PURE__*/ React.createElement("span", null, nodeData.label, " Details")), /*#__PURE__*/ React.createElement(PopoverHeaderButtons, null, /*#__PURE__*/ React.createElement(CloseButton, {
16697
- onClick: onClose
16651
+ onClick: (e)=>{
16652
+ e.stopPropagation();
16653
+ onClose();
16654
+ }
16698
16655
  }, /*#__PURE__*/ React.createElement(X, {
16699
16656
  size: 16
16700
16657
  })))), /*#__PURE__*/ React.createElement(PopoverBody, null, llOverviewDetails && /*#__PURE__*/ React.createElement(Section, null, /*#__PURE__*/ React.createElement(InfoGrid, null, (()=>{
@@ -16838,14 +16795,20 @@ const NodeDetailsPopover = ({ isVisible, onClose, nodeData, triggerRef })=>{
16838
16795
  }), /*#__PURE__*/ React.createElement(OutputRenderer, {
16839
16796
  data: selectedLlmDetails.output
16840
16797
  })) : null))));
16841
- // Use React Portal to render outside of ReactFlow container
16842
- return /*#__PURE__*/ ReactDOM.createPortal(popoverContent, document.body);
16798
+ return popoverContent;
16843
16799
  };
16844
16800
  // Styled components
16845
16801
  const PopoverPortal = styled.div`
16846
- position: fixed;
16802
+ position: absolute;
16803
+ left: calc(100% + 12px);
16804
+ top: 0;
16847
16805
  z-index: 99999;
16848
- pointer-events: none;
16806
+
16807
+ /* Position to the left of the node if there's not enough space on the right */
16808
+ @media (max-width: 768px) {
16809
+ left: auto;
16810
+ right: calc(100% + 12px);
16811
+ }
16849
16812
  `;
16850
16813
  const PopoverContent = styled.div`
16851
16814
  width: ${DEFAULT_POPOVER_WIDTH}px;
@@ -16881,7 +16844,7 @@ const PopoverContent = styled.div`
16881
16844
  height: 0;
16882
16845
  border-top: 6px solid transparent;
16883
16846
  border-bottom: 6px solid transparent;
16884
- ${props.$arrowPosition === "right" ? `
16847
+ ${props.$arrowPosition === "left" ? `
16885
16848
  left: -6px;
16886
16849
  border-right: 6px solid ${props.theme?.colors?.border || "hsl(214.3 31.8% 91.4%)"};
16887
16850
  ` : `
@@ -16898,7 +16861,7 @@ const PopoverContent = styled.div`
16898
16861
  height: 0;
16899
16862
  border-top: 6px solid transparent;
16900
16863
  border-bottom: 6px solid transparent;
16901
- ${props.$arrowPosition === "right" ? `
16864
+ ${props.$arrowPosition === "left" ? `
16902
16865
  left: -5px;
16903
16866
  border-right: 6px solid ${props.theme?.colors?.background || "hsl(0 0% 100%)"};
16904
16867
  ` : `
@@ -16979,7 +16942,7 @@ const PopoverHeaderButtons = styled.div`
16979
16942
  display: flex;
16980
16943
  align-items: center;
16981
16944
  gap: 0.5rem;
16982
- justify-content: flex-start;
16945
+ justify-content: flex-end;
16983
16946
  `;
16984
16947
  const CloseButton = styled.button`
16985
16948
  display: flex;
@@ -16993,6 +16956,8 @@ const CloseButton = styled.button`
16993
16956
  color: ${(props)=>props.theme?.colors?.mutedForeground || "hsl(215.4 16.3% 46.9%)"};
16994
16957
  cursor: pointer;
16995
16958
  transition: all 0.2s ease-in-out;
16959
+ pointer-events: auto;
16960
+ flex-shrink: 0;
16996
16961
 
16997
16962
  &:hover {
16998
16963
  background-color: ${(props)=>props.theme?.colors?.muted || "hsl(210 40% 96%)"};
@@ -17003,9 +16968,13 @@ const CloseButton = styled.button`
17003
16968
  outline: 2px solid ${(props)=>props.theme?.colors?.primary || "hsl(221.2 83.2% 53.3%)"};
17004
16969
  outline-offset: 2px;
17005
16970
  }
16971
+
16972
+ &:active {
16973
+ transform: scale(0.95);
16974
+ }
17006
16975
  `;
17007
16976
  const PopoverBody = styled.div`
17008
- max-height: 500px;
16977
+ max-height: 400px; /* Reduced by 100px to account for PopoverHeader and spacing */
17009
16978
  overflow-y: auto;
17010
16979
  padding: 1rem;
17011
16980
  display: flex;
@@ -17018,6 +16987,7 @@ const Section = styled.div`
17018
16987
  gap: 0.75rem;
17019
16988
  `;
17020
16989
  const FadingSection = styled(Section)`
16990
+ overflow-y: auto; /* Base style: enables scrolling after animation completes */
17021
16991
  animation:
17022
16992
  expandHeight 300ms ease-out,
17023
16993
  fadeInContent 200ms ease-in-out 200ms both;
@@ -17028,8 +16998,8 @@ const FadingSection = styled(Section)`
17028
16998
  overflow: hidden;
17029
16999
  }
17030
17000
  to {
17031
- max-height: 500px; /* Adjust based on expected content height */
17032
- overflow: visible;
17001
+ max-height: 350px; /* Reduced to fit within PopoverBody (400px) accounting for padding and gaps */
17002
+ overflow: hidden; /* Keep hidden during animation, base overflow-y: auto takes effect after */
17033
17003
  }
17034
17004
  }
17035
17005
 
@@ -17138,7 +17108,7 @@ const AgentNode = ({ data, id, onInspect })=>{
17138
17108
  return /*#__PURE__*/ React.createElement(React.Fragment, null, /*#__PURE__*/ React.createElement(NodeContainer$2, {
17139
17109
  ref: nodeRef,
17140
17110
  onClick: handleNodeClick,
17141
- className: "nowheel"
17111
+ className: "nowheel agent-node"
17142
17112
  }, hasIncomingEdges && /*#__PURE__*/ React.createElement(Handle$1, {
17143
17113
  type: "target",
17144
17114
  position: Position.Top,
@@ -17171,15 +17141,14 @@ const AgentNode = ({ data, id, onInspect })=>{
17171
17141
  cursor: "default"
17172
17142
  },
17173
17143
  isConnectable: false
17174
- })), /*#__PURE__*/ React.createElement(NodeDetailsPopover, {
17144
+ }), /*#__PURE__*/ React.createElement(NodeDetailsPopover, {
17175
17145
  isVisible: isPopoverOpen,
17176
17146
  onClose: handleClosePopover,
17177
17147
  nodeData: {
17178
17148
  ...data,
17179
17149
  id: id
17180
- },
17181
- triggerRef: nodeRef
17182
- }));
17150
+ }
17151
+ })));
17183
17152
  };
17184
17153
  // Styled components
17185
17154
  const NodeContainer$2 = styled.div`
@@ -17188,9 +17157,9 @@ const NodeContainer$2 = styled.div`
17188
17157
  border: 2px solid ${(props)=>props.theme?.colors?.border || "hsl(214.3 31.8% 91.4%)"};
17189
17158
  box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
17190
17159
  min-width: 300px;
17160
+ max-width: ${NODE_MAX_WIDTH}px;
17191
17161
  transition: all 0.2s ease-in-out;
17192
17162
  position: relative;
17193
- cursor: pointer;
17194
17163
 
17195
17164
  &:hover {
17196
17165
  border-color: ${(props)=>props.theme?.colors?.primary || "hsl(221.2 83.2% 53.3%)"};
@@ -17371,15 +17340,15 @@ const ToolNode = ({ data, id, onInspect })=>{
17371
17340
  nodeData = {
17372
17341
  ...baseData,
17373
17342
  input: {
17374
- args: data.edgeDetails[0]?.input_args,
17375
- kwargs: data.edgeDetails[0]?.input_kwargs
17343
+ ...data.edgeDetails[0]?.input_kwargs
17376
17344
  },
17377
17345
  output: data.edgeDetails[0]?.output,
17378
17346
  status: data.edgeDetails[0]?.status
17379
17347
  };
17380
17348
  }
17381
17349
  return /*#__PURE__*/ React.createElement(NodeContainer, {
17382
- onClick: handleNodeClick
17350
+ onClick: handleNodeClick,
17351
+ className: "nowheel"
17383
17352
  }, hasIncomingEdges && /*#__PURE__*/ React.createElement(Handle$1, {
17384
17353
  type: "target",
17385
17354
  position: Position.Top,
@@ -17420,6 +17389,7 @@ const NodeContainer = styled.div`
17420
17389
  border: 2px solid ${(props)=>props.theme?.colors?.border || "hsl(214.3 31.8% 91.4%)"};
17421
17390
  box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
17422
17391
  min-width: 300px;
17392
+ max-width: ${NODE_MAX_WIDTH}px;
17423
17393
  transition: all 0.2s ease-in-out;
17424
17394
  position: relative;
17425
17395
  cursor: pointer;
@@ -20691,7 +20661,7 @@ const AgenticFlowVisualizer = ({ flowData: propFlowData, width = "100dvw", heigh
20691
20661
  ]);
20692
20662
  // Pan to specific node when panToNodeId prop is provided
20693
20663
  React.useEffect(()=>{
20694
- if (!panToNodeId || !reactFlowInstance || disableAutoFit || nodes.length === 0) {
20664
+ if (!panToNodeId || !reactFlowInstance || nodes.length === 0) {
20695
20665
  return;
20696
20666
  }
20697
20667
  // Check if the specified node ID exists in the current nodes array
@@ -20716,7 +20686,6 @@ const AgenticFlowVisualizer = ({ flowData: propFlowData, width = "100dvw", heigh
20716
20686
  }, [
20717
20687
  panToNodeId,
20718
20688
  reactFlowInstance,
20719
- disableAutoFit,
20720
20689
  nodes,
20721
20690
  defaultAutoFitDuration,
20722
20691
  defaultAutoFitDelay,
@@ -20730,8 +20699,6 @@ const AgenticFlowVisualizer = ({ flowData: propFlowData, width = "100dvw", heigh
20730
20699
  minWidth: "800px",
20731
20700
  minHeight: "600px",
20732
20701
  boxSizing: "border-box",
20733
- border: `1px solid ${themeColors.border}`,
20734
- borderRadius: "8px",
20735
20702
  overflow: "hidden",
20736
20703
  position: "relative",
20737
20704
  background: themeColors.background
@@ -20852,6 +20819,7 @@ const AgenticFlowVisualizer = ({ flowData: propFlowData, width = "100dvw", heigh
20852
20819
  colorMode: isDarkMode ? "dark" : "light",
20853
20820
  nodes: nodesState,
20854
20821
  edges: edgesState,
20822
+ minZoom: 0.2,
20855
20823
  onNodesChange: onNodesChange,
20856
20824
  onEdgesChange: onEdgesChange,
20857
20825
  onConnect: onConnect,
@@ -20882,6 +20850,7 @@ const AgenticFlowVisualizer = ({ flowData: propFlowData, width = "100dvw", heigh
20882
20850
  }, /*#__PURE__*/ React.createElement(Background, {
20883
20851
  variant: BackgroundVariant.Dots,
20884
20852
  color: themeColors.mutedBorder,
20853
+ bgColor: themeColors.background,
20885
20854
  size: 3
20886
20855
  })), /*#__PURE__*/ React.createElement("style", null, `
20887
20856
  .react-flow__edge-label {
@@ -24587,7 +24556,9 @@ var ScrollDownButton = SelectScrollDownButton$1;
24587
24556
  var Separator = SelectSeparator$1;
24588
24557
 
24589
24558
  const Select = Root2;
24590
- const SelectValue = Value;
24559
+ const SelectValue = styled(Value)`
24560
+ font-family: inherit;
24561
+ `;
24591
24562
  const SelectTrigger = styled(Trigger)`
24592
24563
  display: flex;
24593
24564
  height: 2.5rem;
@@ -24617,6 +24588,7 @@ const SelectTrigger = styled(Trigger)`
24617
24588
  }
24618
24589
 
24619
24590
  &[data-placeholder] {
24591
+ font-family: inherit;
24620
24592
  color: ${(props)=>props.$theme.colors.mutedForeground};
24621
24593
  }
24622
24594
  `;