diff options
17 files changed, 255 insertions, 315 deletions
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/Debug.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/Debug.tsx index 0b4d24cbfb..9522b422e5 100644 --- a/desktop/packages/mullvad-vpn/src/renderer/components/Debug.tsx +++ b/desktop/packages/mullvad-vpn/src/renderer/components/Debug.tsx @@ -3,8 +3,9 @@ import styled from 'styled-components'; import { useHistory } from '../lib/history'; import { useBoolean } from '../lib/utility-hooks'; +import { Spacings } from '../tokens'; import * as AppButton from './AppButton'; -import { measurements, spacings } from './common-styles'; +import { measurements } from './common-styles'; import { BackAction } from './KeyboardNavigation'; import { Layout, SettingsContainer } from './Layout'; import { @@ -24,7 +25,7 @@ const StyledContent = styled.div({ }); const StyledButtonGroup = styled.div({ - margin: `${spacings.spacing6} ${measurements.horizontalViewMargin}`, + margin: `${Spacings.spacing6} ${measurements.horizontalViewMargin}`, }); export default function Debug() { diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/Layout.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/Layout.tsx index 865fc790f6..8ff848cb12 100644 --- a/desktop/packages/mullvad-vpn/src/renderer/components/Layout.tsx +++ b/desktop/packages/mullvad-vpn/src/renderer/components/Layout.tsx @@ -1,7 +1,8 @@ import styled from 'styled-components'; -import { colors } from '../../config.json'; -import { measurements, spacings } from './common-styles'; +import { Colors, Spacings } from '../tokens'; +import { Flex } from './common/layout/Flex'; +import { measurements } from './common-styles'; import HeaderBar from './HeaderBar'; import { NavigationScrollbars } from './NavigationBar'; @@ -13,7 +14,7 @@ export const Container = styled.div({ display: 'flex', flexDirection: 'column', flex: 1, - backgroundColor: colors.blue, + backgroundColor: Colors.blue, overflow: 'hidden', }); @@ -25,7 +26,7 @@ export const Layout = styled.div({ }); export const SettingsContainer = styled(Container)({ - backgroundColor: colors.darkBlue, + backgroundColor: Colors.darkBlue, }); export const SettingsNavigationScrollbars = styled(NavigationScrollbars)({ @@ -40,32 +41,39 @@ export const SettingsContent = styled.div({ marginBottom: measurements.verticalViewMargin, }); -export const SettingsStack = styled.div({ - display: 'flex', - flexDirection: 'column', - gap: spacings.spacing5, -}); - export const Footer = styled.div({ display: 'flex', flexDirection: 'column', flex: 0, - padding: `${spacings.spacing6} ${measurements.horizontalViewMargin} ${measurements.verticalViewMargin}`, + padding: `${Spacings.spacing6} ${measurements.horizontalViewMargin} ${measurements.verticalViewMargin}`, [`${SettingsContent} &&`]: { paddingBottom: 0, }, }); -export const Spacing = styled.div<{ height: string }>((props) => ({ - height: props.height, -})); +export const SettingsStack = styled(Flex).attrs({ + $flexDirection: 'column', + $gap: Spacings.spacing5, +})({}); -export const ButtonStack = styled.div({ - display: 'flex', - flexDirection: 'column', - gap: spacings.spacing5, - margin: `0 ${spacings.spacing6}`, +export const SettingsGroup = styled(Flex).attrs({ + $flex: 1, + $flexDirection: 'column', +})({}); + +export const ButtonStack = styled(Flex).attrs(() => ({ + $flexDirection: 'column', + $gap: Spacings.spacing5, + $margin: `0 ${Spacings.spacing6}`, +}))({ [`${Footer} &&`]: { - margin: `0 ${spacings.spacing3}`, + margin: `0 ${Spacings.spacing3}`, }, }); + +export const LabelStack = styled(Flex).attrs(() => ({ + $flexGrow: 1, + $flexDirection: 'row', + $alignItems: 'center', + $gap: Spacings.spacing3, +}))({}); diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/Settings.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/Settings.tsx index 4c79f0225c..15f760941f 100644 --- a/desktop/packages/mullvad-vpn/src/renderer/components/Settings.tsx +++ b/desktop/packages/mullvad-vpn/src/renderer/components/Settings.tsx @@ -1,27 +1,30 @@ import { useCallback } from 'react'; -import { colors, strings } from '../../config.json'; +import { strings } from '../../config.json'; import { messages } from '../../shared/gettext'; import { getDownloadUrl } from '../../shared/version'; import { useAppContext } from '../context'; import { useHistory } from '../lib/history'; import { RoutePath } from '../lib/routes'; import { useSelector } from '../redux/store'; +import { Colors } from '../tokens'; import { RedButton } from './AppButton'; import * as Cell from './cell'; +import { TitleBig } from './common/text'; import { BackAction } from './KeyboardNavigation'; import { ButtonStack, Footer, + LabelStack, Layout, SettingsContainer, SettingsContent, + SettingsGroup, SettingsNavigationScrollbars, SettingsStack, } from './Layout'; import { NavigationBar, NavigationContainer, NavigationItems, TitleBarItem } from './NavigationBar'; -import SettingsHeader, { HeaderTitle } from './SettingsHeader'; -import { StyledCellIcon } from './SettingsStyles'; +import SettingsHeader from './SettingsHeader'; export default function Support() { const history = useHistory(); @@ -52,44 +55,44 @@ export default function Support() { <SettingsNavigationScrollbars fillContainer> <SettingsContent> <SettingsHeader> - <HeaderTitle>{messages.pgettext('navigation-bar', 'Settings')}</HeaderTitle> + <TitleBig>{messages.pgettext('navigation-bar', 'Settings')}</TitleBig> </SettingsHeader> <SettingsStack> {showSubSettings ? ( <> - <Cell.Group $noMarginBottom> + <SettingsGroup> <UserInterfaceSettingsButton /> <MultihopButton /> <DaitaButton /> <VpnSettingsButton /> - </Cell.Group> + </SettingsGroup> {showSplitTunneling && ( - <Cell.Group $noMarginBottom> + <SettingsGroup> <SplitTunnelingButton /> - </Cell.Group> + </SettingsGroup> )} </> ) : ( - <Cell.Group $noMarginBottom> + <SettingsGroup> <UserInterfaceSettingsButton /> - </Cell.Group> + </SettingsGroup> )} - <Cell.Group $noMarginBottom> + <SettingsGroup> <ApiAccessMethodsButton /> - </Cell.Group> + </SettingsGroup> - <Cell.Group $noMarginBottom> + <SettingsGroup> <SupportButton /> <AppVersionButton /> - </Cell.Group> + </SettingsGroup> {window.env.development && ( - <Cell.Group $noMarginBottom> + <SettingsGroup> <DebugButton /> - </Cell.Group> + </SettingsGroup> )} </SettingsStack> <Footer> @@ -229,7 +232,7 @@ function AppVersionButton() { const message = !consistentVersion ? inconsistentVersionMessage : updateAvailableMessage; - alertIcon = <StyledCellIcon source="icon-alert" width={18} tintColor={colors.red} />; + alertIcon = <Cell.UntintedIcon source="icon-alert" width={18} tintColor={Colors.red} />; footer = ( <Cell.CellFooter> <Cell.CellFooterText>{message}</Cell.CellFooterText> @@ -246,8 +249,10 @@ function AppVersionButton() { source: 'icon-extLink', 'aria-label': messages.pgettext('accessibility', 'Opens externally'), }}> - {alertIcon} - <Cell.Label>{messages.pgettext('settings-view', 'App version')}</Cell.Label> + <LabelStack> + {alertIcon} + <Cell.Label>{messages.pgettext('settings-view', 'App version')}</Cell.Label> + </LabelStack> <Cell.SubText>{appVersion}</Cell.SubText> </Cell.CellNavigationButton> {footer} diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/SettingsHeader.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/SettingsHeader.tsx index 1d1a1f4e71..8b78264a9a 100644 --- a/desktop/packages/mullvad-vpn/src/renderer/components/SettingsHeader.tsx +++ b/desktop/packages/mullvad-vpn/src/renderer/components/SettingsHeader.tsx @@ -1,12 +1,12 @@ import * as React from 'react'; import styled from 'styled-components'; -import { colors } from '../../config.json'; -import { hugeText, spacings, tinyText } from './common-styles'; +import { Colors, Spacings } from '../tokens'; +import { LabelTiny, TitleBig } from './common/text'; export const Container = styled.div({ flex: 0, - margin: `${spacings.spacing3} ${spacings.spacing5} ${spacings.spacing4}`, + margin: `${Spacings.spacing3} ${Spacings.spacing5} ${Spacings.spacing4}`, }); export const ContentWrapper = styled.div({ @@ -15,13 +15,14 @@ export const ContentWrapper = styled.div({ }, }); -export const HeaderTitle = styled.span(hugeText, { +export const HeaderTitle = styled(TitleBig)({ wordWrap: 'break-word', hyphens: 'auto', }); -export const HeaderSubTitle = styled.span(tinyText, { - color: colors.white60, -}); + +export const HeaderSubTitle = styled(LabelTiny).attrs({ + $color: Colors.white60, +})({}); interface ISettingsHeaderProps { children?: React.ReactNode; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/SettingsImport.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/SettingsImport.tsx index a9777defaf..8da1f41e87 100644 --- a/desktop/packages/mullvad-vpn/src/renderer/components/SettingsImport.tsx +++ b/desktop/packages/mullvad-vpn/src/renderer/components/SettingsImport.tsx @@ -12,8 +12,8 @@ import { RoutePath } from '../lib/routes'; import { useBoolean, useEffectEvent } from '../lib/utility-hooks'; import settingsImportActions from '../redux/settings-import/actions'; import { useSelector } from '../redux/store'; -import { measurements, normalText } from './common-styles'; -import { tinyText } from './common-styles'; +import { Flex } from './common/layout/Flex'; +import { measurements, normalText, tinyText } from './common-styles'; import ImageView from './ImageView'; import { BackAction } from './KeyboardNavigation'; import { Footer, Layout, SettingsContainer } from './Layout'; @@ -25,20 +25,7 @@ import { TitleBarItem, } from './NavigationBar'; import SettingsHeader, { HeaderSubTitle, HeaderTitle } from './SettingsHeader'; -import { SmallButton, SmallButtonGrid } from './SmallButton'; -import { SmallButtonColor } from './SmallButton'; - -const ContentContainer = styled.div({ - display: 'flex', - flexDirection: 'column', - flex: 1, -}); - -const Content = styled.div({ - display: 'flex', - flexDirection: 'column', - flex: 1, -}); +import { SmallButton, SmallButtonColor, SmallButtonGrid } from './SmallButton'; const StyledSmallButtonGrid = styled(SmallButtonGrid)({ margin: `0 ${measurements.horizontalViewMargin}`, @@ -157,8 +144,7 @@ export default function SettingsImport() { /> </NavigationItems> </NavigationBar> - - <ContentContainer> + <Flex $flexDirection="column" $flex={1}> <SettingsHeader> <HeaderTitle> {messages.pgettext('settings-import', 'Server IP override')} @@ -171,7 +157,7 @@ export default function SettingsImport() { </HeaderSubTitle> </SettingsHeader> - <Content> + <Flex $flexDirection="column" $flex={1}> <StyledSmallButtonGrid> <SmallButton onClick={navigateTextImport}> {messages.pgettext('settings-import', 'Import via text')} @@ -182,7 +168,7 @@ export default function SettingsImport() { </StyledSmallButtonGrid> <SettingsImportStatus status={importStatus} /> - </Content> + </Flex> <Footer> <SmallButton @@ -211,7 +197,7 @@ export default function SettingsImport() { 'Clearing the imported overrides changes the server IPs, in the Select location view, back to default.', )} /> - </ContentContainer> + </Flex> </SettingsContainer> </Layout> </BackAction> diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/SettingsStyles.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/SettingsStyles.tsx deleted file mode 100644 index 55915945f4..0000000000 --- a/desktop/packages/mullvad-vpn/src/renderer/components/SettingsStyles.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import styled from 'styled-components'; - -import * as Cell from './cell'; -import { spacings } from './common-styles'; - -export const StyledCellIcon = styled(Cell.UntintedIcon)({ - marginRight: spacings.spacing3, -}); diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/SplitTunnelingSettings.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/SplitTunnelingSettings.tsx index 072f62728c..5dad65219f 100644 --- a/desktop/packages/mullvad-vpn/src/renderer/components/SplitTunnelingSettings.tsx +++ b/desktop/packages/mullvad-vpn/src/renderer/components/SplitTunnelingSettings.tsx @@ -2,7 +2,7 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { useSelector } from 'react-redux'; import { sprintf } from 'sprintf-js'; -import { colors, strings } from '../../config.json'; +import { strings } from '../../config.json'; import { IApplication, ILinuxSplitTunnelingApplication, @@ -14,13 +14,16 @@ import { useHistory } from '../lib/history'; import { formatHtml } from '../lib/html-formatter'; import { useEffectEvent, useStyledRef } from '../lib/utility-hooks'; import { IReduxState } from '../redux/store'; +import { Colors, Spacings } from '../tokens'; import Accordion from './Accordion'; import * as AppButton from './AppButton'; import * as Cell from './cell'; +import { Flex } from './common/layout'; +import { FootnoteMini } from './common/text'; import { CustomScrollbarsRef } from './CustomScrollbars'; import ImageView from './ImageView'; import { BackAction } from './KeyboardNavigation'; -import { Layout, SettingsContainer, Spacing } from './Layout'; +import { Layout, SettingsContainer } from './Layout'; import List from './List'; import { ModalAlert, ModalAlertType } from './Modal'; import { NavigationBar, NavigationContainer, NavigationItems, TitleBarItem } from './NavigationBar'; @@ -37,7 +40,6 @@ import { StyledIcon, StyledIconPlaceholder, StyledListContainer, - StyledMiniTitle, StyledNavigationScrollbars, StyledNoResult, StyledNoResultText, @@ -201,7 +203,7 @@ function LinuxSplitTunnelingSettings(props: IPlatformSplitTunnelingSettingsProps <ModalAlert isOpen={browseError !== undefined} type={ModalAlertType.warning} - iconColor={colors.red} + iconColor={Colors.red} message={sprintf( // TRANSLATORS: Error message showed in a dialog when an application fails to launch. messages.pgettext( @@ -240,7 +242,7 @@ function LinuxApplicationRow(props: ILinuxApplicationRowProps) { const hideWarningDialog = useCallback(() => setShowWarning(false), []); const disabled = props.application.warning === 'launches-elsewhere'; - const warningColor = disabled ? colors.red : colors.yellow; + const warningColor = disabled ? Colors.red : Colors.yellow; const warningMessage = disabled ? sprintf( messages.pgettext( @@ -538,34 +540,33 @@ function MacOsSplitTunnelingAvailability({ const { showFullDiskAccessSettings, daemonPrepareRestart } = useAppContext(); const restartDaemon = useCallback(() => daemonPrepareRestart(true), [daemonPrepareRestart]); + if (!needFullDiskPermissions) return null; + return ( - <> - {needFullDiskPermissions === true ? ( - <> - <HeaderSubTitle> - {messages.pgettext( - 'split-tunneling-view', - 'To use split tunneling please enable “Full disk access” for “Mullvad VPN” in the macOS system settings.', - )} - </HeaderSubTitle> - <Spacing height="24px" /> + <Flex $flexDirection="column" $gap={Spacings.spacing6}> + <HeaderSubTitle> + {messages.pgettext( + 'split-tunneling-view', + 'To use split tunneling please enable “Full disk access” for “Mullvad VPN” in the macOS system settings.', + )} + </HeaderSubTitle> + <Flex $flexDirection="column" $gap={Spacings.spacing3}> + <Flex $flexDirection="column" $gap={Spacings.spacing7}> <WideSmallButton onClick={showFullDiskAccessSettings}> {messages.pgettext('split-tunneling-view', 'Open System Settings')} </WideSmallButton> - <Spacing height="32px" /> - <StyledMiniTitle> + <FootnoteMini $color={Colors.white60}> {messages.pgettext( 'split-tunneling-view', 'Enabled "Full disk access" and still having issues?', )} - </StyledMiniTitle> - <Spacing height="8px" /> - <WideSmallButton onClick={restartDaemon}> - {messages.pgettext('split-tunneling-view', 'Restart Mullvad Service')} - </WideSmallButton> - </> - ) : null} - </> + </FootnoteMini> + </Flex> + <WideSmallButton onClick={restartDaemon}> + {messages.pgettext('split-tunneling-view', 'Restart Mullvad Service')} + </WideSmallButton> + </Flex> + </Flex> ); } @@ -635,8 +636,8 @@ function ApplicationRow(props: IApplicationRowProps) { source="icon-close" width={18} onClick={onDelete} - tintColor={colors.white40} - tintHoverColor={colors.white60} + tintColor={Colors.white40} + tintHoverColor={Colors.white60} /> )} {props.onAdd && ( @@ -644,8 +645,8 @@ function ApplicationRow(props: IApplicationRowProps) { source="icon-add" width={18} onClick={onAdd} - tintColor={colors.white40} - tintHoverColor={colors.white60} + tintColor={Colors.white40} + tintHoverColor={Colors.white60} /> )} {props.onRemove && ( @@ -653,8 +654,8 @@ function ApplicationRow(props: IApplicationRowProps) { source="icon-remove" width={18} onClick={onRemove} - tintColor={colors.white40} - tintHoverColor={colors.white60} + tintColor={Colors.white40} + tintHoverColor={Colors.white60} /> )} </Cell.CellButton> diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/SplitTunnelingSettingsStyles.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/SplitTunnelingSettingsStyles.tsx index a2046e61c9..01eb73ec50 100644 --- a/desktop/packages/mullvad-vpn/src/renderer/components/SplitTunnelingSettingsStyles.tsx +++ b/desktop/packages/mullvad-vpn/src/renderer/components/SplitTunnelingSettingsStyles.tsx @@ -3,7 +3,7 @@ import styled from 'styled-components'; import { colors } from '../../config.json'; import * as AppButton from './AppButton'; import * as Cell from './cell'; -import { measurements, miniText, normalText } from './common-styles'; +import { measurements, normalText } from './common-styles'; import ImageView from './ImageView'; import { NavigationScrollbars } from './NavigationBar'; import SearchBar from './SearchBar'; @@ -118,11 +118,6 @@ export const StyledHeaderTitle = styled(HeaderTitle)({ flex: 1, }); -export const StyledMiniTitle = styled.span({ - ...miniText, - color: colors.white60, -}); - export const StyledSearchBar = styled(SearchBar)({ marginLeft: measurements.horizontalViewMargin, marginRight: measurements.horizontalViewMargin, diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/UserInterfaceSettings.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/UserInterfaceSettings.tsx index 9c3415d90d..38a0f71bbd 100644 --- a/desktop/packages/mullvad-vpn/src/renderer/components/UserInterfaceSettings.tsx +++ b/desktop/packages/mullvad-vpn/src/renderer/components/UserInterfaceSettings.tsx @@ -9,7 +9,14 @@ import { useSelector } from '../redux/store'; import { AriaDescription, AriaInput, AriaInputGroup, AriaLabel } from './AriaGroup'; import * as Cell from './cell'; import { BackAction } from './KeyboardNavigation'; -import { Layout, SettingsContainer } from './Layout'; +import { + LabelStack, + Layout, + SettingsContainer, + SettingsContent, + SettingsGroup, + SettingsStack, +} from './Layout'; import { NavigationBar, NavigationContainer, @@ -19,18 +26,7 @@ import { } from './NavigationBar'; import SettingsHeader, { HeaderTitle } from './SettingsHeader'; -const StyledContent = styled.div({ - display: 'flex', - flexDirection: 'column', - flex: 1, - marginBottom: '2px', -}); - -const StyledCellIcon = styled(Cell.UntintedIcon)({ - marginRight: '8px', -}); - -const StyledAnimateMapSettingsGroup = styled(Cell.Group)({ +const StyledAnimateMapCellGroup = styled(SettingsGroup)({ '@media (prefers-reduced-motion: reduce)': { display: 'none', }, @@ -63,35 +59,37 @@ export default function UserInterfaceSettings() { </HeaderTitle> </SettingsHeader> - <StyledContent> - <Cell.Group> - <NotificationsSetting /> - </Cell.Group> - <Cell.Group> - <MonochromaticTrayIconSetting /> - </Cell.Group> + <SettingsContent> + <SettingsStack> + <SettingsGroup> + <NotificationsSetting /> + </SettingsGroup> + <SettingsGroup> + <MonochromaticTrayIconSetting /> + </SettingsGroup> - <Cell.Group> - <LanguageButton /> - </Cell.Group> + <SettingsGroup> + <LanguageButton /> + </SettingsGroup> - {(window.env.platform === 'win32' || - (window.env.platform === 'darwin' && window.env.development)) && ( - <Cell.Group> - <UnpinnedWindowSetting /> - </Cell.Group> - )} + {(window.env.platform === 'win32' || + (window.env.platform === 'darwin' && window.env.development)) && ( + <SettingsGroup> + <UnpinnedWindowSetting /> + </SettingsGroup> + )} - {unpinnedWindow && ( - <Cell.Group> - <StartMinimizedSetting /> - </Cell.Group> - )} + {unpinnedWindow && ( + <SettingsGroup> + <StartMinimizedSetting /> + </SettingsGroup> + )} - <StyledAnimateMapSettingsGroup> - <AnimateMapSetting /> - </StyledAnimateMapSettingsGroup> - </StyledContent> + <StyledAnimateMapCellGroup> + <AnimateMapSetting /> + </StyledAnimateMapCellGroup> + </SettingsStack> + </SettingsContent> </NavigationScrollbars> </NavigationContainer> </SettingsContainer> @@ -259,13 +257,15 @@ function LanguageButton() { return ( <Cell.CellNavigationButton onClick={navigate}> - <StyledCellIcon width={24} height={24} source="icon-language" /> - <Cell.Label> - { - // TRANSLATORS: Navigation button to the 'Language' settings view - messages.pgettext('user-interface-settings-view', 'Language') - } - </Cell.Label> + <LabelStack> + <Cell.UntintedIcon width={24} height={24} source="icon-language" /> + <Cell.Label> + { + // TRANSLATORS: Navigation button to the 'Language' settings view + messages.pgettext('user-interface-settings-view', 'Language') + } + </Cell.Label> + </LabelStack> <Cell.SubText>{localeDisplayName}</Cell.SubText> </Cell.CellNavigationButton> ); diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/VpnSettings.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/VpnSettings.tsx index c23ecdbf47..c27072cab2 100644 --- a/desktop/packages/mullvad-vpn/src/renderer/components/VpnSettings.tsx +++ b/desktop/packages/mullvad-vpn/src/renderer/components/VpnSettings.tsx @@ -2,7 +2,7 @@ import { useCallback, useMemo } from 'react'; import { sprintf } from 'sprintf-js'; import styled from 'styled-components'; -import { colors, strings } from '../../config.json'; +import { strings } from '../../config.json'; import { IDnsOptions, TunnelProtocol, wrapConstraint } from '../../shared/daemon-rpc-types'; import { messages } from '../../shared/gettext'; import log from '../../shared/logging'; @@ -15,6 +15,7 @@ import { RoutePath } from '../lib/routes'; import { useBoolean } from '../lib/utility-hooks'; import { RelaySettingsRedux } from '../redux/settings/reducers'; import { useSelector } from '../redux/store'; +import { Colors, Spacings } from '../tokens'; import * as AppButton from './AppButton'; import { AriaDescription, AriaDetails, AriaInput, AriaInputGroup, AriaLabel } from './AriaGroup'; import * as Cell from './cell'; @@ -22,7 +23,7 @@ import Selector, { SelectorItem } from './cell/Selector'; import CustomDnsSettings from './CustomDnsSettings'; import InfoButton, { InfoIcon } from './InfoButton'; import { BackAction } from './KeyboardNavigation'; -import { Layout, SettingsContainer } from './Layout'; +import { Layout, SettingsContainer, SettingsContent, SettingsGroup, SettingsStack } from './Layout'; import { ModalAlert, ModalAlertType, ModalMessage } from './Modal'; import { NavigationBar, @@ -33,19 +34,8 @@ import { } from './NavigationBar'; import SettingsHeader, { HeaderTitle } from './SettingsHeader'; -const StyledContent = styled.div({ - display: 'flex', - flexDirection: 'column', - flex: 1, - marginBottom: '2px', -}); - const StyledInfoIcon = styled(InfoIcon)({ - marginRight: '16px', -}); - -const StyledSelectorContainer = styled.div({ - flex: 0, + marginRight: Spacings.spacing5, }); const StyledTitleLabel = styled(Cell.SectionTitle)({ @@ -53,16 +43,16 @@ const StyledTitleLabel = styled(Cell.SectionTitle)({ }); const StyledSectionItem = styled(Cell.Container)({ - backgroundColor: colors.blue40, + backgroundColor: Colors.blue40, }); const LanIpRanges = styled.ul({ listStyle: 'disc outside', - marginLeft: '20px', + marginLeft: Spacings.spacing6, }); const IndentedValueLabel = styled(Cell.ValueLabel)({ - marginLeft: '16px', + marginLeft: Spacings.spacing5, }); export default function VpnSettings() { @@ -89,46 +79,48 @@ export default function VpnSettings() { <HeaderTitle>{messages.pgettext('vpn-settings-view', 'VPN settings')}</HeaderTitle> </SettingsHeader> - <StyledContent> - <Cell.Group> - <AutoStart /> - <AutoConnect /> - </Cell.Group> + <SettingsContent> + <SettingsStack> + <SettingsGroup> + <AutoStart /> + <AutoConnect /> + </SettingsGroup> - <Cell.Group> - <AllowLan /> - </Cell.Group> + <SettingsGroup> + <AllowLan /> + </SettingsGroup> - <Cell.Group> - <DnsBlockers /> - </Cell.Group> + <SettingsGroup> + <DnsBlockers /> + </SettingsGroup> - <Cell.Group> - <EnableIpv6 /> - </Cell.Group> + <SettingsGroup> + <EnableIpv6 /> + </SettingsGroup> - <Cell.Group> - <KillSwitchInfo /> - <LockdownMode /> - </Cell.Group> + <SettingsGroup> + <KillSwitchInfo /> + <LockdownMode /> + </SettingsGroup> - <Cell.Group> - <TunnelProtocolSetting /> - </Cell.Group> + <SettingsGroup> + <TunnelProtocolSetting /> + </SettingsGroup> - <Cell.Group> - <WireguardSettingsButton /> - <OpenVpnSettingsButton /> - </Cell.Group> + <SettingsGroup> + <WireguardSettingsButton /> + <OpenVpnSettingsButton /> + </SettingsGroup> - <Cell.Group> - <CustomDnsSettings /> - </Cell.Group> + <SettingsGroup> + <CustomDnsSettings /> + </SettingsGroup> - <Cell.Group> - <IpOverrideButton /> - </Cell.Group> - </StyledContent> + <SettingsGroup> + <IpOverrideButton /> + </SettingsGroup> + </SettingsStack> + </SettingsContent> </NavigationScrollbars> </NavigationContainer> </SettingsContainer> @@ -736,15 +728,13 @@ function TunnelProtocolSetting() { return ( <AriaInputGroup> - <StyledSelectorContainer> - <Selector - title={messages.pgettext('vpn-settings-view', 'Tunnel protocol')} - items={tunnelProtocolItems} - value={tunnelProtocol ?? null} - onSelect={setTunnelProtocol} - automaticValue={null} - /> - </StyledSelectorContainer> + <Selector + title={messages.pgettext('vpn-settings-view', 'Tunnel protocol')} + items={tunnelProtocolItems} + value={tunnelProtocol ?? null} + onSelect={setTunnelProtocol} + automaticValue={null} + /> {openVpnDisabled ? ( <Cell.CellFooter> <AriaDescription> diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/WireguardSettings.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/WireguardSettings.tsx index b199bd5ee5..b9ee3dedb1 100644 --- a/desktop/packages/mullvad-vpn/src/renderer/components/WireguardSettings.tsx +++ b/desktop/packages/mullvad-vpn/src/renderer/components/WireguardSettings.tsx @@ -21,7 +21,7 @@ import { AriaDescription, AriaInput, AriaInputGroup, AriaLabel } from './AriaGro import * as Cell from './cell'; import Selector, { SelectorItem, SelectorWithCustomItem } from './cell/Selector'; import { BackAction } from './KeyboardNavigation'; -import { Layout, SettingsContainer } from './Layout'; +import { Layout, SettingsContainer, SettingsContent, SettingsGroup, SettingsStack } from './Layout'; import { ModalMessage } from './Modal'; import { NavigationBar, @@ -40,13 +40,6 @@ function mapPortToSelectorItem(value: number): SelectorItem<number> { return { label: value.toString(), value }; } -const StyledContent = styled.div({ - display: 'flex', - flexDirection: 'column', - flex: 1, - marginBottom: '2px', -}); - const StyledSelectorContainer = styled.div({ flex: 0, }); @@ -84,28 +77,29 @@ export default function WireguardSettings() { )} </HeaderTitle> </SettingsHeader> + <SettingsContent> + <SettingsStack> + <SettingsGroup> + <PortSelector /> + </SettingsGroup> - <StyledContent> - <Cell.Group> - <PortSelector /> - </Cell.Group> - - <Cell.Group> - <ObfuscationSettings /> - </Cell.Group> + <SettingsGroup> + <ObfuscationSettings /> + </SettingsGroup> - <Cell.Group> - <QuantumResistantSetting /> - </Cell.Group> + <SettingsGroup> + <QuantumResistantSetting /> + </SettingsGroup> - <Cell.Group> - <IpVersionSetting /> - </Cell.Group> + <SettingsGroup> + <IpVersionSetting /> + </SettingsGroup> - <Cell.Group> - <MtuSetting /> - </Cell.Group> - </StyledContent> + <SettingsGroup> + <MtuSetting /> + </SettingsGroup> + </SettingsStack> + </SettingsContent> </NavigationScrollbars> </NavigationContainer> </SettingsContainer> diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/cell/CellButton.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/cell/CellButton.tsx index 83f73be146..f637008a68 100644 --- a/desktop/packages/mullvad-vpn/src/renderer/components/cell/CellButton.tsx +++ b/desktop/packages/mullvad-vpn/src/renderer/components/cell/CellButton.tsx @@ -1,8 +1,8 @@ import React, { useContext } from 'react'; import styled from 'styled-components'; -import { colors } from '../../../config.json'; -import { spacings } from '../common-styles'; +import { Colors, Spacings } from '../../tokens'; +import { Center } from '../common/layout'; import { IImageViewProps } from '../ImageView'; import { CellDisabledContext } from './Container'; import { Icon } from './Label'; @@ -16,15 +16,15 @@ interface IStyledCellButtonProps extends React.HTMLAttributes<HTMLButtonElement> const StyledCellButton = styled(Row)<IStyledCellButtonProps>((props) => { const backgroundColor = props.$selected - ? colors.green + ? Colors.green : props.$containedInSection - ? colors.blue40 - : colors.blue; - const backgroundColorHover = props.$selected ? colors.green : colors.blue80; + ? Colors.blue40 + : Colors.blue; + const backgroundColorHover = props.$selected ? Colors.green : Colors.blue80; return { - paddingRight: spacings.spacing5, - paddingLeft: spacings.spacing5, + paddingRight: Spacings.spacing5, + paddingLeft: Spacings.spacing5, flex: 1, alignContent: 'center', cursor: 'default', @@ -58,13 +58,6 @@ export const CellButton = styled( }), )({}); -const StyledNavigationButtonIcon = styled('div')({ - display: 'grid', - placeItems: 'center', - width: '24px', - height: '24px', -}); - interface ICellNavigationButtonProps extends ICellButtonProps { isAriaDescription?: boolean; icon?: IImageViewProps; @@ -80,9 +73,9 @@ export function CellNavigationButton({ return ( <CellButton {...props}> {children} - <StyledNavigationButtonIcon> + <Center $height="24px" $width="24px"> <Icon {...icon} /> - </StyledNavigationButtonIcon> + </Center> </CellButton> ); } diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/cell/Container.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/cell/Container.tsx index e35babf790..f8db1c45e6 100644 --- a/desktop/packages/mullvad-vpn/src/renderer/components/cell/Container.tsx +++ b/desktop/packages/mullvad-vpn/src/renderer/components/cell/Container.tsx @@ -1,10 +1,11 @@ import React from 'react'; import styled from 'styled-components'; +import { Spacings } from '../../tokens'; import { Row } from './Row'; const StyledContainer = styled(Row)({ - paddingRight: '16px', + padding: `0 ${Spacings.spacing5}`, }); export const CellDisabledContext = React.createContext<boolean>(false); diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/cell/Footer.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/cell/Footer.tsx index 8d5391c002..2454225638 100644 --- a/desktop/packages/mullvad-vpn/src/renderer/components/cell/Footer.tsx +++ b/desktop/packages/mullvad-vpn/src/renderer/components/cell/Footer.tsx @@ -1,16 +1,12 @@ import styled from 'styled-components'; -import { colors } from '../../../config.json'; -import { spacings, tinyText } from '../common-styles'; +import { Colors, Spacings } from '../../tokens'; +import { LabelTiny } from '../common/text'; export const CellFooter = styled.div({ - margin: `${spacings.spacing1} ${spacings.spacing6} 0px`, + margin: `${Spacings.spacing1} ${Spacings.spacing6} 0px`, }); -export const CellFooterText = styled.span(tinyText, { - color: colors.white60, -}); - -export const CellFooterBoldText = styled(CellFooterText)({ - fontWeight: 900, -}); +export const CellFooterText = styled(LabelTiny).attrs({ + $color: Colors.white60, +})({}); diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/cell/Label.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/cell/Label.tsx index 556481e50e..3123a31dc4 100644 --- a/desktop/packages/mullvad-vpn/src/renderer/components/cell/Label.tsx +++ b/desktop/packages/mullvad-vpn/src/renderer/components/cell/Label.tsx @@ -1,8 +1,8 @@ import React, { useContext } from 'react'; import styled from 'styled-components'; -import { colors } from '../../../config.json'; -import { buttonText, normalText, spacings, tinyText } from '../common-styles'; +import { Colors, Spacings } from '../../tokens'; +import { buttonText, normalText, tinyText } from '../common-styles'; import ImageView, { IImageViewProps } from '../ImageView'; import { CellButton } from './CellButton'; import { CellDisabledContext } from './Container'; @@ -11,7 +11,7 @@ const StyledLabel = styled.div<{ disabled: boolean }>(buttonText, (props) => ({ display: 'flex', margin: '10px 0', flex: 1, - color: props.disabled ? colors.white40 : colors.white, + color: props.disabled ? Colors.white40 : Colors.white, textAlign: 'left', [`${LabelContainer} &&`]: { @@ -27,10 +27,10 @@ const StyledLabel = styled.div<{ disabled: boolean }>(buttonText, (props) => ({ })); const StyledSubText = styled.span<{ disabled: boolean }>(tinyText, (props) => ({ - color: props.disabled ? colors.white20 : colors.white60, + color: props.disabled ? Colors.white20 : Colors.white60, flex: -1, textAlign: 'right', - margin: `0 ${spacings.spacing3}`, + margin: `0 ${Spacings.spacing3}`, })); const StyledIconContainer = styled.div<{ disabled: boolean }>((props) => ({ @@ -38,8 +38,8 @@ const StyledIconContainer = styled.div<{ disabled: boolean }>((props) => ({ })); const StyledTintedIcon = styled(ImageView).attrs((props: IImageViewProps) => ({ - tintColor: props.tintColor ?? colors.white, - tintHoverColor: props.tintHoverColor ?? props.tintColor ?? colors.white60, + tintColor: props.tintColor ?? Colors.white, + tintHoverColor: props.tintHoverColor ?? props.tintColor ?? Colors.white60, }))((props: IImageViewProps) => ({ '&&:hover': { backgroundColor: props.tintHoverColor, @@ -52,7 +52,7 @@ const StyledTintedIcon = styled(ImageView).attrs((props: IImageViewProps) => ({ const StyledSubLabel = styled.div<{ disabled: boolean }>(tinyText, { display: 'flex', alignItems: 'center', - color: colors.white60, + color: Colors.white60, marginBottom: '5px', lineHeight: '14px', height: '14px', diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/cell/Section.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/cell/Section.tsx index b7465ecb93..0e390eb901 100644 --- a/desktop/packages/mullvad-vpn/src/renderer/components/cell/Section.tsx +++ b/desktop/packages/mullvad-vpn/src/renderer/components/cell/Section.tsx @@ -1,10 +1,10 @@ import React, { useEffect } from 'react'; import styled from 'styled-components'; -import { colors } from '../../../config.json'; import { useAppContext } from '../../context'; import { useHistory } from '../../lib/history'; import { useBoolean, useEffectEvent } from '../../lib/utility-hooks'; +import { Colors, Spacings } from '../../tokens'; import Accordion from '../Accordion'; import ChevronButton from '../ChevronButton'; import { buttonText, openSans, sourceSansPro } from '../common-styles'; @@ -22,8 +22,8 @@ interface SectionTitleProps { } export const SectionTitle = styled(Row)<SectionTitleProps>(buttonText, (props) => ({ - paddingRight: '16px', - color: props.disabled ? colors.white20 : colors.white, + paddingRight: Spacings.spacing5, + color: props.disabled ? Colors.white20 : Colors.white, fontWeight: props.$thin ? 400 : 600, fontSize: props.$thin ? '15px' : '18px', ...(props.$thin ? openSans : sourceSansPro), @@ -49,7 +49,7 @@ export function Section(props: SectionProps) { const StyledChevronButton = styled(ChevronButton)({ padding: 0, - marginRight: '16px', + marginRight: Spacings.spacing5, }); const StyledTitleContainer = styled(Container)({ diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/common-styles.ts b/desktop/packages/mullvad-vpn/src/renderer/components/common-styles.ts index 18c5237843..fc08d8411d 100644 --- a/desktop/packages/mullvad-vpn/src/renderer/components/common-styles.ts +++ b/desktop/packages/mullvad-vpn/src/renderer/components/common-styles.ts @@ -1,6 +1,6 @@ import React from 'react'; -import { colors } from '../../config.json'; +import { Colors, Spacings } from '../tokens'; export const openSans: React.CSSProperties = { fontFamily: 'Open Sans', @@ -10,13 +10,6 @@ export const sourceSansPro: React.CSSProperties = { fontFamily: '"Source Sans Pro", "Noto Sans Myanmar", "Noto Sans Thai", sans-serif', }; -export const miniText = { - ...openSans, - fontSize: '10px', - fontWeight: 600, - lineHeight: '15px', -}; - export const tinyText = { ...openSans, fontSize: '12px', @@ -29,7 +22,7 @@ export const smallText = { fontSize: '14px', fontWeight: 600, lineHeight: '20px', - color: colors.white80, + color: Colors.white80, }; export const smallNormalText = { @@ -52,7 +45,7 @@ export const largeText = { export const buttonText = { ...largeText, - color: colors.white, + color: Colors.white, }; export const bigText = { @@ -67,29 +60,13 @@ export const hugeText = { fontSize: '32px', fontWeight: 700, lineHeight: '34px', - color: colors.white, -}; - -export const spacings = { - spacing1: '4px', - spacing2: '6px', - spacing3: '8px', - spacing4: '12px', - spacing5: '16px', - spacing6: '24px', - spacing7: '32px', - spacing8: '40px', - spacing9: '48px', - spacing10: '56px', - spacing11: '64px', - spacing12: '72px', - spacing13: '80px', + color: Colors.white, }; export const measurements = { - rowMinHeight: spacings.spacing9, - horizontalViewMargin: spacings.spacing5, - verticalViewMargin: spacings.spacing6, - rowVerticalMargin: spacings.spacing6, - buttonVerticalMargin: spacings.spacing5, + rowMinHeight: Spacings.spacing9, + horizontalViewMargin: Spacings.spacing5, + verticalViewMargin: Spacings.spacing6, + rowVerticalMargin: Spacings.spacing6, + buttonVerticalMargin: Spacings.spacing5, }; |
