@honeydeck/honeydeck 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/AGENTS.md +25 -0
- package/DEVELOPMENT.md +522 -0
- package/LICENSE +21 -0
- package/Readme.md +49 -0
- package/SPEC.md +88 -0
- package/docs/components.md +63 -0
- package/docs/configuration.md +91 -0
- package/docs/getting-started.md +116 -0
- package/docs/kit-authoring.md +207 -0
- package/docs/kits.md +387 -0
- package/docs/local-development.md +95 -0
- package/docs/mermaid.md +198 -0
- package/docs/mobile.md +108 -0
- package/docs/navigation.md +93 -0
- package/docs/next-steps.md +377 -0
- package/docs/pdf-export.md +91 -0
- package/docs/presenter-mode.md +104 -0
- package/docs/slides.md +130 -0
- package/docs/slidev-migration.md +42 -0
- package/docs/steps-and-reveals.md +171 -0
- package/package.json +134 -0
- package/skills/SPEC.md +21 -0
- package/skills/honeydeck/SKILL.md +65 -0
- package/skills/presentation-writing/SKILL.md +75 -0
- package/skills/slidev-migration/SKILL.md +153 -0
- package/src/SPEC.md +89 -0
- package/src/assets.d.ts +30 -0
- package/src/cli/SPEC.md +230 -0
- package/src/cli/args.ts +3 -0
- package/src/cli/banner.ts +9 -0
- package/src/cli/bin.js +5 -0
- package/src/cli/build.ts +229 -0
- package/src/cli/deck-path.ts +32 -0
- package/src/cli/dev.ts +263 -0
- package/src/cli/index.ts +126 -0
- package/src/cli/init.ts +369 -0
- package/src/cli/pdf.ts +923 -0
- package/src/cli/skill.ts +75 -0
- package/src/cli/templates/SPEC.md +70 -0
- package/src/cli/templates/deck-mdx.ts +15 -0
- package/src/cli/templates/package-json.ts +36 -0
- package/src/cli/templates/sparkle-button.ts +15 -0
- package/src/cli/templates/starter/components/SparkleButton.tsx +84 -0
- package/src/cli/templates/starter/deck.mdx +153 -0
- package/src/cli/templates/starter/styles.css +14 -0
- package/src/cli/templates/styles-css.ts +14 -0
- package/src/defaults.ts +1 -0
- package/src/layouts/ColorModeImage.tsx +55 -0
- package/src/layouts/SPEC.md +393 -0
- package/src/layouts/SlideFrame.tsx +48 -0
- package/src/layouts/bee/Blank.tsx +12 -0
- package/src/layouts/bee/Cover.tsx +70 -0
- package/src/layouts/bee/Default.tsx +42 -0
- package/src/layouts/bee/Image/Image.tsx +151 -0
- package/src/layouts/bee/Image/placeholder-dark.webp +0 -0
- package/src/layouts/bee/Image/placeholder-vertical-dark.webp +0 -0
- package/src/layouts/bee/Image/placeholder-vertical.webp +0 -0
- package/src/layouts/bee/Image/placeholder.webp +0 -0
- package/src/layouts/bee/ImageLeft.tsx +27 -0
- package/src/layouts/bee/ImageRight.tsx +27 -0
- package/src/layouts/bee/ImageSide.tsx +107 -0
- package/src/layouts/bee/Section.tsx +40 -0
- package/src/layouts/bee/TwoCol.tsx +108 -0
- package/src/layouts/bee/index.ts +40 -0
- package/src/layouts/clean/Blank.tsx +12 -0
- package/src/layouts/clean/Cover.tsx +58 -0
- package/src/layouts/clean/Default.tsx +33 -0
- package/src/layouts/clean/Image/Image.tsx +103 -0
- package/src/layouts/clean/ImageLeft.tsx +27 -0
- package/src/layouts/clean/ImageRight.tsx +27 -0
- package/src/layouts/clean/ImageSide.tsx +113 -0
- package/src/layouts/clean/Section.tsx +35 -0
- package/src/layouts/clean/TwoCol.tsx +63 -0
- package/src/layouts/clean/index.ts +40 -0
- package/src/layouts/index.ts +60 -0
- package/src/layouts/placeholders.ts +9 -0
- package/src/layouts/utils.ts +13 -0
- package/src/remark/SPEC.md +49 -0
- package/src/remark/h1-extract.ts +124 -0
- package/src/remark/index.ts +4 -0
- package/src/remark/shiki-code-blocks.ts +325 -0
- package/src/remark/step-numbering.ts +412 -0
- package/src/runtime/Deck.tsx +533 -0
- package/src/runtime/SPEC.md +256 -0
- package/src/runtime/SlideCanvas.tsx +95 -0
- package/src/runtime/TimelineContext.tsx +122 -0
- package/src/runtime/app-shell/index.html +31 -0
- package/src/runtime/app-shell/main.tsx +42 -0
- package/src/runtime/aspectRatio.ts +34 -0
- package/src/runtime/colorMode.ts +23 -0
- package/src/runtime/components/BrowserFrame.tsx +233 -0
- package/src/runtime/components/Button.tsx +57 -0
- package/src/runtime/components/CodeBlock.tsx +210 -0
- package/src/runtime/components/ColorModeCycleButton.tsx +59 -0
- package/src/runtime/components/ErrorBoundary.tsx +125 -0
- package/src/runtime/components/Keyboard.tsx +87 -0
- package/src/runtime/components/ListStyle.tsx +203 -0
- package/src/runtime/components/NavBar.tsx +223 -0
- package/src/runtime/components/NavBarButton.tsx +47 -0
- package/src/runtime/components/NavBarDivider.tsx +3 -0
- package/src/runtime/components/Notes.tsx +171 -0
- package/src/runtime/components/Reveal.tsx +82 -0
- package/src/runtime/components/RevealGroup.tsx +193 -0
- package/src/runtime/components/SPEC.md +263 -0
- package/src/runtime/components/SlideNumberBadge.tsx +11 -0
- package/src/runtime/components/TimelineSteps.tsx +115 -0
- package/src/runtime/components/index.ts +55 -0
- package/src/runtime/index.ts +42 -0
- package/src/runtime/inputOwnership.ts +68 -0
- package/src/runtime/keyboardTarget.ts +7 -0
- package/src/runtime/lastSlideRoute.ts +56 -0
- package/src/runtime/navigation.ts +211 -0
- package/src/runtime/router.ts +157 -0
- package/src/runtime/slideData.ts +137 -0
- package/src/runtime/sync.ts +267 -0
- package/src/runtime/types.ts +182 -0
- package/src/runtime/useKeyboardNav.ts +138 -0
- package/src/runtime/useSwipeNav.ts +257 -0
- package/src/runtime/views/DocsView.tsx +74 -0
- package/src/runtime/views/OverviewView.tsx +386 -0
- package/src/runtime/views/PresenterNotesPanel.tsx +76 -0
- package/src/runtime/views/PresenterView.tsx +340 -0
- package/src/runtime/views/SPEC.md +152 -0
- package/src/runtime/views/docs/ComponentsTab.tsx +178 -0
- package/src/runtime/views/docs/DocsHeader.tsx +101 -0
- package/src/runtime/views/docs/Intro.tsx +20 -0
- package/src/runtime/views/docs/LayoutsTab.tsx +324 -0
- package/src/runtime/views/docs/ThemeTab.tsx +110 -0
- package/src/runtime/views/index.ts +7 -0
- package/src/runtime/views/overviewGrid.ts +106 -0
- package/src/runtime/views/presenterPreview.ts +27 -0
- package/src/runtime/virtual-modules.d.ts +98 -0
- package/src/theme/SPEC.md +179 -0
- package/src/theme/base.css +623 -0
- package/src/theme/bee.css +35 -0
- package/src/theme/clean.css +38 -0
- package/src/vite-plugin/SPEC.md +114 -0
- package/src/vite-plugin/component-doc-crawler.ts +350 -0
- package/src/vite-plugin/deck-loader.ts +148 -0
- package/src/vite-plugin/index.ts +373 -0
- package/src/vite-plugin/layout-demo-crawler.ts +802 -0
- package/src/vite-plugin/splitter.ts +353 -0
- package/src/vite-plugin/token-manifest.ts +163 -0
- package/src/vite-plugin/virtual-modules.ts +587 -0
package/docs/kits.md
ADDED
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
# Customization - Kits
|
|
2
|
+
|
|
3
|
+
Honeydeck works out of the box with sensible defaults. Customize progressively — override a color, swap a layout, or adopt a full kit from npm.
|
|
4
|
+
|
|
5
|
+
## Zero Config
|
|
6
|
+
|
|
7
|
+
A plain deck needs no imports or configuration:
|
|
8
|
+
|
|
9
|
+
```mdx
|
|
10
|
+
# Hello world
|
|
11
|
+
|
|
12
|
+
This just works with built-in styling.
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Honeydeck automatically loads base CSS with default design tokens and the built-in layout set.
|
|
16
|
+
|
|
17
|
+
## Customizing Colors & Typography
|
|
18
|
+
|
|
19
|
+
Import a CSS file to override design tokens. The cascade does the rest:
|
|
20
|
+
|
|
21
|
+
```mdx
|
|
22
|
+
import './my-theme.css'
|
|
23
|
+
|
|
24
|
+
# Now with my brand colors
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
```css
|
|
28
|
+
/* my-theme.css */
|
|
29
|
+
:root {
|
|
30
|
+
--honeydeck-primary: oklch(55% 0.25 280);
|
|
31
|
+
--honeydeck-font-heading: 'Playfair Display', serif;
|
|
32
|
+
--honeydeck-border-radius: 1rem;
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
You only override what you want — everything else keeps its default. Both light and dark modes can be targeted:
|
|
37
|
+
|
|
38
|
+
```css
|
|
39
|
+
[data-honeydeck-color-mode="light"] {
|
|
40
|
+
--honeydeck-primary: oklch(50% 0.2 250);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
[data-honeydeck-color-mode="dark"] {
|
|
44
|
+
--honeydeck-primary: oklch(70% 0.2 250);
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Available Tokens
|
|
49
|
+
|
|
50
|
+
| Token | Purpose |
|
|
51
|
+
|-------|---------|
|
|
52
|
+
| `--honeydeck-primary` | Brand color (per mode) |
|
|
53
|
+
| `--honeydeck-background` | Slide background |
|
|
54
|
+
| `--honeydeck-foreground` | Main text color |
|
|
55
|
+
| `--honeydeck-surface` | Cards, code blocks, callouts |
|
|
56
|
+
| `--honeydeck-border` | Border/divider color |
|
|
57
|
+
| `--honeydeck-accent` | Accent, computed as complementary by default |
|
|
58
|
+
| `--honeydeck-font-heading` | Heading font family |
|
|
59
|
+
| `--honeydeck-font-body` | Body font family |
|
|
60
|
+
| `--honeydeck-font-mono` | Monospace font family |
|
|
61
|
+
| `--honeydeck-font-base` | Base font size (default: 16px) |
|
|
62
|
+
| `--honeydeck-font-scale` | Heading scale factor (default: 1.25) |
|
|
63
|
+
| `--honeydeck-border-radius` | Default border radius |
|
|
64
|
+
| `--honeydeck-code-line-dim-opacity` | Dim for non-highlighted code lines |
|
|
65
|
+
|
|
66
|
+
→ Full token reference in [Kit Authoring](kit-authoring.md#design-tokens)
|
|
67
|
+
|
|
68
|
+
### Bundled Themes
|
|
69
|
+
|
|
70
|
+
Honeydeck defaults to a clean black, white, and grey theme:
|
|
71
|
+
|
|
72
|
+
```css
|
|
73
|
+
@import "tailwindcss";
|
|
74
|
+
@import "@honeydeck/honeydeck/theme.css";
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
`@honeydeck/honeydeck/themes/clean.css` is available as an optional clean theme layer when you want to name that layer directly.
|
|
78
|
+
|
|
79
|
+
Honeydeck also includes a Bee theme that can be layered on top of the base theme:
|
|
80
|
+
|
|
81
|
+
```css
|
|
82
|
+
@import "tailwindcss";
|
|
83
|
+
@import "@honeydeck/honeydeck/theme.css";
|
|
84
|
+
@import "@honeydeck/honeydeck/themes/bee.css";
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Bundled Layout Sets
|
|
88
|
+
|
|
89
|
+
The default layout set is clean and minimal:
|
|
90
|
+
|
|
91
|
+
```yaml
|
|
92
|
+
---
|
|
93
|
+
layouts: "@honeydeck/honeydeck/layouts"
|
|
94
|
+
---
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
The same clean set is also available through the named clean kit import path `@honeydeck/honeydeck/layouts/clean`.
|
|
98
|
+
|
|
99
|
+
Use the Bee layout set with the Bee theme when you want the original playful Bee look:
|
|
100
|
+
|
|
101
|
+
```yaml
|
|
102
|
+
---
|
|
103
|
+
layouts: "@honeydeck/honeydeck/layouts/bee"
|
|
104
|
+
---
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
For two-column slides, import slots from the matching layout set:
|
|
108
|
+
|
|
109
|
+
```mdx
|
|
110
|
+
// Clean default
|
|
111
|
+
import { Left, Right } from '@honeydeck/honeydeck/layouts/TwoCol'
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
```mdx
|
|
115
|
+
// Bee layout set
|
|
116
|
+
import { Left, Right } from '@honeydeck/honeydeck/layouts/bee/TwoCol'
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Using Tailwind
|
|
120
|
+
|
|
121
|
+
Tokens are mapped to Tailwind utilities, so you can use them inline:
|
|
122
|
+
|
|
123
|
+
```mdx
|
|
124
|
+
<div className="bg-surface text-surface-foreground border border-border rounded-honeydeck">
|
|
125
|
+
Styled with theme tokens
|
|
126
|
+
</div>
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Using Layouts
|
|
130
|
+
|
|
131
|
+
in your decks frontmatter, configure which layouts to use:
|
|
132
|
+
|
|
133
|
+
```yaml
|
|
134
|
+
---
|
|
135
|
+
layouts: "awsome-kit/layouts"
|
|
136
|
+
---
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Select a layout in slide frontmatter:
|
|
140
|
+
|
|
141
|
+
```yaml
|
|
142
|
+
---
|
|
143
|
+
layout: Section
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
# Big Idea
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
If no `layout:` is specified, `Default` is used. Layout names are PascalCase.
|
|
150
|
+
|
|
151
|
+
### Built-in Layouts
|
|
152
|
+
|
|
153
|
+
| Layout | Description |
|
|
154
|
+
|--------|-------------|
|
|
155
|
+
| `Blank` | Empty slide with only children |
|
|
156
|
+
| `Default` | Title top-left, body flows below |
|
|
157
|
+
| `Section` | Big centered heading for section breaks |
|
|
158
|
+
| `Cover` | Opening/closing slide (title, body, author) |
|
|
159
|
+
| `TwoCol` | Two equal columns |
|
|
160
|
+
| `Image` | Prominent image with optional title and children |
|
|
161
|
+
| `ImageLeft` | Prominent left image with title and body on the right |
|
|
162
|
+
| `ImageRight` | Prominent right image with title and body on the left |
|
|
163
|
+
|
|
164
|
+
### Passing Props to Layouts
|
|
165
|
+
|
|
166
|
+
Layouts receive extra frontmatter fields as props; Cover body copy belongs in the slide content:
|
|
167
|
+
|
|
168
|
+
```mdx
|
|
169
|
+
---
|
|
170
|
+
layout: Cover
|
|
171
|
+
author: You_Name_Here
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
# Honeydeck
|
|
175
|
+
|
|
176
|
+
A modern slide framework.
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### Two-Column Layout
|
|
180
|
+
|
|
181
|
+
`TwoCol` uses slot components you import:
|
|
182
|
+
|
|
183
|
+
```mdx
|
|
184
|
+
---
|
|
185
|
+
layout: TwoCol
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
import { Left, Right } from '@honeydeck/honeydeck/layouts/TwoCol'
|
|
189
|
+
|
|
190
|
+
<Left>
|
|
191
|
+
## Benefits
|
|
192
|
+
- Fast iteration
|
|
193
|
+
- Live reload
|
|
194
|
+
</Left>
|
|
195
|
+
|
|
196
|
+
<Right>
|
|
197
|
+
## Trade-offs
|
|
198
|
+
- Requires Node.js
|
|
199
|
+
</Right>
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Image Layout
|
|
203
|
+
|
|
204
|
+
Displays a specified image large and prominent:
|
|
205
|
+
|
|
206
|
+
```yaml
|
|
207
|
+
---
|
|
208
|
+
layout: Image
|
|
209
|
+
image: /diagrams/architecture.png
|
|
210
|
+
darkImage: /diagrams/architecture-dark.png
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
# System Architecture
|
|
214
|
+
|
|
215
|
+
Our distributed system.
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### Side Image Layouts
|
|
219
|
+
|
|
220
|
+
`ImageLeft` and `ImageRight` place the image beside the content while using the same `image`, `darkImage`, and `alt` frontmatter as `Image`:
|
|
221
|
+
|
|
222
|
+
```yaml
|
|
223
|
+
---
|
|
224
|
+
layout: ImageRight
|
|
225
|
+
image: /photos/launch.jpg
|
|
226
|
+
darkImage: /photos/launch-dark.jpg
|
|
227
|
+
alt: Launch moment
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
# Launch Moment
|
|
231
|
+
|
|
232
|
+
Supporting context sits beside the image.
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
## Creating Custom Layouts
|
|
236
|
+
|
|
237
|
+
Custom layouts are React components you import and wrap content with:
|
|
238
|
+
|
|
239
|
+
```tsx
|
|
240
|
+
// components/GradientLayout.tsx
|
|
241
|
+
import type { ReactNode } from 'react'
|
|
242
|
+
|
|
243
|
+
export function GradientLayout({ children }: { children: ReactNode }) {
|
|
244
|
+
return (
|
|
245
|
+
<div className="grid place-items-center h-full bg-gradient-to-br from-purple-900 to-indigo-900 text-white p-12">
|
|
246
|
+
{children}
|
|
247
|
+
</div>
|
|
248
|
+
)
|
|
249
|
+
}
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
Use it in MDX:
|
|
253
|
+
|
|
254
|
+
```mdx
|
|
255
|
+
---
|
|
256
|
+
|
|
257
|
+
import { GradientLayout } from './components/GradientLayout'
|
|
258
|
+
|
|
259
|
+
<GradientLayout>
|
|
260
|
+
# Special Slide
|
|
261
|
+
|
|
262
|
+
With a custom gradient background.
|
|
263
|
+
</GradientLayout>
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
Built-in placeholder images are available as URL exports for custom image layouts:
|
|
269
|
+
|
|
270
|
+
```ts
|
|
271
|
+
import {
|
|
272
|
+
imagePlaceholder,
|
|
273
|
+
imagePlaceholderDark,
|
|
274
|
+
verticalImagePlaceholder,
|
|
275
|
+
verticalImagePlaceholderDark,
|
|
276
|
+
} from '@honeydeck/honeydeck/layouts/placeholders'
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
Use `ColorModeImage` when a custom layout accepts separate light and dark image URLs:
|
|
280
|
+
|
|
281
|
+
```tsx
|
|
282
|
+
import { ColorModeImage } from '@honeydeck/honeydeck'
|
|
283
|
+
|
|
284
|
+
<ColorModeImage src={image} darkSrc={darkImage} alt={alt} />
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
### Creating a Reusable Layout Set
|
|
288
|
+
|
|
289
|
+
For a set of layouts you want to reuse across slides or decks, create a layout map:
|
|
290
|
+
|
|
291
|
+
```ts
|
|
292
|
+
// layouts/index.ts
|
|
293
|
+
import defaultLayouts from '@honeydeck/honeydeck/layouts'
|
|
294
|
+
import HeroLayout from './Hero'
|
|
295
|
+
|
|
296
|
+
export default {
|
|
297
|
+
...defaultLayouts,
|
|
298
|
+
Hero: HeroLayout,
|
|
299
|
+
}
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
Layouts can export a colocated demo for `/#/layouts`:
|
|
303
|
+
|
|
304
|
+
```tsx
|
|
305
|
+
// layouts/Hero.tsx
|
|
306
|
+
import type { LayoutDemo, LayoutProps } from '@honeydeck/honeydeck/types'
|
|
307
|
+
|
|
308
|
+
export default function HeroLayout({ title, children }: LayoutProps) {
|
|
309
|
+
return (/* ... */)
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
export const demo: LayoutDemo = {
|
|
313
|
+
mdx: `---
|
|
314
|
+
layout: Hero
|
|
315
|
+
---
|
|
316
|
+
|
|
317
|
+
# Hero Moment
|
|
318
|
+
|
|
319
|
+
This snippet and preview come from the same demo.`,
|
|
320
|
+
}
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
Reference it in deck frontmatter:
|
|
324
|
+
|
|
325
|
+
```yaml
|
|
326
|
+
---
|
|
327
|
+
layouts: "./layouts"
|
|
328
|
+
---
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
Now you can use `layout: Hero` in any slide. The docs reference lists every layout in the active map, even if no slide currently uses it.
|
|
332
|
+
|
|
333
|
+
## Using Third-Party Kits
|
|
334
|
+
|
|
335
|
+
A **kit** is an npm package that bundles theme CSS, layouts, and/or components. You reference each part individually:
|
|
336
|
+
|
|
337
|
+
```yaml
|
|
338
|
+
---
|
|
339
|
+
layouts: "@company/honeydeck-kit-brand/layouts"
|
|
340
|
+
---
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
```mdx
|
|
344
|
+
import '@company/honeydeck-kit-brand/theme.css'
|
|
345
|
+
import { Callout } from '@company/honeydeck-kit-brand/components'
|
|
346
|
+
|
|
347
|
+
# Hello
|
|
348
|
+
|
|
349
|
+
<Callout>Important!</Callout>
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
### Mix and Match
|
|
353
|
+
|
|
354
|
+
Since each concern is an explicit reference, mix freely:
|
|
355
|
+
|
|
356
|
+
```yaml
|
|
357
|
+
---
|
|
358
|
+
layouts: "@company/honeydeck-kit-brand/layouts"
|
|
359
|
+
---
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
```mdx
|
|
363
|
+
import '@other/honeydeck-kit-minimal/theme.css'
|
|
364
|
+
import { Callout } from '@company/honeydeck-kit-brand/components'
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
Use layouts from one kit, colors from another, components from a third.
|
|
368
|
+
|
|
369
|
+
### Extending a Kit's Theme
|
|
370
|
+
|
|
371
|
+
Layer your overrides on top of a kit's CSS:
|
|
372
|
+
|
|
373
|
+
```css
|
|
374
|
+
/* my-overrides.css */
|
|
375
|
+
@import '@company/honeydeck-kit-brand/theme.css';
|
|
376
|
+
|
|
377
|
+
:root {
|
|
378
|
+
--honeydeck-primary: oklch(50% 0.2 300);
|
|
379
|
+
--honeydeck-font-heading: 'My Font', sans-serif;
|
|
380
|
+
}
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
```mdx
|
|
384
|
+
import './my-overrides.css'
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
→ Building your own kit? See [Kit Authoring](kit-authoring.md)
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# Local development
|
|
2
|
+
|
|
3
|
+
This guide explains how to test Honeydeck locally before it is published to npm.
|
|
4
|
+
|
|
5
|
+
## Prerequisites
|
|
6
|
+
|
|
7
|
+
Honeydeck is currently developed and tested with Node 26+.
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
node --version
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Run Honeydeck from the repository
|
|
14
|
+
|
|
15
|
+
From the Honeydeck repository:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install
|
|
19
|
+
npm run dev
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Root `npm run dev` starts the private showcase deck package and the marketing/docs site together.
|
|
23
|
+
|
|
24
|
+
To run only the showcase deck:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npm -w @honeydeck/showcase run dev
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
To demo the starter deck generated by `honeydeck init`, run:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm -w @honeydeck/honeydeck run dev
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
That points at the real starter template files through the source CLI:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
node --import tsx ./src/cli/index.ts dev --deck src/cli/templates/starter/deck.mdx
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Link the local CLI
|
|
43
|
+
|
|
44
|
+
From the Honeydeck package directory:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
cd packages/honeydeck
|
|
48
|
+
npm link
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Then from any folder:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
honeydeck --help
|
|
55
|
+
honeydeck init --name demo-deck --skip-install
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
`npm link` exposes the local `honeydeck` command, but it does not publish Honeydeck to the npm registry.
|
|
59
|
+
|
|
60
|
+
## Install local Honeydeck in a generated project
|
|
61
|
+
|
|
62
|
+
Until Honeydeck is published, `npm install` inside a generated project may fail with:
|
|
63
|
+
|
|
64
|
+
```txt
|
|
65
|
+
404 Not Found - GET https://registry.npmjs.org/@honeydeck%2fhoneydeck - Not found
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
This happens because the generated project depends on `@honeydeck/honeydeck`, but npm cannot find it in the public registry yet.
|
|
69
|
+
|
|
70
|
+
For local testing, link the local Honeydeck package into the generated project:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
cd /path/to/generated-project
|
|
74
|
+
npm link @honeydeck/honeydeck
|
|
75
|
+
npm install
|
|
76
|
+
npm run dev
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
If the global link does not exist yet, create it first from the Honeydeck package directory:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
cd /path/to/honeydeck/packages/honeydeck
|
|
83
|
+
npm link
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
You can also link the package folder directly without a global link step:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
cd /path/to/generated-project
|
|
90
|
+
npm link /path/to/honeydeck/packages/honeydeck
|
|
91
|
+
npm install
|
|
92
|
+
npm run dev
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
`npm link` keeps the generated project wired to your local checkout. Changes in the Honeydeck package are picked up without publishing to npm.
|
package/docs/mermaid.md
ADDED
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
# Mermaid
|
|
2
|
+
|
|
3
|
+
Mermaid is not part of Honeydeck core. Use it as a normal project dependency and render diagrams through a local React component that you import from your deck.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install mermaid
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Add a component
|
|
12
|
+
|
|
13
|
+
Create `components/Mermaid.tsx`:
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
import mermaid from "mermaid";
|
|
17
|
+
import {
|
|
18
|
+
isValidElement,
|
|
19
|
+
type ReactNode,
|
|
20
|
+
useEffect,
|
|
21
|
+
useId,
|
|
22
|
+
useRef,
|
|
23
|
+
useState,
|
|
24
|
+
} from "react";
|
|
25
|
+
|
|
26
|
+
type MermaidProps = {
|
|
27
|
+
chart?: string;
|
|
28
|
+
children?: ReactNode;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
function childrenToChart(children: ReactNode): string {
|
|
32
|
+
if (typeof children === "string" || typeof children === "number") {
|
|
33
|
+
return String(children);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (Array.isArray(children)) {
|
|
37
|
+
return children.map(childrenToChart).join("");
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (isValidElement<{ children?: ReactNode }>(children)) {
|
|
41
|
+
return childrenToChart(children.props.children);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return "";
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function themeColor(name: string, fallback: string): string {
|
|
48
|
+
const value = getComputedStyle(document.documentElement)
|
|
49
|
+
.getPropertyValue(name)
|
|
50
|
+
.trim();
|
|
51
|
+
return value || fallback;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function readHoneydeckColorMode(): "light" | "dark" {
|
|
55
|
+
if (typeof document === "undefined") return "light";
|
|
56
|
+
return document.documentElement.getAttribute("data-honeydeck-color-mode") ===
|
|
57
|
+
"dark"
|
|
58
|
+
? "dark"
|
|
59
|
+
: "light";
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function useHoneydeckColorMode(): "light" | "dark" {
|
|
63
|
+
const [colorMode, setColorMode] = useState(readHoneydeckColorMode);
|
|
64
|
+
|
|
65
|
+
useEffect(() => {
|
|
66
|
+
const observer = new MutationObserver(() => {
|
|
67
|
+
setColorMode(readHoneydeckColorMode());
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
observer.observe(document.documentElement, {
|
|
71
|
+
attributes: true,
|
|
72
|
+
attributeFilter: ["data-honeydeck-color-mode"],
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
return () => observer.disconnect();
|
|
76
|
+
}, []);
|
|
77
|
+
|
|
78
|
+
return colorMode;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export function Mermaid({ chart, children }: MermaidProps) {
|
|
82
|
+
const id = useId().replace(/[^a-zA-Z0-9_-]/g, "");
|
|
83
|
+
const ref = useRef<HTMLDivElement>(null);
|
|
84
|
+
const [error, setError] = useState<string | null>(null);
|
|
85
|
+
const colorMode = useHoneydeckColorMode();
|
|
86
|
+
const source = (chart ?? childrenToChart(children)).trim();
|
|
87
|
+
|
|
88
|
+
useEffect(() => {
|
|
89
|
+
let cancelled = false;
|
|
90
|
+
|
|
91
|
+
async function render() {
|
|
92
|
+
setError(null);
|
|
93
|
+
|
|
94
|
+
try {
|
|
95
|
+
const background = themeColor("--honeydeck-background", "#ffffff");
|
|
96
|
+
const foreground = themeColor("--honeydeck-foreground", "#111111");
|
|
97
|
+
const surface = themeColor("--honeydeck-surface", "#f3f4f6");
|
|
98
|
+
const surfaceForeground = themeColor(
|
|
99
|
+
"--honeydeck-surface-foreground",
|
|
100
|
+
foreground,
|
|
101
|
+
);
|
|
102
|
+
const primary = themeColor("--honeydeck-primary", "#6d4aff");
|
|
103
|
+
const accent = themeColor("--honeydeck-accent", primary);
|
|
104
|
+
const fontFamily = themeColor(
|
|
105
|
+
"--honeydeck-font-body",
|
|
106
|
+
"ui-sans-serif, system-ui, sans-serif",
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
mermaid.initialize({
|
|
110
|
+
startOnLoad: false,
|
|
111
|
+
theme: "base",
|
|
112
|
+
securityLevel: "strict",
|
|
113
|
+
themeVariables: {
|
|
114
|
+
background,
|
|
115
|
+
mainBkg: accent,
|
|
116
|
+
primaryColor: accent,
|
|
117
|
+
primaryBorderColor: primary,
|
|
118
|
+
primaryTextColor: surfaceForeground,
|
|
119
|
+
secondaryColor: surface,
|
|
120
|
+
secondaryBorderColor: accent,
|
|
121
|
+
secondaryTextColor: foreground,
|
|
122
|
+
tertiaryColor: accent,
|
|
123
|
+
tertiaryBorderColor: primary,
|
|
124
|
+
tertiaryTextColor: surfaceForeground,
|
|
125
|
+
lineColor: primary,
|
|
126
|
+
arrowheadColor: primary,
|
|
127
|
+
textColor: foreground,
|
|
128
|
+
fontFamily,
|
|
129
|
+
fontSize: "16px",
|
|
130
|
+
actorBkg: accent,
|
|
131
|
+
actorBorder: primary,
|
|
132
|
+
actorTextColor: surfaceForeground,
|
|
133
|
+
activationBkgColor: background,
|
|
134
|
+
activationBorderColor: accent,
|
|
135
|
+
signalColor: primary,
|
|
136
|
+
signalTextColor: foreground,
|
|
137
|
+
noteBkgColor: accent,
|
|
138
|
+
noteBorderColor: accent,
|
|
139
|
+
noteTextColor: surfaceForeground,
|
|
140
|
+
},
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
const result = await mermaid.render(`mermaid-${id}`, source);
|
|
144
|
+
if (cancelled || !ref.current) return;
|
|
145
|
+
|
|
146
|
+
ref.current.innerHTML = result.svg;
|
|
147
|
+
result.bindFunctions?.(ref.current);
|
|
148
|
+
} catch (err) {
|
|
149
|
+
if (cancelled) return;
|
|
150
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
void render();
|
|
155
|
+
|
|
156
|
+
return () => {
|
|
157
|
+
cancelled = true;
|
|
158
|
+
};
|
|
159
|
+
}, [source, id, colorMode]);
|
|
160
|
+
|
|
161
|
+
return (
|
|
162
|
+
<figure className="user-mermaid m-0 overflow-x-auto rounded-honeydeck border border-border bg-surface p-[1em] text-surface-foreground">
|
|
163
|
+
{error ? (
|
|
164
|
+
<pre className="m-0 whitespace-pre-wrap rounded-honeydeck bg-background p-3 text-foreground">
|
|
165
|
+
<code>{error}</code>
|
|
166
|
+
</pre>
|
|
167
|
+
) : (
|
|
168
|
+
<div ref={ref} />
|
|
169
|
+
)}
|
|
170
|
+
</figure>
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## Add styles
|
|
176
|
+
|
|
177
|
+
Add this to your `styles.css`, after your Honeydeck theme imports:
|
|
178
|
+
|
|
179
|
+
```css
|
|
180
|
+
.user-mermaid svg :is(p, div, span, .label, .nodeLabel, .edgeLabel) {
|
|
181
|
+
/* Honeydeck slide typography is large; keep Mermaid labels diagram-sized. */
|
|
182
|
+
font-size: 16px;
|
|
183
|
+
}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## Use it in MDX
|
|
187
|
+
|
|
188
|
+
```mdx
|
|
189
|
+
import { Mermaid } from './components/Mermaid'
|
|
190
|
+
|
|
191
|
+
<Mermaid>
|
|
192
|
+
flowchart LR
|
|
193
|
+
A[Idea] --> B[Deck]
|
|
194
|
+
B --> C[Presentation]
|
|
195
|
+
</Mermaid>
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
For a runnable example, see the repository's `demos/mermaid` folder.
|