Completely updated React, fixed #11, (hopefully)

This commit is contained in:
2018-03-04 19:11:49 -05:00
parent 6e0afd6e2a
commit 34e5f5139a
13674 changed files with 333464 additions and 473223 deletions

View File

@@ -1,7 +1,5 @@
// @flow
import React from 'react';
import type { Node, ComponentType } from 'react';
import PropTypes from 'prop-types';
import warning from 'warning';
import classNames from 'classnames';
import EventListener from 'react-event-listener';
@@ -12,9 +10,8 @@ import scroll from 'scroll';
import withStyles from '../styles/withStyles';
import TabIndicator from './TabIndicator';
import TabScrollButton from './TabScrollButton';
import type { IndicatorStyle } from './TabIndicator';
export const styles = (theme: Object) => ({
export const styles = theme => ({
root: {
overflow: 'hidden',
minHeight: 48,
@@ -40,126 +37,15 @@ export const styles = (theme: Object) => ({
justifyContent: 'center',
},
buttonAuto: {
[theme.breakpoints.down('sm')]: {
[theme.breakpoints.down('xs')]: {
display: 'none',
},
},
});
type ProvidedProps = {
classes: Object,
indicatorColor: string,
TabScrollButton: ComponentType<*>,
theme: Object,
};
export type Props = {
/**
* The CSS class name of the scroll button elements.
*/
buttonClassName?: string,
/**
* If `true`, the tabs will be centered.
* This property is intended for large views.
*/
centered?: boolean,
/**
* The content of the component.
*/
children?: Node,
/**
* Useful to extend the style applied to components.
*/
classes?: Object,
/**
* @ignore
*/
className?: string,
/**
* If `true`, the tabs will grow to use all the available space.
* This property is intended for small views, like on mobile.
*/
fullWidth?: boolean,
/**
* The CSS class name of the indicator element.
*/
indicatorClassName?: string,
/**
* Determines the color of the indicator.
*/
indicatorColor?: 'accent' | 'primary' | string,
/**
* Callback fired when the value changes.
*
* @param {object} event The event source of the callback
* @param {number} value We default to the index of the child
*/
onChange: Function,
/**
* True invokes scrolling properties and allow for horizontally scrolling
* (or swiping) the tab bar.
*/
scrollable?: boolean,
/**
* 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
*/
scrollButtons?: 'auto' | 'on' | 'off',
/**
* The component used to render the scroll buttons.
*/
TabScrollButton?: ComponentType<*>,
/**
* Determines the color of the `Tab`.
*/
textColor?: 'accent' | 'primary' | 'inherit',
/**
* @ignore
*/
theme?: Object,
/**
* The value of the currently selected `Tab`.
* If you don't want any selected `Tab`, you can set this property to `false`.
*/
value: any,
};
type State = {
indicatorStyle: IndicatorStyle,
scrollerStyle: Object,
showLeftScroll: boolean,
showRightScroll: boolean,
mounted: boolean,
};
export type TabsMeta = {
clientWidth: number,
scrollLeft: number,
scrollLeftNormalized: number,
scrollWidth: number,
// ClientRect
left: number,
right: number,
};
class Tabs extends React.Component<ProvidedProps & Props, State> {
static defaultProps = {
centered: false,
fullWidth: false,
indicatorColor: 'accent',
scrollable: false,
scrollButtons: 'auto',
TabScrollButton,
textColor: 'inherit',
};
class Tabs extends React.Component {
state = {
indicatorStyle: {
left: 0,
width: 0,
},
indicatorStyle: {},
scrollerStyle: {
marginBottom: 0,
},
@@ -173,6 +59,12 @@ class Tabs extends React.Component<ProvidedProps & Props, State> {
this.setState({ mounted: true });
this.updateIndicatorState(this.props);
this.updateScrollButtonState();
if (this.props.action) {
this.props.action({
updateIndicator: this.handleResize,
});
}
}
componentDidUpdate(prevProps, prevState) {
@@ -213,7 +105,7 @@ class Tabs extends React.Component<ProvidedProps & Props, State> {
conditionalElements.scrollButtonLeft = showScrollButtons ? (
<TabScrollButtonProp
direction={theme.direction === 'rtl' ? 'right' : 'left'}
direction={theme && theme.direction === 'rtl' ? 'right' : 'left'}
onClick={this.handleLeftScrollClick}
visible={this.state.showLeftScroll}
className={classNames(
@@ -227,7 +119,7 @@ class Tabs extends React.Component<ProvidedProps & Props, State> {
conditionalElements.scrollButtonRight = showScrollButtons ? (
<TabScrollButtonProp
direction={theme.direction === 'rtl' ? 'left' : 'right'}
direction={theme && theme.direction === 'rtl' ? 'left' : 'right'}
onClick={this.handleRightScrollClick}
visible={this.state.showRightScroll}
className={classNames(
@@ -242,7 +134,7 @@ class Tabs extends React.Component<ProvidedProps & Props, State> {
return conditionalElements;
};
getTabsMeta = (value, direction): { tabsMeta: ?TabsMeta, tabMeta: ?ClientRect } => {
getTabsMeta = (value, direction) => {
let tabsMeta;
if (this.tabs) {
const rect = this.tabs.getBoundingClientRect();
@@ -263,7 +155,7 @@ class Tabs extends React.Component<ProvidedProps & Props, State> {
if (children.length > 0) {
const tab = children[this.valueToIndex[value]];
warning(Boolean(tab), `Material-UI: the value provided \`${value}\` is invalid`);
warning(tab, `Material-UI: the value provided \`${value}\` is invalid`);
tabMeta = tab ? tab.getBoundingClientRect() : null;
}
}
@@ -346,7 +238,6 @@ class Tabs extends React.Component<ProvidedProps & Props, State> {
scrollSelectedIntoView = () => {
const { theme, value } = this.props;
const { tabsMeta, tabMeta } = this.getTabsMeta(value, theme.direction);
if (!tabMeta || !tabsMeta) {
@@ -388,10 +279,11 @@ class Tabs extends React.Component<ProvidedProps & Props, State> {
render() {
const {
action,
buttonClassName,
centered,
classes,
children: childrenProp,
classes,
className: classNameProp,
fullWidth,
indicatorClassName,
@@ -472,4 +364,99 @@ class Tabs extends React.Component<ProvidedProps & Props, State> {
}
}
export default withStyles(styles, { withTheme: true, name: 'MuiTabs' })(Tabs);
Tabs.propTypes = {
/**
* Callback fired when the component mounts.
* This is useful when you want to trigger an action programmatically.
* It currently only supports `updateIndicator()` action.
*
* @param {object} actions This object contains all possible actions
* that can be triggered programmatically.
*/
action: PropTypes.func,
/**
* The CSS class name of the scroll button elements.
*/
buttonClassName: PropTypes.string,
/**
* If `true`, the tabs will be centered.
* This property is intended for large views.
*/
centered: PropTypes.bool,
/**
* The content of the component.
*/
children: PropTypes.node,
/**
* Useful to extend the style applied to components.
*/
classes: PropTypes.object.isRequired,
/**
* @ignore
*/
className: PropTypes.string,
/**
* 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,
/**
* The CSS class name of the indicator element.
*/
indicatorClassName: PropTypes.string,
/**
* Determines the color of the indicator.
*/
indicatorColor: PropTypes.oneOfType([
PropTypes.string,
PropTypes.oneOf(['secondary', 'primary']),
]),
/**
* Callback fired when the value changes.
*
* @param {object} event The event source of the callback
* @param {number} value We default to the index of the child
*/
onChange: PropTypes.func,
/**
* True invokes scrolling properties and allow for horizontally scrolling
* (or swiping) the tab bar.
*/
scrollable: PropTypes.bool,
/**
* 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
*/
scrollButtons: PropTypes.oneOf(['auto', 'on', 'off']),
/**
* The component used to render the scroll buttons.
*/
TabScrollButton: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
/**
* Determines the color of the `Tab`.
*/
textColor: PropTypes.oneOf(['secondary', 'primary', 'inherit']),
/**
* @ignore
*/
theme: PropTypes.object.isRequired,
/**
* The value of the currently selected `Tab`.
* If you don't want any selected `Tab`, you can set this property to `false`.
*/
value: PropTypes.any,
};
Tabs.defaultProps = {
centered: false,
fullWidth: false,
indicatorColor: 'secondary',
scrollable: false,
scrollButtons: 'auto',
TabScrollButton,
textColor: 'inherit',
};
export default withStyles(styles, { name: 'MuiTabs', withTheme: true })(Tabs);