@vanduo-oss/vd3-cbun 1.3.0 → 1.3.1

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/CHANGELOG.md CHANGED
@@ -4,6 +4,20 @@ All notable changes to `@vanduo-oss/vd3-cbun` are documented here. This file
4
4
  tracks the PACKAGE only — never docs-site content. Per-component VERSION
5
5
  constants are listed alongside each bundle release.
6
6
 
7
+ ## 1.3.1 — 2026-08-02
8
+
9
+ **flowchart** — CSS token mixes no longer blend toward fixed light cream/white
10
+ (`#ffffff`, `#efe7d4`, `#f5ecd8`, …); panels, nodes, handles, and inspector
11
+ chrome now follow `--vd-bg-primary` / `--vd-bg-secondary` so dark mode stays
12
+ coherent with the site palette. Toolbar actions use Draw-style Phosphor icons
13
+ (zoom / reset / fit / undo / redo / clear) instead of faint text glyphs; the
14
+ left shapes rail is a compact icon panel with stronger stroke contrast and
15
+ pressed states. The layout `<select>` always shows the active mode
16
+ (Tree / Radial / Grid) instead of resetting to a placeholder, with a single
17
+ no-repeat caret. Shell `min-height` no longer forces 560px, so short parents
18
+ (docs fullscreen) keep the bottom border visible. Styling + chrome UX only;
19
+ `VD_FLOWCHART_VERSION` remains `1.2.0` (serialization unchanged).
20
+
7
21
  ## 1.3.0 — 2026-07-24
8
22
 
9
23
  Minor release. **New — chart mark clicks:** `VdChart` (and the typed
package/README.md CHANGED
@@ -8,11 +8,11 @@ tree-shakeable subpath exports. It replaces the four per-repo publishes
8
8
  (`@vanduo-oss/charts`, `@vanduo-oss/flowchart`, `@vanduo-oss/hex-grid`,
9
9
  `@vanduo-oss/music-player`) of the old line.
10
10
 
11
- **Status: 1.2.1.** Six Vue3-only component families — charts, code-editor, draw,
11
+ **Status: 1.3.1.** Six Vue3-only component families — charts, code-editor, draw,
12
12
  flowchart, hex-grid, music-player — each on its own tree-shakeable subpath, with
13
- the esbuild metafile isolation guard in place. (1.2.0 adds the first-party
14
- `draw` vector drawing tool — a brush engine + color palette; 1.2.1 patches four
15
- core bug fixes across charts / draw / hex-grid / music-player; see the
13
+ the esbuild metafile isolation guard in place. (1.3.0 adds chart mark-click
14
+ emits + bounded draw/flowchart deserialization; 1.3.1 dark-aware flowchart
15
+ chrome, icon toolbar, and short-parent sizing; see the
16
16
  [changelog](./CHANGELOG.md).)
17
17
 
18
18
  ## Install
@@ -221,6 +221,51 @@ var LAYOUT_MODES = ["tree", "radial", "grid"];
221
221
 
222
222
  // src/flowchart/core.js
223
223
  var SVG_NS = "http://www.w3.org/2000/svg";
224
+ var TOOLBAR_ICON_PATHS = {
225
+ "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",
226
+ "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",
227
+ "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",
228
+ "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",
229
+ 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",
230
+ 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",
231
+ 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"
232
+ };
233
+ var TOOLBAR_ACTIONS = [
234
+ { action: "zoom-out", label: "Zoom out", icon: "zoom-out" },
235
+ { action: "zoom-in", label: "Zoom in", icon: "zoom-in" },
236
+ { action: "reset-view", label: "Reset view", icon: "reset-view" },
237
+ { action: "fit-view", label: "Fit view", icon: "fit-view" },
238
+ { action: "undo", label: "Undo", icon: "undo" },
239
+ { action: "redo", label: "Redo", icon: "redo" }
240
+ ];
241
+ var LAYOUT_OPTIONS = [
242
+ { value: "tree", label: "Tree" },
243
+ { value: "radial", label: "Radial" },
244
+ { value: "grid", label: "Grid" }
245
+ ];
246
+ function createToolbarIcon(name) {
247
+ const svg = svgEl("svg", {
248
+ class: "vd-flowchart-icon",
249
+ viewBox: "0 0 256 256",
250
+ "aria-hidden": "true",
251
+ focusable: "false"
252
+ });
253
+ svg.setAttribute("fill", "currentColor");
254
+ svg.appendChild(svgEl("path", { d: TOOLBAR_ICON_PATHS[name] || "" }));
255
+ return svg;
256
+ }
257
+ function createToolbarButton({ action, label, icon, disabled = false }) {
258
+ const button = createElement("button", {
259
+ className: "vd-flowchart-btn vd-flowchart-icon-btn",
260
+ title: label,
261
+ disabled
262
+ });
263
+ button.setAttribute("type", "button");
264
+ button.setAttribute("data-flowchart-action", action);
265
+ button.setAttribute("aria-label", label);
266
+ button.appendChild(createToolbarIcon(icon));
267
+ return button;
268
+ }
224
269
  var DEFAULT_GRID_SIZE = 24;
225
270
  var MIN_SCALE = 0.35;
226
271
  var MAX_SCALE = 3;
@@ -293,14 +338,14 @@ var DEFAULT_NODE_SPECS = {
293
338
  }
294
339
  };
295
340
  var FLOWCHART_PALETTE_ITEMS = [
296
- { kind: "tool", tool: "arrow", label: "arrow" },
297
- { kind: "node", type: "rounded-rect", label: "rounded rect" },
298
- { kind: "node", type: "rect", label: "rect" },
299
- { kind: "node", type: "diamond", label: "diamond" },
300
- { kind: "node", type: "circle", label: "circle" },
301
- { kind: "node", type: "junction", label: "junction" },
302
- { kind: "node", type: "textbox", label: "textbox" },
303
- { kind: "node", type: "label", label: "label" }
341
+ { kind: "tool", tool: "arrow", label: "Arrow" },
342
+ { kind: "node", type: "rounded-rect", label: "Rounded" },
343
+ { kind: "node", type: "rect", label: "Rect" },
344
+ { kind: "node", type: "diamond", label: "Diamond" },
345
+ { kind: "node", type: "circle", label: "Circle" },
346
+ { kind: "node", type: "junction", label: "Junction" },
347
+ { kind: "node", type: "textbox", label: "Textbox" },
348
+ { kind: "node", type: "label", label: "Label" }
304
349
  ];
305
350
  var flowchartId = 0;
306
351
  function nextId(prefix) {
@@ -1091,6 +1136,7 @@ var VdFlowchart = class {
1091
1136
  this.selection = null;
1092
1137
  this.interaction = null;
1093
1138
  this.activeTool = null;
1139
+ this.layoutMode = "tree";
1094
1140
  this.paletteSerial = 0;
1095
1141
  this.destroyed = false;
1096
1142
  this.lastNodePointer = null;
@@ -1174,76 +1220,45 @@ var VdFlowchart = class {
1174
1220
  className: `vd-flowchart-shell${this.readonly ? " vd-flowchart-readonly" : ""}`
1175
1221
  });
1176
1222
  this.toolbar = createElement("div", { className: "vd-flowchart-toolbar" });
1223
+ this.toolbar.setAttribute("role", "toolbar");
1224
+ this.toolbar.setAttribute("aria-label", "Flowchart tools");
1177
1225
  const toolbarLeft = createElement("div", { className: "vd-flowchart-toolbar-group" });
1178
1226
  const toolbarRight = createElement("div", { className: "vd-flowchart-toolbar-group" });
1179
- this.zoomOutButton = createElement("button", { className: "vd-flowchart-btn", text: "-" });
1180
- this.zoomOutButton.setAttribute("data-flowchart-action", "zoom-out");
1181
- this.zoomOutButton.setAttribute("type", "button");
1182
- this.zoomInButton = createElement("button", { className: "vd-flowchart-btn", text: "+" });
1183
- this.zoomInButton.setAttribute("data-flowchart-action", "zoom-in");
1184
- this.zoomInButton.setAttribute("type", "button");
1185
- this.resetViewButton = createElement("button", {
1186
- className: "vd-flowchart-btn",
1187
- text: "Reset"
1188
- });
1189
- this.resetViewButton.setAttribute("data-flowchart-action", "reset-view");
1190
- this.resetViewButton.setAttribute("type", "button");
1191
- this.fitViewButton = createElement("button", { className: "vd-flowchart-btn", text: "Fit" });
1192
- this.fitViewButton.setAttribute("data-flowchart-action", "fit-view");
1193
- this.fitViewButton.setAttribute("type", "button");
1194
- this.undoButton = createElement("button", {
1195
- className: "vd-flowchart-btn",
1196
- text: "\u21B6",
1197
- title: "Undo",
1198
- disabled: true
1199
- });
1200
- this.undoButton.setAttribute("data-flowchart-action", "undo");
1201
- this.undoButton.setAttribute("type", "button");
1202
- this.undoButton.setAttribute("aria-label", "Undo");
1203
- this.redoButton = createElement("button", {
1204
- className: "vd-flowchart-btn",
1205
- text: "\u21B7",
1206
- title: "Redo",
1207
- disabled: true
1227
+ TOOLBAR_ACTIONS.forEach((item) => {
1228
+ const button = createToolbarButton(item);
1229
+ if (item.action === "undo") this.undoButton = button;
1230
+ if (item.action === "redo") this.redoButton = button;
1231
+ if (item.action === "zoom-out") this.zoomOutButton = button;
1232
+ if (item.action === "zoom-in") this.zoomInButton = button;
1233
+ if (item.action === "reset-view") this.resetViewButton = button;
1234
+ if (item.action === "fit-view") this.fitViewButton = button;
1235
+ toolbarLeft.appendChild(button);
1208
1236
  });
1209
- this.redoButton.setAttribute("data-flowchart-action", "redo");
1210
- this.redoButton.setAttribute("type", "button");
1211
- this.redoButton.setAttribute("aria-label", "Redo");
1237
+ this.undoButton.disabled = true;
1238
+ this.redoButton.disabled = true;
1212
1239
  this.arrangeSelect = createElement("select", {
1213
1240
  className: "vd-flowchart-btn vd-flowchart-arrange",
1214
- disabled: this.readonly
1241
+ disabled: this.readonly,
1242
+ title: "Auto-arrange layout"
1215
1243
  });
1216
- this.arrangeSelect.setAttribute("aria-label", "Auto-arrange layout");
1244
+ this.arrangeSelect.setAttribute("aria-label", "Layout mode");
1217
1245
  this.arrangeSelect.setAttribute("data-flowchart-arrange", "");
1218
- [
1219
- { value: "", label: "Arrange \u25BE" },
1220
- { value: "tree", label: "Tree" },
1221
- { value: "radial", label: "Radial" },
1222
- { value: "grid", label: "Grid" }
1223
- ].forEach((item, index) => {
1246
+ LAYOUT_OPTIONS.forEach((item) => {
1224
1247
  const option = createElement("option", { value: item.value, text: item.label });
1225
1248
  option.value = item.value;
1226
- if (index === 0) option.disabled = true;
1227
1249
  this.arrangeSelect.appendChild(option);
1228
1250
  });
1229
- this.arrangeSelect.selectedIndex = 0;
1230
- this.clearButton = createElement("button", {
1231
- className: "vd-flowchart-btn",
1232
- text: "Clear",
1251
+ this.arrangeSelect.value = this.layoutMode;
1252
+ this.clearButton = createToolbarButton({
1253
+ action: "clear",
1254
+ label: "Clear canvas",
1255
+ icon: "clear",
1233
1256
  disabled: this.readonly
1234
1257
  });
1235
- this.clearButton.setAttribute("data-flowchart-action", "clear");
1236
- this.clearButton.setAttribute("type", "button");
1237
1258
  this.zoomLabel = createElement("span", {
1238
1259
  className: "vd-flowchart-toolbar-label",
1239
1260
  text: "100%"
1240
1261
  });
1241
- toolbarLeft.appendChild(this.zoomOutButton);
1242
- toolbarLeft.appendChild(this.zoomInButton);
1243
- toolbarLeft.appendChild(this.resetViewButton);
1244
- toolbarLeft.appendChild(this.fitViewButton);
1245
- toolbarLeft.appendChild(this.undoButton);
1246
- toolbarLeft.appendChild(this.redoButton);
1247
1262
  toolbarLeft.appendChild(this.arrangeSelect);
1248
1263
  toolbarLeft.appendChild(this.clearButton);
1249
1264
  toolbarRight.appendChild(this.zoomLabel);
@@ -1254,17 +1269,23 @@ var VdFlowchart = class {
1254
1269
  className: "vd-flowchart-panel vd-flowchart-panel--palette"
1255
1270
  });
1256
1271
  this.palettePanel.appendChild(
1257
- createElement("h4", { className: "vd-flowchart-panel-title", text: "Shapes & tools" })
1272
+ createElement("h4", { className: "vd-flowchart-panel-title", text: "Shapes" })
1258
1273
  );
1259
- this.paletteGrid = createElement("div", { className: "vd-flowchart-palette" });
1274
+ this.paletteGrid = createElement("div", {
1275
+ className: "vd-flowchart-palette",
1276
+ role: "toolbar"
1277
+ });
1278
+ this.paletteGrid.setAttribute("aria-label", "Shapes and tools");
1260
1279
  FLOWCHART_PALETTE_ITEMS.forEach((item) => {
1261
1280
  const button = createElement("button", {
1262
- className: "vd-flowchart-palette-btn"
1281
+ className: "vd-flowchart-palette-btn",
1282
+ title: item.label
1263
1283
  });
1264
1284
  button.setAttribute("type", "button");
1265
1285
  if (item.kind === "tool") {
1266
1286
  button.setAttribute("data-tool", item.tool);
1267
- button.setAttribute("aria-label", `Use ${item.label}`);
1287
+ button.setAttribute("aria-label", item.label);
1288
+ button.setAttribute("aria-pressed", "false");
1268
1289
  } else {
1269
1290
  button.setAttribute("data-node-type", item.type);
1270
1291
  button.setAttribute("aria-label", `Add ${item.label}`);
@@ -1418,10 +1439,18 @@ var VdFlowchart = class {
1418
1439
  const arrowArmed = this.activeTool === "arrow";
1419
1440
  this.paletteGrid.querySelectorAll(".vd-flowchart-palette-btn").forEach((button) => {
1420
1441
  const tool = button.getAttribute("data-tool");
1421
- button.classList.toggle("is-active", Boolean(tool) && tool === this.activeTool);
1442
+ const active = Boolean(tool) && tool === this.activeTool;
1443
+ button.classList.toggle("is-active", active);
1444
+ if (tool) button.setAttribute("aria-pressed", active ? "true" : "false");
1422
1445
  });
1423
1446
  this.canvasEl.classList.toggle("is-arrow-tool", arrowArmed);
1424
1447
  }
1448
+ syncArrangeSelect() {
1449
+ if (!this.arrangeSelect) return;
1450
+ const mode = LAYOUT_OPTIONS.some((item) => item.value === this.layoutMode) ? this.layoutMode : "tree";
1451
+ this.layoutMode = mode;
1452
+ this.arrangeSelect.value = mode;
1453
+ }
1425
1454
  setActiveTool(tool) {
1426
1455
  this.activeTool = tool || null;
1427
1456
  this.updatePaletteState();
@@ -1442,8 +1471,12 @@ var VdFlowchart = class {
1442
1471
  handleArrangeChange(event) {
1443
1472
  if (this.readonly) return;
1444
1473
  const mode = event.target.value;
1445
- if (mode) this.layout(mode);
1446
- event.target.selectedIndex = 0;
1474
+ if (!LAYOUT_OPTIONS.some((item) => item.value === mode)) {
1475
+ this.syncArrangeSelect();
1476
+ return;
1477
+ }
1478
+ this.layoutMode = mode;
1479
+ this.layout(mode);
1447
1480
  }
1448
1481
  handlePaletteClick(event) {
1449
1482
  if (this.readonly) return;
@@ -3032,6 +3065,8 @@ var VdFlowchart = class {
3032
3065
  layout(mode = "tree", options = {}) {
3033
3066
  if (this.readonly) return this;
3034
3067
  const resolvedMode = LAYOUT_MODES.includes(mode) ? mode : "tree";
3068
+ this.layoutMode = resolvedMode;
3069
+ this.syncArrangeSelect();
3035
3070
  const positions = computeLayout(this.documentData, resolvedMode, options);
3036
3071
  if (!positions.size) return this;
3037
3072
  let changed = false;