dark mode pulled
This commit is contained in:
@@ -1,6 +1,12 @@
|
||||
import { Accessor, createContext, useContext, createMemo } from "solid-js";
|
||||
import {
|
||||
Accessor,
|
||||
createContext,
|
||||
useContext,
|
||||
createMemo,
|
||||
onMount
|
||||
} from "solid-js";
|
||||
import { createSignal } from "solid-js";
|
||||
import { createWindowWidth, isMobile } from "~/lib/resize-utils";
|
||||
import { isMobile, MOBILE_BREAKPOINT } from "~/lib/resize-utils";
|
||||
|
||||
const BarsContext = createContext<{
|
||||
leftBarSize: Accessor<number>;
|
||||
@@ -39,15 +45,41 @@ export function BarsProvider(props: { children: any }) {
|
||||
const [_rightBarNaturalSize, _setRightBarNaturalSize] = createSignal(0);
|
||||
const [syncedBarSize, setSyncedBarSize] = createSignal(0);
|
||||
const [centerWidth, setCenterWidth] = createSignal(0);
|
||||
const windowWidth = createWindowWidth();
|
||||
const initialIsMobile = isMobile(windowWidth());
|
||||
const [leftBarVisible, setLeftBarVisible] = createSignal(!initialIsMobile);
|
||||
const [windowWidth, setWindowWidth] = createSignal(
|
||||
typeof window !== "undefined" ? window.innerWidth : 1024
|
||||
);
|
||||
const [leftBarVisible, setLeftBarVisible] = createSignal(true);
|
||||
const [rightBarVisible, setRightBarVisible] = createSignal(true);
|
||||
const [barsInitialized, setBarsInitialized] = createSignal(false);
|
||||
|
||||
let leftBarSized = false;
|
||||
let rightBarSized = false;
|
||||
|
||||
// Setup window width tracking and initial mobile detection on client only
|
||||
onMount(() => {
|
||||
// Immediately sync to actual window width
|
||||
setWindowWidth(window.innerWidth);
|
||||
const initialIsMobile = isMobile(window.innerWidth);
|
||||
setLeftBarVisible(!initialIsMobile);
|
||||
|
||||
// Initialize immediately on mobile if left bar starts hidden
|
||||
if (initialIsMobile && !leftBarVisible()) {
|
||||
leftBarSized = true;
|
||||
checkAndSync();
|
||||
}
|
||||
|
||||
// Setup resize listener
|
||||
const handleResize = () => {
|
||||
setWindowWidth(window.innerWidth);
|
||||
};
|
||||
|
||||
window.addEventListener("resize", handleResize);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("resize", handleResize);
|
||||
};
|
||||
});
|
||||
|
||||
const wrappedSetLeftBarSize = (size: number) => {
|
||||
if (!barsInitialized()) {
|
||||
// Before initialization, capture natural size
|
||||
@@ -62,11 +94,16 @@ export function BarsProvider(props: { children: any }) {
|
||||
}
|
||||
};
|
||||
|
||||
// Initialize immediately on mobile if left bar starts hidden
|
||||
if (initialIsMobile && !leftBarVisible()) {
|
||||
// Skip waiting for left bar size on mobile when it starts hidden
|
||||
leftBarSized = true;
|
||||
}
|
||||
const checkAndSync = () => {
|
||||
const currentIsMobile = isMobile(windowWidth());
|
||||
const bothBarsReady = leftBarSized && (currentIsMobile || rightBarSized);
|
||||
|
||||
if (bothBarsReady) {
|
||||
const maxWidth = Math.max(_leftBarNaturalSize(), _rightBarNaturalSize());
|
||||
setSyncedBarSize(maxWidth);
|
||||
setBarsInitialized(true);
|
||||
}
|
||||
};
|
||||
|
||||
const wrappedSetRightBarSize = (size: number) => {
|
||||
if (!barsInitialized()) {
|
||||
@@ -82,17 +119,6 @@ export function BarsProvider(props: { children: any }) {
|
||||
}
|
||||
};
|
||||
|
||||
const checkAndSync = () => {
|
||||
const currentIsMobile = isMobile(windowWidth());
|
||||
const bothBarsReady = leftBarSized && (currentIsMobile || rightBarSized);
|
||||
|
||||
if (bothBarsReady) {
|
||||
const maxWidth = Math.max(_leftBarNaturalSize(), _rightBarNaturalSize());
|
||||
setSyncedBarSize(maxWidth);
|
||||
setBarsInitialized(true);
|
||||
}
|
||||
};
|
||||
|
||||
const leftBarSize = createMemo(() => {
|
||||
// Return 0 if hidden (natural size is 0), otherwise return synced size when initialized
|
||||
const naturalSize = _leftBarNaturalSize();
|
||||
|
||||
79
src/context/darkMode.tsx
Normal file
79
src/context/darkMode.tsx
Normal file
@@ -0,0 +1,79 @@
|
||||
import {
|
||||
createContext,
|
||||
useContext,
|
||||
createEffect,
|
||||
onMount,
|
||||
onCleanup,
|
||||
Accessor,
|
||||
ParentComponent
|
||||
} from "solid-js";
|
||||
import { createSignal } from "solid-js";
|
||||
|
||||
interface DarkModeContextType {
|
||||
isDark: Accessor<boolean>;
|
||||
toggleDarkMode: () => void;
|
||||
setDarkMode: (dark: boolean) => void;
|
||||
}
|
||||
|
||||
const DarkModeContext = createContext<DarkModeContextType>({
|
||||
isDark: () => false,
|
||||
toggleDarkMode: () => {},
|
||||
setDarkMode: () => {}
|
||||
});
|
||||
|
||||
export function useDarkMode() {
|
||||
const context = useContext(DarkModeContext);
|
||||
return context;
|
||||
}
|
||||
|
||||
export const DarkModeProvider: ParentComponent = (props) => {
|
||||
const [isDark, setIsDark] = createSignal(false);
|
||||
|
||||
onMount(() => {
|
||||
// Check system preference
|
||||
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
||||
setIsDark(mediaQuery.matches);
|
||||
|
||||
// Listen for system theme changes
|
||||
const handleChange = (e: MediaQueryListEvent) => {
|
||||
setIsDark(e.matches);
|
||||
};
|
||||
|
||||
mediaQuery.addEventListener("change", handleChange);
|
||||
|
||||
onCleanup(() => {
|
||||
mediaQuery.removeEventListener("change", handleChange);
|
||||
});
|
||||
});
|
||||
|
||||
// Reactively update DOM when isDark changes
|
||||
createEffect(() => {
|
||||
if (isDark()) {
|
||||
document.documentElement.classList.add("dark");
|
||||
document.documentElement.classList.remove("light");
|
||||
} else {
|
||||
document.documentElement.classList.add("light");
|
||||
document.documentElement.classList.remove("dark");
|
||||
}
|
||||
});
|
||||
|
||||
const toggleDarkMode = () => {
|
||||
setIsDark(!isDark());
|
||||
};
|
||||
|
||||
const setDarkMode = (dark: boolean) => {
|
||||
setIsDark(dark);
|
||||
};
|
||||
|
||||
return (
|
||||
<DarkModeContext.Provider
|
||||
value={{
|
||||
isDark,
|
||||
toggleDarkMode,
|
||||
setDarkMode
|
||||
}}
|
||||
>
|
||||
{props.children}
|
||||
</DarkModeContext.Provider>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user