1
1
import * as React from 'react' ;
2
- import { useCallback } from 'react' ;
3
- import update from 'immutability-helper' ;
2
+ import { useCallback , useState } from 'react' ;
4
3
import { DndProvider } from 'react-dnd' ;
5
4
import HTML5Backend from 'react-dnd-html5-backend' ;
5
+ import update from 'immutability-helper' ;
6
6
7
- import { Scrollable } from 'mo/components/scrollable' ;
8
- import { TabSwicher , Tab } from './Tab' ;
7
+ import { prefixClaName , getBEMElement , getBEMModifier , classNames } from 'mo/common/className' ;
8
+ import { Icon } from 'mo/components/icon' ;
9
+
10
+ import { Tab , tabItemClassName } from './Tab' ;
9
11
import TabButton from './tabButton' ;
10
- import './style.scss' ;
11
12
13
+ import './style.scss' ;
12
14
export interface ITab {
13
- id ?: number | string ;
15
+ key ?: string ;
14
16
name ?: string ;
15
- activeTab ?: number ;
16
17
modified ?: boolean ;
17
- renderPane ?: ( ) => React . ReactNode ;
18
18
value ?: string ;
19
- mode ?: string | undefined ;
19
+ language ?: string | undefined ;
20
+ tip ?: string | React . ReactNode ;
21
+ label ?: React . ReactNode ;
22
+ renderPanel ?: React . ReactNode ;
20
23
}
21
24
export interface ITabsProps {
25
+ closable ?: boolean ;
22
26
data : ITab [ ] ;
23
- closeTab ?: ( item : ITab ) => void ;
27
+ activeTab ?: string ;
28
+ type ?: 'line' | 'editable-card' ;
29
+ onCloseTab ?: ( item ?: ITab ) => void ;
24
30
onMoveTab ?: ( tabs : ITab [ ] ) => void ;
25
- onSelectTab ?: ( index : number ) => void ;
26
- onTabChange : ( index : number ) => void ;
31
+ onSelectTab ?: ( event : React . MouseEvent , key ?: string ) => void ;
32
+ onTabChange : ( index : string ) => void ;
27
33
}
28
34
29
- const DraggleTabs = ( props : ITabsProps ) => {
30
- const { data, onSelectTab } = props ;
35
+ export const tabsClassName = prefixClaName ( 'tabs' )
36
+ export const tabsHeader = getBEMElement ( tabsClassName , 'header' )
37
+ export const tabsContent = getBEMElement ( tabsClassName , 'content' )
38
+ export const tabsContentItem = getBEMElement ( tabsContent , 'item' )
31
39
40
+ const Tabs = ( props : ITabsProps ) => {
41
+ const { closable, data, activeTab : newActiveTab , type = 'line' , onCloseTab, onSelectTab } = props ;
42
+ const [ activeTab , setActiveTab ] = useState < string | number | void > ( newActiveTab )
32
43
const onMoveTab = useCallback (
33
44
( dragIndex , hoverIndex ) => {
34
45
const dragTab = data [ dragIndex ] ;
@@ -44,37 +55,67 @@ const DraggleTabs = (props: ITabsProps) => {
44
55
[ data ]
45
56
) ;
46
57
47
- const onTabClick = ( key ) => {
48
- console . log ( `onTabClick ${ key } ` ) ;
49
- onSelectTab ?.( key ) ;
58
+ const onTabClick = ( event : React . MouseEvent , key ?: string ) => {
59
+ setActiveTab ( key )
60
+ onSelectTab ?.( event , key ) ;
61
+ } ;
62
+
63
+ const onTabClose = ( item : ITab ) => {
64
+ let activekey = ( data . filter ( tab => item . key === tab . key ) ) ?. [ 0 ] ?. key
65
+ setActiveTab ( activekey )
66
+ onCloseTab ?.( item )
50
67
} ;
51
68
52
- const onTabClose = ( item : ITab ) => { } ;
69
+ const renderTabBar = ( tab ) => (
70
+ < TabButton
71
+ key = { tab . key }
72
+ name = { tab . name }
73
+ modified = { tab . modified }
74
+ active = { activeTab === tab . key }
75
+ onClose = { ( ) => onCloseTab ?.( tab ) }
76
+ className = { 'tab-button' }
77
+ /> )
53
78
return (
54
79
< DndProvider backend = { HTML5Backend } >
55
- < Scrollable className = { 'normal-items' } >
56
- < TabSwicher className = "tab-switcher" >
57
- { data ?. map ( ( item : ITab , index : number ) => (
58
- < Tab
59
- onMoveTab = { onMoveTab }
60
- onTabChange = { onTabClick }
61
- index = { index }
62
- id = { item . id }
63
- >
64
- < TabButton
65
- key = { item . id }
66
- name = { item . name }
67
- modified = { item . modified }
68
- active = { item . activeTab === index }
69
- onClose = { ( ) => onTabClose ( item ) }
70
- className = { 'tab-button' }
71
- />
72
- </ Tab >
73
- ) ) }
74
- </ TabSwicher >
75
- </ Scrollable >
80
+ < div className = { classNames ( tabsClassName , getBEMModifier ( tabsClassName , `${ type } ` ) ) } >
81
+ < div className = { tabsHeader } >
82
+ { data ?. map ( ( tab : ITab , index : number ) => {
83
+ return (
84
+ < Tab
85
+ onMoveTab = { onMoveTab }
86
+ onTabChange = { onTabClick }
87
+ index = { index }
88
+ propsKey = { tab . key }
89
+ key = { tab . key }
90
+ activeTab = { activeTab }
91
+ title = { tab . tip }
92
+ >
93
+ { type === 'editable-card' ? renderTabBar ?.( tab ) : tab . label }
94
+ { closable && (
95
+ < div className = { getBEMModifier ( tabItemClassName , 'close' ) } onClick = { ( e ) => {
96
+ e . stopPropagation ( )
97
+ onTabClose ( tab )
98
+ } } >
99
+ < Icon type = "close" />
100
+ </ div >
101
+ ) }
102
+ </ Tab >
103
+ )
104
+ } ) }
105
+ </ div >
106
+ < div className = { tabsContent } > {
107
+ data ?. map ( ( tab : ITab ) => {
108
+ return (
109
+ < div className = { classNames ( tabsContentItem , { [ getBEMModifier ( tabsContentItem , 'active' ) ] : activeTab === tab . key } ) } >
110
+ { tab . renderPanel }
111
+ </ div >
112
+ )
113
+ } )
114
+ }
115
+ </ div >
116
+ </ div >
76
117
</ DndProvider >
77
118
) ;
78
119
} ;
79
120
80
- export default DraggleTabs ;
121
+ export default Tabs ;
0 commit comments