dishui 0.0.45 → 0.0.46

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 (60) hide show
  1. package/dist/chart.js +46 -0
  2. package/dist/components/Chart/Chart.d.ts +17 -0
  3. package/dist/components/Chart/Chart.js +29 -0
  4. package/dist/components/Chart/Chart.js.map +1 -0
  5. package/dist/components/Chart/index.d.ts +15 -0
  6. package/dist/components/Input/index.js +2 -2
  7. package/dist/components/Input/index.js.map +1 -1
  8. package/dist/components/Select/index.js +1 -1
  9. package/dist/components/Select/index.js.map +1 -1
  10. package/dist/components/pro/Flow/Flow.js +492 -392
  11. package/dist/components/pro/Flow/Flow.js.map +1 -1
  12. package/dist/components/pro/Flow/FlowCanvas.js +895 -864
  13. package/dist/components/pro/Flow/FlowCanvas.js.map +1 -1
  14. package/dist/components/pro/Flow/context/FlowUIContext.d.ts +2 -0
  15. package/dist/components/pro/Flow/context/FlowUIContext.js +68 -65
  16. package/dist/components/pro/Flow/context/FlowUIContext.js.map +1 -1
  17. package/dist/components/pro/Flow/edges/edgePaths.js +234 -216
  18. package/dist/components/pro/Flow/edges/edgePaths.js.map +1 -1
  19. package/dist/components/pro/Flow/hooks/useKeyboardShortcuts.js +21 -10
  20. package/dist/components/pro/Flow/hooks/useKeyboardShortcuts.js.map +1 -1
  21. package/dist/components/pro/Flow/hooks/useMindMap.js +138 -134
  22. package/dist/components/pro/Flow/hooks/useMindMap.js.map +1 -1
  23. package/dist/components/pro/Flow/index.d.ts +1 -1
  24. package/dist/components/pro/Flow/nodes/MediaContent.js +47 -25
  25. package/dist/components/pro/Flow/nodes/MediaContent.js.map +1 -1
  26. package/dist/components/pro/Flow/nodes/Model3DView.d.ts +7 -0
  27. package/dist/components/pro/Flow/nodes/Model3DView.js +118 -0
  28. package/dist/components/pro/Flow/nodes/Model3DView.js.map +1 -0
  29. package/dist/components/pro/Flow/nodes/NodeHandles.d.ts +2 -1
  30. package/dist/components/pro/Flow/nodes/NodeHandles.js +4 -2
  31. package/dist/components/pro/Flow/nodes/NodeHandles.js.map +1 -1
  32. package/dist/components/pro/Flow/nodes/NodeRenderer.d.ts +2 -0
  33. package/dist/components/pro/Flow/nodes/NodeRenderer.js +115 -113
  34. package/dist/components/pro/Flow/nodes/NodeRenderer.js.map +1 -1
  35. package/dist/components/pro/Flow/nodes/NodeText.d.ts +3 -0
  36. package/dist/components/pro/Flow/nodes/NodeText.js +26 -17
  37. package/dist/components/pro/Flow/nodes/NodeText.js.map +1 -1
  38. package/dist/components/pro/Flow/panels/FlowToolbar.js +85 -79
  39. package/dist/components/pro/Flow/panels/FlowToolbar.js.map +1 -1
  40. package/dist/components/pro/Flow/panels/InspectorPanel.js +618 -488
  41. package/dist/components/pro/Flow/panels/InspectorPanel.js.map +1 -1
  42. package/dist/components/pro/Flow/panels/OutlinePanel.js +15 -15
  43. package/dist/components/pro/Flow/panels/OutlinePanel.js.map +1 -1
  44. package/dist/components/pro/Flow/panels/ShapePalette.js +71 -55
  45. package/dist/components/pro/Flow/panels/ShapePalette.js.map +1 -1
  46. package/dist/components/pro/Flow/panels/toolbarIcons.d.ts +1 -0
  47. package/dist/components/pro/Flow/panels/toolbarIcons.js +59 -41
  48. package/dist/components/pro/Flow/panels/toolbarIcons.js.map +1 -1
  49. package/dist/components/pro/Flow/types.d.ts +13 -4
  50. package/dist/components/pro/Flow/types.js.map +1 -1
  51. package/dist/dishui.css +1 -1
  52. package/dist/index-nostyled.d.ts +3 -1
  53. package/dist/index.d.ts +3 -1
  54. package/dist/index.js +145 -143
  55. package/dist/utils/i18n.d.ts +1 -0
  56. package/dist/utils/i18n.js +200 -6
  57. package/dist/utils/i18n.js.map +1 -1
  58. package/dist/utils/menu.js +26 -10
  59. package/dist/utils/menu.js.map +1 -1
  60. package/package.json +14 -3
@@ -1,119 +1,119 @@
1
- import oo from "../../../Button/index.js";
2
- import { useFlowContext as io } from "../context/FlowContext.js";
3
- import { useFlowUI as eo } from "../context/FlowUIContext.js";
4
- import { downloadDataURL as to, useFlowImportExport as no } from "../hooks/useFlowImportExport.js";
5
- import { useLayoutActions as lo } from "../hooks/useLayoutActions.js";
6
- import { IconAlign as t, IconAnchorVisible as co, IconBack as so, IconExport as ro, IconExportImage as ao, IconFitView as ho, IconGeoGroup as po, IconGrid as mo, IconGroup as uo, IconImport as wo, IconInspector as fo, IconJson as ko, IconMiniMap as Io, IconOutline as vo, IconPresent as Co, IconPublish as bo, IconRedo as No, IconShapes as So, IconUndo as zo, IconUngroup as Oo, IconZoomIn as yo, IconZoomOut as xo } from "./toolbarIcons.js";
7
- import { useCallback as C, useRef as go } from "react";
8
- import { Fragment as b, jsx as o, jsxs as d } from "react/jsx-runtime";
1
+ import eo from "../../../Button/index.js";
2
+ import { useFlowContext as to } from "../context/FlowContext.js";
3
+ import { useFlowUI as no } from "../context/FlowUIContext.js";
4
+ import { downloadDataURL as co, useFlowImportExport as lo } from "../hooks/useFlowImportExport.js";
5
+ import { useLayoutActions as so } from "../hooks/useLayoutActions.js";
6
+ import { IconAlign as t, IconAnchorVisible as ro, IconAutoFocus as ao, IconBack as ho, IconExport as po, IconExportImage as mo, IconFitView as uo, IconGeoGroup as wo, IconGrid as fo, IconGroup as ko, IconImport as Io, IconInspector as vo, IconJson as Co, IconMiniMap as bo, IconOutline as No, IconPresent as So, IconPublish as zo, IconRedo as Ao, IconShapes as Oo, IconUndo as yo, IconUngroup as xo, IconZoomIn as Fo, IconZoomOut as go } from "./toolbarIcons.js";
7
+ import { useCallback as b, useRef as Jo } from "react";
8
+ import { Fragment as N, jsx as o, jsxs as d } from "react/jsx-runtime";
9
9
  function i({ tip: a, shortcut: h, onClick: u, active: f, disabled: k, children: p }) {
10
- const c = h ? `${a} (${h})` : a;
10
+ const l = h ? `${a} (${h})` : a;
11
11
  return /* @__PURE__ */ d("span", {
12
12
  className: "flow-tip",
13
- children: [/* @__PURE__ */ o(oo, {
13
+ children: [/* @__PURE__ */ o(eo, {
14
14
  size: "xs",
15
15
  variant: f ? "primary" : "ghost",
16
16
  onClick: u,
17
17
  disabled: k,
18
18
  square: !0,
19
19
  children: /* @__PURE__ */ o("span", {
20
- "aria-label": c,
20
+ "aria-label": l,
21
21
  style: { display: "inline-flex" },
22
22
  children: p
23
23
  })
24
24
  }), /* @__PURE__ */ o("span", {
25
25
  className: "flow-tip-label",
26
26
  role: "tooltip",
27
- children: c
27
+ children: l
28
28
  })]
29
29
  });
30
30
  }
31
- function Po({ onBack: a, onUndo: h, onRedo: u, canUndo: f, canRedo: k, onGroup: p, onGeoGroup: c, onUngroup: I, onExportPNG: N, onPublish: S }) {
32
- const { viewport: m, setViewport: v, showGrid: z, setShowGrid: L, showPalette: O, setShowPalette: P, showInspector: y, setShowInspector: U, showOutline: x, setShowOutline: T, showJson: g, setShowJson: V, showMiniMap: A, setShowMiniMap: B, showAnchors: w, setShowAnchors: E, presentation: J, setPresentation: $ } = eo(), { doc: D, selection: n, currentCanvas: q } = io(), { exportJSON: j, importJSON: M } = no(), { align: s, distribute: R } = lo(), F = go(null), Z = n.nodeIds.size + n.lineIds.size, W = n.nodeIds.size > 0 && q.nodes.some((e) => n.nodeIds.has(e.id) && (e.type === "flowGroup" || e.type === "geometryGroup" || e.data.isGroup)), G = Object.values(D.canvases).some((e) => e.nodes.some((r) => r.type === "animAnchor")), H = Math.round(m.zoom * 100), K = () => {
31
+ function Vo({ onBack: a, onUndo: h, onRedo: u, canUndo: f, canRedo: k, onGroup: p, onGeoGroup: l, onUngroup: I, onExportPNG: S, onPublish: z }) {
32
+ const { viewport: m, setViewport: v, autoFocus: C, setAutoFocus: P, showGrid: A, setShowGrid: U, showPalette: O, setShowPalette: T, showInspector: y, setShowInspector: V, showOutline: x, setShowOutline: B, showJson: F, setShowJson: E, showMiniMap: g, setShowMiniMap: $, showAnchors: w, setShowAnchors: D, presentation: J, setPresentation: q } = no(), { doc: W, selection: n, currentCanvas: H } = to(), { exportJSON: j, importJSON: M } = lo(), { align: s, distribute: R } = so(), Z = Jo(null), G = n.nodeIds.size + n.lineIds.size, K = n.nodeIds.size > 0 && H.nodes.some((e) => n.nodeIds.has(e.id) && (e.type === "flowGroup" || e.type === "geometryGroup" || e.data.isGroup)), L = Object.values(W.canvases).some((e) => e.nodes.some((r) => r.type === "animAnchor")), Q = Math.round(m.zoom * 100), X = () => {
33
33
  const e = Math.min(4, m.zoom * 1.2);
34
34
  v({
35
35
  ...m,
36
36
  zoom: e
37
37
  });
38
- }, Q = () => {
38
+ }, Y = () => {
39
39
  const e = Math.max(0.1, m.zoom / 1.2);
40
40
  v({
41
41
  ...m,
42
42
  zoom: e
43
43
  });
44
- }, X = () => {
44
+ }, _ = () => {
45
45
  v({
46
46
  x: 0,
47
47
  y: 0,
48
48
  zoom: 1
49
49
  });
50
- }, Y = C(() => {
51
- const e = j(), r = new Blob([e], { type: "application/json" }), l = URL.createObjectURL(r);
52
- to(l, `flowchart-${Date.now()}.json`), URL.revokeObjectURL(l);
53
- }, [j]), _ = C(() => {
54
- F.current?.click();
50
+ }, oo = b(() => {
51
+ const e = j(), r = new Blob([e], { type: "application/json" }), c = URL.createObjectURL(r);
52
+ co(c, `flowchart-${Date.now()}.json`), URL.revokeObjectURL(c);
53
+ }, [j]), io = b(() => {
54
+ Z.current?.click();
55
55
  }, []);
56
56
  return /* @__PURE__ */ d("div", {
57
57
  className: "flow-toolbar",
58
58
  children: [
59
59
  /* @__PURE__ */ o("input", {
60
- ref: F,
60
+ ref: Z,
61
61
  type: "file",
62
62
  accept: ".json",
63
63
  style: { display: "none" },
64
- onChange: C((e) => {
64
+ onChange: b((e) => {
65
65
  const r = e.target.files?.[0];
66
66
  if (!r) return;
67
- const l = new FileReader();
68
- l.onload = () => {
69
- typeof l.result == "string" && M(l.result);
70
- }, l.readAsText(r), e.target.value = "";
67
+ const c = new FileReader();
68
+ c.onload = () => {
69
+ typeof c.result == "string" && M(c.result);
70
+ }, c.readAsText(r), e.target.value = "";
71
71
  }, [M])
72
72
  }),
73
- a && /* @__PURE__ */ d(b, { children: [/* @__PURE__ */ o(i, {
73
+ a && /* @__PURE__ */ d(N, { children: [/* @__PURE__ */ o(i, {
74
74
  tip: "返回列表",
75
75
  onClick: a,
76
- children: /* @__PURE__ */ o(so, {})
76
+ children: /* @__PURE__ */ o(ho, {})
77
77
  }), /* @__PURE__ */ o("div", { className: "flow-toolbar-divider" })] }),
78
78
  h && /* @__PURE__ */ o(i, {
79
79
  tip: "撤销",
80
80
  shortcut: "Ctrl+Z",
81
81
  onClick: h,
82
82
  disabled: !f,
83
- children: /* @__PURE__ */ o(zo, {})
83
+ children: /* @__PURE__ */ o(yo, {})
84
84
  }),
85
85
  u && /* @__PURE__ */ o(i, {
86
86
  tip: "重做",
87
87
  shortcut: "Ctrl+Shift+Z",
88
88
  onClick: u,
89
89
  disabled: !k,
90
- children: /* @__PURE__ */ o(No, {})
90
+ children: /* @__PURE__ */ o(Ao, {})
91
91
  }),
92
- (p || c || I) && /* @__PURE__ */ d(b, { children: [
92
+ (p || l || I) && /* @__PURE__ */ d(N, { children: [
93
93
  /* @__PURE__ */ o("div", { className: "flow-toolbar-divider" }),
94
94
  p && /* @__PURE__ */ o(i, {
95
95
  tip: "成组",
96
96
  shortcut: "⌘G",
97
97
  onClick: p,
98
- disabled: Z < 2,
99
- children: /* @__PURE__ */ o(uo, {})
98
+ disabled: G < 2,
99
+ children: /* @__PURE__ */ o(ko, {})
100
100
  }),
101
- c && /* @__PURE__ */ o(i, {
101
+ l && /* @__PURE__ */ o(i, {
102
102
  tip: "几何分组",
103
103
  shortcut: "⌘⌥G",
104
- onClick: c,
105
- disabled: Z < 2,
106
- children: /* @__PURE__ */ o(po, {})
104
+ onClick: l,
105
+ disabled: G < 2,
106
+ children: /* @__PURE__ */ o(wo, {})
107
107
  }),
108
108
  I && /* @__PURE__ */ o(i, {
109
109
  tip: "取消成组",
110
110
  shortcut: "⌘⇧G",
111
111
  onClick: I,
112
- disabled: !W,
113
- children: /* @__PURE__ */ o(Oo, {})
112
+ disabled: !K,
113
+ children: /* @__PURE__ */ o(xo, {})
114
114
  })
115
115
  ] }),
116
- n.nodeIds.size >= 2 && /* @__PURE__ */ d(b, { children: [
116
+ n.nodeIds.size >= 2 && /* @__PURE__ */ d(N, { children: [
117
117
  /* @__PURE__ */ o("div", { className: "flow-toolbar-divider" }),
118
118
  /* @__PURE__ */ o(i, {
119
119
  tip: "居左",
@@ -161,108 +161,114 @@ function Po({ onBack: a, onUndo: h, onRedo: u, canUndo: f, canRedo: k, onGroup:
161
161
  /* @__PURE__ */ o("div", { className: "flow-toolbar-divider" }),
162
162
  /* @__PURE__ */ o(i, {
163
163
  tip: "缩小",
164
- onClick: Q,
165
- children: /* @__PURE__ */ o(xo, {})
164
+ onClick: Y,
165
+ children: /* @__PURE__ */ o(go, {})
166
166
  }),
167
167
  /* @__PURE__ */ d("span", {
168
168
  className: "flow-zoom-info",
169
- children: [H, "%"]
169
+ children: [Q, "%"]
170
170
  }),
171
171
  /* @__PURE__ */ o(i, {
172
172
  tip: "放大",
173
- onClick: K,
174
- children: /* @__PURE__ */ o(yo, {})
173
+ onClick: X,
174
+ children: /* @__PURE__ */ o(Fo, {})
175
175
  }),
176
176
  /* @__PURE__ */ o(i, {
177
177
  tip: "适应视图",
178
- onClick: X,
179
- children: /* @__PURE__ */ o(ho, {})
178
+ onClick: _,
179
+ children: /* @__PURE__ */ o(uo, {})
180
+ }),
181
+ /* @__PURE__ */ o(i, {
182
+ tip: C ? "关闭 Auto Focus" : "开启 Auto Focus",
183
+ active: C,
184
+ onClick: () => P(!C),
185
+ children: /* @__PURE__ */ o(ao, {})
180
186
  }),
181
187
  /* @__PURE__ */ o("div", { className: "flow-toolbar-divider" }),
182
188
  /* @__PURE__ */ o(i, {
183
189
  tip: "形状面板",
184
190
  active: O,
185
- onClick: () => P(!O),
186
- children: /* @__PURE__ */ o(So, {})
191
+ onClick: () => T(!O),
192
+ children: /* @__PURE__ */ o(Oo, {})
187
193
  }),
188
194
  /* @__PURE__ */ o(i, {
189
195
  tip: "属性面板",
190
196
  active: y,
191
- onClick: () => U(!y),
192
- children: /* @__PURE__ */ o(fo, {})
197
+ onClick: () => V(!y),
198
+ children: /* @__PURE__ */ o(vo, {})
193
199
  }),
194
200
  /* @__PURE__ */ o(i, {
195
201
  tip: "大纲",
196
202
  active: x,
197
- onClick: () => T(!x),
198
- children: /* @__PURE__ */ o(vo, {})
203
+ onClick: () => B(!x),
204
+ children: /* @__PURE__ */ o(No, {})
199
205
  }),
200
206
  /* @__PURE__ */ o(i, {
201
207
  tip: "JSON",
202
- active: g,
203
- onClick: () => V(!g),
204
- children: /* @__PURE__ */ o(ko, {})
208
+ active: F,
209
+ onClick: () => E(!F),
210
+ children: /* @__PURE__ */ o(Co, {})
205
211
  }),
206
212
  /* @__PURE__ */ o("div", { className: "flow-toolbar-divider" }),
207
213
  /* @__PURE__ */ o(i, {
208
214
  tip: "网格",
209
- active: z,
210
- onClick: () => L(!z),
211
- children: /* @__PURE__ */ o(mo, {})
215
+ active: A,
216
+ onClick: () => U(!A),
217
+ children: /* @__PURE__ */ o(fo, {})
212
218
  }),
213
219
  /* @__PURE__ */ o(i, {
214
220
  tip: "缩略图",
215
- active: A,
216
- onClick: () => B(!A),
217
- children: /* @__PURE__ */ o(Io, {})
221
+ active: g,
222
+ onClick: () => $(!g),
223
+ children: /* @__PURE__ */ o(bo, {})
218
224
  }),
219
225
  /* @__PURE__ */ o(i, {
220
226
  tip: w ? "隐藏所有 Anchor 对象" : "显示所有 Anchor 对象",
221
227
  active: w,
222
- disabled: !G,
228
+ disabled: !L,
223
229
  onClick: () => {
224
- G && E(!w);
230
+ L && D(!w);
225
231
  },
226
- children: /* @__PURE__ */ o(co, { visible: w })
232
+ children: /* @__PURE__ */ o(ro, { visible: w })
227
233
  }),
228
234
  /* @__PURE__ */ o("div", { className: "flow-toolbar-divider" }),
229
235
  /* @__PURE__ */ o(i, {
230
236
  tip: "动画预览",
231
237
  active: J !== null,
232
- onClick: () => $(J ? null : {
238
+ onClick: () => q(J ? null : {
233
239
  current: 0,
234
240
  showAnchor: !1
235
241
  }),
236
- children: /* @__PURE__ */ o(Co, {})
242
+ children: /* @__PURE__ */ o(So, {})
237
243
  }),
238
244
  /* @__PURE__ */ o("div", { className: "flow-toolbar-divider" }),
239
245
  /* @__PURE__ */ o(i, {
240
246
  tip: "导入 JSON",
241
- onClick: _,
242
- children: /* @__PURE__ */ o(wo, {})
247
+ onClick: io,
248
+ children: /* @__PURE__ */ o(Io, {})
243
249
  }),
244
250
  /* @__PURE__ */ o(i, {
245
251
  tip: "导出 JSON",
246
- onClick: Y,
247
- children: /* @__PURE__ */ o(ro, {})
252
+ onClick: oo,
253
+ children: /* @__PURE__ */ o(po, {})
248
254
  }),
249
- N && /* @__PURE__ */ o(i, {
255
+ S && /* @__PURE__ */ o(i, {
250
256
  tip: "导出 PNG",
251
257
  onClick: () => {
252
- N();
258
+ S();
253
259
  },
254
- children: /* @__PURE__ */ o(ao, {})
260
+ children: /* @__PURE__ */ o(mo, {})
255
261
  }),
256
- S && /* @__PURE__ */ o(i, {
262
+ z && /* @__PURE__ */ o(i, {
257
263
  tip: "发布与共享",
258
- onClick: S,
259
- children: /* @__PURE__ */ o(bo, {})
264
+ onClick: z,
265
+ children: /* @__PURE__ */ o(zo, {})
260
266
  })
261
267
  ]
262
268
  });
263
269
  }
264
270
  export {
265
- Po as default
271
+ Vo as default
266
272
  };
267
273
 
268
274
  //# sourceMappingURL=FlowToolbar.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"FlowToolbar.js","names":[],"sources":["../../../../../src/components/pro/Flow/panels/FlowToolbar.tsx"],"sourcesContent":["import React, { useRef, useCallback } from 'react';\nimport Button from '../../../Button';\nimport { useFlowUI } from '../context/FlowUIContext';\nimport { useFlowContext } from '../context/FlowContext';\nimport { useFlowImportExport, downloadDataURL } from '../hooks/useFlowImportExport';\nimport { useLayoutActions } from '../hooks/useLayoutActions';\n\nimport {\n IconBack,\n IconUndo,\n IconRedo,\n IconGroup,\n IconGeoGroup,\n IconUngroup,\n IconAlign,\n IconZoomIn,\n IconZoomOut,\n IconFitView,\n IconShapes,\n IconInspector,\n IconOutline,\n IconJson,\n IconGrid,\n IconMiniMap,\n IconImport,\n IconExport,\n IconExportImage,\n IconPublish,\n IconAnchorVisible,\n IconPresent,\n} from './toolbarIcons';\n\n\n/** A toolbar button with an accessible, hover-revealed tooltip below it. */\ninterface ToolButtonProps {\n tip: string;\n shortcut?: string;\n onClick: () => void;\n active?: boolean;\n disabled?: boolean;\n children: React.ReactNode;\n}\n\nfunction ToolButton({ tip, shortcut, onClick, active, disabled, children }: ToolButtonProps) {\n const label = shortcut ? `${tip} (${shortcut})` : tip;\n return (\n <span className=\"flow-tip\">\n <Button\n size=\"xs\"\n variant={active ? 'primary' : 'ghost'}\n onClick={onClick}\n disabled={disabled}\n square\n >\n <span aria-label={label} style={{ display: 'inline-flex' }}>{children}</span>\n </Button>\n <span className=\"flow-tip-label\" role=\"tooltip\">{label}</span>\n </span>\n );\n}\n\nexport interface FlowToolbarProps {\n onBack?: () => void;\n onUndo?: () => void;\n onRedo?: () => void;\n canUndo?: boolean;\n canRedo?: boolean;\n onGroup?: () => void;\n onGeoGroup?: () => void;\n onUngroup?: () => void;\n onExportPNG?: () => void | Promise<void>;\n onPublish?: () => void;\n}\n\nexport default function FlowToolbar({ onBack, onUndo, onRedo, canUndo, canRedo, onGroup, onGeoGroup, onUngroup, onExportPNG, onPublish }: FlowToolbarProps) {\n const {\n viewport, setViewport,\n showGrid, setShowGrid,\n showPalette, setShowPalette,\n showInspector, setShowInspector,\n showOutline, setShowOutline,\n showJson, setShowJson,\n showMiniMap, setShowMiniMap,\n showAnchors, setShowAnchors,\n presentation, setPresentation,\n } = useFlowUI();\n const { doc, selection, currentCanvas } = useFlowContext();\n const { exportJSON, importJSON } = useFlowImportExport();\n const { align, distribute } = useLayoutActions();\n const fileInputRef = useRef<HTMLInputElement>(null);\n\n const selTotalCount = selection.nodeIds.size + selection.lineIds.size;\n const hasGroupSelected = selection.nodeIds.size > 0 && currentCanvas.nodes.some(\n n => selection.nodeIds.has(n.id) && (n.type === 'flowGroup' || n.type === 'geometryGroup' || n.data.isGroup),\n );\n const hasAnchors = Object.values(doc.canvases).some(canvas =>\n canvas.nodes.some(node => node.type === 'animAnchor'),\n );\n\n\n const zoomPercent = Math.round(viewport.zoom * 100);\n\n const handleZoomIn = () => {\n const newZoom = Math.min(4, viewport.zoom * 1.2);\n setViewport({ ...viewport, zoom: newZoom });\n };\n\n const handleZoomOut = () => {\n const newZoom = Math.max(0.1, viewport.zoom / 1.2);\n setViewport({ ...viewport, zoom: newZoom });\n };\n\n const handleFitView = () => {\n setViewport({ x: 0, y: 0, zoom: 1 });\n };\n\n const handleExportJSON = useCallback(() => {\n const json = exportJSON();\n const blob = new Blob([json], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n downloadDataURL(url, `flowchart-${Date.now()}.json`);\n URL.revokeObjectURL(url);\n }, [exportJSON]);\n\n const handleImportJSON = useCallback(() => {\n fileInputRef.current?.click();\n }, []);\n\n const handleFileChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (!file) return;\n const reader = new FileReader();\n reader.onload = () => {\n if (typeof reader.result === 'string') importJSON(reader.result);\n };\n reader.readAsText(file);\n e.target.value = '';\n }, [importJSON]);\n\n return (\n <div className=\"flow-toolbar\">\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\".json\"\n style={{ display: 'none' }}\n onChange={handleFileChange}\n />\n\n {onBack && (\n <>\n <ToolButton tip=\"返回列表\" onClick={onBack}>\n <IconBack />\n </ToolButton>\n <div className=\"flow-toolbar-divider\" />\n </>\n )}\n\n {/* Undo / Redo */}\n {onUndo && (\n <ToolButton tip=\"撤销\" shortcut=\"Ctrl+Z\" onClick={onUndo} disabled={!canUndo}>\n <IconUndo />\n </ToolButton>\n )}\n {onRedo && (\n <ToolButton tip=\"重做\" shortcut=\"Ctrl+Shift+Z\" onClick={onRedo} disabled={!canRedo}>\n <IconRedo />\n </ToolButton>\n )}\n\n {/* Group / Ungroup */}\n {(onGroup || onGeoGroup || onUngroup) && (\n <>\n <div className=\"flow-toolbar-divider\" />\n {onGroup && (\n <ToolButton tip=\"成组\" shortcut=\"⌘G\" onClick={onGroup} disabled={selTotalCount < 2}>\n <IconGroup />\n </ToolButton>\n )}\n {onGeoGroup && (\n <ToolButton tip=\"几何分组\" shortcut=\"⌘⌥G\" onClick={onGeoGroup} disabled={selTotalCount < 2}>\n <IconGeoGroup />\n </ToolButton>\n )}\n {onUngroup && (\n <ToolButton tip=\"取消成组\" shortcut=\"⌘⇧G\" onClick={onUngroup} disabled={!hasGroupSelected}>\n <IconUngroup />\n </ToolButton>\n )}\n </>\n )}\n\n {selection.nodeIds.size >= 2 && (\n <>\n <div className=\"flow-toolbar-divider\" />\n <ToolButton tip=\"居左\" onClick={() => align('left')}><IconAlign kind=\"left\" /></ToolButton>\n <ToolButton tip=\"水平居中\" onClick={() => align('center-h')}><IconAlign kind=\"center-h\" /></ToolButton>\n <ToolButton tip=\"居右\" onClick={() => align('right')}><IconAlign kind=\"right\" /></ToolButton>\n <ToolButton tip=\"居上\" onClick={() => align('top')}><IconAlign kind=\"top\" /></ToolButton>\n <ToolButton tip=\"垂直居中\" onClick={() => align('center-v')}><IconAlign kind=\"center-v\" /></ToolButton>\n <ToolButton tip=\"居下\" onClick={() => align('bottom')}><IconAlign kind=\"bottom\" /></ToolButton>\n <ToolButton tip=\"水平平分\" onClick={() => distribute('horizontal')} disabled={selection.nodeIds.size < 3}>\n <IconAlign kind=\"distribute-h\" />\n </ToolButton>\n <ToolButton tip=\"垂直平分\" onClick={() => distribute('vertical')} disabled={selection.nodeIds.size < 3}>\n <IconAlign kind=\"distribute-v\" />\n </ToolButton>\n </>\n )}\n\n <div className=\"flow-toolbar-divider\" />\n\n {/* Zoom */}\n <ToolButton tip=\"缩小\" onClick={handleZoomOut}>\n <IconZoomOut />\n </ToolButton>\n <span className=\"flow-zoom-info\">{zoomPercent}%</span>\n <ToolButton tip=\"放大\" onClick={handleZoomIn}>\n <IconZoomIn />\n </ToolButton>\n <ToolButton tip=\"适应视图\" onClick={handleFitView}>\n <IconFitView />\n </ToolButton>\n\n <div className=\"flow-toolbar-divider\" />\n\n {/* Panel toggles */}\n <ToolButton tip=\"形状面板\" active={showPalette} onClick={() => setShowPalette(!showPalette)}>\n <IconShapes />\n </ToolButton>\n <ToolButton tip=\"属性面板\" active={showInspector} onClick={() => setShowInspector(!showInspector)}>\n <IconInspector />\n </ToolButton>\n <ToolButton tip=\"大纲\" active={showOutline} onClick={() => setShowOutline(!showOutline)}>\n <IconOutline />\n </ToolButton>\n <ToolButton tip=\"JSON\" active={showJson} onClick={() => setShowJson(!showJson)}>\n <IconJson />\n </ToolButton>\n\n <div className=\"flow-toolbar-divider\" />\n\n {/* Canvas view toggles */}\n <ToolButton tip=\"网格\" active={showGrid} onClick={() => setShowGrid(!showGrid)}>\n <IconGrid />\n </ToolButton>\n <ToolButton tip=\"缩略图\" active={showMiniMap} onClick={() => setShowMiniMap(!showMiniMap)}>\n <IconMiniMap />\n </ToolButton>\n <ToolButton\n tip={showAnchors ? '隐藏所有 Anchor 对象' : '显示所有 Anchor 对象'}\n active={showAnchors}\n disabled={!hasAnchors}\n onClick={() => {\n if (hasAnchors) setShowAnchors(!showAnchors);\n }}\n >\n <IconAnchorVisible visible={showAnchors} />\n </ToolButton>\n\n <div className=\"flow-toolbar-divider\" />\n\n {/* Presentation mode */}\n <ToolButton\n tip=\"动画预览\"\n active={presentation !== null}\n onClick={() => setPresentation(presentation ? null : { current: 0, showAnchor: false })}\n >\n <IconPresent />\n </ToolButton>\n\n <div className=\"flow-toolbar-divider\" />\n\n {/* Import / Export */}\n <ToolButton tip=\"导入 JSON\" onClick={handleImportJSON}>\n <IconImport />\n </ToolButton>\n <ToolButton tip=\"导出 JSON\" onClick={handleExportJSON}>\n <IconExport />\n </ToolButton>\n {onExportPNG && (\n <ToolButton tip=\"导出 PNG\" onClick={() => void onExportPNG()}>\n <IconExportImage />\n </ToolButton>\n )}\n {onPublish && (\n <ToolButton tip=\"发布与共享\" onClick={onPublish}>\n <IconPublish />\n </ToolButton>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"FlowToolbar.js","names":[],"sources":["../../../../../src/components/pro/Flow/panels/FlowToolbar.tsx"],"sourcesContent":["import React, { useRef, useCallback } from 'react';\nimport Button from '../../../Button';\nimport { useFlowUI } from '../context/FlowUIContext';\nimport { useFlowContext } from '../context/FlowContext';\nimport { useFlowImportExport, downloadDataURL } from '../hooks/useFlowImportExport';\nimport { useLayoutActions } from '../hooks/useLayoutActions';\n\nimport {\n IconBack,\n IconUndo,\n IconRedo,\n IconGroup,\n IconGeoGroup,\n IconUngroup,\n IconAlign,\n IconZoomIn,\n IconZoomOut,\n IconFitView,\n IconAutoFocus,\n IconShapes,\n IconInspector,\n IconOutline,\n IconJson,\n IconGrid,\n IconMiniMap,\n IconImport,\n IconExport,\n IconExportImage,\n IconPublish,\n IconAnchorVisible,\n IconPresent,\n} from './toolbarIcons';\n\n\n/** A toolbar button with an accessible, hover-revealed tooltip below it. */\ninterface ToolButtonProps {\n tip: string;\n shortcut?: string;\n onClick: () => void;\n active?: boolean;\n disabled?: boolean;\n children: React.ReactNode;\n}\n\nfunction ToolButton({ tip, shortcut, onClick, active, disabled, children }: ToolButtonProps) {\n const label = shortcut ? `${tip} (${shortcut})` : tip;\n return (\n <span className=\"flow-tip\">\n <Button\n size=\"xs\"\n variant={active ? 'primary' : 'ghost'}\n onClick={onClick}\n disabled={disabled}\n square\n >\n <span aria-label={label} style={{ display: 'inline-flex' }}>{children}</span>\n </Button>\n <span className=\"flow-tip-label\" role=\"tooltip\">{label}</span>\n </span>\n );\n}\n\nexport interface FlowToolbarProps {\n onBack?: () => void;\n onUndo?: () => void;\n onRedo?: () => void;\n canUndo?: boolean;\n canRedo?: boolean;\n onGroup?: () => void;\n onGeoGroup?: () => void;\n onUngroup?: () => void;\n onExportPNG?: () => void | Promise<void>;\n onPublish?: () => void;\n}\n\nexport default function FlowToolbar({ onBack, onUndo, onRedo, canUndo, canRedo, onGroup, onGeoGroup, onUngroup, onExportPNG, onPublish }: FlowToolbarProps) {\n const {\n viewport, setViewport,\n autoFocus, setAutoFocus,\n showGrid, setShowGrid,\n showPalette, setShowPalette,\n showInspector, setShowInspector,\n showOutline, setShowOutline,\n showJson, setShowJson,\n showMiniMap, setShowMiniMap,\n showAnchors, setShowAnchors,\n presentation, setPresentation,\n } = useFlowUI();\n const { doc, selection, currentCanvas } = useFlowContext();\n const { exportJSON, importJSON } = useFlowImportExport();\n const { align, distribute } = useLayoutActions();\n const fileInputRef = useRef<HTMLInputElement>(null);\n\n const selTotalCount = selection.nodeIds.size + selection.lineIds.size;\n const hasGroupSelected = selection.nodeIds.size > 0 && currentCanvas.nodes.some(\n n => selection.nodeIds.has(n.id) && (n.type === 'flowGroup' || n.type === 'geometryGroup' || n.data.isGroup),\n );\n const hasAnchors = Object.values(doc.canvases).some(canvas =>\n canvas.nodes.some(node => node.type === 'animAnchor'),\n );\n\n\n const zoomPercent = Math.round(viewport.zoom * 100);\n\n const handleZoomIn = () => {\n const newZoom = Math.min(4, viewport.zoom * 1.2);\n setViewport({ ...viewport, zoom: newZoom });\n };\n\n const handleZoomOut = () => {\n const newZoom = Math.max(0.1, viewport.zoom / 1.2);\n setViewport({ ...viewport, zoom: newZoom });\n };\n\n const handleFitView = () => {\n setViewport({ x: 0, y: 0, zoom: 1 });\n };\n\n const handleExportJSON = useCallback(() => {\n const json = exportJSON();\n const blob = new Blob([json], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n downloadDataURL(url, `flowchart-${Date.now()}.json`);\n URL.revokeObjectURL(url);\n }, [exportJSON]);\n\n const handleImportJSON = useCallback(() => {\n fileInputRef.current?.click();\n }, []);\n\n const handleFileChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (!file) return;\n const reader = new FileReader();\n reader.onload = () => {\n if (typeof reader.result === 'string') importJSON(reader.result);\n };\n reader.readAsText(file);\n e.target.value = '';\n }, [importJSON]);\n\n return (\n <div className=\"flow-toolbar\">\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\".json\"\n style={{ display: 'none' }}\n onChange={handleFileChange}\n />\n\n {onBack && (\n <>\n <ToolButton tip=\"返回列表\" onClick={onBack}>\n <IconBack />\n </ToolButton>\n <div className=\"flow-toolbar-divider\" />\n </>\n )}\n\n {/* Undo / Redo */}\n {onUndo && (\n <ToolButton tip=\"撤销\" shortcut=\"Ctrl+Z\" onClick={onUndo} disabled={!canUndo}>\n <IconUndo />\n </ToolButton>\n )}\n {onRedo && (\n <ToolButton tip=\"重做\" shortcut=\"Ctrl+Shift+Z\" onClick={onRedo} disabled={!canRedo}>\n <IconRedo />\n </ToolButton>\n )}\n\n {/* Group / Ungroup */}\n {(onGroup || onGeoGroup || onUngroup) && (\n <>\n <div className=\"flow-toolbar-divider\" />\n {onGroup && (\n <ToolButton tip=\"成组\" shortcut=\"⌘G\" onClick={onGroup} disabled={selTotalCount < 2}>\n <IconGroup />\n </ToolButton>\n )}\n {onGeoGroup && (\n <ToolButton tip=\"几何分组\" shortcut=\"⌘⌥G\" onClick={onGeoGroup} disabled={selTotalCount < 2}>\n <IconGeoGroup />\n </ToolButton>\n )}\n {onUngroup && (\n <ToolButton tip=\"取消成组\" shortcut=\"⌘⇧G\" onClick={onUngroup} disabled={!hasGroupSelected}>\n <IconUngroup />\n </ToolButton>\n )}\n </>\n )}\n\n {selection.nodeIds.size >= 2 && (\n <>\n <div className=\"flow-toolbar-divider\" />\n <ToolButton tip=\"居左\" onClick={() => align('left')}><IconAlign kind=\"left\" /></ToolButton>\n <ToolButton tip=\"水平居中\" onClick={() => align('center-h')}><IconAlign kind=\"center-h\" /></ToolButton>\n <ToolButton tip=\"居右\" onClick={() => align('right')}><IconAlign kind=\"right\" /></ToolButton>\n <ToolButton tip=\"居上\" onClick={() => align('top')}><IconAlign kind=\"top\" /></ToolButton>\n <ToolButton tip=\"垂直居中\" onClick={() => align('center-v')}><IconAlign kind=\"center-v\" /></ToolButton>\n <ToolButton tip=\"居下\" onClick={() => align('bottom')}><IconAlign kind=\"bottom\" /></ToolButton>\n <ToolButton tip=\"水平平分\" onClick={() => distribute('horizontal')} disabled={selection.nodeIds.size < 3}>\n <IconAlign kind=\"distribute-h\" />\n </ToolButton>\n <ToolButton tip=\"垂直平分\" onClick={() => distribute('vertical')} disabled={selection.nodeIds.size < 3}>\n <IconAlign kind=\"distribute-v\" />\n </ToolButton>\n </>\n )}\n\n <div className=\"flow-toolbar-divider\" />\n\n {/* Zoom */}\n <ToolButton tip=\"缩小\" onClick={handleZoomOut}>\n <IconZoomOut />\n </ToolButton>\n <span className=\"flow-zoom-info\">{zoomPercent}%</span>\n <ToolButton tip=\"放大\" onClick={handleZoomIn}>\n <IconZoomIn />\n </ToolButton>\n <ToolButton tip=\"适应视图\" onClick={handleFitView}>\n <IconFitView />\n </ToolButton>\n <ToolButton\n tip={autoFocus ? '关闭 Auto Focus' : '开启 Auto Focus'}\n active={autoFocus}\n onClick={() => setAutoFocus(!autoFocus)}\n >\n <IconAutoFocus />\n </ToolButton>\n\n <div className=\"flow-toolbar-divider\" />\n\n {/* Panel toggles */}\n <ToolButton tip=\"形状面板\" active={showPalette} onClick={() => setShowPalette(!showPalette)}>\n <IconShapes />\n </ToolButton>\n <ToolButton tip=\"属性面板\" active={showInspector} onClick={() => setShowInspector(!showInspector)}>\n <IconInspector />\n </ToolButton>\n <ToolButton tip=\"大纲\" active={showOutline} onClick={() => setShowOutline(!showOutline)}>\n <IconOutline />\n </ToolButton>\n <ToolButton tip=\"JSON\" active={showJson} onClick={() => setShowJson(!showJson)}>\n <IconJson />\n </ToolButton>\n\n <div className=\"flow-toolbar-divider\" />\n\n {/* Canvas view toggles */}\n <ToolButton tip=\"网格\" active={showGrid} onClick={() => setShowGrid(!showGrid)}>\n <IconGrid />\n </ToolButton>\n <ToolButton tip=\"缩略图\" active={showMiniMap} onClick={() => setShowMiniMap(!showMiniMap)}>\n <IconMiniMap />\n </ToolButton>\n <ToolButton\n tip={showAnchors ? '隐藏所有 Anchor 对象' : '显示所有 Anchor 对象'}\n active={showAnchors}\n disabled={!hasAnchors}\n onClick={() => {\n if (hasAnchors) setShowAnchors(!showAnchors);\n }}\n >\n <IconAnchorVisible visible={showAnchors} />\n </ToolButton>\n\n <div className=\"flow-toolbar-divider\" />\n\n {/* Presentation mode */}\n <ToolButton\n tip=\"动画预览\"\n active={presentation !== null}\n onClick={() => setPresentation(presentation ? null : { current: 0, showAnchor: false })}\n >\n <IconPresent />\n </ToolButton>\n\n <div className=\"flow-toolbar-divider\" />\n\n {/* Import / Export */}\n <ToolButton tip=\"导入 JSON\" onClick={handleImportJSON}>\n <IconImport />\n </ToolButton>\n <ToolButton tip=\"导出 JSON\" onClick={handleExportJSON}>\n <IconExport />\n </ToolButton>\n {onExportPNG && (\n <ToolButton tip=\"导出 PNG\" onClick={() => void onExportPNG()}>\n <IconExportImage />\n </ToolButton>\n )}\n {onPublish && (\n <ToolButton tip=\"发布与共享\" onClick={onPublish}>\n <IconPublish />\n </ToolButton>\n )}\n </div>\n );\n}\n"],"mappings":"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"}