Skip to content

Presentation Mode

The <Presentation> component turns Elucim into a full slide-deck system. Each <Slide> can contain its own normalized document rendered with <DslRenderer>, and transitions handle movement between slides.

This is a React composition shell from @elucim/core, not the canonical JSON/YAML DSL authoring model. Agent-authored documents should stay as normalized scenes with timelines and state machines; use <Presentation> only when a React host app wants to arrange multiple scenes into a deck.

PropTypeDefaultDescription
widthnumber1920Slide width in pixels
heightnumber1080Slide height in pixels
backgroundstring'#0d0d1a'Default background color for all slides
transitionstring'none'Transition type: 'none' | 'fade' | 'slide-left' | 'slide-up' | 'zoom'
transitionDurationnumber400Transition duration in milliseconds
showHUDbooleantrueShow the slide counter overlay
showNotesbooleanfalseShow the presenter notes panel
startSlidenumber0Zero-based index of the initial slide
onSlideChange(index: number) => voidCallback fired when the active slide changes
childrenReact.ReactNodeMust be <Slide> components
PropTypeDefaultDescription
titlestringSlide title (displayed in the HUD and presenter view)
notesstringPresenter notes (shown when showNotes is enabled)
backgroundstringBackground color override for this slide
childrenReact.ReactNodeSlide content — usually a <DslRenderer> scene, but any React content is allowed
import { Presentation, Slide } from '@elucim/core';
import { DslRenderer, type ElucimDocument } from '@elucim/dsl';
const welcome: ElucimDocument = {
version: '2.0',
scene: { type: 'player', width: 1920, height: 1080, children: ['title'] },
elements: {
title: { id: 'title', type: 'text', props: { type: 'text', x: 960, y: 540, content: 'Welcome to Elucim', fill: '$title', fontSize: 64, textAnchor: 'middle' } },
},
};
const equation: ElucimDocument = {
version: '2.0',
scene: { type: 'player', width: 1920, height: 1080, children: ['equation'] },
elements: {
equation: { id: 'equation', type: 'latex', props: { type: 'latex', expression: 'e^{i\\pi} + 1 = 0', x: 960, y: 500, fontSize: 48 } },
},
};
<Presentation
width={1920}
height={1080}
transition="fade"
transitionDuration={500}
showHUD
>
<Slide title="Welcome" notes="Introduce the topic">
<DslRenderer dsl={welcome} controls={false} fitToContainer />
</Slide>
<Slide title="The Math" notes="Show the core equation">
<DslRenderer dsl={equation} controls={false} fitToContainer />
</Slide>
</Presentation>
InputAction
/ Next slide
/ Previous slide
SpaceNext slide
Click navigation buttonsNext / previous slide
FToggle fullscreen

Use usePresentationContext() inside any component rendered within a <Presentation> to access slide state and navigation:

import { usePresentationContext } from '@elucim/core';
function SlideCounter() {
const { slideIndex, totalSlides, goTo, next, prev, isFullscreen, toggleFullscreen } =
usePresentationContext();
return (
<div>
Slide {slideIndex + 1} / {totalSlides}
<button onClick={prev}>Prev</button>
<button onClick={next}>Next</button>
<button onClick={toggleFullscreen}>
{isFullscreen ? 'Exit' : 'Fullscreen'}
</button>
<button onClick={() => goTo(0)}>Go to start</button>
</div>
);
}
PropertyTypeDescription
slideIndexnumberCurrent slide index (zero-based)
totalSlidesnumberTotal number of slides
goTo(index)(number) => voidJump to a specific slide
next()() => voidAdvance to the next slide
prev()() => voidGo back to the previous slide
isFullscreenbooleanWhether the presentation is in fullscreen mode
toggleFullscreen()() => voidToggle fullscreen on/off

The Presentation component is fully theme-aware. All UI elements (navigation arrows, fullscreen button, HUD text, progress dots) use currentColor and CSS color-mix(), so they automatically adapt to any light or dark color scheme.

Pass a CSS custom property for the background prop to let your site’s theme control the slide background:

<Presentation background="var(--slide-bg, #1a1a2e)" />

Render normalized documents inside slides with controls={false} so the Presentation’s own HUD handles navigation:

<Slide title="Animated Math">
<DslRenderer dsl={sceneDoc} controls={false} fitToContainer />
</Slide>

Using fill="currentColor" in your slide content ensures text and shapes inherit the theme color automatically.