Skip to content
ghostui

Preview

How's your product's design today?
1/3

Progress counts valid answers and optional skips. It does not count the current step. Choice questions can add an editable final row with custom without exposing a visible “Other” label; custom answers are typed records with a stable question-scoped identity, so text never collides with a known option. After acknowledgement, a valid submitted response may also count an explicitly stored empty optional answer; an empty questionnaire stays incomplete. Cancelled and expired requests remain readable with their retained response or drafts, while a submitted request without a response says that the response is unavailable.

Design guidance

In a chat, place Questionnaire directly in ChatFooter in place of Composer. It fills the same available width. Keep the editable questionnaire outside Message; put the acknowledged QuestionnaireRecord in one user Message. The caller restores the preserved draft and textarea focus after acknowledgement. See SDK integration for tool-result and approval wiring.

Accessibility

Each question has a real legend or Field label. Errors link to the invalid control and focus the first invalid question after validation. Back, Next, Skip, and Submit are native buttons; terminal responses are read-only and cancelled or expired requests are inert.

Installation

Install
Source files

Basic usage

Structures

Examples

Design intake

Answer a short design-intake conversation with one question visible at a time.

How's your product's design today?
1/3

Required single-choice

Move through required choices with the native RadioGroup and explicit arrow action.

How should we deliver the replacement?
1/2

Multiple choices

Toggle one or more options with the shared Checkbox owner, then continue explicitly.

Which updates should we send?
1/1

Freeform

Enter a required text answer with the shared Field and Input owners.

1/1

Optional skip

Skip an optional question while preserving the skipped id in the response.

1/2

Validation

Submit without a required choice to show the linked error and focus the first invalid control.

Which updates should we send?
1/1

Failed send and acknowledgement

A rejected send retains the draft. A later success waits for the parent to confirm receipt.

How should we deliver the replacement?
1/2

Submitted record

Show the accepted response as a read-only record.

Submitted answers

How should we deliver the replacement?
Express delivery
What else should we know?
Please leave it with reception.

Cancelled request

Keep retained answers readable after the request is cancelled; the record has no interactive controls.

Cancelled answers

This request was cancelled.

How should we deliver the replacement?
Express delivery
What else should we know?
Please leave it with reception.

Expired request

Keep an expired request readable and inert.

Expired answers

This request expired.

How should we deliver the replacement?
Skipped
What else should we know?
Skipped

Long and narrow content

Wrap long translated labels and notes without clipping the controls.

Which translated delivery instruction best describes where the replacement package should be left?

Long labels remain readable and controls keep distinct targets on narrow screens.

1/2

Unavailable response

Keep every question readable when the conversation cannot receive an answer.

Questions

How should we deliver the replacement?
No answer recorded.
What else should we know?
No answer recorded.

Responses are unavailable for this request.

Complete conversation

The conversation owner turns one acknowledged response into a readable user answer and restores its composer.

I can tailor the product design. Answer three quick questions first.
How's your product's design today?
1/3

API reference

QuestionDefinition.custom adds a final editable row to a single- or multiple-choice question. Set it to true, or provide its placeholder and maximum length as an object. The submitted value is { type: "custom", id: "custom:<question-id>", value: "..." }; multiple-choice answers contain this record beside known option values.

QuestionnaireRecord displays submitted, cancelled, expired, or unavailable answers as a read-only record and forwards native div props and its ref.