<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.6/css/all.css"> <link rel="stylesheet" href="https://codepen.io/TheVVaFFle/pen/JpWrWw.css"> <link href='https://fonts.googleapis.com/css?family=Roboto:100,300,400,700' rel='stylesheet' type='text/css'> <div id="root"></div> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.2.0/umd/react.development.js" ></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.2.0/umd/react-dom.development.js"></script> html, body, #root, #app { height: 100%; margin: 0px; padding: 0px; width: 100%; } body { overflow-x: hidden; } #app div, #app h1, #app h2, #app h3, #app h4, #app h5, #app h6, #app input, #app button, #app li { font-family: "Roboto", sans-serif; } #app #app-content { left: 50%; position: absolute; top: 50%; transform: translateX(-50%) translateY(-50%); } #app #app-content .my-tab-content { height: 300px; } #app #app-content .my-tab-content .tab-icon { left: 50%; position: absolute; top: 50%; transform: translateX(-50%) translateY(-50%); } #app #app-content .my-tab-content .tab-icon i { color: #f0f0f0; font-size: 10em; } #app #app-content .my-tab-content .tab-icon h1 { color: #c8c8c8; font-size: 0.9em; font-weight: 100; margin: 0px; margin-top: 10px; text-align: center; } class Tabs extends React.PureComponent { constructor(props) { super(props); this.getTabSize = this.getTabSize.bind(this); this.getColors = this.getColors.bind(this); this.getTabs = this.getTabs.bind(this); this.getTabOptions = this.getTabOptions.bind(this); this.setSelectedTab = this.setSelectedTab.bind(this); this.createTabOptions = this.createTabOptions.bind(this); this.updateTabBarStyles = this.updateTabBarStyles.bind(this); this.state = { selectedTab: 0, transitionDuration: 400, isTransitioning: false, tabBarStyles: {} }; } componentDidMount() { const { selectedTab, transitionDuration } = this.state; const tabWidth = this.getTabSize().width, options = this.getTabOptions(), tabOptionWidth = tabWidth / options.length, left = `${tabOptionWidth * selectedTab}px`, right = `${tabWidth - tabOptionWidth * (selectedTab + 1)}px`, transition = `left ${transitionDuration}ms, right ${transitionDuration}ms, width ${transitionDuration / 2}ms`, accentColor = this.getColors().accent; this.updateTabBarStyles(left, right, transition, accentColor); //Added later for initial animation purposes if (this.props.initialTab) { setTimeout(() => this.setSelectedTab(this.props.initialTab), 250); } } componentDidUpdate(prevProps, prevState) { if (prevState.selectedTab !== this.state.selectedTab) { const { selectedTab, transitionDuration, tabBarStyles } = this.state; const tabWidth = this.getTabSize().width, options = this.getTabOptions(), tabOptionWidth = tabWidth / options.length, direction = prevState.selectedTab < selectedTab ? 1 : -1, left = direction === -1 ? `${tabOptionWidth * selectedTab + tabOptionWidth / 2}px` : null, right = direction === 1 ? `${tabWidth - tabOptionWidth * (selectedTab + 1) + tabOptionWidth / 2}px` : null, nextLeft = `${tabOptionWidth * selectedTab}px`, nextRight = `${tabWidth - tabOptionWidth * (selectedTab + 1)}px`; this.setState({ isTransitioning: true }); this.updateTabBarStyles(left, right, null, null); setTimeout(() => this.updateTabBarStyles(nextLeft, nextRight, null, null), transitionDuration / 2); setTimeout(() => this.setState({ isTransitioning: false }), transitionDuration); } } getTabSize() { const { tabHeight, tabWidth } = this.props; return { height: tabHeight || 300, width: tabWidth || 450 }; } getColors() { const { accentColor, backgroundColor } = this.props; return { accent: accentColor || '#03a9f4', background: backgroundColor || 'white' }; } setSelectedTab(index) { index = Math.max(0, index); index = Math.min(index, this.props.children.length - 1); this.setState({ selectedTab: index }); } getTabs() { const { children } = this.props; const { transitionDuration } = this.state; const tabSize = this.getTabSize(), moreProps = { width: `${tabSize.width}px`, transition: `opacity ${transitionDuration * 1.5}ms, transform ${transitionDuration / 2}ms` }; let tabs = !children ? new Array( /*#__PURE__*/React.createElement(Tab, { key: 0, label: 'Default' })) : children.length ? children : new Array(children); return tabs.map(tab => ({ ...tab, props: { ...tab.props, ...moreProps } })); } getTabOptions() { const { children } = this.props; let tabOptions = null; if (!children) { tabOptions = new Array( /*#__PURE__*/React.createElement(Tab, { key: 0, label: 'Default' })); } else { tabOptions = children.length ? children : new Array(children); } return tabOptions.map(tab => tab.props.label); } createTabOptions() { const { selectedTab } = this.state; const tabWidth = this.getTabSize().width, options = this.getTabOptions(), tabOptionWidth = tabWidth / options.length; return options.map((tab, index) => { const selected = selectedTab === index, textStyle = selected ? { color: this.getColors().accent } : {}, classes = `tab-option ${selected ? 'selected' : ''}`; return /*#__PURE__*/( React.createElement("div", { key: index, className: classes, style: { width: `${tabOptionWidth}px` }, onClick: () => this.setSelectedTab(index) }, /*#__PURE__*/ React.createElement("h1", { style: textStyle }, tab))); }); } updateTabBarStyles(left, right, transition, backgroundColor) { const { tabBarStyles } = this.state; this.setState({ tabBarStyles: { left: left || tabBarStyles.left, right: right || tabBarStyles.right, transition: transition || tabBarStyles.transition, backgroundColor: backgroundColor || tabBarStyles.backgroundColor } }); } render() { const { customClass } = this.props; const { tabBarStyles, selectedTab, transitionDuration, isTransitioning } = this.state; const tabSize = this.getTabSize(), colors = this.getColors(), options = this.getTabOptions(), tabWrapperClasses = `tab-wrapper ${isTransitioning ? 'transitioning' : ''} ${customClass ? customClass : ''}`, tabWrapperStyles = { backgroundColor: colors.background, width: `${tabSize.width}px` }, tabsStyles = { height: `${tabSize.height}px`, width: `${tabSize.width * options.length}px`, transform: `translateX(${-1 * selectedTab * tabSize.width}px)`, transition: `transform ${transitionDuration}ms` }, tabs = this.getTabs(); return /*#__PURE__*/( React.createElement("div", { className: tabWrapperClasses, style: tabWrapperStyles }, /*#__PURE__*/ React.createElement("div", { className: "tab-selection" }, /*#__PURE__*/ React.createElement("div", { className: "tab-options" }, this.createTabOptions()), /*#__PURE__*/ React.createElement("div", { className: "tab-selection-bar-track" }, /*#__PURE__*/ React.createElement("div", { className: "tab-selection-bar", style: tabBarStyles }))), /*#__PURE__*/ React.createElement("div", { className: "tabs", style: tabsStyles }, tabs))); }} class Tab extends React.Component { render() { const { children, width, transition, customClass } = this.props; const tabClasses = `tab ${customClass ? customClass : ''}`, tabStyles = { width, transition }, tabContentStyles = { transition }; return /*#__PURE__*/( React.createElement("div", { className: tabClasses, style: tabStyles }, /*#__PURE__*/ React.createElement("div", { className: "tab-contents", style: tabContentStyles }, children))); }} class App extends React.Component { constructor(props) { super(props); this.state = { accentColor: '#03a9f4', backgroundColor: '#fff' }; } getTabs() { return [ { label: 'Home', icon: 'fas fa-home' }, { label: 'Trending', icon: 'fas fa-fire' }, { label: 'Inbox', icon: 'fas fa-inbox' }, { label: 'Profile', icon: 'far fa-user-circle' }]. map((tab, index) => /*#__PURE__*/ React.createElement(Tab, { key: index, customClass: 'my-custom-tab-class', label: tab.label }, /*#__PURE__*/ React.createElement("div", { className: "my-tab-content" }, /*#__PURE__*/ React.createElement("div", { className: "tab-icon" }, /*#__PURE__*/ React.createElement("i", { className: tab.icon }), /*#__PURE__*/ React.createElement("h1", null, "The ", tab.label, " Tab"))))); } render() { const { accentColor, backgroundColor } = this.state; const tabs = this.getTabs(); return /*#__PURE__*/( React.createElement("div", { id: "app", style: { backgroundColor: accentColor } }, /*#__PURE__*/ React.createElement("div", { id: "app-content" }, /*#__PURE__*/ React.createElement(Tabs, { customClass: 'my-custom-tab-wrapper-class', tabHeight: 300, tabWidth: 500, backgroundColor: backgroundColor, accentColor: accentColor, initialTab: 2 }, tabs)))); }} ReactDOM.render( /*#__PURE__*/React.createElement(App, null), document.getElementById('root')); Навигация по записям React – Inbox Slider (React)