1+ 'strict'
2+
13import {
24 EuiButton ,
35 EuiContextMenu ,
@@ -6,7 +8,12 @@ import {
68 EuiIcon ,
79 EuiPopover ,
810 EuiText ,
11+ EuiPanel ,
12+ EuiLink ,
13+ useEuiOverflowScroll ,
914 useGeneratedHtmlId ,
15+ useEuiTheme ,
16+ useEuiFontSize ,
1017} from '@elastic/eui'
1118import { icon as EuiIconVisualizeApp } from '@elastic/eui/es/components/icon/assets/app_visualize'
1219import { icon as EuiIconArrowDown } from '@elastic/eui/es/components/icon/assets/arrow_down'
@@ -45,15 +52,23 @@ appendIconComponentCache({
4552type VersionDropdownItem = {
4653 name : string
4754 href ?: string
55+ disabled : boolean
4856 children ?: VersionDropdownItem [ ]
4957}
5058
5159type VersionDropdownProps = {
52- items : VersionDropdownItem [ ]
60+ currentVersion ?: string
61+ allVersionsUrl ?: string
62+ items ?: VersionDropdownItem [ ]
5363}
5464
55- const VersionDropdown = ( { items } : VersionDropdownProps ) => {
65+ const VersionDropdown = ( {
66+ allVersionsUrl,
67+ currentVersion,
68+ items,
69+ } : VersionDropdownProps ) => {
5670 const [ isPopoverOpen , setPopover ] = useState ( false )
71+ const { euiTheme } = useEuiTheme ( )
5772
5873 const contextMenuPopoverId = useGeneratedHtmlId ( {
5974 prefix : 'contextMenuPopover' ,
@@ -74,63 +89,120 @@ const VersionDropdown = ({ items }: VersionDropdownProps) => {
7489 return {
7590 name : item . name ,
7691 href : item . href ,
92+ disabled : item . disabled ,
7793 }
7894 } )
7995 }
8096
8197 const convertToPanels = (
8298 items : VersionDropdownItem [ ]
8399 ) : EuiContextMenuPanelDescriptor [ ] => {
84- return items . flatMap ( ( item , index ) => {
85- if ( item . children == null ) {
86- return [ ]
87- } else {
88- return {
89- id : index + 1 ,
90- title : item . name ,
91- initialFocusedItemIndex : 0 ,
92- width : WIDTH ,
93- size : 's' ,
94- items : item . children ? convertItems ( item . children ) : [ ] ,
95- }
96- }
97- } )
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+ } )
98119 }
99120
100121 const WIDTH = 175
101122
102- const topLevelItems = items . map ( ( item , index ) => {
103- return {
104- name : item . name ,
105- panel : item . children ?. length ? index + 1 : undefined ,
106- href : item . href ,
107- }
108- } )
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+ } )
109132
110- const subpanels = convertToPanels ( items )
133+ const subpanels = ( ) => convertToPanels ( items )
111134
112- const panels : EuiContextMenuPanelDescriptor [ ] = [
135+ const panels = ( ) : EuiContextMenuPanelDescriptor [ ] => [
113136 {
114137 id : 0 ,
115138 title : (
116139 < EuiFlexGroup gutterSize = "s" alignItems = "center" >
117140 < EuiFlexItem grow = { 0 } >
118- < EuiIcon type = "check" />
141+ < EuiIcon type = "check" size = "s" />
142+ </ EuiFlexItem >
143+ < EuiFlexItem grow = { 1 } >
144+ < EuiText size = "s" > { currentVersion } </ EuiText >
119145 </ EuiFlexItem >
120- < EuiFlexItem grow = { 1 } > Current (9.0+)</ EuiFlexItem >
121146 </ EuiFlexGroup >
122147 ) ,
123148 width : WIDTH ,
124149 size : 's' ,
125150 items : [
126- ...topLevelItems ,
127- {
128- name : 'All versions' ,
129- href : 'https://elastic.co' ,
130- } ,
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+ : [ ] ) ,
131203 ] ,
132204 } ,
133- ...subpanels ,
205+ ...( items != null ? subpanels ( ) : [ ] ) ,
134206 ]
135207
136208 const button = (
@@ -143,13 +215,12 @@ const VersionDropdown = ({ items }: VersionDropdownProps) => {
143215 style = { { borderRadius : 9999 } }
144216 >
145217 < EuiText
146- size = "xs"
147218 css = { css `
148- font-weight : 600 ;
149- font-size : 0.875 rem ;
219+ font-weight : ${ euiTheme . font . weight . bold } ;
220+ font-size : ${ useEuiFontSize ( 'xs' ) . fontSize } ;
150221 ` }
151222 >
152- Current (9.0+ )
223+ Current version ( { currentVersion } )
153224 </ EuiText >
154225 </ EuiButton >
155226 )
@@ -161,10 +232,35 @@ const VersionDropdown = ({ items }: VersionDropdownProps) => {
161232 isOpen = { isPopoverOpen }
162233 closePopover = { closePopover }
163234 panelPaddingSize = "none"
164- anchorPosition = "downLeft "
235+ anchorPosition = "downRight "
165236 repositionOnScroll = { true }
166237 >
167- < 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+ />
168264 </ EuiPopover >
169265 )
170266}
@@ -174,6 +270,8 @@ customElements.define(
174270 r2wc ( VersionDropdown , {
175271 props : {
176272 items : 'json' ,
273+ currentVersion : 'string' ,
274+ allVersionsUrl : 'string' ,
177275 } ,
178276 } )
179277)
0 commit comments