summaryrefslogtreecommitdiff
path: root/ui/shadcn/.claude/commands/setup-dark-mode.md
diff options
context:
space:
mode:
authorTheSiahxyz <164138827+TheSiahxyz@users.noreply.github.com>2026-01-16 08:30:14 +0900
committerTheSiahxyz <164138827+TheSiahxyz@users.noreply.github.com>2026-01-16 08:30:14 +0900
commit3fbb9a18372f2b6a675dd6c039ba52be76f3eeb4 (patch)
treeaa694a36cdd323a7853672ee7a2ba60409ac3b06 /ui/shadcn/.claude/commands/setup-dark-mode.md
updates
Diffstat (limited to 'ui/shadcn/.claude/commands/setup-dark-mode.md')
-rw-r--r--ui/shadcn/.claude/commands/setup-dark-mode.md243
1 files changed, 243 insertions, 0 deletions
diff --git a/ui/shadcn/.claude/commands/setup-dark-mode.md b/ui/shadcn/.claude/commands/setup-dark-mode.md
new file mode 100644
index 0000000..c9867b6
--- /dev/null
+++ b/ui/shadcn/.claude/commands/setup-dark-mode.md
@@ -0,0 +1,243 @@
+---
+description: Configure dark mode for your framework
+argument-hint: "[framework]"
+allowed-tools: Read, Write, Edit, Bash
+---
+
+Set up dark mode with theme switching for your specific framework.
+
+## Instructions
+
+Based on the framework detected or specified:
+1. Install required dependencies
+2. Set up theme provider
+3. Configure CSS variables
+4. Create theme toggle component
+5. Set up persistence (cookies/localStorage)
+
+## Framework Configurations
+
+### Next.js (App Router)
+```bash
+npm install next-themes
+```
+
+Create `components/theme-provider.tsx`:
+```tsx
+"use client"
+
+import * as React from "react"
+import { ThemeProvider as NextThemesProvider } from "next-themes"
+import { type ThemeProviderProps } from "next-themes/dist/types"
+
+export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
+ return <NextThemesProvider {...props}>{children}</NextThemesProvider>
+}
+```
+
+Wrap in `app/layout.tsx`:
+```tsx
+<ThemeProvider
+ attribute="class"
+ defaultTheme="system"
+ enableSystem
+ disableTransitionOnChange
+>
+ {children}
+</ThemeProvider>
+```
+
+### Vite
+Create `components/theme-provider.tsx`:
+```tsx
+import { createContext, useContext, useEffect, useState } from "react"
+
+type Theme = "dark" | "light" | "system"
+
+const ThemeProviderContext = createContext<{
+ theme: Theme
+ setTheme: (theme: Theme) => void
+}>({
+ theme: "system",
+ setTheme: () => null,
+})
+
+export function ThemeProvider({ children }: { children: React.ReactNode }) {
+ const [theme, setTheme] = useState<Theme>(
+ () => (localStorage.getItem("theme") as Theme) || "system"
+ )
+
+ useEffect(() => {
+ const root = window.document.documentElement
+ root.classList.remove("light", "dark")
+
+ if (theme === "system") {
+ const systemTheme = window.matchMedia("(prefers-color-scheme: dark)")
+ .matches
+ ? "dark"
+ : "light"
+ root.classList.add(systemTheme)
+ return
+ }
+
+ root.classList.add(theme)
+ }, [theme])
+
+ const value = {
+ theme,
+ setTheme: (theme: Theme) => {
+ localStorage.setItem("theme", theme)
+ setTheme(theme)
+ },
+ }
+
+ return (
+ <ThemeProviderContext.Provider value={value}>
+ {children}
+ </ThemeProviderContext.Provider>
+ )
+}
+
+export const useTheme = () => {
+ const context = useContext(ThemeProviderContext)
+ if (context === undefined)
+ throw new Error("useTheme must be used within a ThemeProvider")
+ return context
+}
+```
+
+### Remix
+```bash
+npm install remix-themes
+```
+
+In `app/root.tsx`:
+```tsx
+import { themeSessionResolver } from "remix-themes"
+import {
+ PreventFlashOnWrongTheme,
+ ThemeProvider,
+ useTheme,
+} from "remix-themes"
+
+export async function loader({ request }: LoaderFunctionArgs) {
+ const { getTheme } = await themeSessionResolver(request)
+ return { theme: getTheme() }
+}
+
+export default function App() {
+ const data = useLoaderData<typeof loader>()
+ const [theme] = useTheme()
+
+ return (
+ <html lang="en" className={theme ?? ""}>
+ <head>
+ <PreventFlashOnWrongTheme ssrTheme={Boolean(data.theme)} />
+ </head>
+ <body>
+ <ThemeProvider
+ specifiedTheme={data.theme}
+ themeAction="/action/set-theme"
+ >
+ <Outlet />
+ </ThemeProvider>
+ </body>
+ </html>
+ )
+}
+```
+
+### Astro
+In layout file:
+```astro
+<script is:inline>
+ const theme = (() => {
+ if (typeof localStorage !== 'undefined' && localStorage.getItem('theme')) {
+ return localStorage.getItem('theme')
+ }
+ if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
+ return 'dark'
+ }
+ return 'light'
+ })()
+
+ if (theme === 'light') {
+ document.documentElement.classList.remove('dark')
+ } else {
+ document.documentElement.classList.add('dark')
+ }
+ window.localStorage.setItem('theme', theme)
+</script>
+```
+
+## Theme Toggle Component
+
+Create `components/theme-toggle.tsx`:
+```tsx
+import { Moon, Sun } from "lucide-react"
+import { Button } from "@/components/ui/button"
+import {
+ DropdownMenu,
+ DropdownMenuContent,
+ DropdownMenuItem,
+ DropdownMenuTrigger,
+} from "@/components/ui/dropdown-menu"
+import { useTheme } from "@/components/theme-provider" // or "next-themes"
+
+export function ThemeToggle() {
+ const { setTheme } = useTheme()
+
+ return (
+ <DropdownMenu>
+ <DropdownMenuTrigger asChild>
+ <Button variant="outline" size="icon">
+ <Sun className="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
+ <Moon className="absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
+ <span className="sr-only">Toggle theme</span>
+ </Button>
+ </DropdownMenuTrigger>
+ <DropdownMenuContent align="end">
+ <DropdownMenuItem onClick={() => setTheme("light")}>
+ Light
+ </DropdownMenuItem>
+ <DropdownMenuItem onClick={() => setTheme("dark")}>
+ Dark
+ </DropdownMenuItem>
+ <DropdownMenuItem onClick={() => setTheme("system")}>
+ System
+ </DropdownMenuItem>
+ </DropdownMenuContent>
+ </DropdownMenu>
+ )
+}
+```
+
+## CSS Configuration
+
+Ensure `globals.css` has:
+```css
+@layer base {
+ :root {
+ --background: 0 0% 100%;
+ --foreground: 222.2 84% 4.9%;
+ /* ... other variables ... */
+ }
+
+ .dark {
+ --background: 222.2 84% 4.9%;
+ --foreground: 210 40% 98%;
+ /* ... other variables ... */
+ }
+}
+```
+
+## Example
+
+If the user says: `/setup-dark-mode next`
+
+1. Install next-themes
+2. Create ThemeProvider component
+3. Wrap app in ThemeProvider
+4. Create ThemeToggle component
+5. Add to navigation/header
+6. Test theme switching \ No newline at end of file