forked from sombochea/verdaccio-ui
feat(lng): Added change language on the fly (#456)
* feat(lng): added change language on the fly * fixed dropdown * applied feedbacks * added translation * updated bundlesize * fixed error * updated snaps * added french language * added language in storage * updated styles * fixed tests
This commit is contained in:
parent
b17368470d
commit
675ee980ee
@ -8,6 +8,29 @@ import translationDE from './translations/de-DE.json';
|
||||
import translationFR from './translations/fr-FR.json';
|
||||
import translationCN from './translations/zh-CN.json';
|
||||
|
||||
const languages = {
|
||||
'en-US': {
|
||||
translation: translationEN,
|
||||
},
|
||||
'pt-BR': {
|
||||
translation: translationPT,
|
||||
},
|
||||
'es-ES': {
|
||||
translation: translationES,
|
||||
},
|
||||
'de-DE': {
|
||||
translation: translationDE,
|
||||
},
|
||||
'fr-FR': {
|
||||
translation: translationFR,
|
||||
},
|
||||
'zh-CN': {
|
||||
translation: translationCN,
|
||||
},
|
||||
};
|
||||
|
||||
type Language = keyof typeof languages;
|
||||
|
||||
i18n
|
||||
// pass the i18n instance to react-i18next.
|
||||
.use(initReactI18next)
|
||||
@ -19,26 +42,7 @@ i18n
|
||||
fallbackLng: 'en-US',
|
||||
whitelist: ['en-US', 'pt-BR', 'es-ES', 'de-DE', 'fr-FR', 'zh-CN'],
|
||||
load: 'currentOnly',
|
||||
resources: {
|
||||
'en-US': {
|
||||
translation: translationEN,
|
||||
},
|
||||
'pt-BR': {
|
||||
translation: translationPT,
|
||||
},
|
||||
'es-ES': {
|
||||
translation: translationES,
|
||||
},
|
||||
'de-DE': {
|
||||
translation: translationDE,
|
||||
},
|
||||
'fr-FR': {
|
||||
translation: translationFR,
|
||||
},
|
||||
'zh-CN': {
|
||||
translation: translationCN,
|
||||
},
|
||||
},
|
||||
resources: languages,
|
||||
debug: false,
|
||||
interpolation: {
|
||||
escapeValue: false, // react already safes from xss
|
||||
@ -46,3 +50,4 @@ i18n
|
||||
});
|
||||
|
||||
export default i18n;
|
||||
export { Language };
|
||||
|
@ -135,5 +135,15 @@
|
||||
"app-context-not-correct-used": "Der App-Kontext wurde nicht korrekt verwendet",
|
||||
"theme-context-not-correct-used": "Der Theme-Kontext wurde nicht korrekt verwendet",
|
||||
"package-meta-is-required-at-detail-context": "packageMeta wird bei DetailContext benötigt"
|
||||
}
|
||||
},
|
||||
"lng": {
|
||||
"english": "Englisch",
|
||||
"portuguese": "Portugiesisch",
|
||||
"spanish": "Spanisch",
|
||||
"german": "Deutsch",
|
||||
"chinese": "Chinesisch",
|
||||
"french": "Französisch"
|
||||
},
|
||||
"help-to-translate": "Hilfe beim Übersetzen",
|
||||
"change-language": "Sprache ändern"
|
||||
}
|
||||
|
@ -135,5 +135,15 @@
|
||||
"app-context-not-correct-used": "The app context was not used correctly",
|
||||
"theme-context-not-correct-used": "The theme context was not used correctly",
|
||||
"package-meta-is-required-at-detail-context": "packageMeta is required at DetailContext"
|
||||
}
|
||||
},
|
||||
"lng": {
|
||||
"english": "English",
|
||||
"portuguese": "Portuguese",
|
||||
"spanish": "Spanish",
|
||||
"german": "German",
|
||||
"chinese": "Chinese",
|
||||
"french": "French"
|
||||
},
|
||||
"help-to-translate": "Help to translate",
|
||||
"change-language": "Change language"
|
||||
}
|
@ -135,5 +135,15 @@
|
||||
"app-context-not-correct-used": "El contexto de la aplicación no fue correctamente usado",
|
||||
"theme-context-not-correct-used": "El contexto del tema no fue correctamente usado",
|
||||
"package-meta-is-required-at-detail-context": "packageMeta es requerido en DetailContext"
|
||||
}
|
||||
},
|
||||
"lng": {
|
||||
"english": "Inglés",
|
||||
"portuguese": "Portugués",
|
||||
"spanish": "Español",
|
||||
"german": "Alemán",
|
||||
"chinese": "Chino",
|
||||
"french": "francés"
|
||||
},
|
||||
"help-to-translate": "Ayuda a traducir",
|
||||
"change-language": "Cambiar idioma"
|
||||
}
|
||||
|
@ -135,5 +135,15 @@
|
||||
"app-context-not-correct-used": "Le contexte de l'application n'a pas été utilisé correctement",
|
||||
"theme-context-not-correct-used": "Le contexte du thème n'a pas été utilisé correctement",
|
||||
"package-meta-is-required-at-detail-context": "packageMeta est obligatoire à DetailContext"
|
||||
}
|
||||
},
|
||||
"lng": {
|
||||
"english": "Anglaise",
|
||||
"portuguese": "Portugaise",
|
||||
"spanish": "Espagnol",
|
||||
"german": "Allemande",
|
||||
"chinese": "Chinoise",
|
||||
"french": "Française"
|
||||
},
|
||||
"help-to-translate": "Aide à traduire",
|
||||
"change-language": "Changer la langue"
|
||||
}
|
@ -114,7 +114,7 @@
|
||||
}
|
||||
},
|
||||
"footer": {
|
||||
"powered-by": "Distribuído por",
|
||||
"powered-by": "Feito por",
|
||||
"made-with-love-on": "Feito com amor <0>♥</0> no(a)"
|
||||
},
|
||||
"button": {
|
||||
@ -135,5 +135,15 @@
|
||||
"app-context-not-correct-used": "O contexto do aplicativo não foi usado corretamente",
|
||||
"theme-context-not-correct-used": "O contexto do tema não foi usado corretamente",
|
||||
"package-meta-is-required-at-detail-context": "packageMeta é requerido em DetailContext"
|
||||
}
|
||||
},
|
||||
"lng": {
|
||||
"english": "Inglês",
|
||||
"portuguese": "Português",
|
||||
"spanish": "Espanhol",
|
||||
"german": "Alemão",
|
||||
"chinese": "Chinês",
|
||||
"french": "Francês"
|
||||
},
|
||||
"help-to-translate": "Ajude a traduzir",
|
||||
"change-language": "Mudar idioma"
|
||||
}
|
@ -134,5 +134,15 @@
|
||||
},
|
||||
"app-context-not-correct-used": "The app context was not correct used",
|
||||
"package-meta-is-required-at-detail-context": "packageMeta is required at DetailContext"
|
||||
}
|
||||
},
|
||||
"lng": {
|
||||
"english": "英語",
|
||||
"portuguese": "葡萄牙語",
|
||||
"spanish": "西班牙文",
|
||||
"german": "德語",
|
||||
"chinese": "中文",
|
||||
"french": "法國人"
|
||||
},
|
||||
"help-to-translate": "幫助翻譯",
|
||||
"change-language": "改變語言"
|
||||
}
|
@ -140,7 +140,7 @@
|
||||
"bundlesize": [
|
||||
{
|
||||
"path": "./static/vendors.*.js",
|
||||
"maxSize": "200 kB"
|
||||
"maxSize": "210 kB"
|
||||
},
|
||||
{
|
||||
"path": "./static/main.*.js",
|
||||
|
@ -1,11 +1,11 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`<App /> should display the Header component 1`] = `
|
||||
.emotion-81 {
|
||||
.emotion-85 {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.emotion-24 {
|
||||
.emotion-28 {
|
||||
background-color: #4b5e40;
|
||||
color: #fff;
|
||||
min-height: 60px;
|
||||
@ -20,29 +20,29 @@ exports[`<App /> should display the Header component 1`] = `
|
||||
}
|
||||
|
||||
@media (min-width:768px) {
|
||||
.emotion-24 .emotion-13 {
|
||||
.emotion-28 .emotion-13 {
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.emotion-24 .emotion-17 {
|
||||
.emotion-28 .emotion-17 {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.emotion-24 .e1jf5lit4 {
|
||||
.emotion-28 .e1jf5lit4 {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width:1024px) {
|
||||
.emotion-24 .emotion-23 {
|
||||
.emotion-28 .emotion-27 {
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
@media (min-width:1275px) {
|
||||
.emotion-24 .emotion-23 {
|
||||
.emotion-28 .emotion-27 {
|
||||
max-width: 1240px;
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
@ -50,7 +50,7 @@ exports[`<App /> should display the Header component 1`] = `
|
||||
}
|
||||
}
|
||||
|
||||
.emotion-22 {
|
||||
.emotion-26 {
|
||||
-webkit-box-pack: justify;
|
||||
-webkit-justify-content: space-between;
|
||||
-ms-flex-pack: justify;
|
||||
@ -128,7 +128,7 @@ exports[`<App /> should display the Header component 1`] = `
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.emotion-20 {
|
||||
.emotion-24 {
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
@ -140,12 +140,32 @@ exports[`<App /> should display the Header component 1`] = `
|
||||
display: block;
|
||||
}
|
||||
|
||||
.emotion-20 {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media screen and (min-width:768px) {
|
||||
.emotion-20 {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
.emotion-18 {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media screen and (min-width:768px) {
|
||||
.emotion-18 {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
.emotion-22 {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
@media screen and (min-width:1240px) {
|
||||
.emotion-36 {
|
||||
.emotion-40 {
|
||||
max-width: 1240px;
|
||||
width: 100%;
|
||||
margin-left: auto;
|
||||
@ -153,7 +173,7 @@ exports[`<App /> should display the Header component 1`] = `
|
||||
}
|
||||
}
|
||||
|
||||
.emotion-79 {
|
||||
.emotion-83 {
|
||||
background: #f9f9f9;
|
||||
border-top: 1px solid #e3e3e3;
|
||||
color: #999999;
|
||||
@ -161,7 +181,7 @@ exports[`<App /> should display the Header component 1`] = `
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.emotion-77 {
|
||||
.emotion-81 {
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
@ -178,7 +198,7 @@ exports[`<App /> should display the Header component 1`] = `
|
||||
}
|
||||
|
||||
@media (min-width:768px) {
|
||||
.emotion-77 {
|
||||
.emotion-81 {
|
||||
min-width: 400px;
|
||||
max-width: 800px;
|
||||
margin: auto;
|
||||
@ -190,12 +210,12 @@ exports[`<App /> should display the Header component 1`] = `
|
||||
}
|
||||
|
||||
@media (min-width:1024px) {
|
||||
.emotion-77 {
|
||||
.emotion-81 {
|
||||
max-width: 1240px;
|
||||
}
|
||||
}
|
||||
|
||||
.emotion-68 {
|
||||
.emotion-72 {
|
||||
-webkit-align-items: center;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
@ -204,7 +224,7 @@ exports[`<App /> should display the Header component 1`] = `
|
||||
}
|
||||
|
||||
@media (min-width:768px) {
|
||||
.emotion-68 {
|
||||
.emotion-72 {
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
@ -212,21 +232,21 @@ exports[`<App /> should display the Header component 1`] = `
|
||||
}
|
||||
}
|
||||
|
||||
.emotion-38 {
|
||||
.emotion-42 {
|
||||
color: #e25555;
|
||||
padding: 0 5px;
|
||||
}
|
||||
|
||||
.emotion-66 {
|
||||
.emotion-70 {
|
||||
position: relative;
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
.emotion-66:hover .emotion-65 {
|
||||
.emotion-70:hover .emotion-69 {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.emotion-41 {
|
||||
.emotion-45 {
|
||||
box-sizing: initial;
|
||||
display: inline-block;
|
||||
cursor: default;
|
||||
@ -235,7 +255,7 @@ exports[`<App /> should display the Header component 1`] = `
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
.emotion-64 {
|
||||
.emotion-68 {
|
||||
position: absolute;
|
||||
background: #d3dddd;
|
||||
padding: 1px 4px;
|
||||
@ -253,7 +273,7 @@ exports[`<App /> should display the Header component 1`] = `
|
||||
top: -2px;
|
||||
}
|
||||
|
||||
.emotion-64:before {
|
||||
.emotion-68:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 29%;
|
||||
@ -266,7 +286,7 @@ exports[`<App /> should display the Header component 1`] = `
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
.emotion-44 {
|
||||
.emotion-48 {
|
||||
box-sizing: initial;
|
||||
display: inline-block;
|
||||
cursor: default;
|
||||
@ -275,7 +295,7 @@ exports[`<App /> should display the Header component 1`] = `
|
||||
padding: 0 5px;
|
||||
}
|
||||
|
||||
.emotion-75 {
|
||||
.emotion-79 {
|
||||
-webkit-align-items: center;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
@ -288,7 +308,7 @@ exports[`<App /> should display the Header component 1`] = `
|
||||
}
|
||||
|
||||
@media (min-width:768px) {
|
||||
.emotion-75 {
|
||||
.emotion-79 {
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
@ -296,7 +316,7 @@ exports[`<App /> should display the Header component 1`] = `
|
||||
}
|
||||
}
|
||||
|
||||
.emotion-73 {
|
||||
.emotion-77 {
|
||||
box-sizing: initial;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
@ -305,12 +325,12 @@ exports[`<App /> should display the Header component 1`] = `
|
||||
padding: 0 5px;
|
||||
}
|
||||
|
||||
.emotion-70 {
|
||||
.emotion-74 {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.emotion-34 {
|
||||
.emotion-38 {
|
||||
-webkit-transform: translate(-50%,-50%);
|
||||
-ms-transform: translate(-50%,-50%);
|
||||
transform: translate(-50%,-50%);
|
||||
@ -319,14 +339,14 @@ exports[`<App /> should display the Header component 1`] = `
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.emotion-28 {
|
||||
.emotion-32 {
|
||||
margin: 0 0 30px 0;
|
||||
border-radius: 25px;
|
||||
box-shadow: 0 10px 20px 0 rgba(69,58,100,0.2);
|
||||
background: #f7f8f6;
|
||||
}
|
||||
|
||||
.emotion-26 {
|
||||
.emotion-30 {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
box-sizing: border-box;
|
||||
@ -338,7 +358,7 @@ exports[`<App /> should display the Header component 1`] = `
|
||||
height: 90px;
|
||||
}
|
||||
|
||||
.emotion-32 {
|
||||
.emotion-36 {
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
@ -353,19 +373,19 @@ exports[`<App /> should display the Header component 1`] = `
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.emotion-30 {
|
||||
.emotion-34 {
|
||||
color: #4b5e40;
|
||||
}
|
||||
|
||||
<div
|
||||
class="MuiBox-root MuiBox-root-219 emotion-81 emotion-82"
|
||||
class="MuiBox-root MuiBox-root-220 emotion-85 emotion-86"
|
||||
>
|
||||
<header
|
||||
class="MuiPaper-root MuiPaper-elevation4 MuiAppBar-root MuiAppBar-positionStatic emotion-24 emotion-25 MuiAppBar-colorPrimary"
|
||||
class="MuiPaper-root MuiPaper-elevation4 MuiAppBar-root MuiAppBar-positionStatic emotion-28 emotion-29 MuiAppBar-colorPrimary"
|
||||
data-testid="header"
|
||||
>
|
||||
<div
|
||||
class="MuiToolbar-root MuiToolbar-regular emotion-22 emotion-23 MuiToolbar-gutters"
|
||||
class="MuiToolbar-root MuiToolbar-regular emotion-26 emotion-27 MuiToolbar-gutters"
|
||||
>
|
||||
<div
|
||||
class="MuiToolbar-root MuiToolbar-regular emotion-14 emotion-15 MuiToolbar-gutters"
|
||||
@ -434,7 +454,7 @@ exports[`<App /> should display the Header component 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="MuiToolbar-root MuiToolbar-regular emotion-20 emotion-21 MuiToolbar-gutters"
|
||||
class="MuiToolbar-root MuiToolbar-regular emotion-24 emotion-25 MuiToolbar-gutters"
|
||||
data-testid="header-right"
|
||||
>
|
||||
<button
|
||||
@ -461,8 +481,53 @@ exports[`<App /> should display the Header component 1`] = `
|
||||
class="MuiTouchRipple-root"
|
||||
/>
|
||||
</button>
|
||||
<div
|
||||
class="emotion-20 emotion-21"
|
||||
>
|
||||
<button
|
||||
class="MuiButtonBase-root MuiButton-root MuiButton-text MuiButton-colorInherit"
|
||||
tabindex="0"
|
||||
title="Change language"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
class="MuiButton-label ForwardRef(Button)-label-339"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="MuiSvgIcon-root"
|
||||
focusable="false"
|
||||
role="presentation"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zm6.93 6h-2.95c-.32-1.25-.78-2.45-1.38-3.56 1.84.63 3.37 1.91 4.33 3.56zM12 4.04c.83 1.2 1.48 2.53 1.91 3.96h-3.82c.43-1.43 1.08-2.76 1.91-3.96zM4.26 14C4.1 13.36 4 12.69 4 12s.1-1.36.26-2h3.38c-.08.66-.14 1.32-.14 2 0 .68.06 1.34.14 2H4.26zm.82 2h2.95c.32 1.25.78 2.45 1.38 3.56-1.84-.63-3.37-1.9-4.33-3.56zm2.95-8H5.08c.96-1.66 2.49-2.93 4.33-3.56C8.81 5.55 8.35 6.75 8.03 8zM12 19.96c-.83-1.2-1.48-2.53-1.91-3.96h3.82c-.43 1.43-1.08 2.76-1.91 3.96zM14.34 14H9.66c-.09-.66-.16-1.32-.16-2 0-.68.07-1.35.16-2h4.68c.09.65.16 1.32.16 2 0 .68-.07 1.34-.16 2zm.25 5.56c.6-1.11 1.06-2.31 1.38-3.56h2.95c-.96 1.65-2.49 2.93-4.33 3.56zM16.36 14c.08-.66.14-1.32.14-2 0-.68-.06-1.34-.14-2h3.38c.16.64.26 1.31.26 2s-.1 1.36-.26 2h-3.38z"
|
||||
/>
|
||||
</svg>
|
||||
<span
|
||||
class="emotion-18 emotion-19"
|
||||
>
|
||||
English
|
||||
</span>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="MuiSvgIcon-root MuiSvgIcon-fontSizeSmall"
|
||||
focusable="false"
|
||||
role="presentation"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
d="M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
<span
|
||||
class="MuiTouchRipple-root"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
<a
|
||||
class="emotion-18 emotion-19"
|
||||
class="emotion-22 emotion-23"
|
||||
data-testid="header--tooltip-documentation"
|
||||
href="https://verdaccio.org/docs/en/installation"
|
||||
rel="noopener noreferrer"
|
||||
@ -566,28 +631,28 @@ exports[`<App /> should display the Header component 1`] = `
|
||||
</div>
|
||||
</header>
|
||||
<div
|
||||
class="MuiBox-root MuiBox-root-412 emotion-36 emotion-37"
|
||||
class="MuiBox-root MuiBox-root-414 emotion-40 emotion-41"
|
||||
>
|
||||
<div
|
||||
class="container content"
|
||||
data-testid="home-page-container"
|
||||
>
|
||||
<div
|
||||
class="emotion-34 emotion-35"
|
||||
class="emotion-38 emotion-39"
|
||||
data-testid="loading"
|
||||
>
|
||||
<div
|
||||
class="emotion-28 emotion-29"
|
||||
>
|
||||
<div
|
||||
class="emotion-26 emotion-1"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="emotion-32 emotion-33"
|
||||
>
|
||||
<div
|
||||
class="MuiCircularProgress-root emotion-30 emotion-31 MuiCircularProgress-colorPrimary MuiCircularProgress-indeterminate"
|
||||
class="emotion-30 emotion-1"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="emotion-36 emotion-37"
|
||||
>
|
||||
<div
|
||||
class="MuiCircularProgress-root emotion-34 emotion-35 MuiCircularProgress-colorPrimary MuiCircularProgress-indeterminate"
|
||||
role="progressbar"
|
||||
style="width: 50px; height: 50px;"
|
||||
>
|
||||
@ -610,26 +675,26 @@ exports[`<App /> should display the Header component 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="emotion-79 emotion-80"
|
||||
class="emotion-83 emotion-84"
|
||||
>
|
||||
<div
|
||||
class="emotion-77 emotion-78"
|
||||
class="emotion-81 emotion-82"
|
||||
>
|
||||
<div
|
||||
class="emotion-68 emotion-69"
|
||||
class="emotion-72 emotion-73"
|
||||
>
|
||||
Made with
|
||||
<span
|
||||
class="emotion-38 emotion-39"
|
||||
class="emotion-42 emotion-43"
|
||||
>
|
||||
♥
|
||||
</span>
|
||||
on
|
||||
<span
|
||||
class="emotion-66 emotion-67"
|
||||
class="emotion-70 emotion-71"
|
||||
>
|
||||
<svg
|
||||
class="emotion-40 emotion-41 emotion-42"
|
||||
class="emotion-44 emotion-45 emotion-46"
|
||||
>
|
||||
<title>
|
||||
Earth
|
||||
@ -639,10 +704,10 @@ exports[`<App /> should display the Header component 1`] = `
|
||||
/>
|
||||
</svg>
|
||||
<span
|
||||
class="emotion-64 emotion-65"
|
||||
class="emotion-68 emotion-69"
|
||||
>
|
||||
<svg
|
||||
class="emotion-43 emotion-44 emotion-42"
|
||||
class="emotion-47 emotion-48 emotion-46"
|
||||
>
|
||||
<title>
|
||||
Spain
|
||||
@ -652,7 +717,7 @@ exports[`<App /> should display the Header component 1`] = `
|
||||
/>
|
||||
</svg>
|
||||
<svg
|
||||
class="emotion-43 emotion-44 emotion-42"
|
||||
class="emotion-47 emotion-48 emotion-46"
|
||||
>
|
||||
<title>
|
||||
Nicaragua
|
||||
@ -662,7 +727,7 @@ exports[`<App /> should display the Header component 1`] = `
|
||||
/>
|
||||
</svg>
|
||||
<svg
|
||||
class="emotion-43 emotion-44 emotion-42"
|
||||
class="emotion-47 emotion-48 emotion-46"
|
||||
>
|
||||
<title>
|
||||
India
|
||||
@ -672,7 +737,7 @@ exports[`<App /> should display the Header component 1`] = `
|
||||
/>
|
||||
</svg>
|
||||
<svg
|
||||
class="emotion-43 emotion-44 emotion-42"
|
||||
class="emotion-47 emotion-48 emotion-46"
|
||||
>
|
||||
<title>
|
||||
Brazil
|
||||
@ -682,7 +747,7 @@ exports[`<App /> should display the Header component 1`] = `
|
||||
/>
|
||||
</svg>
|
||||
<svg
|
||||
class="emotion-43 emotion-44 emotion-42"
|
||||
class="emotion-47 emotion-48 emotion-46"
|
||||
>
|
||||
<title>
|
||||
China
|
||||
@ -692,7 +757,7 @@ exports[`<App /> should display the Header component 1`] = `
|
||||
/>
|
||||
</svg>
|
||||
<svg
|
||||
class="emotion-43 emotion-44 emotion-42"
|
||||
class="emotion-47 emotion-48 emotion-46"
|
||||
>
|
||||
<title>
|
||||
Austria
|
||||
@ -702,7 +767,7 @@ exports[`<App /> should display the Header component 1`] = `
|
||||
/>
|
||||
</svg>
|
||||
<svg
|
||||
class="emotion-43 emotion-44 emotion-42"
|
||||
class="emotion-47 emotion-48 emotion-46"
|
||||
>
|
||||
<title>
|
||||
Germany
|
||||
@ -715,16 +780,16 @@ exports[`<App /> should display the Header component 1`] = `
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="emotion-75 emotion-76"
|
||||
class="emotion-79 emotion-80"
|
||||
>
|
||||
Powered by
|
||||
<span
|
||||
class="emotion-43 emotion-73 emotion-74"
|
||||
class="emotion-47 emotion-77 emotion-78"
|
||||
title="Verdaccio"
|
||||
>
|
||||
<img
|
||||
alt="Verdaccio"
|
||||
class="emotion-70 emotion-71"
|
||||
class="emotion-74 emotion-75"
|
||||
src="[object Object]"
|
||||
/>
|
||||
</span>
|
||||
@ -736,11 +801,11 @@ exports[`<App /> should display the Header component 1`] = `
|
||||
`;
|
||||
|
||||
exports[`<App /> should display the Loading component at the beginning 1`] = `
|
||||
.emotion-71 {
|
||||
.emotion-75 {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.emotion-24 {
|
||||
.emotion-28 {
|
||||
background-color: #4b5e40;
|
||||
color: #fff;
|
||||
min-height: 60px;
|
||||
@ -755,29 +820,29 @@ exports[`<App /> should display the Loading component at the beginning 1`] = `
|
||||
}
|
||||
|
||||
@media (min-width:768px) {
|
||||
.emotion-24 .emotion-13 {
|
||||
.emotion-28 .emotion-13 {
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.emotion-24 .emotion-17 {
|
||||
.emotion-28 .emotion-17 {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.emotion-24 .e1jf5lit4 {
|
||||
.emotion-28 .e1jf5lit4 {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width:1024px) {
|
||||
.emotion-24 .emotion-23 {
|
||||
.emotion-28 .emotion-27 {
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
@media (min-width:1275px) {
|
||||
.emotion-24 .emotion-23 {
|
||||
.emotion-28 .emotion-27 {
|
||||
max-width: 1240px;
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
@ -785,7 +850,7 @@ exports[`<App /> should display the Loading component at the beginning 1`] = `
|
||||
}
|
||||
}
|
||||
|
||||
.emotion-22 {
|
||||
.emotion-26 {
|
||||
-webkit-box-pack: justify;
|
||||
-webkit-justify-content: space-between;
|
||||
-ms-flex-pack: justify;
|
||||
@ -863,7 +928,7 @@ exports[`<App /> should display the Loading component at the beginning 1`] = `
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.emotion-20 {
|
||||
.emotion-24 {
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
@ -875,12 +940,32 @@ exports[`<App /> should display the Loading component at the beginning 1`] = `
|
||||
display: block;
|
||||
}
|
||||
|
||||
.emotion-20 {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media screen and (min-width:768px) {
|
||||
.emotion-20 {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
.emotion-18 {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media screen and (min-width:768px) {
|
||||
.emotion-18 {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
.emotion-22 {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
@media screen and (min-width:1240px) {
|
||||
.emotion-26 {
|
||||
.emotion-30 {
|
||||
max-width: 1240px;
|
||||
width: 100%;
|
||||
margin-left: auto;
|
||||
@ -888,7 +973,7 @@ exports[`<App /> should display the Loading component at the beginning 1`] = `
|
||||
}
|
||||
}
|
||||
|
||||
.emotion-69 {
|
||||
.emotion-73 {
|
||||
background: #f9f9f9;
|
||||
border-top: 1px solid #e3e3e3;
|
||||
color: #999999;
|
||||
@ -896,7 +981,7 @@ exports[`<App /> should display the Loading component at the beginning 1`] = `
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.emotion-67 {
|
||||
.emotion-71 {
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
@ -913,7 +998,7 @@ exports[`<App /> should display the Loading component at the beginning 1`] = `
|
||||
}
|
||||
|
||||
@media (min-width:768px) {
|
||||
.emotion-67 {
|
||||
.emotion-71 {
|
||||
min-width: 400px;
|
||||
max-width: 800px;
|
||||
margin: auto;
|
||||
@ -925,12 +1010,12 @@ exports[`<App /> should display the Loading component at the beginning 1`] = `
|
||||
}
|
||||
|
||||
@media (min-width:1024px) {
|
||||
.emotion-67 {
|
||||
.emotion-71 {
|
||||
max-width: 1240px;
|
||||
}
|
||||
}
|
||||
|
||||
.emotion-58 {
|
||||
.emotion-62 {
|
||||
-webkit-align-items: center;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
@ -939,7 +1024,7 @@ exports[`<App /> should display the Loading component at the beginning 1`] = `
|
||||
}
|
||||
|
||||
@media (min-width:768px) {
|
||||
.emotion-58 {
|
||||
.emotion-62 {
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
@ -947,21 +1032,21 @@ exports[`<App /> should display the Loading component at the beginning 1`] = `
|
||||
}
|
||||
}
|
||||
|
||||
.emotion-28 {
|
||||
.emotion-32 {
|
||||
color: #e25555;
|
||||
padding: 0 5px;
|
||||
}
|
||||
|
||||
.emotion-56 {
|
||||
.emotion-60 {
|
||||
position: relative;
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
.emotion-56:hover .emotion-55 {
|
||||
.emotion-60:hover .emotion-59 {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.emotion-31 {
|
||||
.emotion-35 {
|
||||
box-sizing: initial;
|
||||
display: inline-block;
|
||||
cursor: default;
|
||||
@ -970,7 +1055,7 @@ exports[`<App /> should display the Loading component at the beginning 1`] = `
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
.emotion-54 {
|
||||
.emotion-58 {
|
||||
position: absolute;
|
||||
background: #d3dddd;
|
||||
padding: 1px 4px;
|
||||
@ -988,7 +1073,7 @@ exports[`<App /> should display the Loading component at the beginning 1`] = `
|
||||
top: -2px;
|
||||
}
|
||||
|
||||
.emotion-54:before {
|
||||
.emotion-58:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 29%;
|
||||
@ -1001,7 +1086,7 @@ exports[`<App /> should display the Loading component at the beginning 1`] = `
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
.emotion-34 {
|
||||
.emotion-38 {
|
||||
box-sizing: initial;
|
||||
display: inline-block;
|
||||
cursor: default;
|
||||
@ -1010,7 +1095,7 @@ exports[`<App /> should display the Loading component at the beginning 1`] = `
|
||||
padding: 0 5px;
|
||||
}
|
||||
|
||||
.emotion-65 {
|
||||
.emotion-69 {
|
||||
-webkit-align-items: center;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
@ -1023,7 +1108,7 @@ exports[`<App /> should display the Loading component at the beginning 1`] = `
|
||||
}
|
||||
|
||||
@media (min-width:768px) {
|
||||
.emotion-65 {
|
||||
.emotion-69 {
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
@ -1031,7 +1116,7 @@ exports[`<App /> should display the Loading component at the beginning 1`] = `
|
||||
}
|
||||
}
|
||||
|
||||
.emotion-63 {
|
||||
.emotion-67 {
|
||||
box-sizing: initial;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
@ -1040,21 +1125,21 @@ exports[`<App /> should display the Loading component at the beginning 1`] = `
|
||||
padding: 0 5px;
|
||||
}
|
||||
|
||||
.emotion-60 {
|
||||
.emotion-64 {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
<div
|
||||
class="MuiBox-root MuiBox-root-2 emotion-71 emotion-72"
|
||||
class="MuiBox-root MuiBox-root-2 emotion-75 emotion-76"
|
||||
style="display: none;"
|
||||
>
|
||||
<header
|
||||
class="MuiPaper-root MuiPaper-elevation4 MuiAppBar-root MuiAppBar-positionStatic emotion-24 emotion-25 MuiAppBar-colorPrimary"
|
||||
class="MuiPaper-root MuiPaper-elevation4 MuiAppBar-root MuiAppBar-positionStatic emotion-28 emotion-29 MuiAppBar-colorPrimary"
|
||||
data-testid="header"
|
||||
>
|
||||
<div
|
||||
class="MuiToolbar-root MuiToolbar-regular emotion-22 emotion-23 MuiToolbar-gutters"
|
||||
class="MuiToolbar-root MuiToolbar-regular emotion-26 emotion-27 MuiToolbar-gutters"
|
||||
>
|
||||
<div
|
||||
class="MuiToolbar-root MuiToolbar-regular emotion-14 emotion-15 MuiToolbar-gutters"
|
||||
@ -1123,7 +1208,7 @@ exports[`<App /> should display the Loading component at the beginning 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="MuiToolbar-root MuiToolbar-regular emotion-20 emotion-21 MuiToolbar-gutters"
|
||||
class="MuiToolbar-root MuiToolbar-regular emotion-24 emotion-25 MuiToolbar-gutters"
|
||||
data-testid="header-right"
|
||||
>
|
||||
<button
|
||||
@ -1150,8 +1235,53 @@ exports[`<App /> should display the Loading component at the beginning 1`] = `
|
||||
class="MuiTouchRipple-root"
|
||||
/>
|
||||
</button>
|
||||
<div
|
||||
class="emotion-20 emotion-21"
|
||||
>
|
||||
<button
|
||||
class="MuiButtonBase-root MuiButton-root MuiButton-text MuiButton-colorInherit"
|
||||
tabindex="0"
|
||||
title="Change language"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
class="MuiButton-label ForwardRef(Button)-label-121"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="MuiSvgIcon-root"
|
||||
focusable="false"
|
||||
role="presentation"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zm6.93 6h-2.95c-.32-1.25-.78-2.45-1.38-3.56 1.84.63 3.37 1.91 4.33 3.56zM12 4.04c.83 1.2 1.48 2.53 1.91 3.96h-3.82c.43-1.43 1.08-2.76 1.91-3.96zM4.26 14C4.1 13.36 4 12.69 4 12s.1-1.36.26-2h3.38c-.08.66-.14 1.32-.14 2 0 .68.06 1.34.14 2H4.26zm.82 2h2.95c.32 1.25.78 2.45 1.38 3.56-1.84-.63-3.37-1.9-4.33-3.56zm2.95-8H5.08c.96-1.66 2.49-2.93 4.33-3.56C8.81 5.55 8.35 6.75 8.03 8zM12 19.96c-.83-1.2-1.48-2.53-1.91-3.96h3.82c-.43 1.43-1.08 2.76-1.91 3.96zM14.34 14H9.66c-.09-.66-.16-1.32-.16-2 0-.68.07-1.35.16-2h4.68c.09.65.16 1.32.16 2 0 .68-.07 1.34-.16 2zm.25 5.56c.6-1.11 1.06-2.31 1.38-3.56h2.95c-.96 1.65-2.49 2.93-4.33 3.56zM16.36 14c.08-.66.14-1.32.14-2 0-.68-.06-1.34-.14-2h3.38c.16.64.26 1.31.26 2s-.1 1.36-.26 2h-3.38z"
|
||||
/>
|
||||
</svg>
|
||||
<span
|
||||
class="emotion-18 emotion-19"
|
||||
>
|
||||
English
|
||||
</span>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="MuiSvgIcon-root MuiSvgIcon-fontSizeSmall"
|
||||
focusable="false"
|
||||
role="presentation"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
d="M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
<span
|
||||
class="MuiTouchRipple-root"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
<a
|
||||
class="emotion-18 emotion-19"
|
||||
class="emotion-22 emotion-23"
|
||||
data-testid="header--tooltip-documentation"
|
||||
href="https://verdaccio.org/docs/en/installation"
|
||||
rel="noopener noreferrer"
|
||||
@ -1255,29 +1385,29 @@ exports[`<App /> should display the Loading component at the beginning 1`] = `
|
||||
</div>
|
||||
</header>
|
||||
<div
|
||||
class="MuiBox-root MuiBox-root-195 emotion-26 emotion-27"
|
||||
class="MuiBox-root MuiBox-root-196 emotion-30 emotion-31"
|
||||
/>
|
||||
<div
|
||||
class="emotion-69 emotion-70"
|
||||
class="emotion-73 emotion-74"
|
||||
>
|
||||
<div
|
||||
class="emotion-67 emotion-68"
|
||||
class="emotion-71 emotion-72"
|
||||
>
|
||||
<div
|
||||
class="emotion-58 emotion-59"
|
||||
class="emotion-62 emotion-63"
|
||||
>
|
||||
Made with
|
||||
<span
|
||||
class="emotion-28 emotion-29"
|
||||
class="emotion-32 emotion-33"
|
||||
>
|
||||
♥
|
||||
</span>
|
||||
on
|
||||
<span
|
||||
class="emotion-56 emotion-57"
|
||||
class="emotion-60 emotion-61"
|
||||
>
|
||||
<svg
|
||||
class="emotion-30 emotion-31 emotion-32"
|
||||
class="emotion-34 emotion-35 emotion-36"
|
||||
>
|
||||
<title>
|
||||
Earth
|
||||
@ -1287,10 +1417,10 @@ exports[`<App /> should display the Loading component at the beginning 1`] = `
|
||||
/>
|
||||
</svg>
|
||||
<span
|
||||
class="emotion-54 emotion-55"
|
||||
class="emotion-58 emotion-59"
|
||||
>
|
||||
<svg
|
||||
class="emotion-33 emotion-34 emotion-32"
|
||||
class="emotion-37 emotion-38 emotion-36"
|
||||
>
|
||||
<title>
|
||||
Spain
|
||||
@ -1300,7 +1430,7 @@ exports[`<App /> should display the Loading component at the beginning 1`] = `
|
||||
/>
|
||||
</svg>
|
||||
<svg
|
||||
class="emotion-33 emotion-34 emotion-32"
|
||||
class="emotion-37 emotion-38 emotion-36"
|
||||
>
|
||||
<title>
|
||||
Nicaragua
|
||||
@ -1310,7 +1440,7 @@ exports[`<App /> should display the Loading component at the beginning 1`] = `
|
||||
/>
|
||||
</svg>
|
||||
<svg
|
||||
class="emotion-33 emotion-34 emotion-32"
|
||||
class="emotion-37 emotion-38 emotion-36"
|
||||
>
|
||||
<title>
|
||||
India
|
||||
@ -1320,7 +1450,7 @@ exports[`<App /> should display the Loading component at the beginning 1`] = `
|
||||
/>
|
||||
</svg>
|
||||
<svg
|
||||
class="emotion-33 emotion-34 emotion-32"
|
||||
class="emotion-37 emotion-38 emotion-36"
|
||||
>
|
||||
<title>
|
||||
Brazil
|
||||
@ -1330,7 +1460,7 @@ exports[`<App /> should display the Loading component at the beginning 1`] = `
|
||||
/>
|
||||
</svg>
|
||||
<svg
|
||||
class="emotion-33 emotion-34 emotion-32"
|
||||
class="emotion-37 emotion-38 emotion-36"
|
||||
>
|
||||
<title>
|
||||
China
|
||||
@ -1340,7 +1470,7 @@ exports[`<App /> should display the Loading component at the beginning 1`] = `
|
||||
/>
|
||||
</svg>
|
||||
<svg
|
||||
class="emotion-33 emotion-34 emotion-32"
|
||||
class="emotion-37 emotion-38 emotion-36"
|
||||
>
|
||||
<title>
|
||||
Austria
|
||||
@ -1350,7 +1480,7 @@ exports[`<App /> should display the Loading component at the beginning 1`] = `
|
||||
/>
|
||||
</svg>
|
||||
<svg
|
||||
class="emotion-33 emotion-34 emotion-32"
|
||||
class="emotion-37 emotion-38 emotion-36"
|
||||
>
|
||||
<title>
|
||||
Germany
|
||||
@ -1363,16 +1493,16 @@ exports[`<App /> should display the Loading component at the beginning 1`] = `
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="emotion-65 emotion-66"
|
||||
class="emotion-69 emotion-70"
|
||||
>
|
||||
Powered by
|
||||
<span
|
||||
class="emotion-33 emotion-63 emotion-64"
|
||||
class="emotion-37 emotion-67 emotion-68"
|
||||
title="Verdaccio"
|
||||
>
|
||||
<img
|
||||
alt="Verdaccio"
|
||||
class="emotion-60 emotion-61"
|
||||
class="emotion-64 emotion-65"
|
||||
src="[object Object]"
|
||||
/>
|
||||
</span>
|
||||
|
@ -25,14 +25,13 @@ function loadDayJSLocale() {
|
||||
}
|
||||
|
||||
switch (locale.toLowerCase()) {
|
||||
// At the moment we only support pt-BR, please see: i18n/translations/*
|
||||
case 'pt-br':
|
||||
{
|
||||
require('dayjs/locale/pt-br');
|
||||
dayjs.locale('pt-br');
|
||||
}
|
||||
break;
|
||||
case 'de':
|
||||
case 'de-de':
|
||||
{
|
||||
require('dayjs/locale/de');
|
||||
dayjs.locale('de');
|
||||
|
@ -3,6 +3,7 @@ import { useTranslation } from 'react-i18next';
|
||||
|
||||
import Button from '../../muiComponents/Button';
|
||||
import ThemeContext from '../../design-tokens/ThemeContext';
|
||||
import LanguageSwitch from '../LanguageSwitch';
|
||||
|
||||
import { RightSide } from './styles';
|
||||
import HeaderToolTip from './HeaderToolTip';
|
||||
@ -72,6 +73,7 @@ const HeaderRight: React.FC<Props> = ({
|
||||
{!withoutSearch && (
|
||||
<HeaderToolTip onClick={onToggleMobileNav} title={t('search.packages')} tooltipIconType={'search'} />
|
||||
)}
|
||||
<LanguageSwitch />
|
||||
<HeaderToolTip title={t('header.documentation')} tooltipIconType={'help'} />
|
||||
<HeaderToolTip onClick={onOpenRegistryInfoDialog} title={t('header.registry-info')} tooltipIconType={'info'} />
|
||||
<HeaderToolTip
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`<Header /> component with logged in state should load the component in logged in state 1`] = `
|
||||
.emotion-24 {
|
||||
.emotion-28 {
|
||||
background-color: #4b5e40;
|
||||
color: #fff;
|
||||
min-height: 60px;
|
||||
@ -16,29 +16,29 @@ exports[`<Header /> component with logged in state should load the component in
|
||||
}
|
||||
|
||||
@media (min-width:768px) {
|
||||
.emotion-24 .emotion-13 {
|
||||
.emotion-28 .emotion-13 {
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.emotion-24 .emotion-17 {
|
||||
.emotion-28 .emotion-17 {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.emotion-24 .e1jf5lit4 {
|
||||
.emotion-28 .e1jf5lit4 {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width:1024px) {
|
||||
.emotion-24 .emotion-23 {
|
||||
.emotion-28 .emotion-27 {
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
@media (min-width:1275px) {
|
||||
.emotion-24 .emotion-23 {
|
||||
.emotion-28 .emotion-27 {
|
||||
max-width: 1240px;
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
@ -46,7 +46,7 @@ exports[`<Header /> component with logged in state should load the component in
|
||||
}
|
||||
}
|
||||
|
||||
.emotion-22 {
|
||||
.emotion-26 {
|
||||
-webkit-box-pack: justify;
|
||||
-webkit-justify-content: space-between;
|
||||
-ms-flex-pack: justify;
|
||||
@ -124,7 +124,7 @@ exports[`<Header /> component with logged in state should load the component in
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.emotion-20 {
|
||||
.emotion-24 {
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
@ -136,16 +136,36 @@ exports[`<Header /> component with logged in state should load the component in
|
||||
display: block;
|
||||
}
|
||||
|
||||
.emotion-20 {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media screen and (min-width:768px) {
|
||||
.emotion-20 {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
.emotion-18 {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media screen and (min-width:768px) {
|
||||
.emotion-18 {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
.emotion-22 {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
<header
|
||||
class="MuiPaper-root MuiPaper-elevation4 MuiAppBar-root MuiAppBar-positionStatic emotion-24 emotion-25 MuiAppBar-colorPrimary"
|
||||
class="MuiPaper-root MuiPaper-elevation4 MuiAppBar-root MuiAppBar-positionStatic emotion-28 emotion-29 MuiAppBar-colorPrimary"
|
||||
data-testid="header"
|
||||
>
|
||||
<div
|
||||
class="MuiToolbar-root MuiToolbar-regular emotion-22 emotion-23 MuiToolbar-gutters"
|
||||
class="MuiToolbar-root MuiToolbar-regular emotion-26 emotion-27 MuiToolbar-gutters"
|
||||
>
|
||||
<div
|
||||
class="MuiToolbar-root MuiToolbar-regular emotion-14 emotion-15 MuiToolbar-gutters"
|
||||
@ -214,7 +234,7 @@ exports[`<Header /> component with logged in state should load the component in
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="MuiToolbar-root MuiToolbar-regular emotion-20 emotion-21 MuiToolbar-gutters"
|
||||
class="MuiToolbar-root MuiToolbar-regular emotion-24 emotion-25 MuiToolbar-gutters"
|
||||
data-testid="header-right"
|
||||
>
|
||||
<button
|
||||
@ -241,8 +261,53 @@ exports[`<Header /> component with logged in state should load the component in
|
||||
class="MuiTouchRipple-root"
|
||||
/>
|
||||
</button>
|
||||
<div
|
||||
class="emotion-20 emotion-21"
|
||||
>
|
||||
<button
|
||||
class="MuiButtonBase-root MuiButton-root MuiButton-text MuiButton-colorInherit"
|
||||
tabindex="0"
|
||||
title="Change language"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
class="MuiButton-label ForwardRef(Button)-label-322"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="MuiSvgIcon-root"
|
||||
focusable="false"
|
||||
role="presentation"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zm6.93 6h-2.95c-.32-1.25-.78-2.45-1.38-3.56 1.84.63 3.37 1.91 4.33 3.56zM12 4.04c.83 1.2 1.48 2.53 1.91 3.96h-3.82c.43-1.43 1.08-2.76 1.91-3.96zM4.26 14C4.1 13.36 4 12.69 4 12s.1-1.36.26-2h3.38c-.08.66-.14 1.32-.14 2 0 .68.06 1.34.14 2H4.26zm.82 2h2.95c.32 1.25.78 2.45 1.38 3.56-1.84-.63-3.37-1.9-4.33-3.56zm2.95-8H5.08c.96-1.66 2.49-2.93 4.33-3.56C8.81 5.55 8.35 6.75 8.03 8zM12 19.96c-.83-1.2-1.48-2.53-1.91-3.96h3.82c-.43 1.43-1.08 2.76-1.91 3.96zM14.34 14H9.66c-.09-.66-.16-1.32-.16-2 0-.68.07-1.35.16-2h4.68c.09.65.16 1.32.16 2 0 .68-.07 1.34-.16 2zm.25 5.56c.6-1.11 1.06-2.31 1.38-3.56h2.95c-.96 1.65-2.49 2.93-4.33 3.56zM16.36 14c.08-.66.14-1.32.14-2 0-.68-.06-1.34-.14-2h3.38c.16.64.26 1.31.26 2s-.1 1.36-.26 2h-3.38z"
|
||||
/>
|
||||
</svg>
|
||||
<span
|
||||
class="emotion-18 emotion-19"
|
||||
>
|
||||
English
|
||||
</span>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="MuiSvgIcon-root MuiSvgIcon-fontSizeSmall"
|
||||
focusable="false"
|
||||
role="presentation"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
d="M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
<span
|
||||
class="MuiTouchRipple-root"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
<a
|
||||
class="emotion-18 emotion-19"
|
||||
class="emotion-22 emotion-23"
|
||||
data-testid="header--tooltip-documentation"
|
||||
href="https://verdaccio.org/docs/en/installation"
|
||||
rel="noopener noreferrer"
|
||||
@ -359,7 +424,7 @@ exports[`<Header /> component with logged in state should load the component in
|
||||
`;
|
||||
|
||||
exports[`<Header /> component with logged in state should load the component in logged out state 1`] = `
|
||||
.emotion-24 {
|
||||
.emotion-28 {
|
||||
background-color: #4b5e40;
|
||||
color: #fff;
|
||||
min-height: 60px;
|
||||
@ -374,29 +439,29 @@ exports[`<Header /> component with logged in state should load the component in
|
||||
}
|
||||
|
||||
@media (min-width:768px) {
|
||||
.emotion-24 .emotion-13 {
|
||||
.emotion-28 .emotion-13 {
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.emotion-24 .emotion-17 {
|
||||
.emotion-28 .emotion-17 {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.emotion-24 .e1jf5lit4 {
|
||||
.emotion-28 .e1jf5lit4 {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width:1024px) {
|
||||
.emotion-24 .emotion-23 {
|
||||
.emotion-28 .emotion-27 {
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
@media (min-width:1275px) {
|
||||
.emotion-24 .emotion-23 {
|
||||
.emotion-28 .emotion-27 {
|
||||
max-width: 1240px;
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
@ -404,7 +469,7 @@ exports[`<Header /> component with logged in state should load the component in
|
||||
}
|
||||
}
|
||||
|
||||
.emotion-22 {
|
||||
.emotion-26 {
|
||||
-webkit-box-pack: justify;
|
||||
-webkit-justify-content: space-between;
|
||||
-ms-flex-pack: justify;
|
||||
@ -482,7 +547,7 @@ exports[`<Header /> component with logged in state should load the component in
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.emotion-20 {
|
||||
.emotion-24 {
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
@ -494,16 +559,36 @@ exports[`<Header /> component with logged in state should load the component in
|
||||
display: block;
|
||||
}
|
||||
|
||||
.emotion-20 {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media screen and (min-width:768px) {
|
||||
.emotion-20 {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
.emotion-18 {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media screen and (min-width:768px) {
|
||||
.emotion-18 {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
.emotion-22 {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
<header
|
||||
class="MuiPaper-root MuiPaper-elevation4 MuiAppBar-root MuiAppBar-positionStatic emotion-24 emotion-25 MuiAppBar-colorPrimary"
|
||||
class="MuiPaper-root MuiPaper-elevation4 MuiAppBar-root MuiAppBar-positionStatic emotion-28 emotion-29 MuiAppBar-colorPrimary"
|
||||
data-testid="header"
|
||||
>
|
||||
<div
|
||||
class="MuiToolbar-root MuiToolbar-regular emotion-22 emotion-23 MuiToolbar-gutters"
|
||||
class="MuiToolbar-root MuiToolbar-regular emotion-26 emotion-27 MuiToolbar-gutters"
|
||||
>
|
||||
<div
|
||||
class="MuiToolbar-root MuiToolbar-regular emotion-14 emotion-15 MuiToolbar-gutters"
|
||||
@ -572,7 +657,7 @@ exports[`<Header /> component with logged in state should load the component in
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="MuiToolbar-root MuiToolbar-regular emotion-20 emotion-21 MuiToolbar-gutters"
|
||||
class="MuiToolbar-root MuiToolbar-regular emotion-24 emotion-25 MuiToolbar-gutters"
|
||||
data-testid="header-right"
|
||||
>
|
||||
<button
|
||||
@ -599,8 +684,53 @@ exports[`<Header /> component with logged in state should load the component in
|
||||
class="MuiTouchRipple-root"
|
||||
/>
|
||||
</button>
|
||||
<div
|
||||
class="emotion-20 emotion-21"
|
||||
>
|
||||
<button
|
||||
class="MuiButtonBase-root MuiButton-root MuiButton-text MuiButton-colorInherit"
|
||||
tabindex="0"
|
||||
title="Change language"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
class="MuiButton-label ForwardRef(Button)-label-119"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="MuiSvgIcon-root"
|
||||
focusable="false"
|
||||
role="presentation"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zm6.93 6h-2.95c-.32-1.25-.78-2.45-1.38-3.56 1.84.63 3.37 1.91 4.33 3.56zM12 4.04c.83 1.2 1.48 2.53 1.91 3.96h-3.82c.43-1.43 1.08-2.76 1.91-3.96zM4.26 14C4.1 13.36 4 12.69 4 12s.1-1.36.26-2h3.38c-.08.66-.14 1.32-.14 2 0 .68.06 1.34.14 2H4.26zm.82 2h2.95c.32 1.25.78 2.45 1.38 3.56-1.84-.63-3.37-1.9-4.33-3.56zm2.95-8H5.08c.96-1.66 2.49-2.93 4.33-3.56C8.81 5.55 8.35 6.75 8.03 8zM12 19.96c-.83-1.2-1.48-2.53-1.91-3.96h3.82c-.43 1.43-1.08 2.76-1.91 3.96zM14.34 14H9.66c-.09-.66-.16-1.32-.16-2 0-.68.07-1.35.16-2h4.68c.09.65.16 1.32.16 2 0 .68-.07 1.34-.16 2zm.25 5.56c.6-1.11 1.06-2.31 1.38-3.56h2.95c-.96 1.65-2.49 2.93-4.33 3.56zM16.36 14c.08-.66.14-1.32.14-2 0-.68-.06-1.34-.14-2h3.38c.16.64.26 1.31.26 2s-.1 1.36-.26 2h-3.38z"
|
||||
/>
|
||||
</svg>
|
||||
<span
|
||||
class="emotion-18 emotion-19"
|
||||
>
|
||||
English
|
||||
</span>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="MuiSvgIcon-root MuiSvgIcon-fontSizeSmall"
|
||||
focusable="false"
|
||||
role="presentation"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
d="M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
<span
|
||||
class="MuiTouchRipple-root"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
<a
|
||||
class="emotion-18 emotion-19"
|
||||
class="emotion-22 emotion-23"
|
||||
data-testid="header--tooltip-documentation"
|
||||
href="https://verdaccio.org/docs/en/installation"
|
||||
rel="noopener noreferrer"
|
||||
|
@ -11,6 +11,8 @@ import nicaragua from './img/nicaragua.svg';
|
||||
import pakistan from './img/pakistan.svg';
|
||||
import austria from './img/austria.svg';
|
||||
import spain from './img/spain.svg';
|
||||
import usa from './img/usa.svg';
|
||||
import france from './img/france.svg';
|
||||
import earth from './img/earth.svg';
|
||||
import verdaccio from './img/verdaccio.svg';
|
||||
import filebinary from './img/filebinary.svg';
|
||||
@ -23,9 +25,11 @@ export interface IconsMap {
|
||||
brazil: string;
|
||||
spain: string;
|
||||
china: string;
|
||||
usa: string;
|
||||
nicaragua: string;
|
||||
pakistan: string;
|
||||
austria: string;
|
||||
france: string;
|
||||
germany: string;
|
||||
india: string;
|
||||
earth: string;
|
||||
@ -54,6 +58,8 @@ export const Icons: IconsMap = {
|
||||
time,
|
||||
version,
|
||||
germany,
|
||||
usa,
|
||||
france,
|
||||
};
|
||||
|
||||
export interface Props {
|
||||
|
1
src/components/Icon/img/france.svg
Normal file
1
src/components/Icon/img/france.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" id="france"><path d="M38.345 88.273C17.167 88.273 0 105.44 0 126.618v258.759c0 21.177 17.167 38.345 38.345 38.345h132.322V88.273H38.345z" fill="#41479b"/><path fill="#f5f5f5" d="M170.67 88.277h170.67v335.45H170.67z"/><path d="M473.655 88.273H341.333v335.448h132.322c21.177 0 38.345-17.167 38.345-38.345V126.618c0-21.178-17.167-38.345-38.345-38.345z" fill="#ff4b55"/></svg>
|
After Width: | Height: | Size: 434 B |
1
src/components/Icon/img/usa.svg
Normal file
1
src/components/Icon/img/usa.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 12 KiB |
204
src/components/LanguageSwitch/LanguageSwitch.tsx
Normal file
204
src/components/LanguageSwitch/LanguageSwitch.tsx
Normal file
@ -0,0 +1,204 @@
|
||||
import React, { MouseEvent, useCallback, useState, useRef, useContext } from 'react';
|
||||
import LanguageIcon from '@material-ui/icons/Language';
|
||||
import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
|
||||
import i18next, { TFunction } from 'i18next';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { withStyles } from '@material-ui/core/styles';
|
||||
import ClickAwayListener from '@material-ui/core/ClickAwayListener';
|
||||
import Grow from '@material-ui/core/Grow';
|
||||
import Popper from '@material-ui/core/Popper';
|
||||
import MenuList from '@material-ui/core/MenuList';
|
||||
import styled from '@emotion/styled';
|
||||
import { css } from '@emotion/core';
|
||||
|
||||
import { Language } from '../../../i18n/config';
|
||||
import ThemeContext from '../../design-tokens/ThemeContext';
|
||||
import Paper from '../../muiComponents/Paper';
|
||||
import MenuItem from '../../muiComponents/MenuItem';
|
||||
import Button from '../../muiComponents/Button';
|
||||
import Tooltip from '../../muiComponents/Tooltip';
|
||||
import Divider from '../../muiComponents/Divider';
|
||||
import Box from '../../muiComponents/Box';
|
||||
import { Theme } from '../../design-tokens/theme';
|
||||
import Link from '../Link';
|
||||
import Icon from '../Icon';
|
||||
|
||||
const VERDACCIO_UI_GITHUB_REPOSITORY = 'https://github.com/verdaccio/ui';
|
||||
|
||||
const getTranslatedCurrentLanguage = (
|
||||
t: TFunction
|
||||
): { [key: string]: { translation: string; icon: React.ComponentProps<typeof Icon>['name'] } } => ({
|
||||
'en-us': {
|
||||
translation: t('lng.english'),
|
||||
icon: 'usa',
|
||||
},
|
||||
'fr-fr': {
|
||||
translation: t('lng.french'),
|
||||
icon: 'france',
|
||||
},
|
||||
'pt-br': {
|
||||
translation: t('lng.portuguese'),
|
||||
icon: 'brazil',
|
||||
},
|
||||
'de-de': {
|
||||
translation: t('lng.german'),
|
||||
icon: 'germany',
|
||||
},
|
||||
'es-es': {
|
||||
translation: t('lng.spanish'),
|
||||
icon: 'spain',
|
||||
},
|
||||
'zh-cn': {
|
||||
translation: t('lng.chinese'),
|
||||
icon: 'china',
|
||||
},
|
||||
});
|
||||
|
||||
const LanguageSwitch = () => {
|
||||
const themeContext = useContext(ThemeContext);
|
||||
const { t } = useTranslation();
|
||||
const [open, setOpen] = useState(false);
|
||||
const anchorRef = useRef<HTMLButtonElement>(null);
|
||||
|
||||
if (!themeContext) {
|
||||
throw Error(t('theme-context-not-correct-used'));
|
||||
}
|
||||
|
||||
const languages = (i18next.options.resources ? Object.keys(i18next.options.resources) : []) as Array<Language>;
|
||||
const currentLanguage: Language = i18next.language || i18next.options?.fallbackLng?.[0];
|
||||
|
||||
const { translation: userLanguage } = getTranslatedCurrentLanguage(t)[currentLanguage.toLowerCase()];
|
||||
|
||||
const handleToggle = useCallback(() => {
|
||||
setOpen(prevOpen => !prevOpen);
|
||||
}, []);
|
||||
|
||||
const handleClose = useCallback(
|
||||
(event: MouseEvent<HTMLLIElement | Document | HTMLAnchorElement>) => {
|
||||
if (anchorRef.current) {
|
||||
if (anchorRef.current.contains(event.currentTarget)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
setOpen(false);
|
||||
},
|
||||
[setOpen]
|
||||
);
|
||||
|
||||
const handleSwitchLanguage = useCallback(
|
||||
(language: Language) => (event: MouseEvent<HTMLLIElement>) => {
|
||||
themeContext.setLanguage(language);
|
||||
handleClose(event);
|
||||
},
|
||||
[handleClose, themeContext]
|
||||
);
|
||||
|
||||
// return focus to the button when we transitioned from !open -> open
|
||||
const prevOpen = React.useRef(open);
|
||||
React.useEffect(() => {
|
||||
if (prevOpen.current === true && open === false) {
|
||||
if (anchorRef.current) {
|
||||
anchorRef.current.focus();
|
||||
}
|
||||
}
|
||||
|
||||
prevOpen.current = open;
|
||||
}, [open]);
|
||||
|
||||
return (
|
||||
<Wrapper>
|
||||
<Tooltip enterDelay={300} title={t('change-language')}>
|
||||
<SwitchButton color="inherit" onClick={handleToggle} ref={anchorRef}>
|
||||
<LanguageIcon />
|
||||
<UserLanguage>{userLanguage}</UserLanguage>
|
||||
<ExpandMoreIcon fontSize="small" />
|
||||
</SwitchButton>
|
||||
</Tooltip>
|
||||
<Popper anchorEl={anchorRef.current} disablePortal={true} open={open} role={undefined} transition={true}>
|
||||
{({ TransitionProps }) => (
|
||||
<Grow {...TransitionProps}>
|
||||
<StyledPaper>
|
||||
<ClickAwayListener onClickAway={handleClose}>
|
||||
<MenuList>
|
||||
{languages
|
||||
.filter(language => language !== currentLanguage)
|
||||
.map(language => {
|
||||
const { icon, translation } = getTranslatedCurrentLanguage(t)[language.toLowerCase()];
|
||||
return (
|
||||
<StyledMenuItem
|
||||
key={language}
|
||||
onClick={handleSwitchLanguage(language)}
|
||||
selected={userLanguage === translation}>
|
||||
<Icon name={icon} size="md" />
|
||||
{translation}
|
||||
</StyledMenuItem>
|
||||
);
|
||||
})}
|
||||
<Box my={1}>
|
||||
<Divider />
|
||||
</Box>
|
||||
<MenuItem button={true}>
|
||||
<StyledLink external={true} onClick={handleClose} to={VERDACCIO_UI_GITHUB_REPOSITORY}>
|
||||
{`${t('help-to-translate')}`}
|
||||
</StyledLink>
|
||||
</MenuItem>
|
||||
</MenuList>
|
||||
</ClickAwayListener>
|
||||
</StyledPaper>
|
||||
</Grow>
|
||||
)}
|
||||
</Popper>
|
||||
</Wrapper>
|
||||
);
|
||||
};
|
||||
|
||||
export default LanguageSwitch;
|
||||
|
||||
const Wrapper = styled('div')<{ theme?: Theme }>(({ theme }) => ({
|
||||
display: 'none',
|
||||
[`@media screen and (min-width: ${theme && theme.breakPoints.medium}px)`]: {
|
||||
display: 'inline-block',
|
||||
},
|
||||
}));
|
||||
|
||||
const UserLanguage = styled('span')<{ theme?: Theme }>(({ theme }) => ({
|
||||
display: 'none',
|
||||
[`@media screen and (min-width: ${theme && theme.breakPoints.medium}px)`]: {
|
||||
display: 'inline-block',
|
||||
},
|
||||
}));
|
||||
|
||||
const SwitchButton = withStyles((theme: Theme) => ({
|
||||
label: {
|
||||
display: 'grid',
|
||||
gridGap: theme?.spacing(1),
|
||||
gridTemplateColumns: '24px 20px',
|
||||
[`@media screen and (min-width: ${theme && theme.breakPoints.medium}px)`]: {
|
||||
gridTemplateColumns: '24px 1fr 20px',
|
||||
},
|
||||
},
|
||||
}))(Button);
|
||||
|
||||
const StyledMenuItem = withStyles((theme: Theme) => ({
|
||||
root: {
|
||||
display: 'grid',
|
||||
cursor: 'pointer',
|
||||
gridGap: theme?.spacing(0.5),
|
||||
gridTemplateColumns: '20px 1fr',
|
||||
alignItems: 'center',
|
||||
'&:first-child': {
|
||||
borderTopLeftRadius: 4,
|
||||
borderTopRightRadius: 4,
|
||||
},
|
||||
},
|
||||
}))(MenuItem);
|
||||
|
||||
const StyledLink = styled(Link)<{ theme?: Theme }>(({ theme }) => ({
|
||||
color: theme?.palette.type === 'dark' ? theme?.palette.white : theme?.palette.text.primary,
|
||||
textDecoration: 'none',
|
||||
}));
|
||||
|
||||
const StyledPaper = styled(Paper)<{ theme?: Theme }>(({ theme }) => ({
|
||||
backgroundColor: theme?.palette.type === 'dark' ? theme?.palette.cyanBlue : theme?.palette.white,
|
||||
}));
|
1
src/components/LanguageSwitch/index.ts
Normal file
1
src/components/LanguageSwitch/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export { default } from './LanguageSwitch';
|
@ -1,8 +1,11 @@
|
||||
import { createContext } from 'react';
|
||||
|
||||
import { Language } from '../../i18n/config';
|
||||
interface Props {
|
||||
isDarkMode: boolean;
|
||||
setIsDarkMode: (isDarkMode: boolean) => void;
|
||||
language: Language;
|
||||
setLanguage: (language: Language) => void;
|
||||
}
|
||||
|
||||
const ThemeContext = createContext<undefined | Props>(undefined);
|
||||
|
@ -1,6 +1,9 @@
|
||||
import React from 'react';
|
||||
import React, { useEffect } from 'react';
|
||||
import { ThemeProvider as MuiThemeProvider } from '@material-ui/core/styles';
|
||||
import { ThemeProvider as EmotionThemeProvider } from 'emotion-theming';
|
||||
import i18next from 'i18next';
|
||||
|
||||
import { Language } from '../../i18n/config';
|
||||
|
||||
import ThemeContext from './ThemeContext';
|
||||
import { getTheme, ThemeMode } from './theme';
|
||||
@ -8,12 +11,23 @@ import useLocalStorage from './useLocalStorage';
|
||||
|
||||
const ThemeProvider: React.FC = ({ children }) => {
|
||||
const isDarkModeDefault = window?.__VERDACCIO_BASENAME_UI_OPTIONS?.darkMode;
|
||||
const currentLanguage: Language = i18next.language || i18next.options?.fallbackLng?.[0];
|
||||
|
||||
const [isDarkMode, setIsDarkMode] = useLocalStorage('darkMode', !!isDarkModeDefault);
|
||||
const [language, setLanguage] = useLocalStorage('language', currentLanguage);
|
||||
|
||||
const themeMode: ThemeMode = isDarkMode ? 'dark' : 'light';
|
||||
|
||||
const changeLanguage = async () => {
|
||||
await i18next.changeLanguage(language);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
changeLanguage();
|
||||
}, [language, changeLanguage]);
|
||||
|
||||
return (
|
||||
<ThemeContext.Provider value={{ isDarkMode, setIsDarkMode }}>
|
||||
<ThemeContext.Provider value={{ isDarkMode, setIsDarkMode, language, setLanguage }}>
|
||||
<EmotionThemeProvider theme={getTheme(themeMode)}>
|
||||
<MuiThemeProvider theme={getTheme(themeMode)}>{children}</MuiThemeProvider>
|
||||
</EmotionThemeProvider>
|
||||
|
@ -9,10 +9,10 @@ interface Props extends Omit<MenuItemProps, 'component'> {
|
||||
component?: HTMLElementTagName;
|
||||
}
|
||||
|
||||
const MenuItem = forwardRef<MenuItemRef, Props>(function MenuItem({ button, ...props }, ref) {
|
||||
const MenuItem = forwardRef<MenuItemRef, Props>(function MenuItem(props, ref) {
|
||||
// it seems typescript has some discrimination type limitions. Please see: https://github.com/mui-org/material-ui/issues/14971
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
return <StyledMaterialUIMenuItem {...props} button={button as any} innerRef={ref} />;
|
||||
// @ts-ignore Type Types of property 'button' are incompatible.
|
||||
return <StyledMaterialUIMenuItem {...props} ref={ref as any} />;
|
||||
});
|
||||
|
||||
MenuItem.defaultProps = {
|
||||
@ -20,7 +20,6 @@ MenuItem.defaultProps = {
|
||||
};
|
||||
|
||||
export default MenuItem;
|
||||
|
||||
const StyledMaterialUIMenuItem = styled(MaterialUIMenuItem)({
|
||||
outline: 'none',
|
||||
});
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { isObject } from 'util';
|
||||
|
||||
import i18n from 'i18next';
|
||||
import i18next from 'i18next';
|
||||
import { UpLinks } from '@verdaccio/types';
|
||||
import isString from 'lodash/isString';
|
||||
import dayjs from 'dayjs';
|
||||
@ -93,5 +93,5 @@ export function getRecentReleases(time: Time = {}): Time[] {
|
||||
}
|
||||
|
||||
export function getAuthorName(authorName: string): string {
|
||||
return authorName.toLowerCase() === 'anonymous' ? i18n.t('author-anonymous') : authorName;
|
||||
return authorName.toLowerCase() === 'anonymous' ? i18next.t('author-anonymous') : authorName;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user