生态产品多个设计器现已发布候选版本

查看生态总览
Skip to content

QuestionFlow alpha ​

AI chat component. This page is the API reference, generated from the source code. Usage guidance and live examples are on the Chinese page.

Anatomy ​

Parts in bold are required.

data-scope="question-flow": root · viewport · track · question · prompt · description · group · item · item-indicator · item-text · item-description · note · footer · prev-trigger · counter · next-trigger · skip-trigger · submit-trigger · result · live-region

API reference ​

Descriptions of individual props, events and slots are written in Chinese and appear on the Chinese page.

Artifacts ​

LayerValue
Custom element<xh-question-flow>
Vue componentsXhQuestionFlowCounter XhQuestionFlowDescription XhQuestionFlowFooter XhQuestionFlowGroup XhQuestionFlowItem XhQuestionFlowItemDescription XhQuestionFlowItemIndicator XhQuestionFlowItemText XhQuestionFlowLiveRegion XhQuestionFlowNextTrigger XhQuestionFlowNote XhQuestionFlowPrevTrigger XhQuestionFlowPrompt XhQuestionFlowQuestion XhQuestionFlowResult XhQuestionFlowRoot XhQuestionFlowSkipTrigger XhQuestionFlowSubmitTrigger XhQuestionFlowTrack XhQuestionFlowViewport
ComposableuseQuestionFlow
State machinequestionFlowMachine
Skin@xihan-ui/styles/question-flow.css

Props ​

PropTypeRequired
questionsreadonly QuestionFlowQuestion[]
indexnumber
defaultIndexnumber
answersQuestionFlowAnswers
defaultAnswersQuestionFlowAnswers
notesQuestionFlowNotes
defaultNotesQuestionFlowNotes
statusQuestionFlowStatus
defaultStatusQuestionFlowStatus
autoAdvanceboolean
autoAdvanceDelaynumber
allowSkipboolean
loopboolean
variantControlVariant
toneTone
sizeSize
translationsPartial<QuestionFlowTranslations>
onIndexChange(details: QuestionFlowIndexChangeDetails) => void
onAnswersChange(details: QuestionFlowAnswersChangeDetails) => void
onNotesChange(details: QuestionFlowNotesChangeDetails) => void
onSkip(details: QuestionFlowSkipDetails) => void
onSubmit(details: QuestionFlowSubmitDetails) => void

QuestionFlowQuestion ​

Elements of questions.

FieldTypeRequired
idstringYes
promptstring
typeQuestionFlowType
optionsreadonly QuestionFlowOption[]Yes
optionalboolean
descriptionstring
minSelectionsnumber
maxSelectionsnumber

Events ​

Custom elements put the payload in detail; Vue emits an event of the same name.

EventPayload
index-changeQuestionFlowIndexChangeDetails
answers-changeQuestionFlowAnswersChangeDetails
notes-changeQuestionFlowNotesChangeDetails
skipQuestionFlowSkipDetails
submitQuestionFlowSubmitDetails

Slots ​

Only slots with a payload are listed.

Vue componentSlotPayload
XhQuestionFlowItemdefaultQuestionFlowOptionSlotProps
XhQuestionFlowRootdefaultQuestionFlowRootSlotProps

React adapter props ​

Only the props each component declares itself: DOM attributes inherited from ComponentPropsWithRef are left out, and root props already listed in the Props table are not repeated. The Vue counterpart is the slot table above.

React componentPropTypeRequired
XhQuestionFlowDescriptionquestionIdstringYes
XhQuestionFlowGroupquestionIdstringYes
XhQuestionFlowItemquestionIdstringYes
XhQuestionFlowItemoptionValuestringYes
XhQuestionFlowItemoptionDisabledboolean
XhQuestionFlowItemchildrenSlotChildren<QuestionFlowOptionSlotProps>
XhQuestionFlowItemDescriptionquestionIdstringYes
XhQuestionFlowItemDescriptionoptionValuestringYes
XhQuestionFlowItemIndicatorquestionIdstringYes
XhQuestionFlowItemIndicatoroptionValuestringYes
XhQuestionFlowItemTextquestionIdstringYes
XhQuestionFlowItemTextoptionValuestringYes
XhQuestionFlowNotequestionIdstringYes
XhQuestionFlowPromptquestionIdstringYes
XhQuestionFlowQuestionquestionIdstringYes
XhQuestionFlowRootchildrenSlotChildren<QuestionFlowRootSlotProps>

State ​

Public state is written to data-state.

PartValues
root'answering' | 'submitted'
item'checked' | 'unchecked'
item-indicator'checked' | 'unchecked'
item-text'checked' | 'unchecked'
item-description'checked' | 'unchecked'
result'answering' | 'submitted'

The following names are internal to the state machine.

States: answering · submitted

Events: OPTION.TOGGLE · NOTE.SET · GOTO · NEXT · PREV · SKIP · SUBMIT · VIEWPORT.MEASURE · after.autoAdvance · CONTROLLED.ANSWERING · CONTROLLED.SUBMITTED · PRESS.START · PRESS.END

Guards: isStatusControlled · canToggle · canSkip · isFirstQuestion · isLastQuestion · canPress

connect API ​

getXxxProps() returns the host attributes of the matching part.

MemberType
statusQuestionFlowStatus
submittedboolean
indexnumber
countnumber
currentQuestionFlowQuestion | undefined
isFirstboolean
isLastboolean
canAdvanceboolean
allowSkipboolean
counterstring
announcementstring
answersQuestionFlowAnswers
notesQuestionFlowNotes
answersOf(questionId: string) => readonly string[]
noteOf(questionId: string) => string
isOptionSelected(questionId: string, value: string) => boolean
isCurrent(questionId: string) => boolean
selectionLimitsOf(questionId: string) => QuestionFlowSelectionLimits
descriptionOf(questionId: string) => string
goTo(index: number) => void
next() => void
prev() => void
skip() => void
submit() => void
toggleOption(questionId: string, value: string) => void
setNote(questionId: string, value: string) => void
measure() => void
getRootProps() => T['element']
getViewportProps() => T['element']
getTrackProps() => T['element']
getQuestionProps(props: QuestionFlowQuestionProps) => T['element']
getPromptProps(props: QuestionFlowQuestionProps) => T['element']
getDescriptionProps(props: QuestionFlowQuestionProps) => T['element']
getGroupProps(props: QuestionFlowQuestionProps) => T['element']
getItemProps(props: QuestionFlowItemProps) => T['button']
getItemIndicatorProps(props: QuestionFlowItemProps) => T['element']
getItemTextProps(props: QuestionFlowItemProps) => T['element']
getItemDescriptionProps(props: QuestionFlowItemProps) => T['element']
getNoteProps(props: QuestionFlowQuestionProps) => T['input']
getFooterProps() => T['element']
getPrevTriggerProps() => T['button']
getCounterProps() => T['element']
getNextTriggerProps() => T['button']
getSkipTriggerProps() => T['button']
getSubmitTriggerProps() => T['button']
getResultProps() => T['element']
getLiveRegionProps() => T['element']

Accessibility ​

Keyboard ​

Specification: W3C APG. Each row is a stable behavior id that the conformance tests cover; the conditions and effects are described on the Chinese page.

KeysBehavior
ArrowDown / ArrowRightquestion-flow.kbd.next-option
ArrowUp / ArrowLeftquestion-flow.kbd.prev-option
Homequestion-flow.kbd.first-option
Endquestion-flow.kbd.last-option
Spacequestion-flow.kbd.toggle
Enterquestion-flow.kbd.advance
Spacequestion-flow.kbd.item-press
Enter / Spacequestion-flow.kbd.press

ARIA ​

These attributes are produced by connect.

PartAttributeValue
questionaria-hiddenundefined | 'true'
questionaria-labelundefined | translations.prompt
questionaria-labelledbyid of the prompt part | undefined
questionrole'group'
grouparia-describedbyundefined | id of the description part
grouparia-labelundefined | translations.options
grouparia-labelledbyid of the prompt part | undefined
grouprole'radiogroup' | 'group'
itemaria-checked'true' | 'false'
itemaria-disabled'true' | 'false'
itemrole'radio' | 'checkbox'
item-indicatoraria-hidden'true'
notearia-labeltranslations.note
prev-triggeraria-labeltranslations.prev
counteraria-hidden'true'
next-triggeraria-labeltranslations.next
skip-triggeraria-labeltranslations.skip
submit-triggeraria-labeltranslations.send | translations.continue
resultaria-hidden'true'
live-regionaria-atomic'true'
live-regionaria-live'polite'

Style reference ​

Skin ​

@xihan-ui/styles/question-flow.css is written against [data-scope="question-flow"][data-part="root"] part selectors; the published build uses the mount class .xh-scope-question-flow in place of data-scope (same specificity) and sits in the xihan.components layer. Put overrides in xihan.overrides; the part selectors work as usual.

Data attributes ​

Produced by connect; valueless attributes are omitted while their condition does not hold.

PartAttributeValue
rootdata-sizeprops.size
rootdata-state'answering' | 'submitted'
rootdata-toneprops.tone
rootdata-variantprops.variant
questiondata-current'' (present only while the condition holds)
groupdata-at-max'' (present only while the condition holds)
groupdata-select-mode'single' | 'multiple'
itemdata-disabled'' (present only while the condition holds)
itemdata-pressed'' (present only while the condition holds)
itemdata-select-mode'single' | 'multiple'
itemdata-state'checked' | 'unchecked'
itemdata-xh-action-control''
itemdata-xh-action-display'always'
itemdata-xh-action-profile'row'
itemdata-xh-action-sizeprops.size
itemdata-xh-action-variant'ghost'
item-indicatordata-select-mode'single' | 'multiple'
item-indicatordata-state'checked' | 'unchecked'
item-indicatordata-xh-check-markundefined | 'checked' | 'unchecked'
item-indicatordata-xh-check-mark-profileundefined | 'box'
item-textdata-state'checked' | 'unchecked'
item-textdata-valueitem.value
item-descriptiondata-state'checked' | 'unchecked'
item-descriptiondata-valueitem.value
prev-triggerdata-disabled'' (present only while the condition holds)
prev-triggerdata-pressed'' (present only while the condition holds)
prev-triggerdata-xh-action-control''
prev-triggerdata-xh-action-display'always'
prev-triggerdata-xh-action-profile'icon'
prev-triggerdata-xh-action-size'xs'
prev-triggerdata-xh-action-variant'ghost'
next-triggerdata-disabled'' (present only while the condition holds)
next-triggerdata-pressed'' (present only while the condition holds)
next-triggerdata-xh-action-control''
next-triggerdata-xh-action-display'always'
next-triggerdata-xh-action-profile'icon'
next-triggerdata-xh-action-size'xs'
next-triggerdata-xh-action-variant'ghost'
skip-triggerdata-disabled'' (present only while the condition holds)
skip-triggerdata-pressed'' (present only while the condition holds)
skip-triggerdata-xh-action-control''
skip-triggerdata-xh-action-display'always'
skip-triggerdata-xh-action-profile'text'
skip-triggerdata-xh-action-sizeprops.size
skip-triggerdata-xh-action-variant'ghost'
submit-triggerdata-disabled'' (present only while the condition holds)
submit-triggerdata-mode'send' | 'continue'
submit-triggerdata-pressed'' (present only while the condition holds)
submit-triggerdata-toneprops.tone
submit-triggerdata-xh-action-control''
submit-triggerdata-xh-action-display'always'
submit-triggerdata-xh-action-profile'text'
submit-triggerdata-xh-action-sizeprops.size
submit-triggerdata-xh-action-variant'solid'
submit-triggerdata-xh-ink-surface''
resultdata-state'answering' | 'submitted'
resultdata-tone'success' | undefined

CSS variables ​

The public override slots, generated from what the standalone skin actually consumes.

VariablePartCSS propertyStateDefault from
--xh-question-flow-action-font-sizeskip-trigger
submit-trigger
font-sizedefault--xh-text-label-size
--xh-question-flow-action-font-weightskip-trigger
submit-trigger
font-weightdefault--xh-text-label-weight
--xh-question-flow-action-gapskip-trigger
submit-trigger
gapdefault--xh-space-1
--xh-question-flow-action-hskip-trigger
submit-trigger
block-size
inline-size
min-block-size
default
xh-action-profile=icon
xh-action-profile=row
--xh-_question-flow-h
--xh-question-flow-action-pxskip-trigger
submit-trigger
padding-inlinedefault--xh-_question-flow-px
--xh-question-flow-action-radiusskip-trigger
submit-trigger
border-radiusdefault--xh-shape-control
--xh-question-flow-bgrootbackgrounddefault
variant=subtle
--xh-_tone-subtle
--xh-bg-surface
--xh-question-flow-borderrootborderdefault--xh-border-default
--xh-question-flow-counter-fgcountercolordefault--xh-fg-subtle
--xh-question-flow-counter-font-sizecounterfont-sizedefault--xh-text-caption-size
--xh-question-flow-description-fgdescriptioncolordefault--xh-fg-muted
--xh-question-flow-description-font-sizedescriptionfont-sizedefault--xh-text-secondary-size
--xh-question-flow-dot-radiusitem-indicatorborder-radiusempty
select-mode=single
--xh-shape-circle
--xh-question-flow-dot-sizeitem-indicatorblock-size
inline-size
empty
select-mode=single
--xh-question-flow-indicator-size
--xh-question-flow-footer-gapfootergapdefault--xh-space-3
--xh-question-flow-gaprootgapdefault--xh-_question-flow-gap
--xh-question-flow-group-gapgroupgapdefault--xh-space-1
--xh-question-flow-icon-sizeroot--xh-icon-sizedefault
size=lg
size=md
size=sm
--xh-glyph-size-lg
--xh-glyph-size-md
--xh-glyph-size-sm
--xh-question-flow-indicator-bgitem-indicatorbackgrounddefaulttransparent
--xh-question-flow-indicator-bg-checkeditem-indicatorbackgroundstate=checked--xh-_tone
--xh-question-flow-indicator-borderitem-indicatorborderdefault--xh-border-strong
--xh-question-flow-indicator-border-checkeditem-indicatorborder-colorstate=checked--xh-_tone
--xh-question-flow-indicator-fgitem-indicatorcolordefault--xh-_tone-on
--xh-question-flow-indicator-icon-sizeitem-indicator--xh-icon-sizedefault--xh-_question-flow-indicator-glyph
--xh-question-flow-indicator-radiusitem-indicatorborder-radiusdefault--xh-shape-inset
--xh-question-flow-indicator-radius-singleitem-indicatorborder-radiusselect-mode=single--xh-shape-circle
--xh-question-flow-indicator-sizeitem-description
item-indicator
--xh-icon-size
block-size
inline-size
padding-inline-start
default
empty
select-mode=single
--xh-_question-flow-indicator
--xh-question-flow-item-bgitem--xh-ink-surface
background-color
default
xh-ink-surface
--xh-_action-variant-bg-rest
--xh-question-flow-item-bg-hoveritembackground-colordisabled
hover
loading
not([data-disabled])
not([data-loading])
--xh-_action-variant-bg-hover
--xh-question-flow-item-description-fgitem-descriptioncolordefault--xh-fg-subtle
--xh-question-flow-item-description-font-sizeitem-descriptionfont-sizedefault--xh-text-caption-size
--xh-question-flow-item-fgitemcolordefault
disabled
hover
is(:active, [data-pressed])
loading
not([data-disabled])
not([data-loading])
pressed
--xh-fg-muted
--xh-question-flow-item-fg-checkeditemcolordisabled
hover
is(:active, [data-pressed])
loading
not([data-disabled])
not([data-loading])
pressed
state=checked
--xh-fg-default
--xh-question-flow-item-font-sizeitemfont-sizedefault--xh-_question-flow-font-size
--xh-question-flow-item-gapitem
item-description
gap
padding-inline-start
default--xh-space-1_5
--xh-question-flow-item-pxitempadding-inlinedefault--xh-space-2
--xh-question-flow-item-pyitempadding-blockxh-action-profile=row--xh-space-1
--xh-question-flow-item-radiusitemborder-radiusdefault--xh-_action-profile-radius
--xh-question-flow-note-bgnotebackgrounddefault--xh-bg-field
--xh-question-flow-note-bg-disablednotebackgrounddisabled--xh-bg-subtle
--xh-question-flow-note-bg-focusnotebackgroundfocus-within--xh-bg-surface
--xh-question-flow-note-bordernoteborderdefault--xh-border-control
--xh-question-flow-note-border-disablednoteborder-colordisabled--xh-border-default
--xh-question-flow-note-border-focusnoteborder-color
box-shadow
focus-within--xh-border-control-focus
--xh-question-flow-note-border-hovernoteborder-colorhover
invalid
not(:disabled, :focus, [data-invalid])
--xh-border-strong
--xh-question-flow-note-fgnotecolordefault--xh-fg-default
--xh-question-flow-note-font-sizenotefont-sizedefault--xh-_question-flow-font-size
--xh-question-flow-note-pxnotepadding-inlinedefault--xh-space-2
--xh-question-flow-note-pynotepadding-blockdefault--xh-space-1_5
--xh-question-flow-note-radiusnoteborder-radiusdefault--xh-shape-control
--xh-question-flow-paddingrootpaddingdefault--xh-_question-flow-p
--xh-question-flow-placeholder-fgnotecolorplaceholder--xh-fg-subtle
--xh-question-flow-prompt-fgpromptcolordefault--xh-fg-default
--xh-question-flow-prompt-font-sizepromptfont-sizedefault--xh-text-label-size
--xh-question-flow-prompt-font-weightpromptfont-weightdefault--xh-font-weight-semibold
--xh-question-flow-question-gapquestiongapdefault--xh-space-2
--xh-question-flow-radiusrootborder-radiusdefault--xh-shape-surface
--xh-question-flow-result-bgresultbackgrounddefault--xh-_tone-subtle
--xh-question-flow-result-fgresultcolordefault--xh-_tone-fg
--xh-question-flow-result-font-sizeresultfont-sizedefault--xh-text-caption-size
--xh-question-flow-result-font-weightresultfont-weightdefault--xh-font-weight-medium
--xh-question-flow-result-gapresultgapdefault--xh-space-1
--xh-question-flow-result-hresultmin-block-sizedefault--xh-chip-h-sm
--xh-question-flow-result-pxresultpadding-inlinedefault--xh-space-1_5
--xh-question-flow-result-pyresultpadding-blockdefault0
--xh-question-flow-result-radiusresultborder-radiusdefault--xh-shape-control
--xh-question-flow-shadowrootbox-shadowdefaultnone
--xh-question-flow-skip-bgskip-trigger--xh-ink-surface
background-color
default
xh-ink-surface
--xh-_action-variant-bg-rest
--xh-question-flow-skip-bg-hoverskip-triggerbackground-colordisabled
hover
loading
not([data-disabled])
not([data-loading])
--xh-_action-variant-bg-hover
--xh-question-flow-skip-fgskip-triggercolordefault--xh-fg-muted
--xh-question-flow-skip-fg-hoverskip-triggercolordisabled
hover
is(:active, [data-pressed])
loading
not([data-disabled])
not([data-loading])
pressed
--xh-fg-default
--xh-question-flow-step-bgnext-trigger
prev-trigger
--xh-ink-surface
background-color
default
xh-ink-surface
--xh-_action-variant-bg-rest
--xh-question-flow-step-bg-hovernext-trigger
prev-trigger
background-colordisabled
hover
loading
not([data-disabled])
not([data-loading])
--xh-_action-variant-bg-hover
--xh-question-flow-step-fgnext-trigger
prev-trigger
colordefault--xh-fg-subtle
--xh-question-flow-step-fg-hovernext-trigger
prev-trigger
colordisabled
hover
is(:active, [data-pressed])
loading
not([data-disabled])
not([data-loading])
pressed
--xh-fg-default
--xh-question-flow-step-paddingnext-trigger
prev-trigger
padding-inlinedefault--xh-_action-profile-padding-inline
--xh-question-flow-step-radiusnext-trigger
prev-trigger
border-radiusdefault--xh-shape-inset
--xh-question-flow-step-sizenext-trigger
prev-trigger
block-size
inline-size
min-block-size
default
xh-action-profile=icon
xh-action-profile=row
--xh-_action-profile-visual-size
--xh-question-flow-submit-bgsubmit-trigger--xh-ink-surface
background-color
default
xh-ink-surface
--xh-_action-variant-bg-rest
--xh-question-flow-submit-bg-activesubmit-triggerbackground-colordisabled
is(:active, [data-pressed])
loading
not([data-disabled])
not([data-loading])
pressed
--xh-_action-variant-bg-pressed
--xh-question-flow-submit-bg-hoversubmit-triggerbackground-colordisabled
hover
loading
not([data-disabled])
not([data-loading])
--xh-_action-variant-bg-hover
--xh-question-flow-submit-bg-offsubmit-trigger--xh-ink-surface
background-color
disabled
xh-ink-surface
--xh-_action-variant-bg-disabled
--xh-question-flow-submit-fgsubmit-triggercolordefault
disabled
hover
is(:active, [data-pressed])
loading
not([data-disabled])
not([data-loading])
pressed
--xh-_action-variant-fg-hover
--xh-_action-variant-fg-pressed
--xh-_action-variant-fg-rest
--xh-question-flow-submit-shadowsubmit-triggerbox-shadowdefault
disabled
hover
is(:active, [data-pressed])
loading
not([data-disabled])
not([data-loading])
pressed
--xh-_highlight-tone
--xh-question-flow-track-gaptrackgapdefault--xh-_question-flow-gap
--xh-question-flow-track-ytracktranslatedefault--xh-_question-flow-track-y
--xh-question-flow-viewport-hviewportblock-sizedefault--xh-_question-flow-viewport-h

Released under The MIT License