From 5a4bbb171683255e2c71bd387841655a72508342 Mon Sep 17 00:00:00 2001 From: Giancarlo Buomprisco Date: Sat, 4 Jan 2025 16:07:12 +0800 Subject: [PATCH] Refactor Root layout theme and fonts. Encapsulate functions into separate files. Fix default theme handling when cookie is not set by fall-backing to the selected theme mode. (#103) --- apps/web/app/layout.tsx | 40 ++++++++------------------------------ apps/web/lib/fonts.ts | 26 +++++++++++++++++++++++++ apps/web/lib/root-theme.ts | 16 +++++++++++++++ 3 files changed, 50 insertions(+), 32 deletions(-) create mode 100644 apps/web/lib/root-theme.ts diff --git a/apps/web/app/layout.tsx b/apps/web/app/layout.tsx index 8959f4fbc..6d62b5cf0 100644 --- a/apps/web/app/layout.tsx +++ b/apps/web/app/layout.tsx @@ -1,23 +1,25 @@ -import { cookies } from 'next/headers'; - import { Toaster } from '@kit/ui/sonner'; -import { cn } from '@kit/ui/utils'; import { RootProviders } from '~/components/root-providers'; -import { heading, sans } from '~/lib/fonts'; +import { getFontsClassName } from '~/lib/fonts'; import { createI18nServerInstance } from '~/lib/i18n/i18n.server'; import { generateRootMetadata } from '~/lib/root-metdata'; +import { getRootTheme } from '~/lib/root-theme'; import '../styles/globals.css'; +export const generateMetadata = () => { + return generateRootMetadata(); +}; + export default async function RootLayout({ children, }: { children: React.ReactNode; }) { const { language } = await createI18nServerInstance(); - const theme = await getTheme(); - const className = getClassName(theme); + const theme = await getRootTheme(); + const className = getFontsClassName(theme); return ( @@ -31,29 +33,3 @@ export default async function RootLayout({ ); } - -function getClassName(theme?: string) { - const dark = theme === 'dark'; - const light = !dark; - - const font = [sans.variable, heading.variable].reduce( - (acc, curr) => { - if (acc.includes(curr)) return acc; - - return [...acc, curr]; - }, - [], - ); - - return cn('min-h-screen bg-background antialiased', ...font, { - dark, - light, - }); -} - -async function getTheme() { - const cookiesStore = await cookies(); - return cookiesStore.get('theme')?.value as 'light' | 'dark' | 'system'; -} - -export const generateMetadata = generateRootMetadata; diff --git a/apps/web/lib/fonts.ts b/apps/web/lib/fonts.ts index b74a05574..874c84ca2 100644 --- a/apps/web/lib/fonts.ts +++ b/apps/web/lib/fonts.ts @@ -1,5 +1,7 @@ import { Inter as SansFont } from 'next/font/google'; +import { cn } from '@kit/ui/utils'; + /** * @sans * @description Define here the sans font. @@ -21,3 +23,27 @@ const heading = sans; // we export these fonts into the root layout export { sans, heading }; + +/** + * @name getClassName + * @description Get the class name for the root layout. + * @param theme + */ +export function getFontsClassName(theme?: string) { + const dark = theme === 'dark'; + const light = !dark; + + const font = [sans.variable, heading.variable].reduce( + (acc, curr) => { + if (acc.includes(curr)) return acc; + + return [...acc, curr]; + }, + [], + ); + + return cn('min-h-screen bg-background antialiased', ...font, { + dark, + light, + }); +} diff --git a/apps/web/lib/root-theme.ts b/apps/web/lib/root-theme.ts new file mode 100644 index 000000000..672cc2a8b --- /dev/null +++ b/apps/web/lib/root-theme.ts @@ -0,0 +1,16 @@ +import { cookies } from 'next/headers'; + +type Theme = 'light' | 'dark' | 'system'; + +/** + * @name getRootTheme + * @description Get the root theme from the cookies or default theme. + * @returns The root theme. + */ +export async function getRootTheme() { + const cookiesStore = await cookies(); + + const themeCookie = cookiesStore.get('theme')?.value as Theme + + return themeCookie ?? process.env.NEXT_PUBLIC_DEFAULT_THEME_MODE ?? 'light'; +}