| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 | import React, { createRef, PureComponent, ReactNode } from 'react';import PropTypes from 'prop-types';import cls from 'classnames';import { cssClasses } from '@douyinfe/semi-foundation/tabs/constants';import getDataAttr from '@douyinfe/semi-foundation/utils/getDataAttr';import TabsContext from './tabs-context';import { TabContextValue } from './interface';import TabPaneTransition from './TabPaneTransition';import { PlainTab, TabPaneProps } from './interface';class TabPane extends PureComponent<TabPaneProps> {    static isTabPane = true;    static contextType = TabsContext;    static propTypes = {        className: PropTypes.string,        style: PropTypes.object,        children: PropTypes.node,        disabled: PropTypes.bool,        itemKey: PropTypes.string,        tab: PropTypes.node,        icon: PropTypes.node,        closable: PropTypes.bool    };    lastActiveKey: string = null;    ref = createRef<HTMLDivElement>();    isAnimating: boolean;    _active: boolean;    context: TabContextValue;    componentDidMount(): void {        this.lastActiveKey = this.context.activeKey;    }    // get direction from current item key to activeKey    getDirection = (activeKey: string, itemKey: string, panes: Array<PlainTab>): boolean => {        if (itemKey !== null && activeKey !== null && Array.isArray(panes) && panes.length) {            const activeIndex = panes.findIndex(pane => pane.itemKey === activeKey);            const itemIndex = panes.findIndex(pane => pane.itemKey === itemKey);            const lastActiveIndex = panes.findIndex(pane => pane.itemKey === this.lastActiveKey);            this.lastActiveKey = activeKey;            if (activeIndex === itemIndex) {                return lastActiveIndex > activeIndex;            } else {                return itemIndex < activeIndex;            }        }        return false;    };    /* istanbul ignore next */    hideScroll = (): void => {        if (this.ref && this.ref.current) {            this.ref.current.style.overflow = 'hidden';            this.isAnimating = true;        }    };    /* istanbul ignore next */    autoScroll = (): void => {        if (this.ref && this.ref.current) {            this.ref.current.style.overflow = '';            this.isAnimating = false;        }    };    shouldRender = (): boolean => {        const { itemKey } = this.props;        const { activeKey, lazyRender } = this.context;        const active = activeKey === itemKey;        this._active = this._active || active;        return lazyRender ? this._active : true;    };    render(): ReactNode {        const { tabPaneMotion: motion, tabPosition } = this.context;        const { className, style, children, itemKey, ...restProps } = this.props;        const active = this.context.activeKey === itemKey;        const classNames = cls(className, {            [cssClasses.TABS_PANE_INACTIVE]: !active,            [cssClasses.TABS_PANE_ACTIVE]: active,            [cssClasses.TABS_PANE]: true,        });        const shouldRender = this.shouldRender();        return (            <div                ref={this.ref}                role="tabpanel"                id={`semiTabPanel${itemKey}`}                aria-labelledby={`semiTab${itemKey}`}                className={classNames}                style={style}                aria-hidden={active ? 'false' : 'true'}                tabIndex={0}                {...getDataAttr(restProps)}                x-semi-prop="children"            >                {motion ? (                    <TabPaneTransition                        direction={this.getDirection(this.context.activeKey, itemKey, this.context.panes)}                        motion={motion}                        mode={tabPosition === 'top' ? 'horizontal' : 'vertical'}                        state={active ? 'enter' : 'leave'}                    >                        {(transitionStyle): ReactNode => (                            <div                                className={`${cssClasses.TABS_PANE_MOTION_OVERLAY}`}                                style={{ ...transitionStyle }}                                x-semi-prop="children"                            >                                {shouldRender ? children : null}                            </div>                        )}                    </TabPaneTransition>                ) : shouldRender ? (                    children                ) : null}            </div>        );    }}export default TabPane;
 |