From 80e41c6f298857634d9055f283169869f1109666 Mon Sep 17 00:00:00 2001 From: Dominik Stumpf Date: Mon, 18 Nov 2024 19:19:06 +0100 Subject: [PATCH] feat: add dark theme --- package.json | 1 + src/app/globals.css | 278 ++++++++++++++++--------------- src/app/layout.tsx | 5 +- src/app/playground/page.tsx | 2 +- src/components/csr-providers.tsx | 19 +++ tailwind.config.ts | 4 +- 6 files changed, 168 insertions(+), 141 deletions(-) create mode 100644 src/components/csr-providers.tsx diff --git a/package.json b/package.json index 04231d4005..ce15be43c5 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", "next": "15.0.3", + "next-themes": "^0.4.3", "react": "19.0.0-rc-66855b96-20241106", "react-dom": "19.0.0-rc-66855b96-20241106", "tailwind-merge": "^2.5.4", diff --git a/src/app/globals.css b/src/app/globals.css index 165e521c3d..b1169dba1c 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -2,140 +2,146 @@ @tailwind components; @tailwind utilities; -@layer base { - html { - scroll-behavior: smooth; - } - - :root { - /* Raw colors */ - --indigo-50: #eef2ff; - --indigo-100: #e0e7ff; - --indigo-200: #c7d2fe; - --indigo-300: #a5b4fc; - --indigo-400: #818cf8; - --indigo-500: #6366f1; - --indigo-600: #4f46e5; - --indigo-700: #4338ca; - --indigo-800: #3730a3; - --indigo-900: #312e81; - - --green-50: #f0fdf4; - --green-100: #dcfce7; - --green-200: #bbf7d0; - --green-300: #86efac; - --green-400: #4ade80; - --green-500: #22c55e; - --green-600: #16a34a; - --green-700: #15803d; - --green-800: #166534; - --green-900: #14532d; - - --blue-50: #eff6ff; - --blue-100: #dbeafe; - --blue-200: #bfdbfe; - --blue-300: #93c5fd; - --blue-400: #60a5fa; - --blue-500: #3b82f6; - --blue-600: #2563eb; - --blue-700: #1d4ed8; - --blue-800: #1e40af; - --blue-900: #1e3a8a; - - --red-50: #fef2f2; - --red-100: #fee2e2; - --red-200: #fecaca; - --red-300: #fca5a5; - --red-400: #f87171; - --red-500: #ef4444; - --red-600: #dc2626; - --red-700: #b91c1c; - --red-800: #991b1b; - --red-900: #7f1d1d; - - --gray-50: #fafafa; - --gray-100: #f4f4f5; - --gray-200: #e4e4e7; - --gray-300: #d4d4d8; - --gray-350: #b0b0b9; - --gray-400: #a1a1aa; - --gray-450: #8a8a96; - --gray-500: #71717a; - --gray-600: #52525b; - --gray-700: #3f3f46; - --gray-800: #27272a; - --gray-900: #18181b; - - /* Semantic colors */ - --background: var(--gray-100); - --foreground: var(--gray-800); - --card: #fff; - --image: var(--gray-700); - --skeleton: var(--gray-300); - - --button-primary: var(--indigo-500); - --button-primary-hover: var(--indigo-600); - --button-primary-active: var(--indigo-700); - --button-primary-foreground: #fff; - --button-primary-subtle: var(--indigo-300); - --button-primary-subtle-foreground: var(--indigo-500); - - --button-secondary: rgba(0, 0, 0, 0.06); - --button-secondary-hover: rgba(0, 0, 0, 0.08); - --button-secondary-active: rgba(0, 0, 0, 0.16); - --button-secondary-foreground: var(--foreground); - --button-secondary-subtle: #a1a1aa; - --button-secondary-subtle-foreground: var(--foreground); - - --button-destructive: var(--red-500); - --button-destructive-hover: var(--red-600); - --button-destructive-active: var(--red-700); - --button-destructive-foreground: #fff; - --button-destructive-subtle: var(--red-300); - --button-destructive-subtle-foreground: var(--red-500); - - --button-success: var(--green-500); - --button-success-hover: var(--green-600); - --button-success-active: var(--green-700); - --button-success-foreground: #fff; - --button-success-subtle: var(--green-300); - --button-success-subtle-foreground: var(--green-500); - } - - :root[data-theme="dark"], - [data-theme="dark"] { - --background: var(--gray-800); - --foreground: var(--gray-100); - --card: var(--gray-700); - --image: var(--gray-600); - --skeleton: var(--gray-600); - - --button-primary: var(--indigo-500); - --button-primary-hover: var(--indigo-400); - --button-primary-active: var(--indigo-300); - --button-primary-foreground: #fff; - --button-primary-subtle: var(--indigo-300); - --button-primary-subtle-foreground: var(--indigo-500); - - --button-secondary: rgba(255, 255, 255, 0.06); - --button-secondary-hover: rgba(255, 255, 255, 0.08); - --button-secondary-active: rgba(255, 255, 255, 0.16); - --button-secondary-foreground: var(--foreground); - --button-secondary-subtle: #a1a1aa; - --button-secondary-subtle-foreground: var(--foreground); - - --button-destructive: var(--red-500); - --button-destructive-hover: var(--red-400); - --button-destructive-active: var(--red-300); - --button-destructive-foreground: #fff; - --button-destructive-subtle: var(--red-300); - --button-destructive-subtle-foreground: var(--red-500); - - --button-success: var(--green-500); - --button-success-hover: var(--green-400); - --button-success-active: var(--green-300); - --button-success-foreground: #fff; - --button-success-subtle: var(--green-300); - --button-success-subtle-foreground: var(--green-500); - } +html { + scroll-behavior: smooth; +} + +:root { + /* Raw colors */ + --indigo-50: #eef2ff; + --indigo-100: #e0e7ff; + --indigo-200: #c7d2fe; + --indigo-300: #a5b4fc; + --indigo-400: #818cf8; + --indigo-500: #6366f1; + --indigo-600: #4f46e5; + --indigo-700: #4338ca; + --indigo-800: #3730a3; + --indigo-900: #312e81; + + --green-50: #f0fdf4; + --green-100: #dcfce7; + --green-200: #bbf7d0; + --green-300: #86efac; + --green-400: #4ade80; + --green-500: #22c55e; + --green-600: #16a34a; + --green-700: #15803d; + --green-800: #166534; + --green-900: #14532d; + + --blue-50: #eff6ff; + --blue-100: #dbeafe; + --blue-200: #bfdbfe; + --blue-300: #93c5fd; + --blue-400: #60a5fa; + --blue-500: #3b82f6; + --blue-600: #2563eb; + --blue-700: #1d4ed8; + --blue-800: #1e40af; + --blue-900: #1e3a8a; + + --red-50: #fef2f2; + --red-100: #fee2e2; + --red-200: #fecaca; + --red-300: #fca5a5; + --red-400: #f87171; + --red-500: #ef4444; + --red-600: #dc2626; + --red-700: #b91c1c; + --red-800: #991b1b; + --red-900: #7f1d1d; + + --gray-50: #fafafa; + --gray-100: #f4f4f5; + --gray-200: #e4e4e7; + --gray-300: #d4d4d8; + --gray-350: #b0b0b9; + --gray-400: #a1a1aa; + --gray-450: #8a8a96; + --gray-500: #71717a; + --gray-600: #52525b; + --gray-700: #3f3f46; + --gray-800: #27272a; + --gray-900: #18181b; + + /* Semantic colors */ + --background: var(--gray-100); + --foreground: var(--gray-800); + --card: #fff; + --image: var(--gray-700); + --skeleton: var(--gray-300); + + --button-primary: var(--indigo-500); + --button-primary-hover: var(--indigo-600); + --button-primary-active: var(--indigo-700); + --button-primary-foreground: #fff; + --button-primary-subtle: var(--indigo-300); + --button-primary-subtle-foreground: var(--indigo-500); + + --button-secondary: rgba(0, 0, 0, 0.06); + --button-secondary-hover: rgba(0, 0, 0, 0.08); + --button-secondary-active: rgba(0, 0, 0, 0.16); + --button-secondary-foreground: var(--foreground); + --button-secondary-subtle: #a1a1aa; + --button-secondary-subtle-foreground: var(--foreground); + + --button-destructive: var(--red-500); + --button-destructive-hover: var(--red-600); + --button-destructive-active: var(--red-700); + --button-destructive-foreground: #fff; + --button-destructive-subtle: var(--red-300); + --button-destructive-subtle-foreground: var(--red-500); + + --button-success: var(--green-500); + --button-success-hover: var(--green-600); + --button-success-active: var(--green-700); + --button-success-foreground: #fff; + --button-success-subtle: var(--green-300); + --button-success-subtle-foreground: var(--green-500); +} + +.dark { + --background: var(--gray-800); + --foreground: var(--gray-100); + --card: var(--gray-700); + --image: var(--gray-600); + --skeleton: var(--gray-600); + + --button-primary: var(--indigo-500); + --button-primary-hover: var(--indigo-400); + --button-primary-active: var(--indigo-300); + --button-primary-foreground: #fff; + --button-primary-subtle: var(--indigo-300); + --button-primary-subtle-foreground: var(--indigo-500); + + --button-secondary: rgba(255, 255, 255, 0.06); + --button-secondary-hover: rgba(255, 255, 255, 0.08); + --button-secondary-active: rgba(255, 255, 255, 0.16); + --button-secondary-foreground: var(--foreground); + --button-secondary-subtle: #a1a1aa; + --button-secondary-subtle-foreground: var(--foreground); + + --button-destructive: var(--red-500); + --button-destructive-hover: var(--red-400); + --button-destructive-active: var(--red-300); + --button-destructive-foreground: #fff; + --button-destructive-subtle: var(--red-300); + --button-destructive-subtle-foreground: var(--red-500); + + --button-success: var(--green-500); + --button-success-hover: var(--green-400); + --button-success-active: var(--green-300); + --button-success-foreground: #fff; + --button-success-subtle: var(--green-300); + --button-success-subtle-foreground: var(--green-500); +} + +.dark video, +.dark img { + @apply brightness-90 contrast-125; +} + +body { + @apply bg-background text-foreground font-sans min-h-screen antialiased selection:bg-foreground selection:text-background; } diff --git a/src/app/layout.tsx b/src/app/layout.tsx index fd538bbc77..f4d5cec69f 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,5 +1,6 @@ import type { Metadata } from "next"; import "./globals.css"; +import { CsrProviders } from "components/csr-providers"; import { dystopian, inter } from "fonts"; import { cn } from "lib/css-utils"; @@ -19,7 +20,7 @@ const RootLayout = ({ children: React.ReactNode; }>) => { return ( - + - {children} + {children} ); diff --git a/src/app/playground/page.tsx b/src/app/playground/page.tsx index 5dc21f2d6a..a1a773e213 100644 --- a/src/app/playground/page.tsx +++ b/src/app/playground/page.tsx @@ -4,7 +4,7 @@ const Playground = () => {

Hello, Guild!

Hello, Guild!

Test, one, two, three...

-

+

Test, one, two, three...

diff --git a/src/components/csr-providers.tsx b/src/components/csr-providers.tsx new file mode 100644 index 0000000000..50115c2fe8 --- /dev/null +++ b/src/components/csr-providers.tsx @@ -0,0 +1,19 @@ +"use client"; + +import { ThemeProvider } from "next-themes"; +import type { FunctionComponent, PropsWithChildren } from "react"; + +export const CsrProviders: FunctionComponent = ({ + children, +}) => { + return ( + + {children} + + ); +}; diff --git a/tailwind.config.ts b/tailwind.config.ts index 5552e2489a..8ed8044d91 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -2,7 +2,7 @@ import type { Config } from "tailwindcss" import animatePlugin from "tailwindcss-animate"; const config = { - darkMode: ["selector", "[data-theme='dark']"], + darkMode: ["class"], content: [ "./pages/**/*.{ts,tsx}", "./components/**/*.{ts,tsx}", @@ -16,7 +16,7 @@ const config = { display: ["var(--font-dystopian,sans-serif)"], }, extend: { - + colors: { background: "var(--background)", foreground: "var(--foreground)",