Skip to content

feat: (WIP) support Textfields in collection components#10159

Draft
LFDanLu wants to merge 6 commits into
mainfrom
textfield_gridlists
Draft

feat: (WIP) support Textfields in collection components#10159
LFDanLu wants to merge 6 commits into
mainfrom
textfield_gridlists

Conversation

@LFDanLu
Copy link
Copy Markdown
Member

@LFDanLu LFDanLu commented Jun 5, 2026

Closes

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

🧢 Your Project:

@rspbot
Copy link
Copy Markdown

rspbot commented Jun 5, 2026

@rspbot
Copy link
Copy Markdown

rspbot commented Jun 5, 2026

@rspbot
Copy link
Copy Markdown

rspbot commented Jun 5, 2026

## API Changes

react-aria-components

/react-aria-components:Tree

 Tree <T> {
   aria-describedby?: string
   aria-details?: string
   aria-label?: string
   aria-labelledby?: string
   autoFocus?: boolean | FocusStrategy
   children?: ReactNode | (T) => ReactNode
   className?: ClassNameOrFunction<TreeRenderProps> = 'react-aria-Tree'
   defaultExpandedKeys?: Iterable<Key>
   defaultSelectedKeys?: 'all' | Iterable<Key>
   dependencies?: ReadonlyArray<any>
   disabledBehavior?: DisabledBehavior = 'all'
   disabledKeys?: Iterable<Key>
   disallowEmptySelection?: boolean
   dragAndDropHooks?: DragAndDropHooks<NoInfer<T>>
   escapeKeyBehavior?: 'clearSelection' | 'none' = 'clearSelection'
   expandedKeys?: Iterable<Key>
   id?: string
   items?: Iterable<T>
+  keyboardNavigationBehavior?: 'arrow' | 'tab' = 'arrow'
   onAction?: (Key) => void
   onExpandedChange?: (Set<Key>) => any
   onSelectionChange?: (Selection) => void
   render?: DOMRenderFunction<keyof React.JSX.IntrinsicElements, TreeRenderProps>
   selectedKeys?: 'all' | Iterable<Key>
   selectionBehavior?: SelectionBehavior = 'toggle'
   selectionMode?: SelectionMode
   shouldSelectOnPressUp?: boolean
   slot?: string | null
   style?: StyleOrFunction<TreeRenderProps>
 }

/react-aria-components:TreeProps

 TreeProps <T> {
   aria-describedby?: string
   aria-details?: string
   aria-label?: string
   aria-labelledby?: string
   autoFocus?: boolean | FocusStrategy
   children?: ReactNode | (T) => ReactNode
   className?: ClassNameOrFunction<TreeRenderProps> = 'react-aria-Tree'
   defaultExpandedKeys?: Iterable<Key>
   defaultSelectedKeys?: 'all' | Iterable<Key>
   dependencies?: ReadonlyArray<any>
   disabledBehavior?: DisabledBehavior = 'all'
   disabledKeys?: Iterable<Key>
   disallowEmptySelection?: boolean
   dragAndDropHooks?: DragAndDropHooks<NoInfer<T>>
   escapeKeyBehavior?: 'clearSelection' | 'none' = 'clearSelection'
   expandedKeys?: Iterable<Key>
   id?: string
   items?: Iterable<T>
+  keyboardNavigationBehavior?: 'arrow' | 'tab' = 'arrow'
   onAction?: (Key) => void
   onExpandedChange?: (Set<Key>) => any
   onSelectionChange?: (Selection) => void
   render?: DOMRenderFunction<keyof React.JSX.IntrinsicElements, TreeRenderProps>
   selectedKeys?: 'all' | Iterable<Key>
   selectionBehavior?: SelectionBehavior = 'toggle'
   selectionMode?: SelectionMode
   shouldSelectOnPressUp?: boolean
   slot?: string | null
   style?: StyleOrFunction<TreeRenderProps>
 }

@react-aria/tree

/@react-aria/tree:AriaTreeProps

 AriaTreeProps <T> {
   aria-describedby?: string
   aria-details?: string
   aria-label?: string
   aria-labelledby?: string
   autoFocus?: boolean | FocusStrategy
   children: CollectionChildren<T>
   defaultSelectedKeys?: 'all' | Iterable<Key>
   disabledBehavior?: DisabledBehavior = 'all'
   disabledKeys?: Iterable<Key>
   disallowEmptySelection?: boolean
   escapeKeyBehavior?: 'clearSelection' | 'none' = 'clearSelection'
   id?: string
   items?: Iterable<T>
+  keyboardNavigationBehavior?: 'arrow' | 'tab' = 'arrow'
   onAction?: (Key) => void
   onSelectionChange?: (Selection) => void
   selectedKeys?: 'all' | Iterable<Key>
   selectionMode?: SelectionMode
 }

@react-spectrum/s2

/@react-spectrum/s2:DisclosureTitle

 DisclosureTitle {
   UNSAFE_className?: UnsafeClassName
   UNSAFE_style?: CSSProperties
   children: React.ReactNode
   id?: string
   level?: number = 3
-  styles?: StylesPropWithFont
 }

tmp/dist/base-api/@react-spectrum/s2-ai

/tmp/dist/base-api/@react-spectrum/s2-ai:Attachment

-Attachment {
-
-}

/tmp/dist/base-api/@react-spectrum/s2-ai:AttachmentList

-AttachmentList {
-
-}

/tmp/dist/base-api/@react-spectrum/s2-ai:BasicHorizontalCard

-BasicHorizontalCard {
-  children: ReactNode | (CardRenderProps) => ReactNode
-  density?: 'compact' | 'regular' | 'spacious' = 'regular'
-  download?: boolean | string
-  href?: Href
-  hrefLang?: string
-  id?: Key
-  isDisabled?: boolean
-  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
-  size?: 'XS' | 'S' | 'M' | 'L' | 'XL' = 'M'
-  styles?: StyleString
-  target?: HTMLAttributeAnchorTarget
-  textValue?: string
-  value?: T
-  variant?: 'primary' | 'secondary' | 'tertiary' | 'quiet' = 'primary'
-}

/tmp/dist/base-api/@react-spectrum/s2-ai:HorizontalCard

-HorizontalCard {
-  children: ReactNode | (CardRenderProps) => ReactNode
-  density?: 'compact' | 'regular' | 'spacious' = 'regular'
-  download?: boolean | string
-  href?: Href
-  hrefLang?: string
-  id?: Key
-  isDisabled?: boolean
-  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
-  size?: 'XS' | 'S' | 'M' | 'L' | 'XL' = 'M'
-  styles?: StyleString
-  target?: HTMLAttributeAnchorTarget
-  textValue?: string
-  value?: T
-  variant?: 'primary' | 'secondary' | 'tertiary' | 'quiet' = 'primary'
-}

/tmp/dist/base-api/@react-spectrum/s2-ai:MessageFeedback

-MessageFeedback {
-  aria-describedby?: string
-  aria-details?: string
-  aria-label?: string
-  aria-labelledby?: string
-  defaultValue?: MessageFeedbackValue
-  id?: string
-  isDisabled?: boolean
-  onChange?: (MessageFeedbackValue) => void
-  slot?: string | null
-  styles?: StyleString
-  thumbDownLabel?: string
-  thumbUpLabel?: string
-  value?: MessageFeedbackValue
-}

/tmp/dist/base-api/@react-spectrum/s2-ai:MessageSuggestion

-MessageSuggestion {
-  aria-controls?: string
-  aria-current?: boolean | 'true' | 'false' | 'page' | 'step' | 'location' | 'date' | 'time'
-  aria-describedby?: string
-  aria-details?: string
-  aria-disabled?: boolean | 'true' | 'false'
-  aria-expanded?: boolean | 'true' | 'false'
-  aria-haspopup?: boolean | 'menu' | 'listbox' | 'tree' | 'grid' | 'dialog' | 'true' | 'false'
-  aria-label?: string
-  aria-labelledby?: string
-  aria-pressed?: boolean | 'true' | 'false' | 'mixed'
-  autoFocus?: boolean
-  children: ReactNode
-  excludeFromTabOrder?: boolean
-  form?: string
-  formAction?: ButtonHTMLAttributes<HTMLButtonElement>['formAction']
-  formEncType?: string
-  formMethod?: string
-  formNoValidate?: boolean
-  formTarget?: string
-  id?: string
-  name?: string
-  onBlur?: (FocusEvent<Target>) => void
-  onClick?: (MouseEvent<FocusableElement>) => void
-  onFocus?: (FocusEvent<Target>) => void
-  onFocusChange?: (boolean) => void
-  onHoverChange?: (boolean) => void
-  onHoverEnd?: (HoverEvent) => void
-  onHoverStart?: (HoverEvent) => void
-  onKeyDown?: (KeyboardEvent) => void
-  onKeyUp?: (KeyboardEvent) => void
-  onPress?: (PressEvent) => void
-  onPressChange?: (boolean) => void
-  onPressEnd?: (PressEvent) => void
-  onPressStart?: (PressEvent) => void
-  onPressUp?: (PressEvent) => void
-  preventFocusOnPress?: boolean
-  render?: DOMRenderFunction<keyof React.JSX.IntrinsicElements, ButtonRenderProps>
-  size?: 'S' | 'M' | 'L' | 'XL'
-  slot?: string | null
-  styles?: StyleString
-  type?: 'button' | 'submit' | 'reset' = 'button'
-  value?: string
-}

/tmp/dist/base-api/@react-spectrum/s2-ai:MessageSuggestionList

-MessageSuggestionList {
-  aria-describedby?: string
-  aria-details?: string
-  aria-label?: string
-  aria-labelledby?: string
-  children: ReactNode
-  id?: string
-  size?: 'S' | 'M' | 'L' | 'XL'
-  slot?: string | null
-  styles?: StyleString
-  title: string
-}

/tmp/dist/base-api/@react-spectrum/s2-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
-  styles?: StyleString
-}

/tmp/dist/base-api/@react-spectrum/s2-ai:ResponseStatusPanel

-ResponseStatusPanel {
-  aria-describedby?: string
-  aria-details?: string
-  aria-label?: string
-  aria-labelledby?: string
-  children: React.ReactNode
-  id?: string
-  label?: ReactNode
-  labelElementType?: ElementType = 'label'
-  role?: 'group' | 'region' = 'group'
-  styles?: StyleString
-}

/tmp/dist/base-api/@react-spectrum/s2-ai:UserMessage

-UserMessage {
-  aria-describedby?: string
-  aria-details?: string
-  aria-label?: string
-  aria-labelledby?: string
-  children: ReactNode
-  id?: string
-  slot?: string | null
-  styles?: StyleString
-}

@react-spectrum/tree

/@react-spectrum/tree:TreeView

 TreeView <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
   autoFocus?: boolean | FocusStrategy
   bottom?: Responsive<DimensionValue>
   children?: ReactNode | ({}) => ReactNode
   defaultExpandedKeys?: Iterable<Key>
   defaultSelectedKeys?: 'all' | Iterable<Key>
   disabledBehavior?: DisabledBehavior = 'all'
   disabledKeys?: Iterable<Key>
   disallowEmptySelection?: boolean
   end?: Responsive<DimensionValue>
   escapeKeyBehavior?: 'clearSelection' | 'none' = 'clearSelection'
   expandedKeys?: Iterable<Key>
   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>
   items?: Iterable<T>
   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
   onExpandedChange?: (Set<Key>) => any
   onSelectionChange?: (Selection) => void
   order?: Responsive<number>
   position?: Responsive<'static' | 'relative' | 'absolute' | 'fixed' | 'sticky'>
   renderEmptyState?: () => JSX.Element
   right?: Responsive<DimensionValue>
   selectedKeys?: 'all' | Iterable<Key>
   selectionMode?: SelectionMode
   selectionStyle?: 'checkbox' | 'highlight'
   shouldSelectOnPressUp?: boolean
   start?: Responsive<DimensionValue>
   top?: Responsive<DimensionValue>
   width?: Responsive<DimensionValue>
   zIndex?: Responsive<number>
 }

/@react-spectrum/tree:SpectrumTreeViewProps

 SpectrumTreeViewProps <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
   autoFocus?: boolean | FocusStrategy
   bottom?: Responsive<DimensionValue>
   children?: ReactNode | (T) => ReactNode
   defaultExpandedKeys?: Iterable<Key>
   defaultSelectedKeys?: 'all' | Iterable<Key>
   disabledBehavior?: DisabledBehavior = 'all'
   disabledKeys?: Iterable<Key>
   disallowEmptySelection?: boolean
   end?: Responsive<DimensionValue>
   escapeKeyBehavior?: 'clearSelection' | 'none' = 'clearSelection'
   expandedKeys?: Iterable<Key>
   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>
   items?: Iterable<T>
   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
   onExpandedChange?: (Set<Key>) => any
   onSelectionChange?: (Selection) => void
   order?: Responsive<number>
   position?: Responsive<'static' | 'relative' | 'absolute' | 'fixed' | 'sticky'>
   renderEmptyState?: () => JSX.Element
   right?: Responsive<DimensionValue>
   selectedKeys?: 'all' | Iterable<Key>
   selectionMode?: SelectionMode
   selectionStyle?: 'checkbox' | 'highlight'
   shouldSelectOnPressUp?: boolean
   start?: Responsive<DimensionValue>
   top?: Responsive<DimensionValue>
   width?: Responsive<DimensionValue>
   zIndex?: Responsive<number>
 }

@rspbot
Copy link
Copy Markdown

rspbot commented Jun 5, 2026

Agent Skills Changes

Modified (8)
Install

React Spectrum S2:

npx skills add https://d1pzu54gtk2aed.cloudfront.net/pr/0aecbf1425281e1d518582701856c9f83e14b6c7/

React Aria:

npx skills add https://d5iwopk28bdhl.cloudfront.net/pr/0aecbf1425281e1d518582701856c9f83e14b6c7/

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.

2 participants