@msdshsk/react-er-canvas 0.0.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 (41) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE.md +48 -0
  3. package/README.ja.md +216 -0
  4. package/README.md +216 -0
  5. package/dist/components/JoinEdge.d.ts +10 -0
  6. package/dist/components/JoinEdge.d.ts.map +1 -0
  7. package/dist/components/MermaidER.d.ts +46 -0
  8. package/dist/components/MermaidER.d.ts.map +1 -0
  9. package/dist/components/TableNode.d.ts +30 -0
  10. package/dist/components/TableNode.d.ts.map +1 -0
  11. package/dist/core/index.d.ts +5 -0
  12. package/dist/core/index.d.ts.map +1 -0
  13. package/dist/core/layout.d.ts +58 -0
  14. package/dist/core/layout.d.ts.map +1 -0
  15. package/dist/core/layout.test.d.ts +2 -0
  16. package/dist/core/layout.test.d.ts.map +1 -0
  17. package/dist/core/model.d.ts +55 -0
  18. package/dist/core/model.d.ts.map +1 -0
  19. package/dist/core/parser/grammar.d.ts +22 -0
  20. package/dist/core/parser/grammar.d.ts.map +1 -0
  21. package/dist/core/parser/index.d.ts +15 -0
  22. package/dist/core/parser/index.d.ts.map +1 -0
  23. package/dist/core/parser/lexer.d.ts +18 -0
  24. package/dist/core/parser/lexer.d.ts.map +1 -0
  25. package/dist/core/parser/parser.test.d.ts +2 -0
  26. package/dist/core/parser/parser.test.d.ts.map +1 -0
  27. package/dist/core/parser/resolve.test.d.ts +2 -0
  28. package/dist/core/parser/resolve.test.d.ts.map +1 -0
  29. package/dist/core-BtdV83x9.cjs +2 -0
  30. package/dist/core-BtdV83x9.cjs.map +1 -0
  31. package/dist/core-DZ30VgUT.js +345 -0
  32. package/dist/core-DZ30VgUT.js.map +1 -0
  33. package/dist/core.cjs +1 -0
  34. package/dist/core.js +2 -0
  35. package/dist/index.cjs +2 -0
  36. package/dist/index.cjs.map +1 -0
  37. package/dist/index.d.ts +6 -0
  38. package/dist/index.d.ts.map +1 -0
  39. package/dist/index.js +592 -0
  40. package/dist/index.js.map +1 -0
  41. package/package.json +92 -0
package/dist/index.js ADDED
@@ -0,0 +1,592 @@
1
+ import { a as e, c as t, i as n, n as r, o as i, r as a, s as o, t as s } from "./core-DZ30VgUT.js";
2
+ import { Fragment as c, createContext as l, memo as u, useCallback as d, useContext as f, useEffect as p, useMemo as m, useState as h } from "react";
3
+ import { Background as ee, BaseEdge as g, Controls as _, EdgeLabelRenderer as v, Handle as y, MiniMap as te, Position as b, ReactFlow as ne, getSmoothStepPath as x, useNodesState as S } from "@xyflow/react";
4
+ import { Fragment as C, jsx as w, jsxs as T } from "react/jsx-runtime";
5
+ //#region src/components/TableNode.tsx
6
+ var E = l(/* @__PURE__ */ new Map()), D = l({
7
+ enabled: !1,
8
+ selected: /* @__PURE__ */ new Set(),
9
+ onToggle: () => void 0
10
+ }), O = l(!1), k = l({}), A = {
11
+ pk: {
12
+ label: "PK",
13
+ bg: "#f59e0b"
14
+ },
15
+ fk: {
16
+ label: "FK",
17
+ bg: "#3b82f6"
18
+ },
19
+ uk: {
20
+ label: "UK",
21
+ bg: "#10b981"
22
+ }
23
+ };
24
+ function j({ tableName: e, column: t, highlighted: n, onClick: r, selectionEnabled: i, selected: a, onSelectToggle: o }) {
25
+ let s = [];
26
+ return t.keys.pk && s.push(A.pk), t.keys.fk && s.push(A.fk), t.keys.uk && s.push(A.uk), /* @__PURE__ */ T("div", {
27
+ title: t.comment,
28
+ onClick: r ? () => r(e, t.name) : void 0,
29
+ style: {
30
+ display: "flex",
31
+ alignItems: "center",
32
+ gap: 6,
33
+ padding: "0 10px",
34
+ fontSize: 12,
35
+ fontFamily: "ui-monospace, SFMono-Regular, Consolas, monospace",
36
+ borderTop: "1px solid #eee",
37
+ height: 22,
38
+ boxSizing: "border-box",
39
+ cursor: r ? "pointer" : "default",
40
+ background: n ? "#fef3c7" : a ? "#eff6ff" : "transparent",
41
+ transition: "background 0.15s"
42
+ },
43
+ children: [
44
+ i && /* @__PURE__ */ w("input", {
45
+ type: "checkbox",
46
+ checked: a,
47
+ onChange: (e) => o(e.target.checked),
48
+ onClick: (e) => e.stopPropagation(),
49
+ style: {
50
+ width: 13,
51
+ height: 13,
52
+ margin: 0,
53
+ flexShrink: 0,
54
+ cursor: "pointer"
55
+ }
56
+ }),
57
+ /* @__PURE__ */ w("span", {
58
+ style: {
59
+ display: "flex",
60
+ gap: 2,
61
+ flexShrink: 0,
62
+ minWidth: 18
63
+ },
64
+ children: s.map((e) => /* @__PURE__ */ w("span", {
65
+ style: {
66
+ display: "inline-block",
67
+ padding: "0 4px",
68
+ borderRadius: 3,
69
+ background: e.bg,
70
+ color: "#fff",
71
+ fontSize: 9,
72
+ fontWeight: 700,
73
+ lineHeight: "14px"
74
+ },
75
+ children: e.label
76
+ }, e.label))
77
+ }),
78
+ /* @__PURE__ */ w("span", {
79
+ style: {
80
+ flexShrink: 0,
81
+ fontWeight: t.keys.pk ? 600 : 400,
82
+ color: "#1f2937"
83
+ },
84
+ children: t.name
85
+ }),
86
+ t.type && /* @__PURE__ */ w("span", {
87
+ style: {
88
+ flex: 1,
89
+ textAlign: "right",
90
+ color: "#9ca3af",
91
+ fontStyle: "italic",
92
+ overflow: "hidden",
93
+ textOverflow: "ellipsis",
94
+ whiteSpace: "nowrap"
95
+ },
96
+ children: t.type
97
+ })
98
+ ]
99
+ });
100
+ }
101
+ var M = u(function({ data: e }) {
102
+ let { table: t } = e, n = f(E), r = f(D), i = f(O), a = f(k), o = a.onColumnClick, s = n.get(t.name), l = t.group ? "#1e40af" : "#374151", u = (e) => ({
103
+ ...e,
104
+ width: i ? 9 : 6,
105
+ height: i ? 9 : 6,
106
+ background: i ? "#3b82f6" : "transparent",
107
+ border: i ? "1.5px solid #fff" : "none",
108
+ boxShadow: i ? "0 0 0 1px rgba(59,130,246,0.4)" : "none",
109
+ opacity: i ? .85 : 0,
110
+ pointerEvents: i ? "auto" : "none",
111
+ cursor: i ? "crosshair" : "default"
112
+ });
113
+ return /* @__PURE__ */ T("div", {
114
+ style: {
115
+ background: "#fff",
116
+ border: "1px solid #c4c4c4",
117
+ borderRadius: 6,
118
+ boxShadow: "0 2px 6px rgba(0,0,0,0.08)",
119
+ overflow: "visible",
120
+ width: "100%",
121
+ height: "100%",
122
+ display: "flex",
123
+ flexDirection: "column",
124
+ position: "relative"
125
+ },
126
+ children: [
127
+ /* @__PURE__ */ w(y, {
128
+ id: "__default-target",
129
+ type: "target",
130
+ position: b.Left,
131
+ style: u({ top: 32 / 2 })
132
+ }),
133
+ /* @__PURE__ */ w(y, {
134
+ id: "__default-source",
135
+ type: "source",
136
+ position: b.Right,
137
+ style: u({ top: 32 / 2 })
138
+ }),
139
+ /* @__PURE__ */ T("div", {
140
+ style: {
141
+ padding: "6px 10px",
142
+ background: l,
143
+ color: "#fff",
144
+ fontWeight: 600,
145
+ fontSize: 13,
146
+ height: 32,
147
+ boxSizing: "border-box",
148
+ display: "flex",
149
+ alignItems: "center",
150
+ justifyContent: "space-between",
151
+ gap: 8,
152
+ borderTopLeftRadius: 6,
153
+ borderTopRightRadius: 6
154
+ },
155
+ children: [/* @__PURE__ */ w("span", {
156
+ style: {
157
+ overflow: "hidden",
158
+ textOverflow: "ellipsis",
159
+ whiteSpace: "nowrap"
160
+ },
161
+ children: t.name
162
+ }), /* @__PURE__ */ T("span", {
163
+ style: {
164
+ display: "flex",
165
+ alignItems: "center",
166
+ gap: 4,
167
+ flexShrink: 0
168
+ },
169
+ children: [t.group && /* @__PURE__ */ w("span", {
170
+ style: {
171
+ fontSize: 10,
172
+ opacity: .75,
173
+ fontWeight: 400,
174
+ padding: "1px 5px",
175
+ border: "1px solid rgba(255,255,255,0.3)",
176
+ borderRadius: 3
177
+ },
178
+ children: t.group
179
+ }), a.onTableRemove && /* @__PURE__ */ w("button", {
180
+ className: "nodrag",
181
+ onClick: (e) => {
182
+ e.stopPropagation(), a.onTableRemove?.(t.name);
183
+ },
184
+ onMouseDown: (e) => e.stopPropagation(),
185
+ title: "Remove this table",
186
+ style: {
187
+ background: "rgba(255,255,255,0.18)",
188
+ border: "none",
189
+ color: "#fff",
190
+ width: 18,
191
+ height: 18,
192
+ borderRadius: 3,
193
+ cursor: "pointer",
194
+ fontSize: 13,
195
+ fontWeight: 700,
196
+ padding: 0,
197
+ lineHeight: 1,
198
+ display: "flex",
199
+ alignItems: "center",
200
+ justifyContent: "center"
201
+ },
202
+ children: "×"
203
+ })]
204
+ })]
205
+ }),
206
+ t.columns.map((e, n) => {
207
+ let i = 32 + n * 22 + 22 / 2, a = s?.has(e.name) ?? !1, l = `${t.name}.${e.name}`, d = r.enabled && r.selected.has(l);
208
+ return /* @__PURE__ */ T(c, { children: [
209
+ /* @__PURE__ */ w(y, {
210
+ id: `${e.name}__target`,
211
+ type: "target",
212
+ position: b.Left,
213
+ style: u({ top: i })
214
+ }),
215
+ /* @__PURE__ */ w(y, {
216
+ id: `${e.name}__source`,
217
+ type: "source",
218
+ position: b.Right,
219
+ style: u({ top: i })
220
+ }),
221
+ /* @__PURE__ */ w(j, {
222
+ tableName: t.name,
223
+ column: e,
224
+ highlighted: a,
225
+ onClick: o,
226
+ selectionEnabled: r.enabled,
227
+ selected: d,
228
+ onSelectToggle: (n) => r.onToggle(t.name, e.name, n)
229
+ })
230
+ ] }, `${e.name}-${n}`);
231
+ })
232
+ ]
233
+ });
234
+ }), N = u(function({ id: e, sourceX: t, sourceY: n, targetX: r, targetY: i, sourcePosition: a, targetPosition: o, data: s, selected: c }) {
235
+ let [l, u, d] = x({
236
+ sourceX: t,
237
+ sourceY: n,
238
+ sourcePosition: a,
239
+ targetX: r,
240
+ targetY: i,
241
+ targetPosition: o
242
+ }), f = s ?? {}, p = !!c || !!f.hovered, m = f.color || "#3b82f6";
243
+ return /* @__PURE__ */ T(C, { children: [/* @__PURE__ */ w(g, {
244
+ id: e,
245
+ path: l,
246
+ style: {
247
+ stroke: m,
248
+ strokeWidth: p ? 2.5 : 2,
249
+ strokeDasharray: "6 3"
250
+ }
251
+ }), /* @__PURE__ */ w(v, { children: /* @__PURE__ */ T("div", {
252
+ className: "nodrag nopan",
253
+ style: {
254
+ position: "absolute",
255
+ transform: `translate(-50%, -50%) translate(${u}px, ${d}px)`,
256
+ background: m,
257
+ color: "#fff",
258
+ fontSize: 10,
259
+ fontFamily: "ui-monospace, SFMono-Regular, Consolas, monospace",
260
+ fontWeight: 700,
261
+ borderRadius: 3,
262
+ padding: "2px 4px 2px 6px",
263
+ display: "flex",
264
+ alignItems: "center",
265
+ gap: 4,
266
+ pointerEvents: "all",
267
+ boxShadow: p ? "0 0 0 2px rgba(0,0,0,0.4)" : "0 1px 2px rgba(0,0,0,0.15)",
268
+ userSelect: "none"
269
+ },
270
+ children: [/* @__PURE__ */ w("span", { children: f.type }), f.onDelete && /* @__PURE__ */ w("button", {
271
+ type: "button",
272
+ onClick: (e) => {
273
+ e.stopPropagation(), f.onDelete?.();
274
+ },
275
+ onMouseDown: (e) => e.stopPropagation(),
276
+ title: "Remove this JOIN",
277
+ style: {
278
+ background: "rgba(255,255,255,0.25)",
279
+ border: "none",
280
+ color: "#fff",
281
+ width: 14,
282
+ height: 14,
283
+ borderRadius: 2,
284
+ cursor: "pointer",
285
+ fontSize: 11,
286
+ fontWeight: 700,
287
+ padding: 0,
288
+ lineHeight: 1,
289
+ display: "flex",
290
+ alignItems: "center",
291
+ justifyContent: "center"
292
+ },
293
+ children: "×"
294
+ })]
295
+ }) })] });
296
+ }), P = { table: M }, re = { joinEdge: N };
297
+ function ie(e) {
298
+ try {
299
+ return {
300
+ model: t(e),
301
+ error: null
302
+ };
303
+ } catch (e) {
304
+ if (e instanceof o) return {
305
+ model: null,
306
+ error: e
307
+ };
308
+ throw e;
309
+ }
310
+ }
311
+ function F(e, t) {
312
+ return t ? `${t}__${e}` : `__default-${e}`;
313
+ }
314
+ var I = "join:";
315
+ function L(e) {
316
+ if (!e || e.startsWith("__default-")) return;
317
+ let t = /^(.+)__(?:source|target)$/.exec(e);
318
+ return t ? t[1] : void 0;
319
+ }
320
+ function R(e) {
321
+ return `${e.table}.${e.column}`;
322
+ }
323
+ var ae = {
324
+ INNER: "#3b82f6",
325
+ LEFT: "#8b5cf6",
326
+ RIGHT: "#a855f7",
327
+ FULL: "#ec4899",
328
+ CROSS: "#6b7280"
329
+ };
330
+ function z(e) {
331
+ let { source: t, model: n, algorithm: r, direction: a, aspectRatio: o, positions: s, onPositionsChange: c, showColumnCheckboxes: l, selectedColumns: u, onColumnSelectionChange: f, enableManualJoins: g, joins: v, onJoinConnect: y, onJoinDelete: b, onTableRemove: x, onColumnClick: C, onTableClick: A, deleteKeyCode: j = "Delete", className: M, style: N, highlightReferencesOnHover: z = !0 } = e, { model: B, error: V } = m(() => n ? {
332
+ model: n,
333
+ error: null
334
+ } : t == null ? {
335
+ model: null,
336
+ error: null
337
+ } : ie(t), [t, n]), [H, U] = h(null), [W, G] = h(null);
338
+ p(() => {
339
+ if (!B) {
340
+ U(null);
341
+ return;
342
+ }
343
+ let e = !1;
344
+ return i(B, {
345
+ algorithm: r,
346
+ direction: a,
347
+ aspectRatio: o
348
+ }).then((t) => {
349
+ e || U(t);
350
+ }), () => {
351
+ e = !0;
352
+ };
353
+ }, [
354
+ B,
355
+ r,
356
+ a,
357
+ o
358
+ ]);
359
+ let K = m(() => {
360
+ if (!H || !B) return [];
361
+ let e = new Map(B.tables.map((e) => [e.name, e])), t = [];
362
+ for (let n of H.nodes) {
363
+ let r = e.get(n.id);
364
+ if (!r) continue;
365
+ let i = s?.[n.id], a = { table: r };
366
+ t.push({
367
+ id: n.id,
368
+ type: "table",
369
+ position: i ?? {
370
+ x: n.x,
371
+ y: n.y
372
+ },
373
+ data: a,
374
+ width: n.width,
375
+ height: n.height,
376
+ draggable: !0,
377
+ deletable: !1
378
+ });
379
+ }
380
+ return t;
381
+ }, [
382
+ H,
383
+ B,
384
+ s
385
+ ]), [q, J, oe] = S(K);
386
+ p(() => {
387
+ J(K);
388
+ }, [K, J]);
389
+ let se = d((e, t, n) => {
390
+ if (!c) return;
391
+ let r = { ...s ?? {} };
392
+ for (let e of n) r[e.id] = {
393
+ x: e.position.x,
394
+ y: e.position.y
395
+ };
396
+ c(r);
397
+ }, [s, c]), Y = m(() => {
398
+ if (!(!W || !B)) return B.relations.find((e) => e.id === W);
399
+ }, [W, B]), X = m(() => {
400
+ if (!W || !v || !W.startsWith(I)) return;
401
+ let e = W.slice(5);
402
+ return v.find((t) => t.id === e);
403
+ }, [W, v]), ce = m(() => {
404
+ let e = /* @__PURE__ */ new Map();
405
+ if (!z) return e;
406
+ let t = (t, n) => {
407
+ if (!n) return;
408
+ let r = e.get(t) ?? /* @__PURE__ */ new Set();
409
+ r.add(n), e.set(t, r);
410
+ };
411
+ return Y && (t(Y.from, Y.fromColumn), t(Y.to, Y.toColumn)), X && (t(X.source.table, X.source.column), t(X.target.table, X.target.column)), e;
412
+ }, [
413
+ Y,
414
+ X,
415
+ z
416
+ ]), Z = m(() => new Set((u ?? []).map(R)), [u]), Q = d((e, t, n) => {
417
+ if (!f) return;
418
+ let r = u ?? [];
419
+ if (n) {
420
+ if (r.some((n) => n.table === e && n.column === t)) return;
421
+ f([...r, {
422
+ table: e,
423
+ column: t
424
+ }]);
425
+ } else f(r.filter((n) => !(n.table === e && n.column === t)));
426
+ }, [u, f]), le = m(() => ({
427
+ enabled: l ?? !1,
428
+ selected: Z,
429
+ onToggle: Q
430
+ }), [
431
+ l,
432
+ Z,
433
+ Q
434
+ ]), ue = m(() => {
435
+ if (!H || !B) return [];
436
+ let e = new Set(B.tables.map((e) => e.name)), t = new Map(B.relations.map((e) => [e.id, e])), n = [];
437
+ for (let r of H.edges) {
438
+ if (!e.has(r.source) || !e.has(r.target)) continue;
439
+ let i = t.get(r.id), a = r.id === W;
440
+ n.push({
441
+ id: r.id,
442
+ source: r.source,
443
+ target: r.target,
444
+ sourceHandle: F("source", i?.fromColumn),
445
+ targetHandle: F("target", i?.toColumn),
446
+ type: "smoothstep",
447
+ animated: a,
448
+ deletable: !1,
449
+ style: {
450
+ stroke: a ? "#f59e0b" : "#9ca3af",
451
+ strokeWidth: a ? 2 : 1.5
452
+ },
453
+ label: i?.label,
454
+ labelStyle: {
455
+ fontSize: 10,
456
+ fill: "#6b7280"
457
+ },
458
+ labelBgStyle: {
459
+ fill: "#fff",
460
+ fillOpacity: .85
461
+ },
462
+ labelBgPadding: [4, 2],
463
+ labelBgBorderRadius: 3
464
+ });
465
+ }
466
+ let r = [];
467
+ for (let t of v ?? []) {
468
+ if (!e.has(t.source.table) || !e.has(t.target.table)) continue;
469
+ let n = `${I}${t.id}`, i = n === W, a = ae[t.type] ?? "#3b82f6", o = {
470
+ type: t.type,
471
+ color: a,
472
+ hovered: i,
473
+ onDelete: b ? () => b(t.id) : void 0
474
+ };
475
+ r.push({
476
+ id: n,
477
+ source: t.source.table,
478
+ target: t.target.table,
479
+ sourceHandle: F("source", t.source.column),
480
+ targetHandle: F("target", t.target.column),
481
+ type: "joinEdge",
482
+ deletable: !0,
483
+ data: o
484
+ });
485
+ }
486
+ return [...n, ...r];
487
+ }, [
488
+ H,
489
+ B,
490
+ v,
491
+ W,
492
+ b
493
+ ]), de = d((e) => {
494
+ y && (!e.source || !e.target || y({
495
+ table: e.source,
496
+ column: L(e.sourceHandle)
497
+ }, {
498
+ table: e.target,
499
+ column: L(e.targetHandle)
500
+ }));
501
+ }, [y]), fe = d((e) => {
502
+ if (b) for (let t of e) t.id.startsWith(I) && b(t.id.slice(5));
503
+ }, [b]), $ = !!g, pe = m(() => ({
504
+ onTableRemove: x,
505
+ onColumnClick: C
506
+ }), [x, C]);
507
+ return /* @__PURE__ */ T("div", {
508
+ className: M,
509
+ style: {
510
+ width: "100%",
511
+ height: "100%",
512
+ position: "relative",
513
+ ...N
514
+ },
515
+ children: [
516
+ V && /* @__PURE__ */ w("div", {
517
+ style: {
518
+ position: "absolute",
519
+ top: 8,
520
+ left: 8,
521
+ right: 8,
522
+ zIndex: 10,
523
+ padding: "8px 12px",
524
+ background: "#fef2f2",
525
+ border: "1px solid #fecaca",
526
+ borderRadius: 6,
527
+ color: "#991b1b",
528
+ fontFamily: "ui-monospace, SFMono-Regular, Consolas, monospace",
529
+ fontSize: 12,
530
+ whiteSpace: "pre-wrap"
531
+ },
532
+ children: V.message
533
+ }),
534
+ !V && !H && /* @__PURE__ */ w("div", {
535
+ style: {
536
+ position: "absolute",
537
+ inset: 0,
538
+ display: "flex",
539
+ alignItems: "center",
540
+ justifyContent: "center",
541
+ color: "#9ca3af",
542
+ fontSize: 13
543
+ },
544
+ children: "Computing layout…"
545
+ }),
546
+ /* @__PURE__ */ w(E.Provider, {
547
+ value: ce,
548
+ children: /* @__PURE__ */ w(D.Provider, {
549
+ value: le,
550
+ children: /* @__PURE__ */ w(O.Provider, {
551
+ value: $,
552
+ children: /* @__PURE__ */ w(k.Provider, {
553
+ value: pe,
554
+ children: /* @__PURE__ */ T(ne, {
555
+ nodes: q,
556
+ edges: ue,
557
+ nodeTypes: P,
558
+ edgeTypes: re,
559
+ fitView: !0,
560
+ onNodesChange: oe,
561
+ onNodeDragStop: se,
562
+ onNodeClick: A ? (e, t) => A(t.id) : void 0,
563
+ onEdgeMouseEnter: (e, t) => G(t.id),
564
+ onEdgeMouseLeave: () => G(null),
565
+ onConnect: de,
566
+ onEdgesDelete: fe,
567
+ nodesDraggable: !0,
568
+ nodesConnectable: $,
569
+ elementsSelectable: !0,
570
+ deleteKeyCode: j,
571
+ minZoom: .1,
572
+ maxZoom: 4,
573
+ children: [
574
+ /* @__PURE__ */ w(ee, {}),
575
+ /* @__PURE__ */ w(_, {}),
576
+ /* @__PURE__ */ w(te, {
577
+ pannable: !0,
578
+ zoomable: !0
579
+ })
580
+ ]
581
+ })
582
+ })
583
+ })
584
+ })
585
+ })
586
+ ]
587
+ });
588
+ }
589
+ //#endregion
590
+ export { s as HEADER_HEIGHT, z as MermaidER, o as MermaidERParseError, r as NODE_WIDTH, a as ROW_HEIGHT, n as VERTICAL_PADDING, e as estimateNodeHeight, i as layoutER, t as parseMermaidER };
591
+
592
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/components/TableNode.tsx","../src/components/JoinEdge.tsx","../src/components/MermaidER.tsx"],"sourcesContent":["import { Fragment, createContext, memo, useContext } from 'react';\nimport { Handle, Position } from '@xyflow/react';\nimport type { NodeProps } from '@xyflow/react';\nimport type { Column, Table } from '../core/model';\nimport { HEADER_HEIGHT, ROW_HEIGHT } from '../core/layout';\n\nexport interface TableNodeData extends Record<string, unknown> {\n table: Table;\n}\n\n/**\n * Map from table name -> set of highlighted column names.\n * Provided by MermaidER, consumed by TableNode for hover-driven highlighting\n * without forcing the whole node array to recompute on every hover change.\n */\nexport const HighlightContext = createContext<ReadonlyMap<string, ReadonlySet<string>>>(new Map());\n\nexport interface ColumnSelectionContextValue {\n enabled: boolean;\n /** \"table.column\" keys for fast lookup. */\n selected: ReadonlySet<string>;\n onToggle: (table: string, column: string, checked: boolean) => void;\n}\n\nexport const ColumnSelectionContext = createContext<ColumnSelectionContextValue>({\n enabled: false,\n selected: new Set(),\n onToggle: () => undefined,\n});\n\n/** When true, column handles become visible/connectable for manual JOIN drawing. */\nexport const ConnectModeContext = createContext<boolean>(false);\n\nexport interface TableActionsContextValue {\n /** When provided, a delete affordance is shown on the table header. */\n onTableRemove?: (table: string) => void;\n /** Per-column click handler. Provided via context (not node data) so its\n * identity can change without invalidating the React Flow node array. */\n onColumnClick?: (table: string, column: string) => void;\n}\n\nexport const TableActionsContext = createContext<TableActionsContextValue>({});\n\nconst KEY_STYLES: Record<'pk' | 'fk' | 'uk', { label: string; bg: string }> = {\n pk: { label: 'PK', bg: '#f59e0b' },\n fk: { label: 'FK', bg: '#3b82f6' },\n uk: { label: 'UK', bg: '#10b981' },\n};\n\nfunction ColumnRow({\n tableName,\n column,\n highlighted,\n onClick,\n selectionEnabled,\n selected,\n onSelectToggle,\n}: {\n tableName: string;\n column: Column;\n highlighted: boolean;\n onClick?: (table: string, column: string) => void;\n selectionEnabled: boolean;\n selected: boolean;\n onSelectToggle: (checked: boolean) => void;\n}) {\n const badges: Array<{ label: string; bg: string }> = [];\n if (column.keys.pk) badges.push(KEY_STYLES.pk);\n if (column.keys.fk) badges.push(KEY_STYLES.fk);\n if (column.keys.uk) badges.push(KEY_STYLES.uk);\n\n return (\n <div\n title={column.comment}\n onClick={onClick ? () => onClick(tableName, column.name) : undefined}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 6,\n padding: '0 10px',\n fontSize: 12,\n fontFamily: 'ui-monospace, SFMono-Regular, Consolas, monospace',\n borderTop: '1px solid #eee',\n height: ROW_HEIGHT,\n boxSizing: 'border-box',\n cursor: onClick ? 'pointer' : 'default',\n background: highlighted ? '#fef3c7' : selected ? '#eff6ff' : 'transparent',\n transition: 'background 0.15s',\n }}\n >\n {selectionEnabled && (\n <input\n type=\"checkbox\"\n checked={selected}\n onChange={(e) => onSelectToggle(e.target.checked)}\n onClick={(e) => e.stopPropagation()}\n style={{\n width: 13,\n height: 13,\n margin: 0,\n flexShrink: 0,\n cursor: 'pointer',\n }}\n />\n )}\n <span style={{ display: 'flex', gap: 2, flexShrink: 0, minWidth: 18 }}>\n {badges.map((b) => (\n <span\n key={b.label}\n style={{\n display: 'inline-block',\n padding: '0 4px',\n borderRadius: 3,\n background: b.bg,\n color: '#fff',\n fontSize: 9,\n fontWeight: 700,\n lineHeight: '14px',\n }}\n >\n {b.label}\n </span>\n ))}\n </span>\n <span\n style={{\n flexShrink: 0,\n fontWeight: column.keys.pk ? 600 : 400,\n color: '#1f2937',\n }}\n >\n {column.name}\n </span>\n {column.type && (\n <span\n style={{\n flex: 1,\n textAlign: 'right',\n color: '#9ca3af',\n fontStyle: 'italic',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n }}\n >\n {column.type}\n </span>\n )}\n </div>\n );\n}\n\nexport const TableNode = memo(function TableNode({ data }: NodeProps) {\n const { table } = data as TableNodeData;\n const highlightMap = useContext(HighlightContext);\n const selection = useContext(ColumnSelectionContext);\n const connectMode = useContext(ConnectModeContext);\n const tableActions = useContext(TableActionsContext);\n const onColumnClick = tableActions.onColumnClick;\n const highlightedCols = highlightMap.get(table.name);\n const headerBg = table.group ? '#1e40af' : '#374151';\n\n const handleStyle = (extra: { top?: number }): React.CSSProperties => ({\n ...extra,\n width: connectMode ? 9 : 6,\n height: connectMode ? 9 : 6,\n background: connectMode ? '#3b82f6' : 'transparent',\n border: connectMode ? '1.5px solid #fff' : 'none',\n boxShadow: connectMode ? '0 0 0 1px rgba(59,130,246,0.4)' : 'none',\n opacity: connectMode ? 0.85 : 0,\n pointerEvents: connectMode ? 'auto' : 'none',\n cursor: connectMode ? 'crosshair' : 'default',\n });\n\n return (\n <div\n style={{\n background: '#fff',\n border: '1px solid #c4c4c4',\n borderRadius: 6,\n boxShadow: '0 2px 6px rgba(0,0,0,0.08)',\n overflow: 'visible',\n width: '100%',\n height: '100%',\n display: 'flex',\n flexDirection: 'column',\n position: 'relative',\n }}\n >\n <Handle\n id=\"__default-target\"\n type=\"target\"\n position={Position.Left}\n style={handleStyle({ top: HEADER_HEIGHT / 2 })}\n />\n <Handle\n id=\"__default-source\"\n type=\"source\"\n position={Position.Right}\n style={handleStyle({ top: HEADER_HEIGHT / 2 })}\n />\n\n <div\n style={{\n padding: '6px 10px',\n background: headerBg,\n color: '#fff',\n fontWeight: 600,\n fontSize: 13,\n height: HEADER_HEIGHT,\n boxSizing: 'border-box',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 8,\n borderTopLeftRadius: 6,\n borderTopRightRadius: 6,\n }}\n >\n <span style={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>\n {table.name}\n </span>\n <span style={{ display: 'flex', alignItems: 'center', gap: 4, flexShrink: 0 }}>\n {table.group && (\n <span\n style={{\n fontSize: 10,\n opacity: 0.75,\n fontWeight: 400,\n padding: '1px 5px',\n border: '1px solid rgba(255,255,255,0.3)',\n borderRadius: 3,\n }}\n >\n {table.group}\n </span>\n )}\n {tableActions.onTableRemove && (\n <button\n className=\"nodrag\"\n onClick={(e) => {\n e.stopPropagation();\n tableActions.onTableRemove?.(table.name);\n }}\n onMouseDown={(e) => e.stopPropagation()}\n title=\"Remove this table\"\n style={{\n background: 'rgba(255,255,255,0.18)',\n border: 'none',\n color: '#fff',\n width: 18,\n height: 18,\n borderRadius: 3,\n cursor: 'pointer',\n fontSize: 13,\n fontWeight: 700,\n padding: 0,\n lineHeight: 1,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n ×\n </button>\n )}\n </span>\n </div>\n\n {table.columns.map((col, i) => {\n const handleY = HEADER_HEIGHT + i * ROW_HEIGHT + ROW_HEIGHT / 2;\n const highlighted = highlightedCols?.has(col.name) ?? false;\n const selectionKey = `${table.name}.${col.name}`;\n const selected = selection.enabled && selection.selected.has(selectionKey);\n return (\n <Fragment key={`${col.name}-${i}`}>\n <Handle\n id={`${col.name}__target`}\n type=\"target\"\n position={Position.Left}\n style={handleStyle({ top: handleY })}\n />\n <Handle\n id={`${col.name}__source`}\n type=\"source\"\n position={Position.Right}\n style={handleStyle({ top: handleY })}\n />\n <ColumnRow\n tableName={table.name}\n column={col}\n highlighted={highlighted}\n onClick={onColumnClick}\n selectionEnabled={selection.enabled}\n selected={selected}\n onSelectToggle={(checked) =>\n selection.onToggle(table.name, col.name, checked)\n }\n />\n </Fragment>\n );\n })}\n </div>\n );\n});\n","import { memo } from 'react';\nimport {\n BaseEdge,\n EdgeLabelRenderer,\n getSmoothStepPath,\n type EdgeProps,\n} from '@xyflow/react';\nimport type { JoinType } from '../core/model';\n\nexport interface JoinEdgeData extends Record<string, unknown> {\n type: JoinType;\n color: string;\n hovered?: boolean;\n onDelete?: () => void;\n}\n\nexport const JoinEdge = memo(function JoinEdge({\n id,\n sourceX,\n sourceY,\n targetX,\n targetY,\n sourcePosition,\n targetPosition,\n data,\n selected,\n}: EdgeProps) {\n const [edgePath, labelX, labelY] = getSmoothStepPath({\n sourceX,\n sourceY,\n sourcePosition,\n targetX,\n targetY,\n targetPosition,\n });\n\n const d = (data ?? {}) as JoinEdgeData;\n const emphasized = !!selected || !!d.hovered;\n const color = d.color || '#3b82f6';\n\n return (\n <>\n <BaseEdge\n id={id}\n path={edgePath}\n style={{\n stroke: color,\n strokeWidth: emphasized ? 2.5 : 2,\n strokeDasharray: '6 3',\n }}\n />\n <EdgeLabelRenderer>\n <div\n className=\"nodrag nopan\"\n style={{\n position: 'absolute',\n transform: `translate(-50%, -50%) translate(${labelX}px, ${labelY}px)`,\n background: color,\n color: '#fff',\n fontSize: 10,\n fontFamily: 'ui-monospace, SFMono-Regular, Consolas, monospace',\n fontWeight: 700,\n borderRadius: 3,\n padding: '2px 4px 2px 6px',\n display: 'flex',\n alignItems: 'center',\n gap: 4,\n pointerEvents: 'all',\n boxShadow: emphasized\n ? '0 0 0 2px rgba(0,0,0,0.4)'\n : '0 1px 2px rgba(0,0,0,0.15)',\n userSelect: 'none',\n }}\n >\n <span>{d.type}</span>\n {d.onDelete && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n d.onDelete?.();\n }}\n onMouseDown={(e) => e.stopPropagation()}\n title=\"Remove this JOIN\"\n style={{\n background: 'rgba(255,255,255,0.25)',\n border: 'none',\n color: '#fff',\n width: 14,\n height: 14,\n borderRadius: 2,\n cursor: 'pointer',\n fontSize: 11,\n fontWeight: 700,\n padding: 0,\n lineHeight: 1,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n ×\n </button>\n )}\n </div>\n </EdgeLabelRenderer>\n </>\n );\n});\n","import {\n useCallback,\n useEffect,\n useMemo,\n useState,\n type CSSProperties,\n} from 'react';\nimport {\n ReactFlow,\n Background,\n Controls,\n MiniMap,\n useNodesState,\n type Connection,\n type Edge,\n type EdgeTypes,\n type Node,\n type NodeTypes,\n} from '@xyflow/react';\n// React Flow's CSS is intentionally NOT imported here. Consumers must add it\n// once at their app entry point: `import '@xyflow/react/dist/style.css';`.\n// Importing it from this file would cause double-injection in apps that\n// already use React Flow, and inflate this library's bundled assets.\nimport { parseMermaidER, MermaidERParseError } from '../core/parser';\nimport {\n layoutER,\n type LayoutAlgorithm,\n type LayoutDirection,\n type LayoutResult,\n} from '../core/layout';\nimport type {\n ColumnRef,\n ERModel,\n Join,\n PartialColumnRef,\n Relation,\n} from '../core/model';\nimport {\n ColumnSelectionContext,\n ConnectModeContext,\n HighlightContext,\n TableActionsContext,\n TableNode,\n type ColumnSelectionContextValue,\n type TableActionsContextValue,\n type TableNodeData,\n} from './TableNode';\nimport { JoinEdge, type JoinEdgeData } from './JoinEdge';\n\nconst nodeTypes: NodeTypes = {\n table: TableNode,\n};\n\nconst edgeTypes: EdgeTypes = {\n joinEdge: JoinEdge,\n};\n\nexport interface NodePosition {\n x: number;\n y: number;\n}\n\nexport type NodePositions = Record<string, NodePosition>;\n\nexport interface MermaidERProps {\n /** Mermaid ER source. Mutually exclusive with `model`. */\n source?: string;\n /** Pre-built ER model. Takes precedence over `source`. */\n model?: ERModel;\n layout?: 'elk';\n algorithm?: LayoutAlgorithm;\n direction?: LayoutDirection;\n aspectRatio?: number;\n positions?: NodePositions;\n onPositionsChange?: (positions: NodePositions) => void;\n showColumnCheckboxes?: boolean;\n selectedColumns?: ColumnRef[];\n onColumnSelectionChange?: (selectedColumns: ColumnRef[]) => void;\n /** Enable column-to-column / card-to-card drag for manual JOINs. */\n enableManualJoins?: boolean;\n /** Existing manual joins to render alongside FK relations. */\n joins?: Join[];\n /**\n * Fired when the user finishes a connect drag. The consumer typically opens\n * a dialog to ask for join type, then appends a complete `Join` to its state.\n * `column` may be undefined when the drag landed on a default (table-center) handle.\n */\n onJoinConnect?: (source: PartialColumnRef, target: PartialColumnRef) => void;\n /** Fired when the user removes a manual join via Delete or the trash icon. */\n onJoinDelete?: (joinId: string) => void;\n /** When provided, a small × appears on each table header to remove it from the canvas. */\n onTableRemove?: (table: string) => void;\n highlightReferencesOnHover?: boolean;\n onColumnClick?: (table: string, column: string) => void;\n onTableClick?: (table: string) => void;\n /** Override the default delete-key code(s). Default is 'Delete' (Backspace ignored to prevent accidents). */\n deleteKeyCode?: string | string[] | null;\n className?: string;\n style?: CSSProperties;\n}\n\ninterface ParseState {\n model: ERModel | null;\n error: MermaidERParseError | null;\n}\n\nfunction safeParse(source: string): ParseState {\n try {\n return { model: parseMermaidER(source), error: null };\n } catch (e) {\n if (e instanceof MermaidERParseError) {\n return { model: null, error: e };\n }\n throw e;\n }\n}\n\nfunction handleIdFor(side: 'source' | 'target', column: string | undefined): string {\n return column ? `${column}__${side}` : `__default-${side}`;\n}\n\nconst JOIN_EDGE_PREFIX = 'join:';\n\nfunction parseHandleColumn(handleId: string | null | undefined): string | undefined {\n if (!handleId) return undefined;\n if (handleId.startsWith('__default-')) return undefined;\n const m = /^(.+)__(?:source|target)$/.exec(handleId);\n return m ? m[1] : undefined;\n}\n\nfunction refKey(ref: ColumnRef): string {\n return `${ref.table}.${ref.column}`;\n}\n\nconst JOIN_TYPE_COLOR: Record<Join['type'], string> = {\n INNER: '#3b82f6',\n LEFT: '#8b5cf6',\n RIGHT: '#a855f7',\n FULL: '#ec4899',\n CROSS: '#6b7280',\n};\n\nexport function MermaidER(props: MermaidERProps) {\n const {\n source,\n model: modelProp,\n algorithm,\n direction,\n aspectRatio,\n positions,\n onPositionsChange,\n showColumnCheckboxes,\n selectedColumns,\n onColumnSelectionChange,\n enableManualJoins,\n joins,\n onJoinConnect,\n onJoinDelete,\n onTableRemove,\n onColumnClick,\n onTableClick,\n deleteKeyCode = 'Delete',\n className,\n style,\n highlightReferencesOnHover = true,\n } = props;\n\n const { model, error } = useMemo<ParseState>(() => {\n if (modelProp) return { model: modelProp, error: null };\n if (source != null) return safeParse(source);\n return { model: null, error: null };\n }, [source, modelProp]);\n\n const [layout, setLayout] = useState<LayoutResult | null>(null);\n const [hoveredEdgeId, setHoveredEdgeId] = useState<string | null>(null);\n\n useEffect(() => {\n if (!model) {\n setLayout(null);\n return;\n }\n let cancelled = false;\n layoutER(model, { algorithm, direction, aspectRatio }).then((result) => {\n if (!cancelled) setLayout(result);\n });\n return () => {\n cancelled = true;\n };\n }, [model, algorithm, direction, aspectRatio]);\n\n const baseNodes = useMemo<Node[]>(() => {\n if (!layout || !model) return [];\n const tableMap = new Map(model.tables.map((t) => [t.name, t]));\n const result: Node[] = [];\n for (const n of layout.nodes) {\n const table = tableMap.get(n.id);\n // Skip stale nodes: a model update can arrive before the new layout\n // finishes; in that gap, layout may still reference a removed table.\n if (!table) continue;\n const override = positions?.[n.id];\n const data: TableNodeData = { table };\n result.push({\n id: n.id,\n type: 'table',\n position: override ?? { x: n.x, y: n.y },\n data,\n width: n.width,\n height: n.height,\n draggable: true,\n deletable: false,\n });\n }\n return result;\n // `onColumnClick` is intentionally NOT a dep — it flows via TableActionsContext\n // so a non-stable callback identity from the parent doesn't reset React Flow\n // node state (which would clobber an in-flight drag).\n }, [layout, model, positions]);\n\n const [nodes, setNodes, onNodesChange] = useNodesState<Node>(baseNodes);\n\n useEffect(() => {\n setNodes(baseNodes);\n }, [baseNodes, setNodes]);\n\n const handleNodeDragStop = useCallback(\n (_: unknown, _primary: Node, dragged: Node[]) => {\n if (!onPositionsChange) return;\n const next: NodePositions = { ...(positions ?? {}) };\n for (const n of dragged) {\n next[n.id] = { x: n.position.x, y: n.position.y };\n }\n onPositionsChange(next);\n },\n [positions, onPositionsChange],\n );\n\n const hoveredRelation = useMemo<Relation | undefined>(() => {\n if (!hoveredEdgeId || !model) return undefined;\n return model.relations.find((r) => r.id === hoveredEdgeId);\n }, [hoveredEdgeId, model]);\n\n const hoveredJoin = useMemo<Join | undefined>(() => {\n if (!hoveredEdgeId || !joins) return undefined;\n if (!hoveredEdgeId.startsWith(JOIN_EDGE_PREFIX)) return undefined;\n const id = hoveredEdgeId.slice(JOIN_EDGE_PREFIX.length);\n return joins.find((j) => j.id === id);\n }, [hoveredEdgeId, joins]);\n\n const highlightMap = useMemo<ReadonlyMap<string, ReadonlySet<string>>>(() => {\n const map = new Map<string, Set<string>>();\n if (!highlightReferencesOnHover) return map;\n\n const add = (table: string, column: string | undefined) => {\n if (!column) return;\n const set = map.get(table) ?? new Set();\n set.add(column);\n map.set(table, set);\n };\n\n if (hoveredRelation) {\n add(hoveredRelation.from, hoveredRelation.fromColumn);\n add(hoveredRelation.to, hoveredRelation.toColumn);\n }\n if (hoveredJoin) {\n add(hoveredJoin.source.table, hoveredJoin.source.column);\n add(hoveredJoin.target.table, hoveredJoin.target.column);\n }\n return map;\n }, [hoveredRelation, hoveredJoin, highlightReferencesOnHover]);\n\n const selectionSet = useMemo<ReadonlySet<string>>(() => {\n return new Set((selectedColumns ?? []).map(refKey));\n }, [selectedColumns]);\n\n const handleColumnSelectToggle = useCallback(\n (table: string, column: string, checked: boolean) => {\n if (!onColumnSelectionChange) return;\n const list = selectedColumns ?? [];\n if (checked) {\n if (list.some((r) => r.table === table && r.column === column)) return;\n onColumnSelectionChange([...list, { table, column }]);\n } else {\n onColumnSelectionChange(\n list.filter((r) => !(r.table === table && r.column === column)),\n );\n }\n },\n [selectedColumns, onColumnSelectionChange],\n );\n\n const selectionContext = useMemo<ColumnSelectionContextValue>(\n () => ({\n enabled: showColumnCheckboxes ?? false,\n selected: selectionSet,\n onToggle: handleColumnSelectToggle,\n }),\n [showColumnCheckboxes, selectionSet, handleColumnSelectToggle],\n );\n\n const edges = useMemo<Edge[]>(() => {\n if (!layout || !model) return [];\n const tableSet = new Set(model.tables.map((t) => t.name));\n const relMap = new Map(model.relations.map((r) => [r.id, r]));\n\n const fkEdges: Edge[] = [];\n for (const e of layout.edges) {\n // Skip stale edges referencing tables removed since the layout was computed.\n if (!tableSet.has(e.source) || !tableSet.has(e.target)) continue;\n const rel = relMap.get(e.id);\n const isHovered = e.id === hoveredEdgeId;\n fkEdges.push({\n id: e.id,\n source: e.source,\n target: e.target,\n sourceHandle: handleIdFor('source', rel?.fromColumn),\n targetHandle: handleIdFor('target', rel?.toColumn),\n type: 'smoothstep',\n animated: isHovered,\n deletable: false,\n style: {\n stroke: isHovered ? '#f59e0b' : '#9ca3af',\n strokeWidth: isHovered ? 2 : 1.5,\n },\n label: rel?.label,\n labelStyle: { fontSize: 10, fill: '#6b7280' },\n labelBgStyle: { fill: '#fff', fillOpacity: 0.85 },\n labelBgPadding: [4, 2] as [number, number],\n labelBgBorderRadius: 3,\n });\n }\n\n const joinEdges: Edge[] = [];\n for (const j of joins ?? []) {\n if (!tableSet.has(j.source.table) || !tableSet.has(j.target.table)) continue;\n const edgeId = `${JOIN_EDGE_PREFIX}${j.id}`;\n const isHovered = edgeId === hoveredEdgeId;\n const color = JOIN_TYPE_COLOR[j.type] ?? '#3b82f6';\n const data: JoinEdgeData = {\n type: j.type,\n color,\n hovered: isHovered,\n onDelete: onJoinDelete ? () => onJoinDelete(j.id) : undefined,\n };\n joinEdges.push({\n id: edgeId,\n source: j.source.table,\n target: j.target.table,\n sourceHandle: handleIdFor('source', j.source.column),\n targetHandle: handleIdFor('target', j.target.column),\n type: 'joinEdge',\n deletable: true,\n data: data as unknown as Record<string, unknown>,\n });\n }\n\n return [...fkEdges, ...joinEdges];\n }, [layout, model, joins, hoveredEdgeId, onJoinDelete]);\n\n const handleConnect = useCallback(\n (conn: Connection) => {\n if (!onJoinConnect) return;\n if (!conn.source || !conn.target) return;\n onJoinConnect(\n { table: conn.source, column: parseHandleColumn(conn.sourceHandle) },\n { table: conn.target, column: parseHandleColumn(conn.targetHandle) },\n );\n },\n [onJoinConnect],\n );\n\n const handleEdgesDelete = useCallback(\n (deleted: Edge[]) => {\n if (!onJoinDelete) return;\n for (const e of deleted) {\n if (e.id.startsWith(JOIN_EDGE_PREFIX)) {\n onJoinDelete(e.id.slice(JOIN_EDGE_PREFIX.length));\n }\n }\n },\n [onJoinDelete],\n );\n\n const connectModeOn = !!enableManualJoins;\n const tableActions = useMemo<TableActionsContextValue>(\n () => ({ onTableRemove, onColumnClick }),\n [onTableRemove, onColumnClick],\n );\n\n return (\n <div\n className={className}\n style={{ width: '100%', height: '100%', position: 'relative', ...style }}\n >\n {error && (\n <div\n style={{\n position: 'absolute',\n top: 8,\n left: 8,\n right: 8,\n zIndex: 10,\n padding: '8px 12px',\n background: '#fef2f2',\n border: '1px solid #fecaca',\n borderRadius: 6,\n color: '#991b1b',\n fontFamily: 'ui-monospace, SFMono-Regular, Consolas, monospace',\n fontSize: 12,\n whiteSpace: 'pre-wrap',\n }}\n >\n {error.message}\n </div>\n )}\n {!error && !layout && (\n <div\n style={{\n position: 'absolute',\n inset: 0,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n color: '#9ca3af',\n fontSize: 13,\n }}\n >\n Computing layout…\n </div>\n )}\n <HighlightContext.Provider value={highlightMap}>\n <ColumnSelectionContext.Provider value={selectionContext}>\n <ConnectModeContext.Provider value={connectModeOn}>\n <TableActionsContext.Provider value={tableActions}>\n <ReactFlow\n nodes={nodes}\n edges={edges}\n nodeTypes={nodeTypes}\n edgeTypes={edgeTypes}\n fitView\n onNodesChange={onNodesChange}\n onNodeDragStop={handleNodeDragStop}\n onNodeClick={\n onTableClick ? (_, node) => onTableClick(node.id) : undefined\n }\n onEdgeMouseEnter={(_, edge) => setHoveredEdgeId(edge.id)}\n onEdgeMouseLeave={() => setHoveredEdgeId(null)}\n onConnect={handleConnect}\n onEdgesDelete={handleEdgesDelete}\n nodesDraggable\n nodesConnectable={connectModeOn}\n elementsSelectable\n deleteKeyCode={deleteKeyCode}\n minZoom={0.1}\n maxZoom={4}\n >\n <Background />\n <Controls />\n <MiniMap pannable zoomable />\n </ReactFlow>\n </TableActionsContext.Provider>\n </ConnectModeContext.Provider>\n </ColumnSelectionContext.Provider>\n </HighlightContext.Provider>\n </div>\n );\n}\n"],"mappings":"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"}