Skip to content

Commit

Permalink
feat: server side theme
Browse files Browse the repository at this point in the history
  • Loading branch information
jer3m01 committed Oct 10, 2024
1 parent e3db3d4 commit f9e8641
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 16 deletions.
3 changes: 2 additions & 1 deletion docs/src/entry-server.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
// @refresh reload
import { StartServer, createHandler } from "@solidjs/start/server";
import {getTheme} from "@kobalte/solidbase/client";

export default createHandler(() => (
<StartServer
document={({ assets, children, scripts }) => (
<html lang="en">
<html lang="en" data-theme={getTheme()}>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
Expand Down
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@
"@kobalte/core": "^0.13.6",
"@mdx-js/mdx": "^3.0.1",
"@solid-primitives/clipboard": "^1.5.10",
"@solid-primitives/event-listener": "^2.3.3",
"@solidjs/meta": "^0.29.4",
"@solidjs/router": "^0.14.7",
"@vinxi/plugin-mdx": "^3.7.2",
Expand Down
3 changes: 0 additions & 3 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 16 additions & 2 deletions src/client/components/Layout.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,27 @@
import { Title } from "@solidjs/meta";

import type { ParentProps } from "solid-js";
import { ParentProps, createEffect, onMount } from "solid-js";
import { useSolidBaseContext } from "../context";
import { CurrentPageDataContext, useCurrentPageData } from "../page-data";
import {getTheme, setTheme} from "../theme";

export default function Layout(props: ParentProps) {
const { Header, TableOfContent } = useSolidBaseContext().components;

const pageData = useCurrentPageData();

onMount(() => {
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change',({ matches }) => {
const match = matches ? "dark" : "light";
if (getTheme() !== match) setTheme(match);
})
});

createEffect(() => {
document.documentElement.setAttribute('data-theme', getTheme() ?? "light");
document.cookie = `theme=${getTheme()}; max-age=31536000; path=/`;
})

return (
<CurrentPageDataContext.Provider value={pageData}>
<div
Expand All @@ -20,7 +33,8 @@ export default function Layout(props: ParentProps) {
>
<Title>{pageData().frontmatter?.title ?? ""}</Title>

<Header>{JSON.stringify(pageData())}</Header>
<Header/>

<div
style={{
"flex-direction": "row",
Expand Down
6 changes: 3 additions & 3 deletions src/client/components/mdx-components.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ export function h4(props: ComponentProps<"h4">) {
}

export function h5(props: ComponentProps<"h5">) {
return <h4 {...props} style={{ color: "green" }} />;
return <h4 {...props} />;
}

export function h6(props: ComponentProps<"h6">) {
return <h4 {...props} style={{ color: "green" }} />;
return <h4 {...props} />;
}

export function a(props: ComponentProps<"a"> & { "data-auto-heading"?: "" }) {
Expand All @@ -42,7 +42,7 @@ export function a(props: ComponentProps<"a"> & { "data-auto-heading"?: "" }) {
}

export function code(props: ComponentProps<"code">) {
return <code class={""} {...props} />;
return <code {...props} />;
}

export function table(props: ComponentProps<"table">) {
Expand Down
11 changes: 5 additions & 6 deletions src/client/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import {
Router,
} from "@solidjs/router";
import { FileRoutes } from "@solidjs/start/router";
import { type JSX, Show, Suspense, children, onMount } from "solid-js";
import { Dynamic } from "solid-js/web";
import { type JSX, Show, Suspense, children } from "solid-js";
import {Dynamic} from "solid-js/web";
import { SolidBaseProvider, useSolidBaseContext } from "./context";

interface SolidBaseAppProps {
Expand All @@ -18,10 +18,6 @@ export function SolidBaseApp(props: SolidBaseAppProps) {
return props.children as unknown as JSX.Element;
});

onMount(() => {
document.documentElement.setAttribute("data-theme", "dark");
});

return (
<SolidBaseProvider>
<Router
Expand Down Expand Up @@ -50,3 +46,6 @@ function Layout(rootProps: RouteSectionProps) {
</Suspense>
);
}


export { getTheme, setTheme } from "./theme";
32 changes: 32 additions & 0 deletions src/client/theme.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import {isServer} from "solid-js/web";
import {createSignal} from "solid-js";
import {getCookie as getServerCookie} from "vinxi/server";

type ThemeType = "light" | "dark" | undefined;

function getClientCookie(name: string) {
if (!name || !document.cookie) return undefined;
const match = document.cookie.match(new RegExp(`\\\\W?${name}=(?<value>\\\\w+)`));
return match?.groups?.value || undefined;
}

function getServerTheme() {
"use server";

return getServerCookie("theme") as ThemeType;
}

const [theme, _setTheme] = createSignal<ThemeType>();

export function getTheme(): ThemeType {
if (isServer) return getServerTheme();

const userTheme = getClientCookie("theme");
if (userTheme) setTheme(userTheme as ThemeType);
setTheme(window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light");

return theme();
}

export const setTheme = _setTheme;

0 comments on commit f9e8641

Please sign in to comment.