summaryrefslogtreecommitdiffhomepage
path: root/gui/src
diff options
context:
space:
mode:
authorOskar Nyberg <oskar@mullvad.net>2020-05-07 09:06:47 +0200
committerOskar Nyberg <oskar@mullvad.net>2020-05-15 15:42:06 +0200
commit11bfac6e9dc3284057299611933a4f6fc92473e1 (patch)
tree16ebcd2c67f4d5af1a798b2632694ace856f3387 /gui/src
parent98c62cd60e88926b73168042a9bb46a95bcff92e (diff)
downloadmullvadvpn-11bfac6e9dc3284057299611933a4f6fc92473e1.tar.xz
mullvadvpn-11bfac6e9dc3284057299611933a4f6fc92473e1.zip
Convert Cell to Styled components
Diffstat (limited to 'gui/src')
-rw-r--r--gui/src/renderer/components/AdvancedSettings.tsx70
-rw-r--r--gui/src/renderer/components/AdvancedSettingsStyles.tsx24
-rw-r--r--gui/src/renderer/components/Cell.tsx385
-rw-r--r--gui/src/renderer/components/CellStyles.tsx266
-rw-r--r--gui/src/renderer/components/CityRow.tsx34
-rw-r--r--gui/src/renderer/components/CountryRow.tsx27
-rw-r--r--gui/src/renderer/components/LocationList.tsx2
-rw-r--r--gui/src/renderer/components/Login.tsx22
-rw-r--r--gui/src/renderer/components/LoginStyles.tsx57
-rw-r--r--gui/src/renderer/components/RelayRow.tsx26
-rw-r--r--gui/src/renderer/components/SelectLanguage.tsx11
-rw-r--r--gui/src/renderer/components/Selector.tsx25
-rw-r--r--gui/src/renderer/components/Settings.tsx22
-rw-r--r--gui/src/renderer/components/SettingsStyles.tsx12
-rw-r--r--gui/src/renderer/components/Switch.tsx6
15 files changed, 401 insertions, 588 deletions
diff --git a/gui/src/renderer/components/AdvancedSettings.tsx b/gui/src/renderer/components/AdvancedSettings.tsx
index 2bcd0d44d8..ecc93a2544 100644
--- a/gui/src/renderer/components/AdvancedSettings.tsx
+++ b/gui/src/renderer/components/AdvancedSettings.tsx
@@ -4,7 +4,11 @@ import { sprintf } from 'sprintf-js';
import { BridgeState, RelayProtocol, TunnelProtocol } from '../../shared/daemon-rpc-types';
import { messages } from '../../shared/gettext';
import { WgKeyState } from '../redux/settings/reducers';
-import styles from './AdvancedSettingsStyles';
+import styles, {
+ BlockWhenDisconnectedLabel,
+ InputFrame,
+ TunnelProtocolSelector,
+} from './AdvancedSettingsStyles';
import * as AppButton from './AppButton';
import * as Cell from './Cell';
import { Container, Layout } from './Layout';
@@ -181,10 +185,9 @@ export default class AdvancedSettings extends Component<IProps, IState> {
</Cell.Footer>
<Cell.Container>
- <Cell.Label
- textStyle={styles.advanced_settings__block_when_disconnected_label}>
+ <BlockWhenDisconnectedLabel>
{messages.pgettext('advanced-settings-view', 'Always require VPN')}
- </Cell.Label>
+ </BlockWhenDisconnectedLabel>
<Cell.Switch
isOn={this.props.blockWhenDisconnected}
onChange={this.setBlockWhenDisconnected}
@@ -204,12 +207,11 @@ export default class AdvancedSettings extends Component<IProps, IState> {
styles.advanced_settings__content,
styles.advanced_settings__tunnel_protocol,
]}>
- <Selector
+ <TunnelProtocolSelector
title={messages.pgettext('advanced-settings-view', 'Tunnel protocol')}
values={this.tunnelProtocolItems(hasWireguardKey)}
value={this.props.tunnelProtocol}
onSelect={this.onSelectTunnelProtocol}
- style={styles.advanced_settings__tunnel_protocol_selector}
/>
{!hasWireguardKey && (
<Text style={styles.advanced_settings__wg_no_key}>
@@ -281,20 +283,18 @@ export default class AdvancedSettings extends Component<IProps, IState> {
<Cell.Label>
{messages.pgettext('advanced-settings-view', 'OpenVPN Mssfix')}
</Cell.Label>
- <Cell.InputFrame style={styles.advanced_settings__input_frame}>
- <Cell.AutoSizingTextInputContainer>
- <Cell.Input
- value={this.props.mssfix ? this.props.mssfix.toString() : ''}
- keyboardType={'numeric'}
- maxLength={4}
- placeholder={messages.pgettext('advanced-settings-view', 'Default')}
- onSubmit={this.onMssfixSubmit}
- validateValue={AdvancedSettings.mssfixIsValid}
- submitOnBlur={true}
- modifyValue={AdvancedSettings.removeNonNumericCharacters}
- />
- </Cell.AutoSizingTextInputContainer>
- </Cell.InputFrame>
+ <InputFrame>
+ <Cell.AutoSizingTextInput
+ value={this.props.mssfix ? this.props.mssfix.toString() : ''}
+ inputMode={'numeric'}
+ maxLength={4}
+ placeholder={messages.pgettext('advanced-settings-view', 'Default')}
+ onSubmitValue={this.onMssfixSubmit}
+ validateValue={AdvancedSettings.mssfixIsValid}
+ submitOnBlur={true}
+ modifyValue={AdvancedSettings.removeNonNumericCharacters}
+ />
+ </InputFrame>
</Cell.Container>
<Cell.Footer>
<Cell.FooterText>
@@ -319,22 +319,18 @@ export default class AdvancedSettings extends Component<IProps, IState> {
<Cell.Label>
{messages.pgettext('advanced-settings-view', 'WireGuard MTU')}
</Cell.Label>
- <Cell.InputFrame style={styles.advanced_settings__input_frame}>
- <Cell.AutoSizingTextInputContainer>
- <Cell.Input
- value={
- this.props.wireguardMtu ? this.props.wireguardMtu.toString() : ''
- }
- keyboardType={'numeric'}
- maxLength={4}
- placeholder={messages.pgettext('advanced-settings-view', 'Default')}
- onSubmit={this.onWireguardMtuSubmit}
- validateValue={AdvancedSettings.wireguarMtuIsValid}
- submitOnBlur={true}
- modifyValue={AdvancedSettings.removeNonNumericCharacters}
- />
- </Cell.AutoSizingTextInputContainer>
- </Cell.InputFrame>
+ <InputFrame>
+ <Cell.AutoSizingTextInput
+ value={this.props.wireguardMtu ? this.props.wireguardMtu.toString() : ''}
+ inputMode={'numeric'}
+ maxLength={4}
+ placeholder={messages.pgettext('advanced-settings-view', 'Default')}
+ onSubmitValue={this.onWireguardMtuSubmit}
+ validateValue={AdvancedSettings.wireguarMtuIsValid}
+ submitOnBlur={true}
+ modifyValue={AdvancedSettings.removeNonNumericCharacters}
+ />
+ </InputFrame>
</Cell.Container>
<Cell.Footer>
<Cell.FooterText>
@@ -356,7 +352,7 @@ export default class AdvancedSettings extends Component<IProps, IState> {
</Cell.Footer>
<View style={styles.advanced_settings__wgkeys_cell}>
- <Cell.CellButton onPress={this.props.onViewWireguardKeys}>
+ <Cell.CellButton onClick={this.props.onViewWireguardKeys}>
<Cell.Label>
{messages.pgettext('advanced-settings-view', 'WireGuard key')}
</Cell.Label>
diff --git a/gui/src/renderer/components/AdvancedSettingsStyles.tsx b/gui/src/renderer/components/AdvancedSettingsStyles.tsx
index 737a3e1acd..721df6cf55 100644
--- a/gui/src/renderer/components/AdvancedSettingsStyles.tsx
+++ b/gui/src/renderer/components/AdvancedSettingsStyles.tsx
@@ -1,5 +1,20 @@
import { Styles } from 'reactxp';
+import styled from 'styled-components';
import { colors } from '../../config.json';
+import * as Cell from './Cell';
+import Selector from './Selector';
+
+export const InputFrame = styled(Cell.InputFrame)({
+ flex: 0,
+});
+
+export const BlockWhenDisconnectedLabel = styled(Cell.Label)({
+ letterSpacing: -0.5,
+});
+
+export const TunnelProtocolSelector = (styled(Selector)({
+ marginBottom: 0,
+}) as unknown) as new <T>() => Selector<T>;
export default {
advanced_settings: Styles.createViewStyle({
@@ -19,9 +34,6 @@ export default {
advanced_settings__tunnel_protocol: Styles.createViewStyle({
marginBottom: 24,
}),
- advanced_settings__tunnel_protocol_selector: Styles.createViewStyle({
- marginBottom: 0,
- }),
advanced_settings__wgkeys_cell: Styles.createViewStyle({
marginBottom: 24,
}),
@@ -55,10 +67,4 @@ export default {
advanced_settings__cell_footer_internet_warning_label: Styles.createTextStyle({
marginTop: 4,
}),
- advanced_settings__input_frame: Styles.createViewStyle({
- flex: 0,
- }),
- advanced_settings__block_when_disconnected_label: Styles.createTextStyle({
- letterSpacing: -0.5,
- }),
};
diff --git a/gui/src/renderer/components/Cell.tsx b/gui/src/renderer/components/Cell.tsx
index 04fc0729b8..23f63114b7 100644
--- a/gui/src/renderer/components/Cell.tsx
+++ b/gui/src/renderer/components/Cell.tsx
@@ -1,164 +1,62 @@
-import * as React from 'react';
-import { Button, Component, Styles, Text, TextInput, Types, View } from 'reactxp';
-import { colors } from '../../config.json';
-import styles, { StyledIcon } from './CellStyles';
-import { IImageViewProps } from './ImageView';
-import { default as SwitchControl } from './Switch';
+import React, { useCallback, useContext, useState } from 'react';
+import {
+ StyledAutoSizingTextInputContainer,
+ StyledAutoSizingTextInputWrapper,
+ StyledAutoSizingTextInputFiller,
+ StyledCellButton,
+ StyledSection,
+ StyledInput,
+} from './CellStyles';
-export { StyledIcon as UntintedIcon } from './CellStyles';
+export {
+ StyledContainer as Container,
+ StyledFooter as Footer,
+ StyledFooterBoldText as FooterBoldText,
+ StyledFooterText as FooterText,
+ StyledIcon as UntintedIcon,
+ StyledInputFrame as InputFrame,
+ StyledLabel as Label,
+ StyledSectionTitle as SectionTitle,
+ StyledSubText as SubText,
+ StyledTintedIcon as Icon,
+} from './CellStyles';
-interface ICellButtonProps {
- children?: React.ReactNode;
- disabled?: boolean;
- selected?: boolean;
- style?: Types.StyleRuleSetRecursive<Types.ButtonStyleRuleSet>;
- hoverStyle?: Types.StyleRuleSetRecursive<Types.ButtonStyleRuleSet>;
- onPress?: () => void;
-}
-
-interface IState {
- hovered: boolean;
-}
+export { default as Switch } from './Switch';
const CellSectionContext = React.createContext<boolean>(false);
-const CellHoverContext = React.createContext<boolean>(false);
-
-export class CellButton extends Component<ICellButtonProps, IState> {
- public state: IState = { hovered: false };
-
- public onHoverStart = () => (!this.props.disabled ? this.setState({ hovered: true }) : null);
- public onHoverEnd = () => (!this.props.disabled ? this.setState({ hovered: false }) : null);
-
- public render() {
- const { children, style, hoverStyle, ...otherProps } = this.props;
-
- const stateStyle = this.props.selected
- ? styles.cellButton.selected
- : this.state.hovered
- ? hoverStyle || styles.cellButton.hover
- : undefined;
- return (
- <CellSectionContext.Consumer>
- {(containedInSection) => (
- <Button
- style={[
- styles.cellButton.base,
- containedInSection ? styles.cellButton.section : undefined,
- style,
- stateStyle,
- ]}
- onHoverStart={this.onHoverStart}
- onHoverEnd={this.onHoverEnd}
- {...otherProps}>
- <CellHoverContext.Provider value={this.state.hovered}>
- {children}
- </CellHoverContext.Provider>
- </Button>
- )}
- </CellSectionContext.Consumer>
- );
- }
-}
-
-interface ISectionTitleProps {
- children?: React.ReactText;
+interface ICellButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
+ selected?: boolean;
}
-export const SectionTitle = function CellSectionTitle(props: ISectionTitleProps) {
- return <Text style={styles.sectionTitle}>{props.children}</Text>;
-};
+export const CellButton = React.forwardRef(function Button(
+ props: ICellButtonProps,
+ ref: React.Ref<HTMLButtonElement>,
+) {
+ const containedInSection = useContext(CellSectionContext);
+ return <StyledCellButton ref={ref} containedInSection={containedInSection} {...props} />;
+});
interface ISectionProps {
children?: React.ReactNode;
- style?: Types.StyleRuleSetRecursive<Types.ViewStyleRuleSet>;
-}
-
-export const Section = class CellSection extends Component<ISectionProps> {
- public render() {
- return (
- <View style={this.props.style}>
- <CellSectionContext.Provider value={true}>
- {this.props.children}
- </CellSectionContext.Provider>
- </View>
- );
- }
-};
-
-interface IContainerProps {
- children: React.ReactNode;
-}
-
-export const Container = function CellContainer({ children }: IContainerProps) {
- return <View style={styles.cellContainer}>{children}</View>;
-};
-
-interface ILabelProps {
- containerStyle?: Types.ViewStyleRuleSet;
- textStyle?: Types.TextStyleRuleSet;
- cellHoverContainerStyle?: Types.ViewStyleRuleSet;
- cellHoverTextStyle?: Types.TextStyleRuleSet;
- onPress?: (event: Types.SyntheticEvent) => void;
- children?: React.ReactNode;
+ className?: string;
}
-export const Label = function CellLabel(props: ILabelProps) {
- const {
- children,
- containerStyle,
- textStyle,
- cellHoverContainerStyle,
- cellHoverTextStyle,
- ...otherProps
- } = props;
-
- return (
- <CellHoverContext.Consumer>
- {(hovered) => (
- <View
- style={[
- styles.label.container,
- containerStyle,
- hovered ? cellHoverContainerStyle : undefined,
- ]}
- {...otherProps}>
- <Text style={[styles.label.text, textStyle, hovered ? cellHoverTextStyle : undefined]}>
- {children}
- </Text>
- </View>
- )}
- </CellHoverContext.Consumer>
- );
-};
-
-export const Switch = React.forwardRef(function CellSwitch(
- props: SwitchControl['props'],
- ref?: React.Ref<SwitchControl>,
-) {
+export function Section(props: ISectionProps) {
return (
- <View style={styles.switch}>
- <SwitchControl ref={ref} {...props} />
- </View>
+ <StyledSection className={props.className}>
+ <CellSectionContext.Provider value={true}>{props.children}</CellSectionContext.Provider>
+ </StyledSection>
);
-});
-
-interface IInputFrameProps {
- children?: React.ReactNode;
- style?: Types.StyleRuleSetRecursive<Types.ViewStyleRuleSet>;
}
-export const InputFrame = function CellInputFrame(props: IInputFrameProps) {
- const { style, children } = props;
-
- return <View style={[styles.input.frame, style]}>{children}</View>;
-};
-
-interface IInputProps extends Types.TextInputProps {
+interface IInputProps extends React.InputHTMLAttributes<HTMLInputElement> {
+ value?: string;
validateValue?: (value: string) => boolean;
modifyValue?: (value: string) => string;
submitOnBlur?: boolean;
- onSubmit?: (value: string) => void;
+ onSubmitValue?: (value: string) => void;
+ onChangeValue?: (value: string) => void;
}
interface IInputState {
@@ -166,9 +64,9 @@ interface IInputState {
focused: boolean;
}
-export class Input extends Component<IInputProps, IInputState> {
+export class Input extends React.Component<IInputProps, IInputState> {
public state = {
- value: this.props.value || '',
+ value: this.props.value ?? '',
focused: false,
};
@@ -178,187 +76,94 @@ export class Input extends Component<IInputProps, IInputState> {
prevProps.value !== this.props.value &&
this.props.value !== this.state.value
) {
- this.setState((_state, props) => ({
- value: props.value,
- }));
+ this.setState(
+ (_state, props) => ({
+ value: props.value,
+ }),
+ () => {
+ this.props.onChangeValue?.(this.state.value);
+ },
+ );
}
}
public render() {
const {
- style,
- value: _value,
- onChangeText: _onChangeText,
+ type: _type,
+ onChange: _onChange,
onFocus: _onFocus,
onBlur: _onBlur,
- onSubmitEditing: _onSubmitEditing,
+ onKeyPress: _onKeyPress,
+ value: _value,
+ modifyValue: _modifyValue,
+ submitOnBlur: _submitOnBlur,
+ onChangeValue: _onChangeValue,
+ onSubmitValue: _onSubmitValue,
+ validateValue,
...otherProps
} = this.props;
- const validityStyle =
- this.props.validateValue && this.props.validateValue(this.state.value)
- ? styles.input.validValue
- : styles.input.invalidValue;
-
return (
- <TextInput
- placeholderTextColor={colors.white60}
- autoCorrect={false}
- style={[styles.input.text, validityStyle, style]}
- onChangeText={this.onChangeText}
+ <StyledInput
+ type="text"
+ valid={validateValue?.(this.state.value)}
+ onChange={this.onChange}
onFocus={this.onFocus}
onBlur={this.onBlur}
- onSubmitEditing={this.onSubmitEditing}
+ onKeyPress={this.onKeyPress}
value={this.state.value}
{...otherProps}
/>
);
}
- private onChangeText = (value: string) => {
+ private onChange = (event: React.ChangeEvent<HTMLInputElement>) => {
+ const value = this.props.modifyValue?.(event.target.value) ?? event.target.value;
this.setState({ value });
- if (this.props.onChangeText) {
- this.props.onChangeText(value);
- }
+ this.props.onChange?.(event);
+ this.props.onChangeValue?.(value);
};
- private onFocus = (e: Types.FocusEvent) => {
+ private onFocus = (event: React.FocusEvent<HTMLInputElement>) => {
this.setState({ focused: true });
- if (this.props.onFocus) {
- this.props.onFocus(e);
- }
+ this.props.onFocus?.(event);
};
- private onBlur = (e: Types.FocusEvent) => {
+ private onBlur = (event: React.FocusEvent<HTMLInputElement>) => {
this.setState({ focused: false });
- if (this.props.onBlur) {
- this.props.onBlur(e);
- }
- if (this.props.submitOnBlur && this.props.onSubmit) {
- this.props.onSubmit(this.state.value);
+ this.props.onBlur?.(event);
+ if (this.props.submitOnBlur) {
+ this.props.onSubmitValue?.(this.state.value);
}
};
- private onSubmitEditing = () => {
- if (this.props.onSubmit) {
- this.props.onSubmit(this.state.value);
- }
- if (this.props.onSubmitEditing) {
- this.props.onSubmitEditing();
+ private onKeyPress = (event: React.KeyboardEvent<HTMLInputElement>) => {
+ if (event.key === 'Enter') {
+ this.props.onSubmitValue?.(this.state.value);
}
+ this.props.onKeyPress?.(event);
};
}
-interface IAutoSizingTextInputContainerProps {
- style?: Types.StyleRuleSetRecursive<Types.ViewStyleRuleSet>;
- children: React.ReactElement<Types.TextInputProps>;
-}
-
-interface IAutoSizingTextInputContainerState {
- placeholderWidth?: number;
- widthStyle?: Types.TextInputStyleRuleSet;
-}
-
-export const AutoSizingTextInputContainer = class CellAutoSizingTextInputContainer extends Component<
- IAutoSizingTextInputContainerProps,
- IAutoSizingTextInputContainerState
-> {
- public state: IAutoSizingTextInputContainerState = {};
-
- public render() {
- const children: React.ReactElement<Types.TextInputProps> = this.props.children;
-
- return (
- <View style={this.props.style}>
- <View style={styles.autoSizingInputContainer.measuringView} onLayout={this.onLayout}>
- <Text
- style={[
- styles.input.text,
-
- // TextInputStyle is basically an alias for TextStyle, so it's legit to assume that we
- // can use both of them interchangably.
- children.props.style,
-
- // this style resets any style properties that could constraint the text width.
- styles.autoSizingInputContainer.measureText,
- ]}
- numberOfLines={1}>
- {children.props.placeholder}
- </Text>
- </View>
+export function AutoSizingTextInput({ onChangeValue, ...otherProps }: IInputProps) {
+ const [value, setValue] = useState(otherProps.value ?? '');
- {React.cloneElement(children, {
- ...children.props,
- style: [children.props.style, this.state.widthStyle],
- })}
- </View>
- );
- }
-
- private onLayout = (layout: Types.ViewOnLayoutEvent) => {
- if (this.state.placeholderWidth !== layout.width) {
- this.setState({
- placeholderWidth: layout.width,
- widthStyle: Styles.createTextInputStyle(
- {
- width: layout.width,
- },
- false,
- ),
- });
- }
- };
-};
-
-type SubTextProps = Types.TextProps & {
- cellHoverStyle?: Types.ViewStyle;
-};
-
-export const SubText = function CellSubText(props: SubTextProps) {
- const { children, ref: _, style, cellHoverStyle, ...otherProps } = props;
-
- return (
- <CellHoverContext.Consumer>
- {(hovered) => (
- <Text style={[styles.subtext, style, hovered ? cellHoverStyle : undefined]} {...otherProps}>
- {children}
- </Text>
- )}
- </CellHoverContext.Consumer>
+ const onChangeValueWrapper = useCallback(
+ (value: string) => {
+ setValue(value);
+ onChangeValue?.(value);
+ },
+ [onChangeValue],
);
-};
-export const Icon = function CellIcon(props: IImageViewProps) {
- const { tintColor, tintHoverColor, ...otherProps } = props;
-
- return (
- <CellHoverContext.Consumer>
- {(hovered) => (
- <StyledIcon
- tintColor={(hovered && tintHoverColor) || tintColor || colors.white60}
- {...otherProps}
- />
- )}
- </CellHoverContext.Consumer>
- );
-};
-
-export const Footer = function CellFooter({ children }: IContainerProps) {
- return <View style={styles.footer.container}>{children}</View>;
-};
-
-export const FooterText = function CellFooterText(props: Text['props']) {
return (
- <Text {...props} style={[styles.footer.text, props.style]}>
- {props.children}
- </Text>
+ <StyledAutoSizingTextInputContainer>
+ <StyledAutoSizingTextInputWrapper>
+ <Input onChangeValue={onChangeValueWrapper} {...otherProps} />
+ </StyledAutoSizingTextInputWrapper>
+ <StyledAutoSizingTextInputFiller className={otherProps.className}>
+ {value === '' ? otherProps.placeholder : value}
+ </StyledAutoSizingTextInputFiller>
+ </StyledAutoSizingTextInputContainer>
);
-};
-
-export const FooterBoldText = function CellFooterText(props: Text['props']) {
- return (
- <Text {...props} style={[styles.footer.text, styles.footer.boldText, props.style]}>
- {props.children}
- </Text>
- );
-};
+}
diff --git a/gui/src/renderer/components/CellStyles.tsx b/gui/src/renderer/components/CellStyles.tsx
index 045ad3c6ff..40b27abbb0 100644
--- a/gui/src/renderer/components/CellStyles.tsx
+++ b/gui/src/renderer/components/CellStyles.tsx
@@ -1,133 +1,151 @@
-import { Styles } from 'reactxp';
+import React from 'react';
import styled from 'styled-components';
import { colors } from '../../config.json';
-import ImageView from './ImageView';
+import ImageView, { IImageViewProps } from './ImageView';
+
+export const StyledContainer = styled.div({
+ display: 'flex',
+ backgroundColor: colors.blue,
+ alignItems: 'center',
+ paddingLeft: '16px',
+ paddingRight: '12px',
+});
+
+export const StyledSection = styled.div({
+ display: 'flex',
+ flexDirection: 'column',
+});
+
+export const StyledSectionTitle = styled.span({
+ backgroundColor: colors.blue,
+ padding: '14px 24px',
+ marginBottom: '1px',
+ fontFamily: 'DINPro',
+ fontSize: '20px',
+ fontWeight: 900,
+ lineHeight: '26px',
+ color: colors.white,
+});
+
+interface IStyledCellButtonProps {
+ selected?: boolean;
+ containedInSection: boolean;
+}
+
+export const StyledCellButton = styled.button({}, (props: IStyledCellButtonProps) => ({
+ display: 'flex',
+ padding: '0 16px',
+ marginBottom: '1px',
+ flex: 1,
+ alignItems: 'center',
+ alignContent: 'center',
+ cursor: 'default',
+ border: 'none',
+ backgroundColor: props.selected
+ ? colors.green
+ : props.containedInSection
+ ? colors.blue40
+ : colors.blue,
+ ':not(:disabled):hover': {
+ backgroundColor: props.selected ? colors.green : colors.blue80,
+ },
+}));
+
+export const StyledLabel = styled.div({
+ margin: '14px 0 14px 8px',
+ flex: 1,
+ fontFamily: 'DINPro',
+ fontSize: '20px',
+ fontWeight: 900,
+ lineHeight: '26px',
+ letterSpacing: -0.2,
+ color: colors.white,
+ textAlign: 'left',
+});
+
+export const StyledSubText = styled.span({
+ color: colors.white60,
+ fontFamily: 'Open Sans',
+ fontSize: '13px',
+ fontWeight: 800,
+ flex: -1,
+ textAlign: 'right',
+ marginLeft: '8px',
+});
export const StyledIcon = styled(ImageView)({
marginLeft: '8px',
});
-export default {
- cellButton: {
- base: Styles.createButtonStyle({
- backgroundColor: colors.blue,
- paddingVertical: 0,
- paddingHorizontal: 16,
- marginBottom: 1,
- flex: 1,
- flexDirection: 'row',
- alignItems: 'center',
- alignContent: 'center',
- cursor: 'default',
- }),
- section: Styles.createButtonStyle({
- backgroundColor: colors.blue40,
- }),
- hover: Styles.createButtonStyle({
- backgroundColor: colors.blue80,
- }),
- selected: Styles.createViewStyle({
- backgroundColor: colors.green,
- }),
- },
- cellContainer: Styles.createViewStyle({
- backgroundColor: colors.blue,
- flexDirection: 'row',
- alignItems: 'center',
- paddingLeft: 16,
- paddingRight: 12,
- }),
- footer: {
- container: Styles.createViewStyle({
- paddingTop: 8,
- paddingRight: 24,
- paddingBottom: 24,
- paddingLeft: 24,
- }),
- text: Styles.createTextStyle({
- fontFamily: 'Open Sans',
- fontSize: 13,
- fontWeight: '600',
- lineHeight: 20,
- letterSpacing: -0.2,
- color: colors.white80,
- }),
- boldText: Styles.createTextStyle({
- fontWeight: '900',
- }),
+export const StyledTintedIcon = styled(StyledIcon).attrs((props: IImageViewProps) => ({
+ tintColor: props.tintColor ?? colors.white60,
+ tintHoverColor: props.tintHoverColor ?? props.tintColor ?? colors.white60,
+}))((props: IImageViewProps) => ({
+ [StyledCellButton + ':hover &']: {
+ backgroundColor: props.tintHoverColor,
},
- label: {
- container: Styles.createViewStyle({
- marginLeft: 8,
- marginTop: 14,
- marginBottom: 14,
- flex: 1,
- }),
- text: Styles.createTextStyle({
- fontFamily: 'DINPro',
- fontSize: 20,
- fontWeight: '900',
- lineHeight: 26,
- letterSpacing: -0.2,
- color: colors.white,
- }),
- },
- switch: Styles.createViewStyle({
- flex: 0,
- }),
- input: {
- frame: Styles.createViewStyle({
- flexGrow: 0,
- backgroundColor: 'rgba(255,255,255,0.1)',
- borderRadius: 4,
- padding: 4,
- }),
- text: Styles.createTextInputStyle({
- color: colors.white,
- backgroundColor: 'transparent',
- fontFamily: 'Open Sans',
- fontSize: 20,
- fontWeight: '600',
- lineHeight: 26,
- textAlign: 'right',
- padding: 0,
- minWidth: 80,
- }),
- validValue: Styles.createTextStyle({
- color: colors.white,
- }),
- invalidValue: Styles.createTextStyle({
- color: colors.red,
- }),
- },
- autoSizingInputContainer: {
- measuringView: Styles.createViewStyle({
- position: 'absolute',
- opacity: 0,
- }),
- measureText: Styles.createTextStyle({
- width: undefined,
- flexBasis: undefined,
- }),
- },
- subtext: Styles.createTextStyle({
- color: colors.white60,
- fontFamily: 'Open Sans',
- fontSize: 13,
- fontWeight: '800',
- flex: -1,
- textAlign: 'right',
- marginLeft: 8,
- }),
- sectionTitle: Styles.createTextStyle({
- backgroundColor: colors.blue,
- paddingVertical: 14,
- paddingHorizontal: 24,
- marginBottom: 1,
- fontFamily: 'DINPro',
- fontSize: 20,
- fontWeight: '900',
- lineHeight: 26,
- color: colors.white,
- }),
+}));
+
+export const StyledFooter = styled.div({
+ padding: '8px 24px 24px',
+});
+
+export const StyledFooterText = styled.span({
+ fontFamily: 'Open Sans',
+ fontSize: '13px',
+ fontWeight: 600,
+ lineHeight: '20px',
+ letterSpacing: -0.2,
+ color: colors.white80,
+});
+
+export const StyledFooterBoldText = styled(StyledFooterText)({
+ fontWeight: 900,
+});
+
+export const StyledInputFrame = styled.div({
+ flexGrow: 0,
+ backgroundColor: 'rgba(255,255,255,0.1)',
+ borderRadius: '4px',
+ padding: '4px',
+});
+
+const inputTextStyles: React.CSSProperties = {
+ fontFamily: 'Open Sans',
+ fontSize: '20px',
+ fontWeight: 600,
+ lineHeight: '26px',
+ height: '26px',
+ textAlign: 'right',
+ padding: '0px',
};
+
+export const StyledInput = styled.input({}, (props: { valid?: boolean }) => ({
+ ...inputTextStyles,
+ backgroundColor: 'transparent',
+ border: 'none',
+ width: '100%',
+ height: '100%',
+ color: props.valid !== false ? colors.white : colors.red,
+ '::placeholder': {
+ color: colors.white60,
+ },
+}));
+
+export const StyledAutoSizingTextInputContainer = styled.div({
+ position: 'relative',
+});
+
+export const StyledAutoSizingTextInputFiller = styled.pre({
+ ...inputTextStyles,
+ minWidth: '80px',
+ color: 'transparent',
+});
+
+export const StyledAutoSizingTextInputWrapper = styled.div({
+ position: 'absolute',
+ top: '0px',
+ left: '0px',
+ width: '100%',
+ height: '100%',
+});
diff --git a/gui/src/renderer/components/CityRow.tsx b/gui/src/renderer/components/CityRow.tsx
index 472c468222..65f8e1075c 100644
--- a/gui/src/renderer/components/CityRow.tsx
+++ b/gui/src/renderer/components/CityRow.tsx
@@ -1,6 +1,6 @@
import * as React from 'react';
-import ReactDOM from 'react-dom';
-import { Component, Styles, View } from 'reactxp';
+import { Component, View } from 'reactxp';
+import styled from 'styled-components';
import { colors } from '../../config.json';
import { compareRelayLocation, RelayLocation } from '../../shared/daemon-rpc-types';
import Accordion from './Accordion';
@@ -24,16 +24,14 @@ interface IProps {
children?: RelayRowElement | RelayRowElement[];
}
-const styles = {
- base: Styles.createButtonStyle({
- paddingRight: 0,
- paddingLeft: 32,
- backgroundColor: colors.blue40,
- }),
-};
+const Button = styled(Cell.CellButton)((props: { selected: boolean }) => ({
+ paddingRight: 0,
+ paddingLeft: 32,
+ backgroundColor: !props.selected ? colors.blue40 : undefined,
+}));
export default class CityRow extends Component<IProps> {
- private buttonRef = React.createRef<Cell.CellButton>();
+ private buttonRef = React.createRef<HTMLButtonElement>();
public static compareProps(oldProps: IProps, nextProps: IProps): boolean {
if (React.Children.count(oldProps.children) !== React.Children.count(nextProps.children)) {
@@ -74,12 +72,11 @@ export default class CityRow extends Component<IProps> {
return (
<View>
- <Cell.CellButton
+ <Button
ref={this.buttonRef}
- onPress={this.handlePress}
+ onClick={this.handleClick}
disabled={!this.props.hasActiveRelays}
- selected={this.props.selected}
- style={styles.base}>
+ selected={this.props.selected}>
<RelayStatusIndicator
active={this.props.hasActiveRelays}
selected={this.props.selected}
@@ -87,7 +84,7 @@ export default class CityRow extends Component<IProps> {
<Cell.Label>{this.props.name}</Cell.Label>
{hasChildren && <ChevronButton onClick={this.toggleCollapse} up={this.props.expanded} />}
- </Cell.CellButton>
+ </Button>
{hasChildren && (
<Accordion
@@ -109,16 +106,15 @@ export default class CityRow extends Component<IProps> {
event.stopPropagation();
};
- private handlePress = () => {
+ private handleClick = () => {
if (this.props.onSelect) {
this.props.onSelect(this.props.location);
}
};
private onWillExpand = (nextHeight: number) => {
- const buttonNode = ReactDOM.findDOMNode(this.buttonRef.current);
- if (buttonNode instanceof HTMLElement) {
- const buttonRect = buttonNode.getBoundingClientRect();
+ const buttonRect = this.buttonRef.current?.getBoundingClientRect();
+ if (buttonRect) {
this.props.onWillExpand?.(buttonRect, nextHeight);
}
};
diff --git a/gui/src/renderer/components/CountryRow.tsx b/gui/src/renderer/components/CountryRow.tsx
index a541403cbd..35a082a27a 100644
--- a/gui/src/renderer/components/CountryRow.tsx
+++ b/gui/src/renderer/components/CountryRow.tsx
@@ -1,6 +1,6 @@
import * as React from 'react';
-import ReactDOM from 'react-dom';
import { Component, Styles, View } from 'reactxp';
+import styled from 'styled-components';
import { compareRelayLocation, RelayLocation } from '../../shared/daemon-rpc-types';
import Accordion from './Accordion';
import * as Cell from './Cell';
@@ -28,14 +28,15 @@ const styles = {
flexDirection: 'column',
flex: 0,
}),
- base: Styles.createViewStyle({
- paddingRight: 0,
- paddingLeft: 16,
- }),
};
+const Button = styled(Cell.CellButton)({
+ paddingRight: 0,
+ paddingLeft: 16,
+});
+
export default class CountryRow extends Component<IProps> {
- private buttonRef = React.createRef<Cell.CellButton>();
+ private buttonRef = React.createRef<HTMLButtonElement>();
public static compareProps(oldProps: IProps, nextProps: IProps) {
if (React.Children.count(oldProps.children) !== React.Children.count(nextProps.children)) {
@@ -82,10 +83,9 @@ export default class CountryRow extends Component<IProps> {
return (
<View style={styles.container}>
- <Cell.CellButton
+ <Button
ref={this.buttonRef}
- style={styles.base}
- onPress={this.handlePress}
+ onClick={this.handleClick}
disabled={!this.props.hasActiveRelays}
selected={this.props.selected}>
<RelayStatusIndicator
@@ -96,7 +96,7 @@ export default class CountryRow extends Component<IProps> {
{hasChildren ? (
<ChevronButton onClick={this.toggleCollapse} up={this.props.expanded} />
) : null}
- </Cell.CellButton>
+ </Button>
{hasChildren && (
<Accordion
@@ -118,16 +118,15 @@ export default class CountryRow extends Component<IProps> {
event.stopPropagation();
};
- private handlePress = () => {
+ private handleClick = () => {
if (this.props.onSelect) {
this.props.onSelect(this.props.location);
}
};
private onWillExpand = (nextHeight: number) => {
- const buttonNode = ReactDOM.findDOMNode(this.buttonRef.current);
- if (buttonNode instanceof HTMLElement) {
- const buttonRect = buttonNode.getBoundingClientRect();
+ const buttonRect = this.buttonRef.current?.getBoundingClientRect();
+ if (buttonRect) {
this.props.onWillExpand?.(buttonRect, nextHeight);
}
};
diff --git a/gui/src/renderer/components/LocationList.tsx b/gui/src/renderer/components/LocationList.tsx
index efd8969e4f..06c2221314 100644
--- a/gui/src/renderer/components/LocationList.tsx
+++ b/gui/src/renderer/components/LocationList.tsx
@@ -220,7 +220,7 @@ interface ISpecialLocationProps<T> {
export class SpecialLocation<T> extends Component<ISpecialLocationProps<T>> {
public render() {
return (
- <Cell.CellButton selected={this.props.isSelected} onPress={this.onSelect}>
+ <Cell.CellButton selected={this.props.isSelected} onClick={this.onSelect}>
<Cell.Icon
source={this.props.isSelected ? 'icon-tick' : this.props.icon}
tintColor={colors.white}
diff --git a/gui/src/renderer/components/Login.tsx b/gui/src/renderer/components/Login.tsx
index e77ddcbe09..9d317091ac 100644
--- a/gui/src/renderer/components/Login.tsx
+++ b/gui/src/renderer/components/Login.tsx
@@ -6,11 +6,15 @@ import { messages } from '../../shared/gettext';
import { formatAccountToken } from '../lib/account';
import Accordion from './Accordion';
import * as AppButton from './AppButton';
-import * as Cell from './Cell';
import { Brand, SettingsBarButton } from './HeaderBar';
import ImageView from './ImageView';
import { Container, Header, Layout } from './Layout';
-import styles, { AccountDropdownRemoveIcon, InputSubmitIcon } from './LoginStyles';
+import styles, {
+ AccountDropdownItemButton,
+ AccountDropdownItemButtonLabel,
+ AccountDropdownRemoveIcon,
+ InputSubmitIcon,
+} from './LoginStyles';
import { AccountToken } from '../../shared/daemon-rpc-types';
import { LoginState } from '../redux/account/reducers';
@@ -445,16 +449,10 @@ class AccountDropdownItem extends Component<IAccountDropdownItemProps> {
return (
<View>
<View style={styles.account_dropdown__spacer} />
- <Cell.CellButton
- style={styles.account_dropdown__item}
- hoverStyle={styles.account_dropdown__item_hover}>
- <Cell.Label
- textStyle={styles.account_dropdown__label}
- containerStyle={styles.account_dropdown__label_container}
- cellHoverTextStyle={styles.account_dropdown__label_hover}
- onPress={this.handleSelect}>
+ <AccountDropdownItemButton>
+ <AccountDropdownItemButtonLabel onClick={this.handleSelect}>
{this.props.label}
- </Cell.Label>
+ </AccountDropdownItemButtonLabel>
<AccountDropdownRemoveIcon
tintColor={colors.blue40}
tintHoverColor={colors.blue}
@@ -463,7 +461,7 @@ class AccountDropdownItem extends Component<IAccountDropdownItemProps> {
width={16}
onClick={this.handleRemove}
/>
- </Cell.CellButton>
+ </AccountDropdownItemButton>
</View>
);
}
diff --git a/gui/src/renderer/components/LoginStyles.tsx b/gui/src/renderer/components/LoginStyles.tsx
index c60b7471ca..d935eb195e 100644
--- a/gui/src/renderer/components/LoginStyles.tsx
+++ b/gui/src/renderer/components/LoginStyles.tsx
@@ -2,6 +2,7 @@ import { Styles } from 'reactxp';
import styled from 'styled-components';
import { colors } from '../../config.json';
import ImageView from './ImageView';
+import * as Cell from './Cell';
export const AccountDropdownRemoveIcon = styled(ImageView)({
justifyContent: 'center',
@@ -21,6 +22,31 @@ export const InputSubmitIcon = styled(ImageView)((props: { visible: boolean }) =
opacity: props.visible ? 1 : 0,
}));
+export const AccountDropdownItemButton = styled(Cell.CellButton)({
+ padding: '0px',
+ marginBottom: '0px',
+ flexDirection: 'row',
+ alignItems: 'stretch',
+ backgroundColor: colors.white60,
+ cursor: 'default',
+ ':not(:disabled):hover': {
+ backgroundColor: colors.white40,
+ },
+});
+
+export const AccountDropdownItemButtonLabel = styled(Cell.Label)({
+ padding: '11px 0px 11px 12px',
+ margin: '0',
+ color: colors.blue80,
+ borderWidth: 0,
+ textAlign: 'left',
+ marginLeft: 0,
+ cursor: 'default',
+ [AccountDropdownItemButton + ':hover']: {
+ color: colors.blue,
+ },
+});
+
export default {
login_footer: Styles.createViewStyle({
flex: 0,
@@ -83,30 +109,6 @@ export default {
height: 1,
backgroundColor: colors.darkBlue,
}),
- account_dropdown__item: Styles.createViewStyle({
- paddingTop: 0,
- paddingRight: 0,
- paddingLeft: 0,
- paddingBottom: 0,
- marginBottom: 0,
- flexDirection: 'row',
- alignItems: 'stretch',
- backgroundColor: colors.white60,
- cursor: 'default',
- }),
- account_dropdown__item_hover: Styles.createViewStyle({
- backgroundColor: colors.white40,
- }),
- account_dropdown__label_hover: Styles.createTextStyle({
- color: colors.blue,
- }),
- account_dropdown__label_container: Styles.createViewStyle({
- paddingLeft: 12,
- paddingTop: 11,
- paddingBottom: 11,
- marginHorizontal: 0,
- marginVertical: 0,
- }),
login_footer__prompt: Styles.createTextStyle({
color: colors.white80,
@@ -150,11 +152,4 @@ export default {
backgroundColor: 'transparent',
flex: 1,
}),
- account_dropdown__label: Styles.createTextStyle({
- color: colors.blue80,
- borderWidth: 0,
- textAlign: 'left',
- marginLeft: 0,
- cursor: 'default',
- }),
};
diff --git a/gui/src/renderer/components/RelayRow.tsx b/gui/src/renderer/components/RelayRow.tsx
index cd87610944..f7f3998ab5 100644
--- a/gui/src/renderer/components/RelayRow.tsx
+++ b/gui/src/renderer/components/RelayRow.tsx
@@ -1,5 +1,6 @@
import * as React from 'react';
-import { Component, Styles } from 'reactxp';
+import { Component } from 'reactxp';
+import styled from 'styled-components';
import { colors } from '../../config.json';
import { compareRelayLocation, RelayLocation } from '../../shared/daemon-rpc-types';
import * as Cell from './Cell';
@@ -13,13 +14,11 @@ interface IProps {
onSelect?: (location: RelayLocation) => void;
}
-const styles = {
- base: Styles.createViewStyle({
- paddingRight: 0,
- paddingLeft: 48,
- backgroundColor: colors.blue20,
- }),
-};
+const Button = styled(Cell.CellButton)((props: { selected: boolean }) => ({
+ paddingRight: 0,
+ paddingLeft: 48,
+ backgroundColor: !props.selected ? colors.blue20 : undefined,
+}));
export default class RelayRow extends Component<IProps> {
public static compareProps(oldProps: IProps, nextProps: IProps) {
@@ -37,19 +36,18 @@ export default class RelayRow extends Component<IProps> {
public render() {
return (
- <Cell.CellButton
- onPress={this.handlePress}
+ <Button
+ onClick={this.handleClick}
selected={this.props.selected}
- disabled={!this.props.active}
- style={styles.base}>
+ disabled={!this.props.active}>
<RelayStatusIndicator active={this.props.active} selected={this.props.selected} />
<Cell.Label>{this.props.hostname}</Cell.Label>
- </Cell.CellButton>
+ </Button>
);
}
- private handlePress = () => {
+ private handleClick = () => {
if (this.props.onSelect) {
this.props.onSelect(this.props.location);
}
diff --git a/gui/src/renderer/components/SelectLanguage.tsx b/gui/src/renderer/components/SelectLanguage.tsx
index 254272cc46..1a294a05ba 100644
--- a/gui/src/renderer/components/SelectLanguage.tsx
+++ b/gui/src/renderer/components/SelectLanguage.tsx
@@ -1,6 +1,7 @@
import * as React from 'react';
import ReactDOM from 'react-dom';
import { Component, Styles, View } from 'reactxp';
+import styled from 'styled-components';
import { colors } from '../../config.json';
import { messages } from '../../shared/gettext';
import CustomScrollbars from './CustomScrollbars';
@@ -35,15 +36,16 @@ const styles = {
container: Styles.createViewStyle({
flex: 1,
}),
- selector: Styles.createViewStyle({
- marginBottom: 0,
- }),
// plain CSS style
scrollview: {
flex: 1,
},
};
+const StyledSelector = (styled(Selector)({
+ marginBottom: 0,
+}) as unknown) as new <T>() => Selector<T>;
+
export default class SelectLanguage extends Component<IProps, IState> {
private scrollView = React.createRef<CustomScrollbars>();
private selectedCellRef = React.createRef<SelectorCell<string>>();
@@ -92,8 +94,7 @@ export default class SelectLanguage extends Component<IProps, IState> {
{messages.pgettext('select-language-nav', 'Select language')}
</HeaderTitle>
</SettingsHeader>
- <Selector
- style={styles.selector}
+ <StyledSelector
title=""
values={this.state.source}
value={this.props.preferredLocale}
diff --git a/gui/src/renderer/components/Selector.tsx b/gui/src/renderer/components/Selector.tsx
index 1c3fdcdaf7..57f2323cef 100644
--- a/gui/src/renderer/components/Selector.tsx
+++ b/gui/src/renderer/components/Selector.tsx
@@ -1,5 +1,4 @@
import * as React from 'react';
-import { Component, Styles, Types, View } from 'reactxp';
import styled from 'styled-components';
import { colors } from '../../config.json';
import * as Cell from './Cell';
@@ -11,21 +10,19 @@ export interface ISelectorItem<T> {
}
interface ISelectorProps<T> {
- style?: Types.ViewStyleRuleSet;
title?: string;
values: Array<ISelectorItem<T>>;
value: T;
onSelect: (value: T) => void;
selectedCellRef?: React.Ref<SelectorCell<T>>;
+ className?: string;
}
-const styles = {
- section: Styles.createViewStyle({
- marginBottom: 24,
- }),
-};
+const Section = styled(Cell.Section)({
+ marginBottom: 24,
+});
-export default class Selector<T> extends Component<ISelectorProps<T>> {
+export default class Selector<T> extends React.Component<ISelectorProps<T>> {
public render() {
const items = this.props.values.map((item, i) => {
const selected = item.value === this.props.value;
@@ -45,13 +42,13 @@ export default class Selector<T> extends Component<ISelectorProps<T>> {
if (this.props.title) {
return (
- <Cell.Section style={[styles.section, this.props.style]}>
+ <Section className={this.props.className}>
<Cell.SectionTitle>{this.props.title}</Cell.SectionTitle>
{items}
- </Cell.Section>
+ </Section>
);
} else {
- return <View style={[styles.section, this.props.style]}>{items}</View>;
+ return <Section className={this.props.className}>{items}</Section>;
}
}
}
@@ -68,11 +65,11 @@ interface ISelectorCellProps<T> {
children?: React.ReactText;
}
-export class SelectorCell<T> extends Component<ISelectorCellProps<T>> {
+export class SelectorCell<T> extends React.Component<ISelectorCellProps<T>> {
public render() {
return (
<Cell.CellButton
- onPress={this.onPress}
+ onClick={this.onClick}
selected={this.props.selected}
disabled={this.props.disabled}>
<StyledCellIcon
@@ -87,7 +84,7 @@ export class SelectorCell<T> extends Component<ISelectorCellProps<T>> {
);
}
- private onPress = () => {
+ private onClick = () => {
if (!this.props.selected) {
this.props.onSelect(this.props.value);
}
diff --git a/gui/src/renderer/components/Settings.tsx b/gui/src/renderer/components/Settings.tsx
index eb12187dc9..644190a4db 100644
--- a/gui/src/renderer/components/Settings.tsx
+++ b/gui/src/renderer/components/Settings.tsx
@@ -15,7 +15,7 @@ import {
TitleBarItem,
} from './NavigationBar';
import SettingsHeader, { HeaderTitle } from './SettingsHeader';
-import styles from './SettingsStyles';
+import styles, { OutOfTimeSubText } from './SettingsStyles';
import { LoginState } from '../redux/account/reducers';
@@ -113,21 +113,21 @@ export default class Settings extends Component<IProps> {
return (
<View>
<View>
- <Cell.CellButton onPress={this.props.onViewAccount}>
+ <Cell.CellButton onClick={this.props.onViewAccount}>
<Cell.Label>
{
// TRANSLATORS: Navigation button to the 'Account' view
messages.pgettext('settings-view', 'Account')
}
</Cell.Label>
- <Cell.SubText style={isOutOfTime ? styles.accountPaidUntilErrorLabel : undefined}>
+ <OutOfTimeSubText isOutOfTime={isOutOfTime}>
{isOutOfTime ? outOfTimeMessage : formattedExpiry}
- </Cell.SubText>
+ </OutOfTimeSubText>
<Cell.Icon height={12} width={7} source="icon-chevron" />
</Cell.CellButton>
</View>
- <Cell.CellButton onPress={this.props.onViewPreferences}>
+ <Cell.CellButton onClick={this.props.onViewPreferences}>
<Cell.Label>
{
// TRANSLATORS: Navigation button to the 'Preferences' view
@@ -137,7 +137,7 @@ export default class Settings extends Component<IProps> {
<Cell.Icon height={12} width={7} source="icon-chevron" />
</Cell.CellButton>
- <Cell.CellButton onPress={this.props.onViewAdvancedSettings}>
+ <Cell.CellButton onClick={this.props.onViewAdvancedSettings}>
<Cell.Label>
{
// TRANSLATORS: Navigation button to the 'Advanced' settings view
@@ -181,10 +181,10 @@ export default class Settings extends Component<IProps> {
return (
<View>
- <Cell.CellButton disabled={this.props.isOffline} onPress={this.openDownloadLink}>
+ <Cell.CellButton disabled={this.props.isOffline} onClick={this.openDownloadLink}>
{icon}
<Cell.Label>{messages.pgettext('settings-view', 'App version')}</Cell.Label>
- <Cell.SubText style={styles.appVersionLabel}>{this.props.appVersion}</Cell.SubText>
+ <Cell.SubText>{this.props.appVersion}</Cell.SubText>
<Cell.Icon height={16} width={16} source="icon-extLink" />
</Cell.CellButton>
{footer}
@@ -195,7 +195,7 @@ export default class Settings extends Component<IProps> {
private renderBottomButtons() {
return (
<View>
- <Cell.CellButton onPress={this.props.onViewSupport}>
+ <Cell.CellButton onClick={this.props.onViewSupport}>
<Cell.Label>
{
// TRANSLATORS: Navigation button to the 'Report a problem' help view
@@ -205,7 +205,7 @@ export default class Settings extends Component<IProps> {
<Cell.Icon height={12} width={7} source="icon-chevron" />
</Cell.CellButton>
- <Cell.CellButton disabled={this.props.isOffline} onPress={this.openFaqLink}>
+ <Cell.CellButton disabled={this.props.isOffline} onClick={this.openFaqLink}>
<Cell.Label>
{
// TRANSLATORS: Link to the webpage
@@ -215,7 +215,7 @@ export default class Settings extends Component<IProps> {
<Cell.Icon height={16} width={16} source="icon-extLink" />
</Cell.CellButton>
- <Cell.CellButton onPress={this.props.onViewSelectLanguage}>
+ <Cell.CellButton onClick={this.props.onViewSelectLanguage}>
<Cell.UntintedIcon width={24} height={24} source="icon-language" />
<Cell.Label>
{
diff --git a/gui/src/renderer/components/SettingsStyles.tsx b/gui/src/renderer/components/SettingsStyles.tsx
index 51a215d0fc..1406fba209 100644
--- a/gui/src/renderer/components/SettingsStyles.tsx
+++ b/gui/src/renderer/components/SettingsStyles.tsx
@@ -1,5 +1,11 @@
import { Styles } from 'reactxp';
+import styled from 'styled-components';
import { colors } from '../../config.json';
+import * as Cell from './Cell';
+
+export const OutOfTimeSubText = styled(Cell.SubText)((props: { isOutOfTime: boolean }) => ({
+ color: props.isOutOfTime ? colors.red : undefined,
+}));
export default {
settings: Styles.createViewStyle({
@@ -36,9 +42,6 @@ export default {
paddingLeft: 24,
paddingRight: 24,
}),
- accountPaidUntilErrorLabel: Styles.createTextStyle({
- color: colors.red,
- }),
cellFooterLabel: Styles.createTextStyle({
fontFamily: 'Open Sans',
fontSize: 13,
@@ -47,7 +50,4 @@ export default {
letterSpacing: -0.2,
color: colors.white60,
}),
- appVersionLabel: Styles.createTextStyle({
- flex: 0,
- }),
};
diff --git a/gui/src/renderer/components/Switch.tsx b/gui/src/renderer/components/Switch.tsx
index ceda826fb0..7a1555c761 100644
--- a/gui/src/renderer/components/Switch.tsx
+++ b/gui/src/renderer/components/Switch.tsx
@@ -5,6 +5,7 @@ import { colors } from '../../config.json';
interface IProps {
isOn: boolean;
onChange?: (isOn: boolean) => void;
+ className?: string;
}
interface IState {
@@ -70,7 +71,10 @@ export default class Switch extends React.Component<IProps, IState> {
public render() {
return (
- <SwitchContainer ref={this.containerRef} onClick={this.handleClick}>
+ <SwitchContainer
+ ref={this.containerRef}
+ onClick={this.handleClick}
+ className={this.props.className}>
<Knob
isOn={this.state.isOn}
isPressed={this.state.isPressed}