Theme
Sound
Jump to a component
AniCanonKit · Productions
PromptComposer
PromptComposer is Studio's prompt: who and where it binds on top, the words, then its tools.
Live, from @anicanon/sakuga 2.0.0
Sakuga for iOS and Android is coming
iOS
Coming soon
PromptComposer for iOS is in the roughs. The tokens it will read are the ones on this page, the same on every platform.
Android
Coming soon
PromptComposer for Android is in the roughs. The tokens it will read are the ones on this page, the same on every platform.
- Use it for
- The prompt that makes a take (in Studio, and for episodes in Quick mode): the cast, places and references it binds on top, the words, then its tools with Generate and its cost, and
variant="media"as the phone's dock over the take. - Not for
- Writing to MakiMakiComposer
- A plain text fieldTextField
- The script itselfManuscript
- Choosing direction as tilesOptionTiles
Guidelines
slot="refs":MentionChips for the cast (@), places (#) and references ($) the prompt binds.- The words are its children; a mention inside them is a
Mention. slot="tools": the opening frame, the length, templates, with Generate (aSpendButtonand itscost) at the end of the row (or inslot="footer").placeholdershows while there are no words;slot="hint"is the one line that says what is missing before Generate works ("Add a place, or describe the moment in 24 characters or more").variant="media"is the phone's dock over the take: glass, and its chips taketone="media".- Episodes in Quick mode and Studio take from the same composer.
onInput(text)makes the words a field the creator writes in, as plain text, showingplaceholderuntil they type;valuesets its text. WithoutonInputthe words only show.
import { Button, IconButton } from '@anicanon/sakuga/ui';
import {
Mention,
MentionChip,
PromptComposer,
SpendButton,
} from '@anicanon/sakuga/anicanonkit';
export default function PromptComposerExample() {
return (
<PromptComposer label="Make a take">
<Mention>Lisa</Mention>
{
' waits for the last train in the rain; the doors close before she moves.'
}
<span slot="refs">
<MentionChip name="Lisa" note="school" />
<MentionChip
kind="place"
name="Red Line Platform Edge"
image="/art/eba-cinema.webp"
/>
</span>
<span slot="tools">
<IconButton variant="plain" icon="image" label="Opening frame" />
<Button variant="ghost" size="sm" icon="clock">
10 s
</Button>
</span>
<span slot="footer">
<SpendButton variant="primary" fullWidth cost="~100">
Generate
</SpendButton>
</span>
</PromptComposer>
);
}PropsPromptComposerProps
labelstringpromptLabelstringplaceholderstringonInput(text: string) => voidMakes the words a plain-text field the creator writes in; called with its text. Without it the words only show.
valuestringWith onInput: the text the field holds.
childrenReactNodeclassNamestringEach token reads a role, and the role lands on a value in each theme. Change the role and every component that reads it follows.
Colour
composer-bgPromptComposer: its surface.bg-surfaceneutral-0#ffffffbg-surfaceneutral-900#111117composer-edgePromptComposer: its edge.border-dividershade-a12rgba(11,10,16,0.12)border-dividerwhite-a12rgba(255,255,255,0.12)composer-fgPromptComposer: the words.text-primaryneutral-925#0b0a10text-primaryneutral-0#ffffffcomposer-rulePromptComposer: the rule over its tools.border-hairlineshade-a08rgba(11,10,16,0.08)border-hairlinewhite-a06rgba(255,255,255,0.06)Space and shape
composer-radiusradius-xl24px
composer-inset-ring-widthline-hairline1px
composer-padding-yinset-md12px
composer-padding-xinset-lg16px
composer-refs-gapgap-sm6px
composer-prompt-padding-topinset-md12px
composer-prompt-padding-xinset-xs4px
composer-prompt-padding-bottominset-sm8px
composer-prompt-focus-radiusradius-xs4px
composer-tools-gapgap-xs4px
composer-tools-border-top-widthline-hairline1px
composer-tools-padding-topinset-md12px
composer-foot-padding-topinset-sm8px
composer-hint-gapgap-sm6px
composer-hint-margin-bottomgap-md8px
composer-hint-padding-xinset-xs4px
composer-media-radiusradius-xl24px
composer-media-paddinginset-md12px
composer-media-blurblur-glassblur(22px) saturate(1.8)
composer-media-inset-ring-widthline-hairline1px
composer-media-prompt-padding-yinset-sm8px
composer-media-prompt-padding-xinset-xs4px
composer-media-tools-gapgap-xs4px
composer-forced-edge-widthline-hairline1px
composer-forced-focus-widthline-strong2px
Type
composer-prompt-fonttext-body-lg400 15px/24px "Funnel Sans", system-ui, -apple-system, "Segoe UI", sans-serif
composer-hint-fonttext-caption500 13px/18px "Funnel Sans", system-ui, -apple-system, "Segoe UI", sans-serif
composer-media-prompt-font-sizetext-body-lg-size15px
Aa
composer-media-prompt-line-heighttext-body-lg-line-height24px
Checked automatically with axe-core 4.11.4 against WCAG 2.2 A and AA, on the live preview above, in light and dark, on 26 October 2026.
- Result
- No issues found, in light or in dark.
- By design
- A region named by
label(default "Prompt"): Tab reaches the refs, then the words, then the tools. WithonInputthe words are a multi-line text box named bypromptLabel(default "Prompt") that takes typing as plain text, withplaceholderas its placeholder; without it they are text and take no focus. - Not tested
- The automated check doesn't test keyboard use, focus order or what a screen reader says. The lines above are the design system's own account of them.