@deckio/deck-engine 1.7.8 → 1.8.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/components/Slide.jsx
CHANGED
|
@@ -1,15 +1,43 @@
|
|
|
1
|
+
import { useRef, useEffect, useState } from 'react'
|
|
1
2
|
import { useSlides } from '../context/SlideContext'
|
|
2
3
|
|
|
4
|
+
const DEV = typeof import.meta !== 'undefined' && import.meta.env?.DEV
|
|
5
|
+
|
|
3
6
|
export default function Slide({ index, className = '', children }) {
|
|
4
7
|
const { current } = useSlides()
|
|
8
|
+
const ref = useRef(null)
|
|
9
|
+
const [overflow, setOverflow] = useState(false)
|
|
5
10
|
|
|
6
11
|
let stateClass = ''
|
|
7
12
|
if (index === current) stateClass = 'active'
|
|
8
13
|
else if (index < current) stateClass = 'exit-left'
|
|
9
14
|
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
if (!DEV || index !== current || !ref.current) return
|
|
17
|
+
const el = ref.current
|
|
18
|
+
const check = () => {
|
|
19
|
+
// Only check flow-positioned children; ignore absolute/fixed decorations (orbs, accent-bar)
|
|
20
|
+
const hasOverflow = Array.from(el.children).some(c => {
|
|
21
|
+
const pos = getComputedStyle(c).position
|
|
22
|
+
if (pos === 'absolute' || pos === 'fixed') return false
|
|
23
|
+
return c.offsetTop + c.offsetHeight > el.clientHeight
|
|
24
|
+
})
|
|
25
|
+
setOverflow(hasOverflow)
|
|
26
|
+
}
|
|
27
|
+
check()
|
|
28
|
+
const obs = new ResizeObserver(check)
|
|
29
|
+
obs.observe(el)
|
|
30
|
+
return () => obs.disconnect()
|
|
31
|
+
}, [index, current])
|
|
32
|
+
|
|
10
33
|
return (
|
|
11
|
-
<div className={`slide ${stateClass} ${className}`} data-slide={index}>
|
|
34
|
+
<div ref={ref} className={`slide ${stateClass} ${className}`} data-slide={index}>
|
|
12
35
|
{children}
|
|
36
|
+
{DEV && overflow && (
|
|
37
|
+
<div className="slide-overflow-warn">
|
|
38
|
+
⚠ Content overflows slide — reduce content or use smaller elements
|
|
39
|
+
</div>
|
|
40
|
+
)}
|
|
13
41
|
</div>
|
|
14
42
|
)
|
|
15
43
|
}
|
|
@@ -10,12 +10,13 @@ applyTo: "**/slides/**/*.module.css"
|
|
|
10
10
|
```css
|
|
11
11
|
.mySlide {
|
|
12
12
|
background: var(--bg-deep);
|
|
13
|
-
flex-direction: column;
|
|
14
13
|
padding: 0 0 44px 0; /* reserve BottomBar height */
|
|
15
14
|
}
|
|
16
15
|
```
|
|
17
16
|
|
|
18
|
-
|
|
17
|
+
The engine's `.slide` class already sets `flex-direction: column`, `justify-content: center`, and `overflow: hidden`. The engine also sets `flex-grow: 0` on all direct slide children, so **content stays at its natural height and is vertically centered by default** — building from the center outward. No scrolling is allowed.
|
|
18
|
+
|
|
19
|
+
For dense slides that need top-alignment, override with `justify-content: flex-start`.
|
|
19
20
|
|
|
20
21
|
## Orb positioning recipe
|
|
21
22
|
|
|
@@ -40,12 +41,12 @@ Add `justify-content: center` for cover or thank-you slides.
|
|
|
40
41
|
z-index: 10;
|
|
41
42
|
display: flex;
|
|
42
43
|
flex-direction: column;
|
|
43
|
-
|
|
44
|
-
flex: 1;
|
|
45
|
-
min-height: 0;
|
|
44
|
+
gap: 24px;
|
|
46
45
|
}
|
|
47
46
|
```
|
|
48
47
|
|
|
48
|
+
> **Do NOT add `flex: 1` or `flex-grow: 1`** to the body wrapper or any direct slide child — it stretches the wrapper to fill the slide and defeats the engine's built-in vertical centering. The engine sets `flex-grow: 0` on all direct slide children to ensure content builds from the center outward. Inner elements within the body wrapper should also avoid `flex: 1` unless they genuinely need to fill remaining space within the body.
|
|
49
|
+
|
|
49
50
|
## Theme variables (always use these, never hard-code colors)
|
|
50
51
|
|
|
51
52
|
| Variable | Value |
|
|
@@ -89,3 +90,7 @@ Add `justify-content: center` for cover or thank-you slides.
|
|
|
89
90
|
| Subtitle | `17px` | 300–400 | — |
|
|
90
91
|
| Body | `13px–14px` | 400 | — |
|
|
91
92
|
| Badge | `10px–11px` | 600–700 | `1.5px` |
|
|
93
|
+
|
|
94
|
+
## Content density limits
|
|
95
|
+
|
|
96
|
+
Slides must never overflow the viewport. The engine shows a **red dashed border warning** in dev mode when content exceeds the slide bounds. When content doesn't fit, split across multiple slides rather than cramming. A presentation with more slides is better than one with clipped content.
|
package/package.json
CHANGED
|
@@ -59,16 +59,16 @@ Create a companion `.module.css` file matching the JSX filename (e.g., `MyNewSli
|
|
|
59
59
|
```css
|
|
60
60
|
.myNewSlide {
|
|
61
61
|
background: var(--bg-deep);
|
|
62
|
-
flex-direction: column;
|
|
63
62
|
padding: 0 0 44px 0;
|
|
64
63
|
}
|
|
65
64
|
```
|
|
66
65
|
|
|
67
66
|
- `background: var(--bg-deep)` — dark background on every slide
|
|
68
|
-
- `flex-direction: column` — global `.slide` sets `display: flex`; this orients content vertically
|
|
69
67
|
- `padding: 0 0 44px 0` — reserves space for the 44px BottomBar
|
|
70
68
|
|
|
71
|
-
|
|
69
|
+
The engine's `.slide` class provides `flex-direction: column`, `justify-content: center`, `align-items: stretch`, and `overflow: hidden` by default. It also sets `flex-grow: 0` on all direct slide children, so **content stays at its natural height and is vertically centered by default** — building from the center outward. No scrolling is allowed.
|
|
70
|
+
|
|
71
|
+
For dense slides that need top-alignment, override with `justify-content: flex-start`.
|
|
72
72
|
|
|
73
73
|
### Orb positioning (standard recipe)
|
|
74
74
|
|
|
@@ -85,7 +85,7 @@ Optional: add `justify-content: center` to vertically center content (cover slid
|
|
|
85
85
|
}
|
|
86
86
|
```
|
|
87
87
|
|
|
88
|
-
###
|
|
88
|
+
### Body wrapper
|
|
89
89
|
|
|
90
90
|
```css
|
|
91
91
|
.body {
|
|
@@ -93,12 +93,12 @@ Optional: add `justify-content: center` to vertically center content (cover slid
|
|
|
93
93
|
z-index: 10;
|
|
94
94
|
display: flex;
|
|
95
95
|
flex-direction: column;
|
|
96
|
-
|
|
97
|
-
flex: 1;
|
|
98
|
-
min-height: 0;
|
|
96
|
+
gap: 24px;
|
|
99
97
|
}
|
|
100
98
|
```
|
|
101
99
|
|
|
100
|
+
> **Do NOT add `flex: 1` or `flex-grow: 1`** to the body wrapper or any direct slide child — it stretches the wrapper to fill the slide and defeats the engine's built-in vertical centering. Inner elements within the body should also avoid `flex: 1` unless they genuinely need to fill remaining space within the body.
|
|
101
|
+
|
|
102
102
|
### Available CSS custom properties
|
|
103
103
|
|
|
104
104
|
```
|
|
@@ -190,7 +190,23 @@ export default {
|
|
|
190
190
|
|
|
191
191
|
---
|
|
192
192
|
|
|
193
|
-
## F.
|
|
193
|
+
## F. Content Density Limits
|
|
194
|
+
|
|
195
|
+
Slides must never overflow the viewport. The engine shows a **red dashed border warning** in dev mode when content exceeds the slide bounds. Follow these limits:
|
|
196
|
+
|
|
197
|
+
| Layout | Max items | Notes |
|
|
198
|
+
|--------|-----------|-------|
|
|
199
|
+
| Cards (3-col grid) | 6 (2 rows) | Reduce card padding if tight |
|
|
200
|
+
| Cards (2-col grid) | 4 (2 rows) | Preferred for detailed cards |
|
|
201
|
+
| Timeline / event list | 3–4 items | Use compact card height for 4 |
|
|
202
|
+
| Bullet points | 6–8 | Depends on line length |
|
|
203
|
+
| Full-width content blocks | 2–3 | E.g. quote + detail section |
|
|
204
|
+
|
|
205
|
+
**When content exceeds limits**, split across multiple slides rather than cramming.
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
## G. Anti-Patterns to Avoid
|
|
194
210
|
|
|
195
211
|
1. **Missing `accent-bar`** — include on every slide.
|
|
196
212
|
2. **Missing `content-frame content-gutter`** — content will be full-width without standard margins.
|
|
@@ -198,10 +214,13 @@ export default {
|
|
|
198
214
|
4. **String paths for images** — always use `import logo from '../data/...'` (Vite resolves to URL).
|
|
199
215
|
5. **Missing `padding: 0 0 44px 0`** on the slide root CSS class — content will overlap the BottomBar.
|
|
200
216
|
6. **Inconsistent `BottomBar text`** — check existing slides and match their footer text.
|
|
217
|
+
7. **Using `flex: 1` on body wrapper** — defeats vertical centering; the body should size to its content.
|
|
218
|
+
8. **Adding `flex-direction: column` on slide root** — already provided by the engine's `.slide` class.
|
|
219
|
+
9. **Overloading a slide** — if the dev server shows a red dashed border, the slide has too much content. Split into multiple slides.
|
|
201
220
|
|
|
202
221
|
---
|
|
203
222
|
|
|
204
|
-
##
|
|
223
|
+
## H. Complete Step-by-Step
|
|
205
224
|
|
|
206
225
|
1. **Create** `src/slides/<SlideName>Slide.jsx` following the mandatory skeleton (section A).
|
|
207
226
|
2. **Create** `src/slides/<SlideName>Slide.module.css` with required root properties (section B).
|
|
@@ -211,7 +230,7 @@ export default {
|
|
|
211
230
|
### Quick checklist
|
|
212
231
|
|
|
213
232
|
- [ ] Created `<SlideName>Slide.jsx` with Slide, accent-bar, orbs, content-frame, BottomBar
|
|
214
|
-
- [ ] Created `<SlideName>Slide.module.css` with `background: var(--bg-deep)`, `
|
|
233
|
+
- [ ] Created `<SlideName>Slide.module.css` with `background: var(--bg-deep)`, `padding: 0 0 44px 0`, body wrapper (no `flex: 1`)
|
|
215
234
|
- [ ] Import added to `deck.config.js`
|
|
216
235
|
- [ ] Component added to `slides` array at correct position
|
|
217
236
|
- [ ] `BottomBar text` matches project convention
|
|
@@ -35,8 +35,9 @@ For each slide `.jsx` file in `src/slides/`, verify:
|
|
|
35
35
|
|
|
36
36
|
For each `.module.css` file, verify the root class has:
|
|
37
37
|
- [ ] `background: var(--bg-deep)`
|
|
38
|
-
- [ ] `flex-direction: column`
|
|
39
38
|
- [ ] `padding: 0 0 44px 0`
|
|
39
|
+
- [ ] Does NOT use `flex: 1` on the body wrapper (defeats vertical centering)
|
|
40
|
+
- [ ] Does NOT redundantly set `flex-direction: column` (inherited from engine `.slide` class)
|
|
40
41
|
|
|
41
42
|
---
|
|
42
43
|
|
|
@@ -76,5 +77,5 @@ Summarize findings:
|
|
|
76
77
|
- [ ] Every `.jsx` slide has a companion `.module.css`
|
|
77
78
|
- [ ] All slides have accent-bar, content-frame, BottomBar
|
|
78
79
|
- [ ] BottomBar text is consistent across the project
|
|
79
|
-
- [ ] CSS root classes have required properties
|
|
80
|
+
- [ ] CSS root classes have required properties (`background`, `padding`) and no `flex: 1` on body wrapper
|
|
80
81
|
- [ ] Project metadata (id, title, subtitle, icon, accent) is present
|
package/styles/global.css
CHANGED
|
@@ -40,6 +40,9 @@ html, body, #root {
|
|
|
40
40
|
position: absolute;
|
|
41
41
|
inset: 0;
|
|
42
42
|
display: flex;
|
|
43
|
+
flex-direction: column;
|
|
44
|
+
justify-content: center;
|
|
45
|
+
align-items: stretch;
|
|
43
46
|
opacity: 0;
|
|
44
47
|
pointer-events: none;
|
|
45
48
|
transition: opacity 0.6s cubic-bezier(0.4, 0, 0.2, 1),
|
|
@@ -47,6 +50,9 @@ html, body, #root {
|
|
|
47
50
|
transform: translateX(60px);
|
|
48
51
|
overflow: hidden;
|
|
49
52
|
}
|
|
53
|
+
.slide > * {
|
|
54
|
+
flex-grow: 0;
|
|
55
|
+
}
|
|
50
56
|
.slide.active {
|
|
51
57
|
opacity: 1;
|
|
52
58
|
pointer-events: auto;
|
|
@@ -57,6 +63,24 @@ html, body, #root {
|
|
|
57
63
|
transform: translateX(-60px);
|
|
58
64
|
}
|
|
59
65
|
|
|
66
|
+
/* ── Dev-mode overflow warning ── */
|
|
67
|
+
.slide-overflow-warn {
|
|
68
|
+
position: absolute;
|
|
69
|
+
inset: 0;
|
|
70
|
+
border: 3px dashed #f85149;
|
|
71
|
+
pointer-events: none;
|
|
72
|
+
z-index: 9999;
|
|
73
|
+
display: flex;
|
|
74
|
+
align-items: flex-end;
|
|
75
|
+
justify-content: center;
|
|
76
|
+
padding-bottom: 56px;
|
|
77
|
+
background: rgba(248, 81, 73, 0.04);
|
|
78
|
+
font-size: 13px;
|
|
79
|
+
font-weight: 600;
|
|
80
|
+
color: #f85149;
|
|
81
|
+
letter-spacing: 0.3px;
|
|
82
|
+
}
|
|
83
|
+
|
|
60
84
|
/* ── Shared Decorations ── */
|
|
61
85
|
.orb {
|
|
62
86
|
position: absolute;
|
|
@@ -98,11 +122,7 @@ html, body, #root {
|
|
|
98
122
|
══════════════════════════════════════════════════ */
|
|
99
123
|
.deck-ty {
|
|
100
124
|
background: var(--bg-deep);
|
|
101
|
-
flex-direction: column;
|
|
102
|
-
align-items: stretch;
|
|
103
|
-
justify-content: center;
|
|
104
125
|
padding: 0 0 44px 0;
|
|
105
|
-
overflow: hidden;
|
|
106
126
|
}
|
|
107
127
|
|
|
108
128
|
/* Ambient glow orbs */
|