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

[Tabs] Add scrollable behavior #6502

Merged
merged 5 commits into from
Apr 11, 2017
Merged

[Tabs] Add scrollable behavior #6502

merged 5 commits into from
Apr 11, 2017

Conversation

shawnmcknight
Copy link
Contributor

This PR adds the scrolling behavior requested in #4795 for both scrolling and arrows. Closes #1148.
Scrolling is treated as an opt-in prop and arrow button behavior can be customized to work automatically based on viewport size or forced on or off. Doc demos have been updated to show the various possibilities. Tests have been added and code coverage of module is at 100%.

  • PR has tests / docs demo, and is linted.
  • Commit and PR titles begin with [ComponentName], and are in imperative form: "[Component] Fix leaky abstraction".
  • Description explains the issue / use-case resolved, and auto-closes the related issue(s) (http://tr.im/vFqem).

@muibot muibot added PR: Needs Review PR: needs revision The pull request can't be merged. More details is available on the code review or fails in the CI and removed PR: Needs Review labels Apr 5, 2017
@shawnmcknight
Copy link
Contributor Author

The PR is failing on the vrtest run. I'm not really sure what to do about it since I'm not familiar with that tool and the docs seem to be wip.
I believe vrtest is comparing against a suite of baseline images. The live run of the test code looks very similar but it's probably not pixel identical because of the different css techniques involved in rendering the new structure.
I'm looking for some guidance and/or assistance on how to proceed with this. Thanks!

@muibot muibot added PR: out-of-date The pull request has merge conflicts and can't be merged and removed PR: Needs Review labels Apr 7, 2017
@oliviertassinari
Copy link
Member

oliviertassinari commented Apr 7, 2017

@shawnmcknight Hey, thanks for working on that feature! The UX is pretty cool 😍 . I have only noticed one issue so far, the demo do not render well on mobile (too large).

avr -07-2017 23-31-20

@mbrookes mbrookes changed the title [Tabs] Add scrollable behavior #4795 [Tabs] Add scrollable behavior Apr 7, 2017
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.

The overall implementation looks rock solid. Good work guys!


const styleSheet = createStyleSheet('ScrollableTabsButtonAuto', (theme) => ({
root: {
width: 500,
Copy link
Member

Choose a reason for hiding this comment

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

I would use width: '100%' for all the example (to address the small width issue).

index={this.state.index}
onChange={this.handleChange}
scrollable
scrollButtons={'auto'}
Copy link
Member

Choose a reason for hiding this comment

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

scrollButtons="auto"

textColor="accent"
>
<Tab
label="Item One"
Copy link
Member

Choose a reason for hiding this comment

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

I think that having the component on a single line would be better. At least our current rule is we stick 3 props then break it into different lines.

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe you should consider using https://github.com/prettier

Copy link
Member

Choose a reason for hiding this comment

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

@stunaz I looked at it a while back, and it was just too rigid / opinionated.

Copy link
Member

Choose a reason for hiding this comment

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

Isn't what we are looking for, something rigid and opinionated to focus on something else?

index={this.state.index}
onChange={this.handleChange}
scrollable
scrollButtons={'on'}
Copy link
Member

Choose a reason for hiding this comment

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

scrollButtons="on"

scrollButtons={'off'}
>
<Tab
icon={<PhoneIcon />}
Copy link
Member

Choose a reason for hiding this comment

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

Single line, the shorter the demos are the better.

src/Tabs/Tabs.js Outdated
const {
buttonClassName,
scrollable,
scrollButtons: scrollButtonsProp,
Copy link
Member

Choose a reason for hiding this comment

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

renaming the property to scrollButtonsProp seems point less.

src/Tabs/Tabs.js Outdated
fullWidth,
index,
indicatorClassName,
indicatorColor,
onChange,
scrollable, // eslint-disable-line no-unused-vars
scrollButtons: scrollButtonsProp, // eslint-disable-line no-unused-vars
Copy link
Member

Choose a reason for hiding this comment

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

renaming the property to scrollButtonsProp seems point less.

src/Tabs/Tabs.js Outdated
showScrollButtons ? (
<TabScrollButton
className={buttonClassName}
direction={'right'}
Copy link
Member

Choose a reason for hiding this comment

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

direction="right"

src/Tabs/Tabs.js Outdated
conditionalElements.scrollButtonLeft = (
showScrollButtons ? (
<TabScrollButton
direction={'left'}
Copy link
Member

Choose a reason for hiding this comment

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

direction="left"


handleScrollbarSizeChange = ({ scrollbarHeight }) => {
Copy link
Member

Choose a reason for hiding this comment

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

Sounds like it's for supporting Windows 👍 .

@oliviertassinari oliviertassinari added next and removed PR: out-of-date The pull request has merge conflicts and can't be merged labels Apr 7, 2017
@muibot muibot added the PR: out-of-date The pull request has merge conflicts and can't be merged label Apr 8, 2017
@oliviertassinari oliviertassinari removed the PR: out-of-date The pull request has merge conflicts and can't be merged label Apr 8, 2017
@muibot muibot added the PR: out-of-date The pull request has merge conflicts and can't be merged label Apr 8, 2017
@muibot muibot added PR: Needs Review and removed PR: out-of-date The pull request has merge conflicts and can't be merged labels Apr 9, 2017
@shawnmcknight
Copy link
Contributor Author

@oliviertassinari I believe I've got everything you requested other than the dive() update. I tried for a while to get it working, but I was unable to get the shallow rendered withWidth() to let me find() or dive() or really anything at all. Any thoughts and/or advice on how to get this functional? I'll definitely update the tests to use it if I can get something working with it.

I'm also continuing to get the failure from the vrtest tool. I had attempted to get something added for this, but ran into problems with test:regressions. I had logged #6518 for that, but haven't heard anything so I'm stuck on that as well. If you could point me in a direction I can hopefully get this PR wrapped up.

Thanks!

@oliviertassinari oliviertassinari dismissed their stale review April 9, 2017 13:56

I'm gonna have a look at it, thanks! I'm wondering what's going on with the vrtest.

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.

Some last small things. It's close to be merged 😄 .

// @flow weak
/* eslint-disable react/no-multi-comp */

import React, { Component, PropTypes } from 'react';
Copy link
Member

Choose a reason for hiding this comment

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

Could you rebase the branch on next we started the migration to use the prop-types packages.

@@ -0,0 +1,15 @@
/* eslint-disable */
Copy link
Member

Choose a reason for hiding this comment

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

I have updated the format, please rebase, here is an example of what it looks like now. I have just disabled some eslint rules instead of all of them, it's safer that way.

// @flow weak

import React from 'react';
import pure from 'recompose/pure';
import SvgIcon from '../SvgIcon';

let CheckBox = (props) => (
  <SvgIcon {...props}>
    <path d="M19 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.11 0 2-.9 2-2V5c0-1.1-.89-2-2-2zm-9 14l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z" />
  </SvgIcon>
);
CheckBox = pure(CheckBox);
CheckBox.muiName = 'SvgIcon';

export default CheckBox;

@oliviertassinari
Copy link
Member

Regarding the vrtest issue, I can always run the visual regression tests locally.

@mbrookes
Copy link
Member

- Rebase/syntax requests
- Support components docs
- vrtest baseline image update
Visible now has a default propType of true and the not visible test requires an explicit declaration of false.
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.

😍

@oliviertassinari oliviertassinari added PR: Review Accepted component: tabs This is the name of the generic UI component, not the React module! and removed PR: Needs Review PR: needs revision The pull request can't be merged. More details is available on the code review or fails in the CI labels Apr 10, 2017
@oliviertassinari oliviertassinari merged commit ee5b8ad into mui:next Apr 11, 2017
@oliviertassinari
Copy link
Member

@shawnmcknight Thanks a lot, I'm glad @STORIS is investing on the project 🙏 .

@mbrookes
Copy link
Member

PS. Your website is down. 😱

@ArsenyYankovsky
Copy link

This actually broke tabs for me. Unfortunately I don't have time right now to make a reproducible example, but the fix is to check for this.tabs in updateScrollButtonState same as it's done in updatePositionStates. Thanks.

@shawnmcknight
Copy link
Contributor Author

but the fix is to check for this.tabs in updateScrollButtonState same as it's done in updatePositionStates.

It's not immediately clear to me why that would be the case. Under what scenario are you ending up in updateScrollButtonState where there isn't a reference on this.tabs? updateScrollButtonState is invoked from three places: handleResize, handleTabsScroll, and updatePositionStates. In updatePositionStates, the invocation is already nested under the check for this.tabs. Both handleResize and handleTabsScroll should be events that are only fired once the component has rendered and the ref has been applied to this.tabs.

There shouldn't be any harm caused by adding a check for this.tabs to updateScrollButtonState but I'm just trying to understand the scenario that would cause a problem before making any change.

@ArsenyYankovsky
Copy link

ArsenyYankovsky commented Apr 26, 2017

@shawnmcknight
Well, I use it inside of a dialog and the error occurs at the moment dialog is being closed. It is not immediately reproducible because for some reason it only occurs if you scrolled a dialog with a vertical scroll.

@shawnmcknight
Copy link
Contributor Author

I've been able to duplicate the issue, but not exactly the way described. I must put the tabs in a dialog, the tabs must be scrollable, and I must have scrolled the tabs. After that, dismissing the dialog will throw an error.

The issue seems to be due to events firing on a component that is in the process of being unmounted. The browser ends up firing events on something that has been dropped out of scope. We'd hide all of that nastiness by checking for this.tabs where you suggested, but I think the real problem is that we're rendering/scrolling the tab strip/firing scroll events when the dialog is dismissed.

I'll log an issue and get something comprehensive in place to improve performance while fixing the thrown error.

@ArsenyYankovsky
Copy link

Thanks. Also I don't think that function should be called if scrollButtons is set to 'off'.
Any ETA on the fix being in one of the new alpha versions?

@oliviertassinari
Copy link
Member

oliviertassinari commented Apr 26, 2017

I don't know if it's related but I have noticed one issue with how the throttle is handle. We need to cancel it during the unmount, here is an example.

@shawnmcknight
Copy link
Contributor Author

@oliviertassinari There's a very good chance it's related, and might solve the null variable issue all on its own. I'd still like to improve the lifecycle handling to prevent unnecessary activity in the component, but the throttle cancel is probably a good start to addressing the issue.

@ArsenyYankovsky I'll get working on it asap, but I don't know how the PR will coincide with the timing of the next alpha release.

@oliviertassinari
Copy link
Member

Impression of déjà vu 😄 . Regarding the releases of the next branch, we are doing them frequently, every week or so.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: tabs 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.

[Tabs] Make the <Tabs /> component scrollable like <paper-tabs/> in polymer's paper-elements
7 participants