@markdy/renderer-dom 0.8.19 → 0.8.20

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 CHANGED
@@ -70,18 +70,21 @@ diagram.destroy(); // clean up DOM + cancel animations
70
70
  |---|---|---|---|
71
71
  | `container` | `HTMLElement` | *(required)* | DOM element to mount the scene into |
72
72
  | `code` | `string` | *(required)* | MarkdyScript source code |
73
- | `autoplay` | `boolean` | `true` | Start playing immediately |
74
- | `loop` | `boolean` | `true` | Loop the animation when it reaches the end |
75
- | `copyright` | `boolean` | `true` | Show a small "Powered by Markdy" badge below the animation |
76
- | `progressBar` | `boolean` | `true` | Deprecated compatibility flag for the rainbow scene-boundary progress bar |
77
- | `sceneBoundaryProgress` | `boolean` | `progressBar ?? true` | Preferred flag for the rainbow scene-boundary progress bar |
78
- | `playbackRate` | `number` | `1` | Normalized timeline speed multiplier; `1` is Markdy's normal pace |
79
- | `interactiveViewport` | `boolean` | `false` | Enable wheel zoom and drag pan on the rendered viewport |
80
- | `controls` | `boolean` | `false` | Show a compact toolbar with play/pause, restart, speed, and view reset controls; also enables viewport interaction |
73
+ | `autoplay` | `boolean` | `plan.meta.autoplay ?? true` | Start playing immediately |
74
+ | `loop` | `boolean` | `plan.meta.loop ?? true` | Loop the animation when it reaches the end |
75
+ | `copyright` | `boolean` | `plan.meta.copyright ?? true` | Show a small "Powered by Markdy" badge below the animation |
76
+ | `progressBar` | `boolean \| string` | `true` | Deprecated compatibility flag for the scene-boundary progress bar |
77
+ | `sceneBoundaryProgress` | `boolean \| string` | `true` | Show boundary progress bar, or pass a custom color/gradient string |
78
+ | `progressColor` | `string` | `plan.meta.progressColor ?? "rainbow"` | Custom progress bar color (e.g. `"#3b82f6"`) or gradient (e.g. `"#ec4899, #8b5cf6"`) |
79
+ | `playbackRate` | `number` | `plan.meta.playbackRate ?? 1` | Normalized timeline speed multiplier; `1` is Markdy's normal pace |
80
+ | `interactiveViewport` | `boolean` | `controls \|\| plan.meta.interactiveViewport` | Enable wheel zoom and drag pan on the rendered viewport |
81
+ | `controls` | `boolean` | `plan.meta.controls ?? false` | Show left-aligned footer controls toolbar (play/pause, restart, speed, reset view); also enables viewport interaction |
81
82
  | `onWarning` | `(warning: Diagnostic) => void` | `console.warn` | Called for each soft parse warning |
82
83
  | `onTimeUpdate` | `(seconds: number, durationSeconds: number) => void` | — | Called whenever playback or seek changes the current time |
83
84
  | `onPlayStateChange` | `(playing: boolean) => void` | — | Called when playback starts or pauses |
84
85
 
86
+ > **Note:** Directives declared inside the MarkdyScript code (e.g. `controls true`, `interactive true`, `progressColor "#3b82f6"`) apply automatically if the corresponding JavaScript option is omitted (`undefined`). Options passed to `createDiagram()` override the in-script declarations.
87
+
85
88
  ### `Diagram`
86
89
 
87
90
  | Method | Description |
package/dist/index.d.ts CHANGED
@@ -17,9 +17,13 @@ interface DiagramOptions {
17
17
  */
18
18
  assets?: Record<string, string>;
19
19
  /** @deprecated Prefer sceneBoundaryProgress. */
20
- progressBar?: boolean;
21
- /** Show rainbow progress around scene boundary. Defaults to true. */
22
- sceneBoundaryProgress?: boolean;
20
+ progressBar?: boolean | string;
21
+ /** Show rainbow progress around scene boundary, or specify a custom color/gradient. Defaults to true. */
22
+ sceneBoundaryProgress?: boolean | string;
23
+ /** Custom progress bar color or gradient. Defaults to rainbow. */
24
+ progressColor?: string;
25
+ /** @deprecated Prefer progressColor. */
26
+ progressBarColor?: string;
23
27
  /** Playback speed multiplier. Defaults to 1, where 1 is Markdy's normal pace. */
24
28
  playbackRate?: number;
25
29
  /** Enable wheel zoom and drag pan on the rendered viewport. Defaults to false. */
package/dist/index.js CHANGED
@@ -1769,6 +1769,34 @@ function ensureSceneStyles(doc) {
1769
1769
  transform: translateY(8px);
1770
1770
  will-change: opacity, transform;
1771
1771
  }
1772
+ .markdy-footer {
1773
+ font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
1774
+ }
1775
+ .markdy-controls button {
1776
+ touch-action: manipulation;
1777
+ user-select: none;
1778
+ -webkit-user-select: none;
1779
+ transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease, transform 0.05s ease;
1780
+ }
1781
+ .markdy-controls button:hover:not([aria-pressed="true"]) {
1782
+ background: rgba(241, 245, 249, 1);
1783
+ color: #1e293b;
1784
+ border-color: rgba(100, 116, 139, 0.6);
1785
+ }
1786
+ .markdy-controls button:focus-visible {
1787
+ outline: 2px solid #3b82f6;
1788
+ outline-offset: 1px;
1789
+ }
1790
+ .markdy-controls button:active {
1791
+ transform: scale(0.96);
1792
+ }
1793
+ .markdy-footer a {
1794
+ transition: opacity 0.15s ease, color 0.15s ease;
1795
+ }
1796
+ .markdy-footer a:hover {
1797
+ opacity: 1 !important;
1798
+ color: #64748b !important;
1799
+ }
1772
1800
  `;
1773
1801
  doc.head.appendChild(style);
1774
1802
  }
@@ -1856,24 +1884,36 @@ function createDiagram(opts) {
1856
1884
  const {
1857
1885
  container,
1858
1886
  code,
1859
- autoplay = true,
1860
- loop = true,
1861
- copyright = true,
1862
1887
  assets,
1863
1888
  progressBar,
1864
1889
  sceneBoundaryProgress,
1865
- playbackRate: initialPlaybackRate = DEFAULT_PLAYBACK_RATE,
1866
- controls = false,
1867
- interactiveViewport = controls,
1890
+ progressColor,
1891
+ progressBarColor,
1892
+ playbackRate: initialPlaybackRate,
1893
+ controls: explicitControls,
1894
+ interactiveViewport: explicitInteractiveViewport,
1895
+ autoplay: explicitAutoplay,
1896
+ loop: explicitLoop,
1897
+ copyright: explicitCopyright,
1868
1898
  onWarning = (w) => console.warn(`[markdy] line ${w.line}: ${w.message}`),
1869
1899
  onTimeUpdate,
1870
1900
  onPlayStateChange
1871
1901
  } = opts;
1872
- const showSceneBoundaryProgress = sceneBoundaryProgress ?? progressBar ?? true;
1873
1902
  const { ast, plan } = parseAndCompile(code);
1874
1903
  for (const w of ast.diagnostics) {
1875
1904
  if (w.severity === "warning") onWarning(w);
1876
1905
  }
1906
+ const controls = explicitControls ?? plan.meta.controls ?? false;
1907
+ const interactiveViewport = explicitInteractiveViewport ?? (explicitControls !== void 0 ? explicitControls : plan.meta.interactiveViewport ?? plan.meta.controls ?? false);
1908
+ const autoplay = explicitAutoplay ?? plan.meta.autoplay ?? true;
1909
+ const loop = explicitLoop ?? plan.meta.loop ?? true;
1910
+ const copyright = explicitCopyright ?? plan.meta.copyright ?? true;
1911
+ const rawPlaybackRate = initialPlaybackRate ?? plan.meta.playbackRate ?? DEFAULT_PLAYBACK_RATE;
1912
+ let playbackRate = Number.isFinite(rawPlaybackRate) && rawPlaybackRate > 0 ? rawPlaybackRate : DEFAULT_PLAYBACK_RATE;
1913
+ const showSceneBoundaryProgress = sceneBoundaryProgress === false || sceneBoundaryProgress === void 0 && progressBar === false ? false : plan.meta.progressColor === "none" ? false : true;
1914
+ const rawColor = progressColor ?? progressBarColor ?? (typeof sceneBoundaryProgress === "string" && sceneBoundaryProgress !== "true" && sceneBoundaryProgress !== "false" ? sceneBoundaryProgress : typeof progressBar === "string" && progressBar !== "true" && progressBar !== "false" ? progressBar : void 0) ?? (plan.meta.progressColor && plan.meta.progressColor !== "none" ? plan.meta.progressColor : void 0);
1915
+ const customColor = rawColor && rawColor.trim() !== "rainbow" ? rawColor.trim() : null;
1916
+ const DEFAULT_RAINBOW = "hsl(0,90%,60%), hsl(45,90%,55%), hsl(90,80%,50%), hsl(180,80%,50%), hsl(270,80%,55%), hsl(330,90%,60%)";
1877
1917
  const totalDurationMs = plan.duration * 1e3;
1878
1918
  const durationSeconds = plan.duration;
1879
1919
  const viewport = document.createElement("div");
@@ -1901,8 +1941,8 @@ function createDiagram(opts) {
1901
1941
  function updateProgressBar(pct) {
1902
1942
  if (!progressEl) return;
1903
1943
  const deg = pct * 360;
1904
- const rainbow = "hsl(0,90%,60%), hsl(45,90%,55%), hsl(90,80%,50%), hsl(180,80%,50%), hsl(270,80%,55%), hsl(330,90%,60%)";
1905
- progressEl.style.background = `conic-gradient(from ${tlAngleNorm}deg, ${rainbow} ${deg}deg, transparent ${deg}deg)`;
1944
+ const colorStops = customColor ? customColor.includes(",") ? customColor : `${customColor} 0deg, ${customColor}` : DEFAULT_RAINBOW;
1945
+ progressEl.style.background = `conic-gradient(from ${tlAngleNorm}deg, ${colorStops} ${deg}deg, transparent ${deg}deg)`;
1906
1946
  progressEl.style.mask = "linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0)";
1907
1947
  progressEl.style.webkitMask = progressEl.style.mask;
1908
1948
  progressEl.style.maskComposite = "exclude";
@@ -1917,7 +1957,7 @@ function createDiagram(opts) {
1917
1957
  Object.assign(footer.style, {
1918
1958
  display: "flex",
1919
1959
  alignItems: "center",
1920
- justifyContent: "flex-end",
1960
+ justifyContent: "space-between",
1921
1961
  flexWrap: "wrap",
1922
1962
  gap: "6px",
1923
1963
  width: "100%",
@@ -1944,7 +1984,8 @@ function createDiagram(opts) {
1944
1984
  color: "#999",
1945
1985
  textDecoration: "none",
1946
1986
  padding: "0",
1947
- opacity: "0.7"
1987
+ opacity: "0.7",
1988
+ marginLeft: "auto"
1948
1989
  });
1949
1990
  ensureFooter().appendChild(badge);
1950
1991
  }
@@ -2080,7 +2121,6 @@ function createDiagram(opts) {
2080
2121
  anim.currentTime = 0;
2081
2122
  }
2082
2123
  let sceneMs = 0;
2083
- let playbackRate = Number.isFinite(initialPlaybackRate) && initialPlaybackRate > 0 ? initialPlaybackRate : DEFAULT_PLAYBACK_RATE;
2084
2124
  let lastRafTs = null;
2085
2125
  let isPlaying = false;
2086
2126
  let rafId = null;
@@ -2158,15 +2198,19 @@ function createDiagram(opts) {
2158
2198
  }
2159
2199
  function syncControls() {
2160
2200
  if (controlsPlayButton) {
2161
- controlsPlayButton.textContent = isPlaying ? "Pause" : "Play";
2162
- controlsPlayButton.setAttribute("aria-label", isPlaying ? "Pause diagram" : "Play diagram");
2201
+ const playing = isPlaying;
2202
+ controlsPlayButton.textContent = playing ? "Pause" : "Play";
2203
+ const playLabel = playing ? "Pause diagram" : "Play diagram";
2204
+ controlsPlayButton.setAttribute("aria-label", playLabel);
2205
+ controlsPlayButton.title = playLabel;
2163
2206
  }
2164
2207
  for (const button of controlsRateButtons) {
2165
2208
  const rate = Number(button.dataset.rate ?? "1");
2166
2209
  const active = Math.abs(rate - playbackRate) < 1e-3;
2167
2210
  button.setAttribute("aria-pressed", active ? "true" : "false");
2168
- button.style.background = active ? "rgba(15, 23, 42, 0.92)" : "rgba(255, 255, 255, 0.92)";
2169
- button.style.color = active ? "#ffffff" : "#111827";
2211
+ button.style.background = active ? "#1e293b" : "rgba(248, 250, 252, 0.92)";
2212
+ button.style.color = active ? "#ffffff" : "#475569";
2213
+ button.style.borderColor = active ? "#0f172a" : "rgba(148, 163, 184, 0.55)";
2170
2214
  }
2171
2215
  }
2172
2216
  function emitPlayStateChange(playing) {
@@ -2288,7 +2332,7 @@ function createDiagram(opts) {
2288
2332
  position: "static",
2289
2333
  display: "flex",
2290
2334
  alignItems: "center",
2291
- justifyContent: "flex-end",
2335
+ justifyContent: "flex-start",
2292
2336
  flexWrap: "wrap",
2293
2337
  gap: "4px",
2294
2338
  maxWidth: "100%",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@markdy/renderer-dom",
3
- "version": "0.8.19",
3
+ "version": "0.8.20",
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",
@@ -44,14 +44,14 @@
44
44
  "access": "public"
45
45
  },
46
46
  "dependencies": {
47
- "@markdy/core": "0.8.19"
47
+ "@markdy/core": "0.8.20"
48
48
  },
49
49
  "devDependencies": {
50
50
  "jsdom": "^29.1.1",
51
51
  "tsup": "^8.5.1",
52
52
  "typescript": "^5.9.3",
53
53
  "vitest": "^4.1.7",
54
- "@markdy/stdlib-systems": "0.8.19"
54
+ "@markdy/stdlib-systems": "0.8.20"
55
55
  },
56
56
  "scripts": {
57
57
  "build": "tsup",