From 0102308e1252f952401337fb22ba429035b86892 Mon Sep 17 00:00:00 2001 From: Rui Botto Date: Tue, 25 Dec 2018 23:31:44 +0000 Subject: [PATCH] [Tabs] Add variant prop and deprecate fullWidth and scrollable props (#13980) * [Tabs] Add variant prop and deprecate fullWidth and scrollable props * Update Tabs.d.ts and tabs.md * Fix wrong comment * Add backwards compatibility with old props. Add deprecated warnings * Missing scrollable reference * Fullwidth docs * good for me --- docs/src/pages/demos/tabs/FullWidthTabs.js | 2 +- docs/src/pages/demos/tabs/IconLabelTabs.js | 2 +- docs/src/pages/demos/tabs/IconTabs.js | 2 +- docs/src/pages/demos/tabs/NavTabs.js | 2 +- .../demos/tabs/ScrollableTabsButtonAuto.js | 2 +- .../demos/tabs/ScrollableTabsButtonForce.js | 2 +- .../demos/tabs/ScrollableTabsButtonPrevent.js | 2 +- docs/src/pages/demos/tabs/tabs.md | 2 +- packages/material-ui/src/Tabs/Tabs.d.ts | 1 + packages/material-ui/src/Tabs/Tabs.js | 48 ++++++++++++++----- packages/material-ui/src/Tabs/Tabs.test.js | 26 +++++----- pages/api/tabs.md | 14 ++++-- 12 files changed, 66 insertions(+), 39 deletions(-) diff --git a/docs/src/pages/demos/tabs/FullWidthTabs.js b/docs/src/pages/demos/tabs/FullWidthTabs.js index 171bd756ed73f8..69809333ea8c24 100644 --- a/docs/src/pages/demos/tabs/FullWidthTabs.js +++ b/docs/src/pages/demos/tabs/FullWidthTabs.js @@ -51,7 +51,7 @@ class FullWidthTabs extends React.Component { onChange={this.handleChange} indicatorColor="primary" textColor="primary" - fullWidth + variant="fullWidth" > diff --git a/docs/src/pages/demos/tabs/IconLabelTabs.js b/docs/src/pages/demos/tabs/IconLabelTabs.js index 5a4ef50cf8663e..a97f0cf1eb70ca 100644 --- a/docs/src/pages/demos/tabs/IconLabelTabs.js +++ b/docs/src/pages/demos/tabs/IconLabelTabs.js @@ -32,7 +32,7 @@ class IconLabelTabs extends React.Component { diff --git a/docs/src/pages/demos/tabs/IconTabs.js b/docs/src/pages/demos/tabs/IconTabs.js index 493d9137e53450..a47a7dc33a265c 100644 --- a/docs/src/pages/demos/tabs/IconTabs.js +++ b/docs/src/pages/demos/tabs/IconTabs.js @@ -32,7 +32,7 @@ class IconTabs extends React.Component { diff --git a/docs/src/pages/demos/tabs/NavTabs.js b/docs/src/pages/demos/tabs/NavTabs.js index 4791a8a4f1ff55..70a0f305c2e0f8 100644 --- a/docs/src/pages/demos/tabs/NavTabs.js +++ b/docs/src/pages/demos/tabs/NavTabs.js @@ -47,7 +47,7 @@ class NavTabs extends React.Component {
- + diff --git a/docs/src/pages/demos/tabs/ScrollableTabsButtonAuto.js b/docs/src/pages/demos/tabs/ScrollableTabsButtonAuto.js index fbea9407a94f4b..502bc5b0cb0248 100644 --- a/docs/src/pages/demos/tabs/ScrollableTabsButtonAuto.js +++ b/docs/src/pages/demos/tabs/ScrollableTabsButtonAuto.js @@ -47,7 +47,7 @@ class ScrollableTabsButtonAuto extends React.Component { onChange={this.handleChange} indicatorColor="primary" textColor="primary" - scrollable + variant="scrollable" scrollButtons="auto" > diff --git a/docs/src/pages/demos/tabs/ScrollableTabsButtonForce.js b/docs/src/pages/demos/tabs/ScrollableTabsButtonForce.js index 0f3912c2663f7d..f6d481aad02e17 100644 --- a/docs/src/pages/demos/tabs/ScrollableTabsButtonForce.js +++ b/docs/src/pages/demos/tabs/ScrollableTabsButtonForce.js @@ -52,7 +52,7 @@ class ScrollableTabsButtonForce extends React.Component { - + } /> } /> } /> diff --git a/docs/src/pages/demos/tabs/tabs.md b/docs/src/pages/demos/tabs/tabs.md index 7098de7b43bd1e..cfc98b0fe7951d 100644 --- a/docs/src/pages/demos/tabs/tabs.md +++ b/docs/src/pages/demos/tabs/tabs.md @@ -33,7 +33,7 @@ Fixed tabs should be used with a limited number of tabs and when consistent plac ### Full width -The `fullWidth` property should be used for smaller views. +The `variant="fullWidth"` property should be used for smaller views. This demo also uses [react-swipeable-views](https://github.com/oliviertassinari/react-swipeable-views) to animate the Tab transition, and allowing tabs to be swiped on touch devices. {{"demo": "pages/demos/tabs/FullWidthTabs.js"}} diff --git a/packages/material-ui/src/Tabs/Tabs.d.ts b/packages/material-ui/src/Tabs/Tabs.d.ts index 31e6dc685047f9..f6321ba0e95bf1 100644 --- a/packages/material-ui/src/Tabs/Tabs.d.ts +++ b/packages/material-ui/src/Tabs/Tabs.d.ts @@ -18,6 +18,7 @@ export interface TabsProps TabIndicatorProps?: Partial; textColor?: 'secondary' | 'primary' | 'inherit' | string; value: any; + variant?: 'scrollable' | 'fullWidth'; width?: string; } diff --git a/packages/material-ui/src/Tabs/Tabs.js b/packages/material-ui/src/Tabs/Tabs.js index 72ae7ed8e99bec..3e2804821e73f4 100644 --- a/packages/material-ui/src/Tabs/Tabs.js +++ b/packages/material-ui/src/Tabs/Tabs.js @@ -13,6 +13,7 @@ import ScrollbarSize from './ScrollbarSize'; import withStyles from '../styles/withStyles'; import TabIndicator from './TabIndicator'; import TabScrollButton from './TabScrollButton'; +import deprecatedPropType from '../utils/deprecatedPropType'; export const styles = theme => ({ /* Styles applied to the root element. */ @@ -25,7 +26,7 @@ export const styles = theme => ({ flexContainer: { display: 'flex', }, - /* Styles applied to the flex container element if `centered={true}` & `scrollable={false}`. */ + /* Styles applied to the flex container element if `centered={true}` & `!variant="scrollable"`. */ centered: { justifyContent: 'center', }, @@ -36,12 +37,12 @@ export const styles = theme => ({ flex: '1 1 auto', whiteSpace: 'nowrap', }, - /* Styles applied to the tablist element if `scrollable={false}`. */ + /* Styles applied to the tablist element if `!variant="scrollable"`. */ fixed: { overflowX: 'hidden', width: '100%', }, - /* Styles applied to the tablist element if `scrollable={true}`. */ + /* Styles applied to the tablist element if `variant="scrollable"`. */ scrollable: { overflowX: 'scroll', }, @@ -112,8 +113,16 @@ class Tabs extends React.Component { } getConditionalElements = () => { - const { classes, scrollable, ScrollButtonComponent, scrollButtons, theme } = this.props; + const { + classes, + scrollable: deprecatedScrollable, + ScrollButtonComponent, + scrollButtons, + theme, + variant, + } = this.props; const conditionalElements = {}; + const scrollable = variant === 'scrollable' || deprecatedScrollable; conditionalElements.scrollbarSizeListener = scrollable ? ( ) : null; @@ -234,7 +243,8 @@ class Tabs extends React.Component { }; updateScrollButtonState = () => { - const { scrollable, scrollButtons, theme } = this.props; + const { scrollable: deprecatedScrollable, scrollButtons, theme, variant } = this.props; + const scrollable = variant === 'scrollable' || deprecatedScrollable; if (scrollable && scrollButtons !== 'off') { const { scrollWidth, clientWidth } = this.tabsRef; @@ -293,22 +303,25 @@ class Tabs extends React.Component { classes, className: classNameProp, component: Component, - fullWidth, + fullWidth = false, indicatorColor, onChange, - scrollable, + scrollable: deprecatedScrollable = false, ScrollButtonComponent, scrollButtons, TabIndicatorProps = {}, textColor, theme, value, + variant, ...other } = this.props; + const scrollable = variant === 'scrollable' || deprecatedScrollable; + warning( !centered || !scrollable, - 'Material-UI: you can not use the `centered={true}` and `scrollable={true}` properties ' + + 'Material-UI: you can not use the `centered={true}` and `variant="scrollable"` properties ' + 'at the same time on a `Tabs` component.', ); @@ -354,7 +367,7 @@ class Tabs extends React.Component { childIndex += 1; return React.cloneElement(child, { - fullWidth, + fullWidth: variant === 'fullWidth' || fullWidth, indicator: selected && !this.state.mounted && indicator, selected, onChange, @@ -427,7 +440,7 @@ Tabs.propTypes = { * If `true`, the tabs will grow to use all the available space. * This property is intended for small views, like on mobile. */ - fullWidth: PropTypes.bool, + fullWidth: deprecatedPropType(PropTypes.bool, 'Instead, use the `variant="fullWidth"` property.'), /** * Determines the color of the indicator. */ @@ -443,7 +456,10 @@ Tabs.propTypes = { * True invokes scrolling properties and allow for horizontally scrolling * (or swiping) the tab bar. */ - scrollable: PropTypes.bool, + scrollable: deprecatedPropType( + PropTypes.bool, + 'Instead, use the `variant="scrollable"` property.', + ), /** * The component used to render the scroll buttons. */ @@ -472,14 +488,20 @@ Tabs.propTypes = { * If you don't want any selected `Tab`, you can set this property to `false`. */ value: PropTypes.any, + /** + * Determines additional display behavior of the tabs: + * - `scrollable` will invoke scrolling properties and allow for horizontally + * scrolling (or swiping) of the tab bar. + * -`fullWidth` will make the tabs grow to use all the available space, + * which should be used for small views, like on mobile. + */ + variant: PropTypes.oneOf(['scrollable', 'fullWidth']), }; Tabs.defaultProps = { centered: false, component: 'div', - fullWidth: false, indicatorColor: 'secondary', - scrollable: false, ScrollButtonComponent: TabScrollButton, scrollButtons: 'auto', textColor: 'inherit', diff --git a/packages/material-ui/src/Tabs/Tabs.test.js b/packages/material-ui/src/Tabs/Tabs.test.js index ca8ededb669b69..25550fae0ca17e 100644 --- a/packages/material-ui/src/Tabs/Tabs.test.js +++ b/packages/material-ui/src/Tabs/Tabs.test.js @@ -59,10 +59,10 @@ describe('', () => { }); it('should warn if the input is invalid', () => { - shallow(); + shallow(); assert.match( consoleErrorMock.args()[0][0], - /Material-UI: you can not use the `centered={true}` and `scrollable={true}`/, + /Material-UI: you can not use the `centered={true}` and `variant="scrollable"`/, ); }); }); @@ -347,14 +347,14 @@ describe('', () => { }); }); - describe('prop: scrollable', () => { + describe('prop: variant="scrollable"', () => { let clock; let wrapper; before(() => { clock = useFakeTimers(); wrapper = shallow( - + , @@ -388,7 +388,7 @@ describe('', () => { it('should get a scrollbar size listener', () => { // use mount to ensure that handleScrollbarSizeChange gets covered const mountWrapper = mount( - + , @@ -398,7 +398,7 @@ describe('', () => { }); }); - describe('prop: !scrollable', () => { + describe('prop: !variant="scrollable"', () => { it('should not render with the scrollable class', () => { const wrapper = shallow( @@ -426,7 +426,7 @@ describe('', () => { it('should render scroll buttons', () => { const wrapper = shallow( - + , @@ -436,7 +436,7 @@ describe('', () => { it('should render scroll buttons automatically', () => { const wrapper = shallow( - + , @@ -446,7 +446,7 @@ describe('', () => { it('should should not render scroll buttons automatically', () => { const wrapper = shallow( - + , @@ -460,7 +460,7 @@ describe('', () => { it('should handle window resize event', () => { const wrapper = shallow( - + , @@ -482,7 +482,7 @@ describe('', () => { let instance; before(() => { wrapper = shallow( - + , @@ -527,7 +527,7 @@ describe('', () => { const dimensions = { scrollLeft: 100, clientWidth: 200, scrollWidth: 1000 }; before(() => { wrapper = shallow( - + , @@ -566,7 +566,7 @@ describe('', () => { beforeEach(() => { const wrapper = shallow( - + , diff --git a/pages/api/tabs.md b/pages/api/tabs.md index aa5663afc9f822..82f1b84bd07904 100644 --- a/pages/api/tabs.md +++ b/pages/api/tabs.md @@ -23,15 +23,19 @@ import Tabs from '@material-ui/core/Tabs'; | children | node |   | The content of the component. | | classes | object |   | Override or extend the styles applied to the component. See [CSS API](#css-api) below for more details. | | component | componentPropType | 'div' | The component used for the root node. Either a string to use a DOM element or a component. | -| fullWidth | bool | false | If `true`, the tabs will grow to use all the available space. This property is intended for small views, like on mobile. | +| ~~fullWidth~~ | bool |   | *Deprecated*. Instead, use the `variant="fullWidth"` property.

If `true`, the tabs will grow to use all the available space. This property is intended for small views, like on mobile. | | indicatorColor | enum: 'secondary' |
 'primary'
| 'secondary' | Determines the color of the indicator. | | onChange | func |   | Callback fired when the value changes.

**Signature:**
`function(event: object, value: number) => void`
*event:* The event source of the callback
*value:* We default to the index of the child | -| scrollable | bool | false | True invokes scrolling properties and allow for horizontally scrolling (or swiping) the tab bar. | +| scrollable | deprecatedPropType( + PropTypes.bool, + 'Instead, use the `variant="scrollable"` property.', +) |   | True invokes scrolling properties and allow for horizontally scrolling (or swiping) the tab bar. | | ScrollButtonComponent | componentPropType | TabScrollButton | The component used to render the scroll buttons. | | scrollButtons | enum: 'auto' |
 'on' |
 'off'
| 'auto' | Determine behavior of scroll buttons when tabs are set to scroll `auto` will only present them on medium and larger viewports `on` will always present them `off` will never present them | | TabIndicatorProps | object |   | Properties applied to the `TabIndicator` element. | | textColor | enum: 'secondary' |
 'primary' |
 'inherit'
| 'inherit' | Determines the color of the `Tab`. | | value | any |   | The value of the currently selected `Tab`. If you don't want any selected `Tab`, you can set this property to `false`. | +| variant | enum: 'scrollable' |
 'fullWidth'
|   | Determines additional display behavior of the tabs: - `scrollable` will invoke scrolling properties and allow for horizontally scrolling (or swiping) of the tab bar. -`fullWidth` will make the tabs grow to use all the available space, which should be used for small views, like on mobile. | Any other properties supplied will be spread to the root element (native element). @@ -45,10 +49,10 @@ This property accepts the following keys: |:-----|:------------| | root | Styles applied to the root element. | flexContainer | Styles applied to the flex container element. -| centered | Styles applied to the flex container element if `centered={true}` & `scrollable={false}`. +| centered | Styles applied to the flex container element if `centered={true}` & `!variant="scrollable"`. | scroller | Styles applied to the tablist element. -| fixed | Styles applied to the tablist element if `scrollable={false}`. -| scrollable | Styles applied to the tablist element if `scrollable={true}`. +| fixed | Styles applied to the tablist element if `!variant="scrollable"`. +| scrollable | Styles applied to the tablist element if `variant="scrollable"`. | scrollButtons | Styles applied to the `ScrollButtonComponent` component. | scrollButtonsAuto | Styles applied to the `ScrollButtonComponent` component if `scrollButtons="auto"`. | indicator | Styles applied to the `TabIndicator` component.