11import React , { MouseEvent } from 'react' ;
22import LanguageIcon from '@material-ui/icons/Language' ;
3- import { useTranslation } from 'react-i18next' ;
43import ExpandMoreIcon from '@material-ui/icons/ExpandMore' ;
5- import i18n from 'i18next' ;
4+ import i18next , { TFunction } from 'i18next' ;
5+ import { useTranslation } from 'react-i18next' ;
66import { withStyles } from '@material-ui/core/styles' ;
7+ import ClickAwayListener from '@material-ui/core/ClickAwayListener' ;
8+ import Grow from '@material-ui/core/Grow' ;
9+ import Popper from '@material-ui/core/Popper' ;
10+ import MenuList from '@material-ui/core/MenuList' ;
711import styled from '@emotion/styled' ;
8- import Menu from '@material-ui/core/Menu' ;
9- import MenuItem from '@material-ui/core/MenuItem' ;
1012
13+ import Paper from '../../muiComponents/Paper' ;
14+ import MenuItem from '../../muiComponents/MenuItem' ;
1115import Button from '../../muiComponents/Button' ;
1216import Tooltip from '../../muiComponents/Tooltip' ;
1317import Divider from '../../muiComponents/Divider' ;
1418import Box from '../../muiComponents/Box' ;
15- import Link from '../Link' ;
1619import { Theme } from '../../design-tokens/theme' ;
20+ import Link from '../Link' ;
21+ import Icon from '../Icon' ;
1722
18- import LanguageSwitchMenuItemContent from './LanguageSwitchMenuItemContent' ;
23+ const getTranslatedCurrentLanguage = (
24+ t : TFunction
25+ ) : { [ key : string ] : { translation : string ; icon : React . ComponentProps < typeof Icon > [ 'name' ] } } => ( {
26+ 'en-us' : {
27+ translation : t ( 'lng.english' ) ,
28+ icon : 'usa' ,
29+ } ,
30+ 'pt-br' : {
31+ translation : t ( 'lng.portuguese' ) ,
32+ icon : 'brazil' ,
33+ } ,
34+ 'de-de' : {
35+ translation : t ( 'lng.german' ) ,
36+ icon : 'germany' ,
37+ } ,
38+ 'es-es' : {
39+ translation : t ( 'lng.spanish' ) ,
40+ icon : 'spain' ,
41+ } ,
42+ 'zh-cn' : {
43+ translation : t ( 'lng.chinese' ) ,
44+ icon : 'china' ,
45+ } ,
46+ } ) ;
1947
2048const LanguageSwitch = ( ) => {
2149 const { t } = useTranslation ( ) ;
2250 const [ open , setOpen ] = React . useState ( false ) ;
2351 const anchorRef = React . useRef < HTMLButtonElement > ( null ) ;
2452
25- const languages = i18n . options . resources ? Object . keys ( i18n . options . resources ) : [ ] ;
26- const userLanguage = i18n . language || i18n . options ?. fallbackLng ?. [ 0 ] ;
53+ const languages = i18next . options . resources ? Object . keys ( i18next . options . resources ) : [ ] ;
54+ const currentLanguage = i18next . language || i18next . options ?. fallbackLng ?. [ 0 ] ;
55+
56+ const { translation : userLanguage } = getTranslatedCurrentLanguage ( t ) [ currentLanguage . toLowerCase ( ) ] ;
2757
2858 const handleToggle = ( ) => {
2959 setOpen ( prevOpen => ! prevOpen ) ;
3060 } ;
3161
32- const handleClose = ( event : MouseEvent < HTMLLIElement | HTMLUListElement > ) => {
62+ const handleClose = ( event : MouseEvent < HTMLLIElement | Document | HTMLAnchorElement > ) => {
3363 if ( anchorRef . current ) {
3464 if ( anchorRef . current . contains ( event . currentTarget ) ) {
3565 return ;
@@ -52,7 +82,7 @@ const LanguageSwitch = () => {
5282 } , [ open ] ) ;
5383
5484 const handleSwitchLanguage = ( language : string ) => ( event : MouseEvent < HTMLLIElement > ) => {
55- i18n . changeLanguage ( language ) ;
85+ i18next . changeLanguage ( language ) ;
5686 handleClose ( event ) ;
5787 } ;
5888
@@ -65,23 +95,38 @@ const LanguageSwitch = () => {
6595 < ExpandMoreIcon fontSize = "small" />
6696 </ SwitchButton >
6797 </ Tooltip >
68- < Menu anchorEl = { anchorRef . current } onClose = { handleClose } open = { open } >
69- { languages . map ( language => (
70- < MenuItem key = { language } onClick = { handleSwitchLanguage ( language ) } selected = { userLanguage === language } >
71- < LanguageSwitchMenuItemContent language = { language } />
72- </ MenuItem >
73- ) ) }
74- < Box my = { 1 } >
75- < Divider />
76- </ Box >
77- < MenuItem
78- component = "a"
79- href = "https://github.com/verdaccio/ui#translations"
80- onClick = { handleClose }
81- target = "_blank" >
82- { `${ t ( 'help-to-translate' ) } ` }
83- </ MenuItem >
84- </ Menu >
98+ < Popper anchorEl = { anchorRef . current } disablePortal = { true } open = { open } role = { undefined } transition = { true } >
99+ { ( { TransitionProps } ) => (
100+ < Grow { ...TransitionProps } >
101+ < Paper >
102+ < ClickAwayListener onClickAway = { handleClose } >
103+ < MenuList >
104+ { languages . map ( language => {
105+ const { icon, translation } = getTranslatedCurrentLanguage ( t ) [ language . toLowerCase ( ) ] ;
106+ return (
107+ < StyledMenuItem
108+ key = { language }
109+ onClick = { handleSwitchLanguage ( language ) }
110+ selected = { userLanguage === translation } >
111+ < Icon name = { icon } size = "md" />
112+ { translation }
113+ </ StyledMenuItem >
114+ ) ;
115+ } ) }
116+ < Box my = { 1 } >
117+ < Divider />
118+ </ Box >
119+ < MenuItem button = { true } >
120+ < StyledLink external = { true } onClick = { handleClose } to = "https://github.com/verdaccio/ui#translations" >
121+ { `${ t ( 'help-to-translate' ) } ` }
122+ </ StyledLink >
123+ </ MenuItem >
124+ </ MenuList >
125+ </ ClickAwayListener >
126+ </ Paper >
127+ </ Grow >
128+ ) }
129+ </ Popper >
85130 </ >
86131 ) ;
87132} ;
@@ -96,7 +141,17 @@ const SwitchButton = withStyles((theme: Theme) => ({
96141 } ,
97142} ) ) ( Button ) ;
98143
144+ const StyledMenuItem = withStyles ( ( theme : Theme ) => ( {
145+ root : {
146+ display : 'grid' ,
147+ cursor : 'pointer' ,
148+ gridGap : theme ?. spacing ( 0.5 ) ,
149+ gridTemplateColumns : '20px 1fr' ,
150+ alignItems : 'center' ,
151+ } ,
152+ } ) ) ( MenuItem ) ;
153+
99154const StyledLink = styled ( Link ) < { theme ?: Theme } > ( ( { theme } ) => ( {
100- color : theme ?. palette . white ,
155+ color : theme ?. palette . type === 'dark' ? theme ?. palette . white : theme ?. palette . text . primary ,
101156 textDecoration : 'none' ,
102157} ) ) ;
0 commit comments