Skip to content

Commit

Permalink
feat: ThemeModeScript - avoid page flicker on reload on SSR applica…
Browse files Browse the repository at this point in the history
…tion (NextJS, Remix) (#1056)

* feat: create `ThemeModeScript` to avoid page flicker on reload when dark mode is set; add script to root layout on homepage + docs

* refactor: move `ThemeModeScript` into `components` directory

---------

Co-authored-by: Sebastian Sutu <[email protected]>
  • Loading branch information
SutuSebastian and Sebastian Sutu authored Oct 19, 2023
1 parent 2e1202c commit 4f0399b
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 0 deletions.
4 changes: 4 additions & 0 deletions app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Inter as InterFont } from 'next/font/google';
import type { FC, PropsWithChildren } from 'react';
import '~/app/docs.css';
import '~/app/style.css';
import { ThemeModeScript } from '~/src';

const interFont = InterFont({
subsets: ['latin'],
Expand Down Expand Up @@ -56,6 +57,9 @@ export const metadata: Metadata = {
const RootLayout: NextPage<PropsWithChildren> = ({ children }) => {
return (
<html lang="en" className={`${interFont.variable} font-sans`}>
<head>
<ThemeModeScript />
</head>
<body>
{children}
<FathomScript />
Expand Down
42 changes: 42 additions & 0 deletions src/components/ThemeModeScript/ThemeModeScript.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React from 'react';
import type { ThemeMode } from '../../helpers/use-theme-mode';

export interface ThemeModeScriptProps extends React.ComponentPropsWithoutRef<'script'> {
mode?: ThemeMode;
}

export const ThemeModeScript = ({ mode, ...others }: ThemeModeScriptProps) => {
return (
<script
{...others}
data-flowbite-theme-mode-script
dangerouslySetInnerHTML={{
__html: getScript({ mode, defaultMode: 'light', localStorageKey: 'flowbite-theme-mode' }),
}}
/>
);
};

function getScript({
mode,
defaultMode,
localStorageKey,
}: {
mode?: ThemeMode;
defaultMode: ThemeMode;
localStorageKey: string;
}) {
return `
try {
const mode = window.localStorage.getItem('${localStorageKey}') ?? '${mode}' ?? '${defaultMode}';
const computedMode =
mode === 'auto' ? (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light') : mode;
if (computedMode === 'dark') {
document.documentElement.classList.add('dark');
} else {
document.documentElement.classList.remove('dark');
}
} catch (e) {}
`;
}
1 change: 1 addition & 0 deletions src/components/ThemeModeScript/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './ThemeModeScript';
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export * from './components/Tab';
export * from './components/Table';
export * from './components/TextInput';
export * from './components/Textarea';
export * from './components/ThemeModeScript';
export * from './components/Timeline';
export * from './components/Toast';
export * from './components/ToggleSwitch';
Expand Down

1 comment on commit 4f0399b

@vercel
Copy link

@vercel vercel bot commented on 4f0399b Oct 19, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.