import React, { cloneElement } from 'react'; import { findDOMNode } from 'react-dom'; import RcTabs, { TabPane } from 'rc-tabs'; import ScrollableInkTabBar from 'rc-tabs/lib/ScrollableInkTabBar'; import TabContent from 'rc-tabs/lib/TabContent'; import classNames from 'classnames'; import Icon from '../icon'; import warning from '../_util/warning'; import isFlexSupported from '../_util/isFlexSupported'; export type TabsType = 'line' | 'card' | 'editable-card'; export type TabsPosition = 'top' | 'right' | 'bottom' | 'left'; export interface TabsProps { activeKey?: string; defaultActiveKey?: string; hideAdd?: boolean; onChange?: (activeKey: string) => void; onTabClick?: Function; onPrevClick?: React.MouseEventHandler; onNextClick?: React.MouseEventHandler; tabBarExtraContent?: React.ReactNode | null; tabBarStyle?: React.CSSProperties; type?: TabsType; tabPosition?: TabsPosition; onEdit?: (targetKey: string, action: any) => void; size?: 'default' | 'small'; style?: React.CSSProperties; prefixCls?: string; className?: string; animated?: boolean | { inkBar: boolean; tabPane: boolean; }; } // Tabs export interface TabPaneProps { /** 选项卡头显示文字 */ tab?: React.ReactNode | string; style?: React.CSSProperties; closable?: boolean; className?: string; disabled?: boolean; } export default class Tabs extends React.Component { static TabPane = TabPane as React.ClassicComponentClass; static defaultProps = { prefixCls: 'ant-tabs', hideAdd: false, }; createNewTab = (targetKey) => { const onEdit = this.props.onEdit; if (onEdit) { onEdit(targetKey, 'add'); } } removeTab = (targetKey, e) => { e.stopPropagation(); if (!targetKey) { return; } const onEdit = this.props.onEdit; if (onEdit) { onEdit(targetKey, 'remove'); } } handleChange = (activeKey) => { const onChange = this.props.onChange; if (onChange) { onChange(activeKey); } } componentDidMount() { const NO_FLEX = ' no-flex'; const tabNode = findDOMNode(this); if (tabNode && !isFlexSupported() && tabNode.className.indexOf(NO_FLEX) === -1) { tabNode.className += NO_FLEX; } } render() { let { prefixCls, className = '', size, type = 'line', tabPosition, children, tabBarExtraContent, tabBarStyle, hideAdd, onTabClick, onPrevClick, onNextClick, animated = true, } = this.props; let { inkBarAnimated, tabPaneAnimated } = typeof animated === 'object' ? { inkBarAnimated: animated.inkBar, tabPaneAnimated: animated.tabPane, } : { inkBarAnimated: animated, tabPaneAnimated: animated, }; // card tabs should not have animation if (type !== 'line') { tabPaneAnimated = 'animated' in this.props ? tabPaneAnimated : false; } warning( !(type.indexOf('card') >= 0 && size === 'small'), 'Tabs[type=card|editable-card] doesn\'t have small size, it\'s by designed.', ); let cls = classNames(className, { [`${prefixCls}-mini`]: size === 'small' || size as string === 'mini', [`${prefixCls}-vertical`]: tabPosition === 'left' || tabPosition === 'right', [`${prefixCls}-card`]: type.indexOf('card') >= 0, [`${prefixCls}-${type}`]: true, [`${prefixCls}-no-animation`]: !tabPaneAnimated, }); // only card type tabs can be added and closed let childrenWithClose; if (type === 'editable-card') { childrenWithClose = []; React.Children.forEach(children as React.ReactNode, (child: React.ReactElement, index) => { let closable = child.props.closable; closable = typeof closable === 'undefined' ? true : closable; const closeIcon = closable ? ( this.removeTab(child.key, e)} /> ) : null; childrenWithClose.push(cloneElement(child, { tab: (
{child.props.tab} {closeIcon}
), key: child.key || index, })); }); // Add new tab handler if (!hideAdd) { tabBarExtraContent = ( {tabBarExtraContent} ); } } tabBarExtraContent = tabBarExtraContent ? (
{tabBarExtraContent}
) : null; const renderTabBar = () => ( ); return ( } onChange={this.handleChange} > {childrenWithClose || children} ); } }