Files
learnharness/components/artifacts/download.ts
T
amosblomqvist 4070cc7926 artifacts: demo scrollbar death, figure natural sizing + fullscreen, downloads, invert toggles (release polish 7)
- demo iframe: scrolling=no (the bridge auto-sizes; a scrollable iframe
  trapped the wheel) + content-box so the bridge height is the viewport
- figures: svgNaturalWidth hug + center (w-fit max-w-full mx-auto),
  full-width fallback for viewBox-only svgs
- fullscreen: MermaidOverlay figure mode (raw svg, white stage, invert
  carried); openFigure context; figureFocus rides the mermaid Esc layer
- downloads: figure.svg + <slug>.html (raw pre-bridge), shared download.ts
- invert: manual ContrastIcon toggle on both cards — invert(1)
  hue-rotate(180deg) on the white-bearing element, default off, no
  detection, no theme wiring (owner rulings 2026-10-07)

1433 tests green; live smoke passed (hug/center measured, filters verified,
downloads fired, Esc closed; wheel-chaining structurally sound)
2026-10-07 13:45:03 +03:00

33 lines
1.1 KiB
TypeScript

/**
* Artifact download helpers (release polish, 2026-10-07): the tiny
* save-a-blob seam shared by the demo + figure cards, plus the filename
* slug. The slug is pure (test-pinned); downloadFile touches the DOM and
* only runs on click.
*/
/** Slugify a demo title into a filename stem — lowercase, accents folded,
* runs of non-alphanumerics collapsed to "-", trimmed, capped at 64
* chars. Empty/fully-symbolic titles fall back to "demo". */
export function slugFilename(title: string): string {
const slug = title
.toLowerCase()
.normalize("NFKD")
.replace(/[\u0300-\u036f]/g, "")
.replace(/[^a-z0-9]+/g, "-")
.replace(/^-+|-+$/g, "")
.slice(0, 64);
return slug || "demo";
}
/** Save text as a downloaded file. The blob URL is revoked right after the
* click — Chromium keeps the download alive past the revoke. */
export function downloadFile(name: string, text: string, mime: string): void {
const blob = new Blob([text], { type: mime });
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = name;
a.click();
URL.revokeObjectURL(url);
}