Show the editor beside a chat
Put the PPTX editor in a panel next to a chat, with a layout for a tall panel.
A panel beside a chat is taller than it is wide, and a slide is wider than it is tall. Stack the parts so the slide gets the full width, and connect the chat to the deck through one root. The chat example shows the result.
Use one root
Wrap the chat and the panel in one PptxEditor.Root. Put PptxEditor.Viewport around the panel only, so the editor styles stay in it:
<PptxEditor.Root document={bytes}>
<Chat />
<aside className="deck-panel">
<PptxEditor.Viewport>
<PptxEditor.Toolbar />
<div className="deck-workspace">
<PptxEditor.Content />
<PptxEditor.SlideRail orientation="horizontal" />
<PptxEditor.NotesPane />
</div>
<PptxEditor.Slideshow />
</PptxEditor.Viewport>
</aside>
</PptxEditor.Root>The horizontal rail sits under the slide and leaves the width to it. See Horizontal slide rail.
Connect the chat
Inside the root, the chat reads and drives the deck:
| Task | Call |
|---|---|
| Show a slide in a message | editor.renderThumbnail(index, element) paints at once |
| Go to a slide | editor.goToSlide(index) |
| Present | useSlideshow().start('current') |
| Download | editor.save() |
| Tell the model where the user is | editor.snapshot().currentSlide |
Match the chat's look
Map your chat's tokens to the editor tokens, so the panel reads as part of your app. Use public tokens and parts only, never internal class names. Scope the rule to your wrapper, here .chat-app, so it reaches only the editor in your app. Name both .pptx-editor and .pptx-editor.dark: each scope declares its own light and dark defaults.
.chat-app .pptx-editor,
.chat-app .pptx-editor.dark {
--doc-font-ui: var(--chat-font);
--doc-radius-surface: var(--chat-radius-card);
--doc-radius-control: var(--chat-radius-control);
--doc-surface: var(--chat-surface);
--doc-primary: var(--chat-accent);
}In a narrow panel, hide the rail's move buttons with its parts. Ctrl+Left and Ctrl+Right still move slides:
<PptxEditor.SlideRail orientation="horizontal">
<PptxEditor.SlideRail.MoveEarlier hidden />
<PptxEditor.SlideRail.MoveLater hidden />
</PptxEditor.SlideRail>A full match maps more tokens. The palette reference lists each one.
The example's styles.css (the "EDITOR THEME" block) owns the whole page, so it scopes the rule as :is(.pptx-editor, .pptx-editor.dark), with no wrapper. A host page that has other content scopes the same rule to its wrapper, as above. The example maps these groups:
- The chrome font, and the surface and control corner radii.
- The main, hover, and input surfaces, and the popover colors.
- The text and icon colors, including the disabled icons.
- The borders.
- The primary actions and the active toggles.
- Focus, selection, and the collaboration accent.
- The shadows and the tooltips.
It keeps the editor's defaults for the other groups. These are the errors, the warnings, the caret and slide guides, the backgrounds behind the slide, the overlay, and the slide show. A dialog draws its own border, so the example also gives .pptx-dialog.pptx-editor a --doc-card-shadow without the hairline ring.
Put your own panel buttons, such as Present or Close, in PptxEditor.Toolbar.Action. It works outside the toolbar too, and gives your button the editor's tooltip, disabled state, and focus behavior:
<PptxEditor.Toolbar.Action
label="Present"
icon={<PresentIcon />}
onSelect={() => show.start('current')}
/>Fit the slide to the panel width
In a tall panel, give the slide only the height that fits the panel width. Then no empty bands appear above and below the slide. Set the room around the slide with --doc-slide-padding, and use the same value for the height:
const SLIDE_PADDING = 12;
// width: the panel width. ratio: slideHeight / slideWidth, from useEditorState.
const height = (width - 2 * SLIDE_PADDING) * ratio + 2 * SLIDE_PADDING;
<div style={{ '--doc-slide-padding': `${SLIDE_PADDING}px` } as CSSProperties}>
<div className="deck-canvas" style={{ flex: `0 1 ${height}px` }}>
<PptxEditor.Content />
</div>
<PptxEditor.SlideRail orientation="horizontal" />
<PptxEditor.NotesPane className="deck-notes" />
</div>;Give the notes the rest of the panel height: give .deck-notes flex: 1 in your flex column. The notes field fills the pane. See Appearance and Slide rail parts.