• Tabs 标签页

    选项卡切换组件。

    何时使用

    提供平级的区域将大块内容进行收纳和展现,保持界面整洁。

    Choerodon 依次提供了三级选项卡,分别用于不同的场景。

    代码演示

    默认选中第一项。
    expand code expand code
    import { Tabs } from 'choerodon-ui';
    const TabPane = Tabs.TabPane;
    
    function callback(key) {
      console.log(key);
    }
    
    ReactDOM.render(
      <Tabs defaultActiveKey="1" onChange={callback}>
        <TabPane tab="Tab 1" key="1">Content of Tab Pane 1</TabPane>
        <TabPane tab="Tab 2" key="2">Content of Tab Pane 2</TabPane>
        <TabPane tab="Tab 3" key="3">Content of Tab Pane 3</TabPane>
      </Tabs>,
      mountNode);
    
    禁用某一项。
    expand code expand code
    import { Tabs } from 'choerodon-ui';
    const TabPane = Tabs.TabPane;
    
    ReactDOM.render(
      <Tabs defaultActiveKey="1">
        <TabPane tab="Tab 1" key="1">Tab 1</TabPane>
        <TabPane tab="Tab 2" disabled key="2">Tab 2</TabPane>
        <TabPane tab="Tab 3" key="3">Tab 3</TabPane>
      </Tabs>,
      mountNode);
    
    有图标的标签。
    expand code expand code
    import { Tabs, Icon } from 'choerodon-ui';
    const TabPane = Tabs.TabPane;
    
    ReactDOM.render(
      <Tabs defaultActiveKey="2">
        <TabPane tab={<span><Icon type="apple" />Tab 1</span>} key="1">
          Tab 1
        </TabPane>
        <TabPane tab={<span><Icon type="android" />Tab 2</span>} key="2">
          Tab 2
        </TabPane>
      </Tabs>,
      mountNode);
    
    可以左右、上下滑动,容纳更多标签。
    expand code expand code
    import { Tabs, Radio } from 'choerodon-ui';
    const TabPane = Tabs.TabPane;
    
    class SlidingTabsDemo extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          mode: 'top',
        };
      }
    
      handleModeChange = (e) => {
        const mode = e.target.value;
        this.setState({ mode });
      }
    
      render() {
        const { mode } = this.state;
        return (
          <div>
            <Radio.Group onChange={this.handleModeChange} value={mode} style={{ marginBottom: 8 }}>
              <Radio.Button value="top">Horizontal</Radio.Button>
              <Radio.Button value="left">Vertical</Radio.Button>
            </Radio.Group>
            <Tabs
              defaultActiveKey="1"
              tabPosition={mode}
              style={{ height: 220 }}
            >
              <TabPane tab="Tab 1" key="1">Content of tab 1</TabPane>
              <TabPane tab="Tab 2" key="2">Content of tab 2</TabPane>
              <TabPane tab="Tab 3" key="3">Content of tab 3</TabPane>
              <TabPane tab="Tab 4" key="4">Content of tab 4</TabPane>
              <TabPane tab="Tab 5" key="5">Content of tab 5</TabPane>
              <TabPane tab="Tab 6" key="6">Content of tab 6</TabPane>
              <TabPane tab="Tab 7" key="7">Content of tab 7</TabPane>
              <TabPane tab="Tab 8" key="8">Content of tab 8</TabPane>
              <TabPane tab="Tab 9" key="9">Content of tab 9</TabPane>
              <TabPane tab="Tab 10" key="10">Content of tab 10</TabPane>
              <TabPane tab="Tab 11" key="11">Content of tab 11</TabPane>
            </Tabs>
          </div>
        );
      }
    }
    
    ReactDOM.render(<SlidingTabsDemo />, mountNode);
    
    可以在页签右边添加附加操作。
    expand code expand code
    import { Tabs, Button } from 'choerodon-ui';
    const TabPane = Tabs.TabPane;
    
    const operations = <Button>Extra Action</Button>;
    
    ReactDOM.render(
      <Tabs tabBarExtraContent={operations}>
        <TabPane tab="Tab 1" key="1">Content of tab 1</TabPane>
        <TabPane tab="Tab 2" key="2">Content of tab 2</TabPane>
        <TabPane tab="Tab 3" key="3">Content of tab 3</TabPane>
      </Tabs>,
      mountNode);
    
    大号页签用在页头区域,小号用在弹出框等较狭窄的容器内。
    expand code expand code
    import { Tabs, Radio } from 'choerodon-ui';
    const { TabPane } = Tabs;
    
    class Demo extends React.Component {
      state = { size: 'small' }
    
      onChange = (e) => {
        this.setState({ size: e.target.value });
      }
    
      render() {
        const { size } = this.state;
        return (
          <div>
            <Radio.Group value={size} onChange={this.onChange} style={{ marginBottom: 16 }}>
              <Radio.Button value="small">Small</Radio.Button>
              <Radio.Button value="default">Default</Radio.Button>
              <Radio.Button value="large">Large</Radio.Button>
            </Radio.Group>
            <Tabs defaultActiveKey="1" size={size}>
              <TabPane tab="Tab 1" key="1">Content of tab 1</TabPane>
              <TabPane tab="Tab 2" key="2">Content of tab 2</TabPane>
              <TabPane tab="Tab 3" key="3">Content of tab 3</TabPane>
            </Tabs>
          </div>
        );
      }
    }
    
    ReactDOM.render(<Demo />, mountNode);
    
    有四个位置,tabPosition="left|right|top|bottom"
    expand code expand code
    import { Tabs, Select } from 'choerodon-ui';
    const TabPane = Tabs.TabPane;
    const Option = Select.Option;
    
    
    class Demo extends React.Component {
      state = {
        tabPosition: 'top',
      }
    
      changeTabPosition = (tabPosition) => {
        this.setState({ tabPosition });
      }
    
      render() {
        return (
          <div>
            <div style={{ marginBottom: 16 }}>
              Tab position:
              <Select
                value={this.state.tabPosition}
                onChange={this.changeTabPosition}
                dropdownMatchSelectWidth={false}
              >
                <Option value="top">top</Option>
                <Option value="bottom">bottom</Option>
                <Option value="left">left</Option>
                <Option value="right">right</Option>
              </Select>
            </div>
            <Tabs tabPosition={this.state.tabPosition}>
              <TabPane tab="Tab 1" key="1">Content of Tab 1</TabPane>
              <TabPane tab="Tab 2" key="2">Content of Tab 2</TabPane>
              <TabPane tab="Tab 3" key="3">Content of Tab 3</TabPane>
            </Tabs>
          </div>
        );
      }
    }
    
    ReactDOM.render(<Demo />, mountNode);
    
    另一种样式的页签,不提供对应的垂直样式。
    expand code expand code
    import { Tabs } from 'choerodon-ui';
    const TabPane = Tabs.TabPane;
    
    function callback(key) {
      console.log(key);
    }
    
    ReactDOM.render(
      <Tabs onChange={callback} type="card">
        <TabPane tab="Tab 1" key="1">Content of Tab Pane 1</TabPane>
        <TabPane tab="Tab 2" key="2">Content of Tab Pane 2</TabPane>
        <TabPane tab="Tab 3" key="3">Content of Tab Pane 3</TabPane>
      </Tabs>,
      mountNode);
    
    只有卡片样式的页签支持新增和关闭选项。 使用 closable={false} 禁止关闭。
    expand code expand code
    import { Tabs } from 'choerodon-ui';
    const TabPane = Tabs.TabPane;
    
    class Demo extends React.Component {
      constructor(props) {
        super(props);
        this.newTabIndex = 0;
        const panes = [
          { title: 'Tab 1', content: 'Content of Tab 1', key: '1' },
          { title: 'Tab 2', content: 'Content of Tab 2', key: '2' },
          { title: 'Tab 3', content: 'Content of Tab 3', key: '3', closable: false },
        ];
        this.state = {
          activeKey: panes[0].key,
          panes,
        };
      }
    
      onChange = (activeKey) => {
        this.setState({ activeKey });
      }
    
      onEdit = (targetKey, action) => {
        this[action](targetKey);
      }
    
      add = () => {
        const panes = this.state.panes;
        const activeKey = `newTab${this.newTabIndex++}`;
        panes.push({ title: 'New Tab', content: 'Content of new Tab', key: activeKey });
        this.setState({ panes, activeKey });
      }
    
      remove = (targetKey) => {
        let activeKey = this.state.activeKey;
        let lastIndex;
        this.state.panes.forEach((pane, i) => {
          if (pane.key === targetKey) {
            lastIndex = i - 1;
          }
        });
        const panes = this.state.panes.filter(pane => pane.key !== targetKey);
        if (lastIndex >= 0 && activeKey === targetKey) {
          activeKey = panes[lastIndex].key;
        }
        this.setState({ panes, activeKey });
      }
    
      render() {
        return (
          <Tabs
            onChange={this.onChange}
            activeKey={this.state.activeKey}
            type="editable-card"
            onEdit={this.onEdit}
          >
            {this.state.panes.map(pane => <TabPane tab={pane.title} key={pane.key} closable={pane.closable}>{pane.content}</TabPane>)}
          </Tabs>
        );
      }
    }
    
    ReactDOM.render(<Demo />, mountNode);
    
    用于容器顶部,需要一点额外的样式覆盖。
    expand code expand code
    import { Tabs } from 'choerodon-ui';
    const TabPane = Tabs.TabPane;
    
    ReactDOM.render(
      <div className="card-container">
        <Tabs type="card">
          <TabPane tab="Tab Title 1" key="1">
            <p>Content of Tab Pane 1</p>
            <p>Content of Tab Pane 1</p>
            <p>Content of Tab Pane 1</p>
          </TabPane>
          <TabPane tab="Tab Title 2" key="2">
            <p>Content of Tab Pane 2</p>
            <p>Content of Tab Pane 2</p>
            <p>Content of Tab Pane 2</p>
          </TabPane>
          <TabPane tab="Tab Title 3" key="3">
            <p>Content of Tab Pane 3</p>
            <p>Content of Tab Pane 3</p>
            <p>Content of Tab Pane 3</p>
          </TabPane>
        </Tabs>
      </div>,
      mountNode);
    
    隐藏默认的页签增加图标,给自定义触发器绑定事件。
    expand code expand code
    import { Tabs, Button } from 'choerodon-ui';
    const TabPane = Tabs.TabPane;
    
    class Demo extends React.Component {
      constructor(props) {
        super(props);
        this.newTabIndex = 0;
        const panes = [
          { title: 'Tab 1', content: 'Content of Tab Pane 1', key: '1' },
          { title: 'Tab 2', content: 'Content of Tab Pane 2', key: '2' },
        ];
        this.state = {
          activeKey: panes[0].key,
          panes,
        };
      }
    
      onChange = (activeKey) => {
        this.setState({ activeKey });
      }
    
      onEdit = (targetKey, action) => {
        this[action](targetKey);
      }
    
      add = () => {
        const panes = this.state.panes;
        const activeKey = `newTab${this.newTabIndex++}`;
        panes.push({ title: 'New Tab', content: 'New Tab Pane', key: activeKey });
        this.setState({ panes, activeKey });
      }
    
      remove = (targetKey) => {
        let activeKey = this.state.activeKey;
        let lastIndex;
        this.state.panes.forEach((pane, i) => {
          if (pane.key === targetKey) {
            lastIndex = i - 1;
          }
        });
        const panes = this.state.panes.filter(pane => pane.key !== targetKey);
        if (lastIndex >= 0 && activeKey === targetKey) {
          activeKey = panes[lastIndex].key;
        }
        this.setState({ panes, activeKey });
      }
    
      render() {
        return (
          <div>
            <div style={{ marginBottom: 16 }}>
              <Button onClick={this.add}>ADD</Button>
            </div>
            <Tabs
              hideAdd
              onChange={this.onChange}
              activeKey={this.state.activeKey}
              type="editable-card"
              onEdit={this.onEdit}
            >
              {this.state.panes.map(pane => <TabPane tab={pane.title} key={pane.key}>{pane.content}</TabPane>)}
            </Tabs>
          </div>
        );
      }
    }
    
    ReactDOM.render(<Demo />, mountNode);
    

    API

    Tabs

    参数说明类型默认值
    activeKey当前激活 tab 面板的 keystring
    animated是否使用动画切换 Tabs,在 `tabPosition=topbottom` 时有效boolean | {inkBar:boolean, tabPane:boolean}
    defaultActiveKey初始化选中面板的 key,如果没有设置 activeKeystring第一个面板
    hideAdd是否隐藏加号图标,在 type="editable-card" 时有效booleanfalse
    size大小,提供 large defaultsmall 三种大小string‘default’
    tabBarExtraContenttab bar 上额外的元素React.ReactNode
    tabBarStyletab bar 的样式对象object-
    tabPosition页签位置,可选值有 top right bottom leftstring‘top’
    type页签的基本样式,可选 linecard editable-card 类型string‘line’
    onChange切换面板的回调Function(activeKey) {}
    onEdit新增和删除页签的回调,在 type="editable-card" 时有效(targetKey, action): void
    onNextClicknext 按钮被点击的回调Function
    onPrevClickprev 按钮被点击的回调Function
    onTabClicktab 被点击的回调Function
    tabBarGuttertabs 之间的间隙number

    Tabs.TabPane

    参数说明类型默认值
    forceRender被隐藏时是否渲染 DOM 结构booleanfalse
    key对应 activeKeystring
    tab选项卡头显示文字string|ReactNode