Skip to content

feat: support Textfields and other interactive components in Table - #10159

Merged
LFDanLu merged 36 commits into
mainfrom
textfield_gridlists
Jul 17, 2026
Merged

feat: support Textfields and other interactive components in Table#10159
LFDanLu merged 36 commits into
mainfrom
textfield_gridlists

Conversation

@LFDanLu

@LFDanLu LFDanLu commented Jun 5, 2026

Copy link
Copy Markdown
Member

Closes #2328

✅ 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:

Test GridList/Table/Tree with textfield stories and test keyboardNavigationBehavior=tab behavior. You should be able to interact/type/etc with the interactive elements without causing focus navigation/row selection even if you use the arrow keys/Enter/Space/etc. It should require Tab from the cell/row to the cell/row's content to interact with the children, and Shift-Tab back to the cell/row to perform row navigation/selection via arrow keys/Enter/Space as usual.

Test the same in S2 TableView/CardView/TagGroup. Be sure to test TableView more throughly since keyboardNavigationBehavior=tab is net new as well

In addition, focusMode and allowsArrowNavigation has been added to Cell/GridListItem/TreeViewItem/etc. This allows users to have selection cells automatically focus the checkbox and maintain arrow key navigation to the adjacent rows even in keyboardNavigationBehavior=tab. Docs added for this in RAC Table and Grid, S2 TableView takes advantage of this automatically for its selection checkbox cells, drag cells, and column headers that have menus

🧢 Your Project:

RSP

@rspbot

rspbot commented Jun 5, 2026

Copy link
Copy Markdown

@rspbot

rspbot commented Jun 5, 2026

Copy link
Copy Markdown

@rspbot

rspbot commented Jun 8, 2026

Copy link
Copy Markdown

@snowystinger snowystinger left a comment

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.

CardView story. Tab into Card with textfield, open menu, press Esc, focus returns to Card not menu trigger.
I think focus return was something we knew we'd struggle with. We have some open issues about this when Shift+Tab'ing back to a collection.
Looks like you noted this as well https://github.com/adobe/react-spectrum/pull/10159/changes#diff-b741e806d7e03bb7f42427dbe388c23128044ae2c96c612a9bceb9852ec408abR1021

Should hitting Esc in a TextField of a selected card de-select it? I thought we were ignoring events that came from inside a cell? basically, if the event's target was anything other than a data-collection* element, then it should be ignored.
In a similar vein, fn+arrow causes grid level navigation even when inside the textfield, which it shouldn't because those keys are shortcuts for moving the cursor inside the textfield already.


## Keyboard navigation

By default, GridList uses arrow key navigation to move focus into rows. Set `keyboardNavigationBehavior="tab"` to have <Keyboard>Tab</Keyboard> move focus in and out of a row.

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.

We should include a blurb about when you'd be likely to want to change the keyboard navigation behavior, ie you have something like a textfield or something else that would conflict with arrow key navigation

Comment thread packages/react-aria-components/test/TagGroup.test.js Outdated
// TODO: guarding against selection when firing space/enter/click on a element in a row is technically not only limited to textfields so I
// am not making it specific to keyboardNavigationBehavior = tab, but maybe we should still?
// we need to guard against space/enter triggering selection/row link via usePress (from itemProps) so check if propagation
// is stopped. this also fixes space not working in a textfield in a tree parent row

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 also fixes space not working in a textfield in a tree parent row

was this not fixed in my other PRs for event leaks? I'm not following the issue here

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 didn't check against your PR since I wanted to approach this in a more isolated approach to see what was the minimal set of changes I needed.

The issue was that useSelectableItem returns itemProps that include onKeyDown that handles updating row selection that then gets merged with our onKeyDown via mergeProps below. That meant hitting Enter in a textfield/area in a row also toggled selection

role: 'row',
onKeyDownCapture,
onKeyDown,
onKeyDownCapture: keyboardNavigationBehavior === 'arrow' ? onKeyDownCapture : undefined,

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.

I want to move this one away from capturing, maybe that will simplify, I was going to look at this in keyboard-shortcut-handler...new-event-leaks#diff-3989d5920106dcc67dc6bdd9497aac4530373a27f5cc521fbee771d773650b92R171

@LFDanLu

LFDanLu commented Jun 9, 2026

Copy link
Copy Markdown
Member Author

@snowystinger with regards to

Should hitting Esc in a TextField of a selected card de-select it? I thought we were ignoring events that came from inside a cell? basically, if the event's target was anything other than a data-collection* element, then it should be ignored.

I agree, I made a comment here wondering if we should automatically stop propagation on ALL events if they bubbled up from the cell. I can update the code to do so, but still a bit wary about if its too much of a blanket approach.

EDIT:
We will actually still need to let Tab pass through so the useSelectableCollection Tab handler still runs when attempting to tab out from the collection

@rspbot

rspbot commented Jun 9, 2026

Copy link
Copy Markdown

@LFDanLu
LFDanLu marked this pull request as ready for review June 10, 2026 17:08
snowystinger
snowystinger previously approved these changes Jun 23, 2026

@snowystinger snowystinger left a comment

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.

happy to get in for more testing and use


return (
<RACColumn
// will need to make sure that focusMode and allowsArrowNavigation are only both set if said cell

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.

do we need to police this? what happens if this is ignored?

@LFDanLu LFDanLu Jun 23, 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.

I guess it partially depends on our stance around if we want to expose this in S2 or just in RAC. I'm currently leaning towards exposing these in S2 but not policing it since it falls into the realm of user error rather an accessibility problem IMO

I'm also not 100% tied to exposing these props in S2, I'm not sure what use cases may exist that S2 end users would have so maybe it would best to wait for requests to expose these props.

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.

chatted in otters about this, we are ok exposing these for now

@nwidynski

nwidynski commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

@snowystinger Just noting that this PR will need the work of #10102 and another follow-up to patch scrollIntoView, otherwise cells with inputs will fail to be positioned correctly on devices with an OSK.

@rspbot

rspbot commented Jun 25, 2026

Copy link
Copy Markdown

@rspbot

rspbot commented Jun 26, 2026

Copy link
Copy Markdown

@rspbot

rspbot commented Jul 13, 2026

Copy link
Copy Markdown

@LFDanLu LFDanLu mentioned this pull request Jul 13, 2026
9 tasks

@snowystinger snowystinger left a comment

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.

not doing "Esc" to exit a cell at the moment right?


let baseOnPointerDown = mergedItemProps.onPointerDown;
mergedItemProps.onPointerDown = e => {
let target = getEventTarget(e) as Element | null;

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.

I think in this case we actually don't want the getEventTarget

el.parentElement search won't go through a shadow, and all we actually care about here is that pointer event happened on any child. So I think just e.target is fine, but you'll need to add an eslint ignore and comment for why

you can check this out by putting a button inside a shadow dom inside an item

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 catch, I'll update

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.

actually I did some testing around this, e.target would return the shadowDOM host thus it would hit the isTabbable portion check of isChildInteraction and thus cause row selection to happen right? With getEventTarget (and shadowDOM flag turned on) we'll get the actual shadow child element and thus can properly check if it is tabbable.

If the flag is off, then it works essentially like using e.target anyways (thus possibly toggling row selection erroneously) but in that case we can argue that they needed to turn on the shadowDOM flag support IMO

// up to the tree, and move focus to a focusable child if possible.
requestAnimationFrame(() => {
if (focusMode === 'child' && getActiveElement() === ref.current) {
if (

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.

I don't supposed you reasoned about #10228 while you were working on this? It's ok if not

Just noticed it also appears down below https://github.com/adobe/react-spectrum/pull/10159/changes#diff-3989d5920106dcc67dc6bdd9497aac4530373a27f5cc521fbee771d773650b92R332

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 nope, interesting that the raf was removed there, if I remember correctly that was to ensure focused key got updated properly?

was added it to useGridListItem since we now allow autofocusing the children rather than landing on the row first

@LFDanLu

LFDanLu commented Jul 15, 2026

Copy link
Copy Markdown
Member Author

@snowystinger nope, not supporting Esc just yet. IMO we can collect some feedback from users first when this goes in (though its probably a non-contentious addition haha)

@devongovett devongovett left a comment

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.

lgtm. docs updates can be followup if you want


You can further control if a row automatically focuses itself or its children on keyboard focus via `focusMode`. Futhermore, `allowsArrowNavigation` can be used to allow arrow key navigation from the row's children to adjacent rows.
This allows keyboard users to navigate to the contents of the row without needing to tab in and out of the row even when in tab keyboard navigation.
Be sure to only set `allowsArrowNavigation` on rows whose interactive content don't use arrow keys.

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.

I think this docs section is getting too long for something quite nitty-gritty compared with the rest of the overall page. Is it possible to add these two props as controls to the previous example instead?

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.

opted to remove this block entirely, and didn't add the props as controls due to the textfields as discussed yesterday

You can further control if a cell automatically focuses itself or its children on keyboard focus via `focusMode`. Futhermore, `allowsArrowNavigation` can be used to allow arrow key navigation from the cell's children to adjacent cells.
This allows keyboard users to navigate to the selection checkboxes without needing to tab in and out of the selection cell even when in tab keyboard navigation.
The vanilla CSS starter applies these to selection cells automatically, see the **Table.tsx** tab above.
Be sure to only set `allowsArrowNavigation` on cells whose interactive content don't use arrow keys.

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.

Too looooong 😅 Not sure if we need something here other than the prop descriptions?

<Cell>{item.name}</Cell>
<Cell>{item.type}</Cell>
<Cell>{item.date}</Cell>
<Cell><TextField aria-label={`${item.name} notes`} defaultValue="" /></Cell>

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 should add a placeholder since the border doesn't pass contrast

<Cell>{item.name}</Cell>
<Cell>{item.type}</Cell>
<Cell>{item.date}</Cell>
<Cell><TextField aria-label={`${item.name} notes`} defaultValue="" /></Cell>

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.

same

onAction?: () => void;
/**
* Whether the row or its first focusable child element should be focused when the row is
* focused. Defaults to 'row'.

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 navigating to the row" instead of "when the row is focused"? (since this is controlling what will be focused)

@LFDanLu
LFDanLu enabled auto-merge July 17, 2026 00:32
@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
   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, 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:ThreadItem

 ThreadItem {
+  allowsArrowNavigation?: boolean
   children?: ChildrenOrFunction<GridListItemRenderProps>
+  focusMode?: 'child' | 'row'
   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
   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, 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:ThreadItemProps

 ThreadItemProps {
+  allowsArrowNavigation?: boolean
   children?: ChildrenOrFunction<GridListItemRenderProps>
+  focusMode?: 'child' | 'row'
   isStreaming?: boolean
   shouldAnnounceOnMount?: boolean
   styles?: StyleString
   textValue?: string

@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 (7)
Install

React Spectrum S2:

npx skills add https://d1pzu54gtk2aed.cloudfront.net/pr/c06a5ecf88bcceec04d11bacf78e59e225eda3e5/

React Aria:

npx skills add https://d5iwopk28bdhl.cloudfront.net/pr/c06a5ecf88bcceec04d11bacf78e59e225eda3e5/

@LFDanLu
LFDanLu added this pull request to the merge queue Jul 17, 2026
Merged via the queue into main with commit 7fd0237 Jul 17, 2026
31 checks passed
@LFDanLu
LFDanLu deleted the textfield_gridlists branch July 17, 2026 07:30
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.

Grid navigation edit mode

5 participants