-
-
Notifications
You must be signed in to change notification settings - Fork 32.4k
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
[SwipeableDrawer] Add callback to customise touchstart ignore for swipeable drawer #30759
Conversation
|
Could you please create an issue/codeasndbox illustrating what is the problem and how it can be solved. It's hard to follow based on the PR description what is the issue you are trying to solve. |
👋 The migration PR has been merged. Please follow these steps to make sure that the contents are all updated. (Sorry for the inconvenience)
If you are struggle with the steps above, feel free to tag @siriwatknp |
The if (!open) {
if (
disableSwipeToOpen ||
!(
nativeEvent.target === swipeAreaRef.current ||
(detectSwipeWithinChildren && paperRef.current?.contains(nativeEvent.target))
)
) {
return;
}
// ...
} @mnajdova, @hbjORbj - could you also take a look at this, please? |
The reason I made it a callback is so you could customise which children you want to be able to swipe with, and not assume all of them. So this is the code we're using for that: swipeAreaIgnoreTouchStartEvent={(e, swipeArea) => {
const target = e.target as HTMLElement;
return target.closest(".MuiSlider-root") != null;
}} |
Maybe making it a So the default would be something like:
Edit: |
There is a problem with this that I have discovered (although, it's a new problem, not one that breaks previous functionality). If you have a button in a swipeable edge of a drawer, then you can click on it with this PR's fix.
The key part being the last part:
Because the touchstart & subsequently mousemove events causes a load of changes (like classes and stuff), it causes further mouse events to be cancelled, and not happen at all. The way to fix this would be to prevent any changes on iOS until actually moving, however, that directly contradicts with drawer discovery. Edit: fixed in 74d2c81 |
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.
* | ||
* @default false | ||
*/ | ||
AllowSwipeInChildren?: |
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.
Use camel case in prop names
AllowSwipeInChildren?: | |
allowSwipeInChildren?: |
Hi there. You may want to look into the other PR I have done (#30763). |
Let's add tests and docs for this new behavior and do one final review :) |
Looking forward to seeing this feature coming to master. Anything that can be helped with to progress with that? |
Sorry, I do apologise. I have very little free time to work on this. I'll see if I can do it this week. |
I apologise for how long it has taken, but I have finally had time and finished the tests for this prop. |
@tech-meppem I just ran into this and needed this as well - what are the odds - 7 days ago :p @mnajdova figured I would tag in case it fell off the radar |
@hbjORbj @michaldudak checking back in on this PR to avoid maintaining a patch package for a while :p |
Coming back to this PR after some time, as I was working on some issues related to the |
I did make it so that you can use either a boolean, or a function. The reason for this is because there is some weird interactivity with sliders & buttons, but also there's the use-case if you want a specific drag-handle, rather than everything. There was a problem when using this patch when I originally made it as a boolean, when it came to sliders in drawers (our main use-case for this). It would move both the slider & drawer at the same time, depending on what you did first. If you started swiping horizontally, then the slider would consume the event, and the drawer wouldn't open on swiping up or down. I've managed to recreate the problem I encountered just editing the swipeable-drawer demo slightly (with mobile touch emulation): I think it just makes more sense to allow both, especially as that's how it's currently working. |
startMaybeSwiping(); | ||
|
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.
startMaybeSwiping(); |
This looks unrelated to the changes, it can create some changes in the behavior.
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 was to fix the problem listed here:
#30759 (comment)
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.
This looks like the only blocker at this moment.
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.
Just realised I didn't set force to true.
The call here is meant to have the param true
to force it.
I'll update that, and can change the comment as suggested below if wanted to.
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've pushed the change.
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.
We need a test for this. This component is already loaded, so if we decide to refactor in the future, we may remove this without a test.
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.
Or even better, let's create an issue + a separate fix for it, as it doesn't seem much related to these changes.
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.
It's here because it was only affecting interactivity with components (such as buttons) inside a swipeable edge drawer.
It's an issue that only affects the contents of the drawer, which previously, were not interactable.
I agree that it could be split out, however to test it, you would need the changes from this PR to be able to interact with the contents of the drawer & trigger the drawer simultaneously, which is where the issue is triggered.
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.
Ok, we can then either create a follow up PR, or add the test now. Whatever works better for you :)
* Callback to determine what children of the drawer the user can use to drag open the drawer. | ||
* Can be a custom function to control the behavior. | ||
* Set or return true / false to allow / disallow the swipe event. |
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.
* Callback to determine what children of the drawer the user can use to drag open the drawer. | |
* Can be a custom function to control the behavior. | |
* Set or return true / false to allow / disallow the swipe event. | |
* If set to true the swipe event will open the drawer even if it starts over some of its children. | |
* It can be useful in scenarios where the drawer is partially visible. | |
* Can be further customized by a callback to determine which children the user can drag over to open the drawer (for e.g. to ignore other elements that handle the touch move events, like sliders). |
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've restructured a bit to start with the "most common" usage first. Then I explained a possible scenario, and then finished with the least common use-case. cc @samuelsycamore for a final checkup on the wording.
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.
cc @samuelsycamore pinging you again
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.
Sorry I missed this the first time! I'm not sure exactly what is meant here:
even if it starts over some of its children
Is there another way to phrase this?
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.
It is related to the drag event. You started dragging over some children element. Considering your comment, this would be confusing for other users of the library too :\
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.
@michaldudak maybe you can help here to unblock the PR, the only thing left as far as I remember is the prop descriotion. Sam is on PTO, so I don't expect him to respond, and the PR has been sitting for quite some time.
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'm back! 😁 How does this sound?
* Callback to determine what children of the drawer the user can use to drag open the drawer. | |
* Can be a custom function to control the behavior. | |
* Set or return true / false to allow / disallow the swipe event. | |
* If set to true, the swipe event will open the drawer even if the user begins the swipe on one of the drawer's children. | |
* This can be useful in scenarios where the drawer is partially visible. | |
* You can customize it further with a callback that determines which children the user can drag over to open the drawer (for example, to ignore other elements that handle touch move events, like sliders). |
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.
Sam's suggestion looks good. I merged in the latest master and fixed all the conflicts. It should be good to go now.
Thanks a lot for the contribution & patience @tech-meppem It took us a while to get this one in. Good work 👌 |
Currently with SwipeableDrawer, if you have a button inside a swipeable edge (following the demo), then you cannot click on it due to
pointer-events: none
being applied.You can easily set
pointer-events: all
to reallow clicking the button.However, this means you can no longer click and drag the button to open the drawer, making a large area of the drawer's edge unswipeable.
Looking through the source, I discovered that this line was the problem:
if (disableSwipeToOpen || nativeEvent.target !== swipeAreaRef.current) {
This PR adds a callback that allows overriding of this behaviour, allowing for custom filtering of which elements / target elements can also be used to drag the drawer.
Edit:
Created issue thread: #30805