chore: moving language selection to own settings panel (#7169)
* chore: moving language selection to own settings panel * auto switch when close * updating e2e * clickable style * moving behind feature flag * fixing tests * this looks nicer * nowrap for overflow
This commit is contained in:
parent
bf1f613a4f
commit
ea5af12b1d
@ -1,3 +1,5 @@
|
|||||||
|
import { FeatureFlag } from 'featureFlags'
|
||||||
|
|
||||||
import { getTestSelector } from '../utils'
|
import { getTestSelector } from '../utils'
|
||||||
|
|
||||||
describe('Wallet Dropdown', () => {
|
describe('Wallet Dropdown', () => {
|
||||||
@ -21,10 +23,14 @@ describe('Wallet Dropdown', () => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function itChangesLocale() {
|
function itChangesLocale({ featureFlag = false }: { featureFlag?: boolean } = {}) {
|
||||||
it('should change locale', () => {
|
it('should change locale', () => {
|
||||||
cy.contains('Uniswap available in: English').should('not.exist')
|
cy.contains('Uniswap available in: English').should('not.exist')
|
||||||
|
|
||||||
|
if (featureFlag) {
|
||||||
|
cy.get(getTestSelector('language-settings-button')).click()
|
||||||
|
}
|
||||||
|
|
||||||
cy.get(getTestSelector('wallet-language-item')).contains('Afrikaans').click({ force: true })
|
cy.get(getTestSelector('wallet-language-item')).contains('Afrikaans').click({ force: true })
|
||||||
cy.location('search').should('match', /\?lng=af-ZA$/)
|
cy.location('search').should('match', /\?lng=af-ZA$/)
|
||||||
cy.contains('Uniswap available in: English')
|
cy.contains('Uniswap available in: English')
|
||||||
@ -45,6 +51,15 @@ describe('Wallet Dropdown', () => {
|
|||||||
itChangesLocale()
|
itChangesLocale()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('should change locale with feature flag', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.visit('/', { featureFlags: [FeatureFlag.currencyConversion] })
|
||||||
|
cy.get(getTestSelector('web3-status-connected')).click()
|
||||||
|
cy.get(getTestSelector('wallet-settings')).click()
|
||||||
|
})
|
||||||
|
itChangesLocale({ featureFlag: true })
|
||||||
|
})
|
||||||
|
|
||||||
describe('testnet toggle', () => {
|
describe('testnet toggle', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.visit('/swap')
|
cy.visit('/swap')
|
||||||
|
@ -5,6 +5,7 @@ import { useCallback, useEffect, useState } from 'react'
|
|||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
|
|
||||||
import AuthenticatedHeader from './AuthenticatedHeader'
|
import AuthenticatedHeader from './AuthenticatedHeader'
|
||||||
|
import LanguageMenu from './LanguageMenu'
|
||||||
import SettingsMenu from './SettingsMenu'
|
import SettingsMenu from './SettingsMenu'
|
||||||
|
|
||||||
const DefaultMenuWrap = styled(Column)`
|
const DefaultMenuWrap = styled(Column)`
|
||||||
@ -15,6 +16,7 @@ const DefaultMenuWrap = styled(Column)`
|
|||||||
enum MenuState {
|
enum MenuState {
|
||||||
DEFAULT,
|
DEFAULT,
|
||||||
SETTINGS,
|
SETTINGS,
|
||||||
|
LANGUAGE_SETTINGS,
|
||||||
}
|
}
|
||||||
|
|
||||||
function DefaultMenu({ drawerOpen }: { drawerOpen: boolean }) {
|
function DefaultMenu({ drawerOpen }: { drawerOpen: boolean }) {
|
||||||
@ -24,9 +26,10 @@ function DefaultMenu({ drawerOpen }: { drawerOpen: boolean }) {
|
|||||||
const [menu, setMenu] = useState<MenuState>(MenuState.DEFAULT)
|
const [menu, setMenu] = useState<MenuState>(MenuState.DEFAULT)
|
||||||
const openSettings = useCallback(() => setMenu(MenuState.SETTINGS), [])
|
const openSettings = useCallback(() => setMenu(MenuState.SETTINGS), [])
|
||||||
const closeSettings = useCallback(() => setMenu(MenuState.DEFAULT), [])
|
const closeSettings = useCallback(() => setMenu(MenuState.DEFAULT), [])
|
||||||
|
const openLanguageSettings = useCallback(() => setMenu(MenuState.LANGUAGE_SETTINGS), [])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!drawerOpen && menu === MenuState.SETTINGS) {
|
if (!drawerOpen && menu !== MenuState.DEFAULT) {
|
||||||
// wait for the drawer to close before resetting the menu
|
// wait for the drawer to close before resetting the menu
|
||||||
const timer = setTimeout(() => {
|
const timer = setTimeout(() => {
|
||||||
closeSettings()
|
closeSettings()
|
||||||
@ -44,7 +47,10 @@ function DefaultMenu({ drawerOpen }: { drawerOpen: boolean }) {
|
|||||||
) : (
|
) : (
|
||||||
<WalletModal openSettings={openSettings} />
|
<WalletModal openSettings={openSettings} />
|
||||||
))}
|
))}
|
||||||
{menu === MenuState.SETTINGS && <SettingsMenu onClose={closeSettings} />}
|
{menu === MenuState.SETTINGS && (
|
||||||
|
<SettingsMenu onClose={closeSettings} openLanguageSettings={openLanguageSettings} />
|
||||||
|
)}
|
||||||
|
{menu === MenuState.LANGUAGE_SETTINGS && <LanguageMenu onClose={openSettings} />}
|
||||||
</DefaultMenuWrap>
|
</DefaultMenuWrap>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
56
src/components/AccountDrawer/LanguageMenu.tsx
Normal file
56
src/components/AccountDrawer/LanguageMenu.tsx
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
import { Trans } from '@lingui/macro'
|
||||||
|
import { LOCALE_LABEL, SUPPORTED_LOCALES, SupportedLocale } from 'constants/locales'
|
||||||
|
import { useActiveLocale } from 'hooks/useActiveLocale'
|
||||||
|
import { useLocationLinkProps } from 'hooks/useLocationLinkProps'
|
||||||
|
import { Check } from 'react-feather'
|
||||||
|
import { Link } from 'react-router-dom'
|
||||||
|
import styled, { useTheme } from 'styled-components'
|
||||||
|
import { ClickableStyle, ThemedText } from 'theme'
|
||||||
|
|
||||||
|
import { SlideOutMenu } from './SlideOutMenu'
|
||||||
|
|
||||||
|
const InternalLinkMenuItem = styled(Link)`
|
||||||
|
${ClickableStyle}
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
padding: 12px 0;
|
||||||
|
justify-content: space-between;
|
||||||
|
text-decoration: none;
|
||||||
|
color: ${({ theme }) => theme.textPrimary};
|
||||||
|
`
|
||||||
|
|
||||||
|
function LanguageMenuItem({ locale, isActive }: { locale: SupportedLocale; isActive: boolean }) {
|
||||||
|
const { to, onClick } = useLocationLinkProps(locale)
|
||||||
|
const theme = useTheme()
|
||||||
|
|
||||||
|
if (!to) return null
|
||||||
|
|
||||||
|
return (
|
||||||
|
<InternalLinkMenuItem onClick={onClick} to={to}>
|
||||||
|
<ThemedText.BodySmall data-testid="wallet-language-item">{LOCALE_LABEL[locale]}</ThemedText.BodySmall>
|
||||||
|
{isActive && <Check color={theme.accentActive} opacity={1} size={20} />}
|
||||||
|
</InternalLinkMenuItem>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function LanguageMenuItems() {
|
||||||
|
const activeLocale = useActiveLocale()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{SUPPORTED_LOCALES.map((locale) => (
|
||||||
|
<LanguageMenuItem locale={locale} isActive={activeLocale === locale} key={locale} />
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function LanguageMenu({ onClose }: { onClose: () => void }) {
|
||||||
|
return (
|
||||||
|
<SlideOutMenu title={<Trans>Language</Trans>} onClose={onClose}>
|
||||||
|
<LanguageMenuItems />
|
||||||
|
</SlideOutMenu>
|
||||||
|
)
|
||||||
|
}
|
@ -1,46 +1,27 @@
|
|||||||
import { Trans } from '@lingui/macro'
|
import { Trans } from '@lingui/macro'
|
||||||
import { LOCALE_LABEL, SUPPORTED_LOCALES, SupportedLocale } from 'constants/locales'
|
import Column from 'components/Column'
|
||||||
|
import Row from 'components/Row'
|
||||||
|
import { LOCALE_LABEL } from 'constants/locales'
|
||||||
|
import { useCurrencyConversionFlagEnabled } from 'featureFlags/flags/currencyConversion'
|
||||||
import { useActiveLocale } from 'hooks/useActiveLocale'
|
import { useActiveLocale } from 'hooks/useActiveLocale'
|
||||||
import { useLocationLinkProps } from 'hooks/useLocationLinkProps'
|
import { ReactNode } from 'react'
|
||||||
import { Check } from 'react-feather'
|
import { ChevronRight } from 'react-feather'
|
||||||
import { Link } from 'react-router-dom'
|
import styled from 'styled-components'
|
||||||
import styled, { useTheme } from 'styled-components'
|
|
||||||
import { ClickableStyle, ThemedText } from 'theme'
|
import { ClickableStyle, ThemedText } from 'theme'
|
||||||
import ThemeToggle from 'theme/components/ThemeToggle'
|
import ThemeToggle from 'theme/components/ThemeToggle'
|
||||||
|
|
||||||
import { AnalyticsToggle } from './AnalyticsToggle'
|
import { AnalyticsToggle } from './AnalyticsToggle'
|
||||||
import { GitVersionRow } from './GitVersionRow'
|
import { GitVersionRow } from './GitVersionRow'
|
||||||
|
import { LanguageMenuItems } from './LanguageMenu'
|
||||||
import { SlideOutMenu } from './SlideOutMenu'
|
import { SlideOutMenu } from './SlideOutMenu'
|
||||||
import { SmallBalanceToggle } from './SmallBalanceToggle'
|
import { SmallBalanceToggle } from './SmallBalanceToggle'
|
||||||
import { TestnetsToggle } from './TestnetsToggle'
|
import { TestnetsToggle } from './TestnetsToggle'
|
||||||
|
|
||||||
const InternalLinkMenuItem = styled(Link)`
|
const Container = styled(Column)`
|
||||||
${ClickableStyle}
|
height: 100%;
|
||||||
flex: 1;
|
|
||||||
color: ${({ theme }) => theme.textTertiary};
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
padding: 12px 0;
|
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
text-decoration: none;
|
|
||||||
color: ${({ theme }) => theme.textPrimary};
|
|
||||||
`
|
`
|
||||||
|
|
||||||
function LanguageMenuItem({ locale, isActive }: { locale: SupportedLocale; isActive: boolean }) {
|
|
||||||
const { to, onClick } = useLocationLinkProps(locale)
|
|
||||||
const theme = useTheme()
|
|
||||||
|
|
||||||
if (!to) return null
|
|
||||||
|
|
||||||
return (
|
|
||||||
<InternalLinkMenuItem onClick={onClick} to={to}>
|
|
||||||
<ThemedText.BodySmall data-testid="wallet-language-item">{LOCALE_LABEL[locale]}</ThemedText.BodySmall>
|
|
||||||
{isActive && <Check color={theme.accentActive} opacity={1} size={20} />}
|
|
||||||
</InternalLinkMenuItem>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
const SectionTitle = styled(ThemedText.SubHeader)`
|
const SectionTitle = styled(ThemedText.SubHeader)`
|
||||||
color: ${({ theme }) => theme.textSecondary};
|
color: ${({ theme }) => theme.textSecondary};
|
||||||
padding-bottom: 24px;
|
padding-bottom: 24px;
|
||||||
@ -53,12 +34,53 @@ const ToggleWrapper = styled.div`
|
|||||||
margin-bottom: 24px;
|
margin-bottom: 24px;
|
||||||
`
|
`
|
||||||
|
|
||||||
export default function SettingsMenu({ onClose }: { onClose: () => void }) {
|
const SettingsButtonWrapper = styled(Row)`
|
||||||
|
${ClickableStyle}
|
||||||
|
`
|
||||||
|
|
||||||
|
const StyledChevron = styled(ChevronRight)`
|
||||||
|
color: ${({ theme }) => theme.textSecondary};
|
||||||
|
`
|
||||||
|
|
||||||
|
const LanguageLabel = styled(Row)`
|
||||||
|
white-space: nowrap;
|
||||||
|
`
|
||||||
|
|
||||||
|
const SettingsButton = ({
|
||||||
|
title,
|
||||||
|
currentState,
|
||||||
|
onClick,
|
||||||
|
testId,
|
||||||
|
}: {
|
||||||
|
title: ReactNode
|
||||||
|
currentState: ReactNode
|
||||||
|
onClick: () => void
|
||||||
|
testId?: string
|
||||||
|
}) => (
|
||||||
|
<SettingsButtonWrapper data-testid={testId} align="center" justify="space-between" onClick={onClick}>
|
||||||
|
<ThemedText.SubHeaderSmall color="textPrimary">{title}</ThemedText.SubHeaderSmall>
|
||||||
|
<LanguageLabel gap="xs" align="center" width="min-content">
|
||||||
|
<ThemedText.LabelMedium color="textPrimary">{currentState}</ThemedText.LabelMedium>
|
||||||
|
<StyledChevron size={20} />
|
||||||
|
</LanguageLabel>
|
||||||
|
</SettingsButtonWrapper>
|
||||||
|
)
|
||||||
|
|
||||||
|
export default function SettingsMenu({
|
||||||
|
onClose,
|
||||||
|
openLanguageSettings,
|
||||||
|
}: {
|
||||||
|
onClose: () => void
|
||||||
|
openLanguageSettings: () => void
|
||||||
|
}) {
|
||||||
|
const currencyConversionEnabled = useCurrencyConversionFlagEnabled()
|
||||||
const activeLocale = useActiveLocale()
|
const activeLocale = useActiveLocale()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SlideOutMenu title={<Trans>Settings</Trans>} onClose={onClose}>
|
<SlideOutMenu title={<Trans>Settings</Trans>} onClose={onClose}>
|
||||||
<SectionTitle>
|
<Container>
|
||||||
|
<div>
|
||||||
|
<SectionTitle data-testid="wallet-header">
|
||||||
<Trans>Preferences</Trans>
|
<Trans>Preferences</Trans>
|
||||||
</SectionTitle>
|
</SectionTitle>
|
||||||
<ToggleWrapper>
|
<ToggleWrapper>
|
||||||
@ -67,14 +89,26 @@ export default function SettingsMenu({ onClose }: { onClose: () => void }) {
|
|||||||
<AnalyticsToggle />
|
<AnalyticsToggle />
|
||||||
<TestnetsToggle />
|
<TestnetsToggle />
|
||||||
</ToggleWrapper>
|
</ToggleWrapper>
|
||||||
|
{!currencyConversionEnabled && (
|
||||||
|
<>
|
||||||
<SectionTitle data-testid="wallet-header">
|
<SectionTitle data-testid="wallet-header">
|
||||||
<Trans>Language</Trans>
|
<Trans>Language</Trans>
|
||||||
</SectionTitle>
|
</SectionTitle>
|
||||||
{SUPPORTED_LOCALES.map((locale) => (
|
<LanguageMenuItems />
|
||||||
<LanguageMenuItem locale={locale} isActive={activeLocale === locale} key={locale} />
|
</>
|
||||||
))}
|
)}
|
||||||
|
|
||||||
|
{currencyConversionEnabled && (
|
||||||
|
<SettingsButton
|
||||||
|
title={<Trans>Language</Trans>}
|
||||||
|
currentState={LOCALE_LABEL[activeLocale]}
|
||||||
|
onClick={openLanguageSettings}
|
||||||
|
testId="language-settings-button"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
<GitVersionRow />
|
<GitVersionRow />
|
||||||
|
</Container>
|
||||||
</SlideOutMenu>
|
</SlideOutMenu>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
|
import Column from 'components/Column'
|
||||||
import { ScrollBarStyles } from 'components/Common'
|
import { ScrollBarStyles } from 'components/Common'
|
||||||
import { ArrowLeft } from 'react-feather'
|
import { ArrowLeft } from 'react-feather'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
import { ClickableStyle, ThemedText } from 'theme'
|
import { ClickableStyle, ThemedText } from 'theme'
|
||||||
|
|
||||||
const Menu = styled.div`
|
const Menu = styled(Column)`
|
||||||
width: 100%;
|
width: 100%;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
margin-top: 4px;
|
margin-top: 4px;
|
||||||
|
@ -3,3 +3,7 @@ import { BaseVariant, FeatureFlag, useBaseFlag } from '../index'
|
|||||||
export function useCurrencyConversionFlag(): BaseVariant {
|
export function useCurrencyConversionFlag(): BaseVariant {
|
||||||
return useBaseFlag(FeatureFlag.currencyConversion)
|
return useBaseFlag(FeatureFlag.currencyConversion)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function useCurrencyConversionFlagEnabled(): boolean {
|
||||||
|
return useCurrencyConversionFlag() === BaseVariant.Enabled
|
||||||
|
}
|
||||||
|
@ -43,6 +43,9 @@ export const ThemedText = {
|
|||||||
Hero(props: TextProps) {
|
Hero(props: TextProps) {
|
||||||
return <TextWrapper fontWeight={500} fontSize={48} color="textPrimary" {...props} />
|
return <TextWrapper fontWeight={500} fontSize={48} color="textPrimary" {...props} />
|
||||||
},
|
},
|
||||||
|
LabelMedium(props: TextProps) {
|
||||||
|
return <TextWrapper fontWeight={500} fontSize={16} color="textPrimary" lineHeight="20px" {...props} />
|
||||||
|
},
|
||||||
LabelSmall(props: TextProps) {
|
LabelSmall(props: TextProps) {
|
||||||
return <TextWrapper fontWeight={600} fontSize={14} color="textSecondary" {...props} />
|
return <TextWrapper fontWeight={600} fontSize={14} color="textSecondary" {...props} />
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user