Skip to content
This repository was archived by the owner on Jan 16, 2022. It is now read-only.

Commit afc0175

Browse files
fixed dropdown
1 parent 5f6dc6c commit afc0175

File tree

8 files changed

+125
-109
lines changed

8 files changed

+125
-109
lines changed

i18n/translations/de-DE.json

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,5 +135,13 @@
135135
"app-context-not-correct-used": "Der App-Kontext wurde nicht korrekt verwendet",
136136
"theme-context-not-correct-used": "Der Theme-Kontext wurde nicht korrekt verwendet",
137137
"package-meta-is-required-at-detail-context": "packageMeta wird bei DetailContext benötigt"
138-
}
138+
},
139+
"lng": {
140+
"english": "Englisch",
141+
"portuguese": "Portugiesisch",
142+
"spanish": "Spanisch",
143+
"german": "Deutsch",
144+
"chinese": "Chinesisch"
145+
},
146+
"help-to-translate": "Hilfe beim Übersetzen"
139147
}

i18n/translations/es-ES.json

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,5 +135,13 @@
135135
"app-context-not-correct-used": "El contexto de la aplicación no fue correctamente usado",
136136
"theme-context-not-correct-used": "El contexto del tema no fue correctamente usado",
137137
"package-meta-is-required-at-detail-context": "packageMeta es requerido en DetailContext"
138-
}
138+
},
139+
"lng": {
140+
"english": "Inglés",
141+
"portuguese": "Portugués",
142+
"spanish": "Español",
143+
"german": "Alemán",
144+
"chinese": "Chino"
145+
},
146+
"help-to-translate": "Ayuda a traducir"
139147
}

i18n/translations/pt-BR.json

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@
114114
}
115115
},
116116
"footer": {
117-
"powered-by": "Distribuído por",
117+
"powered-by": "Feito por",
118118
"made-with-love-on": "Feito com amor <0>♥</0> no(a)"
119119
},
120120
"button": {
@@ -135,5 +135,13 @@
135135
"app-context-not-correct-used": "O contexto do aplicativo não foi usado corretamente",
136136
"theme-context-not-correct-used": "O contexto do tema não foi usado corretamente",
137137
"package-meta-is-required-at-detail-context": "packageMeta é requerido em DetailContext"
138-
}
138+
},
139+
"lng": {
140+
"english": "Inglês",
141+
"portuguese": "Português",
142+
"spanish": "Espanhol",
143+
"german": "Alemão",
144+
"chinese": "Chinês"
145+
},
146+
"help-to-translate": "Ajude a traduzir"
139147
}

i18n/translations/zh-CN.json

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,5 +134,13 @@
134134
},
135135
"app-context-not-correct-used": "The app context was not correct used",
136136
"package-meta-is-required-at-detail-context": "packageMeta is required at DetailContext"
137-
}
137+
},
138+
"lng": {
139+
"english": "英語",
140+
"portuguese": "葡萄牙語",
141+
"spanish": "西班牙文",
142+
"german": "德語",
143+
"chinese": "中文"
144+
},
145+
"help-to-translate": "幫助翻譯"
138146
}
Lines changed: 83 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,65 @@
11
import React, { MouseEvent } from 'react';
22
import LanguageIcon from '@material-ui/icons/Language';
3-
import { useTranslation } from 'react-i18next';
43
import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
5-
import i18n from 'i18next';
4+
import i18next, { TFunction } from 'i18next';
5+
import { useTranslation } from 'react-i18next';
66
import { 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';
711
import 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';
1115
import Button from '../../muiComponents/Button';
1216
import Tooltip from '../../muiComponents/Tooltip';
1317
import Divider from '../../muiComponents/Divider';
1418
import Box from '../../muiComponents/Box';
15-
import Link from '../Link';
1619
import { 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

2048
const 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+
99154
const 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
}));

src/components/LanguageSwitch/LanguageSwitchMenuItemContent.tsx

Lines changed: 0 additions & 63 deletions
This file was deleted.

src/muiComponents/MenuItem/MenuItem.tsx

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,12 @@ import { default as MaterialUIMenuItem, MenuItemProps } from '@material-ui/core/
55
type HTMLElementTagName = keyof HTMLElementTagNameMap;
66
type MenuItemRef = HTMLElementTagNameMap[HTMLElementTagName];
77

8-
interface Props extends Omit<MenuItemProps, 'component'> {
9-
component?: HTMLElementTagName;
10-
}
11-
12-
const MenuItem = forwardRef<MenuItemRef, Props>(function MenuItem({ button, ...props }, ref) {
8+
const MenuItem = forwardRef<MenuItemRef, MenuItemProps>(function MenuItem(props, ref) {
139
// it seems typescript has some discrimination type limitions. Please see: https://github.com/mui-org/material-ui/issues/14971
14-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
15-
return <StyledMaterialUIMenuItem {...props} button={button as any} ref={ref as any} />;
10+
// @ts-ignore Type Types of property 'button' are incompatible.
11+
return <StyledMaterialUIMenuItem {...props} ref={ref as any} />;
1612
});
1713

18-
MenuItem.defaultProps = {
19-
component: 'li',
20-
};
21-
2214
export default MenuItem;
2315

2416
const StyledMaterialUIMenuItem = styled(MaterialUIMenuItem)({

src/utils/package.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { isObject } from 'util';
22

3-
import i18n from 'i18next';
3+
import i18next from 'i18next';
44
import { UpLinks } from '@verdaccio/types';
55
import isString from 'lodash/isString';
66
import dayjs from 'dayjs';
@@ -93,5 +93,5 @@ export function getRecentReleases(time: Time = {}): Time[] {
9393
}
9494

9595
export function getAuthorName(authorName: string): string {
96-
return authorName.toLowerCase() === 'anonymous' ? i18n.t('author-anonymous') : authorName;
96+
return authorName.toLowerCase() === 'anonymous' ? i18next.t('author-anonymous') : authorName;
9797
}

0 commit comments

Comments
 (0)