UNPKG

material-ui

Version:

Material Design UI components built with React

156 lines (130 loc) 4.62 kB
'use strict'; var React = require('react/addons'); var TabTemplate = require('./tabTemplate'); var InkBar = require('../ink-bar'); var StylePropable = require('../mixins/style-propable'); var Events = require('../utils/events'); var Tabs = React.createClass({ displayName: 'Tabs', mixins: [StylePropable], contextTypes: { muiTheme: React.PropTypes.object }, propTypes: { initialSelectedIndex: React.PropTypes.number, onActive: React.PropTypes.func, tabWidth: React.PropTypes.number, tabItemContainerStyle: React.PropTypes.object, contentContainerStyle: React.PropTypes.object, inkBarStyle: React.PropTypes.object, contentContainerClassName: React.PropTypes.string }, getInitialState: function getInitialState() { var selectedIndex = 0; if (this.props.initialSelectedIndex && this.props.initialSelectedIndex < this.getTabCount()) { selectedIndex = this.props.initialSelectedIndex; } return { selectedIndex: selectedIndex }; }, getEvenWidth: function getEvenWidth() { return parseInt(window.getComputedStyle(React.findDOMNode(this)).getPropertyValue('width'), 10); }, getTabCount: function getTabCount() { return React.Children.count(this.props.children); }, componentDidMount: function componentDidMount() { this._updateTabWidth(); Events.on(window, 'resize', this._updateTabWidth); }, componentWillUnmount: function componentWillUnmount() { Events.off(window, 'resize', this._updateTabWidth); }, componentWillReceiveProps: function componentWillReceiveProps(newProps) { if (newProps.hasOwnProperty('style')) this._updateTabWidth(); }, handleTouchTap: function handleTouchTap(tabIndex, tab) { if (this.props.onChange && this.state.selectedIndex !== tabIndex) { this.props.onChange(tabIndex, tab); } this.setState({ selectedIndex: tabIndex }); //default CB is _onActive. Can be updated in tab.jsx if (tab.props.onActive) tab.props.onActive(tab); }, getStyles: function getStyles() { var themeVariables = this.context.muiTheme.component.tabs; return { tabItemContainer: { margin: '0', padding: '0', width: '100%', height: '48px', backgroundColor: themeVariables.backgroundColor, whiteSpace: 'nowrap', display: 'table' } }; }, render: function render() { var _this = this; var styles = this.getStyles(); var tabContent = []; var width = this.state.fixedWidth ? 100 / this.getTabCount() + '%' : this.props.tabWidth + 'px'; var left = 'calc(' + width + '*' + this.state.selectedIndex + ')'; var tabs = React.Children.map(this.props.children, function (tab, index) { if (tab.type.displayName === 'Tab') { if (tab.props.children) { tabContent.push(React.createElement(TabTemplate, { key: index, selected: _this.state.selectedIndex === index }, tab.props.children)); } else { tabContent.push(undefined); } return React.addons.cloneWithProps(tab, { key: index, selected: _this.state.selectedIndex === index, tabIndex: index, width: width, handleTouchTap: _this.handleTouchTap }); } else { var type = tab.type.displayName || tab.type; throw 'Tabs only accepts Tab Components as children. Found ' + type + ' as child number ' + (index + 1) + ' of Tabs'; } }, this); return React.createElement( 'div', { style: this.mergeAndPrefix(this.props.style) }, React.createElement( 'div', { style: this.mergeAndPrefix(styles.tabItemContainer, this.props.tabItemContainerStyle) }, tabs ), React.createElement(InkBar, { left: left, width: width, style: this.props.inkBarStyle }), React.createElement( 'div', { style: this.mergeAndPrefix(this.props.contentContainerStyle), className: this.props.contentContainerClassName }, tabContent ) ); }, _tabWidthPropIsValid: function _tabWidthPropIsValid() { return this.props.tabWidth && this.props.tabWidth * this.getTabCount() <= this.getEvenWidth(); }, // Validates that the tabWidth can fit all tabs on the tab bar. If not, the // tabWidth is recalculated and fixed. _updateTabWidth: function _updateTabWidth() { if (this._tabWidthPropIsValid()) { this.setState({ fixedWidth: false }); } else { this.setState({ fixedWidth: true }); } } }); module.exports = Tabs;