Skip to content

feat: Updates to AI components for additional chat prompt use cases#10335

Open
LFDanLu wants to merge 22 commits into
mainfrom
ai_followups_coworker
Open

feat: Updates to AI components for additional chat prompt use cases#10335
LFDanLu wants to merge 22 commits into
mainfrom
ai_followups_coworker

Conversation

@LFDanLu

@LFDanLu LFDanLu commented Jul 16, 2026

Copy link
Copy Markdown
Member

fills in gaps in our current AI components that we found when integrating with other experiences. Includes the following:

  • localization for various components (translated strings to come)
  • exposing size on MessageFeedback
  • "failed" and "no disclosure" variants to ResponseStatus
  • expose onKeyDown handler so users can add custom keyboard commands to their PromptField and ArrowUp/Down to cycle through old prompts
  • controlled field value and attachment support to PromptField
  • support for injecting plain text and triggering injection less callbacks in the PromptField
  • voice input support
  • error variant for AttachmentList cards
  • bug fixes for things like misplaced text cursor position after adding a token into the field, cancelling the prompt in the "Streaming" story now stops streaming, etc

✅ Pull Request Checklist:

  • Included link to corresponding React Spectrum GitHub Issue.
  • Added/updated unit tests and storybook for this change (for new code or code which already has tests).
  • Filled out test instructions.
  • Updated documentation (if it already exists for this component).
  • Looked at the Accessibility Practices for this feature - Aria Practices

📝 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

@LFDanLu LFDanLu changed the title feat: (WIP) Updates to AI components for additional chat prompt use cases feat: Updates to AI components for additional chat prompt use cases Jul 16, 2026
} 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';

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exported in case a user don't use our PromptField with Chat. They will need to wire up the onFocusChange to their input field

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

strings to be translated, open to discussion for copy

borderRadius: 'default'
});

const attachmentErrorStyles = style({

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The styles for invalid + thumbnail only aren't added yet, to be discussed with design

Comment on lines +79 to +86
// 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;

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

open to discussion

if (text.length === 0) {
return [{type: 'text', text}];
}
function tokenizeURLs(text: string): TokenFieldSegment[] {

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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(

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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;

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

support for custom user defined keyboard commands (Opt + Enter for followup while streaming, arrow keys to autofil old prompts)

Comment on lines +781 to +787
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));

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as mentioned in the comment, seems to be a race here that caused inconsistent text cursor positioning when doing insertions via the "+" menu.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

API change we'll have to call out

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

based off what Coworker had, but refactored a bit since it didn't seem they actually needed some of the callbacks

@github-actions github-actions Bot added the RAC label Jul 16, 2026
@github-actions github-actions Bot removed the RAC label Jul 16, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@LFDanLu
LFDanLu marked this pull request as ready for review July 16, 2026 18:58
@rspbot

rspbot commented Jul 16, 2026

Copy link
Copy Markdown

Comment thread packages/@react-spectrum/ai/intl/en-US.json Outdated
<ProgressCircle
aria-label={stringFormatter.format('promptfield.uploading')}
value={props.uploadProgress}
size="S"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

always? or is it just one size smaller than whatever is used for the rest of it?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment thread packages/@react-spectrum/ai/src/AttachmentList.tsx Outdated
export interface PromptFieldVoiceButtonProps {
lang?: string;
isDisabled?: boolean;
// TODO: coworker renders a toast too, but this gives more flexibility

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment thread packages/@react-spectrum/ai/src/useVoiceInput.ts Outdated
}
// similar to useInsertPromptSegment, calling programatic focus on the input causes the caret positioning
// to be inaccurate
let finalPrompt = buildVoicePrompt(basePromptRef.current, transcript);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need for the ref, this is a useEffectEvent, so it's up to date

Suggested change
let finalPrompt = buildVoicePrompt(basePromptRef.current, transcript);
let finalPrompt = buildVoicePrompt(prompt, transcript);

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when does this happen?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 => {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably will have to have an icon as well for accessibility (otherwise it's a color only change...). design question

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup, added to the canvas

}
});

let [isListening, setListening] = useState(false);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this state need to be in the top-level component or could it live in the microphone button?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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, {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also should add some space between this button and the submit button. Maybe the toolbar needs a columnGap on it

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok that's fine for now. I would just increase the gap a little

LFDanLu added 2 commits July 17, 2026 14:18
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
@rspbot

rspbot commented Jul 17, 2026

Copy link
Copy Markdown

@rspbot

rspbot commented Jul 17, 2026

Copy link
Copy Markdown
## 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
 }

@rspbot

rspbot commented Jul 17, 2026

Copy link
Copy Markdown

Agent Skills Changes

Modified (8)
Install

React Spectrum S2:

npx skills add https://d1pzu54gtk2aed.cloudfront.net/pr/5b995606d4493f7b11ff776dc34ccd82395f7cb6/

React Aria:

npx skills add https://d5iwopk28bdhl.cloudfront.net/pr/5b995606d4493f7b11ff776dc34ccd82395f7cb6/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants