From 60c49f18389ff625177a57277ef8f292a31097bf Mon Sep 17 00:00:00 2001 From: Armand Philippot Date: Sat, 28 Oct 2023 17:12:58 +0200 Subject: refactor(providers,hooks): rewrite PrismThemeProvider & usePrismTheme * reuse Theme provider logic * move DOM mutation from provider to hook * add a script to init theme before page load --- .../prism-theme-toggle/prism-theme-toggle.tsx | 27 +--- src/pages/_app.tsx | 7 +- src/pages/_document.tsx | 17 ++- src/types/app.ts | 3 + src/utils/constants.ts | 5 + src/utils/helpers/themes.ts | 7 + src/utils/hooks/index.ts | 4 +- src/utils/hooks/use-add-classname.tsx | 32 ----- src/utils/hooks/use-attributes.tsx | 50 ------- src/utils/hooks/use-prism-theme/index.ts | 1 + .../hooks/use-prism-theme/use-prism-theme.test.tsx | 134 +++++++++++++++++ src/utils/hooks/use-prism-theme/use-prism-theme.ts | 54 +++++++ src/utils/hooks/use-query-selector-all.tsx | 22 --- src/utils/providers/index.ts | 2 +- src/utils/providers/prism-theme-provider/index.ts | 1 + .../prism-theme-provider.test.tsx | 50 +++++++ .../prism-theme-provider/prism-theme-provider.tsx | 86 +++++++++++ src/utils/providers/prism-theme.tsx | 158 --------------------- .../providers/theme-provider/theme-provider.tsx | 17 +-- 19 files changed, 376 insertions(+), 301 deletions(-) delete mode 100644 src/utils/hooks/use-add-classname.tsx delete mode 100644 src/utils/hooks/use-attributes.tsx create mode 100644 src/utils/hooks/use-prism-theme/index.ts create mode 100644 src/utils/hooks/use-prism-theme/use-prism-theme.test.tsx create mode 100644 src/utils/hooks/use-prism-theme/use-prism-theme.ts delete mode 100644 src/utils/hooks/use-query-selector-all.tsx create mode 100644 src/utils/providers/prism-theme-provider/index.ts create mode 100644 src/utils/providers/prism-theme-provider/prism-theme-provider.test.tsx create mode 100644 src/utils/providers/prism-theme-provider/prism-theme-provider.tsx delete mode 100644 src/utils/providers/prism-theme.tsx (limited to 'src') diff --git a/src/components/organisms/forms/prism-theme-toggle/prism-theme-toggle.tsx b/src/components/organisms/forms/prism-theme-toggle/prism-theme-toggle.tsx index 2b0a179..1eba191 100644 --- a/src/components/organisms/forms/prism-theme-toggle/prism-theme-toggle.tsx +++ b/src/components/organisms/forms/prism-theme-toggle/prism-theme-toggle.tsx @@ -1,6 +1,6 @@ -import { useCallback, type ChangeEvent, type FC } from 'react'; +import type { FC } from 'react'; import { useIntl } from 'react-intl'; -import { type PrismTheme, usePrismTheme } from '../../../../utils/providers'; +import { usePrismTheme } from '../../../../utils/hooks'; import { Icon, Legend } from '../../../atoms'; import { Switch, @@ -20,24 +20,7 @@ export type PrismThemeToggleProps = Omit< */ export const PrismThemeToggle: FC = (props) => { const intl = useIntl(); - const { theme, setTheme, resolvedTheme } = usePrismTheme(); - - /** - * Check if the resolved or chosen theme is dark theme. - * - * @returns {boolean} True if it is dark theme. - */ - const isDarkTheme = (prismTheme?: PrismTheme): boolean => { - if (prismTheme === 'system') return resolvedTheme === 'dark'; - return prismTheme === 'dark'; - }; - - const updateTheme = useCallback( - (e: ChangeEvent) => { - setTheme(e.target.value === 'light' ? 'light' : 'dark'); - }, - [setTheme] - ); + const { currentTheme, toggleTheme } = usePrismTheme(); const themeLabel = intl.formatMessage({ defaultMessage: 'Code blocks:', @@ -85,8 +68,8 @@ export const PrismThemeToggle: FC = (props) => { items={options} legend={{themeLabel}} name="code-blocks" - onSwitch={updateTheme} - value={isDarkTheme(theme) ? 'dark' : 'light'} + onSwitch={toggleTheme} + value={currentTheme} /> ); }; diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index 0c92c93..caf4a96 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -3,7 +3,7 @@ import { IntlProvider } from 'react-intl'; import '../styles/globals.scss'; import type { AppPropsWithLayout } from '../types'; import { settings } from '../utils/config'; -import { STORAGE_KEY } from '../utils/constants'; +import { PRISM_THEME_ATTRIBUTE, STORAGE_KEY } from '../utils/constants'; import { AckeeProvider, MotionProvider, @@ -37,7 +37,10 @@ const App = ({ Component, pageProps }: AppPropsWithLayout) => { attribute={STORAGE_KEY.THEME} storageKey={STORAGE_KEY.THEME} > - + {getLayout(, {})} diff --git a/src/pages/_document.tsx b/src/pages/_document.tsx index 7e3b5e6..6d065cd 100644 --- a/src/pages/_document.tsx +++ b/src/pages/_document.tsx @@ -1,6 +1,12 @@ import { Html, Head, Main, NextScript } from 'next/document'; import Script from 'next/script'; -import { STORAGE_KEY } from '../utils/constants'; +import { + PRISM_THEME_ATTRIBUTE, + STORAGE_KEY, + VALID_THEMES, +} from '../utils/constants'; + +const validPrismThemesStr = VALID_THEMES.map((t) => `"${t}"`); // eslint-disable-next-line @typescript-eslint/no-shadow -- Required by NextJs export default function Document() { @@ -25,6 +31,15 @@ export default function Document() { // eslint-disable-next-line react/jsx-no-literals strategy="beforeInteractive" /> +