From 05f1dfc6896d3affa7c494a1b955f230d836a4b7 Mon Sep 17 00:00:00 2001 From: Armand Philippot Date: Fri, 27 Oct 2023 18:07:45 +0200 Subject: feat: replace next-themes with a custom ThemeProvider To be honest, next-themes was working fine. However since I use a theme provider for Prism code blocks, some code is duplicated between this app and the library. So I prefer to use a custom Provider without the options I don't need. --- .../organisms/forms/theme-toggle/theme-toggle.tsx | 15 +--- src/pages/_app.tsx | 7 +- src/pages/_document.tsx | 9 +++ src/utils/constants.ts | 1 + src/utils/helpers/index.ts | 1 + src/utils/helpers/themes.ts | 18 +++++ src/utils/hooks/index.ts | 3 + src/utils/hooks/use-match-media/index.ts | 1 + src/utils/hooks/use-match-media/use-match-media.ts | 17 +++++ src/utils/hooks/use-system-color-scheme/index.ts | 1 + .../use-system-color-scheme.ts | 24 ++++++ src/utils/hooks/use-theme/index.ts | 1 + src/utils/hooks/use-theme/use-theme.test.tsx | 82 ++++++++++++++++++++ src/utils/hooks/use-theme/use-theme.ts | 15 ++++ src/utils/providers/index.ts | 1 + src/utils/providers/theme-provider/index.ts | 1 + .../theme-provider/theme-provider.test.tsx | 78 +++++++++++++++++++ .../providers/theme-provider/theme-provider.tsx | 88 ++++++++++++++++++++++ 18 files changed, 348 insertions(+), 15 deletions(-) create mode 100644 src/utils/helpers/themes.ts create mode 100644 src/utils/hooks/use-match-media/index.ts create mode 100644 src/utils/hooks/use-match-media/use-match-media.ts create mode 100644 src/utils/hooks/use-system-color-scheme/index.ts create mode 100644 src/utils/hooks/use-system-color-scheme/use-system-color-scheme.ts create mode 100644 src/utils/hooks/use-theme/index.ts create mode 100644 src/utils/hooks/use-theme/use-theme.test.tsx create mode 100644 src/utils/hooks/use-theme/use-theme.ts create mode 100644 src/utils/providers/theme-provider/index.ts create mode 100644 src/utils/providers/theme-provider/theme-provider.test.tsx create mode 100644 src/utils/providers/theme-provider/theme-provider.tsx (limited to 'src') diff --git a/src/components/organisms/forms/theme-toggle/theme-toggle.tsx b/src/components/organisms/forms/theme-toggle/theme-toggle.tsx index 6026e1c..88f3c75 100644 --- a/src/components/organisms/forms/theme-toggle/theme-toggle.tsx +++ b/src/components/organisms/forms/theme-toggle/theme-toggle.tsx @@ -1,5 +1,4 @@ -import { useTheme } from 'next-themes'; -import { useCallback, type ChangeEvent, type FC } from 'react'; +import type { FC } from 'react'; import { useIntl } from 'react-intl'; import { Icon, Legend } from '../../../atoms'; import { @@ -7,6 +6,7 @@ import { type SwitchOption, type SwitchProps, } from '../../../molecules'; +import { useTheme } from 'src/utils/hooks'; export type ThemeToggleProps = Omit< SwitchProps, @@ -20,16 +20,9 @@ export type ThemeToggleProps = Omit< */ export const ThemeToggle: FC = (props) => { const intl = useIntl(); - const { resolvedTheme, setTheme } = useTheme(); + const { resolvedTheme, toggleTheme } = useTheme(); const isDarkTheme = resolvedTheme === 'dark'; - const updateTheme = useCallback( - (e: ChangeEvent) => { - setTheme(e.target.value === 'light' ? 'light' : 'dark'); - }, - [setTheme] - ); - const themeLabel = intl.formatMessage({ defaultMessage: 'Theme:', description: 'ThemeToggle: theme label', @@ -76,7 +69,7 @@ export const ThemeToggle: FC = (props) => { items={options} legend={{themeLabel}} name="theme" - onSwitch={updateTheme} + onSwitch={toggleTheme} value={isDarkTheme ? 'dark' : 'light'} /> ); diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index c332432..0c92c93 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -1,5 +1,4 @@ import { useRouter } from 'next/router'; -import { ThemeProvider } from 'next-themes'; import { IntlProvider } from 'react-intl'; import '../styles/globals.scss'; import type { AppPropsWithLayout } from '../types'; @@ -9,6 +8,7 @@ import { AckeeProvider, MotionProvider, PrismThemeProvider, + ThemeProvider, } from '../utils/providers'; const App = ({ Component, pageProps }: AppPropsWithLayout) => { @@ -34,9 +34,8 @@ const App = ({ Component, pageProps }: AppPropsWithLayout) => { messages={translation} > {getLayout(, {})} diff --git a/src/pages/_document.tsx b/src/pages/_document.tsx index 317d3af..7e3b5e6 100644 --- a/src/pages/_document.tsx +++ b/src/pages/_document.tsx @@ -16,6 +16,15 @@ export default function Document() { // eslint-disable-next-line react/jsx-no-literals strategy="beforeInteractive" /> +