7
7
* License v3.0 only", or the "Server Side Public License, v 1".
8
8
*/
9
9
10
- import React , { MouseEvent , useCallback } from 'react' ;
10
+ import React , { MouseEvent , useCallback , useRef } from 'react' ;
11
11
import { i18n } from '@kbn/i18n' ;
12
12
import { css } from '@emotion/react' ;
13
13
import {
@@ -18,19 +18,29 @@ import {
18
18
EuiThemeComputed ,
19
19
useEuiTheme ,
20
20
} from '@elastic/eui' ;
21
+ import { TabMenu } from '../tab_menu' ;
21
22
import { getTabAttributes } from '../../utils/get_tab_attributes' ;
22
- import type { TabItem } from '../../types' ;
23
+ import type { TabItem , GetTabMenuItems } from '../../types' ;
23
24
24
25
export interface TabProps {
25
26
item : TabItem ;
26
27
isSelected : boolean ;
27
28
tabContentId : string ;
29
+ getTabMenuItems ?: GetTabMenuItems ;
28
30
onSelect : ( item : TabItem ) => void ;
29
- onClose : ( item : TabItem ) => void ;
31
+ onClose : ( ( item : TabItem ) => void ) | undefined ;
30
32
}
31
33
32
- export const Tab : React . FC < TabProps > = ( { item, isSelected, tabContentId, onSelect, onClose } ) => {
34
+ export const Tab : React . FC < TabProps > = ( {
35
+ item,
36
+ isSelected,
37
+ tabContentId,
38
+ getTabMenuItems,
39
+ onSelect,
40
+ onClose,
41
+ } ) => {
33
42
const { euiTheme } = useEuiTheme ( ) ;
43
+ const containerRef = useRef < HTMLDivElement > ( ) ;
34
44
35
45
const tabContainerDataTestSubj = `unifiedTabs_tab_${ item . id } ` ;
36
46
const closeButtonLabel = i18n . translate ( 'unifiedTabs.closeTabButton' , {
@@ -51,23 +61,24 @@ export const Tab: React.FC<TabProps> = ({ item, isSelected, tabContentId, onSele
51
61
const onCloseEvent = useCallback (
52
62
( event : MouseEvent < HTMLButtonElement > ) => {
53
63
event . stopPropagation ( ) ;
54
- onClose ( item ) ;
64
+ onClose ?. ( item ) ;
55
65
} ,
56
66
[ onClose , item ]
57
67
) ;
58
68
59
69
const onClickEvent = useCallback (
60
70
( event : MouseEvent < HTMLDivElement > ) => {
61
- if ( event . currentTarget . getAttribute ( 'data-test-subj' ) === tabContainerDataTestSubj ) {
71
+ if ( event . currentTarget === containerRef . current ) {
62
72
// if user presses on the space around the buttons, we should still trigger the onSelectEvent
63
73
onSelectEvent ( event ) ;
64
74
}
65
75
} ,
66
- [ onSelectEvent , tabContainerDataTestSubj ]
76
+ [ onSelectEvent ]
67
77
) ;
68
78
69
79
return (
70
80
< EuiFlexGroup
81
+ ref = { containerRef }
71
82
alignItems = "center"
72
83
css = { getTabContainerCss ( euiTheme , isSelected ) }
73
84
data-test-subj = { tabContainerDataTestSubj }
@@ -89,15 +100,26 @@ export const Tab: React.FC<TabProps> = ({ item, isSelected, tabContentId, onSele
89
100
{ item . label }
90
101
</ EuiText >
91
102
</ button >
92
- < EuiFlexItem grow = { false } className = "unifiedTabs__closeTabBtn" >
93
- < EuiButtonIcon
94
- aria-label = { closeButtonLabel }
95
- title = { closeButtonLabel }
96
- color = "text"
97
- data-test-subj = { `unifiedTabs_closeTabBtn_${ item . id } ` }
98
- iconType = "cross"
99
- onClick = { onCloseEvent }
100
- />
103
+ < EuiFlexItem grow = { false } className = "unifiedTabs__tabActions" >
104
+ < EuiFlexGroup responsive = { false } direction = "row" gutterSize = "none" >
105
+ { ! ! getTabMenuItems && (
106
+ < EuiFlexItem grow = { false } className = "unifiedTabs__tabMenuBtn" >
107
+ < TabMenu item = { item } getTabMenuItems = { getTabMenuItems } />
108
+ </ EuiFlexItem >
109
+ ) }
110
+ { ! ! onClose && (
111
+ < EuiFlexItem grow = { false } className = "unifiedTabs__closeTabBtn" >
112
+ < EuiButtonIcon
113
+ aria-label = { closeButtonLabel }
114
+ title = { closeButtonLabel }
115
+ color = "text"
116
+ data-test-subj = { `unifiedTabs_closeTabBtn_${ item . id } ` }
117
+ iconType = "cross"
118
+ onClick = { onCloseEvent }
119
+ />
120
+ </ EuiFlexItem >
121
+ ) }
122
+ </ EuiFlexGroup >
101
123
</ EuiFlexItem >
102
124
</ EuiFlexGroup >
103
125
) ;
@@ -111,22 +133,22 @@ function getTabContainerCss(euiTheme: EuiThemeComputed, isSelected: boolean) {
111
133
border-right : ${ euiTheme . border . thin } ;
112
134
border-color : ${ euiTheme . colors . lightShade } ;
113
135
height : ${ euiTheme . size . xl } ;
114
- padding-left : ${ euiTheme . size . m } ;
115
- padding-right : ${ euiTheme . size . xs } ;
136
+ padding-inline : ${ euiTheme . size . xs } ;
116
137
min-width : 96px ;
117
138
max-width : 280px ;
118
139
119
140
background-color : ${ isSelected ? euiTheme . colors . emptyShade : euiTheme . colors . lightestShade } ;
120
141
color : ${ isSelected ? euiTheme . colors . text : euiTheme . colors . subduedText } ;
121
142
transition : background-color ${ euiTheme . animation . fast } ;
122
143
123
- .unifiedTabs__closeTabBtn {
144
+ .unifiedTabs__tabActions {
124
145
opacity : 0 ;
125
146
transition : opacity ${ euiTheme . animation . fast } ;
126
147
}
127
148
128
- & : hover {
129
- .unifiedTabs__closeTabBtn {
149
+ & : hover ,
150
+ & : focus-within {
151
+ .unifiedTabs__tabActions {
130
152
opacity : 1 ;
131
153
}
132
154
}
@@ -149,9 +171,10 @@ function getTabContainerCss(euiTheme: EuiThemeComputed, isSelected: boolean) {
149
171
function getTabButtonCss ( euiTheme : EuiThemeComputed ) {
150
172
return css `
151
173
width : 100% ;
174
+ min-height : 100% ;
152
175
min-width : 0 ;
153
176
flex-grow : 1 ;
154
- padding-right : ${ euiTheme . size . xs } ;
177
+ padding-inline : ${ euiTheme . size . xs } ;
155
178
text-align : left;
156
179
color : inherit;
157
180
border : none;
0 commit comments