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

Use either one of click / tap handlers in menus #581

Closed
wants to merge 4 commits into from

Conversation

pomerantsev
Copy link
Contributor

Fixes #366.

This PR fixes a real issue, but even if @hai-cea and @mmrtnz don't like the implementation, I'd like to discuss whether it's a good idea to consistently use either onClick or onTouchTap in the API.
I'm not sure if it makes any sense to use both onClick and onTouchTap on the same element. onClick does the same thing as onTouchTap, only 300ms later on some devices.
So my proposal is to only use onTouchTap on native elements (since the project depends on react-tap-event-plugin anyway), and to use the Click idiom for all material-ui components, just because everyone's used to it.
Although using onClick directly on a component which internally transforms it into an onTouchTap is a bit confusing, so instead, I would prefer to have a property called onItemClick or something (see PR).

If you're happy with this approach, you could merge it, and I could proceed with the rest of the codebase.

@hai-cea
Copy link
Member

hai-cea commented May 10, 2015

@pomerantsev Yeh, I agree that using both onClick and onTouchTap doesn't make sense. I think part of the problem is the bad design on the menu item component and we should strive for a more DOM like structure see (#27).

With that said, we need to do something to resolve this issue in the mean time. I prefer to just use onTouchTap, which is what you seem to be doing. However, the props are still named onItemClick?

@pomerantsev
Copy link
Contributor Author

@hai-cea As I said, any name will do, but I feel that naming it something different from onClick and onTouchTap lets us help the developer worry less about the implementation (is it a real browser-generated click, or is it the synthetic tap event?) and focus on the action itself (the user pressing the element with whatever pointing device they have).

@hai-cea
Copy link
Member

hai-cea commented May 13, 2015

@pomerantsev What do you think about using react-tappable instead of react-tap-event-plugin? It seems to be better and we can just use onTap.

https://github.com/JedWatson/react-tappable

@pomerantsev
Copy link
Contributor Author

@hai-cea Looks like react-tappable has a couple of nice abstractions (Press and Pinch events), but I'm not sure if using its Tap is any better than react-tap-event-plugin's TouchTap. It's just that it has a slightly different API, so instead of <div onTouchTap={...} /> it will be <Tappable component="div" onTap={...} />.
Do you think such a change is necessary? Or are we going to make use of Press or Pinch events?

@pomerantsev
Copy link
Contributor Author

@hai-cea Should we get back to this discussion? Anything stopping you from introducing this breaking change for the sake of consistency?

@hai-cea
Copy link
Member

hai-cea commented Jun 3, 2015

@pomerantsev Thanks for pushing this discussion.

One thing I'm not sure about is if we should introduce a new synthetic event to a UI library. The original idea was to build our components as flexible as possible so that developers can choose which events they want to listen to - just like native elements. That is the reason behind exposing both onItemClick and onItemTap.

With that said, it sounds like there are problems with this approach?

@pomerantsev
Copy link
Contributor Author

@hai-cea Sorry, I guess I lost the point of this discussion :).
As I see it, here's the big problem (correct me if I'm wrong): to deal with the 300ms delay, react-tap-event-plugin has been introduced to the project, but with it came confusion as to what to expose in the API, and it's also a source of subtle bugs like #366.
There are two ways to deal with this problem:

  1. Give developers freedom to use onClick or onTouchTap at their will. The only thing that would be good to take care of in this case is warning developers if they're attaching handlers to both (I can't think of a usecase where we would want to handle these differently).
  2. Hide this as an implementation detail and use onTouchTap throughout the project. This way we would only have to come up with a consistent naming scheme for properties attaching an event handler to onTouchTap on some internal element.

Looks like you're in favor of the first approach, whereas I like the second better. But I totally understand that it's not a question of my personal preference.

Some examples from various components:

  • app-bar.jsx: onLeftIconButtonTouchTap and onRightIconButtonTouchTap (no click handlers)
  • dialog-window.jsx: onClickAway (which is bound to touchTap)
  • drop-down-icon.jsx: closeOnMenuItemClick (which is bound to click)
  • enhanced-button.jsx: onTouchTap (bound to onTouchTap, although nothing prevents the user from also attaching an onClick handler)
  • input.jsx: has an onClick handler for the placeholder item, but no onTouchTap
  • left-nav.jsx: has an onTouchTap handler for the overlay, but no onClick.

I guess I could come up with more examples, but you can see that the use of onClick and onTouchTap is inconsistent both internally and externally (in the API). I would like to find a solution that would help both users of this library and contributors. And I think we can figure it out.
Do you think some research should be done on this matter? Or let me know if you want me to at least document all uses of onClick and onTouchTap in material-ui - I could spend some time on that, so that it's easier to make decisions based on facts rather than speculation.

@hai-cea
Copy link
Member

hai-cea commented Jun 3, 2015

Thanks @pomerantsev - It was my fault for taking so long to get my thoughts together on this.

I think some more research will definitely be helpful. The examples you have given so far are definitely short comings of the current components and I think we can address them on a case by case basis?

Also, is your preference for the 2nd approach because of simplicity for developers?

@pomerantsev
Copy link
Contributor Author

@hai-cea Okay, I guess you're right that this confusion is not the problem of material-ui, but rather of React and the fact that they introduced onTouchTap on top of onClick.
In Angular, for example, there's an angular-touch module, which, if included in the project, replaces the ng-click directive, so that it doesn't react to the native click event, but rather to touchstart and touchend (which is the solution to the 300ms problem).
We don't have this in React (and I'm not sure if it's easy to write a plugin that would substitute the onClick event), so in the meanwhile we're stuck with two events that are nearly the same.

After looking more closely at the code, I see that there are several specific issues instead of a single big one - which makes them easier to deal with.

  1. Issue LeftNav doesn't play with iOS fullscreen mode #366 that we've been trying to deal with in the first place. I've decided to create a new PR for it (Fix left-nav behavior in full-screen #751) - it fixes only one thing now.
  2. There's a single place where using onClick or onTouchTap will yield significantly different results. It's the Dialog component. If you pass an onClick handler in its actions array, it'll run it. Not so for the onTouchTap handler (it'll simply dismiss the dialog). I've fixed it in Make it possible to pass an onTouchTap handler to a dialog action #752.
  3. There are API inconsistencies: closeOnMenuItemClick (DropDownIcon), onLeftIconButtonTouchTap and onRightIconButtonTouchTap (AppBar), onActionTouchTap (SnackBar), handleTouchTap (Tab), onItemClick and onItemTap (Menu). Would you suggest something? Or should we just live with these names? I can create a separate issue though.
  4. Using onClick internally. Fixed in Consistently use onTouchTap instead of onClick internally #753.
  5. Also, the click event is used in the ClickAwayable mixin. I can create a separate issue for it.

So, with all the aforementioned changes, I think this PR can be closed. I don't feel that there's a huge need to remove onItemClick any more.
I'm not sure how to properly address this duplication made by React unless they have a proper mobile-friendly replacement for onClick.

@hai-cea
Copy link
Member

hai-cea commented Jun 5, 2015

@pomerantsev Thank you very much for this!

Yeh, I think we need to decide on whether we want to use onTap or onTouchTap. My preference is that we go with onTouchTap since the underlying event we're binding to is onTouchTap. What do you think?

I've merged the other PRs you submitted and agree what we should create separate issues for #3 and #5.

From what I understand from attending the React conference earlier this year, the react team is still working out how best to handle mobile.

@pomerantsev
Copy link
Contributor Author

@hai-cea I created separate issues / PRs for everything listed above, so I'm closing this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: menu This is the name of the generic UI component, not the React module!
Projects
None yet
Development

Successfully merging this pull request may close these issues.

LeftNav doesn't play with iOS fullscreen mode
3 participants