dishui 0.0.59 → 0.0.61

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.
Files changed (36) hide show
  1. package/dist/components/pro/Flow/Flow.js +517 -543
  2. package/dist/components/pro/Flow/Flow.js.map +1 -1
  3. package/dist/components/pro/Flow/FlowCanvas.js +1104 -957
  4. package/dist/components/pro/Flow/FlowCanvas.js.map +1 -1
  5. package/dist/components/pro/Flow/context/FlowUIContext.d.ts +3 -0
  6. package/dist/components/pro/Flow/context/FlowUIContext.js +67 -64
  7. package/dist/components/pro/Flow/context/FlowUIContext.js.map +1 -1
  8. package/dist/components/pro/Flow/edges/EdgeRenderer.js +1 -1
  9. package/dist/components/pro/Flow/edges/edgePaths.js +170 -159
  10. package/dist/components/pro/Flow/edges/edgePaths.js.map +1 -1
  11. package/dist/components/pro/Flow/hooks/useDeleteSelection.d.ts +8 -0
  12. package/dist/components/pro/Flow/hooks/useDeleteSelection.js +43 -0
  13. package/dist/components/pro/Flow/hooks/useDeleteSelection.js.map +1 -0
  14. package/dist/components/pro/Flow/hooks/useMindMap.js +19 -17
  15. package/dist/components/pro/Flow/hooks/useMindMap.js.map +1 -1
  16. package/dist/components/pro/Flow/lines/LineRenderer.js +1 -1
  17. package/dist/components/pro/Flow/nodes/NodeRenderer.d.ts +2 -0
  18. package/dist/components/pro/Flow/nodes/NodeRenderer.js +174 -145
  19. package/dist/components/pro/Flow/nodes/NodeRenderer.js.map +1 -1
  20. package/dist/components/pro/Flow/nodes/shapes.d.ts +20 -0
  21. package/dist/components/pro/Flow/nodes/shapes.js +438 -203
  22. package/dist/components/pro/Flow/nodes/shapes.js.map +1 -1
  23. package/dist/components/pro/Flow/nodes/svgIconTexture.d.ts +4 -0
  24. package/dist/components/pro/Flow/nodes/svgIconTexture.js.map +1 -1
  25. package/dist/components/pro/Flow/panels/FlowToolbar.d.ts +4 -1
  26. package/dist/components/pro/Flow/panels/FlowToolbar.js +106 -100
  27. package/dist/components/pro/Flow/panels/FlowToolbar.js.map +1 -1
  28. package/dist/components/pro/Flow/panels/InspectorPanel.js +739 -476
  29. package/dist/components/pro/Flow/panels/InspectorPanel.js.map +1 -1
  30. package/dist/components/pro/Flow/panels/toolbarIcons.d.ts +2 -0
  31. package/dist/components/pro/Flow/panels/toolbarIcons.js +30 -25
  32. package/dist/components/pro/Flow/panels/toolbarIcons.js.map +1 -1
  33. package/dist/components/pro/Flow/types.d.ts +32 -0
  34. package/dist/components/pro/Flow/types.js.map +1 -1
  35. package/dist/dishui.css +1 -1
  36. package/package.json +1 -1
@@ -58,6 +58,9 @@ export interface FlowUIContextValue {
58
58
  setShowAnchors: (v: boolean) => void;
59
59
  gridSize: number;
60
60
  setGridSize: (s: number) => void;
61
+ /** Placement magnet: when true, stamping a shape snaps it to the canvas grid. */
62
+ placementSnap: boolean;
63
+ setPlacementSnap: (v: boolean) => void;
61
64
  pendingPlacement: PendingPlacement | null;
62
65
  setPendingPlacement: (p: PendingPlacement | null) => void;
63
66
  contextMenu: ContextMenuState | null;
@@ -1,84 +1,86 @@
1
- import { createContext as dt, useCallback as o, useContext as ft, useMemo as gt, useRef as w, useState as t } from "react";
2
- import { jsx as pt } from "react/jsx-runtime";
3
- var T = dt(null);
4
- function St() {
5
- const c = ft(T);
1
+ import { createContext as gt, useCallback as o, useContext as pt, useMemo as St, useRef as w, useState as t } from "react";
2
+ import { jsx as mt } from "react/jsx-runtime";
3
+ var V = gt(null);
4
+ function Rt() {
5
+ const c = pt(V);
6
6
  if (!c) throw new Error("useFlowUI must be used within FlowUIProvider");
7
7
  return c;
8
8
  }
9
- function mt({ showMiniMap: c = !0, showGrid: V = !0, gridSize: b = 20, showAI: J = !0, readOnly: s = !1, children: j }) {
10
- const [a, q] = t("select"), [l, B] = t("smoothstep"), [h, d] = t({
9
+ function xt({ showMiniMap: c = !0, showGrid: b = !0, gridSize: J = 20, showAI: j = !0, readOnly: s = !1, children: q }) {
10
+ const [a, B] = t("select"), [l, H] = t("smoothstep"), [h, d] = t({
11
11
  x: 0,
12
12
  y: 0,
13
13
  zoom: 1
14
- }), f = w(0), H = o((e) => {
14
+ }), f = w(0), K = o((e) => {
15
15
  f.current += 1, d(e);
16
- }, []), K = o((e) => {
16
+ }, []), L = o((e) => {
17
17
  d(e);
18
- }, []), [g, L] = t(!1), [p, Q] = t(null), W = o((e) => {
19
- s || Q(e);
20
- }, [s]), r = w(0), [i, I] = t(!1), M = o(() => {
21
- r.current += 1, i || I(!0);
22
- }, [i]), P = o(() => {
23
- r.current = Math.max(0, r.current - 1), r.current === 0 && I(!1);
24
- }, []), [S, X] = t(!0), [m, Y] = t(!0), [R, Z] = t(!0), [x, _] = t(!0), [F, $] = t(J), [C, O] = t(c), [D, y] = t(V), [N, tt] = t(!0), [A, et] = t(b), [v, ot] = t(null), [U, st] = t(null), nt = o((e) => {
25
- s || ot(e);
26
- }, [s]), ct = o((e) => {
27
- s || st(e);
28
- }, [s]), [z, rt] = t(null), [E, it] = t({}), G = o((e, u) => {
29
- it((n) => n[e] === u ? n : {
18
+ }, []), [g, Q] = t(!1), [p, W] = t(null), X = o((e) => {
19
+ s || W(e);
20
+ }, [s]), r = w(0), [i, S] = t(!1), m = o(() => {
21
+ r.current += 1, i || S(!0);
22
+ }, [i]), I = o(() => {
23
+ r.current = Math.max(0, r.current - 1), r.current === 0 && S(!1);
24
+ }, []), [P, Y] = t(!0), [M, Z] = t(!0), [R, _] = t(!0), [x, $] = t(!0), [F, O] = t(j), [C, y] = t(c), [D, tt] = t(b), [N, et] = t(!0), [A, ot] = t(J), [v, st] = t(!0), [U, nt] = t(null), [z, ct] = t(null), rt = o((e) => {
25
+ s || nt(e);
26
+ }, [s]), it = o((e) => {
27
+ s || ct(e);
28
+ }, [s]), [E, ut] = t(null), [G, wt] = t({}), k = o((e, u) => {
29
+ wt((n) => n[e] === u ? n : {
30
30
  ...n,
31
31
  [e]: u
32
32
  });
33
- }, []), k = w(() => {
34
- }), ut = o((e, u, n, lt, ht) => {
35
- k.current(e, u, n, lt, ht);
36
- }, []), wt = o((e) => {
37
- k.current = e;
38
- }, []), at = gt(() => ({
33
+ }, []), T = w(() => {
34
+ }), at = o((e, u, n, dt, ft) => {
35
+ T.current(e, u, n, dt, ft);
36
+ }, []), lt = o((e) => {
37
+ T.current = e;
38
+ }, []), ht = St(() => ({
39
39
  toolMode: a,
40
- setToolMode: q,
40
+ setToolMode: B,
41
41
  edgeType: l,
42
- setEdgeType: B,
42
+ setEdgeType: H,
43
43
  viewport: h,
44
- setViewport: H,
45
- setViewportInternal: K,
44
+ setViewport: K,
45
+ setViewportInternal: L,
46
46
  viewportReqRef: f,
47
- focusOnRect: ut,
48
- setFocusOnRect: wt,
47
+ focusOnRect: at,
48
+ setFocusOnRect: lt,
49
49
  autoFocus: g,
50
- setAutoFocus: L,
50
+ setAutoFocus: Q,
51
51
  editingNodeId: p,
52
- setEditingNodeId: W,
52
+ setEditingNodeId: X,
53
53
  isNodeDragging: i,
54
- beginNodeDrag: M,
55
- endNodeDrag: P,
56
- showPalette: S,
57
- setShowPalette: X,
58
- showInspector: m,
59
- setShowInspector: Y,
54
+ beginNodeDrag: m,
55
+ endNodeDrag: I,
56
+ showPalette: P,
57
+ setShowPalette: Y,
58
+ showInspector: M,
59
+ setShowInspector: Z,
60
60
  showOutline: R,
61
- setShowOutline: Z,
61
+ setShowOutline: _,
62
62
  showJson: x,
63
- setShowJson: _,
63
+ setShowJson: $,
64
64
  showAI: F,
65
- setShowAI: $,
65
+ setShowAI: O,
66
66
  showMiniMap: C,
67
- setShowMiniMap: O,
67
+ setShowMiniMap: y,
68
68
  showGrid: D,
69
- setShowGrid: y,
69
+ setShowGrid: tt,
70
70
  showAnchors: N,
71
- setShowAnchors: tt,
71
+ setShowAnchors: et,
72
72
  gridSize: A,
73
- setGridSize: et,
74
- pendingPlacement: v,
75
- setPendingPlacement: nt,
76
- contextMenu: U,
77
- setContextMenu: ct,
78
- presentation: z,
79
- setPresentation: rt,
80
- panelDocks: E,
81
- setPanelDock: G,
73
+ setGridSize: ot,
74
+ placementSnap: v,
75
+ setPlacementSnap: st,
76
+ pendingPlacement: U,
77
+ setPendingPlacement: rt,
78
+ contextMenu: z,
79
+ setContextMenu: it,
80
+ presentation: E,
81
+ setPresentation: ut,
82
+ panelDocks: G,
83
+ setPanelDock: k,
82
84
  readOnly: s
83
85
  }), [
84
86
  a,
@@ -87,10 +89,10 @@ function mt({ showMiniMap: c = !0, showGrid: V = !0, gridSize: b = 20, showAI: J
87
89
  g,
88
90
  p,
89
91
  i,
90
- M,
91
- P,
92
- S,
93
92
  m,
93
+ I,
94
+ P,
95
+ M,
94
96
  R,
95
97
  x,
96
98
  F,
@@ -103,16 +105,17 @@ function mt({ showMiniMap: c = !0, showGrid: V = !0, gridSize: b = 20, showAI: J
103
105
  z,
104
106
  E,
105
107
  G,
108
+ k,
106
109
  s
107
110
  ]);
108
- return /* @__PURE__ */ pt(T.Provider, {
109
- value: at,
110
- children: j
111
+ return /* @__PURE__ */ mt(V.Provider, {
112
+ value: ht,
113
+ children: q
111
114
  });
112
115
  }
113
116
  export {
114
- mt as FlowUIProvider,
115
- St as useFlowUI
117
+ xt as FlowUIProvider,
118
+ Rt as useFlowUI
116
119
  };
117
120
 
118
121
  //# sourceMappingURL=FlowUIContext.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"FlowUIContext.js","names":[],"sources":["../../../../../src/components/pro/Flow/context/FlowUIContext.tsx"],"sourcesContent":["import React, { createContext, useContext, useMemo, useState, useRef, useCallback } from 'react';\nimport type { FlowToolMode, FlowEdgeTypeName, FlowShapeType, FlowNodeData, ViewportState } from '../types';\n\nexport interface ContextMenuState {\n x: number;\n y: number;\n nodeId: string | null;\n}\n\n/** Where an editing panel lives: left dock, right dock or a floating overlay. */\nexport type FlowPanelDock = 'left' | 'right' | 'float';\n\nexport interface FocusOnRectOptions {\n /** Screen-space padding around the focused rectangle, in pixels. */\n padding?: number;\n /** Maximum zoom allowed for this focus operation. */\n maxZoom?: number;\n /** Viewport transition duration in milliseconds. */\n duration?: number;\n /** Keep the current zoom and only animate the focused rectangle to center. */\n preserveZoom?: boolean;\n}\n\nexport interface FlowUIContextValue {\n toolMode: FlowToolMode;\n setToolMode: (mode: FlowToolMode) => void;\n edgeType: FlowEdgeTypeName;\n setEdgeType: (type: FlowEdgeTypeName) => void;\n viewport: ViewportState;\n setViewport: (v: ViewportState) => void;\n /** Internal VM→React bridge setter (does not request a VM apply). */\n setViewportInternal: (v: ViewportState) => void;\n /** Monotonic counter of external viewport commands. */\n viewportReqRef: React.MutableRefObject<number>;\n focusOnRect: (wx: number, wy: number, ww: number, wh: number, options?: FocusOnRectOptions) => void;\n setFocusOnRect: (fn: (wx: number, wy: number, ww: number, wh: number, options?: FocusOnRectOptions) => void) => void;\n autoFocus: boolean;\n setAutoFocus: (v: boolean) => void;\n editingNodeId: string | null;\n setEditingNodeId: (id: string | null) => void;\n /** True while any node/line is being dragged. Used to suppress interactive\n * DOM overlays (e.g. HTML iframes) that would otherwise swallow pointerup. */\n isNodeDragging: boolean;\n beginNodeDrag: () => void;\n endNodeDrag: () => void;\n showPalette: boolean;\n setShowPalette: (v: boolean) => void;\n showInspector: boolean;\n setShowInspector: (v: boolean) => void;\n showOutline: boolean;\n setShowOutline: (v: boolean) => void;\n showJson: boolean;\n setShowJson: (v: boolean) => void;\n showAI: boolean;\n setShowAI: (v: boolean) => void;\n showMiniMap: boolean;\n setShowMiniMap: (v: boolean) => void;\n showGrid: boolean;\n setShowGrid: (v: boolean) => void;\n /** Global editor-only visibility for animation anchor objects. */\n showAnchors: boolean;\n setShowAnchors: (v: boolean) => void;\n gridSize: number;\n setGridSize: (s: number) => void;\n pendingPlacement: PendingPlacement | null;\n setPendingPlacement: (p: PendingPlacement | null) => void;\n contextMenu: ContextMenuState | null;\n setContextMenu: (m: ContextMenuState | null) => void;\n /** Dock assignment per panel id. Panels not listed default to the left\n * dock; users can move them to the right dock or let them float. */\n panelDocks: Record<string, FlowPanelDock>;\n setPanelDock: (tabId: string, dock: FlowPanelDock) => void;\n /** PPT-style presentation mode. When set, the overlay animates the viewport\n * between animation anchors, navigable via arrow keys. */\n presentation: PresentationState | null;\n setPresentation: (p: PresentationState | null) => void;\n /** When true, all editing affordances are suppressed (read-only preview). */\n readOnly: boolean;\n}\n\nexport interface PresentationState {\n /** Index into the anchor sequence (0-based). */\n current: number;\n /** Whether to show the active anchor frame and sequence badge in preview. */\n showAnchor?: boolean;\n}\n\nexport interface PendingPlacement {\n type: FlowShapeType;\n width: number;\n height: number;\n data: FlowNodeData;\n}\n\nconst FlowUIContext = createContext<FlowUIContextValue | null>(null);\n\nexport function useFlowUI(): FlowUIContextValue {\n const ctx = useContext(FlowUIContext);\n if (!ctx) throw new Error('useFlowUI must be used within FlowUIProvider');\n return ctx;\n}\n\nexport interface FlowUIProviderProps {\n showMiniMap?: boolean;\n showGrid?: boolean;\n gridSize?: number;\n showAI?: boolean;\n /** Suppresses context menu, inline text editing and palette placement.\n * Document mutations are additionally blocked in `Flow` (single choke point). */\n readOnly?: boolean;\n children: React.ReactNode;\n}\n\nexport function FlowUIProvider({ showMiniMap: initMiniMap = true, showGrid: initGrid = true, gridSize: initGridSize = 20, showAI: initShowAI = true, readOnly = false, children }: FlowUIProviderProps) {\n const [toolMode, setToolMode] = useState<FlowToolMode>('select');\n const [edgeType, setEdgeType] = useState<FlowEdgeTypeName>('smoothstep');\n const [viewport, setViewportState] = useState<ViewportState>({ x: 0, y: 0, zoom: 1 });\n // Distinguishes EXTERNAL viewport commands (toolbar, minimap, outline) from\n // internal echoes emitted by the ViewportManager. Only external commands\n // should be pushed back into the VM; echoing VM changes causes jitter.\n const viewportReqRef = useRef(0);\n const setViewport = useCallback((v: ViewportState) => {\n viewportReqRef.current += 1;\n setViewportState(v);\n }, []);\n // Internal setter used by the VM→React bridge; does NOT bump the request\n // counter, so the sync effect will not echo it back to the VM.\n const setViewportInternal = useCallback((v: ViewportState) => {\n setViewportState(v);\n }, []);\n const [autoFocus, setAutoFocus] = useState(false);\n const [editingNodeId, setEditingNodeIdRaw] = useState<string | null>(null);\n // In read-only mode the inline node/edge text editor must never open.\n const setEditingNodeId = useCallback((id: string | null) => {\n if (readOnly) return;\n setEditingNodeIdRaw(id);\n }, [readOnly]);\n // Counter so concurrent drags (multi-node) don't flip the flag early.\n const dragCountRef = useRef(0);\n const [isNodeDragging, setIsNodeDragging] = useState(false);\n const beginNodeDrag = useCallback(() => {\n dragCountRef.current += 1;\n if (!isNodeDragging) setIsNodeDragging(true);\n }, [isNodeDragging]);\n const endNodeDrag = useCallback(() => {\n dragCountRef.current = Math.max(0, dragCountRef.current - 1);\n if (dragCountRef.current === 0) setIsNodeDragging(false);\n }, []);\n const [showPalette, setShowPalette] = useState(true);\n const [showInspector, setShowInspector] = useState(true);\n const [showOutline, setShowOutline] = useState(true);\n const [showJson, setShowJson] = useState(true);\n const [showAI, setShowAI] = useState(initShowAI);\n const [showMiniMap, setShowMiniMap] = useState(initMiniMap);\n const [showGrid, setShowGrid] = useState(initGrid);\n const [showAnchors, setShowAnchors] = useState(true);\n const [gridSize, setGridSize] = useState(initGridSize);\n const [pendingPlacement, setPendingPlacementRaw] = useState<PendingPlacement | null>(null);\n const [contextMenu, setContextMenuRaw] = useState<ContextMenuState | null>(null);\n // Read-only: palette drops and the right-click menu are editing affordances.\n const setPendingPlacement = useCallback((p: PendingPlacement | null) => {\n if (readOnly) return;\n setPendingPlacementRaw(p);\n }, [readOnly]);\n const setContextMenu = useCallback((m: ContextMenuState | null) => {\n if (readOnly) return;\n setContextMenuRaw(m);\n }, [readOnly]);\n const [presentation, setPresentation] = useState<PresentationState | null>(null);\n const [panelDocks, setPanelDocks] = useState<Record<string, FlowPanelDock>>({});\n const setPanelDock = useCallback((tabId: string, dock: FlowPanelDock) => {\n setPanelDocks(prev => (prev[tabId] === dock ? prev : { ...prev, [tabId]: dock }));\n }, []);\n\n const focusOnRectRef = useRef<(wx: number, wy: number, ww: number, wh: number, options?: FocusOnRectOptions) => void>(() => {});\n const focusOnRect = useCallback((wx: number, wy: number, ww: number, wh: number, options?: FocusOnRectOptions) => {\n focusOnRectRef.current(wx, wy, ww, wh, options);\n }, []);\n const setFocusOnRect = useCallback((fn: (wx: number, wy: number, ww: number, wh: number, options?: FocusOnRectOptions) => void) => {\n focusOnRectRef.current = fn;\n }, []);\n\n const value = useMemo<FlowUIContextValue>(() => ({\n toolMode, setToolMode,\n edgeType, setEdgeType,\n viewport, setViewport,\n setViewportInternal,\n viewportReqRef,\n focusOnRect, setFocusOnRect,\n autoFocus, setAutoFocus,\n editingNodeId, setEditingNodeId,\n isNodeDragging, beginNodeDrag, endNodeDrag,\n showPalette, setShowPalette,\n showInspector, setShowInspector,\n showOutline, setShowOutline,\n showJson, setShowJson,\n showAI, setShowAI,\n showMiniMap, setShowMiniMap,\n showGrid, setShowGrid,\n showAnchors, setShowAnchors,\n gridSize, setGridSize,\n pendingPlacement, setPendingPlacement,\n contextMenu, setContextMenu,\n presentation, setPresentation,\n panelDocks, setPanelDock,\n readOnly,\n }), [toolMode, edgeType, viewport, autoFocus, editingNodeId, isNodeDragging, beginNodeDrag, endNodeDrag, showPalette, showInspector, showOutline, showJson, showAI, showMiniMap, showGrid, showAnchors, gridSize, pendingPlacement, contextMenu, presentation, panelDocks, setPanelDock, readOnly]);\n\n return <FlowUIContext.Provider value={value}>{children}</FlowUIContext.Provider>;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"FlowUIContext.js","names":[],"sources":["../../../../../src/components/pro/Flow/context/FlowUIContext.tsx"],"sourcesContent":["import React, { createContext, useContext, useMemo, useState, useRef, useCallback } from 'react';\nimport type { FlowToolMode, FlowEdgeTypeName, FlowShapeType, FlowNodeData, ViewportState } from '../types';\n\nexport interface ContextMenuState {\n x: number;\n y: number;\n nodeId: string | null;\n}\n\n/** Where an editing panel lives: left dock, right dock or a floating overlay. */\nexport type FlowPanelDock = 'left' | 'right' | 'float';\n\nexport interface FocusOnRectOptions {\n /** Screen-space padding around the focused rectangle, in pixels. */\n padding?: number;\n /** Maximum zoom allowed for this focus operation. */\n maxZoom?: number;\n /** Viewport transition duration in milliseconds. */\n duration?: number;\n /** Keep the current zoom and only animate the focused rectangle to center. */\n preserveZoom?: boolean;\n}\n\nexport interface FlowUIContextValue {\n toolMode: FlowToolMode;\n setToolMode: (mode: FlowToolMode) => void;\n edgeType: FlowEdgeTypeName;\n setEdgeType: (type: FlowEdgeTypeName) => void;\n viewport: ViewportState;\n setViewport: (v: ViewportState) => void;\n /** Internal VM→React bridge setter (does not request a VM apply). */\n setViewportInternal: (v: ViewportState) => void;\n /** Monotonic counter of external viewport commands. */\n viewportReqRef: React.MutableRefObject<number>;\n focusOnRect: (wx: number, wy: number, ww: number, wh: number, options?: FocusOnRectOptions) => void;\n setFocusOnRect: (fn: (wx: number, wy: number, ww: number, wh: number, options?: FocusOnRectOptions) => void) => void;\n autoFocus: boolean;\n setAutoFocus: (v: boolean) => void;\n editingNodeId: string | null;\n setEditingNodeId: (id: string | null) => void;\n /** True while any node/line is being dragged. Used to suppress interactive\n * DOM overlays (e.g. HTML iframes) that would otherwise swallow pointerup. */\n isNodeDragging: boolean;\n beginNodeDrag: () => void;\n endNodeDrag: () => void;\n showPalette: boolean;\n setShowPalette: (v: boolean) => void;\n showInspector: boolean;\n setShowInspector: (v: boolean) => void;\n showOutline: boolean;\n setShowOutline: (v: boolean) => void;\n showJson: boolean;\n setShowJson: (v: boolean) => void;\n showAI: boolean;\n setShowAI: (v: boolean) => void;\n showMiniMap: boolean;\n setShowMiniMap: (v: boolean) => void;\n showGrid: boolean;\n setShowGrid: (v: boolean) => void;\n /** Global editor-only visibility for animation anchor objects. */\n showAnchors: boolean;\n setShowAnchors: (v: boolean) => void;\n gridSize: number;\n setGridSize: (s: number) => void;\n /** Placement magnet: when true, stamping a shape snaps it to the canvas grid. */\n placementSnap: boolean;\n setPlacementSnap: (v: boolean) => void;\n pendingPlacement: PendingPlacement | null;\n setPendingPlacement: (p: PendingPlacement | null) => void;\n contextMenu: ContextMenuState | null;\n setContextMenu: (m: ContextMenuState | null) => void;\n /** Dock assignment per panel id. Panels not listed default to the left\n * dock; users can move them to the right dock or let them float. */\n panelDocks: Record<string, FlowPanelDock>;\n setPanelDock: (tabId: string, dock: FlowPanelDock) => void;\n /** PPT-style presentation mode. When set, the overlay animates the viewport\n * between animation anchors, navigable via arrow keys. */\n presentation: PresentationState | null;\n setPresentation: (p: PresentationState | null) => void;\n /** When true, all editing affordances are suppressed (read-only preview). */\n readOnly: boolean;\n}\n\nexport interface PresentationState {\n /** Index into the anchor sequence (0-based). */\n current: number;\n /** Whether to show the active anchor frame and sequence badge in preview. */\n showAnchor?: boolean;\n}\n\nexport interface PendingPlacement {\n type: FlowShapeType;\n width: number;\n height: number;\n data: FlowNodeData;\n}\n\nconst FlowUIContext = createContext<FlowUIContextValue | null>(null);\n\nexport function useFlowUI(): FlowUIContextValue {\n const ctx = useContext(FlowUIContext);\n if (!ctx) throw new Error('useFlowUI must be used within FlowUIProvider');\n return ctx;\n}\n\nexport interface FlowUIProviderProps {\n showMiniMap?: boolean;\n showGrid?: boolean;\n gridSize?: number;\n showAI?: boolean;\n /** Suppresses context menu, inline text editing and palette placement.\n * Document mutations are additionally blocked in `Flow` (single choke point). */\n readOnly?: boolean;\n children: React.ReactNode;\n}\n\nexport function FlowUIProvider({ showMiniMap: initMiniMap = true, showGrid: initGrid = true, gridSize: initGridSize = 20, showAI: initShowAI = true, readOnly = false, children }: FlowUIProviderProps) {\n const [toolMode, setToolMode] = useState<FlowToolMode>('select');\n const [edgeType, setEdgeType] = useState<FlowEdgeTypeName>('smoothstep');\n const [viewport, setViewportState] = useState<ViewportState>({ x: 0, y: 0, zoom: 1 });\n // Distinguishes EXTERNAL viewport commands (toolbar, minimap, outline) from\n // internal echoes emitted by the ViewportManager. Only external commands\n // should be pushed back into the VM; echoing VM changes causes jitter.\n const viewportReqRef = useRef(0);\n const setViewport = useCallback((v: ViewportState) => {\n viewportReqRef.current += 1;\n setViewportState(v);\n }, []);\n // Internal setter used by the VM→React bridge; does NOT bump the request\n // counter, so the sync effect will not echo it back to the VM.\n const setViewportInternal = useCallback((v: ViewportState) => {\n setViewportState(v);\n }, []);\n const [autoFocus, setAutoFocus] = useState(false);\n const [editingNodeId, setEditingNodeIdRaw] = useState<string | null>(null);\n // In read-only mode the inline node/edge text editor must never open.\n const setEditingNodeId = useCallback((id: string | null) => {\n if (readOnly) return;\n setEditingNodeIdRaw(id);\n }, [readOnly]);\n // Counter so concurrent drags (multi-node) don't flip the flag early.\n const dragCountRef = useRef(0);\n const [isNodeDragging, setIsNodeDragging] = useState(false);\n const beginNodeDrag = useCallback(() => {\n dragCountRef.current += 1;\n if (!isNodeDragging) setIsNodeDragging(true);\n }, [isNodeDragging]);\n const endNodeDrag = useCallback(() => {\n dragCountRef.current = Math.max(0, dragCountRef.current - 1);\n if (dragCountRef.current === 0) setIsNodeDragging(false);\n }, []);\n const [showPalette, setShowPalette] = useState(true);\n const [showInspector, setShowInspector] = useState(true);\n const [showOutline, setShowOutline] = useState(true);\n const [showJson, setShowJson] = useState(true);\n const [showAI, setShowAI] = useState(initShowAI);\n const [showMiniMap, setShowMiniMap] = useState(initMiniMap);\n const [showGrid, setShowGrid] = useState(initGrid);\n const [showAnchors, setShowAnchors] = useState(true);\n const [gridSize, setGridSize] = useState(initGridSize);\n const [placementSnap, setPlacementSnap] = useState(true);\n const [pendingPlacement, setPendingPlacementRaw] = useState<PendingPlacement | null>(null);\n const [contextMenu, setContextMenuRaw] = useState<ContextMenuState | null>(null);\n // Read-only: palette drops and the right-click menu are editing affordances.\n const setPendingPlacement = useCallback((p: PendingPlacement | null) => {\n if (readOnly) return;\n setPendingPlacementRaw(p);\n }, [readOnly]);\n const setContextMenu = useCallback((m: ContextMenuState | null) => {\n if (readOnly) return;\n setContextMenuRaw(m);\n }, [readOnly]);\n const [presentation, setPresentation] = useState<PresentationState | null>(null);\n const [panelDocks, setPanelDocks] = useState<Record<string, FlowPanelDock>>({});\n const setPanelDock = useCallback((tabId: string, dock: FlowPanelDock) => {\n setPanelDocks(prev => (prev[tabId] === dock ? prev : { ...prev, [tabId]: dock }));\n }, []);\n\n const focusOnRectRef = useRef<(wx: number, wy: number, ww: number, wh: number, options?: FocusOnRectOptions) => void>(() => {});\n const focusOnRect = useCallback((wx: number, wy: number, ww: number, wh: number, options?: FocusOnRectOptions) => {\n focusOnRectRef.current(wx, wy, ww, wh, options);\n }, []);\n const setFocusOnRect = useCallback((fn: (wx: number, wy: number, ww: number, wh: number, options?: FocusOnRectOptions) => void) => {\n focusOnRectRef.current = fn;\n }, []);\n\n const value = useMemo<FlowUIContextValue>(() => ({\n toolMode, setToolMode,\n edgeType, setEdgeType,\n viewport, setViewport,\n setViewportInternal,\n viewportReqRef,\n focusOnRect, setFocusOnRect,\n autoFocus, setAutoFocus,\n editingNodeId, setEditingNodeId,\n isNodeDragging, beginNodeDrag, endNodeDrag,\n showPalette, setShowPalette,\n showInspector, setShowInspector,\n showOutline, setShowOutline,\n showJson, setShowJson,\n showAI, setShowAI,\n showMiniMap, setShowMiniMap,\n showGrid, setShowGrid,\n showAnchors, setShowAnchors,\n gridSize, setGridSize,\n placementSnap, setPlacementSnap,\n pendingPlacement, setPendingPlacement,\n contextMenu, setContextMenu,\n presentation, setPresentation,\n panelDocks, setPanelDock,\n readOnly,\n }), [toolMode, edgeType, viewport, autoFocus, editingNodeId, isNodeDragging, beginNodeDrag, endNodeDrag, showPalette, showInspector, showOutline, showJson, showAI, showMiniMap, showGrid, showAnchors, gridSize, placementSnap, pendingPlacement, contextMenu, presentation, panelDocks, setPanelDock, readOnly]);\n\n return <FlowUIContext.Provider value={value}>{children}</FlowUIContext.Provider>;\n}\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { resolveThemeColor as E } from "../utils/themeColor.js";
2
+ import { drawDashedPath as y } from "../utils/dashedLine.js";
2
3
  import { buildEdgePath as T, getPathCenter as B, resolveEdgeEndpoints as M } from "./edgePaths.js";
3
4
  import { angleBetween as k, drawMarker as _ } from "./edgeMarkers.js";
4
- import { drawDashedPath as y } from "../utils/dashedLine.js";
5
5
  import { Container as v, Graphics as x, Text as L, TextStyle as O } from "pixi.js";
6
6
  function P(e, l, a = 2) {
7
7
  if (!(!e || e === "solid"))