feat: (WIP) Thread ai component#10045
Conversation
|
Build successful! 🎉 |
|
Build successful! 🎉 |
## API Changes
react-aria-components/react-aria-components:GridList GridList <T extends {}> {
aria-describedby?: string
aria-details?: string
aria-label?: string
aria-labelledby?: string
autoFocus?: boolean | FocusStrategy
children?: ReactNode | ({}) => ReactNode
className?: ClassNameOrFunction<GridListRenderProps> = 'react-aria-GridList'
defaultSelectedKeys?: 'all' | Iterable<Key>
dependencies?: ReadonlyArray<any>
disabledBehavior?: DisabledBehavior = 'all'
disabledKeys?: Iterable<Key>
disallowEmptySelection?: boolean
disallowTypeAhead?: boolean = false
dragAndDropHooks?: DragAndDropHooks<NoInfer<{}>>
escapeKeyBehavior?: 'clearSelection' | 'none' = 'clearSelection'
+ focusOnEntry?: 'first' | 'last'
id?: string
items?: Iterable<T>
keyboardNavigationBehavior?: 'arrow' | 'tab' = 'arrow'
layout?: 'stack' | 'grid' = 'stack'
onSelectionChange?: (Selection) => void
orientation?: Orientation = 'vertical'
render?: DOMRenderFunction<keyof React.JSX.IntrinsicElements, GridListRenderProps>
renderEmptyState?: (GridListRenderProps) => ReactNode
selectedKeys?: 'all' | Iterable<Key>
selectionBehavior?: SelectionBehavior = 'toggle'
selectionMode?: SelectionMode
shouldSelectOnPressUp?: boolean
slot?: string | null
style?: StyleOrFunction<GridListRenderProps>
}/react-aria-components:GridListProps GridListProps <T> {
aria-describedby?: string
aria-details?: string
aria-label?: string
aria-labelledby?: string
autoFocus?: boolean | FocusStrategy
children?: ReactNode | (T) => ReactNode
className?: ClassNameOrFunction<GridListRenderProps> = 'react-aria-GridList'
defaultSelectedKeys?: 'all' | Iterable<Key>
dependencies?: ReadonlyArray<any>
disabledBehavior?: DisabledBehavior = 'all'
disabledKeys?: Iterable<Key>
disallowEmptySelection?: boolean
disallowTypeAhead?: boolean = false
dragAndDropHooks?: DragAndDropHooks<NoInfer<T>>
escapeKeyBehavior?: 'clearSelection' | 'none' = 'clearSelection'
+ focusOnEntry?: 'first' | 'last'
id?: string
items?: Iterable<T>
keyboardNavigationBehavior?: 'arrow' | 'tab' = 'arrow'
layout?: 'stack' | 'grid' = 'stack'
onSelectionChange?: (Selection) => void
orientation?: Orientation = 'vertical'
render?: DOMRenderFunction<keyof React.JSX.IntrinsicElements, GridListRenderProps>
renderEmptyState?: (GridListRenderProps) => ReactNode
selectedKeys?: 'all' | Iterable<Key>
selectionBehavior?: SelectionBehavior = 'toggle'
selectionMode?: SelectionMode
shouldSelectOnPressUp?: boolean
slot?: string | null
style?: StyleOrFunction<GridListRenderProps>
}@react-aria/gridlist/@react-aria/gridlist:AriaGridListOptions AriaGridListOptions <T> {
aria-describedby?: string
aria-details?: string
aria-label?: string
aria-labelledby?: string
autoFocus?: boolean | FocusStrategy
defaultSelectedKeys?: 'all' | Iterable<Key>
disabledBehavior?: DisabledBehavior = 'all'
disabledKeys?: Iterable<Key>
disallowEmptySelection?: boolean
disallowTypeAhead?: boolean = false
escapeKeyBehavior?: 'clearSelection' | 'none' = 'clearSelection'
+ focusOnEntry?: 'first' | 'last'
id?: string
isVirtualized?: boolean
items?: Iterable<T>
keyboardDelegate?: KeyboardDelegate
layoutDelegate?: LayoutDelegate
linkBehavior?: 'action' | 'selection' | 'override' = 'action'
onAction?: (Key) => void
onSelectionChange?: (Selection) => void
selectedKeys?: 'all' | Iterable<Key>
selectionMode?: SelectionMode
shouldFocusWrap?: boolean = false
shouldSelectOnPressUp?: boolean
}@react-aria/selection/@react-aria/selection:AriaSelectableCollectionOptions AriaSelectableCollectionOptions {
allowsTabNavigation?: boolean
autoFocus?: boolean | FocusStrategy = false
disallowEmptySelection?: boolean = false
disallowSelectAll?: boolean = false
disallowTypeAhead?: boolean = false
escapeKeyBehavior?: 'clearSelection' | 'none' = 'clearSelection'
+ focusOnEntry?: 'first' | 'last'
isVirtualized?: boolean
keyboardDelegate: KeyboardDelegate
linkBehavior?: 'action' | 'selection' | 'override' = 'action'
ref: RefObject<HTMLElement | null>
selectOnFocus?: boolean = false
selectionManager: MultipleSelectionManager
shouldFocusWrap?: boolean = false
shouldUseVirtualFocus?: boolean
}/@react-aria/selection:AriaSelectableListOptions AriaSelectableListOptions {
allowsTabNavigation?: boolean
autoFocus?: boolean | FocusStrategy = false
collection: Collection<Node<unknown>>
disabledKeys: Set<Key>
disallowEmptySelection?: boolean = false
disallowSelectAll?: boolean = false
disallowTypeAhead?: boolean = false
escapeKeyBehavior?: 'clearSelection' | 'none' = 'clearSelection'
+ focusOnEntry?: 'first' | 'last'
isVirtualized?: boolean
keyboardDelegate?: KeyboardDelegate
layoutDelegate?: LayoutDelegate
linkBehavior?: 'action' | 'selection' | 'override' = 'action'
ref: RefObject<HTMLElement | null>
scrollRef?: RefObject<HTMLElement | null>
selectOnFocus?: boolean = false
selectionManager: MultipleSelectionManager
shouldFocusWrap?: boolean = false
shouldUseVirtualFocus?: boolean
}@react-aria/tree/@react-aria/tree:AriaTreeOptions AriaTreeOptions <T> {
aria-describedby?: string
aria-details?: string
aria-label?: string
aria-labelledby?: string
autoFocus?: boolean | FocusStrategy
defaultSelectedKeys?: 'all' | Iterable<Key>
disabledBehavior?: DisabledBehavior = 'all'
disabledKeys?: Iterable<Key>
disallowEmptySelection?: boolean
disallowTypeAhead?: boolean = false
escapeKeyBehavior?: 'clearSelection' | 'none' = 'clearSelection'
+ focusOnEntry?: 'first' | 'last'
id?: string
isVirtualized?: boolean
items?: Iterable<T>
keyboardDelegate?: KeyboardDelegate
layoutDelegate?: LayoutDelegate
linkBehavior?: 'action' | 'selection' | 'override' = 'action'
onAction?: (Key) => void
onSelectionChange?: (Selection) => void
selectedKeys?: 'all' | Iterable<Key>
selectionMode?: SelectionMode
shouldSelectOnPressUp?: boolean
}@react-spectrum/s2/@react-spectrum/s2:CardView CardView <T extends {}> {
UNSAFE_className?: UnsafeClassName
UNSAFE_style?: CSSProperties
aria-describedby?: string
aria-details?: string
aria-label?: string
aria-labelledby?: string
autoFocus?: boolean | FocusStrategy
children?: ReactNode | (T) => ReactNode
defaultSelectedKeys?: 'all' | Iterable<Key>
density?: 'compact' | 'regular' | 'spacious' = 'regular'
dependencies?: ReadonlyArray<any>
disabledBehavior?: DisabledBehavior = 'all'
disabledKeys?: Iterable<Key>
disallowEmptySelection?: boolean
disallowTypeAhead?: boolean = false
dragAndDropHooks?: DragAndDropHooks<NoInfer<T>>
escapeKeyBehavior?: 'clearSelection' | 'none' = 'clearSelection'
+ focusOnEntry?: 'first' | 'last'
id?: string
items?: Iterable<T>
layout?: 'grid' | 'waterfall' = 'grid'
loadingState?: LoadingState
onLoadMore?: () => void
onSelectionChange?: (Selection) => void
orientation?: Orientation = 'vertical'
renderActionBar?: ('all' | Set<Key>) => ReactElement
renderEmptyState?: (GridListRenderProps) => ReactNode
selectedKeys?: 'all' | Iterable<Key>
selectionMode?: SelectionMode
selectionStyle?: 'checkbox' | 'highlight' = 'checkbox'
shouldSelectOnPressUp?: boolean
size?: 'XS' | 'S' | 'M' | 'L' | 'XL' = 'M'
slot?: string | null
styles?: StylesPropWithHeight
variant?: 'primary' | 'secondary' | 'tertiary' | 'quiet' = 'primary'
}/@react-spectrum/s2:ListView ListView <T extends {}> {
UNSAFE_className?: UnsafeClassName
UNSAFE_style?: CSSProperties
aria-describedby?: string
aria-details?: string
aria-label?: string
aria-labelledby?: string
autoFocus?: boolean | FocusStrategy
children: ReactNode | ({}) => ReactNode
defaultSelectedKeys?: 'all' | Iterable<Key>
dependencies?: ReadonlyArray<any>
disabledBehavior?: DisabledBehavior = 'all'
disabledKeys?: Iterable<Key>
disallowEmptySelection?: boolean
disallowTypeAhead?: boolean = false
escapeKeyBehavior?: 'clearSelection' | 'none' = 'clearSelection'
+ focusOnEntry?: 'first' | 'last'
hideLinkOutIcon?: boolean
id?: string
isQuiet?: boolean
items?: Iterable<T>
onAction?: (Key) => void
onLoadMore?: () => void
onSelectionChange?: (Selection) => void
overflowMode?: 'wrap' | 'truncate' = 'truncate'
renderActionBar?: ('all' | Set<Key>) => ReactElement
renderEmptyState?: (GridListRenderProps) => ReactNode
selectedKeys?: 'all' | Iterable<Key>
selectionMode?: SelectionMode
selectionStyle?: 'highlight' | 'checkbox' = 'checkbox'
shouldSelectOnPressUp?: boolean
slot?: string | null
styles?: StylesPropWithHeight
}/@react-spectrum/s2:CardViewProps CardViewProps <T> {
UNSAFE_className?: UnsafeClassName
UNSAFE_style?: CSSProperties
aria-describedby?: string
aria-details?: string
aria-label?: string
aria-labelledby?: string
autoFocus?: boolean | FocusStrategy
children?: ReactNode | (T) => ReactNode
defaultSelectedKeys?: 'all' | Iterable<Key>
density?: 'compact' | 'regular' | 'spacious' = 'regular'
dependencies?: ReadonlyArray<any>
disabledBehavior?: DisabledBehavior = 'all'
disabledKeys?: Iterable<Key>
disallowEmptySelection?: boolean
disallowTypeAhead?: boolean = false
dragAndDropHooks?: DragAndDropHooks<NoInfer<T>>
escapeKeyBehavior?: 'clearSelection' | 'none' = 'clearSelection'
+ focusOnEntry?: 'first' | 'last'
id?: string
items?: Iterable<T>
layout?: 'grid' | 'waterfall' = 'grid'
loadingState?: LoadingState
onLoadMore?: () => void
onSelectionChange?: (Selection) => void
orientation?: Orientation = 'vertical'
renderActionBar?: ('all' | Set<Key>) => ReactElement
renderEmptyState?: (GridListRenderProps) => ReactNode
selectedKeys?: 'all' | Iterable<Key>
selectionMode?: SelectionMode
selectionStyle?: 'checkbox' | 'highlight' = 'checkbox'
shouldSelectOnPressUp?: boolean
size?: 'XS' | 'S' | 'M' | 'L' | 'XL' = 'M'
slot?: string | null
styles?: StylesPropWithHeight
variant?: 'primary' | 'secondary' | 'tertiary' | 'quiet' = 'primary'
}/@react-spectrum/s2:ListViewProps ListViewProps <T> {
UNSAFE_className?: UnsafeClassName
UNSAFE_style?: CSSProperties
aria-describedby?: string
aria-details?: string
aria-label?: string
aria-labelledby?: string
autoFocus?: boolean | FocusStrategy
children: ReactNode | (T) => ReactNode
defaultSelectedKeys?: 'all' | Iterable<Key>
dependencies?: ReadonlyArray<any>
disabledBehavior?: DisabledBehavior = 'all'
disabledKeys?: Iterable<Key>
disallowEmptySelection?: boolean
disallowTypeAhead?: boolean = false
escapeKeyBehavior?: 'clearSelection' | 'none' = 'clearSelection'
+ focusOnEntry?: 'first' | 'last'
hideLinkOutIcon?: boolean
id?: string
isQuiet?: boolean
items?: Iterable<T>
onAction?: (Key) => void
onLoadMore?: () => void
onSelectionChange?: (Selection) => void
overflowMode?: 'wrap' | 'truncate' = 'truncate'
renderActionBar?: ('all' | Set<Key>) => ReactElement
renderEmptyState?: (GridListRenderProps) => ReactNode
selectedKeys?: 'all' | Iterable<Key>
selectionMode?: SelectionMode
selectionStyle?: 'highlight' | 'checkbox' = 'checkbox'
shouldSelectOnPressUp?: boolean
slot?: string | null
styles?: StylesPropWithHeight
} |
| overflow: 'hidden', | ||
| flexGrow: 1 | ||
| })}> | ||
| {/* TODO: move this Virtualizer into the Thread component eventually when we get column reverse support */} |
There was a problem hiding this comment.
Have you thought about whether you will want virtualizer rects to be positioned in negative space, or should everything be converted to positive, similar to scroll offset?
There was a problem hiding this comment.
honestly haven't thought about it yet haha, would need to play around with the implementation to figure out the edge cases/pros/cons. I think you mentioned you were looking into this in another comment, have you been leaning one way or the other?
There was a problem hiding this comment.
Probably leaning towards doing this "just in time" by swapping "top" for "bottom" in layoutInfoToStyle(), aka normalizing to positive.
I'm working on low-level utils for this kind of stuff, yeah. Will hopefully land today since there is a bunch of complexity with different type of elements (root, iframe, etc.).
I'm primarily focused on scrollIntoView and usePreventScroll, so there won't be any overlap with your work. Hopefully yours will just get simpler with the additions 🙏
Closes
✅ Pull Request Checklist:
📝 Test Instructions:
🧢 Your Project: