From b70526a20b326bf815258f8617f6937e44cf9db7 Mon Sep 17 00:00:00 2001 From: Eugene Chybisov Date: Thu, 26 May 2022 13:35:13 +0200 Subject: [PATCH] feat: add dark color scheme support --- packages/widget-embedded/src/index.css | 6 + packages/widget-embedded/src/index.tsx | 42 +++++- packages/widget/src/App.tsx | 76 +++++----- .../widget/src/components/AppContainer.tsx | 14 +- .../components/BottomSheet/BottomSheet.tsx | 7 +- .../src/components/Card/CardContainer.tsx | 8 +- .../src/components/Header/Header.style.ts | 6 +- .../components/Header/NavigationHeader.tsx | 4 - .../src/components/Header/WalletHeader.tsx | 12 +- packages/widget/src/components/Input.tsx | 2 +- packages/widget/src/components/LiFiLogo.tsx | 22 +++ packages/widget/src/components/PoweredBy.tsx | 4 +- .../ProgressToNextUpdate.tsx | 5 +- .../src/components/ReverseTokensButton.tsx | 1 - packages/widget/src/components/Select.tsx | 2 +- .../StepActions/StepActions.style.tsx | 17 ++- .../components/StepActions/StepActions.tsx | 6 +- .../components/SwapButton/SwapButton.style.ts | 5 +- .../SwapInProgress/SwapInProgress.style.ts | 9 +- .../SwapInProgress/SwapInProgress.tsx | 14 +- .../SwapRouteCard/SwapRouteCard.style.ts | 24 ++- .../src/components/SwapRoutes/SwapRoutes.tsx | 1 - packages/widget/src/components/Switch.tsx | 2 +- .../components/TokenList/TokenList.style.tsx | 3 +- packages/widget/src/config/theme.ts | 142 ++++++++++++++++++ .../{LiFiLogoFull.svg => LiFiFullLogo.svg} | 16 +- packages/widget/src/icons/LiFiLogo.svg | 6 +- .../SelectTokenPage/SelectTokenPage.style.tsx | 28 ---- .../SelectWalletPage.style.tsx | 3 +- .../src/pages/SwapPage/ExecutionItem.tsx | 1 - .../providers/ThemeProvider/ThemeProvider.tsx | 47 ++++++ .../src/providers/ThemeProvider/index.ts | 2 + .../src/providers/ThemeProvider/types.ts | 3 + packages/widget/src/theme.ts | 117 --------------- packages/widget/src/types/widget.ts | 1 + packages/widget/src/utils/colors.ts | 6 + 36 files changed, 403 insertions(+), 261 deletions(-) create mode 100644 packages/widget/src/components/LiFiLogo.tsx create mode 100644 packages/widget/src/config/theme.ts rename packages/widget/src/icons/{LiFiLogoFull.svg => LiFiFullLogo.svg} (73%) delete mode 100644 packages/widget/src/pages/SelectTokenPage/SelectTokenPage.style.tsx create mode 100644 packages/widget/src/providers/ThemeProvider/ThemeProvider.tsx create mode 100644 packages/widget/src/providers/ThemeProvider/index.ts create mode 100644 packages/widget/src/providers/ThemeProvider/types.ts delete mode 100644 packages/widget/src/theme.ts create mode 100644 packages/widget/src/utils/colors.ts diff --git a/packages/widget-embedded/src/index.css b/packages/widget-embedded/src/index.css index 725952d74..a658459f8 100644 --- a/packages/widget-embedded/src/index.css +++ b/packages/widget-embedded/src/index.css @@ -4,3 +4,9 @@ body { -moz-osx-font-smoothing: grayscale; background-color: #F4F5F6; } + +@media (prefers-color-scheme: dark) { + body { + background-color: #000; + } +} diff --git a/packages/widget-embedded/src/index.tsx b/packages/widget-embedded/src/index.tsx index 0f5f824e8..c8b3c2350 100644 --- a/packages/widget-embedded/src/index.tsx +++ b/packages/widget-embedded/src/index.tsx @@ -1,5 +1,5 @@ import { LiFiWidget, WidgetConfig } from '@lifinance/widget'; -import React from 'react'; +import React, { useEffect, useState } from 'react'; import { createRoot } from 'react-dom/client'; import './index.css'; import { reportWebVitals } from './reportWebVitals'; @@ -10,7 +10,7 @@ if (!rootElement) { } const root = createRoot(rootElement); -const config: WidgetConfig = { +const widgetConfig: WidgetConfig = { enabledChains: JSON.parse(process.env.LIFI_ENABLED_CHAINS_JSON!), fromChain: 'pol', toChain: 'bsc', @@ -20,16 +20,42 @@ const config: WidgetConfig = { containerStyle: { width: 480, height: 640, - border: '1px solid rgb(234, 234, 234)', + border: `1px solid ${ + window.matchMedia('(prefers-color-scheme: dark)').matches + ? 'rgb(66, 66, 66)' + : 'rgb(234, 234, 234)' + }`, borderRadius: '16px', display: 'flex', maxWidth: '480px', flex: 1, }, + baselineStyle: { + borderRadius: '16px', + }, }; -root.render( - +const App = () => { + const [config, setConfig] = useState(widgetConfig); + useEffect(() => { + const eventHadler = (event: MediaQueryListEvent) => { + setConfig((config) => ({ + ...config, + containerStyle: { + ...config.containerStyle, + border: `1px solid ${ + event.matches ? 'rgb(66, 66, 66)' : 'rgb(234, 234, 234)' + }`, + }, + })); + }; + const matchMedia = window.matchMedia('(prefers-color-scheme: dark)'); + matchMedia.addEventListener('change', eventHadler); + return () => { + matchMedia.removeEventListener('change', eventHadler); + }; + }, [config]); + return (
+ ); +}; + +root.render( + + , ); diff --git a/packages/widget/src/App.tsx b/packages/widget/src/App.tsx index 8ad09f22e..e71363c54 100644 --- a/packages/widget/src/App.tsx +++ b/packages/widget/src/App.tsx @@ -1,5 +1,3 @@ -import { ScopedCssBaseline } from '@mui/material'; -import { ThemeProvider } from '@mui/material/styles'; import { FC, PropsWithChildren } from 'react'; import { QueryClientProvider, QueryClientProviderProps } from 'react-query'; import { MemoryRouter, Route, Routes } from 'react-router-dom'; @@ -14,9 +12,9 @@ import { SettingsPage } from './pages/SettingsPage'; import { SwapPage } from './pages/SwapPage'; import { SwapRoutesPage } from './pages/SwapRoutesPage'; import { SwapFormProvider } from './providers/SwapFormProvider'; +import { ThemeProvider } from './providers/ThemeProvider'; import { WalletProvider } from './providers/WalletProvider'; import { WidgetProvider } from './providers/WidgetProvider'; -import { theme } from './theme'; import { routes } from './utils/routes'; interface AppProps { @@ -29,46 +27,44 @@ const QueryProvider = QueryClientProvider as FC< export const App: React.FC = ({ config }) => { return ( - - - - + + + + - - -
- - } /> - } - /> - } - /> - } - /> - } - /> - } - /> - } /> - - - + +
+ + } /> + } + /> + } /> + } + /> + } + /> + } + /> + } /> + + - - - - + + + + ); }; diff --git a/packages/widget/src/components/AppContainer.tsx b/packages/widget/src/components/AppContainer.tsx index fff3075ce..764b66993 100644 --- a/packages/widget/src/components/AppContainer.tsx +++ b/packages/widget/src/components/AppContainer.tsx @@ -1,4 +1,9 @@ -import { Box, BoxProps, Container as MuiContainer } from '@mui/material'; +import { + Box, + BoxProps, + Container as MuiContainer, + ScopedCssBaseline, +} from '@mui/material'; import { styled } from '@mui/material/styles'; import { PropsWithChildren, RefObject, useLayoutEffect, useRef } from 'react'; import { useLocation } from 'react-router-dom'; @@ -20,7 +25,7 @@ const Container = styled(MuiContainer)(({ theme }) => ({ const RelativeContainer = styled(Box)(({ theme }) => ({ position: 'relative', width: '480px', - background: theme.palette.common.white, + background: theme.palette.background.default, overflow: 'auto', })); @@ -35,10 +40,11 @@ const ScrollableContainer = styled(Box)({ export const AppContainer: React.FC> = ({ children, sx, + style, }) => { const ref = useRef(null); return ( - <> + @@ -48,7 +54,7 @@ export const AppContainer: React.FC> = ({ - + ); }; diff --git a/packages/widget/src/components/BottomSheet/BottomSheet.tsx b/packages/widget/src/components/BottomSheet/BottomSheet.tsx index 4ca617c03..414f4656f 100644 --- a/packages/widget/src/components/BottomSheet/BottomSheet.tsx +++ b/packages/widget/src/components/BottomSheet/BottomSheet.tsx @@ -65,13 +65,14 @@ export const BottomSheet = forwardRef( borderTopLeftRadius: (theme.shape.borderRadius as number) * 2, borderTopRightRadius: (theme.shape.borderRadius as number) * 2, }), + // elevation: 5, }} BackdropProps={{ - sx: { + sx: (theme) => ({ position: 'absolute', - backgroundColor: 'rgba(0,0,0,0.48)', + backgroundColor: 'rgb(0 0 0 / 48%)', backdropFilter: 'blur(3px)', - }, + }), }} SlideProps={{ container: containerElement, diff --git a/packages/widget/src/components/Card/CardContainer.tsx b/packages/widget/src/components/Card/CardContainer.tsx index 2a7690271..b877f34f7 100644 --- a/packages/widget/src/components/Card/CardContainer.tsx +++ b/packages/widget/src/components/Card/CardContainer.tsx @@ -4,9 +4,13 @@ import { styled } from '@mui/material/styles'; export const CardContainer = styled(Box, { shouldForwardProp: (prop) => prop !== 'isError', })<{ isError?: boolean }>(({ theme, isError }) => ({ - backgroundColor: theme.palette.common.white, + backgroundColor: theme.palette.background.paper, border: `1px solid`, - borderColor: isError ? theme.palette.error.main : theme.palette.grey[300], + borderColor: isError + ? theme.palette.error.main + : theme.palette.mode === 'light' + ? theme.palette.grey[300] + : theme.palette.grey[800], borderRadius: (theme.shape.borderRadius as number) * 2, overflow: 'hidden', position: 'relative', diff --git a/packages/widget/src/components/Header/Header.style.ts b/packages/widget/src/components/Header/Header.style.ts index fd1fd22a4..ea671a373 100644 --- a/packages/widget/src/components/Header/Header.style.ts +++ b/packages/widget/src/components/Header/Header.style.ts @@ -4,8 +4,8 @@ import { styled } from '@mui/material/styles'; export const HeaderAppBar = styled(AppBar, { shouldForwardProp: (prop) => prop !== 'pt', })<{ pt?: number }>(({ theme, pt }) => ({ - backgroundColor: 'transparent', - color: theme.palette.common.black, + backgroundColor: theme.palette.background.default, + color: theme.palette.text.primary, flexDirection: 'row', alignItems: 'center', position: 'relative', @@ -16,7 +16,7 @@ export const HeaderAppBar = styled(AppBar, { export const Container = styled(Box, { shouldForwardProp: (prop) => prop !== 'sticky', })<{ sticky?: boolean }>(({ theme, sticky }) => ({ - backgroundColor: sticky ? theme.palette.common.white : 'transparent', + backgroundColor: theme.palette.background.default, position: sticky ? 'sticky' : 'relative', top: 0, zIndex: 1200, diff --git a/packages/widget/src/components/Header/NavigationHeader.tsx b/packages/widget/src/components/Header/NavigationHeader.tsx index 8d14a12b2..c1acf696c 100644 --- a/packages/widget/src/components/Header/NavigationHeader.tsx +++ b/packages/widget/src/components/Header/NavigationHeader.tsx @@ -61,7 +61,6 @@ export const NavigationHeader: React.FC = () => { @@ -70,7 +69,6 @@ export const NavigationHeader: React.FC = () => { ) : null} {/* */} { @@ -104,7 +101,6 @@ export const NavigationHeader: React.FC = () => { diff --git a/packages/widget/src/components/Header/WalletHeader.tsx b/packages/widget/src/components/Header/WalletHeader.tsx index f8e05af29..be12b10dc 100644 --- a/packages/widget/src/components/Header/WalletHeader.tsx +++ b/packages/widget/src/components/Header/WalletHeader.tsx @@ -30,22 +30,16 @@ export const WalletHeader: React.FC = () => { }} mr={0.5} > - + {t(`header.walletConnected`)} - + {walletAddress} @@ -57,7 +51,6 @@ export const WalletHeader: React.FC = () => { { diff --git a/packages/widget/src/components/Input.tsx b/packages/widget/src/components/Input.tsx index af33478ee..0288e827c 100644 --- a/packages/widget/src/components/Input.tsx +++ b/packages/widget/src/components/Input.tsx @@ -6,7 +6,7 @@ export const Input = styled(InputBase)(({ theme }) => ({ backgroundColor: theme.palette.mode === 'light' ? theme.palette.common.white - : theme.palette.grey[900], + : theme.palette.background.paper, paddingRight: theme.spacing(2), [`.${inputBaseClasses.input}`]: { padding: theme.spacing(1.5, 1, 1.5, 2), diff --git a/packages/widget/src/components/LiFiLogo.tsx b/packages/widget/src/components/LiFiLogo.tsx new file mode 100644 index 000000000..578815437 --- /dev/null +++ b/packages/widget/src/components/LiFiLogo.tsx @@ -0,0 +1,22 @@ +import { useTheme } from '@mui/material/styles'; +import { CSSProperties } from 'react'; +import { ReactComponent as LiFiFullLogo } from '../icons/LiFiFullLogo.svg'; +import { ReactComponent as LiFiIconLogo } from '../icons/LiFiLogo.svg'; + +export const LiFiLogo: React.FC<{ + variant?: 'icon' | 'full'; + style?: CSSProperties; +}> = ({ variant = 'icon', style }) => { + const theme = useTheme(); + const Component = variant === 'icon' ? LiFiIconLogo : LiFiFullLogo; + return ( + + ); +}; diff --git a/packages/widget/src/components/PoweredBy.tsx b/packages/widget/src/components/PoweredBy.tsx index b790f2506..c0476c3be 100644 --- a/packages/widget/src/components/PoweredBy.tsx +++ b/packages/widget/src/components/PoweredBy.tsx @@ -1,5 +1,5 @@ import { Box, Link, Typography } from '@mui/material'; -import { ReactComponent as LiFiFullLogo } from '../icons/LiFiLogoFull.svg'; +import { LiFiLogo } from './LiFiLogo'; export const PoweredBy: React.FC = () => { return ( @@ -26,7 +26,7 @@ export const PoweredBy: React.FC = () => { Powered by - + ); diff --git a/packages/widget/src/components/ProgressToNextUpdate/ProgressToNextUpdate.tsx b/packages/widget/src/components/ProgressToNextUpdate/ProgressToNextUpdate.tsx index 5e4f21cd4..4cabbb121 100644 --- a/packages/widget/src/components/ProgressToNextUpdate/ProgressToNextUpdate.tsx +++ b/packages/widget/src/components/ProgressToNextUpdate/ProgressToNextUpdate.tsx @@ -55,7 +55,10 @@ export const ProgressToNextUpdate: React.FC< color="info" sx={(theme) => ({ position: 'absolute', - color: theme.palette.grey[300], + color: + theme.palette.mode === 'light' + ? theme.palette.grey[300] + : theme.palette.grey[700], })} /> { onClick={handleClick} size="small" aria-label="swap-destinations" - color="inherit" > diff --git a/packages/widget/src/components/Select.tsx b/packages/widget/src/components/Select.tsx index 0027643ce..7f0572928 100644 --- a/packages/widget/src/components/Select.tsx +++ b/packages/widget/src/components/Select.tsx @@ -11,7 +11,7 @@ export const Select = styled(MuiSelect, { backgroundColor: theme.palette.mode === 'light' ? theme.palette.common.white - : theme.palette.grey[900], + : theme.palette.background.paper, [`.${inputBaseClasses.input}`]: { padding: dense ? theme.spacing(1.625, 2, 1.5, 2) : theme.spacing(2), display: 'flex', diff --git a/packages/widget/src/components/StepActions/StepActions.style.tsx b/packages/widget/src/components/StepActions/StepActions.style.tsx index 89f77f40c..2658877ce 100644 --- a/packages/widget/src/components/StepActions/StepActions.style.tsx +++ b/packages/widget/src/components/StepActions/StepActions.style.tsx @@ -12,7 +12,11 @@ export const StepIcon = styled('span')(({ theme }) => ({ width: 12, height: 12, borderRadius: '50%', - border: `2px solid ${theme.palette.grey[300]}`, + border: `2px solid ${ + theme.palette.mode === 'light' + ? theme.palette.grey[300] + : theme.palette.grey[800] + }`, })); export const StepConnector = styled(MuiStepConnector)(({ theme }) => ({ @@ -20,7 +24,10 @@ export const StepConnector = styled(MuiStepConnector)(({ theme }) => ({ [`.${stepConnectorClasses.line}`]: { minHeight: 8, borderLeftWidth: 2, - borderColor: theme.palette.grey[300], + borderColor: + theme.palette.mode === 'light' + ? theme.palette.grey[300] + : theme.palette.grey[800], }, })); @@ -33,7 +40,11 @@ export const StepLabel = styled(MuiStepLabel)(({ theme }) => ({ })); export const StepContent = styled(MuiStepContent)(({ theme }) => ({ - borderLeft: `2px solid ${theme.palette.grey[300]}`, + borderLeft: `2px solid ${ + theme.palette.mode === 'light' + ? theme.palette.grey[300] + : theme.palette.grey[800] + }`, marginLeft: theme.spacing(1.875), paddingLeft: theme.spacing(3.875), [`&.${stepContentClasses.last}`]: { diff --git a/packages/widget/src/components/StepActions/StepActions.tsx b/packages/widget/src/components/StepActions/StepActions.tsx index ac3425e21..76d2f9914 100644 --- a/packages/widget/src/components/StepActions/StepActions.tsx +++ b/packages/widget/src/components/StepActions/StepActions.tsx @@ -10,8 +10,8 @@ import { } from '@mui/material'; import { useTranslation } from 'react-i18next'; import { useChains } from '../../hooks'; -import LiFiLogo from '../../icons/LiFiLogo.svg'; import { formatTokenAmount } from '../../utils/format'; +import { LiFiLogo } from '../LiFiLogo'; import { StepConnector, StepContent, @@ -38,10 +38,10 @@ export const StepActions: React.FC = ({ > - {step.toolDetails.name[0]} + {step.type === 'lifi' ? : step.toolDetails.name[0]} ({ textTransform: 'none', @@ -9,12 +10,12 @@ export const Button = styled(LoadingButton)(({ theme }) => ({ padding: theme.spacing(1.25, 2), fontSize: '1rem', [`&.${buttonClasses.disabled}`]: { - color: 'rgb(0 0 0 / 70%)', + color: getContrastAlphaColor(theme, '70%'), }, [`&.${loadingButtonClasses.loading}`]: { color: 'transparent', }, [`.${loadingButtonClasses.loadingIndicator}`]: { - color: 'rgb(0 0 0 / 70%)', + color: getContrastAlphaColor(theme, '70%'), }, })); diff --git a/packages/widget/src/components/SwapInProgress/SwapInProgress.style.ts b/packages/widget/src/components/SwapInProgress/SwapInProgress.style.ts index 61037f56c..0483e2050 100644 --- a/packages/widget/src/components/SwapInProgress/SwapInProgress.style.ts +++ b/packages/widget/src/components/SwapInProgress/SwapInProgress.style.ts @@ -1,9 +1,10 @@ +import { Avatar } from '@mui/material'; import { styled } from '@mui/material/styles'; import { CardContainer, CardHeader } from '../Card'; export const Card = styled(CardContainer)(({ theme }) => ({ - borderColor: '#F7D4FF', - background: '#FEF0FF', + borderColor: theme.palette.mode === 'light' ? '#F7D4FF' : '#ee00ff47', + background: theme.palette.mode === 'light' ? '#FEF0FF' : '#ee00ff47', })); export const RouteCard = styled(CardHeader)(({ theme }) => ({ @@ -11,3 +12,7 @@ export const RouteCard = styled(CardHeader)(({ theme }) => ({ paddingTop: 0, paddingBottom: 0, })); + +export const RouteAvatar = styled(Avatar)(({ theme }) => ({ + backgroundColor: theme.palette.background.paper, +})); diff --git a/packages/widget/src/components/SwapInProgress/SwapInProgress.tsx b/packages/widget/src/components/SwapInProgress/SwapInProgress.tsx index c04e259d7..9d5adb2d8 100644 --- a/packages/widget/src/components/SwapInProgress/SwapInProgress.tsx +++ b/packages/widget/src/components/SwapInProgress/SwapInProgress.tsx @@ -2,14 +2,14 @@ import { ArrowForward as ArrowForwardIcon, KeyboardArrowRight as KeyboardArrowRightIcon, } from '@mui/icons-material'; -import { Avatar, AvatarGroup, Box, BoxProps, Stack } from '@mui/material'; +import { AvatarGroup, Box, BoxProps, Stack } from '@mui/material'; import { useCallback } from 'react'; import { useTranslation } from 'react-i18next'; import { useNavigate } from 'react-router-dom'; import { useExecutingRoutes } from '../../hooks'; import { routes } from '../../utils/routes'; import { CardTitle } from '../Card'; -import { Card, RouteCard } from './SwapInProgress.style'; +import { Card, RouteAvatar, RouteCard } from './SwapInProgress.style'; export const SwapInProgress: React.FC = (props) => { const { t } = useTranslation(); @@ -37,20 +37,18 @@ export const SwapInProgress: React.FC = (props) => { onClick={() => handleCardClick(route.id)} avatar={ - {route.fromToken.symbol[0]} - - + {route.toToken.symbol[0]} - + } action={} diff --git a/packages/widget/src/components/SwapRouteCard/SwapRouteCard.style.ts b/packages/widget/src/components/SwapRouteCard/SwapRouteCard.style.ts index dc2243a9e..2c44b6e9a 100644 --- a/packages/widget/src/components/SwapRouteCard/SwapRouteCard.style.ts +++ b/packages/widget/src/components/SwapRouteCard/SwapRouteCard.style.ts @@ -6,10 +6,16 @@ export const Card = styled(Box, { !['dense', 'active', 'blur'].includes(prop as string), })<{ active?: boolean; blur?: boolean; dense?: boolean }>( ({ theme, active, blur, dense }) => ({ - backgroundColor: theme.palette.common.white, + backgroundColor: theme.palette.background.paper, padding: theme.spacing(2), border: `1px solid ${ - active ? theme.palette.common.black : theme.palette.grey[300] + active + ? theme.palette.mode === 'light' + ? theme.palette.common.black + : theme.palette.grey[700] + : theme.palette.mode === 'light' + ? theme.palette.grey[300] + : theme.palette.grey[800] }`, borderRadius: theme.shape.borderRadius, boxSizing: 'border-box', @@ -28,11 +34,19 @@ export const Label = styled(Typography, { })<{ active?: boolean }>(({ theme, active }) => ({ backgroundColor: active ? theme.palette.primary.main - : theme.palette.common.white, + : theme.palette.background.paper, border: '1px solid', - borderColor: active ? theme.palette.primary.main : theme.palette.common.black, + borderColor: active + ? theme.palette.primary.main + : theme.palette.mode === 'light' + ? theme.palette.common.black + : theme.palette.grey[300], borderRadius: 4, - color: active ? theme.palette.common.white : theme.palette.common.black, + color: active + ? theme.palette.common.white + : theme.palette.mode === 'light' + ? theme.palette.common.black + : theme.palette.grey[300], padding: theme.spacing(0.5, 0.75), fontSize: 12, lineHeight: 1.2, diff --git a/packages/widget/src/components/SwapRoutes/SwapRoutes.tsx b/packages/widget/src/components/SwapRoutes/SwapRoutes.tsx index 4706047c8..6e784d0a1 100644 --- a/packages/widget/src/components/SwapRoutes/SwapRoutes.tsx +++ b/packages/widget/src/components/SwapRoutes/SwapRoutes.tsx @@ -59,7 +59,6 @@ export const SwapRoutes: React.FC = ({ mb }) => { onClick={handleCardClick} size="medium" aria-label="swap-routes" - color="inherit" > diff --git a/packages/widget/src/components/Switch.tsx b/packages/widget/src/components/Switch.tsx index 24f650761..8f85bbca1 100644 --- a/packages/widget/src/components/Switch.tsx +++ b/packages/widget/src/components/Switch.tsx @@ -47,7 +47,7 @@ export const Switch = styled(MuiSwitch)(({ theme }) => ({ backgroundColor: theme.palette.mode === 'light' ? theme.palette.grey[400] - : theme.palette.grey[900], + : theme.palette.grey[800], opacity: 1, transition: theme.transitions.create(['background-color'], { duration: theme.transitions.duration.standard, diff --git a/packages/widget/src/components/TokenList/TokenList.style.tsx b/packages/widget/src/components/TokenList/TokenList.style.tsx index 291fd8b35..9159b82f4 100644 --- a/packages/widget/src/components/TokenList/TokenList.style.tsx +++ b/packages/widget/src/components/TokenList/TokenList.style.tsx @@ -4,13 +4,14 @@ import { } from '@mui/material'; import { listItemSecondaryActionClasses } from '@mui/material/ListItemSecondaryAction'; import { styled } from '@mui/material/styles'; +import { getContrastAlphaColor } from '../../utils/colors'; export const ListItemButton = styled(MuiListItemButton)(({ theme }) => ({ borderRadius: theme.shape.borderRadius, paddingLeft: theme.spacing(2), height: 64, '&:hover': { - backgroundColor: 'rgba(0, 0, 0, 0.04)', + backgroundColor: getContrastAlphaColor(theme, '4%'), }, })); diff --git a/packages/widget/src/config/theme.ts b/packages/widget/src/config/theme.ts new file mode 100644 index 000000000..51bc32e5f --- /dev/null +++ b/packages/widget/src/config/theme.ts @@ -0,0 +1,142 @@ +import { PaletteMode } from '@mui/material'; +import { createTheme } from '@mui/material/styles'; + +// https://mui.com/customization/palette/ +// declare module '@mui/material/styles' { +// interface Palette { +// appBar: Palette['primary']; +// } +// interface PaletteOptions { +// appBar?: PaletteOptions['primary']; +// } +// } + +declare module '@mui/material/styles' { + interface TypographyVariants { + '@supports (font-variation-settings: normal)': React.CSSProperties; + } + interface TypographyVariantsOptions { + '@supports (font-variation-settings: normal)'?: React.CSSProperties; + } +} + +declare module '@mui/material/Typography' { + interface TypographyPropsVariantOverrides { + '@supports (font-variation-settings: normal)': true; + } +} + +export const createColorSchemeTheme = (mode: PaletteMode) => + createTheme({ + typography: { + fontFamily: 'Inter var, Inter, sans-serif', + }, + palette: { + mode, + ...(mode === 'light' + ? { + primary: { + main: '#3F49E1', + light: '#ACBEFF', + }, + secondary: { + main: '#F5B5FF', + }, + text: { + primary: '#000', + secondary: '#52575b', + }, + success: { + main: '#0AA65B', + }, + grey: { + 100: '#F4F5F6', + 200: '#EFF1F2', + 300: '#E3E7E9', + 400: '#C6C9CD', + 500: '#AEB3B7', + 600: '#798086', + 700: '#57595C', + }, + } + : { + primary: { + main: '#3F49E1', + light: '#ACBEFF', + }, + secondary: { + main: '#F5B5FF', + }, + background: { + paper: '#212121', + }, + success: { + main: '#0AA65B', + }, + }), + }, + shape: { + borderRadius: 6, + }, + components: { + MuiScopedCssBaseline: { + styleOverrides: { + root: { + fontFamily: 'Inter, sans-serif', + '@supports (font-variation-settings: normal)': { + fontFamily: 'Inter var, sans-serif', + }, + }, + }, + }, + MuiAvatar: { + styleOverrides: { + root: { + height: 32, + width: 32, + }, + }, + }, + MuiIconButton: { + styleOverrides: { + root: { + color: 'inherit', + }, + }, + }, + MuiListItemAvatar: { + styleOverrides: { + root: { + minWidth: 48, + }, + }, + }, + MuiListItemText: { + styleOverrides: { + primary: ({ theme }) => ({ + fontWeight: '500', + fontSize: '1.125rem', + lineHeight: '1.2778', + color: theme.palette.text.primary, + }), + secondary: ({ theme }) => ({ + fontWeight: '400', + fontSize: '0.75rem', + color: theme.palette.text.secondary, + }), + }, + }, + }, + // components: { + // MuiPopover: { + // styleOverrides: { + // paper: { + // border: '1px black solid', + // borderLeft: 'none', + // borderRadius: 0, + // boxShadow: '5px 5px 0px 0px #000000 !important', + // }, + // }, + // }, + // }, + }); diff --git a/packages/widget/src/icons/LiFiLogoFull.svg b/packages/widget/src/icons/LiFiFullLogo.svg similarity index 73% rename from packages/widget/src/icons/LiFiLogoFull.svg rename to packages/widget/src/icons/LiFiFullLogo.svg index 6ec65806a..37d9cac4f 100644 --- a/packages/widget/src/icons/LiFiLogoFull.svg +++ b/packages/widget/src/icons/LiFiFullLogo.svg @@ -1,10 +1,10 @@ - - - - - - - - + + + + + + + diff --git a/packages/widget/src/icons/LiFiLogo.svg b/packages/widget/src/icons/LiFiLogo.svg index 47a88c2a5..b51d1ff4a 100644 --- a/packages/widget/src/icons/LiFiLogo.svg +++ b/packages/widget/src/icons/LiFiLogo.svg @@ -1,5 +1,5 @@ - - - + + diff --git a/packages/widget/src/pages/SelectTokenPage/SelectTokenPage.style.tsx b/packages/widget/src/pages/SelectTokenPage/SelectTokenPage.style.tsx deleted file mode 100644 index d2bdc567f..000000000 --- a/packages/widget/src/pages/SelectTokenPage/SelectTokenPage.style.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import { Select as MuiSelect } from '@mui/material'; -import { inputBaseClasses } from '@mui/material/InputBase'; -import { listItemIconClasses } from '@mui/material/ListItemIcon'; -import { outlinedInputClasses } from '@mui/material/OutlinedInput'; -import { styled } from '@mui/material/styles'; - -export const TokenFilterSelect = styled(MuiSelect)(({ theme }) => ({ - backgroundColor: - theme.palette.mode === 'light' - ? theme.palette.grey[100] - : theme.palette.grey[900], - borderRadius: theme.shape.borderRadius, - border: 'none', - '&:focus': { - outline: 'none', - }, - [`.${inputBaseClasses.input}`]: { - padding: theme.spacing(0.5, 1.5), - display: 'flex', - alignItems: 'center', - }, - [`.${listItemIconClasses.root}`]: { - minWidth: 38, - }, - [`.${outlinedInputClasses.notchedOutline}`]: { - display: 'none', - }, -})); diff --git a/packages/widget/src/pages/SelectWalletPage/SelectWalletPage.style.tsx b/packages/widget/src/pages/SelectWalletPage/SelectWalletPage.style.tsx index c9d7b4757..299aff34a 100644 --- a/packages/widget/src/pages/SelectWalletPage/SelectWalletPage.style.tsx +++ b/packages/widget/src/pages/SelectWalletPage/SelectWalletPage.style.tsx @@ -7,13 +7,14 @@ import { import { listItemSecondaryActionClasses } from '@mui/material/ListItemSecondaryAction'; import { listItemTextClasses } from '@mui/material/ListItemText'; import { styled } from '@mui/material/styles'; +import { getContrastAlphaColor } from '../../utils/colors'; export const WalletListItemButton = styled(ListItemButton)(({ theme }) => ({ borderRadius: theme.shape.borderRadius, paddingLeft: theme.spacing(1.5), height: 64, '&:hover': { - backgroundColor: 'rgba(0, 0, 0, 0.04)', + backgroundColor: getContrastAlphaColor(theme, '4%'), }, })); diff --git a/packages/widget/src/pages/SwapPage/ExecutionItem.tsx b/packages/widget/src/pages/SwapPage/ExecutionItem.tsx index cc55bad9a..ba7b656bb 100644 --- a/packages/widget/src/pages/SwapPage/ExecutionItem.tsx +++ b/packages/widget/src/pages/SwapPage/ExecutionItem.tsx @@ -38,7 +38,6 @@ export const ExecutionItem: React.FC<{ { + throw new Error('You forgot to wrap your component in .'); +}; + +const initialContext: ThemeContextProps = { + toggleColorScheme: stub, +}; + +const ThemeContext = createContext(initialContext); + +export const useColorScheme = (): ThemeContextProps => useContext(ThemeContext); + +export const ThemeProvider: React.FC> = ({ + children, +}) => { + const prefersDarkMode = useMediaQuery('(prefers-color-scheme: dark)'); + const [mode, setMode] = useState( + prefersDarkMode ? 'dark' : 'light', + ); + const context = useMemo( + () => ({ + toggleColorScheme: () => { + setMode((prevMode: PaletteMode) => + prevMode === 'light' ? 'dark' : 'light', + ); + }, + }), + [], + ); + + useEffect(() => { + setMode(prefersDarkMode ? 'dark' : 'light'); + }, [prefersDarkMode]); + + const theme = useMemo(() => createColorSchemeTheme(mode), [mode]); + return ( + + {children} + + ); +}; diff --git a/packages/widget/src/providers/ThemeProvider/index.ts b/packages/widget/src/providers/ThemeProvider/index.ts new file mode 100644 index 000000000..707f49c2e --- /dev/null +++ b/packages/widget/src/providers/ThemeProvider/index.ts @@ -0,0 +1,2 @@ +export * from './ThemeProvider'; +export * from './types'; diff --git a/packages/widget/src/providers/ThemeProvider/types.ts b/packages/widget/src/providers/ThemeProvider/types.ts new file mode 100644 index 000000000..77e428b55 --- /dev/null +++ b/packages/widget/src/providers/ThemeProvider/types.ts @@ -0,0 +1,3 @@ +export interface ThemeContextProps { + toggleColorScheme(): void; +} diff --git a/packages/widget/src/theme.ts b/packages/widget/src/theme.ts deleted file mode 100644 index 1c3a82eb5..000000000 --- a/packages/widget/src/theme.ts +++ /dev/null @@ -1,117 +0,0 @@ -import { createTheme } from '@mui/material/styles'; - -// https://mui.com/customization/palette/ -// declare module '@mui/material/styles' { -// interface Palette { -// appBar: Palette['primary']; -// } -// interface PaletteOptions { -// appBar?: PaletteOptions['primary']; -// } -// } - -declare module '@mui/material/styles' { - interface TypographyVariants { - '@supports (font-variation-settings: normal)': React.CSSProperties; - } - interface TypographyVariantsOptions { - '@supports (font-variation-settings: normal)'?: React.CSSProperties; - } -} - -declare module '@mui/material/Typography' { - interface TypographyPropsVariantOverrides { - '@supports (font-variation-settings: normal)': true; - } -} - -export const theme = createTheme({ - typography: { - fontFamily: 'Inter var, Inter, sans-serif', - }, - palette: { - primary: { - main: '#3F49E1', - light: '#ACBEFF', - }, - secondary: { - main: '#F5B5FF', - }, - background: { - default: '#F4F5F6', - }, - text: { - primary: '#000', - secondary: '#52575b', - }, - success: { - main: '#0AA65B', - }, - grey: { - 100: '#F4F5F6', - 200: '#EFF1F2', - 300: '#E3E7E9', - 400: '#C6C9CD', - 500: '#AEB3B7', - 600: '#798086', - 700: '#57595C', - }, - }, - shape: { - borderRadius: 6, - }, - components: { - MuiScopedCssBaseline: { - styleOverrides: { - root: { - fontFamily: 'Inter, sans-serif', - '@supports (font-variation-settings: normal)': { - fontFamily: 'Inter var, sans-serif', - }, - }, - }, - }, - MuiAvatar: { - styleOverrides: { - root: { - height: 32, - width: 32, - }, - }, - }, - MuiListItemAvatar: { - styleOverrides: { - root: { - minWidth: 48, - }, - }, - }, - MuiListItemText: { - styleOverrides: { - primary: ({ theme }) => ({ - fontWeight: '500', - fontSize: '1.125rem', - lineHeight: '1.2778', - color: theme.palette.text.primary, - }), - secondary: ({ theme }) => ({ - fontWeight: '400', - fontSize: '0.75rem', - color: theme.palette.text.secondary, - }), - }, - }, - }, - // components: { - // MuiPopover: { - // styleOverrides: { - // paper: { - // border: '1px black solid', - // borderLeft: 'none', - // borderRadius: 0, - // boxShadow: '5px 5px 0px 0px #000000 !important', - // }, - // }, - // }, - // }, -}); diff --git a/packages/widget/src/types/widget.ts b/packages/widget/src/types/widget.ts index 6582239a2..81ca03392 100644 --- a/packages/widget/src/types/widget.ts +++ b/packages/widget/src/types/widget.ts @@ -18,4 +18,5 @@ export interface WidgetConfig { addToken: { (): void }; }; containerStyle?: CSSProperties; + baselineStyle?: CSSProperties; } diff --git a/packages/widget/src/utils/colors.ts b/packages/widget/src/utils/colors.ts new file mode 100644 index 000000000..718c27b02 --- /dev/null +++ b/packages/widget/src/utils/colors.ts @@ -0,0 +1,6 @@ +import { Theme } from '@mui/material'; + +export const getContrastAlphaColor = (theme: Theme, alpha: string | number) => + theme.palette.mode === 'light' + ? `rgb(0 0 0 / ${alpha})` + : `rgb(255 255 255 / ${alpha})`;