touchstone-navigator
Version:
A UINavigationViewController like component for TouchstoneJS
121 lines (99 loc) • 3.13 kB
JavaScript
import React, { Component, PropTypes } from 'react';
import { Container, UI, View, ViewManager } from 'touchstonejs';
import _ from 'lodash';
import prepareViewController from './utils/prepareViewController';
class TouchstoneTabs extends Component {
getViewController(id) {
return _.find(this.state.viewControllers, { id });
}
renderTabs() {
const { viewControllers } = this.state;
return (
<UI.Tabs.Navigator>
{viewControllers.map(({ id, tab }, i) => {
return (
<UI.Tabs.Tab
key={id}
onTap={() => this.setSelectedIndex(i)}
selected={this.state.selectedIndex === i}>
{tab}
</UI.Tabs.Tab>
);
})}
</UI.Tabs.Navigator>
);
}
render() {
const { name, position } = this.props;
const { selectedIndex, viewControllers } = this.state;
return (
<Container fill direction="column">
{position === 'top' && this.renderTabs()}
<ViewManager
ref="viewManager"
name={name}
defaultView={viewControllers[selectedIndex].id}>
{viewControllers.map(({ id, component, props, savedState, scrollable }) => (
<View
key={id}
name={id}
component={component}
{...props}
initialState={savedState}
scrollable={scrollable}
tabinator={this._createPropsTabinator(id)} />
))}
</ViewManager>
{position === 'bottom' && this.renderTabs()}
</Container>
);
}
setSelectedIndex(index, acknowledge = true) {
const { selectedIndex, viewControllers } = this.state;
const selectedViewController = viewControllers[index];
const { id, props, savedState, scrollable } = selectedViewController;
const tabinator = this._createPropsTabinator(id);
this.refs.viewManager.transitionTo(id, {
transition: 'instant',
viewProps: {
...props,
initialState: savedState,
scrollable,
tabinator,
},
});
if (acknowledge) { this.props.onLeave(selectedIndex); }
this.setState({ selectedIndex: index });
}
_createPropsTabinator(viewControllerId) {
return {
saveState: (state) => {
const viewController = this.getViewController(viewControllerId);
if (viewController) { viewController.savedState = { ...state }; }
},
};
}
constructor(props) {
super(...arguments);
this.state = {
selectedIndex: 0,
viewControllers: props.viewControllers.map((vc) => prepareViewController(vc)),
...props.initialState,
};
}
}
TouchstoneTabs.propTypes = {
name: PropTypes.string.isRequired,
position: PropTypes.oneOf([ 'top', 'bottom' ]),
viewControllers: PropTypes.arrayOf(PropTypes.shape({
component: PropTypes.func.isRequired,
props: PropTypes.object,
tab: PropTypes.node.isRequired,
})).isRequired,
onLeave: PropTypes.func,
};
TouchstoneTabs.defaultProps = {
onLeave: () => {},
position: 'bottom',
};
export default TouchstoneTabs;