Prompt Composer
The box where people write to an AI: a growing text area, pill controls for attachments and modes, and a send button, edged with a glow in the brand's colours.
Preview
Installation
pnpm add @syntara/react @syntara/tokensimport { PromptComposer, ComposerButton, ComposerSelect } from '@syntara/react';Usage
import { ComposerButton, ComposerSelect, PromptComposer } from '@syntara/react';
import { IconPlus } from '@syntara/icons';
export function Chat() {
return (
<PromptComposer
onSubmit={(text) => console.log(text)}
startActions={
<>
<ComposerButton aria-label="Attach a file" icon={<IconPlus />} />
<ComposerSelect
label="Reasoning"
options={[
{ id: 'quick', label: 'Quick answer' },
{ id: 'deep', label: 'DeepThink' },
]}
/>
</>
}
/>
);
}Examples
Brand glow
glow="brand": the edge and halo in the brand's primary and accent colours, on a solid face.
No glow
glow={false} for a quiet composer: the same keyboard behaviour without the light.
Accessibility
| Keys | Action |
|---|---|
| Enter | Sends. Does nothing while an input method is still composing a word. |
| ShiftEnter | Adds a new line. |
| Tab | Moves from the text box through the toolbar controls to send. |
- The send button is disabled while the box is empty, and becomes a Stop button while a reply is pending.
- Focus in the text box draws the 2px focus ring around the whole composer; the brighter glow is decoration.
- The glow colours swap sides and the send arrow mirrors on right-to-left pages.
- On narrow composers pills with an icon show only the icon; the label stays as visually hidden text, so the name is unchanged.
Guidelines
Do
- Keep the toolbar to a few controls; put the rest in the attach menu.
Don’t
- Don't use the glow on more than one element in a view.
API reference
PromptComposer
onSubmit(value: string) => voidCalled with the trimmed text on Enter or the send button. Shift+Enter adds a line.
isPendingbooleanA reply is being written: the send button becomes stop and the glow breathes.
Default
falseonStop() => voidCalled by the stop button.
startActionsReactNodeToolbar controls at the start: attach, pickers.
endActionsReactNodeToolbar controls before the send button.
glowboolean | 'brand' | 'spectrum'The two-colour edge and halo. brand: primary and accent. spectrum: warning to info, warm to cool, the same in every brand's palette. false turns it off.
Default
'brand'surfacesoliddefaultglass
glass is a frosted face for a composer floating over content; text keeps 4.5:1 over any backdrop.
labelstringAccessible name of the text box.
Default
'Message'
ComposerButton
iconReactNodeLeading icon. With no children the pill becomes a circle and needs aria-label.
ComposerSelect
labelRequiredstringWhat is being chosen. Read together with the choice, e.g. "Reasoning: DeepThink".
optionsRequiredComposerOption[]{ id, label, icon?, description? } for each choice.
Tokens
The semantic tokens this component reads, grouped by what they control. Swatches show this site’s theme; change a tenant’s brand and the component follows with no code change.
- Colour14
action.primary.bgaction.primary.fgaction.primary.hoveraccent.bgsurface.raisedsurface.selectedborder.defaultborder.strongtext.defaulttext.subtletext.disabledfocus.ringfeedback.warning.solidfeedback.info.solid- Type3
font.size.mdfont.size.lgfont.weight.medium- Space and size2
control.heightcontrol.padding.inline- Shape2
radius.containerradius.button- Depth4
shadow.raisedhairlineglass.opacityglass.blur- Motion2
motion.springmotion.duration.spring