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 } from 'lodash'; import { IconChevronRight, IconChevronLeft, IconClose } from '@douyinfe/semi-icons'; import { getUuidv4 } from '@douyinfe/semi-foundation/utils/uuid'; export interface TabBarState { endInd: number; rePosKey: number; startInd: number } 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 }; uuid: string; constructor(props: TabBarProps) { super(props); this.state = { endInd: props.list.length, rePosKey: 0, startInd: 0, }; this.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); // eslint-disable-next-line max-len const tabItem = document.querySelector(`[data-uuid="${this.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 } = this.props; const panelIcon = panel.icon ? this.renderIcon(panel.icon) : null; const closableIcon = (type === 'card' && panel.closable) ? ) => deleteTabItem(panel.itemKey, e)} /> : null; let events = {}; const key = panel.itemKey; if (!panel.disabled) { events = { onClick: (e: MouseEvent): void => this.handleItemClick(key, e), }; } const isSelected = this._isActive(key); const className = cls(cssClasses.TABS_TAB, { [cssClasses.TABS_TAB_ACTIVE]: isSelected, [cssClasses.TABS_TAB_DISABLED]: panel.disabled, [`${cssClasses.TABS_TAB}-small`]: size === 'small', [`${cssClasses.TABS_TAB}-medium`]: size === 'medium', }); return ( ); }; renderTabComponents = (list: Array): Array => list.map(panel => this.renderTabItem(panel)); handleArrowClick = (items: Array, pos: 'start' | 'end'): void => { const inline = pos === 'start' ? 'end' : 'start'; const lastItem = pos === 'start' ? items.pop() : items.shift(); if (!lastItem) { return; } const key = this._getItemKey(lastItem.itemKey); // eslint-disable-next-line max-len const tabItem = document.querySelector(`[data-uuid="${this.uuid}"] .${cssClasses.TABS_TAB}[data-scrollkey="${key}"]`); tabItem.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline }); }; renderCollapse = (items: Array, icon: ReactNode, pos: 'start' | 'end'): ReactNode => { if (isEmpty(items)) { return (