XDSChatDictationButton@xds/core · Chat
Preview coming soon
Usage
ChatDictationButton is a toggle button that starts and stops voice dictation inside a chat composer. It pairs with useXDSChatDictation to show a microphone icon when idle and animated frequency bars when listening. Place it in the sendActions slot of XDSChatComposer.Best practices
| Guidance | Practices |
|---|---|
| Do | Place the dictation button in the sendActions slot of XDSChatComposer so it sits next to the send button where users expect voice input controls. |
| Do | Pass an inputRef to useXDSChatDictation so interim transcripts appear as ghost text in the composer input while the user speaks. |
| Do | Enable hasSounds on useXDSChatDictation to give users audio feedback when dictation starts and stops — especially helpful when the button's visual change is subtle. |
| Don't | Don't use the dictation button outside a chat composer context — it's designed for the composer's send-action layout, not as a standalone recording control. |
| Don't | Don't forget to handle the unsupported case — the button hides itself by default when the browser lacks SpeechRecognition, but you should still design the composer to work without it. |
Anatomy
| Element | Description | |
|---|---|---|
| Microphone icon | required | Shown in the idle state. Indicates that tapping will start voice input. |
| Frequency bars | Animated equalizer bars that replace the icon during listening. React to real microphone volume. | |
| Ghost button | required | The underlying XDSButton with ghost variant and isIconOnly, providing the hit target and focus ring. |
Import
tsimport {XDSChatDictationButton} from '@xds/core/Chat'
Props
| Prop | Type | Description |
|---|---|---|
dictationrequired | UseSpeechRecognitionReturn | The return value from useXDSChatDictation or useSpeechRecognition. Controls all button state — listening, volume, bands, and toggle. |
size | 'sm' | 'md' (default: 'md') | Button size. Matches XDSChatComposer density. |
isHiddenWhenUnsupported | boolean (default: true) | When true, renders nothing if the browser does not support SpeechRecognition. |
label | string | Accessible label override. Defaults to "Start dictation" or "Stop dictation" based on state. |
xstyle | StyleXStyles | Additional StyleX styles applied to the wrapper. |
Showcase source
tsx'use client';import {useRef} from 'react';import {XDSChatDictationButton,XDSChatComposer,XDSChatComposerInput,useXDSChatDictation,} from '@xds/core/Chat';import type {XDSChatComposerInputHandle} from '@xds/core/Chat';import {XDSHStack, XDSVStack} from '@xds/core/Layout';import {XDSText} from '@xds/core/Text';export default function ChatDictationButtonShowcase() {const inputRef = useRef<XDSChatComposerInputHandle>(null);const dictation = useXDSChatDictation({inputRef,hasSounds: true,onResult: (text) => {console.log('Dictation result:', text);},});return (<XDSVStack gap={4}><XDSText type="supporting" color="secondary">Click the microphone to start dictating. Speech is transcribed into theinput.</XDSText><XDSChatComposeronSubmit={(v) => console.log('Submit:', v)}input={<XDSChatComposerInput ref={inputRef} />}sendActions={<XDSChatDictationButton dictation={dictation} />}/>{dictation.isListening && (<XDSHStack gap={2} vAlign="center"><XDSText type="supporting" color="secondary">{dictation.isSpeaking ? 'Speaking detected' : 'Listening...'}</XDSText><divstyle={{width: 80,height: 6,backgroundColor: 'var(--color-surface-secondary)',borderRadius: 3,overflow: 'hidden',}}><divstyle={{height: '100%',backgroundColor: dictation.isSpeaking? 'var(--color-accent)': 'var(--color-text-secondary)',borderRadius: 3,transition: 'width 0.08s ease-out',width: `${Math.min(dictation.volume * 200, 100)}%`,}}/></div></XDSHStack>)}{!dictation.isSupported && (<XDSText type="supporting" color="active">SpeechRecognition is not supported in this browser.</XDSText>)}</XDSVStack>);}