feat: PromptField#10191
Conversation
|
Build successful! 🎉 |
|
|
||
| let ref = useObjectRef(forwardedRef); | ||
| let [state, setState] = useControlledState(valueProp, defaultValueProp, onChange); | ||
| let graphemeSegmenter = useMemo(() => new Intl.Segmenter('en-US', {granularity: 'grapheme'}), []); |
There was a problem hiding this comment.
Todo: use correct locale
|
Build successful! 🎉 |
|
Build successful! 🎉 |
reidbarber
left a comment
There was a problem hiding this comment.
Just a few comments, but we can get this in for testing.
|
|
||
| return ( | ||
| <Autocomplete> | ||
| <TokenField |
There was a problem hiding this comment.
Can we increase the "hit area" for focusing the field? I think it should be a bit more generous since there isn't a border. We could even make it to where clicking anywhere in the PromptField that isn't already interactive focuses the field itself.
| ); | ||
| }; | ||
|
|
||
| export const Basic = () => ( |
There was a problem hiding this comment.
Might be good to add a maxHeight story since I assume most of these will have one when used.
| </PromptField> | ||
| ); | ||
|
|
||
| export const AsyncCompletions = () => ( |
There was a problem hiding this comment.
Should we render the Popover in a loading state while the completions are loading? Otherwise it might be confusing UX if the response is slow.
There was a problem hiding this comment.
We render the old results while the new ones are loading in ComboBox too. I think it would also be weird if the entire list flickered in and out swapping between a spinner and the menu as you typed each character. But perhaps we can find somewhere to show a loading state in addition to the old list, or some other skeleton-like way of showing the results are outdated...
| }, | ||
| transform: 'translate(-50%, -50%)' | ||
| })}> | ||
| <ProgressCircle aria-label="Uploading" value={props.uploadProgress} size="S" /> |
There was a problem hiding this comment.
yeah we'll need it for all the ai components, post release.
| onAction={() => { | ||
| let input = document.createElement('input'); | ||
| input.type = 'file'; | ||
| input.accept = 'image/*'; |
There was a problem hiding this comment.
Should this use acceptedAttachmentTypes?
| } | ||
|
|
||
| props.onSubmit?.(prompt, attachments); | ||
| setPrompt(new AutoLinkingSegmentList([])); |
There was a problem hiding this comment.
Should attachments be cleared too?
| aria-label="Attachments" | ||
| onRemove={keys => { | ||
| let removedAttachments = attachments.filter(attachment => keys.has(attachment.id)); | ||
| onRemoveAttachments?.(removedAttachments); |
There was a problem hiding this comment.
Should the input get focused after removing the last attachment?
|
Build successful! 🎉 |
## API Changes
react-aria-components/react-aria-components:Menu Menu <T> {
aria-describedby?: string
aria-details?: string
aria-label?: string
aria-labelledby?: string
autoFocus?: boolean | FocusStrategy
children?: ReactNode | (T) => ReactNode
className?: ClassNameOrFunction<MenuRenderProps> = 'react-aria-Menu'
defaultSelectedKeys?: 'all' | Iterable<Key>
dependencies?: ReadonlyArray<any>
disabledKeys?: Iterable<Key>
disallowEmptySelection?: boolean
escapeKeyBehavior?: 'clearSelection' | 'none' = 'clearSelection'
id?: string
items?: Iterable<T>
- onAction?: (Key) => void
+ onAction?: (Key, T) => void
onClose?: () => void
onSelectionChange?: (Selection) => void
render?: DOMRenderFunction<keyof React.JSX.IntrinsicElements, MenuRenderProps>
renderEmptyState?: () => ReactNode
selectionMode?: SelectionMode
shouldCloseOnSelect?: boolean
shouldFocusWrap?: boolean
slot?: string | null
style?: StyleOrFunction<MenuRenderProps>
}/react-aria-components:Popover Popover {
aria-describedby?: string
aria-details?: string
aria-label?: string
aria-labelledby?: string
arrowBoundaryOffset?: number = 0
arrowRef?: RefObject<Element | null>
boundaryElement?: Element = document.body
children?: ChildrenOrFunction<PopoverRenderProps>
className?: ClassNameOrFunction<PopoverRenderProps> = 'react-aria-Popover'
containerPadding?: number = 12
crossOffset?: number = 0
defaultOpen?: boolean
+ getTargetRect?: (Element) => DOMRect | null | undefined = target.getBoundingClientRect()
isEntering?: boolean
isExiting?: boolean
isKeyboardDismissDisabled?: boolean = false
isNonModal?: boolean
maxHeight?: number
offset?: number = 8
onOpenChange?: (boolean) => void
placement?: Placement = 'bottom'
render?: DOMRenderFunction<keyof React.JSX.IntrinsicElements, PopoverRenderProps>
scrollRef?: RefObject<Element | null> = overlayRef
shouldCloseOnInteractOutside?: (Element) => boolean
shouldFlip?: boolean = true
shouldUpdatePosition?: boolean = true
slot?: string | null
style?: StyleOrFunction<PopoverRenderProps>
trigger?: string
triggerRef?: RefObject<Element | null>
}/react-aria-components:MenuProps MenuProps <T> {
aria-describedby?: string
aria-details?: string
aria-label?: string
aria-labelledby?: string
autoFocus?: boolean | FocusStrategy
children?: ReactNode | (T) => ReactNode
className?: ClassNameOrFunction<MenuRenderProps> = 'react-aria-Menu'
defaultSelectedKeys?: 'all' | Iterable<Key>
dependencies?: ReadonlyArray<any>
disabledKeys?: Iterable<Key>
disallowEmptySelection?: boolean
escapeKeyBehavior?: 'clearSelection' | 'none' = 'clearSelection'
id?: string
items?: Iterable<T>
- onAction?: (Key) => void
+ onAction?: (Key, T) => void
onClose?: () => void
onSelectionChange?: (Selection) => void
render?: DOMRenderFunction<keyof React.JSX.IntrinsicElements, MenuRenderProps>
renderEmptyState?: () => ReactNode
selectionMode?: SelectionMode
shouldCloseOnSelect?: boolean
shouldFocusWrap?: boolean
slot?: string | null
style?: StyleOrFunction<MenuRenderProps>
}/react-aria-components:PopoverProps PopoverProps {
aria-describedby?: string
aria-details?: string
aria-label?: string
aria-labelledby?: string
arrowBoundaryOffset?: number = 0
arrowRef?: RefObject<Element | null>
boundaryElement?: Element = document.body
children?: ChildrenOrFunction<PopoverRenderProps>
className?: ClassNameOrFunction<PopoverRenderProps> = 'react-aria-Popover'
containerPadding?: number = 12
crossOffset?: number = 0
defaultOpen?: boolean
+ getTargetRect?: (Element) => DOMRect | null | undefined = target.getBoundingClientRect()
isEntering?: boolean
isExiting?: boolean
isKeyboardDismissDisabled?: boolean = false
isNonModal?: boolean
maxHeight?: number
offset?: number = 8
onOpenChange?: (boolean) => void
placement?: Placement = 'bottom'
render?: DOMRenderFunction<keyof React.JSX.IntrinsicElements, PopoverRenderProps>
scrollRef?: RefObject<Element | null> = overlayRef
shouldCloseOnInteractOutside?: (Element) => boolean
shouldFlip?: boolean = true
shouldUpdatePosition?: boolean = true
slot?: string | null
style?: StyleOrFunction<PopoverRenderProps>
trigger?: string
triggerRef?: RefObject<Element | null>
}/react-aria-components:DragTypes DragTypes {
- has: (string | symbol) => boolean
+ has: (DragType | Array<DragType>) => boolean
}@react-aria/dnd/@react-aria/dnd:DragTypes DragTypes {
- has: (string | symbol) => boolean
+ has: (DragType | Array<DragType>) => boolean
}@react-aria/menu/@react-aria/menu:MenuProps MenuProps <T> {
autoFocus?: boolean | FocusStrategy
children: CollectionChildren<T>
defaultSelectedKeys?: 'all' | Iterable<Key>
disabledKeys?: Iterable<Key>
disallowEmptySelection?: boolean
items?: Iterable<T>
- onAction?: (Key) => void
+ onAction?: (Key, T) => void
onClose?: () => void
onSelectionChange?: (Selection) => void
selectedKeys?: 'all' | Iterable<Key>
selectionMode?: SelectionMode
}/@react-aria/menu:AriaMenuProps AriaMenuProps <T> {
aria-describedby?: string
aria-details?: string
aria-label?: string
aria-labelledby?: string
autoFocus?: boolean | FocusStrategy
children: CollectionChildren<T>
defaultSelectedKeys?: 'all' | Iterable<Key>
disabledKeys?: Iterable<Key>
disallowEmptySelection?: boolean
escapeKeyBehavior?: 'clearSelection' | 'none' = 'clearSelection'
id?: string
items?: Iterable<T>
- onAction?: (Key) => void
+ onAction?: (Key, T) => void
onClose?: () => void
onSelectionChange?: (Selection) => void
selectedKeys?: 'all' | Iterable<Key>
selectionMode?: SelectionMode
}/@react-aria/menu:AriaMenuOptions AriaMenuOptions <T> {
aria-describedby?: string
aria-details?: string
aria-label?: string
aria-labelledby?: string
autoFocus?: boolean | FocusStrategy
defaultSelectedKeys?: 'all' | Iterable<Key>
disabledKeys?: Iterable<Key>
disallowEmptySelection?: boolean
escapeKeyBehavior?: 'clearSelection' | 'none' = 'clearSelection'
id?: string
isVirtualized?: boolean
items?: Iterable<T>
keyboardDelegate?: KeyboardDelegate
- onAction?: (Key) => void
+ onAction?: (Key, T) => void
onClose?: () => void
onKeyDown?: (KeyboardEvent) => void
onKeyUp?: (KeyboardEvent) => void
onSelectionChange?: (Selection) => void
selectionMode?: SelectionMode
shouldFocusWrap?: boolean
shouldUseVirtualFocus?: boolean
}@react-aria/overlays/@react-aria/overlays:AriaPositionProps AriaPositionProps {
arrowBoundaryOffset?: number = 0
arrowRef?: RefObject<Element | null>
arrowSize?: number = 0
boundaryElement?: Element = document.body
containerPadding?: number = 12
crossOffset?: number = 0
+ getTargetRect?: (Element) => DOMRect | null | undefined = target.getBoundingClientRect()
isOpen?: boolean
maxHeight?: number
offset?: number = 0
onClose?: () => void | null
placement?: Placement = 'bottom'
scrollRef?: RefObject<Element | null> = overlayRef
shouldFlip?: boolean = true
shouldUpdatePosition?: boolean = true
targetRef: RefObject<Element | null>
}/@react-aria/overlays:AriaPopoverProps AriaPopoverProps {
arrowBoundaryOffset?: number = 0
arrowRef?: RefObject<Element | null>
arrowSize?: number = 0
boundaryElement?: Element = document.body
containerPadding?: number = 12
crossOffset?: number = 0
+ getTargetRect?: (Element) => DOMRect | null | undefined = target.getBoundingClientRect()
groupRef?: RefObject<Element | null>
isKeyboardDismissDisabled?: boolean = false
isNonModal?: boolean
maxHeight?: number
placement?: Placement = 'bottom'
popoverRef: RefObject<Element | null>
scrollRef?: RefObject<Element | null> = overlayRef
shouldCloseOnInteractOutside?: (Element) => boolean
shouldFlip?: boolean = true
shouldUpdatePosition?: boolean = true
triggerRef: RefObject<Element | null>
}@react-spectrum/ai/@react-spectrum/ai:Attachment Attachment {
-
+ UNSAFE_className?: UnsafeClassName
+ UNSAFE_style?: CSSProperties
+ aria-describedby?: string
+ aria-details?: string
+ aria-label?: string
+ aria-labelledby?: string
+ 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?: StylesProp
+ target?: HTMLAttributeAnchorTarget
+ textValue?: string
+ uploadProgress?: number
+ value?: T
+ variant?: 'primary' | 'secondary' | 'tertiary' | 'quiet' = 'primary'
}/@react-spectrum/ai:AttachmentList-AttachmentList {
+AttachmentList <T> {
-
+ UNSAFE_className?: UnsafeClassName
+ UNSAFE_style?: CSSProperties
+ aria-describedby?: string
+ aria-details?: string
+ aria-label?: string
+ aria-labelledby?: string
+ children?: ReactNode | (T) => ReactNode
+ className?: string = 'react-aria-TagGroup'
+ defaultSelectedKeys?: 'all' | Iterable<Key>
+ dependencies?: ReadonlyArray<any>
+ disabledKeys?: Iterable<Key>
+ disallowEmptySelection?: boolean
+ escapeKeyBehavior?: 'clearSelection' | 'none' = 'clearSelection'
+ id?: string
+ items?: Iterable<T>
+ onAction?: (Key) => void
+ onRemove?: (Set<Key>) => void
+ onSelectionChange?: (Selection) => void
+ render?: DOMRenderFunction<keyof React.JSX.IntrinsicElements, undefined>
+ selectedKeys?: 'all' | Iterable<Key>
+ selectionBehavior?: SelectionBehavior = 'toggle'
+ selectionMode?: SelectionMode
+ shouldSelectOnPressUp?: boolean
+ slot?: string | null
+ style?: CSSProperties
+ styles?: StylesProp
}@react-spectrum/dnd/@react-spectrum/dnd:DragTypes DragTypes {
- has: (string | symbol) => boolean
+ has: (DragType | Array<DragType>) => boolean
}@react-spectrum/menu/@react-spectrum/menu:Menu Menu <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: CollectionChildren<{}>
defaultSelectedKeys?: 'all' | Iterable<Key>
disabledKeys?: Iterable<Key>
disallowEmptySelection?: boolean
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>
items?: Iterable<{}>
justifySelf?: Responsive<'auto' | 'normal' | 'start' | 'end' | 'flex-start' | 'flex-end' | 'self-start' | 'self-end' | 'center' | 'left' | 'right' | 'stretch'>
left?: Responsive<DimensionValue>
margin?: Responsive<DimensionValue>
marginBottom?: Responsive<DimensionValue>
marginEnd?: Responsive<DimensionValue>
marginStart?: 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
+ onAction?: (Key, {}) => void
onClose?: () => void
onSelectionChange?: (Selection) => void
order?: Responsive<number>
position?: Responsive<'static' | 'relative' | 'absolute' | 'fixed' | 'sticky'>
selectedKeys?: 'all' | Iterable<Key>
selectionMode?: SelectionMode
shouldFocusWrap?: boolean
start?: Responsive<DimensionValue>
top?: Responsive<DimensionValue>
width?: Responsive<DimensionValue>
zIndex?: Responsive<number>
}/@react-spectrum/menu:SpectrumMenuProps SpectrumMenuProps <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: CollectionChildren<T>
defaultSelectedKeys?: 'all' | Iterable<Key>
disabledKeys?: Iterable<Key>
disallowEmptySelection?: boolean
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>
items?: Iterable<T>
justifySelf?: Responsive<'auto' | 'normal' | 'start' | 'end' | 'flex-start' | 'flex-end' | 'self-start' | 'self-end' | 'center' | 'left' | 'right' | 'stretch'>
left?: Responsive<DimensionValue>
margin?: Responsive<DimensionValue>
marginBottom?: Responsive<DimensionValue>
marginEnd?: Responsive<DimensionValue>
marginStart?: 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
+ onAction?: (Key, T) => void
onClose?: () => void
onSelectionChange?: (Selection) => void
order?: Responsive<number>
position?: Responsive<'static' | 'relative' | 'absolute' | 'fixed' | 'sticky'>
selectedKeys?: 'all' | Iterable<Key>
selectionMode?: SelectionMode
shouldFocusWrap?: boolean
start?: Responsive<DimensionValue>
top?: Responsive<DimensionValue>
width?: Responsive<DimensionValue>
zIndex?: Responsive<number>
}@react-spectrum/overlays/@react-spectrum/overlays:Popover Popover {
UNSAFE_className?: string
UNSAFE_style?: CSSProperties
alignSelf?: Responsive<'auto' | 'normal' | 'start' | 'end' | 'center' | 'flex-start' | 'flex-end' | 'self-start' | 'self-end' | 'stretch'>
arrowBoundaryOffset?: number = 0
arrowRef?: RefObject<Element | null>
arrowSize?: number = 0
bottom?: Responsive<DimensionValue>
boundaryElement?: Element = document.body
children: ReactNode
container?: HTMLElement
containerPadding?: number = 12
crossOffset?: number = 0
disableFocusManagement?: boolean
enableBothDismissButtons?: boolean
end?: Responsive<DimensionValue>
flex?: Responsive<string | number | boolean>
flexBasis?: Responsive<number | string>
flexGrow?: Responsive<number>
flexShrink?: Responsive<number>
+ getTargetRect?: (Element) => DOMRect | null | undefined = target.getBoundingClientRect()
gridArea?: Responsive<string>
gridColumn?: Responsive<string>
gridColumnEnd?: Responsive<string>
gridColumnStart?: Responsive<string>
gridRowEnd?: Responsive<string>
gridRowStart?: Responsive<string>
groupRef?: RefObject<Element | null>
height?: Responsive<DimensionValue>
hideArrow?: boolean
isDisabled?: boolean
isHidden?: Responsive<boolean>
isKeyboardDismissDisabled?: boolean = false
isNonModal?: boolean
justifySelf?: Responsive<'auto' | 'normal' | 'start' | 'end' | 'flex-start' | 'flex-end' | 'self-start' | 'self-end' | 'center' | 'left' | 'right' | 'stretch'>
left?: Responsive<DimensionValue>
margin?: Responsive<DimensionValue>
marginBottom?: Responsive<DimensionValue>
marginEnd?: Responsive<DimensionValue>
marginStart?: Responsive<DimensionValue>
marginTop?: Responsive<DimensionValue>
marginX?: Responsive<DimensionValue>
marginY?: Responsive<DimensionValue>
maxHeight?: Responsive<DimensionValue>
maxWidth?: Responsive<DimensionValue>
minHeight?: Responsive<DimensionValue>
minWidth?: Responsive<DimensionValue>
offset?: number = 0
onBlurWithin?: (FocusEvent) => void
onDismissButtonPress?: () => void
onEnter?: () => void
onEntered?: () => void
onEntering?: () => void
onExit?: () => void
onExited?: () => void
onExiting?: () => void
onFocusWithin?: (FocusEvent) => void
onFocusWithinChange?: (boolean) => void
order?: Responsive<number>
placement?: Placement = 'bottom'
position?: Responsive<'static' | 'relative' | 'absolute' | 'fixed' | 'sticky'>
right?: Responsive<DimensionValue>
scrollRef?: RefObject<Element | null> = overlayRef
shouldCloseOnInteractOutside?: (Element) => boolean
shouldContainFocus?: boolean
shouldFlip?: boolean = true
shouldUpdatePosition?: boolean = true
start?: Responsive<DimensionValue>
state: OverlayTriggerState
top?: Responsive<DimensionValue>
triggerRef: RefObject<Element | null>
width?: Responsive<DimensionValue>
zIndex?: Responsive<number>
}@react-spectrum/s2/@react-spectrum/s2:ActionMenu ActionMenu <T> {
UNSAFE_className?: UnsafeClassName
UNSAFE_style?: CSSProperties
align?: 'start' | 'end' = 'start'
aria-describedby?: string
aria-details?: string
aria-label?: string
aria-labelledby?: string
autoFocus?: boolean
children: ReactNode | (T) => ReactNode
defaultOpen?: boolean
direction?: 'bottom' | 'top' | 'left' | 'right' | 'start' | 'end' = 'bottom'
disabledKeys?: Iterable<Key>
id?: string
isDisabled?: boolean
isOpen?: boolean
isQuiet?: boolean
items?: Iterable<T>
menuSize?: 'S' | 'M' | 'L' | 'XL' = 'M'
- onAction?: (Key) => void
+ onAction?: (Key, T) => void
onOpenChange?: (boolean) => void
shouldCloseOnSelect?: boolean
shouldFlip?: boolean = true
size?: 'XS' | 'S' | 'M' | 'L' | 'XL' = 'M'
}/@react-spectrum/s2:ContextualHelpPopover ContextualHelpPopover {
UNSAFE_className?: UnsafeClassName
UNSAFE_style?: CSSProperties
aria-describedby?: string
aria-details?: string
aria-label?: string
aria-labelledby?: string
children: ReactNode
containerPadding?: number = 12
crossOffset?: number = 0
+ getTargetRect?: (Element) => DOMRect | null | undefined = target.getBoundingClientRect()
hideArrow?: boolean = false
id?: string
+ isNonModal?: boolean
isOpen?: boolean
offset?: number = 8
onOpenChange?: (boolean) => void
padding?: 'default' | 'none' = 'default'
role?: 'dialog' | 'alertdialog' = 'dialog'
shouldFlip?: boolean = true
size?: 'S' | 'M' | 'L'
slot?: string | null
styles?: PopoverStylesProp
triggerRef?: RefObject<Element | null>
}/@react-spectrum/s2:Menu Menu <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>
disabledKeys?: Iterable<Key>
disallowEmptySelection?: boolean
escapeKeyBehavior?: 'clearSelection' | 'none' = 'clearSelection'
hideLinkOutIcon?: boolean
id?: string
items?: Iterable<T>
- onAction?: (Key) => void
+ onAction?: (Key, T) => void
onClose?: () => void
onSelectionChange?: (Selection) => void
selectedKeys?: 'all' | Iterable<Key>
selectionMode?: SelectionMode
shouldFocusWrap?: boolean
size?: 'S' | 'M' | 'L' | 'XL' = 'M'
slot?: string | null
styles?: StylesProp
}/@react-spectrum/s2:Popover Popover {
UNSAFE_className?: UnsafeClassName
UNSAFE_style?: CSSProperties
aria-describedby?: string
aria-details?: string
aria-label?: string
aria-labelledby?: string
children?: ReactNode
containerPadding?: number = 12
crossOffset?: number = 0
+ getTargetRect?: (Element) => DOMRect | null | undefined = target.getBoundingClientRect()
hideArrow?: boolean = false
id?: string
+ isNonModal?: boolean
isOpen?: boolean
offset?: number = 8
onOpenChange?: (boolean) => void
padding?: 'default' | 'none' = 'default'
role?: 'dialog' | 'alertdialog' = 'dialog'
shouldFlip?: boolean = true
size?: 'S' | 'M' | 'L'
slot?: string | null
styles?: PopoverStylesProp
triggerRef?: RefObject<Element | null>
}/@react-spectrum/s2:ActionMenuProps ActionMenuProps <T> {
UNSAFE_className?: UnsafeClassName
UNSAFE_style?: CSSProperties
align?: 'start' | 'end' = 'start'
aria-describedby?: string
aria-details?: string
aria-label?: string
aria-labelledby?: string
autoFocus?: boolean
children: ReactNode | (T) => ReactNode
defaultOpen?: boolean
direction?: 'bottom' | 'top' | 'left' | 'right' | 'start' | 'end' = 'bottom'
disabledKeys?: Iterable<Key>
id?: string
isDisabled?: boolean
isOpen?: boolean
isQuiet?: boolean
items?: Iterable<T>
menuSize?: 'S' | 'M' | 'L' | 'XL' = 'M'
- onAction?: (Key) => void
+ onAction?: (Key, T) => void
onOpenChange?: (boolean) => void
shouldCloseOnSelect?: boolean
shouldFlip?: boolean = true
size?: 'XS' | 'S' | 'M' | 'L' | 'XL' = 'M'
}/@react-spectrum/s2:ContextualHelpPopoverProps ContextualHelpPopoverProps {
UNSAFE_className?: UnsafeClassName
UNSAFE_style?: CSSProperties
aria-describedby?: string
aria-details?: string
aria-label?: string
aria-labelledby?: string
children: ReactNode
containerPadding?: number = 12
crossOffset?: number = 0
+ getTargetRect?: (Element) => DOMRect | null | undefined = target.getBoundingClientRect()
hideArrow?: boolean = false
id?: string
+ isNonModal?: boolean
isOpen?: boolean
offset?: number = 8
onOpenChange?: (boolean) => void
padding?: 'default' | 'none' = 'default'
role?: 'dialog' | 'alertdialog' = 'dialog'
shouldFlip?: boolean = true
size?: 'S' | 'M' | 'L'
slot?: string | null
styles?: PopoverStylesProp
triggerRef?: RefObject<Element | null>
}/@react-spectrum/s2:MenuProps MenuProps <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>
disabledKeys?: Iterable<Key>
disallowEmptySelection?: boolean
escapeKeyBehavior?: 'clearSelection' | 'none' = 'clearSelection'
hideLinkOutIcon?: boolean
id?: string
items?: Iterable<T>
- onAction?: (Key) => void
+ onAction?: (Key, T) => void
onClose?: () => void
onSelectionChange?: (Selection) => void
selectedKeys?: 'all' | Iterable<Key>
selectionMode?: SelectionMode
shouldFocusWrap?: boolean
size?: 'S' | 'M' | 'L' | 'XL' = 'M'
slot?: string | null
styles?: StylesProp
}/@react-spectrum/s2:PopoverProps PopoverProps {
UNSAFE_className?: UnsafeClassName
UNSAFE_style?: CSSProperties
aria-describedby?: string
aria-details?: string
aria-label?: string
aria-labelledby?: string
arrowRef?: RefObject<Element | null>
boundaryElement?: Element = document.body
children?: ChildrenOrFunction<PopoverRenderProps>
containerPadding?: number = 12
crossOffset?: number = 0
defaultOpen?: boolean
+ getTargetRect?: (Element) => DOMRect | null | undefined = target.getBoundingClientRect()
hideArrow?: boolean = false
isEntering?: boolean
isExiting?: boolean
+ isNonModal?: boolean
isOpen?: boolean
maxHeight?: number
offset?: number = 8
onOpenChange?: (boolean) => void
scrollRef?: RefObject<Element | null> = overlayRef
shouldFlip?: boolean = true
size?: 'S' | 'M' | 'L'
slot?: string | null
styles?: StyleString
trigger?: string
triggerRef?: RefObject<Element | null>
}/@react-spectrum/s2:DragTypes DragTypes {
- has: (string | symbol) => boolean
+ has: (DragType | Array<DragType>) => boolean
} |
Agent Skills ChangesModified (2)
InstallReact Spectrum S2: React Aria: |
LFDanLu
left a comment
There was a problem hiding this comment.
approving for testing, parital review
There was a problem hiding this comment.
early days for the AttachmentList so I sure either this hasn't been implemented/designed yet but might be nice to have a collapsed list for the attachments since it is a TagGroup.
There was a problem hiding this comment.
oh I guess that can actually be set since PromptFieldAttachmentList allows that prop?
| isFocused?: boolean; | ||
| } | ||
|
|
||
| function PromptTokenFieldPopover(props: PromptTokenFieldPopoverProps) { |
There was a problem hiding this comment.
would we consider somehow allowing users to customize some aspects of this (max width, flipping, etc)?
There was a problem hiding this comment.
if a usecase comes up, sure
| // TODO: do we want to export these? | ||
| export function setCursor(root: Element, pos: Position, fireEvent = false) { | ||
| setSelection(root, pos, pos, fireEvent); | ||
| } |
There was a problem hiding this comment.
are you imagining providing them as handy utils for people building their own TokenField?
There was a problem hiding this comment.
yeah possibly. I used them in the tests, and at least one of them for positioning the popover relative to the cursor position
| <PromptField onSubmit={handleSend} isGenerating={isPending}> | ||
| <div className={style({display: 'flex', gap: 16, alignItems: 'center'})}> | ||
| <PromptTokenField /> | ||
| <PromptFieldSubmitButton /> |
There was a problem hiding this comment.
minor since it is in the story styles but noticed the button is vertically centered when you add more lines to the field
| ); | ||
| }; | ||
|
|
||
| function ComboBoxTagInput() { |
There was a problem hiding this comment.
it might just be the logic in here but I noticed that deleting tokens via backspace didn't actually remove them from the selectedItems list
There was a problem hiding this comment.
ya the combobox example is incomplete for now
Implements a PromptField component for the S2 AI package, supporting text with inline tokens, attachments with dnd / paste support,
/commandsand@referenceautocomplete, plus menu, etc. Eventually the lower level TokenField will be used for other use cases as well.Changes in other packages:
getTargetRectprop to allow customizing the position to be relative to a character position or arbitrary rectangleisNonModaldependenciesimage/*)Many changes still to come. This is an initial version for internal testing.