T45 Website: native captures stand in where a browser cannot run, an OG image, no web notes

This commit is contained in:
ZacharyZhang-NY committed 2026-09-30 00:03:23 -04:00
1 parent 5550552e76
commit b4ad854508
68 files changed
+315 -155

No files matched your search

+7 -1
View File
@@ -1,5 +1,6 @@
import { all, chapter, chapters, esc, href, storyCount, type Chapter, type Story } from "./data";
import { icon } from "./icons";
import { isCaptured, native } from "./native";
import { preview } from "./preview";
/** Chapters on the left, a story or the index beside. */
@@ -22,7 +23,11 @@ export function components(main: HTMLElement, path: string[]): () => void {
}
document.title = `${story.title} · ${current.title} · Ely`;
body.innerHTML = detail(current, story);
return preview(body.querySelector<HTMLElement>(".live")!, current.slug, story.slug, story.title);
const live = body.querySelector<HTMLElement>(".live")!;
const shots = body.querySelector<HTMLElement>(".native")!;
if (isCaptured(current.slug, story.slug)) return native(live, current.slug, story.slug, story.title);
const [stopLive, stopShots] = [preview(live, current.slug, story.slug, story.title), native(shots, current.slug, story.slug, story.title)];
return () => (stopLive(), stopShots());
}
function sidebar(side: HTMLElement, current?: Chapter, story?: Story): void {
@@ -66,6 +71,7 @@ function detail(current: Chapter, story: Story): string {
<h1>${esc(story.title)}</h1>
<p class="names">${story.components.map(esc).join(" · ")}</p>
<div class="live"></div>
<div class="native"></div>
<nav class="pager" aria-label="More stories">${pager(prev, "prev", "Previous", icon("ArrowLeft"))}${pager(next, "next", "Next", icon("ArrowRight"))}</nav>
</article>`;
}
+33
View File
@@ -0,0 +1,33 @@
import shots from "./shots.json";
import { esc } from "./data";
import { mode, onMode, type Mode } from "./theme";
const captured = new Set<string>(shots.stories);
const windows: Record<string, string[]> = shots.windows;
/** Whether the site shows this story as a native capture. */
export function isCaptured(page: string, story: string): boolean {
return captured.has(`${page}/${story}`);
}
const src = (name: string, theme: Mode) => `/shots/${name}-${theme}.jpg`;
function figure(name: string, alt: string): string {
// Captures are at twice the pixels, drawn at their size.
return `<img class="shot" data-shot="${name}" srcset="${src(name, mode())} 2x" alt="${esc(alt)}" loading="lazy" />`;
}
/** Draws the story's capture, or the windows it opens, in the site's mode. */
export function native(host: HTMLElement, page: string, story: string, title: string): () => void {
const key = `${page}/${story}`;
if (captured.has(key)) {
host.innerHTML = `<p class="label">Native capture · macOS</p>${figure(`${page}--${story}`, `${title}, captured from the native gallery`)}`;
} else if (windows[key]) {
host.innerHTML = `<p class="label">The windows it opens, natively</p><div class="shots">${windows[key]
.map((name) => figure(name, `A window ${title} opens, captured natively`))
.join("")}</div>`;
} else {
return () => {};
}
return onMode((next) => host.querySelectorAll<HTMLImageElement>("img[data-shot]").forEach((img) => (img.srcset = `${src(img.dataset.shot!, next)} 2x`)));
}
+41
View File
@@ -0,0 +1,41 @@
{
"stories": [
"files/dragdropfiles",
"forms/fileinput-dropzone",
"forms/pathinput",
"media/imageupload",
"shell/dockbadge",
"shell/trayicon-traymenu",
"shell/windowdragregion",
"shell/windowresizeborder",
"terminal/terminal-terminaltabs-terminalsplit-terminaltoolbar-shellselector-terminalsearch-terminallink",
"theme/themeimporter-syntaxthemes"
],
"windows": {
"shell/splashscreen": [
"shell-splash-window"
],
"shell/aboutdialog": [
"shell-about-window"
],
"shell/multiwindow-manager": [
"shell-managed-window"
],
"shell/miniwindow-compactmode-pictureinpicture": [
"shell-mini-window",
"shell-pip-window"
],
"shell/updatedialog": [
"shell-update-window"
],
"shell/crashreporter": [
"shell-crash-window"
],
"navigation/searchpalette-spotlightsearch-quicklauncher": [
"navigation-launcher"
],
"theme/platform-style-iconthemeprovider-vibrancybackground": [
"theme-frosted-window"
]
}
}
+4
View File
@@ -126,6 +126,10 @@ canvas.iso { position: fixed; inset: 0; width: 100vw; height: 100vh; pointer-eve
.stage-skip { position: absolute; left: -9999px; }
.stage-skip:focus { position: static; display: inline-block; margin-bottom: 8px; font-size: 14px; color: var(--accent); }
img.shot { display: block; max-width: 100%; height: auto; margin-top: 12px; }
.native .label { margin-top: 48px; }
.shots { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 24px; }
.shots img.shot { max-width: min(100%, 560px); }
.pager { display: flex; justify-content: space-between; gap: 16px; margin-top: 32px; padding-top: 16px; border-top: 1px solid var(--line); }
.pager a { display: flex; flex-direction: column; gap: 4px; max-width: 48%; font-size: 14px; line-height: 20px; }
.pager a:hover { color: var(--accent); }