@grafloria/element 0.3.23 → 0.4.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.
Files changed (69) hide show
  1. package/README.md +9 -7
  2. package/package.json +7 -9
  3. package/src/index.d.ts +16 -16
  4. package/src/index.js +58 -339
  5. package/src/lib/dashboard-kit/dashboard.d.ts +1 -1
  6. package/src/lib/dashboard-kit/dashboard.js +22 -26
  7. package/src/lib/dashboard-kit/grid-binder.d.ts +1 -1
  8. package/src/lib/dashboard-kit/grid-binder.js +62 -65
  9. package/src/lib/dashboard-kit/grid-mapping.js +14 -26
  10. package/src/lib/dashboard-kit/index.d.ts +5 -5
  11. package/src/lib/dashboard-kit/index.js +5 -30
  12. package/src/lib/dashboard-kit/styles.js +4 -8
  13. package/src/lib/dashboard-kit/widgets.d.ts +1 -1
  14. package/src/lib/dashboard-kit/widgets.js +16 -26
  15. package/src/lib/diagram-kit/card.d.ts +2 -2
  16. package/src/lib/diagram-kit/card.js +22 -32
  17. package/src/lib/diagram-kit/editing.js +15 -20
  18. package/src/lib/diagram-kit/er.d.ts +1 -1
  19. package/src/lib/diagram-kit/er.js +15 -18
  20. package/src/lib/diagram-kit/handles.d.ts +4 -4
  21. package/src/lib/diagram-kit/handles.js +16 -29
  22. package/src/lib/diagram-kit/index.d.ts +10 -10
  23. package/src/lib/diagram-kit/index.js +10 -50
  24. package/src/lib/diagram-kit/join-guidance.js +9 -18
  25. package/src/lib/diagram-kit/rows.js +1 -4
  26. package/src/lib/diagram-kit/styles.js +4 -8
  27. package/src/lib/diagram-kit/uml.js +10 -13
  28. package/src/lib/diagram-kit/update.d.ts +1 -1
  29. package/src/lib/diagram-kit/update.js +19 -26
  30. package/src/lib/grafloria-flow-element.js +19 -24
  31. package/src/lib/grafloria.d.ts +4 -4
  32. package/src/lib/grafloria.js +12 -17
  33. package/src/lib/load.d.ts +3 -3
  34. package/src/lib/load.js +19 -22
  35. package/src/lib/node-type-registry.js +6 -14
  36. package/src/lib/stencil-kit/builders.js +4 -10
  37. package/src/lib/stencil-kit/card-builders.js +14 -17
  38. package/src/lib/stencil-kit/index.d.ts +7 -7
  39. package/src/lib/stencil-kit/index.js +6 -16
  40. package/src/lib/stencil-kit/palette.js +14 -17
  41. package/src/lib/stencil-kit/shape-data.js +25 -28
  42. package/src/lib/stencil-kit/styles.js +1 -4
  43. package/esm/src/index.js +0 -295
  44. package/esm/src/lib/dashboard-kit/dashboard.js +0 -590
  45. package/esm/src/lib/dashboard-kit/grid-binder.js +0 -1633
  46. package/esm/src/lib/dashboard-kit/grid-mapping.js +0 -164
  47. package/esm/src/lib/dashboard-kit/index.js +0 -8
  48. package/esm/src/lib/dashboard-kit/styles.js +0 -205
  49. package/esm/src/lib/dashboard-kit/widgets.js +0 -379
  50. package/esm/src/lib/diagram-kit/card.js +0 -199
  51. package/esm/src/lib/diagram-kit/editing.js +0 -448
  52. package/esm/src/lib/diagram-kit/er.js +0 -160
  53. package/esm/src/lib/diagram-kit/handles.js +0 -312
  54. package/esm/src/lib/diagram-kit/index.js +0 -15
  55. package/esm/src/lib/diagram-kit/join-guidance.js +0 -322
  56. package/esm/src/lib/diagram-kit/rows.js +0 -144
  57. package/esm/src/lib/diagram-kit/styles.js +0 -118
  58. package/esm/src/lib/diagram-kit/uml.js +0 -135
  59. package/esm/src/lib/diagram-kit/update.js +0 -244
  60. package/esm/src/lib/grafloria-flow-element.js +0 -266
  61. package/esm/src/lib/grafloria.js +0 -69
  62. package/esm/src/lib/load.js +0 -252
  63. package/esm/src/lib/node-type-registry.js +0 -42
  64. package/esm/src/lib/stencil-kit/builders.js +0 -18
  65. package/esm/src/lib/stencil-kit/card-builders.js +0 -105
  66. package/esm/src/lib/stencil-kit/index.js +0 -9
  67. package/esm/src/lib/stencil-kit/palette.js +0 -427
  68. package/esm/src/lib/stencil-kit/shape-data.js +0 -537
  69. package/esm/src/lib/stencil-kit/styles.js +0 -126
@@ -1,7 +1,4 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.bindStencilPalette = bindStencilPalette;
4
- const tslib_1 = require("tslib");
1
+ import { __awaiter } from "tslib";
5
2
  /**
6
3
  * The stencil palette — the signature Visio surface: a categorized, searchable
7
4
  * list of shape masters you DRAG ONTO THE CANVAS.
@@ -17,10 +14,10 @@ const tslib_1 = require("tslib");
17
14
  * drop lands the master at the cursor as ONE undoable
18
15
  * BatchCommand.
19
16
  */
20
- const engine_1 = require("@grafloria/engine");
21
- const renderer_1 = require("@grafloria/renderer");
22
- const styles_1 = require("./styles");
23
- const builders_1 = require("./builders");
17
+ import { listStencils, NodeFactory, AddNodeCommand, BatchCommand, } from '@grafloria/engine';
18
+ import { getShape } from '@grafloria/renderer';
19
+ import { ensureStencilKitStyles } from './styles.js';
20
+ import { getStencilBuilder } from './builders.js';
24
21
  const SVG_NS = 'http://www.w3.org/2000/svg';
25
22
  /** The MIME the palette drags with — namespaced so a page's other DnD is untouched. */
26
23
  const DND_TYPE = 'application/x-grafloria-master';
@@ -123,7 +120,7 @@ function thumbnail(master, box = 34) {
123
120
  const h = Math.max(6, h0 * s);
124
121
  let el;
125
122
  try {
126
- const spec = (0, renderer_1.getShape)(paint.type).outline(w, h);
123
+ const spec = getShape(paint.type).outline(w, h);
127
124
  el = document.createElementNS(SVG_NS, spec.el);
128
125
  for (const [k, v] of Object.entries(spec.geom))
129
126
  el.setAttribute(k, String(v));
@@ -168,10 +165,10 @@ function subtree(diagram, root) {
168
165
  * @param hosts `palette`: where the list renders · `canvas`: the drop target
169
166
  * (the element the diagram is mounted in)
170
167
  */
171
- function bindStencilPalette(api, hosts, options = {}) {
168
+ export function bindStencilPalette(api, hosts, options = {}) {
172
169
  var _a, _b, _c;
173
- (0, styles_1.ensureStencilKitStyles)((_a = hosts.palette.ownerDocument) !== null && _a !== void 0 ? _a : document);
174
- const stencils = (_b = options.stencils) !== null && _b !== void 0 ? _b : (0, engine_1.listStencils)();
170
+ ensureStencilKitStyles((_a = hosts.palette.ownerDocument) !== null && _a !== void 0 ? _a : document);
171
+ const stencils = (_b = options.stencils) !== null && _b !== void 0 ? _b : listStencils();
175
172
  /** master id → stencil id, so a drop knows which notation it belongs to. */
176
173
  const stencilOf = new Map();
177
174
  for (const st of stencils)
@@ -362,7 +359,7 @@ function bindStencilPalette(api, hosts, options = {}) {
362
359
  * normal add.
363
360
  */
364
361
  function place(masterId, world) {
365
- return tslib_1.__awaiter(this, void 0, void 0, function* () {
362
+ return __awaiter(this, void 0, void 0, function* () {
366
363
  var _a, _b, _c, _d, _e, _f, _g, _h;
367
364
  const engine = api.getEngine();
368
365
  const diagram = api.getModel();
@@ -378,9 +375,9 @@ function bindStencilPalette(api, hosts, options = {}) {
378
375
  // a kit card, not a silhouette). Anything without one takes the template
379
376
  // path — see stencil-kit/builders.ts for why this is a registry and not an
380
377
  // id check inside the palette.
381
- const builder = (0, builders_1.getStencilBuilder)(masterId);
378
+ const builder = getStencilBuilder(masterId);
382
379
  const built = builder ? builder({ api, master, at }) : null;
383
- const factory = built ? null : new engine_1.NodeFactory(registry, diagram);
380
+ const factory = built ? null : new NodeFactory(registry, diagram);
384
381
  const root = built !== null && built !== void 0 ? built : factory.createFromTemplate(masterId, (_e = (_d = options.data) === null || _d === void 0 ? void 0 : _d.call(options, master)) !== null && _e !== void 0 ? _e : {}, at);
385
382
  const created = built ? [built] : subtree(diagram, root);
386
383
  // NOTE: masters used to need `useHTMLLayer` stripped here or they rendered
@@ -403,10 +400,10 @@ function bindStencilPalette(api, hosts, options = {}) {
403
400
  applyNotationTheme(root, stencilOf.get(masterId), options.notationTheme, api);
404
401
  // Serialize into commands BEFORE detaching (AddNodeCommand snapshots in its
405
402
  // constructor), then detach and replay through the command manager.
406
- const cmds = created.map((n) => new engine_1.AddNodeCommand(n));
403
+ const cmds = created.map((n) => new AddNodeCommand(n));
407
404
  for (const n of [...created].reverse())
408
405
  diagram.removeNode(n.id);
409
- yield engine.commandManager.execute(new engine_1.BatchCommand(`Place ${(_g = (_f = master.meta) === null || _f === void 0 ? void 0 : _f.name) !== null && _g !== void 0 ? _g : masterId}`, cmds));
406
+ yield engine.commandManager.execute(new BatchCommand(`Place ${(_g = (_f = master.meta) === null || _f === void 0 ? void 0 : _f.name) !== null && _g !== void 0 ? _g : masterId}`, cmds));
410
407
  (_h = options.onPlace) === null || _h === void 0 ? void 0 : _h.call(options, { master, nodeId: root.id, x: at.x, y: at.y });
411
408
  return root.id;
412
409
  });
@@ -1,6 +1,3 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.bindShapeDataPanel = bindShapeDataPanel;
4
1
  /**
5
2
  * The shape-data panel — Visio's "Shape Data" window, grown into the full
6
3
  * properties panel Visio users actually expect.
@@ -29,9 +26,9 @@ exports.bindShapeDataPanel = bindShapeDataPanel;
29
26
  * `.gf-sd-input` selector contract (first match = first dataSchema field; the
30
27
  * kit card's Name rows) is load-bearing for existing demos and gates.
31
28
  */
32
- const engine_1 = require("@grafloria/engine");
33
- const diagram_kit_1 = require("../diagram-kit");
34
- const styles_1 = require("./styles");
29
+ import { BatchCommand, MoveNodeCommand, ResizeNodeCommand, SetLinkDisplayLabelCommand, SetLinkPathTypeCommand, SetNodeDataCommand, SetNodeLabelCommand, SetNodeShapeConfigCommand, SetNodeStyleCommand, UpdateLinkStyleCommand, } from '@grafloria/engine';
30
+ import { erTable, umlClass } from '../diagram-kit/index.js';
31
+ import { ensureStencilKitStyles } from './styles.js';
35
32
  /** The schema a node's shape data follows, via the master it was stamped from. */
36
33
  function schemaFor(engine, node) {
37
34
  var _a, _b, _c, _d;
@@ -103,10 +100,10 @@ function ensureShapeDataPanelStyles(doc = document) {
103
100
  * nodes, edges and multi-selections each get their own sections; nothing
104
101
  * selected shows the empty message.
105
102
  */
106
- function bindShapeDataPanel(api, host, options = {}) {
103
+ export function bindShapeDataPanel(api, host, options = {}) {
107
104
  var _a, _b, _c;
108
105
  const doc = (_a = host.ownerDocument) !== null && _a !== void 0 ? _a : document;
109
- (0, styles_1.ensureStencilKitStyles)(doc);
106
+ ensureStencilKitStyles(doc);
110
107
  ensureShapeDataPanelStyles(doc);
111
108
  host.classList.add('gf-shapedata');
112
109
  const title = (_b = options.title) !== null && _b !== void 0 ? _b : 'Shape data';
@@ -175,7 +172,7 @@ function bindShapeDataPanel(api, host, options = {}) {
175
172
  // Commit through the command so the edit is undoable and collab-safe.
176
173
  const commit = (value) => {
177
174
  var _a;
178
- void engine.commandManager.execute(new engine_1.SetNodeDataCommand(node.id, { [key]: value }));
175
+ void engine.commandManager.execute(new SetNodeDataCommand(node.id, { [key]: value }));
179
176
  (_a = options.onEdit) === null || _a === void 0 ? void 0 : _a.call(options, { nodeId: node.id, key, value });
180
177
  };
181
178
  let field;
@@ -247,14 +244,14 @@ function bindShapeDataPanel(api, host, options = {}) {
247
244
  form.className = 'gf-sd-fields';
248
245
  if (!isKit) {
249
246
  form.appendChild(sectionLabel('Shape'));
250
- form.appendChild(ctlTextField('Name', String((_b = (_a = node.getLabel) === null || _a === void 0 ? void 0 : _a.call(node)) !== null && _b !== void 0 ? _b : ''), (v) => exec(new engine_1.SetNodeLabelCommand(node.id, v))));
247
+ form.appendChild(ctlTextField('Name', String((_b = (_a = node.getLabel) === null || _a === void 0 ? void 0 : _a.call(node)) !== null && _b !== void 0 ? _b : ''), (v) => exec(new SetNodeLabelCommand(node.id, v))));
251
248
  }
252
249
  form.appendChild(sectionLabel('Size & Position'));
253
- const move = (x, y) => { var _a; return exec(new engine_1.MoveNodeCommand(node.id, { x, y, z: (_a = node.position) === null || _a === void 0 ? void 0 : _a.z }, undefined, { mergeable: false })); };
250
+ const move = (x, y) => { var _a; return exec(new MoveNodeCommand(node.id, { x, y, z: (_a = node.position) === null || _a === void 0 ? void 0 : _a.z }, undefined, { mergeable: false })); };
254
251
  const resize = (w, h) => {
255
252
  var _a;
256
253
  const min = minSize(node);
257
- exec(new engine_1.ResizeNodeCommand(node.id, {
254
+ exec(new ResizeNodeCommand(node.id, {
258
255
  width: Math.max(min.w, w),
259
256
  height: Math.max(min.h, h),
260
257
  depth: (_a = node.size) === null || _a === void 0 ? void 0 : _a.depth,
@@ -269,10 +266,10 @@ function bindShapeDataPanel(api, host, options = {}) {
269
266
  const shape = ((_d = (_c = node.getMetadata) === null || _c === void 0 ? void 0 : _c.call(node, 'shape')) !== null && _d !== void 0 ? _d : {});
270
267
  const style = ((_e = node.style) !== null && _e !== void 0 ? _e : {});
271
268
  form.appendChild(sectionLabel('Format'));
272
- form.appendChild(colorField('Fill', toHexColor((_f = style['fill']) !== null && _f !== void 0 ? _f : shape['fill'], '#ffffff'), (v) => exec(new engine_1.SetNodeStyleCommand(node.id, { fill: v }))));
273
- form.appendChild(colorField('Line', toHexColor((_g = style['stroke']) !== null && _g !== void 0 ? _g : shape['stroke'], '#333333'), (v) => exec(new engine_1.SetNodeStyleCommand(node.id, { stroke: v }))));
274
- form.appendChild(numberField('Line width', () => { var _a, _b; return (_b = (_a = style['strokeWidth']) !== null && _a !== void 0 ? _a : shape['strokeWidth']) !== null && _b !== void 0 ? _b : 1; }, (n) => exec(new engine_1.SetNodeStyleCommand(node.id, { strokeWidth: Math.max(0, n) }))));
275
- form.appendChild(checkField('Dashed', !!style['strokeDasharray'], (c) => exec(new engine_1.SetNodeStyleCommand(node.id, { strokeDasharray: c ? DASH : undefined }))));
269
+ form.appendChild(colorField('Fill', toHexColor((_f = style['fill']) !== null && _f !== void 0 ? _f : shape['fill'], '#ffffff'), (v) => exec(new SetNodeStyleCommand(node.id, { fill: v }))));
270
+ form.appendChild(colorField('Line', toHexColor((_g = style['stroke']) !== null && _g !== void 0 ? _g : shape['stroke'], '#333333'), (v) => exec(new SetNodeStyleCommand(node.id, { stroke: v }))));
271
+ form.appendChild(numberField('Line width', () => { var _a, _b; return (_b = (_a = style['strokeWidth']) !== null && _a !== void 0 ? _a : shape['strokeWidth']) !== null && _b !== void 0 ? _b : 1; }, (n) => exec(new SetNodeStyleCommand(node.id, { strokeWidth: Math.max(0, n) }))));
272
+ form.appendChild(checkField('Dashed', !!style['strokeDasharray'], (c) => exec(new SetNodeStyleCommand(node.id, { strokeDasharray: c ? DASH : undefined }))));
276
273
  // Corner radius only where the silhouette HAS corners: the rect family.
277
274
  const silhouette = (_h = shape['type']) !== null && _h !== void 0 ? _h : 'rect';
278
275
  if (silhouette === 'rect') {
@@ -282,8 +279,8 @@ function bindShapeDataPanel(api, host, options = {}) {
282
279
  // borderRadius — on masters that ship it (BPMN tasks), the style
283
280
  // write would not paint. Edit the key that does.
284
281
  exec(shape['cornerRadius'] !== undefined
285
- ? new engine_1.SetNodeShapeConfigCommand(node.id, { cornerRadius: r })
286
- : new engine_1.SetNodeStyleCommand(node.id, { borderRadius: r }));
282
+ ? new SetNodeShapeConfigCommand(node.id, { cornerRadius: r })
283
+ : new SetNodeStyleCommand(node.id, { borderRadius: r }));
287
284
  }));
288
285
  }
289
286
  }
@@ -296,16 +293,16 @@ function bindShapeDataPanel(api, host, options = {}) {
296
293
  form.className = 'gf-sd-fields';
297
294
  const style = ((_a = link.style) !== null && _a !== void 0 ? _a : {});
298
295
  form.appendChild(sectionLabel('Label'));
299
- form.appendChild(ctlTextField('Text', String((_c = (_b = link.getLabel) === null || _b === void 0 ? void 0 : _b.call(link)) !== null && _c !== void 0 ? _c : ''), (v) => exec(new engine_1.SetLinkDisplayLabelCommand(link.id, v))));
296
+ form.appendChild(ctlTextField('Text', String((_c = (_b = link.getLabel) === null || _b === void 0 ? void 0 : _b.call(link)) !== null && _c !== void 0 ? _c : ''), (v) => exec(new SetLinkDisplayLabelCommand(link.id, v))));
300
297
  form.appendChild(sectionLabel('Line'));
301
- form.appendChild(colorField('Colour', toHexColor(style['stroke'], '#999999'), (v) => exec(new engine_1.UpdateLinkStyleCommand(link.id, { stroke: v }))));
302
- form.appendChild(numberField('Width', () => { var _a; return (_a = style['strokeWidth']) !== null && _a !== void 0 ? _a : 2; }, (n) => exec(new engine_1.UpdateLinkStyleCommand(link.id, { strokeWidth: Math.max(0, n) }))));
303
- form.appendChild(checkField('Dashed', !!style['strokeDasharray'], (c) => exec(new engine_1.UpdateLinkStyleCommand(link.id, { strokeDasharray: c ? DASH : undefined }))));
298
+ form.appendChild(colorField('Colour', toHexColor(style['stroke'], '#999999'), (v) => exec(new UpdateLinkStyleCommand(link.id, { stroke: v }))));
299
+ form.appendChild(numberField('Width', () => { var _a; return (_a = style['strokeWidth']) !== null && _a !== void 0 ? _a : 2; }, (n) => exec(new UpdateLinkStyleCommand(link.id, { strokeWidth: Math.max(0, n) }))));
300
+ form.appendChild(checkField('Dashed', !!style['strokeDasharray'], (c) => exec(new UpdateLinkStyleCommand(link.id, { strokeDasharray: c ? DASH : undefined }))));
304
301
  form.appendChild(sectionLabel('Arrows'));
305
302
  const marker = (slot, type) => {
306
303
  var _a;
307
304
  const existing = ((_a = style[slot]) !== null && _a !== void 0 ? _a : {});
308
- exec(new engine_1.UpdateLinkStyleCommand(link.id, {
305
+ exec(new UpdateLinkStyleCommand(link.id, {
309
306
  [slot]: Object.assign(Object.assign({ size: 10, filled: true }, existing), { type }),
310
307
  }));
311
308
  };
@@ -314,7 +311,7 @@ function bindShapeDataPanel(api, host, options = {}) {
314
311
  form.appendChild(selectField('Start', ARROW_TYPES, String((_e = (_d = style['arrowTail']) === null || _d === void 0 ? void 0 : _d.type) !== null && _e !== void 0 ? _e : 'none'), (v) => marker('arrowTail', v)));
315
312
  form.appendChild(selectField('End', ARROW_TYPES, String((_g = (_f = style['arrowHead']) === null || _f === void 0 ? void 0 : _f.type) !== null && _g !== void 0 ? _g : 'arrow'), (v) => marker('arrowHead', v)));
316
313
  form.appendChild(sectionLabel('Route'));
317
- form.appendChild(selectField('Path', ROUTE_TYPES, String((_h = link.pathType) !== null && _h !== void 0 ? _h : 'smooth'), (v) => exec(new engine_1.SetLinkPathTypeCommand(link.id, v))));
314
+ form.appendChild(selectField('Path', ROUTE_TYPES, String((_h = link.pathType) !== null && _h !== void 0 ? _h : 'smooth'), (v) => exec(new SetLinkPathTypeCommand(link.id, v))));
318
315
  host.appendChild(form);
319
316
  }
320
317
  // ── multi-selection ───────────────────────────────────────────────────────
@@ -335,13 +332,13 @@ function bindShapeDataPanel(api, host, options = {}) {
335
332
  const applyAll = (nodePatch, linkPatch) => {
336
333
  const cmds = [];
337
334
  if (nodePatch && nodeIds.length > 0)
338
- cmds.push(new engine_1.SetNodeStyleCommand(nodeIds, nodePatch));
335
+ cmds.push(new SetNodeStyleCommand(nodeIds, nodePatch));
339
336
  if (linkPatch)
340
337
  for (const l of links)
341
- cmds.push(new engine_1.UpdateLinkStyleCommand(l.id, linkPatch));
338
+ cmds.push(new UpdateLinkStyleCommand(l.id, linkPatch));
342
339
  if (cmds.length === 0)
343
340
  return;
344
- exec(cmds.length === 1 ? cmds[0] : new engine_1.BatchCommand('Format selection', cmds));
341
+ exec(cmds.length === 1 ? cmds[0] : new BatchCommand('Format selection', cmds));
345
342
  };
346
343
  const form = document.createElement('div');
347
344
  form.className = 'gf-sd-fields';
@@ -365,7 +362,7 @@ function bindShapeDataPanel(api, host, options = {}) {
365
362
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
366
363
  const isEr = !!node.getMetadata('kitEntity');
367
364
  const spec = node.getMetadata(isEr ? 'kitEntity' : 'kitClass');
368
- const handle = isEr ? (0, diagram_kit_1.erTable)(api, node.id) : (0, diagram_kit_1.umlClass)(api, node.id);
365
+ const handle = isEr ? erTable(api, node.id) : umlClass(api, node.id);
369
366
  const form = document.createElement('div');
370
367
  form.className = 'gf-sd-fields';
371
368
  // ── the card itself ──
@@ -1,6 +1,3 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ensureStencilKitStyles = ensureStencilKitStyles;
4
1
  /**
5
2
  * Stencil-palette styles, injected once per document (same discipline as the
6
3
  * dashboard kit: the kit owns its chrome so a host gets a working palette
@@ -118,7 +115,7 @@ const CSS = `
118
115
  .gf-stencil-ghost svg { display: block; }
119
116
  `;
120
117
  /** Inject the palette stylesheet once per document. */
121
- function ensureStencilKitStyles(doc = document) {
118
+ export function ensureStencilKitStyles(doc = document) {
122
119
  if (doc.getElementById(STENCIL_KIT_STYLE_ID))
123
120
  return;
124
121
  const style = doc.createElement('style');
package/esm/src/index.js DELETED
@@ -1,295 +0,0 @@
1
- /**
2
- * `@grafloria/element` — the universal embed.
3
- *
4
- * Two surfaces over the same headless core:
5
- *
6
- * 1. `<grafloria-flow>` — a custom element. Attributes/properties in, DOM events
7
- * out, slotted `<template>`s for custom nodes. Works in Vue, Svelte, Solid,
8
- * Lit, Alpine, plain HTML, a CMS, a notebook — with no wrapper library.
9
- * 2. `Grafloria.render(spec, el)` — the Mermaid-shaped one-call API.
10
- *
11
- * Importing this module registers `<grafloria-flow>` automatically (and is a no-op
12
- * on the server, where `customElements` does not exist). Call
13
- * `Grafloria.define('my-flow')` yourself if you want a different tag name.
14
- */
15
- import { defineGrafloriaFlow } from './lib/grafloria-flow-element';
16
- export { GrafloriaFlowElement, defineGrafloriaFlow, GRAFLORIA_EVENTS } from './lib/grafloria-flow-element';
17
- export { Grafloria, render, renderStatic } from './lib/grafloria';
18
- // The LOAD front door — the other half of `DiagramSerializer.serialize()`.
19
- // `render(fromDocument(json), host)` is the one-liner; see lib/load.ts for why
20
- // the loaded models go back in as models rather than being re-specced.
21
- export { fromDocument } from './lib/load';
22
- export { registerNodeType, unregisterNodeType, registeredNodeTypes, getNodeType, hasNodeType, renderFromTemplate, } from './lib/node-type-registry';
23
- export { renderToStaticSVG, LIGHT_THEME, DARK_THEME } from '@grafloria/renderer';
24
- // React Flow-parity helper surface (getIntersectingNodes & friends) — an embed
25
- // gets the same convenience wrapper the frameworks get, from the same import.
26
- export { createDiagramApi } from '@grafloria/renderer';
27
- /* ==========================================================================
28
- * WAVE 10 — THE REACHABILITY FIX.
29
- *
30
- * Everything below this line ALREADY EXISTED, was ALREADY unit-tested, and was
31
- * ALREADY exported from `@grafloria/renderer` / `@grafloria/engine`. None of it was
32
- * reachable by an actual embedder, because THIS file — the public package —
33
- * re-exported exactly three runtime values (`renderToStaticSVG`, `LIGHT_THEME`,
34
- * `DARK_THEME`) and nothing else.
35
- *
36
- * So: PNG/SVG/PDF export, the round-trip artifact, the Mermaid text format, the
37
- * minimap, the perf HUD, the quality governor, the named-style registry, the
38
- * WCAG contrast maths, `deriveTheme()`, `themeRef()`, the design-token bridges,
39
- * cross-tab sync, the CRDT, presence, comments and presentation mode were all
40
- * built, all green, and all WIRED TO NOTHING at the package boundary. The
41
- * gallery is what caught it: not one of these demos could be written.
42
- *
43
- * The rule this file now follows: if the library claims a feature, this file
44
- * exports the handle you drive it with. `libs/element/src/reachability.spec.ts`
45
- * is the lock — it fails if any of these names stops being reachable.
46
- * ========================================================================== */
47
- // -- Theming ---------------------------------------------------------------
48
- // The theme set + the OS-preference controller behind `colorMode: 'system'`.
49
- export { HIGH_CONTRAST_LIGHT_THEME, HIGH_CONTRAST_DARK_THEME, DEFAULT_THEME_SET, ColorModeController, resolveThemeFromPrefs, readColorPreferences, MEDIA_PREFERS_DARK, MEDIA_PREFERS_CONTRAST, MEDIA_FORCED_COLORS, } from '@grafloria/renderer';
50
- // Theme-bound properties: the CALLER's semantic colours follow a theme swap.
51
- export { themeRef, isThemeRef, themeRefToken, themeRefVar, resolveThemeRef, themeRefCssValue, resolveBindableVars, } from '@grafloria/renderer';
52
- // WCAG maths + a theme derivation that audits its own output.
53
- export { WCAG, parseColor, toHex, relativeLuminance, contrastRatio, meetsContrast, rgbToHsl, hslToRgb, lightnessOf, withLightness, ensureContrast, auditThemeContrast, assertThemeContrast, deriveTheme, } from '@grafloria/renderer';
54
- // The design-token bridge: drive Grafloria from shadcn / MUI / Tailwind variables.
55
- export { shadcnBridge, muiBridge, tailwindBridge, BRIDGEABLE_TOKENS, generateTokenBridgeBlock, generateInstanceOverrideCSS, } from '@grafloria/renderer';
56
- // Port data types — the registry the renderer reads for glyph colours and the
57
- // validator reads for connection compatibility. Same reachability hole as the
58
- // style classes below: read on every frame, and no embedder could WRITE to it —
59
- // the typed-ports demo could not colour its own types through the public API
60
- // (its glyphs silently fell back to direction colours, and the screenshot audit
61
- // read them as such).
62
- export { portTypeRegistry, arePortDataTypesCompatible, portTypeColor } from '@grafloria/engine';
63
- // Stencils & shape masters — the Visio-style palette surface. Named here (not
64
- // left to the `export *` below) because this IS the documented way to browse and
65
- // register shapes: listStencils() feeds a palette, registerStencils() puts every
66
- // master behind engine.templateRegistry for NodeFactory to stamp.
67
- export { listStencils, builtInStencils, getStencil, registerStencils, registerGeneratedTemplates, generatedTemplates, TemplateRegistry, NodeFactory, registerTemplateLibrary, } from '@grafloria/engine';
68
- // Named style classes — the `named-class` layer of the cascade. The cascade read
69
- // this registry on every frame; nothing could WRITE to it.
70
- export { defineStyle, defineStyles, getStyle, hasStyle, removeStyle, clearStyles, listStyles, resolveStyleClasses, resolveNodeStyle, resolveLinkStyle, CASCADE_ORDER, } from '@grafloria/renderer';
71
- // Instance-scoped CSS variables — two diagrams, two themes, one page.
72
- export { GRAFLORIA_INSTANCE_ATTR, GRAFLORIA_VAR_PREFIX, THEME_VARS, THEME_TOKENS, cssVarName, themeVar, themeVarValue, resolveThemeVars, instanceScopeSelector, } from '@grafloria/renderer';
73
- // -- Export ----------------------------------------------------------------
74
- // Deterministic, DOM-free SVG serialization; true vector PDF; the raster seam.
75
- export { exportSvg, serializeVNode, vnodeBounds, exportPdf, paginate, buildPrintDocument, exportBatch, createDomRasterBackend, resolveRasterBackend, canRasterizeInThisEnvironment, svgToDataUri, mimeTypeForFormat, } from '@grafloria/renderer';
76
- // The model rides INSIDE the artifact: SVG metadata + a real PNG iTXt chunk.
77
- export { GRAFLORIA_NS, GRAFLORIA_MODEL_KEY, embedModelInSvg, extractModelFromSvg, embedModelInPng, extractModelFromPng, extractModel, isEditableArtifact, importDiagram, } from '@grafloria/renderer';
78
- // -- Canvas furniture ------------------------------------------------------
79
- // One call over a DiagramInstance. `gridEnabled` / `showMinimap` / `snapEnabled`
80
- // are only live once this runs — which nothing could call.
81
- export { attachCanvasPlugins, createMiniMap, createControls, createBackground, } from '@grafloria/renderer';
82
- // -- Performance -----------------------------------------------------------
83
- export { PerfHud, formatSnapshot, EMPTY_SNAPSHOT, QualityGovernor } from '@grafloria/renderer';
84
- // -- Collaboration (renderer half) -----------------------------------------
85
- // Presence is a SEPARATE DOM layer that never enters the VNode tree.
86
- export { bindPresence, PresenceOverlay, PRESENCE_LAYER_CLASS, actorColor, actorInitials, contrastingTextColor, } from '@grafloria/renderer';
87
- export { CommentOverlayController } from '@grafloria/renderer';
88
- export { InMemoryViewportChannel, presentTo, followPresenter, lockDocument, isDocumentLocked, loadReadonlySnapshot, } from '@grafloria/renderer';
89
- // -- Collaboration (engine half) -------------------------------------------
90
- // Sync, the CRDT and comments live in the ENGINE, and this package did not
91
- // re-export the engine AT ALL — its only reference was a type-only import,
92
- // erased at build. Zero collaboration symbols survived into the bundle.
93
- export { createSyncSession, SyncAdapter, MemoryHub, MemoryTransport, BroadcastChannelTransport, WebSocketTransport, UnreliableHub, Awareness, VersionVector, OpBatcher, CausalBuffer, } from '@grafloria/engine';
94
- // The per-property CRDT. Whole-entity LWW would silently throw one edit away.
95
- export { Replica, LwwRegistry, OpLog, UndoStack, ReferentialIntegrity, LamportClock, applyOp, replay, compareOps, opId, } from '@grafloria/engine';
96
- // Threaded comments. A deleted node ORPHANS its thread; it never destroys it.
97
- export { CommentStore } from '@grafloria/engine';
98
- // The lossless Mermaid-compatible text format, with hand-edit detection.
99
- export { exportDiagramText, importDiagramText, stripGrafloriaSidecar, GRAFLORIA_DOC_PREFIX, GRAFLORIA_HASH_PREFIX, } from '@grafloria/engine';
100
- export { DiagramSerializer } from '@grafloria/engine';
101
- // wave10/whiteboard: ink as a first-class model entity — authors seed and inspect strokes
102
- // through this, the same class the draw tool commits.
103
- export { StrokeModel, DEFAULT_STROKE_STYLE } from '@grafloria/engine';
104
- // ===========================================================================
105
- // wave10/gallery BUG FIX — the AUTHORING SEAMS were not on the public embed.
106
- //
107
- // This package's own doc calls itself "the universal embed … so an embed never
108
- // needs a second import". It exported fifteen values, and every registry an
109
- // author actually extends the engine THROUGH was missing from all of them:
110
- //
111
- // registerLinkTemplate / registerLabelTemplate — custom edges & labels
112
- // registerMarker — named custom arrowheads
113
- // registerConnector / registerAnchor /
114
- // registerConnectionPoint — the wave-6 link pipeline
115
- // registerConnectionValidator / isValidConnection — vetoing a connection
116
- // registerTool — replacing a gesture
117
- // createPortal / createViewportPortal — anchoring UI to geometry
118
- // (an edge toolbar, a badge)
119
- //
120
- // Every one of them is a documented, semver'd, unit-tested extension point of
121
- // `@grafloria/renderer`. None was reachable from `<grafloria-flow>` or `Grafloria.render()`
122
- // — i.e. from the surface this package exists to BE. An embedder who took the
123
- // package at its word ("no second import") could not write a custom edge.
124
- //
125
- // These are re-exports, not new API. The registries are process-wide singletons
126
- // in @grafloria/renderer, so registering through here is the same registration the
127
- // renderer's own consumers read.
128
- // ===========================================================================
129
- export {
130
- // Custom edges, labels and named markers (Wave 4 — Card 5).
131
- registerLinkTemplate, unregisterLinkTemplate, listLinkTemplates, registerLabelTemplate, unregisterLabelTemplate, listLabelTemplates, registerMarker, unregisterMarker, listMarkers, htmlLabelVNode,
132
- // The link pipeline: anchors, connection points, connectors (Wave 6 — Card 2).
133
- registerAnchor, listAnchors, registerConnectionPoint, listConnectionPoints, registerConnector, listConnectors,
134
- // Connection validation + the tool registry (Wave 6 — Card 5).
135
- registerConnectionValidator, isValidConnection, clearConnectionValidators, registerTool, listTools,
136
- // wave10/whiteboard: the freehand-draw / rectangle / eraser tools + the in-progress
137
- // ink overlay. Register them through `registerTool` — an embed draws on its diagram
138
- // with no second import, which is the whole promise of this package.
139
- createDrawTool, createRectangleTool, createEraserTool,
140
- // wave13/stroke-edit: select + move committed ink (the drawn/erased/EDITED triad closes).
141
- createStrokeEditTool, DrawTool, RectangleTool, EraserTool, StrokeEditTool, InkOverlay, INK_OVERLAY_CLASS,
142
- // Anchoring your own DOM to diagram geometry — how an edge toolbar is built.
143
- createPortal, createViewportPortal, createCounterScaledPortal, } from '@grafloria/renderer';
144
- // ===========================================================================
145
- // wave11/nodes GALLERY BUG FIX — the NODE authoring seams were not on the embed.
146
- //
147
- // Same finding shape as Wave 10, one layer down. This package re-exported the
148
- // EDGE/PORT authoring registries (Wave 10) and the whole collaboration/export
149
- // stack, but the NODE-shape and node-sizing seams — every one a documented,
150
- // unit-tested, `@grafloria/renderer`-exported extension point — were missing from
151
- // all fifteen-plus re-exports. An embedder taking the package at its word ("the
152
- // universal embed … an embed never needs a second import") could NOT:
153
- //
154
- // - draw any of the 21 built-in figures' CUSTOM cousins, or register a custom
155
- // silhouette: `registerShape` / `registerPathShape` / `listShapes` were
156
- // reachable only past the package boundary. (The 21 built-ins render fine via
157
- // `shape: { type }`, because the registry pre-registers them; a custom shape
158
- // could not be added at all.)
159
- // - read or reuse the per-node sizing contract the resizer AND the auto-sizer
160
- // share (`getNodeSizing` / `clampSizeToConstraints` / `resolveAspectRatio`) —
161
- // the min/max/aspect clamp math that a custom resize gesture (built on the
162
- // public `registerTool` seam) needs to honour a node's declared limits.
163
- // - measure a node from its content (`desiredNodeSize` / `measureLabelContent`
164
- // / `autoSizeNode`), or build an in-node foreignObject / read its toolbar
165
- // config, or drive proximity-connect from the shipped `SnapController`, or
166
- // create SWIMLANES — `SwimlaneService`, a whole engine feature React Flow
167
- // does not have, was reachable only via a second `@grafloria/engine` import.
168
- //
169
- // All re-exports, no new API. The registries are process-wide singletons in
170
- // @grafloria/renderer / @grafloria/engine, so registering through here is the exact
171
- // registration the renderer's own consumers read.
172
- // ===========================================================================
173
- export {
174
- // The node figure registry (21 built-ins + custom silhouettes).
175
- registerShape, registerPathShape, unregisterShape, getShape, hasShape, listShapes, getShapeDefinition, getShapeRegistryVersion, onShapeRegistryChange,
176
- // Per-node sizing constraints — the min/max/aspect contract the resizer clamps
177
- // to DURING a gesture and the auto-sizer floors/ceils to.
178
- getNodeSizing, isAutoSized, resolveAspectRatio, clampSizeToConstraints, clampValue,
179
- // Content-aware auto-sizing (a node grows to fit its label + panel).
180
- measureLabelContent, desiredNodeSize, outerSizeForInner, autoSizeNode, autoSizeDiagram,
181
- // Per-node toolbar config seam + in-node HTML (foreignObject) content.
182
- getNodeToolbar, resolveToolbar, getHtmlContent, hasHtmlContent, buildHtmlForeignObject,
183
- // Proximity-connect: the shipped reference implementation, addressable at last.
184
- SnapController, DEFAULT_SNAP_CONFIG, } from '@grafloria/renderer';
185
- // Swimlanes / pools / lanes — a whole containment model in the ENGINE that the
186
- // package re-exported none of. React Flow has no equivalent.
187
- export { SwimlaneService } from '@grafloria/engine';
188
- export { GroupModel } from '@grafloria/engine';
189
- export { GroupCollapseService, PROXY_NODE_GROUP_KEY, PROXY_LINK_GROUP_KEY } from '@grafloria/engine';
190
- // serveLayout — the worker body for OFF-THREAD layout. `engine.setLayoutPort()`
191
- // takes any port; an app runs the layout in a real Worker by importing this
192
- // package inside the worker and calling `serveLayout(self)`. It was exported
193
- // from @grafloria/engine and reachable by NOBODY through the embed, so the whole
194
- // off-thread-layout capability (progress streaming + mid-run cancellation with
195
- // a retained partial result) could not be wired from the public package.
196
- export { serveLayout } from '@grafloria/engine';
197
- // ===========================================================================
198
- // DIAGRAM KIT — reusable ER / UML builders (wave16m).
199
- //
200
- // The diagrams/* demos proved Grafloria can draw database tables with crow's-foot
201
- // cardinality (field-level FK→PK included) and full-vocabulary UML class
202
- // diagrams — but every page hand-composed the HTML cards, the CSS, the
203
- // selection overrides and the marker tables. That is a capability, not a
204
- // feature. This kit is the feature: typed builders that emit a ready render()
205
- // spec + one self-injected stylesheet, so an embedder writes DATA:
206
- //
207
- // const spec = erDiagram({ entities, relationships });
208
- // render(spec, el);
209
- //
210
- // const uml = umlDiagram({ classes, relationships });
211
- // const api = render(uml, el); uml.finalize(api);
212
- // ===========================================================================
213
- export { erDiagram, erRowCenterY, ER_ROW_H, ER_HEAD_H, umlDiagram, ensureDiagramKitStyles, DIAGRAM_KIT_STYLE_ID,
214
- // In-canvas editing (P2–P4): live edits + the gesture binder.
215
- updateEntity, updateClass, addColumnAt, removeColumnAt, renameColumnAt, bindCardEditing, matchColumns, rowIndexFromY,
216
- // Live join guidance (query-builder): score every other table's columns
217
- // against a connection drag's source column and tint the kit rows by fit.
218
- scoreMatch, matchTier, assignTiers, singularize, bindJoinGuidance, ensureJoinGuidanceStyles, JOIN_GUIDANCE_STYLE_ID, } from './lib/diagram-kit';
219
- // Typed façade handles (domain-API decision, Option B): the OO surface —
220
- // CardHandle → ErTable/UmlClass, ErField — over the data-first kit.
221
- export { erTable, umlClass, erTables, umlClasses, CardHandle, ErTable, ErField, ErColumnList, UmlClass, UmlMemberList, } from './lib/diagram-kit';
222
- // ===========================================================================
223
- // THE DASHBOARD KIT — Phase 2 of the dashboard-grid plan.
224
- //
225
- // The dashboard demo proved Grafloria can host a dashboard-builder app — but its
226
- // interaction (live push while you hover, truthful placeholder, cell-stepped
227
- // resize, one undo step per gesture) was page JS. This kit is the feature:
228
- // `bindDashboardGrid(api, group)` puts a GridPackEngine-driven pack grid on
229
- // any group of widget nodes, with cells persisted in the EXISTING
230
- // GridItemConfig. Element-local code, so the Phase-0 wholesale re-export
231
- // below does NOT cover it — this curated block is its only door.
232
- // ===========================================================================
233
- export { bindDashboardGrid, rowHeightFor, boardHeightFor, columnUnitFor, cellToRect, pointToCell, sizeToSpan, gridItemFromCell, cellFromGridItem, buildCommitCommands, ensureDashboardKitStyles, DASHBOARD_KIT_STYLE_ID,
234
- // The DATA-FIRST authoring API — the erDiagram()/umlDiagram() equivalent.
235
- dashboard,
236
- // …and the built-in renderers behind `kind`, so a dashboard is useful with
237
- // no renderWidget at all. Composable: call defaultWidgetRenderer first, then
238
- // decorate the host.
239
- defaultWidgetRenderer, renderKpiWidget, renderLineWidget, renderBarWidget, renderDonutWidget, renderFunnelWidget, renderTableWidget, BUILT_IN_WIDGET_KINDS, } from './lib/dashboard-kit';
240
- // The stencil kit — a Visio-style palette that drags shape masters onto the
241
- // canvas (T6/T7). Pairs with listStencils()/registerStencils() above.
242
- export { bindStencilPalette, bindShapeDataPanel, ensureStencilKitStyles } from './lib/stencil-kit';
243
- /* ==========================================================================
244
- * PHASE 0 — THE INVERSION.
245
- *
246
- * Everything above this line is a CURATED re-export: a hand-written list, added
247
- * to whenever someone noticed a capability was missing. That model made the
248
- * front door default-DENY — a capability shipped in `@grafloria/engine` or
249
- * `@grafloria/renderer` was invisible to embedders until a human remembered to add
250
- * a line here. The Wave 10 comment above records what that cost the first time.
251
- * It kept costing: an audit found 207 capability-level symbols (classes, and
252
- * `register…` / `create…` / `define…` factories) built, tested, exported one
253
- * layer down, and unreachable from this package — including `DiagramEngine`, `DiagramModel`,
254
- * `NodeModel`, `Command`, `CommandManager`, `RoutingEngine`, `LayoutRegistry`,
255
- * `EventBus`, `PluginManager` and every one of the 30 undoable commands. The
256
- * repo's own flagship app (apps/renderer-demo, which contains a dashboard
257
- * builder, a workflow builder and an ERD designer — exactly the apps this
258
- * package is meant to enable) imports `@grafloria/engine` in 41 files and
259
- * `@grafloria/element` in ZERO. It could not have used the front door.
260
- *
261
- * So the default flips: this package now re-exports the two lower packages
262
- * WHOLESALE. Adding a capability downstairs makes it reachable here with no
263
- * edit to this file, and `reachability.spec.ts` — now an INVERTED lock — fails
264
- * the build if a capability is NOT reachable, rather than passing silently.
265
- *
266
- * The curated block above is kept deliberately: it is the DOCUMENTED surface
267
- * (what the 15-line getting-started guide uses), and explicit exports take
268
- * precedence over `export *`, so it also resolves the collisions below.
269
- * ========================================================================== */
270
- export * from '@grafloria/engine';
271
- export * from '@grafloria/renderer';
272
- /* -- Collision resolution (9 names are declared in BOTH lower packages) -----
273
- * Under ES `export *` semantics an ambiguous name is silently OMITTED from the
274
- * re-export — a silent hole, which is the exact failure mode this phase exists
275
- * to kill. So every one is resolved explicitly. The ENGINE wins by default:
276
- * its declarations are the document vocabulary an app manipulates. Nothing is
277
- * dropped — each renderer counterpart keeps a qualified name below.
278
- *
279
- * (`NodeModel`, `PortModel`, `PortLayoutArgs` and `PortLayoutSpec` are NOT real
280
- * collisions: `svg/port-layout.ts` re-exports the engine's own declarations.
281
- * They are pinned here anyway — they are the most load-bearing names in the
282
- * package, and pinning costs one line.)
283
- */
284
- export { NodeModel, PortModel, distanceToSegment, rotatePoint, coalesce, } from '@grafloria/engine';
285
- // The three genuine VALUE collisions, kept reachable under qualified names.
286
- // `coalesce` is the one that matters: the engine's coalesces op-log entries for
287
- // batching, the renderer's merges dirty rectangles for partial redraw. Same
288
- // name, unrelated jobs — losing either to an `export *` ambiguity would be a
289
- // silent capability hole rather than a compile error.
290
- export { distanceToSegment as distanceToSegmentCanvas, rotatePoint as rotatePointSelection, coalesce as coalesceRects, } from '@grafloria/renderer';
291
- // Side effect: define the element on import. This is what makes
292
- // `<script type="module" src="…/grafloria.js"></script>` + `<grafloria-flow>` in the
293
- // markup Just Work, which is the entire point of the card.
294
- defineGrafloriaFlow();
295
- //# sourceMappingURL=index.js.map