Skip to content

Commit

Permalink
create a reusable dialog that is theme context aware
Browse files Browse the repository at this point in the history
  • Loading branch information
alexanderjoe committed Apr 29, 2024
1 parent b804267 commit 09fa514
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 46 deletions.
36 changes: 36 additions & 0 deletions ui/src/components/dialog-modal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { ComponentProps, JSX, useContext } from "solid-js";
import {
AlertDialog,
AlertDialogContent,
AlertDialogDescription,
AlertDialogTitle,
AlertDialogTrigger
} from "~/components/ui/alert-dialog";
import { Button } from "~/components/ui/button";
import { IThemeContext, ThemeContext } from "~/context/ThemeContext.tsx";

export interface DialogModalProps extends ComponentProps<"div"> {
children?: JSX.Element;
title?: string;
trigger?: JSX.Element;
}

export function DialogModal(props: DialogModalProps) {
const themeContext: IThemeContext = useContext(ThemeContext);

return (
<AlertDialog>
<AlertDialogTrigger>{props.trigger || <Button>Open Dialog</Button>}</AlertDialogTrigger>
<AlertDialogContent
class={`bg-primary dark:bg-blackout text-100 dark:text-white ${themeContext.theme}`}
>
<AlertDialogTitle
class={`font-bold text-100 light:text-black underline underline-offset-2`}
>
{props.title}
</AlertDialogTitle>
<AlertDialogDescription>{props.children}</AlertDialogDescription>
</AlertDialogContent>
</AlertDialog>
);
}
63 changes: 22 additions & 41 deletions ui/src/components/settings.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
import { ComponentProps, useContext } from "solid-js";
import {
AlertDialog,
AlertDialogContent,
AlertDialogDescription,
AlertDialogTitle,
AlertDialogTrigger
} from "~/components/ui/alert-dialog";
import { useContext } from "solid-js";
import {
Select,
SelectContent,
Expand All @@ -14,44 +7,32 @@ import {
SelectValue
} from "~/components/ui/select.tsx";
import { OcGear3 } from "solid-icons/oc";
import { IThemeContext, ThemeContext } from "~/context/ThemeContext.tsx";
import { IThemeContext, ThemeContext, themeOptions } from "~/context/ThemeContext.tsx";
import { DialogModal } from "~/components/dialog-modal.tsx";

export function Settings() {
const availableThemes = ["blackout", "logan", "lavender", "light", "blue"];
const themeContext: IThemeContext = useContext(ThemeContext);

return (
<AlertDialog>
<AlertDialogTrigger>
<OcGear3 class="w-6 h-6" />
</AlertDialogTrigger>
<AlertDialogContent
class={`bg-primary dark:bg-blackout text-100 dark:text-white ${themeContext.theme}`}
<DialogModal title="Settings" trigger={<OcGear3 class="w-6 h-6" />}>
<label class="block text-sm font-medium mb-2 text-100 light:text-black">Theme</label>
<Select
value={themeContext.theme}
onChange={themeContext.setTheme}
options={themeOptions}
placeholder="Select a theme"
itemComponent={props => (
<SelectItem item={props.item} class="focus:bg-400 focus:font-bold light:focus:bg-800">
{props.item.rawValue}
</SelectItem>
)}
class="text-100 light:text-black"
>
<AlertDialogTitle class="font-bold text-100 light:text-black underline underline-offset-2">
Settings
</AlertDialogTitle>
<AlertDialogDescription>
<label class="block text-sm font-medium mb-2 text-100 light:text-black">Theme</label>
<Select
value={themeContext.theme}
onChange={themeContext.setTheme}
options={availableThemes}
placeholder="Select a theme"
itemComponent={props => (
<SelectItem item={props.item} class="focus:bg-400 focus:font-bold light:focus:bg-800">
{props.item.rawValue}
</SelectItem>
)}
class="text-100 light:text-black"
>
<SelectTrigger aria-label="Theme" class="w-[180px] bg-secondary">
<SelectValue<string>>{state => state.selectedOption()}</SelectValue>
</SelectTrigger>
<SelectContent class={`bg-secondary text-100 light:text-black ${themeContext.theme}`} />
</Select>
</AlertDialogDescription>
</AlertDialogContent>
</AlertDialog>
<SelectTrigger aria-label="Theme" class="w-[180px] bg-secondary">
<SelectValue<string>>{state => state.selectedOption()}</SelectValue>
</SelectTrigger>
<SelectContent class={`bg-secondary text-100 light:text-black ${themeContext.theme}`} />
</Select>
</DialogModal>
);
}
14 changes: 9 additions & 5 deletions ui/src/context/ThemeContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,23 @@ export interface ThemeContextProviderProps {
}

export interface IThemeContext {
theme: string;
setTheme: (theme: string) => void;
theme: Theme;
setTheme: (theme: Theme) => void;
}

export type Theme = "blackout" | "logan" | "lavender" | "light" | "blue";
export const themeOptions: Theme[] = ["blackout", "logan", "lavender", "light", "blue"];

export const ThemeContext = createContext({} as IThemeContext);

const ACCURIBET_THEME_KEY: string = "accuribet-theme";

export function ThemeContextProvider(props: ThemeContextProviderProps) {
let preferredTheme = localStorage.getItem(ACCURIBET_THEME_KEY);
let storedTheme: Theme | undefined = localStorage.getItem(ACCURIBET_THEME_KEY) as Theme;
let preferredTheme: Theme = themeOptions.includes(storedTheme) ? storedTheme : "blackout";
const [themeStore, setThemeStore] = createStore<IThemeContext>({
theme: preferredTheme ? preferredTheme : "blackout",
setTheme(theme: string) {
theme: preferredTheme,
setTheme(theme: Theme) {
localStorage.setItem(ACCURIBET_THEME_KEY, theme);
setThemeStore("theme", theme);
}
Expand Down

0 comments on commit 09fa514

Please sign in to comment.