Skip to content

Commit dbc270f

Browse files
ofriwclaude
andcommitted
Implement codeExecution slide rendering with auto-scroll
- Add CodeExecutionStep interface and codeExecution slide type - Render execution steps with semantic highlighting and annotations - Add fragment navigation handler to auto-scroll steps into view - Support all scrollable containers (execution, comparison, marketingReality) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent aa5450b commit dbc270f

File tree

1 file changed

+63
-1
lines changed

1 file changed

+63
-1
lines changed

website/src/components/PresentationMode/RevealSlideshow.tsx

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,14 @@ interface SpeakerNotes {
1919
transition?: string;
2020
}
2121

22+
interface CodeExecutionStep {
23+
line: string;
24+
highlightType?: 'human' | 'prediction' | 'execution' | 'feedback' | 'summary';
25+
annotation?: string;
26+
}
27+
2228
interface Slide {
23-
type: 'title' | 'concept' | 'code' | 'comparison' | 'visual' | 'takeaway' | 'marketingReality';
29+
type: 'title' | 'concept' | 'code' | 'comparison' | 'visual' | 'takeaway' | 'marketingReality' | 'codeExecution';
2430
title: string;
2531
subtitle?: string;
2632
content?: string[];
@@ -32,6 +38,7 @@ interface Slide {
3238
right?: { label: string; content: string[] };
3339
metaphor?: { label: string; content: string[] };
3440
reality?: { label: string; content: string[] };
41+
steps?: CodeExecutionStep[];
3542
speakerNotes?: SpeakerNotes;
3643
}
3744

@@ -96,11 +103,13 @@ export default function RevealSlideshow({ presentation, onClose }: RevealSlidesh
96103

97104
deck.initialize().then(() => {
98105
revealRef.current = deck;
106+
deck.on('fragmentshown', handleFragmentShown);
99107
});
100108

101109
// Cleanup
102110
return () => {
103111
if (revealRef.current) {
112+
revealRef.current.off('fragmentshown', handleFragmentShown);
104113
revealRef.current.destroy();
105114
revealRef.current = null;
106115
}
@@ -119,6 +128,27 @@ export default function RevealSlideshow({ presentation, onClose }: RevealSlidesh
119128
return () => window.removeEventListener('keydown', handleKeyDown);
120129
}, [onClose]);
121130

131+
const handleFragmentShown = (event: { fragment: HTMLElement }) => {
132+
const fragment = event.fragment;
133+
134+
// Find any scrollable container parent
135+
const scrollContainer = fragment.closest(`.${styles.executionFlow}`) ||
136+
fragment.closest(`.${styles.comparisonLeft}`) ||
137+
fragment.closest(`.${styles.comparisonRight}`) ||
138+
fragment.closest(`.${styles.metaphorColumn}`) ||
139+
fragment.closest(`.${styles.realityColumn}`);
140+
141+
if (scrollContainer) {
142+
// Scroll minimum amount needed to bring fragment into view
143+
// Does nothing if fragment already visible
144+
fragment.scrollIntoView({
145+
behavior: 'smooth',
146+
block: 'nearest', // Only scroll if not visible
147+
inline: 'nearest'
148+
});
149+
}
150+
};
151+
122152
const renderSlide = (slide: Slide, index: number) => {
123153
const key = `slide-${index}`;
124154

@@ -259,6 +289,38 @@ export default function RevealSlideshow({ presentation, onClose }: RevealSlidesh
259289
</section>
260290
);
261291

292+
case 'codeExecution':
293+
return (
294+
<section key={key} data-notes={formatSpeakerNotes(slide.speakerNotes)}>
295+
<h2>{slide.title}</h2>
296+
{slide.steps && (
297+
<div className={styles.executionFlow}>
298+
{slide.steps.map((step, i) => {
299+
const highlightClass = step.highlightType
300+
? styles[`execution${step.highlightType.charAt(0).toUpperCase()}${step.highlightType.slice(1)}`]
301+
: '';
302+
303+
return (
304+
<div
305+
key={i}
306+
className={`${styles.executionStep} ${highlightClass} fragment`}
307+
data-fragment-index={i}
308+
>
309+
<div className={styles.stepLine}>
310+
{i > 0 && <span className={styles.flowArrow}></span>}
311+
<span className={styles.stepText}>{step.line}</span>
312+
</div>
313+
{step.annotation && (
314+
<div className={styles.stepAnnotation}>{step.annotation}</div>
315+
)}
316+
</div>
317+
);
318+
})}
319+
</div>
320+
)}
321+
</section>
322+
);
323+
262324
default:
263325
return (
264326
<section key={key}>

0 commit comments

Comments
 (0)