summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorOskar Nyberg <oskar@mullvad.net>2020-05-07 11:47:28 +0200
committerOskar Nyberg <oskar@mullvad.net>2020-05-08 14:43:05 +0200
commit05ff02a622c14562b54a11d675655d7327afdc79 (patch)
tree1af082914b00fd3d0c7063653a49b3295cd89976
parent0f7a364f9a8f6087da007fac3c6d5606472e956d (diff)
downloadmullvadvpn-05ff02a622c14562b54a11d675655d7327afdc79.tar.xz
mullvadvpn-05ff02a622c14562b54a11d675655d7327afdc79.zip
Convert ImageView into a styled component
-rw-r--r--gui/src/renderer/components/Cell.tsx17
-rw-r--r--gui/src/renderer/components/CellStyles.tsx9
-rw-r--r--gui/src/renderer/components/ChevronButton.tsx38
-rw-r--r--gui/src/renderer/components/CityRow.tsx6
-rw-r--r--gui/src/renderer/components/CountryRow.tsx6
-rw-r--r--gui/src/renderer/components/ErrorBoundary.tsx10
-rw-r--r--gui/src/renderer/components/HeaderBar.tsx10
-rw-r--r--gui/src/renderer/components/ImageView.tsx98
-rw-r--r--gui/src/renderer/components/Launch.tsx10
-rw-r--r--gui/src/renderer/components/Login.tsx21
-rw-r--r--gui/src/renderer/components/LoginStyles.tsx38
-rw-r--r--gui/src/renderer/components/NavigationBar.tsx23
-rw-r--r--gui/src/renderer/components/RedeemVoucher.tsx7
-rw-r--r--gui/src/renderer/components/RedeemVoucherStyles.tsx9
-rw-r--r--gui/src/renderer/components/Selector.tsx12
15 files changed, 150 insertions, 164 deletions
diff --git a/gui/src/renderer/components/Cell.tsx b/gui/src/renderer/components/Cell.tsx
index 8d884db307..04fc0729b8 100644
--- a/gui/src/renderer/components/Cell.tsx
+++ b/gui/src/renderer/components/Cell.tsx
@@ -1,10 +1,12 @@
import * as React from 'react';
import { Button, Component, Styles, Text, TextInput, Types, View } from 'reactxp';
import { colors } from '../../config.json';
-import styles from './CellStyles';
-import ImageView from './ImageView';
+import styles, { StyledIcon } from './CellStyles';
+import { IImageViewProps } from './ImageView';
import { default as SwitchControl } from './Switch';
+export { StyledIcon as UntintedIcon } from './CellStyles';
+
interface ICellButtonProps {
children?: React.ReactNode;
disabled?: boolean;
@@ -326,15 +328,14 @@ export const SubText = function CellSubText(props: SubTextProps) {
);
};
-export const Icon = function CellIcon(props: ImageView['props']) {
- const { children: _children, style, tintColor, tintHoverColor, ...otherProps } = props;
+export const Icon = function CellIcon(props: IImageViewProps) {
+ const { tintColor, tintHoverColor, ...otherProps } = props;
return (
<CellHoverContext.Consumer>
{(hovered) => (
- <ImageView
+ <StyledIcon
tintColor={(hovered && tintHoverColor) || tintColor || colors.white60}
- style={[styles.icon, style]}
{...otherProps}
/>
)}
@@ -342,10 +343,6 @@ export const Icon = function CellIcon(props: ImageView['props']) {
);
};
-export const UntintedIcon = function CellIcon(props: ImageView['props']) {
- return <ImageView {...props} style={[styles.icon, props.style]} />;
-};
-
export const Footer = function CellFooter({ children }: IContainerProps) {
return <View style={styles.footer.container}>{children}</View>;
};
diff --git a/gui/src/renderer/components/CellStyles.tsx b/gui/src/renderer/components/CellStyles.tsx
index 453a8d3cca..045ad3c6ff 100644
--- a/gui/src/renderer/components/CellStyles.tsx
+++ b/gui/src/renderer/components/CellStyles.tsx
@@ -1,5 +1,11 @@
import { Styles } from 'reactxp';
+import styled from 'styled-components';
import { colors } from '../../config.json';
+import ImageView from './ImageView';
+
+export const StyledIcon = styled(ImageView)({
+ marginLeft: '8px',
+});
export default {
cellButton: {
@@ -104,9 +110,6 @@ export default {
flexBasis: undefined,
}),
},
- icon: Styles.createViewStyle({
- marginLeft: 8,
- }),
subtext: Styles.createTextStyle({
color: colors.white60,
fontFamily: 'Open Sans',
diff --git a/gui/src/renderer/components/ChevronButton.tsx b/gui/src/renderer/components/ChevronButton.tsx
index 04aabf6a99..aed6bacaec 100644
--- a/gui/src/renderer/components/ChevronButton.tsx
+++ b/gui/src/renderer/components/ChevronButton.tsx
@@ -1,34 +1,32 @@
import * as React from 'react';
-import { Component, Styles, Types } from 'reactxp';
+import styled from 'styled-components';
import { colors } from '../../config.json';
import * as Cell from './Cell';
interface IProps {
up: boolean;
- onPress?: (event: Types.SyntheticEvent) => void;
- style?: Types.StyleRuleSetRecursive<Types.ViewStyleRuleSet>;
+ onClick?: (event: React.MouseEvent) => void;
+ className?: string;
}
-const style = Styles.createViewStyle({
+const Icon = styled(Cell.Icon)({
flex: 0,
alignSelf: 'stretch',
justifyContent: 'center',
- paddingRight: 16,
- paddingLeft: 16,
+ paddingRight: '16px',
+ paddingLeft: '16px',
});
-export default class ChevronButton extends Component<IProps> {
- public render() {
- return (
- <Cell.Icon
- style={[style, this.props.style]}
- tintColor={colors.white80}
- tintHoverColor={colors.white}
- onPress={this.props.onPress}
- source={this.props.up ? 'icon-chevron-up' : 'icon-chevron-down'}
- height={24}
- width={24}
- />
- );
- }
+export default function ChevronButton(props: IProps) {
+ return (
+ <Icon
+ tintColor={colors.white80}
+ tintHoverColor={colors.white}
+ onClick={props.onClick}
+ source={props.up ? 'icon-chevron-up' : 'icon-chevron-down'}
+ height={24}
+ width={24}
+ className={props.className}
+ />
+ );
}
diff --git a/gui/src/renderer/components/CityRow.tsx b/gui/src/renderer/components/CityRow.tsx
index c015bd5f76..472c468222 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, Types, View } from 'reactxp';
+import { Component, Styles, View } from 'reactxp';
import { colors } from '../../config.json';
import { compareRelayLocation, RelayLocation } from '../../shared/daemon-rpc-types';
import Accordion from './Accordion';
@@ -86,7 +86,7 @@ export default class CityRow extends Component<IProps> {
/>
<Cell.Label>{this.props.name}</Cell.Label>
- {hasChildren && <ChevronButton onPress={this.toggleCollapse} up={this.props.expanded} />}
+ {hasChildren && <ChevronButton onClick={this.toggleCollapse} up={this.props.expanded} />}
</Cell.CellButton>
{hasChildren && (
@@ -102,7 +102,7 @@ export default class CityRow extends Component<IProps> {
);
}
- private toggleCollapse = (event: Types.SyntheticEvent) => {
+ private toggleCollapse = (event: React.MouseEvent) => {
if (this.props.onExpand) {
this.props.onExpand(this.props.location, !this.props.expanded);
}
diff --git a/gui/src/renderer/components/CountryRow.tsx b/gui/src/renderer/components/CountryRow.tsx
index 5218afdf73..a541403cbd 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, Types, View } from 'reactxp';
+import { Component, Styles, View } from 'reactxp';
import { compareRelayLocation, RelayLocation } from '../../shared/daemon-rpc-types';
import Accordion from './Accordion';
import * as Cell from './Cell';
@@ -94,7 +94,7 @@ export default class CountryRow extends Component<IProps> {
/>
<Cell.Label>{this.props.name}</Cell.Label>
{hasChildren ? (
- <ChevronButton onPress={this.toggleCollapse} up={this.props.expanded} />
+ <ChevronButton onClick={this.toggleCollapse} up={this.props.expanded} />
) : null}
</Cell.CellButton>
@@ -111,7 +111,7 @@ export default class CountryRow extends Component<IProps> {
);
}
- private toggleCollapse = (event: Types.SyntheticEvent) => {
+ private toggleCollapse = (event: React.MouseEvent) => {
if (this.props.onExpand) {
this.props.onExpand(this.props.location, !this.props.expanded);
}
diff --git a/gui/src/renderer/components/ErrorBoundary.tsx b/gui/src/renderer/components/ErrorBoundary.tsx
index 18ac8f7d03..aa0fbba3b6 100644
--- a/gui/src/renderer/components/ErrorBoundary.tsx
+++ b/gui/src/renderer/components/ErrorBoundary.tsx
@@ -1,6 +1,7 @@
import log from 'electron-log';
import * as React from 'react';
import { Component, Styles, Text, View } from 'reactxp';
+import styled from 'styled-components';
import { colors, links } from '../../config.json';
import { messages } from '../../shared/gettext';
import PlatformWindowContainer from '../containers/PlatformWindowContainer';
@@ -23,9 +24,6 @@ const styles = {
justifyContent: 'center',
backgroundColor: colors.blue,
}),
- logo: Styles.createViewStyle({
- marginBottom: 5,
- }),
title: Styles.createTextStyle({
fontFamily: 'DINPro',
fontSize: 24,
@@ -48,6 +46,10 @@ const styles = {
}),
};
+const Logo = styled(ImageView)({
+ marginBottom: '5px',
+});
+
export default class ErrorBoundary extends Component<IProps, IState> {
public state = { hasError: false };
@@ -77,7 +79,7 @@ export default class ErrorBoundary extends Component<IProps, IState> {
<Layout>
<Container>
<View style={styles.container}>
- <ImageView height={106} width={106} source="logo-icon" style={styles.logo} />
+ <Logo height={106} width={106} source="logo-icon" />
<Text style={styles.title}>{messages.pgettext('generic', 'MULLVAD VPN')}</Text>
<Text style={styles.subtitle}>{reachBackMessage}</Text>
</View>
diff --git a/gui/src/renderer/components/HeaderBar.tsx b/gui/src/renderer/components/HeaderBar.tsx
index 912df6a01c..b32e81be9b 100644
--- a/gui/src/renderer/components/HeaderBar.tsx
+++ b/gui/src/renderer/components/HeaderBar.tsx
@@ -1,5 +1,6 @@
import * as React from 'react';
import { Button, Component, Styles, Text, Types, View } from 'reactxp';
+import styled from 'styled-components';
import { colors } from '../../config.json';
import { messages } from '../../shared/gettext';
import ImageView from './ImageView';
@@ -78,9 +79,6 @@ const brandStyles = {
flexDirection: 'row',
alignItems: 'center',
}),
- icon: Styles.createViewStyle({
- marginLeft: 6,
- }),
title: Styles.createTextStyle({
fontFamily: 'DINPro',
fontSize: 24,
@@ -92,11 +90,15 @@ const brandStyles = {
}),
};
+const Logo = styled(ImageView)({
+ marginLeft: '6px',
+});
+
export class Brand extends Component {
public render() {
return (
<View style={brandStyles.container}>
- <ImageView width={44} height={44} source="logo-icon" style={brandStyles.icon} />
+ <Logo width={44} height={44} source="logo-icon" />
<Text style={brandStyles.title}>{messages.pgettext('generic', 'MULLVAD VPN')}</Text>
</View>
);
diff --git a/gui/src/renderer/components/ImageView.tsx b/gui/src/renderer/components/ImageView.tsx
index 1f6a90493a..3b7ea88e84 100644
--- a/gui/src/renderer/components/ImageView.tsx
+++ b/gui/src/renderer/components/ImageView.tsx
@@ -1,73 +1,59 @@
import * as React from 'react';
-import { Component, Types, View } from 'reactxp';
+import styled from 'styled-components';
-interface IProps {
+export interface IImageViewProps extends IImageMaskProps {
+ onClick?: (event: React.MouseEvent) => void;
+ className?: string;
+}
+
+interface IImageMaskProps {
source: string;
width?: number;
height?: number;
+ disabled?: boolean;
tintColor?: string;
tintHoverColor?: string;
- disabled?: boolean;
- onPress?: (event: Types.SyntheticEvent) => void;
- style?: Types.StyleRuleSetRecursive<Types.ViewStyleRuleSet>;
}
-interface IState {
- hovered: boolean;
-}
-
-export default class ImageView extends Component<IProps, IState> {
- public state = { hovered: false };
+const Wrapper = styled.div({
+ display: 'flex',
+ flexDirection: 'column',
+ justifyContent: 'center',
+});
- public render() {
- const { source, width, height, tintColor, tintHoverColor, ...otherProps } = this.props;
- const url = `../../assets/images/${source}.svg`;
- let image;
+const ImageMask = styled.div((props: IImageMaskProps) => {
+ const maskWidth = props.width ? `${props.width}px` : 'auto';
+ const maskHeight = props.height ? `${props.height}px` : 'auto';
+ return {
+ maskImage: `url('${props.source}')`,
+ maskRepeat: 'no-repeat',
+ maskSize: `${maskWidth} ${maskHeight}`,
+ maskPosition: 'center',
+ lineHeight: 0,
+ backgroundColor: props.tintColor,
+ ':hover': {
+ backgroundColor: (!props.disabled && props.tintHoverColor) || props.tintColor,
+ },
+ };
+});
- const activeTintColor = (this.state.hovered && tintHoverColor) || tintColor;
+const HiddenImage = styled.img({ visibility: 'hidden' });
- if (activeTintColor) {
- const maskWidth = typeof width === 'number' ? `${width}px` : 'auto';
- const maskHeight = typeof height === 'number' ? `${height}px` : 'auto';
- image = (
- <div
- style={{
- WebkitMaskImage: `url('${url}')`,
- WebkitMaskRepeat: 'no-repeat',
- WebkitMaskSize: `${maskWidth} ${maskHeight}`,
- backgroundColor: activeTintColor,
- lineHeight: 0,
- }}>
- <img
- src={url}
- width={width}
- height={height}
- style={{
- visibility: 'hidden',
- }}
- />
- </div>
- );
- } else {
- image = <img src={url} width={width} height={height} />;
- }
+export default function ImageView(props: IImageViewProps) {
+ const url = `../../assets/images/${props.source}.svg`;
+ if (props.tintColor) {
+ const { source: _source, ...otherProps } = props;
return (
- <View {...otherProps} onMouseEnter={this.onHoverStart} onMouseLeave={this.onHoverEnd}>
- {image}
- </View>
+ <ImageMask source={url} {...otherProps}>
+ <HiddenImage src={url} width={props.width} height={props.height} />
+ </ImageMask>
+ );
+ } else {
+ return (
+ <Wrapper onClick={props.onClick} className={props.className}>
+ <img src={url} width={props.width} height={props.height} />
+ </Wrapper>
);
}
-
- private onHoverStart = () => {
- if (!this.props.disabled) {
- this.setState({ hovered: true });
- }
- };
-
- private onHoverEnd = () => {
- if (!this.props.disabled) {
- this.setState({ hovered: false });
- }
- };
}
diff --git a/gui/src/renderer/components/Launch.tsx b/gui/src/renderer/components/Launch.tsx
index 3c1843fea9..40e993fe2a 100644
--- a/gui/src/renderer/components/Launch.tsx
+++ b/gui/src/renderer/components/Launch.tsx
@@ -1,5 +1,6 @@
import * as React from 'react';
import { Component, Styles, Text, View } from 'reactxp';
+import styled from 'styled-components';
import { colors } from '../../config.json';
import { messages } from '../../shared/gettext';
import { SettingsBarButton } from './HeaderBar';
@@ -14,9 +15,6 @@ const styles = {
justifyContent: 'center',
marginTop: -150,
}),
- logo: Styles.createViewStyle({
- marginBottom: 5,
- }),
title: Styles.createTextStyle({
fontFamily: 'DINPro',
fontSize: 24,
@@ -34,6 +32,10 @@ const styles = {
}),
};
+const Logo = styled(ImageView)({
+ marginBottom: '5px',
+});
+
interface IProps {
openSettings: () => void;
}
@@ -47,7 +49,7 @@ export default class Launch extends Component<IProps> {
</Header>
<Container>
<View style={styles.container}>
- <ImageView height={106} width={106} source="logo-icon" style={styles.logo} />
+ <Logo height={106} width={106} source="logo-icon" />
<Text style={styles.title}>{messages.pgettext('generic', 'MULLVAD VPN')}</Text>
<Text style={styles.subtitle}>
{messages.pgettext('launch-view', 'Connecting to Mullvad system service...')}
diff --git a/gui/src/renderer/components/Login.tsx b/gui/src/renderer/components/Login.tsx
index a69f5db48c..e77ddcbe09 100644
--- a/gui/src/renderer/components/Login.tsx
+++ b/gui/src/renderer/components/Login.tsx
@@ -10,7 +10,7 @@ import * as Cell from './Cell';
import { Brand, SettingsBarButton } from './HeaderBar';
import ImageView from './ImageView';
import { Container, Header, Layout } from './Layout';
-import styles from './LoginStyles';
+import styles, { AccountDropdownRemoveIcon, InputSubmitIcon } from './LoginStyles';
import { AccountToken } from '../../shared/daemon-rpc-types';
import { LoginState } from '../redux/account/reducers';
@@ -301,16 +301,6 @@ export default class Login extends Component<IProps, IState> {
return classes;
}
- private accountInputArrowStyles(): Types.ViewStyleRuleSet[] {
- const classes = [styles.input_arrow];
-
- if (this.props.loginState.type === 'logging in') {
- classes.push(styles.input_arrow__invisible);
- }
-
- return classes;
- }
-
private allowInteraction() {
return this.props.loginState.type !== 'logging in' && this.props.loginState.type !== 'ok';
}
@@ -376,8 +366,8 @@ export default class Login extends Component<IProps, IState> {
ref={this.accountInput}
/>
<Animated.View style={this.accountInputButtonStyles()} onPress={this.onSubmit}>
- <ImageView
- style={this.accountInputArrowStyles()}
+ <InputSubmitIcon
+ visible={this.props.loginState.type !== 'logging in'}
source="icon-arrow"
height={16}
width={24}
@@ -465,14 +455,13 @@ class AccountDropdownItem extends Component<IAccountDropdownItemProps> {
onPress={this.handleSelect}>
{this.props.label}
</Cell.Label>
- <ImageView
- style={styles.account_dropdown__remove}
+ <AccountDropdownRemoveIcon
tintColor={colors.blue40}
tintHoverColor={colors.blue}
source="icon-close-sml"
height={16}
width={16}
- onPress={this.handleRemove}
+ onClick={this.handleRemove}
/>
</Cell.CellButton>
</View>
diff --git a/gui/src/renderer/components/LoginStyles.tsx b/gui/src/renderer/components/LoginStyles.tsx
index c28cebd4e5..c60b7471ca 100644
--- a/gui/src/renderer/components/LoginStyles.tsx
+++ b/gui/src/renderer/components/LoginStyles.tsx
@@ -1,5 +1,25 @@
import { Styles } from 'reactxp';
+import styled from 'styled-components';
import { colors } from '../../config.json';
+import ImageView from './ImageView';
+
+export const AccountDropdownRemoveIcon = styled(ImageView)({
+ justifyContent: 'center',
+ paddingTop: '10px',
+ paddingRight: '12px',
+ paddingBottom: '12px',
+ paddingLeft: '12px',
+ marginLeft: '0px',
+});
+
+export const InputSubmitIcon = styled(ImageView)((props: { visible: boolean }) => ({
+ flex: 0,
+ borderWidth: '0px',
+ width: '48px',
+ alignItems: 'center',
+ justifyContent: 'center',
+ opacity: props.visible ? 1 : 0,
+}));
export default {
login_footer: Styles.createViewStyle({
@@ -59,16 +79,6 @@ export default {
backgroundColor: colors.white,
opacity: 0,
}),
- input_arrow: Styles.createViewStyle({
- flex: 0,
- borderWidth: 0,
- width: 48,
- alignItems: 'center',
- justifyContent: 'center',
- }),
- input_arrow__invisible: Styles.createViewStyle({
- opacity: 0,
- }),
account_dropdown__spacer: Styles.createViewStyle({
height: 1,
backgroundColor: colors.darkBlue,
@@ -87,14 +97,6 @@ export default {
account_dropdown__item_hover: Styles.createViewStyle({
backgroundColor: colors.white40,
}),
- account_dropdown__remove: Styles.createViewStyle({
- justifyContent: 'center',
- paddingTop: 10,
- paddingRight: 12,
- paddingBottom: 12,
- paddingLeft: 12,
- marginLeft: 0,
- }),
account_dropdown__label_hover: Styles.createTextStyle({
color: colors.blue,
}),
diff --git a/gui/src/renderer/components/NavigationBar.tsx b/gui/src/renderer/components/NavigationBar.tsx
index 37f47816a9..da481df495 100644
--- a/gui/src/renderer/components/NavigationBar.tsx
+++ b/gui/src/renderer/components/NavigationBar.tsx
@@ -1,5 +1,6 @@
import * as React from 'react';
import { Animated, Button, Component, Styles, Text, Types, UserInterface, View } from 'reactxp';
+import styled from 'styled-components';
import { colors } from '../../config.json';
import CustomScrollbars, { IScrollEvent } from './CustomScrollbars';
import ImageView from './ImageView';
@@ -61,10 +62,6 @@ const styles = {
default: Styles.createViewStyle({
cursor: 'default',
}),
- icon: Styles.createViewStyle({
- flex: 0,
- opacity: 0.6,
- }),
},
backBarButton: {
default: Styles.createViewStyle({
@@ -83,10 +80,6 @@ const styles = {
fontWeight: '600',
color: colors.white60,
}),
- icon: Styles.createViewStyle({
- opacity: 0.6,
- marginRight: 8,
- }),
},
scopeBar: {
container: Styles.createViewStyle({
@@ -605,6 +598,11 @@ export function TitleBarItem(props: ITitleBarItemProps) {
);
}
+const CloseBarItemIcon = styled(ImageView)({
+ flex: 0,
+ opacity: 0.6,
+});
+
interface ICloseBarItemProps {
action: () => void;
}
@@ -617,12 +615,17 @@ export class CloseBarItem extends Component<ICloseBarItemProps> {
return (
<Button style={[styles.closeBarItem.default]} onPress={this.props.action}>
- <ImageView height={24} width={24} style={[styles.closeBarItem.icon]} source={iconName} />
+ <CloseBarItemIcon height={24} width={24} source={iconName} />
</Button>
);
}
}
+const BackBarItemIcon = styled(ImageView)({
+ opacity: 0.6,
+ marginRight: '8px',
+});
+
interface IBackBarItemProps {
children?: React.ReactText;
action: () => void;
@@ -633,7 +636,7 @@ export class BackBarItem extends Component<IBackBarItemProps> {
return (
<Button style={styles.backBarButton.default} onPress={this.props.action}>
<View style={styles.backBarButton.content}>
- <ImageView style={styles.backBarButton.icon} source="icon-back" />
+ <BackBarItemIcon source="icon-back" />
<Text style={styles.backBarButton.label}>{this.props.children}</Text>
</View>
</Button>
diff --git a/gui/src/renderer/components/RedeemVoucher.tsx b/gui/src/renderer/components/RedeemVoucher.tsx
index 453200ab7c..4ce00a9a24 100644
--- a/gui/src/renderer/components/RedeemVoucher.tsx
+++ b/gui/src/renderer/components/RedeemVoucher.tsx
@@ -4,8 +4,7 @@ import { colors } from '../../config.json';
import { VoucherResponse } from '../../shared/daemon-rpc-types';
import { messages } from '../../shared/gettext';
import * as AppButton from './AppButton';
-import ImageView from './ImageView';
-import styles from './RedeemVoucherStyles';
+import styles, { Spinner } from './RedeemVoucherStyles';
interface IRedeemVoucherContextValue {
onSubmit: () => void;
@@ -141,9 +140,7 @@ export class RedeemVoucherResponse extends Component {
<RedeemVoucherContext.Consumer>
{(context) => {
if (context.submitting) {
- return (
- <ImageView source="icon-spinner" style={styles.spinner} height={20} width={20} />
- );
+ return <Spinner source="icon-spinner" height={20} width={20} />;
}
if (context.response) {
diff --git a/gui/src/renderer/components/RedeemVoucherStyles.tsx b/gui/src/renderer/components/RedeemVoucherStyles.tsx
index 00eea8340d..b2e462e7cd 100644
--- a/gui/src/renderer/components/RedeemVoucherStyles.tsx
+++ b/gui/src/renderer/components/RedeemVoucherStyles.tsx
@@ -1,5 +1,11 @@
import { Styles } from 'reactxp';
+import styled from 'styled-components';
import { colors } from '../../config.json';
+import ImageView from './ImageView';
+
+export const Spinner = styled(ImageView)({
+ marginTop: '8px',
+});
export default {
textInput: Styles.createTextInputStyle({
@@ -37,7 +43,4 @@ export default {
height: 20,
marginTop: 8,
}),
- spinner: Styles.createViewStyle({
- marginTop: 8,
- }),
};
diff --git a/gui/src/renderer/components/Selector.tsx b/gui/src/renderer/components/Selector.tsx
index c78b5a3ad8..1c3fdcdaf7 100644
--- a/gui/src/renderer/components/Selector.tsx
+++ b/gui/src/renderer/components/Selector.tsx
@@ -1,5 +1,6 @@
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';
@@ -22,9 +23,6 @@ const styles = {
section: Styles.createViewStyle({
marginBottom: 24,
}),
- invisibleIcon: Styles.createViewStyle({
- opacity: 0,
- }),
};
export default class Selector<T> extends Component<ISelectorProps<T>> {
@@ -58,6 +56,10 @@ export default class Selector<T> extends Component<ISelectorProps<T>> {
}
}
+const StyledCellIcon = styled(Cell.Icon)((props: { visible: boolean }) => ({
+ opacity: props.visible ? 1 : 0,
+}));
+
interface ISelectorCellProps<T> {
value: T;
selected: boolean;
@@ -73,8 +75,8 @@ export class SelectorCell<T> extends Component<ISelectorCellProps<T>> {
onPress={this.onPress}
selected={this.props.selected}
disabled={this.props.disabled}>
- <Cell.Icon
- style={this.props.selected ? undefined : styles.invisibleIcon}
+ <StyledCellIcon
+ visible={this.props.selected}
source="icon-tick"
width={24}
height={24}