@@ -30,10 +30,12 @@ import { PropertiesPopover } from "../PropertiesPopover";
3030import { QuickSearch } from "../QuickSearch" ;
3131import { ScrollableList } from "../ScrollableList" ;
3232import DropdownMenuGroup from "../dropdownMenu/DropdownMenuGroup" ;
33- import DropdownMenuItem , {
33+ import {
3434 DropDownMenuItemBadgeType ,
3535 DropDownMenuItemBadge ,
3636} from "../dropdownMenu/DropdownMenuItem" ;
37+ import MenuItemContent from "../dropdownMenu/DropdownMenuItemContent" ;
38+ import { getDropdownMenuItemClassName } from "../dropdownMenu/common" ;
3739import {
3840 FontFamilyCodeIcon ,
3941 FontFamilyHeadingIcon ,
@@ -269,55 +271,88 @@ export const FontPickerList = React.memo(
269271 [ filteredFonts , sceneFamilies ] ,
270272 ) ;
271273
272- const renderFont = ( font : FontDescriptor , index : number ) => (
273- < DropdownMenuItem
274- key = { font . value }
275- icon = { font . icon }
276- value = { font . value }
277- order = { index }
278- textStyle = { {
279- fontFamily : getFontFamilyString ( { fontFamily : font . value } ) ,
280- } }
281- hovered = { font . value === hoveredFont ?. value }
282- selected = { font . value === selectedFontFamily }
283- // allow to tab between search and selected font
284- tabIndex = { font . value === selectedFontFamily ? 0 : - 1 }
285- onClick = { ( e ) => {
286- wrappedOnSelect ( Number ( e . currentTarget . value ) ) ;
287- } }
288- onMouseMove = { ( ) => {
289- if ( hoveredFont ?. value !== font . value ) {
290- onHover ( font . value ) ;
291- }
292- } }
293- badge = {
294- font . badge && (
295- < DropDownMenuItemBadge type = { font . badge . type } >
296- { font . badge . placeholder }
297- </ DropDownMenuItemBadge >
298- )
274+ const FontPickerListItem = ( {
275+ font,
276+ order,
277+ } : {
278+ font : FontDescriptor ;
279+ order : number ;
280+ } ) => {
281+ const ref = useRef < HTMLButtonElement > ( null ) ;
282+ const isHovered = font . value === hoveredFont ?. value ;
283+ const isSelected = font . value === selectedFontFamily ;
284+
285+ useEffect ( ( ) => {
286+ if ( ! isHovered ) {
287+ return ;
299288 }
300- >
301- { font . text }
302- </ DropdownMenuItem >
303- ) ;
289+ if ( order === 0 ) {
290+ // scroll into the first item differently, so it's visible what is above (i.e. group title)
291+ ref . current ?. scrollIntoView ?.( { block : "end" } ) ;
292+ } else {
293+ ref . current ?. scrollIntoView ?.( { block : "nearest" } ) ;
294+ }
295+ } , [ isHovered , order ] ) ;
296+
297+ return (
298+ < button
299+ ref = { ref }
300+ type = "button"
301+ value = { font . value }
302+ className = { getDropdownMenuItemClassName ( "" , isSelected , isHovered ) }
303+ title = { font . text }
304+ // allow to tab between search and selected font
305+ tabIndex = { isSelected ? 0 : - 1 }
306+ onClick = { ( e ) => {
307+ wrappedOnSelect ( Number ( e . currentTarget . value ) ) ;
308+ } }
309+ onMouseMove = { ( ) => {
310+ if ( hoveredFont ?. value !== font . value ) {
311+ onHover ( font . value ) ;
312+ }
313+ } }
314+ >
315+ < MenuItemContent
316+ icon = { font . icon }
317+ badge = {
318+ font . badge && (
319+ < DropDownMenuItemBadge type = { font . badge . type } >
320+ { font . badge . placeholder }
321+ </ DropDownMenuItemBadge >
322+ )
323+ }
324+ textStyle = { {
325+ fontFamily : getFontFamilyString ( { fontFamily : font . value } ) ,
326+ } }
327+ >
328+ { font . text }
329+ </ MenuItemContent >
330+ </ button >
331+ ) ;
332+ } ;
304333
305334 const groups = [ ] ;
306335
307336 if ( sceneFilteredFonts . length ) {
308337 groups . push (
309338 < DropdownMenuGroup title = { t ( "fontList.sceneFonts" ) } key = "group_1" >
310- { sceneFilteredFonts . map ( renderFont ) }
339+ { sceneFilteredFonts . map ( ( font , index ) => (
340+ < FontPickerListItem key = { font . value } font = { font } order = { index } />
341+ ) ) }
311342 </ DropdownMenuGroup > ,
312343 ) ;
313344 }
314345
315346 if ( availableFilteredFonts . length ) {
316347 groups . push (
317348 < DropdownMenuGroup title = { t ( "fontList.availableFonts" ) } key = "group_2" >
318- { availableFilteredFonts . map ( ( font , index ) =>
319- renderFont ( font , index + sceneFilteredFonts . length ) ,
320- ) }
349+ { availableFilteredFonts . map ( ( font , index ) => (
350+ < FontPickerListItem
351+ key = { font . value }
352+ font = { font }
353+ order = { index + sceneFilteredFonts . length }
354+ />
355+ ) ) }
321356 </ DropdownMenuGroup > ,
322357 ) ;
323358 }
0 commit comments