-
Notifications
You must be signed in to change notification settings - Fork 384
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
Allow drag to different page #3312
Conversation
_Fixes #3311._ This WIP allows editors to drag elements to neighboring pages. This is done by while dragging, detecting where the actual mouse cursor is relative to the current page. A highlight callback is invoked while dragging with the offset of the page currently under the cursor. If dropped above a neighboring page, a drop callback is invoked. The callbacks then check if there even is a neigbor in this direction and then either highlight that page or clone the element to that page. It doesn't work correctly for CTA's and Page Attachments yet. The code is also a little weirdly structured with the bulk of the logic placed in `block-draggable`, which doesn't really sound like the right place - concern-wise. Perhaps a simple renaming solves it, but perhaps a larger restructuring is in order.
assets/src/stories-editor/components/block-mover/block-draggable.js
Outdated
Show resolved
Hide resolved
CTA blocks have their positions defined by a different property than regular blocks, 'btnPositionLeft` rather than `positionLeft` and similarly for top. This fixes that. Also, CTA blocks aren't allowed on the first page. This invariant is also maintained now.
assets/src/stories-editor/components/block-mover/block-draggable.js
Outdated
Show resolved
Hide resolved
assets/src/stories-editor/components/block-mover/block-draggable.js
Outdated
Show resolved
Hide resolved
assets/src/stories-editor/components/block-mover/block-draggable.js
Outdated
Show resolved
Hide resolved
assets/src/stories-editor/components/block-mover/block-draggable.js
Outdated
Show resolved
Hide resolved
assets/src/stories-editor/components/block-mover/block-draggable.js
Outdated
Show resolved
Hide resolved
This PR really needs e2e tests. I would also look rebasing and running those e2e tests against AXE for accessibility. I would look aria-grabbed and aria-dropeffect accessibility attributes. These attributes will likely need to be updated dynamically blocks move. |
We might want to update using the screen reader feature using speak. We might want to update these users that the drag was / wasn't successful. |
I'm having problems getting the e2e setup to properly test these. It might be because those tests are just too power-intensive for my machine though (which is bad!). Also, e2e's aren't meant for exhaustive testing in any way. It's an anti-pattern if e2e's are used for this. e2e should only be used for some very overall happy-path testing to ensure, that overall dragging works as expected. Unit and integration testing should be done to validate the finer things. |
FWIW we've had issues in the past with testing dragging as Chromium/Puppeteer doesn't have the best support there. |
Uh, that's a simple yet interesting package. It could definitely be used here. But maybe the overall a11y of dragging should be considered in some strategy rather than hotfixes I can attempt with |
I agree here, my understanding of However the aria-grabbed and aria-dropeffect accessibility attributes seem simple enough to implement here and would be a good start. This feature is not an accessibility friendly one in the first place, as most people with accessibility needs will be using screen readers or keyboard anyway. Which is why #3330 would be better for those users. |
Several locations checked if a block was allowed on a given page, including the media inserter, the shortcut handler, paste handler and now also multi-page drag handler. All these instances have now been a) centralised and b) changed to use the built-in method of checking for allowed blocks inside another block using core block editor functionality. This also removed the need for a specific test for the `ensureAllowedBlocksOnPaste` as it just used other functions now more specific and central to the issue.
The recent refactor of the "is block A allowed on page B" functionality touches on a lot of extra components, that will need to be QA'ed as well: Media Inserter, Shortcuts, Paste Block. Just FYI for future reference. |
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.
Really great work on the refactor to use hooks. The code is much clearer.
Just a couple of tweaks, questions and comments to be added. Otherwise, we are looking good 👍
Work noting that they are conflicts that need to be resolved.
This converts the helper function `isBlockAllowedOnPage` to the hook `useIsBlockAllowedOnPage` which ensures that selectors are properly updated once the registry changes and any component using it is properly re-rendered. However, because some uses of `isBlockAllowedOnPage` is located in class components, the old function has only been deprecated for now, not completely removed.
Making `attributes` optional and adding unit tests for all aspects of the hook.
@spacedmonkey Could you re-review this? |
@@ -52,6 +52,7 @@ import { addQueryArgs } from '@wordpress/url'; | |||
import BlockPreview from '../block-preview'; | |||
import BlockTypesList from '../block-types-list'; | |||
import { ALLOWED_TOP_LEVEL_BLOCKS } from '../../constants'; | |||
import { isBlockAllowedOnPage } from '../../helpers'; |
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.
Why can't the hook be used here?
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.
Because this is still a class component, not a functional one. See #2538 for explanation.
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 am just worried about bug coming from not using select correctly here and getting stale data.
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.
Isn't the benefit of hooks if that you put them everyone and mix and match?
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.
How that isBlockAllowedOnPage
is only used in Menu
, I think we should get rid of the helper and move the logic to withSelect
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.
That could work yeah 👍
This bug is still happening for me on the latest update. |
Hmm that seems to be because the drop zone around a page is a bit bigger than the page itself, to allow for better positioning of elements. |
This way it can use the new `useIsBlockAllowedOnPage` hook
So, the thing is, you're allowed to drop items off-page if you feel like it – but only within a certain boundary off-page. The general item drop is handled in However, in this case it gets extra weird, because off-page is technically on top of another page, that you just can't move the item to. I don't know if there's an easy way to handle this, that doesn't impact too many other things and doesn't feel like a workaround and special-case-handling. I'll look into this drop zone, and maybe limit the drop zone so it never overlaps a neighbouring page - seems like a fair restriction. |
Remove last remaining usage of that function as all other components use the new `useIsBlockAllowedOnPage` hook.
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.
LGTM
Given that the situation with the drop zone mentioned above has been around before, it can be addressed in a separate PR |
Fixes #3311.
This PR allows editors to drag elements to other pages.
See early demo here: https://www.youtube.com/watch?v=ONFOvRF2jog
This is done by while dragging, detecting where the actual mouse cursor is relative to the current page. A highlight callback is invoked while dragging with the offset of the page currently under the cursor. If dropped above another page, a drop callback is invoked.
The callbacks then check if there even is a page in this direction and then either highlight that page or clone the element to that page respectively.
TODO