import * as React from 'react'; import * as ReactDOM 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 | React.MouseEvent, action: any) => void; size?: 'large' | 'default' | 'small'; style?: React.CSSProperties; prefixCls?: string; className?: string; animated?: boolean | { inkBar: boolean; tabPane: boolean; }; tabBarGutter?: number; } // Tabs export interface TabPaneProps { /** 选项卡头显示文字 */ tab?: React.ReactNode | string; style?: React.CSSProperties; closable?: boolean; className?: string; disabled?: boolean; forceRender?: boolean; } export default class Tabs extends React.Component { static TabPane = TabPane as React.ClassicComponentClass; static defaultProps = { prefixCls: 'ant-tabs', hideAdd: false, }; createNewTab = (targetKey: React.MouseEvent) => { const onEdit = this.props.onEdit; if (onEdit) { onEdit(targetKey, 'add'); } } removeTab = (targetKey: string, e: React.MouseEvent) => { e.stopPropagation(); if (!targetKey) { return; } const onEdit = this.props.onEdit; if (onEdit) { onEdit(targetKey, 'remove'); } } handleChange = (activeKey: string) => { const onChange = this.props.onChange; if (onChange) { onChange(activeKey); } } componentDidMount() { const NO_FLEX = ' no-flex'; const tabNode = ReactDOM.findDOMNode(this) as Element; 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, tabBarGutter, } = 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' || size === 'large')), 'Tabs[type=card|editable-card] doesn\'t have small or large size, it\'s by designed.', ); const cls = classNames(className, { [`${prefixCls}-vertical`]: tabPosition === 'left' || tabPosition === 'right', [`${prefixCls}-${size}`]: !!size, [`${prefixCls}-card`]: type.indexOf('card') >= 0, [`${prefixCls}-${type}`]: true, [`${prefixCls}-no-animation`]: !tabPaneAnimated, }); // only card type tabs can be added and closed let childrenWithClose: React.ReactElement[] = []; 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 as string, e)} /> ) : null; childrenWithClose.push(React.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.length > 0 ? childrenWithClose : children} ); } }