Skip to content

Commit 5280aa3

Browse files
committed
feat: setup dark mode
1 parent 74f12b2 commit 5280aa3

File tree

12 files changed

+97
-48
lines changed

12 files changed

+97
-48
lines changed

site/src/App.css

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -5,38 +5,3 @@
55
text-align: center;
66
}
77

8-
.logo {
9-
height: 6em;
10-
padding: 1.5em;
11-
will-change: filter;
12-
transition: filter 300ms;
13-
}
14-
.logo:hover {
15-
filter: drop-shadow(0 0 2em #646cffaa);
16-
}
17-
.logo.react:hover {
18-
filter: drop-shadow(0 0 2em #61dafbaa);
19-
}
20-
21-
@keyframes logo-spin {
22-
from {
23-
transform: rotate(0deg);
24-
}
25-
to {
26-
transform: rotate(360deg);
27-
}
28-
}
29-
30-
@media (prefers-reduced-motion: no-preference) {
31-
a:nth-of-type(2) .logo {
32-
animation: logo-spin infinite 20s linear;
33-
}
34-
}
35-
36-
.card {
37-
padding: 2em;
38-
}
39-
40-
.read-the-docs {
41-
color: #888;
42-
}

site/src/App.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import './App.css'
22
import { DynamicForm } from './DynamicForm'
3+
import { ThemeProvider } from "./components/theme-provider"
4+
35
function App() {
46
return (
5-
<>
7+
<ThemeProvider defaultTheme="dark" storageKey="vite-ui-theme">
68
<DynamicForm />
7-
</>
9+
</ThemeProvider>
810
);
911
}
1012

site/src/DynamicForm.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -571,7 +571,7 @@ export function DynamicForm() {
571571

572572
<CollapsibleSummary label="Server Response JSON">
573573
<div className="rounded-lg bg-gray-50 p-4 dark:bg-gray-900 text-left">
574-
{serverResponse && <ReactJson src={serverResponse} />}
574+
{serverResponse && <ReactJson src={serverResponse} theme="twilight" />}
575575
</div>
576576
</CollapsibleSummary>
577577
</div>

site/src/components/Checkbox/Checkbox.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ function Checkbox({
1212
<CheckboxPrimitive.Root
1313
data-slot="checkbox"
1414
className={cn(
15-
"peer border-input dark:bg-input/30 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground dark:data-[state=checked]:bg-primary data-[state=checked]:border-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive size-4 shrink-0 rounded-[4px] border shadow-xs transition-shadow outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50",
15+
"peer border-border-default dark:bg-input/30 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground dark:data-[state=checked]:bg-primary data-[state=checked]:border-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive size-4 shrink-0 rounded-[4px] border shadow-xs transition-shadow outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50",
1616
className
1717
)}
1818
{...props}

site/src/components/Input/Input.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export const Input = forwardRef<
99
<input
1010
type={type}
1111
className={cn(
12-
`flex h-10 w-full rounded-md border border-border border-solid bg-transparent px-3
12+
`flex h-10 w-full rounded-md border border-border-default border-solid bg-transparent px-3
1313
text-base shadow-sm transition-colors
1414
file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-content-primary
1515
placeholder:text-content-secondary

site/src/components/Select/Select.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ const SelectTrigger = React.forwardRef<
1919
<SelectPrimitive.Trigger
2020
ref={ref}
2121
className={cn(
22-
"flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm ring-offset-background data-[placeholder]:text-content-secondary focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
22+
"flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border border-border-default bg-transparent px-3 py-2 text-sm shadow-sm ring-offset-background data-[placeholder]:text-content-secondary focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
2323
className
2424
)}
2525
{...props}

site/src/components/Textarea/Textarea.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ function Textarea({ className, ...props }: React.ComponentProps<"textarea">) {
77
<textarea
88
data-slot="textarea"
99
className={cn(
10-
"border-input placeholder:text-content-secondary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
10+
"border-border-default placeholder:text-content-secondary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
1111
className
1212
)}
1313
{...props}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import { createContext, useContext, useEffect, useState } from "react"
2+
3+
type Theme = "dark" | "light" | "system"
4+
5+
type ThemeProviderProps = {
6+
children: React.ReactNode
7+
defaultTheme?: Theme
8+
storageKey?: string
9+
}
10+
11+
type ThemeProviderState = {
12+
theme: Theme
13+
setTheme: (theme: Theme) => void
14+
}
15+
16+
const initialState: ThemeProviderState = {
17+
theme: "system",
18+
setTheme: () => null,
19+
}
20+
21+
const ThemeProviderContext = createContext<ThemeProviderState>(initialState)
22+
23+
export function ThemeProvider({
24+
children,
25+
defaultTheme = "system",
26+
storageKey = "vite-ui-theme",
27+
...props
28+
}: ThemeProviderProps) {
29+
const [theme, setTheme] = useState<Theme>(
30+
() => (localStorage.getItem(storageKey) as Theme) || defaultTheme
31+
)
32+
33+
useEffect(() => {
34+
const root = window.document.documentElement
35+
36+
root.classList.remove("light", "dark")
37+
38+
if (theme === "system") {
39+
const systemTheme = window.matchMedia("(prefers-color-scheme: dark)")
40+
.matches
41+
? "dark"
42+
: "light"
43+
44+
root.classList.add(systemTheme)
45+
return
46+
}
47+
48+
root.classList.add(theme)
49+
}, [theme])
50+
51+
const value = {
52+
theme,
53+
setTheme: (theme: Theme) => {
54+
localStorage.setItem(storageKey, theme)
55+
setTheme(theme)
56+
},
57+
}
58+
59+
return (
60+
<ThemeProviderContext.Provider {...props} value={value}>
61+
{children}
62+
</ThemeProviderContext.Provider>
63+
)
64+
}
65+
66+
export const useTheme = () => {
67+
const context = useContext(ThemeProviderContext)
68+
69+
if (context === undefined)
70+
throw new Error("useTheme must be used within a ThemeProvider")
71+
72+
return context
73+
}

site/src/components/ui/command.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ function CommandInput({
5353
...props
5454
}: React.ComponentProps<typeof CommandPrimitive.Input>) {
5555
return (
56-
<div className="border-input flex items-center border-b px-5" cmdk-input-wrapper="">
56+
<div className="border-border-default flex items-center border-b px-5" cmdk-input-wrapper="">
5757
<SearchIcon size={20} className="text-muted-foreground/80 me-3" />
5858
<CommandPrimitive.Input
5959
data-slot="command-input-wrapper"

site/src/components/ui/multiselect.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,7 @@ const MultipleSelector = ({
415415
>
416416
<div
417417
className={cn(
418-
"border-input focus-within:border-ring focus-within:ring-ring/50 has-aria-invalid:ring-destructive/20 dark:has-aria-invalid:ring-destructive/40 has-aria-invalid:border-destructive relative min-h-[38px] rounded-md border text-sm transition-[color,box-shadow] outline-none focus-within:ring-[3px] has-disabled:pointer-events-none has-disabled:cursor-not-allowed has-disabled:opacity-50",
418+
"border-border-default focus-within:border-ring focus-within:ring-ring/50 has-aria-invalid:ring-destructive/20 dark:has-aria-invalid:ring-destructive/40 has-aria-invalid:border-destructive relative min-h-[38px] rounded-md border text-sm transition-[color,box-shadow] outline-none focus-within:ring-[3px] has-disabled:pointer-events-none has-disabled:cursor-not-allowed has-disabled:opacity-50",
419419
{
420420
"p-1": selected.length !== 0,
421421
"cursor-text": !disabled && selected.length !== 0,
@@ -434,7 +434,7 @@ const MultipleSelector = ({
434434
<div
435435
key={option.value}
436436
className={cn(
437-
"animate-fadeIn bg-background text-secondary-foreground hover:bg-background relative inline-flex h-7 cursor-default items-center rounded-md border ps-2 pe-7 pl-2 text-xs font-medium transition-all disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 data-fixed:pe-2",
437+
"animate-fadeIn bg-background text-content-secondary hover:bg-background relative inline-flex h-7 cursor-default items-center rounded-md border border-border-default ps-2 pe-7 pl-2 text-xs font-medium transition-all disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 data-fixed:pe-2",
438438
badgeClassName,
439439
)}
440440
data-fixed={option.fixed}
@@ -517,7 +517,7 @@ const MultipleSelector = ({
517517
<div className="relative">
518518
<div
519519
className={cn(
520-
"border-input absolute top-2 z-10 w-full overflow-hidden rounded-md border",
520+
"border-border-default absolute top-2 z-10 w-full overflow-hidden rounded-md border",
521521
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
522522
!open && "hidden",
523523
)}

0 commit comments

Comments
 (0)