Skip to content

Components

Twelve primitives cover the entire authoring surface. Every one is a normal React component, but each carries a static __helixuiSlideKind field so the exporter can dispatch on identity rather than imports.

Container

<Deck>

Root of a presentation. Manages slide list, theme, and active-slide state.

PropTypeDefaultDescription
size'16:9' | '16:10' | '4:3' | { w, h }'16:9'Slide dimensions in inches
themePartial<DeckTheme>helixui defaultsOverride colors, fonts, default sizes
mode'flow' | 'single''flow'Vertical scroll vs. one-at-a-time
controlsbooleanfalseRender the prev/next/counter strip in single mode
activeIndexnumberControlled active slide
onActiveIndexChange(i: number) => voidFires on navigation
toolbarReactNodeCustom slot above the deck (e.g. an Export button)
exportFileNamestring'helixui-deck.pptx'Default filename used by exportToPptx
<Deck size="16:9" mode="single" controls>
<Slide layout="title">
<Title>Hello</Title>
</Slide>
</Deck>

<Slide>

PropTypeDefault
layout'blank' | 'title' | 'section' | 'content' | 'two-column' | 'image-right' | 'quote''blank'
bgSlideColortheme paper
notesstring
idstring
thumbnailTitlestringfirst <Title>

<Frame>

Absolute positioning in inches. Optionally fills, strokes, rounds corners.

<Frame x={0.5} y={1} w={6} h={3} fill="brand" radius={0.1} padding={0.25}>
<Title color="paper">Hello</Title>
</Frame>

Text

<Title>, <Subtitle>, <Heading>, <SlideText>

All accept the TextStyle props (size in pt, weight, italic, underline, strike, color, font, align, lineHeight, tracking).

<Title>The deck is data.</Title>
<Subtitle>The renderer is a detail.</Subtitle>
<Heading level={2}>Why slides as components?</Heading>
<SlideText size={14} color="neutral" font="mono">
exportToPptx(deck)
</SlideText>

<Bullets> + <Bullet>

<Bullets type="check" size={20}>
<Bullet>Same tokens as the rest of helixui.</Bullet>
<Bullet level={1}>Themes flow through automatically.</Bullet>
<Bullet type="arrow">Override the marker per item.</Bullet>
</Bullets>

type accepts 'disc' | 'number' | 'check' | 'arrow' | 'none'. level is 0..3 for indentation.

Geometry

<SlideShape>

Twenty preset shapes: rect, roundRect, ellipse, triangle, rightTriangle, diamond, parallelogram, pentagon, hexagon, octagon, star, arrowRight, arrowLeft, arrowUp, arrowDown, chevron, cloud, cross, line.

<SlideShape kind="roundRect" x={1} y={1} w={4} h={1.4} radius={0.15}
fill="brand" stroke={{ color: 'border', width: 1 }}
label="Click here" labelStyle={{ color: 'paper', size: 14 }} />

<SlideImage>

<SlideImage src="/logo.png" alt="logo" x={1} y={1} w={3} h={2} fit="contain" radius={0.1} />

In a browser, the exporter fetches the image and inlines it as base64 so the resulting .pptx is self-contained.

<SlideTable>

<SlideTable
header={['Name', 'Role', 'Joined']}
rows={[
['Sora', 'Designer', '2024-02'],
['Mira', 'PM', '2024-04'],
]}
colWidths={[3, 2.5, 2]}
/>

<SlideChart>

Renders a native PowerPoint chart on export — data stays editable in PowerPoint / Keynote.

<SlideChart
type="area"
title="Weekly sessions"
data={{
labels: ['Mon','Tue','Wed','Thu','Fri'],
datasets: [
{ label: 'Web', data: [320,410,380,520,600], color: 'brand' },
{ label: 'Mobile', data: [180,240,220,310,360], color: 'success' },
],
}}
/>

Supported types: line, area, bar, stackedBar, pie, doughnut, radar.

Metadata

<Notes>

Not rendered. Picked up by the exporter and emitted into the slide’s notes pane.

<Slide layout="title">
<Title>helixui slides</Title>
<Notes>Open with this slide for ~30 seconds. Don't read the bullets.</Notes>
</Slide>

<DeckThumbnails>

Companion component that renders a horizontal strip of clickable thumbnails. Drives an external active-index state.

<DeckThumbnails activeIndex={i} onSelect={setI} thumbWidth={150}>
{slides /* same children passed to <Deck> */}
</DeckThumbnails>

Color references

SlideColor accepts:

  • theme keys'brand' | 'success' | 'warning' | 'danger' | 'neutral' | 'ink' | 'paper' | 'subtle' | 'border' | 'accent'
  • CSS variables'--helixui-color-bg-action-brand-default'
  • CSS colors'#FF6680', 'oklch(0.62 0.18 264)', 'rgba(0,0,0,.5)'

The DOM renderer uses CSS values directly. The exporter resolves any non-hex value to a concrete hex via a hidden canvas at export time.