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.
- package/dist/components/pro/Flow/hooks/useMindMap.js +1 -1
- package/dist/components/pro/Flow/hooks/useMindMap.js.map +1 -1
- package/dist/components/pro/Flow/nodes/NodeRenderer.js +87 -89
- package/dist/components/pro/Flow/nodes/NodeRenderer.js.map +1 -1
- package/dist/components/pro/Flow/nodes/shapes.d.ts +4 -0
- package/dist/components/pro/Flow/nodes/shapes.js +95 -83
- package/dist/components/pro/Flow/nodes/shapes.js.map +1 -1
- package/dist/components/pro/Flow/panels/FlowToolbar.js +38 -36
- package/dist/components/pro/Flow/panels/FlowToolbar.js.map +1 -1
- package/dist/dishui.css +1 -1
- package/package.json +1 -1
|
@@ -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
|
|
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:
|
|
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:
|
|
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:
|
|
32
|
-
const { viewport: m, setViewport: v, showGrid: z, setShowGrid:
|
|
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 =
|
|
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
|
-
}, [
|
|
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
|
|
66
|
-
if (!
|
|
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" &&
|
|
70
|
-
}, l.readAsText(
|
|
71
|
-
}, [
|
|
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(
|
|
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: !
|
|
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: !
|
|
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: () =>
|
|
120
|
+
onClick: () => s("left"),
|
|
121
121
|
children: /* @__PURE__ */ o(t, { kind: "left" })
|
|
122
122
|
}),
|
|
123
123
|
/* @__PURE__ */ o(i, {
|
|
124
124
|
tip: "水平居中",
|
|
125
|
-
onClick: () =>
|
|
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: () =>
|
|
130
|
+
onClick: () => s("right"),
|
|
131
131
|
children: /* @__PURE__ */ o(t, { kind: "right" })
|
|
132
132
|
}),
|
|
133
133
|
/* @__PURE__ */ o(i, {
|
|
134
134
|
tip: "居上",
|
|
135
|
-
onClick: () =>
|
|
135
|
+
onClick: () => s("top"),
|
|
136
136
|
children: /* @__PURE__ */ o(t, { kind: "top" })
|
|
137
137
|
}),
|
|
138
138
|
/* @__PURE__ */ o(i, {
|
|
139
139
|
tip: "垂直居中",
|
|
140
|
-
onClick: () =>
|
|
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: () =>
|
|
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: () =>
|
|
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: () =>
|
|
192
|
-
children: /* @__PURE__ */ o(
|
|
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: () =>
|
|
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: () =>
|
|
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: () =>
|
|
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: () =>
|
|
216
|
+
onClick: () => B(!A),
|
|
217
217
|
children: /* @__PURE__ */ o(Io, {})
|
|
218
218
|
}),
|
|
219
219
|
/* @__PURE__ */ o(i, {
|
|
220
|
-
tip:
|
|
221
|
-
active:
|
|
222
|
-
disabled:
|
|
223
|
-
onClick: () =>
|
|
224
|
-
|
|
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: () =>
|
|
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(
|
|
242
|
+
children: /* @__PURE__ */ o(wo, {})
|
|
241
243
|
}),
|
|
242
244
|
/* @__PURE__ */ o(i, {
|
|
243
245
|
tip: "导出 JSON",
|
|
244
246
|
onClick: Y,
|
|
245
|
-
children: /* @__PURE__ */ o(
|
|
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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"}
|