11import { useRouter } from 'next/router'
2- import { GlobeIcon } from '@primer/octicons-react'
2+ import { GlobeIcon , KebabHorizontalIcon } from '@primer/octicons-react'
33
44import { useLanguages } from 'components/context/LanguagesContext'
55import { useTranslation } from 'components/hooks/useTranslation'
66import { useUserLanguage } from 'components/hooks/useUserLanguage'
7- import { Picker } from 'src/tools/components/Picker '
7+ import { ActionList , ActionMenu , IconButton , Link } from '@primer/react '
88
99type Props = {
10+ xs ?: boolean
1011 mediumOrLower ?: boolean
1112}
1213
13- export const LanguagePicker = ( { mediumOrLower } : Props ) => {
14+ export const LanguagePicker = ( { xs , mediumOrLower } : Props ) => {
1415 const router = useRouter ( )
1516 const { languages } = useLanguages ( )
1617 const { setUserLanguageCookie } = useUserLanguage ( )
@@ -37,39 +38,80 @@ export const LanguagePicker = ({ mediumOrLower }: Props) => {
3738 // in a "denormalized" way.
3839 const routerPath = router . asPath . split ( '#' ) [ 0 ]
3940
40- return (
41- < div data-testid = "language-picker" >
42- < Picker
43- defaultText = { t ( 'language_picker_default_text' ) }
44- items = { langs . map ( ( lang ) => ( {
45- text : lang . nativeName || lang . name ,
46- selected : lang === selectedLang ,
47- href : `/${ lang . code } ${ routerPath } ` ,
48- extra : {
49- locale : lang . code ,
50- } ,
51- } ) ) }
52- pickerLabel = { mediumOrLower ? 'Language' : '' }
53- iconButton = { mediumOrLower ? undefined : GlobeIcon }
54- onSelect = { ( item ) => {
55- if ( item . extra ?. locale ) {
56- try {
57- setUserLanguageCookie ( item . extra . locale )
58- } catch ( err ) {
59- // You can never be too careful because setting a cookie
60- // can fail. For example, some browser
61- // extensions disallow all setting of cookies and attempts
62- // at the `document.cookie` setter could throw. Just swallow
63- // and move on.
64- console . warn ( 'Unable to set preferred language cookie' , err )
65- }
41+ // languageList is specifically <ActionList.Item>'s which are reused
42+ // for menus that behave differently at the breakpoints.
43+ const languageList = langs . map ( ( lang ) => (
44+ < ActionList . Item
45+ key = { `/${ lang . code } ${ routerPath } ` }
46+ selected = { lang === selectedLang }
47+ as = { Link }
48+ href = { `/${ lang . code } ${ routerPath } ` }
49+ onSelect = { ( ) => {
50+ if ( lang . code ) {
51+ try {
52+ setUserLanguageCookie ( lang . code )
53+ } catch ( err ) {
54+ // You can never be too careful because setting a cookie
55+ // can fail. For example, some browser
56+ // extensions disallow all setting of cookies and attempts
57+ // at the `document.cookie` setter could throw. Just swallow
58+ // and move on.
59+ console . warn ( 'Unable to set preferred language cookie' , err )
6660 }
67- } }
68- buttonBorder = { mediumOrLower }
69- dataTestId = "default-language"
70- ariaLabel = { `Select language: current language is ${ selectedLang . name } ` }
71- alignment = { mediumOrLower ? 'start' : 'end' }
72- />
61+ }
62+ } }
63+ >
64+ < span data-testid = "default-language" > { lang . nativeName || lang . name } </ span >
65+ </ ActionList . Item >
66+ ) )
67+
68+ // At large breakpoints, we return the full <ActionMenu> with just the languages,
69+ // at smaller breakpoints, we return just the <ActionList> with its items so that
70+ // the <Header> component can place it inside its own <ActionMenu> with multiple
71+ // groups, language being just one of those groups.
72+ return (
73+ < div data-testid = "language-picker" className = "d-flex" >
74+ { xs ? (
75+ < >
76+ { /* XS Mobile Menu */ }
77+ < ActionMenu >
78+ < ActionMenu . Anchor >
79+ < ActionMenu . Button
80+ variant = "invisible"
81+ className = "color-fg-default width-full"
82+ aria-label = { `Select language: current language is ${ selectedLang . name } ` }
83+ sx = { {
84+ height : 'auto' ,
85+ textAlign : 'left' ,
86+ 'span:first-child' : { display : 'inline' } ,
87+ } }
88+ >
89+ < span style = { { whiteSpace : 'pre-wrap' } } > { t ( 'language_picker_label' ) + '\n' } </ span >
90+ < span className = "color-fg-muted text-normal f6" > { selectedLang . name } </ span >
91+ </ ActionMenu . Button >
92+ </ ActionMenu . Anchor >
93+ < ActionMenu . Overlay align = "start" >
94+ < ActionList selectionVariant = "single" > { languageList } </ ActionList >
95+ </ ActionMenu . Overlay >
96+ </ ActionMenu >
97+ </ >
98+ ) : mediumOrLower ? (
99+ < ActionList className = "hide-sm" selectionVariant = "single" >
100+ < ActionList . Group title = { t ( 'language_picker_label' ) } > { languageList } </ ActionList . Group >
101+ </ ActionList >
102+ ) : (
103+ < ActionMenu >
104+ < ActionMenu . Anchor >
105+ < IconButton
106+ icon = { mediumOrLower ? KebabHorizontalIcon : GlobeIcon }
107+ aria-label = { `Select language: current language is ${ selectedLang . name } ` }
108+ />
109+ </ ActionMenu . Anchor >
110+ < ActionMenu . Overlay align = "end" >
111+ < ActionList selectionVariant = "single" > { languageList } </ ActionList >
112+ </ ActionMenu . Overlay >
113+ </ ActionMenu >
114+ ) }
73115 </ div >
74116 )
75117}
0 commit comments