Tabs that receive the prop centered
should always center.
They remain left aligned if they are also set scrollable
.
https://codesandbox.io/s/kk371k1w75
| Tech | Version |
|--------------|---------|
| Material-UI | @next |
| React | 16.2.0 |
| browser | chrome |
@barbalex Good catch! We should add a warning about it. It's not possible.
@oliviertassinari Sad that it is not possible. Because this seems like the feature that would make tabs work well from huge to tiny screen sizes.
@oliviertassinari Would this not work if the tabs were per css centered div's whose bottom border is highlighted when the tab is active?
I'm sure this is very naive and there are good reasons it is not solved that way. But I'm curious.
@barbalex I try to do some changes for this issue and I think we can to do something. I should think
any update on this? or a work around? I would love to use scrollable tabs at smaller viewports while keeping them centered at larger viewports
any update on this? or a work around?
@KyleAsaff The plan going forward is to add a warning to prevent people from reaching this set of properties.
I would love to use scrollable tabs at smaller viewports while keeping them centered at larger viewports
You can dynamically toggle properties based on the screen width with the withWidth()
higher order component. I think that we should better document this module.
Thanks @oliviertassinari! For anyone looking for a workaround, I created one using react-measure. I have pasted the relevant portion of the code in the snippet below:
import React from 'react';
import { Link, withRouter } from 'react-router-dom';
import AppBar from 'material-ui/AppBar';
import Tabs, { Tab } from 'material-ui/Tabs';
import Measure from 'react-measure';
class Navigation extends React.Component {
state = {
appBarWidth: 1179,
}
render() {
const { navigation } = this.props;
const { appBarWidth } = this.state;
return (
<div>
<Measure
bounds
onResize={(contentRect) => {
this.setState({ appBarWidth: contentRect.bounds.width });
}}
>
{({ measureRef }) => (
<div ref={measureRef}>
<AppBar position="static" color="default">
<Tabs
value={navigation.value}
onChange={this.handleChange}
indicatorColor="primary"
textColor="primary"
scrollButtons="auto"
centered={appBarWidth > 1179}
scrollable={appBarWidth < 1179}
>
<Tab label="Overview" component={Link} to="/overview" />
<Tab label="PDP" component={Link} to="/ecomm/pdp" />
<Tab label="Shoppable Galleries" component={Link} to="/ecomm/shoppable_galleries" />
<Tab label="Shoppable Instagram" component={Link} to="/ecomm/shoppable_instagram" />
<Tab label="Brand Emails" component={Link} to="/email/brand_emails" />
<Tab label="Shopping Cart Abandonment" component={Link} to="/email/shopping_cart_abandonment" />
</Tabs>
</AppBar>
</div>
)}
</Measure>
</div>
);
}
}
@KyleAsaff react-measure is a good solution you can also use material-ui/withWidth or react-virtualized/AutoSizer.
@KyleAsaff thank you for sharing your code, it helped me so much for this kind of problem
What about dynamic tabs?
This won't work when I build the tabs dynamically. centered on scrolleable is a must.
Any suggestions?
I don't understand why centered tabs can't be scrollable (therefore left-aligned) after the container width has been becoming smaller than its content 馃
I'd also like to be able to combine these, if it's feasible.
Found a simple solution if you want the fullWidth
style (where the tabs spread to cover the entire area) instead of the centered
style (where they're bunched up in the middle).
First, turn off centered
, and turn on fullWidth
and scrollable
. Then just add a flexShrink: 0
style to each of the Tab
components. This overrides the shrinking that fullWidth
normally allows. Since we're scrolling, we don't want shrinking.
what's good @jacobweber !! that's clutch, great call right there. Seconding that as a solution. It's super slick to use the fullWidth and scrollable, definitely looks the best. And setting each tab to flexShrink: 0 prevents them from overlapping as they would without the additional css. Thanks again!
Oops. @jacobweber 's great workaround seems not to work any more since last update: https://github.com/mui-org/material-ui/pull/13980
:-(
Not being able to center and scroll looks broken on desktop.
@barbalex Try adding flexGrow: 1
instead. Looks like the defaults have changed.
Did something change?
I was able to make it centered with two lines of css.
Setting flex-grow: 0
on MuiTabs-scroller
and justify-content: center
on first MuiTabs-flexContainer
in the tabs tree.
Works perfectly, unless I am missing something. @oliviertassinari do you want me to make a PR?
Add variant="scrollable"
prop to Tabs and omit centered
prop.
Then add
@media (min-width: 768px) {
.MuiTabs-flexContainer {
justify-content: center;
}
}
to center on larger screens.
I have an alternate solution for centered + scrollable tabs and is not dependent on media queries, so works with dynamic number of tabs. Seems to work in Chrome, Firefox and Safari. Does anyone see any issues with this approach?
https://codesandbox.io/s/material-ui-centered-scrollable-tabs-ud26w
related to @jacobweber answer, the magic margin: auto
instead of flexShrink: 0
works for me :)
variant: fullWidth
and styling margin: 'auto'
works for me.
I would suggest to please address this issue in the API section. centered
is still not working..
A workaround that works across all viewports could be this. Not adding the breakpoint breaks the tabs on small viewports.
variant="scrollable"
tabs:{
[theme.breakpoints.up("md")]: {
margin:'auto'
}
}
Hope this helps!
If anyone is still looking for a solution. Here is my approach
const scrollableTabs = useMediaQuery(theme.breakpoints.down('sm'));
<Tabs variant={scrollableTabs ? "scrollable" : "centered" } scrollButtons="on" centered>
</Tabs>
Most helpful comment
I have an alternate solution for centered + scrollable tabs and is not dependent on media queries, so works with dynamic number of tabs. Seems to work in Chrome, Firefox and Safari. Does anyone see any issues with this approach?
https://codesandbox.io/s/material-ui-centered-scrollable-tabs-ud26w