dishui 0.0.43 → 0.0.45

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.
@@ -3,16 +3,16 @@ import { useFlowContext as io } from "../context/FlowContext.js";
3
3
  import { useFlowUI as eo } from "../context/FlowUIContext.js";
4
4
  import { downloadDataURL as to, useFlowImportExport as no } from "../hooks/useFlowImportExport.js";
5
5
  import { useLayoutActions as lo } from "../hooks/useLayoutActions.js";
6
- import { IconAlign as t, IconAnchorVisible as co, IconBack as ro, IconExport as so, IconExportImage as ao, IconFitView as ho, IconGeoGroup as po, IconGrid as mo, IconGroup as uo, IconImport as fo, IconInspector as wo, 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";
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
7
  import { useCallback as C, useRef as go } from "react";
8
8
  import { Fragment as b, jsx as o, jsxs as d } from "react/jsx-runtime";
9
- function i({ tip: a, shortcut: h, onClick: u, active: w, disabled: k, children: p }) {
9
+ function i({ tip: a, shortcut: h, onClick: u, active: f, disabled: k, children: p }) {
10
10
  const c = h ? `${a} (${h})` : a;
11
11
  return /* @__PURE__ */ d("span", {
12
12
  className: "flow-tip",
13
13
  children: [/* @__PURE__ */ o(oo, {
14
14
  size: "xs",
15
- variant: w ? "primary" : "ghost",
15
+ variant: f ? "primary" : "ghost",
16
16
  onClick: u,
17
17
  disabled: k,
18
18
  square: !0,
@@ -28,8 +28,8 @@ function i({ tip: a, shortcut: h, onClick: u, active: w, disabled: k, children:
28
28
  })]
29
29
  });
30
30
  }
31
- function Po({ onBack: a, onUndo: h, onRedo: u, canUndo: w, canRedo: k, onGroup: p, onGeoGroup: c, onUngroup: I, onExportPNG: N, onPublish: S }) {
32
- const { viewport: m, setViewport: v, showGrid: z, setShowGrid: G, showPalette: O, setShowPalette: L, showInspector: y, setShowInspector: P, showOutline: x, setShowOutline: U, showJson: g, setShowJson: T, showMiniMap: A, setShowMiniMap: V, showAnchors: f, setShowAnchors: B, presentation: J, setPresentation: E } = eo(), { doc: $, selection: n, currentCanvas: D } = io(), { exportJSON: M, importJSON: j } = no(), { align: r, distribute: R } = lo(), F = go(null), Z = n.nodeIds.size + n.lineIds.size, q = n.nodeIds.size > 0 && D.nodes.some((e) => n.nodeIds.has(e.id) && (e.type === "flowGroup" || e.type === "geometryGroup" || e.data.isGroup)), W = Object.values($.canvases).flatMap((e) => e.nodes.filter((s) => s.type === "animAnchor")), H = Math.round(m.zoom * 100), K = () => {
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 = () => {
33
33
  const e = Math.min(4, m.zoom * 1.2);
34
34
  v({
35
35
  ...m,
@@ -48,9 +48,9 @@ function Po({ onBack: a, onUndo: h, onRedo: u, canUndo: w, canRedo: k, onGroup:
48
48
  zoom: 1
49
49
  });
50
50
  }, Y = C(() => {
51
- const e = M(), s = new Blob([e], { type: "application/json" }), l = URL.createObjectURL(s);
51
+ const e = j(), r = new Blob([e], { type: "application/json" }), l = URL.createObjectURL(r);
52
52
  to(l, `flowchart-${Date.now()}.json`), URL.revokeObjectURL(l);
53
- }, [M]), _ = C(() => {
53
+ }, [j]), _ = C(() => {
54
54
  F.current?.click();
55
55
  }, []);
56
56
  return /* @__PURE__ */ d("div", {
@@ -62,24 +62,24 @@ function Po({ onBack: a, onUndo: h, onRedo: u, canUndo: w, canRedo: k, onGroup:
62
62
  accept: ".json",
63
63
  style: { display: "none" },
64
64
  onChange: C((e) => {
65
- const s = e.target.files?.[0];
66
- if (!s) return;
65
+ const r = e.target.files?.[0];
66
+ if (!r) return;
67
67
  const l = new FileReader();
68
68
  l.onload = () => {
69
- typeof l.result == "string" && j(l.result);
70
- }, l.readAsText(s), e.target.value = "";
71
- }, [j])
69
+ typeof l.result == "string" && M(l.result);
70
+ }, l.readAsText(r), e.target.value = "";
71
+ }, [M])
72
72
  }),
73
73
  a && /* @__PURE__ */ d(b, { children: [/* @__PURE__ */ o(i, {
74
74
  tip: "返回列表",
75
75
  onClick: a,
76
- children: /* @__PURE__ */ o(ro, {})
76
+ children: /* @__PURE__ */ o(so, {})
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
- disabled: !w,
82
+ disabled: !f,
83
83
  children: /* @__PURE__ */ o(zo, {})
84
84
  }),
85
85
  u && /* @__PURE__ */ o(i, {
@@ -109,7 +109,7 @@ function Po({ onBack: a, onUndo: h, onRedo: u, canUndo: w, canRedo: k, onGroup:
109
109
  tip: "取消成组",
110
110
  shortcut: "⌘⇧G",
111
111
  onClick: I,
112
- disabled: !q,
112
+ disabled: !W,
113
113
  children: /* @__PURE__ */ o(Oo, {})
114
114
  })
115
115
  ] }),
@@ -117,32 +117,32 @@ function Po({ onBack: a, onUndo: h, onRedo: u, canUndo: w, canRedo: k, onGroup:
117
117
  /* @__PURE__ */ o("div", { className: "flow-toolbar-divider" }),
118
118
  /* @__PURE__ */ o(i, {
119
119
  tip: "居左",
120
- onClick: () => r("left"),
120
+ onClick: () => s("left"),
121
121
  children: /* @__PURE__ */ o(t, { kind: "left" })
122
122
  }),
123
123
  /* @__PURE__ */ o(i, {
124
124
  tip: "水平居中",
125
- onClick: () => r("center-h"),
125
+ onClick: () => s("center-h"),
126
126
  children: /* @__PURE__ */ o(t, { kind: "center-h" })
127
127
  }),
128
128
  /* @__PURE__ */ o(i, {
129
129
  tip: "居右",
130
- onClick: () => r("right"),
130
+ onClick: () => s("right"),
131
131
  children: /* @__PURE__ */ o(t, { kind: "right" })
132
132
  }),
133
133
  /* @__PURE__ */ o(i, {
134
134
  tip: "居上",
135
- onClick: () => r("top"),
135
+ onClick: () => s("top"),
136
136
  children: /* @__PURE__ */ o(t, { kind: "top" })
137
137
  }),
138
138
  /* @__PURE__ */ o(i, {
139
139
  tip: "垂直居中",
140
- onClick: () => r("center-v"),
140
+ onClick: () => s("center-v"),
141
141
  children: /* @__PURE__ */ o(t, { kind: "center-v" })
142
142
  }),
143
143
  /* @__PURE__ */ o(i, {
144
144
  tip: "居下",
145
- onClick: () => r("bottom"),
145
+ onClick: () => s("bottom"),
146
146
  children: /* @__PURE__ */ o(t, { kind: "bottom" })
147
147
  }),
148
148
  /* @__PURE__ */ o(i, {
@@ -182,52 +182,54 @@ function Po({ onBack: a, onUndo: h, onRedo: u, canUndo: w, canRedo: k, onGroup:
182
182
  /* @__PURE__ */ o(i, {
183
183
  tip: "形状面板",
184
184
  active: O,
185
- onClick: () => L(!O),
185
+ onClick: () => P(!O),
186
186
  children: /* @__PURE__ */ o(So, {})
187
187
  }),
188
188
  /* @__PURE__ */ o(i, {
189
189
  tip: "属性面板",
190
190
  active: y,
191
- onClick: () => P(!y),
192
- children: /* @__PURE__ */ o(wo, {})
191
+ onClick: () => U(!y),
192
+ children: /* @__PURE__ */ o(fo, {})
193
193
  }),
194
194
  /* @__PURE__ */ o(i, {
195
195
  tip: "大纲",
196
196
  active: x,
197
- onClick: () => U(!x),
197
+ onClick: () => T(!x),
198
198
  children: /* @__PURE__ */ o(vo, {})
199
199
  }),
200
200
  /* @__PURE__ */ o(i, {
201
201
  tip: "JSON",
202
202
  active: g,
203
- onClick: () => T(!g),
203
+ onClick: () => V(!g),
204
204
  children: /* @__PURE__ */ o(ko, {})
205
205
  }),
206
206
  /* @__PURE__ */ o("div", { className: "flow-toolbar-divider" }),
207
207
  /* @__PURE__ */ o(i, {
208
208
  tip: "网格",
209
209
  active: z,
210
- onClick: () => G(!z),
210
+ onClick: () => L(!z),
211
211
  children: /* @__PURE__ */ o(mo, {})
212
212
  }),
213
213
  /* @__PURE__ */ o(i, {
214
214
  tip: "缩略图",
215
215
  active: A,
216
- onClick: () => V(!A),
216
+ onClick: () => B(!A),
217
217
  children: /* @__PURE__ */ o(Io, {})
218
218
  }),
219
219
  /* @__PURE__ */ o(i, {
220
- tip: f ? "隐藏所有 Anchor 对象" : "显示所有 Anchor 对象",
221
- active: f,
222
- disabled: W.length === 0,
223
- onClick: () => B(!f),
224
- children: /* @__PURE__ */ o(co, { visible: f })
220
+ tip: w ? "隐藏所有 Anchor 对象" : "显示所有 Anchor 对象",
221
+ active: w,
222
+ disabled: !G,
223
+ onClick: () => {
224
+ G && E(!w);
225
+ },
226
+ children: /* @__PURE__ */ o(co, { visible: w })
225
227
  }),
226
228
  /* @__PURE__ */ o("div", { className: "flow-toolbar-divider" }),
227
229
  /* @__PURE__ */ o(i, {
228
230
  tip: "动画预览",
229
231
  active: J !== null,
230
- onClick: () => E(J ? null : {
232
+ onClick: () => $(J ? null : {
231
233
  current: 0,
232
234
  showAnchor: !1
233
235
  }),
@@ -237,12 +239,12 @@ function Po({ onBack: a, onUndo: h, onRedo: u, canUndo: w, canRedo: k, onGroup:
237
239
  /* @__PURE__ */ o(i, {
238
240
  tip: "导入 JSON",
239
241
  onClick: _,
240
- children: /* @__PURE__ */ o(fo, {})
242
+ children: /* @__PURE__ */ o(wo, {})
241
243
  }),
242
244
  /* @__PURE__ */ o(i, {
243
245
  tip: "导出 JSON",
244
246
  onClick: Y,
245
- children: /* @__PURE__ */ o(so, {})
247
+ children: /* @__PURE__ */ o(ro, {})
246
248
  }),
247
249
  N && /* @__PURE__ */ o(i, {
248
250
  tip: "导出 PNG",
@@ -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 anchors = Object.values(doc.canvases).flatMap(canvas =>\n canvas.nodes.filter(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={anchors.length === 0}\n onClick={() => setShowAnchors(!showAnchors)}\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 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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"}