feat: (WIP) support Textfields in collection components#10159
Conversation
…ection when in input field
the failing tests didnt focus the element when triggering a keypress
|
Build successful! 🎉 |
|
Build successful! 🎉 |
|
Build successful! 🎉 |
snowystinger
left a comment
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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
|
|
||
| // TODO: a change in behavior since taggroup is a gridlist with "tab" keyboard navigation behavior | ||
| // previously you could go to the next tab via arrow keys when you were focused on the close button | ||
| await user.keyboard('{Shift>}{Tab}{/Shift}'); |
There was a problem hiding this comment.
?
| await user.keyboard('{Shift>}{Tab}{/Shift}'); | |
| await user.tab({shift: true}); |
Do you think Tags should be special and differ on this? Not like they can have anything other than the button inside them? or do you think editable tags could be a thing?
There was a problem hiding this comment.
I feel like it might be odd to make an exception since it muddies the waters w/ regards to expected behavior. I do feel like editable tabs could be a thing, but I'm not sure if the experience would be more like our editable table or with an inline textfield
There was a problem hiding this comment.
some other exceptions/special cases that we will want to discuss:
- selection checkboxes in Table, feels a bit awkward that you have to tab into them now
- drag handles, same case as the checkboxes
- table column menus
- do we want to change the editable table row experience to use inline textfields now that is supported?
| // 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 |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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, |
There was a problem hiding this comment.
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
|
@snowystinger with regards to
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: |
|
Build successful! 🎉 |
## API Changes
react-aria-components/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: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: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: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/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/interactions/@react-aria/interactions:KeyboardProps KeyboardProps {
- allowComposing?: boolean
- allowRepeats?: boolean
isDisabled?: boolean
onKeyDown?: (KeyboardEvent) => void
onKeyUp?: (KeyboardEvent) => void
- shortcuts?: KeyboardShortcutBindings
}@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/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: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: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/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: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>
}@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
} |
Closes
✅ Pull Request Checklist:
📝 Test Instructions:
Test GridList/Table/Tree with textfield stories and test
keyboardNavigationBehavior=tabbehavior. 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 requireTabfrom the cell/row to the cell/row's content to interact with the children, andShift-Tabback 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=tabis net new as well🧢 Your Project:
RSP