Skip to content
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] Only trigger a swipe when appropriate #17993

Merged

Conversation

leMaik
Copy link
Member

@leMaik leMaik commented Oct 22, 2019

Fixes #17408, using @oliviertassinari's proposed solution.

Also, this fixes #16942, using the approach suggested here, taken from react-swipeable-views and simplified/adapted for the swipeable drawer.

I changed the temporary swipeable drawer demo to show the reproduction content on all sides, here's a video (Github doesn't let me upload webm files and the gif was way too big): demo.webm.zip

@mui-pr-bot
Copy link

mui-pr-bot commented Oct 22, 2019

@material-ui/core: parsed: +0.29% , gzip: +0.38%

Details of bundle changes.

Comparing: 36b8ac9...34c3c50

bundle Size Change Size Gzip Change Gzip
docs.main ▲ +1.07 kB (+0.18% ) 601 kB ▲ +349 B (+0.18% ) 191 kB
@material-ui/core[umd] ▲ +1.02 kB (+0.33% ) 307 kB ▲ +383 B (+0.43% ) 88.4 kB
SwipeableDrawer ▲ +1.02 kB (+1.15% ) 90.1 kB ▲ +365 B (+1.32% ) 28 kB
@material-ui/core ▲ +1.02 kB (+0.29% ) 348 kB ▲ +361 B (+0.38% ) 95.2 kB
@material-ui/lab -- 143 kB -- 44.6 kB
@material-ui/styles -- 50.8 kB -- 15.4 kB
@material-ui/system -- 14.8 kB -- 4.07 kB
AppBar -- 62.3 kB -- 19.5 kB
Avatar -- 61.1 kB -- 19.2 kB
Backdrop -- 66.2 kB -- 20.4 kB
Badge -- 63.8 kB -- 19.7 kB
BottomNavigation -- 60.8 kB -- 19 kB
BottomNavigationAction -- 73.8 kB -- 23.3 kB
Box -- 69.2 kB -- 20.9 kB
Breadcrumbs -- 66.4 kB -- 20.8 kB
Button -- 77.7 kB -- 24.1 kB
ButtonBase -- 72.2 kB -- 22.6 kB
ButtonGroup -- 62.6 kB -- 19.5 kB
Card -- 61.3 kB -- 19.2 kB
CardActionArea -- 73.3 kB -- 23.1 kB
CardActions -- 60.5 kB -- 18.9 kB
CardContent -- 60.4 kB -- 18.9 kB
CardHeader -- 63.5 kB -- 20 kB
CardMedia -- 60.8 kB -- 19.1 kB
Checkbox -- 80 kB -- 25.1 kB
Chip -- 69 kB -- 21.3 kB
CircularProgress -- 62.5 kB -- 19.7 kB
ClickAwayListener -- 3.85 kB -- 1.55 kB
Collapse -- 66.3 kB -- 20.5 kB
colorManipulator -- 3.83 kB -- 1.52 kB
Container -- 61.6 kB -- 19.2 kB
CssBaseline -- 56 kB -- 17.5 kB
Dialog -- 80.9 kB -- 25.1 kB
DialogActions -- 60.5 kB -- 18.9 kB
DialogContent -- 60.6 kB -- 19 kB
DialogContentText -- 62.5 kB -- 19.6 kB
DialogTitle -- 62.7 kB -- 19.7 kB
Divider -- 61 kB -- 19.1 kB
docs.landing -- 55.5 kB -- 14.5 kB
Drawer -- 82.7 kB -- 25.6 kB
ExpansionPanel -- 69.5 kB -- 21.7 kB
ExpansionPanelActions -- 60.5 kB -- 18.9 kB
ExpansionPanelDetails -- 60.4 kB -- 18.9 kB
ExpansionPanelSummary -- 76.3 kB -- 24.1 kB
Fab -- 75.1 kB -- 23.3 kB
Fade -- 22 kB -- 7.6 kB
FilledInput -- 71.5 kB -- 22.2 kB
FormControl -- 62.7 kB -- 19.4 kB
FormControlLabel -- 63.9 kB -- 20.1 kB
FormGroup -- 60.4 kB -- 18.9 kB
FormHelperText -- 61.7 kB -- 19.3 kB
FormLabel -- 61.7 kB -- 19.1 kB
Grid -- 63.5 kB -- 19.9 kB
GridList -- 60.9 kB -- 19.1 kB
GridListTile -- 62.1 kB -- 19.5 kB
GridListTileBar -- 61.6 kB -- 19.3 kB
Grow -- 22.6 kB -- 7.72 kB
Hidden -- 64.5 kB -- 20.2 kB
Icon -- 61.2 kB -- 19.1 kB
IconButton -- 74.4 kB -- 23.2 kB
Input -- 70.5 kB -- 22 kB
InputAdornment -- 63.5 kB -- 20 kB
InputBase -- 68.6 kB -- 21.5 kB
InputLabel -- 63.5 kB -- 19.8 kB
LinearProgress -- 63.7 kB -- 19.8 kB
Link -- 65 kB -- 20.6 kB
List -- 60.8 kB -- 18.9 kB
ListItem -- 75.4 kB -- 23.5 kB
ListItemAvatar -- 60.5 kB -- 18.9 kB
ListItemIcon -- 60.6 kB -- 19 kB
ListItemSecondaryAction -- 60.4 kB -- 18.9 kB
ListItemText -- 63.4 kB -- 19.9 kB
ListSubheader -- 61.2 kB -- 19.2 kB
Menu -- 86.6 kB -- 27.2 kB
MenuItem -- 76.4 kB -- 23.8 kB
MenuList -- 64.4 kB -- 20.1 kB
MobileStepper -- 66.2 kB -- 20.6 kB
Modal -- 14.2 kB -- 4.97 kB
NativeSelect -- 74.8 kB -- 23.5 kB
NoSsr -- 2.19 kB -- 1.04 kB
OutlinedInput -- 72.1 kB -- 22.4 kB
Paper -- 60.8 kB -- 18.9 kB
Popover -- 81 kB -- 25 kB
Popper -- 28.3 kB -- 10.2 kB
Portal -- 2.87 kB -- 1.29 kB
Radio -- 80.9 kB -- 25.4 kB
RadioGroup -- 61.7 kB -- 19.3 kB
Rating -- 68.3 kB -- 21.8 kB
RootRef -- 4.43 kB -- 1.67 kB
Select -- 112 kB -- 33.2 kB
Skeleton -- 60.9 kB -- 19.1 kB
Slide -- 24.1 kB -- 8.21 kB
Slider -- 73.7 kB -- 23.2 kB
Snackbar -- 75.6 kB -- 23.5 kB
SnackbarContent -- 64.2 kB -- 20.1 kB
SpeedDial -- 84.3 kB -- 26.5 kB
SpeedDialAction -- 113 kB -- 35.9 kB
SpeedDialIcon -- 63 kB -- 19.8 kB
Step -- 61 kB -- 19.1 kB
StepButton -- 80.6 kB -- 25.3 kB
StepConnector -- 61.1 kB -- 19.2 kB
StepContent -- 67.4 kB -- 21 kB
StepIcon -- 63.1 kB -- 19.6 kB
StepLabel -- 67 kB -- 21 kB
Stepper -- 63.3 kB -- 19.9 kB
styles/createMuiTheme -- 15.2 kB -- 5.36 kB
SvgIcon -- 61.5 kB -- 19.1 kB
Switch -- 79.3 kB -- 24.7 kB
Tab -- 74.6 kB -- 23.6 kB
Table -- 61 kB -- 19.1 kB
TableBody -- 60.5 kB -- 18.9 kB
TableCell -- 62.5 kB -- 19.6 kB
TableFooter -- 60.5 kB -- 18.9 kB
TableHead -- 60.5 kB -- 18.9 kB
TablePagination -- 138 kB -- 40.3 kB
TableRow -- 60.9 kB -- 19.1 kB
TableSortLabel -- 75.6 kB -- 23.9 kB
Tabs -- 83.7 kB -- 26.7 kB
TextareaAutosize -- 5.06 kB -- 2.11 kB
TextField -- 120 kB -- 35.1 kB
ToggleButton -- 74.4 kB -- 23.5 kB
ToggleButtonGroup -- 61.6 kB -- 19.3 kB
Toolbar -- 60.7 kB -- 19 kB
Tooltip -- 97.5 kB -- 30.9 kB
TreeItem -- 71.8 kB -- 22.6 kB
TreeView -- 64.4 kB -- 20.2 kB
Typography -- 62.1 kB -- 19.3 kB
useMediaQuery -- 2.49 kB -- 1.05 kB
Zoom -- 22.1 kB -- 7.61 kB

Generated by 🚫 dangerJS against 34c3c50

@oliviertassinari oliviertassinari added the component: SwipeableDrawer The React component. label Oct 23, 2019
Copy link
Member

@oliviertassinari oliviertassinari left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great start ✌️

@@ -201,6 +278,19 @@ const SwipeableDrawer = React.forwardRef(function SwipeableDrawer(props, ref) {
const currentX = calculateCurrentX(anchorRtl, event.touches);
const currentY = calculateCurrentY(anchorRtl, event.touches);

if (open && paperRef.current.contains(event.target)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think of introducing a nodeWhoClaimedTheScroll like variable back? I think that we can improve the UX by disabling the swipe for all the touch session if we have found one native scroll handler. Does it make sense, I can provide more detail if needed.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By not doing the touch start, everything works just fine. I don't see why introducing a global lock would help.

Copy link
Member

@oliviertassinari oliviertassinari Oct 24, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have observed two issues using this logic:

  1. Once you reach the end of the native scroll, the drawer starts to drag. If you look at the behavior of nested scroll containers, you would need to reach the end of the scrollbar with the nested container and start a new interaction to scroll the parent. In this demo, I don't think that the drawer should start to drag. It's the behavior implemented react-swipeable-views, I think that it's more intuitive/less disturbing.

double interactions

  1. Because of 1., something else happens:
    jump

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this demo, I don't think that the drawer should start to drag.

I liked that behavior, but I see why it may not be desired. Regarding point 2: oh... Allright, 1. should fixed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regarding 1. I have a strong conviction that we should allow a single scroll container, per touch session (start, move, end).

I'm no longer sure that 2. is strictly related to 1. I think that it requires further investigation.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I fixed both issues by re-introducing nodeThatClaimedTheSwipe. It isn't used for inter-drawer locking anymore, but for drawer vs. scrollable container inside that drawer locking, that's why it's updating while moving (to fix the behavior in your gif).

@oliviertassinari oliviertassinari added the bug 🐛 Something doesn't work label Oct 23, 2019
@leMaik
Copy link
Member Author

leMaik commented Oct 23, 2019

@oliviertassinari I can't get the tests to work. 😭 The touchstart events need to be raised on the drawer's paper (or the backdrop; do fulfill the new target check) as target if the drawer is open (that's simple to do), but I can't get a reference to that paper/backdrop somehow.

@oliviertassinari
Copy link
Member

@leMaik Let met know if you need help with this effort. I should be able to find the time next week.

@leMaik
Copy link
Member Author

leMaik commented Oct 26, 2019

@leMaik Let met know if you need help with this effort. I should be able to find the time next week.

Thank you! 👍 I looked into the tests again and just fixed them by adding an wrapper.update() call after setProps; seems to be required when changing open to update everything properly. I'm done so far. 🎉

@mui mui deleted a comment from codesandbox-ci bot Oct 28, 2019
@oliviertassinari
Copy link
Member

Awesome, I will have a look at the changes later today. I had a quick look, I might have spotted some possible edge cases, but nothing confirmed yet.

@oliviertassinari oliviertassinari changed the title [SwipeableDrawer] Fix native scrolling in the drawer and prevent swiping through overlayed components [SwipeableDrawer] Only trigger a swipe when appropriate Oct 30, 2019
@oliviertassinari oliviertassinari merged commit 9d485f8 into mui:master Oct 30, 2019
@oliviertassinari
Copy link
Member

@leMaik Well done 👏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug 🐛 Something doesn't work component: drawer This is the name of the generic UI component, not the React module! component: SwipeableDrawer The React component.
Projects
None yet
3 participants