import React, { MouseEvent, ReactElement, ReactNode } from 'react'; import PropTypes from 'prop-types'; import cls from 'classnames'; import { cssClasses, strings } from '@douyinfe/semi-foundation/tabs/constants'; import getDataAttr from '@douyinfe/semi-foundation/utils/getDataAttr'; import OverflowList from '../overflowList'; import Dropdown from '../dropdown'; import Button from '../button'; import { TabBarProps, PlainTab } from './interface'; import { isEmpty, pick } from 'lodash'; import { IconChevronRight, IconChevronLeft, IconClose } from '@douyinfe/semi-icons'; import { getUuidv4 } from '@douyinfe/semi-foundation/utils/uuid'; import TabItem from './TabItem'; export interface TabBarState { endInd: number; rePosKey: number; startInd: number; uuid: string } export interface OverflowItem extends PlainTab { key: string; active: boolean } class TabBar extends React.Component { static propTypes = { activeKey: PropTypes.string, className: PropTypes.string, collapsible: PropTypes.bool, list: PropTypes.array, onTabClick: PropTypes.func, size: PropTypes.oneOf(strings.SIZE), style: PropTypes.object, tabBarExtraContent: PropTypes.node, tabPosition: PropTypes.oneOf(strings.POSITION_MAP), type: PropTypes.oneOf(strings.TYPE_MAP), closable: PropTypes.bool, deleteTabItem: PropTypes.func }; constructor(props: TabBarProps) { super(props); this.state = { endInd: props.list.length, rePosKey: 0, startInd: 0, uuid: '', }; } componentDidMount() { this.setState({ uuid: getUuidv4(), }); } renderIcon(icon: ReactNode): ReactNode { return ( {icon} ); } renderExtra(): ReactNode { const { tabBarExtraContent, type, size } = this.props; const tabBarExtraContentDefaultStyle = { float: 'right' }; const tabBarExtraContentStyle = tabBarExtraContent && (tabBarExtraContent as ReactElement).props ? (tabBarExtraContent as ReactElement).props.style : {}; const extraCls = cls(cssClasses.TABS_BAR_EXTRA, { [`${cssClasses.TABS_BAR}-${type}-extra`]: type, [`${cssClasses.TABS_BAR}-${type}-extra-${size}`]: size, }); if (tabBarExtraContent) { const tabBarStyle = { ...tabBarExtraContentDefaultStyle, ...tabBarExtraContentStyle }; return (
{tabBarExtraContent}
); } return null; } handleItemClick = (itemKey: string, e: MouseEvent): void => { this.props.onTabClick(itemKey, e); if (this.props.collapsible) { const key = this._getItemKey(itemKey); const tabItem = document.querySelector(`[data-uuid="${this.state.uuid}"] .${cssClasses.TABS_TAB}[data-scrollkey="${key}"]`); tabItem.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'nearest' }); } }; handleKeyDown = (event: React.KeyboardEvent, itemKey: string, closable: boolean) => { this.props.handleKeyDown(event, itemKey, closable); } renderTabItem = (panel: PlainTab): ReactNode => { const { size, type, deleteTabItem, handleKeyDown, tabPosition } = this.props; const isSelected = this._isActive(panel.itemKey); return ( ); }; renderTabComponents = (list: Array): Array => list.map(panel => this.renderTabItem(panel)); handleArrowClick = (items: Array, pos: 'start' | 'end'): void => { const lastItem = pos === 'start' ? items.pop() : items.shift(); if (!lastItem) { return; } const key = this._getItemKey(lastItem.itemKey); const tabItem = document.querySelector(`[data-uuid="${this.state.uuid}"] .${cssClasses.TABS_TAB}[data-scrollkey="${key}"]`); tabItem.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'nearest' }); }; renderCollapse = (items: Array, icon: ReactNode, pos: 'start' | 'end'): ReactNode => { if (isEmpty(items)) { return (