import * as React from 'react' ; import { useEffect , useState } from 'react' ; import classNames from 'classnames' ; import toArray from 'rc-util/lib/Children/toArray' ; import isMobile from 'rc-util/lib/isMobile' ; import useMergedState from 'rc-util/lib/hooks/useMergedState' ; import TabNavList from './TabNavList' ; import TabPanelList from './TabPanelList' ; import type { TabPaneProps } from './TabPanelList/TabPane' ; import TabPane from './TabPanelList/TabPane' ; import type { TabPosition , RenderTabBar , TabsLocale , EditableConfig , AnimatedConfig , OnTabScroll , Tab , TabBarExtraContent , } from './interface' ; import TabContext from './TabContext' ; /**
 * Should added antd:
 * - type
 *
 * Removed:
 * - onNextClick
 * - onPrevClick
 * - keyboard
 */ let uuid = 0 ; export interface TabsProps extends Omit < React . HTMLAttributes < HTMLDivElement > , 'onChange' > { prefixCls ? : string ; className ? : string ; style ? : React . CSSProperties ; children ? : React . ReactNode ; id ? : string ; activeKey ? : string ; defaultActiveKey ? : string ; direction ? : 'ltr' | 'rtl' ; animated ? : boolean | AnimatedConfig ; renderTabBar ? : RenderTabBar ; tabBarExtraContent ? : TabBarExtraContent ; tabBarGutter ? : number ; tabBarStyle ? : React . CSSProperties ; tabPosition ? : TabPosition ; destroyInactiveTabPane ? : boolean ; onChange ? : ( activeKey : string ) => void ; onTabClick ? : ( activeKey : string , e : React . KeyboardEvent | React . MouseEvent ) => void ; onTabScroll ? : OnTabScroll ; editable ? : EditableConfig ; locale ? : TabsLocale ; moreIcon ? : React . ReactNode ; private moreTransitionName ? : string ; } function parseTabList ( children ) { return toArray ( children ) . map ( ( node ) => { if ( React . isValidElement ( node ) ) { const key = node . key !== undefined ? String ( node . key ) : undefined ; return { key , ... node . props , node , } ; } return null ; } ) . filter ( tab => tab ) ; } function Tabs ( { id , prefixCls = 'rc-tabs' , className , children , direction , activeKey , defaultActiveKey , editable , animated = { inkBar : true , tabPane : false , } , tabPosition = 'top' , tabBarGutter , tabBarStyle , tabBarExtraContent , locale , moreIcon , moreTransitionName , destroyInactiveTabPane , renderTabBar , onChange , onTabClick , onTabScroll , ... restProps } , ref ) { const tabs = parseTabList ( children ) ; const rtl = direction === 'rtl' ; let mergedAnimated ; if ( animated === false ) { mergedAnimated = { inkBar : false , tabPane : false , } ; } else if ( animated === true ) { mergedAnimated = { inkBar : true , tabPane : true , } ; } else { mergedAnimated = { inkBar : true , tabPane : false , ... ( typeof animated === 'object' ? animated : { } ) , } ; } const [ mobile , setMobile ] = useState ( false ) ; useEffect ( ( ) => { setMobile ( isMobile ( ) ) ; } , [ ] ) ; const [ mergedActiveKey , setMergedActiveKey ] = useMergedState < string > ( ( ) => tabs [ 0 ] ?. key , { value : activeKey , defaultValue : defaultActiveKey , } ) ; const [ activeIndex , setActiveIndex ] = useState ( ( ) => tabs . findIndex ( tab => tab . key === mergedActiveKey ) ) ; useEffect ( ( ) => { let newActiveIndex = tabs . findIndex ( tab => tab . key === mergedActiveKey ) ; if ( newActiveIndex === - 1 ) { newActiveIndex = Math . max ( 0 , Math . min ( activeIndex , tabs . length - 1 ) ) ; setMergedActiveKey ( tabs [ newActiveIndex ] ?. key ) ; } setActiveIndex ( newActiveIndex ) ; } , [ tabs . map ( tab => tab . key ) . join ( '_' ) , mergedActiveKey , activeIndex ] ) ; const [ mergedId , setMergedId ] = useMergedState ( null , { value : id , } ) ; let mergedTabPosition = tabPosition ; if ( mobile && ! [ 'left' , 'right' ] . includes ( tabPosition ) ) { mergedTabPosition = 'top' ; } useEffect ( ( ) => { if ( ! id ) { setMergedId ( `rc-tabs-${ process . env . NODE_ENV === 'test' ? 'test' : uuid }` ) ; uuid += 1 ; } } , [ ] ) ; function onInternalTabClick ( key , e ) { onTabClick ?. ( key , e ) ; const isActiveChanged = key !== mergedActiveKey ; setMergedActiveKey ( key ) ; if ( isActiveChanged ) { onChange ?. ( key ) ; } } const sharedProps = { id : mergedId , activeKey : mergedActiveKey , animated : mergedAnimated , tabPosition : mergedTabPosition , rtl , mobile , } ; let tabNavBar ; const tabNavBarProps = { ... sharedProps , editable , locale , moreIcon , moreTransitionName , tabBarGutter , onTabClick : onInternalTabClick , onTabScroll , extra : tabBarExtraContent , style : tabBarStyle , panes : children , } ; if ( renderTabBar ) { tabNavBar = renderTabBar ( tabNavBarProps , TabNavList ) ; } else { tabNavBar = < TabNavList { ... tabNavBarProps } / > ; } return ( < TabContext . Provider value = { { tabs , prefixCls } } > < div ref = { ref } id = { id } className = { classNames ( prefixCls , `${ prefixCls } - $ { mergedTabPosition } `, {
            [` $ { prefixCls } - mobile `]: mobile,
            [` $ { prefixCls } - editable `]: editable,
            [` $ { prefixCls } - rtl `]: rtl,
        }, className)} {...restProps}>
        {tabNavBar}
        <TabPanelList destroyInactiveTabPane={destroyInactiveTabPane} {...sharedProps} animated={mergedAnimated}/>
      </div>
    </TabContext.Provider>);
}
const ForwardTabs = React.forwardRef(Tabs);
export type ForwardTabsType = typeof ForwardTabs & {
    TabPane: typeof TabPane;
};
(ForwardTabs as ForwardTabsType).TabPane = TabPane;
export default ForwardTabs as ForwardTabsType;
