Skip to content

Commit

Permalink
feat(web): prettify nav bar
Browse files Browse the repository at this point in the history
  • Loading branch information
ivan-aksamentov committed Sep 15, 2023
1 parent 131fedd commit cabb824
Show file tree
Hide file tree
Showing 8 changed files with 97 additions and 103 deletions.
2 changes: 1 addition & 1 deletion packages_rs/nextclade-web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@
"react-file-icon": "1.1.0",
"react-helmet": "6.1.0",
"react-i18next": "11.3.3",
"react-icons": "4.3.1",
"react-icons": "4.11.0",
"react-if": "4.1.4",
"react-loader-spinner": "5.1.4",
"react-markdown": "6.0.3",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,11 @@ export const FilePickerTitle = styled.h4`
margin: auto 0;
`

export const TabsPanelStyled = styled(TabsPanel)``
export const TabsPanelStyled = styled(TabsPanel)`
* {
background: transparent !important;
}
`

const TabsContentStyled = styled(TabsContent)`
height: 100%;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import React, { useCallback, useMemo, useState } from 'react'
import { Dropdown, DropdownToggle, DropdownMenu, DropdownItem, DropdownProps } from 'reactstrap'
import {
Dropdown as DropdownBase,
DropdownToggle as DropdownToggleBase,
DropdownMenu as DropdownMenuBase,
DropdownItem,
DropdownProps,
} from 'reactstrap'
import { useRecoilState } from 'recoil'

import styled from 'styled-components'
import { localeAtom } from 'src/state/locale.state'
import { getLocaleWithKey, Locale, localesArray } from 'src/i18n/i18n'

Expand All @@ -14,11 +20,11 @@ export function LanguageSwitcher({ ...restProps }: LanguageSwitcherProps) {
const setLocaleLocal = useCallback((locale: Locale) => () => setCurrentLocale(locale.key), [setCurrentLocale])

return (
<Dropdown className="language-switcher" isOpen={dropdownOpen} toggle={toggle} {...restProps}>
<Dropdown isOpen={dropdownOpen} toggle={toggle} {...restProps}>
<DropdownToggle nav caret>
<LanguageSwitcherItem locale={currentLocale} />
<LabelShort locale={currentLocale} />
</DropdownToggle>
<DropdownMenu className="language-switcher-menu" positionFixed>
<DropdownMenu positionFixed>
{localesArray.map((locale) => {
const isCurrent = locale.key === currentLocale
return (
Expand All @@ -33,20 +39,42 @@ export function LanguageSwitcher({ ...restProps }: LanguageSwitcherProps) {
}

export function LanguageSwitcherItem({ locale }: { locale: string }) {
const { Flag, name, native } = getLocaleWithKey(locale)

const label = useMemo(() => {
if (name === native) {
return name
}

return `${native} (${name})`
const { name, native } = getLocaleWithKey(locale)
const { label, tooltip } = useMemo(() => {
return { label: `(${native})`, tooltip: `${name} (${native})` }
}, [name, native])

return (
<>
<Flag className="language-switcher-flag" />
<span className="pl-2">{label}</span>
</>
<span title={tooltip}>
<LabelShort locale={locale} />
<span className="mx-2">{label}</span>
</span>
)
}

export function LabelShort({ locale, ...restProps }: { locale: string; className?: string }) {
const { key } = getLocaleWithKey(locale)
return <LabelShortText {...restProps}>{key}</LabelShortText>
}

const LabelShortText = styled.span`
font-family: ${(props) => props.theme.font.monospace};
text-transform: uppercase !important;
color: unset !important;
`

const Dropdown = styled(DropdownBase)`
padding: 0;
margin: 0;
`

const DropdownToggle = styled(DropdownToggleBase)`
color: ${(props) => props.theme.bodyColor};
padding: 0;
margin: 0;
`

const DropdownMenu = styled(DropdownMenuBase)`
background-color: ${(props) => props.theme.bodyBg};
box-shadow: 1px 1px 20px 0 #0005;
transition: opacity ease-out 0.25s;
`
28 changes: 18 additions & 10 deletions packages_rs/nextclade-web/src/components/Layout/NavigationBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
} from 'reactstrap'
import { useRecoilValue } from 'recoil'
import { Link } from 'src/components/Link/Link'
import { FaDocker, FaGithub, FaTwitter } from 'react-icons/fa'
import { FaDocker, FaGithub, FaXTwitter, FaDiscourse } from 'react-icons/fa6'
import { LinkSmart } from 'src/components/Link/LinkSmart'
import { hasRanAtom, hasTreeAtom } from 'src/state/results.state'
import styled from 'styled-components'
Expand All @@ -18,15 +18,14 @@ import { CitationButton } from 'src/components/Citation/CitationButton'
import { NextcladeTextLogo } from 'src/components/Layout/NextcladeTextLogo'
import { LanguageSwitcher } from './LanguageSwitcher'

const LOGO_SIZE = 30
const LOGO_SIZE = 36

export const Navbar = styled(NavbarBase)`
height: 38px;
height: 45px;
display: flex;
vertical-align: middle;
padding: 0 !important;
margin: 0 !important;
box-shadow: ${(props) => props.theme.shadows.large};
box-shadow: 0 0 8px 0 #0004;
`

export const Nav = styled(NavBase)`
Expand All @@ -40,7 +39,11 @@ export const NavItem = styled(NavItemBase)`
padding: 0 0.5rem;
flex-grow: 0;
flex-shrink: 0;
margin: 0 !important;
margin: auto;
* {
vertical-align: middle;
}
`

const NavbarBrand = styled(NavbarBrandBase)`
Expand Down Expand Up @@ -138,18 +141,23 @@ export function NavigationBar() {
},
{
url: 'https://twitter.com/nextstrain',
title: t('Link to our Twitter'),
content: <FaTwitter size={20} color="#aaa" />,
title: t('Link to our X.com (Twitter)'),
content: <FaXTwitter size={20} color="#aaa" className="mb-1" />,
},
{
url: 'https://discussion.nextstrain.org/',
title: t('Link to our discussion forum'),
content: <FaDiscourse size={20} color="#aaa" className="mb-1" />,
},
{
url: 'https://hub.docker.com/r/nextstrain/nextclade',
title: t('Link to our Docker containers'),
content: <FaDocker size={20} color="#aaa" />,
content: <FaDocker size={20} color="#aaa" className="mb-1" />,
},
{
url: 'https://github.com/nextstrain/nextclade',
title: t('Link to our Github page'),
content: <FaGithub size={20} color="#aaa" />,
content: <FaGithub size={20} color="#aaa" className="mb-1" />,
},
{
title: t('Change language'),
Expand Down
72 changes: 23 additions & 49 deletions packages_rs/nextclade-web/src/i18n/i18n.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
import { ElementType, FC } from 'react'

import type { StrictOmit } from 'ts-essentials'
import { get, isNil, mapValues } from 'lodash'

import i18nOriginal, { i18n as I18N, Resource } from 'i18next'
import { initReactI18next } from 'react-i18next'

import { Settings as LuxonSettings } from 'luxon'
import numbro from 'numbro'
import { languages } from 'countries-list'
Expand All @@ -15,28 +11,6 @@ import prettyBytesOriginal, { Options as PrettyBytesOptionsOriginal } from 'pret
// @ts-ignore
import numbroLanguages from 'numbro/dist/languages.min'

import CN from 'flag-icon-css/flags/1x1/cn.svg'
import DE from 'flag-icon-css/flags/1x1/de.svg'
import ES from 'flag-icon-css/flags/1x1/es.svg'
import FR from 'flag-icon-css/flags/1x1/fr.svg'
import GB from 'flag-icon-css/flags/1x1/gb.svg'
import GR from 'flag-icon-css/flags/1x1/gr.svg'
import ID from 'flag-icon-css/flags/1x1/id.svg'
import IL from 'flag-icon-css/flags/1x1/il.svg'
import IN from 'flag-icon-css/flags/1x1/in.svg'
import IR from 'flag-icon-css/flags/1x1/ir.svg'
import IT from 'flag-icon-css/flags/1x1/it.svg'
import JP from 'flag-icon-css/flags/1x1/jp.svg'
import KR from 'flag-icon-css/flags/1x1/kr.svg'
import NL from 'flag-icon-css/flags/1x1/nl.svg'
import PK from 'flag-icon-css/flags/1x1/pk.svg'
import PT from 'flag-icon-css/flags/1x1/pt.svg'
import RU from 'flag-icon-css/flags/1x1/ru.svg'
import SA from 'flag-icon-css/flags/1x1/sa.svg'
import TH from 'flag-icon-css/flags/1x1/th.svg'
import TR from 'flag-icon-css/flags/1x1/tr.svg'
import VN from 'flag-icon-css/flags/1x1/vn.svg'

import ar from './resources/ar/common.json'
import de from './resources/de/common.json'
import el from './resources/el/common.json'
Expand Down Expand Up @@ -97,32 +71,32 @@ export interface Locale {
readonly full: string
readonly name: string
readonly native: string
readonly Flag: ElementType
readonly rtl: number | undefined
}

export const locales: Record<LocaleKey, Locale> = {
en: { key: 'en', full: 'en-US', name: languages.en.name, native: languages.en.native, Flag: GB as FC },
ar: { key: 'ar', full: 'ar-SA', name: languages.ar.name, native: languages.ar.native, Flag: SA as FC },
de: { key: 'de', full: 'de-DE', name: languages.de.name, native: languages.de.native, Flag: DE as FC },
el: { key: 'el', full: 'el-GR', name: languages.el.name, native: languages.el.native, Flag: GR as FC },
es: { key: 'es', full: 'es-ES', name: languages.es.name, native: languages.es.native, Flag: ES as FC },
fa: { key: 'fa', full: 'fa-IR', name: languages.fa.name, native: languages.fa.native, Flag: IR as FC },
fr: { key: 'fr', full: 'fr-FR', name: languages.fr.name, native: languages.fr.native, Flag: FR as FC },
he: { key: 'he', full: 'he-IL', name: languages.he.name, native: languages.he.native, Flag: IL as FC },
hi: { key: 'hi', full: 'hi-IN', name: languages.hi.name, native: languages.hi.native, Flag: IN as FC },
id: { key: 'id', full: 'id-ID', name: languages.id.name, native: languages.id.native, Flag: ID as FC },
it: { key: 'it', full: 'it-IT', name: languages.it.name, native: languages.it.native, Flag: IT as FC },
ja: { key: 'ja', full: 'ja-JP', name: languages.ja.name, native: languages.ja.native, Flag: JP as FC },
ko: { key: 'ko', full: 'ko-KR', name: languages.ko.name, native: languages.ko.native, Flag: KR as FC },
nl: { key: 'nl', full: 'nl-NL', name: languages.nl.name, native: languages.nl.native, Flag: NL as FC },
pt: { key: 'pt', full: 'pt-PT', name: languages.pt.name, native: languages.pt.native, Flag: PT as FC },
ru: { key: 'ru', full: 'ru-RU', name: languages.ru.name, native: languages.ru.native, Flag: RU as FC },
ta: { key: 'ta', full: 'ta-IN', name: languages.ta.name, native: languages.ta.native, Flag: IN as FC },
th: { key: 'th', full: 'th-TH', name: languages.th.name, native: languages.th.native, Flag: TH as FC },
tr: { key: 'tr', full: 'tr-TR', name: languages.tr.name, native: languages.tr.native, Flag: TR as FC },
ur: { key: 'ur', full: 'ur-PK', name: languages.ur.name, native: languages.ur.native, Flag: PK as FC },
vi: { key: 'vi', full: 'vi-VN', name: languages.vi.name, native: languages.vi.native, Flag: VN as FC },
zh: { key: 'zh', full: 'zh-CN', name: languages.zh.name, native: languages.zh.native, Flag: CN as FC },
en: { key: 'en', full: 'en-US', name: languages.en.name, native: languages.en.native, rtl: languages.en.rtl },
ar: { key: 'ar', full: 'ar-SA', name: languages.ar.name, native: languages.ar.native, rtl: languages.ar.rtl },
de: { key: 'de', full: 'de-DE', name: languages.de.name, native: languages.de.native, rtl: languages.de.rtl },
el: { key: 'el', full: 'el-GR', name: languages.el.name, native: languages.el.native, rtl: languages.el.rtl },
es: { key: 'es', full: 'es-ES', name: languages.es.name, native: languages.es.native, rtl: languages.es.rtl },
fa: { key: 'fa', full: 'fa-IR', name: languages.fa.name, native: languages.fa.native, rtl: languages.fa.rtl },
fr: { key: 'fr', full: 'fr-FR', name: languages.fr.name, native: languages.fr.native, rtl: languages.fr.rtl },
he: { key: 'he', full: 'he-IL', name: languages.he.name, native: languages.he.native, rtl: languages.he.rtl },
hi: { key: 'hi', full: 'hi-IN', name: languages.hi.name, native: languages.hi.native, rtl: languages.hi.rtl },
id: { key: 'id', full: 'id-ID', name: languages.id.name, native: languages.id.native, rtl: languages.id.rtl },
it: { key: 'it', full: 'it-IT', name: languages.it.name, native: languages.it.native, rtl: languages.it.rtl },
ja: { key: 'ja', full: 'ja-JP', name: languages.ja.name, native: languages.ja.native, rtl: languages.ja.rtl },
ko: { key: 'ko', full: 'ko-KR', name: languages.ko.name, native: languages.ko.native, rtl: languages.ko.rtl },
nl: { key: 'nl', full: 'nl-NL', name: languages.nl.name, native: languages.nl.native, rtl: languages.nl.rtl },
pt: { key: 'pt', full: 'pt-PT', name: languages.pt.name, native: languages.pt.native, rtl: languages.pt.rtl },
ru: { key: 'ru', full: 'ru-RU', name: languages.ru.name, native: languages.ru.native, rtl: languages.ru.rtl },
ta: { key: 'ta', full: 'ta-IN', name: languages.ta.name, native: languages.ta.native, rtl: languages.ta.rtl },
th: { key: 'th', full: 'th-TH', name: languages.th.name, native: languages.th.native, rtl: languages.th.rtl },
tr: { key: 'tr', full: 'tr-TR', name: languages.tr.name, native: languages.tr.native, rtl: languages.tr.rtl },
ur: { key: 'ur', full: 'ur-PK', name: languages.ur.name, native: languages.ur.native, rtl: languages.ur.rtl },
vi: { key: 'vi', full: 'vi-VN', name: languages.vi.name, native: languages.vi.native, rtl: languages.vi.rtl },
zh: { key: 'zh', full: 'zh-CN', name: languages.zh.name, native: languages.zh.native, rtl: languages.zh.rtl },
} as const

export const localeKeys = Object.keys(locales)
Expand Down

This file was deleted.

1 change: 0 additions & 1 deletion packages_rs/nextclade-web/src/styles/global.scss
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@

@import './auspice';

@import './components/LanguageSwitcher';
@import './components/Results';

html, body, #__next {
Expand Down
8 changes: 4 additions & 4 deletions packages_rs/nextclade-web/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -13274,10 +13274,10 @@ [email protected], react-i18next@^11.3.3:
"@babel/runtime" "^7.3.1"
html-parse-stringify2 "2.0.1"

react-icons@4.3.1:
version "4.3.1"
resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-4.3.1.tgz#2fa92aebbbc71f43d2db2ed1aed07361124e91ca"
integrity sha512-cB10MXLTs3gVuXimblAdI71jrJx8njrJZmNMEMC+sQu5B/BIOmlsAjskdqpn81y8UBVEGuHODd7/ci5DvoSzTQ==
react-icons@4.11.0:
version "4.11.0"
resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-4.11.0.tgz#4b0e31c9bfc919608095cc429c4f1846f4d66c65"
integrity sha512-V+4khzYcE5EBk/BvcuYRq6V/osf11ODUM2J8hg2FDSswRrGvqiYUYPRy4OdrWaQOBj4NcpJfmHZLNaD+VH0TyA==

react-icons@^3.9.0:
version "3.11.0"
Expand Down

0 comments on commit cabb824

Please sign in to comment.