From 17de249b6b4ab6f417d9b3b97c9764a09170f2ba Mon Sep 17 00:00:00 2001 From: Oskar Nyberg Date: Sun, 29 Oct 2023 21:11:05 +0100 Subject: [PATCH 1/5] Fix no result text in split tunneling view --- .../components/SplitTunnelingSettings.tsx | 16 +++++++++++++++- .../components/SplitTunnelingSettingsStyles.tsx | 1 + 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/gui/src/renderer/components/SplitTunnelingSettings.tsx b/gui/src/renderer/components/SplitTunnelingSettings.tsx index c8242cdd8881..9b674df4fcb4 100644 --- a/gui/src/renderer/components/SplitTunnelingSettings.tsx +++ b/gui/src/renderer/components/SplitTunnelingSettings.tsx @@ -173,7 +173,21 @@ function LinuxSplitTunnelingSettings(props: IPlatformSplitTunnelingSettingsProps - + {filteredApplications !== undefined && filteredApplications.length > 0 && ( + + )} + + {searchTerm !== '' && + (filteredApplications === undefined || filteredApplications.length === 0) && ( + + + {formatHtml( + sprintf(messages.gettext('No result for %(searchTerm)s.'), { searchTerm }), + )} + + {messages.gettext('Try a different search.')} + + )} {messages.pgettext('split-tunneling-view', 'Find another app')} diff --git a/gui/src/renderer/components/SplitTunnelingSettingsStyles.tsx b/gui/src/renderer/components/SplitTunnelingSettingsStyles.tsx index 028fac30a353..61a1606b2e7a 100644 --- a/gui/src/renderer/components/SplitTunnelingSettingsStyles.tsx +++ b/gui/src/renderer/components/SplitTunnelingSettingsStyles.tsx @@ -93,6 +93,7 @@ export const StyledNoResult = styled(Cell.CellFooter)({ flexDirection: 'column', paddingTop: 0, marginTop: 0, + marginBottom: '69px', }); export const StyledNoResultText = styled(Cell.CellFooterText)({ From ea4b8a36c0eacdda848e1a1f3a8af388be026551 Mon Sep 17 00:00:00 2001 From: Oskar Nyberg Date: Tue, 24 Oct 2023 20:17:42 +0200 Subject: [PATCH 2/5] Move ref cast to hook --- gui/src/renderer/components/CustomDnsSettings.tsx | 10 +++++----- gui/src/renderer/components/FormattableTextInput.tsx | 6 +++--- .../renderer/components/MacOsScrollbarDetection.tsx | 5 +++-- gui/src/renderer/components/NotificationBanner.tsx | 3 ++- gui/src/renderer/components/SearchBar.tsx | 5 +++-- gui/src/renderer/components/SplitTunnelingSettings.tsx | 6 +++--- gui/src/renderer/components/cell/Input.tsx | 10 +++++----- gui/src/renderer/components/cell/Selector.tsx | 3 ++- .../components/select-location/CustomLists.tsx | 8 ++++---- .../components/select-location/LocationRow.tsx | 4 ++-- .../select-location/ScrollPositionContext.tsx | 4 ++-- gui/src/renderer/lib/utilityHooks.ts | 4 ++++ 12 files changed, 38 insertions(+), 30 deletions(-) diff --git a/gui/src/renderer/components/CustomDnsSettings.tsx b/gui/src/renderer/components/CustomDnsSettings.tsx index 824e0109704d..6b8024c9e281 100644 --- a/gui/src/renderer/components/CustomDnsSettings.tsx +++ b/gui/src/renderer/components/CustomDnsSettings.tsx @@ -6,7 +6,7 @@ import { messages } from '../../shared/gettext'; import { useAppContext } from '../context'; import { formatHtml } from '../lib/html-formatter'; import { IpAddress } from '../lib/ip'; -import { useBoolean, useMounted } from '../lib/utilityHooks'; +import { useBoolean, useMounted, useStyledRef } from '../lib/utilityHooks'; import { useSelector } from '../redux/store'; import Accordion from './Accordion'; import * as AppButton from './AppButton'; @@ -57,9 +57,9 @@ export default function CustomDnsSettings() { [dns], ); - const switchRef = useRef() as React.RefObject; - const addButtonRef = useRef() as React.RefObject; - const inputContainerRef = useRef() as React.RefObject; + const switchRef = useStyledRef(); + const addButtonRef = useStyledRef(); + const inputContainerRef = useStyledRef(); const confirm = useCallback(() => { void confirmAction?.(); @@ -323,7 +323,7 @@ function CellListItem(props: ICellListItemProps) { const [invalid, setInvalid, setValid] = useBoolean(false); const isMounted = useMounted(); - const inputContainerRef = useRef() as React.RefObject; + const inputContainerRef = useStyledRef(); const onRemove = useCallback(() => props.onRemove(props.children), [ props.onRemove, diff --git a/gui/src/renderer/components/FormattableTextInput.tsx b/gui/src/renderer/components/FormattableTextInput.tsx index 133a6692e072..f6c259c4c4cf 100644 --- a/gui/src/renderer/components/FormattableTextInput.tsx +++ b/gui/src/renderer/components/FormattableTextInput.tsx @@ -1,6 +1,6 @@ -import React, { useCallback, useEffect, useRef } from 'react'; +import React, { useCallback, useEffect } from 'react'; -import { useCombinedRefs } from '../lib/utilityHooks'; +import { useCombinedRefs, useStyledRef } from '../lib/utilityHooks'; interface IFormattableTextInputProps extends React.InputHTMLAttributes { allowedCharacters: string; @@ -28,7 +28,7 @@ function FormattableTextInput( ...otherProps } = props; - const ref = useRef() as React.RefObject; + const ref = useStyledRef(); const combinedRef = useCombinedRefs(ref, forwardedRef); const unformat = useCallback( diff --git a/gui/src/renderer/components/MacOsScrollbarDetection.tsx b/gui/src/renderer/components/MacOsScrollbarDetection.tsx index de636827bd4d..aebb144f9b3b 100644 --- a/gui/src/renderer/components/MacOsScrollbarDetection.tsx +++ b/gui/src/renderer/components/MacOsScrollbarDetection.tsx @@ -1,8 +1,9 @@ -import React, { useEffect, useRef } from 'react'; +import { useEffect } from 'react'; import styled from 'styled-components'; import { MacOsScrollbarVisibility } from '../../shared/ipc-schema'; import useActions from '../lib/actionsHook'; +import { useStyledRef } from '../lib/utilityHooks'; import { useSelector } from '../redux/store'; import userInterface from '../redux/userinterface/actions'; @@ -21,7 +22,7 @@ const StyledContainer = styled.div({ export default function MacOsScrollbarDetection() { const visibility = useSelector((state) => state.userInterface.macOsScrollbarVisibility); const { setMacOsScrollbarVisibility } = useActions(userInterface); - const ref = useRef() as React.RefObject; + const ref = useStyledRef(); useEffect(() => { if (visibility === MacOsScrollbarVisibility.automatic) { diff --git a/gui/src/renderer/components/NotificationBanner.tsx b/gui/src/renderer/components/NotificationBanner.tsx index 18e18ce4f52b..0c63d3ba2d96 100644 --- a/gui/src/renderer/components/NotificationBanner.tsx +++ b/gui/src/renderer/components/NotificationBanner.tsx @@ -4,6 +4,7 @@ import styled from 'styled-components'; import { colors } from '../../config.json'; import { messages } from '../../shared/gettext'; import { InAppNotificationIndicatorType } from '../../shared/notifications/notification'; +import { useStyledRef } from '../lib/utilityHooks'; import * as AppButton from './AppButton'; import { tinyText } from './common-styles'; import ImageView from './ImageView'; @@ -156,7 +157,7 @@ export function NotificationBanner(props: INotificationBannerProps) { const [contentHeight, setContentHeight] = useState(); const [alignBottom, setAlignBottom] = useState(false); - const contentRef = useRef() as React.RefObject; + const contentRef = useStyledRef(); // Save last non-undefined children to be able to show them during the hide-transition. const prevChildren = useRef(); diff --git a/gui/src/renderer/components/SearchBar.tsx b/gui/src/renderer/components/SearchBar.tsx index 7983441ed8c5..fbe7d3573ac5 100644 --- a/gui/src/renderer/components/SearchBar.tsx +++ b/gui/src/renderer/components/SearchBar.tsx @@ -1,8 +1,9 @@ -import { useCallback, useEffect, useRef } from 'react'; +import { useCallback, useEffect } from 'react'; import styled from 'styled-components'; import { colors } from '../../config.json'; import { messages } from '../../shared/gettext'; +import { useStyledRef } from '../lib/utilityHooks'; import { normalText } from './common-styles'; import ImageView from './ImageView'; @@ -73,7 +74,7 @@ interface ISearchBarProps { } export default function SearchBar(props: ISearchBarProps) { - const inputRef = useRef() as React.RefObject; + const inputRef = useStyledRef(); const onInput = useCallback( (event: React.FormEvent) => { diff --git a/gui/src/renderer/components/SplitTunnelingSettings.tsx b/gui/src/renderer/components/SplitTunnelingSettings.tsx index 9b674df4fcb4..aa1f82b2fc09 100644 --- a/gui/src/renderer/components/SplitTunnelingSettings.tsx +++ b/gui/src/renderer/components/SplitTunnelingSettings.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { useSelector } from 'react-redux'; import { sprintf } from 'sprintf-js'; @@ -12,7 +12,7 @@ import { messages } from '../../shared/gettext'; import { useAppContext } from '../context'; import { useHistory } from '../lib/history'; import { formatHtml } from '../lib/html-formatter'; -import { useAsyncEffect } from '../lib/utilityHooks'; +import { useAsyncEffect, useStyledRef } from '../lib/utilityHooks'; import { IReduxState } from '../redux/store'; import Accordion from './Accordion'; import * as AppButton from './AppButton'; @@ -49,7 +49,7 @@ import Switch from './Switch'; export default function SplitTunneling() { const { pop } = useHistory(); const [browsing, setBrowsing] = useState(false); - const scrollbarsRef = useRef() as React.RefObject; + const scrollbarsRef = useStyledRef(); const scrollToTop = useCallback(() => scrollbarsRef.current?.scrollToTop(true), [scrollbarsRef]); diff --git a/gui/src/renderer/components/cell/Input.tsx b/gui/src/renderer/components/cell/Input.tsx index bff8364d212f..55260f670368 100644 --- a/gui/src/renderer/components/cell/Input.tsx +++ b/gui/src/renderer/components/cell/Input.tsx @@ -1,8 +1,8 @@ -import React, { useCallback, useContext, useEffect, useRef, useState } from 'react'; +import React, { useCallback, useContext, useEffect, useState } from 'react'; import styled from 'styled-components'; import { colors } from '../../../config.json'; -import { useBoolean, useCombinedRefs } from '../../lib/utilityHooks'; +import { useBoolean, useCombinedRefs, useStyledRef } from '../../lib/utilityHooks'; import { normalText } from '../common-styles'; import ImageView from '../ImageView'; import { BackAction } from '../KeyboardNavigation'; @@ -68,7 +68,7 @@ function InputWithRef(props: IInputProps, forwardedRef: React.Ref; + const inputRef = useStyledRef(); const combinedRef = useCombinedRefs(inputRef, forwardedRef); const onSubmit = useCallback( @@ -197,7 +197,7 @@ function AutoSizingTextInputWithRef(props: IInputProps, forwardedRef: React.Ref< const { onFocus, onBlur, ...otherProps } = props; const [focused, setFocused, setBlurred] = useBoolean(false); - const inputRef = useRef() as React.RefObject; + const inputRef = useStyledRef(); const combinedRef = useCombinedRefs(inputRef, forwardedRef); const onBlurWrapper = useCallback( @@ -304,7 +304,7 @@ interface IRowInputProps { export function RowInput(props: IRowInputProps) { const [value, setValue] = useState(props.initialValue ?? ''); - const textAreaRef = useRef() as React.RefObject; + const textAreaRef = useStyledRef(); const [focused, setFocused, setBlurred] = useBoolean(false); const submit = useCallback(() => props.onSubmit(value), [props.onSubmit, value]); diff --git a/gui/src/renderer/components/cell/Selector.tsx b/gui/src/renderer/components/cell/Selector.tsx index 5eb9762eb36e..0842ce2c0e85 100644 --- a/gui/src/renderer/components/cell/Selector.tsx +++ b/gui/src/renderer/components/cell/Selector.tsx @@ -3,6 +3,7 @@ import styled from 'styled-components'; import { colors } from '../../../config.json'; import { messages } from '../../../shared/gettext'; +import { useStyledRef } from '../../lib/utilityHooks'; import { AriaDetails, AriaInput, AriaLabel } from '../AriaGroup'; import { normalText } from '../common-styles'; import InfoButton from '../InfoButton'; @@ -212,7 +213,7 @@ export function SelectorWithCustomItem(props: SelectorWithCustomItemProps< const [customValue, setCustomValue] = useState(itemIsSelected ? undefined : `${value}`); const customIsSelected = customValue !== undefined; - const inputRef = useRef() as React.RefObject; + const inputRef = useStyledRef(); const handleClickCustom = useCallback(() => { inputRef.current?.focus(); diff --git a/gui/src/renderer/components/select-location/CustomLists.tsx b/gui/src/renderer/components/select-location/CustomLists.tsx index b87de1fe46b9..358070ae467e 100644 --- a/gui/src/renderer/components/select-location/CustomLists.tsx +++ b/gui/src/renderer/components/select-location/CustomLists.tsx @@ -1,4 +1,4 @@ -import { useCallback, useEffect, useRef, useState } from 'react'; +import { useCallback, useEffect, useState } from 'react'; import styled from 'styled-components'; import { colors } from '../../../config.json'; @@ -6,7 +6,7 @@ import { CustomListError, CustomLists, RelayLocation } from '../../../shared/dae import { messages } from '../../../shared/gettext'; import log from '../../../shared/logging'; import { useAppContext } from '../../context'; -import { useBoolean } from '../../lib/utilityHooks'; +import { useBoolean, useStyledRef } from '../../lib/utilityHooks'; import Accordion from '../Accordion'; import * as Cell from '../cell'; import { measurements } from '../common-styles'; @@ -118,8 +118,8 @@ interface AddListFormProps { function AddListForm(props: AddListFormProps) { const [name, setName] = useState(''); const [error, setError, unsetError] = useBoolean(); - const containerRef = useRef() as React.RefObject; - const inputRef = useRef() as React.RefObject; + const containerRef = useStyledRef(); + const inputRef = useStyledRef(); // Errors should be reset when editing the value const onChange = useCallback((value: string) => { diff --git a/gui/src/renderer/components/select-location/LocationRow.tsx b/gui/src/renderer/components/select-location/LocationRow.tsx index 514fd1920748..7ebae688a602 100644 --- a/gui/src/renderer/components/select-location/LocationRow.tsx +++ b/gui/src/renderer/components/select-location/LocationRow.tsx @@ -11,7 +11,7 @@ import { import { messages } from '../../../shared/gettext'; import log from '../../../shared/logging'; import { useAppContext } from '../../context'; -import { useBoolean } from '../../lib/utilityHooks'; +import { useBoolean, useStyledRef } from '../../lib/utilityHooks'; import { useSelector } from '../../redux/store'; import Accordion from '../Accordion'; import * as Cell from '../cell'; @@ -152,7 +152,7 @@ interface IProps { // Renders the rows and its children for countries, cities and relays function LocationRow(props: IProps) { const hasChildren = getLocationChildren(props.source).some((child) => child.visible); - const buttonRef = useRef() as React.RefObject; + const buttonRef = useStyledRef(); const userInvokedExpand = useRef(false); const { updateCustomList, deleteCustomList } = useAppContext(); diff --git a/gui/src/renderer/components/select-location/ScrollPositionContext.tsx b/gui/src/renderer/components/select-location/ScrollPositionContext.tsx index 973e4484b6ae..04fcd0bccc81 100644 --- a/gui/src/renderer/components/select-location/ScrollPositionContext.tsx +++ b/gui/src/renderer/components/select-location/ScrollPositionContext.tsx @@ -1,6 +1,6 @@ import React, { useCallback, useContext, useEffect, useMemo, useRef } from 'react'; -import { useNormalRelaySettings } from '../../lib/utilityHooks'; +import { useNormalRelaySettings, useStyledRef } from '../../lib/utilityHooks'; import { CustomScrollbarsRef } from '../CustomScrollbars'; import { LocationType } from './select-location-types'; import { useSelectLocationContext } from './SelectLocationContainer'; @@ -39,7 +39,7 @@ export function ScrollPositionContextProvider(props: ScrollPositionContextProps) const scrollPositions = useRef>>({}); const scrollViewRef = useRef(null); - const spacePreAllocationViewRef = useRef() as React.RefObject; + const spacePreAllocationViewRef = useStyledRef(); const selectedLocationRef = useRef(null); const saveScrollPosition = useCallback(() => { diff --git a/gui/src/renderer/lib/utilityHooks.ts b/gui/src/renderer/lib/utilityHooks.ts index 378a6d5ae5e0..49f508a883ee 100644 --- a/gui/src/renderer/lib/utilityHooks.ts +++ b/gui/src/renderer/lib/utilityHooks.ts @@ -16,6 +16,10 @@ export function useMounted() { return isMounted; } +export function useStyledRef(): React.RefObject { + return useRef() as React.RefObject; +} + export function useCombinedRefs(...refs: (React.Ref | undefined)[]): React.RefCallback { return useCallback((element: T | null) => refs.forEach((ref) => assignToRef(element, ref)), []); } From 67ab02560bbc0508eaa82c66b04868a388e5ebc9 Mon Sep 17 00:00:00 2001 From: Oskar Nyberg Date: Tue, 24 Oct 2023 10:32:49 +0200 Subject: [PATCH 3/5] Update styled components --- gui/package-lock.json | 701 +++++++++++++----------------------------- gui/package.json | 3 +- 2 files changed, 223 insertions(+), 481 deletions(-) diff --git a/gui/package-lock.json b/gui/package-lock.json index 034b8c609d44..bdd3476016fd 100644 --- a/gui/package-lock.json +++ b/gui/package-lock.json @@ -24,7 +24,7 @@ "react-simple-maps": "^3.0.0", "redux": "^4.2.0", "sprintf-js": "^1.1.2", - "styled-components": "^5.1.1" + "styled-components": "^6.1.0" }, "devDependencies": { "@electron/notarize": "^2.1.0", @@ -46,7 +46,6 @@ "@types/react-simple-maps": "^1.0.8", "@types/sinon": "^10.0.13", "@types/sprintf-js": "^1.1.2", - "@types/styled-components": "^5.1.26", "@types/topojson-specification": "^1.0.2", "@typescript-eslint/eslint-plugin": "^5.56.0", "@typescript-eslint/parser": "^5.56.0", @@ -89,18 +88,11 @@ "nseventmonitor": "^1.0.3" } }, - "node_modules/@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "dependencies": { - "@babel/highlight": "^7.10.4" - } - }, "node_modules/@babel/generator": { "version": "7.18.2", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.2.tgz", "integrity": "sha512-W1lG5vUwFvfMd8HVXqdfbuG7RuaSrTCCD8cl8fP8wOivdbtbIg2Db3IWUcgvfxKbbn6ZBGYRW/Zk1MIwK49mgw==", + "dev": true, "dependencies": { "@babel/types": "^7.18.2", "@jridgewell/gen-mapping": "^0.3.0", @@ -110,70 +102,20 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.4.tgz", - "integrity": "sha512-XQlqKQP4vXFB7BN8fEEerrmYvHp3fK/rBkRFz9jaJbzK0B1DSfej9Kc7ZzE8Z/OnId1jpJdNAZ3BFQjWG68rcA==", - "dependencies": { - "@babel/types": "^7.10.4" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", - "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", - "dependencies": { - "@babel/helper-get-function-arity": "^7.10.4", - "@babel/template": "^7.10.4", - "@babel/types": "^7.10.4" - } - }, - "node_modules/@babel/helper-get-function-arity": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", - "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", - "dependencies": { - "@babel/types": "^7.10.4" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz", - "integrity": "sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA==", - "dependencies": { - "@babel/types": "^7.12.5" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", - "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==", - "dependencies": { - "@babel/types": "^7.11.0" - } - }, "node_modules/@babel/helper-validator-identifier": { "version": "7.19.1", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "dev": true, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/highlight": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz", - "integrity": "sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==", - "dependencies": { - "@babel/helper-validator-identifier": "^7.14.0", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, "node_modules/@babel/parser": { "version": "7.18.4", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.4.tgz", "integrity": "sha512-FDge0dFazETFcxGw/EXzOkN8uJp0PC7Qbm+Pe9T+av2zlBpOgunFHkQPPn+eRuClU73JF+98D531UgayY89tow==", + "dev": true, "bin": { "parser": "bin/babel-parser.js" }, @@ -192,60 +134,11 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/template": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", - "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", - "dependencies": { - "@babel/code-frame": "^7.10.4", - "@babel/parser": "^7.12.7", - "@babel/types": "^7.12.7" - } - }, - "node_modules/@babel/traverse": { - "version": "7.12.9", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.9.tgz", - "integrity": "sha512-iX9ajqnLdoU1s1nHt36JDI9KG4k+vmI8WgjK5d+aDTwQbL2fUnzedNedssA645Ede3PM2ma1n8Q4h2ohwXgMXw==", - "dependencies": { - "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.12.5", - "@babel/helper-function-name": "^7.10.4", - "@babel/helper-split-export-declaration": "^7.11.0", - "@babel/parser": "^7.12.7", - "@babel/types": "^7.12.7", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.19" - } - }, - "node_modules/@babel/traverse/node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - } - }, - "node_modules/@babel/traverse/node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/traverse/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, "node_modules/@babel/types": { "version": "7.18.4", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.18.4.tgz", "integrity": "sha512-ThN1mBcMq5pG/Vm2IcBmPPfyPXbd8S02rS+OBIDENdufvqC7Z/jHPCv9IcP01277aKtDI8g/2XysBN4hA8niiw==", + "dev": true, "dependencies": { "@babel/helper-validator-identifier": "^7.16.7", "to-fast-properties": "^2.0.0" @@ -486,27 +379,22 @@ } }, "node_modules/@emotion/is-prop-valid": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.0.tgz", - "integrity": "sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz", + "integrity": "sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw==", "dependencies": { - "@emotion/memoize": "^0.8.0" + "@emotion/memoize": "^0.8.1" } }, "node_modules/@emotion/memoize": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz", - "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==" - }, - "node_modules/@emotion/stylis": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz", - "integrity": "sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==" + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" }, "node_modules/@emotion/unitless": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", - "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", + "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==" }, "node_modules/@eslint-community/eslint-utils": { "version": "4.3.0", @@ -784,6 +672,7 @@ "version": "0.3.2", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "dev": true, "dependencies": { "@jridgewell/set-array": "^1.0.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -797,6 +686,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true, "engines": { "node": ">=6.0.0" } @@ -805,6 +695,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true, "engines": { "node": ">=6.0.0" } @@ -812,12 +703,14 @@ "node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.14", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.9", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -1568,16 +1461,10 @@ "integrity": "sha512-hkgzYF+qnIl8uTO8rmUSVSfQ8BIfMXC4yJAF4n8BE758YsKBZvFC4NumnAegj7KmylP0liEZNpb9RRGFMbFejA==", "dev": true }, - "node_modules/@types/styled-components": { - "version": "5.1.26", - "resolved": "https://registry.npmjs.org/@types/styled-components/-/styled-components-5.1.26.tgz", - "integrity": "sha512-KuKJ9Z6xb93uJiIyxo/+ksS7yLjS1KzG6iv5i78dhVg/X3u5t1H7juRWqVmodIdz6wGVaIApo1u01kmFRdJHVw==", - "dev": true, - "dependencies": { - "@types/hoist-non-react-statics": "*", - "@types/react": "*", - "csstype": "^3.0.2" - } + "node_modules/@types/stylis": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@types/stylis/-/stylis-4.2.2.tgz", + "integrity": "sha512-Rm17MsTpQQP5Jq4BF7CdrxJsDufoiL/q5IbJZYZmOZAJALyijgF7BzLgobXUqraNcQdqFYLYGeglDp6QzaxPpg==" }, "node_modules/@types/topojson-specification": { "version": "1.0.2", @@ -2059,17 +1946,6 @@ "node": ">=0.10.0" } }, - "node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/ansi-wrap": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", @@ -2683,22 +2559,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/babel-plugin-styled-components": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-1.12.0.tgz", - "integrity": "sha512-FEiD7l5ZABdJPpLssKXjBUJMYqzbcNzBowfXDCdJhOpbhWiewapUaY+LZGT8R4Jg2TwOjGjG4RKeyrO5p9sBkA==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.0.0", - "@babel/helper-module-imports": "^7.0.0", - "babel-plugin-syntax-jsx": "^6.18.0", - "lodash": "^4.17.11" - } - }, - "node_modules/babel-plugin-syntax-jsx": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", - "integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=" - }, "node_modules/bach": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/bach/-/bach-1.2.0.tgz", @@ -3404,9 +3264,12 @@ } }, "node_modules/camelize": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz", - "integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs=" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz", + "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/chai": { "version": "4.3.6", @@ -3444,19 +3307,6 @@ "node": ">= 4.0.0" } }, - "node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/check-error": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", @@ -3704,19 +3554,6 @@ "node": ">=0.10.0" } }, - "node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, "node_modules/color-support": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", @@ -4017,7 +3854,7 @@ "node_modules/css-color-keywords": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", - "integrity": "sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU=", + "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==", "engines": { "node": ">=4" } @@ -4032,9 +3869,9 @@ ] }, "node_modules/css-to-react-native": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.0.0.tgz", - "integrity": "sha512-Ro1yETZA813eoyUp2GDBhG2j+YggidUmzO1/v9eYBKR2EHVEniE2MI/NqpTQ954BMpTPZFsGNPm46qFB9dpaPQ==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz", + "integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==", "dependencies": { "camelize": "^1.0.0", "css-color-keywords": "^1.0.0", @@ -4062,9 +3899,9 @@ } }, "node_modules/csstype": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.4.tgz", - "integrity": "sha512-xc8DUsCLmjvCfoD7LTGE0ou2MIWLx0K9RCZwSHMOdynqRsP4MtUcLeqh1HcQ2dInwDTqn+3CE0/FZh1et+p4jA==" + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", + "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" }, "node_modules/d": { "version": "1.0.1", @@ -5340,14 +5177,6 @@ "node": ">=6" } }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/eslint": { "version": "8.36.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.36.0.tgz", @@ -7339,14 +7168,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "engines": { - "node": ">=4" - } - }, "node_modules/has-property-descriptors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", @@ -8470,6 +8291,7 @@ "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, "bin": { "jsesc": "bin/jsesc" }, @@ -8755,7 +8577,8 @@ "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true }, "node_modules/lodash.camelcase": { "version": "4.3.0", @@ -11079,9 +10902,9 @@ } }, "node_modules/postcss-value-parser": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz", - "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==" + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" }, "node_modules/postcss/node_modules/source-map": { "version": "0.6.1", @@ -12501,6 +12324,14 @@ "node": ">=0.10.0" } }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/source-map-resolve": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", @@ -12903,24 +12734,22 @@ } }, "node_modules/styled-components": { - "version": "5.3.6", - "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.3.6.tgz", - "integrity": "sha512-hGTZquGAaTqhGWldX7hhfzjnIYBZ0IXQXkCYdvF1Sq3DsUaLx6+NTHC5Jj1ooM2F68sBiVz3lvhfwQs/S3l6qg==", - "hasInstallScript": true, - "dependencies": { - "@babel/helper-module-imports": "^7.0.0", - "@babel/traverse": "^7.4.5", - "@emotion/is-prop-valid": "^1.1.0", - "@emotion/stylis": "^0.8.4", - "@emotion/unitless": "^0.7.4", - "babel-plugin-styled-components": ">= 1.12.0", - "css-to-react-native": "^3.0.0", - "hoist-non-react-statics": "^3.0.0", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.0.tgz", + "integrity": "sha512-VWNfYYBuXzuLS/QYEeoPgMErP26WL+dX9//rEh80B2mmlS1yRxRxuL5eax4m6ybYEUoHWlTy2XOU32767mlMkg==", + "dependencies": { + "@emotion/is-prop-valid": "^1.2.1", + "@emotion/unitless": "^0.8.0", + "@types/stylis": "^4.0.2", + "css-to-react-native": "^3.2.0", + "csstype": "^3.1.2", + "postcss": "^8.4.31", "shallowequal": "^1.1.0", - "supports-color": "^5.5.0" + "stylis": "^4.3.0", + "tslib": "^2.5.0" }, "engines": { - "node": ">=10" + "node": ">= 16" }, "funding": { "type": "opencollective", @@ -12928,10 +12757,68 @@ }, "peerDependencies": { "react": ">= 16.8.0", - "react-dom": ">= 16.8.0", - "react-is": ">= 16.8.0" + "react-dom": ">= 16.8.0" } }, + "node_modules/styled-components/node_modules/nanoid": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/styled-components/node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + }, + "node_modules/styled-components/node_modules/postcss": { + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/styled-components/node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + }, + "node_modules/stylis": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.0.tgz", + "integrity": "sha512-E87pIogpwUsUwXw7dNyU4QDjdgVMy52m+XEOPEKUn161cCzWjjhPSQhByfd1CcNvrOLnXQ6OnnZDwnJrz/Z4YQ==" + }, "node_modules/subarg": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", @@ -12976,17 +12863,6 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", @@ -13251,6 +13127,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true, "engines": { "node": ">=4" } @@ -14381,85 +14258,28 @@ } }, "dependencies": { - "@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "requires": { - "@babel/highlight": "^7.10.4" - } - }, "@babel/generator": { "version": "7.18.2", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.2.tgz", "integrity": "sha512-W1lG5vUwFvfMd8HVXqdfbuG7RuaSrTCCD8cl8fP8wOivdbtbIg2Db3IWUcgvfxKbbn6ZBGYRW/Zk1MIwK49mgw==", + "dev": true, "requires": { "@babel/types": "^7.18.2", "@jridgewell/gen-mapping": "^0.3.0", "jsesc": "^2.5.1" } }, - "@babel/helper-annotate-as-pure": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.4.tgz", - "integrity": "sha512-XQlqKQP4vXFB7BN8fEEerrmYvHp3fK/rBkRFz9jaJbzK0B1DSfej9Kc7ZzE8Z/OnId1jpJdNAZ3BFQjWG68rcA==", - "requires": { - "@babel/types": "^7.10.4" - } - }, - "@babel/helper-function-name": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", - "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", - "requires": { - "@babel/helper-get-function-arity": "^7.10.4", - "@babel/template": "^7.10.4", - "@babel/types": "^7.10.4" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", - "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", - "requires": { - "@babel/types": "^7.10.4" - } - }, - "@babel/helper-module-imports": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz", - "integrity": "sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA==", - "requires": { - "@babel/types": "^7.12.5" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", - "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==", - "requires": { - "@babel/types": "^7.11.0" - } - }, "@babel/helper-validator-identifier": { "version": "7.19.1", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==" - }, - "@babel/highlight": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz", - "integrity": "sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==", - "requires": { - "@babel/helper-validator-identifier": "^7.14.0", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "dev": true }, "@babel/parser": { "version": "7.18.4", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.4.tgz", - "integrity": "sha512-FDge0dFazETFcxGw/EXzOkN8uJp0PC7Qbm+Pe9T+av2zlBpOgunFHkQPPn+eRuClU73JF+98D531UgayY89tow==" + "integrity": "sha512-FDge0dFazETFcxGw/EXzOkN8uJp0PC7Qbm+Pe9T+av2zlBpOgunFHkQPPn+eRuClU73JF+98D531UgayY89tow==", + "dev": true }, "@babel/runtime": { "version": "7.19.0", @@ -14469,56 +14289,11 @@ "regenerator-runtime": "^0.13.4" } }, - "@babel/template": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", - "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", - "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/parser": "^7.12.7", - "@babel/types": "^7.12.7" - } - }, - "@babel/traverse": { - "version": "7.12.9", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.9.tgz", - "integrity": "sha512-iX9ajqnLdoU1s1nHt36JDI9KG4k+vmI8WgjK5d+aDTwQbL2fUnzedNedssA645Ede3PM2ma1n8Q4h2ohwXgMXw==", - "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.12.5", - "@babel/helper-function-name": "^7.10.4", - "@babel/helper-split-export-declaration": "^7.11.0", - "@babel/parser": "^7.12.7", - "@babel/types": "^7.12.7", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.19" - }, - "dependencies": { - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "requires": { - "ms": "2.1.2" - } - }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } - } - }, "@babel/types": { "version": "7.18.4", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.18.4.tgz", "integrity": "sha512-ThN1mBcMq5pG/Vm2IcBmPPfyPXbd8S02rS+OBIDENdufvqC7Z/jHPCv9IcP01277aKtDI8g/2XysBN4hA8niiw==", + "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.16.7", "to-fast-properties": "^2.0.0" @@ -14699,27 +14474,22 @@ } }, "@emotion/is-prop-valid": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.0.tgz", - "integrity": "sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz", + "integrity": "sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw==", "requires": { - "@emotion/memoize": "^0.8.0" + "@emotion/memoize": "^0.8.1" } }, "@emotion/memoize": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz", - "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==" - }, - "@emotion/stylis": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz", - "integrity": "sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==" + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" }, "@emotion/unitless": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", - "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", + "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==" }, "@eslint-community/eslint-utils": { "version": "4.3.0", @@ -14922,6 +14692,7 @@ "version": "0.3.2", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "dev": true, "requires": { "@jridgewell/set-array": "^1.0.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -14931,22 +14702,26 @@ "@jridgewell/resolve-uri": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==" + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true }, "@jridgewell/set-array": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==" + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true }, "@jridgewell/sourcemap-codec": { "version": "1.4.14", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true }, "@jridgewell/trace-mapping": { "version": "0.3.9", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, "requires": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -15610,16 +15385,10 @@ "integrity": "sha512-hkgzYF+qnIl8uTO8rmUSVSfQ8BIfMXC4yJAF4n8BE758YsKBZvFC4NumnAegj7KmylP0liEZNpb9RRGFMbFejA==", "dev": true }, - "@types/styled-components": { - "version": "5.1.26", - "resolved": "https://registry.npmjs.org/@types/styled-components/-/styled-components-5.1.26.tgz", - "integrity": "sha512-KuKJ9Z6xb93uJiIyxo/+ksS7yLjS1KzG6iv5i78dhVg/X3u5t1H7juRWqVmodIdz6wGVaIApo1u01kmFRdJHVw==", - "dev": true, - "requires": { - "@types/hoist-non-react-statics": "*", - "@types/react": "*", - "csstype": "^3.0.2" - } + "@types/stylis": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@types/stylis/-/stylis-4.2.2.tgz", + "integrity": "sha512-Rm17MsTpQQP5Jq4BF7CdrxJsDufoiL/q5IbJZYZmOZAJALyijgF7BzLgobXUqraNcQdqFYLYGeglDp6QzaxPpg==" }, "@types/topojson-specification": { "version": "1.0.2", @@ -15954,14 +15723,6 @@ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "devOptional": true }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, "ansi-wrap": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", @@ -16448,22 +16209,6 @@ "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", "dev": true }, - "babel-plugin-styled-components": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-1.12.0.tgz", - "integrity": "sha512-FEiD7l5ZABdJPpLssKXjBUJMYqzbcNzBowfXDCdJhOpbhWiewapUaY+LZGT8R4Jg2TwOjGjG4RKeyrO5p9sBkA==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.0.0", - "@babel/helper-module-imports": "^7.0.0", - "babel-plugin-syntax-jsx": "^6.18.0", - "lodash": "^4.17.11" - } - }, - "babel-plugin-syntax-jsx": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", - "integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=" - }, "bach": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/bach/-/bach-1.2.0.tgz", @@ -17078,9 +16823,9 @@ "dev": true }, "camelize": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz", - "integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs=" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz", + "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==" }, "chai": { "version": "4.3.6", @@ -17112,16 +16857,6 @@ "integrity": "sha512-elF2ZUczBsFoP07qCfMO/zeggs8pqCf3fZGyK5+2X4AndS8jycZYID91ztD9oQ7d/0tnS963dPkd0frQEThDsg==", "dev": true }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, "check-error": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", @@ -17317,19 +17052,6 @@ "object-visit": "^1.0.0" } }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, "color-support": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", @@ -17611,7 +17333,7 @@ "css-color-keywords": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", - "integrity": "sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU=" + "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==" }, "css-selector-parser": { "version": "1.3.0", @@ -17620,9 +17342,9 @@ "dev": true }, "css-to-react-native": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.0.0.tgz", - "integrity": "sha512-Ro1yETZA813eoyUp2GDBhG2j+YggidUmzO1/v9eYBKR2EHVEniE2MI/NqpTQ954BMpTPZFsGNPm46qFB9dpaPQ==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz", + "integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==", "requires": { "camelize": "^1.0.0", "css-color-keywords": "^1.0.0", @@ -17630,9 +17352,9 @@ } }, "csstype": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.4.tgz", - "integrity": "sha512-xc8DUsCLmjvCfoD7LTGE0ou2MIWLx0K9RCZwSHMOdynqRsP4MtUcLeqh1HcQ2dInwDTqn+3CE0/FZh1et+p4jA==" + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", + "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" }, "d": { "version": "1.0.1", @@ -18677,11 +18399,6 @@ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, "eslint": { "version": "8.36.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.36.0.tgz", @@ -20241,11 +19958,6 @@ "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", "dev": true }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, "has-property-descriptors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", @@ -21091,7 +20803,8 @@ "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true }, "json-buffer": { "version": "3.0.1", @@ -21320,7 +21033,8 @@ "lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true }, "lodash.camelcase": { "version": "4.3.0", @@ -23093,9 +22807,9 @@ } }, "postcss-value-parser": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz", - "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==" + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" }, "prebuild-install": { "version": "6.1.4", @@ -24219,6 +23933,11 @@ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true }, + "source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==" + }, "source-map-resolve": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", @@ -24565,22 +24284,53 @@ "dev": true }, "styled-components": { - "version": "5.3.6", - "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.3.6.tgz", - "integrity": "sha512-hGTZquGAaTqhGWldX7hhfzjnIYBZ0IXQXkCYdvF1Sq3DsUaLx6+NTHC5Jj1ooM2F68sBiVz3lvhfwQs/S3l6qg==", - "requires": { - "@babel/helper-module-imports": "^7.0.0", - "@babel/traverse": "^7.4.5", - "@emotion/is-prop-valid": "^1.1.0", - "@emotion/stylis": "^0.8.4", - "@emotion/unitless": "^0.7.4", - "babel-plugin-styled-components": ">= 1.12.0", - "css-to-react-native": "^3.0.0", - "hoist-non-react-statics": "^3.0.0", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.0.tgz", + "integrity": "sha512-VWNfYYBuXzuLS/QYEeoPgMErP26WL+dX9//rEh80B2mmlS1yRxRxuL5eax4m6ybYEUoHWlTy2XOU32767mlMkg==", + "requires": { + "@emotion/is-prop-valid": "^1.2.1", + "@emotion/unitless": "^0.8.0", + "@types/stylis": "^4.0.2", + "css-to-react-native": "^3.2.0", + "csstype": "^3.1.2", + "postcss": "^8.4.31", "shallowequal": "^1.1.0", - "supports-color": "^5.5.0" + "stylis": "^4.3.0", + "tslib": "^2.5.0" + }, + "dependencies": { + "nanoid": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==" + }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + }, + "postcss": { + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "requires": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + } + }, + "tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + } } }, + "stylis": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.0.tgz", + "integrity": "sha512-E87pIogpwUsUwXw7dNyU4QDjdgVMy52m+XEOPEKUn161cCzWjjhPSQhByfd1CcNvrOLnXQ6OnnZDwnJrz/Z4YQ==" + }, "subarg": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", @@ -24616,14 +24366,6 @@ } } }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - }, "supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", @@ -24846,7 +24588,8 @@ "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true }, "to-object-path": { "version": "0.3.0", diff --git a/gui/package.json b/gui/package.json index 1ca1192cbebe..cae1ec64c9bc 100644 --- a/gui/package.json +++ b/gui/package.json @@ -26,7 +26,7 @@ "react-simple-maps": "^3.0.0", "redux": "^4.2.0", "sprintf-js": "^1.1.2", - "styled-components": "^5.1.1" + "styled-components": "^6.1.0" }, "optionalDependencies": { "grpc-tools": "^1.12.4", @@ -52,7 +52,6 @@ "@types/react-simple-maps": "^1.0.8", "@types/sinon": "^10.0.13", "@types/sprintf-js": "^1.1.2", - "@types/styled-components": "^5.1.26", "@types/topojson-specification": "^1.0.2", "@typescript-eslint/eslint-plugin": "^5.56.0", "@typescript-eslint/parser": "^5.56.0", From 754b15058eaf37dba76387f803e623a94698242f Mon Sep 17 00:00:00 2001 From: Oskar Nyberg Date: Tue, 24 Oct 2023 19:34:15 +0200 Subject: [PATCH 4/5] Add types for convering between transient props --- gui/src/renderer/lib/styles.ts | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 gui/src/renderer/lib/styles.ts diff --git a/gui/src/renderer/lib/styles.ts b/gui/src/renderer/lib/styles.ts new file mode 100644 index 000000000000..554e669373b0 --- /dev/null +++ b/gui/src/renderer/lib/styles.ts @@ -0,0 +1,9 @@ +type NonTransientPropKey = K extends `$${infer L}` ? L : K; + +export type NonTransientProps> = { + [P in keyof T as NonTransientPropKey

extends K ? NonTransientPropKey

: P]: T[P]; +}; + +export type TransientProps = { + [P in keyof T as P extends K ? `$${P & string}` : P]: T[P]; +}; From db89a8d51de88ca08599fa331f6376ef477d15e8 Mon Sep 17 00:00:00 2001 From: Oskar Nyberg Date: Tue, 24 Oct 2023 13:34:02 +0200 Subject: [PATCH 5/5] 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) { )}