Authoring guide
The fastest way to learn the API is to build a deck. Open
/showcase/slides in another tab — every example below
maps directly to a slide in that deck.
1. Title slide
<Slide layout="title"> <Title>helixui slides</Title> <Subtitle>tokens · components · pptx export</Subtitle></Slide>The 'title' layout centers the title and subtitle vertically with
generous side margins. Add a colored band by stacking a <Frame> with a
fill underneath:
<Slide layout="title"> <Frame x={0} y={0} w={13.333} h={2.4} fill="brand" /> <Frame x={0.7} y={0.7} w={6} h={1}> <SlideText size={14} weight="semibold" color="paper">helixui · slides</SlideText> </Frame> <Title>An AI-friendly design system, now for slides.</Title> <Subtitle>Build presentations as React components. Export to PPTX.</Subtitle></Slide>2. Bulleted content
<Slide layout="content"> <Title>Why slides as components?</Title> <Bullets type="check" size={20}> <Bullet>Same tokens as the rest of helixui.</Bullet> <Bullet>Diffable, reviewable, programmatic.</Bullet> <Bullet>Render anywhere — DOM preview, .pptx export.</Bullet> </Bullets></Slide>The 'content' layout reserves the top ~13% for the title and the rest
for the body. The <Bullets> component falls into the body slot when not
wrapped in a frame.
3. Two-column comparison
<Slide layout="two-column"> <Title>The deck is data, the renderer is a detail.</Title>
<Frame x={0.5} y={1.7} w={6} h={5.3}> <Heading level={3}>Web preview</Heading> <Bullets type="arrow"> <Bullet>Auto-scales to any container width</Bullet> <Bullet>Speaker mode with keyboard navigation</Bullet> </Bullets> </Frame>
<Frame x={6.833} y={1.7} w={6} h={5.3}> <Heading level={3}>PPTX export</Heading> <Bullets type="arrow"> <Bullet>One async call: <SlideText font="mono" size={15}>exportToPptx(deck)</SlideText></Bullet> <Bullet>Native PPTX shapes, tables, and charts</Bullet> </Bullets> </Frame></Slide>The 'two-column' layout exposes bodyLeft and bodyRight placeholders,
but explicit <Frame>s give you full control over column widths and gaps.
4. Native PPTX charts
<Slide layout="content"> <Title>Charts export as real PowerPoint charts.</Title> <Frame x={0.5} y={1.5} w={6.2} h={5.5}> <SlideChart type="area" title="Weekly sessions" data={{ labels: ['Mon','Tue','Wed','Thu','Fri','Sat','Sun'], datasets: [ { label: 'Web', data: [320,410,380,520,600,540,640], color: 'brand' }, { label: 'Mobile', data: [180,240,220,310,360,410,480], color: 'success' }, ], }} /> </Frame> <Frame x={6.9} y={1.5} w={5.9} h={5.5}> <SlideChart type="doughnut" data={{ labels: ['A','B','C'], datasets: [{ label: 'mix', data: [3,5,2] }] }} /> </Frame></Slide>The DOM rendering uses pure SVG (zero charting peer dependency). The exporter emits a native PowerPoint chart so end users can edit the data right inside PowerPoint.
5. Data-driven generation
The whole point of authoring slides as React is that they’re functions of data. Build a slide per item:
function ProductOverview({ products }: { products: Product[] }) { return ( <Deck size="16:9" exportFileName="catalog.pptx"> <Slide layout="title"> <Title>{`Catalog · ${products.length} products`}</Title> </Slide>
{products.map((p) => ( <Slide key={p.id} layout="image-right"> <Title>{p.name}</Title> <SlideImage src={p.heroUrl} alt={p.name} /> <Bullets type="check"> {p.features.map((f) => <Bullet key={f}>{f}</Bullet>)} </Bullets> <Notes>{p.salesNotes}</Notes> </Slide> ))} </Deck> );}
await exportToPptx(<ProductOverview products={data} />);That’s the headline use case for @helixui/slides — programmatic decks.
6. Diagrams from primitives
A flow diagram is a few <SlideShape>s plus connector lines:
<Slide layout="content"> <Title>How a request flows</Title>
{STEPS.map((step, i) => ( <Frame key={step} x={0.5 + i * 3.0} y={3.5} w={2.6} h={1.2}> <SlideShape kind="roundRect" radius={0.12} fill={i === STEPS.length - 1 ? 'success' : 'brand'} label={step} labelStyle={{ color: 'paper', weight: 'semibold', size: 16 }} /> </Frame> ))}
{STEPS.slice(0, -1).map((_, i) => ( <SlideShape key={i} kind="arrowRight" x={0.5 + i * 3.0 + 2.6} y={4.0} w={0.4} h={0.2} fill="neutral" /> ))}</Slide>7. Tables
<Slide layout="content"> <Title>How it maps to PPTX</Title> <Frame x={0.5} y={1.6} w={12.333} h={5.4}> <SlideTable header={['Component', 'PPTX equivalent', 'Notes']} rows={[ ['<Slide>', 'sld', 'One slide per element'], ['<Frame>', 'sp (group bounds)', 'Children inherit x/y/w/h'], ['<SlideShape>', 'sp prstGeom', 'Twenty preset shapes mapped 1:1'], ['<SlideChart>', 'graphicFrame chart', 'Editable PowerPoint chart'], ]} colWidths={[3.4, 3.6, 5.0]} /> </Frame></Slide>Tips
- Always wrap floating content in a
<Frame>when a layout doesn’t already place it. Frames make the export deterministic. - Use theme color refs (
'brand','success') instead of hex literals whenever possible — your decks pick up live theme changes for free. - Keep speaker notes in
<Notes>, not in commented-out JSX. They survive the PPTX round-trip. - Inline images are best for portability. The exporter does this for
you in the browser; in node, set
path: 'http(s)://...'and the pptxgenjs runtime resolves it.