@@ -19,12 +19,16 @@ const MAX_DISPLAYED_VERSIONS = TRUNCATION_THRESHOLD - 1;
1919const HOVER_DELAY = 200 ;
2020const TOOLTIP_OPEN_DELAY = 200 ;
2121
22+ type VersionsBarSize = 's' | 'm' ;
23+
2224interface VersionsBarProps {
2325 preparedVersions : PreparedVersion [ ] ;
26+ withTitles ?: boolean ;
27+ size ?: VersionsBarSize ;
2428}
2529
26- export function VersionsBar ( { preparedVersions} : VersionsBarProps ) {
27- const shouldTruncateVersions = preparedVersions . length > TRUNCATION_THRESHOLD ;
30+ export function VersionsBar ( { preparedVersions, withTitles = true , size = 's' } : VersionsBarProps ) {
31+ const shouldTruncateVersions = preparedVersions . length > TRUNCATION_THRESHOLD && size === 's' ;
2832
2933 const [ hoveredVersion , setHoveredVersion ] = React . useState < string | undefined > ( ) ;
3034 const [ allVersionsDisplayed , setAllVersionsDisplayed ] = React . useState < boolean > ( false ) ;
@@ -103,12 +107,12 @@ export function VersionsBar({preparedVersions}: VersionsBarProps) {
103107 } , [ handleMouseEnter ] ) ;
104108
105109 const isDimmed = ( version : string ) => {
106- return hoveredVersion && hoveredVersion !== version ;
110+ return Boolean ( hoveredVersion && hoveredVersion !== version ) ;
107111 } ;
108112
109113 return (
110- < Flex gap = { 2 } direction = { 'column' } className = { b ( null ) } wrap >
111- < Flex className = { b ( 'bar' ) } grow = { 1 } gap = { 0.5 } >
114+ < Flex direction = { 'column' } className = { b ( 'bar-wrapper' , { size } ) } wrap >
115+ < Flex className = { b ( 'bar' , { size } ) } grow = { 1 } >
112116 { displayedVersions . map ( ( item ) => (
113117 < Tooltip
114118 key = { item . version }
@@ -119,54 +123,103 @@ export function VersionsBar({preparedVersions}: VersionsBarProps) {
119123 { item . version }
120124 </ React . Fragment >
121125 }
122- placement = { 'top-start' }
126+ placement = { size === 'm' ? 'auto' : 'top-start' }
123127 openDelay = { TOOLTIP_OPEN_DELAY }
124128 >
125129 < span
126130 onMouseEnter = { ( ) => {
127131 handleMouseEnter ( item . version ) ;
128132 } }
129133 onMouseLeave = { handleMouseLeave }
130- className = { b ( 'version' , { dimmed : isDimmed ( item . version ) } ) }
134+ className = { b ( 'version' , { dimmed : isDimmed ( item . version ) , size } ) }
131135 style = { { backgroundColor : item . color , width : `${ item . value } %` } }
132136 />
133137 </ Tooltip >
134138 ) ) }
135139 </ Flex >
136140
137- < Flex gap = { 0.5 } direction = { 'column' } >
138- { truncatedDisplayedVersions . map ( ( item ) => (
139- < Tooltip
140- key = { item . version }
141- content = { i18n ( 'tooltip_nodes' , { count : item . count } ) }
142- placement = { 'bottom-end' }
143- openDelay = { TOOLTIP_OPEN_DELAY }
144- >
145- < Flex gap = { 1 } alignItems = { 'center' } className = { b ( 'titles-wrapper' ) } >
146- < svg
147- xmlns = "http://www.w3.org/2000/svg"
148- width = "6"
149- height = "6"
150- viewBox = "0 0 6 6"
151- fill = "none"
152- className = { b ( 'version-icon' , { dimmed : isDimmed ( item . version ) } ) }
153- >
154- < circle cx = "3" cy = "3" r = "3" fill = { item . color } />
155- </ svg >
156- < div
157- className = { b ( 'title' , { dimmed : isDimmed ( item . version ) } ) }
158- onMouseEnter = { ( ) => {
159- handleMouseEnter ( item . version ) ;
160- } }
161- onMouseLeave = { handleMouseLeave }
162- >
163- { item . version }
164- </ div >
165- </ Flex >
166- </ Tooltip >
167- ) ) }
168- < Flex > { renderButton ( ) } </ Flex >
169- </ Flex >
141+ { withTitles && (
142+ < Flex className = { b ( 'titles-wrapper' , { size} ) } >
143+ { truncatedDisplayedVersions . map ( ( item ) => (
144+ < VersionTitle
145+ key = { item . version }
146+ version = { item . version }
147+ color = { item . color || '' }
148+ count = { item . count }
149+ isDimmed = { isDimmed ( item . version ) }
150+ onMouseEnter = { ( ) => {
151+ handleMouseEnter ( item . version ) ;
152+ } }
153+ onMouseLeave = { handleMouseLeave }
154+ size = { size }
155+ />
156+ ) ) }
157+ < Flex > { renderButton ( ) } </ Flex >
158+ </ Flex >
159+ ) }
170160 </ Flex >
171161 ) ;
172162}
163+
164+ interface VersionTitleProps {
165+ version : string ;
166+ color : string ;
167+ count ?: number ;
168+ isDimmed : boolean ;
169+ onMouseEnter : ( ) => void ;
170+ onMouseLeave : ( ) => void ;
171+ size : VersionsBarSize ;
172+ }
173+
174+ function VersionTitle ( {
175+ version,
176+ color,
177+ count,
178+ isDimmed,
179+ onMouseEnter,
180+ onMouseLeave,
181+ size,
182+ } : VersionTitleProps ) {
183+ return (
184+ < Tooltip
185+ content = { i18n ( 'tooltip_nodes' , { count : count } ) }
186+ placement = { 'bottom-end' }
187+ openDelay = { TOOLTIP_OPEN_DELAY }
188+ >
189+ < Flex alignItems = { 'center' } className = { b ( 'title' , { size} ) } >
190+ < VersionCircle size = { size } dimmed = { isDimmed } color = { color } />
191+ < div
192+ className = { b ( 'title-text' , { dimmed : isDimmed , size} ) }
193+ onMouseEnter = { onMouseEnter }
194+ onMouseLeave = { onMouseLeave }
195+ >
196+ { version }
197+ </ div >
198+ </ Flex >
199+ </ Tooltip >
200+ ) ;
201+ }
202+
203+ interface VersionCircleProps {
204+ size : VersionsBarSize ;
205+ dimmed : boolean ;
206+ color : string ;
207+ }
208+
209+ function VersionCircle ( { size, dimmed, color} : VersionCircleProps ) {
210+ const numericSize = size === 'm' ? 8 : 6 ;
211+ const radius = numericSize / 2 ;
212+
213+ return (
214+ < svg
215+ xmlns = "http://www.w3.org/2000/svg"
216+ width = { numericSize }
217+ height = { numericSize }
218+ viewBox = { `0 0 ${ numericSize } ${ numericSize } ` }
219+ fill = "none"
220+ className = { b ( 'version-icon' , { dimmed} ) }
221+ >
222+ < circle cx = { radius } cy = { radius } r = { radius } fill = { color } />
223+ </ svg >
224+ ) ;
225+ }
0 commit comments