@@ -123,13 +123,13 @@ const MobileLanguageSelector = ({
123123 </ option >
124124 ) }
125125 { srcLangs . map ( ( [ code , name ] ) => (
126- < option disabled = { pairs [ srcLang ] . size === 0 } key = { code } value = { code } >
126+ < option disabled = { ! pairs [ code ] || pairs [ code ] . size === 0 } key = { code } value = { code } >
127127 { name }
128128 </ option >
129129 ) ) }
130130 </ >
131131 ) ,
132- [ detectLangEnabled , detectedLang , pairs , srcLang , srcLangs , t , tLang ] ,
132+ [ detectLangEnabled , detectedLang , pairs , srcLangs , t , tLang ] ,
133133 ) ;
134134
135135 const tgtLangOptions = React . useMemo (
@@ -337,12 +337,42 @@ const DesktopLanguageSelector = ({
337337 const validTgtLang = React . useCallback ( ( lang : string ) => isPair ( pairs , srcLang , lang ) , [ pairs , srcLang ] ) ;
338338 const validSrcLang = React . useCallback ( ( lang : string ) => ! ! pairs [ lang ] && pairs [ lang ] . size > 0 , [ pairs ] ) ;
339339
340+ const MAX_QUICK = 3 ;
341+
342+ const visibleSrcLangs = React . useMemo ( ( ) => {
343+ const uniq = ( arr : string [ ] ) => Array . from ( new Set ( arr ) ) ;
344+ const fromRecents = ( recentSrcLangs || [ ] ) . filter ( validSrcLang ) ;
345+ if ( fromRecents . length ) {
346+ const pad = srcLangs
347+ . map ( ( [ c ] ) => c )
348+ . filter ( validSrcLang )
349+ . filter ( ( c ) => ! fromRecents . includes ( c ) ) ;
350+ return uniq ( [ srcLang , ...fromRecents , ...pad ] ) . slice ( 0 , MAX_QUICK ) ;
351+ }
352+ const fallbacks = srcLangs . map ( ( [ c ] ) => c ) . filter ( validSrcLang ) ;
353+ return uniq ( [ srcLang , ...fallbacks ] ) . slice ( 0 , MAX_QUICK ) ;
354+ } , [ recentSrcLangs , srcLangs , validSrcLang , srcLang ] ) ;
355+
356+ const visibleTgtLangs = React . useMemo ( ( ) => {
357+ const uniq = ( arr : string [ ] ) => Array . from ( new Set ( arr ) ) ;
358+ const fromRecents = ( recentTgtLangs || [ ] ) . filter ( validTgtLang ) ;
359+ if ( fromRecents . length ) {
360+ const pad = tgtLangs
361+ . map ( ( [ c ] ) => c )
362+ . filter ( validTgtLang )
363+ . filter ( ( c ) => ! fromRecents . includes ( c ) ) ;
364+ return uniq ( [ tgtLang , ...fromRecents , ...pad ] ) . slice ( 0 , MAX_QUICK ) ;
365+ }
366+ const fallbacks = tgtLangs . map ( ( [ c ] ) => c ) . filter ( validTgtLang ) ;
367+ return uniq ( [ tgtLang , ...fallbacks ] ) . slice ( 0 , MAX_QUICK ) ;
368+ } , [ recentTgtLangs , tgtLangs , validTgtLang , tgtLang ] ) ;
369+
340370 return (
341371 < >
342372 < Form . Group className = "row" >
343373 < Col className = "d-inline-flex align-items-start justify-content-between" xs = "6" >
344374 < ButtonGroup className = "d-flex flex-wrap pl-0" data-testid = "src-lang-buttons" >
345- { recentSrcLangs . map ( ( lang ) => (
375+ { visibleSrcLangs . map ( ( lang ) => (
346376 < Button
347377 active = { lang === srcLang && ! detectingLang && ! detectedLang }
348378 className = "language-button"
@@ -404,7 +434,7 @@ const DesktopLanguageSelector = ({
404434
405435 < Col className = "d-inline-flex align-items-start justify-content-between" xs = "6" >
406436 < ButtonGroup className = "d-flex flex-wrap pl-0" data-testid = "tgt-lang-buttons" >
407- { recentTgtLangs . map ( ( lang ) => (
437+ { visibleTgtLangs . map ( ( lang ) => (
408438 < Button
409439 active = { lang === tgtLang }
410440 className = "language-button"
0 commit comments