SplitCanvasTemplate
StableChat or controls on the left, and the thing you are making on the right.
Also known as split layout, canvas layout, two pane layout
Install with npm install @tattva/ui (setup), or copy the code from the kit in Downloads.
A prompt and a canvas
<div className="h-105 overflow-hidden rounded-card border border-line">
<AppShell>
<SplitCanvasTemplate
primary={<Composer onSend={() => {}} />}
canvas={
<CanvasPanel title="Launch announcement.md">
<Markdown>{"# Launch announcement\n\nA calmer way to build with AI."}</Markdown>
</CanvasPanel>
}
/>
</AppShell>
</div>A document on the right. On a narrow screen the two sides stack.
When to use it
Splits the main area in two: chat or controls on the left, the thing being made on the right. The work stays in view while the person keeps changing it.
Made of: Left side · Canvas (right side)
Use it for
- Editing a document or code with the assistant beside it.
- A studio with the prompt and options on the left and the chosen draft on the right.
- Any screen where the result must stay visible while people work.
Not for
- A plain chat with no lasting result: use ThreadTemplate.
- A new chat before the first message: use HomeTemplate.
Do and avoid
Welcome email
Welcome email
Hi Sam, thanks for joining. Here is how to get started this week.
Baggage question
Do
- Put a CanvasPanel on the right so it fills the height.
- Use it when the result should stay in view while the person makes changes.
- Keep the controls for making things on the left.
- Check the stacked layout on small screens, where the canvas comes after the left side.
Avoid
- Do not use it for plain chat. ThreadTemplate is the right frame.
- Do not put lasting content on the left and short-lived content on the canvas. The canvas is for the thing being made.
- Do not set fixed heights on the sides. The template handles overflow itself.
On a phone
- Below the lg breakpoint the conversation and the canvas stack in one column, conversation first, and the page scrolls as one.
- The stacked canvas is at least 22.5rem tall; from lg up the two sit side by side and scroll separately.
- Side padding is 1rem on a phone and 1.5rem from sm.
Properties
| Prop | Type | Default | Description |
|---|---|---|---|
| primaryrequired | ReactNode | none | Left column: the conversation or controls. Wrapped in a section named by primaryLabel (default Conversation) that scrolls and spaces its children by 24px. |
| canvasrequired | ReactNode | none | Right column: the artifact that outlives a single message, usually CanvasPanel. Wrapped in a section named by canvasLabel (default Canvas). Stacks under primary on narrow screens. |
| primaryLabel | string | "Conversation" | Accessible name for the left region. Change it when the column holds controls rather than a chat. |
| canvasLabel | string | "Canvas" | Accessible name for the right region. |
"Show code under the preview gives the code for the example on the stage."
Tokens
Change one of these and every part that uses it follows.
gap-4 / p-4grid-cols 5fr / 6fr at lgmin-h-90 canvas on small screens
Built in
- The two sides are named areas, "Conversation" and "Canvas" by default.
- The left side comes first in reading order, which matches the stacked layout on small screens.
- The title bar holds the page's top heading.
What you need to do
- Rename the sides with primaryLabel and canvasLabel when they hold something other than a chat and a canvas.
- Pass a header. Without one, the page's top heading is empty.
- Tell people when the canvas changes because of something they did on the left. The template does not.
Built toward WCAG 2.2 AA and checked automatically; no independent audit yet. Read the accessibility guide