nextjs-slides 0.6.0 → 0.7.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.md +54 -39
- package/dist/cn.d.ts +1 -0
- package/dist/cn.js.map +1 -1
- package/dist/get-slide.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +9 -2
- package/dist/index.js.map +1 -1
- package/dist/parse-speaker-notes.js.map +1 -1
- package/dist/primitives.d.ts +134 -12
- package/dist/primitives.js +150 -34
- package/dist/primitives.js.map +1 -1
- package/dist/slide-deck.d.ts +30 -1
- package/dist/slide-deck.js +28 -6
- package/dist/slide-deck.js.map +1 -1
- package/dist/slide-demo-content.d.ts +7 -0
- package/dist/slide-demo-content.js +3 -1
- package/dist/slide-demo-content.js.map +1 -1
- package/dist/slide-link.d.ts +11 -0
- package/dist/slide-link.js.map +1 -1
- package/dist/slide-notes-view.js +7 -1
- package/dist/slide-notes-view.js.map +1 -1
- package/dist/slides.css +39 -33
- package/dist/types.d.ts +3 -0
- package/package.json +4 -1
package/README.md
CHANGED
|
@@ -28,7 +28,6 @@ Open http://localhost:3000 — choose "Geist deck" or "Alternate deck" (Playfair
|
|
|
28
28
|
|
|
29
29
|
Peer dependencies: `next >=15`, `react >=19`, `tailwindcss >=4`.
|
|
30
30
|
|
|
31
|
-
|
|
32
31
|
## Quick Start
|
|
33
32
|
|
|
34
33
|
### 1. Import the stylesheet
|
|
@@ -36,8 +35,8 @@ Peer dependencies: `next >=15`, `react >=19`, `tailwindcss >=4`.
|
|
|
36
35
|
In your root layout or global CSS:
|
|
37
36
|
|
|
38
37
|
```css
|
|
39
|
-
@import
|
|
40
|
-
@import
|
|
38
|
+
@import 'tailwindcss';
|
|
39
|
+
@import 'nextjs-slides/styles.css';
|
|
41
40
|
|
|
42
41
|
@source "../node_modules/nextjs-slides/dist";
|
|
43
42
|
```
|
|
@@ -54,7 +53,7 @@ import {
|
|
|
54
53
|
SlideSubtitle,
|
|
55
54
|
SlideBadge,
|
|
56
55
|
SlideCode,
|
|
57
|
-
} from
|
|
56
|
+
} from 'nextjs-slides';
|
|
58
57
|
|
|
59
58
|
export const slides = [
|
|
60
59
|
<Slide key="intro">
|
|
@@ -75,8 +74,8 @@ console.log(greeting);`}</SlideCode>
|
|
|
75
74
|
|
|
76
75
|
```tsx
|
|
77
76
|
// app/slides/layout.tsx
|
|
78
|
-
import { SlideDeck } from
|
|
79
|
-
import { slides } from
|
|
77
|
+
import { SlideDeck } from 'nextjs-slides';
|
|
78
|
+
import { slides } from './slides';
|
|
80
79
|
|
|
81
80
|
export default function SlidesLayout({
|
|
82
81
|
children,
|
|
@@ -93,17 +92,17 @@ export default function SlidesLayout({
|
|
|
93
92
|
|
|
94
93
|
```tsx
|
|
95
94
|
// app/slides/page.tsx
|
|
96
|
-
import { redirect } from
|
|
95
|
+
import { redirect } from 'next/navigation';
|
|
97
96
|
|
|
98
97
|
export default function SlidesPage() {
|
|
99
|
-
redirect(
|
|
98
|
+
redirect('/slides/1');
|
|
100
99
|
}
|
|
101
100
|
```
|
|
102
101
|
|
|
103
102
|
```tsx
|
|
104
103
|
// app/slides/[page]/page.tsx
|
|
105
|
-
import { getSlide, generateSlideParams } from
|
|
106
|
-
import { slides } from
|
|
104
|
+
import { getSlide, generateSlideParams } from 'nextjs-slides';
|
|
105
|
+
import { slides } from '../slides';
|
|
107
106
|
|
|
108
107
|
export const generateStaticParams = () => generateSlideParams(slides);
|
|
109
108
|
|
|
@@ -120,17 +119,17 @@ That's it. Navigate to `/slides` and you have a full slide deck.
|
|
|
120
119
|
|
|
121
120
|
## `<SlideDeck>` Props
|
|
122
121
|
|
|
123
|
-
| Prop | Type | Default | Description
|
|
124
|
-
| -------------- | --------------------------------- | ------------ |
|
|
125
|
-
| `slides` | `ReactNode[]` | **required** | Your slides array
|
|
126
|
-
| `speakerNotes` | `(string \| ReactNode \| null)[]` | — | Notes per slide (same index). See Speaker Notes below.
|
|
127
|
-
| `syncEndpoint` | `string` | — | API route for presenter ↔ phone sync.
|
|
128
|
-
| `basePath` | `string` | `"/slides"` | URL prefix for slide routes
|
|
129
|
-
| `exitUrl` | `string` | — | URL for exit button (×). Shows in top-right when set.
|
|
130
|
-
| `showProgress` | `boolean` | `true` | Show dot progress indicator
|
|
131
|
-
| `showCounter` | `boolean` | `true` | Show "3 / 10" counter
|
|
132
|
-
| `className` | `string` | — | Additional class for the deck container
|
|
133
|
-
| `children` | `React.ReactNode` | **required** | Route content (from Next.js)
|
|
122
|
+
| Prop | Type | Default | Description |
|
|
123
|
+
| -------------- | --------------------------------- | ------------ | ------------------------------------------------------ |
|
|
124
|
+
| `slides` | `ReactNode[]` | **required** | Your slides array |
|
|
125
|
+
| `speakerNotes` | `(string \| ReactNode \| null)[]` | — | Notes per slide (same index). See Speaker Notes below. |
|
|
126
|
+
| `syncEndpoint` | `string` | — | API route for presenter ↔ phone sync. |
|
|
127
|
+
| `basePath` | `string` | `"/slides"` | URL prefix for slide routes |
|
|
128
|
+
| `exitUrl` | `string` | — | URL for exit button (×). Shows in top-right when set. |
|
|
129
|
+
| `showProgress` | `boolean` | `true` | Show dot progress indicator |
|
|
130
|
+
| `showCounter` | `boolean` | `true` | Show "3 / 10" counter |
|
|
131
|
+
| `className` | `string` | — | Additional class for the deck container |
|
|
132
|
+
| `children` | `React.ReactNode` | **required** | Route content (from Next.js) |
|
|
134
133
|
|
|
135
134
|
## Primitives
|
|
136
135
|
|
|
@@ -196,20 +195,20 @@ Slide 4 notes. Slide 3 had none.
|
|
|
196
195
|
**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
196
|
|
|
198
197
|
```ts
|
|
199
|
-
parseSpeakerNotes(markdown, { stripLeadingTitle: true })
|
|
198
|
+
parseSpeakerNotes(markdown, { stripLeadingTitle: true });
|
|
200
199
|
```
|
|
201
200
|
|
|
202
201
|
Parse the file and pass it to `SlideDeck`. Include `syncEndpoint` so the phone can follow along:
|
|
203
202
|
|
|
204
203
|
```tsx
|
|
205
204
|
// app/slides/layout.tsx
|
|
206
|
-
import fs from
|
|
207
|
-
import path from
|
|
208
|
-
import { SlideDeck, parseSpeakerNotes } from
|
|
209
|
-
import { slides } from
|
|
205
|
+
import fs from 'fs';
|
|
206
|
+
import path from 'path';
|
|
207
|
+
import { SlideDeck, parseSpeakerNotes } from 'nextjs-slides';
|
|
208
|
+
import { slides } from './slides';
|
|
210
209
|
|
|
211
210
|
const notes = parseSpeakerNotes(
|
|
212
|
-
fs.readFileSync(path.join(process.cwd(),
|
|
211
|
+
fs.readFileSync(path.join(process.cwd(), 'app/slides/notes.md'), 'utf-8')
|
|
213
212
|
);
|
|
214
213
|
|
|
215
214
|
export default function SlidesLayout({
|
|
@@ -218,7 +217,11 @@ export default function SlidesLayout({
|
|
|
218
217
|
children: React.ReactNode;
|
|
219
218
|
}) {
|
|
220
219
|
return (
|
|
221
|
-
<SlideDeck
|
|
220
|
+
<SlideDeck
|
|
221
|
+
slides={slides}
|
|
222
|
+
speakerNotes={notes}
|
|
223
|
+
syncEndpoint="/api/nxs-sync"
|
|
224
|
+
>
|
|
222
225
|
{children}
|
|
223
226
|
</SlideDeck>
|
|
224
227
|
);
|
|
@@ -237,19 +240,19 @@ Open `/notes` on your phone while presenting on your laptop. The phone shows the
|
|
|
237
240
|
|
|
238
241
|
```ts
|
|
239
242
|
// app/api/nxs-sync/route.ts
|
|
240
|
-
export { GET, POST } from
|
|
243
|
+
export { GET, POST } from 'nextjs-slides/sync';
|
|
241
244
|
```
|
|
242
245
|
|
|
243
246
|
**2. Create the notes page** (same `notes.md`, same `parseSpeakerNotes` — indices must match slides):
|
|
244
247
|
|
|
245
248
|
```tsx
|
|
246
249
|
// app/notes/page.tsx
|
|
247
|
-
import fs from
|
|
248
|
-
import path from
|
|
249
|
-
import { parseSpeakerNotes, SlideNotesView } from
|
|
250
|
+
import fs from 'fs';
|
|
251
|
+
import path from 'path';
|
|
252
|
+
import { parseSpeakerNotes, SlideNotesView } from 'nextjs-slides';
|
|
250
253
|
|
|
251
254
|
const notes = parseSpeakerNotes(
|
|
252
|
-
fs.readFileSync(path.join(process.cwd(),
|
|
255
|
+
fs.readFileSync(path.join(process.cwd(), 'app/slides/notes.md'), 'utf-8')
|
|
253
256
|
);
|
|
254
257
|
|
|
255
258
|
export default function NotesPage() {
|
|
@@ -284,7 +287,12 @@ The notes view auto-follows the deck during slides. Once you tap "Next" past the
|
|
|
284
287
|
Use `basePath` for a different URL, `exitUrl` for an exit button (×), and `className` for scoped font/syntax overrides:
|
|
285
288
|
|
|
286
289
|
```tsx
|
|
287
|
-
<SlideDeck
|
|
290
|
+
<SlideDeck
|
|
291
|
+
slides={slides}
|
|
292
|
+
basePath="/slides-alt"
|
|
293
|
+
exitUrl="/"
|
|
294
|
+
className="slides-alt-deck"
|
|
295
|
+
>
|
|
288
296
|
{children}
|
|
289
297
|
</SlideDeck>
|
|
290
298
|
```
|
|
@@ -316,13 +324,16 @@ Install `geist`, wire the fonts in your layout, and add the theme variables:
|
|
|
316
324
|
|
|
317
325
|
```tsx
|
|
318
326
|
// app/layout.tsx
|
|
319
|
-
import { GeistSans } from
|
|
320
|
-
import { GeistMono } from
|
|
321
|
-
import { GeistPixelSquare } from
|
|
327
|
+
import { GeistSans } from 'geist/font/sans';
|
|
328
|
+
import { GeistMono } from 'geist/font/mono';
|
|
329
|
+
import { GeistPixelSquare } from 'geist/font/pixel';
|
|
322
330
|
|
|
323
331
|
export default function RootLayout({ children }) {
|
|
324
332
|
return (
|
|
325
|
-
<html
|
|
333
|
+
<html
|
|
334
|
+
lang="en"
|
|
335
|
+
className={`${GeistSans.variable} ${GeistMono.variable} ${GeistPixelSquare.variable}`}
|
|
336
|
+
>
|
|
326
337
|
<body className={GeistSans.className}>{children}</body>
|
|
327
338
|
</html>
|
|
328
339
|
);
|
|
@@ -333,7 +344,9 @@ export default function RootLayout({ children }) {
|
|
|
333
344
|
/* globals.css @theme inline */
|
|
334
345
|
--font-sans: var(--font-geist-sans), ui-sans-serif, system-ui, sans-serif;
|
|
335
346
|
--font-mono: var(--font-geist-mono), ui-monospace, monospace;
|
|
336
|
-
--font-pixel:
|
|
347
|
+
--font-pixel:
|
|
348
|
+
var(--font-geist-pixel-square), var(--font-geist-sans), ui-sans-serif,
|
|
349
|
+
system-ui, sans-serif;
|
|
337
350
|
```
|
|
338
351
|
|
|
339
352
|
Use `className="font-pixel"` on primitives where you want the pixel display font.
|
|
@@ -346,6 +359,8 @@ Slide transitions use the React 19 `<ViewTransition>` component with `addTransit
|
|
|
346
359
|
|
|
347
360
|
**SlideCode syntax highlighting looks broken or colorless** — Ensure you import `nextjs-slides/styles.css` in your root layout or global CSS (see Quick Start). The `--sh-*` variables must be in scope for highlight.js tokens to display correctly.
|
|
348
361
|
|
|
362
|
+
**Split layout not stacking on small screens** — Import `nextjs-slides/styles.css` without a layer: `@import "nextjs-slides/styles.css"` (not `layer(base)`). Layered imports can be overridden by Tailwind utilities. Also ensure the library CSS loads after Tailwind.
|
|
363
|
+
|
|
349
364
|
**`@source` path not found** — The `@source "../node_modules/nextjs-slides/dist"` path is relative to your CSS file. If your `globals.css` lives in `app/`, use `../node_modules/...`. If it lives in the project root, use `./node_modules/nextjs-slides/dist`.
|
|
350
365
|
|
|
351
366
|
**SlideCode error "Could not find the language '…'"** — Only JavaScript, TypeScript, and HTML/XML are registered. Unrecognized file extensions in the `title` prop (e.g. `.terminal`, `.sh`, `.py`) will fall back to TypeScript highlighting. If you previously saw this error, update the package — the fix gracefully handles unknown languages instead of throwing.
|
package/dist/cn.d.ts
CHANGED
package/dist/cn.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cn.ts"],"sourcesContent":["import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n"],"mappings":"AAAA,SAAS,YAA6B;AACtC,SAAS,eAAe;
|
|
1
|
+
{"version":3,"sources":["../src/cn.ts"],"sourcesContent":["import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\n/** Merge Tailwind classes with `clsx` + `tailwind-merge` (internal utility). */\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n"],"mappings":"AAAA,SAAS,YAA6B;AACtC,SAAS,eAAe;AAGjB,SAAS,MAAM,QAAsB;AAC1C,SAAO,QAAQ,KAAK,MAAM,CAAC;AAC7B;","names":[]}
|
package/dist/get-slide.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/get-slide.tsx"],"sourcesContent":["import { notFound } from 'next/navigation';\n\n/**\n * Resolves the current slide from params and the slides array.\n * Use in your `[page]/page.tsx` dynamic route.\n *\n * @example\n * ```tsx\n * import { getSlide } from 'nextjs-slides';\n * import { slides } from '../slides';\n *\n * export default async function SlidePage({ params }: { params: Promise<{ page: string }> }) {\n * return getSlide(await params, slides);\n * }\n * ```\n */\nexport function getSlide(params: { page: string }
|
|
1
|
+
{"version":3,"sources":["../src/get-slide.tsx"],"sourcesContent":["import { notFound } from 'next/navigation';\n\n/**\n * Resolves the current slide from params and the slides array.\n * Use in your `[page]/page.tsx` dynamic route.\n *\n * @example\n * ```tsx\n * import { getSlide } from 'nextjs-slides';\n * import { slides } from '../slides';\n *\n * export default async function SlidePage({ params }: { params: Promise<{ page: string }> }) {\n * return getSlide(await params, slides);\n * }\n * ```\n */\nexport function getSlide(\n params: { page: string },\n slides: React.ReactNode[]\n): React.ReactNode {\n const index = Number(params.page) - 1;\n\n if (isNaN(index) || index < 0 || index >= slides.length) {\n notFound();\n }\n\n return slides[index];\n}\n\n/**\n * Generates static params for all slides. Use with `generateStaticParams`.\n *\n * @example\n * ```tsx\n * import { generateSlideParams } from 'nextjs-slides';\n * import { slides } from '../slides';\n *\n * export const generateStaticParams = () => generateSlideParams(slides);\n * ```\n */\nexport function generateSlideParams(slides: React.ReactNode[]) {\n return slides.map((_, i) => ({ page: String(i + 1) }));\n}\n"],"mappings":"AAAA,SAAS,gBAAgB;AAgBlB,SAAS,SACd,QACA,QACiB;AACjB,QAAM,QAAQ,OAAO,OAAO,IAAI,IAAI;AAEpC,MAAI,MAAM,KAAK,KAAK,QAAQ,KAAK,SAAS,OAAO,QAAQ;AACvD,aAAS;AAAA,EACX;AAEA,SAAO,OAAO,KAAK;AACrB;AAaO,SAAS,oBAAoB,QAA2B;AAC7D,SAAO,OAAO,IAAI,CAAC,GAAG,OAAO,EAAE,MAAM,OAAO,IAAI,CAAC,EAAE,EAAE;AACvD;","names":[]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { SlideDeck } from './slide-deck.js';
|
|
2
2
|
export { generateSlideParams, getSlide } from './get-slide.js';
|
|
3
|
-
export { Slide, SlideBadge, SlideCode, SlideDemo, SlideHeaderBadge, SlideList, SlideListItem, SlideNote, SlideSpeaker, SlideSpeakerGrid, SlideSpeakerList, SlideSplitLayout, SlideStatement, SlideStatementList, SlideSubtitle, SlideTitle } from './primitives.js';
|
|
3
|
+
export { Slide, SlideBadge, SlideCode, SlideColumns, SlideDemo, SlideHeaderBadge, SlideList, SlideListItem, SlideNote, SlideSpeaker, SlideSpeakerGrid, SlideSpeakerList, SlideSplitLayout, SlideStatement, SlideStatementList, SlideSubtitle, SlideTitle } from './primitives.js';
|
|
4
4
|
export { SlideLink } from './slide-link.js';
|
|
5
5
|
export { parseSpeakerNotes } from './parse-speaker-notes.js';
|
|
6
6
|
export { SlideNotesView } from './slide-notes-view.js';
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import { SlideDeck } from "./slide-deck";
|
|
2
2
|
import { getSlide, generateSlideParams } from "./get-slide";
|
|
3
|
-
import { Slide, SlideSplitLayout } from "./primitives";
|
|
4
|
-
import {
|
|
3
|
+
import { Slide, SlideColumns, SlideSplitLayout } from "./primitives";
|
|
4
|
+
import {
|
|
5
|
+
SlideTitle,
|
|
6
|
+
SlideSubtitle,
|
|
7
|
+
SlideBadge,
|
|
8
|
+
SlideHeaderBadge,
|
|
9
|
+
SlideNote
|
|
10
|
+
} from "./primitives";
|
|
5
11
|
import { SlideCode, SlideList, SlideListItem, SlideDemo } from "./primitives";
|
|
6
12
|
import { SlideStatementList, SlideStatement } from "./primitives";
|
|
7
13
|
import { SlideSpeaker, SlideSpeakerGrid, SlideSpeakerList } from "./primitives";
|
|
@@ -12,6 +18,7 @@ export {
|
|
|
12
18
|
Slide,
|
|
13
19
|
SlideBadge,
|
|
14
20
|
SlideCode,
|
|
21
|
+
SlideColumns,
|
|
15
22
|
SlideDeck,
|
|
16
23
|
SlideDemo,
|
|
17
24
|
SlideHeaderBadge,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["// Provider\nexport { SlideDeck } from './slide-deck';\n\n// Routing helpers\nexport { getSlide, generateSlideParams } from './get-slide';\n\n// Primitives — Layout\nexport { Slide, SlideSplitLayout } from './primitives';\n\n// Primitives — Typography\nexport {
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["// Provider\nexport { SlideDeck } from './slide-deck';\n\n// Routing helpers\nexport { getSlide, generateSlideParams } from './get-slide';\n\n// Primitives — Layout\nexport { Slide, SlideColumns, SlideSplitLayout } from './primitives';\n\n// Primitives — Typography\nexport {\n SlideTitle,\n SlideSubtitle,\n SlideBadge,\n SlideHeaderBadge,\n SlideNote,\n} from './primitives';\n\n// Primitives — Content\nexport { SlideCode, SlideList, SlideListItem, SlideDemo } from './primitives';\n\n// Primitives — Statements\nexport { SlideStatementList, SlideStatement } from './primitives';\n\n// Primitives — Speakers\nexport { SlideSpeaker, SlideSpeakerGrid, SlideSpeakerList } from './primitives';\n\n// Navigation\nexport { SlideLink } from './slide-link';\n\n// Utilities\nexport { parseSpeakerNotes } from './parse-speaker-notes';\n\n// Speaker notes\nexport { SlideNotesView } from './slide-notes-view';\n\n// Types\nexport type { SlideAlign, SlideLinkVariant, SlideDeckConfig } from './types';\n"],"mappings":"AACA,SAAS,iBAAiB;AAG1B,SAAS,UAAU,2BAA2B;AAG9C,SAAS,OAAO,cAAc,wBAAwB;AAGtD;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGP,SAAS,WAAW,WAAW,eAAe,iBAAiB;AAG/D,SAAS,oBAAoB,sBAAsB;AAGnD,SAAS,cAAc,kBAAkB,wBAAwB;AAGjE,SAAS,iBAAiB;AAG1B,SAAS,yBAAyB;AAGlC,SAAS,sBAAsB;","names":[]}
|
|
@@ -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 * 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 }
|
|
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 (\n options?.stripLeadingTitle &&\n sections[0] &&\n /^#+\\s+.+$/.test(sections[0].replace(/\\n.*/s, ''))\n ) {\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,MACE,SAAS,qBACT,SAAS,CAAC,KACV,YAAY,KAAK,SAAS,CAAC,EAAE,QAAQ,SAAS,EAAE,CAAC,GACjD;AACA,eAAW,SAAS,MAAM,CAAC;AAAA,EAC7B;AAEA,SAAO;AACT;","names":[]}
|
package/dist/primitives.d.ts
CHANGED
|
@@ -1,63 +1,178 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import { SlideAlign } from './types.js';
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Full-viewport slide container with centered content and a decorative border.
|
|
6
|
+
*
|
|
7
|
+
* This is the primary slide primitive — use it as a top-level element in
|
|
8
|
+
* the slides array. For a two-column layout that fills the whole viewport,
|
|
9
|
+
* use {@link SlideSplitLayout} instead.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```tsx
|
|
13
|
+
* <Slide align="left">
|
|
14
|
+
* <SlideTitle>My Slide</SlideTitle>
|
|
15
|
+
* <SlideSubtitle>Supporting text</SlideSubtitle>
|
|
16
|
+
* </Slide>
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
4
19
|
declare function Slide({ children, align, className, }: {
|
|
5
20
|
children: React.ReactNode;
|
|
21
|
+
/** Content alignment. `"center"` centers both horizontally and text; `"left"` aligns to the start. */
|
|
6
22
|
align?: SlideAlign;
|
|
7
23
|
className?: string;
|
|
8
24
|
}): react_jsx_runtime.JSX.Element;
|
|
25
|
+
/**
|
|
26
|
+
* Inline two-column grid for use **inside** a `Slide`.
|
|
27
|
+
*
|
|
28
|
+
* Use this when you need a title or other content above two columns.
|
|
29
|
+
* For a full-viewport two-column slide, use `SlideSplitLayout` instead.
|
|
30
|
+
*/
|
|
31
|
+
declare function SlideColumns({ left, right, className, }: {
|
|
32
|
+
left: React.ReactNode;
|
|
33
|
+
right: React.ReactNode;
|
|
34
|
+
className?: string;
|
|
35
|
+
}): react_jsx_runtime.JSX.Element;
|
|
36
|
+
/**
|
|
37
|
+
* Full-viewport two-column slide — a **top-level** alternative to `Slide`.
|
|
38
|
+
*
|
|
39
|
+
* Do **not** nest this inside `Slide`; it renders its own `h-dvh w-dvw`
|
|
40
|
+
* container, border, and padding. To combine a title with two columns,
|
|
41
|
+
* use `SlideColumns` inside a `Slide` instead.
|
|
42
|
+
*/
|
|
9
43
|
declare function SlideSplitLayout({ left, right, className, }: {
|
|
10
44
|
left: React.ReactNode;
|
|
11
45
|
right: React.ReactNode;
|
|
12
46
|
className?: string;
|
|
13
47
|
}): react_jsx_runtime.JSX.Element;
|
|
14
|
-
|
|
48
|
+
/**
|
|
49
|
+
* Primary heading for a slide. Renders an `<h1>` with responsive sizing
|
|
50
|
+
* that scales from `text-4xl` to `text-7xl` across breakpoints.
|
|
51
|
+
*
|
|
52
|
+
* Override the default size with `className` (e.g. `className="text-3xl sm:text-4xl"`).
|
|
53
|
+
*/
|
|
54
|
+
declare function SlideTitle({ children, className, }: {
|
|
15
55
|
children: React.ReactNode;
|
|
16
56
|
className?: string;
|
|
17
57
|
}): react_jsx_runtime.JSX.Element;
|
|
18
|
-
|
|
58
|
+
/**
|
|
59
|
+
* Secondary text below a title. Renders a `<p>` in a muted foreground color
|
|
60
|
+
* with responsive sizing (`text-lg` to `text-2xl`).
|
|
61
|
+
*/
|
|
62
|
+
declare function SlideSubtitle({ children, className, }: {
|
|
19
63
|
children: React.ReactNode;
|
|
20
64
|
className?: string;
|
|
21
65
|
}): react_jsx_runtime.JSX.Element;
|
|
22
|
-
|
|
66
|
+
/**
|
|
67
|
+
* Small pill-shaped label, typically placed above a title to categorise
|
|
68
|
+
* the slide (e.g. component name, topic tag).
|
|
69
|
+
*/
|
|
70
|
+
declare function SlideBadge({ children, className, }: {
|
|
23
71
|
children: React.ReactNode;
|
|
24
72
|
className?: string;
|
|
25
73
|
}): react_jsx_runtime.JSX.Element;
|
|
26
|
-
|
|
74
|
+
/**
|
|
75
|
+
* Italic accent text for slide headers — use for event names, series labels,
|
|
76
|
+
* or other branding above the title.
|
|
77
|
+
*/
|
|
78
|
+
declare function SlideHeaderBadge({ children, className, }: {
|
|
27
79
|
children: React.ReactNode;
|
|
28
80
|
className?: string;
|
|
29
81
|
}): react_jsx_runtime.JSX.Element;
|
|
30
|
-
|
|
82
|
+
/**
|
|
83
|
+
* Syntax-highlighted code block powered by highlight.js.
|
|
84
|
+
*
|
|
85
|
+
* Pass code as a **string** child. The language is auto-detected from the
|
|
86
|
+
* `title` file extension (e.g. `"example.tsx"` → TypeScript); falls back
|
|
87
|
+
* to TypeScript when unspecified. Supports JS, TS, JSX, and TSX.
|
|
88
|
+
*
|
|
89
|
+
* Theme colours are controlled by CSS custom properties (`--sh-*` / `--nxs-code-*`)
|
|
90
|
+
* defined in `nextjs-slides/styles.css`. Override them in `:root` or `.dark`.
|
|
91
|
+
*
|
|
92
|
+
* @example
|
|
93
|
+
* ```tsx
|
|
94
|
+
* <SlideCode title="api.ts">{`export async function fetchData() {
|
|
95
|
+
* return fetch('/api/data');
|
|
96
|
+
* }`}</SlideCode>
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
99
|
+
declare function SlideCode({ children, className, title, }: {
|
|
100
|
+
/** Code string to highlight. Leading/trailing whitespace is trimmed automatically. */
|
|
31
101
|
children: string;
|
|
32
102
|
className?: string;
|
|
103
|
+
/** File name shown above the code block. Its extension determines the highlight language. */
|
|
33
104
|
title?: string;
|
|
34
105
|
}): react_jsx_runtime.JSX.Element;
|
|
35
|
-
|
|
106
|
+
/**
|
|
107
|
+
* Bullet-point list container. Wrap {@link SlideListItem} children inside this.
|
|
108
|
+
*/
|
|
109
|
+
declare function SlideList({ children, className, }: {
|
|
36
110
|
children: React.ReactNode;
|
|
37
111
|
className?: string;
|
|
38
112
|
}): react_jsx_runtime.JSX.Element;
|
|
39
|
-
|
|
113
|
+
/**
|
|
114
|
+
* Single bullet item inside a {@link SlideList}. Renders a small dot
|
|
115
|
+
* followed by the content.
|
|
116
|
+
*/
|
|
117
|
+
declare function SlideListItem({ children, className, }: {
|
|
40
118
|
children: React.ReactNode;
|
|
41
119
|
className?: string;
|
|
42
120
|
}): react_jsx_runtime.JSX.Element;
|
|
43
|
-
|
|
121
|
+
/**
|
|
122
|
+
* Small footnote text in a faded colour, typically placed at the bottom
|
|
123
|
+
* of a slide for annotations or caveats.
|
|
124
|
+
*/
|
|
125
|
+
declare function SlideNote({ children, className, }: {
|
|
44
126
|
children: React.ReactNode;
|
|
45
127
|
className?: string;
|
|
46
128
|
}): react_jsx_runtime.JSX.Element;
|
|
129
|
+
/**
|
|
130
|
+
* Live interactive component embed. Keyboard navigation (arrow keys, space)
|
|
131
|
+
* is disabled while focus is inside the demo area so the embedded component
|
|
132
|
+
* can handle its own input.
|
|
133
|
+
*
|
|
134
|
+
* The container tracks its maximum height to prevent layout jumps when the
|
|
135
|
+
* child re-renders with different content sizes.
|
|
136
|
+
*
|
|
137
|
+
* @example
|
|
138
|
+
* ```tsx
|
|
139
|
+
* <SlideDemo label="Live counter">
|
|
140
|
+
* <Counter />
|
|
141
|
+
* </SlideDemo>
|
|
142
|
+
* ```
|
|
143
|
+
*/
|
|
47
144
|
declare function SlideDemo({ children, className, label, }: {
|
|
48
145
|
children: React.ReactNode;
|
|
49
146
|
className?: string;
|
|
147
|
+
/** Optional uppercase label shown above the demo area. */
|
|
50
148
|
label?: string;
|
|
51
149
|
}): react_jsx_runtime.JSX.Element;
|
|
52
|
-
|
|
150
|
+
/**
|
|
151
|
+
* Container for {@link SlideStatement} items. Adds border separators between
|
|
152
|
+
* statements automatically.
|
|
153
|
+
*/
|
|
154
|
+
declare function SlideStatementList({ children, className, }: {
|
|
53
155
|
children: React.ReactNode;
|
|
54
156
|
className?: string;
|
|
55
157
|
}): react_jsx_runtime.JSX.Element;
|
|
158
|
+
/**
|
|
159
|
+
* Title + description pair for structured content blocks.
|
|
160
|
+
* Use inside a {@link SlideStatementList} for automatic border separators.
|
|
161
|
+
*/
|
|
56
162
|
declare function SlideStatement({ title, description, className, }: {
|
|
163
|
+
/** Bold heading text. */
|
|
57
164
|
title: string;
|
|
165
|
+
/** Optional muted description below the title. */
|
|
58
166
|
description?: string;
|
|
59
167
|
className?: string;
|
|
60
168
|
}): react_jsx_runtime.JSX.Element;
|
|
169
|
+
/**
|
|
170
|
+
* Speaker card with an avatar circle, name, and role/title.
|
|
171
|
+
* When `avatar` is omitted a placeholder circle is shown.
|
|
172
|
+
*
|
|
173
|
+
* Use inside {@link SlideSpeakerGrid} or {@link SlideSpeakerList} to
|
|
174
|
+
* lay out multiple speakers.
|
|
175
|
+
*/
|
|
61
176
|
declare function SlideSpeaker({ name, title, avatar, className, }: {
|
|
62
177
|
name: string;
|
|
63
178
|
title: string;
|
|
@@ -65,13 +180,20 @@ declare function SlideSpeaker({ name, title, avatar, className, }: {
|
|
|
65
180
|
avatar?: string;
|
|
66
181
|
className?: string;
|
|
67
182
|
}): react_jsx_runtime.JSX.Element;
|
|
68
|
-
|
|
183
|
+
/**
|
|
184
|
+
* Two-column responsive grid for laying out {@link SlideSpeaker} cards
|
|
185
|
+
* side by side (stacks to one column on small screens).
|
|
186
|
+
*/
|
|
187
|
+
declare function SlideSpeakerGrid({ children, className, }: {
|
|
69
188
|
children: React.ReactNode;
|
|
70
189
|
className?: string;
|
|
71
190
|
}): react_jsx_runtime.JSX.Element;
|
|
72
|
-
|
|
191
|
+
/**
|
|
192
|
+
* Vertical stack layout for {@link SlideSpeaker} cards.
|
|
193
|
+
*/
|
|
194
|
+
declare function SlideSpeakerList({ children, className, }: {
|
|
73
195
|
children: React.ReactNode;
|
|
74
196
|
className?: string;
|
|
75
197
|
}): react_jsx_runtime.JSX.Element;
|
|
76
198
|
|
|
77
|
-
export { Slide, SlideBadge, SlideCode, SlideDemo, SlideHeaderBadge, SlideList, SlideListItem, SlideNote, SlideSpeaker, SlideSpeakerGrid, SlideSpeakerList, SlideSplitLayout, SlideStatement, SlideStatementList, SlideSubtitle, SlideTitle };
|
|
199
|
+
export { Slide, SlideBadge, SlideCode, SlideColumns, SlideDemo, SlideHeaderBadge, SlideList, SlideListItem, SlideNote, SlideSpeaker, SlideSpeakerGrid, SlideSpeakerList, SlideSplitLayout, SlideStatement, SlideStatementList, SlideSubtitle, SlideTitle };
|