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] Let each tab set its own width #5415

Closed
wants to merge 1 commit into from

Conversation

GAumala
Copy link

@GAumala GAumala commented Oct 17, 2016

  • 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).

The Tab component has a new prop of type number: labelWidth. This number
is the width of the label in pixels. The user must either set this prop
to every tab or none. If this condition is not met, the ink bar is not
drawn, and a warning is displayed in the console.

The docs have also been updated with information and an example for this
prop.

This solves issue #4420. This approach was suggested in #5301.

The Tab component has a new prop of type number: labelWidth. This number
is the width of the label in pixels. The user must either set this prop
to every tab or none. If this condition is not met, the ink bar is not
drawn, and a warning is displayed in the console.

The docs have also been updated with information and an example for this
prop.

This solves issue mui#4420. This approach was suggested in mui#5301.
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.

I'm glad to see that you keep pushing this forward.
We miss some unit test.
I also believe this PR would be better on the next branch. The Tabs component hasn't been rewrote yet. We have quite some freedom.


const TabsExampleLabelWidth = () => (
<Tabs >
<Tab labelWidth={100} label="100 width" />
Copy link
Member

@oliviertassinari oliviertassinari Oct 18, 2016

Choose a reason for hiding this comment

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

What's the tradeoff behind explicating the tab width?
We could have make it work by computing the tab widths.

@@ -28,6 +30,8 @@ const descriptions = {
'and allowing tabs to be swiped on touch devices.',
icon: 'An example of tabs with icon.',
iconText: 'An example of tabs with icon and text.',
labelWidth: 'An example using the `labelWidth` property. Each tab label specifies its own fixed width regardless ' +
Copy link
Member

Choose a reason for hiding this comment

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

It could be a block comment before the demo example component declaration.

@@ -87,6 +87,7 @@ class Tabs extends Component {

state = {selectedIndex: 0};


Copy link
Member

Choose a reason for hiding this comment

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

Blank line

@@ -113,6 +114,29 @@ class Tabs extends Component {
this.setState(newState);
}

calculateTabWidthAndInkbarPosition(tabs, selectedIndex, defaultWidth) {
Copy link
Member

Choose a reason for hiding this comment

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

We don't rely on the instance, it would be better to have this function as a module function.

if (labelWidth && i < selectedIndex)
left += labelWidth;
else if (!labelWidth)
undefinedLabelWidths++;
Copy link
Member

Choose a reason for hiding this comment

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

No need to increment a counter. A simple boolean should be enough.

Copy link
Author

Choose a reason for hiding this comment

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

A simple boolean is not enough. There are 3 possible scenarios in the calculateTabWidthAndInkbarPosition:

  • Not a single Tab has defined labelWidth prop. This is the default behavior. Each tab is assigned a percentage of the container's width. If have 2 tabs, each gets 50%. The inkbar position is also a percentage (first tab would be 0% and the second would be 50%).
  • Every single Tab has defined labelWidth prop. Now we have to use pixels instead of percentages. Each tab is assigned a string with the value of the labelWidth prop appending px. To calculate the inkbar position, we add the labelWidths of every single component at the left of the selected tab.
  • Some Tabs have defined labelWidth but other's have not. This is an error. The user probably forgot about one or more tabs. It could be possible to fallback to using percentages for the tabs that are mssing the labelWidth prop, but calculating the inkbar position would be impossible because you can't add undefined values. In this scenario inkbar is not displayed.

I'm aware that this sounds a bit complicated, but I could not find easier alternatives. Adding numbers is far easier than parsing strings with percentages.
I will move this function to a new module TabUtils.js and write a test for it before submitting a new PR to the next branch.

If you have any other suggestions or comments please let me know.

Copy link
Member

@oliviertassinari oliviertassinari Oct 19, 2016

Choose a reason for hiding this comment

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

Thanks for providing more details!
We have had quite some contribution tentatives on this component for the past 2 years.
E.g. #2861.
I'm not quite happy with the API decision here.
I'm gonna post a draft proposal on #4795 so we can bootstrap a conversion around it and find the best approach all together.

@oliviertassinari oliviertassinari added PR: needs revision The pull request can't be merged. More details is available on the code review or fails in the CI component: tabs This is the name of the generic UI component, not the React module! and removed PR: Needs Review labels Oct 18, 2016
@oliviertassinari
Copy link
Member

oliviertassinari commented Oct 19, 2016

Actually, following #4795 (comment) I think that it would be better to drop any work on the master branch, as some major improvements have already been done on the next branch.

@oliviertassinari
Copy link
Member

@GAumala Thanks for pushing forward the Tabs component. I'm closing this PR following my previous comment.

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! PR: needs revision The pull request can't be merged. More details is available on the code review or fails in the CI
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants