hono-decks 1.0.4 → 1.2.0
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.ja.md +221 -3
- package/README.md +241 -3
- package/dist/adapters/hono-markdown.d.ts +39 -0
- package/dist/adapters/hono-markdown.js +47 -0
- package/dist/advanced.d.ts +8 -1
- package/dist/advanced.js +165 -118
- package/dist/bin.js +356 -86
- package/dist/cli.js +356 -86
- package/dist/file-transaction-NjDxX6Gt.js +80 -0
- package/dist/honox.d.ts +21 -0
- package/dist/honox.js +47 -0
- package/dist/init-vite-EA_L4k2H.js +441 -0
- package/dist/mod.d.ts +8 -1
- package/dist/mod.js +7 -2
- package/dist/node.d.ts +121 -98
- package/dist/node.js +474 -157
- package/dist/vite.d.ts +4 -2
- package/dist/vite.js +441 -53
- package/package.json +15 -2
- package/skills/hono-decks/references/getting-started.md +40 -1
- package/skills/hono-decks/references/integrating.md +12 -0
- package/skills/hono-decks/references/styling.md +10 -0
- package/vite-env.d.ts +7 -0
package/dist/node.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
import { mkdir, mkdtemp, readFile, readdir, rename, rm, writeFile } from "node:fs/promises";
|
|
2
3
|
import { join, relative, resolve } from "node:path";
|
|
3
4
|
import { unified } from "unified";
|
|
4
5
|
import remarkGfm from "remark-gfm";
|
|
@@ -7,8 +8,8 @@ import remarkParse from "remark-parse";
|
|
|
7
8
|
import { compile } from "@mdx-js/mdx";
|
|
8
9
|
import remarkDirective from "remark-directive";
|
|
9
10
|
import { codeToHtml } from "shiki";
|
|
11
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
10
12
|
import { existsSync, watch } from "node:fs";
|
|
11
|
-
import { fileURLToPath } from "node:url";
|
|
12
13
|
import { build } from "esbuild";
|
|
13
14
|
import { lookup } from "node:dns/promises";
|
|
14
15
|
import { isIP } from "node:net";
|
|
@@ -17,23 +18,23 @@ import { raw } from "hono/html";
|
|
|
17
18
|
import { jsx } from "hono/jsx/jsx-runtime";
|
|
18
19
|
import { HtmlEscapedCallbackPhase, resolveCallback } from "hono/utils/html";
|
|
19
20
|
//#region src/routing/file-routing.ts
|
|
20
|
-
function resolveDeckFiles(paths, root = "decks") {
|
|
21
|
+
function resolveDeckFiles(paths, root = "decks", options = {}) {
|
|
21
22
|
const normalizedRoot = normalizePath$3(root).replace(/\/$/, "");
|
|
22
23
|
const decks = /* @__PURE__ */ new Map();
|
|
23
24
|
const assetsBySlug = /* @__PURE__ */ new Map();
|
|
24
25
|
for (const inputPath of paths.map(normalizePath$3).sort()) {
|
|
25
26
|
assertInsideRoot(inputPath, normalizedRoot);
|
|
26
27
|
const segments = inputPath.slice(normalizedRoot.length + 1).split("/");
|
|
27
|
-
if (segments.length === 1 && segments[0].endsWith(".mdx")) {
|
|
28
|
+
if (segments.length === 1 && (segments[0].endsWith(".mdx") || options.markdown && segments[0].endsWith(".md"))) {
|
|
28
29
|
addDeck(decks, {
|
|
29
|
-
slug: segments[0].replace(/\.mdx
|
|
30
|
+
slug: segments[0].replace(/\.mdx?$/, ""),
|
|
30
31
|
sourcePath: inputPath,
|
|
31
32
|
kind: "single-file",
|
|
32
33
|
assetPaths: []
|
|
33
34
|
});
|
|
34
35
|
continue;
|
|
35
36
|
}
|
|
36
|
-
if (segments.length === 2 && segments[1] === "deck.mdx") {
|
|
37
|
+
if (segments.length === 2 && (segments[1] === "deck.mdx" || options.markdown && segments[1] === "deck.md")) {
|
|
37
38
|
addDeck(decks, {
|
|
38
39
|
slug: segments[0],
|
|
39
40
|
sourcePath: inputPath,
|
|
@@ -51,7 +52,7 @@ function resolveDeckFiles(paths, root = "decks") {
|
|
|
51
52
|
if (deck?.kind === "directory") deck.assetPaths = assetPaths;
|
|
52
53
|
continue;
|
|
53
54
|
}
|
|
54
|
-
if (inputPath.endsWith(".mdx")) throw new Error(`Nested deck slugs are not supported in this slice: ${inputPath}`);
|
|
55
|
+
if (inputPath.endsWith(".mdx") || options.markdown && inputPath.endsWith(".md")) throw new Error(`Nested deck slugs are not supported in this slice: ${inputPath}`);
|
|
55
56
|
}
|
|
56
57
|
return [...decks.values()].map((deck) => ({
|
|
57
58
|
...deck,
|
|
@@ -1184,8 +1185,8 @@ import { configureDecks, defineDecks } from ${JSON.stringify(DECKS_ADVANCED_ENTR
|
|
|
1184
1185
|
import type { ConfiguredDecks, DecksConfig } from ${runtimeEntry};
|
|
1185
1186
|
import type { Env } from "hono";
|
|
1186
1187
|
import { decksClientEntry } from "./client-entry";
|
|
1187
|
-
${input.decks.flatMap((deck) => deck.slideModules.map((slide, index) => `import ${slideImportName(
|
|
1188
|
-
${input.decks.
|
|
1188
|
+
${input.decks.flatMap((deck, deckIndex) => deck.slideModules.map((slide, index) => `import ${slideImportName(deckIndex, index)} from ${JSON.stringify(slide.importPath)};`)).join("\n")}
|
|
1189
|
+
${input.decks.flatMap((deck, deckIndex) => deck.componentModulePath ? [`import * as ${componentImportName(deckIndex)} from ${JSON.stringify(deck.componentModulePath)};`] : []).join("\n")}
|
|
1189
1190
|
|
|
1190
1191
|
function withClientComponentIds(module, clientIds) {
|
|
1191
1192
|
const registry = {};
|
|
@@ -1205,7 +1206,7 @@ function withClientComponentIds(module, clientIds) {
|
|
|
1205
1206
|
const generatedDecks = defineDecks({
|
|
1206
1207
|
clientEntryAsset: decksClientEntry,
|
|
1207
1208
|
decks: [
|
|
1208
|
-
${input.decks.map(emitDeckObject).join(",\n")}
|
|
1209
|
+
${input.decks.map((deck, deckIndex) => emitDeckObject(deck, deckIndex)).join(",\n")}
|
|
1209
1210
|
]
|
|
1210
1211
|
});
|
|
1211
1212
|
|
|
@@ -1218,15 +1219,16 @@ function definedDecksFor<E extends Env>() {
|
|
|
1218
1219
|
}
|
|
1219
1220
|
`;
|
|
1220
1221
|
}
|
|
1221
|
-
function emitDeckObject(deck) {
|
|
1222
|
+
function emitDeckObject(deck, deckIndex) {
|
|
1222
1223
|
return ` {
|
|
1223
1224
|
slug: ${JSON.stringify(deck.deck.slug)},
|
|
1224
1225
|
sourcePath: ${JSON.stringify(deck.deck.sourcePath)},
|
|
1225
1226
|
kind: ${JSON.stringify(deck.deck.kind)},
|
|
1226
1227
|
meta: ${serializeValue(deck.deck.meta, 3)},
|
|
1228
|
+
${typeof deck.deck.clientEntryRequired === "boolean" ? ` clientEntryRequired: ${deck.deck.clientEntryRequired},\n` : ""}
|
|
1227
1229
|
${deck.deck.themeStyle ? ` "themeStyle": ${serializeValue(deck.deck.themeStyle, 3)},\n` : ""}${deck.deck.themeSourcePath ? ` "themeSourcePath": ${JSON.stringify(deck.deck.themeSourcePath)},\n` : ""}
|
|
1228
1230
|
assets: ${serializeValue(deck.deck.assets, 3)},
|
|
1229
|
-
componentRegistry: ${deck.componentModulePath ? `withClientComponentIds(${componentImportName(
|
|
1231
|
+
componentRegistry: ${deck.componentModulePath ? `withClientComponentIds(${componentImportName(deckIndex)}, ${serializeValue(deck.clientComponentIds ?? {}, 3)})` : "{}"},
|
|
1230
1232
|
warnings: ${serializeValue(deck.deck.warnings, 3)},
|
|
1231
1233
|
slides: [
|
|
1232
1234
|
${deck.deck.slides.map((slide) => ` {
|
|
@@ -1235,19 +1237,16 @@ ${deck.deck.slides.map((slide) => ` {
|
|
|
1235
1237
|
html: "",
|
|
1236
1238
|
components: [],
|
|
1237
1239
|
notes: ${serializeValue(slide.notes, 5)},
|
|
1238
|
-
render: ${slideImportName(
|
|
1240
|
+
render: ${slideImportName(deckIndex, slide.index)}
|
|
1239
1241
|
}`).join(",\n")}
|
|
1240
1242
|
]
|
|
1241
1243
|
}`;
|
|
1242
1244
|
}
|
|
1243
|
-
function slideImportName(
|
|
1244
|
-
return `Slide_${
|
|
1245
|
+
function slideImportName(deckIndex, slideIndex) {
|
|
1246
|
+
return `Slide_${deckIndex}_${slideIndex}`;
|
|
1245
1247
|
}
|
|
1246
|
-
function componentImportName(
|
|
1247
|
-
return `Components_${
|
|
1248
|
-
}
|
|
1249
|
-
function safeIdentifier$1(value) {
|
|
1250
|
-
return value.replace(/[^A-Za-z0-9_$]+/g, "_").replace(/^[^A-Za-z_$]+/, "_") || "_";
|
|
1248
|
+
function componentImportName(deckIndex) {
|
|
1249
|
+
return `Components_${deckIndex}`;
|
|
1251
1250
|
}
|
|
1252
1251
|
function serializeValue(value, depth) {
|
|
1253
1252
|
const indent = " ".repeat(depth);
|
|
@@ -1699,6 +1698,191 @@ function extractDeckPrelude(source) {
|
|
|
1699
1698
|
};
|
|
1700
1699
|
}
|
|
1701
1700
|
//#endregion
|
|
1701
|
+
//#region src/node/markdown-decks.ts
|
|
1702
|
+
async function compileMarkdownDecks(input, adapter) {
|
|
1703
|
+
const markdownEntries = input.decks.filter((entry) => entry.sourcePath.endsWith(".md"));
|
|
1704
|
+
const mdx = await compileMdxModuleDecks({
|
|
1705
|
+
...input,
|
|
1706
|
+
decks: input.decks.filter((entry) => !entry.sourcePath.endsWith(".md"))
|
|
1707
|
+
});
|
|
1708
|
+
if (!markdownEntries.length) return mdx;
|
|
1709
|
+
const decks = [...mdx.decks];
|
|
1710
|
+
const clients = /* @__PURE__ */ new Set();
|
|
1711
|
+
const markdownIslands = /* @__PURE__ */ new Map();
|
|
1712
|
+
for (const entry of markdownEntries) try {
|
|
1713
|
+
const source = await input.readText(entry.sourcePath);
|
|
1714
|
+
const parsed = adapter.read(source);
|
|
1715
|
+
if (input.clientComponentIds?.[entry.slug] && Object.keys(input.clientComponentIds[entry.slug]).length) throw new Error("Void Markdown slides support static components only; use MDX for hono-decks client components.");
|
|
1716
|
+
const warnings = [];
|
|
1717
|
+
const meta = toDeckFrontmatter(parsed.frontmatter, warnings);
|
|
1718
|
+
addUnknownFrontmatterWarnings(warnings, meta.meta, "deck");
|
|
1719
|
+
const assets = [...await buildAssetRefs(entry.slug, entry.assetPaths, input), ...buildExternalAssetRefs([
|
|
1720
|
+
...collectMarkdownAssetCandidates(parsed.content),
|
|
1721
|
+
...collectFrontmatterAssetCandidates(meta.assets),
|
|
1722
|
+
...collectFrontmatterAssetCandidates(parsed.frontmatter.background)
|
|
1723
|
+
])];
|
|
1724
|
+
const candidates = [
|
|
1725
|
+
...collectMarkdownAssetCandidates(parsed.content),
|
|
1726
|
+
...collectFrontmatterAssetCandidates(parsed.frontmatter.assets),
|
|
1727
|
+
...collectFrontmatterAssetCandidates(parsed.frontmatter.background)
|
|
1728
|
+
];
|
|
1729
|
+
if (entry.kind === "single-file" && candidates.some(isLocalRelativeAssetCandidate)) throw new Error("Single-file Markdown decks cannot reference local relative assets; use a directory deck.");
|
|
1730
|
+
let clientEntryRequired = false;
|
|
1731
|
+
const slideModules = [];
|
|
1732
|
+
const slides = [];
|
|
1733
|
+
for (const [index, slideSource] of splitMarkdownSlides(parsed.content).entries()) {
|
|
1734
|
+
const prelude = parsed.script ? `<script>\n${parsed.script}\n<\/script>\n` : "";
|
|
1735
|
+
const slide = adapter.read(prelude + slideSource);
|
|
1736
|
+
const path = `${input.outDir}/decks/${entry.slug}/slide-${index}.ts`;
|
|
1737
|
+
const rewritten = rewriteAssetUrls(`${prelude}---\n${JSON.stringify({
|
|
1738
|
+
...parsed.frontmatter,
|
|
1739
|
+
...slide.frontmatter
|
|
1740
|
+
})}\n---\n${slide.content}`, assets);
|
|
1741
|
+
const result = await adapter.compile(rewritten, { sourcePath: resolve(input.cwd ?? process.cwd(), entry.sourcePath) });
|
|
1742
|
+
clientEntryRequired ||= Boolean(result.clientCode || result.islands?.length);
|
|
1743
|
+
if (result.clientCode) clients.add(result.clientCode);
|
|
1744
|
+
for (const island of result.islands ?? []) markdownIslands.set(island.id, island);
|
|
1745
|
+
const slideMeta = toSlideFrontmatter(slide.frontmatter, warnings, {
|
|
1746
|
+
slideIndex: index,
|
|
1747
|
+
fallbackTitle: result.headings[0]?.text,
|
|
1748
|
+
fallbackTransition: meta.transition,
|
|
1749
|
+
fallbackTransitionDuration: meta.transitionDuration,
|
|
1750
|
+
fallbackTransitionEasing: meta.transitionEasing
|
|
1751
|
+
});
|
|
1752
|
+
addUnknownFrontmatterWarnings(warnings, slideMeta.meta, "slide", index);
|
|
1753
|
+
slideModules.push({
|
|
1754
|
+
path,
|
|
1755
|
+
importPath: `./decks/${entry.slug}/slide-${index}`,
|
|
1756
|
+
code: `// @ts-nocheck\n${rewriteRelativeMdxImports(result.code, dirname$1(entry.sourcePath), dirname$1(path))}`
|
|
1757
|
+
});
|
|
1758
|
+
slides.push({
|
|
1759
|
+
index,
|
|
1760
|
+
meta: slideMeta,
|
|
1761
|
+
html: "",
|
|
1762
|
+
components: [],
|
|
1763
|
+
notes: slideMeta.notes
|
|
1764
|
+
});
|
|
1765
|
+
}
|
|
1766
|
+
addExternalAssetWarnings(warnings, assets);
|
|
1767
|
+
const themeStyle = input.themeStyles?.[entry.slug];
|
|
1768
|
+
decks.push({
|
|
1769
|
+
deck: {
|
|
1770
|
+
slug: entry.slug,
|
|
1771
|
+
sourcePath: entry.sourcePath,
|
|
1772
|
+
kind: entry.kind,
|
|
1773
|
+
clientEntryRequired,
|
|
1774
|
+
meta,
|
|
1775
|
+
slides,
|
|
1776
|
+
assets,
|
|
1777
|
+
warnings,
|
|
1778
|
+
themeStyle: themeStyle?.style,
|
|
1779
|
+
themeSourcePath: themeStyle?.sourcePath
|
|
1780
|
+
},
|
|
1781
|
+
slideModules
|
|
1782
|
+
});
|
|
1783
|
+
} catch (error) {
|
|
1784
|
+
throw new CompileError(`Void Markdown compile failed in ${entry.sourcePath}: ${error instanceof Error ? error.message : String(error)}`, "void-markdown-compile-error");
|
|
1785
|
+
}
|
|
1786
|
+
decks.sort((a, b) => a.deck.slug.localeCompare(b.deck.slug));
|
|
1787
|
+
return {
|
|
1788
|
+
decks,
|
|
1789
|
+
routerModule: emitModuleDecksRouter({ decks }),
|
|
1790
|
+
clientCode: [...clients].join("\n"),
|
|
1791
|
+
clientModules: [adapter.client([...markdownIslands.values()])].filter(Boolean),
|
|
1792
|
+
markdownIslands: [...markdownIslands.values()]
|
|
1793
|
+
};
|
|
1794
|
+
}
|
|
1795
|
+
/** Protect fenced code from the deck separator parser. */
|
|
1796
|
+
function splitMarkdownSlides(source) {
|
|
1797
|
+
const fences = [];
|
|
1798
|
+
let prefix = "HONO_DECKS_FENCE_";
|
|
1799
|
+
while (source.includes(prefix)) prefix += "_";
|
|
1800
|
+
const lines = source.replace(/\r\n/g, "\n").split("\n");
|
|
1801
|
+
const protectedLines = [];
|
|
1802
|
+
for (let index = 0; index < lines.length; index++) {
|
|
1803
|
+
const open = /^ {0,3}(`{3,}|~{3,})/.exec(lines[index]);
|
|
1804
|
+
if (/^[ \t]+---[ \t]*$/.test(lines[index])) {
|
|
1805
|
+
protectedLines.push(`${prefix}${fences.push(lines[index]) - 1}_END`);
|
|
1806
|
+
continue;
|
|
1807
|
+
}
|
|
1808
|
+
if (!open) {
|
|
1809
|
+
protectedLines.push(lines[index]);
|
|
1810
|
+
continue;
|
|
1811
|
+
}
|
|
1812
|
+
const block = [lines[index]];
|
|
1813
|
+
const close = new RegExp(`^ {0,3}${open[1][0]}{${open[1].length},}[ \\t]*$`);
|
|
1814
|
+
let closed = false;
|
|
1815
|
+
while (++index < lines.length) {
|
|
1816
|
+
block.push(lines[index]);
|
|
1817
|
+
if (close.test(lines[index])) {
|
|
1818
|
+
closed = true;
|
|
1819
|
+
break;
|
|
1820
|
+
}
|
|
1821
|
+
}
|
|
1822
|
+
if (!closed) throw new Error("Markdown code fence is not closed.");
|
|
1823
|
+
protectedLines.push(`${prefix}${fences.push(block.join("\n")) - 1}_END`);
|
|
1824
|
+
}
|
|
1825
|
+
return splitSlideSources(protectedLines.join("\n")).map((slide) => slide.replace(new RegExp(`${prefix}(\\d+)_END`, "g"), (_, id) => fences[Number(id)]));
|
|
1826
|
+
}
|
|
1827
|
+
//#endregion
|
|
1828
|
+
//#region src/adapters/hono-markdown.ts
|
|
1829
|
+
/** Node-only bridge. Existing Void configs retain their original compiler/runtime pair. */
|
|
1830
|
+
async function createHonoMarkdownAdapter(cwd, legacy = false, options) {
|
|
1831
|
+
const require = createRequire(resolve(cwd, "package.json"));
|
|
1832
|
+
const entry = legacy ? "void-plugin-hono-jsx/markdown/compiler" : "@ts-76/hono-markdown/compiler";
|
|
1833
|
+
let compiler;
|
|
1834
|
+
try {
|
|
1835
|
+
compiler = await import(pathToFileURL(require.resolve(entry)).href);
|
|
1836
|
+
} catch (cause) {
|
|
1837
|
+
throw new Error(`Hono Markdown requires ${legacy ? "its public /markdown/compiler API" : "@ts-76/hono-markdown/compiler"} and Markdown peers installed in the app.`, { cause });
|
|
1838
|
+
}
|
|
1839
|
+
const read = compiler.readMarkdownModule ?? compiler.readStaticMarkdown;
|
|
1840
|
+
const compile = compiler.compileMarkdownModule ?? compiler.compileStaticMarkdown;
|
|
1841
|
+
if (typeof read !== "function" || typeof compile !== "function") throw new Error("Missing standalone compiler API");
|
|
1842
|
+
const runtime = entry.startsWith("void-plugin") ? "void-plugin-hono-jsx/markdown/client" : "@ts-76/hono-markdown/client";
|
|
1843
|
+
return {
|
|
1844
|
+
read,
|
|
1845
|
+
compile: (source, input) => compile(source, {
|
|
1846
|
+
...input,
|
|
1847
|
+
options
|
|
1848
|
+
}),
|
|
1849
|
+
client: (islands) => emitMarkdownClient(islands, runtime)
|
|
1850
|
+
};
|
|
1851
|
+
}
|
|
1852
|
+
function emitMarkdownClient(islands, runtime) {
|
|
1853
|
+
if (!islands.length) return "";
|
|
1854
|
+
const literal = (value) => JSON.stringify(value).replace(/</g, "\\u003c");
|
|
1855
|
+
return `import { hydrateMarkdownIslands } from ${literal(runtime)};
|
|
1856
|
+
hydrateMarkdownIslands({ ${islands.map((island) => `${literal(island.id)}: () => import(${literal(island.modulePath)})`).join(",")} }, {
|
|
1857
|
+
ready(element, start) {
|
|
1858
|
+
const slide = element.closest('section[data-slide-state]');
|
|
1859
|
+
if (!slide || slide.dataset.slideState === 'active') { start(); return; }
|
|
1860
|
+
const observer = new MutationObserver(() => {
|
|
1861
|
+
if (slide.dataset.slideState === 'active') { observer.disconnect(); start(); }
|
|
1862
|
+
});
|
|
1863
|
+
observer.observe(slide, { attributes: true, attributeFilter: ['data-slide-state'] });
|
|
1864
|
+
}
|
|
1865
|
+
});`;
|
|
1866
|
+
}
|
|
1867
|
+
//#endregion
|
|
1868
|
+
//#region src/node/markdown-adapter.ts
|
|
1869
|
+
async function loadMarkdownAdapter(selection, cwd) {
|
|
1870
|
+
if (selection === "void") return createHonoMarkdownAdapter(cwd, true);
|
|
1871
|
+
if (selection.adapter === "hono-decks/adapters/hono-markdown") return createHonoMarkdownAdapter(cwd, false, selection.options);
|
|
1872
|
+
const module = await import(pathToFileURL(createRequire(resolve(cwd, "package.json")).resolve(selection.adapter)).href);
|
|
1873
|
+
if (typeof module.createMarkdownAdapter !== "function") throw new Error("Markdown adapter must export createMarkdownAdapter.");
|
|
1874
|
+
const adapter = await module.createMarkdownAdapter({
|
|
1875
|
+
cwd,
|
|
1876
|
+
options: selection.options
|
|
1877
|
+
});
|
|
1878
|
+
if (![
|
|
1879
|
+
adapter?.read,
|
|
1880
|
+
adapter?.compile,
|
|
1881
|
+
adapter?.client
|
|
1882
|
+
].every((value) => typeof value === "function")) throw new Error("Markdown adapter must provide read, compile and client functions.");
|
|
1883
|
+
return adapter;
|
|
1884
|
+
}
|
|
1885
|
+
//#endregion
|
|
1702
1886
|
//#region src/generator/component-registry.ts
|
|
1703
1887
|
function applyDeckComponentRegistry(input) {
|
|
1704
1888
|
const components = input.components.map((component) => ({
|
|
@@ -1809,10 +1993,12 @@ async function emitClientEntryModule(input) {
|
|
|
1809
1993
|
registrations.push(`${JSON.stringify(clientId)}: ${localName}`);
|
|
1810
1994
|
}
|
|
1811
1995
|
}
|
|
1812
|
-
|
|
1813
|
-
const
|
|
1996
|
+
const clientModules = input.clientModules ?? [];
|
|
1997
|
+
if (registrations.length === 0 && clientModules.length === 0) return `export const decksClientEntry = ${JSON.stringify(input.extraCode ?? "")};\n`;
|
|
1998
|
+
const result = await build({
|
|
1814
1999
|
stdin: {
|
|
1815
|
-
contents:
|
|
2000
|
+
contents: `${clientModules.join("\n")}
|
|
2001
|
+
import { hydrateSlideIslands } from "hono-decks/client";
|
|
1816
2002
|
${imports.join("\n")}
|
|
1817
2003
|
|
|
1818
2004
|
hydrateSlideIslands({
|
|
@@ -1827,6 +2013,15 @@ hydrateSlideIslands({
|
|
|
1827
2013
|
},
|
|
1828
2014
|
bundle: true,
|
|
1829
2015
|
write: false,
|
|
2016
|
+
outdir: join(input.cwd, ".hono-decks-client"),
|
|
2017
|
+
loader: {
|
|
2018
|
+
".svg": "dataurl",
|
|
2019
|
+
".png": "dataurl",
|
|
2020
|
+
".jpg": "dataurl",
|
|
2021
|
+
".webp": "dataurl",
|
|
2022
|
+
".woff2": "dataurl",
|
|
2023
|
+
".woff": "dataurl"
|
|
2024
|
+
},
|
|
1830
2025
|
format: "esm",
|
|
1831
2026
|
platform: "browser",
|
|
1832
2027
|
target: "es2022",
|
|
@@ -1836,9 +2031,12 @@ hydrateSlideIslands({
|
|
|
1836
2031
|
alias: { "hono-decks/client": resolveClientRuntimeEntry() },
|
|
1837
2032
|
sourcemap: false,
|
|
1838
2033
|
minify: false
|
|
1839
|
-
})
|
|
2034
|
+
});
|
|
2035
|
+
const output = result.outputFiles.find((file) => file.path.endsWith(".js"));
|
|
2036
|
+
const css = result.outputFiles.filter((file) => file.path.endsWith(".css")).map((file) => file.text).join("\n");
|
|
2037
|
+
input.onCss?.(css);
|
|
1840
2038
|
if (!output) throw new Error("Client entry did not produce output.");
|
|
1841
|
-
return `export const decksClientEntry = ${JSON.stringify(output.text)};\n`;
|
|
2039
|
+
return `export const decksClientEntry = ${JSON.stringify(output.text + (input.extraCode ? "\n" + input.extraCode : ""))};\n`;
|
|
1842
2040
|
}
|
|
1843
2041
|
function resolveClientRuntimeEntry() {
|
|
1844
2042
|
const built = fileURLToPath(new URL("./client.js", import.meta.url));
|
|
@@ -1966,6 +2164,63 @@ function slugForDeckPath(path, root) {
|
|
|
1966
2164
|
if (segments.length >= 3 && segments[1] === "assets") return segments[0];
|
|
1967
2165
|
}
|
|
1968
2166
|
//#endregion
|
|
2167
|
+
//#region src/node/file-transaction.ts
|
|
2168
|
+
/** Stage every file before publishing; restore the previous files on an I/O error.
|
|
2169
|
+
* Individual renames are atomic. This is rollback on failure, not a cross-process
|
|
2170
|
+
* or crash-atomic filesystem transaction. Failed rollback retains recovery files.
|
|
2171
|
+
*/
|
|
2172
|
+
async function publishGeneratedFiles(files, renameFile = rename) {
|
|
2173
|
+
const staged = [];
|
|
2174
|
+
const published = [];
|
|
2175
|
+
let keepRecovery = false;
|
|
2176
|
+
try {
|
|
2177
|
+
if (new Set(files.map((file) => file.path)).size !== files.length) throw new Error("Generated output paths must be unique.");
|
|
2178
|
+
for (const file of files) {
|
|
2179
|
+
const parent = dirname(file.path);
|
|
2180
|
+
await mkdir(parent, { recursive: true });
|
|
2181
|
+
const dir = await mkdtemp(join(parent, ".hono-decks-"));
|
|
2182
|
+
const entry = {
|
|
2183
|
+
path: file.path,
|
|
2184
|
+
dir,
|
|
2185
|
+
next: join(dir, "next")
|
|
2186
|
+
};
|
|
2187
|
+
staged.push(entry);
|
|
2188
|
+
await writeFile(entry.next, file.content, "utf8");
|
|
2189
|
+
let previous;
|
|
2190
|
+
try {
|
|
2191
|
+
previous = await readFile(file.path);
|
|
2192
|
+
} catch (error) {
|
|
2193
|
+
if (error.code === "ENOENT") continue;
|
|
2194
|
+
throw error;
|
|
2195
|
+
}
|
|
2196
|
+
entry.backup = join(dir, "previous");
|
|
2197
|
+
await writeFile(entry.backup, previous);
|
|
2198
|
+
}
|
|
2199
|
+
for (const entry of staged) {
|
|
2200
|
+
await renameFile(entry.next, entry.path);
|
|
2201
|
+
published.push(entry);
|
|
2202
|
+
}
|
|
2203
|
+
} catch (error) {
|
|
2204
|
+
const failures = [];
|
|
2205
|
+
for (const entry of published.reverse()) try {
|
|
2206
|
+
if (entry.backup) await renameFile(entry.backup, entry.path);
|
|
2207
|
+
else await rm(entry.path, { force: true });
|
|
2208
|
+
} catch (failure) {
|
|
2209
|
+
failures.push(failure);
|
|
2210
|
+
}
|
|
2211
|
+
if (failures.length) {
|
|
2212
|
+
keepRecovery = true;
|
|
2213
|
+
throw new AggregateError([error, ...failures], `Generated output rollback failed. Recovery files remain in: ${staged.map((entry) => entry.dir).join(", ")}`);
|
|
2214
|
+
}
|
|
2215
|
+
throw error;
|
|
2216
|
+
} finally {
|
|
2217
|
+
if (!keepRecovery) await Promise.allSettled(staged.map((entry) => rm(entry.dir, {
|
|
2218
|
+
recursive: true,
|
|
2219
|
+
force: true
|
|
2220
|
+
})));
|
|
2221
|
+
}
|
|
2222
|
+
}
|
|
2223
|
+
//#endregion
|
|
1969
2224
|
//#region src/node/ogp.ts
|
|
1970
2225
|
const MAX_OGP_BYTES = 256 * 1024;
|
|
1971
2226
|
const MAX_OGP_REDIRECTS = 3;
|
|
@@ -2152,10 +2407,16 @@ function isHttpUrl(value) {
|
|
|
2152
2407
|
//#endregion
|
|
2153
2408
|
//#region src/node/compile-decks.ts
|
|
2154
2409
|
async function compileDecks(input) {
|
|
2410
|
+
const compiled = await compileDeckModules(input);
|
|
2411
|
+
await publishGeneratedFiles([...compiled.modules, ...compiled.cacheFile ? [compiled.cacheFile] : []]);
|
|
2412
|
+
return compiled.result;
|
|
2413
|
+
}
|
|
2414
|
+
/** Shared by file output and Vite's in-memory module graph. Does not write files. */
|
|
2415
|
+
async function compileDeckModules(input) {
|
|
2155
2416
|
const out = normalizeRelativePath(input.out, "Output directory");
|
|
2156
2417
|
const root = normalizeDeckRoot(input.root);
|
|
2157
2418
|
const paths = await listFiles(input.cwd, join(input.cwd, root));
|
|
2158
|
-
const resolved = resolveDeckFiles(paths, root);
|
|
2419
|
+
const resolved = resolveDeckFiles(paths, root, { markdown: Boolean(input.markdown) });
|
|
2159
2420
|
const componentModulePaths = Object.fromEntries(resolved.flatMap((deck) => {
|
|
2160
2421
|
const path = deck.kind === "directory" ? findComponentModule(paths, root, deck.slug) : void 0;
|
|
2161
2422
|
return path ? [[deck.slug, path]] : [];
|
|
@@ -2183,7 +2444,9 @@ async function compileDecks(input) {
|
|
|
2183
2444
|
refresh: input.refreshOgp,
|
|
2184
2445
|
resolveOgp: input.resolveOgp ?? resolveOgpMetadata
|
|
2185
2446
|
});
|
|
2186
|
-
const
|
|
2447
|
+
const adapter = input.markdown && resolved.some((entry) => entry.sourcePath.endsWith(".md")) ? await loadMarkdownAdapter(input.markdown, input.cwd) : void 0;
|
|
2448
|
+
const generated = await (adapter ? (value) => compileMarkdownDecks(value, adapter) : compileMdxModuleDecks)({
|
|
2449
|
+
cwd: input.cwd,
|
|
2187
2450
|
root,
|
|
2188
2451
|
outDir: out,
|
|
2189
2452
|
mountPath: input.mountPath,
|
|
@@ -2195,20 +2458,57 @@ async function compileDecks(input) {
|
|
|
2195
2458
|
readText: (path) => readFile(join(input.cwd, path), "utf8"),
|
|
2196
2459
|
readBinary: (path) => readFile(join(input.cwd, path))
|
|
2197
2460
|
});
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
await writeTextFile(join(input.cwd, out, "client-entry.ts"), await emitClientEntryModule({
|
|
2461
|
+
let clientCss = "";
|
|
2462
|
+
const clientEntry = await emitClientEntryModule({
|
|
2201
2463
|
cwd: input.cwd,
|
|
2202
2464
|
clientEntries: clientEntryPaths,
|
|
2203
|
-
clientComponentIds
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2465
|
+
clientComponentIds,
|
|
2466
|
+
extraCode: generated.clientCode,
|
|
2467
|
+
clientModules: generated.clientModules,
|
|
2468
|
+
onCss: (css) => {
|
|
2469
|
+
clientCss = css;
|
|
2470
|
+
}
|
|
2471
|
+
});
|
|
2472
|
+
if (clientCss) {
|
|
2473
|
+
for (const deck of generated.decks) if (deck.deck.clientEntryRequired || Object.keys(deck.clientComponentIds ?? {}).length) deck.deck.themeStyle = [deck.deck.themeStyle, clientCss].filter(Boolean).join("\n");
|
|
2474
|
+
generated.routerModule = emitModuleDecksRouter({ decks: generated.decks });
|
|
2475
|
+
}
|
|
2476
|
+
const files = generated.decks.flatMap((deck) => deck.slideModules.map((slide) => ({
|
|
2477
|
+
path: join(input.cwd, slide.path),
|
|
2478
|
+
content: slide.code
|
|
2479
|
+
})));
|
|
2480
|
+
files.push({
|
|
2481
|
+
path: join(input.cwd, out, "decks.ts"),
|
|
2482
|
+
content: generated.routerModule
|
|
2483
|
+
}, {
|
|
2484
|
+
path: join(input.cwd, out, "client-entry.ts"),
|
|
2485
|
+
content: clientEntry
|
|
2486
|
+
});
|
|
2487
|
+
return {
|
|
2488
|
+
modules: files,
|
|
2489
|
+
cacheFile: ogpCache.output(),
|
|
2490
|
+
result: {
|
|
2491
|
+
outDir: out,
|
|
2492
|
+
routerModulePath: `${out}/decks.ts`,
|
|
2493
|
+
decks: generated.decks.map(({ deck, slideModules }) => {
|
|
2494
|
+
const { slides, componentRegistry: _componentRegistry, ...metadata } = deck;
|
|
2495
|
+
return {
|
|
2496
|
+
...metadata,
|
|
2497
|
+
slides: slides.map((slide, index) => ({
|
|
2498
|
+
index: slide.index,
|
|
2499
|
+
meta: slide.meta,
|
|
2500
|
+
notes: slide.notes,
|
|
2501
|
+
modulePath: slideModules[index].path
|
|
2502
|
+
}))
|
|
2503
|
+
};
|
|
2504
|
+
})
|
|
2505
|
+
}
|
|
2506
|
+
};
|
|
2207
2507
|
}
|
|
2208
2508
|
async function createOgpCacheResolver(input) {
|
|
2209
2509
|
if (!input.cacheFile) return {
|
|
2210
2510
|
resolveOgp: input.resolveOgp,
|
|
2211
|
-
|
|
2511
|
+
output: () => void 0
|
|
2212
2512
|
};
|
|
2213
2513
|
const cachePath = join(input.cwd, normalizeRelativePath(input.cacheFile, "OGP cache file"));
|
|
2214
2514
|
const cache = await readOgpCache(cachePath);
|
|
@@ -2224,9 +2524,11 @@ async function createOgpCacheResolver(input) {
|
|
|
2224
2524
|
}
|
|
2225
2525
|
return metadata;
|
|
2226
2526
|
},
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2527
|
+
output() {
|
|
2528
|
+
return dirty ? {
|
|
2529
|
+
path: cachePath,
|
|
2530
|
+
content: `${JSON.stringify(cache, null, 2)}\n`
|
|
2531
|
+
} : void 0;
|
|
2230
2532
|
}
|
|
2231
2533
|
};
|
|
2232
2534
|
}
|
|
@@ -2288,10 +2590,6 @@ async function buildDeckManifestFromPaths(input) {
|
|
|
2288
2590
|
readBinary: (path) => readFile(join(input.cwd, path))
|
|
2289
2591
|
});
|
|
2290
2592
|
}
|
|
2291
|
-
async function writeTextFile(path, contents) {
|
|
2292
|
-
await mkdir(dirname(path), { recursive: true });
|
|
2293
|
-
await writeFile(path, contents, "utf8");
|
|
2294
|
-
}
|
|
2295
2593
|
function findComponentModule(paths, root, slug) {
|
|
2296
2594
|
const base = `${normalizePath(root).replace(/\/$/, "")}/${slug}/components/index`;
|
|
2297
2595
|
return paths.find((path) => {
|
|
@@ -3087,6 +3385,108 @@ function controlIconPaths(name) {
|
|
|
3087
3385
|
}
|
|
3088
3386
|
}
|
|
3089
3387
|
//#endregion
|
|
3388
|
+
//#region src/renderer/presentation-style.ts
|
|
3389
|
+
const PRESENTATION_DESIGN_WIDTH = 1920;
|
|
3390
|
+
const PRESENTATION_DESIGN_HEIGHT = 1080;
|
|
3391
|
+
function presentationDesignCssVariables() {
|
|
3392
|
+
return `--hono-decks-width:${PRESENTATION_DESIGN_WIDTH}px;--hono-decks-height:${PRESENTATION_DESIGN_HEIGHT}px`;
|
|
3393
|
+
}
|
|
3394
|
+
function basePresentationStyle() {
|
|
3395
|
+
return `
|
|
3396
|
+
:root{color-scheme:light;font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;font-size:32px;${presentationDesignCssVariables()};--hono-decks-transition-duration:.24s;--hono-decks-transition-easing:ease;--hono-decks-background:#fff;--hono-decks-color:#172033;--hono-decks-muted-color:#475569;--hono-decks-accent-color:#0369a1;--hono-decks-border-color:#cbd5e1;--hono-decks-inline-code-background:#f1f5f9;--hono-decks-code-background:#f1f5f9;--hono-decks-card-background:#f1f5f9;--hono-decks-card-image-background:#e2e8f0;--hono-decks-warning-background:#fef3c7;--hono-decks-warning-color:#854d0e;background:var(--hono-decks-background);color:var(--hono-decks-color)}
|
|
3397
|
+
html,body{margin:0;width:100%;height:100%;overflow:hidden}
|
|
3398
|
+
.hono-decks-stage{width:100vw;height:100vh;overflow:hidden;position:relative;display:grid;grid-template-columns:minmax(0,1fr);grid-template-rows:minmax(0,1fr);place-items:center}
|
|
3399
|
+
.hono-decks-deck{display:grid;gap:1rem;width:var(--hono-decks-width);height:var(--hono-decks-height);box-sizing:border-box;transform-origin:center}
|
|
3400
|
+
.slide{box-sizing:border-box;aspect-ratio:16/9;background:var(--hono-decks-background);color:var(--hono-decks-color);padding:1.8rem;overflow:hidden}
|
|
3401
|
+
.hono-decks-slide-content{width:100%;height:100%}
|
|
3402
|
+
.slide.layout-cover,.slide.layout-statement{display:flex;flex-direction:column;justify-content:center}
|
|
3403
|
+
.slide.layout-cover>.hono-decks-slide-content,.slide.layout-statement>.hono-decks-slide-content{display:flex;flex-direction:column;justify-content:center}
|
|
3404
|
+
.slide code{font-family:"SFMono-Regular","Cascadia Code","Liberation Mono",Menlo,Consolas,monospace;font-size:.9em;line-height:1.45}
|
|
3405
|
+
.slide :not(pre)>code{border-radius:6px;background:var(--hono-decks-inline-code-background);padding:.12em .34em}
|
|
3406
|
+
.slide pre{max-width:100%;overflow:auto;box-sizing:border-box;border:1px solid var(--hono-decks-border-color);border-radius:8px;background:var(--hono-decks-code-background);padding:1rem;tab-size:2;white-space:pre}
|
|
3407
|
+
.slide pre code{display:block;min-width:max-content;background:transparent;padding:0}
|
|
3408
|
+
.slide table{width:100%;margin:1rem 0;border-collapse:collapse}
|
|
3409
|
+
.slide th,.slide td{border:1px solid var(--hono-decks-border-color);padding:.4em .75em;text-align:left}
|
|
3410
|
+
.slide th{background:var(--hono-decks-card-background);font-weight:700}
|
|
3411
|
+
.slide del{color:var(--hono-decks-muted-color)}
|
|
3412
|
+
.slide li.task-list-item{list-style:none;margin-left:-1.4em}
|
|
3413
|
+
.slide li.task-list-item input[type=checkbox]{margin-right:.5em;vertical-align:middle}
|
|
3414
|
+
.hono-decks-code-block{margin:1rem 0;max-width:100%}
|
|
3415
|
+
.hono-decks-code-caption{display:inline-flex;margin:0 0 .4rem;border:1px solid var(--hono-decks-border-color);border-radius:6px;padding:.2rem .5rem;background:var(--hono-decks-inline-code-background);color:var(--hono-decks-muted-color);font-size:.82rem}
|
|
3416
|
+
.hono-decks-embed-frame{margin:1rem 0;max-width:100%}
|
|
3417
|
+
.hono-decks-embed-viewport{width:min(100%,72rem);overflow:hidden}
|
|
3418
|
+
.hono-decks-embed-viewport iframe{display:block;width:100%;height:100%;border:0}
|
|
3419
|
+
.hono-decks-embed-print-fallback{display:none}
|
|
3420
|
+
.hono-decks-embed-print-poster{display:block;width:100%;height:100%;object-fit:cover}
|
|
3421
|
+
.hono-decks-embed-fallback{margin:.45rem 0 0;color:var(--hono-decks-muted-color);font-size:.84rem}
|
|
3422
|
+
.hono-decks-embed-fallback a{color:inherit}
|
|
3423
|
+
.hono-decks-social-embed{margin:1rem 0;max-width:min(100%,42rem)}
|
|
3424
|
+
.hono-decks-social-card{margin:0;border:1px solid var(--hono-decks-border-color);border-radius:8px;background:var(--hono-decks-card-background);padding:1rem}
|
|
3425
|
+
.hono-decks-social-card p{margin:0 0 .75rem;line-height:1.55}
|
|
3426
|
+
.hono-decks-social-card footer{display:flex;flex-wrap:wrap;gap:.65rem;align-items:center;color:var(--hono-decks-muted-color);font-size:.9rem}
|
|
3427
|
+
.hono-decks-social-card a{color:inherit}
|
|
3428
|
+
.hono-decks-tweet-embed{margin:1rem 0;max-width:min(100%,42rem)}
|
|
3429
|
+
.hono-decks-tweet-embed .twitter-tweet{margin:0;border:1px solid var(--hono-decks-border-color);border-radius:8px;background:var(--hono-decks-card-background);padding:1rem}
|
|
3430
|
+
.hono-decks-tweet-embed .twitter-tweet a{color:inherit}
|
|
3431
|
+
.hono-decks-tweet-print-fallback{display:none}
|
|
3432
|
+
.hono-decks-link-card{margin:1rem 0;max-width:min(100%,42rem)}
|
|
3433
|
+
.hono-decks-link-card-anchor{display:grid;grid-template-columns:minmax(9rem,32%) minmax(0,1fr);gap:.75rem;align-items:stretch;border:1px solid var(--hono-decks-border-color);border-radius:8px;background:var(--hono-decks-card-background);padding:1rem;color:inherit;text-decoration:none}
|
|
3434
|
+
.hono-decks-link-card-body{display:grid;gap:.35rem;min-width:0}
|
|
3435
|
+
.hono-decks-link-card-image{width:100%;height:100%;max-height:10rem;aspect-ratio:16/9;object-fit:cover;border-radius:6px;background:var(--hono-decks-card-image-background)}
|
|
3436
|
+
.hono-decks-link-card-site{color:var(--hono-decks-accent-color);font-size:.8rem;text-transform:uppercase}
|
|
3437
|
+
.hono-decks-link-card-title{font-weight:700}
|
|
3438
|
+
.hono-decks-link-card-description{color:var(--hono-decks-muted-color);line-height:1.45}
|
|
3439
|
+
.hono-decks-link-card-label{color:var(--hono-decks-accent-color);font-size:.88rem}
|
|
3440
|
+
.mdx-hero{height:100%;display:grid;grid-template-columns:minmax(0,1fr) minmax(280px,42%);gap:1.8rem;align-items:center}
|
|
3441
|
+
.mdx-hero:not(.has-image){grid-template-columns:1fr}
|
|
3442
|
+
.mdx-hero-copy{min-width:0}
|
|
3443
|
+
.mdx-hero-eyebrow{margin:0 0 .75rem;color:var(--hono-decks-accent-color);text-transform:uppercase;font-size:.85rem;letter-spacing:0}
|
|
3444
|
+
.mdx-hero h1{margin:0;font-size:3rem;line-height:1.02}
|
|
3445
|
+
.mdx-hero-subtitle{margin:1rem 0 0;font-size:1.125rem;line-height:1.45;color:var(--hono-decks-muted-color)}
|
|
3446
|
+
.mdx-hero-image{width:100%;height:auto;max-height:756px;object-fit:contain;border-radius:8px}
|
|
3447
|
+
[data-hono-decks-fire]{--fire-duration:.18s;--fire-easing:ease;--fire-opacity:0;--fire-transform:translateY(.35rem);--fire-filter:none;visibility:visible;opacity:1;transform:none;filter:none;transition:visibility 0s linear 0s,opacity var(--fire-duration) var(--fire-easing),transform var(--fire-duration) var(--fire-easing),filter var(--fire-duration) var(--fire-easing)}
|
|
3448
|
+
[data-hono-decks-fire][data-fire-hidden]{visibility:hidden;opacity:var(--fire-opacity);transform:var(--fire-transform);filter:var(--fire-filter);transition-delay:var(--fire-duration),0s,0s,0s}
|
|
3449
|
+
[data-fire-effect=none]{--fire-duration:0s;--fire-transform:none}
|
|
3450
|
+
[data-fire-effect=fade]{--fire-transform:none}
|
|
3451
|
+
[data-fire-effect=fade-up]{--fire-transform:translateY(.85rem)}
|
|
3452
|
+
[data-fire-effect=scale]{--fire-transform:scale(.96)}
|
|
3453
|
+
body:not([data-overview-mode]) .hono-decks-deck{position:relative}
|
|
3454
|
+
body:not([data-overview-mode]) .slide{position:absolute;inset:0;width:100%;height:100%}
|
|
3455
|
+
.slide[data-active-transition]{transition:opacity var(--hono-decks-active-transition-duration,var(--hono-decks-slide-transition-duration,var(--hono-decks-transition-duration))) var(--hono-decks-active-transition-easing,var(--hono-decks-slide-transition-easing,var(--hono-decks-transition-easing))),transform var(--hono-decks-active-transition-duration,var(--hono-decks-slide-transition-duration,var(--hono-decks-transition-duration))) var(--hono-decks-active-transition-easing,var(--hono-decks-slide-transition-easing,var(--hono-decks-transition-easing)));will-change:opacity,transform}
|
|
3456
|
+
.slide[data-slide-state="inactive"]{visibility:hidden;pointer-events:none}
|
|
3457
|
+
.slide[data-slide-state="active"]{visibility:visible;opacity:1;transform:translate3d(0,0,0) scale(1)}
|
|
3458
|
+
.slide[data-active-transition="fade"][data-slide-state="entering"],.slide[data-active-transition="fade"][data-slide-state="leaving"],.slide[data-active-transition="view-transition"][data-slide-state="entering"],.slide[data-active-transition="view-transition"][data-slide-state="leaving"]{opacity:0}
|
|
3459
|
+
.slide[data-active-transition="fade-out"][data-slide-state="entering"]{opacity:1}
|
|
3460
|
+
.slide[data-active-transition="fade-out"][data-slide-state="leaving"]{opacity:0}
|
|
3461
|
+
.slide[data-active-transition="slide-left"][data-slide-direction="forward"][data-slide-state="entering"],.slide[data-active-transition="slide-right"][data-slide-direction="backward"][data-slide-state="leaving"]{transform:translate3d(100%,0,0)}
|
|
3462
|
+
.slide[data-active-transition="slide-left"][data-slide-direction="forward"][data-slide-state="leaving"],.slide[data-active-transition="slide-right"][data-slide-direction="backward"][data-slide-state="entering"]{transform:translate3d(-100%,0,0)}
|
|
3463
|
+
.slide[data-active-transition="slide-left"][data-slide-direction="backward"][data-slide-state="entering"],.slide[data-active-transition="slide-right"][data-slide-direction="forward"][data-slide-state="leaving"]{transform:translate3d(-100%,0,0)}
|
|
3464
|
+
.slide[data-active-transition="slide-left"][data-slide-direction="backward"][data-slide-state="leaving"],.slide[data-active-transition="slide-right"][data-slide-direction="forward"][data-slide-state="entering"]{transform:translate3d(100%,0,0)}
|
|
3465
|
+
.slide[data-active-transition="slide-up"][data-slide-direction="forward"][data-slide-state="entering"],.slide[data-active-transition="slide-down"][data-slide-direction="backward"][data-slide-state="leaving"]{transform:translate3d(0,100%,0)}
|
|
3466
|
+
.slide[data-active-transition="slide-up"][data-slide-direction="forward"][data-slide-state="leaving"],.slide[data-active-transition="slide-down"][data-slide-direction="backward"][data-slide-state="entering"]{transform:translate3d(0,-100%,0)}
|
|
3467
|
+
.slide[data-active-transition="slide-up"][data-slide-direction="backward"][data-slide-state="entering"],.slide[data-active-transition="slide-down"][data-slide-direction="forward"][data-slide-state="leaving"]{transform:translate3d(0,-100%,0)}
|
|
3468
|
+
.slide[data-active-transition="slide-up"][data-slide-direction="backward"][data-slide-state="leaving"],.slide[data-active-transition="slide-down"][data-slide-direction="forward"][data-slide-state="entering"]{transform:translate3d(0,100%,0)}
|
|
3469
|
+
body:not([data-overview-mode]) .slide[hidden]{display:none}
|
|
3470
|
+
body[data-overview-mode] .hono-decks-deck{grid-template-columns:repeat(auto-fit,minmax(260px,1fr))}
|
|
3471
|
+
body[data-overview-mode] .slide{cursor:pointer}
|
|
3472
|
+
body[data-presenter-mode] .speaker-notes{display:block;margin-top:1rem;padding:.75rem;border-radius:8px;background:var(--hono-decks-card-image-background)}
|
|
3473
|
+
.hono-decks-warnings{margin:1rem;padding:.75rem;border-radius:14px;background:var(--hono-decks-warning-background);color:var(--hono-decks-warning-color)}
|
|
3474
|
+
@media screen{html[data-hono-decks-print-preview]{width:auto;height:auto;min-height:100%;overflow:visible}
|
|
3475
|
+
body[data-hono-decks-print-preview]{min-height:100vh;overflow:auto;color-scheme:light;color:#000;--hono-decks-print-gap:6mm;--hono-decks-print-slot-height:80mm;--hono-decks-print-scale:.28}
|
|
3476
|
+
body[data-hono-decks-print-preview] .hono-decks-stage{display:block;width:auto;height:auto;min-height:100vh;overflow:visible;padding:12mm 0;box-sizing:border-box}
|
|
3477
|
+
body[data-hono-decks-print-preview] .hono-decks-deck{display:grid;grid-template-columns:1fr;grid-auto-rows:var(--hono-decks-print-slot-height);gap:var(--hono-decks-print-gap);width:calc(var(--hono-decks-print-slot-height) * 16 / 9);max-width:calc(100vw - 24px);height:auto;margin:0 auto;transform:none!important}
|
|
3478
|
+
body[data-hono-decks-print-preview] .slide{position:static;width:100%;max-width:100%;height:var(--hono-decks-print-slot-height);aspect-ratio:16/9;justify-self:center;align-self:center;padding:0;box-shadow:0 2px 10px rgba(15,23,42,.16);transition:none!important;transform:none!important}
|
|
3479
|
+
body[data-hono-decks-print-preview] .slide.layout-cover,body[data-hono-decks-print-preview] .slide.layout-statement{display:block}
|
|
3480
|
+
body[data-hono-decks-print-preview] .hono-decks-slide-content{width:var(--hono-decks-width);height:var(--hono-decks-height);box-sizing:border-box;padding:1.8rem;transform:scale(var(--hono-decks-print-scale));transform-origin:left top;overflow:hidden}
|
|
3481
|
+
body[data-hono-decks-print-preview]:not([data-overview-mode]) .slide[hidden]{display:block!important}
|
|
3482
|
+
body[data-hono-decks-print-preview] .slide[data-slide-state]{visibility:visible!important;opacity:1!important;transform:none!important}
|
|
3483
|
+
body[data-hono-decks-print-preview] [data-hono-decks-fire]{visibility:visible!important;opacity:1!important;transform:none!important;filter:none!important}}
|
|
3484
|
+
@page{size:A4 portrait;margin:12mm}
|
|
3485
|
+
@media print{:root{color-scheme:light;color:#000;--hono-decks-print-gap:6mm;--hono-decks-print-slot-height:80mm;--hono-decks-print-scale:.28}html,body{width:auto;height:auto;overflow:visible}.hono-decks-stage{display:block;width:auto;height:auto;overflow:visible}.hono-decks-deck{display:grid;grid-template-columns:1fr;grid-auto-rows:var(--hono-decks-print-slot-height);gap:var(--hono-decks-print-gap);width:calc(var(--hono-decks-print-slot-height) * 16 / 9);height:auto;margin:0 auto;transform:none!important}body:not([data-overview-mode]) .slide{position:relative}.slide{position:relative;width:100%;max-width:100%;height:var(--hono-decks-print-slot-height);aspect-ratio:16/9;justify-self:center;align-self:center;padding:0;page-break-after:auto;break-after:auto;break-inside:avoid;box-shadow:none;transition:none!important;transform:none!important}.slide.layout-cover,.slide.layout-statement{display:block}.hono-decks-slide-content{position:absolute;inset:0 auto auto 0;width:var(--hono-decks-width);height:var(--hono-decks-height);box-sizing:border-box;padding:1.8rem;zoom:var(--hono-decks-print-scale);overflow:hidden}.slide:nth-of-type(3n):not(:last-child){page-break-after:always;break-after:page}body:not([data-overview-mode]) .slide[hidden]{display:block!important}.slide[data-slide-state]{visibility:visible!important;opacity:1!important;transform:none!important}[data-hono-decks-fire]{visibility:visible!important;opacity:1!important;transform:none!important;filter:none!important}}
|
|
3486
|
+
@media print{.hono-decks-embed-viewport iframe,.hono-decks-tweet-embed iframe,.hono-decks-tweet-embed .twitter-tweet{display:none!important}.hono-decks-embed-print-fallback{display:grid;width:100%;height:100%;place-items:center;overflow:hidden;background:var(--hono-decks-card-background);color:var(--hono-decks-accent-color);text-decoration:none}.hono-decks-embed-print-fallback:has(.hono-decks-embed-print-poster){display:block}.hono-decks-embed-print-poster+span{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}.hono-decks-tweet-print-fallback{display:flex;min-height:12rem;align-items:center;justify-content:center;border:1px solid var(--hono-decks-border-color);border-radius:8px;background:var(--hono-decks-card-background);color:var(--hono-decks-accent-color);text-decoration:none}}
|
|
3487
|
+
@media (prefers-reduced-motion: reduce){*,*::before,*::after{scroll-behavior:auto!important;animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important;transition-delay:0s!important}.slide[data-active-transition]{transform:none!important}}`;
|
|
3488
|
+
}
|
|
3489
|
+
//#endregion
|
|
3090
3490
|
//#region src/server/document.ts
|
|
3091
3491
|
async function resolveDeckDocument(input, options, overrides) {
|
|
3092
3492
|
const page = {
|
|
@@ -3138,8 +3538,8 @@ function renderPresentationScript(nonce) {
|
|
|
3138
3538
|
const slides = Array.from(document.querySelectorAll(".slide"));
|
|
3139
3539
|
const stage = document.querySelector("[data-hono-decks-stage]");
|
|
3140
3540
|
const deck = document.querySelector("[data-hono-decks-deck]");
|
|
3141
|
-
const DESIGN_WIDTH =
|
|
3142
|
-
const DESIGN_HEIGHT =
|
|
3541
|
+
const DESIGN_WIDTH = ${PRESENTATION_DESIGN_WIDTH};
|
|
3542
|
+
const DESIGN_HEIGHT = ${PRESENTATION_DESIGN_HEIGHT};
|
|
3143
3543
|
let index = 0;
|
|
3144
3544
|
let previousIndex = 0;
|
|
3145
3545
|
let stepIndex = 0;
|
|
@@ -3524,6 +3924,10 @@ function renderPresentationScript(nonce) {
|
|
|
3524
3924
|
});
|
|
3525
3925
|
|
|
3526
3926
|
document.addEventListener("keydown", (event) => {
|
|
3927
|
+
if (event.defaultPrevented || event.metaKey || event.ctrlKey || event.altKey) return;
|
|
3928
|
+
const target = event.target;
|
|
3929
|
+
if (target instanceof HTMLElement && (target.isContentEditable || target.closest("input,textarea,select,button,a[href],[role=textbox],[role=button],[role=slider]"))) return;
|
|
3930
|
+
if (["ArrowRight", "ArrowLeft", " "].includes(event.key)) event.preventDefault();
|
|
3527
3931
|
if (event.key === "ArrowRight" || event.key === " ") handleCommand("next");
|
|
3528
3932
|
if (event.key === "ArrowLeft") handleCommand("previous");
|
|
3529
3933
|
if (event.key === "f") handleCommand("fullscreen");
|
|
@@ -3543,6 +3947,9 @@ function renderPresentationScript(nonce) {
|
|
|
3543
3947
|
window.__honoDecksPresentationRuntime = { command: handleCommand };
|
|
3544
3948
|
|
|
3545
3949
|
window.addEventListener("resize", fitDeck);
|
|
3950
|
+
if (typeof ResizeObserver !== "undefined" && stage instanceof HTMLElement) {
|
|
3951
|
+
new ResizeObserver(fitDeck).observe(stage);
|
|
3952
|
+
}
|
|
3546
3953
|
fitDeck();
|
|
3547
3954
|
const initialState = readInitialState();
|
|
3548
3955
|
show(initialState.index, initialState.stepIndex);
|
|
@@ -3553,109 +3960,6 @@ function escapeHtml$7(value) {
|
|
|
3553
3960
|
return value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll("\"", """).replaceAll("'", "'");
|
|
3554
3961
|
}
|
|
3555
3962
|
//#endregion
|
|
3556
|
-
//#region src/renderer/presentation-style.ts
|
|
3557
|
-
const PRESENTATION_DESIGN_WIDTH = 1920;
|
|
3558
|
-
const PRESENTATION_DESIGN_HEIGHT = 1080;
|
|
3559
|
-
function presentationDesignCssVariables() {
|
|
3560
|
-
return `--hono-decks-width:${PRESENTATION_DESIGN_WIDTH}px;--hono-decks-height:${PRESENTATION_DESIGN_HEIGHT}px`;
|
|
3561
|
-
}
|
|
3562
|
-
function basePresentationStyle() {
|
|
3563
|
-
return `
|
|
3564
|
-
:root{color-scheme:dark;font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;font-size:32px;${presentationDesignCssVariables()};--hono-decks-transition-duration:.24s;--hono-decks-transition-easing:ease;--hono-decks-color:#eef2ff;--hono-decks-muted-color:#cbd5e1;--hono-decks-accent-color:#8bd3ff;--hono-decks-border-color:rgba(148,163,184,.24);--hono-decks-inline-code-background:rgba(15,23,42,.72);--hono-decks-code-background:rgba(15,23,42,.78);--hono-decks-card-background:rgba(15,23,42,.78);--hono-decks-card-image-background:rgba(255,255,255,.08);--hono-decks-warning-background:rgba(255,193,7,.12);--hono-decks-warning-color:#ffe59b;color:var(--hono-decks-color)}
|
|
3565
|
-
html,body{margin:0;width:100%;height:100%;overflow:hidden}
|
|
3566
|
-
.hono-decks-stage{width:100vw;height:100vh;overflow:hidden;position:relative;display:grid;place-items:center}
|
|
3567
|
-
.hono-decks-deck{display:grid;gap:1rem;width:var(--hono-decks-width);height:var(--hono-decks-height);box-sizing:border-box;transform-origin:left top}
|
|
3568
|
-
.slide{box-sizing:border-box;aspect-ratio:16/9;padding:clamp(1.2rem,3vw,3rem);overflow:hidden}
|
|
3569
|
-
.hono-decks-slide-content{width:100%;height:100%}
|
|
3570
|
-
.slide.layout-cover,.slide.layout-statement{display:flex;flex-direction:column;justify-content:center}
|
|
3571
|
-
.slide.layout-cover>.hono-decks-slide-content,.slide.layout-statement>.hono-decks-slide-content{display:flex;flex-direction:column;justify-content:center}
|
|
3572
|
-
.slide code{font-family:"SFMono-Regular","Cascadia Code","Liberation Mono",Menlo,Consolas,monospace;font-size:.9em;line-height:1.45}
|
|
3573
|
-
.slide :not(pre)>code{border-radius:6px;background:var(--hono-decks-inline-code-background);padding:.12em .34em}
|
|
3574
|
-
.slide pre{max-width:100%;overflow:auto;box-sizing:border-box;border:1px solid var(--hono-decks-border-color);border-radius:8px;background:var(--hono-decks-code-background);padding:1rem;tab-size:2;white-space:pre}
|
|
3575
|
-
.slide pre code{display:block;min-width:max-content;background:transparent;padding:0}
|
|
3576
|
-
.slide table{width:100%;margin:1rem 0;border-collapse:collapse}
|
|
3577
|
-
.slide th,.slide td{border:1px solid var(--hono-decks-border-color);padding:.4em .75em;text-align:left}
|
|
3578
|
-
.slide th{background:var(--hono-decks-card-background);font-weight:700}
|
|
3579
|
-
.slide del{color:var(--hono-decks-muted-color)}
|
|
3580
|
-
.slide li.task-list-item{list-style:none;margin-left:-1.4em}
|
|
3581
|
-
.slide li.task-list-item input[type=checkbox]{margin-right:.5em;vertical-align:middle}
|
|
3582
|
-
.hono-decks-code-block{margin:1rem 0;max-width:100%}
|
|
3583
|
-
.hono-decks-code-caption{display:inline-flex;margin:0 0 .4rem;border:1px solid var(--hono-decks-border-color);border-radius:6px;padding:.2rem .5rem;background:var(--hono-decks-inline-code-background);color:var(--hono-decks-muted-color);font-size:.82rem}
|
|
3584
|
-
.hono-decks-embed-frame{margin:1rem 0;max-width:100%}
|
|
3585
|
-
.hono-decks-embed-viewport{width:min(100%,72rem);overflow:hidden}
|
|
3586
|
-
.hono-decks-embed-viewport iframe{display:block;width:100%;height:100%;border:0}
|
|
3587
|
-
.hono-decks-embed-print-fallback{display:none}
|
|
3588
|
-
.hono-decks-embed-print-poster{display:block;width:100%;height:100%;object-fit:cover}
|
|
3589
|
-
.hono-decks-embed-fallback{margin:.45rem 0 0;color:var(--hono-decks-muted-color);font-size:.84rem}
|
|
3590
|
-
.hono-decks-embed-fallback a{color:inherit}
|
|
3591
|
-
.hono-decks-social-embed{margin:1rem 0;max-width:min(100%,42rem)}
|
|
3592
|
-
.hono-decks-social-card{margin:0;border:1px solid var(--hono-decks-border-color);border-radius:8px;background:var(--hono-decks-card-background);padding:1rem}
|
|
3593
|
-
.hono-decks-social-card p{margin:0 0 .75rem;line-height:1.55}
|
|
3594
|
-
.hono-decks-social-card footer{display:flex;flex-wrap:wrap;gap:.65rem;align-items:center;color:var(--hono-decks-muted-color);font-size:.9rem}
|
|
3595
|
-
.hono-decks-social-card a{color:inherit}
|
|
3596
|
-
.hono-decks-tweet-embed{margin:1rem 0;max-width:min(100%,42rem)}
|
|
3597
|
-
.hono-decks-tweet-embed .twitter-tweet{margin:0;border:1px solid var(--hono-decks-border-color);border-radius:8px;background:var(--hono-decks-card-background);padding:1rem}
|
|
3598
|
-
.hono-decks-tweet-embed .twitter-tweet a{color:inherit}
|
|
3599
|
-
.hono-decks-tweet-print-fallback{display:none}
|
|
3600
|
-
.hono-decks-link-card{margin:1rem 0;max-width:min(100%,42rem)}
|
|
3601
|
-
.hono-decks-link-card-anchor{display:grid;grid-template-columns:minmax(9rem,32%) minmax(0,1fr);gap:.75rem;align-items:stretch;border:1px solid var(--hono-decks-border-color);border-radius:8px;background:var(--hono-decks-card-background);padding:1rem;color:inherit;text-decoration:none}
|
|
3602
|
-
.hono-decks-link-card-body{display:grid;gap:.35rem;min-width:0}
|
|
3603
|
-
.hono-decks-link-card-image{width:100%;height:100%;max-height:10rem;aspect-ratio:16/9;object-fit:cover;border-radius:6px;background:var(--hono-decks-card-image-background)}
|
|
3604
|
-
.hono-decks-link-card-site{color:var(--hono-decks-accent-color);font-size:.8rem;text-transform:uppercase}
|
|
3605
|
-
.hono-decks-link-card-title{font-weight:700}
|
|
3606
|
-
.hono-decks-link-card-description{color:var(--hono-decks-muted-color);line-height:1.45}
|
|
3607
|
-
.hono-decks-link-card-label{color:var(--hono-decks-accent-color);font-size:.88rem}
|
|
3608
|
-
@media (max-width: 640px){.hono-decks-link-card-anchor{grid-template-columns:1fr}.hono-decks-link-card-image{height:auto;max-height:12rem}}
|
|
3609
|
-
.mdx-hero{height:100%;display:grid;grid-template-columns:minmax(0,1fr) minmax(280px,42%);gap:clamp(1rem,3vw,3rem);align-items:center}
|
|
3610
|
-
.mdx-hero:not(.has-image){grid-template-columns:1fr}
|
|
3611
|
-
.mdx-hero-copy{min-width:0}
|
|
3612
|
-
.mdx-hero-eyebrow{margin:0 0 .75rem;color:var(--hono-decks-accent-color);text-transform:uppercase;font-size:.85rem;letter-spacing:0}
|
|
3613
|
-
.mdx-hero h1{margin:0;font-size:clamp(2.2rem,5vw,5rem);line-height:1.02}
|
|
3614
|
-
.mdx-hero-subtitle{margin:1rem 0 0;font-size:clamp(1rem,1.8vw,1.5rem);line-height:1.45;color:var(--hono-decks-muted-color)}
|
|
3615
|
-
.mdx-hero-image{width:100%;height:auto;max-height:70vh;object-fit:contain;border-radius:8px}
|
|
3616
|
-
[data-hono-decks-fire]{--fire-duration:.18s;--fire-easing:ease;--fire-opacity:0;--fire-transform:translateY(.35rem);--fire-filter:none;visibility:visible;opacity:1;transform:none;filter:none;transition:visibility 0s linear 0s,opacity var(--fire-duration) var(--fire-easing),transform var(--fire-duration) var(--fire-easing),filter var(--fire-duration) var(--fire-easing)}
|
|
3617
|
-
[data-hono-decks-fire][data-fire-hidden]{visibility:hidden;opacity:var(--fire-opacity);transform:var(--fire-transform);filter:var(--fire-filter);transition-delay:var(--fire-duration),0s,0s,0s}
|
|
3618
|
-
[data-fire-effect=none]{--fire-duration:0s;--fire-transform:none}
|
|
3619
|
-
[data-fire-effect=fade]{--fire-transform:none}
|
|
3620
|
-
[data-fire-effect=fade-up]{--fire-transform:translateY(.85rem)}
|
|
3621
|
-
[data-fire-effect=scale]{--fire-transform:scale(.96)}
|
|
3622
|
-
body:not([data-overview-mode]) .hono-decks-deck{position:relative}
|
|
3623
|
-
body:not([data-overview-mode]) .slide{position:absolute;inset:0;width:100%;height:100%}
|
|
3624
|
-
.slide[data-active-transition]{transition:opacity var(--hono-decks-active-transition-duration,var(--hono-decks-slide-transition-duration,var(--hono-decks-transition-duration))) var(--hono-decks-active-transition-easing,var(--hono-decks-slide-transition-easing,var(--hono-decks-transition-easing))),transform var(--hono-decks-active-transition-duration,var(--hono-decks-slide-transition-duration,var(--hono-decks-transition-duration))) var(--hono-decks-active-transition-easing,var(--hono-decks-slide-transition-easing,var(--hono-decks-transition-easing)));will-change:opacity,transform}
|
|
3625
|
-
.slide[data-slide-state="inactive"]{visibility:hidden;pointer-events:none}
|
|
3626
|
-
.slide[data-slide-state="active"]{visibility:visible;opacity:1;transform:translate3d(0,0,0) scale(1)}
|
|
3627
|
-
.slide[data-active-transition="fade"][data-slide-state="entering"],.slide[data-active-transition="fade"][data-slide-state="leaving"],.slide[data-active-transition="view-transition"][data-slide-state="entering"],.slide[data-active-transition="view-transition"][data-slide-state="leaving"]{opacity:0}
|
|
3628
|
-
.slide[data-active-transition="fade-out"][data-slide-state="entering"]{opacity:1}
|
|
3629
|
-
.slide[data-active-transition="fade-out"][data-slide-state="leaving"]{opacity:0}
|
|
3630
|
-
.slide[data-active-transition="slide-left"][data-slide-direction="forward"][data-slide-state="entering"],.slide[data-active-transition="slide-right"][data-slide-direction="backward"][data-slide-state="leaving"]{transform:translate3d(100%,0,0)}
|
|
3631
|
-
.slide[data-active-transition="slide-left"][data-slide-direction="forward"][data-slide-state="leaving"],.slide[data-active-transition="slide-right"][data-slide-direction="backward"][data-slide-state="entering"]{transform:translate3d(-100%,0,0)}
|
|
3632
|
-
.slide[data-active-transition="slide-left"][data-slide-direction="backward"][data-slide-state="entering"],.slide[data-active-transition="slide-right"][data-slide-direction="forward"][data-slide-state="leaving"]{transform:translate3d(-100%,0,0)}
|
|
3633
|
-
.slide[data-active-transition="slide-left"][data-slide-direction="backward"][data-slide-state="leaving"],.slide[data-active-transition="slide-right"][data-slide-direction="forward"][data-slide-state="entering"]{transform:translate3d(100%,0,0)}
|
|
3634
|
-
.slide[data-active-transition="slide-up"][data-slide-direction="forward"][data-slide-state="entering"],.slide[data-active-transition="slide-down"][data-slide-direction="backward"][data-slide-state="leaving"]{transform:translate3d(0,100%,0)}
|
|
3635
|
-
.slide[data-active-transition="slide-up"][data-slide-direction="forward"][data-slide-state="leaving"],.slide[data-active-transition="slide-down"][data-slide-direction="backward"][data-slide-state="entering"]{transform:translate3d(0,-100%,0)}
|
|
3636
|
-
.slide[data-active-transition="slide-up"][data-slide-direction="backward"][data-slide-state="entering"],.slide[data-active-transition="slide-down"][data-slide-direction="forward"][data-slide-state="leaving"]{transform:translate3d(0,-100%,0)}
|
|
3637
|
-
.slide[data-active-transition="slide-up"][data-slide-direction="backward"][data-slide-state="leaving"],.slide[data-active-transition="slide-down"][data-slide-direction="forward"][data-slide-state="entering"]{transform:translate3d(0,100%,0)}
|
|
3638
|
-
body:not([data-overview-mode]) .slide[hidden]{display:none}
|
|
3639
|
-
body[data-overview-mode] .hono-decks-deck{grid-template-columns:repeat(auto-fit,minmax(260px,1fr))}
|
|
3640
|
-
body[data-overview-mode] .slide{cursor:pointer}
|
|
3641
|
-
body[data-presenter-mode] .speaker-notes{display:block;margin-top:1rem;padding:.75rem;border-radius:8px;background:var(--hono-decks-card-image-background)}
|
|
3642
|
-
.hono-decks-warnings{margin:1rem;padding:.75rem;border-radius:14px;background:var(--hono-decks-warning-background);color:var(--hono-decks-warning-color)}
|
|
3643
|
-
@media screen{html[data-hono-decks-print-preview]{width:auto;height:auto;min-height:100%;overflow:visible}
|
|
3644
|
-
body[data-hono-decks-print-preview]{min-height:100vh;overflow:auto;color-scheme:light;color:#000;--hono-decks-print-gap:6mm;--hono-decks-print-slot-height:80mm;--hono-decks-print-scale:.28}
|
|
3645
|
-
body[data-hono-decks-print-preview] .hono-decks-stage{display:block;width:auto;height:auto;min-height:100vh;overflow:visible;padding:12mm 0;box-sizing:border-box}
|
|
3646
|
-
body[data-hono-decks-print-preview] .hono-decks-deck{display:grid;grid-template-columns:1fr;grid-auto-rows:var(--hono-decks-print-slot-height);gap:var(--hono-decks-print-gap);width:calc(var(--hono-decks-print-slot-height) * 16 / 9);max-width:calc(100vw - 24px);height:auto;margin:0 auto;transform:none!important}
|
|
3647
|
-
body[data-hono-decks-print-preview] .slide{position:static;width:100%;max-width:100%;height:var(--hono-decks-print-slot-height);aspect-ratio:16/9;justify-self:center;align-self:center;padding:0;box-shadow:0 2px 10px rgba(15,23,42,.16);transition:none!important;transform:none!important}
|
|
3648
|
-
body[data-hono-decks-print-preview] .slide.layout-cover,body[data-hono-decks-print-preview] .slide.layout-statement{display:block}
|
|
3649
|
-
body[data-hono-decks-print-preview] .hono-decks-slide-content{width:var(--hono-decks-width);height:var(--hono-decks-height);box-sizing:border-box;padding:clamp(1.2rem,3vw,3rem);transform:scale(var(--hono-decks-print-scale));transform-origin:left top;overflow:hidden}
|
|
3650
|
-
body[data-hono-decks-print-preview]:not([data-overview-mode]) .slide[hidden]{display:block!important}
|
|
3651
|
-
body[data-hono-decks-print-preview] .slide[data-slide-state]{visibility:visible!important;opacity:1!important;transform:none!important}
|
|
3652
|
-
body[data-hono-decks-print-preview] [data-hono-decks-fire]{visibility:visible!important;opacity:1!important;transform:none!important;filter:none!important}}
|
|
3653
|
-
@page{size:A4 portrait;margin:12mm}
|
|
3654
|
-
@media print{:root{color-scheme:light;color:#000;--hono-decks-print-gap:6mm;--hono-decks-print-slot-height:80mm;--hono-decks-print-scale:.28}html,body{width:auto;height:auto;overflow:visible}.hono-decks-stage{display:block;width:auto;height:auto;overflow:visible}.hono-decks-deck{display:grid;grid-template-columns:1fr;grid-auto-rows:var(--hono-decks-print-slot-height);gap:var(--hono-decks-print-gap);width:calc(var(--hono-decks-print-slot-height) * 16 / 9);height:auto;margin:0 auto;transform:none!important}body:not([data-overview-mode]) .slide{position:relative}.slide{position:relative;width:100%;max-width:100%;height:var(--hono-decks-print-slot-height);aspect-ratio:16/9;justify-self:center;align-self:center;padding:0;page-break-after:auto;break-after:auto;break-inside:avoid;box-shadow:none;transition:none!important;transform:none!important}.slide.layout-cover,.slide.layout-statement{display:block}.hono-decks-slide-content{position:absolute;inset:0 auto auto 0;width:var(--hono-decks-width);height:var(--hono-decks-height);box-sizing:border-box;padding:clamp(1.2rem,3vw,3rem);zoom:var(--hono-decks-print-scale);overflow:hidden}.slide:nth-of-type(3n):not(:last-child){page-break-after:always;break-after:page}body:not([data-overview-mode]) .slide[hidden]{display:block!important}.slide[data-slide-state]{visibility:visible!important;opacity:1!important;transform:none!important}[data-hono-decks-fire]{visibility:visible!important;opacity:1!important;transform:none!important;filter:none!important}}
|
|
3655
|
-
@media print{.hono-decks-embed-viewport iframe,.hono-decks-tweet-embed iframe,.hono-decks-tweet-embed .twitter-tweet{display:none!important}.hono-decks-embed-print-fallback{display:grid;width:100%;height:100%;place-items:center;overflow:hidden;background:var(--hono-decks-card-background);color:var(--hono-decks-accent-color);text-decoration:none}.hono-decks-embed-print-fallback:has(.hono-decks-embed-print-poster){display:block}.hono-decks-embed-print-poster+span{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}.hono-decks-tweet-print-fallback{display:flex;min-height:12rem;align-items:center;justify-content:center;border:1px solid var(--hono-decks-border-color);border-radius:8px;background:var(--hono-decks-card-background);color:var(--hono-decks-accent-color);text-decoration:none}}
|
|
3656
|
-
@media (prefers-reduced-motion: reduce){*,*::before,*::after{scroll-behavior:auto!important;animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important;transition-delay:0s!important}.slide[data-active-transition]{transform:none!important}}`;
|
|
3657
|
-
}
|
|
3658
|
-
//#endregion
|
|
3659
3963
|
//#region src/renderer/presentation-page.ts
|
|
3660
3964
|
function presentationPageTitle(deck) {
|
|
3661
3965
|
return deck.meta.title ?? deck.slug;
|
|
@@ -3949,12 +4253,16 @@ function slideStyleAttribute(slide, assets) {
|
|
|
3949
4253
|
if (slide.meta.transitionEasing) declarations.push(`--hono-decks-slide-transition-easing:${slide.meta.transitionEasing}`);
|
|
3950
4254
|
return declarations.length ? ` style="${escapeHtml$5(declarations.join(";"))}"` : "";
|
|
3951
4255
|
}
|
|
4256
|
+
function requireSlideHtml(slide) {
|
|
4257
|
+
if (typeof slide.html !== "string") throw new RenderError("Slide has no renderable body. Import createDecks() from the generated module; compileDecks() returns build information only.", "slide-body-missing");
|
|
4258
|
+
return slide.html;
|
|
4259
|
+
}
|
|
3952
4260
|
async function renderSlideBodyAsync(slide, assets, input) {
|
|
3953
4261
|
try {
|
|
3954
4262
|
return slide.render ? await renderJsxValue(slide.render({ components: createMdxComponents(input.components ?? builtInSlideComponents, { assets }) })) : slide.nodes?.length ? await renderSlideNodesAsync(slide.nodes, {
|
|
3955
4263
|
components: input.components,
|
|
3956
4264
|
assets
|
|
3957
|
-
}) : rewriteLocalAssetUrls(slide
|
|
4265
|
+
}) : rewriteLocalAssetUrls(requireSlideHtml(slide), assets);
|
|
3958
4266
|
} catch (error) {
|
|
3959
4267
|
if (error instanceof RenderError) throw error;
|
|
3960
4268
|
throw new RenderError(`Render failed in ${input.deck?.sourcePath ?? "unknown deck"} slide ${slide.index + 1}: ${formatErrorMessage$1(error)}`, "slide-render-error", error);
|
|
@@ -3981,7 +4289,7 @@ function formatErrorMessage$1(error) {
|
|
|
3981
4289
|
function serveDecksClientEntry(clientEntry, options = {}) {
|
|
3982
4290
|
return (c) => {
|
|
3983
4291
|
const headers = { "content-type": options.contentType ?? "text/javascript; charset=utf-8" };
|
|
3984
|
-
const cacheControl = options.cacheControl ?? "
|
|
4292
|
+
const cacheControl = options.cacheControl ?? "no-cache";
|
|
3985
4293
|
if (cacheControl !== false) headers["cache-control"] = cacheControl;
|
|
3986
4294
|
return c.body(clientEntry, 200, headers);
|
|
3987
4295
|
};
|
|
@@ -4275,6 +4583,7 @@ function renderViewerScript(nonce) {
|
|
|
4275
4583
|
}
|
|
4276
4584
|
|
|
4277
4585
|
function handleKeydown(event) {
|
|
4586
|
+
if (event.defaultPrevented) return;
|
|
4278
4587
|
if ((event.metaKey || event.ctrlKey) && event.key.toLowerCase() === "p" && printPath) {
|
|
4279
4588
|
event.preventDefault();
|
|
4280
4589
|
const printUrl = new URL(printPath, window.location.href);
|
|
@@ -4282,6 +4591,10 @@ function renderViewerScript(nonce) {
|
|
|
4282
4591
|
window.location.assign(printUrl);
|
|
4283
4592
|
return;
|
|
4284
4593
|
}
|
|
4594
|
+
if (event.metaKey || event.ctrlKey || event.altKey) return;
|
|
4595
|
+
const target = event.target;
|
|
4596
|
+
if (target instanceof HTMLElement && (target.isContentEditable || target.closest("input,textarea,select,button,a[href],[role=textbox],[role=button],[role=slider]"))) return;
|
|
4597
|
+
if (["ArrowRight", "ArrowLeft", " "].includes(event.key)) event.preventDefault();
|
|
4285
4598
|
if (event.key === "ArrowRight" || event.key === " ") sendCommand("next");
|
|
4286
4599
|
if (event.key === "ArrowLeft") sendCommand("previous");
|
|
4287
4600
|
if (event.key === "f") void toggleViewerFullscreen();
|
|
@@ -4345,7 +4658,7 @@ function baseViewerStyle() {
|
|
|
4345
4658
|
html,body{margin:0;width:100%;height:100%;min-height:100vh}
|
|
4346
4659
|
@supports (height:100dvh){html,body{height:100dvh;min-height:100dvh}}
|
|
4347
4660
|
body{overflow:hidden}
|
|
4348
|
-
*:focus-visible{outline:
|
|
4661
|
+
*:focus-visible{outline:2px solid currentColor;outline-offset:2px}
|
|
4349
4662
|
[data-hono-decks-viewer]{width:100%;height:100vh;min-height:0;display:grid;place-items:center;box-sizing:border-box;overflow:hidden}
|
|
4350
4663
|
@supports (height:100dvh){[data-hono-decks-viewer]{height:100dvh}}
|
|
4351
4664
|
.hono-decks-viewer-header{position:absolute;width:1px;height:1px;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
|
|
@@ -4363,7 +4676,7 @@ ${viewerViewportRule()}
|
|
|
4363
4676
|
.hono-decks-mobile-navigation:focus-visible{outline:2px solid currentColor;outline-offset:-4px}
|
|
4364
4677
|
.hono-decks-mobile-navigation:active{background:rgba(15,23,42,.28);color:#eef2ff;opacity:1}
|
|
4365
4678
|
.hono-decks-mobile-navigation .hono-decks-control-icon{width:22px;height:22px}
|
|
4366
|
-
.hono-decks-viewport>[data-hono-decks-position]{position:absolute;left:50%;bottom:max(8px,env(safe-area-inset-bottom,0));z-index:3;transform:translateX(-50%);border:0;background:
|
|
4679
|
+
.hono-decks-viewport>[data-hono-decks-position]{position:absolute;left:50%;bottom:max(8px,env(safe-area-inset-bottom,0));z-index:3;transform:translateX(-50%);border:0;border-radius:4px;background:rgba(15,23,42,.9);color:#eef2ff;padding:4px 6px;font:inherit;font-size:12px;line-height:1;opacity:1;pointer-events:none;white-space:nowrap}
|
|
4367
4680
|
.hono-decks-viewer-controls{position:absolute;left:50%;bottom:max(.25rem,env(safe-area-inset-bottom,0));display:flex;gap:8px;align-items:center;justify-content:center;max-width:calc(100% - 1rem);min-width:0;z-index:4;transform:translateX(-50%)}
|
|
4368
4681
|
.hono-decks-viewer-controls [data-hono-decks-navigation-control="previous"],.hono-decks-viewer-controls [data-hono-decks-navigation-control="next"],.hono-decks-viewer-controls [data-hono-decks-position]{position:absolute;visibility:hidden;pointer-events:none}
|
|
4369
4682
|
.hono-decks-viewer-controls button,.hono-decks-viewer-controls a,.hono-decks-viewer-controls span{border:1px solid rgba(148,163,184,.32);border-radius:8px;background:rgba(15,23,42,.78);color:inherit;padding:8px 10px;font:inherit;font-size:14px}
|
|
@@ -4380,7 +4693,7 @@ ${viewerViewportRule()}
|
|
|
4380
4693
|
function embeddedViewerStyle() {
|
|
4381
4694
|
const root = "[data-hono-decks-viewer][data-hono-decks-embed]";
|
|
4382
4695
|
return `${root}{color-scheme:dark;background:#050816;color:#eef2ff;font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;display:grid;gap:12px;width:100%;min-width:0;box-sizing:border-box}
|
|
4383
|
-
${root} *:focus-visible{outline:
|
|
4696
|
+
${root} *:focus-visible{outline:2px solid currentColor;outline-offset:2px}
|
|
4384
4697
|
${root} .hono-decks-viewer-shell{position:relative;display:grid;grid-template-rows:minmax(0,1fr);place-items:center;width:100%;min-width:0;min-height:0;box-sizing:border-box}
|
|
4385
4698
|
${root} .hono-decks-viewer-stage{display:grid;place-items:center;width:100%;min-width:0;min-height:0;container-type:inline-size}
|
|
4386
4699
|
${root} .hono-decks-viewport{width:100%;aspect-ratio:${VIEWER_ASPECT_RATIO};position:relative;overflow:hidden;touch-action:pan-y}
|
|
@@ -4393,7 +4706,7 @@ ${root} .hono-decks-mobile-navigation-next{right:.25rem}
|
|
|
4393
4706
|
${root} .hono-decks-mobile-navigation:focus-visible{outline:2px solid currentColor;outline-offset:-4px}
|
|
4394
4707
|
${root} .hono-decks-mobile-navigation:active{background:rgba(15,23,42,.28);color:#eef2ff;opacity:1}
|
|
4395
4708
|
${root} .hono-decks-mobile-navigation .hono-decks-control-icon{width:22px;height:22px}
|
|
4396
|
-
${root} .hono-decks-viewport>[data-hono-decks-position]{position:absolute;left:50%;bottom:8px;z-index:3;transform:translateX(-50%);border:0;background:
|
|
4709
|
+
${root} .hono-decks-viewport>[data-hono-decks-position]{position:absolute;left:50%;bottom:8px;z-index:3;transform:translateX(-50%);border:0;border-radius:4px;background:rgba(15,23,42,.9);color:#eef2ff;padding:4px 6px;font:inherit;font-size:12px;line-height:1;opacity:1;pointer-events:none;white-space:nowrap}
|
|
4397
4710
|
${root} .hono-decks-viewer-controls{position:absolute;left:50%;bottom:max(.25rem,env(safe-area-inset-bottom,0));display:flex;gap:8px;align-items:center;justify-content:center;max-width:calc(100% - 1rem);min-width:0;z-index:4;transform:translateX(-50%)}
|
|
4398
4711
|
${root} .hono-decks-viewer-controls [data-hono-decks-navigation-control="previous"],${root} .hono-decks-viewer-controls [data-hono-decks-navigation-control="next"],${root} .hono-decks-viewer-controls [data-hono-decks-position]{position:absolute;visibility:hidden;pointer-events:none}
|
|
4399
4712
|
${root} .hono-decks-viewer-controls button,${root} .hono-decks-viewer-controls a,${root} .hono-decks-viewer-controls span{border:1px solid rgba(148,163,184,.32);border-radius:8px;background:rgba(15,23,42,.78);color:inherit;padding:8px 10px;font:inherit;font-size:14px}
|
|
@@ -5034,7 +5347,7 @@ function decksRouter(options) {
|
|
|
5034
5347
|
slug,
|
|
5035
5348
|
surface: "render"
|
|
5036
5349
|
}, 404);
|
|
5037
|
-
const clientEntry = options.clientEntry ?? resolveGeneratedClientEntryUrl(options, mountPath);
|
|
5350
|
+
const clientEntry = options.clientEntry ?? (deck.clientEntryRequired === false ? void 0 : resolveGeneratedClientEntryUrl(options, mountPath));
|
|
5038
5351
|
try {
|
|
5039
5352
|
const document = await resolveRouterDocument(c, options, "render", mountPath, deck);
|
|
5040
5353
|
return c.html(await renderCompiledDeckPageAsync({
|
|
@@ -5139,7 +5452,7 @@ function decksRouter(options) {
|
|
|
5139
5452
|
slug,
|
|
5140
5453
|
surface: "presentation"
|
|
5141
5454
|
}, 404);
|
|
5142
|
-
const clientEntry = options.clientEntry ?? resolveGeneratedClientEntryUrl(options, mountPath);
|
|
5455
|
+
const clientEntry = options.clientEntry ?? (deck.clientEntryRequired === false ? void 0 : resolveGeneratedClientEntryUrl(options, mountPath));
|
|
5143
5456
|
try {
|
|
5144
5457
|
const document = await resolveRouterDocument(c, options, "presentation", mountPath, deck);
|
|
5145
5458
|
return c.html(await renderCompiledDeckPageAsync({
|
|
@@ -5419,7 +5732,7 @@ const DEFAULT_DECKS_CONFIG_FILE = "hono-decks.config.ts";
|
|
|
5419
5732
|
async function loadDecksConfig(input) {
|
|
5420
5733
|
const path = resolve(input.cwd, input.configFile ?? "hono-decks.config.ts");
|
|
5421
5734
|
if (!existsSync(path)) throw new Error(`Config file not found: ${input.configFile ?? "hono-decks.config.ts"}. Run \`hono-decks init\` first.`);
|
|
5422
|
-
const
|
|
5735
|
+
const result = await build({
|
|
5423
5736
|
absWorkingDir: input.cwd,
|
|
5424
5737
|
entryPoints: [path],
|
|
5425
5738
|
bundle: true,
|
|
@@ -5427,16 +5740,20 @@ async function loadDecksConfig(input) {
|
|
|
5427
5740
|
platform: "node",
|
|
5428
5741
|
target: "node20",
|
|
5429
5742
|
write: false,
|
|
5743
|
+
metafile: true,
|
|
5430
5744
|
logLevel: "silent",
|
|
5431
5745
|
alias: { "hono-decks": resolveRuntimeEntry() }
|
|
5432
|
-
})
|
|
5746
|
+
});
|
|
5747
|
+
const source = result.outputFiles[0]?.text;
|
|
5433
5748
|
if (!source) throw new Error(`Could not load config file: ${path}`);
|
|
5434
5749
|
const config = (await import(`data:text/javascript;charset=utf-8,${encodeURIComponent(source)}#${Date.now()}`)).default;
|
|
5435
5750
|
if (!config || typeof config !== "object") throw new Error(`Config must have a default export: ${path}`);
|
|
5436
5751
|
if (typeof config.mountPath !== "string") throw new Error(`Config mountPath must be a string: ${path}`);
|
|
5752
|
+
if (config.build?.markdown !== void 0 && config.build.markdown !== "void" && (typeof config.build.markdown !== "object" || !config.build.markdown || typeof config.build.markdown.adapter !== "string" || !config.build.markdown.adapter.trim())) throw new Error("Config build.markdown must be \"void\" or an adapter reference.");
|
|
5437
5753
|
return {
|
|
5438
5754
|
path,
|
|
5439
5755
|
config,
|
|
5756
|
+
dependencies: Object.keys(result.metafile.inputs).map((inputPath) => resolve(input.cwd, inputPath)),
|
|
5440
5757
|
root: config.build?.root ?? "decks",
|
|
5441
5758
|
outDir: config.build?.outDir ?? "src/generated",
|
|
5442
5759
|
ogpCacheFile: config.build?.ogpCacheFile
|