alpha

AI Components

React Spectrum provides components for building AI-powered experiences, including prompts, messages, suggestions, attachments, and voice input.

Responses are generated using AI, and may be inaccurate. Check before using. AI User Guidelines

Example
promptfield.tsx
chat.tsx
import {useState, useRef} from 'react';
import {
  AttachFileMenuItem,
  CommandMenuItem,
  InsertTokenMenuItem,
  InsertMenuButton,
  PromptField,
  Attachment,
  AttachmentPreview,
  PromptFieldAttachment,
  PromptFieldAttachmentList,
  PromptFieldSubmitButton,
  PromptFieldToolbar,
  PromptFieldValue,
  PromptFieldVoiceButton,
  PromptToken,
  PromptTokenField
} from '@react-spectrum/ai';
import {type FocusableRefValue} from '@react-types/shared';
import {getIcon, slashCommands, objects, renderCompletions, suggestions, type UploadState} from './ai-component-helpers/promptfield';
import {style} from '@react-spectrum/s2/style' with {type: 'macro'};
import {Collection, SubmenuTrigger, Menu, MenuItem, MenuSection, Header, Heading, Text} from '@react-spectrum/s2';
import Data from '@react-spectrum/s2/icons/Data';
import Plugin from '@react-spectrum/s2/icons/Plugin';
import Prompt from '@react-spectrum/s2/icons/Prompt';
import {VirtualizedStreamingChat} from './ai-component-helpers/chat';

function Example() {
  let [value, setValue] = useState<PromptFieldValue>(() => new PromptFieldValue([]));
  let promptFieldRef = useRef<FocusableRefValue<HTMLDivElement>>(null);
  let [attachments, setAttachments] = useState<PromptFieldAttachment[]>([]);
  let [attachmentState, setAttachmentState] = useState<Map<string, UploadState>>(new Map());

  let mockUpload = async (id: string) => {
    await new Promise(resolve => setTimeout(resolve, Math.random() * 30));
    setAttachmentState(prev => {
      let item = prev.get(id);
      if (!item || item.status === 'completed') {
        return prev;
      }
      let newState = new Map(prev);
      let progress = (item.progress ?? 0) + 1;
      if (progress >= 100) {
        newState.set(id, {status: 'completed'});
      } else {
        newState.set(id, {status: 'uploading', progress});
        mockUpload(id);
      }
      return newState;
    });
  };

  let clearPrompt = () => {
    setValue(new PromptFieldValue([]));
    setAttachments([]);
    alert('Conversation cleared');
  };

  let compactPrompt = () => {
    alert('Conversation compacted');
  };

  return (
    <div className={style({height: 700, width: 'full'})}>
      <VirtualizedStreamingChat
        suggestions={suggestions}
        onSelectSuggestion={value => {
          setValue(value as PromptFieldValue);
          promptFieldRef.current?.focus();
        }}>
        {(onSend, isGenerating) => (
          <PromptField
            ref={promptFieldRef}
            value={value}
            onChange={setValue}
            attachments={attachments}
            onAttachmentsChange={setAttachments}
            isGenerating={isGenerating}
            onSubmit={prompt => {
              onSend(prompt);
              setValue(new PromptFieldValue([]));
              setAttachments([]);
              setAttachmentState(new Map());
            }}
            acceptedAttachmentTypes={['*/*']}
            onAddAttachments={newAttachments => {
              setAttachmentState(prev => {
                let newState = new Map(prev);
                newAttachments.forEach(attachment => {
                  newState.set(attachment.id, {status: 'uploading', progress: 0});
                  mockUpload(attachment.id);
                });
                return newState;
              });
            }}
            onRemoveAttachments={removedAttachments => {
              setAttachmentState(prev => {
                let newState = new Map(prev);
                removedAttachments.forEach(attachment => {
                  newState.delete(attachment.id);
                });
                return newState;
              });
            }}>
            <PromptFieldAttachmentList dependencies={[attachmentState]}>
              {attachment => {
                let state = attachmentState.get(attachment.id);
                return (
                  <Attachment uploadProgress={state?.status === 'uploading' ? state?.progress : undefined}>
                    <AttachmentPreview mimeType={attachment.file.type} src={attachment.image} />
                  </Attachment>
                );
              }}
            </PromptFieldAttachmentList>
            <PromptTokenField
              completionTrigger={/(?<=^|\s)[@/]/}
              renderCompletions={(filterValue, valueType) => {
                return renderCompletions(filterValue, {valueType, onClear: clearPrompt, onCompact: compactPrompt});
              }}>
              {token => (
                <PromptToken token={token}>
                  {getIcon(token)}
                  {token.text}
                </PromptToken>
              )}
            </PromptTokenField>
            <PromptFieldToolbar>
              <div className={style({display: 'flex', gap: 8, alignItems: 'center'})}>
                <InsertMenuButton>
                  <AttachFileMenuItem />
                  <SubmenuTrigger>
                    <MenuItem>
                      <Prompt />
                      <Text>Commands</Text>
                    </MenuItem>
                    <Menu items={slashCommands.filter(item => item.kind === 'command')}>
                      {item => (
                        <CommandMenuItem
                          id={item.command}
                          onAction={item.command === '/clear' ? clearPrompt : compactPrompt}>
                          <Prompt />
                          <Text slot="label">{item.command}</Text>
                          <Text slot="description">{item.description}</Text>
                        </CommandMenuItem>
                      )}
                    </Menu>
                  </SubmenuTrigger>
                  <SubmenuTrigger>
                    <MenuItem>
                      <Plugin />
                      <Text>Skills</Text>
                    </MenuItem>
                    <Menu items={slashCommands.filter(item => item.kind === 'skill')}>
                      {item => (
                        <InsertTokenMenuItem
                          id={item.command}
                          token={{
                            type: 'token',
                            text: item.command,
                            value: {type: 'custom', anchor: '/', valueType: item.kind, data: item}
                          }}>
                          <Plugin />
                          <Text slot="label">{item.command}</Text>
                          <Text slot="description">{item.description}</Text>
                        </InsertTokenMenuItem>
                      )}
                    </Menu>
                  </SubmenuTrigger>
                  <SubmenuTrigger>
                    <MenuItem>
                      <Data />
                      <Text>Reference an object</Text>
                    </MenuItem>
                    <Menu items={objects}>
                      {item => (
                        <MenuSection>
                          <Header>
                            <Heading>{item.section}</Heading>
                          </Header>
                          <Collection items={item.items}>
                            {item => (
                              <InsertTokenMenuItem
                                id={item.title}
                                token={{
                                  type: 'token',
                                  text: item.title,
                                  value: {type: 'custom', anchor: '@', valueType: item.kind, data: item}
                                }}>
                                {item.title}
                              </InsertTokenMenuItem>
                            )}
                          </Collection>
                        </MenuSection>
                      )}
                    </Menu>
                  </SubmenuTrigger>
                </InsertMenuButton>
              </div>
              <div className={style({display: 'flex', gap: 8, alignItems: 'center'})}>
                <PromptFieldVoiceButton />
                <PromptFieldSubmitButton />
              </div>
            </PromptFieldToolbar>
          </PromptField>
        )}
      </VirtualizedStreamingChat>
    </div>
  );
}

Installation

AI components are published as a separate package from @react-spectrum/s2.

npm install @react-spectrum/ai

Prompt fields

Use PromptField as the foundation for allowing the user to submit a prompt. It manages an editable sequence of text and tokens, while PromptTokenField renders the input and PromptFieldToolbar contains its actions.

Responses are generated using AI, and may be inaccurate. Check before using. AI User Guidelines

variant 
size 
isGenerating 
import {useState} from 'react';
import {
  PromptField,
  PromptFieldSubmitButton,
  PromptFieldToolbar,
  PromptFieldValue,
  PromptTokenField
} from '@react-spectrum/ai';
import {style} from '@react-spectrum/s2/style' with {type: 'macro'};

function BasicPrompt(props) {
  let [value, setValue] = useState<PromptFieldValue>(() => new PromptFieldValue([]));

  return (
    <div 
      className={style({
        minWidth: 190,
        width: {
          default: 'full',
          size: {
            S: '50%'
          }
        }
      })({size: props.size})}>
      <PromptField
        {...props}
        value={value}
        onChange={setValue}
        onSubmit={value => {
          console.log(value.toString());
          setValue(new PromptFieldValue([]));
        }}>
        <PromptTokenField />
        <PromptFieldToolbar>
          <div style={{marginInlineStart: 'auto'}}>
            <PromptFieldSubmitButton />
          </div>
        </PromptFieldToolbar>
      </PromptField>
    </div>
  );
}

Suggestions and tokens

Suggestions can prefill a prompt, and a token field can offer context-aware completions such as mentions or commands.

Try asking

Responses are generated using AI, and may be inaccurate. Check before using. AI User Guidelines

import {useState} from 'react';
import {
  InsertTokenMenuItem,
  MessageSuggestion,
  MessageSuggestionList,
  PromptField,
  PromptFieldSubmitButton,
  PromptFieldToolbar,
  PromptFieldValue,
  PromptTokenField
} from '@react-spectrum/ai';
import {style} from '@react-spectrum/s2/style' with {type: 'macro'};

let people = ['Customers', 'Designers', 'Developers']; let suggestions = [ new PromptFieldValue([{type: 'text', text: 'Summarize this report'}]), new PromptFieldValue([ {type: 'text', text: 'Draft a project brief for '}, { type: 'token', text: 'Designers', value: {type: 'custom', anchor: '@', valueType: 'person', data: 'Designers'} } ]), new PromptFieldValue([{type: 'text', text: 'Find risks in this plan'}]) ]; function PromptSuggestions() { let [value, setValue] = useState<PromptFieldValue>(() => new PromptFieldValue([])); return ( <div style={{display: 'flex', flexDirection: 'column', gap: 16}}> <MessageSuggestionList title="Try asking"> {suggestions.map((suggestion, i) => ( <MessageSuggestion key={i} onPress={() => setValue(suggestion)}> {suggestion.segments.map((segment, j) => segment.type === 'token' ? ( <span key={j} className={suggestionToken}>{segment.text}</span> ) : ( segment.text ) )} </MessageSuggestion> ))} </MessageSuggestionList> <PromptField value={value} onChange={setValue} onSubmit={console.log}>
<PromptTokenField completionTrigger={/(?<=^|\s)@/} renderCompletions={filterValue => people .filter(person => person.toLowerCase().includes(filterValue.slice(1).toLowerCase())) .map(person => ( <InsertTokenMenuItem key={person} id={person} token={{ type: 'token', text: person, value: {type: 'custom', anchor: '@', valueType: 'person', data: person} }}> {person} </InsertTokenMenuItem> )) } placeholder="Ask about @customers" /> <PromptFieldToolbar> <div style={{marginInlineStart: 'auto'}}> <PromptFieldSubmitButton /> </div> </PromptFieldToolbar> </PromptField> </div> ); }

Attachments and actions

Use PromptFieldAttachmentList to render a preview of attached files the user has dragged onto the PromptField or added via the InsertMenuButton in the toolbar. Custom menu items and toolbar controls can be added as well.

Responses are generated using AI, and may be inaccurate. Check before using. AI User Guidelines

import {useState} from 'react';
import {
  Attachment,
  AttachmentPreview,
  AttachFileMenuItem,
  InsertMenuButton,
  InsertTextMenuItem,
  PromptField,
  PromptFieldAttachment,
  PromptFieldAttachmentList,
  PromptFieldSubmitButton,
  PromptFieldToolbar,
  PromptFieldVoiceButton,
  PromptFieldValue,
  PromptTokenField
} from '@react-spectrum/ai';
import {Text} from '@react-spectrum/s2';
import CommentText from '@react-spectrum/s2/icons/CommentText';

function PromptAttachments() {
  let [attachments, setAttachments] = useState<PromptFieldAttachment[]>([
    {id: '0', file: new File([], 'preview.png', {type: 'image/png'}), image: 'https://images.unsplash.com/photo-1705034598432-1694e203cdf3?q=80&w=600&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D'},
    {id: '1', file: new File([], 'notes.txt', {type: 'text/plain'}), image: ''}
  ]);

  return (
    <PromptField
      defaultValue={new PromptFieldValue([])}
      attachments={attachments}
      onAttachmentsChange={setAttachments}
      acceptedAttachmentTypes={['*/*']}>
      <PromptFieldAttachmentList>
        {attachment => (
          <Attachment textValue={attachment.file.name}>
            <AttachmentPreview mimeType={attachment.file.type} src={attachment.image} />
          </Attachment>
        )}
      </PromptFieldAttachmentList>
      <PromptTokenField placeholder="Describe the image" />
      <PromptFieldToolbar>
        <InsertMenuButton>
          <AttachFileMenuItem />
          <InsertTextMenuItem id="summarize" text="Summarize this image">
            <CommentText />
            <Text>Summarize image</Text>
          </InsertTextMenuItem>
        </InsertMenuButton>
        <div style={{display: 'flex', gap: 8, alignItems: 'center'}}>
          <PromptFieldVoiceButton />
          <PromptFieldSubmitButton />
        </div>
      </PromptFieldToolbar>
    </PromptField>
  );
}

Chat threads

Compose a conversation from Chat, Thread, ResponseStatus, and message components. The thread can be driven by a collection as messages arrive from your application.

import {Chat, Thread, ThreadItem, UserMessage, ResponseStatus, ResponseStatusTitle, ResponseStatusPanel, ExecutionTrace, ExecutionTraceItem} from '@react-spectrum/ai';
import {prose} from '@react-spectrum/ai/style' with {type: 'macro'};
import {style} from '@react-spectrum/s2/style' with {type: 'macro'};

let messages = [
  {id: 1, type: 'user', text: 'Summarize the campaign results.'},
  {
    id: 2,
    type: 'status',
    status: 'success' as const,
    text: 'Response complete',
    steps: [
      {id: 1, label: 'Fetching campaign', status: 'success' as const, detail: 'Loaded campaign details and fetched engagement results from the database.'},
      {id: 2, label: 'Summarizing results', status: 'success' as const, detail: 'Created a full channel report and summarized the results.'}
    ]
  },
  {
    id: 3,
    type: 'assistant',
    text: 'Engagement increased 18% this month, led by email and social. See the full report for a channel breakdown.',
    content: (
      <>
        Engagement increased <strong>18%</strong> this month, led by email and social. See the{' '}
        <a href="#">full report</a> for a channel breakdown.
      </>
    )
  },
  {id: 4, type: 'user', text: 'Which channel performed best?'},
  {
    id: 5,
    type: 'assistant',
    text: 'Email drove the most conversions, with social close behind: Email with 4,200 conversions, Social with 3,100 conversions.',
    content: (
      <>
        <p>Email drove the most conversions, with social close behind:</p>
        <ul>
          <li>Email: 4,200 conversions</li>
          <li>Social: 3,100 conversions</li>
        </ul>
      </>
    )
  }
];

function BasicChat() {
  return (
    <Chat
      styles={style({width: 'full'})}>
      <Thread
        items={messages}
        aria-label="Campaign discussion"
        styles={style({
          height: 350,
          overflowX: 'hidden',
          overflowY: 'auto',
          scrollPadding: 8
        })}>
        {message => {
          switch (message.type) {
            case 'user':
              return (
                <ThreadItem
                  textValue={message.text}
                  styles={style({display: 'flex', justifyContent: 'end'})}>
                  <UserMessage>{message.text}</UserMessage>
                </ThreadItem>
              );
            case 'assistant':
              return (
                <ThreadItem textValue={message.text}>
                  <div className={prose()}>{message.content}</div>
                </ThreadItem>
              );
            case 'status':
              return (
                <ThreadItem textValue={message.text}>
                  <ResponseStatus status={message.status}>
                    <ResponseStatusTitle>{message.text}</ResponseStatusTitle>
                    <ResponseStatusPanel>
                      <ExecutionTrace>
                        {message.steps?.map(step => (
                          <ExecutionTraceItem
                            key={step.id}
                            status={step.status}
                            detail={<p className={style({font: 'body-sm', margin: 0})}>{step.detail}</p>}>
                            {step.label}
                          </ExecutionTraceItem>
                        ))}
                      </ExecutionTrace>
                    </ResponseStatusPanel>
                  </ResponseStatus>
                </ThreadItem>
              );
          }
        }}
      </Thread>
    </Chat>
  );
}

API

<Chat>
  <Thread>
    <ThreadItem />
  </Thread>
  <ThreadScrollButton />
  <PromptField />
</Chat>

Chat

A Chat displays an accessible, streaming conversation between a user and an AI.

NameType
styles

Spectrum-defined styles, returned by the style() macro.

childrenReactNode

Children of the chat, such as Thread, PromptField, and ThreadScrollButton.

ThreadScrollButton

A ThreadScrollButton displays a button to scroll to the bottom of a Chat thread.

NameType
childrenReactNode

Thread

<Thread>
  <ThreadItem>
    <UserMessage /> or <ResponseStatus /> or <MessageSuggestionList /> or assistant content
    <MessageSource /> and/or <MessageFeedback />
  </ThreadItem>
  <ThreadLoadMoreItem />
</Thread>

A Thread shows a conversation within a Chat.

NameTypeDefault
stylesDefault:

Spectrum-defined styles, returned by the style() macro.

scrollEndThresholdnumberDefault: 100

The maximum distance in px from the bottom of the content for the viewport to be considered "near the end". While near the end, appended content and streaming size changes will keep the viewport pinned to the latest output.

childrenReactNode(item: T) => ReactNodeDefault:

The contents of the collection.

itemsIterable<T>Default:

Item objects in the collection.

ThreadItem

A ThreadItem displays an individual chat message.

NameType
styles

Spectrum-defined styles, returned by the style() macro.

isStreamingboolean

Whether or not the item's content is currently being streamed in.

shouldAnnounceOnMountboolean

Announce textValue on mount even when isStreaming is provided.

idKey

The unique id of the item.

textValuestring

A string representation of the item's contents, used for features like typeahead.

focusMode'child''row'

Whether the row or its first focusable child element should be focused when navigating to the row. Defaults to 'row'.

allowsArrowNavigationboolean

Whether the row should support arrow key navigation even when the containing collection uses tab keyboard navigation. Allows users to navigate between rows with arrow keys while focus is on an interactive child element within the row.

children<>

The children of the component. A function may be provided to alter the children based on component state.

Render PropCSS Selector
isFocusVisibleWithinCSS Selector: [data-focus-visible-within]
Whether the item's children have keyboard focus.
stateCSS Selector:
State of the grid list.
isHoveredCSS Selector: [data-hovered]
Whether the item is currently hovered with a mouse.
isPressedCSS Selector: [data-pressed]
Whether the item is currently in a pressed state.
isSelectedCSS Selector: [data-selected]
Whether the item is currently selected.
isFocusedCSS Selector: [data-focused]
Whether the item is currently focused.
isFocusVisibleCSS Selector: [data-focus-visible]
Whether the item is currently keyboard focused.
isDisabledCSS Selector: [data-disabled]
Whether the item is non-interactive, i.e. both selection and actions are disabled and the item may not be focused. Dependent on disabledKeys and disabledBehavior.
selectionModeCSS Selector: [data-selection-mode="single | multiple"]
The type of selection that is allowed in the collection.
selectionBehaviorCSS Selector:
The selection behavior for the collection.

ThreadLoadMoreItem

A ThreadLoadMoreItem loads more chat messages when it is scrolled into the viewport.

NameTypeDefault
childrenReactNodeDefault:

The load more spinner to render when loading additional items.

isLoadingbooleanDefault:

Whether or not the loading spinner should be rendered or not.

scrollOffsetnumberDefault: 1

The amount of offset from the bottom of your scrollable region that should trigger load more. Uses a percentage value relative to the scroll body's client height. Load more is then triggered when your current scroll position's distance from the bottom of the currently loaded list of items is less than or equal to the provided value. (e.g. 1 = 100% of the scroll region's height).

onLoadMore() => anyDefault:

Handler that is called when more items should be loaded, e.g. while scrolling near the bottom.

Default className: react-aria-GridListLoadingIndicator

UserMessage

UserMessage renders a single user-authored message in a conversational AI thread. Pass slot="image" on an Image child to switch to a vertical layout with a full-width preview.

NameType
childrenReactNode

The contents of the user message bubble.

styles

Spectrum-defined styles, returned by the style() macro.

ResponseStatus

<ResponseStatus>
  <ResponseStatusTitle />
  <ResponseStatusPanel>
    <ExecutionTrace>
      <ExecutionTraceItem />
    </ExecutionTrace>
  </ResponseStatusPanel>
</ResponseStatus>

A ResponseStatus indicates the progress of a system response while it is being generated and when it is complete. If a ResponseStatusPanel is provided, the title can be pressed to expand and collapse it.

NameTypeDefault
status'pending''failed''success'Default: 'pending'

The current status of the response.

childrenReactNodeDefault:

The contents of the response status, consisting of a ResponseStatusTitle and ResponseStatusPanel.

stylesDefault:

Spectrum-defined styles, returned by the style() macro.

idKeyDefault:

An id for the disclosure when used within a DisclosureGroup, matching the id used in expandedKeys.

isDisabledbooleanDefault:

Whether the disclosure is disabled.

isExpandedbooleanDefault:

Whether the disclosure is expanded (controlled).

defaultExpandedbooleanDefault:

Whether the disclosure is expanded by default (uncontrolled).

ResponseStatusTitle

A response status title consisting of a heading and a trigger button. The leading icon is a progress circle while loading and a chevron once complete and there is further content to display.

NameTypeDefault
levelnumberDefault: 3

The heading level of the response status header.

childrenReact.ReactNodeDefault:

The contents of the response status header.

stylesDefault:

Spectrum-defined styles, returned by the style() macro.

pixelLoader[][][]Default:

Pixel loader icon or sequence to display.

ResponseStatusPanel

A response status panel is a collapsible section of content that is hidden until the response status is expanded.

NameTypeDefault
childrenReact.ReactNodeDefault:
stylesDefault:

Spectrum-defined styles, returned by the style() macro.

labelElementTypeElementTypeDefault: 'label'

The HTML element used to render the label, e.g. 'label', or 'span'.

ExecutionTrace

An ExecutionTrace displays a timeline of the steps taken while generating a response, such as tool calls or searches.

NameType
childrenReactNode

The ExecutionTraceItem elements to render as a timeline. Typically placed inside a ResponseStatusPanel.

styles

Spectrum-defined styles, returned by the style() macro.

ExecutionTraceItem

An ExecutionTraceItem represents a single step within an ExecutionTrace, such as a tool call or search. When a detail is provided, the row can be expanded to reveal it.

NameTypeDefault
childrenReactNodeDefault:

The label describing the step.

status'pending''failed''success'Default:

The status of this step.

detailReactNodeDefault:

Additional detail revealed when the step is expanded, such as tool call input or output. If omitted, the row is static and cannot be expanded.

detailMaxHeightnumberDefault: 120

Maximum height for the detail panel.

iconReactNodeDefault:

An icon shown at the leading edge of the row. If omitted, a checkmark is rendered by default.

stylesDefault:

Spectrum-defined styles, returned by the style() macro.

Alert

An Alert shows an error message within a Chat thread or PromptField.

NameType
childrenReactNode
variant'informative''positive''notice''negative''neutral'
styles

MessageSuggestionList

<MessageSuggestionList>
  <MessageSuggestion />
</MessageSuggestionList>

MessageSuggestionList renders a group of suggestion responses with a title heading.

NameType
childrenReactNode

The MessageSuggestion children to display.

titlestring

Heading displayed above the suggestions.

size'S''M''L''XL'

The size of hte Buttons within the MessageSuggestionList.

styles

Spectrum-defined styles, returned by the style() macro.

MessageSuggestion

MessageSuggestion renders a single pressable suggestion in a conversation.

NameTypeDefault
childrenReactNodeDefault:

The text content of the suggestion.

size'S''M''L''XL'Default: 'M'

The size of the MessageSuggestion.

stylesDefault:

Spectrum-defined styles, returned by the style() macro.

MessageFeedback

MessageFeedback collects thumbs up / thumbs down feedback on an AI response.

NameTypeDefault
isDisabledbooleanDefault:

Whether the feedback controls are disabled.

thumbUpLabelstringDefault:

Accessible label for the thumbs up button.

thumbDownLabelstringDefault:

Accessible label for the thumbs down button.

stylesDefault:

Spectrum-defined styles, returned by the style() macro.

size'XS''S''M''L''XL'Default: 'M'

Size of the buttons.

valueDefault:

The selected feedback value (controlled).

defaultValueDefault:

The default feedback value (uncontrolled).

onChange(value: ) => voidDefault:

Called when the selection changes, including when toggled off (value=null).

MessageSource

<MessageSource>
  <SourceList>
    <SourceListItem />
  </SourceList>
</MessageSource>

Message sources display references associated with a system message. Associating the source to the output builds trust and transparency in the conversation.

NameTypeDefault
size'S''M''L''XL'Default: 'M'

The size of the disclosure.

density'compact''regular''spacious'Default: 'regular'

The amount of space between the disclosures.

childrenReactNodeDefault:

The contents of the disclosure, consisting of a DisclosureTitle and DisclosurePanel.

idKeyDefault:

An id for the disclosure when used within a DisclosureGroup, matching the id used in expandedKeys.

isDisabledbooleanDefault:

Whether the disclosure is disabled.

isExpandedbooleanDefault:

Whether the disclosure is expanded (controlled).

defaultExpandedbooleanDefault:

Whether the disclosure is expanded by default (uncontrolled).

stylesDefault:

Spectrum-defined styles, returned by the style() macro.

SourceList

A SourceList displays an ordered list of sources inside a MessageSource. Wrap SourceListItem children inside to have them numbered automatically.

NameTypeDefault
childrenReact.ReactNodeDefault:
labelElementTypeElementTypeDefault: 'label'

The HTML element used to render the label, e.g. 'label', or 'span'.

SourceListItem

A SourceListItem represents a single source within a SourceList. The item number is provided automatically by the parent SourceList.

NameType
childrenReact.ReactNode

The content of the source list item.

styles

Spectrum-defined styles, returned by the style() macro.

isDisabledboolean

Whether the link is disabled.

PromptField

<PromptField>
  <PromptFieldAttachmentList />
  <PromptTokenField />
  <PromptFieldToolbar />
</PromptField>

A PromptField allows users to compose and submit prompts containing text, tokens, and attachments.

NameTypeDefault
childrenReact.ReactNodeDefault:
acceptedAttachmentTypesstring[]Default:
attachments[]Default:
defaultAttachments[]Default:
isGeneratingbooleanDefault:
stylesDefault:
variant'balanced''prominent''subtle'Default: 'balanced'
brandColorstringDefault:
size'S''M'Default: 'M'

The size of the PromptField.

valueDefault:
defaultValueDefault:
onChange(value: ) => voidDefault:

PromptFieldAttachmentList

<PromptFieldAttachmentList>
  {attachment => (
    <Attachment>
      <AttachmentPreview />
    </Attachment>
  )}
</PromptFieldAttachmentList>

PromptFieldAttachmentList displays a list of file attachments within a PromptField.

NameType
styles

Spectrum-defined styles, returned by the style() macro.

children(attachment: ) => React.ReactNode
itemsIterable<>

Item objects in the collection.

dependenciesReadonlyArray<any>

Values that should invalidate the item cache when using dynamic collections.

disabledKeysIterable<Key>

The item keys that are disabled. These items cannot be selected, focused, or otherwise interacted with.

Attachment

Attachment displays an individual file attachment within a PromptFieldAttachmentList.

NameTypeDefault
childrenReactNode(renderProps: ) => ReactNodeDefault:

The children of the Attachment.

uploadProgressnumberDefault:
stylesDefault:

Spectrum-defined styles, returned by the style() macro.

size'XS''S''M''L''XL'Default: 'M'

The size of the Card.

density'compact''regular''spacious'Default: 'regular'

The amount of internal padding within the Card.

variant'primary''secondary''tertiary''quiet'Default: 'primary'

The visual style of the Card.

idKeyDefault:

The unique id of the item.

valueTDefault:

The object value that this item represents. When using dynamic collections, this is set automatically.

textValuestringDefault:

A string representation of the item's contents, used for features like typeahead.

isDisabledbooleanDefault:

Whether the item is disabled.

Render Prop
size
The size of the Card.

AttachmentPreview

AttachmentPreview renders a preview of a file attachment.

NameType
mimeTypestring
srcstring[]

The URL of the image or a list of conditional sources.

altstring

Accessible alt text for the image.

crossOrigin'anonymous''use-credentials'

Indicates if the fetching of the image must be done using a CORS request. See MDN.

decoding'async''auto''sync'

Whether the browser should decode images synchronously or asynchronously. See MDN.

fetchPriority'high''low''auto'

Provides a hint of the relative priority to use when fetching the image. See MDN.

loading'eager''lazy'

Whether the image should be loaded immediately or lazily when scrolled into view. See MDN.

widthnumber

The intrinsic width of the image. See MDN.

heightnumber

The intrinsic height of the image. See MDN.

styles

Spectrum-defined styles, returned by the style() macro.

renderError() => ReactNode

A function that is called to render a fallback when the image fails to load.

group

A group of images to coordinate between, matching the group passed to the <ImageCoordinator> component. If not provided, the default image group is used.

PromptTokenField

<PromptTokenField>
  {token => <PromptToken token={token} />}
</PromptTokenField>

PromptTokenField renders an editable text input for a prompt, and supports inserting inline object references as tokens via autocomplete.

NameType
completionTriggerRegExp
renderCompletions(filterValue: string, valueType: stringnull) => React.ReactNode[]nullPromise<React.ReactNode[]null>
children(segment: <>) => React.ReactElement
pixelLoader[][][]
shouldAnimatePixelLoaderboolean
placeholderstring

PromptToken

A PromptToken displays a non-editable inline object reference within a PromptTokenField.

NameType
token<>
childrenReact.ReactNode

Default className: react-aria-Token

Render PropCSS Selector
isSelectedCSS Selector: [data-selected]
Whether the token is selected.
isDisabledCSS Selector: [data-disabled]
Whether the token is disabled.

PromptFieldToolbar

<PromptFieldToolbar>
  <InsertMenuButton>
    <AttachFileMenuItem />
    <SubmenuTrigger>
      <InsertTextMenuItem /> or <InsertTokenMenuItem /> or <CommandMenuItem />
      <Menu />
    </SubmenuTrigger>
  </InsertMenuButton>
  <PromptFieldVoiceButton />
  <PromptFieldSubmitButton />
</PromptFieldToolbar>

PromptFieldToolbar contains action buttons related to the PromptField.

NameType
childrenReact.ReactNode

InsertMenuButton

InsertMenuButton renders an ActionButton with a plus icon that opens a menu.

NameType
childrenReact.ReactNode

AttachFileMenuItem

AttachFileMenuItem triggers a system file dialog to attach files within an InsertMenuButton.

NameType
idKey

The unique id of the item.

valueT

The object value that this item represents. When using dynamic collections, this is set automatically.

textValuestring

A string representation of the item's contents, used for features like typeahead.

isDisabledboolean

Whether the item is disabled.

styles

Spectrum-defined styles, returned by the style() macro.

InsertTextMenuItem

InsertTextMenuItem inserts plain text into the PromptField from within an InsertMenuButton.

NameType
textstring
childrenReactNode

The contents of the item.

idKey

The unique id of the item.

textValuestring

A string representation of the item's contents, used for features like typeahead.

isDisabledboolean

Whether the item is disabled.

styles

Spectrum-defined styles, returned by the style() macro.

InsertTokenMenuItem

InsertTokenMenuItem inserts a token (i.e. object reference) into the PromptField within an InsertMenuButton.

NameType
token<>
childrenReactNode

The contents of the item.

idKey

The unique id of the item.

textValuestring

A string representation of the item's contents, used for features like typeahead.

isDisabledboolean

Whether the item is disabled.

styles

Spectrum-defined styles, returned by the style() macro.

CommandMenuItem

CommandMenuItem performs an immediate action from within an InsertMenuButton.

NameType
childrenReactNode

The contents of the item.

idKey

The unique id of the item.

valueT

The object value that this item represents. When using dynamic collections, this is set automatically.

textValuestring

A string representation of the item's contents, used for features like typeahead.

isDisabledboolean

Whether the item is disabled.

styles

Spectrum-defined styles, returned by the style() macro.

PromptFieldVoiceButton

PromptFieldVoiceButton triggers voice input for the PromptField.

NameType
langstring
isDisabledboolean

PromptFieldSubmitButton

PromptFieldSubmitButton submits the PromptField.

NameType