-
Notifications
You must be signed in to change notification settings - Fork 79
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DEP Replace react-dnd with dnd-kit #1527
base: 3.0
Are you sure you want to change the base?
DEP Replace react-dnd with dnd-kit #1527
Conversation
7ec8af0
to
f14a00f
Compare
c26d42d
to
e54fea8
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that I didn't split converting this or other components to functional as its own PR or commit because the lifycycle functions needed to be removed anyway. Converting it with the lifecycle events in-tact and then removing them separately would have been more work.
<div className={classnames(className, { 'gallery__main--dragging': this.state.dragging })}> | ||
return ( | ||
<div className={classnames(className, { 'gallery__main--dragging': dragging })}> | ||
<DndContext sensors={sensors} onDragStart={handleDragStart} onDragEnd={handleDragEnd} modifiers={[snapCenterToCursor]}> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried using built-in modifiers (including restrictToWindowEdges
) to restrict where we can drag the files, but none of them worked how I'd expect them to, so I opted to go without. The end result is the same unbound dragging as the old approach so it's not worse than it was before, at least.
if (this.props.item.type === 'folder') { | ||
thumbnailClassNames.push('gallery-item__thumbnail--folder'); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needed for styling the draglayer for folders
background: $white url("../../images/icon_archive.png") center center no-repeat; | ||
background: transparent url("../../images/icon_archive.png") center center no-repeat; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These changes were required to fix a problem where the background was being drawn over top of the border of the drag layer.
Note that I can't just use background-image
because that seems to be overridden by something elseand results in no thumbnail being displayed
getOffset() { | ||
const { | ||
offset, | ||
dragged, | ||
} = this.props; | ||
return { | ||
transform: offset && `translate(${offset.x + dragged.x}px, ${offset.y + dragged.y}px)`, | ||
}; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Offset stuff is handled by the snapCenterToCursor
modifier now
<GalleryItem item={{id: 2}} selectable={true} /> | ||
<GalleryItem item={{id: 2, exists: true, type: 'file', category: 'document'}} selectable={true} /> | ||
<GalleryItem item={{id: 2, exists: true, type: 'folder', category: 'folder'}} selectable={true} /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While updating styling, I had to render out these directly so I could mess with css in the browser.
I found that just an ID wasn't enough, so I've updated for an example for a file and for a folder, for future reference.
canDrag(props) { | ||
return props.canDrag; | ||
}, | ||
beginDrag(props) { | ||
const { id } = props.item; | ||
if (typeof props.onDrag === 'function') { | ||
props.onDrag(true, id); | ||
} | ||
const selected = props.selectedFiles.concat([]); | ||
if (!selected.includes(id)) { | ||
selected.push(id); | ||
} | ||
|
||
return { selected, props }; | ||
}, | ||
endDrag(props) { | ||
const { id } = props.item; | ||
if (typeof props.onDrag === 'function') { | ||
props.onDrag(false, id); | ||
} | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Handling what happens on drag/drop is done inside GalleryDND
instead.
@@ -952,7 +950,12 @@ class Gallery extends Component { | |||
ref={gallery => { this.gallery = gallery; }} | |||
> | |||
{this.renderTransitionBulkActions()} | |||
<GalleryDND className={galleryClasses.join(' ')}> | |||
<GalleryDND | |||
onDragStartEnd={(dragging) => this.handleEnableDropzone(!dragging)} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replaces handleDrag
in ThumbnailView
4728667
to
2c975bc
Compare
public function stepDragTheFileToTheFolder(string $fileName, string $folderName): void | ||
{ | ||
$file = $this->getGalleryItem($fileName)->find('xpath', "/ancestor-or-self::div[contains(@class, 'gallery-item__draggable')]"); | ||
Assert::assertNotNull($file, "File named {$fileName} could not be found or isn't draggable"); | ||
$folder = $this->getGalleryItem($folderName)->find('xpath', "/ancestor-or-self::div[contains(@class, 'gallery-item__droppable')]"); | ||
Assert::assertNotNull($folder, "Folder named {$folderName} could not be found or isn't droppable"); | ||
$file->dragTo($folder); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I couldn't use the existing I drag the "some element" element to the "some other element" element
method, because the only selectors available rely on fixed IDs which works locally but fails in CI.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Couple of weird things happening when I tested locally in firefox, neither of which happen in CMS 5
- After moving, the thumbnail animates back to its original location
- There's a red toast error when attempting to move to the parent folder. Only happens with moving files, not moving folders.
@@ -0,0 +1,34 @@ | |||
@javascript @assets @retry @job3 @gsat |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@javascript @assets @retry @job3 @gsat | |
@javascript @assets @retry @job3 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
If the parent folder is the root, this is a known regression that was already linked in the issue description. |
Server error still happens when trying to move files to the parent folder in deeply nested folders |
Can't reproduce. Please:
|
Good spot. Fixed. |
2c975bc
to
f9a4d8d
Compare
This PR replaces the
react-dnd
withdnd-kit
with like-for-like functionality, except:GalleryItemDragLayer
works now. The changes aren't fully compatible with CMS 5 so I won't be backporting the changes there, so#1016
needs to remain open.react-dnd
is actually coming from the browser itself with default HTML5 drag-and-drop functionality (see https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/dropEffect). That cursor is not selectable with CSS as far as I can tell.no-drop
cursor when dragging anywhere else, and only usegrabbing
for when we're over a valid drop target - but that wouldn't be consistent with cursors used in other drag-and-drop scenarios in the CMS. I'd recommend if we want to do that, it's handled in a wider-reaching card that standardises this approach.Ran
yarn upgrade
to get silverstripe/eslint-config#29Issue