summaryrefslogtreecommitdiffhomepage
path: root/gui/src
diff options
context:
space:
mode:
authorOskar Nyberg <oskar@mullvad.net>2022-10-03 17:21:09 +0200
committerOskar Nyberg <oskar@mullvad.net>2022-10-03 17:21:09 +0200
commit31cd7cc00e587896d15bdeb24ef6f124a7260144 (patch)
tree6a864cd49cf0630f31892fa882e8e4c40e914e44 /gui/src
parent65ec42f0fa3979c13a91cf8ce0db89bfd55b4bb6 (diff)
parent92f20c1bee76c6e074604aa5169a7a35a214a0fa (diff)
downloadmullvadvpn-31cd7cc00e587896d15bdeb24ef6f124a7260144.tar.xz
mullvadvpn-31cd7cc00e587896d15bdeb24ef6f124a7260144.zip
Merge branch 'use-common-distance-definitions'
Diffstat (limited to 'gui/src')
-rw-r--r--gui/src/renderer/components/Account.tsx58
-rw-r--r--gui/src/renderer/components/AccountStyles.tsx22
-rw-r--r--gui/src/renderer/components/AppButton.tsx5
-rw-r--r--gui/src/renderer/components/CustomDnsSettings.tsx4
-rw-r--r--gui/src/renderer/components/CustomDnsSettingsStyles.tsx2
-rw-r--r--gui/src/renderer/components/DeviceRevokedView.tsx19
-rw-r--r--gui/src/renderer/components/ErrorView.tsx3
-rw-r--r--gui/src/renderer/components/ExpiredAccountAddTime.tsx25
-rw-r--r--gui/src/renderer/components/ExpiredAccountErrorView.tsx37
-rw-r--r--gui/src/renderer/components/ExpiredAccountErrorViewStyles.tsx19
-rw-r--r--gui/src/renderer/components/Filter.tsx27
-rw-r--r--gui/src/renderer/components/Layout.tsx11
-rw-r--r--gui/src/renderer/components/List.tsx1
-rw-r--r--gui/src/renderer/components/LocationRow.tsx10
-rw-r--r--gui/src/renderer/components/LoginStyles.tsx11
-rw-r--r--gui/src/renderer/components/Modal.tsx18
-rw-r--r--gui/src/renderer/components/OpenVpnSettings.tsx24
-rw-r--r--gui/src/renderer/components/ProblemReport.tsx54
-rw-r--r--gui/src/renderer/components/ProblemReportStyles.tsx16
-rw-r--r--gui/src/renderer/components/Settings.tsx6
-rw-r--r--gui/src/renderer/components/SettingsHeader.tsx7
-rw-r--r--gui/src/renderer/components/SettingsStyles.tsx4
-rw-r--r--gui/src/renderer/components/SplitTunnelingSettingsStyles.tsx20
-rw-r--r--gui/src/renderer/components/Support.tsx8
-rw-r--r--gui/src/renderer/components/TooManyDevices.tsx19
-rw-r--r--gui/src/renderer/components/TunnelControl.tsx62
-rw-r--r--gui/src/renderer/components/UserInterfaceSettings.tsx32
-rw-r--r--gui/src/renderer/components/VpnSettings.tsx32
-rw-r--r--gui/src/renderer/components/WireguardSettings.tsx32
-rw-r--r--gui/src/renderer/components/cell/CellButton.tsx15
-rw-r--r--gui/src/renderer/components/cell/Container.tsx8
-rw-r--r--gui/src/renderer/components/cell/Footer.tsx10
-rw-r--r--gui/src/renderer/components/cell/Group.tsx33
-rw-r--r--gui/src/renderer/components/cell/Row.tsx18
-rw-r--r--gui/src/renderer/components/cell/Section.tsx9
-rw-r--r--gui/src/renderer/components/cell/Selector.tsx5
-rw-r--r--gui/src/renderer/components/cell/index.ts1
-rw-r--r--gui/src/renderer/components/common-styles.ts7
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',
+};