Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/josuerhea/remix-themes
Dark and light mode with SSR for Remix.run
https://github.com/josuerhea/remix-themes
dark-mode remix remix-run theme-ui themes
Last synced: about 1 month ago
JSON representation
Dark and light mode with SSR for Remix.run
- Host: GitHub
- URL: https://github.com/josuerhea/remix-themes
- Owner: JosueRhea
- Created: 2023-08-08T15:29:57.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2023-08-09T21:59:14.000Z (over 1 year ago)
- Last Synced: 2024-11-17T13:46:38.567Z (about 2 months ago)
- Topics: dark-mode, remix, remix-run, theme-ui, themes
- Language: TypeScript
- Homepage:
- Size: 488 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
## Remix themes
Dark and light mode with SSR
### Installation
```bash
pnpm i @josuerhea/remix-themes
#or
npm i @josuerhea/remix-themes
```### Usage
Firt create `app/theme.server.ts` to setup the session storage
```ts
// app/theme.server.tsimport { createCookieSessionStorage } from "@remix-run/node";
import { Theme, isTheme } from "@josuerhea/remix-themes";const themeStorage = createCookieSessionStorage({
cookie: {
name: "your-theme-name",
secure: true,
sameSite: "lax",
path: "/",
httpOnly: true,
secrets: ["your-secret"],
},
});async function getThemeSession(request: Request) {
const session = await themeStorage.getSession(request.headers.get("Cookie"));
return {
getTheme: () => {
const themeValue = session.get("theme");
return isTheme(themeValue) ? themeValue : Theme.DARK;
},
setTheme: (theme: Theme) => session.set("theme", theme),
commit: () =>
// no theme for you on my 100th birthday! 😂
themeStorage.commitSession(session, { expires: new Date("2088-10-18") }),
};
}export { getThemeSession };
```Update the `app/root.tsx` file. You'll ned a extra component that look like this.
```tsx
// app/root.tsx
import type { LinksFunction, LoaderArgs, SerializeFrom } from "@remix-run/node";
import { NonFlashOfWrongThemeEls, ThemeProvider, useTheme } from "@josuerhea/remix-themes";
import { getThemeSession } from "~/theme.server";
import stylesheet from "~/tailwind.css";
import { useLoaderData } from "@remix-run/react";export const links: LinksFunction = () => [
{ rel: "stylesheet", href: stylesheet },
];export async function loader({ request }: LoaderArgs) {
const theme = await getThemeSession(request);return { theme: theme.getTheme() };
}type LoaderData = SerializeFrom;
export function App() {
const data = useLoaderData();
const [theme] = useTheme();return (
{/* ... */}
{/* ... */}
{/* .... */}
);
}export default function AppWithProviders() {
const data = useLoaderData();
return (
);
}
```Create a new route in `app/routes/action.set-theme.tsx` that will contain the actions that saves the session storage.
```tsx
// app/routes/action.set-theme.tsximport { json, type ActionFunction, redirect } from "@remix-run/node";
import { isTheme } from "@josuerhea/remix-themes";
import { getThemeSession } from "~/theme.server";export const action: ActionFunction = async ({ request }) => {
const themeSession = await getThemeSession(request);
const requestText = await request.text();
const form = new URLSearchParams(requestText);
const theme = form.get("theme");
if (!isTheme(theme)) {
return json({
success: false,
message: `theme value of ${theme} is not a valid theme.`,
});
}themeSession.setTheme(theme);
return json(
{ success: true },
{
headers: { "Set-Cookie": await themeSession.commit() },
},
);
};export const loader = () => redirect("/", { status: 404 });
```### useTheme
Now you can use the hook to see your current theme or change the theme.```tsx
// app/routes/_index.tsx
import { Theme, Themed, useTheme } from "@josuerhea/remix-themes";export default function Page() {
const [theme, setTheme] = useTheme();return (
Active theme: {theme ?? ""}
setTheme(e.target.value as Theme)}
>
Dark
Light
);
}
```