diff options
| author | Oskar Nyberg <oskar@mullvad.net> | 2022-10-03 17:21:09 +0200 |
|---|---|---|
| committer | Oskar Nyberg <oskar@mullvad.net> | 2022-10-03 17:21:09 +0200 |
| commit | 31cd7cc00e587896d15bdeb24ef6f124a7260144 (patch) | |
| tree | 6a864cd49cf0630f31892fa882e8e4c40e914e44 /gui/src | |
| parent | 65ec42f0fa3979c13a91cf8ce0db89bfd55b4bb6 (diff) | |
| parent | 92f20c1bee76c6e074604aa5169a7a35a214a0fa (diff) | |
| download | mullvadvpn-31cd7cc00e587896d15bdeb24ef6f124a7260144.tar.xz mullvadvpn-31cd7cc00e587896d15bdeb24ef6f124a7260144.zip | |
Merge branch 'use-common-distance-definitions'
Diffstat (limited to 'gui/src')
38 files changed, 320 insertions, 374 deletions
diff --git a/gui/src/renderer/components/Account.tsx b/gui/src/renderer/components/Account.tsx index b5bbfd773c..83d06fa290 100644 --- a/gui/src/renderer/components/Account.tsx +++ b/gui/src/renderer/components/Account.tsx @@ -6,15 +6,12 @@ import { messages } from '../../shared/gettext'; import { useSelector } from '../redux/store'; import { AccountContainer, - AccountFooter, AccountOutOfTime, AccountRow, AccountRowLabel, AccountRows, AccountRowValue, DeviceRowValue, - StyledBuyCreditButton, - StyledRedeemVoucherButton, StyledSpinnerContainer, } from './AccountStyles'; import AccountTokenLabel from './AccountTokenLabel'; @@ -22,9 +19,10 @@ import * as AppButton from './AppButton'; import { AriaDescribed, AriaDescription, AriaDescriptionGroup } from './AriaGroup'; import ImageView from './ImageView'; import { BackAction } from './KeyboardNavigation'; -import { Layout, SettingsContainer } from './Layout'; +import { Footer, Layout, SettingsContainer } from './Layout'; import { ModalAlert, ModalAlertType, ModalMessage } from './Modal'; import { NavigationBar, NavigationItems, TitleBarItem } from './NavigationBar'; +import { RedeemVoucherButton } from './RedeemVoucher'; import SettingsHeader, { HeaderTitle } from './SettingsHeader'; interface IProps { @@ -96,33 +94,35 @@ export default class Account extends React.Component<IProps, IState> { </AccountRow> </AccountRows> - <AccountFooter> - <AppButton.BlockingButton - disabled={this.props.isOffline} - onClick={this.props.onBuyMore}> - <AriaDescriptionGroup> - <AriaDescribed> - <StyledBuyCreditButton> - <AppButton.Label>{messages.gettext('Buy more credit')}</AppButton.Label> - <AriaDescription> - <AppButton.Icon - source="icon-extLink" - height={16} - width={16} - aria-label={messages.pgettext('accessibility', 'Opens externally')} - /> - </AriaDescription> - </StyledBuyCreditButton> - </AriaDescribed> - </AriaDescriptionGroup> - </AppButton.BlockingButton> + <Footer> + <AppButton.ButtonGroup> + <AppButton.BlockingButton + disabled={this.props.isOffline} + onClick={this.props.onBuyMore}> + <AriaDescriptionGroup> + <AriaDescribed> + <AppButton.GreenButton> + <AppButton.Label>{messages.gettext('Buy more credit')}</AppButton.Label> + <AriaDescription> + <AppButton.Icon + source="icon-extLink" + height={16} + width={16} + aria-label={messages.pgettext('accessibility', 'Opens externally')} + /> + </AriaDescription> + </AppButton.GreenButton> + </AriaDescribed> + </AriaDescriptionGroup> + </AppButton.BlockingButton> - <StyledRedeemVoucherButton /> + <RedeemVoucherButton /> - <AppButton.RedButton onClick={this.onTryLogout}> - {messages.pgettext('account-view', 'Log out')} - </AppButton.RedButton> - </AccountFooter> + <AppButton.RedButton onClick={this.onTryLogout}> + {messages.pgettext('account-view', 'Log out')} + </AppButton.RedButton> + </AppButton.ButtonGroup> + </Footer> </AccountContainer> </SettingsContainer> diff --git a/gui/src/renderer/components/AccountStyles.tsx b/gui/src/renderer/components/AccountStyles.tsx index 5e736a1ded..5cb934134a 100644 --- a/gui/src/renderer/components/AccountStyles.tsx +++ b/gui/src/renderer/components/AccountStyles.tsx @@ -1,15 +1,12 @@ import styled from 'styled-components'; import { colors } from '../../config.json'; -import * as AppButton from './AppButton'; -import { normalText, tinyText } from './common-styles'; -import { RedeemVoucherButton } from './RedeemVoucher'; +import { measurements, normalText, tinyText } from './common-styles'; export const AccountContainer = styled.div({ display: 'flex', flexDirection: 'column', flex: 1, - paddingBottom: '22px', }); export const AccountRows = styled.div({ @@ -19,8 +16,8 @@ export const AccountRows = styled.div({ }); export const AccountRow = styled.div({ - padding: '0 22px', - marginBottom: '20px', + padding: `0 ${measurements.viewMargin}`, + marginBottom: measurements.rowVerticalMargin, }); const AccountRowText = styled.span({ @@ -53,16 +50,3 @@ export const StyledSpinnerContainer = styled.div({ justifyContent: 'center', padding: '8px 0', }); - -export const AccountFooter = styled.div({ - display: 'flex', - flexDirection: 'column', - padding: '0 22px', -}); - -const buttonStyle = { - marginBottom: '18px', -}; - -export const StyledRedeemVoucherButton = styled(RedeemVoucherButton)(buttonStyle); -export const StyledBuyCreditButton = styled(AppButton.GreenButton)(buttonStyle); diff --git a/gui/src/renderer/components/AppButton.tsx b/gui/src/renderer/components/AppButton.tsx index a9bc44a7f4..a3edc78ad3 100644 --- a/gui/src/renderer/components/AppButton.tsx +++ b/gui/src/renderer/components/AppButton.tsx @@ -13,6 +13,7 @@ import { StyledVisibleSide, transparentButton, } from './AppButtonStyles'; +import { measurements } from './common-styles'; import ImageView from './ImageView'; interface ILabelProps { @@ -190,12 +191,12 @@ const StyledButtonWrapper = styled.div({ flexDirection: 'column', flex: 0, ':not(:last-child)': { - marginBottom: '18px', + marginBottom: measurements.buttonVerticalMargin, }, }); interface IButtonGroupProps { - children: React.ReactElement[]; + children: React.ReactNode | React.ReactNode[]; } export function ButtonGroup(props: IButtonGroupProps) { diff --git a/gui/src/renderer/components/CustomDnsSettings.tsx b/gui/src/renderer/components/CustomDnsSettings.tsx index 4fb785d686..97a3f10818 100644 --- a/gui/src/renderer/components/CustomDnsSettings.tsx +++ b/gui/src/renderer/components/CustomDnsSettings.tsx @@ -283,7 +283,7 @@ export default function CustomDnsSettings() { </Accordion> <StyledCustomDnsFooter> - <Cell.FooterText> + <Cell.CellFooterText> {featureAvailable ? messages.pgettext('vpn-settings-view', 'Enable to add at least one DNS server.') : // This line makes sure that the next one isn't prefixed by the color. @@ -296,7 +296,7 @@ export default function CustomDnsSettings() { 'vpn-settings-view', 'Disable all content blockers to activate this setting.', )} - </Cell.FooterText> + </Cell.CellFooterText> </StyledCustomDnsFooter> <ConfirmationDialog diff --git a/gui/src/renderer/components/CustomDnsSettingsStyles.tsx b/gui/src/renderer/components/CustomDnsSettingsStyles.tsx index 9d927ba52d..b660504a01 100644 --- a/gui/src/renderer/components/CustomDnsSettingsStyles.tsx +++ b/gui/src/renderer/components/CustomDnsSettingsStyles.tsx @@ -4,7 +4,7 @@ import { colors } from '../../config.json'; import * as Cell from './cell'; import ImageView from './ImageView'; -export const StyledCustomDnsFooter = styled(Cell.Footer)({ +export const StyledCustomDnsFooter = styled(Cell.CellFooter)({ marginBottom: '2px', }); diff --git a/gui/src/renderer/components/DeviceRevokedView.tsx b/gui/src/renderer/components/DeviceRevokedView.tsx index 74d4c0fd53..f12bbbf9ff 100644 --- a/gui/src/renderer/components/DeviceRevokedView.tsx +++ b/gui/src/renderer/components/DeviceRevokedView.tsx @@ -5,11 +5,11 @@ import { messages } from '../../shared/gettext'; import { useAppContext } from '../context'; import { useSelector } from '../redux/store'; import * as AppButton from './AppButton'; -import { bigText, smallText } from './common-styles'; +import { bigText, measurements, smallText } from './common-styles'; import CustomScrollbars from './CustomScrollbars'; import { calculateHeaderBarStyle, DefaultHeaderBar } from './HeaderBar'; import ImageView from './ImageView'; -import { Container } from './Layout'; +import { Container, Footer } from './Layout'; import { Layout } from './Layout'; export const StyledHeader = styled(DefaultHeaderBar)({ @@ -30,14 +30,7 @@ export const StyledBody = styled.div({ display: 'flex', flexDirection: 'column', flex: 1, - padding: '0 22px', -}); - -export const StyledFooter = styled.div({ - display: 'flex', - flexDirection: 'column', - flex: 0, - padding: '18px 22px 22px', + padding: `0 ${measurements.viewMargin}`, }); export const StyledStatusIcon = styled.div({ @@ -54,7 +47,7 @@ export const StyledTitle = styled.span(bigText, { }); export const StyledMessage = styled.span(smallText, { - marginBottom: '20px', + marginBottom: measurements.rowVerticalMargin, color: colors.white, }); @@ -91,11 +84,11 @@ export function DeviceRevokedView() { </StyledMessage> </StyledBody> - <StyledFooter> + <Footer> <Button onClick={leaveRevokedDevice}> {messages.pgettext('device-management', 'Go to login')} </Button> - </StyledFooter> + </Footer> </StyledContainer> </StyledCustomScrollbars> </Layout> diff --git a/gui/src/renderer/components/ErrorView.tsx b/gui/src/renderer/components/ErrorView.tsx index 527b982860..12ca510396 100644 --- a/gui/src/renderer/components/ErrorView.tsx +++ b/gui/src/renderer/components/ErrorView.tsx @@ -1,6 +1,7 @@ import styled from 'styled-components'; import { colors } from '../../config.json'; +import { measurements } from './common-styles'; import { HeaderBarSettingsButton } from './HeaderBar'; import ImageView from './ImageView'; import { Container, Header, Layout } from './Layout'; @@ -26,7 +27,7 @@ const Subtitle = styled.span({ fontFamily: 'Open Sans', fontSize: '14px', lineHeight: '20px', - marginHorizontal: '22px', + margin: `0 ${measurements.viewMargin}`, color: colors.white40, textAlign: 'center', }); diff --git a/gui/src/renderer/components/ExpiredAccountAddTime.tsx b/gui/src/renderer/components/ExpiredAccountAddTime.tsx index 276af92e26..75363c4d79 100644 --- a/gui/src/renderer/components/ExpiredAccountAddTime.tsx +++ b/gui/src/renderer/components/ExpiredAccountAddTime.tsx @@ -15,11 +15,11 @@ import account from '../redux/account/actions'; import { useSelector } from '../redux/store'; import * as AppButton from './AppButton'; import { AriaDescribed, AriaDescription, AriaDescriptionGroup } from './AriaGroup'; -import { hugeText, tinyText } from './common-styles'; +import { hugeText, measurements, tinyText } from './common-styles'; import CustomScrollbars from './CustomScrollbars'; import { calculateHeaderBarStyle, DefaultHeaderBar, HeaderBarStyle } from './HeaderBar'; import ImageView from './ImageView'; -import { Container, Layout } from './Layout'; +import { Container, Footer, Layout } from './Layout'; import { RedeemVoucherContainer, RedeemVoucherInput, @@ -45,17 +45,10 @@ export const StyledBody = styled.div({ display: 'flex', flexDirection: 'column', flex: 1, - padding: '0 22px', + padding: `0 ${measurements.viewMargin}`, paddingBottom: 'auto', }); -export const StyledFooter = styled.div({ - display: 'flex', - flexDirection: 'column', - flex: 0, - padding: '18px 22px 22px', -}); - export const StyledTitle = styled.span(hugeText, { lineHeight: '38px', marginBottom: '8px', @@ -106,14 +99,14 @@ export function VoucherInput() { <RedeemVoucherResponse /> </StyledBody> - <StyledFooter> + <Footer> <AppButton.ButtonGroup> <RedeemVoucherSubmitButton /> <AppButton.BlueButton onClick={navigateBack}> {messages.gettext('Cancel')} </AppButton.BlueButton> </AppButton.ButtonGroup> - </StyledFooter> + </Footer> </RedeemVoucherContainer> </StyledContainer> </StyledCustomScrollbars> @@ -193,11 +186,11 @@ export function TimeAdded(props: ITimeAddedProps) { </StyledLabel> </StyledBody> - <StyledFooter> + <Footer> <AppButton.BlueButton onClick={navigateToSetupFinished}> {messages.gettext('Next')} </AppButton.BlueButton> - </StyledFooter> + </Footer> </StyledContainer> </StyledCustomScrollbars> </Layout> @@ -231,7 +224,7 @@ export function SetupFinished() { </StyledLabel> </StyledBody> - <StyledFooter> + <Footer> <AppButton.ButtonGroup> <AriaDescriptionGroup> <AriaDescribed> @@ -254,7 +247,7 @@ export function SetupFinished() { {messages.pgettext('connect-view', 'Start using the app')} </AppButton.GreenButton> </AppButton.ButtonGroup> - </StyledFooter> + </Footer> </StyledContainer> </StyledCustomScrollbars> </Layout> diff --git a/gui/src/renderer/components/ExpiredAccountErrorView.tsx b/gui/src/renderer/components/ExpiredAccountErrorView.tsx index a2645dd14f..2d4fcdb216 100644 --- a/gui/src/renderer/components/ExpiredAccountErrorView.tsx +++ b/gui/src/renderer/components/ExpiredAccountErrorView.tsx @@ -13,11 +13,8 @@ import { StyledAccountTokenLabel, StyledAccountTokenMessage, StyledBody, - StyledBuyCreditButton, StyledContainer, StyledCustomScrollbars, - StyledDisconnectButton, - StyledFooter, StyledHeader, StyledMessage, StyledModalCellContainer, @@ -26,7 +23,7 @@ import { } from './ExpiredAccountErrorViewStyles'; import { calculateHeaderBarStyle, HeaderBarStyle } from './HeaderBar'; import ImageView from './ImageView'; -import { Layout } from './Layout'; +import { Footer, Layout } from './Layout'; import { ModalAlert, ModalAlertType, ModalMessage } from './Modal'; export enum RecoveryAction { @@ -72,21 +69,23 @@ export default class ExpiredAccountErrorView extends React.Component< <StyledContainer> <StyledBody>{this.renderContent()}</StyledBody> - <StyledFooter> - {this.getRecoveryAction() === RecoveryAction.disconnect && ( - <AppButton.BlockingButton onClick={this.props.onDisconnect}> - <StyledDisconnectButton> - {messages.pgettext('connect-view', 'Disconnect')} - </StyledDisconnectButton> - </AppButton.BlockingButton> - )} + <Footer> + <AppButton.ButtonGroup> + {this.getRecoveryAction() === RecoveryAction.disconnect && ( + <AppButton.BlockingButton onClick={this.props.onDisconnect}> + <AppButton.RedButton> + {messages.pgettext('connect-view', 'Disconnect')} + </AppButton.RedButton> + </AppButton.BlockingButton> + )} - {this.renderExternalPaymentButton()} + {this.renderExternalPaymentButton()} - <AppButton.GreenButton onClick={this.props.navigateToRedeemVoucher}> - {messages.pgettext('connect-view', 'Redeem voucher')} - </AppButton.GreenButton> - </StyledFooter> + <AppButton.GreenButton onClick={this.props.navigateToRedeemVoucher}> + {messages.pgettext('connect-view', 'Redeem voucher')} + </AppButton.GreenButton> + </AppButton.ButtonGroup> + </Footer> {this.renderBlockWhenDisconnectedAlert()} </StyledContainer> @@ -173,7 +172,7 @@ export default class ExpiredAccountErrorView extends React.Component< onClick={this.onOpenExternalPayment}> <AriaDescriptionGroup> <AriaDescribed> - <StyledBuyCreditButton> + <AppButton.GreenButton> <AppButton.Label>{buttonText}</AppButton.Label> <AriaDescription> <AppButton.Icon @@ -183,7 +182,7 @@ export default class ExpiredAccountErrorView extends React.Component< aria-label={messages.pgettext('accessibility', 'Opens externally')} /> </AriaDescription> - </StyledBuyCreditButton> + </AppButton.GreenButton> </AriaDescribed> </AriaDescriptionGroup> </AppButton.BlockingButton> diff --git a/gui/src/renderer/components/ExpiredAccountErrorViewStyles.tsx b/gui/src/renderer/components/ExpiredAccountErrorViewStyles.tsx index c1edce3599..17c02cfc3c 100644 --- a/gui/src/renderer/components/ExpiredAccountErrorViewStyles.tsx +++ b/gui/src/renderer/components/ExpiredAccountErrorViewStyles.tsx @@ -2,9 +2,8 @@ import styled from 'styled-components'; import { colors } from '../../config.json'; import AccountTokenLabel from './AccountTokenLabel'; -import * as AppButton from './AppButton'; import * as Cell from './cell'; -import { hugeText, tinyText } from './common-styles'; +import { hugeText, measurements, tinyText } from './common-styles'; import CustomScrollbars from './CustomScrollbars'; import { DefaultHeaderBar } from './HeaderBar'; import { Container } from './Layout'; @@ -27,13 +26,6 @@ export const StyledModalCellContainer = styled(Cell.Container)({ paddingRight: '12px', }); -const buttonStyle = { - marginBottom: '18px', -}; - -export const StyledBuyCreditButton = styled(AppButton.GreenButton)(buttonStyle); -export const StyledDisconnectButton = styled(AppButton.RedButton)(buttonStyle); - export const StyledCustomScrollbars = styled(CustomScrollbars)({ flex: 1, }); @@ -48,14 +40,7 @@ export const StyledBody = styled.div({ display: 'flex', flexDirection: 'column', flex: 1, - padding: '0 22px', -}); - -export const StyledFooter = styled.div({ - display: 'flex', - flexDirection: 'column', - flex: 0, - padding: '18px 22px 22px', + padding: `0 ${measurements.viewMargin}`, }); export const StyledTitle = styled.span(hugeText, { diff --git a/gui/src/renderer/components/Filter.tsx b/gui/src/renderer/components/Filter.tsx index 5c2e7e0f55..1bb208cd7f 100644 --- a/gui/src/renderer/components/Filter.tsx +++ b/gui/src/renderer/components/Filter.tsx @@ -18,7 +18,7 @@ import Selector from './cell/Selector'; import { normalText } from './common-styles'; import ImageView from './ImageView'; import { BackAction } from './KeyboardNavigation'; -import { Layout, SettingsContainer } from './Layout'; +import { Footer, Layout, SettingsContainer } from './Layout'; import { NavigationBar, NavigationContainer, @@ -32,12 +32,6 @@ const StyledNavigationScrollbars = styled(NavigationScrollbars)({ flex: 1, }); -const StyledFooter = styled.div({ - display: 'flex', - flexDirection: 'column', - padding: '18px 22px 22px', -}); - export default function Filter() { const history = useHistory(); const { updateRelaySettings } = useAppContext(); @@ -101,13 +95,13 @@ export default function Filter() { setProviders={setProviders} /> </StyledNavigationScrollbars> - <StyledFooter> + <Footer> <AppButton.GreenButton disabled={Object.values(providers).every((provider) => !provider)} onClick={onApply}> {messages.gettext('Apply')} </AppButton.GreenButton> - </StyledFooter> + </Footer> </NavigationContainer> </SettingsContainer> </Layout> @@ -281,14 +275,6 @@ interface IStyledRowTitleProps { bold?: boolean; } -const StyledRow = styled.div({ - display: 'flex', - height: '44px', - alignItems: 'center', - padding: '0 22px', - backgroundColor: colors.blue, -}); - const StyledCheckbox = styled.div({ width: '24px', height: '24px', @@ -299,6 +285,13 @@ const StyledCheckbox = styled.div({ borderRadius: '4px', }); +const StyledRow = styled(Cell.Row)({ + backgroundColor: colors.blue40, + ':hover': { + backgroundColor: colors.blue80, + }, +}); + const StyledRowTitle = styled.label(normalText, (props: IStyledRowTitleProps) => ({ fontWeight: props.bold ? 600 : 400, color: colors.white, diff --git a/gui/src/renderer/components/Layout.tsx b/gui/src/renderer/components/Layout.tsx index 500084e5b1..b74cfd929f 100644 --- a/gui/src/renderer/components/Layout.tsx +++ b/gui/src/renderer/components/Layout.tsx @@ -1,6 +1,7 @@ import styled from 'styled-components'; import { colors } from '../../config.json'; +import { measurements } from './common-styles'; import HeaderBar from './HeaderBar'; export const Header = styled(HeaderBar)({ @@ -25,3 +26,13 @@ export const Layout = styled.div({ flex: 1, height: '100vh', }); + +export const Footer = styled.div({ + display: 'flex', + flexDirection: 'column', + flex: 0, + paddingTop: '18px', + paddingLeft: measurements.viewMargin, + paddingRight: measurements.viewMargin, + paddingBottom: measurements.viewMargin, +}); diff --git a/gui/src/renderer/components/List.tsx b/gui/src/renderer/components/List.tsx index 2915a95c1b..3d1bd99478 100644 --- a/gui/src/renderer/components/List.tsx +++ b/gui/src/renderer/components/List.tsx @@ -7,7 +7,6 @@ import Accordion from './Accordion'; export const stringValueAsKey = (value: string): string => value; const StyledListItem = styled.div({ - marginBottom: '1px', display: 'flex', flex: 1, flexDirection: 'column', diff --git a/gui/src/renderer/components/LocationRow.tsx b/gui/src/renderer/components/LocationRow.tsx index 4e083328c5..9172f8bcd3 100644 --- a/gui/src/renderer/components/LocationRow.tsx +++ b/gui/src/renderer/components/LocationRow.tsx @@ -8,7 +8,7 @@ import { messages } from '../../shared/gettext'; import Accordion from './Accordion'; import * as Cell from './cell'; import ChevronButton from './ChevronButton'; -import { normalText } from './common-styles'; +import { measurements, normalText } from './common-styles'; import RelayStatusIndicator from './RelayStatusIndicator'; interface IButtonColorProps { @@ -50,7 +50,7 @@ export const StyledLocationRowContainer = styled(Cell.Container)({ background: 'none', }); -export const StyledLocationRowButton = styled.button( +export const StyledLocationRowButton = styled(Cell.Row)( buttonColor, (props: { location?: RelayLocation }) => { const paddingLeft = @@ -61,9 +61,6 @@ export const StyledLocationRowButton = styled.button( : 18; return { - display: 'flex', - alignItems: 'center', - minHeight: '44px', flex: 1, border: 'none', padding: `0 10px 0 ${paddingLeft}px`, @@ -76,7 +73,7 @@ export const StyledLocationRowIcon = styled.button(buttonColor, { position: 'relative', alignSelf: 'stretch', paddingLeft: '22px', - paddingRight: '22px', + paddingRight: measurements.viewMargin, '&::before': { content: '""', @@ -136,6 +133,7 @@ function LocationRow(props: IProps, ref: React.Ref<HTMLDivElement>) { <> <StyledLocationRowContainer ref={ref} disabled={props.disabled}> <StyledLocationRowButton + as="button" ref={buttonRef} onClick={handleClick} selected={props.selected} diff --git a/gui/src/renderer/components/LoginStyles.tsx b/gui/src/renderer/components/LoginStyles.tsx index dcfc85c6c3..cff3cdfc67 100644 --- a/gui/src/renderer/components/LoginStyles.tsx +++ b/gui/src/renderer/components/LoginStyles.tsx @@ -2,9 +2,10 @@ import styled from 'styled-components'; import { colors } from '../../config.json'; import * as Cell from './cell'; -import { hugeText, largeText, smallText, tinyText } from './common-styles'; +import { hugeText, largeText, measurements, smallText, tinyText } from './common-styles'; import FormattableTextInput from './FormattableTextInput'; import ImageView from './ImageView'; +import { Footer } from './Layout'; export const StyledAccountDropdownContainer = styled.ul({ display: 'flex', @@ -74,15 +75,11 @@ export const StyledTopInfo = styled.div({ flex: 1, }); -export const StyledFooter = styled.div({}, (props: { show: boolean }) => ({ +export const StyledFooter = styled(Footer)({}, (props: { show: boolean }) => ({ position: 'relative', width: '100%', bottom: 0, transform: `translateY(${props.show ? 0 : 100}%)`, - display: 'flex', - flex: '0', - flexDirection: 'column', - padding: '18px 22px 22px', backgroundColor: colors.darkBlue, transition: 'transform 250ms ease-in-out', })); @@ -102,7 +99,7 @@ export const StyledLoginForm = styled.div({ flex: '0 1 225px', flexDirection: 'column', overflow: 'visible', - padding: '0 22px', + padding: `0 ${measurements.viewMargin}`, }); interface IStyledAccountInputGroupProps { diff --git a/gui/src/renderer/components/Modal.tsx b/gui/src/renderer/components/Modal.tsx index 723235a839..97631caec4 100644 --- a/gui/src/renderer/components/Modal.tsx +++ b/gui/src/renderer/components/Modal.tsx @@ -5,7 +5,8 @@ import styled from 'styled-components'; import { colors } from '../../config.json'; import log from '../../shared/logging'; import { useWillExit } from '../lib/will-exit'; -import { tinyText } from './common-styles'; +import * as AppButton from './AppButton'; +import { measurements, tinyText } from './common-styles'; import CustomScrollbars from './CustomScrollbars'; import ImageView from './ImageView'; import { BackAction } from './KeyboardNavigation'; @@ -142,10 +143,13 @@ const ModalAlertIcon = styled.div({ marginTop: '8px', }); +const ModalAlertButtonGroupContainer = styled.div({ + marginTop: measurements.buttonVerticalMargin, +}); + const ModalAlertButtonContainer = styled.div({ display: 'flex', flexDirection: 'column', - marginTop: '18px', marginRight: '16px', }); @@ -265,9 +269,13 @@ class ModalAlertImpl extends React.Component<IModalAlertImplProps, IModalAlertSt {this.props.children} </StyledCustomScrollbars> - {this.props.buttons.map((button, index) => ( - <ModalAlertButtonContainer key={index}>{button}</ModalAlertButtonContainer> - ))} + <ModalAlertButtonGroupContainer> + <AppButton.ButtonGroup> + {this.props.buttons.map((button, index) => ( + <ModalAlertButtonContainer key={index}>{button}</ModalAlertButtonContainer> + ))} + </AppButton.ButtonGroup> + </ModalAlertButtonGroupContainer> </StyledModalAlert> </ModalAlertContainer> </ModalBackground> diff --git a/gui/src/renderer/components/OpenVpnSettings.tsx b/gui/src/renderer/components/OpenVpnSettings.tsx index af4404fd1a..69a570c356 100644 --- a/gui/src/renderer/components/OpenVpnSettings.tsx +++ b/gui/src/renderer/components/OpenVpnSettings.tsx @@ -156,9 +156,9 @@ function TransportProtocolSelector() { automaticValue={null} /> {bridgeState === 'on' && ( - <Cell.Footer> + <Cell.CellFooter> <AriaDescription> - <Cell.FooterText> + <Cell.CellFooterText> {formatMarkdown( // TRANSLATORS: This is used to instruct users how to make UDP mode // TRANSLATORS: available. @@ -167,9 +167,9 @@ function TransportProtocolSelector() { 'To activate UDP, change **Bridge mode** to **Automatic** or **Off**.', ), )} - </Cell.FooterText> + </Cell.CellFooterText> </AriaDescription> - </Cell.Footer> + </Cell.CellFooter> )} </AriaInputGroup> </StyledSelectorContainer> @@ -340,13 +340,13 @@ function BridgeModeSelector() { automaticValue={'auto' as const} /> </StyledSelectorContainer> - <Cell.Footer> + <Cell.CellFooter> <AriaDescription> - <Cell.FooterText> + <Cell.CellFooterText> {bridgeModeFooterText(tunnelProtocol, transportProtocol)} - </Cell.FooterText> + </Cell.CellFooterText> </AriaDescription> - </Cell.Footer> + </Cell.CellFooter> </AriaInputGroup> <ModalAlert isOpen={confirmationDialogVisible} @@ -476,9 +476,9 @@ function MssFixSetting() { /> </AriaInput> </Cell.Container> - <Cell.Footer> + <Cell.CellFooter> <AriaDescription> - <Cell.FooterText> + <Cell.CellFooterText> {sprintf( // TRANSLATORS: The hint displayed below the Mssfix input field. // TRANSLATORS: Available placeholders: @@ -495,9 +495,9 @@ function MssFixSetting() { max: MAX_MSSFIX_VALUE, }, )} - </Cell.FooterText> + </Cell.CellFooterText> </AriaDescription> - </Cell.Footer> + </Cell.CellFooter> </AriaInputGroup> ); } diff --git a/gui/src/renderer/components/ProblemReport.tsx b/gui/src/renderer/components/ProblemReport.tsx index e2c3bf4d5b..f7f5e4cd5a 100644 --- a/gui/src/renderer/components/ProblemReport.tsx +++ b/gui/src/renderer/components/ProblemReport.tsx @@ -8,16 +8,14 @@ import * as AppButton from './AppButton'; import { AriaDescribed, AriaDescription, AriaDescriptionGroup } from './AriaGroup'; import ImageView from './ImageView'; import { BackAction } from './KeyboardNavigation'; -import { Layout, SettingsContainer } from './Layout'; +import { Footer, Layout, SettingsContainer } from './Layout'; import { ModalAlert, ModalAlertType } from './Modal'; import { NavigationBar, NavigationItems, TitleBarItem } from './NavigationBar'; import { - StyledBlueButton, StyledContent, StyledContentContainer, StyledEmail, StyledEmailInput, - StyledFooter, StyledForm, StyledFormEmailRow, StyledFormMessageRow, @@ -343,22 +341,24 @@ export default class ProblemReport extends React.Component< /> </StyledFormMessageRow> </StyledForm> - <StyledFooter> + <Footer> <AriaDescriptionGroup> <AriaDescribed> - <StyledBlueButton onClick={this.onViewLog} disabled={this.state.disableActions}> - <AppButton.Label> - {messages.pgettext('support-view', 'View app logs')} - </AppButton.Label> - <AriaDescription> - <AppButton.Icon - source="icon-extLink" - height={16} - width={16} - aria-label={messages.pgettext('accessibility', 'Opens externally')} - /> - </AriaDescription> - </StyledBlueButton> + <AppButton.ButtonGroup> + <AppButton.BlueButton onClick={this.onViewLog} disabled={this.state.disableActions}> + <AppButton.Label> + {messages.pgettext('support-view', 'View app logs')} + </AppButton.Label> + <AriaDescription> + <AppButton.Icon + source="icon-extLink" + height={16} + width={16} + aria-label={messages.pgettext('accessibility', 'Opens externally')} + /> + </AriaDescription> + </AppButton.BlueButton> + </AppButton.ButtonGroup> </AriaDescribed> </AriaDescriptionGroup> <AppButton.GreenButton @@ -366,7 +366,7 @@ export default class ProblemReport extends React.Component< onClick={this.onSend}> {messages.pgettext('support-view', 'Send')} </AppButton.GreenButton> - </StyledFooter> + </Footer> </StyledContent> ); } @@ -429,14 +429,16 @@ export default class ProblemReport extends React.Component< )} </StyledSentMessage> </StyledForm> - <StyledFooter> - <StyledBlueButton onClick={this.handleEditMessage}> - {messages.pgettext('support-view', 'Edit message')} - </StyledBlueButton> - <AppButton.GreenButton onClick={this.onSend}> - {messages.pgettext('support-view', 'Try again')} - </AppButton.GreenButton> - </StyledFooter> + <Footer> + <AppButton.ButtonGroup> + <AppButton.BlueButton onClick={this.handleEditMessage}> + {messages.pgettext('support-view', 'Edit message')} + </AppButton.BlueButton> + <AppButton.GreenButton onClick={this.onSend}> + {messages.pgettext('support-view', 'Try again')} + </AppButton.GreenButton> + </AppButton.ButtonGroup> + </Footer> </StyledContent> ); } diff --git a/gui/src/renderer/components/ProblemReportStyles.tsx b/gui/src/renderer/components/ProblemReportStyles.tsx index 25457c2593..4b32c3fd53 100644 --- a/gui/src/renderer/components/ProblemReportStyles.tsx +++ b/gui/src/renderer/components/ProblemReportStyles.tsx @@ -1,12 +1,7 @@ import styled from 'styled-components'; import { colors } from '../../config.json'; -import * as AppButton from './AppButton'; -import { hugeText, smallText } from './common-styles'; - -export const StyledBlueButton = styled(AppButton.BlueButton)({ - marginBottom: '18px', -}); +import { hugeText, measurements, smallText } from './common-styles'; export const StyledContentContainer = styled.div({ display: 'flex', @@ -25,7 +20,7 @@ export const StyledForm = styled.div({ display: 'flex', flex: 1, flexDirection: 'column', - margin: '0 22px', + margin: `0 ${measurements.viewMargin}`, }); export const StyledFormEmailRow = styled.div({ @@ -57,13 +52,6 @@ export const StyledMessageInput = styled.textarea(smallText, input, { fontWeight: 400, }); -export const StyledFooter = styled.div({ - display: 'flex', - flexDirection: 'column', - flex: 0, - padding: '18px 22px 22px', -}); - export const StyledStatusIcon = styled.div({ display: 'flex', justifyContent: 'center', diff --git a/gui/src/renderer/components/Settings.tsx b/gui/src/renderer/components/Settings.tsx index 985c013a48..69d4e2b80a 100644 --- a/gui/src/renderer/components/Settings.tsx +++ b/gui/src/renderer/components/Settings.tsx @@ -198,9 +198,9 @@ function AppVersionButton() { icon = <StyledCellIcon source="icon-alert" width={18} tintColor={colors.red} />; footer = ( - <Cell.Footer> - <Cell.FooterText>{message}</Cell.FooterText> - </Cell.Footer> + <Cell.CellFooter> + <Cell.CellFooterText>{message}</Cell.CellFooterText> + </Cell.CellFooter> ); } diff --git a/gui/src/renderer/components/SettingsHeader.tsx b/gui/src/renderer/components/SettingsHeader.tsx index 01e62e50d0..94f36cb8b2 100644 --- a/gui/src/renderer/components/SettingsHeader.tsx +++ b/gui/src/renderer/components/SettingsHeader.tsx @@ -2,11 +2,14 @@ import * as React from 'react'; import styled from 'styled-components'; import { colors } from '../../config.json'; -import { hugeText, tinyText } from './common-styles'; +import { hugeText, measurements, tinyText } from './common-styles'; export const Container = styled.div({ flex: 0, - padding: '2px 22px 20px', + paddingTop: '2px', + paddingLeft: measurements.viewMargin, + paddingRight: measurements.viewMargin, + paddingBottom: measurements.rowVerticalMargin, }); export const ContentWrapper = styled.div({ diff --git a/gui/src/renderer/components/SettingsStyles.tsx b/gui/src/renderer/components/SettingsStyles.tsx index 612af16dab..57e7ecc7ad 100644 --- a/gui/src/renderer/components/SettingsStyles.tsx +++ b/gui/src/renderer/components/SettingsStyles.tsx @@ -3,6 +3,7 @@ import styled from 'styled-components'; import { colors } from '../../config.json'; import * as AppButton from './AppButton'; import * as Cell from './cell'; +import { measurements } from './common-styles'; import { NavigationScrollbars } from './NavigationBar'; export const StyledOutOfTimeSubText = styled(Cell.SubText)((props: { isOutOfTime: boolean }) => ({ @@ -30,5 +31,6 @@ export const StyledSettingsContent = styled.div({ }); export const StyledQuitButton = styled(AppButton.RedButton)({ - margin: '20px 22px 22px', + margin: measurements.viewMargin, + marginTop: measurements.rowVerticalMargin, }); diff --git a/gui/src/renderer/components/SplitTunnelingSettingsStyles.tsx b/gui/src/renderer/components/SplitTunnelingSettingsStyles.tsx index 412d04181f..6b135486db 100644 --- a/gui/src/renderer/components/SplitTunnelingSettingsStyles.tsx +++ b/gui/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 { normalText } from './common-styles'; +import { measurements, normalText } from './common-styles'; import ImageView from './ImageView'; import { NavigationScrollbars } from './NavigationBar'; import { HeaderTitle } from './SettingsHeader'; @@ -69,36 +69,36 @@ export const StyledSpinnerRow = styled(Cell.CellButton)({ alignItems: 'center', justifyContent: 'center', padding: '8px 0', - marginBottom: '20px', + marginBottom: measurements.rowVerticalMargin, background: colors.blue40, }); export const StyledListContainer = styled.div({ display: 'flex', flexDirection: 'column', - marginBottom: '20px', + marginBottom: measurements.rowVerticalMargin, }); export const StyledBrowseButton = styled(AppButton.BlueButton)({ - margin: '0 22px 22px', + margin: `0 ${measurements.viewMargin} ${measurements.viewMargin}`, }); export const StyledCellContainer = styled(Cell.Container)({ - marginBottom: '20px', + marginBottom: measurements.rowVerticalMargin, }); export const StyledSearchContainer = styled.div({ position: 'relative', - marginBottom: '18px', + marginBottom: measurements.buttonVerticalMargin, }); export const StyledSearchInput = styled.input.attrs({ type: 'text' })({ ...normalText, - width: 'calc(100% - 22px * 2)', + width: `calc(100% - ${measurements.viewMargin} * 2)`, border: 'none', borderRadius: '4px', padding: '9px 38px', - margin: '0 22px', + margin: `0 ${measurements.viewMargin}`, color: colors.white60, backgroundColor: colors.white10, '::placeholder': { @@ -145,14 +145,14 @@ export const StyledClearIcon = styled(ImageView)({ }, }); -export const StyledNoResult = styled(Cell.Footer)({ +export const StyledNoResult = styled(Cell.CellFooter)({ display: 'flex', flexDirection: 'column', paddingTop: 0, marginTop: 0, }); -export const StyledNoResultText = styled(Cell.FooterText)({ +export const StyledNoResultText = styled(Cell.CellFooterText)({ textAlign: 'center', }); diff --git a/gui/src/renderer/components/Support.tsx b/gui/src/renderer/components/Support.tsx index 0579b1d944..2785883ecf 100644 --- a/gui/src/renderer/components/Support.tsx +++ b/gui/src/renderer/components/Support.tsx @@ -135,9 +135,9 @@ function BetaProgramSetting() { <Cell.Switch isOn={showBetaReleases} onChange={setShowBetaReleases} /> </AriaInput> </Cell.Container> - <Cell.Footer> + <Cell.CellFooter> <AriaDescription> - <Cell.FooterText> + <Cell.CellFooterText> {isBeta ? messages.pgettext( 'support-view', @@ -147,9 +147,9 @@ function BetaProgramSetting() { 'support-view', 'Enable to get notified when new beta versions of the app are released.', )} - </Cell.FooterText> + </Cell.CellFooterText> </AriaDescription> - </Cell.Footer> + </Cell.CellFooter> </AriaInputGroup> ); } diff --git a/gui/src/renderer/components/TooManyDevices.tsx b/gui/src/renderer/components/TooManyDevices.tsx index 83789c8bfe..1d824d2d50 100644 --- a/gui/src/renderer/components/TooManyDevices.tsx +++ b/gui/src/renderer/components/TooManyDevices.tsx @@ -15,11 +15,11 @@ import { formatMarkdown } from '../markdown-formatter'; import { useSelector } from '../redux/store'; import * as AppButton from './AppButton'; import * as Cell from './cell'; -import { bigText } from './common-styles'; +import { bigText, measurements } from './common-styles'; import CustomScrollbars from './CustomScrollbars'; import { Brand, HeaderBarSettingsButton } from './HeaderBar'; import ImageView from './ImageView'; -import { Header, Layout, SettingsContainer } from './Layout'; +import { Footer, Header, Layout, SettingsContainer } from './Layout'; import List from './List'; import { ModalAlert, ModalAlertType, ModalContainer, ModalMessage } from './Modal'; @@ -39,13 +39,6 @@ const StyledBody = styled.div({ paddingBottom: 'auto', }); -const StyledFooter = styled.div({ - display: 'flex', - flexDirection: 'column', - flex: 0, - padding: '18px 22px 22px', -}); - const StyledStatusIcon = styled.div({ alignSelf: 'center', width: '60px', @@ -55,7 +48,7 @@ const StyledStatusIcon = styled.div({ const StyledTitle = styled.span(bigText, { lineHeight: '38px', - margin: '0 22px 8px', + margin: `0 ${measurements.viewMargin} 8px`, color: colors.white, }); @@ -65,7 +58,7 @@ const StyledLabel = styled.span({ fontWeight: 600, lineHeight: '20px', color: colors.white, - margin: '0 22px 18px', + margin: `0 ${measurements.viewMargin} 18px`, }); const StyledSpacer = styled.div({ @@ -136,7 +129,7 @@ export default function TooManyDevices() { </StyledBody> {devices !== undefined && ( - <StyledFooter> + <Footer> <AppButton.ButtonGroup> <AppButton.GreenButton onClick={continueLogin} disabled={continueButtonDisabled}> { @@ -148,7 +141,7 @@ export default function TooManyDevices() { {messages.gettext('Back')} </AppButton.BlueButton> </AppButton.ButtonGroup> - </StyledFooter> + </Footer> )} </StyledContainer> </StyledCustomScrollbars> diff --git a/gui/src/renderer/components/TunnelControl.tsx b/gui/src/renderer/components/TunnelControl.tsx index 0e282d88aa..db0503cb0a 100644 --- a/gui/src/renderer/components/TunnelControl.tsx +++ b/gui/src/renderer/components/TunnelControl.tsx @@ -6,8 +6,9 @@ import { TunnelState } from '../../shared/daemon-rpc-types'; import { messages, relayLocations } from '../../shared/gettext'; import ConnectionPanelContainer from '../containers/ConnectionPanelContainer'; import * as AppButton from './AppButton'; -import { hugeText, normalText } from './common-styles'; +import { hugeText, measurements, normalText } from './common-styles'; import ImageView from './ImageView'; +import { Footer } from './Layout'; import Marquee from './Marquee'; import { MultiButton } from './MultiButton'; import SecuredLabel, { SecuredDisplayStyle } from './SecuredLabel'; @@ -24,28 +25,15 @@ interface ITunnelControlProps { onSelectLocation: () => void; } -const SwitchLocationButton = styled(AppButton.TransparentButton)({ - marginBottom: '18px', -}); - const Secured = styled(SecuredLabel)(normalText, { fontWeight: 700, lineHeight: '22px', }); -const Footer = styled.div({ - display: 'flex', - flexDirection: 'column', - flex: 0, - paddingBottom: '22px', - paddingLeft: '22px', - paddingRight: '22px', -}); - const Body = styled.div({ display: 'flex', flexDirection: 'column', - padding: '0 22px', + padding: `0 ${measurements.viewMargin}`, marginTop: '176px', flex: 1, }); @@ -117,8 +105,10 @@ export default class TunnelControl extends React.Component<ITunnelControlProps> <ConnectionPanelContainer /> </Body> <Footer> - {this.switchLocationButton()} - <MultiButton mainButton={this.cancelButton} sideButton={this.reconnectButton} /> + <AppButton.ButtonGroup> + {this.switchLocationButton()} + <MultiButton mainButton={this.cancelButton} sideButton={this.reconnectButton} /> + </AppButton.ButtonGroup> </Footer> </Wrapper> ); @@ -137,8 +127,10 @@ export default class TunnelControl extends React.Component<ITunnelControlProps> <ConnectionPanelContainer /> </Body> <Footer> - {this.switchLocationButton()} - <MultiButton mainButton={this.disconnectButton} sideButton={this.reconnectButton} /> + <AppButton.ButtonGroup> + {this.switchLocationButton()} + <MultiButton mainButton={this.disconnectButton} sideButton={this.reconnectButton} /> + </AppButton.ButtonGroup> </Footer> </Wrapper> ); @@ -155,8 +147,10 @@ export default class TunnelControl extends React.Component<ITunnelControlProps> <Secured displayStyle={SecuredDisplayStyle.failedToSecure} /> </Body> <Footer> - {this.switchLocationButton()} - <MultiButton mainButton={this.dismissButton} sideButton={this.reconnectButton} /> + <AppButton.ButtonGroup> + {this.switchLocationButton()} + <MultiButton mainButton={this.dismissButton} sideButton={this.reconnectButton} /> + </AppButton.ButtonGroup> </Footer> </Wrapper> ); @@ -167,8 +161,10 @@ export default class TunnelControl extends React.Component<ITunnelControlProps> <Secured displayStyle={SecuredDisplayStyle.blocked} /> </Body> <Footer> - {this.switchLocationButton()} - <MultiButton mainButton={this.cancelButton} sideButton={this.reconnectButton} /> + <AppButton.ButtonGroup> + {this.switchLocationButton()} + <MultiButton mainButton={this.cancelButton} sideButton={this.reconnectButton} /> + </AppButton.ButtonGroup> </Footer> </Wrapper> ); @@ -185,8 +181,10 @@ export default class TunnelControl extends React.Component<ITunnelControlProps> </Location> </Body> <Footer> - {this.selectLocationButton()} - {this.connectButton()} + <AppButton.ButtonGroup> + {this.selectLocationButton()} + {this.connectButton()} + </AppButton.ButtonGroup> </Footer> </Wrapper> ); @@ -205,8 +203,10 @@ export default class TunnelControl extends React.Component<ITunnelControlProps> </Location> </Body> <Footer> - {this.selectLocationButton()} - {this.connectButton()} + <AppButton.ButtonGroup> + {this.selectLocationButton()} + {this.connectButton()} + </AppButton.ButtonGroup> </Footer> </Wrapper> ); @@ -238,15 +238,15 @@ export default class TunnelControl extends React.Component<ITunnelControlProps> private switchLocationButton() { return ( - <SwitchLocationButton onClick={this.props.onSelectLocation}> + <AppButton.TransparentButton onClick={this.props.onSelectLocation}> {messages.pgettext('tunnel-control', 'Switch location')} - </SwitchLocationButton> + </AppButton.TransparentButton> ); } private selectLocationButton() { return ( - <SwitchLocationButton + <AppButton.TransparentButton onClick={this.props.onSelectLocation} aria-label={sprintf( messages.pgettext('accessibility', 'Select location. Current location is %(location)s'), @@ -254,7 +254,7 @@ export default class TunnelControl extends React.Component<ITunnelControlProps> )}> <AppButton.Label>{this.props.selectedRelayName}</AppButton.Label> <SelectedLocationChevron height={12} width={7} source="icon-chevron" /> - </SwitchLocationButton> + </AppButton.TransparentButton> ); } diff --git a/gui/src/renderer/components/UserInterfaceSettings.tsx b/gui/src/renderer/components/UserInterfaceSettings.tsx index 745ac715fb..315c3ad06c 100644 --- a/gui/src/renderer/components/UserInterfaceSettings.tsx +++ b/gui/src/renderer/components/UserInterfaceSettings.tsx @@ -108,16 +108,16 @@ function NotificationsSetting() { <Cell.Switch isOn={enableSystemNotifications} onChange={setEnableSystemNotifications} /> </AriaInput> </Cell.Container> - <Cell.Footer> + <Cell.CellFooter> <AriaDescription> - <Cell.FooterText> + <Cell.CellFooterText> {messages.pgettext( 'user-interface-settings-view', 'Enable or disable system notifications. The critical notifications will always be displayed.', )} - </Cell.FooterText> + </Cell.CellFooterText> </AriaDescription> - </Cell.Footer> + </Cell.CellFooter> </AriaInputGroup> ); } @@ -138,16 +138,16 @@ function MonochromaticTrayIconSetting() { <Cell.Switch isOn={monochromaticIcon} onChange={setMonochromaticIcon} /> </AriaInput> </Cell.Container> - <Cell.Footer> + <Cell.CellFooter> <AriaDescription> - <Cell.FooterText> + <Cell.CellFooterText> {messages.pgettext( 'user-interface-settings-view', 'Use a monochromatic tray icon instead of a colored one.', )} - </Cell.FooterText> + </Cell.CellFooterText> </AriaDescription> - </Cell.Footer> + </Cell.CellFooter> </AriaInputGroup> ); } @@ -168,16 +168,16 @@ function UnpinnedWindowSetting() { <Cell.Switch isOn={unpinnedWindow} onChange={setUnpinnedWindow} /> </AriaInput> </Cell.Container> - <Cell.Footer> + <Cell.CellFooter> <AriaDescription> - <Cell.FooterText> + <Cell.CellFooterText> {messages.pgettext( 'user-interface-settings-view', 'Enable to move the app around as a free-standing window.', )} - </Cell.FooterText> + </Cell.CellFooterText> </AriaDescription> - </Cell.Footer> + </Cell.CellFooter> </AriaInputGroup> ); } @@ -198,16 +198,16 @@ function StartMinimizedSetting() { <Cell.Switch isOn={startMinimized} onChange={setStartMinimized} /> </AriaInput> </Cell.Container> - <Cell.Footer> + <Cell.CellFooter> <AriaDescription> - <Cell.FooterText> + <Cell.CellFooterText> {messages.pgettext( 'user-interface-settings-view', 'Show only the tray icon when the app starts.', )} - </Cell.FooterText> + </Cell.CellFooterText> </AriaDescription> - </Cell.Footer> + </Cell.CellFooter> </AriaInputGroup> ); } diff --git a/gui/src/renderer/components/VpnSettings.tsx b/gui/src/renderer/components/VpnSettings.tsx index 76d8a782b6..f42c07e4d2 100644 --- a/gui/src/renderer/components/VpnSettings.tsx +++ b/gui/src/renderer/components/VpnSettings.tsx @@ -167,16 +167,16 @@ function AutoConnect() { <Cell.Switch isOn={autoConnect} onChange={setAutoConnect} /> </AriaInput> </Cell.Container> - <Cell.Footer> + <Cell.CellFooter> <AriaDescription> - <Cell.FooterText> + <Cell.CellFooterText> {messages.pgettext( 'vpn-settings-view', 'Automatically connect to a server when the app launches.', )} - </Cell.FooterText> + </Cell.CellFooterText> </AriaDescription> - </Cell.Footer> + </Cell.CellFooter> </AriaInputGroup> ); } @@ -197,16 +197,16 @@ function AllowLan() { <Cell.Switch isOn={allowLan} onChange={setAllowLan} /> </AriaInput> </Cell.Container> - <Cell.Footer> + <Cell.CellFooter> <AriaDescription> - <Cell.FooterText> + <Cell.CellFooterText> {messages.pgettext( 'vpn-settings-view', 'Allows access to other devices on the same network for sharing, printing etc.', )} - </Cell.FooterText> + </Cell.CellFooterText> </AriaDescription> - </Cell.Footer> + </Cell.CellFooter> </AriaInputGroup> ); } @@ -417,13 +417,13 @@ function CustomDnsEnabledFooter() { ); return ( - <Cell.Footer> + <Cell.CellFooter> <AriaDescription> - <Cell.FooterText> + <Cell.CellFooterText> {formatMarkdown(sprintf(blockingDisabledText, { customDnsFeatureName }))} - </Cell.FooterText> + </Cell.CellFooterText> </AriaDescription> - </Cell.Footer> + </Cell.CellFooter> ); } @@ -453,16 +453,16 @@ function EnableIpv6() { <Cell.Switch isOn={enableIpv6} onChange={setEnableIpv6} /> </AriaInput> </Cell.Container> - <Cell.Footer> + <Cell.CellFooter> <AriaDescription> - <Cell.FooterText> + <Cell.CellFooterText> {messages.pgettext( 'vpn-settings-view', 'Enable IPv6 communication through the tunnel.', )} - </Cell.FooterText> + </Cell.CellFooterText> </AriaDescription> - </Cell.Footer> + </Cell.CellFooter> </AriaInputGroup> ); } diff --git a/gui/src/renderer/components/WireguardSettings.tsx b/gui/src/renderer/components/WireguardSettings.tsx index 9a422cc18e..19afad9928 100644 --- a/gui/src/renderer/components/WireguardSettings.tsx +++ b/gui/src/renderer/components/WireguardSettings.tsx @@ -214,9 +214,9 @@ function PortSelector() { } /> </StyledSelectorContainer> - <Cell.Footer> + <Cell.CellFooter> <AriaDescription> - <Cell.FooterText> + <Cell.CellFooterText> { // TRANSLATORS: The hint displayed below the WireGuard port selector. messages.pgettext( @@ -224,9 +224,9 @@ function PortSelector() { 'The automatic setting will randomly choose from a wide range of ports.', ) } - </Cell.FooterText> + </Cell.CellFooterText> </AriaDescription> - </Cell.Footer> + </Cell.CellFooter> </AriaInputGroup> ); } @@ -389,9 +389,9 @@ function MultihopSetting() { <Cell.Switch isOn={multihop} onChange={setMultihop} /> </AriaInput> </Cell.Container> - <Cell.Footer> + <Cell.CellFooter> <AriaDescription> - <Cell.FooterText> + <Cell.CellFooterText> {sprintf( // TRANSLATORS: Description for multihop settings toggle. // TRANSLATORS: Available placeholders: @@ -402,9 +402,9 @@ function MultihopSetting() { ), { wireguard: strings.wireguard }, )} - </Cell.FooterText> + </Cell.CellFooterText> </AriaDescription> - </Cell.Footer> + </Cell.CellFooter> </AriaInputGroup> <ModalAlert isOpen={confirmationDialogVisible} @@ -482,9 +482,9 @@ function IpVersionSetting() { automaticValue={null} /> </StyledSelectorContainer> - <Cell.Footer> + <Cell.CellFooter> <AriaDescription> - <Cell.FooterText> + <Cell.CellFooterText> {sprintf( // TRANSLATORS: The hint displayed below the WireGuard IP version selector. // TRANSLATORS: Available placeholders: @@ -495,9 +495,9 @@ function IpVersionSetting() { ), { wireguard: strings.wireguard }, )} - </Cell.FooterText> + </Cell.CellFooterText> </AriaDescription> - </Cell.Footer> + </Cell.CellFooter> </AriaInputGroup> ); } @@ -555,9 +555,9 @@ function MtuSetting() { /> </AriaInput> </Cell.Container> - <Cell.Footer> + <Cell.CellFooter> <AriaDescription> - <Cell.FooterText> + <Cell.CellFooterText> {sprintf( // TRANSLATORS: The hint displayed below the WireGuard MTU input field. // TRANSLATORS: Available placeholders: @@ -574,9 +574,9 @@ function MtuSetting() { max: MAX_WIREGUARD_MTU_VALUE, }, )} - </Cell.FooterText> + </Cell.CellFooterText> </AriaDescription> - </Cell.Footer> + </Cell.CellFooter> </AriaInputGroup> ); } diff --git a/gui/src/renderer/components/cell/CellButton.tsx b/gui/src/renderer/components/cell/CellButton.tsx index e8d1c1c649..0111574f70 100644 --- a/gui/src/renderer/components/cell/CellButton.tsx +++ b/gui/src/renderer/components/cell/CellButton.tsx @@ -4,6 +4,7 @@ import styled from 'styled-components'; import { colors } from '../../../config.json'; import { CellDisabledContext } from './Container'; import { Icon } from './Label'; +import { Row } from './Row'; import { CellSectionContext } from './Section'; interface IStyledCellButtonProps extends React.HTMLAttributes<HTMLButtonElement> { @@ -11,7 +12,7 @@ interface IStyledCellButtonProps extends React.HTMLAttributes<HTMLButtonElement> containedInSection: boolean; } -const StyledCellButton = styled.button({}, (props: IStyledCellButtonProps) => { +const StyledCellButton = styled(Row)({}, (props: IStyledCellButtonProps) => { const backgroundColor = props.selected ? colors.green : props.containedInSection @@ -20,11 +21,8 @@ const StyledCellButton = styled.button({}, (props: IStyledCellButtonProps) => { const backgroundColorHover = props.selected ? colors.green : colors.blue80; return { - display: 'flex', - minHeight: '44px', - padding: '0 16px 0 22px', + paddingRight: '16px', flex: 1, - alignItems: 'center', alignContent: 'center', cursor: 'default', border: 'none', @@ -44,7 +42,12 @@ export const CellButton = styled( const containedInSection = useContext(CellSectionContext); return ( <CellDisabledContext.Provider value={props.disabled ?? false}> - <StyledCellButton ref={ref} containedInSection={containedInSection} {...props} /> + <StyledCellButton + as="button" + ref={ref} + containedInSection={containedInSection} + {...props} + /> </CellDisabledContext.Provider> ); }), diff --git a/gui/src/renderer/components/cell/Container.tsx b/gui/src/renderer/components/cell/Container.tsx index 6a2ef108c6..e35babf790 100644 --- a/gui/src/renderer/components/cell/Container.tsx +++ b/gui/src/renderer/components/cell/Container.tsx @@ -1,13 +1,9 @@ import React from 'react'; import styled from 'styled-components'; -import { colors } from '../../../config.json'; +import { Row } from './Row'; -const StyledContainer = styled.div({ - display: 'flex', - backgroundColor: colors.blue, - alignItems: 'center', - paddingLeft: '22px', +const StyledContainer = styled(Row)({ paddingRight: '16px', }); diff --git a/gui/src/renderer/components/cell/Footer.tsx b/gui/src/renderer/components/cell/Footer.tsx index 466ef4acca..86487c676c 100644 --- a/gui/src/renderer/components/cell/Footer.tsx +++ b/gui/src/renderer/components/cell/Footer.tsx @@ -1,16 +1,16 @@ import styled from 'styled-components'; import { colors } from '../../../config.json'; -import { tinyText } from '../common-styles'; +import { measurements, tinyText } from '../common-styles'; -export const Footer = styled.div({ - padding: '6px 22px 0px', +export const CellFooter = styled.div({ + padding: `6px ${measurements.viewMargin} 0px`, }); -export const FooterText = styled.span(tinyText, { +export const CellFooterText = styled.span(tinyText, { color: colors.white60, }); -export const FooterBoldText = styled(FooterText)({ +export const CellFooterBoldText = styled(CellFooterText)({ fontWeight: 900, }); diff --git a/gui/src/renderer/components/cell/Group.tsx b/gui/src/renderer/components/cell/Group.tsx index c167b2d525..a3198cabb0 100644 --- a/gui/src/renderer/components/cell/Group.tsx +++ b/gui/src/renderer/components/cell/Group.tsx @@ -1,39 +1,14 @@ -import React from 'react'; import styled from 'styled-components'; +import { measurements } from '../common-styles'; + interface IStyledGroupProps { noMarginBottom?: boolean; } -const StyledGroup = styled.div({}, (props: IStyledGroupProps) => ({ +export const Group = styled.div({}, (props: IStyledGroupProps) => ({ display: 'flex', flexDirection: 'column', flex: 1, - marginBottom: props.noMarginBottom ? '0px' : '20px', + marginBottom: props.noMarginBottom ? '0px' : measurements.rowVerticalMargin, })); - -const StyledCellWrapper = styled.div({ - display: 'flex', - flexDirection: 'column', - flex: 1, - marginBottom: '1px', -}); - -interface IGroupProps extends IStyledGroupProps { - children: React.ReactNode | React.ReactNode[]; -} - -export function Group(props: IGroupProps) { - const children = React.Children.toArray(props.children); - return ( - <StyledGroup noMarginBottom={props.noMarginBottom}> - {children.map((child, index) => - index === children.length - 1 ? ( - child - ) : ( - <StyledCellWrapper key={index}>{child}</StyledCellWrapper> - ), - )} - </StyledGroup> - ); -} diff --git a/gui/src/renderer/components/cell/Row.tsx b/gui/src/renderer/components/cell/Row.tsx new file mode 100644 index 0000000000..60a1ef6f9b --- /dev/null +++ b/gui/src/renderer/components/cell/Row.tsx @@ -0,0 +1,18 @@ +import styled from 'styled-components'; + +import { colors } from '../../../config.json'; +import { measurements } from '../common-styles'; +import { Group } from './Group'; + +export const Row = styled.div({ + display: 'flex', + alignItems: 'center', + backgroundColor: colors.blue, + minHeight: measurements.rowMinHeight, + paddingLeft: measurements.viewMargin, + paddingRight: measurements.viewMargin, + marginBottom: '1px', + [`${Group} > &:last-child`]: { + marginBottom: '0px', + }, +}); diff --git a/gui/src/renderer/components/cell/Section.tsx b/gui/src/renderer/components/cell/Section.tsx index 83c179d3cc..38df17ebdb 100644 --- a/gui/src/renderer/components/cell/Section.tsx +++ b/gui/src/renderer/components/cell/Section.tsx @@ -3,6 +3,7 @@ import styled from 'styled-components'; import { colors } from '../../../config.json'; import { buttonText, openSans, sourceSansPro } from '../common-styles'; +import { Row } from './Row'; const StyledSection = styled.div({ display: 'flex', @@ -14,12 +15,8 @@ interface SectionTitleProps { thin?: boolean; } -export const SectionTitle = styled.span(buttonText, (props: SectionTitleProps) => ({ - display: 'flex', - minHeight: '44px', - alignItems: 'center', - backgroundColor: colors.blue, - padding: '0 16px 0 22px', +export const SectionTitle = styled(Row)(buttonText, (props: SectionTitleProps) => ({ + paddingRight: '16px', color: props.disabled ? colors.white20 : colors.white, fontWeight: props.thin ? 400 : 600, fontSize: props.thin ? '15px' : '18px', diff --git a/gui/src/renderer/components/cell/Selector.tsx b/gui/src/renderer/components/cell/Selector.tsx index d898e3f51d..2c522178d6 100644 --- a/gui/src/renderer/components/cell/Selector.tsx +++ b/gui/src/renderer/components/cell/Selector.tsx @@ -106,10 +106,10 @@ export default function Selector<T, U>(props: SelectorProps<T, U>) { // Add potential additional items to the list. Used for custom entry. const children = ( - <> + <Cell.Group noMarginBottom> {items} {props.children} - </> + </Cell.Group> ); return ( @@ -172,7 +172,6 @@ interface StyledCustomContainerProps { } const StyledCustomContainer = styled(Cell.Container)((props: StyledCustomContainerProps) => ({ - minHeight: '44px', backgroundColor: props.selected ? colors.green : colors.blue40, ':hover': { backgroundColor: props.selected ? colors.green : colors.blue, diff --git a/gui/src/renderer/components/cell/index.ts b/gui/src/renderer/components/cell/index.ts index cc510e5b22..4e98c9ef3d 100644 --- a/gui/src/renderer/components/cell/index.ts +++ b/gui/src/renderer/components/cell/index.ts @@ -5,3 +5,4 @@ export * from './Input'; export * from './Label'; export * from './Section'; export * from './Group'; +export * from './Row'; diff --git a/gui/src/renderer/components/common-styles.ts b/gui/src/renderer/components/common-styles.ts index 641048d72d..b1a4af250b 100644 --- a/gui/src/renderer/components/common-styles.ts +++ b/gui/src/renderer/components/common-styles.ts @@ -57,3 +57,10 @@ export const hugeText = { lineHeight: '34px', color: colors.white, }; + +export const measurements = { + rowMinHeight: '44px', + viewMargin: '22px', + rowVerticalMargin: '20px', + buttonVerticalMargin: '18px', +}; |
