@markdy/renderer-dom 1.0.19 → 1.0.21
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/dist/index.d.ts +2 -1
- package/dist/index.js +374 -60
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BeatRange, Diagnostic, RenderPlan } from '@markdy/core';
|
|
1
|
+
import { BeatRange, ThemeTokens, Diagnostic, RenderPlan } from '@markdy/core';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Markdy diagram runtime — renders a RenderPlan via WAAPI.
|
|
@@ -50,6 +50,7 @@ interface Diagram {
|
|
|
50
50
|
seekToBeat(name: string): void;
|
|
51
51
|
nextBeat(): void;
|
|
52
52
|
prevBeat(): void;
|
|
53
|
+
setTheme(theme: string | ThemeTokens): void;
|
|
53
54
|
destroy(): void;
|
|
54
55
|
}
|
|
55
56
|
declare function createDiagram(opts: DiagramOptions): Diagram;
|
package/dist/index.js
CHANGED
|
@@ -8,7 +8,8 @@ import {
|
|
|
8
8
|
import {
|
|
9
9
|
compressMarkdyToUrlHash,
|
|
10
10
|
parseAndCompile,
|
|
11
|
-
resolvePlayer
|
|
11
|
+
resolvePlayer,
|
|
12
|
+
resolveTheme
|
|
12
13
|
} from "@markdy/core";
|
|
13
14
|
|
|
14
15
|
// src/geometry/rect.ts
|
|
@@ -188,11 +189,24 @@ function toPathD(points, cornerRadius = 14, existingPaths = []) {
|
|
|
188
189
|
}
|
|
189
190
|
return parts.join(" ");
|
|
190
191
|
}
|
|
191
|
-
function selfLoopPath(rect) {
|
|
192
|
+
function selfLoopPath(rect, bounds) {
|
|
192
193
|
const top = rect.y;
|
|
194
|
+
const loopHeight = 36;
|
|
195
|
+
if (bounds && top - loopHeight < 16) {
|
|
196
|
+
const bottom = rect.y + rect.height;
|
|
197
|
+
const left2 = rect.x + rect.width * 0.3;
|
|
198
|
+
const right2 = rect.x + rect.width * 0.7;
|
|
199
|
+
const apex2 = Math.min(bounds.height - 16, bottom + loopHeight);
|
|
200
|
+
return [
|
|
201
|
+
{ x: round1(right2), y: round1(bottom) },
|
|
202
|
+
{ x: round1(right2), y: round1(apex2) },
|
|
203
|
+
{ x: round1(left2), y: round1(apex2) },
|
|
204
|
+
{ x: round1(left2), y: round1(bottom) }
|
|
205
|
+
];
|
|
206
|
+
}
|
|
193
207
|
const left = rect.x + rect.width * 0.3;
|
|
194
208
|
const right = rect.x + rect.width * 0.7;
|
|
195
|
-
const apex = top -
|
|
209
|
+
const apex = Math.max(12, top - loopHeight);
|
|
196
210
|
return [
|
|
197
211
|
{ x: round1(left), y: round1(top) },
|
|
198
212
|
{ x: round1(left), y: round1(apex) },
|
|
@@ -316,10 +330,112 @@ function routeOrthogonal(sourceRect, targetRect, obstacles, bounds, lane = 0) {
|
|
|
316
330
|
const targetCenter = rectCenter(targetRect);
|
|
317
331
|
const dx = targetCenter.x - sourceCenter.x;
|
|
318
332
|
const dy = targetCenter.y - sourceCenter.y;
|
|
333
|
+
const isDominantVertical = Math.abs(dy) >= Math.abs(dx);
|
|
319
334
|
const stubLen = 18;
|
|
320
335
|
const allObstacles = obstacles;
|
|
321
336
|
const candidates = [];
|
|
322
|
-
if (
|
|
337
|
+
if (dy >= 20) {
|
|
338
|
+
let sX = sourceCenter.x;
|
|
339
|
+
let tX = targetCenter.x;
|
|
340
|
+
if (dx > 16) {
|
|
341
|
+
sX = clamp(sourceCenter.x + (lane > 0 ? Math.abs(laneShift) : 6), sourceRect.x1 + 14, sourceRect.x2 - 14);
|
|
342
|
+
tX = clamp(targetCenter.x - (lane > 0 ? Math.abs(laneShift) : 6), targetRect.x1 + 14, targetRect.x2 - 14);
|
|
343
|
+
} else if (dx < -16) {
|
|
344
|
+
sX = clamp(sourceCenter.x - (lane > 0 ? Math.abs(laneShift) : 6), sourceRect.x1 + 14, sourceRect.x2 - 14);
|
|
345
|
+
tX = clamp(targetCenter.x + (lane > 0 ? Math.abs(laneShift) : 6), targetRect.x1 + 14, targetRect.x2 - 14);
|
|
346
|
+
} else {
|
|
347
|
+
sX = clamp(sourceCenter.x + laneShift, sourceRect.x1 + 14, sourceRect.x2 - 14);
|
|
348
|
+
tX = clamp(targetCenter.x + laneShift, targetRect.x1 + 14, targetRect.x2 - 14);
|
|
349
|
+
}
|
|
350
|
+
const sPort = { x: sX, y: sourceRect.y2 };
|
|
351
|
+
const tPort = { x: tX, y: targetRect.y1 };
|
|
352
|
+
if (Math.abs(sX - tX) < 1) {
|
|
353
|
+
candidates.push([sPort, tPort]);
|
|
354
|
+
} else {
|
|
355
|
+
const midY = round1((sPort.y + tPort.y) / 2 + laneShift);
|
|
356
|
+
candidates.push([
|
|
357
|
+
sPort,
|
|
358
|
+
{ x: sPort.x, y: midY },
|
|
359
|
+
{ x: tPort.x, y: midY },
|
|
360
|
+
tPort
|
|
361
|
+
]);
|
|
362
|
+
}
|
|
363
|
+
let minObstacleX = Math.min(sourceRect.x1, targetRect.x1);
|
|
364
|
+
let maxObstacleX = Math.max(sourceRect.x2, targetRect.x2);
|
|
365
|
+
for (const o of allObstacles) {
|
|
366
|
+
if (o.y2 > sourceRect.y2 && o.y1 < targetRect.y1) {
|
|
367
|
+
minObstacleX = Math.min(minObstacleX, o.x1);
|
|
368
|
+
maxObstacleX = Math.max(maxObstacleX, o.x2);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
const bypassXLeft = Math.max(16, minObstacleX - 24 - Math.abs(laneShift));
|
|
372
|
+
const bypassXRight = Math.min(bounds.width - 16, maxObstacleX + 24 + Math.abs(laneShift));
|
|
373
|
+
candidates.push([
|
|
374
|
+
sPort,
|
|
375
|
+
{ x: sPort.x, y: sPort.y + 12 },
|
|
376
|
+
{ x: bypassXLeft, y: sPort.y + 12 },
|
|
377
|
+
{ x: bypassXLeft, y: tPort.y - 12 },
|
|
378
|
+
{ x: tPort.x, y: tPort.y - 12 },
|
|
379
|
+
tPort
|
|
380
|
+
]);
|
|
381
|
+
candidates.push([
|
|
382
|
+
sPort,
|
|
383
|
+
{ x: sPort.x, y: sPort.y + 12 },
|
|
384
|
+
{ x: bypassXRight, y: sPort.y + 12 },
|
|
385
|
+
{ x: bypassXRight, y: tPort.y - 12 },
|
|
386
|
+
{ x: tPort.x, y: tPort.y - 12 },
|
|
387
|
+
tPort
|
|
388
|
+
]);
|
|
389
|
+
} else if (dy <= -20) {
|
|
390
|
+
let sX = sourceCenter.x;
|
|
391
|
+
let tX = targetCenter.x;
|
|
392
|
+
if (dx > 16) {
|
|
393
|
+
sX = clamp(sourceCenter.x + (lane > 0 ? Math.abs(laneShift) : 6), sourceRect.x1 + 14, sourceRect.x2 - 14);
|
|
394
|
+
tX = clamp(targetCenter.x - (lane > 0 ? Math.abs(laneShift) : 6), targetRect.x1 + 14, targetRect.x2 - 14);
|
|
395
|
+
} else if (dx < -16) {
|
|
396
|
+
sX = clamp(sourceCenter.x - (lane > 0 ? Math.abs(laneShift) : 6), sourceRect.x1 + 14, sourceRect.x2 - 14);
|
|
397
|
+
tX = clamp(targetCenter.x + (lane > 0 ? Math.abs(laneShift) : 6), targetRect.x1 + 14, targetRect.x2 - 14);
|
|
398
|
+
} else {
|
|
399
|
+
sX = clamp(sourceCenter.x + laneShift, sourceRect.x1 + 14, sourceRect.x2 - 14);
|
|
400
|
+
tX = clamp(targetCenter.x + laneShift, targetRect.x1 + 14, targetRect.x2 - 14);
|
|
401
|
+
}
|
|
402
|
+
const sPort = { x: sX, y: sourceRect.y1 };
|
|
403
|
+
const tPort = { x: tX, y: targetRect.y2 };
|
|
404
|
+
if (Math.abs(sX - tX) < 1) {
|
|
405
|
+
candidates.push([sPort, tPort]);
|
|
406
|
+
} else {
|
|
407
|
+
const midY = round1((sPort.y + tPort.y) / 2 + laneShift);
|
|
408
|
+
candidates.push([
|
|
409
|
+
sPort,
|
|
410
|
+
{ x: sPort.x, y: midY },
|
|
411
|
+
{ x: tPort.x, y: midY },
|
|
412
|
+
tPort
|
|
413
|
+
]);
|
|
414
|
+
}
|
|
415
|
+
let minObstacleX = Math.min(sourceRect.x1, targetRect.x1);
|
|
416
|
+
let maxObstacleX = Math.max(sourceRect.x2, targetRect.x2);
|
|
417
|
+
for (const o of allObstacles) {
|
|
418
|
+
if (o.y1 < sourceRect.y2 && o.y2 > targetRect.y1) {
|
|
419
|
+
minObstacleX = Math.min(minObstacleX, o.x1);
|
|
420
|
+
maxObstacleX = Math.max(maxObstacleX, o.x2);
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
const bypassXLeft = Math.max(16, minObstacleX - 28 - Math.abs(laneShift));
|
|
424
|
+
const bypassXRight = Math.min(bounds.width - 16, maxObstacleX + 28 + Math.abs(laneShift));
|
|
425
|
+
candidates.push([
|
|
426
|
+
{ x: sourceRect.x1, y: sourceCenter.y },
|
|
427
|
+
{ x: bypassXLeft, y: sourceCenter.y },
|
|
428
|
+
{ x: bypassXLeft, y: targetCenter.y },
|
|
429
|
+
{ x: targetRect.x1, y: targetCenter.y }
|
|
430
|
+
]);
|
|
431
|
+
candidates.push([
|
|
432
|
+
{ x: sourceRect.x2, y: sourceCenter.y },
|
|
433
|
+
{ x: bypassXRight, y: sourceCenter.y },
|
|
434
|
+
{ x: bypassXRight, y: targetCenter.y },
|
|
435
|
+
{ x: targetRect.x2, y: targetCenter.y }
|
|
436
|
+
]);
|
|
437
|
+
}
|
|
438
|
+
if (dx >= 20) {
|
|
323
439
|
let sY = sourceCenter.y;
|
|
324
440
|
let tY = targetCenter.y;
|
|
325
441
|
if (Math.abs(dy) > 16) {
|
|
@@ -334,15 +450,16 @@ function routeOrthogonal(sourceRect, targetRect, obstacles, bounds, lane = 0) {
|
|
|
334
450
|
const tPort = { x: targetRect.x1, y: tY };
|
|
335
451
|
if (Math.abs(sY - tY) < 1) {
|
|
336
452
|
candidates.push([sPort, tPort]);
|
|
453
|
+
} else {
|
|
454
|
+
const rawMidX = (sPort.x + tPort.x) / 2 + laneShift;
|
|
455
|
+
const midX = round1(clamp(rawMidX, sourceRect.x2 + 8, targetRect.x1 - 8));
|
|
456
|
+
candidates.push([
|
|
457
|
+
sPort,
|
|
458
|
+
{ x: midX, y: sY },
|
|
459
|
+
{ x: midX, y: tY },
|
|
460
|
+
tPort
|
|
461
|
+
]);
|
|
337
462
|
}
|
|
338
|
-
const rawMidX = (sPort.x + tPort.x) / 2 + laneShift;
|
|
339
|
-
const midX = round1(clamp(rawMidX, sourceRect.x2 + 8, targetRect.x1 - 8));
|
|
340
|
-
candidates.push([
|
|
341
|
-
sPort,
|
|
342
|
-
{ x: midX, y: sY },
|
|
343
|
-
{ x: midX, y: tY },
|
|
344
|
-
tPort
|
|
345
|
-
]);
|
|
346
463
|
let minObstacleY = Math.min(sourceRect.y1, targetRect.y1);
|
|
347
464
|
for (const o of allObstacles) {
|
|
348
465
|
if (o.x2 > sourceRect.x2 && o.x1 < targetRect.x1) {
|
|
@@ -356,7 +473,7 @@ function routeOrthogonal(sourceRect, targetRect, obstacles, bounds, lane = 0) {
|
|
|
356
473
|
{ x: targetCenter.x, y: bypassYTop },
|
|
357
474
|
{ x: targetCenter.x, y: targetRect.y1 }
|
|
358
475
|
]);
|
|
359
|
-
} else if (dx
|
|
476
|
+
} else if (dx <= -20) {
|
|
360
477
|
const sX = clamp(sourceCenter.x + (lane > 0 ? lane % 2 === 1 ? 8 : -8 : 0), sourceRect.x1 + 16, sourceRect.x2 - 16);
|
|
361
478
|
const tX = clamp(targetCenter.x + (lane > 0 ? lane % 2 === 1 ? 8 : -8 : 0), targetRect.x1 + 16, targetRect.x2 - 16);
|
|
362
479
|
let minObstacleY = Math.min(sourceRect.y1, targetRect.y1);
|
|
@@ -401,23 +518,6 @@ function routeOrthogonal(sourceRect, targetRect, obstacles, bounds, lane = 0) {
|
|
|
401
518
|
{ x: midX, y: tY },
|
|
402
519
|
tPortR
|
|
403
520
|
]);
|
|
404
|
-
} else {
|
|
405
|
-
const sX = clamp(sourceCenter.x + laneShift, sourceRect.x1 + 16, sourceRect.x2 - 16);
|
|
406
|
-
const tX = clamp(targetCenter.x + laneShift, targetRect.x1 + 16, targetRect.x2 - 16);
|
|
407
|
-
const sourceDown = dy >= 0;
|
|
408
|
-
const sPort = { x: sX, y: sourceDown ? sourceRect.y2 : sourceRect.y1 };
|
|
409
|
-
const tPort = { x: tX, y: sourceDown ? targetRect.y1 : targetRect.y2 };
|
|
410
|
-
if (Math.abs(sX - tX) < 1) {
|
|
411
|
-
candidates.push([sPort, tPort]);
|
|
412
|
-
} else {
|
|
413
|
-
const midY = round1((sPort.y + tPort.y) / 2 + laneShift);
|
|
414
|
-
candidates.push([
|
|
415
|
-
sPort,
|
|
416
|
-
{ x: sPort.x, y: midY },
|
|
417
|
-
{ x: tPort.x, y: midY },
|
|
418
|
-
tPort
|
|
419
|
-
]);
|
|
420
|
-
}
|
|
421
521
|
}
|
|
422
522
|
for (const obstacle of allObstacles) {
|
|
423
523
|
const bypassYTop = Math.max(16, obstacle.y1 - 18 - Math.abs(laneShift));
|
|
@@ -443,6 +543,12 @@ function routeOrthogonal(sourceRect, targetRect, obstacles, bounds, lane = 0) {
|
|
|
443
543
|
tP
|
|
444
544
|
]);
|
|
445
545
|
}
|
|
546
|
+
if (candidates.length === 0) {
|
|
547
|
+
candidates.push([
|
|
548
|
+
{ x: sourceCenter.x, y: sourceCenter.y },
|
|
549
|
+
{ x: targetCenter.x, y: targetCenter.y }
|
|
550
|
+
]);
|
|
551
|
+
}
|
|
446
552
|
let best = candidates[0];
|
|
447
553
|
let bestScore = Number.POSITIVE_INFINITY;
|
|
448
554
|
for (const candidate of candidates) {
|
|
@@ -450,7 +556,27 @@ function routeOrthogonal(sourceRect, targetRect, obstacles, bounds, lane = 0) {
|
|
|
450
556
|
const hits = countPathIntersections(cleaned, allObstacles);
|
|
451
557
|
const bends = routeBends(cleaned);
|
|
452
558
|
const length = routeLength(cleaned);
|
|
453
|
-
|
|
559
|
+
let portPenalty = 0;
|
|
560
|
+
const startP = cleaned[0];
|
|
561
|
+
const endP = cleaned[cleaned.length - 1];
|
|
562
|
+
if (isDominantVertical) {
|
|
563
|
+
if (dy >= 20) {
|
|
564
|
+
if (Math.abs(startP.y - sourceRect.y1) < 1) portPenalty += 25e3;
|
|
565
|
+
if (Math.abs(endP.y - targetRect.y2) < 1) portPenalty += 25e3;
|
|
566
|
+
} else if (dy <= -20) {
|
|
567
|
+
if (Math.abs(startP.y - sourceRect.y2) < 1) portPenalty += 25e3;
|
|
568
|
+
if (Math.abs(endP.y - targetRect.y1) < 1) portPenalty += 25e3;
|
|
569
|
+
}
|
|
570
|
+
} else {
|
|
571
|
+
if (dx >= 20) {
|
|
572
|
+
if (Math.abs(startP.x - sourceRect.x1) < 1) portPenalty += 25e3;
|
|
573
|
+
if (Math.abs(endP.x - targetRect.x2) < 1) portPenalty += 25e3;
|
|
574
|
+
} else if (dx <= -20) {
|
|
575
|
+
if (Math.abs(startP.x - sourceRect.x2) < 1) portPenalty += 25e3;
|
|
576
|
+
if (Math.abs(endP.x - targetRect.x1) < 1) portPenalty += 25e3;
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
const score = hits * 1e6 + portPenalty + bends * 500 + length;
|
|
454
580
|
if (score < bestScore) {
|
|
455
581
|
bestScore = score;
|
|
456
582
|
best = cleaned;
|
|
@@ -522,9 +648,14 @@ function ensureEdgeLayer(scene) {
|
|
|
522
648
|
}
|
|
523
649
|
function ensureDefs(svg, theme, id) {
|
|
524
650
|
const key = `data-markdy-defs-${id}`;
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
651
|
+
let defs = svg.querySelector(`defs[${key}='1']`);
|
|
652
|
+
if (!defs) {
|
|
653
|
+
defs = document.createElementNS("http://www.w3.org/2000/svg", "defs");
|
|
654
|
+
defs.setAttribute(key, "1");
|
|
655
|
+
svg.prepend(defs);
|
|
656
|
+
} else {
|
|
657
|
+
defs.replaceChildren();
|
|
658
|
+
}
|
|
528
659
|
for (const [kind, color] of Object.entries(theme.edges)) {
|
|
529
660
|
const arrow = document.createElementNS("http://www.w3.org/2000/svg", "marker");
|
|
530
661
|
arrow.setAttribute("id", `${id}-arrow-${kind}`);
|
|
@@ -571,7 +702,27 @@ function ensureDefs(svg, theme, id) {
|
|
|
571
702
|
filter.appendChild(turb);
|
|
572
703
|
filter.appendChild(disp);
|
|
573
704
|
defs.appendChild(filter);
|
|
574
|
-
|
|
705
|
+
}
|
|
706
|
+
function updateEdgeLayerTheme(svg, edgeRuntimeMap, theme, sceneId) {
|
|
707
|
+
ensureDefs(svg, theme, sceneId);
|
|
708
|
+
const isDark = isDarkTheme(theme);
|
|
709
|
+
for (const runtime of edgeRuntimeMap.values()) {
|
|
710
|
+
const color = theme.edges[runtime.kind];
|
|
711
|
+
runtime.color = color;
|
|
712
|
+
runtime.path.setAttribute("stroke", color);
|
|
713
|
+
if (runtime.kind !== "dependency") {
|
|
714
|
+
runtime.path.style.filter = `drop-shadow(0 0 4px ${translucentColor(color, "44")})`;
|
|
715
|
+
}
|
|
716
|
+
runtime.dot.setAttribute("fill", color);
|
|
717
|
+
runtime.dot.style.filter = `drop-shadow(0 0 6px ${color}) drop-shadow(0 0 12px ${color}88)`;
|
|
718
|
+
if (runtime.labelPlate) {
|
|
719
|
+
runtime.labelPlate.setAttribute("fill", theme.canvas ?? theme.surface ?? "#ffffff");
|
|
720
|
+
runtime.labelPlate.setAttribute("stroke", translucentColor(color, "28"));
|
|
721
|
+
}
|
|
722
|
+
if (runtime.label) {
|
|
723
|
+
runtime.label.setAttribute("fill", computeEdgeLabelColor(color, isDark));
|
|
724
|
+
}
|
|
725
|
+
}
|
|
575
726
|
}
|
|
576
727
|
function isDarkTheme(theme) {
|
|
577
728
|
if (theme.name === "paper" || theme.name === "editorial" || theme.name === "sketchy") {
|
|
@@ -599,7 +750,7 @@ function createEdgeRuntime(svg, from, to, kind, label, theme, sceneId, routeObst
|
|
|
599
750
|
const color = theme.edges[kind];
|
|
600
751
|
const style = EDGE_STYLES[kind];
|
|
601
752
|
const isSelfLoop = from.id === to.id;
|
|
602
|
-
const points = isSelfLoop ? dedupePoints(selfLoopPath(from)) : dedupePoints(routeEdgePoints(from, to, routeObstacles, bounds, lane));
|
|
753
|
+
const points = isSelfLoop ? dedupePoints(selfLoopPath(from, bounds)) : dedupePoints(routeEdgePoints(from, to, routeObstacles, bounds, lane));
|
|
603
754
|
const d = toPathD(points, 14, existingPaths);
|
|
604
755
|
const len = polylineLength(points);
|
|
605
756
|
const group = document.createElementNS("http://www.w3.org/2000/svg", "g");
|
|
@@ -1635,6 +1786,10 @@ function ensureNodeStyles(doc) {
|
|
|
1635
1786
|
border-radius: 4px;
|
|
1636
1787
|
transform: rotate(0deg);
|
|
1637
1788
|
clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%);
|
|
1789
|
+
filter: drop-shadow(0 0 1px var(--md-hairline, rgba(15, 23, 42, 0.2))) drop-shadow(0 4px 12px var(--md-shadow, rgba(2, 6, 23, 0.15)));
|
|
1790
|
+
}
|
|
1791
|
+
.markdy-node[data-shape="diamond"][data-focal="1"] {
|
|
1792
|
+
filter: drop-shadow(0 0 1.5px var(--md-accent)) drop-shadow(0 4px 14px var(--md-shadow, rgba(2, 6, 23, 0.15)));
|
|
1638
1793
|
}
|
|
1639
1794
|
.markdy-node[data-shape="diamond"] .markdy-node__body {
|
|
1640
1795
|
justify-content: center;
|
|
@@ -1650,6 +1805,13 @@ function ensureNodeStyles(doc) {
|
|
|
1650
1805
|
border-radius: 999px;
|
|
1651
1806
|
min-height: 54px;
|
|
1652
1807
|
}
|
|
1808
|
+
.markdy-node[data-shape="pill"] .markdy-node__body {
|
|
1809
|
+
justify-content: center;
|
|
1810
|
+
padding: 0 20px;
|
|
1811
|
+
}
|
|
1812
|
+
.markdy-node[data-shape="pill"] .markdy-node__label {
|
|
1813
|
+
text-align: center;
|
|
1814
|
+
}
|
|
1653
1815
|
.markdy-node[data-shape="circle"],
|
|
1654
1816
|
.markdy-node[data-kind="dot"] {
|
|
1655
1817
|
border-radius: 50%;
|
|
@@ -1719,9 +1881,10 @@ function ensureNodeStyles(doc) {
|
|
|
1719
1881
|
background: var(--md-node-surface, var(--md-surface));
|
|
1720
1882
|
}
|
|
1721
1883
|
.markdy-node[data-focal="1"] {
|
|
1722
|
-
background: color-mix(in srgb, var(--md-accent-tint, var(--md-accent)) 100%, transparent);
|
|
1723
1884
|
box-shadow:
|
|
1724
|
-
|
|
1885
|
+
0 2px 10px -2px var(--md-shadow, rgba(2, 6, 23, 0.18)),
|
|
1886
|
+
inset 0 0 0 1.5px var(--md-accent),
|
|
1887
|
+
0 0 0 1px color-mix(in srgb, var(--md-accent) 25%, transparent);
|
|
1725
1888
|
}
|
|
1726
1889
|
.markdy-scene-root[data-markdy-theme="nebula"] .markdy-node {
|
|
1727
1890
|
border: 1px solid color-mix(in srgb, var(--md-role-color, var(--md-accent)) 34%, transparent);
|
|
@@ -1732,7 +1895,7 @@ function ensureNodeStyles(doc) {
|
|
|
1732
1895
|
.markdy-scene-root[data-markdy-theme="nebula"] .markdy-node[data-focal="1"] {
|
|
1733
1896
|
box-shadow:
|
|
1734
1897
|
0 0 34px -8px color-mix(in srgb, var(--md-accent) 78%, transparent),
|
|
1735
|
-
inset 0 0 0
|
|
1898
|
+
inset 0 0 0 1.5px var(--md-accent);
|
|
1736
1899
|
}
|
|
1737
1900
|
.markdy-scene-root[data-flat="1"] .markdy-node {
|
|
1738
1901
|
box-shadow: inset 0 0 0 1px var(--md-hairline, color-mix(in srgb, var(--md-border) 50%, transparent));
|
|
@@ -1741,11 +1904,7 @@ function ensureNodeStyles(doc) {
|
|
|
1741
1904
|
box-shadow: inset 0 0 0 1px var(--md-hairline, color-mix(in srgb, var(--md-border) 50%, transparent));
|
|
1742
1905
|
}
|
|
1743
1906
|
.markdy-scene-root[data-flat="1"] .markdy-node[data-focal="1"] {
|
|
1744
|
-
box-shadow: inset 0 0 0 1.5px
|
|
1745
|
-
background:
|
|
1746
|
-
linear-gradient(180deg,
|
|
1747
|
-
color-mix(in srgb, var(--md-accent-tint, var(--md-accent)) 8%, transparent),
|
|
1748
|
-
color-mix(in srgb, var(--md-accent-tint, var(--md-accent)) 4%, transparent));
|
|
1907
|
+
box-shadow: inset 0 0 0 1.5px var(--md-accent);
|
|
1749
1908
|
}
|
|
1750
1909
|
.markdy-node[data-kind="external"] {
|
|
1751
1910
|
border: 1.2px dashed color-mix(in srgb, var(--md-ink, var(--md-text)) 30%, transparent);
|
|
@@ -1768,17 +1927,32 @@ function ensureNodeStyles(doc) {
|
|
|
1768
1927
|
border-color: #ff5a36;
|
|
1769
1928
|
box-shadow: 0 0 18px -8px rgba(255, 90, 54, 0.45);
|
|
1770
1929
|
}
|
|
1930
|
+
.markdy-scene-root[data-markdy-theme="terminal"] .markdy-node[data-shape="diamond"] {
|
|
1931
|
+
filter: drop-shadow(0 0 1px #2b2b2b);
|
|
1932
|
+
}
|
|
1933
|
+
.markdy-scene-root[data-markdy-theme="terminal"] .markdy-node[data-shape="diamond"][data-focal="1"] {
|
|
1934
|
+
filter: drop-shadow(0 0 2px #ff5a36) drop-shadow(0 0 12px rgba(255, 90, 54, 0.35));
|
|
1935
|
+
}
|
|
1771
1936
|
.markdy-scene-root[data-markdy-theme="sketchy"] .markdy-node {
|
|
1772
1937
|
background: #ffffff;
|
|
1773
1938
|
border: 1.5px solid #2d3142;
|
|
1774
1939
|
box-shadow: 3px 3px 0 rgba(45, 49, 66, 0.10);
|
|
1775
1940
|
border-radius: var(--md-radius-md, 4px);
|
|
1776
1941
|
}
|
|
1942
|
+
.markdy-scene-root[data-markdy-theme="sketchy"] .markdy-node[data-shape="diamond"] {
|
|
1943
|
+
filter: drop-shadow(0 0 1px #2d3142) drop-shadow(3px 3px 0 rgba(45, 49, 66, 0.12));
|
|
1944
|
+
}
|
|
1777
1945
|
.markdy-scene-root[data-markdy-theme="sketchy"] .markdy-node[data-focal="1"] {
|
|
1778
1946
|
border-color: #eb6c36;
|
|
1779
1947
|
background: rgba(235, 108, 54, 0.06);
|
|
1780
1948
|
box-shadow: 3px 3px 0 rgba(235, 108, 54, 0.12);
|
|
1781
1949
|
}
|
|
1950
|
+
.markdy-scene-root[data-markdy-theme="nebula"] .markdy-node[data-shape="diamond"] {
|
|
1951
|
+
filter: drop-shadow(0 0 1px var(--md-hairline)) drop-shadow(0 0 18px -4px color-mix(in srgb, var(--md-role-color, var(--md-accent)) 60%, transparent));
|
|
1952
|
+
}
|
|
1953
|
+
.markdy-scene-root[data-markdy-theme="nebula"] .markdy-node[data-shape="diamond"][data-focal="1"] {
|
|
1954
|
+
filter: drop-shadow(0 0 2px var(--md-accent)) drop-shadow(0 0 24px -2px color-mix(in srgb, var(--md-accent) 70%, transparent));
|
|
1955
|
+
}
|
|
1782
1956
|
`;
|
|
1783
1957
|
doc.head.appendChild(style);
|
|
1784
1958
|
}
|
|
@@ -2309,6 +2483,52 @@ function mountSequenceLayer(layer, nodes, messages, activations, theme, bounds)
|
|
|
2309
2483
|
for (const animation of animations) animation.pause();
|
|
2310
2484
|
return animations;
|
|
2311
2485
|
}
|
|
2486
|
+
function updateSequenceLayerTheme(layer, theme) {
|
|
2487
|
+
const svg = layer.querySelector("svg");
|
|
2488
|
+
if (!svg) return;
|
|
2489
|
+
const defs = svg.querySelector("defs");
|
|
2490
|
+
if (defs) {
|
|
2491
|
+
Array.from(defs.querySelectorAll("marker")).forEach((marker) => {
|
|
2492
|
+
const id = marker.getAttribute("id") || "";
|
|
2493
|
+
const path = marker.querySelector("path");
|
|
2494
|
+
if (path) {
|
|
2495
|
+
if (id.includes("response")) {
|
|
2496
|
+
path.setAttribute("stroke", theme.edges.response);
|
|
2497
|
+
} else if (id.includes("event")) {
|
|
2498
|
+
path.setAttribute("fill", theme.edges.event);
|
|
2499
|
+
} else {
|
|
2500
|
+
path.setAttribute("fill", theme.edges.request);
|
|
2501
|
+
}
|
|
2502
|
+
}
|
|
2503
|
+
});
|
|
2504
|
+
}
|
|
2505
|
+
Array.from(svg.querySelectorAll(".markdy-sequence-lifeline")).forEach((line) => {
|
|
2506
|
+
line.setAttribute("stroke", theme.hairline ?? theme.border);
|
|
2507
|
+
});
|
|
2508
|
+
Array.from(svg.querySelectorAll(".markdy-sequence-activation")).forEach((bar) => {
|
|
2509
|
+
bar.setAttribute("fill", theme.accent);
|
|
2510
|
+
bar.style.filter = `drop-shadow(0 0 6px ${theme.accent}66)`;
|
|
2511
|
+
});
|
|
2512
|
+
Array.from(svg.querySelectorAll(".markdy-sequence-message")).forEach((group) => {
|
|
2513
|
+
const line = group.querySelector("line");
|
|
2514
|
+
if (line) {
|
|
2515
|
+
const markerEnd = line.getAttribute("marker-end") || "";
|
|
2516
|
+
if (markerEnd.includes("response")) line.setAttribute("stroke", theme.edges.response);
|
|
2517
|
+
else if (markerEnd.includes("event")) line.setAttribute("stroke", theme.edges.event);
|
|
2518
|
+
else line.setAttribute("stroke", theme.edges.request);
|
|
2519
|
+
}
|
|
2520
|
+
const plate = group.querySelector("rect");
|
|
2521
|
+
if (plate) {
|
|
2522
|
+
plate.setAttribute("fill", theme.labelPlate ?? theme.surface);
|
|
2523
|
+
plate.setAttribute("stroke", theme.hairline ?? `color-mix(in srgb, ${theme.border} 70%, transparent)`);
|
|
2524
|
+
}
|
|
2525
|
+
const text = group.querySelector("text");
|
|
2526
|
+
if (text) {
|
|
2527
|
+
text.setAttribute("fill", theme.text);
|
|
2528
|
+
if (theme.fonts?.mono) text.setAttribute("font-family", theme.fonts.mono);
|
|
2529
|
+
}
|
|
2530
|
+
});
|
|
2531
|
+
}
|
|
2312
2532
|
|
|
2313
2533
|
// src/tree.ts
|
|
2314
2534
|
function mountTreeBuses(layer, buses, theme) {
|
|
@@ -2504,19 +2724,20 @@ function ensureSceneStyles(doc) {
|
|
|
2504
2724
|
}
|
|
2505
2725
|
.markdy-footer {
|
|
2506
2726
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
|
2727
|
+
position: relative;
|
|
2507
2728
|
width: 100%;
|
|
2508
2729
|
box-sizing: border-box;
|
|
2509
2730
|
display: flex;
|
|
2510
2731
|
align-items: center;
|
|
2511
2732
|
justify-content: space-between;
|
|
2512
2733
|
gap: 8px;
|
|
2513
|
-
padding:
|
|
2734
|
+
padding: 8px 12px 4px;
|
|
2514
2735
|
color: var(--md-text, #f8fafc);
|
|
2515
|
-
background:
|
|
2516
|
-
backdrop-filter:
|
|
2517
|
-
-webkit-backdrop-filter:
|
|
2518
|
-
border-top:
|
|
2519
|
-
z-index:
|
|
2736
|
+
background: transparent;
|
|
2737
|
+
backdrop-filter: none;
|
|
2738
|
+
-webkit-backdrop-filter: none;
|
|
2739
|
+
border-top: none;
|
|
2740
|
+
z-index: 100;
|
|
2520
2741
|
}
|
|
2521
2742
|
.markdy-controls {
|
|
2522
2743
|
display: flex;
|
|
@@ -2529,6 +2750,8 @@ function ensureSceneStyles(doc) {
|
|
|
2529
2750
|
max-width: 100%;
|
|
2530
2751
|
overflow-x: auto;
|
|
2531
2752
|
scrollbar-width: none;
|
|
2753
|
+
padding: 4px 2px;
|
|
2754
|
+
margin: -4px -2px;
|
|
2532
2755
|
}
|
|
2533
2756
|
.markdy-controls::-webkit-scrollbar {
|
|
2534
2757
|
display: none;
|
|
@@ -2590,6 +2813,8 @@ function ensureSceneStyles(doc) {
|
|
|
2590
2813
|
transition: all 0.15s cubic-bezier(0.4, 0, 0.2, 1);
|
|
2591
2814
|
}
|
|
2592
2815
|
.markdy-controls button:hover:not([aria-pressed="true"]) {
|
|
2816
|
+
position: relative;
|
|
2817
|
+
z-index: 2;
|
|
2593
2818
|
background: var(--md-control-hover-bg, rgba(255, 255, 255, 0.1));
|
|
2594
2819
|
color: var(--md-control-hover-text, #f8fafc);
|
|
2595
2820
|
border-color: var(--md-control-hover-border, rgba(148, 163, 184, 0.35));
|
|
@@ -2597,12 +2822,16 @@ function ensureSceneStyles(doc) {
|
|
|
2597
2822
|
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.12);
|
|
2598
2823
|
}
|
|
2599
2824
|
.markdy-controls button[aria-pressed="true"] {
|
|
2825
|
+
position: relative;
|
|
2826
|
+
z-index: 2;
|
|
2600
2827
|
background: var(--accent, #10b981) !important;
|
|
2601
2828
|
color: #ffffff !important;
|
|
2602
2829
|
border-color: var(--accent, #10b981) !important;
|
|
2603
2830
|
box-shadow: 0 0 10px var(--accent-glow, rgba(16, 185, 129, 0.4)) !important;
|
|
2604
2831
|
}
|
|
2605
2832
|
.markdy-controls button:focus-visible {
|
|
2833
|
+
position: relative;
|
|
2834
|
+
z-index: 3;
|
|
2606
2835
|
outline: 2px solid var(--accent, #10b981);
|
|
2607
2836
|
outline-offset: 1px;
|
|
2608
2837
|
}
|
|
@@ -2696,10 +2925,10 @@ function ensureSceneStyles(doc) {
|
|
|
2696
2925
|
.markdy-code-panel-overlay {
|
|
2697
2926
|
position: fixed;
|
|
2698
2927
|
inset: 0;
|
|
2699
|
-
z-index:
|
|
2700
|
-
background: rgba(2, 6, 23, 0.
|
|
2701
|
-
backdrop-filter: blur(
|
|
2702
|
-
-webkit-backdrop-filter: blur(
|
|
2928
|
+
z-index: 100000;
|
|
2929
|
+
background: rgba(2, 6, 23, 0.65);
|
|
2930
|
+
backdrop-filter: blur(4px);
|
|
2931
|
+
-webkit-backdrop-filter: blur(4px);
|
|
2703
2932
|
display: flex;
|
|
2704
2933
|
align-items: center;
|
|
2705
2934
|
justify-content: center;
|
|
@@ -3071,14 +3300,15 @@ function applyThemeVariables(element, theme) {
|
|
|
3071
3300
|
element.style.setProperty("--md-node-surface-raised", theme.nodeSurfaceRaised ?? theme.surfaceRaised);
|
|
3072
3301
|
element.style.setProperty("--md-hairline", theme.hairline ?? `color-mix(in srgb, ${theme.border} 50%, transparent)`);
|
|
3073
3302
|
element.style.setProperty("--md-shadow", theme.shadow ?? "rgba(2, 6, 23, 0.55)");
|
|
3074
|
-
element.style.setProperty("--md-footer-bg",
|
|
3075
|
-
element.style.setProperty("--md-footer-border",
|
|
3303
|
+
element.style.setProperty("--md-footer-bg", "transparent");
|
|
3304
|
+
element.style.setProperty("--md-footer-border", "transparent");
|
|
3076
3305
|
element.style.setProperty("--md-control-bg", theme.surfaceRaised);
|
|
3077
3306
|
element.style.setProperty("--md-control-border", theme.border);
|
|
3078
3307
|
element.style.setProperty("--md-control-text", theme.textMuted);
|
|
3079
3308
|
element.style.setProperty("--md-control-hover-bg", theme.canvas);
|
|
3080
3309
|
element.style.setProperty("--md-control-hover-text", theme.text);
|
|
3081
3310
|
element.style.setProperty("--md-control-hover-border", theme.accent);
|
|
3311
|
+
element.style.setProperty("--md-segmented-bg", `color-mix(in srgb, ${theme.surfaceRaised} 60%, transparent)`);
|
|
3082
3312
|
element.style.setProperty("--md-divider", theme.border);
|
|
3083
3313
|
if (theme.fonts?.title) element.style.setProperty("--md-font-title", theme.fonts.title);
|
|
3084
3314
|
if (theme.fonts?.nodeName) element.style.setProperty("--md-font-node", theme.fonts.nodeName);
|
|
@@ -3233,6 +3463,7 @@ function createDiagram(opts) {
|
|
|
3233
3463
|
let progressEl = null;
|
|
3234
3464
|
if (showProgress) {
|
|
3235
3465
|
progressEl = document.createElement("div");
|
|
3466
|
+
progressEl.className = progressMode === "bar" ? "markdy-progress-bar" : "markdy-boundary-progress";
|
|
3236
3467
|
Object.assign(progressEl.style, {
|
|
3237
3468
|
position: "absolute",
|
|
3238
3469
|
...progressMode === "bar" ? { left: "0", right: "0", bottom: "0", height: "3px" } : { inset: "0" },
|
|
@@ -3247,7 +3478,7 @@ function createDiagram(opts) {
|
|
|
3247
3478
|
function updateProgressBar(pct) {
|
|
3248
3479
|
if (!progressEl) return;
|
|
3249
3480
|
if (progressMode === "bar") {
|
|
3250
|
-
progressEl.style.background = customColor ?? "#2563eb";
|
|
3481
|
+
progressEl.style.background = customColor ?? plan.theme.accent ?? "#2563eb";
|
|
3251
3482
|
progressEl.style.transformOrigin = "left center";
|
|
3252
3483
|
progressEl.style.transform = `scaleX(${pct})`;
|
|
3253
3484
|
return;
|
|
@@ -3259,7 +3490,7 @@ function createDiagram(opts) {
|
|
|
3259
3490
|
progressEl.style.webkitMask = progressEl.style.mask;
|
|
3260
3491
|
progressEl.style.maskComposite = "exclude";
|
|
3261
3492
|
progressEl.style.webkitMaskComposite = "xor";
|
|
3262
|
-
progressEl.style.padding = "
|
|
3493
|
+
progressEl.style.padding = "1px";
|
|
3263
3494
|
}
|
|
3264
3495
|
let footer = null;
|
|
3265
3496
|
function ensureFooter() {
|
|
@@ -3268,6 +3499,8 @@ function createDiagram(opts) {
|
|
|
3268
3499
|
footer.className = "markdy-footer";
|
|
3269
3500
|
applyThemeVariables(footer, plan.theme);
|
|
3270
3501
|
Object.assign(footer.style, {
|
|
3502
|
+
position: "relative",
|
|
3503
|
+
zIndex: "100",
|
|
3271
3504
|
display: "flex",
|
|
3272
3505
|
alignItems: "center",
|
|
3273
3506
|
justifyContent: "space-between",
|
|
@@ -3275,7 +3508,8 @@ function createDiagram(opts) {
|
|
|
3275
3508
|
gap: "6px",
|
|
3276
3509
|
width: "100%",
|
|
3277
3510
|
boxSizing: "border-box",
|
|
3278
|
-
padding: "
|
|
3511
|
+
padding: "6px 8px 2px",
|
|
3512
|
+
background: "transparent"
|
|
3279
3513
|
});
|
|
3280
3514
|
if (container.parentNode) container.parentNode.insertBefore(footer, container.nextSibling);
|
|
3281
3515
|
else container.appendChild(footer);
|
|
@@ -3735,6 +3969,84 @@ function createDiagram(opts) {
|
|
|
3735
3969
|
}
|
|
3736
3970
|
diagram.seek(target);
|
|
3737
3971
|
},
|
|
3972
|
+
setTheme(theme) {
|
|
3973
|
+
const newTheme = typeof theme === "string" ? resolveTheme(theme) : theme;
|
|
3974
|
+
plan.theme = newTheme;
|
|
3975
|
+
applyThemeToScene(scene, newTheme);
|
|
3976
|
+
if (footer) {
|
|
3977
|
+
applyThemeVariables(footer, newTheme);
|
|
3978
|
+
}
|
|
3979
|
+
for (const node of plan.nodes) {
|
|
3980
|
+
const el = nodeEls.get(node.id);
|
|
3981
|
+
if (el) {
|
|
3982
|
+
if (newTheme.flatCards) {
|
|
3983
|
+
el.style.setProperty("--md-shadow", "transparent");
|
|
3984
|
+
} else {
|
|
3985
|
+
el.style.removeProperty("--md-shadow");
|
|
3986
|
+
}
|
|
3987
|
+
if (newTheme.accentTint) {
|
|
3988
|
+
el.style.setProperty("--md-accent-tint", newTheme.accentTint);
|
|
3989
|
+
} else {
|
|
3990
|
+
el.style.removeProperty("--md-accent-tint");
|
|
3991
|
+
}
|
|
3992
|
+
const roleColor = newTheme.roles[node.role] ?? newTheme.accent;
|
|
3993
|
+
el.style.setProperty("--md-role-color", roleColor);
|
|
3994
|
+
applyDeclaredNodeStyle(el, node.style);
|
|
3995
|
+
}
|
|
3996
|
+
}
|
|
3997
|
+
const structuralSvg = structuralEdgeHost.querySelector("svg[data-markdy-edge-layer='1']");
|
|
3998
|
+
if (structuralSvg) {
|
|
3999
|
+
updateEdgeLayerTheme(structuralSvg, edgeRuntimes, newTheme, edgeSceneId);
|
|
4000
|
+
}
|
|
4001
|
+
const cameraSvg = cameraLayer.querySelector("svg[data-markdy-edge-layer='1']");
|
|
4002
|
+
if (cameraSvg) {
|
|
4003
|
+
updateEdgeLayerTheme(cameraSvg, edgeRuntimes, newTheme, edgeSceneId);
|
|
4004
|
+
}
|
|
4005
|
+
if (plan.treeBuses && plan.treeBuses.length > 0) {
|
|
4006
|
+
treeLayer.replaceChildren();
|
|
4007
|
+
mountTreeBuses(treeLayer, plan.treeBuses, newTheme);
|
|
4008
|
+
}
|
|
4009
|
+
if (plan.diagramType === "constellation" || plan.diagramType === "radar" || plan.diagramType === "timeline") {
|
|
4010
|
+
constellationLayer.replaceChildren();
|
|
4011
|
+
if (plan.diagramType === "constellation") {
|
|
4012
|
+
mountConstellationLayer(
|
|
4013
|
+
constellationLayer,
|
|
4014
|
+
plan.nodes,
|
|
4015
|
+
newTheme,
|
|
4016
|
+
{ width: plan.meta.width, height: plan.meta.height }
|
|
4017
|
+
);
|
|
4018
|
+
} else if (plan.diagramType === "radar") {
|
|
4019
|
+
mountRadarLayer(
|
|
4020
|
+
constellationLayer,
|
|
4021
|
+
plan.nodes,
|
|
4022
|
+
newTheme,
|
|
4023
|
+
{ width: plan.meta.width, height: plan.meta.height }
|
|
4024
|
+
);
|
|
4025
|
+
} else if (plan.diagramType === "timeline") {
|
|
4026
|
+
mountTimelineLayer(
|
|
4027
|
+
constellationLayer,
|
|
4028
|
+
plan.nodes,
|
|
4029
|
+
newTheme,
|
|
4030
|
+
{ width: plan.meta.width, height: plan.meta.height }
|
|
4031
|
+
);
|
|
4032
|
+
}
|
|
4033
|
+
}
|
|
4034
|
+
if (plan.diagramType === "sequence") {
|
|
4035
|
+
updateSequenceLayerTheme(sequenceLayer, newTheme);
|
|
4036
|
+
}
|
|
4037
|
+
if (plan.groupBoundaries && plan.groupBoundaries.length > 0) {
|
|
4038
|
+
groupLayer.replaceChildren();
|
|
4039
|
+
mountGroupBoundaries(groupLayer, plan.groupBoundaries, newTheme);
|
|
4040
|
+
}
|
|
4041
|
+
if (plan.annotations && plan.annotations.length > 0) {
|
|
4042
|
+
annotationLayer.replaceChildren();
|
|
4043
|
+
mountAnnotations(annotationLayer, plan.annotations, plan.nodes, newTheme, {
|
|
4044
|
+
width: plan.meta.width,
|
|
4045
|
+
height: plan.meta.height
|
|
4046
|
+
});
|
|
4047
|
+
}
|
|
4048
|
+
if (totalDurationMs > 0) updateProgressBar(sceneMs / totalDurationMs);
|
|
4049
|
+
},
|
|
3738
4050
|
destroy() {
|
|
3739
4051
|
diagram.pause();
|
|
3740
4052
|
if (keyboardShortcuts && typeof window !== "undefined") {
|
|
@@ -3901,6 +4213,7 @@ function createDiagram(opts) {
|
|
|
3901
4213
|
const targetThemes = isDark ? lightThemes : darkThemes;
|
|
3902
4214
|
const nextTheme = targetThemes[Math.floor(Math.random() * targetThemes.length)];
|
|
3903
4215
|
flashControlLabel(button, nextTheme);
|
|
4216
|
+
diagram.setTheme(nextTheme);
|
|
3904
4217
|
container.dispatchEvent(
|
|
3905
4218
|
new CustomEvent("markdy-theme-switch", {
|
|
3906
4219
|
bubbles: true,
|
|
@@ -4004,7 +4317,8 @@ function createDiagram(opts) {
|
|
|
4004
4317
|
body.appendChild(pre);
|
|
4005
4318
|
panel.append(header, body);
|
|
4006
4319
|
overlay.appendChild(panel);
|
|
4007
|
-
document.body
|
|
4320
|
+
const mountHost = document.fullscreenElement ?? document.body;
|
|
4321
|
+
mountHost.appendChild(overlay);
|
|
4008
4322
|
closeBtn.focus();
|
|
4009
4323
|
let closing = false;
|
|
4010
4324
|
function removePanel() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@markdy/renderer-dom",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.21",
|
|
4
4
|
"description": "Browser renderer for diagram-native animated MarkdyScript architecture diagrams, built on the Web Animations API.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -45,14 +45,14 @@
|
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
47
|
"html2canvas": "^1.4.1",
|
|
48
|
-
"@markdy/core": "1.0.
|
|
48
|
+
"@markdy/core": "1.0.21"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"jsdom": "^29.1.1",
|
|
52
52
|
"tsup": "^8.5.1",
|
|
53
53
|
"typescript": "^5.9.3",
|
|
54
54
|
"vitest": "^4.1.7",
|
|
55
|
-
"@markdy/stdlib-systems": "1.0.
|
|
55
|
+
"@markdy/stdlib-systems": "1.0.21"
|
|
56
56
|
},
|
|
57
57
|
"scripts": {
|
|
58
58
|
"build": "tsup",
|