KQ-2060 · SCRIBBLE/PROMPT
Scribble Prompt
A prompt composer with a sketch pad that opens beside the text field, where boxes, arrows and loose pen marks — drawn by pointer, by pen with its pressure, or placed with the arrow keys — become part of the request, each landing with a flick of its weight on springs.flick. Attaching docks the drawing: the paper lifts off the pad and shrinks on springs.glide into a thumbnail chip in the field with its strokes still visible, and pressing the chip grows it back out into the pad on the same spring. Cmd or Ctrl+Z undoes a stroke, an empty pad keeps Attach disabled and says why, and under 38rem the pad rises as a full-width sheet that a downward flick closes.
Fernworks Studio
words or a sketch, or both
Here's the Lisbon floor as it stands. Tell me what to move, and sketch it if that's quicker.
Arrow keys move the crosshair, Shift for bigger steps. P, B and A pick pen, box and arrow. Space or Enter anchors a shape and places it. Escape cancels, or closes the pad. Command or Control Z undoes.
pad open · 6 marks · fernworks lisbon floor
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/scribble-prompt
Props
- penWidth
- number
- default 2.5
- Stroke width for new marks, in drawing units (the pad is 400 wide); a pen's pressure scales it.
- gridStyle
- "dots" | "lines" | "blank"
- default "dots"
- The pad's paper.
- accent
- string
- default "var(--accent-bright)"
- Any CSS colour for the active tool, the keyboard crosshair, Attach, Send and the sketch chip's ring.
- value / defaultValue
- string
- default — / defaultScribbleText
- The message text, controlled or initial.
- onValueChange
- (text: string) => void
- default —
- Fires from every keystroke with the new text.
- strokes / defaultStrokes
- SketchStroke[]
- default — / defaultSketchStrokes
- The drawing, controlled or initial: pen marks (points) and boxes and arrows (from, to), each with a colour and width.
- onStrokesChange
- (strokes: SketchStroke[]) => void
- default —
- Fires from every stroke, undo, redo and clear with the whole drawing.
- onStrokeEnd
- (stroke: SketchStroke, strokes: SketchStroke[]) => void
- default —
- A stroke was finished, by pointer, pen or keyboard.
- open / defaultOpen
- boolean
- default — / false
- Whether the pad is open, controlled or initial; closing a pad with marks on it docks them.
- onOpenChange
- (open: boolean) => void
- default —
- Fires from the button, chip, key or drag that opened or closed the pad.
- onAttachSketch
- (strokes: SketchStroke[]) => void
- default —
- The sketch was docked into the field.
- attachments / defaultAttachments
- PromptAttachment[]
- default — / defaultPromptAttachments
- File chips in the field (name and size), controlled or initial.
- onAttachFiles
- (files: File[]) => void
- default —
- Files were picked with Attach file (a real file input).
- onRemoveAttachment
- (id: string) => void
- default —
- A file chip's remove button was pressed.
- onSubmit
- (submission: { text, sketch, attachments }) => void
- default —
- Send (or Enter) with words, a docked sketch or a file.
- messages / defaultMessages
- ScribbleMessage[]
- default — / defaultScribbleMessages
- The thread above the composer, controlled or initial; an uncontrolled send appends to it, sketch thumbnail and all.
- colors
- string[]
- default ink, accent, warn and success tokens
- Pen colours as CSS colours, offered as a radiogroup.
- assistant
- string
- default "Fernworks Studio"
- Who answers, named in the header.
- placeholder
- string
- default "Describe the change, or sketch it"
- The text field's placeholder.
- height
- number
- default 540
- The surface's height in px.
- disabled
- boolean
- default false
- Nothing can be typed, drawn or sent.
- className
- string
- default —
- Classes for the outer surface.
| Prop | Type | Default | Description |
|---|---|---|---|
| penWidth | number | 2.5 | Stroke width for new marks, in drawing units (the pad is 400 wide); a pen's pressure scales it. |
| gridStyle | "dots" | "lines" | "blank" | "dots" | The pad's paper. |
| accent | string | "var(--accent-bright)" | Any CSS colour for the active tool, the keyboard crosshair, Attach, Send and the sketch chip's ring. |
| value / defaultValue | string | — / defaultScribbleText | The message text, controlled or initial. |
| onValueChange | (text: string) => void | — | Fires from every keystroke with the new text. |
| strokes / defaultStrokes | SketchStroke[] | — / defaultSketchStrokes | The drawing, controlled or initial: pen marks (points) and boxes and arrows (from, to), each with a colour and width. |
| onStrokesChange | (strokes: SketchStroke[]) => void | — | Fires from every stroke, undo, redo and clear with the whole drawing. |
| onStrokeEnd | (stroke: SketchStroke, strokes: SketchStroke[]) => void | — | A stroke was finished, by pointer, pen or keyboard. |
| open / defaultOpen | boolean | — / false | Whether the pad is open, controlled or initial; closing a pad with marks on it docks them. |
| onOpenChange | (open: boolean) => void | — | Fires from the button, chip, key or drag that opened or closed the pad. |
| onAttachSketch | (strokes: SketchStroke[]) => void | — | The sketch was docked into the field. |
| attachments / defaultAttachments | PromptAttachment[] | — / defaultPromptAttachments | File chips in the field (name and size), controlled or initial. |
| onAttachFiles | (files: File[]) => void | — | Files were picked with Attach file (a real file input). |
| onRemoveAttachment | (id: string) => void | — | A file chip's remove button was pressed. |
| onSubmit | (submission: { text, sketch, attachments }) => void | — | Send (or Enter) with words, a docked sketch or a file. |
| messages / defaultMessages | ScribbleMessage[] | — / defaultScribbleMessages | The thread above the composer, controlled or initial; an uncontrolled send appends to it, sketch thumbnail and all. |
| colors | string[] | ink, accent, warn and success tokens | Pen colours as CSS colours, offered as a radiogroup. |
| assistant | string | "Fernworks Studio" | Who answers, named in the header. |
| placeholder | string | "Describe the change, or sketch it" | The text field's placeholder. |
| height | number | 540 | The surface's height in px. |
| disabled | boolean | false | Nothing can be typed, drawn or sent. |
| className | string | — | Classes for the outer surface. |