@vanduo-oss/vd3-cbun 1.3.0 → 1.3.2

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.
@@ -187,6 +187,51 @@ var LAYOUT_MODES = ["tree", "radial", "grid"];
187
187
 
188
188
  // src/flowchart/core.js
189
189
  var SVG_NS = "http://www.w3.org/2000/svg";
190
+ var TOOLBAR_ICON_PATHS = {
191
+ "zoom-out": "M229.66,218.34l-50.07-50.06a88.11,88.11,0,1,0-11.31,11.31l50.06,50.07a8,8,0,0,0,11.32-11.32ZM40,112a72,72,0,1,1,72,72A72.08,72.08,0,0,1,40,112Zm112-8H88a8,8,0,0,0,0,16h64a8,8,0,0,0,0-16Z",
192
+ "zoom-in": "M229.66,218.34l-50.07-50.06a88.11,88.11,0,1,0-11.31,11.31l50.06,50.07a8,8,0,0,0,11.32-11.32ZM40,112a72,72,0,1,1,72,72A72.08,72.08,0,0,1,40,112Zm112,24H128v24a8,8,0,0,1-16,0V136H88a8,8,0,0,1,0-16h24V96a8,8,0,0,1,16,0v24h24a8,8,0,0,1,0,16Z",
193
+ "reset-view": "M240,56v48a8,8,0,0,1-8,8H184a8,8,0,0,1,0-16h28.69L187.31,70.63A80,80,0,1,0,208,128a8,8,0,0,1,16,0,96,96,0,1,1-27.22-66.91L224,85.8V56a8,8,0,0,1,16,0Z",
194
+ "fit-view": "M216,48V88a8,8,0,0,1-16,0V67.31l-42.34,42.35a8,8,0,0,1-11.32-11.32L188.69,56H168a8,8,0,0,1,0-16h40A8,8,0,0,1,216,48ZM98.34,146.34,56,188.69V168a8,8,0,0,0-16,0v40a8,8,0,0,0,8,8H88a8,8,0,0,0,0-16H67.31l42.35-42.34a8,8,0,0,0-11.32-11.32Zm11.32-36.68L67.31,56H88a8,8,0,0,0,0-16H48a8,8,0,0,0-8,8V88a8,8,0,0,0,16,0V67.31l42.34,42.35a8,8,0,0,0,11.32-11.32ZM208,160a8,8,0,0,0-8,8v20.69l-42.34-42.35a8,8,0,0,0-11.32,11.32L188.69,200H168a8,8,0,0,0,0,16h40a8,8,0,0,0,8-8V168A8,8,0,0,0,208,160Z",
195
+ undo: "M224,128a96,96,0,0,1-94.71,96H128A95.38,95.38,0,0,1,62.1,197.8a8,8,0,0,1,11-11.63A80,80,0,1,0,71.43,71.39a3.07,3.07,0,0,1-.26.25L44.59,96H72a8,8,0,0,1,0,16H24a8,8,0,0,1-8-8V56a8,8,0,0,1,16,0V85.8L60.25,60A96,96,0,0,1,224,128Z",
196
+ redo: "M240,56v48a8,8,0,0,1-8,8H184a8,8,0,0,1,0-16H211.4L184.81,71.64l-.25-.24a80,80,0,1,0-1.67,114.78,8,8,0,0,1,11,11.63A95.44,95.44,0,0,1,128,224h-1.32A96,96,0,1,1,195.75,60L224,85.8V56a8,8,0,1,1,16,0Z",
197
+ clear: "M216,48H176V40a24,24,0,0,0-24-24H104A24,24,0,0,0,80,40v8H40a8,8,0,0,0,0,16h8V208a16,16,0,0,0,16,16H192a16,16,0,0,0,16-16V64h8a8,8,0,0,0,0-16ZM96,40a8,8,0,0,1,8-8h48a8,8,0,0,1,8,8v8H96Zm96,168H64V64H192ZM112,104v64a8,8,0,0,1-16,0V104a8,8,0,0,1,16,0Zm48,0v64a8,8,0,0,1-16,0V104a8,8,0,0,1,16,0Z"
198
+ };
199
+ var TOOLBAR_ACTIONS = [
200
+ { action: "zoom-out", label: "Zoom out", icon: "zoom-out" },
201
+ { action: "zoom-in", label: "Zoom in", icon: "zoom-in" },
202
+ { action: "reset-view", label: "Reset view", icon: "reset-view" },
203
+ { action: "fit-view", label: "Fit view", icon: "fit-view" },
204
+ { action: "undo", label: "Undo", icon: "undo" },
205
+ { action: "redo", label: "Redo", icon: "redo" }
206
+ ];
207
+ var LAYOUT_OPTIONS = [
208
+ { value: "tree", label: "Tree" },
209
+ { value: "radial", label: "Radial" },
210
+ { value: "grid", label: "Grid" }
211
+ ];
212
+ function createToolbarIcon(name) {
213
+ const svg = svgEl("svg", {
214
+ class: "vd-flowchart-icon",
215
+ viewBox: "0 0 256 256",
216
+ "aria-hidden": "true",
217
+ focusable: "false"
218
+ });
219
+ svg.setAttribute("fill", "currentColor");
220
+ svg.appendChild(svgEl("path", { d: TOOLBAR_ICON_PATHS[name] || "" }));
221
+ return svg;
222
+ }
223
+ function createToolbarButton({ action, label, icon, disabled = false }) {
224
+ const button = createElement("button", {
225
+ className: "vd-flowchart-btn vd-flowchart-icon-btn",
226
+ title: label,
227
+ disabled
228
+ });
229
+ button.setAttribute("type", "button");
230
+ button.setAttribute("data-flowchart-action", action);
231
+ button.setAttribute("aria-label", label);
232
+ button.appendChild(createToolbarIcon(icon));
233
+ return button;
234
+ }
190
235
  var DEFAULT_GRID_SIZE = 24;
191
236
  var MIN_SCALE = 0.35;
192
237
  var MAX_SCALE = 3;
@@ -259,14 +304,14 @@ var DEFAULT_NODE_SPECS = {
259
304
  }
260
305
  };
261
306
  var FLOWCHART_PALETTE_ITEMS = [
262
- { kind: "tool", tool: "arrow", label: "arrow" },
263
- { kind: "node", type: "rounded-rect", label: "rounded rect" },
264
- { kind: "node", type: "rect", label: "rect" },
265
- { kind: "node", type: "diamond", label: "diamond" },
266
- { kind: "node", type: "circle", label: "circle" },
267
- { kind: "node", type: "junction", label: "junction" },
268
- { kind: "node", type: "textbox", label: "textbox" },
269
- { kind: "node", type: "label", label: "label" }
307
+ { kind: "tool", tool: "arrow", label: "Arrow" },
308
+ { kind: "node", type: "rounded-rect", label: "Rounded" },
309
+ { kind: "node", type: "rect", label: "Rect" },
310
+ { kind: "node", type: "diamond", label: "Diamond" },
311
+ { kind: "node", type: "circle", label: "Circle" },
312
+ { kind: "node", type: "junction", label: "Junction" },
313
+ { kind: "node", type: "textbox", label: "Textbox" },
314
+ { kind: "node", type: "label", label: "Label" }
270
315
  ];
271
316
  var flowchartId = 0;
272
317
  function nextId(prefix) {
@@ -1057,6 +1102,7 @@ var VdFlowchart = class {
1057
1102
  this.selection = null;
1058
1103
  this.interaction = null;
1059
1104
  this.activeTool = null;
1105
+ this.layoutMode = "tree";
1060
1106
  this.paletteSerial = 0;
1061
1107
  this.destroyed = false;
1062
1108
  this.lastNodePointer = null;
@@ -1140,76 +1186,45 @@ var VdFlowchart = class {
1140
1186
  className: `vd-flowchart-shell${this.readonly ? " vd-flowchart-readonly" : ""}`
1141
1187
  });
1142
1188
  this.toolbar = createElement("div", { className: "vd-flowchart-toolbar" });
1189
+ this.toolbar.setAttribute("role", "toolbar");
1190
+ this.toolbar.setAttribute("aria-label", "Flowchart tools");
1143
1191
  const toolbarLeft = createElement("div", { className: "vd-flowchart-toolbar-group" });
1144
1192
  const toolbarRight = createElement("div", { className: "vd-flowchart-toolbar-group" });
1145
- this.zoomOutButton = createElement("button", { className: "vd-flowchart-btn", text: "-" });
1146
- this.zoomOutButton.setAttribute("data-flowchart-action", "zoom-out");
1147
- this.zoomOutButton.setAttribute("type", "button");
1148
- this.zoomInButton = createElement("button", { className: "vd-flowchart-btn", text: "+" });
1149
- this.zoomInButton.setAttribute("data-flowchart-action", "zoom-in");
1150
- this.zoomInButton.setAttribute("type", "button");
1151
- this.resetViewButton = createElement("button", {
1152
- className: "vd-flowchart-btn",
1153
- text: "Reset"
1154
- });
1155
- this.resetViewButton.setAttribute("data-flowchart-action", "reset-view");
1156
- this.resetViewButton.setAttribute("type", "button");
1157
- this.fitViewButton = createElement("button", { className: "vd-flowchart-btn", text: "Fit" });
1158
- this.fitViewButton.setAttribute("data-flowchart-action", "fit-view");
1159
- this.fitViewButton.setAttribute("type", "button");
1160
- this.undoButton = createElement("button", {
1161
- className: "vd-flowchart-btn",
1162
- text: "\u21B6",
1163
- title: "Undo",
1164
- disabled: true
1165
- });
1166
- this.undoButton.setAttribute("data-flowchart-action", "undo");
1167
- this.undoButton.setAttribute("type", "button");
1168
- this.undoButton.setAttribute("aria-label", "Undo");
1169
- this.redoButton = createElement("button", {
1170
- className: "vd-flowchart-btn",
1171
- text: "\u21B7",
1172
- title: "Redo",
1173
- disabled: true
1193
+ TOOLBAR_ACTIONS.forEach((item) => {
1194
+ const button = createToolbarButton(item);
1195
+ if (item.action === "undo") this.undoButton = button;
1196
+ if (item.action === "redo") this.redoButton = button;
1197
+ if (item.action === "zoom-out") this.zoomOutButton = button;
1198
+ if (item.action === "zoom-in") this.zoomInButton = button;
1199
+ if (item.action === "reset-view") this.resetViewButton = button;
1200
+ if (item.action === "fit-view") this.fitViewButton = button;
1201
+ toolbarLeft.appendChild(button);
1174
1202
  });
1175
- this.redoButton.setAttribute("data-flowchart-action", "redo");
1176
- this.redoButton.setAttribute("type", "button");
1177
- this.redoButton.setAttribute("aria-label", "Redo");
1203
+ this.undoButton.disabled = true;
1204
+ this.redoButton.disabled = true;
1178
1205
  this.arrangeSelect = createElement("select", {
1179
1206
  className: "vd-flowchart-btn vd-flowchart-arrange",
1180
- disabled: this.readonly
1207
+ disabled: this.readonly,
1208
+ title: "Auto-arrange layout"
1181
1209
  });
1182
- this.arrangeSelect.setAttribute("aria-label", "Auto-arrange layout");
1210
+ this.arrangeSelect.setAttribute("aria-label", "Layout mode");
1183
1211
  this.arrangeSelect.setAttribute("data-flowchart-arrange", "");
1184
- [
1185
- { value: "", label: "Arrange \u25BE" },
1186
- { value: "tree", label: "Tree" },
1187
- { value: "radial", label: "Radial" },
1188
- { value: "grid", label: "Grid" }
1189
- ].forEach((item, index) => {
1212
+ LAYOUT_OPTIONS.forEach((item) => {
1190
1213
  const option = createElement("option", { value: item.value, text: item.label });
1191
1214
  option.value = item.value;
1192
- if (index === 0) option.disabled = true;
1193
1215
  this.arrangeSelect.appendChild(option);
1194
1216
  });
1195
- this.arrangeSelect.selectedIndex = 0;
1196
- this.clearButton = createElement("button", {
1197
- className: "vd-flowchart-btn",
1198
- text: "Clear",
1217
+ this.arrangeSelect.value = this.layoutMode;
1218
+ this.clearButton = createToolbarButton({
1219
+ action: "clear",
1220
+ label: "Clear canvas",
1221
+ icon: "clear",
1199
1222
  disabled: this.readonly
1200
1223
  });
1201
- this.clearButton.setAttribute("data-flowchart-action", "clear");
1202
- this.clearButton.setAttribute("type", "button");
1203
1224
  this.zoomLabel = createElement("span", {
1204
1225
  className: "vd-flowchart-toolbar-label",
1205
1226
  text: "100%"
1206
1227
  });
1207
- toolbarLeft.appendChild(this.zoomOutButton);
1208
- toolbarLeft.appendChild(this.zoomInButton);
1209
- toolbarLeft.appendChild(this.resetViewButton);
1210
- toolbarLeft.appendChild(this.fitViewButton);
1211
- toolbarLeft.appendChild(this.undoButton);
1212
- toolbarLeft.appendChild(this.redoButton);
1213
1228
  toolbarLeft.appendChild(this.arrangeSelect);
1214
1229
  toolbarLeft.appendChild(this.clearButton);
1215
1230
  toolbarRight.appendChild(this.zoomLabel);
@@ -1220,17 +1235,23 @@ var VdFlowchart = class {
1220
1235
  className: "vd-flowchart-panel vd-flowchart-panel--palette"
1221
1236
  });
1222
1237
  this.palettePanel.appendChild(
1223
- createElement("h4", { className: "vd-flowchart-panel-title", text: "Shapes & tools" })
1238
+ createElement("h4", { className: "vd-flowchart-panel-title", text: "Shapes" })
1224
1239
  );
1225
- this.paletteGrid = createElement("div", { className: "vd-flowchart-palette" });
1240
+ this.paletteGrid = createElement("div", {
1241
+ className: "vd-flowchart-palette",
1242
+ role: "toolbar"
1243
+ });
1244
+ this.paletteGrid.setAttribute("aria-label", "Shapes and tools");
1226
1245
  FLOWCHART_PALETTE_ITEMS.forEach((item) => {
1227
1246
  const button = createElement("button", {
1228
- className: "vd-flowchart-palette-btn"
1247
+ className: "vd-flowchart-palette-btn",
1248
+ title: item.label
1229
1249
  });
1230
1250
  button.setAttribute("type", "button");
1231
1251
  if (item.kind === "tool") {
1232
1252
  button.setAttribute("data-tool", item.tool);
1233
- button.setAttribute("aria-label", `Use ${item.label}`);
1253
+ button.setAttribute("aria-label", item.label);
1254
+ button.setAttribute("aria-pressed", "false");
1234
1255
  } else {
1235
1256
  button.setAttribute("data-node-type", item.type);
1236
1257
  button.setAttribute("aria-label", `Add ${item.label}`);
@@ -1384,10 +1405,18 @@ var VdFlowchart = class {
1384
1405
  const arrowArmed = this.activeTool === "arrow";
1385
1406
  this.paletteGrid.querySelectorAll(".vd-flowchart-palette-btn").forEach((button) => {
1386
1407
  const tool = button.getAttribute("data-tool");
1387
- button.classList.toggle("is-active", Boolean(tool) && tool === this.activeTool);
1408
+ const active = Boolean(tool) && tool === this.activeTool;
1409
+ button.classList.toggle("is-active", active);
1410
+ if (tool) button.setAttribute("aria-pressed", active ? "true" : "false");
1388
1411
  });
1389
1412
  this.canvasEl.classList.toggle("is-arrow-tool", arrowArmed);
1390
1413
  }
1414
+ syncArrangeSelect() {
1415
+ if (!this.arrangeSelect) return;
1416
+ const mode = LAYOUT_OPTIONS.some((item) => item.value === this.layoutMode) ? this.layoutMode : "tree";
1417
+ this.layoutMode = mode;
1418
+ this.arrangeSelect.value = mode;
1419
+ }
1391
1420
  setActiveTool(tool) {
1392
1421
  this.activeTool = tool || null;
1393
1422
  this.updatePaletteState();
@@ -1408,8 +1437,12 @@ var VdFlowchart = class {
1408
1437
  handleArrangeChange(event) {
1409
1438
  if (this.readonly) return;
1410
1439
  const mode = event.target.value;
1411
- if (mode) this.layout(mode);
1412
- event.target.selectedIndex = 0;
1440
+ if (!LAYOUT_OPTIONS.some((item) => item.value === mode)) {
1441
+ this.syncArrangeSelect();
1442
+ return;
1443
+ }
1444
+ this.layoutMode = mode;
1445
+ this.layout(mode);
1413
1446
  }
1414
1447
  handlePaletteClick(event) {
1415
1448
  if (this.readonly) return;
@@ -2998,6 +3031,8 @@ var VdFlowchart = class {
2998
3031
  layout(mode = "tree", options = {}) {
2999
3032
  if (this.readonly) return this;
3000
3033
  const resolvedMode = LAYOUT_MODES.includes(mode) ? mode : "tree";
3034
+ this.layoutMode = resolvedMode;
3035
+ this.syncArrangeSelect();
3001
3036
  const positions = computeLayout(this.documentData, resolvedMode, options);
3002
3037
  if (!positions.size) return this;
3003
3038
  let changed = false;