nextjs-slides 0.5.2 → 0.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -4
- package/dist/parse-speaker-notes.d.ts +8 -14
- package/dist/parse-speaker-notes.js +6 -2
- package/dist/parse-speaker-notes.js.map +1 -1
- package/dist/slide-deck.js +13 -4
- package/dist/slide-deck.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -175,7 +175,7 @@ Keyboard events are ignored inside `<SlideDemo>`, inputs, and textareas so you c
|
|
|
175
175
|
|
|
176
176
|
## Speaker Notes
|
|
177
177
|
|
|
178
|
-
Write notes in a markdown file — one section per slide, separated by
|
|
178
|
+
Write notes in a markdown file — one section per slide, separated by `---` on its own line. Sections are matched to slides by **position**: the first section = slide 1, the second = slide 2, and so on. Empty sections mean no notes for that slide.
|
|
179
179
|
|
|
180
180
|
```md
|
|
181
181
|
Welcome everyone. This is the opening slide.
|
|
@@ -191,7 +191,15 @@ Talk about the base container here.
|
|
|
191
191
|
Slide 4 notes. Slide 3 had none.
|
|
192
192
|
```
|
|
193
193
|
|
|
194
|
-
|
|
194
|
+
**Keep the number of sections in sync with your slides** — if you have 12 slides, you need 12 sections (empty is fine). Don't start the file with `---`; the first block of text (before any `---`) is for slide 1.
|
|
195
|
+
|
|
196
|
+
**Leading document title:** If the file starts with `# My Title` (a single heading line), use `stripLeadingTitle: true` so that block isn't treated as slide 1:
|
|
197
|
+
|
|
198
|
+
```ts
|
|
199
|
+
parseSpeakerNotes(markdown, { stripLeadingTitle: true })
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Parse the file and pass it to `SlideDeck`. Include `syncEndpoint` so the phone can follow along:
|
|
195
203
|
|
|
196
204
|
```tsx
|
|
197
205
|
// app/slides/layout.tsx
|
|
@@ -217,10 +225,14 @@ export default function SlidesLayout({
|
|
|
217
225
|
}
|
|
218
226
|
```
|
|
219
227
|
|
|
228
|
+
Without `syncEndpoint`, the deck won't broadcast slide changes and the phone will stay on the first note.
|
|
229
|
+
|
|
220
230
|
### Phone sync (presenter notes on your phone)
|
|
221
231
|
|
|
222
232
|
Open `/notes` on your phone while presenting on your laptop. The phone shows the current slide's notes and follows along as you navigate with the keyboard.
|
|
223
233
|
|
|
234
|
+
**How sync works:** When you navigate with arrow keys or spacebar, the deck POSTs `{ slide, total }` to the sync endpoint. The notes page polls that endpoint every 500ms and displays `notes[slide - 1]` — so the notes array index must match slide order. Use the same `notes.md` file in both the layout and the notes page.
|
|
235
|
+
|
|
224
236
|
**1. Create the sync API route:**
|
|
225
237
|
|
|
226
238
|
```ts
|
|
@@ -228,7 +240,7 @@ Open `/notes` on your phone while presenting on your laptop. The phone shows the
|
|
|
228
240
|
export { GET, POST } from "nextjs-slides/sync";
|
|
229
241
|
```
|
|
230
242
|
|
|
231
|
-
**2. Create the notes page
|
|
243
|
+
**2. Create the notes page** (same `notes.md`, same `parseSpeakerNotes` — indices must match slides):
|
|
232
244
|
|
|
233
245
|
```tsx
|
|
234
246
|
// app/notes/page.tsx
|
|
@@ -245,7 +257,7 @@ export default function NotesPage() {
|
|
|
245
257
|
}
|
|
246
258
|
```
|
|
247
259
|
|
|
248
|
-
Open your phone on `http://<your-ip>:3000/notes` (same network).
|
|
260
|
+
Open your phone on `http://<your-ip>:3000/notes` (same network).
|
|
249
261
|
|
|
250
262
|
### Demo notes (extra sections after the slides)
|
|
251
263
|
|
|
@@ -340,6 +352,10 @@ Slide transitions use the React 19 `<ViewTransition>` component with `addTransit
|
|
|
340
352
|
|
|
341
353
|
**Exit animation (deck-unveil) not running** — Ensure `SlideDeck` is the direct child of the layout. Wrapping it in a `<div>` can prevent the ViewTransition exit from firing. Use the `className` prop for scoped styling instead.
|
|
342
354
|
|
|
355
|
+
**Notes out of sync** — Ensure `syncEndpoint` is set and both layout and notes page use the same `notes.md`. On serverless (Vercel), in-memory sync can hit different instances; use a shared store for production.
|
|
356
|
+
|
|
357
|
+
**Notes show a document title instead of slide 1** — If the file starts with `# My Title` before the first `---`, use `parseSpeakerNotes(markdown, { stripLeadingTitle: true })`.
|
|
358
|
+
|
|
343
359
|
## For maintainers
|
|
344
360
|
|
|
345
361
|
See [DEPLOYMENT.md](DEPLOYMENT.md) for Vercel deployment and release workflow.
|
|
@@ -2,8 +2,12 @@
|
|
|
2
2
|
* Parse speaker notes from a markdown string.
|
|
3
3
|
*
|
|
4
4
|
* Format: one section per slide, separated by `---` on its own line.
|
|
5
|
+
* Sections map to slides by position: notes[0] = slide 1, notes[1] = slide 2, etc.
|
|
5
6
|
* Empty sections produce `null` (no notes for that slide).
|
|
6
7
|
*
|
|
8
|
+
* @param stripLeadingTitle - If true, removes a leading section that is a single
|
|
9
|
+
* markdown heading (# Title). Use when the file starts with a document title.
|
|
10
|
+
*
|
|
7
11
|
* @example
|
|
8
12
|
* ```md
|
|
9
13
|
* Welcome everyone. This is the opening slide.
|
|
@@ -21,21 +25,11 @@
|
|
|
21
25
|
*
|
|
22
26
|
* @example
|
|
23
27
|
* ```tsx
|
|
24
|
-
*
|
|
25
|
-
* import fs from 'fs';
|
|
26
|
-
* import path from 'path';
|
|
27
|
-
* import { SlideDeck, parseSpeakerNotes } from 'nextjs-slides';
|
|
28
|
-
* import { slides } from './slides';
|
|
29
|
-
*
|
|
30
|
-
* const notes = parseSpeakerNotes(
|
|
31
|
-
* fs.readFileSync(path.join(process.cwd(), 'app/slides/notes.md'), 'utf-8'),
|
|
32
|
-
* );
|
|
33
|
-
*
|
|
34
|
-
* export default function SlidesLayout({ children }: { children: React.ReactNode }) {
|
|
35
|
-
* return <SlideDeck slides={slides} speakerNotes={notes}>{children}</SlideDeck>;
|
|
36
|
-
* }
|
|
28
|
+
* const notes = parseSpeakerNotes(markdown, { stripLeadingTitle: true });
|
|
37
29
|
* ```
|
|
38
30
|
*/
|
|
39
|
-
declare function parseSpeakerNotes(markdown: string
|
|
31
|
+
declare function parseSpeakerNotes(markdown: string, options?: {
|
|
32
|
+
stripLeadingTitle?: boolean;
|
|
33
|
+
}): (string | null)[];
|
|
40
34
|
|
|
41
35
|
export { parseSpeakerNotes };
|
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
function parseSpeakerNotes(markdown) {
|
|
2
|
-
|
|
1
|
+
function parseSpeakerNotes(markdown, options) {
|
|
2
|
+
let sections = markdown.split(/^---$/m).map((section) => {
|
|
3
3
|
const trimmed = section.trim();
|
|
4
4
|
return trimmed.length > 0 ? trimmed : null;
|
|
5
5
|
});
|
|
6
|
+
if (options?.stripLeadingTitle && sections[0] && /^#+\s+.+$/.test(sections[0].replace(/\n.*/s, ""))) {
|
|
7
|
+
sections = sections.slice(1);
|
|
8
|
+
}
|
|
9
|
+
return sections;
|
|
6
10
|
}
|
|
7
11
|
export {
|
|
8
12
|
parseSpeakerNotes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/parse-speaker-notes.ts"],"sourcesContent":["/**\n * Parse speaker notes from a markdown string.\n *\n * Format: one section per slide, separated by `---` on its own line.\n * Empty sections produce `null` (no notes for that slide).\n *\n * @example\n * ```md\n * Welcome everyone. This is the opening slide.\n *\n * ---\n *\n * Talk about the base container here.\n *\n * ---\n *\n * ---\n *\n * Slide 4 notes. Slide 3 had none.\n * ```\n *\n * @example\n * ```tsx\n *
|
|
1
|
+
{"version":3,"sources":["../src/parse-speaker-notes.ts"],"sourcesContent":["/**\n * Parse speaker notes from a markdown string.\n *\n * Format: one section per slide, separated by `---` on its own line.\n * Sections map to slides by position: notes[0] = slide 1, notes[1] = slide 2, etc.\n * Empty sections produce `null` (no notes for that slide).\n *\n * @param stripLeadingTitle - If true, removes a leading section that is a single\n * markdown heading (# Title). Use when the file starts with a document title.\n *\n * @example\n * ```md\n * Welcome everyone. This is the opening slide.\n *\n * ---\n *\n * Talk about the base container here.\n *\n * ---\n *\n * ---\n *\n * Slide 4 notes. Slide 3 had none.\n * ```\n *\n * @example\n * ```tsx\n * const notes = parseSpeakerNotes(markdown, { stripLeadingTitle: true });\n * ```\n */\nexport function parseSpeakerNotes(\n markdown: string,\n options?: { stripLeadingTitle?: boolean },\n): (string | null)[] {\n let sections = markdown.split(/^---$/m).map((section) => {\n const trimmed = section.trim();\n return trimmed.length > 0 ? trimmed : null;\n });\n\n if (options?.stripLeadingTitle && sections[0] && /^#+\\s+.+$/.test(sections[0].replace(/\\n.*/s, ''))) {\n sections = sections.slice(1);\n }\n\n return sections;\n}\n"],"mappings":"AA8BO,SAAS,kBACd,UACA,SACmB;AACnB,MAAI,WAAW,SAAS,MAAM,QAAQ,EAAE,IAAI,CAAC,YAAY;AACvD,UAAM,UAAU,QAAQ,KAAK;AAC7B,WAAO,QAAQ,SAAS,IAAI,UAAU;AAAA,EACxC,CAAC;AAED,MAAI,SAAS,qBAAqB,SAAS,CAAC,KAAK,YAAY,KAAK,SAAS,CAAC,EAAE,QAAQ,SAAS,EAAE,CAAC,GAAG;AACnG,eAAW,SAAS,MAAM,CAAC;AAAA,EAC7B;AAEA,SAAO;AACT;","names":[]}
|
package/dist/slide-deck.js
CHANGED
|
@@ -28,12 +28,21 @@ function SlideDeck({
|
|
|
28
28
|
(index) => {
|
|
29
29
|
const clamped = Math.max(0, Math.min(index, total - 1));
|
|
30
30
|
if (clamped === current) return;
|
|
31
|
+
const targetSlide = clamped + 1;
|
|
32
|
+
if (syncEndpoint) {
|
|
33
|
+
fetch(syncEndpoint, {
|
|
34
|
+
method: "POST",
|
|
35
|
+
headers: { "Content-Type": "application/json" },
|
|
36
|
+
body: JSON.stringify({ slide: targetSlide, total })
|
|
37
|
+
}).catch(() => {
|
|
38
|
+
});
|
|
39
|
+
}
|
|
31
40
|
startTransition(() => {
|
|
32
41
|
addTransitionType(clamped > current ? "slide-forward" : "slide-back");
|
|
33
|
-
router.push(`${basePath}/${
|
|
42
|
+
router.push(`${basePath}/${targetSlide}`);
|
|
34
43
|
});
|
|
35
44
|
},
|
|
36
|
-
[basePath, current, router, startTransition, total]
|
|
45
|
+
[basePath, current, router, startTransition, syncEndpoint, total]
|
|
37
46
|
);
|
|
38
47
|
useEffect(() => {
|
|
39
48
|
if (!isSlideRoute) return;
|
|
@@ -66,14 +75,14 @@ function SlideDeck({
|
|
|
66
75
|
};
|
|
67
76
|
}, []);
|
|
68
77
|
useEffect(() => {
|
|
69
|
-
if (!syncEndpoint || !isSlideRoute) return;
|
|
78
|
+
if (!syncEndpoint || !isSlideRoute || isPending) return;
|
|
70
79
|
fetch(syncEndpoint, {
|
|
71
80
|
method: "POST",
|
|
72
81
|
headers: { "Content-Type": "application/json" },
|
|
73
82
|
body: JSON.stringify({ slide: current + 1, total })
|
|
74
83
|
}).catch(() => {
|
|
75
84
|
});
|
|
76
|
-
}, [syncEndpoint, current, total, isSlideRoute]);
|
|
85
|
+
}, [syncEndpoint, current, total, isSlideRoute, isPending]);
|
|
77
86
|
return /* @__PURE__ */ jsx(ViewTransition, { default: "none", exit: "deck-unveil", children: /* @__PURE__ */ jsxs(
|
|
78
87
|
"div",
|
|
79
88
|
{
|
package/dist/slide-deck.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/slide-deck.tsx"],"sourcesContent":["'use client';\n\nimport Link from 'next/link';\nimport { usePathname, useRouter } from 'next/navigation';\nimport { addTransitionType, useCallback, useEffect, useTransition, ViewTransition } from 'react';\nimport { cn } from './cn';\nimport type { SlideDeckConfig } from './types';\n\nexport function SlideDeck({\n children,\n slides,\n basePath = '/slides',\n exitUrl,\n showProgress = true,\n showCounter = true,\n syncEndpoint,\n className,\n}: SlideDeckConfig & { children: React.ReactNode }) {\n const router = useRouter();\n const pathname = usePathname();\n const [isPending, startTransition] = useTransition();\n\n const total = slides.length;\n const slideRoutePattern = new RegExp(`^${basePath}/(\\\\d+)$`);\n const isSlideRoute = slideRoutePattern.test(pathname);\n const current = (() => {\n const match = pathname.match(slideRoutePattern);\n return match ? Number(match[1]) - 1 : 0;\n })();\n\n const goTo = useCallback(\n (index: number) => {\n const clamped = Math.max(0, Math.min(index, total - 1));\n if (clamped === current) return;\n startTransition(() => {\n addTransitionType(clamped > current ? 'slide-forward' : 'slide-back');\n router.push(`${basePath}/${
|
|
1
|
+
{"version":3,"sources":["../src/slide-deck.tsx"],"sourcesContent":["'use client';\n\nimport Link from 'next/link';\nimport { usePathname, useRouter } from 'next/navigation';\nimport { addTransitionType, useCallback, useEffect, useTransition, ViewTransition } from 'react';\nimport { cn } from './cn';\nimport type { SlideDeckConfig } from './types';\n\nexport function SlideDeck({\n children,\n slides,\n basePath = '/slides',\n exitUrl,\n showProgress = true,\n showCounter = true,\n syncEndpoint,\n className,\n}: SlideDeckConfig & { children: React.ReactNode }) {\n const router = useRouter();\n const pathname = usePathname();\n const [isPending, startTransition] = useTransition();\n\n const total = slides.length;\n const slideRoutePattern = new RegExp(`^${basePath}/(\\\\d+)$`);\n const isSlideRoute = slideRoutePattern.test(pathname);\n const current = (() => {\n const match = pathname.match(slideRoutePattern);\n return match ? Number(match[1]) - 1 : 0;\n })();\n\n const goTo = useCallback(\n (index: number) => {\n const clamped = Math.max(0, Math.min(index, total - 1));\n if (clamped === current) return;\n const targetSlide = clamped + 1; // 1-based for sync API\n if (syncEndpoint) {\n fetch(syncEndpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ slide: targetSlide, total }),\n }).catch(() => {});\n }\n startTransition(() => {\n addTransitionType(clamped > current ? 'slide-forward' : 'slide-back');\n router.push(`${basePath}/${targetSlide}`);\n });\n },\n [basePath, current, router, startTransition, syncEndpoint, total],\n );\n\n useEffect(() => {\n if (!isSlideRoute) return;\n if (current > 0) router.prefetch(`${basePath}/${current}`);\n if (current < total - 1) router.prefetch(`${basePath}/${current + 2}`);\n }, [basePath, current, isSlideRoute, router, total]);\n\n useEffect(() => {\n if (!isSlideRoute) return;\n function onKeyDown(e: KeyboardEvent) {\n const target = e.target as HTMLElement;\n if (\n target.closest('[data-slide-interactive]') ||\n target.matches('input, textarea, select, [contenteditable=\"true\"]')\n ) {\n return;\n }\n if (e.key === 'ArrowRight' || e.key === ' ') {\n e.preventDefault();\n goTo(current + 1);\n } else if (e.key === 'ArrowLeft') {\n e.preventDefault();\n goTo(current - 1);\n }\n }\n window.addEventListener('keydown', onKeyDown);\n return () => window.removeEventListener('keydown', onKeyDown);\n }, [current, goTo, isSlideRoute]);\n\n useEffect(() => {\n const prev = document.body.style.overflow;\n document.body.style.overflow = 'hidden';\n return () => {\n document.body.style.overflow = prev;\n };\n }, []);\n\n useEffect(() => {\n if (!syncEndpoint || !isSlideRoute || isPending) return;\n fetch(syncEndpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ slide: current + 1, total }),\n }).catch(() => {});\n }, [syncEndpoint, current, total, isSlideRoute, isPending]);\n\n return (\n <ViewTransition default=\"none\" exit=\"deck-unveil\">\n <div\n id=\"slide-deck\"\n className={cn(\n 'bg-background text-foreground fixed inset-0 z-50 flex flex-col overflow-hidden font-sans select-none',\n className,\n )}\n data-pending={isPending ? '' : undefined}\n >\n <div className=\"flex-1 overflow-hidden\">\n <ViewTransition\n key={pathname}\n default=\"none\"\n enter={{\n default: 'slide-from-right',\n 'slide-back': 'slide-from-left',\n 'slide-forward': 'slide-from-right',\n }}\n exit={{\n default: 'slide-to-left',\n 'slide-back': 'slide-to-right',\n 'slide-forward': 'slide-to-left',\n }}\n >\n <div>{children}</div>\n </ViewTransition>\n </div>\n\n {isSlideRoute && showProgress && (\n <div\n className=\"fixed bottom-8 left-1/2 z-50 flex -translate-x-1/2 items-center gap-1.5\"\n aria-label=\"Slide progress\"\n >\n {Array.from({ length: total }).map((_, i) => (\n <div\n key={i}\n className={cn(\n 'h-1 transition-all duration-300',\n i === current ? 'bg-foreground w-6' : 'bg-foreground/20 w-1',\n )}\n />\n ))}\n </div>\n )}\n\n {isSlideRoute && showCounter && (\n <div className=\"text-foreground/30 fixed right-8 bottom-8 z-50 font-mono text-xs tracking-wider\">\n {current + 1} / {total}\n </div>\n )}\n\n {isSlideRoute && exitUrl && (\n <Link\n href={exitUrl}\n className=\"text-foreground/50 hover:text-foreground fixed top-6 right-8 z-50 flex h-10 w-10 items-center justify-center rounded-md transition-colors hover:bg-foreground/10\"\n aria-label=\"Exit presentation\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n </Link>\n )}\n </div>\n </ViewTransition>\n );\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nextjs-slides",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.3",
|
|
4
4
|
"description": "Composable slide deck primitives for Next.js — powered by React 19 ViewTransitions, Tailwind CSS, and highlight.js syntax highlighting.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|