update dark and ligth theme
This commit is contained in:
@@ -1,7 +1,14 @@
|
||||
import type {Metadata, Viewport} from 'next';
|
||||
import {cookies} from 'next/headers';
|
||||
import {Sora, Inter} from 'next/font/google';
|
||||
import './globals.css';
|
||||
import {getServerSession} from '@/features/auth/services/serverSession';
|
||||
import {
|
||||
htmlThemeAttr,
|
||||
parseThemeMode,
|
||||
THEME_MODE_COOKIE,
|
||||
type ThemeMode,
|
||||
} from '@/shared/theme/themeMode';
|
||||
import {Providers} from './providers';
|
||||
|
||||
const sora = Sora({
|
||||
@@ -39,10 +46,34 @@ export const metadata: Metadata = {
|
||||
},
|
||||
};
|
||||
|
||||
export const viewport: Viewport = {
|
||||
colorScheme: 'dark',
|
||||
themeColor: '#000000',
|
||||
};
|
||||
/**
|
||||
* Resolved per request rather than exported as a constant, so the UA chrome
|
||||
* (address bar, native scrollbars, the paint before CSS arrives) matches the
|
||||
* mode this visitor actually chose. A hardcoded `colorScheme: 'dark'` here
|
||||
* was one of the reasons picking Light did nothing visible.
|
||||
*/
|
||||
export async function generateViewport(): Promise<Viewport> {
|
||||
const mode = await readThemeMode();
|
||||
|
||||
if (mode === 'light') {
|
||||
return {colorScheme: 'light', themeColor: '#F7F7F8'};
|
||||
}
|
||||
if (mode === 'dark') {
|
||||
return {colorScheme: 'dark', themeColor: '#000000'};
|
||||
}
|
||||
return {
|
||||
colorScheme: 'light dark',
|
||||
themeColor: [
|
||||
{media: '(prefers-color-scheme: light)', color: '#F7F7F8'},
|
||||
{media: '(prefers-color-scheme: dark)', color: '#000000'},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
async function readThemeMode(): Promise<ThemeMode> {
|
||||
const store = await cookies();
|
||||
return parseThemeMode(store.get(THEME_MODE_COOKIE)?.value);
|
||||
}
|
||||
|
||||
export default async function RootLayout({
|
||||
children,
|
||||
@@ -56,19 +87,27 @@ export default async function RootLayout({
|
||||
* already answered in this very request.
|
||||
*/
|
||||
const session = await getServerSession();
|
||||
const themeMode = await readThemeMode();
|
||||
|
||||
return (
|
||||
// The theme attributes are server-rendered so the @scope rules in
|
||||
// loyaly.css match on the very first byte — no flash from stock defaults.
|
||||
//
|
||||
// data-theme now comes from the cookie, and is ABSENT for 'system' so
|
||||
// color-scheme stays `light dark` and light-dark() follows the OS. Astryx's
|
||||
// <Theme> re-syncs this same attribute after hydration; it writes exactly
|
||||
// what htmlThemeAttr() writes here, so the two never disagree.
|
||||
<html
|
||||
lang="en"
|
||||
data-theme="dark"
|
||||
data-theme={htmlThemeAttr(themeMode)}
|
||||
data-astryx-theme="loyaly"
|
||||
className={`${sora.variable} ${inter.variable}`}
|
||||
suppressHydrationWarning
|
||||
>
|
||||
<body>
|
||||
<Providers initialSession={session}>{children}</Providers>
|
||||
<Providers initialSession={session} initialThemeMode={themeMode}>
|
||||
{children}
|
||||
</Providers>
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user