From db89a8d51de88ca08599fa331f6376ef477d15e8 Mon Sep 17 00:00:00 2001 From: Oskar Nyberg Date: Tue, 24 Oct 2023 13:34:02 +0200 Subject: [PATCH] Adjust codebase to breaking changes in styled components v6 --- gui/src/renderer/app.tsx | 29 +++++----- gui/src/renderer/components/Accordion.tsx | 10 ++-- gui/src/renderer/components/AppButton.tsx | 16 +++--- .../renderer/components/AppButtonStyles.tsx | 6 +- .../components/ConnectionPanelDisclosure.tsx | 10 ++-- .../components/CustomDnsSettingsStyles.tsx | 25 ++++---- .../renderer/components/CustomScrollbars.tsx | 46 +++++++-------- gui/src/renderer/components/Filter.tsx | 14 ++--- gui/src/renderer/components/HeaderBar.tsx | 20 +++---- gui/src/renderer/components/ImageView.tsx | 25 +++++--- gui/src/renderer/components/Launch.tsx | 6 +- gui/src/renderer/components/Login.tsx | 12 ++-- gui/src/renderer/components/LoginStyles.tsx | 30 +++++----- gui/src/renderer/components/Marquee.tsx | 14 +++-- gui/src/renderer/components/Modal.tsx | 22 +++---- gui/src/renderer/components/NavigationBar.tsx | 2 +- .../components/NavigationBarStyles.tsx | 6 +- .../renderer/components/NotificationArea.tsx | 2 +- .../components/NotificationBanner.tsx | 18 +++--- .../components/RedeemVoucherStyles.tsx | 2 +- .../components/RelayStatusIndicator.tsx | 6 +- gui/src/renderer/components/SearchBar.tsx | 22 +++---- gui/src/renderer/components/SecuredLabel.tsx | 11 +++- .../renderer/components/SelectLanguage.tsx | 2 +- .../renderer/components/SettingsHeader.tsx | 2 +- .../components/SplitTunnelingSettings.tsx | 8 +-- .../SplitTunnelingSettingsStyles.tsx | 34 ++++++----- gui/src/renderer/components/Switch.tsx | 12 ++-- .../components/TransitionContainer.tsx | 57 +++++++++++-------- .../renderer/components/cell/CellButton.tsx | 20 ++++--- gui/src/renderer/components/cell/Group.tsx | 6 +- gui/src/renderer/components/cell/Input.tsx | 30 +++++----- gui/src/renderer/components/cell/Label.tsx | 8 +-- gui/src/renderer/components/cell/Row.tsx | 11 +++- gui/src/renderer/components/cell/Section.tsx | 10 ++-- gui/src/renderer/components/cell/Selector.tsx | 16 +++--- .../select-location/CustomLists.tsx | 14 ++--- .../select-location/LocationRow.tsx | 46 +++++++-------- .../select-location/RelayLocationList.tsx | 2 +- .../components/select-location/ScopeBar.tsx | 4 +- .../select-location/SpecialLocationList.tsx | 4 +- 41 files changed, 339 insertions(+), 301 deletions(-) diff --git a/gui/src/renderer/app.tsx b/gui/src/renderer/app.tsx index 7c7df7379610..bab17524d64a 100644 --- a/gui/src/renderer/app.tsx +++ b/gui/src/renderer/app.tsx @@ -1,6 +1,7 @@ import { batch, Provider } from 'react-redux'; import { Router } from 'react-router'; import { bindActionCreators } from 'redux'; +import { StyleSheetManager } from 'styled-components'; import { hasExpired } from '../shared/account-expiry'; import { ILinuxSplitTunnelingApplication, IWindowsApplication } from '../shared/application-types'; @@ -276,19 +277,21 @@ export default class AppRenderer { return ( - - - - - - - - - {window.env.platform === 'darwin' && } - - - - + + + + + + + + + + {window.env.platform === 'darwin' && } + + + + + ); diff --git a/gui/src/renderer/components/Accordion.tsx b/gui/src/renderer/components/Accordion.tsx index 682f5aa779b3..f70258f1032c 100644 --- a/gui/src/renderer/components/Accordion.tsx +++ b/gui/src/renderer/components/Accordion.tsx @@ -14,11 +14,11 @@ interface IState { containerHeight: string; } -const Container = styled.div((props: { height: string; animationDuration: number }) => ({ +const Container = styled.div<{ $height: string; $animationDuration: number }>((props) => ({ display: 'flex', - height: props.height, + height: props.$height, overflow: 'hidden', - transition: `height ${props.animationDuration}ms ease-in-out`, + transition: `height ${props.$animationDuration}ms ease-in-out`, })); const Content = styled.div({ @@ -55,8 +55,8 @@ export default class Accordion extends React.Component { return ( {this.state.mountChildren && this.props.children} diff --git a/gui/src/renderer/components/AppButton.tsx b/gui/src/renderer/components/AppButton.tsx index 45c93e1b2a78..753f64745e3a 100644 --- a/gui/src/renderer/components/AppButton.tsx +++ b/gui/src/renderer/components/AppButton.tsx @@ -22,7 +22,7 @@ interface ILabelProps { } export function Label(props: ILabelProps) { - return {props.children}; + return {props.children}; } interface IIconProps { @@ -108,7 +108,7 @@ const StyledSimpleButton = styled(SimpleButton)({ borderRadius: 4, border: 'none', padding: 0, - ':disabled': { + '&&:disabled': { opacity: 0.5, }, }); @@ -156,35 +156,35 @@ export function BlockingButton(props: IBlockingProps) { export const RedButton = styled(BaseButton)({ backgroundColor: colors.red, - ':not(:disabled):hover': { + '&&:not(:disabled):hover': { backgroundColor: colors.red95, }, }); export const GreenButton = styled(BaseButton)({ backgroundColor: colors.green, - ':not(:disabled):hover': { + '&&:not(:disabled):hover': { backgroundColor: colors.green90, }, }); export const BlueButton = styled(BaseButton)({ backgroundColor: colors.blue80, - ':not(:disabled):hover': { + '&&:not(:disabled):hover': { backgroundColor: colors.blue60, }, }); export const TransparentButton = styled(BaseButton)(transparentButton, { backgroundColor: colors.white20, - ':not(:disabled):hover': { + '&&:not(:disabled):hover': { backgroundColor: colors.white40, }, }); export const RedTransparentButton = styled(BaseButton)(transparentButton, { backgroundColor: colors.red60, - ':not(:disabled):hover': { + '&&:not(:disabled):hover': { backgroundColor: colors.red80, }, }); @@ -193,7 +193,7 @@ const StyledButtonWrapper = styled.div({ display: 'flex', flexDirection: 'column', flex: 0, - ':not(:last-child)': { + '&&:not(:last-child)': { marginBottom: measurements.buttonVerticalMargin, }, }); diff --git a/gui/src/renderer/components/AppButtonStyles.tsx b/gui/src/renderer/components/AppButtonStyles.tsx index f22eb3473a30..ac65f951f66b 100644 --- a/gui/src/renderer/components/AppButtonStyles.tsx +++ b/gui/src/renderer/components/AppButtonStyles.tsx @@ -2,9 +2,9 @@ import styled from 'styled-components'; import { buttonText } from './common-styles'; -export const StyledLabel = styled.span(buttonText, (props: { textOffset: number }) => ({ - paddingLeft: props.textOffset > 0 ? `${props.textOffset}px` : 0, - paddingRight: props.textOffset < 0 ? `${-props.textOffset}px` : 0, +export const StyledLabel = styled.span<{ $textOffset: number }>(buttonText, (props) => ({ + paddingLeft: props.$textOffset > 0 ? `${props.$textOffset}px` : 0, + paddingRight: props.$textOffset < 0 ? `${-props.$textOffset}px` : 0, textAlign: 'center', wordBreak: 'break-word', })); diff --git a/gui/src/renderer/components/ConnectionPanelDisclosure.tsx b/gui/src/renderer/components/ConnectionPanelDisclosure.tsx index 11ec9a0136da..3941c3d88fdb 100644 --- a/gui/src/renderer/components/ConnectionPanelDisclosure.tsx +++ b/gui/src/renderer/components/ConnectionPanelDisclosure.tsx @@ -11,18 +11,18 @@ const Container = styled.div({ width: '100%', }); -const Caption = styled.span(normalText, (props: { open: boolean }) => ({ +const Caption = styled.span<{ $open: boolean }>(normalText, (props) => ({ fontWeight: 600, lineHeight: '20px', minWidth: '0px', - color: props.open ? colors.white : colors.white40, - [Container + ':hover &']: { + color: props.$open ? colors.white : colors.white40, + [Container + ':hover &&']: { color: colors.white, }, })); const Chevron = styled(ImageView)({ - [Container + ':hover &']: { + [Container + ':hover &&']: { backgroundColor: colors.white, }, }); @@ -37,7 +37,7 @@ interface IProps { export default function ConnectionPanelDisclosure(props: IProps) { return ( - {props.children} + {props.children} ({ - fontFamily: 'Open Sans', - fontWeight: 400, - fontSize: '16px', - paddingLeft: (props.paddingLeft ?? 32) + 'px', - whiteSpace: 'pre-wrap', - overflowWrap: 'break-word', - width: '171px', - marginRight: '25px', - }), -); +export const StyledAddCustomDnsLabel = styled(Cell.Label)<{ $paddingLeft?: number }>((props) => ({ + fontFamily: 'Open Sans', + fontWeight: 400, + fontSize: '16px', + paddingLeft: (props.$paddingLeft ?? 32) + 'px', + whiteSpace: 'pre-wrap', + overflowWrap: 'break-word', + width: '171px', + marginRight: '25px', +})); export const StyledContainer = styled(Cell.Container)({ display: 'flex', @@ -59,7 +56,7 @@ export const StyledRemoveButton = styled.button({ }); export const StyledRemoveIcon = styled(ImageView)({ - [StyledRemoveButton + ':hover &']: { + [StyledRemoveButton + ':hover &&']: { backgroundColor: colors.white80, }, }); diff --git a/gui/src/renderer/components/CustomScrollbars.tsx b/gui/src/renderer/components/CustomScrollbars.tsx index ab95d66511dd..65db8c87fe54 100644 --- a/gui/src/renderer/components/CustomScrollbars.tsx +++ b/gui/src/renderer/components/CustomScrollbars.tsx @@ -19,44 +19,44 @@ const StyledCustomScrollbars = styled.div({ overflow: 'hidden', }); -const StyledScrollable = styled.div((props: { fillContainer?: boolean }) => ({ - flex: props.fillContainer ? '1' : undefined, +const StyledScrollable = styled.div<{ $fillContainer?: boolean }>((props) => ({ + flex: props.$fillContainer ? '1' : undefined, width: '100%', overflow: 'auto', - '::-webkit-scrollbar': { + '&&::-webkit-scrollbar': { display: 'none', }, })); -const StyledTrack = styled.div({}, (props: { canScroll: boolean; show: boolean }) => ({ +const StyledTrack = styled.div<{ $canScroll: boolean; $show: boolean }>((props) => ({ position: 'absolute', top: 0, right: 0, bottom: 0, width: '16px', - backgroundColor: props.show ? 'rgba(0, 0, 0, 0.2)' : 'rgba(0, 0, 0, 0)', + backgroundColor: props.$show ? 'rgba(0, 0, 0, 0.2)' : 'rgba(0, 0, 0, 0)', borderRadius: '8px', transition: 'width 0.1s ease-in-out, background-color 0.25s ease-in-out', zIndex: 99, - pointerEvents: props.canScroll ? 'auto' : 'none', - // Thumb should be less transparent when track is hovered. - [`&:hover ${StyledThumb}`]: { - backgroundColor: 'rgba(255, 255, 255, 0.65)', - }, + pointerEvents: props.$canScroll ? 'auto' : 'none', })); -const StyledThumb = styled.div( - {}, - (props: { show: boolean; isDragging: boolean; wide: boolean }) => ({ +const StyledThumb = styled.div<{ $show: boolean; $isDragging: boolean; $wide: boolean }>( + (props) => ({ position: 'absolute', top: 0, right: 0, - borderRadius: props.wide ? '6px' : '4px', - width: props.wide ? '12px' : '8px', + borderRadius: props.$wide ? '6px' : '4px', + width: props.$wide ? '12px' : '8px', transition: 'width 0.25s ease-in-out, border-radius 0.25s ease-in-out, height 0.25s ease-in-out, opacity 0.25s ease-in-out, background-color 0.1s ease-in-out', - opacity: props.show ? 1 : 0, - backgroundColor: props.isDragging ? 'rgba(255, 255, 255, 0.65)' : 'rgba(255, 255, 255, 0.4)', + opacity: props.$show ? 1 : 0, + backgroundColor: props.$isDragging ? 'rgba(255, 255, 255, 0.65)' : 'rgba(255, 255, 255, 0.4)', + + // Thumb should be less transparent when track is hovered. + [`${StyledTrack}:hover &&`]: { + backgroundColor: 'rgba(255, 255, 255, 0.65)', + }, }), ); @@ -260,20 +260,20 @@ class CustomScrollbars extends React.Component { diff --git a/gui/src/renderer/components/Filter.tsx b/gui/src/renderer/components/Filter.tsx index a8e67b3f9c12..2cbc9ab239af 100644 --- a/gui/src/renderer/components/Filter.tsx +++ b/gui/src/renderer/components/Filter.tsx @@ -201,7 +201,7 @@ function providersSelector(state: IReduxState): Record { const StyledSelector = styled(Selector)({ marginBottom: 0, -}) as typeof Selector; +}); interface IFilterByOwnershipProps { ownership: Ownership; @@ -290,7 +290,7 @@ function FilterByProvider(props: IFilterByProviderProps) { value)} onChange={toggleAll} /> @@ -310,7 +310,7 @@ function toggleAllProviders(providers: Record, value?: boolean) } interface IStyledRowTitleProps { - bold?: boolean; + $bold?: boolean; } const StyledCheckbox = styled.div({ @@ -325,13 +325,13 @@ const StyledCheckbox = styled.div({ const StyledRow = styled(Cell.Row)({ backgroundColor: colors.blue40, - ':hover': { + '&&:hover': { backgroundColor: colors.blue80, }, }); -const StyledRowTitle = styled.label(normalText, (props: IStyledRowTitleProps) => ({ - fontWeight: props.bold ? 600 : 400, +const StyledRowTitle = styled.label(normalText, (props) => ({ + fontWeight: props.$bold ? 600 : 400, color: colors.white, marginLeft: '22px', })); @@ -350,7 +350,7 @@ function CheckboxRow(props: ICheckboxRowProps) { {props.checked && } - + {props.label} diff --git a/gui/src/renderer/components/HeaderBar.tsx b/gui/src/renderer/components/HeaderBar.tsx index a5c3969f0873..98502a6346a1 100644 --- a/gui/src/renderer/components/HeaderBar.tsx +++ b/gui/src/renderer/components/HeaderBar.tsx @@ -29,16 +29,16 @@ const headerBarStyleColorMap = { }; interface IHeaderBarContainerProps { - barStyle?: HeaderBarStyle; - accountInfoVisible: boolean; - unpinnedWindow: boolean; + $barStyle?: HeaderBarStyle; + $accountInfoVisible: boolean; + $unpinnedWindow: boolean; } -const HeaderBarContainer = styled.header({}, (props: IHeaderBarContainerProps) => ({ +const HeaderBarContainer = styled.header((props) => ({ padding: '15px 11px 0px 16px', - minHeight: props.accountInfoVisible ? '80px' : '68px', - height: props.accountInfoVisible ? '80px' : '68px', - backgroundColor: headerBarStyleColorMap[props.barStyle ?? HeaderBarStyle.default], + minHeight: props.$accountInfoVisible ? '80px' : '68px', + height: props.$accountInfoVisible ? '80px' : '68px', + backgroundColor: headerBarStyleColorMap[props.$barStyle ?? HeaderBarStyle.default], transitionProperty: 'height, min-height', transitionDuration: '250ms', transitionTimingFunction: 'ease-in-out', @@ -63,10 +63,10 @@ export default function HeaderBar(props: IHeaderBarProps) { return ( + $accountInfoVisible={props.showAccountInfo ?? false} + $unpinnedWindow={unpinnedWindow}> {props.children} {props.showAccountInfo && } diff --git a/gui/src/renderer/components/ImageView.tsx b/gui/src/renderer/components/ImageView.tsx index 3be04159a2df..fa3855b21a5a 100644 --- a/gui/src/renderer/components/ImageView.tsx +++ b/gui/src/renderer/components/ImageView.tsx @@ -1,7 +1,10 @@ import React, { useMemo } from 'react'; import styled from 'styled-components'; -export interface IImageViewProps extends IImageMaskProps { +import { NonTransientProps } from '../lib/styles'; + +export interface IImageViewProps + extends NonTransientProps { source: string; onClick?: (event: React.MouseEvent) => void; className?: string; @@ -11,8 +14,8 @@ interface IImageMaskProps extends React.HTMLAttributes { width?: number; height?: number; disabled?: boolean; - tintColor?: string; - tintHoverColor?: string; + $tintColor?: string; + $tintHoverColor?: string; } const Wrapper = styled.div({ @@ -21,7 +24,7 @@ const Wrapper = styled.div({ justifyContent: 'center', }); -const ImageMask = styled.div((props: IImageMaskProps) => { +const ImageMask = styled.div((props) => { const maskWidth = props.width ? `${props.width}px` : 'auto'; const maskHeight = props.height ? `${props.height}px` : 'auto'; return { @@ -29,9 +32,9 @@ const ImageMask = styled.div((props: IImageMaskProps) => { maskSize: `${maskWidth} ${maskHeight}`, maskPosition: 'center', lineHeight: 0, - backgroundColor: props.tintColor, - ':hover': { - backgroundColor: (!props.disabled && props.tintHoverColor) || props.tintColor, + backgroundColor: props.$tintColor, + '&&:hover': { + backgroundColor: (!props.disabled && props.$tintHoverColor) || props.$tintColor, }, }; }); @@ -47,9 +50,13 @@ export default function ImageView(props: IImageViewProps) { const style = useMemo(() => ({ WebkitMaskImage: `url('${url}')` }), [url]); if (props.tintColor) { - const { source: _source, ...otherProps } = props; + const { source: _source, tintColor, tintHoverColor, ...otherProps } = props; return ( - + ); diff --git a/gui/src/renderer/components/Launch.tsx b/gui/src/renderer/components/Launch.tsx index 5f12fcce8f6f..3f86e4d19cf7 100644 --- a/gui/src/renderer/components/Launch.tsx +++ b/gui/src/renderer/components/Launch.tsx @@ -21,10 +21,10 @@ export default function Launch() { ); } -const StyledFooter = styled(Footer)({}, (props: { show: boolean }) => ({ +const StyledFooter = styled(Footer)<{ $show: boolean }>((props) => ({ backgroundColor: colors.blue, padding: `0 14px ${measurements.viewMargin}`, - opacity: props.show ? 1 : 0, + opacity: props.$show ? 1 : 0, transition: 'opacity 250ms ease-in-out', })); @@ -55,7 +55,7 @@ function SettingsFooter(props: ISettingsFooterProps) { }, []); return ( - + {messages.pgettext( diff --git a/gui/src/renderer/components/Login.tsx b/gui/src/renderer/components/Login.tsx index 07d4814f1b83..32eb5bbe82a3 100644 --- a/gui/src/renderer/components/Login.tsx +++ b/gui/src/renderer/components/Login.tsx @@ -108,7 +108,7 @@ export default class Login extends React.Component { {this.createLoginForm()} - {this.createFooter()} + {this.createFooter()} ); @@ -297,9 +297,9 @@ export default class Login extends React.Component { <> {this.formSubtitle()} { /> ({ +export const StyledInputSubmitIcon = styled(ImageView)<{ $visible: boolean }>((props) => ({ flex: 0, borderWidth: '0px', width: '48px', alignItems: 'center', justifyContent: 'center', - opacity: props.visible ? 1 : 0, + opacity: props.$visible ? 1 : 0, })); export const StyledAccountDropdownItem = styled.li({ @@ -40,7 +40,7 @@ export const StyledAccountDropdownItem = styled.li({ flex: 1, backgroundColor: colors.white60, cursor: 'default', - ':hover': { + '&&:hover': { backgroundColor: colors.white40, }, }); @@ -51,7 +51,7 @@ export const StyledAccountDropdownItemButton = styled(Cell.CellButton)({ flexDirection: 'row', alignItems: 'stretch', backgroundColor: 'transparent', - ':not(:disabled):hover': { + '&&:not(:disabled):hover': { backgroundColor: 'transparent', }, }); @@ -75,11 +75,11 @@ export const StyledTopInfo = styled.div({ flex: 1, }); -export const StyledFooter = styled(Footer)({}, (props: { show: boolean }) => ({ +export const StyledFooter = styled(Footer)<{ $show: boolean }>((props) => ({ position: 'relative', width: '100%', bottom: 0, - transform: `translateY(${props.show ? 0 : 100}%)`, + transform: `translateY(${props.$show ? 0 : 100}%)`, backgroundColor: colors.darkBlue, transition: 'transform 250ms ease-in-out', })); @@ -103,18 +103,18 @@ export const StyledLoginForm = styled.div({ }); interface IStyledAccountInputGroupProps { - editable: boolean; - active: boolean; - error: boolean; + $editable: boolean; + $active: boolean; + $error: boolean; } -export const StyledAccountInputGroup = styled.form((props: IStyledAccountInputGroupProps) => ({ +export const StyledAccountInputGroup = styled.form((props) => ({ borderWidth: '2px', borderStyle: 'solid', borderRadius: '8px', overflow: 'hidden', - borderColor: props.error ? colors.red40 : props.active ? colors.darkBlue : 'transparent', - opacity: props.editable ? 1 : 0.6, + borderColor: props.$error ? colors.red40 : props.$active ? colors.darkBlue : 'transparent', + opacity: props.$editable ? 1 : 0.6, })); export const StyledAccountInputBackdrop = styled.div({ @@ -123,14 +123,14 @@ export const StyledAccountInputBackdrop = styled.div({ borderColor: colors.darkBlue, }); -export const StyledInputButton = styled.button((props: { visible: boolean }) => ({ +export const StyledInputButton = styled.button<{ $visible: boolean }>((props) => ({ display: 'flex', flex: 0, borderWidth: 0, width: '48px', alignItems: 'center', justifyContent: 'center', - opacity: props.visible ? 1 : 0, + opacity: props.$visible ? 1 : 0, transition: 'opacity 250ms ease-in-out', backgroundColor: colors.green, })); @@ -165,7 +165,7 @@ export const StyledInput = styled(FormattableTextInput)(largeText, { color: colors.blue, backgroundColor: 'transparent', flex: 1, - '::placeholder': { + '&&::placeholder': { color: colors.blue40, }, }); diff --git a/gui/src/renderer/components/Marquee.tsx b/gui/src/renderer/components/Marquee.tsx index 5175fdc4a0ad..c654e473d23c 100644 --- a/gui/src/renderer/components/Marquee.tsx +++ b/gui/src/renderer/components/Marquee.tsx @@ -7,14 +7,16 @@ const Container = styled.div({ overflow: 'hidden', }); -const Text = styled.span({}, (props: { overflow: number; alignRight: boolean }) => ({ +const Text = styled.span<{ $overflow: number; $alignRight: boolean }>((props) => ({ display: 'inline-block', // Prevents Container from adding 2px below the text. verticalAlign: 'middle', whiteSpace: 'nowrap', - willChange: props.overflow > 0 ? 'transform' : 'auto', - transform: props.alignRight ? `translate3d(${-props.overflow}px, 0, 0)` : 'translate3d(0, 0, 0)', - transition: `transform linear ${props.overflow * 80}ms`, + willChange: props.$overflow > 0 ? 'transform' : 'auto', + transform: props.$alignRight + ? `translate3d(${-props.$overflow}px, 0, 0)` + : 'translate3d(0, 0, 0)', + transition: `transform linear ${props.$overflow * 80}ms`, })); interface IMarqueeProps { @@ -67,8 +69,8 @@ export default class Marquee extends React.Component {children} diff --git a/gui/src/renderer/components/Modal.tsx b/gui/src/renderer/components/Modal.tsx index d9be9e767d5d..e87e2113f29f 100644 --- a/gui/src/renderer/components/Modal.tsx +++ b/gui/src/renderer/components/Modal.tsx @@ -25,9 +25,9 @@ const ModalContent = styled.div({ overflow: 'hidden', }); -const ModalBackground = styled.div({}, (props: { visible: boolean }) => ({ - backgroundColor: props.visible ? 'rgba(0,0,0,0.5)' : 'rgba(0,0,0,0)', - backdropFilter: props.visible ? 'blur(1.5px)' : '', +const ModalBackground = styled.div<{ $visible: boolean }>((props) => ({ + backgroundColor: props.$visible ? 'rgba(0,0,0,0.5)' : 'rgba(0,0,0,0)', + backdropFilter: props.$visible ? 'blur(1.5px)' : '', position: 'absolute', display: 'flex', flexDirection: 'column', @@ -37,7 +37,7 @@ const ModalBackground = styled.div({}, (props: { visible: boolean }) => ({ right: 0, bottom: 0, transition: 'background-color 150ms ease-out', - pointerEvents: props.visible ? 'auto' : 'none', + pointerEvents: props.$visible ? 'auto' : 'none', zIndex: 2, })); @@ -111,11 +111,11 @@ const ModalAlertContainer = styled.div({ padding: '14px', }); -const StyledModalAlert = styled.div({}, (props: { visible: boolean; closing: boolean }) => { +const StyledModalAlert = styled.div<{ $visible: boolean; $closing: boolean }>((props) => { let transform = ''; - if (props.visible && props.closing) { + if (props.$visible && props.$closing) { transform = 'scale(80%)'; - } else if (!props.visible) { + } else if (!props.$visible) { transform = 'translateY(10px) scale(98%)'; } @@ -126,7 +126,7 @@ const StyledModalAlert = styled.div({}, (props: { visible: boolean; closing: boo borderRadius: '11px', padding: '16px 0 16px 16px', maxHeight: '80vh', - opacity: props.visible && !props.closing ? 1 : 0, + opacity: props.$visible && !props.$closing ? 1 : 0, transform, boxShadow: ' 0px 15px 35px 5px rgba(0,0,0,0.5)', transition: 'all 150ms ease-out', @@ -254,15 +254,15 @@ class ModalAlertImpl extends React.Component - + {this.props.type && ( diff --git a/gui/src/renderer/components/NavigationBar.tsx b/gui/src/renderer/components/NavigationBar.tsx index 56c3d2b8a3c3..d375fc34d639 100644 --- a/gui/src/renderer/components/NavigationBar.tsx +++ b/gui/src/renderer/components/NavigationBar.tsx @@ -180,7 +180,7 @@ interface ITitleBarItemProps { export const TitleBarItem = React.memo(function TitleBarItemT(props: ITitleBarItemProps) { const { visible } = useContext(TitleBarItemContext); - return {props.children}; + return {props.children}; }); export function BackBarItem() { diff --git a/gui/src/renderer/components/NavigationBarStyles.tsx b/gui/src/renderer/components/NavigationBarStyles.tsx index d773c868d845..eb4472c9005d 100644 --- a/gui/src/renderer/components/NavigationBarStyles.tsx +++ b/gui/src/renderer/components/NavigationBarStyles.tsx @@ -25,7 +25,7 @@ export const StyledNavigationBar = styled.nav({ padding: '12px', }); -export const StyledTitleBarItemLabel = styled.h1(normalText, (props: { visible?: boolean }) => ({ +export const StyledTitleBarItemLabel = styled.h1<{ $visible?: boolean }>(normalText, (props) => ({ fontWeight: 400, lineHeight: '22px', color: colors.white, @@ -33,7 +33,7 @@ export const StyledTitleBarItemLabel = styled.h1(normalText, (props: { visible?: overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', - opacity: props.visible ? 1 : 0, + opacity: props.$visible ? 1 : 0, transition: 'opacity 250ms ease-in-out', })); @@ -51,7 +51,7 @@ export const StyledBackBarItemButton = styled.button({ export const StyledBackBarItemIcon = styled(ImageView)({ marginRight: '8px', - [StyledBackBarItemButton + ':hover &']: { + [StyledBackBarItemButton + ':hover &&']: { backgroundColor: colors.white60, }, }); diff --git a/gui/src/renderer/components/NotificationArea.tsx b/gui/src/renderer/components/NotificationArea.tsx index 79fb3ef17c3f..9bce47eea651 100644 --- a/gui/src/renderer/components/NotificationArea.tsx +++ b/gui/src/renderer/components/NotificationArea.tsx @@ -97,7 +97,7 @@ export default function NotificationArea(props: IProps) { if (notification) { return ( - + {notification.title} {formatHtml(notification.subtitle ?? '')} diff --git a/gui/src/renderer/components/NotificationBanner.tsx b/gui/src/renderer/components/NotificationBanner.tsx index 0c63d3ba2d96..3b66abb204b6 100644 --- a/gui/src/renderer/components/NotificationBanner.tsx +++ b/gui/src/renderer/components/NotificationBanner.tsx @@ -105,7 +105,7 @@ export const NotificationActions = styled.div({ }); interface INotificationIndicatorProps { - type?: InAppNotificationIndicatorType; + $type?: InAppNotificationIndicatorType; } const notificationIndicatorTypeColorMap = { @@ -114,29 +114,29 @@ const notificationIndicatorTypeColorMap = { error: colors.red, }; -export const NotificationIndicator = styled.div((props: INotificationIndicatorProps) => ({ +export const NotificationIndicator = styled.div((props) => ({ width: '10px', height: '10px', borderRadius: '5px', marginTop: '4px', marginRight: '8px', - backgroundColor: props.type ? notificationIndicatorTypeColorMap[props.type] : 'transparent', + backgroundColor: props.$type ? notificationIndicatorTypeColorMap[props.$type] : 'transparent', })); interface ICollapsibleProps { - alignBottom: boolean; - height?: number; + $alignBottom: boolean; + $height?: number; } -const Collapsible = styled.div({}, (props: ICollapsibleProps) => { +const Collapsible = styled.div((props) => { return { display: 'flex', flexDirection: 'column', - justifyContent: props.alignBottom ? 'flex-end' : 'flex-start', + justifyContent: props.$alignBottom ? 'flex-end' : 'flex-start', backgroundColor: 'rgba(25, 38, 56, 0.95)', overflow: 'hidden', // Using auto as the initial value prevents transition if a notification is visible on mount. - height: props.height === undefined ? 'auto' : `${props.height}px`, + height: props.$height === undefined ? 'auto' : `${props.$height}px`, transition: 'height 250ms ease-in-out', }; }); @@ -175,7 +175,7 @@ export function NotificationBanner(props: INotificationBannerProps) { }); return ( - + {props.children ?? prevChildren.current} ); diff --git a/gui/src/renderer/components/RedeemVoucherStyles.tsx b/gui/src/renderer/components/RedeemVoucherStyles.tsx index 2ef0cc26342a..37f51ee5e4d3 100644 --- a/gui/src/renderer/components/RedeemVoucherStyles.tsx +++ b/gui/src/renderer/components/RedeemVoucherStyles.tsx @@ -20,7 +20,7 @@ export const StyledInput = styled(FormattableTextInput)(normalText, { backgroundColor: colors.white, border: 'none', borderRadius: '4px', - '::placeholder': { + '&&::placeholder': { color: colors.blue40, }, }); diff --git a/gui/src/renderer/components/RelayStatusIndicator.tsx b/gui/src/renderer/components/RelayStatusIndicator.tsx index 7d90e1491d5d..549fec4e7037 100644 --- a/gui/src/renderer/components/RelayStatusIndicator.tsx +++ b/gui/src/renderer/components/RelayStatusIndicator.tsx @@ -3,12 +3,12 @@ import styled from 'styled-components'; import { colors } from '../../config.json'; import * as Cell from './cell'; -const StyledRelayStatus = styled.div((props: { active: boolean }) => ({ +const StyledRelayStatus = styled.div<{ $active: boolean }>((props) => ({ width: '16px', height: '16px', borderRadius: '8px', margin: '0 12px 0 4px', - backgroundColor: props.active ? colors.green90 : colors.red95, + backgroundColor: props.$active ? colors.green90 : colors.red95, })); const TickIcon = styled(Cell.Icon)({ @@ -25,6 +25,6 @@ export default function RelayStatusIndicator(props: IProps) { return props.selected ? ( ) : ( - + ); } diff --git a/gui/src/renderer/components/SearchBar.tsx b/gui/src/renderer/components/SearchBar.tsx index fbe7d3573ac5..e21439fbbfff 100644 --- a/gui/src/renderer/components/SearchBar.tsx +++ b/gui/src/renderer/components/SearchBar.tsx @@ -22,15 +22,15 @@ export const StyledSearchInput = styled.input.attrs({ type: 'text' })({ lineHeight: '24px', color: colors.white60, backgroundColor: colors.white10, - '::placeholder': { + '&&::placeholder': { color: colors.white60, }, - ':focus': { + '&&:focus': { color: colors.blue, backgroundColor: colors.white, - '::placeholder': { - color: colors.blue40, - }, + }, + '&&:focus::placeholder': { + color: colors.blue40, }, }); @@ -49,20 +49,20 @@ export const StyledSearchIcon = styled(ImageView)({ top: '50%', transform: 'translateY(-50%)', left: '9px', - [`${StyledSearchInput}:focus ~ &`]: { + [`${StyledSearchInput}:focus ~ &&`]: { backgroundColor: colors.blue, }, }); export const StyledClearIcon = styled(ImageView)({ - ':hover': { + '&&:hover': { backgroundColor: colors.white60, }, - [`${StyledSearchInput}:focus ~ ${StyledClearButton} &`]: { + [`${StyledSearchInput}:focus ~ ${StyledClearButton} &&`]: { backgroundColor: colors.blue40, - ':hover': { - backgroundColor: colors.blue, - }, + }, + [`${StyledSearchInput}:focus ~ ${StyledClearButton} &&:hover`]: { + backgroundColor: colors.blue, }, }); diff --git a/gui/src/renderer/components/SecuredLabel.tsx b/gui/src/renderer/components/SecuredLabel.tsx index 736297b480c2..534a01a58c65 100644 --- a/gui/src/renderer/components/SecuredLabel.tsx +++ b/gui/src/renderer/components/SecuredLabel.tsx @@ -25,10 +25,10 @@ const securedDisplayStyleColorMap = { [SecuredDisplayStyle.failedToSecure]: colors.red, }; -const StyledSecuredLabel = styled.span((props: { displayStyle: SecuredDisplayStyle }) => ({ +const StyledSecuredLabel = styled.span<{ $displayStyle: SecuredDisplayStyle }>((props) => ({ display: 'inline-block', minHeight: '22px', - color: securedDisplayStyleColorMap[props.displayStyle], + color: securedDisplayStyleColorMap[props.$displayStyle], })); interface ISecuredLabelProps { @@ -37,8 +37,13 @@ interface ISecuredLabelProps { } export default function SecuredLabel(props: ISecuredLabelProps) { + const { displayStyle, ...otherProps } = props; return ( - + {getLabelText(props.displayStyle)} ); diff --git a/gui/src/renderer/components/SelectLanguage.tsx b/gui/src/renderer/components/SelectLanguage.tsx index b97243a45611..eb0ad038da34 100644 --- a/gui/src/renderer/components/SelectLanguage.tsx +++ b/gui/src/renderer/components/SelectLanguage.tsx @@ -21,7 +21,7 @@ import SettingsHeader, { HeaderTitle } from './SettingsHeader'; const StyledSelector = styled(Selector)({ marginBottom: 0, -}) as typeof Selector; +}); export default function SelectLanguage() { const history = useHistory(); diff --git a/gui/src/renderer/components/SettingsHeader.tsx b/gui/src/renderer/components/SettingsHeader.tsx index 8724ea93d9a9..47e1f47f7b08 100644 --- a/gui/src/renderer/components/SettingsHeader.tsx +++ b/gui/src/renderer/components/SettingsHeader.tsx @@ -13,7 +13,7 @@ export const Container = styled.div({ }); export const ContentWrapper = styled.div({ - ':not(:first-child)': { + '&&:not(:first-child)': { paddingTop: '8px', }, }); diff --git a/gui/src/renderer/components/SplitTunnelingSettings.tsx b/gui/src/renderer/components/SplitTunnelingSettings.tsx index aa1f82b2fc09..cb4de70deb28 100644 --- a/gui/src/renderer/components/SplitTunnelingSettings.tsx +++ b/gui/src/renderer/components/SplitTunnelingSettings.tsx @@ -55,7 +55,7 @@ export default function SplitTunneling() { return ( <> - + @@ -272,18 +272,18 @@ function LinuxApplicationRow(props: ILinuxApplicationRowProps) { <> + $lookDisabled={disabled}> {props.application.icon ? ( ) : ( )} - {props.application.name} + {props.application.name} {props.application.warning && ( )} diff --git a/gui/src/renderer/components/SplitTunnelingSettingsStyles.tsx b/gui/src/renderer/components/SplitTunnelingSettingsStyles.tsx index 61a1606b2e7a..1aea5108a14b 100644 --- a/gui/src/renderer/components/SplitTunnelingSettingsStyles.tsx +++ b/gui/src/renderer/components/SplitTunnelingSettingsStyles.tsx @@ -9,7 +9,7 @@ import { NavigationScrollbars } from './NavigationBar'; import SearchBar from './SearchBar'; import { HeaderTitle } from './SettingsHeader'; -export const StyledPageCover = styled.div({}, (props: { show: boolean }) => ({ +export const StyledPageCover = styled.div<{ $show: boolean }>((props) => ({ position: 'absolute', zIndex: 2, top: 0, @@ -18,7 +18,7 @@ export const StyledPageCover = styled.div({}, (props: { show: boolean }) => ({ bottom: 0, backgroundColor: colors.black, opacity: 0.5, - display: props.show ? 'block' : 'none', + display: props.$show ? 'block' : 'none', })); export const StyledNavigationScrollbars = styled(NavigationScrollbars)({ @@ -31,17 +31,21 @@ export const StyledContent = styled.div({ flex: 1, }); -export const StyledCellButton = styled(Cell.CellButton)((props: { lookDisabled?: boolean }) => ({ - ':not(:disabled):hover': { - backgroundColor: props.lookDisabled ? colors.blue : undefined, +export const StyledCellButton = styled(Cell.CellButton)<{ $lookDisabled?: boolean }>((props) => ({ + '&&:not(:disabled):hover': { + backgroundColor: props.$lookDisabled ? colors.blue : undefined, }, })); -const disabledApplication = (props: { lookDisabled?: boolean }) => ({ - opacity: props.lookDisabled ? 0.6 : undefined, +interface DisabledApplicationProps { + $lookDisabled?: boolean; +} + +const disabledApplication = (props: DisabledApplicationProps) => ({ + opacity: props.$lookDisabled ? 0.6 : undefined, }); -export const StyledIcon = styled(Cell.UntintedIcon)(disabledApplication, { +export const StyledIcon = styled(Cell.UntintedIcon)(disabledApplication, { marginRight: '12px', }); @@ -54,11 +58,15 @@ export const StyledCellWarningIcon = styled(Cell.Icon)({ marginRight: '3px', }); -export const StyledCellLabel = styled(Cell.Label)(disabledApplication, normalText, { - fontWeight: 400, - wordWrap: 'break-word', - overflow: 'hidden', -}); +export const StyledCellLabel = styled(Cell.Label)( + disabledApplication, + normalText, + { + fontWeight: 400, + wordWrap: 'break-word', + overflow: 'hidden', + }, +); export const StyledIconPlaceholder = styled.div({ width: '35px', diff --git a/gui/src/renderer/components/Switch.tsx b/gui/src/renderer/components/Switch.tsx index cb9e86b219c3..e5aaec4bb0bb 100644 --- a/gui/src/renderer/components/Switch.tsx +++ b/gui/src/renderer/components/Switch.tsx @@ -14,7 +14,7 @@ interface IProps { innerRef?: React.Ref; } -const SwitchContainer = styled.div({}, (props: { disabled: boolean }) => ({ +const SwitchContainer = styled.div<{ disabled: boolean }>((props) => ({ position: 'relative', width: '48px', height: '30px', @@ -25,10 +25,10 @@ const SwitchContainer = styled.div({}, (props: { disabled: boolean }) => ({ padding: '2px', })); -const Knob = styled.div({}, (props: { isOn: boolean; disabled: boolean }) => { - let backgroundColor = props.isOn ? colors.green : colors.red; +const Knob = styled.div<{ $isOn: boolean; disabled: boolean }>((props) => { + let backgroundColor = props.$isOn ? colors.green : colors.red; if (props.disabled) { - backgroundColor = props.isOn ? colors.green40 : colors.red40; + backgroundColor = props.$isOn ? colors.green40 : colors.red40; } return { @@ -40,7 +40,7 @@ const Knob = styled.div({}, (props: { isOn: boolean; disabled: boolean }) => { backgroundColor, // When enabled the button should be placed all the way to the right (100%) minus padding (2px) // minus it's own width (22px). - left: props.isOn ? 'calc(100% - 2px - 22px)' : '2px', + left: props.$isOn ? 'calc(100% - 2px - 22px)' : '2px', }; }); @@ -59,7 +59,7 @@ export default class Switch extends React.PureComponent { aria-disabled={this.props.disabled ?? false} tabIndex={-1} className={this.props.className}> - + ); } diff --git a/gui/src/renderer/components/TransitionContainer.tsx b/gui/src/renderer/components/TransitionContainer.tsx index 56315d5dcbf4..b9a60185edcf 100644 --- a/gui/src/renderer/components/TransitionContainer.tsx +++ b/gui/src/renderer/components/TransitionContainer.tsx @@ -41,29 +41,36 @@ interface IState { export const StyledTransitionContainer = styled.div({ flex: 1 }); -export const StyledTransitionContent = styled.div.attrs({ 'data-testid': 'transition-content' })( - {}, - (props: { transition?: IItemStyle; disableUserInteraction?: boolean }) => { - const x = `${props.transition?.x ?? 0}%`; - const y = `${props.transition?.y ?? 0}%`; - const duration = props.transition?.duration ?? 450; +interface StyledTransitionContentProps { + $transition?: IItemStyle; + $disableUserInteraction?: boolean; +} - return { - display: 'flex', - flexDirection: 'column', - position: 'absolute', - left: 0, - right: 0, - top: 0, - bottom: 0, - zIndex: props.transition?.inFront ? 1 : 0, - willChange: 'transform', - transform: `translate3d(${x}, ${y}, 0)`, - transition: `transform ${duration}ms ease-in-out`, - pointerEvents: props.disableUserInteraction ? 'none' : undefined, - }; - }, -); +export const StyledTransitionContent = styled.div.attrs< + StyledTransitionContentProps, + { 'data-testid': string } +>({ + 'data-testid': 'transition-content', +})((props) => { + const x = `${props.$transition?.x ?? 0}%`; + const y = `${props.$transition?.y ?? 0}%`; + const duration = props.$transition?.duration ?? 450; + + return { + display: 'flex', + flexDirection: 'column', + position: 'absolute', + left: 0, + right: 0, + top: 0, + bottom: 0, + zIndex: props.$transition?.inFront ? 1 : 0, + willChange: 'transform', + transform: `translate3d(${x}, ${y}, 0)`, + transition: `transform ${duration}ms ease-in-out`, + pointerEvents: props.$disableUserInteraction ? 'none' : undefined, + }; +}); export const StyledTransitionView = styled.div({ display: 'flex', @@ -132,9 +139,9 @@ export default class TransitionContainer extends React.Component + $disableUserInteraction={willExit}> {this.state.currentItem.view} @@ -144,7 +151,7 @@ export default class TransitionContainer extends React.Component {this.state.nextItem.view} diff --git a/gui/src/renderer/components/cell/CellButton.tsx b/gui/src/renderer/components/cell/CellButton.tsx index 0111574f70db..b0079226f331 100644 --- a/gui/src/renderer/components/cell/CellButton.tsx +++ b/gui/src/renderer/components/cell/CellButton.tsx @@ -8,17 +8,17 @@ import { Row } from './Row'; import { CellSectionContext } from './Section'; interface IStyledCellButtonProps extends React.HTMLAttributes { - selected?: boolean; - containedInSection: boolean; + $selected?: boolean; + $containedInSection: boolean; } -const StyledCellButton = styled(Row)({}, (props: IStyledCellButtonProps) => { - const backgroundColor = props.selected +const StyledCellButton = styled(Row)((props) => { + const backgroundColor = props.$selected ? colors.green - : props.containedInSection + : props.$containedInSection ? colors.blue40 : colors.blue; - const backgroundColorHover = props.selected ? colors.green : colors.blue80; + const backgroundColorHover = props.$selected ? colors.green : colors.blue80; return { paddingRight: '16px', @@ -27,7 +27,7 @@ const StyledCellButton = styled(Row)({}, (props: IStyledCellButtonProps) => { cursor: 'default', border: 'none', backgroundColor, - ':not(:disabled):hover': { + '&&:not(:disabled):hover': { backgroundColor: props.onClick ? backgroundColorHover : backgroundColor, }, }; @@ -39,14 +39,16 @@ interface ICellButtonProps extends React.ButtonHTMLAttributes export const CellButton = styled( React.forwardRef(function Button(props: ICellButtonProps, ref: React.Ref) { + const { selected, ...otherProps } = props; const containedInSection = useContext(CellSectionContext); return ( ); diff --git a/gui/src/renderer/components/cell/Group.tsx b/gui/src/renderer/components/cell/Group.tsx index a3198cabb036..86d95f0a33ee 100644 --- a/gui/src/renderer/components/cell/Group.tsx +++ b/gui/src/renderer/components/cell/Group.tsx @@ -3,12 +3,12 @@ import styled from 'styled-components'; import { measurements } from '../common-styles'; interface IStyledGroupProps { - noMarginBottom?: boolean; + $noMarginBottom?: boolean; } -export const Group = styled.div({}, (props: IStyledGroupProps) => ({ +export const Group = styled.div((props) => ({ display: 'flex', flexDirection: 'column', flex: 1, - marginBottom: props.noMarginBottom ? '0px' : measurements.rowVerticalMargin, + marginBottom: props.$noMarginBottom ? '0px' : measurements.rowVerticalMargin, })); diff --git a/gui/src/renderer/components/cell/Input.tsx b/gui/src/renderer/components/cell/Input.tsx index 55260f670368..97fe01a18568 100644 --- a/gui/src/renderer/components/cell/Input.tsx +++ b/gui/src/renderer/components/cell/Input.tsx @@ -24,15 +24,15 @@ const inputTextStyles: React.CSSProperties = { padding: '0px', }; -const StyledInput = styled.input({}, (props: { focused: boolean; valid?: boolean }) => ({ +const StyledInput = styled.input<{ $focused: boolean; $valid?: boolean }>((props) => ({ ...inputTextStyles, backgroundColor: 'transparent', border: 'none', width: '100%', height: '100%', - color: props.valid === false ? colors.red : props.focused ? colors.blue : colors.white, - '::placeholder': { - color: props.focused ? colors.blue60 : colors.white60, + color: props.$valid === false ? colors.red : props.$focused ? colors.blue : colors.white, + '&&::placeholder': { + color: props.$focused ? colors.blue60 : colors.white60, }, })); @@ -150,8 +150,8 @@ function InputWithRef(props: IInputProps, forwardedRef: React.Ref ({ +const InputFrame = styled.div<{ $focused: boolean }>((props) => ({ display: 'flex', flexGrow: 0, - backgroundColor: props.focused ? colors.white : 'rgba(255,255,255,0.1)', + backgroundColor: props.$focused ? colors.white : 'rgba(255,255,255,0.1)', borderRadius: '4px', padding: '6px 8px', })); @@ -222,7 +222,7 @@ function AutoSizingTextInputWithRef(props: IInputProps, forwardedRef: React.Ref< return ( - + ({ +const StyledInputWrapper = styled.div<{ $marginLeft: number }>(normalText, (props) => ({ position: 'relative', flex: 1, width: '171px', - marginLeft: props.marginLeft + 'px', + marginLeft: props.$marginLeft + 'px', lineHeight: '24px', minHeight: '24px', fontWeight: 400, @@ -266,7 +266,7 @@ const StyledInputWrapper = styled.div(normalText, (props: { marginLeft: number } maxWidth: '100%', })); -const StyledTextArea = styled.textarea(normalText, (props: { invalid?: boolean }) => ({ +const StyledTextArea = styled.textarea<{ $invalid?: boolean }>(normalText, (props) => ({ position: 'absolute', top: 0, left: 0, @@ -279,7 +279,7 @@ const StyledTextArea = styled.textarea(normalText, (props: { invalid?: boolean } fontWeight: 400, resize: 'none', padding: '10px 25px 10px 0', - color: props.invalid ? colors.red : 'auto', + color: props.$invalid ? colors.red : 'auto', })); const StyledInputFiller = styled.div({ @@ -366,7 +366,7 @@ export function RowInput(props: IRowInputProps) { return ( - + {value} ({ +const StyledLabel = styled.div<{ disabled: boolean }>(buttonText, (props) => ({ margin: '10px 0', flex: 1, color: props.disabled ? colors.white40 : colors.white, textAlign: 'left', })); -const StyledSubText = styled.span(tinyText, (props: { disabled: boolean }) => ({ +const StyledSubText = styled.span<{ disabled: boolean }>(tinyText, (props) => ({ color: props.disabled ? colors.white20 : colors.white60, flex: -1, textAlign: 'right', @@ -22,7 +22,7 @@ const StyledSubText = styled.span(tinyText, (props: { disabled: boolean }) => ({ marginRight: '8px', })); -const StyledIconContainer = styled.div((props: { disabled: boolean }) => ({ +const StyledIconContainer = styled.div<{ disabled: boolean }>((props) => ({ opacity: props.disabled ? 0.4 : 1, })); @@ -30,7 +30,7 @@ const StyledTintedIcon = styled(ImageView).attrs((props: IImageViewProps) => ({ tintColor: props.tintColor ?? colors.white60, tintHoverColor: props.tintHoverColor ?? props.tintColor ?? colors.white60, }))((props: IImageViewProps) => ({ - ':hover': { + '&&:hover': { backgroundColor: props.tintColor, }, [`${CellButton}:not(:disabled):hover &&`]: { diff --git a/gui/src/renderer/components/cell/Row.tsx b/gui/src/renderer/components/cell/Row.tsx index 08309d68436e..9aca25d3a003 100644 --- a/gui/src/renderer/components/cell/Row.tsx +++ b/gui/src/renderer/components/cell/Row.tsx @@ -1,10 +1,17 @@ +import React from 'react'; import styled from 'styled-components'; import { colors } from '../../../config.json'; import { measurements } from '../common-styles'; import { Group } from './Group'; -export const Row = styled.div((props: { includeMarginBottomOnLast?: boolean }) => ({ +interface RowProps extends React.HTMLAttributes { + includeMarginBottomOnLast?: boolean; +} + +export const Row = styled.div.withConfig({ + shouldForwardProp: (prop) => prop !== 'includeMarginBottomOnLast', +})((props) => ({ display: 'flex', alignItems: 'center', backgroundColor: colors.blue, @@ -12,7 +19,7 @@ export const Row = styled.div((props: { includeMarginBottomOnLast?: boolean }) = paddingLeft: measurements.viewMargin, paddingRight: measurements.viewMargin, marginBottom: '1px', - [`${Group} > &:last-child`]: { + [`${Group} > &&:last-child`]: { marginBottom: props.includeMarginBottomOnLast ? '1px' : '0px', }, })); diff --git a/gui/src/renderer/components/cell/Section.tsx b/gui/src/renderer/components/cell/Section.tsx index 8ba597547642..056aa8ceac8b 100644 --- a/gui/src/renderer/components/cell/Section.tsx +++ b/gui/src/renderer/components/cell/Section.tsx @@ -18,15 +18,15 @@ const StyledSection = styled.div({ interface SectionTitleProps { disabled?: boolean; - thin?: boolean; + $thin?: boolean; } -export const SectionTitle = styled(Row)(buttonText, (props: SectionTitleProps) => ({ +export const SectionTitle = styled(Row)(buttonText, (props) => ({ paddingRight: '16px', color: props.disabled ? colors.white20 : colors.white, - fontWeight: props.thin ? 400 : 600, - fontSize: props.thin ? '15px' : '18px', - ...(props.thin ? openSans : sourceSansPro), + fontWeight: props.$thin ? 400 : 600, + fontSize: props.$thin ? '15px' : '18px', + ...(props.$thin ? openSans : sourceSansPro), })); export const CellSectionContext = React.createContext(false); diff --git a/gui/src/renderer/components/cell/Selector.tsx b/gui/src/renderer/components/cell/Selector.tsx index 0842ce2c0e85..f1d9e143602a 100644 --- a/gui/src/renderer/components/cell/Selector.tsx +++ b/gui/src/renderer/components/cell/Selector.tsx @@ -77,7 +77,7 @@ export default function Selector(props: SelectorProps) { const title = props.title ? ( <> - + {props.title} @@ -91,7 +91,7 @@ export default function Selector(props: SelectorProps) { // Add potential additional items to the list. Used for custom entry. const children = ( - + {items} {props.children} @@ -121,8 +121,8 @@ export default function Selector(props: SelectorProps) { } } -const StyledCellIcon = styled(Cell.Icon)((props: { visible: boolean }) => ({ - opacity: props.visible ? 1 : 0, +const StyledCellIcon = styled(Cell.Icon)<{ $visible: boolean }>((props) => ({ + opacity: props.$visible ? 1 : 0, marginRight: '8px', })); @@ -156,7 +156,7 @@ function SelectorCell(props: SelectorCellProps) { aria-selected={props.isSelected} aria-disabled={props.disabled}> ({ +const StyledCustomContainer = styled(Cell.Container)((props) => ({ backgroundColor: props.selected ? colors.green : colors.blue40, - ':hover': { + '&&:hover': { backgroundColor: props.selected ? colors.green : colors.blue, }, })); @@ -286,7 +286,7 @@ export function SelectorWithCustomItem(props: SelectorWithCustomItemProps< aria-selected={customIsSelected} aria-disabled={props.disabled}> ({ - color: props.error ? colors.red : 'auto', +const StyledInput = styled(SimpleInput)<{ $error: boolean }>((props) => ({ + color: props.$error ? colors.red : 'auto', })); interface CustomListsProps { @@ -93,8 +93,8 @@ export default function CustomLists(props: CustomListsProps) { {messages.pgettext('select-location-view', 'Custom lists')} @@ -172,14 +172,14 @@ function AddListForm(props: AddListFormProps) { onSubmitValue={createList} onBlur={onBlur} maxLength={30} - error={error} + $error={error} autoFocus /> diff --git a/gui/src/renderer/components/select-location/LocationRow.tsx b/gui/src/renderer/components/select-location/LocationRow.tsx index 7ebae688a602..97c8528fa94d 100644 --- a/gui/src/renderer/components/select-location/LocationRow.tsx +++ b/gui/src/renderer/components/select-location/LocationRow.tsx @@ -29,15 +29,15 @@ import { } from './select-location-types'; interface IButtonColorProps { - backgroundColor: string; - backgroundColorHover: string; + $backgroundColor: string; + $backgroundColorHover: string; } const buttonColor = (props: IButtonColorProps) => { return { - backgroundColor: props.backgroundColor, - ':not(:disabled):hover': { - backgroundColor: props.backgroundColorHover, + backgroundColor: props.$backgroundColor, + '&&:not(:disabled):hover': { + backgroundColor: props.$backgroundColorHover, }, }; }; @@ -48,10 +48,10 @@ export const StyledLocationRowContainer = styled(Cell.Container)({ background: 'none', }); -export const StyledLocationRowButton = styled(Cell.Row)( +export const StyledLocationRowButton = styled(Cell.Row)( buttonColor, - (props: IButtonColorProps & { level: number }) => { - const paddingLeft = (props.level + 1) * 16 + 2; + (props) => { + const paddingLeft = (props.$level + 1) * 16 + 2; return { display: 'flex', @@ -64,13 +64,13 @@ export const StyledLocationRowButton = styled(Cell.Row)( }, ); -export const StyledLocationRowIcon = styled.button(buttonColor, { +export const StyledLocationRowIcon = styled.button(buttonColor, { position: 'relative', alignSelf: 'stretch', paddingLeft: measurements.viewMargin, paddingRight: measurements.viewMargin, - '&::before': { + '&&::before': { content: '""', position: 'absolute', margin: 'auto', @@ -93,26 +93,26 @@ export const StyledLocationRowLabel = styled(Cell.Label)(normalText, { whiteSpace: 'nowrap', }); -const StyledHoverIconButton = styled.button( +const StyledHoverIconButton = styled.button( buttonColor, - (props: { isLast?: boolean } & IButtonColorProps) => ({ + (props) => ({ flex: 0, display: 'none', padding: '0 10px', - paddingRight: props.isLast ? '17px' : '10px', + paddingRight: props.$isLast ? '17px' : '10px', margin: 0, border: 0, height: measurements.rowMinHeight, appearance: 'none', - ':not(:disabled):hover': { - backgroundColor: props.backgroundColor, + '&&:not(:disabled):hover': { + backgroundColor: props.$backgroundColor, }, [`${StyledLocationRowContainer}:hover &&`]: { display: 'block', }, [`${StyledLocationRowButton}:hover ~ &&`]: { - backgroundColor: props.backgroundColorHover, + backgroundColor: props.$backgroundColorHover, }, }), ); @@ -240,7 +240,7 @@ function LocationRow(props: IProps) { as="button" ref={buttonRef} onClick={handleClick} - level={props.level} + $level={props.level} disabled={props.source.disabled} includeMarginBottomOnLast {...background}> @@ -249,7 +249,7 @@ function LocationRow(props: IProps) { {props.allowAddToCustomList ? ( - + ) : null} @@ -258,7 +258,7 @@ function LocationRow(props: IProps) { {'customList' in props.source.location && 'country' in props.source.location && props.level === 1 ? ( - + ) : null} @@ -269,7 +269,7 @@ function LocationRow(props: IProps) { - + @@ -297,7 +297,7 @@ function LocationRow(props: IProps) { onWillExpand={onWillExpand} onTransitionEnd={props.onTransitionEnd} animationDuration={150}> - {props.children} + {props.children} )} @@ -333,8 +333,8 @@ export function getButtonColor(selected: boolean, level: number, disabled?: bool } return { - backgroundColor, - backgroundColorHover: selected || disabled ? backgroundColor : colors.blue80, + $backgroundColor: backgroundColor, + $backgroundColorHover: selected || disabled ? backgroundColor : colors.blue80, }; } diff --git a/gui/src/renderer/components/select-location/RelayLocationList.tsx b/gui/src/renderer/components/select-location/RelayLocationList.tsx index 27fe75ea50fe..49e1f2a38ca0 100644 --- a/gui/src/renderer/components/select-location/RelayLocationList.tsx +++ b/gui/src/renderer/components/select-location/RelayLocationList.tsx @@ -25,7 +25,7 @@ interface RelayLocationsProps extends CommonProps { export default function RelayLocationList({ source, ...props }: RelayLocationsProps) { return ( - + {source.map((country) => ( {children}; } -const StyledScopeBarItem = styled.button(smallText, (props: { selected?: boolean }) => ({ +const StyledScopeBarItem = styled.button<{ selected?: boolean }>(smallText, (props) => ({ cursor: 'default', flex: 1, flexBasis: 0, @@ -44,7 +44,7 @@ const StyledScopeBarItem = styled.button(smallText, (props: { selected?: boolean textAlign: 'center', border: 'none', backgroundColor: props.selected ? colors.green : 'transparent', - ':hover': { + '&&:hover': { backgroundColor: props.selected ? colors.green : colors.blue40, }, })); diff --git a/gui/src/renderer/components/select-location/SpecialLocationList.tsx b/gui/src/renderer/components/select-location/SpecialLocationList.tsx index c8c0c8e787db..030520fc73b3 100644 --- a/gui/src/renderer/components/select-location/SpecialLocationList.tsx +++ b/gui/src/renderer/components/select-location/SpecialLocationList.tsx @@ -64,7 +64,7 @@ function SpecialLocationRow(props: SpecialLocationRowProps) { const background = getButtonColor(props.source.selected, 0, props.source.disabled); return ( - + {icon && ( (props: SpecialLocationRowProps) { )}