1
+ 'strict'
2
+
1
3
import {
2
4
EuiButton ,
3
5
EuiContextMenu ,
@@ -6,7 +8,12 @@ import {
6
8
EuiIcon ,
7
9
EuiPopover ,
8
10
EuiText ,
11
+ EuiPanel ,
12
+ EuiLink ,
13
+ useEuiOverflowScroll ,
9
14
useGeneratedHtmlId ,
15
+ useEuiTheme ,
16
+ useEuiFontSize ,
10
17
} from '@elastic/eui'
11
18
import { icon as EuiIconVisualizeApp } from '@elastic/eui/es/components/icon/assets/app_visualize'
12
19
import { icon as EuiIconArrowDown } from '@elastic/eui/es/components/icon/assets/arrow_down'
@@ -50,12 +57,18 @@ type VersionDropdownItem = {
50
57
}
51
58
52
59
type VersionDropdownProps = {
53
- currentVersion : string
54
- items : VersionDropdownItem [ ]
60
+ currentVersion ?: string
61
+ allVersionsUrl ?: string
62
+ items ?: VersionDropdownItem [ ]
55
63
}
56
64
57
- const VersionDropdown = ( { currentVersion, items } : VersionDropdownProps ) => {
65
+ const VersionDropdown = ( {
66
+ allVersionsUrl,
67
+ currentVersion,
68
+ items,
69
+ } : VersionDropdownProps ) => {
58
70
const [ isPopoverOpen , setPopover ] = useState ( false )
71
+ const { euiTheme } = useEuiTheme ( )
59
72
60
73
const contextMenuPopoverId = useGeneratedHtmlId ( {
61
74
prefix : 'contextMenuPopover' ,
@@ -84,60 +97,112 @@ const VersionDropdown = ({ currentVersion, items }: VersionDropdownProps) => {
84
97
const convertToPanels = (
85
98
items : VersionDropdownItem [ ]
86
99
) : EuiContextMenuPanelDescriptor [ ] => {
87
- return items . flatMap ( ( item , index ) => {
88
- if ( item . children == null ) {
89
- return [ ]
90
- } else {
91
- return {
92
- id : index + 1 ,
93
- title : item . name ,
94
- initialFocusedItemIndex : 0 ,
95
- width : WIDTH ,
96
- disabled : item . disabled ,
97
- size : 's' ,
98
- items : item . children ? convertItems ( item . children ) : [ ] ,
99
- }
100
- }
101
- } )
100
+ return items == null
101
+ ? [ ]
102
+ : items . flatMap ( ( item , index ) => {
103
+ if ( item . children == null ) {
104
+ return [ ]
105
+ } else {
106
+ return {
107
+ id : index + 1 ,
108
+ title : item . name ,
109
+ initialFocusedItemIndex : 0 ,
110
+ width : WIDTH ,
111
+ disabled : item . disabled ,
112
+ size : 's' ,
113
+ items : item . children
114
+ ? convertItems ( item . children )
115
+ : [ ] ,
116
+ }
117
+ }
118
+ } )
102
119
}
103
120
104
121
const WIDTH = 175
105
122
106
- const topLevelItems = items . map ( ( item , index ) => {
107
- return {
108
- name : item . name ,
109
- panel : item . children ?. length ? index + 1 : undefined ,
110
- href : item . href ,
111
- disabled : item . disabled ,
112
- }
113
- } )
123
+ const topLevelItems = ( ) =>
124
+ items . map ( ( item , index ) => {
125
+ return {
126
+ name : item . name ,
127
+ panel : item . children ?. length ? index + 1 : undefined ,
128
+ href : item . href ,
129
+ disabled : item . disabled ,
130
+ }
131
+ } )
114
132
115
- const subpanels = convertToPanels ( items )
133
+ const subpanels = ( ) => convertToPanels ( items )
116
134
117
- const panels : EuiContextMenuPanelDescriptor [ ] = [
135
+ const panels = ( ) : EuiContextMenuPanelDescriptor [ ] => [
118
136
{
119
137
id : 0 ,
120
138
title : (
121
139
< EuiFlexGroup gutterSize = "s" alignItems = "center" >
122
140
< EuiFlexItem grow = { 0 } >
123
- < EuiIcon type = "check" />
141
+ < EuiIcon type = "check" size = "s" />
124
142
</ EuiFlexItem >
125
143
< EuiFlexItem grow = { 1 } >
126
- Current ( { currentVersion } )
144
+ < EuiText size = "s" > { currentVersion } </ EuiText >
127
145
</ EuiFlexItem >
128
146
</ EuiFlexGroup >
129
147
) ,
130
148
width : WIDTH ,
131
149
size : 's' ,
132
150
items : [
133
- ...topLevelItems ,
134
- {
135
- name : 'All versions' ,
136
- href : 'https://elastic.co' ,
137
- } ,
151
+ ...( items == null
152
+ ? [
153
+ {
154
+ renderItem : ( ) => (
155
+ < EuiPanel paddingSize = "s" hasShadow = { false } >
156
+ < EuiText size = "xs" color = "subdued" >
157
+ There are no other versions available
158
+ for this page.
159
+ </ EuiText >
160
+ </ EuiPanel >
161
+ ) ,
162
+ } ,
163
+ ]
164
+ : topLevelItems ( ) ) ,
165
+ ...( items ?. length === 0
166
+ ? [
167
+ {
168
+ renderItem : ( ) => (
169
+ < EuiPanel paddingSize = "s" hasShadow = { false } >
170
+ < EuiText size = "xs" color = "subdued" >
171
+ This page was fully migrated to the
172
+ current version.
173
+ </ EuiText >
174
+ </ EuiPanel >
175
+ ) ,
176
+ } ,
177
+ ]
178
+ : [ ] ) ,
179
+ ...( allVersionsUrl != null
180
+ ? [
181
+ {
182
+ renderItem : ( ) => (
183
+ < EuiPanel
184
+ css = { css `
185
+ border-top : 1px solid
186
+ ${ euiTheme . border . color } ;
187
+ padding : ${ euiTheme . size . s } ;
188
+ ` }
189
+ >
190
+ < EuiLink
191
+ href = "/docs/versions"
192
+ color = "text"
193
+ >
194
+ < EuiText size = "s" >
195
+ View all versions
196
+ </ EuiText >
197
+ </ EuiLink >
198
+ </ EuiPanel >
199
+ ) ,
200
+ } ,
201
+ ]
202
+ : [ ] ) ,
138
203
] ,
139
204
} ,
140
- ...subpanels ,
205
+ ...( items != null ? subpanels ( ) : [ ] ) ,
141
206
]
142
207
143
208
const button = (
@@ -150,13 +215,12 @@ const VersionDropdown = ({ currentVersion, items }: VersionDropdownProps) => {
150
215
style = { { borderRadius : 9999 } }
151
216
>
152
217
< EuiText
153
- size = "xs"
154
218
css = { css `
155
- font-weight : 600 ;
156
- font-size : 0.875 rem ;
219
+ font-weight : ${ euiTheme . font . weight . bold } ;
220
+ font-size : ${ useEuiFontSize ( 'xs' ) . fontSize } ;
157
221
` }
158
222
>
159
- Current ({ currentVersion } )
223
+ Current version ({ currentVersion } )
160
224
</ EuiText >
161
225
</ EuiButton >
162
226
)
@@ -168,10 +232,35 @@ const VersionDropdown = ({ currentVersion, items }: VersionDropdownProps) => {
168
232
isOpen = { isPopoverOpen }
169
233
closePopover = { closePopover }
170
234
panelPaddingSize = "none"
171
- anchorPosition = "downLeft "
235
+ anchorPosition = "downRight "
172
236
repositionOnScroll = { true }
173
237
>
174
- < EuiContextMenu initialPanelId = { 0 } size = "s" panels = { panels } />
238
+ < EuiContextMenu
239
+ initialPanelId = { 0 }
240
+ size = "s"
241
+ panels = { panels ( ) }
242
+ css = { css `
243
+ max-height : 70vh ;
244
+ // This is needed because the CSS reset we are using
245
+ // is probably not fully compatible with the EUI
246
+ button {
247
+ cursor : pointer;
248
+ & : disabled {
249
+ cursor : default;
250
+ }
251
+ }
252
+ .euiContextMenuPanel__title {
253
+ position : sticky;
254
+ top : 0 ;
255
+ // !important because clicking on the title
256
+ // makes the background transparent
257
+ // and you unexpectedly see the items behind it.
258
+ background-color : ${ euiTheme . colors
259
+ . backgroundBasePlain } !important ;
260
+ }
261
+ ${ useEuiOverflowScroll ( 'y' ) }
262
+ ` }
263
+ />
175
264
</ EuiPopover >
176
265
)
177
266
}
@@ -182,6 +271,7 @@ customElements.define(
182
271
props : {
183
272
items : 'json' ,
184
273
currentVersion : 'string' ,
274
+ allVersionsUrl : 'string' ,
185
275
} ,
186
276
} )
187
277
)
0 commit comments