@markdy/renderer-dom 1.0.11 → 1.0.13

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 (2) hide show
  1. package/dist/index.js +207 -29
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -1636,6 +1636,16 @@ function ensureNodeStyles(doc) {
1636
1636
  transform: rotate(0deg);
1637
1637
  clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%);
1638
1638
  }
1639
+ .markdy-node[data-shape="diamond"] .markdy-node__body {
1640
+ justify-content: center;
1641
+ padding: 6px 16%;
1642
+ text-align: center;
1643
+ }
1644
+ .markdy-node[data-shape="diamond"] .markdy-node__label {
1645
+ flex: 0 1 auto;
1646
+ line-height: 1.18;
1647
+ text-align: center;
1648
+ }
1639
1649
  .markdy-node[data-shape="pill"] {
1640
1650
  border-radius: 999px;
1641
1651
  min-height: 54px;
@@ -2100,11 +2110,11 @@ function createNodeEl(node, theme, assets) {
2100
2110
  el.setAttribute("aria-label", el.title);
2101
2111
  const body = document.createElement("div");
2102
2112
  body.className = "markdy-node__body";
2103
- const icon = createNodeMediaEl(document, node, assets);
2104
2113
  const label = document.createElement("div");
2105
2114
  label.className = "markdy-node__label";
2106
2115
  label.textContent = node.label;
2107
- body.append(icon, label);
2116
+ if (node.shape !== "diamond") body.append(createNodeMediaEl(document, node, assets));
2117
+ body.append(label);
2108
2118
  const value = node.props?.value ?? node.props?.metric;
2109
2119
  if (value !== void 0 && value !== null) {
2110
2120
  const valueEl = document.createElement("div");
@@ -2494,24 +2504,178 @@ function ensureSceneStyles(doc) {
2494
2504
  }
2495
2505
  .markdy-footer {
2496
2506
  font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
2507
+ width: 100%;
2508
+ box-sizing: border-box;
2509
+ }
2510
+ .markdy-controls {
2511
+ display: flex;
2512
+ align-items: center;
2513
+ flex-wrap: nowrap;
2514
+ gap: 2.5px;
2515
+ max-width: 100%;
2516
+ overflow-x: auto;
2517
+ scrollbar-width: none;
2518
+ }
2519
+ .markdy-controls::-webkit-scrollbar {
2520
+ display: none;
2521
+ }
2522
+ @media (max-width: 640px) {
2523
+ .markdy-controls {
2524
+ flex-wrap: wrap;
2525
+ justify-content: center;
2526
+ gap: 3px;
2527
+ }
2497
2528
  }
2498
2529
  .markdy-controls button {
2530
+ appearance: none;
2499
2531
  touch-action: manipulation;
2500
2532
  user-select: none;
2501
2533
  -webkit-user-select: none;
2502
- transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease, transform 0.05s ease;
2534
+ border: 1px solid var(--md-control-border, rgba(148, 163, 184, 0.45));
2535
+ border-radius: 5px;
2536
+ background: var(--md-control-bg, rgba(248, 250, 252, 0.92));
2537
+ color: var(--md-control-text, #334155);
2538
+ cursor: pointer;
2539
+ font: 600 10px/1.2 system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
2540
+ padding: 2.5px 5.5px;
2541
+ min-height: 23px;
2542
+ min-width: 22px;
2543
+ display: inline-flex;
2544
+ align-items: center;
2545
+ justify-content: center;
2546
+ gap: 2px;
2547
+ white-space: nowrap;
2548
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.03);
2549
+ transition: all 0.15s cubic-bezier(0.4, 0, 0.2, 1);
2503
2550
  }
2504
2551
  .markdy-controls button:hover:not([aria-pressed="true"]) {
2505
- background: rgba(241, 245, 249, 1);
2506
- color: #1e293b;
2507
- border-color: rgba(100, 116, 139, 0.6);
2552
+ background: var(--md-control-hover-bg, #ffffff);
2553
+ color: var(--md-control-hover-text, #0f172a);
2554
+ border-color: var(--md-control-hover-border, #94a3b8);
2555
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);
2556
+ }
2557
+ .markdy-controls button[aria-pressed="true"] {
2558
+ background: #0f172a !important;
2559
+ color: #ffffff !important;
2560
+ border-color: #0f172a !important;
2561
+ box-shadow: 0 1px 3px rgba(15, 23, 42, 0.25) !important;
2508
2562
  }
2509
2563
  .markdy-controls button:focus-visible {
2510
2564
  outline: 2px solid #3b82f6;
2511
2565
  outline-offset: 1px;
2512
2566
  }
2513
2567
  .markdy-controls button:active {
2514
- transform: scale(0.96);
2568
+ transform: scale(0.95);
2569
+ }
2570
+ .markdy-control-play::before { content: "\u25B6"; font-size: 7.5px; margin-right: 1px; }
2571
+ .markdy-control-play[aria-label*="Pause"]::before,
2572
+ .markdy-control-play[title*="Pause"]::before { content: "\u23F8"; font-size: 7.5px; margin-right: 1px; }
2573
+ .markdy-control-restart::before { content: "\u21BA"; font-size: 10px; font-weight: 700; margin-right: 1px; }
2574
+ .markdy-control-prev-beat::before { content: "\u23EE"; font-size: 7.5px; margin-right: 1px; }
2575
+ .markdy-control-next-beat::before { content: "\u23ED"; font-size: 7.5px; margin-right: 1px; }
2576
+ .markdy-control-fit::before { content: "\u26F6"; font-size: 8.5px; margin-right: 1px; }
2577
+ .markdy-control-reset-view::before { content: "\u2299"; font-size: 8.5px; margin-right: 1px; }
2578
+ .markdy-control-fullscreen::before { content: "\u26F6"; font-size: 8.5px; margin-right: 1px; }
2579
+ .markdy-control-svg::before { content: "\u{1F4E5}"; font-size: 8.5px; margin-right: 1px; }
2580
+ .markdy-control-share::before { content: "\u{1F517}"; font-size: 8.5px; margin-right: 1px; }
2581
+ .markdy-control-rate {
2582
+ font-family: "JetBrains Mono", monospace, system-ui;
2583
+ font-size: 9px;
2584
+ font-weight: 600;
2585
+ padding: 2px 4.5px;
2586
+ min-width: 18px;
2587
+ min-height: 21px;
2588
+ }
2589
+ .markdy-control-seek {
2590
+ appearance: none;
2591
+ -webkit-appearance: none;
2592
+ background: transparent;
2593
+ cursor: pointer;
2594
+ height: 20px;
2595
+ width: clamp(35px, 5vw, 65px);
2596
+ min-width: 35px;
2597
+ max-width: 70px;
2598
+ margin: 0 1px;
2599
+ }
2600
+ .markdy-control-seek:focus {
2601
+ outline: none;
2602
+ }
2603
+ .markdy-control-seek::-webkit-slider-runnable-track {
2604
+ width: 100%;
2605
+ height: 4.5px;
2606
+ background: rgba(148, 163, 184, 0.35);
2607
+ border-radius: 9999px;
2608
+ transition: background 0.15s ease;
2609
+ }
2610
+ .markdy-control-seek:hover::-webkit-slider-runnable-track {
2611
+ background: rgba(148, 163, 184, 0.55);
2612
+ }
2613
+ .markdy-control-seek::-webkit-slider-thumb {
2614
+ -webkit-appearance: none;
2615
+ height: 13px;
2616
+ width: 13px;
2617
+ border-radius: 50%;
2618
+ background: #2563eb;
2619
+ border: 2px solid #ffffff;
2620
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
2621
+ margin-top: -4.25px;
2622
+ cursor: grab;
2623
+ transition: transform 0.1s ease, background 0.15s ease;
2624
+ }
2625
+ .markdy-control-seek:active::-webkit-slider-thumb {
2626
+ cursor: grabbing;
2627
+ transform: scale(1.2);
2628
+ background: #1d4ed8;
2629
+ }
2630
+ .markdy-control-seek::-moz-range-track {
2631
+ width: 100%;
2632
+ height: 4.5px;
2633
+ background: rgba(148, 163, 184, 0.35);
2634
+ border-radius: 9999px;
2635
+ }
2636
+ .markdy-control-seek::-moz-range-thumb {
2637
+ height: 13px;
2638
+ width: 13px;
2639
+ border-radius: 50%;
2640
+ background: #2563eb;
2641
+ border: 2px solid #ffffff;
2642
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
2643
+ cursor: grab;
2644
+ }
2645
+
2646
+ [data-markdy-theme="midnight"] .markdy-controls button,
2647
+ [data-markdy-theme="blueprint"] .markdy-controls button,
2648
+ [data-markdy-theme="terminal"] .markdy-controls button,
2649
+ [data-markdy-theme="graphite"] .markdy-controls button,
2650
+ [data-markdy-theme="nebula"] .markdy-controls button,
2651
+ :root[data-theme="dark"] .markdy-controls button,
2652
+ .theme-dark .markdy-controls button {
2653
+ background: var(--md-control-bg, rgba(30, 41, 59, 0.85));
2654
+ border-color: var(--md-control-border, rgba(71, 85, 105, 0.55));
2655
+ color: var(--md-control-text, #cbd5e1);
2656
+ }
2657
+ [data-markdy-theme="midnight"] .markdy-controls button:hover:not([aria-pressed="true"]),
2658
+ [data-markdy-theme="blueprint"] .markdy-controls button:hover:not([aria-pressed="true"]),
2659
+ [data-markdy-theme="terminal"] .markdy-controls button:hover:not([aria-pressed="true"]),
2660
+ [data-markdy-theme="graphite"] .markdy-controls button:hover:not([aria-pressed="true"]),
2661
+ [data-markdy-theme="nebula"] .markdy-controls button:hover:not([aria-pressed="true"]),
2662
+ :root[data-theme="dark"] .markdy-controls button:hover:not([aria-pressed="true"]),
2663
+ .theme-dark .markdy-controls button:hover:not([aria-pressed="true"]) {
2664
+ background: rgba(51, 65, 85, 0.95);
2665
+ color: #f8fafc;
2666
+ border-color: #94a3b8;
2667
+ }
2668
+ [data-markdy-theme="midnight"] .markdy-controls button[aria-pressed="true"],
2669
+ [data-markdy-theme="blueprint"] .markdy-controls button[aria-pressed="true"],
2670
+ [data-markdy-theme="terminal"] .markdy-controls button[aria-pressed="true"],
2671
+ [data-markdy-theme="graphite"] .markdy-controls button[aria-pressed="true"],
2672
+ [data-markdy-theme="nebula"] .markdy-controls button[aria-pressed="true"],
2673
+ :root[data-theme="dark"] .markdy-controls button[aria-pressed="true"],
2674
+ .theme-dark .markdy-controls button[aria-pressed="true"] {
2675
+ background: #3b82f6 !important;
2676
+ color: #ffffff !important;
2677
+ border-color: #3b82f6 !important;
2678
+ box-shadow: 0 0 10px rgba(59, 130, 246, 0.5) !important;
2515
2679
  }
2516
2680
  .markdy-footer a {
2517
2681
  transition: opacity 0.15s ease, color 0.15s ease;
@@ -2683,6 +2847,7 @@ function createDiagram(opts) {
2683
2847
  speeds: speedOptions,
2684
2848
  fit: fitViewButton,
2685
2849
  resetView: resetViewButton,
2850
+ fullscreen: fullscreenButton,
2686
2851
  svg: svgButton,
2687
2852
  share: shareButton
2688
2853
  } = player.controls;
@@ -2818,7 +2983,7 @@ function createDiagram(opts) {
2818
2983
  Object.assign(structuralEdgeHost.style, {
2819
2984
  position: "absolute",
2820
2985
  inset: "0",
2821
- zIndex: "45",
2986
+ zIndex: "55",
2822
2987
  pointerEvents: "none"
2823
2988
  });
2824
2989
  cameraLayer.appendChild(structuralEdgeHost);
@@ -3101,16 +3266,10 @@ function createDiagram(opts) {
3101
3266
  const rate = Number(button.dataset.rate ?? "1");
3102
3267
  const active = Math.abs(rate - playbackRate) < 1e-3;
3103
3268
  button.setAttribute("aria-pressed", active ? "true" : "false");
3104
- button.style.background = active ? "#1e293b" : "rgba(248, 250, 252, 0.92)";
3105
- button.style.color = active ? "#ffffff" : "#475569";
3106
- button.style.borderColor = active ? "#0f172a" : "rgba(148, 163, 184, 0.55)";
3107
3269
  }
3108
3270
  if (controlsSeekBar) controlsSeekBar.value = String(sceneMs / 1e3);
3109
3271
  if (controlsFitButton) {
3110
3272
  controlsFitButton.setAttribute("aria-pressed", fitViewActive ? "true" : "false");
3111
- controlsFitButton.style.background = fitViewActive ? "#1e293b" : "rgba(248, 250, 252, 0.92)";
3112
- controlsFitButton.style.color = fitViewActive ? "#ffffff" : "#475569";
3113
- controlsFitButton.style.borderColor = fitViewActive ? "#0f172a" : "rgba(148, 163, 184, 0.55)";
3114
3273
  }
3115
3274
  }
3116
3275
  function emitPlayStateChange(playing) {
@@ -3224,19 +3383,6 @@ function createDiagram(opts) {
3224
3383
  button.textContent = label;
3225
3384
  button.setAttribute("aria-label", ariaLabel);
3226
3385
  button.title = ariaLabel;
3227
- Object.assign(button.style, {
3228
- appearance: "none",
3229
- border: "1px solid rgba(148, 163, 184, 0.55)",
3230
- borderRadius: "5px",
3231
- background: "rgba(248, 250, 252, 0.92)",
3232
- color: "#475569",
3233
- cursor: "pointer",
3234
- font: "600 10px/1.1 system-ui, sans-serif",
3235
- padding: "4px 6px",
3236
- minWidth: "28px",
3237
- whiteSpace: "nowrap",
3238
- boxShadow: "none"
3239
- });
3240
3386
  return button;
3241
3387
  }
3242
3388
  function mountPlayControl(toolbar) {
@@ -3365,6 +3511,39 @@ function createDiagram(opts) {
3365
3511
  button.addEventListener("click", resetViewportTransform);
3366
3512
  toolbar.appendChild(button);
3367
3513
  }
3514
+ function mountFullscreenControl(toolbar) {
3515
+ if (!fullscreenButton) return;
3516
+ const button = makeControlButton("Full", "Toggle fullscreen view");
3517
+ button.className = "markdy-control-fullscreen";
3518
+ button.setAttribute("aria-pressed", "false");
3519
+ const host = container.parentElement ?? container;
3520
+ function syncFullscreenState() {
3521
+ const isFull = document.fullscreenElement === host || document.fullscreenElement === container || document.fullscreenElement === viewport;
3522
+ button.setAttribute("aria-pressed", isFull ? "true" : "false");
3523
+ button.title = isFull ? "Exit fullscreen" : "Toggle fullscreen view";
3524
+ }
3525
+ button.addEventListener("click", async () => {
3526
+ try {
3527
+ if (!document.fullscreenElement) {
3528
+ if (host.requestFullscreen) {
3529
+ await host.requestFullscreen();
3530
+ } else if (host.webkitRequestFullscreen) {
3531
+ await host.webkitRequestFullscreen();
3532
+ }
3533
+ } else {
3534
+ if (document.exitFullscreen) {
3535
+ await document.exitFullscreen();
3536
+ } else if (document.webkitExitFullscreen) {
3537
+ await document.webkitExitFullscreen();
3538
+ }
3539
+ }
3540
+ } catch (err) {
3541
+ onWarning({ severity: "warning", message: `Fullscreen toggle failed: ${String(err)}`, line: 0 });
3542
+ }
3543
+ });
3544
+ document.addEventListener("fullscreenchange", syncFullscreenState);
3545
+ toolbar.appendChild(button);
3546
+ }
3368
3547
  function handleKeyDown(event) {
3369
3548
  const target = event.target;
3370
3549
  if (target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement || target instanceof HTMLSelectElement || target?.isContentEditable) {
@@ -3402,8 +3581,6 @@ function createDiagram(opts) {
3402
3581
  display: "flex",
3403
3582
  alignItems: "center",
3404
3583
  justifyContent: "flex-start",
3405
- flexWrap: "wrap",
3406
- gap: "4px",
3407
3584
  maxWidth: "100%",
3408
3585
  padding: "0",
3409
3586
  border: "0",
@@ -3425,6 +3602,7 @@ function createDiagram(opts) {
3425
3602
  mountSpeedControls(toolbar);
3426
3603
  mountFitControl(toolbar);
3427
3604
  mountResetViewControl(toolbar);
3605
+ mountFullscreenControl(toolbar);
3428
3606
  mountSvgControl(toolbar);
3429
3607
  mountShareControl(toolbar);
3430
3608
  ensureFooter().insertBefore(toolbar, badge ?? null);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@markdy/renderer-dom",
3
- "version": "1.0.11",
3
+ "version": "1.0.13",
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.11"
48
+ "@markdy/core": "1.0.13"
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.11"
55
+ "@markdy/stdlib-systems": "1.0.13"
56
56
  },
57
57
  "scripts": {
58
58
  "build": "tsup",