feat: Updates to AI components for additional chat prompt use cases#10335
feat: Updates to AI components for additional chat prompt use cases#10335LFDanLu wants to merge 22 commits into
Conversation
other changes like gettring rid of the ToggleButtonGroup are deffered in favor of wrapping the group in a Toolbar
…arent using our prompt field
…ve a panel to display
…ursor positioning when token added via + menu also support escape /click on stop button to stop streaming in chat story
this allows a callback (aka like "compact") command to clear the user partial filter text and close the autocomplete menu in the field
| } from '../src/PromptField'; | ||
| export {ResponseStatus, ResponseStatusTitle, ResponseStatusPanel} from '../src/ResponseStatus'; | ||
| export {Chat, Thread, ThreadItem, ThreadScrollButton} from '../src/Chat'; | ||
| export {Chat, Thread, ThreadItem, ThreadScrollButton, PromptFocusContext} from '../src/Chat'; |
There was a problem hiding this comment.
exported in case a user don't use our PromptField with Chat. They will need to wire up the onFocusChange to their input field
There was a problem hiding this comment.
strings to be translated, open to discussion for copy
| borderRadius: 'default' | ||
| }); | ||
|
|
||
| const attachmentErrorStyles = style({ |
There was a problem hiding this comment.
The styles for invalid + thumbnail only aren't added yet, to be discussed with design
| // TODO: mirrors tokenfield, maybe should also be a generic too | ||
| value?: TokenSegmentList; | ||
| defaultValue?: TokenSegmentList; | ||
| onChange?: (value: TokenSegmentList) => void; | ||
| // TODO: discuss, I can imagine a case where we also want to prefill these | ||
| attachments?: PromptFieldAttachment[]; | ||
| defaultAttachments?: PromptFieldAttachment[]; | ||
| onAttachmentsChange?: (attachments: PromptFieldAttachment[]) => void; |
| if (text.length === 0) { | ||
| return [{type: 'text', text}]; | ||
| } | ||
| function tokenizeURLs(text: string): TokenFieldSegment[] { |
There was a problem hiding this comment.
change here looks significant but its just moving/extracting some logic since I had to update AutoLinkingSegmentList to auto convert urls into tokens if added programmatically via controlled value
| let [prompt, setPrompt] = useState<TokenSegmentList>(new AutoLinkingSegmentList([])); | ||
| let [attachments, setAttachments] = useState<PromptFieldAttachment[]>([]); | ||
| let stringFormatter = useLocalizedStringFormatter(intlMessages, '@react-spectrum/ai'); | ||
| let [prompt, setPrompt] = useControlledState( |
There was a problem hiding this comment.
as mentioned before, adds support for controlled value in the PromptField for things like "click this external button to pre-fill a common prompt into your field"
| children?: (segment: TokenSegment) => React.ReactElement; | ||
| pixelLoader?: Cell[] | Cell[][]; | ||
| placeholder?: string; | ||
| onKeyDown?: (e: React.KeyboardEvent<HTMLDivElement>) => void; |
There was a problem hiding this comment.
support for custom user defined keyboard commands (Opt + Enter for followup while streaming, arrow keys to autofil old prompts)
| setCursor(inputRef.current, position); | ||
| // TODO: double check this, claude debugged this one, but essentially reproduced with plain text insertion commands | ||
| // triggered one after another | ||
| // focus() fires a synchronous selectionchange before setCursor can set | ||
| // isProgrammaticSelectionChange, which resets caretPosition to {0,0} in | ||
| // TokenField's useSelectionChange handler. Re-assert the correct position. | ||
| setPrompt(value => value.withCaretPosition(position)); |
There was a problem hiding this comment.
as mentioned in the comment, seems to be a race here that caused inconsistent text cursor positioning when doing insertions via the "+" menu.
There was a problem hiding this comment.
interesting, we unset all the blocking and trapping when dialogs close, wonder why this was causing an issue with the cursor positioning
do you know what it was racing against? was it restore focus from the dialog to the trigger? or what was happening?
| /** | ||
| * Whether the response is still being generated. When true, a ProgressCircle replaces | ||
| * the chevron and the panel cannot be expanded. The trigger remains focusable. | ||
| * The current status of the response. |
There was a problem hiding this comment.
API change we'll have to call out
There was a problem hiding this comment.
based off what Coworker had, but refactored a bit since it didn't seem they actually needed some of the callbacks
There was a problem hiding this comment.
see https://webaudio.github.io/web-speech-api/ and https://developer.mozilla.org/en-US/docs/Web/API/SpeechRecognition, mostly generated by Claude but I did a spot check against the above
|
Build successful! 🎉 |
| <ProgressCircle | ||
| aria-label={stringFormatter.format('promptfield.uploading')} | ||
| value={props.uploadProgress} | ||
| size="S" |
There was a problem hiding this comment.
always? or is it just one size smaller than whatever is used for the rest of it?
There was a problem hiding this comment.
oh good question, that was always defined as "S" and I don't think I saw anything in Coworker that used a different size. I'll poke around, but probably should be one size smaller like you said
There was a problem hiding this comment.
ran into a snag, where the progress circle should be something like
const progressCircleSize = {
XS: 'S',
S: 'M',
M: 'M',
L: 'M',
XL: 'M'
} as const;
if the attachment is thumbnail only (based purely off my own local testing, no designs?), but then should be S if there is sibling text content. The hard part is how to set that properly based on sibling existence... I'm keeping it as S for simplicity for now but we can revisit
| export interface PromptFieldVoiceButtonProps { | ||
| lang?: string; | ||
| isDisabled?: boolean; | ||
| // TODO: coworker renders a toast too, but this gives more flexibility |
There was a problem hiding this comment.
coworker's experience renders a error toast on error that is baked in the component, but I figure we could just have a callback for flexibility in how the user would want to handle errors
| } | ||
| // similar to useInsertPromptSegment, calling programatic focus on the input causes the caret positioning | ||
| // to be inaccurate | ||
| let finalPrompt = buildVoicePrompt(basePromptRef.current, transcript); |
There was a problem hiding this comment.
no need for the ref, this is a useEffectEvent, so it's up to date
| let finalPrompt = buildVoicePrompt(basePromptRef.current, transcript); | |
| let finalPrompt = buildVoicePrompt(prompt, transcript); |
There was a problem hiding this comment.
so we actually don't want to use prompt here because it is up to date. transcript is the entire voice input string so if we keep appending it to the continuously up to date prompt it will result in the parts of the transcript being duplicated
| if (!transcript || !isVoiceListening) { | ||
| return; | ||
| } | ||
| setPrompt(buildVoicePrompt(basePromptRef.current, transcript)); |
There was a problem hiding this comment.
should the effect run whenever prompt changes? seems like we shouldn't use the ref here
otherwise, you could move buildVoicePrompt into the hook and make it a useEffectEvent and then it'll have access to the latest prompt
also, shouldn't call setState in the useEffect, I'm surprised you're not getting an error or warning about this
There was a problem hiding this comment.
updated logic a bit, see #10335 (comment) about the use of basePromptRef vs prompt. I'm opting to keep buildVoicePrompt outside the hook for now since it uses TokenSegmentList which is pretty specific to our token field
|
|
||
| return ( | ||
| <Heading {...domProps} level={level} ref={domRef} className={mergeStyles(headingStyle, styles)}> | ||
| {/* TODO: should this still be a button if the disclosure doesnt have a panel aka no content? |
There was a problem hiding this comment.
coworker has this in their storybook, I'm not 100% how to get it to happen in app tho
| {status === 'failed' ? ( | ||
| <CloseCircle aria-hidden="true" /> | ||
| ) : ( | ||
| // TODO: should this be a different color? This currently matches Coworker |
There was a problem hiding this comment.
design question, where it should be red vs black
| ? 'Type to steer (Enter) or queue a follow-up (Option+Enter) · Esc to stop' | ||
| : undefined | ||
| } | ||
| onKeyDown={e => { |
There was a problem hiding this comment.
this keydown is complicated, can we make this any easier for users?
do we want to use useKeyboard and new shortcuts so that the preventDefaults are handled for us, also probably missing some stop propagations
There was a problem hiding this comment.
I can definitely add useKeyboard into PromptTokenField so it processes the user's onKeyDown but any opinions on extending/changing the user facing API to allow them to specify the shortcuts? I guess shortcuts could be come a prop and its format would just match useKeyboard's expected format?
| forcedColors: 'ButtonFace' | ||
| }, | ||
| boxShadow: `[inset 0 0 0 1px light-dark(${color('transparent-black-300')}, ${color('transparent-white-300')})]`, | ||
| // TODO: for cards that only have images, should they have a red outline around the image thumbnail? |
There was a problem hiding this comment.
probably will have to have an icon as well for accessibility (otherwise it's a color only change...). design question
There was a problem hiding this comment.
yup, added to the canvas
| } | ||
| }); | ||
|
|
||
| let [isListening, setListening] = useState(false); |
There was a problem hiding this comment.
Does this state need to be in the top-level component or could it live in the microphone button?
There was a problem hiding this comment.
I actually use this to make the TokenField readonly while the voice input is happening so I had to place it top level. Coworker and Claude support typing in the field while voice input is transcribing, but it ends up replacing what you type/doing some strange behavior so I figured preventing user keyboard input was appropriate
| return base as AutoLinkingSegmentList; | ||
| } | ||
| let segments: TokenFieldSegment[] = [...base.segments, {type: 'text', text: voiceText}]; | ||
| return new AutoLinkingSegmentList(segments, { |
There was a problem hiding this comment.
Are we sure this should always append and not insert at the caret position? You should just be able to do base.replaceRange(base.caretPosition, base.caretPosition, voiceText) and it'll give you a new value with the text inserted.
| // specifically for menu items that only trigger a callback in the autocomplete menu | ||
| // since they dont end up inserting a token or text, we need to clear the partial text that the user used | ||
| // to filter the menu | ||
| export function InsertCallbackMenuItem(props: MenuItemProps) { |
There was a problem hiding this comment.
Interesting. Too bad this can't just be MenuItem... Maybe call it CommandMenuItem or something? This is a little confusing because it actually isn't inserting anything IMO.
|
|
||
| return ( | ||
| <TooltipTrigger> | ||
| <ToggleButton |
There was a problem hiding this comment.
IMO this should use staticColor="auto" like the other buttons. Also kinda weird that it's a square button right next to a round one but I guess we don't have a round toggle button...
| aria-label={label} | ||
| onPress={toggle}> | ||
| <Microphone /> | ||
| </ToggleButton> |
There was a problem hiding this comment.
Also should add some space between this button and the submit button. Maybe the toolbar needs a columnGap on it
There was a problem hiding this comment.
so I currently have this in the story:
</InsertMenuButton>
{/* TODO is this kind of styling expected from the user? Or should we have a slot that places the mic button next to the submit button? */}
<div style={{display: 'flex', gap: 4, alignItems: 'center'}}>
<PromptFieldVoiceButton />
<PromptFieldSubmitButton />
</div>
</PromptFieldToolbar>
in order to position the voice input button. I could perhaps update the toolbar to have slots or something but I figured it might be nice to just have the end user style the toolbar layout themselves
There was a problem hiding this comment.
ok that's fine for now. I would just increase the gap a little
update to Attachement/horizontal card to properly set aria-invalid and center the progress circle in the thumbnail. Also updates to PromptField to use useKeyboard, and voice input transcript state updates
|
Build successful! 🎉 |
## API Changes
react-aria-components/react-aria-components:GridListItem GridListItem <T> {
- allowsArrowNavigation?: boolean
children?: ChildrenOrFunction<GridListItemRenderProps>
className?: ClassNameOrFunction<GridListItemRenderProps> = 'react-aria-GridListItem'
download?: boolean | string
- focusMode?: 'child' | 'row'
href?: Href
hrefLang?: string
id?: Key
isDisabled?: boolean
onClick?: (MouseEvent<FocusableElement>) => void
onHoverChange?: (boolean) => void
onHoverEnd?: (HoverEvent) => void
onHoverStart?: (HoverEvent) => void
onPress?: (PressEvent) => void
onPressChange?: (boolean) => void
onPressEnd?: (PressEvent) => void
onPressStart?: (PressEvent) => void
onPressUp?: (PressEvent) => void
ping?: string
referrerPolicy?: HTMLAttributeReferrerPolicy
rel?: string
render?: DOMRenderFunction<keyof React.JSX.IntrinsicElements, GridListItemRenderProps>
routerOptions?: RouterOptions
style?: StyleOrFunction<GridListItemRenderProps>
target?: HTMLAttributeAnchorTarget
textValue?: string
value?: T
}/react-aria-components:Table Table {
aria-describedby?: string
aria-details?: string
aria-label?: string
aria-labelledby?: string
children?: ReactNode
className?: ClassNameOrFunction<TableRenderProps> = 'react-aria-Table'
defaultExpandedKeys?: Iterable<Key>
defaultSelectedKeys?: 'all' | Iterable<Key>
disabledBehavior?: DisabledBehavior = 'all'
disabledKeys?: Iterable<Key>
disallowEmptySelection?: boolean
dragAndDropHooks?: DragAndDropHooks
escapeKeyBehavior?: 'clearSelection' | 'none' = 'clearSelection'
expandedKeys?: Iterable<Key>
- keyboardNavigationBehavior?: 'arrow' | 'tab' = 'arrow'
onExpandedChange?: (Set<Key>) => any
onRowAction?: (Key) => void
onSelectionChange?: (Selection) => void
onSortChange?: (SortDescriptor) => any
selectedKeys?: 'all' | Iterable<Key>
selectionBehavior?: SelectionBehavior = 'toggle'
selectionMode?: SelectionMode
shouldSelectOnPressUp?: boolean
slot?: string | null
sortDescriptor?: SortDescriptor
style?: StyleOrFunction<TableRenderProps>
treeColumn?: Key
}/react-aria-components:Cell Cell {
- allowsArrowNavigation?: boolean
children?: ChildrenOrFunction<CellRenderProps>
className?: ClassNameOrFunction<CellRenderProps> = 'react-aria-Cell'
colSpan?: number
- focusMode?: 'child' | 'cell'
id?: Key
render?: DOMRenderFunction<keyof React.JSX.IntrinsicElements, CellRenderProps>
style?: StyleOrFunction<CellRenderProps>
textValue?: string/react-aria-components:Column Column {
- allowsArrowNavigation?: boolean
allowsSorting?: boolean
children?: ChildrenOrFunction<ColumnRenderProps>
className?: ClassNameOrFunction<ColumnRenderProps> = 'react-aria-Column'
defaultWidth?: ColumnSize | null
- focusMode?: 'child' | 'cell'
id?: Key
isRowHeader?: boolean
maxWidth?: ColumnStaticSize | null
minWidth?: ColumnStaticSize | null
style?: StyleOrFunction<ColumnRenderProps>
textValue?: string
width?: ColumnSize | null
}/react-aria-components:TreeItem TreeItem <T extends any> {
- allowsArrowNavigation?: boolean
aria-label?: string
children: ReactNode
className?: ClassNameOrFunction<TreeItemRenderProps> = 'react-aria-TreeItem'
download?: boolean | string
- focusMode?: 'child' | 'row' = 'row'
hasChildItems?: boolean
href?: Href
hrefLang?: string
id?: Key
onAction?: () => void
onClick?: (MouseEvent<FocusableElement>) => void
onHoverChange?: (boolean) => void
onHoverEnd?: (HoverEvent) => void
onHoverStart?: (HoverEvent) => void
onPress?: (PressEvent) => void
onPressChange?: (boolean) => void
onPressEnd?: (PressEvent) => void
onPressStart?: (PressEvent) => void
onPressUp?: (PressEvent) => void
ping?: string
referrerPolicy?: HTMLAttributeReferrerPolicy
rel?: string
render?: DOMRenderFunction<keyof React.JSX.IntrinsicElements, TreeItemRenderProps>
routerOptions?: RouterOptions
style?: StyleOrFunction<TreeItemRenderProps>
target?: HTMLAttributeAnchorTarget
textValue: string
value?: any
}/react-aria-components:GridListItemProps GridListItemProps <T = {}> {
- allowsArrowNavigation?: boolean
children?: ChildrenOrFunction<GridListItemRenderProps>
className?: ClassNameOrFunction<GridListItemRenderProps> = 'react-aria-GridListItem'
download?: boolean | string
- focusMode?: 'child' | 'row'
href?: Href
hrefLang?: string
id?: Key
isDisabled?: boolean
onClick?: (MouseEvent<FocusableElement>) => void
onHoverChange?: (boolean) => void
onHoverEnd?: (HoverEvent) => void
onHoverStart?: (HoverEvent) => void
onPress?: (PressEvent) => void
onPressChange?: (boolean) => void
onPressEnd?: (PressEvent) => void
onPressStart?: (PressEvent) => void
onPressUp?: (PressEvent) => void
ping?: string
referrerPolicy?: HTMLAttributeReferrerPolicy
rel?: string
render?: DOMRenderFunction<keyof React.JSX.IntrinsicElements, GridListItemRenderProps>
routerOptions?: RouterOptions
style?: StyleOrFunction<GridListItemRenderProps>
target?: HTMLAttributeAnchorTarget
textValue?: string
value?: T
}/react-aria-components:TableProps TableProps {
aria-describedby?: string
aria-details?: string
aria-label?: string
aria-labelledby?: string
children?: ReactNode
className?: ClassNameOrFunction<TableRenderProps> = 'react-aria-Table'
defaultExpandedKeys?: Iterable<Key>
defaultSelectedKeys?: 'all' | Iterable<Key>
disabledBehavior?: DisabledBehavior = 'all'
disabledKeys?: Iterable<Key>
disallowEmptySelection?: boolean
dragAndDropHooks?: DragAndDropHooks
escapeKeyBehavior?: 'clearSelection' | 'none' = 'clearSelection'
expandedKeys?: Iterable<Key>
- keyboardNavigationBehavior?: 'arrow' | 'tab' = 'arrow'
onExpandedChange?: (Set<Key>) => any
onRowAction?: (Key) => void
onSelectionChange?: (Selection) => void
onSortChange?: (SortDescriptor) => any
selectedKeys?: 'all' | Iterable<Key>
selectionBehavior?: SelectionBehavior = 'toggle'
selectionMode?: SelectionMode
shouldSelectOnPressUp?: boolean
slot?: string | null
sortDescriptor?: SortDescriptor
style?: StyleOrFunction<TableRenderProps>
treeColumn?: Key
}/react-aria-components:ColumnProps ColumnProps {
- allowsArrowNavigation?: boolean
allowsSorting?: boolean
children?: ChildrenOrFunction<ColumnRenderProps>
className?: ClassNameOrFunction<ColumnRenderProps> = 'react-aria-Column'
defaultWidth?: ColumnSize | null
- focusMode?: 'child' | 'cell'
id?: Key
isRowHeader?: boolean
maxWidth?: ColumnStaticSize | null
minWidth?: ColumnStaticSize | null
style?: StyleOrFunction<ColumnRenderProps>
textValue?: string
width?: ColumnSize | null
}/react-aria-components:CellProps CellProps {
- allowsArrowNavigation?: boolean
children?: ChildrenOrFunction<CellRenderProps>
className?: ClassNameOrFunction<CellRenderProps> = 'react-aria-Cell'
colSpan?: number
- focusMode?: 'child' | 'cell'
id?: Key
render?: DOMRenderFunction<keyof React.JSX.IntrinsicElements, CellRenderProps>
style?: StyleOrFunction<CellRenderProps>
textValue?: string/react-aria-components:TreeItemProps TreeItemProps <T = {}> {
- allowsArrowNavigation?: boolean
aria-label?: string
children: ReactNode
className?: ClassNameOrFunction<TreeItemRenderProps> = 'react-aria-TreeItem'
download?: boolean | string
- focusMode?: 'child' | 'row' = 'row'
hasChildItems?: boolean
href?: Href
hrefLang?: string
id?: Key
onAction?: () => void
onClick?: (MouseEvent<FocusableElement>) => void
onHoverChange?: (boolean) => void
onHoverEnd?: (HoverEvent) => void
onHoverStart?: (HoverEvent) => void
onPress?: (PressEvent) => void
onPressChange?: (boolean) => void
onPressEnd?: (PressEvent) => void
onPressStart?: (PressEvent) => void
onPressUp?: (PressEvent) => void
ping?: string
referrerPolicy?: HTMLAttributeReferrerPolicy
rel?: string
render?: DOMRenderFunction<keyof React.JSX.IntrinsicElements, TreeItemRenderProps>
routerOptions?: RouterOptions
style?: StyleOrFunction<TreeItemRenderProps>
target?: HTMLAttributeAnchorTarget
textValue: string
value?: T
}@react-aria/grid/@react-aria/grid:GridProps GridProps {
aria-describedby?: string
aria-details?: string
aria-label?: string
aria-labelledby?: string
disallowTypeAhead?: boolean = false
escapeKeyBehavior?: 'clearSelection' | 'none' = 'clearSelection'
focusMode?: 'row' | 'cell' = 'row'
getRowText?: (Key) => string = (key) => state.collection.getItem(key)?.textValue
id?: string
isVirtualized?: boolean
keyboardDelegate?: KeyboardDelegate
- keyboardNavigationBehavior?: 'arrow' | 'tab' = 'arrow'
onCellAction?: (Key) => void
onRowAction?: (Key) => void
scrollRef?: RefObject<HTMLElement | null>
shouldSelectOnPressUp?: boolean/@react-aria/grid:GridCellProps GridCellProps {
- allowsArrowNavigation?: boolean
colSpan?: number
focusMode?: 'child' | 'cell'
isVirtualized?: boolean
node: GridNode<unknown>
}@react-aria/gridlist/@react-aria/gridlist:AriaGridListItemOptions AriaGridListItemOptions {
- allowsArrowNavigation?: boolean
- focusMode?: 'child' | 'row' = 'row'
hasChildItems?: boolean
isVirtualized?: boolean
node: Node<unknown>
shouldSelectOnPressUp?: boolean@react-aria/table/@react-aria/table:AriaTableProps AriaTableProps {
aria-describedby?: string
aria-details?: string
aria-label?: string
aria-labelledby?: string
disallowTypeAhead?: boolean = false
escapeKeyBehavior?: 'clearSelection' | 'none' = 'clearSelection'
focusMode?: 'row' | 'cell' = 'row'
getRowText?: (Key) => string = (key) => state.collection.getItem(key)?.textValue
id?: string
isVirtualized?: boolean
keyboardDelegate?: KeyboardDelegate
- keyboardNavigationBehavior?: 'arrow' | 'tab' = 'arrow'
layoutDelegate?: LayoutDelegate
onCellAction?: (Key) => void
onRowAction?: (Key) => void
scrollRef?: RefObject<HTMLElement | null>
}/@react-aria/table:AriaTableColumnHeaderProps AriaTableColumnHeaderProps <T> {
- allowsArrowNavigation?: boolean
- focusMode?: 'child' | 'cell'
isVirtualized?: boolean
node: GridNode<T>
}/@react-aria/table:AriaTableCellProps AriaTableCellProps {
- allowsArrowNavigation?: boolean
- focusMode?: 'child' | 'cell'
isVirtualized?: boolean
node: GridNode<unknown>
shouldSelectOnPressUp?: boolean
}@react-aria/tree/@react-aria/tree:AriaTreeItemOptions AriaTreeItemOptions {
- allowsArrowNavigation?: boolean
- focusMode?: 'child' | 'row' = 'row'
hasChildItems?: boolean
node: Node<unknown>
shouldSelectOnPressUp?: boolean
}@react-spectrum/ai/@react-spectrum/ai:Attachment Attachment {
- allowsArrowNavigation?: boolean
aria-describedby?: string
aria-details?: string
aria-label?: string
aria-labelledby?: string
children: ReactNode | (AttachmentRenderProps) => ReactNode
density?: 'compact' | 'regular' | 'spacious' = 'regular'
download?: boolean | string
- focusMode?: 'child' | 'row'
href?: Href
hrefLang?: string
id?: Key
isDisabled?: boolean
+ isInvalid?: boolean
onAction?: () => void
onPress?: (PressEvent) => void
onPressChange?: (boolean) => void
onPressEnd?: (PressEvent) => void
onPressUp?: (PressEvent) => void
ping?: string
referrerPolicy?: HTMLAttributeReferrerPolicy
rel?: string
render?: DOMRenderFunction<keyof React.JSX.IntrinsicElements, TagRenderProps>
routerOptions?: RouterOptions
size?: 'XS' | 'S' | 'M' | 'L' | 'XL' = 'M'
styles?: StyleString
target?: HTMLAttributeAnchorTarget
textValue?: string
uploadProgress?: number
value?: T
variant?: 'primary' | 'secondary' | 'tertiary' | 'quiet' = 'primary'
}/@react-spectrum/ai:MessageFeedback MessageFeedback {
aria-describedby?: string
aria-details?: string
aria-label?: string
aria-labelledby?: string
defaultValue?: MessageFeedbackValue
id?: string
isDisabled?: boolean
onChange?: (MessageFeedbackValue) => void
+ size?: 'XS' | 'S' | 'M' | 'L' | 'XL' = 'M'
slot?: string | null
styles?: StylesPropWithHeight
thumbDownLabel?: string
thumbUpLabel?: string
}/@react-spectrum/ai:PromptField PromptField {
acceptedAttachmentTypes?: Array<string>
+ attachments?: Array<PromptFieldAttachment>
children: React.ReactNode
+ defaultAttachments?: Array<PromptFieldAttachment>
+ defaultValue?: TokenSegmentList
isGenerating?: boolean
onAddAttachments?: (Array<PromptFieldAttachment>) => void
+ onAttachmentsChange?: (Array<PromptFieldAttachment>) => void
+ onChange?: (TokenSegmentList) => void
onRemoveAttachments?: (Array<PromptFieldAttachment>) => void
onStop?: () => void
onSubmit?: (TokenSegmentList, Array<PromptFieldAttachment>) => void
styles?: StyleString
+ value?: TokenSegmentList
variant?: 'balanced' | 'prominent' | 'subtle'
}/@react-spectrum/ai:PromptTokenField PromptTokenField {
children?: (TokenSegment) => React.ReactElement
completionTrigger?: RegExp
+ onKeyDown?: (React.KeyboardEvent<HTMLDivElement>) => void
pixelLoader?: Array<Cell> | Array<Array<Cell>>
placeholder?: string
renderCompletions?: (string) => Array<React.ReactNode> | null | Promise<Array<React.ReactNode> | null>
}/@react-spectrum/ai:ResponseStatus ResponseStatus {
children: ReactNode
defaultExpanded?: boolean
density?: 'compact' | 'regular' | 'spacious' = 'regular'
id?: Key
isDisabled?: boolean
isExpanded?: boolean
- isLoading?: boolean
onExpandedChange?: (boolean) => void
size?: 'S' | 'M' | 'L' | 'XL' = 'M'
slot?: string | null
+ status?: 'loading' | 'failed' | 'success' = 'loading'
styles?: StyleString
}/@react-spectrum/ai:ThreadItem ThreadItem {
- allowsArrowNavigation?: boolean
children?: ChildrenOrFunction<GridListItemRenderProps>
- focusMode?: 'child' | 'row'
+ id?: Key
isStreaming?: boolean
shouldAnnounceOnMount?: boolean
styles?: StyleString
textValue?: string/@react-spectrum/ai:AttachmentProps AttachmentProps {
- allowsArrowNavigation?: boolean
aria-describedby?: string
aria-details?: string
aria-label?: string
aria-labelledby?: string
children: ReactNode | (AttachmentRenderProps) => ReactNode
density?: 'compact' | 'regular' | 'spacious' = 'regular'
download?: boolean | string
- focusMode?: 'child' | 'row'
href?: Href
hrefLang?: string
id?: Key
isDisabled?: boolean
+ isInvalid?: boolean
onAction?: () => void
onPress?: (PressEvent) => void
onPressChange?: (boolean) => void
onPressEnd?: (PressEvent) => void
onPressUp?: (PressEvent) => void
ping?: string
referrerPolicy?: HTMLAttributeReferrerPolicy
rel?: string
render?: DOMRenderFunction<keyof React.JSX.IntrinsicElements, TagRenderProps>
routerOptions?: RouterOptions
size?: 'XS' | 'S' | 'M' | 'L' | 'XL' = 'M'
styles?: StyleString
target?: HTMLAttributeAnchorTarget
textValue?: string
uploadProgress?: number
value?: T
variant?: 'primary' | 'secondary' | 'tertiary' | 'quiet' = 'primary'
}/@react-spectrum/ai:PromptFieldProps PromptFieldProps {
acceptedAttachmentTypes?: Array<string>
+ attachments?: Array<PromptFieldAttachment>
children: React.ReactNode
+ defaultAttachments?: Array<PromptFieldAttachment>
+ defaultValue?: TokenSegmentList
isGenerating?: boolean
onAddAttachments?: (Array<PromptFieldAttachment>) => void
+ onAttachmentsChange?: (Array<PromptFieldAttachment>) => void
+ onChange?: (TokenSegmentList) => void
onRemoveAttachments?: (Array<PromptFieldAttachment>) => void
onStop?: () => void
onSubmit?: (TokenSegmentList, Array<PromptFieldAttachment>) => void
styles?: StyleString
+ value?: TokenSegmentList
variant?: 'balanced' | 'prominent' | 'subtle'
}/@react-spectrum/ai:PromptTokenFieldProps PromptTokenFieldProps {
children?: (TokenSegment) => React.ReactElement
completionTrigger?: RegExp
+ onKeyDown?: (React.KeyboardEvent<HTMLDivElement>) => void
pixelLoader?: Array<Cell> | Array<Array<Cell>>
placeholder?: string
renderCompletions?: (string) => Array<React.ReactNode> | null | Promise<Array<React.ReactNode> | null>
}/@react-spectrum/ai:MessageFeedbackProps MessageFeedbackProps {
aria-describedby?: string
aria-details?: string
aria-label?: string
aria-labelledby?: string
defaultValue?: MessageFeedbackValue
id?: string
isDisabled?: boolean
onChange?: (MessageFeedbackValue) => void
+ size?: 'XS' | 'S' | 'M' | 'L' | 'XL' = 'M'
slot?: string | null
styles?: StylesPropWithHeight
thumbDownLabel?: string
thumbUpLabel?: string
}/@react-spectrum/ai:ResponseStatusProps ResponseStatusProps {
children: ReactNode
defaultExpanded?: boolean
density?: 'compact' | 'regular' | 'spacious' = 'regular'
id?: Key
isDisabled?: boolean
isExpanded?: boolean
- isLoading?: boolean
onExpandedChange?: (boolean) => void
size?: 'S' | 'M' | 'L' | 'XL' = 'M'
slot?: string | null
+ status?: 'loading' | 'failed' | 'success' = 'loading'
styles?: StyleString
}/@react-spectrum/ai:ThreadItemProps ThreadItemProps {
- allowsArrowNavigation?: boolean
children?: ChildrenOrFunction<GridListItemRenderProps>
- focusMode?: 'child' | 'row'
+ id?: Key
isStreaming?: boolean
shouldAnnounceOnMount?: boolean
styles?: StyleString
textValue?: string/@react-spectrum/ai:AutoLinkingSegmentList+AutoLinkingSegmentList {
+ caretPosition: Position
+ constructor: (readonly Array<TokenFieldSegment>, TokenSegmentListOptions) => void
+ delete: (Position, Intl.Segmenter, any, any) => this
+ deleteLine: (Position, any, any) => this
+ endCoalescing: () => void
+ findBoundaryWithSegmenter: (Position, Intl.Segmenter, any) => Position | null
+ findLineBoundary: (Position, any) => Position | null
+ findText: (Position, any, string | RegExp) => Position | null
+ redo: () => this
+ replaceRange: (Position, Position, string, any) => this
+ replaceRangeWithSegments: (Position, Position, Array<TokenFieldSegment<T>>, any) => this
+ segments: readonly Array<TokenFieldSegment<T>>
+ slice: (Position, Position) => this
+ toString: () => string
+ tokenize: (string) => Array<TokenFieldSegment>
+ undo: () => this
+ withCaretPosition: (Position) => this
+}/@react-spectrum/ai:CommandMenuItem+CommandMenuItem {
+ UNSAFE_className?: UnsafeClassName
+ UNSAFE_style?: CSSProperties
+ aria-label?: string
+ children: ReactNode
+ download?: boolean | string
+ href?: Href
+ hrefLang?: string
+ id?: Key
+ isDisabled?: boolean
+ onAction?: () => void
+ onBlur?: (FocusEvent<Target>) => void
+ onFocus?: (FocusEvent<Target>) => void
+ onFocusChange?: (boolean) => void
+ onHoverChange?: (boolean) => void
+ onHoverEnd?: (HoverEvent) => void
+ onHoverStart?: (HoverEvent) => void
+ onPress?: (PressEvent) => void
+ onPressChange?: (boolean) => void
+ onPressEnd?: (PressEvent) => void
+ onPressStart?: (PressEvent) => void
+ onPressUp?: (PressEvent) => void
+ ping?: string
+ referrerPolicy?: HTMLAttributeReferrerPolicy
+ rel?: string
+ routerOptions?: RouterOptions
+ shouldCloseOnSelect?: boolean
+ styles?: StylesProp
+ target?: HTMLAttributeAnchorTarget
+ textValue?: string
+ value?: T
+}/@react-spectrum/ai:InsertTextMenuItem+InsertTextMenuItem {
+ UNSAFE_className?: UnsafeClassName
+ UNSAFE_style?: CSSProperties
+ aria-label?: string
+ children: ReactNode
+ download?: boolean | string
+ href?: Href
+ hrefLang?: string
+ id?: Key
+ isDisabled?: boolean
+ onAction?: () => void
+ onBlur?: (FocusEvent<Target>) => void
+ onFocus?: (FocusEvent<Target>) => void
+ onFocusChange?: (boolean) => void
+ onHoverChange?: (boolean) => void
+ onHoverEnd?: (HoverEvent) => void
+ onHoverStart?: (HoverEvent) => void
+ onPress?: (PressEvent) => void
+ onPressChange?: (boolean) => void
+ onPressEnd?: (PressEvent) => void
+ onPressStart?: (PressEvent) => void
+ onPressUp?: (PressEvent) => void
+ ping?: string
+ referrerPolicy?: HTMLAttributeReferrerPolicy
+ rel?: string
+ routerOptions?: RouterOptions
+ shouldCloseOnSelect?: boolean
+ styles?: StylesProp
+ target?: HTMLAttributeAnchorTarget
+ textValue?: string
+ value?: T
+}/@react-spectrum/ai:PromptFocusContext+PromptFocusContext {
+ UNTYPED
+}/@react-spectrum/ai:PromptFocusContextValue+PromptFocusContextValue {
+ onFocusChange: (boolean) => void
+}@react-spectrum/s2/@react-spectrum/s2:Card Card {
UNSAFE_className?: UnsafeClassName
UNSAFE_style?: CSSProperties
- allowsArrowNavigation?: boolean
children: ReactNode | (CardRenderProps) => ReactNode
density?: 'compact' | 'regular' | 'spacious' = 'regular'
download?: boolean | string
- focusMode?: 'child' | 'row'
href?: Href
hrefLang?: string
id?: Key
isDisabled?: boolean
onPress?: (PressEvent) => void
onPressChange?: (boolean) => void
onPressEnd?: (PressEvent) => void
onPressStart?: (PressEvent) => void
onPressUp?: (PressEvent) => void
ping?: string
referrerPolicy?: HTMLAttributeReferrerPolicy
rel?: string
routerOptions?: RouterOptions
size?: 'XS' | 'S' | 'M' | 'L' | 'XL' = 'M'
styles?: StylesProp
target?: HTMLAttributeAnchorTarget
textValue?: string
value?: T
variant?: 'primary' | 'secondary' | 'tertiary' | 'quiet' = 'primary'
}/@react-spectrum/s2:AssetCard AssetCard {
UNSAFE_className?: UnsafeClassName
UNSAFE_style?: CSSProperties
- allowsArrowNavigation?: boolean
children: ReactNode | (CardRenderProps) => ReactNode
download?: boolean | string
- focusMode?: 'child' | 'row'
href?: Href
hrefLang?: string
id?: Key
isDisabled?: boolean
onPress?: (PressEvent) => void
onPressChange?: (boolean) => void
onPressEnd?: (PressEvent) => void
onPressStart?: (PressEvent) => void
onPressUp?: (PressEvent) => void
ping?: string
referrerPolicy?: HTMLAttributeReferrerPolicy
rel?: string
routerOptions?: RouterOptions
size?: 'XS' | 'S' | 'M' | 'L' | 'XL' = 'M'
styles?: StylesProp
target?: HTMLAttributeAnchorTarget
textValue?: string
value?: T
variant?: 'primary' | 'secondary' | 'tertiary' | 'quiet' = 'primary'
}/@react-spectrum/s2:UserCard UserCard {
UNSAFE_className?: UnsafeClassName
UNSAFE_style?: CSSProperties
- allowsArrowNavigation?: boolean
children: ReactNode | (CardRenderProps) => ReactNode
download?: boolean | string
- focusMode?: 'child' | 'row'
href?: Href
hrefLang?: string
id?: Key
isDisabled?: boolean
onPress?: (PressEvent) => void
onPressChange?: (boolean) => void
onPressEnd?: (PressEvent) => void
onPressStart?: (PressEvent) => void
onPressUp?: (PressEvent) => void
ping?: string
referrerPolicy?: HTMLAttributeReferrerPolicy
rel?: string
routerOptions?: RouterOptions
size?: 'XS' | 'S' | 'M' | 'L' | 'XL' = 'M'
styles?: StylesProp
target?: HTMLAttributeAnchorTarget
textValue?: string
value?: T
variant?: 'primary' | 'secondary' | 'tertiary'
}/@react-spectrum/s2:ProductCard ProductCard {
UNSAFE_className?: UnsafeClassName
UNSAFE_style?: CSSProperties
- allowsArrowNavigation?: boolean
children: ReactNode | (CardRenderProps) => ReactNode
download?: boolean | string
- focusMode?: 'child' | 'row'
href?: Href
hrefLang?: string
id?: Key
isDisabled?: boolean
onPress?: (PressEvent) => void
onPressChange?: (boolean) => void
onPressEnd?: (PressEvent) => void
onPressStart?: (PressEvent) => void
onPressUp?: (PressEvent) => void
ping?: string
referrerPolicy?: HTMLAttributeReferrerPolicy
rel?: string
routerOptions?: RouterOptions
size?: 'XS' | 'S' | 'M' | 'L' | 'XL' = 'M'
styles?: StylesProp
target?: HTMLAttributeAnchorTarget
textValue?: string
value?: T
variant?: 'primary' | 'secondary' | 'tertiary'
}/@react-spectrum/s2:ListViewItem ListViewItem {
- allowsArrowNavigation?: boolean
children: ReactNode
download?: boolean | string
- focusMode?: 'child' | 'row'
hasChildItems?: boolean
href?: Href
hrefLang?: string
id?: Key
onAction?: () => void
onHoverChange?: (boolean) => void
onHoverEnd?: (HoverEvent) => void
onHoverStart?: (HoverEvent) => void
onPress?: (PressEvent) => void
onPressChange?: (boolean) => void
onPressEnd?: (PressEvent) => void
onPressStart?: (PressEvent) => void
onPressUp?: (PressEvent) => void
ping?: string
referrerPolicy?: HTMLAttributeReferrerPolicy
rel?: string
routerOptions?: RouterOptions
target?: HTMLAttributeAnchorTarget
textValue?: string
value?: T
}/@react-spectrum/s2:TableView TableView {
UNSAFE_className?: UnsafeClassName
UNSAFE_style?: CSSProperties
aria-describedby?: string
aria-details?: string
aria-label?: string
aria-labelledby?: string
children?: ReactNode
defaultExpandedKeys?: Iterable<Key>
defaultSelectedKeys?: 'all' | Iterable<Key>
density?: 'compact' | 'spacious' | 'regular' = 'regular'
disabledBehavior?: DisabledBehavior = 'all'
disabledKeys?: Iterable<Key>
disallowEmptySelection?: boolean
dragAndDropHooks?: DragAndDropHooks
escapeKeyBehavior?: 'clearSelection' | 'none' = 'clearSelection'
expandedKeys?: Iterable<Key>
id?: string
isQuiet?: boolean
- keyboardNavigationBehavior?: 'arrow' | 'tab' = 'arrow'
loadingState?: LoadingState
onAction?: (Key) => void
onExpandedChange?: (Set<Key>) => any
onLoadMore?: () => any
onResizeEnd?: (Map<Key, ColumnSize>) => void
onResizeStart?: (Map<Key, ColumnSize>) => void
onSelectionChange?: (Selection) => void
onSortChange?: (SortDescriptor) => any
overflowMode?: 'wrap' | 'truncate' = 'truncate'
renderActionBar?: ('all' | Set<Key>) => ReactElement
selectedKeys?: 'all' | Iterable<Key>
selectionMode?: SelectionMode
selectionStyle?: 'checkbox' | 'highlight' = 'checkbox'
shouldSelectOnPressUp?: boolean
slot?: string | null
sortDescriptor?: SortDescriptor
styles?: StylesPropWithHeight
treeColumn?: Key
}/@react-spectrum/s2:Cell Cell {
align?: 'start' | 'center' | 'end' = 'start'
- allowsArrowNavigation?: boolean
children: ReactNode
colSpan?: number
- focusMode?: 'child' | 'cell'
id?: Key
showDivider?: boolean
textValue?: string
}/@react-spectrum/s2:Column Column {
align?: 'start' | 'center' | 'end' = 'start'
- allowsArrowNavigation?: boolean
allowsResizing?: boolean
allowsSorting?: boolean
children: ReactNode
defaultWidth?: ColumnSize | null
- focusMode?: 'child' | 'cell'
id?: Key
isRowHeader?: boolean
maxWidth?: ColumnStaticSize | null
menuItems?: ReactNode
showDivider?: boolean
textValue?: string
width?: ColumnSize | null
}/@react-spectrum/s2:EditableCell EditableCell {
action?: string | FormHTMLAttributes<HTMLFormElement>['action']
align?: 'start' | 'center' | 'end' = 'start'
- allowsArrowNavigation?: boolean
children: ReactNode
colSpan?: number
- focusMode?: 'child' | 'cell'
id?: Key
isSaving?: boolean
onCancel?: () => void
onSubmit?: (FormEvent<HTMLFormElement>) => void
showDivider?: boolean
textValue?: string
}/@react-spectrum/s2:TreeViewItem TreeViewItem {
- allowsArrowNavigation?: boolean
aria-label?: string
children: ReactNode
download?: boolean | string
- focusMode?: 'child' | 'row' = 'row'
hasChildItems?: boolean
href?: Href
hrefLang?: string
id?: Key
onAction?: () => void
onHoverChange?: (boolean) => void
onHoverEnd?: (HoverEvent) => void
onHoverStart?: (HoverEvent) => void
onPress?: (PressEvent) => void
onPressChange?: (boolean) => void
onPressEnd?: (PressEvent) => void
onPressStart?: (PressEvent) => void
onPressUp?: (PressEvent) => void
ping?: string
referrerPolicy?: HTMLAttributeReferrerPolicy
rel?: string
routerOptions?: RouterOptions
target?: HTMLAttributeAnchorTarget
textValue: string
value?: T
}/@react-spectrum/s2:CardProps CardProps {
UNSAFE_className?: UnsafeClassName
UNSAFE_style?: CSSProperties
- allowsArrowNavigation?: boolean
children: ReactNode | (CardRenderProps) => ReactNode
density?: 'compact' | 'regular' | 'spacious' = 'regular'
download?: boolean | string
- focusMode?: 'child' | 'row'
href?: Href
hrefLang?: string
id?: Key
isDisabled?: boolean
onPress?: (PressEvent) => void
onPressChange?: (boolean) => void
onPressEnd?: (PressEvent) => void
onPressStart?: (PressEvent) => void
onPressUp?: (PressEvent) => void
ping?: string
referrerPolicy?: HTMLAttributeReferrerPolicy
rel?: string
routerOptions?: RouterOptions
size?: 'XS' | 'S' | 'M' | 'L' | 'XL' = 'M'
styles?: StylesProp
target?: HTMLAttributeAnchorTarget
textValue?: string
value?: T
variant?: 'primary' | 'secondary' | 'tertiary' | 'quiet' = 'primary'
}/@react-spectrum/s2:AssetCardProps AssetCardProps {
UNSAFE_className?: UnsafeClassName
UNSAFE_style?: CSSProperties
- allowsArrowNavigation?: boolean
children: ReactNode | (CardRenderProps) => ReactNode
download?: boolean | string
- focusMode?: 'child' | 'row'
href?: Href
hrefLang?: string
id?: Key
isDisabled?: boolean
onPress?: (PressEvent) => void
onPressChange?: (boolean) => void
onPressEnd?: (PressEvent) => void
onPressStart?: (PressEvent) => void
onPressUp?: (PressEvent) => void
ping?: string
referrerPolicy?: HTMLAttributeReferrerPolicy
rel?: string
routerOptions?: RouterOptions
size?: 'XS' | 'S' | 'M' | 'L' | 'XL' = 'M'
styles?: StylesProp
target?: HTMLAttributeAnchorTarget
textValue?: string
value?: T
variant?: 'primary' | 'secondary' | 'tertiary' | 'quiet' = 'primary'
}/@react-spectrum/s2:ProductCardProps ProductCardProps {
UNSAFE_className?: UnsafeClassName
UNSAFE_style?: CSSProperties
- allowsArrowNavigation?: boolean
children: ReactNode | (CardRenderProps) => ReactNode
download?: boolean | string
- focusMode?: 'child' | 'row'
href?: Href
hrefLang?: string
id?: Key
isDisabled?: boolean
onPress?: (PressEvent) => void
onPressChange?: (boolean) => void
onPressEnd?: (PressEvent) => void
onPressStart?: (PressEvent) => void
onPressUp?: (PressEvent) => void
ping?: string
referrerPolicy?: HTMLAttributeReferrerPolicy
rel?: string
routerOptions?: RouterOptions
size?: 'XS' | 'S' | 'M' | 'L' | 'XL' = 'M'
styles?: StylesProp
target?: HTMLAttributeAnchorTarget
textValue?: string
value?: T
variant?: 'primary' | 'secondary' | 'tertiary'
}/@react-spectrum/s2:UserCardProps UserCardProps {
UNSAFE_className?: UnsafeClassName
UNSAFE_style?: CSSProperties
- allowsArrowNavigation?: boolean
children: ReactNode | (CardRenderProps) => ReactNode
download?: boolean | string
- focusMode?: 'child' | 'row'
href?: Href
hrefLang?: string
id?: Key
isDisabled?: boolean
onPress?: (PressEvent) => void
onPressChange?: (boolean) => void
onPressEnd?: (PressEvent) => void
onPressStart?: (PressEvent) => void
onPressUp?: (PressEvent) => void
ping?: string
referrerPolicy?: HTMLAttributeReferrerPolicy
rel?: string
routerOptions?: RouterOptions
size?: 'XS' | 'S' | 'M' | 'L' | 'XL' = 'M'
styles?: StylesProp
target?: HTMLAttributeAnchorTarget
textValue?: string
value?: T
variant?: 'primary' | 'secondary' | 'tertiary'
}/@react-spectrum/s2:ListViewItemProps ListViewItemProps {
- allowsArrowNavigation?: boolean
children: ReactNode
download?: boolean | string
- focusMode?: 'child' | 'row'
hasChildItems?: boolean
href?: Href
hrefLang?: string
id?: Key
onAction?: () => void
onHoverChange?: (boolean) => void
onHoverEnd?: (HoverEvent) => void
onHoverStart?: (HoverEvent) => void
onPress?: (PressEvent) => void
onPressChange?: (boolean) => void
onPressEnd?: (PressEvent) => void
onPressStart?: (PressEvent) => void
onPressUp?: (PressEvent) => void
ping?: string
referrerPolicy?: HTMLAttributeReferrerPolicy
rel?: string
routerOptions?: RouterOptions
target?: HTMLAttributeAnchorTarget
textValue?: string
value?: T
}/@react-spectrum/s2:TableViewProps TableViewProps {
UNSAFE_className?: UnsafeClassName
UNSAFE_style?: CSSProperties
aria-describedby?: string
aria-details?: string
aria-label?: string
aria-labelledby?: string
children?: ReactNode
defaultExpandedKeys?: Iterable<Key>
defaultSelectedKeys?: 'all' | Iterable<Key>
density?: 'compact' | 'spacious' | 'regular' = 'regular'
disabledBehavior?: DisabledBehavior = 'all'
disabledKeys?: Iterable<Key>
disallowEmptySelection?: boolean
dragAndDropHooks?: DragAndDropHooks
escapeKeyBehavior?: 'clearSelection' | 'none' = 'clearSelection'
expandedKeys?: Iterable<Key>
id?: string
isQuiet?: boolean
- keyboardNavigationBehavior?: 'arrow' | 'tab' = 'arrow'
loadingState?: LoadingState
onAction?: (Key) => void
onExpandedChange?: (Set<Key>) => any
onLoadMore?: () => any
onResizeEnd?: (Map<Key, ColumnSize>) => void
onResizeStart?: (Map<Key, ColumnSize>) => void
onSelectionChange?: (Selection) => void
onSortChange?: (SortDescriptor) => any
overflowMode?: 'wrap' | 'truncate' = 'truncate'
renderActionBar?: ('all' | Set<Key>) => ReactElement
selectedKeys?: 'all' | Iterable<Key>
selectionMode?: SelectionMode
selectionStyle?: 'checkbox' | 'highlight' = 'checkbox'
shouldSelectOnPressUp?: boolean
slot?: string | null
sortDescriptor?: SortDescriptor
styles?: StylesPropWithHeight
treeColumn?: Key
}/@react-spectrum/s2:CellProps CellProps {
align?: 'start' | 'center' | 'end' = 'start'
- allowsArrowNavigation?: boolean
children: ReactNode
colSpan?: number
- focusMode?: 'child' | 'cell'
id?: Key
showDivider?: boolean
textValue?: string
}/@react-spectrum/s2:ColumnProps ColumnProps {
align?: 'start' | 'center' | 'end' = 'start'
- allowsArrowNavigation?: boolean
allowsResizing?: boolean
allowsSorting?: boolean
children: ReactNode
defaultWidth?: ColumnSize | null
- focusMode?: 'child' | 'cell'
id?: Key
isRowHeader?: boolean
maxWidth?: ColumnStaticSize | null
menuItems?: ReactNode
showDivider?: boolean
textValue?: string
width?: ColumnSize | null
}/@react-spectrum/s2:TreeViewItemProps TreeViewItemProps {
- allowsArrowNavigation?: boolean
aria-label?: string
children: ReactNode
download?: boolean | string
- focusMode?: 'child' | 'row' = 'row'
hasChildItems?: boolean
href?: Href
hrefLang?: string
id?: Key
onAction?: () => void
onHoverChange?: (boolean) => void
onHoverEnd?: (HoverEvent) => void
onHoverStart?: (HoverEvent) => void
onPress?: (PressEvent) => void
onPressChange?: (boolean) => void
onPressEnd?: (PressEvent) => void
onPressStart?: (PressEvent) => void
onPressUp?: (PressEvent) => void
ping?: string
referrerPolicy?: HTMLAttributeReferrerPolicy
rel?: string
routerOptions?: RouterOptions
target?: HTMLAttributeAnchorTarget
textValue: string
value?: T
}@react-spectrum/table/@react-spectrum/table:TableView TableView <T extends {}> {
UNSAFE_className?: string
UNSAFE_style?: CSSProperties
alignSelf?: Responsive<'auto' | 'normal' | 'start' | 'end' | 'center' | 'flex-start' | 'flex-end' | 'self-start' | 'self-end' | 'stretch'>
aria-describedby?: string
aria-details?: string
aria-label?: string
aria-labelledby?: string
bottom?: Responsive<DimensionValue>
children: [ReactElement<TableHeaderProps<T>>, ReactElement<TableBodyProps<T>>]
defaultSelectedKeys?: 'all' | Iterable<Key>
density?: 'compact' | 'regular' | 'spacious' = 'regular'
disabledBehavior?: DisabledBehavior = 'selection'
disabledKeys?: Iterable<Key>
disallowEmptySelection?: boolean
dragAndDropHooks?: DragAndDropHooks<NoInfer<{}>>['dragAndDropHooks']
end?: Responsive<DimensionValue>
escapeKeyBehavior?: 'clearSelection' | 'none' = 'clearSelection'
flex?: Responsive<string | number | boolean>
flexBasis?: Responsive<number | string>
flexGrow?: Responsive<number>
flexShrink?: Responsive<number>
gridArea?: Responsive<string>
gridColumn?: Responsive<string>
gridColumnEnd?: Responsive<string>
gridColumnStart?: Responsive<string>
gridRow?: Responsive<string>
gridRowEnd?: Responsive<string>
gridRowStart?: Responsive<string>
height?: Responsive<DimensionValue>
id?: string
isHidden?: Responsive<boolean>
isQuiet?: boolean
justifySelf?: Responsive<'auto' | 'normal' | 'start' | 'end' | 'flex-start' | 'flex-end' | 'self-start' | 'self-end' | 'center' | 'left' | 'right' | 'stretch'>
- keyboardNavigationBehavior?: 'arrow' | 'tab' = 'arrow'
left?: Responsive<DimensionValue>
margin?: Responsive<DimensionValue>
marginBottom?: Responsive<DimensionValue>
marginEnd?: Responsive<DimensionValue>
marginTop?: Responsive<DimensionValue>
marginX?: Responsive<DimensionValue>
marginY?: Responsive<DimensionValue>
maxHeight?: Responsive<DimensionValue>
maxWidth?: Responsive<DimensionValue>
minHeight?: Responsive<DimensionValue>
minWidth?: Responsive<DimensionValue>
onAction?: (Key) => void
onResize?: (Map<Key, ColumnSize>) => void
onResizeEnd?: (Map<Key, ColumnSize>) => void
onResizeStart?: (Map<Key, ColumnSize>) => void
onSelectionChange?: (Selection) => void
onSortChange?: (SortDescriptor) => any
order?: Responsive<number>
overflowMode?: 'wrap' | 'truncate' = 'truncate'
position?: Responsive<'static' | 'relative' | 'absolute' | 'fixed' | 'sticky'>
renderEmptyState?: () => JSX.Element
right?: Responsive<DimensionValue>
selectedKeys?: 'all' | Iterable<Key>
selectionMode?: SelectionMode
selectionStyle?: 'checkbox' | 'highlight'
shouldSelectOnPressUp?: boolean
sortDescriptor?: SortDescriptor
start?: Responsive<DimensionValue>
top?: Responsive<DimensionValue>
width?: Responsive<DimensionValue>
zIndex?: Responsive<number>
}/@react-spectrum/table:SpectrumTableProps SpectrumTableProps <T> {
UNSAFE_className?: string
UNSAFE_style?: CSSProperties
alignSelf?: Responsive<'auto' | 'normal' | 'start' | 'end' | 'center' | 'flex-start' | 'flex-end' | 'self-start' | 'self-end' | 'stretch'>
aria-describedby?: string
aria-details?: string
aria-label?: string
aria-labelledby?: string
bottom?: Responsive<DimensionValue>
children: [ReactElement<TableHeaderProps<T>>, ReactElement<TableBodyProps<T>>]
defaultSelectedKeys?: 'all' | Iterable<Key>
density?: 'compact' | 'regular' | 'spacious' = 'regular'
disabledBehavior?: DisabledBehavior = 'selection'
disabledKeys?: Iterable<Key>
disallowEmptySelection?: boolean
dragAndDropHooks?: DragAndDropHooks<NoInfer<T>>['dragAndDropHooks']
end?: Responsive<DimensionValue>
escapeKeyBehavior?: 'clearSelection' | 'none' = 'clearSelection'
flex?: Responsive<string | number | boolean>
flexBasis?: Responsive<number | string>
flexGrow?: Responsive<number>
flexShrink?: Responsive<number>
gridArea?: Responsive<string>
gridColumn?: Responsive<string>
gridColumnEnd?: Responsive<string>
gridColumnStart?: Responsive<string>
gridRow?: Responsive<string>
gridRowEnd?: Responsive<string>
gridRowStart?: Responsive<string>
height?: Responsive<DimensionValue>
id?: string
isHidden?: Responsive<boolean>
isQuiet?: boolean
justifySelf?: Responsive<'auto' | 'normal' | 'start' | 'end' | 'flex-start' | 'flex-end' | 'self-start' | 'self-end' | 'center' | 'left' | 'right' | 'stretch'>
- keyboardNavigationBehavior?: 'arrow' | 'tab' = 'arrow'
left?: Responsive<DimensionValue>
margin?: Responsive<DimensionValue>
marginBottom?: Responsive<DimensionValue>
marginEnd?: Responsive<DimensionValue>
marginTop?: Responsive<DimensionValue>
marginX?: Responsive<DimensionValue>
marginY?: Responsive<DimensionValue>
maxHeight?: Responsive<DimensionValue>
maxWidth?: Responsive<DimensionValue>
minHeight?: Responsive<DimensionValue>
minWidth?: Responsive<DimensionValue>
onAction?: (Key) => void
onResize?: (Map<Key, ColumnSize>) => void
onResizeEnd?: (Map<Key, ColumnSize>) => void
onResizeStart?: (Map<Key, ColumnSize>) => void
onSelectionChange?: (Selection) => void
onSortChange?: (SortDescriptor) => any
order?: Responsive<number>
overflowMode?: 'wrap' | 'truncate' = 'truncate'
position?: Responsive<'static' | 'relative' | 'absolute' | 'fixed' | 'sticky'>
renderEmptyState?: () => JSX.Element
right?: Responsive<DimensionValue>
selectedKeys?: 'all' | Iterable<Key>
selectionMode?: SelectionMode
selectionStyle?: 'checkbox' | 'highlight'
shouldSelectOnPressUp?: boolean
sortDescriptor?: SortDescriptor
start?: Responsive<DimensionValue>
top?: Responsive<DimensionValue>
width?: Responsive<DimensionValue>
zIndex?: Responsive<number>
}@react-spectrum/tree/@react-spectrum/tree:TreeViewItem TreeViewItem {
- allowsArrowNavigation?: boolean
aria-label?: string
children: ReactNode
download?: boolean | string
- focusMode?: 'child' | 'row' = 'row'
hasChildItems?: boolean
href?: Href
hrefLang?: string
id?: Key
onAction?: () => void
onPress?: (PressEvent) => void
onPressChange?: (boolean) => void
onPressEnd?: (PressEvent) => void
onPressStart?: (PressEvent) => void
onPressUp?: (PressEvent) => void
ping?: string
referrerPolicy?: HTMLAttributeReferrerPolicy
rel?: string
routerOptions?: RouterOptions
target?: HTMLAttributeAnchorTarget
textValue: string
}/@react-spectrum/tree:SpectrumTreeViewItemProps SpectrumTreeViewItemProps {
- allowsArrowNavigation?: boolean
aria-label?: string
children: ReactNode
download?: boolean | string
- focusMode?: 'child' | 'row' = 'row'
hasChildItems?: boolean
href?: Href
hrefLang?: string
id?: Key
onAction?: () => void
onPress?: (PressEvent) => void
onPressChange?: (boolean) => void
onPressEnd?: (PressEvent) => void
onPressStart?: (PressEvent) => void
onPressUp?: (PressEvent) => void
ping?: string
referrerPolicy?: HTMLAttributeReferrerPolicy
rel?: string
routerOptions?: RouterOptions
target?: HTMLAttributeAnchorTarget
textValue: string
}@react-stately/table/@react-stately/table:TableProps TableProps <T> {
children: [ReactElement<TableHeaderProps<T>>, ReactElement<TableBodyProps<T>>]
defaultExpandedKeys?: Iterable<Key>
defaultSelectedKeys?: 'all' | Iterable<Key>
disabledKeys?: Iterable<Key>
disallowEmptySelection?: boolean
escapeKeyBehavior?: 'clearSelection' | 'none' = 'clearSelection'
expandedKeys?: Iterable<Key>
- keyboardNavigationBehavior?: 'arrow' | 'tab' = 'arrow'
onExpandedChange?: (Set<Key>) => any
onSelectionChange?: (Selection) => void
onSortChange?: (SortDescriptor) => any
selectedKeys?: 'all' | Iterable<Key>
shouldSelectOnPressUp?: boolean
sortDescriptor?: SortDescriptor
treeColumn?: Key
} |
Agent Skills ChangesModified (8)
InstallReact Spectrum S2: React Aria: |
fills in gaps in our current AI components that we found when integrating with other experiences. Includes the following:
✅ Pull Request Checklist:
📝 Test Instructions:
See the description above for all the added features. Test the AttachmentList, Chat, and PromptField stories and verify behavior like invalid attachments, token/callback/plain text injection in the PromptField, voice input support, etc
🧢 Your Project:
RSP