Skip to content

Commit

Permalink
feat: dynamic theme with jotai
Browse files Browse the repository at this point in the history
  • Loading branch information
mehdibha committed Oct 24, 2024
1 parent 381510f commit c5be5b8
Show file tree
Hide file tree
Showing 33 changed files with 860 additions and 1,135 deletions.
63 changes: 58 additions & 5 deletions pnpm-lock.yaml

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

4 changes: 4 additions & 0 deletions www/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,11 @@
"fumadocs-ui": "^13.4.10",
"geist": "^1.2.2",
"hast-util-to-string": "^3.0.1",
"immer": "^10.1.1",
"jotai": "^2.10.1",
"jotai-immer": "^0.4.1",
"lucide-react": "^0.311.0",
"nanoid": "^5.0.7",
"next": "14.2.14",
"next-mdx-remote": "^4.4.1",
"next-themes": "^0.2.1",
Expand Down
Binary file removed www/public/android-chrome-192x192.png
Binary file not shown.
Binary file removed www/public/apple-touch-icon.png
Binary file not shown.
Binary file removed www/public/favicon-16x16.png
Binary file not shown.
Binary file removed www/public/favicon-32x32.png
Binary file not shown.
Binary file removed www/public/favicon.ico
Binary file not shown.
4 changes: 2 additions & 2 deletions www/src/__icons__/create-icon.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import React, { forwardRef } from "react";
import { useConfig } from "@/hooks/use-config";

export const createIcon = (icons: {
lucide: React.ElementType;
remix: React.ElementType;
}) => {
const Icon = forwardRef<HTMLElement, { className?: string }>((props, ref) => {
const { iconLibrary } = useConfig();
// TODO: get icon library from config
const iconLibrary = "lucide";
const IconComponent = icons[iconLibrary as keyof typeof icons];
if (!IconComponent) {
return null;
Expand Down
Binary file added www/src/app/apple-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added www/src/app/favicon.ico
Binary file not shown.
6 changes: 0 additions & 6 deletions www/src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,6 @@ export const metadata: Metadata = {
keywords: config.keywords,
authors: config.authors,
creator: config.creator,
icons: {
icon: "/favicon.ico",
shortcut: "/favicon-16x16.png",
apple: "/apple-touch-icon.png",
},
manifest: "/site.webmanifest",
openGraph: {
type: "website",
locale: "en_US",
Expand Down
27 changes: 15 additions & 12 deletions www/src/app/providers.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"use client";

import { useRouter } from "next/navigation";
import { Provider as JotaiProvider } from "jotai";
import { ThemeProvider } from "next-themes";
import { RouterProvider } from "react-aria-components";

Expand All @@ -15,17 +16,19 @@ declare module "react-aria-components" {
export function Providers({ children }: { children: React.ReactNode }) {
const router = useRouter();
return (
<RouterProvider navigate={router.push}>
<ThemeProvider
attribute="class"
defaultTheme="system"
enableSystem
disableTransitionOnChange
>
<div drawer-wrapper="" className="bg-bg">
{children}
</div>
</ThemeProvider>
</RouterProvider>
<JotaiProvider>
<RouterProvider navigate={router.push}>
<ThemeProvider
attribute="class"
defaultTheme="system"
enableSystem
disableTransitionOnChange
>
<div drawer-wrapper="" className="bg-bg">
{children}
</div>
</ThemeProvider>
</RouterProvider>
</JotaiProvider>
);
}
47 changes: 40 additions & 7 deletions www/src/app/themes/clone-theme.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,63 @@
import React from "react";
import { useThemes } from "@/hooks/use-themes";
import { Button } from "@/registry/ui/default/core/button";
import {
DialogRoot,
Dialog,
DialogFooter,
} from "@/registry/ui/default/core/dialog";
import { Form } from "@/registry/ui/default/core/form";
import { TextField } from "@/registry/ui/default/core/text-field";

export const CloneThemeDialog = ({
children,
}: {
children: React.ReactNode;
}) => {
const [name, setName] = React.useState("");
const { cloneTheme, currentThemeId } = useThemes();
return (
<DialogRoot>
{children}
<Dialog title="Clone theme">
{({ close }) => (
<>
<TextField label="Name" className="w-full" />
<Form
onSubmit={(e) => {
e.preventDefault();
cloneTheme(currentThemeId, { name });
setName("");
close();
}}
>
<TextField
autoFocus
label="Name"
isRequired
value={name}
onChange={setName}
className="w-full"
/>
<DialogFooter>
<Button variant="outline" size="sm" onPress={close}>
Cancel
</Button>
<Button
variant="primary"
variant="outline"
size="sm"
onPress={() => {
setName("");
close();
}}
>
Cancel
</Button>
<Button
type="submit"
variant="primary"
size="sm"
isDisabled={!name}
>
Save theme
</Button>
</DialogFooter>
</>
</Form>
)}
</Dialog>
</DialogRoot>
Expand Down
16 changes: 16 additions & 0 deletions www/src/app/themes/copy-theme.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Dialog, DialogRoot } from "@/registry/ui/default/core/dialog";

export const CopyThemeDialog = ({
children,
}: {
children: React.ReactNode;
}) => {
return (
<DialogRoot>
{children}
<Dialog title="Copy theme">
<p>code here</p>
</Dialog>
</DialogRoot>
);
};
39 changes: 32 additions & 7 deletions www/src/app/themes/create-theme.tsx
Original file line number Diff line number Diff line change
@@ -1,41 +1,66 @@
"use client";

import React from "react";
import { useThemes } from "@/hooks/use-themes";
import { Button } from "@/registry/ui/default/core/button";
import {
Dialog,
DialogFooter,
DialogRoot,
} from "@/registry/ui/default/core/dialog";
import { Form } from "@/registry/ui/default/core/form";
import { TextField } from "@/registry/ui/default/core/text-field";

export const CreateThemeDialog = ({
children,
}: {
children: React.ReactNode;
}) => {
const [name, setName] = React.useState("");
const { createTheme } = useThemes();

return (
<DialogRoot>
{children}
<Dialog title="Create new theme">
{({ close }) => (
<>
<TextField label="Name" className="w-full" />
<Form
onSubmit={(e) => {
e.preventDefault();
createTheme({ name });
setName("");
close();
}}
>
<TextField
autoFocus
label="Name"
isRequired
value={name}
onChange={setName}
className="w-full"
/>
<DialogFooter>
<Button variant="outline" size="sm" onPress={close}>
Cancel
</Button>
<Button
variant="primary"
variant="outline"
size="sm"
onPress={() => {
setName("");
close();
}}
>
Cancel
</Button>
<Button
type="submit"
variant="primary"
size="sm"
isDisabled={!name}
>
Save theme
</Button>
</DialogFooter>
</>
</Form>
)}
</Dialog>
</DialogRoot>
Expand Down
Loading

0 comments on commit c5be5b8

Please sign in to comment.