@industry-theme/principal-view-panels 0.12.2 → 0.12.4

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.
@@ -0,0 +1,40 @@
1
+ import React from 'react';
2
+ import { type MultiCanvasLayout } from '@principal-ai/principal-view-react';
3
+ import type { ExtendedCanvas } from '@principal-ai/principal-view-core';
4
+ export interface MultiCanvasPanelProps {
5
+ /** Layout configuration with canvas placements */
6
+ layout: MultiCanvasLayout;
7
+ /** Whether to show group borders around each canvas (default: true) */
8
+ showGroups?: boolean;
9
+ /** Show minimap for navigation (default: false) */
10
+ showMinimap?: boolean;
11
+ /** Show view controls (default: true) */
12
+ showControls?: boolean;
13
+ /** Show background pattern (default: true) */
14
+ showBackground?: boolean;
15
+ /** Background pattern variant */
16
+ backgroundVariant?: 'dots' | 'lines' | 'cross';
17
+ /** Width of the panel */
18
+ width?: number;
19
+ /** Height of the panel */
20
+ height?: number;
21
+ /** Optional click handler for nodes */
22
+ onNodeClick?: (nodeId: string) => void;
23
+ }
24
+ /**
25
+ * MultiCanvasPanel displays multiple canvases on a single unified view
26
+ * using the MultiCanvasRenderer from principal-view-react.
27
+ */
28
+ export declare const MultiCanvasPanel: React.FC<MultiCanvasPanelProps>;
29
+ /**
30
+ * Helper function to create a MultiCanvasLayout from an array of canvases
31
+ */
32
+ export declare function createMultiCanvasLayout(canvases: Array<{
33
+ id: string;
34
+ canvas: ExtendedCanvas;
35
+ label?: string;
36
+ }>, options?: {
37
+ direction?: 'vertical' | 'horizontal';
38
+ gap?: number;
39
+ }): MultiCanvasLayout;
40
+ //# sourceMappingURL=MultiCanvasPanel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MultiCanvasPanel.d.ts","sourceRoot":"","sources":["../../src/panels/MultiCanvasPanel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAuB,KAAK,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AACjG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAExE,MAAM,WAAW,qBAAqB;IACpC,kDAAkD;IAClD,MAAM,EAAE,iBAAiB,CAAC;IAC1B,uEAAuE;IACvE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,mDAAmD;IACnD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,yCAAyC;IACzC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,8CAA8C;IAC9C,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,iCAAiC;IACjC,iBAAiB,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;IAC/C,yBAAyB;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0BAA0B;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,uCAAuC;IACvC,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CACxC;AAED;;;GAGG;AACH,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CAwB5D,CAAC;AAEF;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,KAAK,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,cAAc,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC,EACF,OAAO,CAAC,EAAE;IACR,SAAS,CAAC,EAAE,UAAU,GAAG,YAAY,CAAC;IACtC,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,GACA,iBAAiB,CA0BnB"}
@@ -1 +1 @@
1
- {"version":3,"file":"StoryboardListPanel.d.ts","sourceRoot":"","sources":["../../src/panels/StoryboardListPanel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAiD,MAAM,OAAO,CAAC;AACtE,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,UAAU,CAAC;AAqE9D;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,mBAAmB,EAAE,KAAK,CAAC,EAAE,CAAC,6BAA6B,CAy4BvE,CAAC"}
1
+ {"version":3,"file":"StoryboardListPanel.d.ts","sourceRoot":"","sources":["../../src/panels/StoryboardListPanel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAiD,MAAM,OAAO,CAAC;AACtE,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,UAAU,CAAC;AAqE9D;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,mBAAmB,EAAE,KAAK,CAAC,EAAE,CAAC,6BAA6B,CA+5BvE,CAAC"}
@@ -87144,7 +87144,7 @@ const CenterIndicator = ({ color: color2 }) => {
87144
87144
  zIndex: 5
87145
87145
  }, children: [jsx("line", { x1: screenX, y1: screenY - size, x2: screenX, y2: screenY + size, stroke: color2, strokeWidth, opacity: 0.7 }), jsx("line", { x1: screenX - size, y1: screenY, x2: screenX + size, y2: screenY, stroke: color2, strokeWidth, opacity: 0.7 }), jsx("circle", { cx: screenX, cy: screenY, r: 3, fill: color2, opacity: 0.7 })] });
87146
87146
  };
87147
- const GraphRendererInner = ({ configuration, nodes: propNodes, edges: propEdges, violations = [], configName: _configName, showMinimap = false, showControls = true, showBackground = true, backgroundVariant = "lines", backgroundGap, showCenterIndicator = false, showTooltips = true, fitViewDuration = 200, highlightedNodeId, activeNodeIds, events = [], onEventProcessed, editable = false, onPendingChangesChange, onEditStateChange, editStateRef, onNodeClick: onNodeClickProp, fitViewToNodeIds, fitViewPadding = 0.2 }) => {
87147
+ const GraphRendererInner = ({ configuration, nodes: propNodes, edges: propEdges, violations = [], configName: _configName, showMinimap = false, showControls = true, showBackground = true, backgroundVariant = "lines", backgroundGap, showCenterIndicator = false, showTooltips = true, fitViewDuration = 200, highlightedNodeId, activeNodeIds, events = [], onEventProcessed, editable = false, onPendingChangesChange, onEditStateChange, editStateRef, onNodeClick: onNodeClickProp, fitViewToNodeIds, fitViewPadding = 0.2, draggableNodeIds, onNodeDragStop: onNodeDragStopProp }) => {
87148
87148
  const { fitView: fitView2, fitBounds, getNodes } = useReactFlow();
87149
87149
  const updateNodeInternals2 = useUpdateNodeInternals();
87150
87150
  const { theme: theme2 } = useTheme();
@@ -87652,10 +87652,17 @@ const GraphRendererInner = ({ configuration, nodes: propNodes, edges: propEdges,
87652
87652
  return converted.map((node2) => {
87653
87653
  const animation = animationState.nodeAnimations[node2.id];
87654
87654
  const pendingPosition = editStateRef.current.positionChanges.get(node2.id);
87655
+ const isDraggable = editable || (draggableNodeIds == null ? void 0 : draggableNodeIds.has(node2.id));
87656
+ if (isDraggable && !editable) {
87657
+ console.log("[GraphRenderer] Setting draggable=true for node:", node2.id);
87658
+ }
87659
+ const hasDraggableNodeIds = draggableNodeIds && draggableNodeIds.size > 0;
87655
87660
  return {
87656
87661
  ...node2,
87657
87662
  ...pendingPosition ? { position: pendingPosition } : {},
87658
87663
  selected: selectedNodeIds.has(node2.id),
87664
+ // Explicitly set draggable for each node when using draggableNodeIds
87665
+ draggable: hasDraggableNodeIds ? isDraggable : editable || false,
87659
87666
  data: {
87660
87667
  ...node2.data,
87661
87668
  editable,
@@ -87671,7 +87678,7 @@ const GraphRendererInner = ({ configuration, nodes: propNodes, edges: propEdges,
87671
87678
  }
87672
87679
  };
87673
87680
  });
87674
- }, [localNodes, configuration, violations, animationState.nodeAnimations, editable, showTooltips, highlightedNodeId, activeNodeIds, editStateRef, shiftKeyPressed, selectedNodeIds, hiddenNodeIds]);
87681
+ }, [localNodes, configuration, violations, animationState.nodeAnimations, editable, showTooltips, highlightedNodeId, activeNodeIds, editStateRef, shiftKeyPressed, selectedNodeIds, hiddenNodeIds, draggableNodeIds]);
87675
87682
  const baseNodesKey = useMemo(() => {
87676
87683
  return nodes.map((n) => n.id).sort().join(",");
87677
87684
  }, [nodes]);
@@ -87712,14 +87719,20 @@ const GraphRendererInner = ({ configuration, nodes: propNodes, edges: propEdges,
87712
87719
  }, [editable, xyflowNodesBase, updateNodeInternals2]);
87713
87720
  const xyflowNodes = editable ? xyflowLocalNodes : xyflowNodesBase;
87714
87721
  const handleNodeDrag = useCallback((_event, node2) => {
87715
- if (!editable)
87722
+ const canDrag = editable || (draggableNodeIds == null ? void 0 : draggableNodeIds.has(node2.id));
87723
+ if (!canDrag)
87716
87724
  return;
87717
- const guides = detectAlignmentGuides(node2.id, xyflowNodes);
87718
- setAlignmentGuides(guides);
87719
- }, [editable, xyflowNodes, detectAlignmentGuides]);
87720
- const handleNodeDragStop = useCallback(() => {
87725
+ if (editable) {
87726
+ const guides = detectAlignmentGuides(node2.id, xyflowNodes);
87727
+ setAlignmentGuides(guides);
87728
+ }
87729
+ }, [editable, draggableNodeIds, xyflowNodes, detectAlignmentGuides]);
87730
+ const handleNodeDragStop = useCallback((_event, node2) => {
87721
87731
  setAlignmentGuides([]);
87722
- }, []);
87732
+ if (onNodeDragStopProp && node2.position) {
87733
+ onNodeDragStopProp(node2.id, node2.position);
87734
+ }
87735
+ }, [onNodeDragStopProp]);
87723
87736
  const handleNodesChange = useCallback((changes) => {
87724
87737
  if (!editable)
87725
87738
  return;
@@ -87869,7 +87882,7 @@ const GraphRendererInner = ({ configuration, nodes: propNodes, edges: propEdges,
87869
87882
  }, 150);
87870
87883
  return () => clearTimeout(timeoutId);
87871
87884
  }, [fitViewToNodeIdsKey, fitViewToNodeIds, fitViewPadding, fitView2, fitViewDuration, getNodes, fitBounds]);
87872
- return jsxs(Fragment, { children: [jsxs(index$2, { nodes: xyflowNodes, edges: xyflowEdges, nodeTypes, edgeTypes, minZoom: 0.1, maxZoom: 4, defaultEdgeOptions: { type: "custom" }, onEdgeClick, onNodeClick, onNodeDoubleClick, onNodeDrag: handleNodeDrag, onNodeDragStop: handleNodeDragStop, proOptions: { hideAttribution: true }, nodesDraggable: editable, elementsSelectable: editable, selectNodesOnDrag: false, nodesConnectable: editable, edgesReconnectable: editable, reconnectRadius: 25, elevateEdgesOnSelect: true, onNodesChange: handleNodesChange, onEdgesChange: handleEdgesChange, onConnect: handleConnect, onReconnectStart: handleReconnectStart, onReconnect: handleReconnect, onReconnectEnd: handleReconnectEnd, onPaneClick, onSelectionChange: handleSelectionChange, panOnDrag: !editable, panOnScroll: true, zoomOnScroll: false, zoomOnPinch: true, zoomOnDoubleClick: false, selectionOnDrag: false, selectionKeyCode: null, multiSelectionKeyCode: "Shift", children: [showBackground && jsx(Background, { color: backgroundVariant === "dots" ? theme2.colors.border : theme2.colors.textMuted, gap: backgroundGap ?? (backgroundVariant === "dots" ? 16 : 50), size: backgroundVariant === "dots" ? 1 : 0.5, variant: backgroundVariant === "dots" ? BackgroundVariant.Dots : backgroundVariant === "lines" ? BackgroundVariant.Lines : BackgroundVariant.Cross }), showControls && jsx(Controls, { showZoom: true, showFitView: true, showInteractive: true }), showMinimap && jsx(MiniMap, { nodeColor: (node2) => {
87885
+ return jsxs(Fragment, { children: [jsxs(index$2, { nodes: xyflowNodes, edges: xyflowEdges, nodeTypes, edgeTypes, minZoom: 0.1, maxZoom: 4, defaultEdgeOptions: { type: "custom" }, onEdgeClick, onNodeClick, onNodeDoubleClick, onNodeDrag: handleNodeDrag, onNodeDragStop: handleNodeDragStop, proOptions: { hideAttribution: true }, nodesDraggable: editable || draggableNodeIds && draggableNodeIds.size > 0, elementsSelectable: editable, selectNodesOnDrag: false, nodesConnectable: editable, edgesReconnectable: editable, reconnectRadius: 25, elevateEdgesOnSelect: true, onNodesChange: handleNodesChange, onEdgesChange: handleEdgesChange, onConnect: handleConnect, onReconnectStart: handleReconnectStart, onReconnect: handleReconnect, onReconnectEnd: handleReconnectEnd, onPaneClick, onSelectionChange: handleSelectionChange, panOnDrag: !editable, panOnScroll: true, zoomOnScroll: false, zoomOnPinch: true, zoomOnDoubleClick: false, selectionOnDrag: false, selectionKeyCode: null, multiSelectionKeyCode: "Shift", children: [showBackground && jsx(Background, { color: backgroundVariant === "dots" ? theme2.colors.border : theme2.colors.textMuted, gap: backgroundGap ?? (backgroundVariant === "dots" ? 16 : 50), size: backgroundVariant === "dots" ? 1 : 0.5, variant: backgroundVariant === "dots" ? BackgroundVariant.Dots : backgroundVariant === "lines" ? BackgroundVariant.Lines : BackgroundVariant.Cross }), showControls && jsx(Controls, { showZoom: true, showFitView: true, showInteractive: true }), showMinimap && jsx(MiniMap, { nodeColor: (node2) => {
87873
87886
  var _a;
87874
87887
  const nodeData = node2.data;
87875
87888
  return ((_a = nodeData == null ? void 0 : nodeData.typeDefinition) == null ? void 0 : _a.color) || theme2.colors.secondary;
@@ -88082,10 +88095,158 @@ const GraphRenderer = forwardRef((props2, ref) => {
88082
88095
  }, children: jsx("p", { children: "No canvas data provided." }) });
88083
88096
  }
88084
88097
  const { configuration, nodes, edges } = canvasData;
88085
- const { violations, configName, showMinimap, showControls, showBackground, backgroundVariant, backgroundGap, showCenterIndicator, showTooltips, fitViewDuration, highlightedNodeId, activeNodeIds, events, onEventProcessed, editable, onPendingChangesChange, onNodeClick, fitViewToNodeIds, fitViewPadding } = props2;
88086
- return jsx("div", { className, style: { width, height, position: "relative" }, children: jsx(ReactFlowProvider, { children: jsx(GraphRendererInner, { configuration, nodes, edges, violations, configName, showMinimap, showControls, showBackground, backgroundVariant, backgroundGap, showCenterIndicator, showTooltips, fitViewDuration, highlightedNodeId, activeNodeIds, events, onEventProcessed, editable, onPendingChangesChange, editStateRef, onNodeClick, fitViewToNodeIds, fitViewPadding }) }) });
88098
+ const { violations, configName, showMinimap, showControls, showBackground, backgroundVariant, backgroundGap, showCenterIndicator, showTooltips, fitViewDuration, highlightedNodeId, activeNodeIds, events, onEventProcessed, editable, onPendingChangesChange, onNodeClick, fitViewToNodeIds, fitViewPadding, draggableNodeIds, onNodeDragStop } = props2;
88099
+ return jsx("div", { className, style: { width, height, position: "relative" }, children: jsx(ReactFlowProvider, { children: jsx(GraphRendererInner, { configuration, nodes, edges, violations, configName, showMinimap, showControls, showBackground, backgroundVariant, backgroundGap, showCenterIndicator, showTooltips, fitViewDuration, highlightedNodeId, activeNodeIds, events, onEventProcessed, editable, onPendingChangesChange, editStateRef, onNodeClick, fitViewToNodeIds, fitViewPadding, draggableNodeIds, onNodeDragStop }) }) });
88087
88100
  });
88088
88101
  GraphRenderer.displayName = "GraphRenderer";
88102
+ const DEFAULT_NODE_WIDTH = 200;
88103
+ const DEFAULT_NODE_HEIGHT = 100;
88104
+ const GROUP_PADDING = 40;
88105
+ function prefixNodeId(canvasId, nodeId) {
88106
+ return `${canvasId}:${nodeId}`;
88107
+ }
88108
+ function calculateCanvasBounds(canvas) {
88109
+ if (!canvas.nodes || canvas.nodes.length === 0) {
88110
+ return { minX: 0, minY: 0, maxX: DEFAULT_NODE_WIDTH, maxY: DEFAULT_NODE_HEIGHT };
88111
+ }
88112
+ let minX = Infinity;
88113
+ let minY = Infinity;
88114
+ let maxX = -Infinity;
88115
+ let maxY = -Infinity;
88116
+ for (const node2 of canvas.nodes) {
88117
+ const x = node2.x ?? 0;
88118
+ const y = node2.y ?? 0;
88119
+ const width = node2.width ?? DEFAULT_NODE_WIDTH;
88120
+ const height = node2.height ?? DEFAULT_NODE_HEIGHT;
88121
+ minX = Math.min(minX, x);
88122
+ minY = Math.min(minY, y);
88123
+ maxX = Math.max(maxX, x + width);
88124
+ maxY = Math.max(maxY, y + height);
88125
+ }
88126
+ return { minX, minY, maxX, maxY };
88127
+ }
88128
+ function mergeCanvases(placements, options = {}) {
88129
+ var _a;
88130
+ const { showGroups = true } = options;
88131
+ const groupNodes = [];
88132
+ const mergedNodes = [];
88133
+ const mergedEdges = [];
88134
+ for (const placement of placements) {
88135
+ const { canvasId, canvas, position: position2, label } = placement;
88136
+ if (showGroups && canvas.nodes && canvas.nodes.length > 0) {
88137
+ const bounds = calculateCanvasBounds(canvas);
88138
+ const groupNode = {
88139
+ id: `${canvasId}:__group__`,
88140
+ type: "group",
88141
+ label: label ?? ((_a = canvas.pv) == null ? void 0 : _a.name) ?? canvasId,
88142
+ x: position2.x + bounds.minX - GROUP_PADDING,
88143
+ y: position2.y + bounds.minY - GROUP_PADDING,
88144
+ width: bounds.maxX - bounds.minX + GROUP_PADDING * 2,
88145
+ height: bounds.maxY - bounds.minY + GROUP_PADDING * 2
88146
+ };
88147
+ groupNodes.push(groupNode);
88148
+ }
88149
+ if (canvas.nodes) {
88150
+ for (const node2 of canvas.nodes) {
88151
+ const mergedNode = {
88152
+ ...node2,
88153
+ id: prefixNodeId(canvasId, node2.id),
88154
+ x: (node2.x ?? 0) + position2.x,
88155
+ y: (node2.y ?? 0) + position2.y
88156
+ };
88157
+ mergedNodes.push(mergedNode);
88158
+ }
88159
+ }
88160
+ if (canvas.edges) {
88161
+ for (const edge of canvas.edges) {
88162
+ const mergedEdge = {
88163
+ ...edge,
88164
+ id: prefixNodeId(canvasId, edge.id),
88165
+ fromNode: prefixNodeId(canvasId, edge.fromNode),
88166
+ toNode: prefixNodeId(canvasId, edge.toNode)
88167
+ };
88168
+ mergedEdges.push(mergedEdge);
88169
+ }
88170
+ }
88171
+ }
88172
+ const mergedCanvas = {
88173
+ nodes: [...groupNodes, ...mergedNodes],
88174
+ edges: mergedEdges,
88175
+ pv: {
88176
+ version: "1.0.0",
88177
+ name: "Multi-Canvas View"
88178
+ }
88179
+ };
88180
+ return mergedCanvas;
88181
+ }
88182
+ function parseNodeId(mergedNodeId) {
88183
+ const colonIndex = mergedNodeId.indexOf(":");
88184
+ if (colonIndex === -1)
88185
+ return null;
88186
+ return {
88187
+ canvasId: mergedNodeId.substring(0, colonIndex),
88188
+ nodeId: mergedNodeId.substring(colonIndex + 1)
88189
+ };
88190
+ }
88191
+ forwardRef(function MultiCanvasRenderer({ layout, onLayoutChange, showGroups = true, ...graphRendererProps }, ref) {
88192
+ const groupPositionsRef = useRef(/* @__PURE__ */ new Map());
88193
+ const mergedCanvas = useMemo(() => mergeCanvases(layout.placements, { showGroups }), [layout.placements, showGroups]);
88194
+ const draggableNodeIds = useMemo(() => {
88195
+ if (!showGroups)
88196
+ return void 0;
88197
+ const ids = /* @__PURE__ */ new Set();
88198
+ for (const placement of layout.placements) {
88199
+ if (placement.canvas.nodes && placement.canvas.nodes.length > 0) {
88200
+ ids.add(`${placement.canvasId}:__group__`);
88201
+ }
88202
+ }
88203
+ console.log("[MultiCanvasRenderer] draggableNodeIds:", [...ids]);
88204
+ return ids.size > 0 ? ids : void 0;
88205
+ }, [layout.placements, showGroups]);
88206
+ useMemo(() => {
88207
+ groupPositionsRef.current.clear();
88208
+ for (const placement of layout.placements) {
88209
+ if (placement.canvas.nodes && placement.canvas.nodes.length > 0) {
88210
+ const bounds = calculateCanvasBounds(placement.canvas);
88211
+ groupPositionsRef.current.set(`${placement.canvasId}:__group__`, {
88212
+ x: placement.position.x + bounds.minX - GROUP_PADDING,
88213
+ y: placement.position.y + bounds.minY - GROUP_PADDING
88214
+ });
88215
+ }
88216
+ }
88217
+ }, [layout.placements]);
88218
+ const handleNodeDragStop = useCallback((nodeId, newPosition) => {
88219
+ if (!nodeId.endsWith(":__group__"))
88220
+ return;
88221
+ if (!onLayoutChange)
88222
+ return;
88223
+ const parsed = parseNodeId(nodeId);
88224
+ if (!parsed)
88225
+ return;
88226
+ const { canvasId } = parsed;
88227
+ const originalGroupPos = groupPositionsRef.current.get(nodeId);
88228
+ if (!originalGroupPos)
88229
+ return;
88230
+ const deltaX = newPosition.x - originalGroupPos.x;
88231
+ const deltaY = newPosition.y - originalGroupPos.y;
88232
+ if (Math.abs(deltaX) < 1 && Math.abs(deltaY) < 1)
88233
+ return;
88234
+ const updatedPlacements = layout.placements.map((placement) => {
88235
+ if (placement.canvasId === canvasId) {
88236
+ return {
88237
+ ...placement,
88238
+ position: {
88239
+ x: placement.position.x + deltaX,
88240
+ y: placement.position.y + deltaY
88241
+ }
88242
+ };
88243
+ }
88244
+ return placement;
88245
+ });
88246
+ onLayoutChange({ placements: updatedPlacements });
88247
+ }, [layout.placements, onLayoutChange]);
88248
+ return jsx(GraphRenderer, { ref, canvas: mergedCanvas, editable: false, draggableNodeIds, onNodeDragStop: handleNodeDragStop, ...graphRendererProps });
88249
+ });
88089
88250
  /*! js-yaml 4.1.1 https://github.com/nodeca/js-yaml @license MIT */
88090
88251
  function isNothing(subject) {
88091
88252
  return typeof subject === "undefined" || subject === null;
@@ -98712,18 +98873,36 @@ const StoryboardListPanel = ({
98712
98873
  "button",
98713
98874
  {
98714
98875
  onClick: toggleHelp,
98876
+ draggable: true,
98877
+ onDragStart: (e) => {
98878
+ const cliCommand = storyboards.length > 0 ? "npx @principal-ai/principal-view-cli@latest --help" : "npx @principal-ai/principal-view-cli@latest init";
98879
+ const dragData = {
98880
+ dataType: "cli-command",
98881
+ primaryData: cliCommand,
98882
+ metadata: {
98883
+ description: "Principal View CLI command",
98884
+ action: storyboards.length > 0 ? "help" : "init"
98885
+ },
98886
+ suggestedActions: ["paste", "execute"],
98887
+ sourcePanel: "storyboard-list",
98888
+ dragPreview: cliCommand
98889
+ };
98890
+ e.dataTransfer.setData("application/x-panel-data", JSON.stringify(dragData));
98891
+ e.dataTransfer.setData("text/plain", cliCommand);
98892
+ e.dataTransfer.effectAllowed = "copy";
98893
+ },
98715
98894
  style: {
98716
98895
  background: showHelp ? theme2.colors.primary : theme2.colors.backgroundSecondary,
98717
98896
  border: `1px solid ${theme2.colors.border}`,
98718
98897
  borderRadius: theme2.radii[1],
98719
98898
  padding: "6px",
98720
- cursor: "pointer",
98899
+ cursor: "grab",
98721
98900
  display: "flex",
98722
98901
  alignItems: "center",
98723
98902
  justifyContent: "center",
98724
98903
  transition: "all 0.2s ease"
98725
98904
  },
98726
- title: "Help & Getting Started",
98905
+ title: "Help & Getting Started (drag to copy CLI command)",
98727
98906
  children: /* @__PURE__ */ jsx(
98728
98907
  CircleQuestionMark,
98729
98908
  {