Skip to content

Commit a26b4db

Browse files
committed
fix: mantine color scheme conflict
1 parent 2e5007e commit a26b4db

File tree

2 files changed

+92
-1
lines changed

2 files changed

+92
-1
lines changed
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import { type MantineColorScheme, type MantineColorSchemeManager } from "@mantine/core";
2+
3+
export interface SmartColorSchemeManagerOptions {
4+
/** Local storage key used to retrieve value with `localStorage.getItem(key)` */
5+
key: string;
6+
/** Function that returns the current pathname */
7+
getPathname: () => string;
8+
/** Optional list of paths that should use the dynamic color scheme */
9+
dynamicPaths?: string[];
10+
}
11+
12+
/**
13+
* Creates a smart color scheme manager that handles different behaviors based on the current path
14+
* - For editor paths: Uses dynamic behavior with localStorage persistence and per-tab independence
15+
* - For other paths: Forces light theme
16+
*/
17+
export function smartColorSchemeManager({
18+
key,
19+
getPathname,
20+
dynamicPaths = [],
21+
}: SmartColorSchemeManagerOptions): MantineColorSchemeManager {
22+
// Keep track of theme in memory for dynamic paths
23+
let currentColorScheme: MantineColorScheme | null = null;
24+
25+
// Helper function to check if current path should use dynamic behavior
26+
const shouldUseDynamicBehavior = () => {
27+
const pathname = getPathname();
28+
return dynamicPaths.some(path => pathname === path || pathname.startsWith(`${path}/`));
29+
};
30+
31+
return {
32+
get: defaultValue => {
33+
// If not in a dynamic path (e.g., editor), always return light theme
34+
if (!shouldUseDynamicBehavior()) return "light";
35+
36+
// For dynamic paths, use the stored value (memory first, then localStorage)
37+
if (currentColorScheme) return currentColorScheme;
38+
39+
// First time initialization - read from localStorage
40+
if (typeof window === "undefined") return defaultValue;
41+
42+
try {
43+
currentColorScheme =
44+
(window.localStorage.getItem(key) as MantineColorScheme) || defaultValue;
45+
return currentColorScheme;
46+
} catch {
47+
return defaultValue;
48+
}
49+
},
50+
51+
set: value => {
52+
// Only store theme for dynamic paths
53+
if (!shouldUseDynamicBehavior()) return;
54+
55+
// Update our in-memory value
56+
currentColorScheme = value;
57+
58+
// Also save to localStorage
59+
try {
60+
window.localStorage.setItem(key, value);
61+
} catch (error) {
62+
console.warn("Smart color scheme manager was unable to save color scheme.", error);
63+
}
64+
},
65+
66+
// These do nothing regardless of path
67+
subscribe: () => {},
68+
unsubscribe: () => {},
69+
clear: () => {
70+
currentColorScheme = null;
71+
if (typeof window !== "undefined") {
72+
window.localStorage.removeItem(key);
73+
}
74+
},
75+
};
76+
}

src/pages/_app.tsx

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React from "react";
22
import type { AppProps } from "next/app";
3+
import { useRouter } from "next/router";
34
import { createTheme, MantineProvider } from "@mantine/core";
45
import "@mantine/core/styles.css";
56
import "@mantine/code-highlight/styles.css";
@@ -10,6 +11,7 @@ import { Toaster } from "react-hot-toast";
1011
import GlobalStyle from "../constants/globalStyle";
1112
import { SEO } from "../constants/seo";
1213
import { lightTheme } from "../constants/theme";
14+
import { smartColorSchemeManager } from "../lib/utils/mantineColorScheme";
1315

1416
const theme = createTheme({
1517
autoContrast: true,
@@ -53,6 +55,15 @@ const theme = createTheme({
5355
const IS_PROD = process.env.NODE_ENV === "production";
5456

5557
function JsonCrack({ Component, pageProps }: AppProps) {
58+
const { pathname } = useRouter();
59+
60+
// Create a single smart manager that handles pathname logic internally
61+
const colorSchemeManager = smartColorSchemeManager({
62+
key: "editor-color-scheme",
63+
getPathname: () => pathname,
64+
dynamicPaths: ["/editor"], // Only editor paths use dynamic theme
65+
});
66+
5667
return (
5768
<>
5869
<NextSeo {...SEO} />
@@ -66,7 +77,11 @@ function JsonCrack({ Component, pageProps }: AppProps) {
6677
applicationCategory="DeveloperApplication"
6778
aggregateRating={{ ratingValue: "4.9", ratingCount: "19" }}
6879
/>
69-
<MantineProvider defaultColorScheme="light" theme={theme}>
80+
<MantineProvider
81+
colorSchemeManager={colorSchemeManager}
82+
defaultColorScheme="light"
83+
theme={theme}
84+
>
7085
<ThemeProvider theme={lightTheme}>
7186
<Toaster
7287
position="bottom-right"

0 commit comments

Comments
 (0)