react-super-mermaid 0.1.0 → 0.3.0
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/README.md +338 -165
- package/dist/index.cjs +560 -16
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +30 -2
- package/dist/index.d.ts +30 -2
- package/dist/index.js +560 -17
- package/dist/index.js.map +1 -1
- package/llms.txt +41 -0
- package/package.json +84 -83
package/dist/index.cjs
CHANGED
|
@@ -108,6 +108,7 @@ var RSM_CSS = `
|
|
|
108
108
|
--rsm-hover: #f3f4f6;
|
|
109
109
|
--rsm-surface: #ffffff;
|
|
110
110
|
--rsm-canvas-bg: transparent;
|
|
111
|
+
--rsm-grid-dot: rgba(0, 0, 0, 0.08);
|
|
111
112
|
--rsm-radius: 8px;
|
|
112
113
|
display: flex;
|
|
113
114
|
flex-direction: column;
|
|
@@ -245,6 +246,71 @@ var RSM_CSS = `
|
|
|
245
246
|
--rsm-accent: #60a5fa;
|
|
246
247
|
--rsm-hover: #1f2937;
|
|
247
248
|
--rsm-surface: #111827;
|
|
249
|
+
--rsm-grid-dot: rgba(255, 255, 255, 0.10);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/* \u2500\u2500 \u80CC\u666F\u6A21\u5F0F \u2500\u2500 \u900F\u660E(\u9810\u8A2D,\u8DDF\u96A8\u9801\u9762) / \u7D14\u8272(surface) / \u9EDE\u9663\u683C\u7DDA\u3002 */
|
|
253
|
+
.rsm-root.rsm-bg-solid .rsm-canvas { background: var(--rsm-surface); }
|
|
254
|
+
.rsm-root.rsm-bg-grid .rsm-canvas {
|
|
255
|
+
background-color: var(--rsm-surface);
|
|
256
|
+
background-image: radial-gradient(var(--rsm-grid-dot) 1px, transparent 1px);
|
|
257
|
+
background-size: 18px 18px;
|
|
258
|
+
background-position: -9px -9px;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/* \u2500\u2500 \u5168\u87A2\u5E55\u8DF3\u7A97 \u2500\u2500 position:fixed \u8986\u84CB\u6574\u500B\u8996\u7A97,RWD \u53CB\u5584\u3002 */
|
|
262
|
+
.rsm-root.rsm-fullscreen {
|
|
263
|
+
position: fixed;
|
|
264
|
+
inset: 0;
|
|
265
|
+
width: 100vw;
|
|
266
|
+
width: 100dvw;
|
|
267
|
+
height: 100vh;
|
|
268
|
+
height: 100dvh;
|
|
269
|
+
max-width: 100vw;
|
|
270
|
+
max-height: 100dvh;
|
|
271
|
+
margin: 0;
|
|
272
|
+
z-index: 2147483000;
|
|
273
|
+
border: 0;
|
|
274
|
+
border-radius: 0;
|
|
275
|
+
animation: rsm-fs-in 0.16s ease-out;
|
|
276
|
+
}
|
|
277
|
+
@keyframes rsm-fs-in {
|
|
278
|
+
from { opacity: 0; }
|
|
279
|
+
to { opacity: 1; }
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/* \u5168\u87A2\u5E55\u53F3\u4E0A\u89D2\u7684\u96E2\u958B\u9215(toolbar \u96B1\u85CF\u6642\u4E5F\u80FD\u95DC\u9589)\u3002 */
|
|
283
|
+
.rsm-fs-close {
|
|
284
|
+
position: absolute;
|
|
285
|
+
top: 10px;
|
|
286
|
+
right: 10px;
|
|
287
|
+
z-index: 5;
|
|
288
|
+
display: inline-flex;
|
|
289
|
+
align-items: center;
|
|
290
|
+
justify-content: center;
|
|
291
|
+
width: 34px;
|
|
292
|
+
height: 34px;
|
|
293
|
+
padding: 0;
|
|
294
|
+
font-size: 16px;
|
|
295
|
+
line-height: 1;
|
|
296
|
+
border: 1px solid var(--rsm-border);
|
|
297
|
+
border-radius: 8px;
|
|
298
|
+
background: var(--rsm-surface);
|
|
299
|
+
color: var(--rsm-fg);
|
|
300
|
+
cursor: pointer;
|
|
301
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.18);
|
|
302
|
+
transition: background 0.12s ease, color 0.12s ease;
|
|
303
|
+
}
|
|
304
|
+
.rsm-fs-close:hover { background: var(--rsm-hover); }
|
|
305
|
+
|
|
306
|
+
/* \u2500\u2500 RWD \u2500\u2500 \u5C0F\u87A2\u5E55\u6536\u7DCA toolbar\u3001\u7E2E\u77ED\u641C\u5C0B\u6846,\u907F\u514D\u63DB\u884C\u64E0\u58D3\u756B\u5E03\u3002 */
|
|
307
|
+
@media (max-width: 640px) {
|
|
308
|
+
.rsm-toolbar { gap: 6px; padding: 6px 8px; }
|
|
309
|
+
.rsm-btn { padding: 4px 8px; font-size: 12px; }
|
|
310
|
+
.rsm-label { font-size: 11px; }
|
|
311
|
+
.rsm-select { padding: 3px 6px; font-size: 12px; }
|
|
312
|
+
.rsm-zoom > button { padding: 4px 8px; font-size: 12px; }
|
|
313
|
+
.rsm-input { flex-basis: 150px; }
|
|
248
314
|
}
|
|
249
315
|
`;
|
|
250
316
|
|
|
@@ -282,16 +348,88 @@ var NODE_PALETTE = [
|
|
|
282
348
|
// violet
|
|
283
349
|
];
|
|
284
350
|
var CLUSTER_PALETTE = [
|
|
285
|
-
{ fill: "rgba(59, 130, 246, 0.
|
|
286
|
-
|
|
287
|
-
{ fill: "rgba(
|
|
288
|
-
|
|
289
|
-
{ fill: "rgba(
|
|
290
|
-
|
|
351
|
+
{ fill: "rgba(59, 130, 246, 0.16)", stroke: "#3B82F6" },
|
|
352
|
+
// blue
|
|
353
|
+
{ fill: "rgba(34, 197, 94, 0.16)", stroke: "#22C55E" },
|
|
354
|
+
// green
|
|
355
|
+
{ fill: "rgba(249, 115, 22, 0.16)", stroke: "#F97316" },
|
|
356
|
+
// orange
|
|
357
|
+
{ fill: "rgba(168, 85, 247, 0.16)", stroke: "#A855F7" },
|
|
358
|
+
// purple
|
|
359
|
+
{ fill: "rgba(239, 68, 68, 0.16)", stroke: "#EF4444" },
|
|
360
|
+
// red
|
|
361
|
+
{ fill: "rgba(6, 182, 212, 0.16)", stroke: "#06B6D4" },
|
|
362
|
+
// cyan
|
|
363
|
+
{ fill: "rgba(234, 179, 8, 0.16)", stroke: "#EAB308" },
|
|
364
|
+
// yellow
|
|
365
|
+
{ fill: "rgba(139, 92, 246, 0.16)", stroke: "#8B5CF6" }
|
|
366
|
+
// violet
|
|
367
|
+
];
|
|
368
|
+
var PIE_PALETTE = [
|
|
369
|
+
"#3B82F6",
|
|
370
|
+
// blue
|
|
371
|
+
"#22C55E",
|
|
372
|
+
// green
|
|
373
|
+
"#F59E0B",
|
|
374
|
+
// amber
|
|
375
|
+
"#A855F7",
|
|
376
|
+
// purple
|
|
377
|
+
"#EF4444",
|
|
378
|
+
// red
|
|
379
|
+
"#06B6D4",
|
|
380
|
+
// cyan
|
|
381
|
+
"#EC4899",
|
|
382
|
+
// pink
|
|
383
|
+
"#84CC16",
|
|
384
|
+
// lime
|
|
385
|
+
"#F97316",
|
|
386
|
+
// orange
|
|
387
|
+
"#14B8A6",
|
|
388
|
+
// teal
|
|
389
|
+
"#6366F1",
|
|
390
|
+
// indigo
|
|
391
|
+
"#EAB308"
|
|
392
|
+
// yellow
|
|
291
393
|
];
|
|
292
394
|
var NODE_TEXT = "#1F2937";
|
|
293
395
|
var SHADOW_FILTER_ID = "rsm-soft-shadow";
|
|
294
396
|
var SVG_NS = "http://www.w3.org/2000/svg";
|
|
397
|
+
function resolveSvg(root) {
|
|
398
|
+
if (root instanceof Element && root.tagName.toLowerCase() === "svg") {
|
|
399
|
+
return root;
|
|
400
|
+
}
|
|
401
|
+
return root.querySelector("svg");
|
|
402
|
+
}
|
|
403
|
+
function canonColor(input) {
|
|
404
|
+
const s = (input || "").trim();
|
|
405
|
+
const hex = /^#?([0-9a-f]{3}|[0-9a-f]{6})$/i.exec(s);
|
|
406
|
+
if (hex) {
|
|
407
|
+
let h = hex[1];
|
|
408
|
+
if (h.length === 3) {
|
|
409
|
+
h = h.split("").map((c) => c + c).join("");
|
|
410
|
+
}
|
|
411
|
+
const n = parseInt(h, 16);
|
|
412
|
+
return `${n >> 16 & 255},${n >> 8 & 255},${n & 255}`;
|
|
413
|
+
}
|
|
414
|
+
const rgb = /rgba?\(([^)]+)\)/i.exec(s);
|
|
415
|
+
if (rgb) {
|
|
416
|
+
const p = rgb[1].split(",").map((x) => Math.round(parseFloat(x)));
|
|
417
|
+
return `${p[0]},${p[1]},${p[2]}`;
|
|
418
|
+
}
|
|
419
|
+
return s.toLowerCase();
|
|
420
|
+
}
|
|
421
|
+
function readableTextOn(color) {
|
|
422
|
+
const m = /^#?([0-9a-f]{6})$/i.exec(color.trim());
|
|
423
|
+
if (!m) {
|
|
424
|
+
return "#FFFFFF";
|
|
425
|
+
}
|
|
426
|
+
const n = parseInt(m[1], 16);
|
|
427
|
+
const r = n >> 16 & 255;
|
|
428
|
+
const g = n >> 8 & 255;
|
|
429
|
+
const b = n & 255;
|
|
430
|
+
const lum = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
|
|
431
|
+
return lum > 0.62 ? "#1F2937" : "#FFFFFF";
|
|
432
|
+
}
|
|
295
433
|
function ensureShadowFilter(svg) {
|
|
296
434
|
if (svg.querySelector(`#${SHADOW_FILTER_ID}`)) {
|
|
297
435
|
return;
|
|
@@ -397,6 +535,17 @@ function styleEdgeLabels(svg) {
|
|
|
397
535
|
rect.setAttribute("ry", "4");
|
|
398
536
|
}
|
|
399
537
|
}
|
|
538
|
+
function styleLabelText(svg, dark) {
|
|
539
|
+
const color = dark ? "#E2E8F0" : NODE_TEXT;
|
|
540
|
+
for (const t of Array.from(
|
|
541
|
+
svg.querySelectorAll("text.messageText, .edgeLabel text, .edgeLabel tspan")
|
|
542
|
+
)) {
|
|
543
|
+
t.style.fill = color;
|
|
544
|
+
}
|
|
545
|
+
for (const t of Array.from(svg.querySelectorAll(".edgeLabel span, .edgeLabel p"))) {
|
|
546
|
+
t.style.color = color;
|
|
547
|
+
}
|
|
548
|
+
}
|
|
400
549
|
function colorizeLegacyEr(svg) {
|
|
401
550
|
const erGroups = [];
|
|
402
551
|
for (const rect of Array.from(svg.querySelectorAll("rect.er.entityBox"))) {
|
|
@@ -508,12 +657,194 @@ function colorizeSequence(svg, dark) {
|
|
|
508
657
|
text.style.fill = dark ? "#E2E8F0" : NODE_TEXT;
|
|
509
658
|
}
|
|
510
659
|
}
|
|
660
|
+
function stylePie(svg, dark) {
|
|
661
|
+
const slices = Array.from(svg.querySelectorAll("path.pieCircle"));
|
|
662
|
+
const swatches = Array.from(svg.querySelectorAll("g.legend rect"));
|
|
663
|
+
if (slices.length === 0 && swatches.length === 0) {
|
|
664
|
+
return;
|
|
665
|
+
}
|
|
666
|
+
const remap = /* @__PURE__ */ new Map();
|
|
667
|
+
let next = 0;
|
|
668
|
+
const newColorFor = (old) => {
|
|
669
|
+
const key = canonColor(old) || `#slot-${next}`;
|
|
670
|
+
let c = remap.get(key);
|
|
671
|
+
if (!c) {
|
|
672
|
+
c = PIE_PALETTE[next % PIE_PALETTE.length];
|
|
673
|
+
remap.set(key, c);
|
|
674
|
+
next += 1;
|
|
675
|
+
}
|
|
676
|
+
return c;
|
|
677
|
+
};
|
|
678
|
+
for (const slice of slices) {
|
|
679
|
+
const old = slice.style.fill || slice.getAttribute("fill") || "";
|
|
680
|
+
const c = newColorFor(old);
|
|
681
|
+
slice.style.fill = c;
|
|
682
|
+
slice.style.opacity = "1";
|
|
683
|
+
slice.style.stroke = dark ? "#0F172A" : "#FFFFFF";
|
|
684
|
+
slice.style.strokeWidth = "2px";
|
|
685
|
+
slice.style.strokeLinejoin = "round";
|
|
686
|
+
}
|
|
687
|
+
for (const sw of swatches) {
|
|
688
|
+
const old = sw.style.fill || sw.getAttribute("fill") || "";
|
|
689
|
+
const c = newColorFor(old);
|
|
690
|
+
sw.style.fill = c;
|
|
691
|
+
sw.style.stroke = c;
|
|
692
|
+
sw.setAttribute("rx", "3");
|
|
693
|
+
sw.setAttribute("ry", "3");
|
|
694
|
+
}
|
|
695
|
+
Array.from(svg.querySelectorAll("text.slice")).forEach((label, i) => {
|
|
696
|
+
const slice = slices[i];
|
|
697
|
+
const c = slice ? slice.style.fill || PIE_PALETTE[0] : PIE_PALETTE[0];
|
|
698
|
+
label.style.fill = readableTextOn(c);
|
|
699
|
+
label.style.fontWeight = "600";
|
|
700
|
+
});
|
|
701
|
+
for (const title of Array.from(svg.querySelectorAll("text.pieTitleText"))) {
|
|
702
|
+
title.style.fontWeight = "700";
|
|
703
|
+
title.style.fill = dark ? "#E2E8F0" : "#1F2937";
|
|
704
|
+
}
|
|
705
|
+
for (const t of Array.from(svg.querySelectorAll("g.legend text"))) {
|
|
706
|
+
t.style.fill = dark ? "#E2E8F0" : "#1F2937";
|
|
707
|
+
}
|
|
708
|
+
for (const oc of Array.from(svg.querySelectorAll("circle.pieOuterCircle"))) {
|
|
709
|
+
oc.style.stroke = dark ? "#334155" : "#CBD5E1";
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
function styleGantt(svg, dark) {
|
|
713
|
+
const tasks = Array.from(svg.querySelectorAll("rect.task"));
|
|
714
|
+
if (tasks.length === 0) {
|
|
715
|
+
return;
|
|
716
|
+
}
|
|
717
|
+
for (const task of tasks) {
|
|
718
|
+
const cls = task.getAttribute("class") ?? "";
|
|
719
|
+
if (/\b(done|active|crit|milestone)\d*\b/.test(cls)) {
|
|
720
|
+
continue;
|
|
721
|
+
}
|
|
722
|
+
const m = cls.match(/task(\d+)/);
|
|
723
|
+
if (!m) {
|
|
724
|
+
continue;
|
|
725
|
+
}
|
|
726
|
+
const entry = NODE_PALETTE[Number(m[1]) % NODE_PALETTE.length];
|
|
727
|
+
task.style.fill = entry.fill;
|
|
728
|
+
task.style.stroke = entry.stroke;
|
|
729
|
+
task.setAttribute("rx", "4");
|
|
730
|
+
task.setAttribute("ry", "4");
|
|
731
|
+
}
|
|
732
|
+
Array.from(svg.querySelectorAll("rect.section")).forEach((band) => {
|
|
733
|
+
const m = (band.getAttribute("class") ?? "").match(/section(\d+)/);
|
|
734
|
+
if (m) {
|
|
735
|
+
band.style.fill = CLUSTER_PALETTE[Number(m[1]) % CLUSTER_PALETTE.length].fill;
|
|
736
|
+
}
|
|
737
|
+
});
|
|
738
|
+
for (const inBar of Array.from(svg.querySelectorAll("text.taskText"))) {
|
|
739
|
+
if (!/Outside/.test(inBar.getAttribute("class") ?? "")) {
|
|
740
|
+
inBar.style.fill = NODE_TEXT;
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
for (const tick of Array.from(svg.querySelectorAll("g.grid g.tick line"))) {
|
|
744
|
+
tick.style.stroke = dark ? "#334155" : "#E2E8F0";
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
function styleTimeline(svg) {
|
|
748
|
+
const nodes = Array.from(svg.querySelectorAll('g[class*="timeline-node"]'));
|
|
749
|
+
nodes.forEach((node, i) => {
|
|
750
|
+
const m = (node.getAttribute("class") ?? "").match(/section-(-?\d+)/);
|
|
751
|
+
const section = m ? Number(m[1]) : i;
|
|
752
|
+
const entry = section < 0 ? NODE_PALETTE[7] : NODE_PALETTE[section % NODE_PALETTE.length];
|
|
753
|
+
const backgrounds = Array.from(node.querySelectorAll(".node-bkg"));
|
|
754
|
+
if (backgrounds.length > 0) {
|
|
755
|
+
for (const bkg of backgrounds) {
|
|
756
|
+
bkg.style.fill = entry.fill;
|
|
757
|
+
bkg.style.stroke = entry.stroke;
|
|
758
|
+
bkg.style.strokeWidth = "1.4px";
|
|
759
|
+
}
|
|
760
|
+
} else {
|
|
761
|
+
paintShapes(node, entry);
|
|
762
|
+
}
|
|
763
|
+
darkenNodeText(node);
|
|
764
|
+
});
|
|
765
|
+
}
|
|
766
|
+
function styleMindmap(svg) {
|
|
767
|
+
const nodes = Array.from(svg.querySelectorAll("g.mindmap-node"));
|
|
768
|
+
if (nodes.length === 0) {
|
|
769
|
+
return;
|
|
770
|
+
}
|
|
771
|
+
for (const node of nodes) {
|
|
772
|
+
const m = (node.getAttribute("class") ?? "").match(/section-(-?\d+)/);
|
|
773
|
+
const section = m ? Number(m[1]) : 0;
|
|
774
|
+
const entry = section < 0 ? NODE_PALETTE[7] : NODE_PALETTE[section % NODE_PALETTE.length];
|
|
775
|
+
for (const shape of Array.from(
|
|
776
|
+
node.querySelectorAll("path, rect, circle, ellipse")
|
|
777
|
+
)) {
|
|
778
|
+
if (shape.closest("g.children")) {
|
|
779
|
+
continue;
|
|
780
|
+
}
|
|
781
|
+
shape.style.fill = entry.fill;
|
|
782
|
+
shape.style.stroke = entry.stroke;
|
|
783
|
+
shape.style.strokeWidth = "1.4px";
|
|
784
|
+
}
|
|
785
|
+
darkenNodeText(node);
|
|
786
|
+
}
|
|
787
|
+
for (const edge of Array.from(svg.querySelectorAll('path[class*="edge"]'))) {
|
|
788
|
+
const m = (edge.getAttribute("class") ?? "").match(/section-edge-(-?\d+)/);
|
|
789
|
+
if (m) {
|
|
790
|
+
const section = Number(m[1]);
|
|
791
|
+
const entry = section < 0 ? NODE_PALETTE[7] : NODE_PALETTE[section % NODE_PALETTE.length];
|
|
792
|
+
edge.style.stroke = entry.stroke;
|
|
793
|
+
edge.style.strokeWidth = "2px";
|
|
794
|
+
edge.style.opacity = "0.6";
|
|
795
|
+
edge.style.fill = "none";
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
function styleJourney(svg) {
|
|
800
|
+
const tasks = Array.from(
|
|
801
|
+
svg.querySelectorAll('circle[class*="task-type"], rect[class*="task-type"]')
|
|
802
|
+
);
|
|
803
|
+
tasks.forEach((shape) => {
|
|
804
|
+
const m = (shape.getAttribute("class") ?? "").match(/task-type-(\d+)/);
|
|
805
|
+
if (m) {
|
|
806
|
+
const entry = NODE_PALETTE[Number(m[1]) % NODE_PALETTE.length];
|
|
807
|
+
shape.style.fill = entry.fill;
|
|
808
|
+
shape.style.stroke = entry.stroke;
|
|
809
|
+
}
|
|
810
|
+
});
|
|
811
|
+
Array.from(svg.querySelectorAll('rect[class*="section-type"]')).forEach((rect) => {
|
|
812
|
+
const m = (rect.getAttribute("class") ?? "").match(/section-type-(\d+)/);
|
|
813
|
+
if (m) {
|
|
814
|
+
const entry = CLUSTER_PALETTE[Number(m[1]) % CLUSTER_PALETTE.length];
|
|
815
|
+
rect.style.fill = entry.fill;
|
|
816
|
+
rect.style.stroke = entry.stroke;
|
|
817
|
+
}
|
|
818
|
+
});
|
|
819
|
+
}
|
|
820
|
+
function boostLegibility(root) {
|
|
821
|
+
const svg = resolveSvg(root);
|
|
822
|
+
if (!svg) {
|
|
823
|
+
return;
|
|
824
|
+
}
|
|
825
|
+
for (const el of Array.from(
|
|
826
|
+
svg.querySelectorAll(
|
|
827
|
+
'g.node text, g.node tspan, g.mindmap-node text, g[class*="timeline-node"] text, text.actor'
|
|
828
|
+
)
|
|
829
|
+
)) {
|
|
830
|
+
el.style.fontWeight = "600";
|
|
831
|
+
}
|
|
832
|
+
for (const el of Array.from(svg.querySelectorAll(".nodeLabel, g.node span, g.node p"))) {
|
|
833
|
+
el.style.fontWeight = "600";
|
|
834
|
+
}
|
|
835
|
+
for (const el of Array.from(svg.querySelectorAll("text"))) {
|
|
836
|
+
if (!el.style.fontWeight) {
|
|
837
|
+
el.style.fontWeight = "500";
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
}
|
|
511
841
|
function colorizeDiagram(root, opts = {}) {
|
|
512
|
-
const svg =
|
|
842
|
+
const svg = resolveSvg(root);
|
|
513
843
|
if (!svg) {
|
|
514
844
|
return;
|
|
515
845
|
}
|
|
516
846
|
ensureShadowFilter(svg);
|
|
847
|
+
const dark = opts.dark === true;
|
|
517
848
|
Array.from(svg.querySelectorAll("g.node")).forEach((node, i) => {
|
|
518
849
|
paintShapes(node, NODE_PALETTE[i % NODE_PALETTE.length]);
|
|
519
850
|
darkenNodeText(node);
|
|
@@ -523,14 +854,41 @@ function colorizeDiagram(root, opts = {}) {
|
|
|
523
854
|
for (const rect of Array.from(cluster.querySelectorAll(":scope > rect"))) {
|
|
524
855
|
rect.style.fill = entry.fill;
|
|
525
856
|
rect.style.stroke = entry.stroke;
|
|
526
|
-
rect.style.strokeWidth = "1.
|
|
857
|
+
rect.style.strokeWidth = "1.5px";
|
|
527
858
|
roundRect(rect, 10);
|
|
528
859
|
}
|
|
860
|
+
const label = cluster.querySelector(":scope > .cluster-label");
|
|
861
|
+
if (label) {
|
|
862
|
+
for (const el of Array.from(label.querySelectorAll("text, tspan"))) {
|
|
863
|
+
el.style.fill = entry.stroke;
|
|
864
|
+
el.style.fontWeight = "700";
|
|
865
|
+
}
|
|
866
|
+
for (const el of Array.from(label.querySelectorAll(".nodeLabel, span, p"))) {
|
|
867
|
+
el.style.color = entry.stroke;
|
|
868
|
+
el.style.fontWeight = "700";
|
|
869
|
+
}
|
|
870
|
+
for (const lr of Array.from(label.querySelectorAll("rect"))) {
|
|
871
|
+
lr.style.fill = entry.fill;
|
|
872
|
+
}
|
|
873
|
+
}
|
|
529
874
|
});
|
|
530
875
|
colorizeLegacyEr(svg);
|
|
531
|
-
colorizeSequence(svg,
|
|
532
|
-
styleEdges(svg,
|
|
876
|
+
colorizeSequence(svg, dark);
|
|
877
|
+
styleEdges(svg, dark);
|
|
533
878
|
styleEdgeLabels(svg);
|
|
879
|
+
styleLabelText(svg, dark);
|
|
880
|
+
const kind = svg.getAttribute("aria-roledescription") ?? "";
|
|
881
|
+
if (kind === "pie" || kind === "pieChart") {
|
|
882
|
+
stylePie(svg, dark);
|
|
883
|
+
} else if (kind === "gantt") {
|
|
884
|
+
styleGantt(svg, dark);
|
|
885
|
+
} else if (kind === "timeline") {
|
|
886
|
+
styleTimeline(svg);
|
|
887
|
+
} else if (kind === "mindmap") {
|
|
888
|
+
styleMindmap(svg);
|
|
889
|
+
} else if (kind === "journey") {
|
|
890
|
+
styleJourney(svg);
|
|
891
|
+
}
|
|
534
892
|
}
|
|
535
893
|
|
|
536
894
|
// src/core/themes/sketch.ts
|
|
@@ -814,6 +1172,7 @@ function applyPostProcess(svg, postProcess, opts) {
|
|
|
814
1172
|
} else if (postProcess === "sketch") {
|
|
815
1173
|
sketchifyDiagram(svg, { dark: opts.dark, seed: opts.seed });
|
|
816
1174
|
}
|
|
1175
|
+
boostLegibility(svg);
|
|
817
1176
|
}
|
|
818
1177
|
async function renderDiagram(opts) {
|
|
819
1178
|
assertBrowser("renderDiagram");
|
|
@@ -1312,6 +1671,11 @@ function useMermaidViewer(opts) {
|
|
|
1312
1671
|
getSvg
|
|
1313
1672
|
};
|
|
1314
1673
|
}
|
|
1674
|
+
var BACKGROUND_LABELS = {
|
|
1675
|
+
transparent: { icon: "\u25A6", label: "\u900F\u660E" },
|
|
1676
|
+
solid: { icon: "\u25FB", label: "\u7D14\u8272" },
|
|
1677
|
+
grid: { icon: "\u229E", label: "\u683C\u7DDA" }
|
|
1678
|
+
};
|
|
1315
1679
|
var DEFAULT_THEME_OPTIONS = [
|
|
1316
1680
|
{ value: "colorful", label: "Colorful" },
|
|
1317
1681
|
{ value: "sketch", label: "Excalidraw" },
|
|
@@ -1335,6 +1699,20 @@ function Toolbar(props) {
|
|
|
1335
1699
|
}
|
|
1336
1700
|
)
|
|
1337
1701
|
] }),
|
|
1702
|
+
props.backgroundEnabled ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1703
|
+
"button",
|
|
1704
|
+
{
|
|
1705
|
+
type: "button",
|
|
1706
|
+
className: "rsm-btn",
|
|
1707
|
+
onClick: props.onCycleBackground,
|
|
1708
|
+
title: "\u5207\u63DB\u756B\u5E03\u80CC\u666F\uFF08\u900F\u660E / \u7D14\u8272 / \u683C\u7DDA\uFF0CB\uFF09",
|
|
1709
|
+
children: [
|
|
1710
|
+
BACKGROUND_LABELS[props.background].icon,
|
|
1711
|
+
" \u80CC\u666F\uFF1A",
|
|
1712
|
+
BACKGROUND_LABELS[props.background].label
|
|
1713
|
+
]
|
|
1714
|
+
}
|
|
1715
|
+
) : null,
|
|
1338
1716
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "rsm-toolbar-spacer" }),
|
|
1339
1717
|
props.searchEnabled ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1340
1718
|
"button",
|
|
@@ -1388,9 +1766,21 @@ function Toolbar(props) {
|
|
|
1388
1766
|
),
|
|
1389
1767
|
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: props.onZoomIn, title: "\u653E\u5927\uFF08+\uFF09", children: "\uFF0B" }),
|
|
1390
1768
|
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: props.onReset, title: "\u7B26\u5408\u8996\u7A97\uFF080\uFF09", children: "\u2922" })
|
|
1391
|
-
] })
|
|
1769
|
+
] }),
|
|
1770
|
+
props.fullscreenEnabled ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1771
|
+
"button",
|
|
1772
|
+
{
|
|
1773
|
+
type: "button",
|
|
1774
|
+
className: "rsm-btn rsm-btn-fullscreen",
|
|
1775
|
+
"aria-pressed": props.fullscreen ? "true" : "false",
|
|
1776
|
+
onClick: props.onToggleFullscreen,
|
|
1777
|
+
title: props.fullscreen ? "\u96E2\u958B\u5168\u87A2\u5E55\uFF08Esc\uFF09" : "\u5168\u87A2\u5E55\u6AA2\u8996\uFF08F\uFF09",
|
|
1778
|
+
children: props.fullscreen ? "\u2715 \u96E2\u958B\u5168\u87A2\u5E55" : "\u26F6 \u5168\u87A2\u5E55"
|
|
1779
|
+
}
|
|
1780
|
+
) : null
|
|
1392
1781
|
] });
|
|
1393
1782
|
}
|
|
1783
|
+
var BACKGROUND_CYCLE = ["transparent", "solid", "grid"];
|
|
1394
1784
|
function usePrefersDark(explicit) {
|
|
1395
1785
|
const [autoDark, setAutoDark] = react.useState(false);
|
|
1396
1786
|
react.useEffect(() => {
|
|
@@ -1414,6 +1804,9 @@ var MermaidViewer = react.forwardRef(
|
|
|
1414
1804
|
panZoom = true,
|
|
1415
1805
|
search: searchEnabled = true,
|
|
1416
1806
|
exportable = true,
|
|
1807
|
+
background: backgroundEnabled = true,
|
|
1808
|
+
fullscreen: fullscreenEnabled = true,
|
|
1809
|
+
onFullscreenChange,
|
|
1417
1810
|
keyboard = true,
|
|
1418
1811
|
seed = 42,
|
|
1419
1812
|
fontUrl,
|
|
@@ -1437,6 +1830,15 @@ var MermaidViewer = react.forwardRef(
|
|
|
1437
1830
|
const [query, setQuery] = react.useState("");
|
|
1438
1831
|
const [matchInfo, setMatchInfo] = react.useState({ current: 0, total: 0 });
|
|
1439
1832
|
const [exporting, setExporting] = react.useState(false);
|
|
1833
|
+
const [background, setBackgroundState] = react.useState(
|
|
1834
|
+
props.backgroundMode ?? "transparent"
|
|
1835
|
+
);
|
|
1836
|
+
react.useEffect(() => {
|
|
1837
|
+
if (props.backgroundMode) {
|
|
1838
|
+
setBackgroundState(props.backgroundMode);
|
|
1839
|
+
}
|
|
1840
|
+
}, [props.backgroundMode]);
|
|
1841
|
+
const [isFullscreen, setIsFullscreen] = react.useState(false);
|
|
1440
1842
|
const rootRef = react.useRef(null);
|
|
1441
1843
|
const searchInputRef = react.useRef(null);
|
|
1442
1844
|
const vm = useMermaidViewer({
|
|
@@ -1499,6 +1901,85 @@ var MermaidViewer = react.forwardRef(
|
|
|
1499
1901
|
setExporting(false);
|
|
1500
1902
|
}
|
|
1501
1903
|
}, [vm, onError]);
|
|
1904
|
+
const cycleBackground = react.useCallback(() => {
|
|
1905
|
+
setBackgroundState((prev) => {
|
|
1906
|
+
const i = BACKGROUND_CYCLE.indexOf(prev);
|
|
1907
|
+
return BACKGROUND_CYCLE[(i + 1) % BACKGROUND_CYCLE.length];
|
|
1908
|
+
});
|
|
1909
|
+
}, []);
|
|
1910
|
+
const setBackground = react.useCallback((mode) => {
|
|
1911
|
+
setBackgroundState(mode);
|
|
1912
|
+
}, []);
|
|
1913
|
+
const enterFullscreen = react.useCallback(() => {
|
|
1914
|
+
setIsFullscreen((prev) => {
|
|
1915
|
+
if (!prev) {
|
|
1916
|
+
onFullscreenChange?.(true);
|
|
1917
|
+
}
|
|
1918
|
+
return true;
|
|
1919
|
+
});
|
|
1920
|
+
}, [onFullscreenChange]);
|
|
1921
|
+
const exitFullscreen = react.useCallback(() => {
|
|
1922
|
+
setIsFullscreen((prev) => {
|
|
1923
|
+
if (prev) {
|
|
1924
|
+
onFullscreenChange?.(false);
|
|
1925
|
+
}
|
|
1926
|
+
return false;
|
|
1927
|
+
});
|
|
1928
|
+
}, [onFullscreenChange]);
|
|
1929
|
+
const toggleFullscreen = react.useCallback(() => {
|
|
1930
|
+
setIsFullscreen((prev) => {
|
|
1931
|
+
onFullscreenChange?.(!prev);
|
|
1932
|
+
return !prev;
|
|
1933
|
+
});
|
|
1934
|
+
}, [onFullscreenChange]);
|
|
1935
|
+
react.useEffect(() => {
|
|
1936
|
+
if (!isFullscreen) {
|
|
1937
|
+
return void 0;
|
|
1938
|
+
}
|
|
1939
|
+
const body = typeof document !== "undefined" ? document.body : null;
|
|
1940
|
+
const prevOverflow = body?.style.overflow ?? "";
|
|
1941
|
+
if (body) {
|
|
1942
|
+
body.style.overflow = "hidden";
|
|
1943
|
+
}
|
|
1944
|
+
const onWinKey = (e) => {
|
|
1945
|
+
if (e.key === "Escape") {
|
|
1946
|
+
e.preventDefault();
|
|
1947
|
+
exitFullscreen();
|
|
1948
|
+
}
|
|
1949
|
+
};
|
|
1950
|
+
window.addEventListener("keydown", onWinKey);
|
|
1951
|
+
const fitId = window.setTimeout(() => vm.reset(), 60);
|
|
1952
|
+
let resizeId = 0;
|
|
1953
|
+
const onResize = () => {
|
|
1954
|
+
window.clearTimeout(resizeId);
|
|
1955
|
+
resizeId = window.setTimeout(() => vm.reset(), 150);
|
|
1956
|
+
};
|
|
1957
|
+
window.addEventListener("resize", onResize);
|
|
1958
|
+
window.addEventListener("orientationchange", onResize);
|
|
1959
|
+
rootRef.current?.focus();
|
|
1960
|
+
return () => {
|
|
1961
|
+
window.removeEventListener("keydown", onWinKey);
|
|
1962
|
+
window.removeEventListener("resize", onResize);
|
|
1963
|
+
window.removeEventListener("orientationchange", onResize);
|
|
1964
|
+
window.clearTimeout(fitId);
|
|
1965
|
+
window.clearTimeout(resizeId);
|
|
1966
|
+
if (body) {
|
|
1967
|
+
body.style.overflow = prevOverflow;
|
|
1968
|
+
}
|
|
1969
|
+
};
|
|
1970
|
+
}, [isFullscreen, exitFullscreen]);
|
|
1971
|
+
const fsMountedRef = react.useRef(false);
|
|
1972
|
+
react.useEffect(() => {
|
|
1973
|
+
if (!fsMountedRef.current) {
|
|
1974
|
+
fsMountedRef.current = true;
|
|
1975
|
+
return void 0;
|
|
1976
|
+
}
|
|
1977
|
+
if (isFullscreen) {
|
|
1978
|
+
return void 0;
|
|
1979
|
+
}
|
|
1980
|
+
const id = window.setTimeout(() => vm.reset(), 60);
|
|
1981
|
+
return () => window.clearTimeout(id);
|
|
1982
|
+
}, [isFullscreen]);
|
|
1502
1983
|
react.useEffect(() => {
|
|
1503
1984
|
if (!keyboard) {
|
|
1504
1985
|
return void 0;
|
|
@@ -1524,6 +2005,11 @@ var MermaidViewer = react.forwardRef(
|
|
|
1524
2005
|
closeSearch();
|
|
1525
2006
|
return;
|
|
1526
2007
|
}
|
|
2008
|
+
if (e.key === "Escape" && isFullscreen) {
|
|
2009
|
+
e.preventDefault();
|
|
2010
|
+
exitFullscreen();
|
|
2011
|
+
return;
|
|
2012
|
+
}
|
|
1527
2013
|
if (typing) {
|
|
1528
2014
|
return;
|
|
1529
2015
|
}
|
|
@@ -1537,11 +2023,29 @@ var MermaidViewer = react.forwardRef(
|
|
|
1537
2023
|
vm.actualSize();
|
|
1538
2024
|
} else if (e.key === "w" || e.key === "W") {
|
|
1539
2025
|
vm.fit();
|
|
2026
|
+
} else if (fullscreenEnabled && (e.key === "f" || e.key === "F")) {
|
|
2027
|
+
e.preventDefault();
|
|
2028
|
+
toggleFullscreen();
|
|
2029
|
+
} else if (backgroundEnabled && (e.key === "b" || e.key === "B")) {
|
|
2030
|
+
e.preventDefault();
|
|
2031
|
+
cycleBackground();
|
|
1540
2032
|
}
|
|
1541
2033
|
};
|
|
1542
2034
|
root.addEventListener("keydown", onKey);
|
|
1543
2035
|
return () => root.removeEventListener("keydown", onKey);
|
|
1544
|
-
}, [
|
|
2036
|
+
}, [
|
|
2037
|
+
keyboard,
|
|
2038
|
+
searchOpen,
|
|
2039
|
+
openSearch,
|
|
2040
|
+
closeSearch,
|
|
2041
|
+
vm,
|
|
2042
|
+
isFullscreen,
|
|
2043
|
+
exitFullscreen,
|
|
2044
|
+
toggleFullscreen,
|
|
2045
|
+
cycleBackground,
|
|
2046
|
+
fullscreenEnabled,
|
|
2047
|
+
backgroundEnabled
|
|
2048
|
+
]);
|
|
1545
2049
|
react.useImperativeHandle(
|
|
1546
2050
|
ref,
|
|
1547
2051
|
() => ({
|
|
@@ -1559,9 +2063,25 @@ var MermaidViewer = react.forwardRef(
|
|
|
1559
2063
|
exportPng: vm.exportPng,
|
|
1560
2064
|
downloadSvg: vm.downloadSvg,
|
|
1561
2065
|
downloadPng: vm.downloadPng,
|
|
1562
|
-
getSvg: vm.getSvg
|
|
2066
|
+
getSvg: vm.getSvg,
|
|
2067
|
+
enterFullscreen,
|
|
2068
|
+
exitFullscreen,
|
|
2069
|
+
toggleFullscreen,
|
|
2070
|
+
isFullscreen: () => isFullscreen,
|
|
2071
|
+
setBackground,
|
|
2072
|
+
cycleBackground,
|
|
2073
|
+
getBackground: () => background
|
|
1563
2074
|
}),
|
|
1564
|
-
[
|
|
2075
|
+
[
|
|
2076
|
+
vm,
|
|
2077
|
+
enterFullscreen,
|
|
2078
|
+
exitFullscreen,
|
|
2079
|
+
toggleFullscreen,
|
|
2080
|
+
isFullscreen,
|
|
2081
|
+
setBackground,
|
|
2082
|
+
cycleBackground,
|
|
2083
|
+
background
|
|
2084
|
+
]
|
|
1565
2085
|
);
|
|
1566
2086
|
let countText = "";
|
|
1567
2087
|
if (matchInfo.total > 0) {
|
|
@@ -1569,7 +2089,13 @@ var MermaidViewer = react.forwardRef(
|
|
|
1569
2089
|
} else if (query.trim()) {
|
|
1570
2090
|
countText = "0";
|
|
1571
2091
|
}
|
|
1572
|
-
const rootClassName = [
|
|
2092
|
+
const rootClassName = [
|
|
2093
|
+
"rsm-root",
|
|
2094
|
+
dark ? "rsm-dark" : "",
|
|
2095
|
+
`rsm-bg-${background}`,
|
|
2096
|
+
isFullscreen ? "rsm-fullscreen" : "",
|
|
2097
|
+
className ?? ""
|
|
2098
|
+
].filter(Boolean).join(" ");
|
|
1573
2099
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1574
2100
|
"div",
|
|
1575
2101
|
{
|
|
@@ -1595,7 +2121,13 @@ var MermaidViewer = react.forwardRef(
|
|
|
1595
2121
|
exportEnabled: exportable,
|
|
1596
2122
|
exporting,
|
|
1597
2123
|
onExportSvg: exportSvg,
|
|
1598
|
-
onExportPng: exportPng
|
|
2124
|
+
onExportPng: exportPng,
|
|
2125
|
+
backgroundEnabled,
|
|
2126
|
+
background,
|
|
2127
|
+
onCycleBackground: cycleBackground,
|
|
2128
|
+
fullscreenEnabled,
|
|
2129
|
+
fullscreen: isFullscreen,
|
|
2130
|
+
onToggleFullscreen: toggleFullscreen
|
|
1599
2131
|
}
|
|
1600
2132
|
) : null,
|
|
1601
2133
|
toolbar && searchEnabled && searchOpen ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rsm-searchbar", children: [
|
|
@@ -1635,6 +2167,17 @@ var MermaidViewer = react.forwardRef(
|
|
|
1635
2167
|
"\u5716\u8868\u8F09\u5165\u5931\u6557\uFF1A",
|
|
1636
2168
|
vm.error
|
|
1637
2169
|
] }) : null,
|
|
2170
|
+
isFullscreen ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2171
|
+
"button",
|
|
2172
|
+
{
|
|
2173
|
+
type: "button",
|
|
2174
|
+
className: "rsm-fs-close",
|
|
2175
|
+
onClick: exitFullscreen,
|
|
2176
|
+
title: "\u96E2\u958B\u5168\u87A2\u5E55\uFF08Esc\uFF09",
|
|
2177
|
+
"aria-label": "\u96E2\u958B\u5168\u87A2\u5E55",
|
|
2178
|
+
children: "\u2715"
|
|
2179
|
+
}
|
|
2180
|
+
) : null,
|
|
1638
2181
|
/* @__PURE__ */ jsxRuntime.jsx("div", { ref: vm.stageRef, className: "rsm-stage" })
|
|
1639
2182
|
] })
|
|
1640
2183
|
]
|
|
@@ -1654,6 +2197,7 @@ exports.MermaidDiagram = MermaidDiagram;
|
|
|
1654
2197
|
exports.MermaidViewer = MermaidViewer;
|
|
1655
2198
|
exports.SKETCH_FONT = SKETCH_FONT;
|
|
1656
2199
|
exports.Toolbar = Toolbar;
|
|
2200
|
+
exports.boostLegibility = boostLegibility;
|
|
1657
2201
|
exports.colorizeDiagram = colorizeDiagram;
|
|
1658
2202
|
exports.downloadBlob = downloadBlob;
|
|
1659
2203
|
exports.ensureSketchFont = ensureSketchFont;
|