SolidJSS
SolidJSโ€ข4y agoโ€ข
14 replies
Robin Lindner

Theme management with Solid

I would like to have a Dark and Light Mode on my page. For this I use Solid in combination with Astro.

<html> <!-- index.astro -->
  <body>
    <Scaffold client:only>
      <Header client:load />
      <main>
        <slot />
      </main>
      <Footer />
    </Scaffold>
  </body>
</html>


How would you proceed now?
My current status is that I have created a wrapper object "Scaffold" on the Astro page.

Scaffold is a solidjs component which looks like this:

// Scaffold.tsx
import { Component, ErrorBoundary, JSX, Suspense } from "solid-js";
import { createThemeSignal } from "../../theme";

export interface ScaffoldProps {
    children?: JSX.Element | JSX.Element[];
}

export const Scaffold: Component<ScaffoldProps> = (props: ScaffoldProps) => {
    const [theme] = createThemeSignal();

    return <div class="scaffold" data-theme={theme()}>
        <Suspense fallback={<div>Loading...</div>}>
            <ErrorBoundary fallback={err => <div>Errored: {err}</div>}>
                {props.children}
            </ErrorBoundary>
        </Suspense>
    </div>
};


There I import a "signal" for the theme:
// theme.ts
import { createStore } from "solid-js/store";

export enum Theme {
    Light = "light",
    Dark = "dark"
}

interface StoreProps {
    theme?: Theme | "system"
}

export function createThemeSignal() {
    const [store, setStore] = createStore({} as StoreProps);
    if (!document.documentElement.hasAttribute("data-theme")) {
        document.documentElement.setAttribute("data-theme", store.theme ?? "system");
    }

    let setTheme = (theme: Theme | "system") => {
        document.documentElement.setAttribute("data-theme", theme);
        setStore({ theme });
    }

    let getTheme = () => {
        return store.theme ?? "system";
    }

    return [getTheme, setTheme] as const;
}
Was this page helpful?