SpeakerNotes
StableNotes for one slide: an AI draft held apart until you keep it, "AI draft" or "Edited by you", and the word count and speaking time worked out in code.
Also known as presenter notes, notes
Install with npm install @tattva/ui (setup), or copy the code from the kit in Downloads.
Draft, keep, then edit
For Slide 2: Churn went from 3.1% to 4.4%.
- Chart on this slide: made from your file churn-q3.csv
<SpeakerNotes
slideLabel="Slide 2: Churn went from 3.1% to 4.4%"
value={notes}
state={state} // "empty" | "generating" | "proposed" | "kept" | "edited" | "failed"
proposed={draft}
onChange={(v) => { setNotes(v); if (state === "kept") setState("edited"); }}
onGenerate={draftNotes}
onKeep={() => { setNotes(draft); setState("kept"); }}
onDiscard={() => setState(previousState)}
onRevert={() => { setNotes(aiVersion); setState("kept"); }}
imageCredits={["Chart on this slide: made from your file churn-q3.csv"]}
/>Draft notes with AI, then Keep. Type in the box: the label becomes "Edited by you" with a button to put the AI draft back. Drafting again now asks first.
When to use it
Helps a presenter get notes for a slide quickly while keeping what they will say in their own hands.
Made of: Label or fold button · Origin (AI draft or Edited by you) · Words and speaking time · Notes box · Draft box with Keep and Discard · Draft button · Image credits
Use it for
- The notes panel under the slide in a deck editor.
- Drafting notes for one slide on request, with Keep or Discard.
- Checking how long a slide will take to present.
Not for
- Drafting text that goes into the slide or a document: use SuggestionBar.
- Switching between your text and the AI's for any field: use RevertToggle.
- A plain form text box: use Field.
Do and avoid
For Slide 2.
Start with the two new stores. Then point to the north, which grew fastest.
For Slide 2.
Do
- Hold every AI draft apart until the person presses Keep.
- Show who wrote the notes: "AI draft" or "Edited by you".
- Count words and speaking time in code from the text the person sees.
- List AI images on the slide, so the presenter can say where they came from.
Avoid
- Do not write AI notes straight into the box, even when it is empty.
- Do not ask the model how long the notes take to say.
- Do not keep the lime AI label after the person has edited the notes.
- Do not redraft notes for every slide without asking.
On a phone
- Set collapsible to fold the notes under the slide behind a Speaker notes button.
- The notes box text is 16px on touch screens, so phones do not zoom in.
- Buttons get a 44px touch area; the words and time line wraps under the label when space is short.
Seen in products
- PowerPoint Copilot generates speaker notes for one slide or all slides, then asks Keep it or Discard.
- Copilot writes an "AI-generated" image source into the speaker notes.
- Pitch generates presenter notes from the slide content.
Properties
| Prop | Type | Default | Description |
|---|---|---|---|
| slideLabelrequired | string | none | Which slide the notes are for, such as "Slide 4: Pricing plans". Names the section and the notes box. |
| valuerequired | string | none | The person's notes. AI text lands here only through onKeep. |
| onChangerequired | (value: string) => void | none | Called on every keystroke. |
| staterequired | "empty" | "generating" | "proposed" | "kept" | "edited" | "failed" | none | Where the notes are. kept means the AI draft as kept; edited means the person wrote or changed them. |
| proposed | string | none | The AI draft, shown apart while generating or proposed. |
| onGenerate | () => void | none | Drafts notes for this slide. Asks first when the notes are edited by the person. |
| onKeep | () => void | none | Replaces the notes with the draft. |
| onDiscard | () => void | none | Drops the draft. The notes stay as they were. |
| onStop | () => void | none | Stops a draft that is still being written. |
| onRevert | () => void | none | Puts the AI draft back after an edit. Shows a revert button by "Edited by you". |
| wordsPerMinute | number | 130 | Speaking pace used to turn the word count into time. |
| imageCredits | string[] | none | Lines about images on the slide, such as "Photo on this slide: made by AI". |
| error | string | none | Why the draft failed, in plain words. |
| collapsible | boolean | false | Folds the notes behind a Speaker notes button. |
| defaultOpen | boolean | true | Whether folded notes start open. |
| className | string | none | Extra classes for the section. |
"Show code under the preview gives the code for the example on the stage."
In Figma
In Figma, one SpeakerNotes switches all of this from its properties panel, across 6 variants. Each property sets the React prop beside it, so design and code use the same names.
| Figma property | React | Values |
|---|---|---|
| Status | state | Empty, Generating, Proposed, Kept, Edited, Failed |
States
States this part has beyond its default look. Build each one your screen can reach. States set by a property are in the Code tab.
- empty
- No notes: placeholder text and Draft notes with AI.
- generating
- Draft streams into a separate box with a lime working edge and Stop drafting. The person's notes are untouched.
- proposed
- Draft waits with Keep (or "Keep, replacing my notes") and Discard.
- kept
- AI draft kept: lime "AI draft" label.
- edited
- "Edited by you", a revert button when onRevert is set, and drafting asks first.
- failed
- Red line with the reason and Try drafting again. The notes are unchanged.
- collapsed
- Folded behind the Speaker notes button. Set collapsible.
Tokens
Change one of these and every part that uses it follows.
--surface--sunken--border--border-strong--fg--fg-muted--fg-subtle--lime--danger-fg--radius-field--radius-card--radius-control--dur-fast
Built in
- The notes box is a native textarea labelled "Speaker notes" and described by its slide.
- A polite live region says Drafting notes, Draft ready, Notes kept, Draft discarded or Notes could not be drafted. The streaming words are not read out.
- Origin is written in words: "AI draft" on a lime pill, or "Edited by you" with a pencil icon.
- Drafting over edited notes asks "Draft over your edits?" in place, with Keep mine focused first, so one key press never replaces the person's words.
- The fold button has aria-expanded and aria-controls.
- The working edge around a draft being written holds still under reduced motion.
What you need to do
- Set state to edited as soon as the person changes AI-written notes, and back to kept if they revert.
- Pass the slide's real title in slideLabel, so the notes box is named after its slide.
- Set wordsPerMinute to the presenter's pace if you know it. The default is 130.
- Draft notes for many slides only on a clear request, and still stage each one for Keep or Discard.
Built toward WCAG 2.2 AA and checked automatically; no independent audit yet. Read the accessibility guide