Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs(examples): 📝 added multi-themes example #256

Merged
merged 10 commits into from
May 6, 2024
35 changes: 35 additions & 0 deletions examples/multi-theme/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# local env files
.env*.local

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts
3 changes: 3 additions & 0 deletions examples/multi-theme/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# multi-theme example

> An example on how to use `next-themes` with `next.js` app directory.
trm217 marked this conversation as resolved.
Show resolved Hide resolved
4 changes: 4 additions & 0 deletions examples/multi-theme/next.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/** @type {import('next').NextConfig} */
const nextConfig = {}

module.exports = nextConfig
24 changes: 24 additions & 0 deletions examples/multi-theme/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"name": "multi-theme",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"@types/node": "20.5.7",
"@types/react": "^18.2.21",
"@types/react-dom": "18.2.7",
"autoprefixer": "10.4.15",
"next": "^13.4.19",
"next-themes": "workspace:*",
"postcss": "8.4.28",
"react": "18.2.0",
"react-dom": "18.2.0",
"tailwindcss": "3.3.3",
"typescript": "^5.2.2"
}
}
6 changes: 6 additions & 0 deletions examples/multi-theme/postcss.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
30 changes: 30 additions & 0 deletions examples/multi-theme/src/app/globals.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

@layer base {
:root {
--primary: #1e293b;
--primary-foreground: #f8fafc;
}
html[data-theme='dark-classic'] {
--primary: #cbd5e1;
--primary-foreground: #0f172a;
}
html[data-theme='tangerine'] {
--primary: #fcd34d;
--primary-foreground: #0f172a;
}
html[data-theme='dark-tangerine'] {
--primary: #d97706;
--primary-foreground: #0f172a;
}
html[data-theme='mint'] {
--primary: #6ee7b7;
--primary-foreground: #0f172a;
}
html[data-theme='dark-mint'] {
--primary: #047857;
--primary-foreground: #f8fafc;
}
}
18 changes: 18 additions & 0 deletions examples/multi-theme/src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import './globals.css'
import { ThemeProvider } from '../components/ThemeProvider'

export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en" suppressHydrationWarning>
<body className="bg-white dark:bg-black min-h-[100dvh]">
<ThemeProvider
defaultTheme="light"
enableColorScheme
themes={['light', 'dark-classic', 'tangerine', 'dark-tangerine', 'mint', 'dark-mint']}
>
{children}
</ThemeProvider>
</body>
</html>
)
}
16 changes: 16 additions & 0 deletions examples/multi-theme/src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import ThemeToggles from '../components/ThemeToggles'

export default function Home() {
return (
<div className="w-full container p-4 mx-auto">
<div className="py-20 flex flex-col items-center justify-center text-gray-800 dark:text-gray-100">
<h1 className="text-5xl text-center font-bold">
Next Themes + Tailwind +{' '}
<span className="text-primary-foreground bg-primary py-2 px-4 rounded">Multi</span> Themes
</h1>
<p className="italic text-2xl">with app-dir</p>
<ThemeToggles />
</div>
</div>
)
}
13 changes: 13 additions & 0 deletions examples/multi-theme/src/components/ThemeProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
'use client'

import * as React from 'react'
import { ThemeProvider as NextThemesProvider } from 'next-themes'
type ThemeProviderProps = Parameters<typeof NextThemesProvider>[0]

/**
* Your app's theme provider component.
* 'use client' is essential for next-themes to work with app-dir.
*/
export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
return <NextThemesProvider {...props}>{children}</NextThemesProvider>
}
86 changes: 86 additions & 0 deletions examples/multi-theme/src/components/ThemeToggles.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
'use client'

import { useTheme } from 'next-themes'

function ThemeToggles() {
const { theme, setTheme } = useTheme()

return (
<div className="mt-16 grid grid-cols-3 grid-rows-2 grid-flow-col gap-4">
<button
className={`px-4 py-2 font-semibold rounded-md ${
theme == 'light'
? 'border border-primary bg-primary-foreground text-primary'
: 'bg-primary text-primary-foreground'
}`}
onClick={() => {
setTheme('light')
}}
>
Default
</button>
<button
className={`px-4 py-2 font-semibold rounded-md ${
theme == 'dark-classic'
? 'border border-primary bg-primary-foreground text-primary'
: 'bg-primary text-primary-foreground'
}`}
onClick={() => {
setTheme('dark-classic')
}}
>
Dark
</button>
<button
className={`px-4 py-2 font-semibold rounded-md ${
theme == 'tangerine'
? 'border border-primary bg-primary-foreground text-primary'
: 'bg-primary text-primary-foreground'
}`}
onClick={() => {
setTheme('tangerine')
}}
>
Tangerine
</button>
<button
className={`px-4 py-2 font-semibold rounded-md ${
theme == 'dark-tangerine'
? 'border border-primary bg-primary-foreground text-primary'
: 'bg-primary text-primary-foreground'
}`}
onClick={() => {
setTheme('dark-tangerine')
}}
>
Tangerine (dark)
</button>
<button
className={`px-4 py-2 font-semibold rounded-md ${
theme == 'mint'
? 'border border-primary bg-primary-foreground text-primary'
: 'bg-primary text-primary-foreground'
}`}
onClick={() => {
setTheme('mint')
}}
>
Mint
</button>
<button
className={`px-4 py-2 font-semibold rounded-md ${
theme == 'dark-mint'
? 'border border-primary bg-primary-foreground text-primary'
: 'bg-primary text-primary-foreground'
}`}
onClick={() => {
setTheme('dark-mint')
}}
>
Mint (dark)
</button>
</div>
trm217 marked this conversation as resolved.
Show resolved Hide resolved
)
}

export default ThemeToggles
18 changes: 18 additions & 0 deletions examples/multi-theme/tailwind.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import type { Config } from 'tailwindcss'

const config: Config = {
darkMode: ['class', '[data-theme^="dark-"]'],
content: ['./src/**/*.{js,ts,jsx,tsx,mdx}'],
theme: {
extend: {
colors: {
primary: {
DEFAULT: 'var(--primary)',
foreground: 'var(--primary-foreground)'
}
}
}
},
plugins: []
}
export default config
27 changes: 27 additions & 0 deletions examples/multi-theme/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"plugins": [
{
"name": "next"
}
],
"paths": {
"@/*": ["./*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}
Loading
Loading