supadeck 0.0.5 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/dist/cli/index.js +30532 -88
  2. package/dist/content/rehype-shiki-code-blocks.d.ts +9 -0
  3. package/dist/index.js +2808 -11
  4. package/dist/metafile-esm.json +1 -0
  5. package/dist/runtime/main.js +2868 -21
  6. package/dist/runtime/themes/base/theme.css +183 -145
  7. package/dist/runtime/themes/default/index.js +312 -15
  8. package/dist/runtime/themes/default/theme.css +17 -0
  9. package/dist/runtime/themes/sunset/index.js +2737 -10
  10. package/dist/runtime/vite-config.js +30206 -196
  11. package/package.json +16 -10
  12. package/dist/cli/export.js +0 -35
  13. package/dist/cli/serve.js +0 -12
  14. package/dist/cli/templates.js +0 -69
  15. package/dist/cli/workspace.js +0 -26
  16. package/dist/content/parse-deck.js +0 -136
  17. package/dist/content/remark-unwrap-jsx-paragraphs.js +0 -63
  18. package/dist/export/pdf.js +0 -40
  19. package/dist/runtime/App.js +0 -45
  20. package/dist/runtime/components/Callout.js +0 -13
  21. package/dist/runtime/components/Center.js +0 -4
  22. package/dist/runtime/components/Columns.js +0 -4
  23. package/dist/runtime/components/Disclosure.js +0 -5
  24. package/dist/runtime/components/Frame.js +0 -4
  25. package/dist/runtime/components/index.js +0 -4
  26. package/dist/runtime/default-components.js +0 -38
  27. package/dist/runtime/hooks/slides.js +0 -45
  28. package/dist/runtime/layout/DeckSlide.js +0 -6
  29. package/dist/runtime/layout/SlideFrame.js +0 -6
  30. package/dist/runtime/mdx-components.d.ts +0 -2
  31. package/dist/runtime/mdx-components.js +0 -17
  32. package/dist/runtime/primitives/DeckChrome.js +0 -6
  33. package/dist/runtime/primitives/DeckNavigation.js +0 -4
  34. package/dist/runtime/primitives/DeckProgress.js +0 -5
  35. package/dist/runtime/primitives/DeckTitle.js +0 -4
  36. package/dist/runtime/public-components.d.ts +0 -22
  37. package/dist/runtime/public-components.js +0 -24
  38. package/dist/runtime/styles/base.css +0 -201
  39. package/dist/runtime/tailwind-hmr.js +0 -67
  40. package/dist/runtime/tailwind-sources.js +0 -42
  41. package/dist/runtime/theme-components.d.ts +0 -3
  42. package/dist/runtime/theme-components.js +0 -18
  43. package/dist/runtime/theme-resolution.js +0 -62
  44. package/dist/runtime/theme-types.js +0 -1
  45. package/dist/runtime/themes/base/DefaultDeck.js +0 -10
  46. package/dist/runtime/themes/default/DefaultDeck.d.ts +0 -2
  47. package/dist/runtime/themes/default/DefaultDeck.js +0 -11
  48. package/dist/runtime/themes/default/DefaultThemeDeck.js +0 -22
  49. package/dist/runtime/themes/default/components.js +0 -79
  50. package/dist/runtime/themes/default.css +0 -10
  51. package/dist/runtime/themes/sunset.css +0 -10
  52. package/dist/runtime/themes/supabase/SupabaseDeck.d.ts +0 -2
  53. package/dist/runtime/themes/supabase/SupabaseDeck.js +0 -23
  54. package/dist/runtime/themes/supabase/components.d.ts +0 -65
  55. package/dist/runtime/themes/supabase/components.js +0 -80
  56. package/dist/runtime/themes/supabase/index.d.ts +0 -4
  57. package/dist/runtime/themes/supabase/index.js +0 -17
  58. package/dist/runtime/themes/supabase/theme.css +0 -523
  59. package/dist/runtime/utils/use-current-slide.js +0 -19
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "supadeck",
3
- "version": "0.0.5",
3
+ "version": "0.0.7",
4
4
  "description": "Zero-config MDX presentations with hot reload and PDF export.",
5
5
  "type": "module",
6
6
  "types": "./dist/index.d.ts",
@@ -15,7 +15,7 @@
15
15
  "README.md"
16
16
  ],
17
17
  "scripts": {
18
- "build": "tsc -p tsconfig.build.json && node ./scripts/copy-static.mjs",
18
+ "build": "tsup --config tsup.config.ts && tsc -p tsconfig.build.json --emitDeclarationOnly && node ./scripts/copy-static.mjs",
19
19
  "dev": "SUPADECK_DEFAULT_INPUT=examples/dev tsx ./src/cli/index.ts",
20
20
  "export": "SUPADECK_DEFAULT_INPUT=examples/dev tsx ./src/cli/index.ts export",
21
21
  "smoke:npx": "npm run build && node ./scripts/smoke-npx.mjs",
@@ -35,27 +35,33 @@
35
35
  ],
36
36
  "license": "MIT",
37
37
  "dependencies": {
38
- "@base-ui-components/react": "^1.0.0-rc.0",
39
38
  "@mdx-js/rollup": "^3.1.0",
40
39
  "@tailwindcss/vite": "^4.1.0",
41
40
  "@vitejs/plugin-react": "^5.0.0",
42
- "gray-matter": "^4.0.3",
43
41
  "playwright": "^1.54.0",
44
- "react": "^19.1.0",
45
- "react-dom": "^19.1.0",
46
- "remark-gfm": "^4.0.1",
47
- "remark-mdx": "^3.1.0",
48
- "remark-parse": "^11.0.0",
49
42
  "tailwindcss": "^4.1.0",
50
- "unified": "^11.0.5",
51
43
  "vite": "^7.0.0"
52
44
  },
45
+ "peerDependencies": {
46
+ "react": "^19.1.0",
47
+ "react-dom": "^19.1.0",
48
+ "shiki": "^3.14.0"
49
+ },
53
50
  "devDependencies": {
51
+ "@base-ui/react": "^1.3.0",
54
52
  "@types/node": "^24.0.0",
55
53
  "@types/react": "^19.1.0",
56
54
  "@types/react-dom": "^19.1.0",
55
+ "gray-matter": "^4.0.3",
56
+ "react": "^19.1.0",
57
+ "react-dom": "^19.1.0",
58
+ "remark-gfm": "^4.0.1",
59
+ "remark-mdx": "^3.1.0",
60
+ "remark-parse": "^11.0.0",
61
+ "tsup": "^8.5.0",
57
62
  "tsx": "^4.19.0",
58
63
  "typescript": "^5.8.0",
64
+ "unified": "^11.0.5",
59
65
  "vitest": "^3.2.4"
60
66
  }
61
67
  }
@@ -1,35 +0,0 @@
1
- import { build, preview } from "vite";
2
- import { exportDeckToPdf } from "../export/pdf.js";
3
- import { createSupadeckViteConfig } from "../runtime/vite-config.js";
4
- export async function runExport({ deckPath, outputPath, themeOverride, }) {
5
- const config = createSupadeckViteConfig({
6
- deckPath,
7
- themeOverride,
8
- outputDirName: ".supadeck-dist",
9
- });
10
- await build(config);
11
- const previewServer = await preview({
12
- ...config,
13
- preview: {
14
- host: "127.0.0.1",
15
- port: 4173,
16
- strictPort: false,
17
- },
18
- });
19
- const urls = previewServer.resolvedUrls?.local ?? [];
20
- const baseUrl = urls[0];
21
- if (!baseUrl) {
22
- await previewServer.httpServer?.close();
23
- throw new Error("Unable to determine preview URL for PDF export.");
24
- }
25
- try {
26
- await exportDeckToPdf({
27
- url: `${baseUrl}?print=1`,
28
- outputPath,
29
- });
30
- }
31
- finally {
32
- await previewServer.httpServer?.close();
33
- }
34
- console.log(`[supadeck] PDF exported to ${outputPath}`);
35
- }
package/dist/cli/serve.js DELETED
@@ -1,12 +0,0 @@
1
- import { createServer } from "vite";
2
- import { createSupadeckViteConfig } from "../runtime/vite-config.js";
3
- export async function runDevServer({ deckPath, port, open, themeOverride, }) {
4
- const server = await createServer(createSupadeckViteConfig({
5
- deckPath,
6
- port,
7
- open,
8
- themeOverride,
9
- }));
10
- await server.listen();
11
- server.printUrls();
12
- }
@@ -1,69 +0,0 @@
1
- export function starterDeckTemplate() {
2
- return `---
3
- title: Supadeck
4
- theme: default
5
- aspectRatio: 16:9
6
- showSlideNumbers: true
7
- transition: fade
8
- ---
9
-
10
- # *Supa*deck
11
-
12
- Write presentations in one \`deck.mdx\` file.
13
-
14
- <Callout tone="accent">
15
- Edit this file and the deck will hot reload automatically.
16
- </Callout>
17
-
18
- Use arrow keys to navigate.
19
-
20
- ---
21
-
22
- ## Use *markdown* to write your slides.
23
-
24
- \`\`\`md
25
- Lorem ipsum *dolor* sit **amet**...
26
-
27
- - item 1
28
- - item 2
29
- - item 3
30
- \`\`\`
31
-
32
- Lorem ipsum *dolor* sit **amet**...
33
-
34
- - item 1
35
- - item 2
36
- - item 3
37
-
38
- ---
39
-
40
- ## Or use *custom components*
41
-
42
- <Columns
43
- left={<Frame label="Local imports">Import your own React components only when you need them.</Frame>}
44
- right={<Disclosure title="Theme-provided components">Themes can expose components directly to MDX.</Disclosure>}
45
- />
46
-
47
- You can also import your own React components.
48
-
49
- \`\`\`mdx
50
- import { ExampleCard } from "./ExampleCard.tsx";
51
-
52
- # Local import
53
-
54
- Use a mix of markdown and components.
55
-
56
- <ExampleCard title="Local import">
57
- Your own React component.
58
- </ExampleCard>
59
- \`\`\`
60
-
61
- ---
62
-
63
- ## Export
64
-
65
- - Run \`npx supadeck export\`
66
- - The deck is rendered as HTML first
67
- - Then exported to PDF with headless Chromium
68
- `;
69
- }
@@ -1,26 +0,0 @@
1
- import fs from 'node:fs/promises';
2
- import path from 'node:path';
3
- import { starterDeckTemplate } from './templates.js';
4
- export function resolveDeckPath(input, cwd = process.cwd(), defaultInput) {
5
- const resolvedInput = input ?? defaultInput;
6
- if (!resolvedInput) {
7
- return path.resolve(cwd, 'deck.mdx');
8
- }
9
- const candidate = path.resolve(cwd, resolvedInput);
10
- if (path.extname(candidate)) {
11
- return candidate;
12
- }
13
- return path.join(candidate, 'deck.mdx');
14
- }
15
- async function writeFileIfMissing(filePath, contents) {
16
- try {
17
- await fs.access(filePath);
18
- }
19
- catch {
20
- await fs.mkdir(path.dirname(filePath), { recursive: true });
21
- await fs.writeFile(filePath, contents, 'utf8');
22
- }
23
- }
24
- export async function ensureStarterDeck(deckPath) {
25
- await writeFileIfMissing(deckPath, starterDeckTemplate());
26
- }
@@ -1,136 +0,0 @@
1
- import matter from 'gray-matter';
2
- import { unified } from 'unified';
3
- import remarkGfm from 'remark-gfm';
4
- import remarkParse from 'remark-parse';
5
- import remarkMdx from 'remark-mdx';
6
- const parser = unified().use(remarkParse).use(remarkGfm).use(remarkMdx);
7
- const DEFAULT_CONFIG = {
8
- title: 'Untitled deck',
9
- theme: 'default',
10
- aspectRatio: '16:9',
11
- showSlideNumbers: true,
12
- transition: 'fade'
13
- };
14
- function toOffset(point) {
15
- return point?.offset ?? 0;
16
- }
17
- function asString(value, fallback) {
18
- return typeof value === 'string' && value.trim() ? value : fallback;
19
- }
20
- function asBoolean(value, fallback) {
21
- return typeof value === 'boolean' ? value : fallback;
22
- }
23
- function asPositiveInteger(value) {
24
- const parsed = typeof value === 'number'
25
- ? value
26
- : typeof value === 'string' && value.trim()
27
- ? Number(value)
28
- : Number.NaN;
29
- if (!Number.isInteger(parsed) || parsed < 1) {
30
- return null;
31
- }
32
- return parsed;
33
- }
34
- function normalizeDeckSections(value) {
35
- if (!Array.isArray(value)) {
36
- return undefined;
37
- }
38
- const sections = value.flatMap((entry) => {
39
- if (!entry || typeof entry !== 'object') {
40
- return [];
41
- }
42
- const label = asString(entry.label, '');
43
- const start = asPositiveInteger(entry.start);
44
- const end = asPositiveInteger(entry.end ?? entry.start);
45
- if (!label || start === null || end === null || end < start) {
46
- return [];
47
- }
48
- return [
49
- {
50
- label,
51
- start: start - 1,
52
- end: end - 1
53
- }
54
- ];
55
- });
56
- return sections.length > 0 ? sections : undefined;
57
- }
58
- function sanitizeDeckSections(sections, totalSlides) {
59
- if (!sections || totalSlides <= 0) {
60
- return undefined;
61
- }
62
- const sanitized = sections.flatMap((section) => {
63
- const start = Math.min(Math.max(section.start, 0), totalSlides - 1);
64
- const end = Math.min(Math.max(section.end, start), totalSlides - 1);
65
- if (end < start) {
66
- return [];
67
- }
68
- return [{ ...section, start, end }];
69
- });
70
- return sanitized.length > 0 ? sanitized : undefined;
71
- }
72
- export function normalizeDeckConfig(frontmatter = {}, themeOverride) {
73
- return {
74
- title: asString(frontmatter.title, DEFAULT_CONFIG.title),
75
- theme: themeOverride ?? asString(frontmatter.theme, DEFAULT_CONFIG.theme),
76
- aspectRatio: asString(frontmatter.aspectRatio, DEFAULT_CONFIG.aspectRatio),
77
- showSlideNumbers: asBoolean(frontmatter.showSlideNumbers, DEFAULT_CONFIG.showSlideNumbers),
78
- transition: asString(frontmatter.transition, DEFAULT_CONFIG.transition),
79
- sections: normalizeDeckSections(frontmatter.sections)
80
- };
81
- }
82
- export function parseDeck(source, options = {}) {
83
- const matterFile = matter(source);
84
- const content = matterFile.content.replace(/^\s+/, '');
85
- const tree = parser.parse(content);
86
- const children = tree.children ?? [];
87
- let preludeEnd = 0;
88
- let nodeIndex = 0;
89
- while (nodeIndex < children.length && children[nodeIndex]?.type === 'mdxjsEsm') {
90
- preludeEnd = toOffset(children[nodeIndex].position?.end);
91
- nodeIndex += 1;
92
- }
93
- const prelude = content.slice(0, preludeEnd).trim();
94
- const slideBoundaries = [];
95
- for (const node of children.slice(nodeIndex)) {
96
- if (node.type === 'thematicBreak') {
97
- slideBoundaries.push({
98
- start: toOffset(node.position?.start),
99
- end: toOffset(node.position?.end)
100
- });
101
- }
102
- }
103
- const slides = [];
104
- let cursor = preludeEnd;
105
- if (slideBoundaries.length === 0) {
106
- const body = content.slice(cursor).trim();
107
- if (body) {
108
- slides.push({ index: 0, body });
109
- }
110
- }
111
- else {
112
- for (const boundary of slideBoundaries) {
113
- const body = content.slice(cursor, boundary.start).trim();
114
- if (body) {
115
- slides.push({ index: slides.length, body });
116
- }
117
- cursor = boundary.end;
118
- }
119
- const trailing = content.slice(cursor).trim();
120
- if (trailing) {
121
- slides.push({ index: slides.length, body: trailing });
122
- }
123
- }
124
- if (slides.length === 0) {
125
- slides.push({ index: 0, body: '# Untitled slide' });
126
- }
127
- const config = normalizeDeckConfig(matterFile.data, options.themeOverride);
128
- config.sections = sanitizeDeckSections(config.sections, slides.length);
129
- return {
130
- frontmatter: matterFile.data ?? {},
131
- config,
132
- prelude,
133
- slides,
134
- rawContent: content
135
- };
136
- }
@@ -1,63 +0,0 @@
1
- const PARAGRAPHLESS_TAGS = new Set([
2
- 'abbr',
3
- 'b',
4
- 'button',
5
- 'cite',
6
- 'code',
7
- 'data',
8
- 'dfn',
9
- 'em',
10
- 'h1',
11
- 'h2',
12
- 'h3',
13
- 'h4',
14
- 'h5',
15
- 'h6',
16
- 'kbd',
17
- 'label',
18
- 'legend',
19
- 'mark',
20
- 'output',
21
- 'p',
22
- 'pre',
23
- 'q',
24
- 'rp',
25
- 'rt',
26
- 'ruby',
27
- 's',
28
- 'samp',
29
- 'small',
30
- 'span',
31
- 'strong',
32
- 'sub',
33
- 'summary',
34
- 'sup',
35
- 'time',
36
- 'u',
37
- 'var'
38
- ]);
39
- function shouldUnwrapParagraphChildren(node) {
40
- return ((node.type === 'mdxJsxFlowElement' || node.type === 'mdxJsxTextElement') &&
41
- typeof node.name === 'string' &&
42
- PARAGRAPHLESS_TAGS.has(node.name.toLowerCase()));
43
- }
44
- function unwrapParagraphChildren(children) {
45
- return children.flatMap((child) => (child.type === 'paragraph' ? child.children ?? [] : [child]));
46
- }
47
- function visit(node) {
48
- const children = node.children;
49
- if (!children) {
50
- return;
51
- }
52
- if (shouldUnwrapParagraphChildren(node)) {
53
- node.children = unwrapParagraphChildren(children);
54
- }
55
- for (const child of node.children ?? []) {
56
- visit(child);
57
- }
58
- }
59
- export function remarkUnwrapJsxParagraphs() {
60
- return (tree) => {
61
- visit(tree);
62
- };
63
- }
@@ -1,40 +0,0 @@
1
- import fs from "node:fs/promises";
2
- import path from "node:path";
3
- import { chromium } from "playwright";
4
- export async function exportDeckToPdf({ url, outputPath, }) {
5
- await fs.mkdir(path.dirname(outputPath), { recursive: true });
6
- let browser;
7
- try {
8
- browser = await chromium.launch({ headless: true });
9
- }
10
- catch (error) {
11
- throw new Error(`Chromium is not available for PDF export. Run "npx playwright install chromium" and try again.\n\nOriginal error: ${error instanceof Error ? error.message : String(error)}`);
12
- }
13
- try {
14
- const page = await browser.newPage({
15
- viewport: {
16
- width: 1600,
17
- height: 900,
18
- },
19
- });
20
- await page.goto(url, { waitUntil: "networkidle" });
21
- await page.waitForFunction(() => window.__SUPADECK_READY__ === true);
22
- await page.emulateMedia({ media: "screen" });
23
- await page.pdf({
24
- path: outputPath,
25
- landscape: true,
26
- printBackground: true,
27
- preferCSSPageSize: false,
28
- format: "A4",
29
- margin: {
30
- top: "0",
31
- right: "0",
32
- bottom: "0",
33
- left: "0",
34
- },
35
- });
36
- }
37
- finally {
38
- await browser?.close();
39
- }
40
- }
@@ -1,45 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { useEffect, useMemo } from "react";
3
- import { mergeComponents } from "./default-components.js";
4
- import { useCurrentSlide } from "./hooks/slides.js";
5
- import { DefaultDeck } from "./themes/base/DefaultDeck.js";
6
- import { clamp, getHashIndex, parseAspectRatio, } from "./utils/use-current-slide.js";
7
- const themeHelpers = {
8
- clamp,
9
- getHashIndex,
10
- parseAspectRatio,
11
- };
12
- export function App({ deck, theme }) {
13
- const slides = deck.slides ?? [];
14
- const config = deck.config ?? {};
15
- const [index, setIndex] = useCurrentSlide(slides.length);
16
- const printMode = new URLSearchParams(window.location.search).get("print") === "1";
17
- const components = useMemo(() => mergeComponents(theme), [theme]);
18
- const DeckRenderer = theme.Deck ?? DefaultDeck;
19
- useEffect(() => {
20
- document.title = config.title ?? "Supadeck";
21
- window.__SUPADECK_READY__ = true;
22
- return () => {
23
- window.__SUPADECK_READY__ = false;
24
- };
25
- }, [config.title]);
26
- useEffect(() => {
27
- const cleanup = theme.setup?.({
28
- deck,
29
- config,
30
- slides,
31
- currentIndex: index,
32
- printMode,
33
- components,
34
- helpers: themeHelpers,
35
- rootElement: document.documentElement,
36
- });
37
- return () => {
38
- cleanup?.();
39
- };
40
- }, [theme, deck, config, slides, index, printMode, components]);
41
- if (slides.length === 0) {
42
- return _jsx("div", { className: "p-10 text-white", children: "No slides found." });
43
- }
44
- return (_jsx(DeckRenderer, { deck: deck, config: config, slides: slides, currentIndex: index, setCurrentIndex: setIndex, printMode: printMode, components: components, helpers: themeHelpers }));
45
- }
@@ -1,13 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- function toneClasses(tone) {
3
- if (tone === 'accent') {
4
- return 'border-[color:var(--color-accent)] bg-[color:var(--color-accent)]/10';
5
- }
6
- if (tone === 'danger') {
7
- return 'border-red-500/50 bg-red-500/10';
8
- }
9
- return 'border-[color:var(--color-border)] bg-white/60 dark:bg-white/5';
10
- }
11
- export function Callout({ children, tone = 'default' }) {
12
- return (_jsx("div", { className: `rounded-[var(--radius-lg)] border px-6 py-5 text-xl shadow-lg shadow-black/5 backdrop-blur ${toneClasses(tone)}`, children: children }));
13
- }
@@ -1,4 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- export function Center({ children, className, }) {
3
- return (_jsx("div", { className: `flex gap-4 flex-col items-center justify-center *:text-center ${className}`, children: children }));
4
- }
@@ -1,4 +0,0 @@
1
- import { jsxs as _jsxs } from "react/jsx-runtime";
2
- export function Columns({ left, right }) {
3
- return _jsxs("div", { className: "grid gap-6 md:grid-cols-2", children: [left, right] });
4
- }
@@ -1,5 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Accordion } from '@base-ui-components/react/accordion';
3
- export function Disclosure({ title, children }) {
4
- return (_jsx(Accordion.Root, { className: "rounded-[var(--radius-lg)] border border-[color:var(--color-border)] bg-white/70 dark:bg-white/5", children: _jsxs(Accordion.Item, { value: "item-1", children: [_jsx(Accordion.Header, { children: _jsxs(Accordion.Trigger, { className: "flex w-full items-center justify-between px-5 py-4 text-left text-xl font-semibold", children: [_jsx("span", { children: title }), _jsx("span", { "aria-hidden": "true", children: "+" })] }) }), _jsx(Accordion.Panel, { className: "px-5 pb-5 text-lg text-[color:var(--color-foreground)]/80", children: children })] }) }));
5
- }
@@ -1,4 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- export function Frame({ children }) {
3
- return (_jsx("div", { className: "rounded-[var(--radius-xl)] border border-[color:var(--color-border)] bg-white/70 p-8 shadow-xl shadow-black/10 dark:bg-white/5", children: children }));
4
- }
@@ -1,4 +0,0 @@
1
- export { Callout } from './Callout.js';
2
- export { Columns } from './Columns.js';
3
- export { Disclosure } from './Disclosure.js';
4
- export { Frame } from './Frame.js';
@@ -1,38 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { Callout, Columns, Disclosure, Frame } from "./components/index.js";
3
- import { Center } from "./components/Center.js";
4
- function cx(...values) {
5
- return values.filter(Boolean).join(" ");
6
- }
7
- export function createDefaultComponents() {
8
- return {
9
- h1: (props) => (_jsx("h1", { className: "text-6xl font-semibold tracking-tight text-balance", ...props })),
10
- h2: (props) => (_jsx("h2", { className: "text-4xl font-semibold tracking-tight text-balance", ...props })),
11
- h3: (props) => (_jsx("h3", { className: "text-2xl font-semibold tracking-tight", ...props })),
12
- p: (props) => (_jsx("p", { className: "text-2xl leading-relaxed text-[color:var(--color-foreground)]/90", ...props })),
13
- a: (props) => (_jsx("a", { className: "text-[color:var(--color-accent)] underline decoration-2 underline-offset-4", ...props })),
14
- ul: (props) => (_jsx("ul", { className: "list-disc space-y-3 pl-8 text-2xl", ...props })),
15
- ol: (props) => (_jsx("ol", { className: "list-decimal space-y-3 pl-8 text-2xl", ...props })),
16
- li: (props) => (_jsx("li", { className: "pl-2", ...props })),
17
- code: (props) => (_jsx("code", { className: "rounded-md bg-black/10 px-2 py-1 font-mono text-[0.9em] dark:bg-white/10", ...props })),
18
- pre: (props) => (_jsx("pre", { className: "overflow-x-auto rounded-[var(--radius-lg)] border border-[color:var(--color-border)] bg-[color:var(--color-code-bg)] p-6 text-lg", ...props })),
19
- table: ({ className, ...props }) => (_jsx("div", { className: "deck-table-wrap", children: _jsx("table", { className: cx("deck-table", className), ...props }) })),
20
- thead: ({ className, ...props }) => (_jsx("thead", { className: cx("deck-thead", className), ...props })),
21
- tbody: ({ className, ...props }) => (_jsx("tbody", { className: cx("deck-tbody", className), ...props })),
22
- tr: ({ className, ...props }) => (_jsx("tr", { className: cx("deck-tr", className), ...props })),
23
- th: ({ className, ...props }) => (_jsx("th", { className: cx("deck-th", className), ...props })),
24
- td: ({ className, ...props }) => (_jsx("td", { className: cx("deck-td", className), ...props })),
25
- blockquote: (props) => (_jsx("blockquote", { className: "border-l-4 border-[color:var(--color-accent)] pl-6 text-2xl italic", ...props })),
26
- Callout,
27
- Columns,
28
- Disclosure,
29
- Frame,
30
- Center,
31
- };
32
- }
33
- export function mergeComponents(theme) {
34
- return {
35
- ...createDefaultComponents(),
36
- ...(theme?.components ?? {}),
37
- };
38
- }
@@ -1,45 +0,0 @@
1
- import { useEffect, useState } from "react";
2
- import { clamp, getHashIndex } from "../utils/use-current-slide.js";
3
- export function useCurrentSlide(total) {
4
- const [index, setIndex] = useState(() => getHashIndex(total));
5
- useEffect(() => {
6
- const onHashChange = () => setIndex(getHashIndex(total));
7
- window.addEventListener("hashchange", onHashChange);
8
- return () => window.removeEventListener("hashchange", onHashChange);
9
- }, [total]);
10
- useEffect(() => {
11
- const nextHash = `#${index + 1}`;
12
- if (window.location.hash !== nextHash) {
13
- history.replaceState(null, "", `${window.location.pathname}${window.location.search}${nextHash}`);
14
- }
15
- }, [index]);
16
- useEffect(() => {
17
- const onKeyDown = (event) => {
18
- if (event.metaKey || event.ctrlKey || event.altKey) {
19
- return;
20
- }
21
- if (["ArrowRight", "ArrowDown", "PageDown", " "].includes(event.key)) {
22
- event.preventDefault();
23
- setIndex((current) => clamp(current + 1, 0, total - 1));
24
- }
25
- if (["ArrowLeft", "ArrowUp", "PageUp"].includes(event.key)) {
26
- event.preventDefault();
27
- setIndex((current) => clamp(current - 1, 0, total - 1));
28
- }
29
- if (event.key === "Home") {
30
- event.preventDefault();
31
- setIndex(0);
32
- }
33
- if (event.key === "End") {
34
- event.preventDefault();
35
- setIndex(total - 1);
36
- }
37
- };
38
- window.addEventListener("keydown", onKeyDown);
39
- return () => window.removeEventListener("keydown", onKeyDown);
40
- }, [total]);
41
- useEffect(() => {
42
- setIndex((current) => clamp(current, 0, Math.max(total - 1, 0)));
43
- }, [total]);
44
- return [index, setIndex];
45
- }
@@ -1,6 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { SlideFrame } from './SlideFrame.js';
3
- export function DeckSlide({ slide, config, total, index, printMode, components, }) {
4
- const Slide = slide.Component;
5
- return (_jsx(SlideFrame, { config: config, index: index, total: total, printMode: printMode, children: _jsx(Slide, { components: components }) }));
6
- }
@@ -1,6 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { parseAspectRatio } from '../utils/use-current-slide.js';
3
- export function SlideFrame({ children, config, index, total, printMode, }) {
4
- const ratio = parseAspectRatio(config.aspectRatio);
5
- return (_jsx("section", { className: `slide-frame ${printMode ? 'slide-frame-print' : ''}`, style: { '--slide-aspect-ratio': ratio }, "data-transition": config.transition, children: _jsxs("div", { className: "slide-surface", children: [_jsx("div", { className: "slide-content", children: children }), config.showSlideNumbers ? (_jsx("div", { className: "slide-footer", children: _jsxs("span", { children: [index + 1, " / ", total] }) })) : null] }) }));
6
- }
@@ -1,2 +0,0 @@
1
- import type { MdxComponentMap } from './theme-types.js';
2
- export declare function createDefaultMdxComponents(): MdxComponentMap;
@@ -1,17 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- export function createDefaultMdxComponents() {
3
- return {
4
- h1: (props) => (_jsx("h1", { className: "text-6xl font-semibold tracking-tight text-balance", ...props })),
5
- h2: (props) => (_jsx("h2", { className: "text-4xl font-semibold tracking-tight text-balance", ...props })),
6
- h3: (props) => (_jsx("h3", { className: "text-2xl font-semibold tracking-tight", ...props })),
7
- p: (props) => (_jsx("p", { className: "text-2xl leading-relaxed text-[color:var(--color-foreground)]/90", ...props })),
8
- a: (props) => (_jsx("a", { className: "text-[color:var(--color-accent)] underline decoration-2 underline-offset-4", ...props })),
9
- ul: (props) => (_jsx("ul", { className: "list-disc space-y-3 pl-8 text-2xl", ...props })),
10
- ol: (props) => (_jsx("ol", { className: "list-decimal space-y-3 pl-8 text-2xl", ...props })),
11
- li: (props) => (_jsx("li", { className: "pl-2", ...props })),
12
- code: (props) => (_jsx("code", { className: "rounded-md bg-black/10 px-2 py-1 font-mono text-[0.9em] dark:bg-white/10", ...props })),
13
- pre: (props) => (_jsx("pre", { className: "overflow-x-auto rounded-[var(--radius-lg)] border border-[color:var(--color-border)] bg-[color:var(--color-code-bg)] p-6 text-lg", ...props })),
14
- blockquote: (props) => (_jsx("blockquote", { className: "border-l-4 border-[color:var(--color-accent)] pl-6 text-2xl italic", ...props })),
15
- };
16
- }
17
- //# sourceMappingURL=mdx-components.js.map
@@ -1,6 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { DeckProgress } from './DeckProgress.js';
3
- import { DeckTitle } from './DeckTitle.js';
4
- export function DeckChrome({ title, currentIndex, total }) {
5
- return (_jsxs("div", { className: "deck-chrome", children: [_jsx(DeckTitle, { title: title }), _jsx(DeckProgress, { currentIndex: currentIndex, total: total })] }));
6
- }