@atom63/slides 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 You Zhang (ATOM63)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,210 @@
1
+ # @atom63/slides
2
+
3
+ A host-agnostic **MDX slide presentation engine** — write decks in MDX against an opinionated **template grammar**, and re-theme them with CSS custom-property **tokens**. The same engine powers the Slides app in [OS63](https://os.atom63.io) and runs standalone anywhere React + Vite + Tailwind v4 do.
4
+
5
+ - **Templates, not div soup** — ~20 composable slide templates (`CoverSlide`, `StatBento`, `HeroBento`, `SplitHalf`, `QuoteSlide`, `FullBleedSlide`, …) plus low-level primitives.
6
+ - **Token theming** — every surface reads `--theme-slide-*` (and base) custom properties; swap a token set to restyle a whole deck.
7
+ - **Batteries-included player** — keyboard nav, grid overview, presenter PiP, mobile layout, optional source view and password gate.
8
+ - **Introspectable** — a machine-readable `templateRegistry` describes every template's content slots (for tooling, editors, and agents).
9
+
10
+ > Status: `0.1.x`, extracted from a monorepo. The API may shift before `1.0`.
11
+
12
+ ## Install
13
+
14
+ ```bash
15
+ npm i @atom63/slides
16
+ ```
17
+
18
+ Peer dependencies you must also install:
19
+
20
+ ```bash
21
+ npm i react react-dom sonner
22
+ ```
23
+
24
+ You also need **Tailwind CSS v4** in the consuming app (the engine ships utility classes, not a pre-compiled stylesheet — see [Styling](#styling)).
25
+
26
+ ## Quick start
27
+
28
+ A single-deck app needs four things: compile an `.mdx` deck, build a `SlideDeckItem`, render `<SlidesPlayer>`, and wire up styles. (A complete reference app lives at [`apps/deck-starter`](../../apps/deck-starter) in the repo.)
29
+
30
+ **`vite.config.ts`** — compile MDX with a frontmatter export:
31
+
32
+ ```ts
33
+ import mdx from '@mdx-js/rollup'
34
+ import react from '@vitejs/plugin-react'
35
+ import tailwindcss from '@tailwindcss/vite'
36
+ import remarkFrontmatter from 'remark-frontmatter'
37
+ import remarkMdxFrontmatter from 'remark-mdx-frontmatter'
38
+ import remarkGfm from 'remark-gfm'
39
+ import { defineConfig } from 'vite'
40
+
41
+ export default defineConfig({
42
+ plugins: [
43
+ { enforce: 'pre', ...mdx({
44
+ remarkPlugins: [remarkFrontmatter, remarkMdxFrontmatter, remarkGfm],
45
+ providerImportSource: '@mdx-js/react',
46
+ }) },
47
+ react({ include: /\.(mdx|tsx|jsx)$/ }),
48
+ tailwindcss(),
49
+ ],
50
+ })
51
+ ```
52
+
53
+ **`app.tsx`** — the player provides the slide components internally; just pass the compiled deck:
54
+
55
+ ```tsx
56
+ import { SlidesPlayer } from '@atom63/slides'
57
+ import type { SlideDeckItem, SlideDeckMeta } from '@atom63/slides'
58
+ import Deck, { frontmatter } from './deck.mdx'
59
+
60
+ const deck: SlideDeckItem = {
61
+ slug: 'my-talk',
62
+ meta: frontmatter as unknown as SlideDeckMeta,
63
+ content: Deck,
64
+ }
65
+
66
+ export function App() {
67
+ return (
68
+ <div style={{ height: '100vh', width: '100vw' }}>
69
+ <SlidesPlayer deck={deck} onBack={() => {}} />
70
+ </div>
71
+ )
72
+ }
73
+ ```
74
+
75
+ **`deck.mdx`** — frontmatter, then `---`-separated slides:
76
+
77
+ ```mdx
78
+ ---
79
+ title: "My Talk"
80
+ date: "2026-01-01"
81
+ description: "An example deck."
82
+ ---
83
+
84
+ import { CoverSlide, StatementSlide } from "@atom63/slides";
85
+
86
+ <CoverSlide eyebrow="2026" title="My Talk" credit="You" />
87
+
88
+ ---
89
+
90
+ <StatementSlide kicker="The point" title="One idea per slide." />
91
+
92
+ ---
93
+
94
+ ## Bare markdown works too
95
+
96
+ - it renders through the engine's prose components
97
+ - including inline `code`
98
+ ```
99
+
100
+ ## Styling
101
+
102
+ The engine uses Tailwind v4 utility classes. In your **Tailwind entry CSS**, import its stylesheets and point `@source` at its built classes:
103
+
104
+ ```css
105
+ @import "tailwindcss";
106
+ @import "@atom63/slides/theme-defaults"; /* tokens + Tailwind @theme color mappings */
107
+ @import "@atom63/slides/styles"; /* slide reveal animations */
108
+
109
+ /* Generate the utility classes the engine uses. */
110
+ @source "../node_modules/@atom63/slides/dist/**/*.js";
111
+ ```
112
+
113
+ > Import the engine CSS with **CSS `@import`** (in the Tailwind entry), **not** a JS `import` — `theme-defaults` ships a Tailwind `@theme` block that maps the palette into utilities like `text-foreground`/`bg-primary`, and `@theme` is only processed when the file is part of the Tailwind build.
114
+
115
+ - `@atom63/slides/theme-defaults` — self-contained default values for every token the player reads + the `@theme` color mappings, so it renders out-of-the-box. A host that ships its own design tokens (e.g. via a token package) can skip this import.
116
+ - `@atom63/slides/styles` — the slide reveal animation keyframes.
117
+
118
+ ## Theming
119
+
120
+ Everything is driven by CSS custom properties, so you restyle a deck without touching components. The default is light (`theme-defaults`).
121
+
122
+ **Swap to a built-in theme** — one extra `@import`, *after* `theme-defaults`, in your Tailwind entry CSS:
123
+
124
+ ```css
125
+ @import "tailwindcss";
126
+ @import "@atom63/slides/theme-defaults";
127
+ @import "@atom63/slides/themes/dark"; /* flips the whole deck to dark */
128
+ @import "@atom63/slides/styles";
129
+ ```
130
+
131
+ Five themes ship in the box — each is one line, swapped for the `dark` line above:
132
+
133
+ | Theme | Import | Look |
134
+ |---|---|---|
135
+ | `dark` | `@import "@atom63/slides/themes/dark";` | Neutral dark, blue signal. |
136
+ | `terminal` | `@import "@atom63/slides/themes/terminal";` | Dark monospace; phosphor-green on GitHub-dark greys. |
137
+ | `editorial` | `@import "@atom63/slides/themes/editorial";` | Light paper & ink; Cormorant serif, editorial red. |
138
+ | `neon` | `@import "@atom63/slides/themes/neon";` | Dark cyber; cyan/magenta on navy. |
139
+ | `bold` | `@import "@atom63/slides/themes/bold";` | Dark, charcoal + bright orange, strong Archivo sans. |
140
+
141
+ > Theme palettes adapted from [zarazhangrui/frontend-slides](https://github.com/zarazhangrui/frontend-slides) (MIT).
142
+
143
+ ### Theme contract
144
+
145
+ A theme is **only** a `:root` override of documented CSS custom properties — a palette, the three font tokens (`--font-sans` for headings/body, `--font-mono` for labels/code, `--font-serif` for quotes), and a few `--theme-slide-*` polish tokens — plus an optional `@import url(...)` for a webfont. **There is no per-theme component code.** This is the controllable surface: to restyle a deck you set or override these tokens, you do **not** write freeform CSS or bespoke components. The complete token set lives in [`src/styles/theme-defaults.css`](./src/styles/theme-defaults.css) — that file is the contract; every built-in theme is just a subset of it overridden. Model a new theme on any of the shipped files in [`src/styles/themes/`](./src/styles/themes/).
146
+
147
+ **Write your own theme** — override the tokens in your CSS. Most surfaces derive from the base palette via `color-mix`, so a handful of overrides restyle the whole deck:
148
+
149
+ ```css
150
+ :root {
151
+ /* base palette — drives slides AND chrome */
152
+ --background: #0b0b10;
153
+ --foreground: #f2f2f5;
154
+ --border: #3a3a42; /* control / panel borders */
155
+ --primary: #7c5cff; /* the signal color */
156
+
157
+ /* slide-specific knobs (optional) */
158
+ --theme-slide-accent: var(--primary);
159
+ --theme-slide-rule-color: color-mix(in oklch, var(--foreground) 25%, transparent);
160
+ --theme-slide-surface: #1a1a20; /* card / bento surfaces */
161
+ --theme-slide-quote-color: #d8d8de;
162
+ }
163
+ ```
164
+
165
+ Key tokens: **base palette** — `--background`, `--foreground`, `--card`, `--muted`, `--muted-foreground`, `--border`, `--input`, `--primary`, `--primary-foreground`, `--accent`; **slides** — `--theme-slide-bg`, `--theme-slide-accent`, `--theme-slide-rule-color`, `--theme-slide-rule-width`, `--theme-slide-surface`, `--theme-slide-muted`, `--theme-slide-code-bg`, `--theme-slide-quote-color`, `--theme-slide-stage-bg`. The full set lives in [`src/styles/theme-defaults.css`](./src/styles/theme-defaults.css) — copy it as a starting point for a custom theme.
166
+
167
+ > Runtime light/dark toggle: import `themes/dark` is a hard swap. For a toggle, copy `dark.css` and re-scope its `:root` to e.g. `[data-slides-theme="dark"]`, then set that attribute on a wrapper.
168
+
169
+ ## Authoring
170
+
171
+ See the reference deck for the full template catalog and slot APIs, and inspect templates programmatically:
172
+
173
+ ```ts
174
+ import { templateRegistry, getTemplate, listTemplates } from '@atom63/slides'
175
+
176
+ getTemplate('StatBento')
177
+ // → { name, label, category, props: [...], slots: [{ name: 'Stat', min: 0, max: 6, props: [...] }, ...] }
178
+ ```
179
+
180
+ ## Subpath exports
181
+
182
+ Beyond the engine entry (`@atom63/slides`) and the style sheets (`@atom63/slides/styles`, `@atom63/slides/theme-defaults`), two optional subpaths ship in the same package.
183
+
184
+ ### `@atom63/slides/vite` — build-time Vite plugins
185
+
186
+ For multi-deck apps, the Vite plugins extract MDX frontmatter into a static manifest (so decks code-split into lazy chunks) and make `*.mdx?raw` imports resolve to source even when `@mdx-js/rollup` is active. `vite` is an optional peer dependency — install it only if you use this subpath.
187
+
188
+ ```ts
189
+ // vite.config.ts
190
+ import { mdxManifestPlugin, mdxRawPlugin } from '@atom63/slides/vite'
191
+
192
+ export default defineConfig({
193
+ plugins: [mdxManifestPlugin(), mdxRawPlugin() /* …mdx(), react(), tailwindcss() */],
194
+ })
195
+ ```
196
+
197
+ ### `@atom63/slides/editor` — live deck editor
198
+
199
+ A GUI deck editor with a live, runtime-compiled preview (no bundler in the loop), a registry-driven template palette, and a light/dark preview toggle. Import its chrome stylesheet as a side effect.
200
+
201
+ ```tsx
202
+ import { DeckEditor } from '@atom63/slides/editor'
203
+ import '@atom63/slides/editor/styles'
204
+
205
+ <DeckEditor source={deckMdxSource} onChange={setSource} />
206
+ ```
207
+
208
+ ## License
209
+
210
+ MIT © You Zhang (ATOM63)