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)

This commit is contained in:
Giancarlo Buomprisco
2025-01-04 16:07:12 +08:00
committed by GitHub
parent b8e1bf3c18
commit 5a4bbb1716
3 changed files with 50 additions and 32 deletions

View File

@@ -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 (
<html lang={language} className={className}>
@@ -31,29 +33,3 @@ export default async function RootLayout({
</html>
);
}
function getClassName(theme?: string) {
const dark = theme === 'dark';
const light = !dark;
const font = [sans.variable, heading.variable].reduce<string[]>(
(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;

View File

@@ -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<string[]>(
(acc, curr) => {
if (acc.includes(curr)) return acc;
return [...acc, curr];
},
[],
);
return cn('min-h-screen bg-background antialiased', ...font, {
dark,
light,
});
}

View File

@@ -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';
}