react-spectrum
react-spectrum copied to clipboard
add previewOffset option to useDrag
Closes #5409
✅ Pull Request Checklist:
- [x] Included link to corresponding React Spectrum GitHub Issue.
- [x] Added/updated unit tests and storybook for this change (for new code or code which already has tests).
- [x] Filled out test instructions.
- [x] Updated documentation (if it already exists for this component).
- [x] Looked at the Accessibility Practices for this feature - Aria Practices
📝 Test Instructions:
Go to the story I added and drag.
https://github.com/adobe/react-spectrum/assets/1192452/ebe0358e-cc59-463b-9a92-9de5d495edb7
GET_BUILD
Build successful! 🎉
## API Changes
unknown top level export { type: 'any' } unknown top level export { type: 'any' } unknown top level export { type: 'any' } unknown top level export { type: 'any' } unknown top level export { type: 'any', access: 'private' } unknown top level export { type: 'any', access: 'private' } unknown top level export { type: 'any' } unknown top level export { type: 'any' } unknown top level export { type: 'any' } unknown top level export { type: 'any' } unknown top level export { type: 'identifier', name: 'Column' } unknown top level export { type: 'identifier', name: 'Column' } unknown type { type: 'link' } unknown type { type: 'link' } unknown type { type: 'link' } unknown type { type: 'link' } unknown type { type: 'link' } unknown type { type: 'link' } unknown top level export { type: 'any' } unknown top level export { type: 'any' } unknown top level export { type: 'any' } unknown top level export { type: 'any' } unknown top level export { type: 'any' } unknown top level export { type: 'any' }
@react-aria/dnd
DragOptions
DragOptions {
getAllowedDropOperations?: () => Array<DropOperation>
getItems: () => Array<DragItem>
hasDragButton?: boolean
onDragEnd?: (DragEndEvent) => void
onDragMove?: (DragMoveEvent) => void
onDragStart?: (DragStartEvent) => void
preview?: RefObject<DragPreviewRenderer>
+ previewOffset?: {
+ x: number
+ y: number
+} | 'center' | (DOMRect) => {
+ x: number
+ y: number
}
+}
it changed:
- useDrag
Hey, thank you for your patience! We finally got an API discussion on this. We'd like to change it so that the value can be changed if the drag preview changes. Such as if you have multiple Drag Previews for multiple data types.
We will need to update this in two places. https://github.com/adobe/react-spectrum/blob/main/packages/%40react-spectrum/dnd/src/useDragAndDrop.ts#L70 and https://github.com/adobe/react-spectrum/blob/d330a9dc13dd8376f5d2f8cdffcd7bce53a8fbf4/packages/%40react-aria/dnd/src/DragPreview.tsx#L18
The return type of both of these should be altered to be
JSX.Element | {element: JSX.Element, x:number, y:number}
Below is a rough sketch of the steps to implement it, there may be some holes.
Then in DragPreview we'd change the useImperativeHandler to something along these lines
useImperativeHandle(ref, () => (items: DragItem[], callback: (node: HTMLElement, x?: number, y?: number) => void) => {
// This will be called during the onDragStart event by useDrag. We need to render the
// preview synchronously before this event returns so we can call event.dataTransfer.setDragImage.
let result = render(items);
flushSync(() => {
setChildren(result.element);
});
// Yield back to useDrag to set the drag image.
callback(domRef.current, result.x, result.y);
...
And in https://github.com/adobe/react-spectrum/blob/d330a9dc13dd8376f5d2f8cdffcd7bce53a8fbf4/packages/%40react-aria/dnd/stories/dnd.stories.tsx#L449 we can use it roughly like so
return {
element: (
<div className={classNames(dndStyles, 'draggable', 'is-drag-preview', {'is-dragging-multiple': selectedKeys.size > 1})}>
...
</div>
),
x: 50,
y: 50
}
And then in useDrag https://github.com/adobe/react-spectrum/blob/d330a9dc13dd8376f5d2f8cdffcd7bce53a8fbf4/packages/%40react-aria/dnd/src/useDrag.ts#L132
if (typeof options.preview?.current === 'function') {
// console.log('options', options.preview.current)
options.preview.current(items, (node, xUser, yUser) => {
Going to close this one for now. We can reopen if it's picked up again or someone else can make a new PR