Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/strange-walls-rescue.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"nextjs-darkmode": patch
---

Fix peerDeps
1 change: 1 addition & 0 deletions examples/nextjs/next-env.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
/// <reference types="next/navigation-types/compat/navigation" />

// NOTE: This file should not be edited
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
4 changes: 2 additions & 2 deletions lib/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@
"r18gs": "2.0.2"
},
"peerDependencies": {
"@types/react": "16.8 - 19",
"react": "16.8 - 19"
"@types/react": ">=16.8",
"react": ">=16.8"
},
"funding": [
{
Expand Down
2 changes: 1 addition & 1 deletion lib/src/client/core/core.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ describe("theme-switcher", () => {
afterEach(cleanup);

beforeEach(() => {
noFOUCScript(STORAGE_KEY);
noFOUCScript(STORAGE_KEY, "none", "");
render(<Core />);
});

Expand Down
39 changes: 11 additions & 28 deletions lib/src/client/core/core.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,22 @@ let media: MediaQueryList,
updateDOM: (mode: ColorSchemePreference, systemMode: ResolvedScheme) => void;

interface ScriptProps {
/** themeTransition */
t: string;
/** nonce */
n?: string;
n: string;
/** storageKey */
k: string;
}

/** Avoid rerender of script */
const Script = ({ n, k }: ScriptProps) => (
const Script = ({ n, k, t }: ScriptProps) => (
<script
suppressHydrationWarning
// skipcq: JS-0440
dangerouslySetInnerHTML={{ __html: `(${noFOUCScript.toString()})('${k}')` }}
dangerouslySetInnerHTML={{
__html: `(${noFOUCScript.toString()})(${[k, t, n].map(v => `'${v}'`)})`,
}}
nonce={n}
/>
);
Expand All @@ -33,23 +37,6 @@ export interface CoreProps {
k?: string;
}

/** Modify transition globally to avoid patched transitions */
const modifyTransition = (themeTransition = "none", nonce = "") => {
const doc = document;
const css = doc.createElement("style");
/** split by ';' to prevent CSS injection */
css.textContent = `*,*:after,*:before{transition:${themeTransition.split(";")[0]} !important;}`;
css.setAttribute("nonce", nonce);
doc.head.appendChild(css);

return () => {
// Force restyle
getComputedStyle(doc.body);
// Wait for next tick before removing
setTimeout(() => doc.head.removeChild(css), 1);
};
};

/**
* The Core component wich applies classes and transitions.
* Cookies are set only if corresponding ServerTarget is detected.
Expand All @@ -61,10 +48,10 @@ const modifyTransition = (themeTransition = "none", nonce = "") => {
*
* @source - Source code
*/
export const Core = ({ t, nonce, k = "o" }: CoreProps) => {
export const Core = ({ t = "none", nonce = "", k = "o" }: CoreProps) => {
const isWindowDefined = typeof window != "undefined";
// handle client side exceptions when script is not run. <- for client side apps like vite or CRA
if (isWindowDefined && !window.q) noFOUCScript(k);
if (isWindowDefined && !window.q) noFOUCScript(k, t, nonce);

const [{ m, s }, setThemeState] = useStore();

Expand All @@ -80,11 +67,7 @@ export const Core = ({ t, nonce, k = "o" }: CoreProps) => {
e.key === k && setThemeState(state => ({ ...state, m: e.newValue as ColorSchemePreference }));
});
}
if (updateDOM) {
const restoreTransitions = modifyTransition(t, nonce);
updateDOM(m, s);
restoreTransitions();
}
updateDOM?.(m, s);

return <Script {...{ n: nonce, k }} />;
return <Script {...{ n: nonce, k, t }} />;
};
14 changes: 13 additions & 1 deletion lib/src/client/core/no-fouc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,18 @@ declare global {
}

/** function to be injected in script tag for avoiding FOUC */
export const noFOUCScript = (storageKey: string) => {
export const noFOUCScript = (storageKey: string, themeTransition: string, nonce: string) => {
const [SYSTEM, DARK] = ["system", "dark"] as const;
window.u = (mode: ColorSchemePreference, systemMode: ResolvedScheme) => {
const resolvedMode = mode === SYSTEM ? systemMode : mode;
const doc = document;
const el = document.documentElement;
const css = doc.createElement("style");
/** split by ';' to prevent CSS injection */
css.textContent = `*,*:after,*:before{transition:${themeTransition.split(";")[0]} !important;}`;
css.setAttribute("nonce", nonce);
doc.head.appendChild(css);

if (resolvedMode === DARK) el.classList.add(DARK);
else el.classList.remove(DARK);
[
Expand All @@ -22,6 +29,11 @@ export const noFOUCScript = (storageKey: string) => {
].forEach(([dataLabel, value]) => el.setAttribute(`data-${dataLabel}`, value));
// System mode is decided by current system state and need not be stored in localStorage
localStorage.setItem(storageKey, mode);

// Force restyle
getComputedStyle(doc.body);
// Wait for next tick before removing
setTimeout(() => doc.head.removeChild(css), 1);
};
window.q = matchMedia(`(prefers-color-scheme: ${DARK})`);
u((localStorage.getItem(storageKey) ?? SYSTEM) as ColorSchemePreference, q.matches ? DARK : "");
Expand Down
2 changes: 1 addition & 1 deletion scripts/lite.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const config = require("./rebrand.config.json");
const packageJson = require("../lib/package.json");

const ref = packageJson.name;
packageJson.peerDependencies.r18gs = `${packageJson.dependencies.r18gs.split(".")[0]}`;
packageJson.peerDependencies.r18gs = `>=${packageJson.dependencies.r18gs.split(".")[0]}`;
delete packageJson.dependencies.r18gs;
if (Object.keys(packageJson.devDependencies).length === 0) delete packageJson.devDependencies;
packageJson.name = `${ref}-lite`;
Expand Down
Loading