rc-tabs@10.0.0

tabs ui component for react

/* eslint react/no-multi-comp:0, no-console:0, react/prop-types:0 */
import 'rc-tabs/assets/index.css';
import React from 'react';
import ReactDOM from 'react-dom';
import Tabs, { TabPane } from 'rc-tabs';
import TabContent from 'rc-tabs/lib/TabContent';
import SwipeableInkTabBar from 'rc-tabs/lib/SwipeableInkTabBar';
import ScrollableTabBar from 'rc-tabs/lib/ScrollableTabBar';
import InkTabBar from 'rc-tabs/lib/InkTabBar';

const arrowPath = 'M869 487.8L491.2 159.9c-2.9-2.5-6.6-3.9-10.5-3.9h' +
  '-88.5c-7.4 0-10.8 9.2-5.2 14l350.2 304H152c-4.4 0-8 3.6-8 8v' +
  '60c0 4.4 3.6 8 8 8h585.1L386.9 854c-5.6 4.9-2.2 14 5.2 14h91' +
  '.5c1.9 0 3.8-0.7 5.2-2L869 536.2c14.7-12.8 14.7-35.6 0-48.4z';

const getSvg = (path, style = {}, svgStyle = {}) => {
  return (
    <i style={style}>
      <svg
        viewBox="0 0 1024 1024"
        width="1em"
        height="1em"
        fill="currentColor"
        style={{ verticalAlign: '-.125em ', ...svgStyle }}
      >
        <path d={path} p-id="5827" />
      </svg>
    </i>
  );
};

const next = getSvg(arrowPath, {}, {
  transform: 'scaleX(-1)',
});
const prev = getSvg(arrowPath);

const contentStyle = {
  display: 'flex',
  alignItems: 'center',
  justifyContent: 'center',
  height: '100px',
  backgroundColor: '#fff',
};
const tabTitle = (key) => (<div data-extra="tab-bar-title">{`تب ${key}`}</div>);
const makeTabPane = key => (
  <TabPane tab={tabTitle(key)} data-extra="tabpane" key={`${key}`}>
    <div style={contentStyle}>
      {`مطالب داخل تب ${key}`}
    </div>
  </TabPane>
);

const makeMultiTabPane = (count) => {
  const result = [];
  for (let i = 0; i < count; i++) {
    result.push(makeTabPane(i));
  }
  return result;
};
class PanelContent extends React.Component {
  constructor(props) {
    super(props);
    console.log(this.props.id, 'constructor');
  }

  componentWillReceiveProps(nextProps) {
    console.log(nextProps.id, 'componentWillReceiveProps');
  }

  render() {
    const length = Math.round(10 * (Math.random()) + 4);
    const count = new Array(length);// new Array(4) skip forEach ....
    for (let i = 0; i < length; i++) {
      count[i] = 1;
    }
    const content = new Array(Math.round(100 * (Math.random())) + 4).join(` ${this.props.id}`);
    const els = count.map((c, i) => {
      return <p key={i}>{content}</p>;
    });
    return <div>{els}</div>;
  }
}

function construct(start, num) {
  const ends = [];
  let index = 1;
  for (let i = start; i < start + num; i++) {
    ends.push(<TabPane
      placeholder={`loading ${i}`}
      tab={`tab ${i}`}
      key={index}
    >
      <PanelContent id={i} />
    </TabPane>);
    index++;
  }
  return ends;
}

class Demo extends React.Component {
  state = {
    tabBarPosition: 'top',
    activeKey: '3',
    start: 0,
    useIcon: false,
  };

  onChange = (key) => {
    console.log(`onChange ${key}`);
  }

  onChange2 = (activeKey) => {
    this.setState({ activeKey });
  }

  onTabClick = (key) => {
    console.log(`onTabClick ${key}`);
  }

  tick = () => {
    this.setState({
      start: this.state.start + 10,
    });
  }

  toggleCustomIcon = () => {
    this.setState({
      useIcon: !this.state.useIcon,
    });
  }

  changeTabPosition = (e) => {
    this.setState({
      tabBarPosition: e.target.value,
    });
  }

  scrollToActive = () => {
    this.bar.scrollToActiveTab();
  }

  switchToLast = (ends) => {
    if (this.state.activeKey !== ends[ends.length - 1].key) {
      this.setState({ activeKey: ends[ends.length - 1].key }, this.scrollToActive);
    } else {
      this.scrollToActive();
    }
  }

  saveBar = (bar) => {
    this.bar = bar;
  }

  render() {
    const start = this.state.start;
    const ends = construct(start, 9);
    const ends2 = construct(start, 3);
    const tabBarPosition = this.state.tabBarPosition;
    let style;
    const contentStyleSwipeable = {
      height: 400,
    };
    if (tabBarPosition === 'left' || tabBarPosition === 'right') {
      style = {
        height: 400,
      };
    } else {
      style = {
        width: 500,
      };
    }

    const cls = this.state.useIcon && 'rc-tabs-custom-icon' || undefined;

    const iconProps = this.state.useIcon ? {
      nextIcon: next,
      prevIcon: prev,
    } : {};

    return (
      <div style={{ margin: 20 }}>
        <h2>Basic Tabs With Ink Bar and tabBarGutter</h2>
        <p>
          tabBarPosition:
          <select value={this.state.tabBarPosition} onChange={this.changeTabPosition}>
            <option value="top">top</option>
            <option value="bottom">bottom</option>
            <option value="left">left</option>
            <option value="right">right</option>
          </select>
        </p>
        <div>
          <Tabs
            defaultActiveKey="3"
            style={style}
            tabBarPosition={this.state.tabBarPosition}
            renderTabBar={() => (
              <InkTabBar
                onTabClick={this.onTabClick}
                tabBarGutter={30}
              />
            )}
            renderTabContent={() => <TabContent style={contentStyleSwipeable} animatedWithMargin />}
            onChange={this.onChange}
            direction='rtl'
          >
            {ends2}
          </Tabs>
        </div>
        <h2>Scroll Tabs</h2>
        <div>
          <button onClick={() => this.switchToLast(ends)}>
            switch to last tab
          </button>
          <br />
          <button onClick={this.toggleCustomIcon}>
            toggle custom icon
          </button>
          <span>is using icon: {this.state.useIcon && 'true' || 'false'}</span>
          <Tabs
            activeKey={this.state.activeKey}
            className={cls}
            style={style}
            tabBarPosition={this.state.tabBarPosition}
            renderTabBar={() => <ScrollableTabBar
              ref={this.saveBar}
              onTabClick={this.onTabClick}
              {...iconProps}
            />}
            renderTabContent={() => <TabContent style={contentStyleSwipeable} />}
            onChange={this.onChange2}
            direction='rtl'
          >
            {ends}
          </Tabs>
        </div>
        <button onClick={this.tick}>rerender</button>
        <h2>Swipeable Tabs with inkBar</h2>
        <div>
          <Tabs
            data-extra="tabs"
            direction="rtl"
            renderTabBar={() =>
              <SwipeableInkTabBar
                pageSize={5}
                speed={5}
                data-extra="tabbar"
              />
            }
            renderTabContent={() => <TabContent />}
            defaultActiveKey="2"
          >
            {makeMultiTabPane(11)}
          </Tabs>
        </div>
        <button onClick={this.tick}>rerender</button>
      </div>
    );
  }
}

ReactDOM.render(<Demo />, document.getElementById('__react-content'));
Fork me on GitHub