Read Article)
Beyond Dark Mode (Creating more than one color scheme with Tailwind and Next.js
Creating more than one color scheme with Tailwind and Next.js
let plugin = require('tailwindcss/plugin') | |
module.exports = { | |
darkMode: 'class', | |
plugins: [ | |
plugin(function ({ addVariant }) { | |
addVariant('metal', '.metal &'), | |
}), | |
], | |
} |
@tailwind utilities; | |
@layer utilities { | |
/* Background Colors (combined modes) */ | |
.bg-default { | |
@apply bg-white dark:bg-black metal:bg-black; | |
} | |
/* Border Colors (combined modes) */ | |
.border-default { | |
@apply border-black dark:border-white metal:border-red; | |
} | |
.border-default-50 { | |
@apply border-black border-opacity-50 dark:border-white dark:border-opacity-50 metal:border-red metal:border-opacity-50; | |
} | |
/* Text Colors (combined modes) */ | |
.text-default { | |
@apply text-black dark:text-white metal:text-red; | |
} | |
.text-default-50 { | |
@apply text-black text-opacity-50 dark:text-white dark:text-opacity-50 metal:text-red metal:text-opacity-50; | |
} | |
} |
import React from 'react' | |
const ExampleCard = () => { | |
return ( | |
<div className="bg-default border border-default"> | |
<h2 className="text-default">linguine</h2> | |
<p className="text-default-50">the best pasta</p> | |
</div> | |
) | |
} | |
export default ExampleCard |
import { ThemeProvider } from 'next-themes' | |
function MyApp({ Component, pageProps }) { | |
return ( | |
<ThemeProvider | |
themes={['dark', 'light', 'metal']} | |
enableSystem={false} | |
disableTransitionOnChange | |
attribute="class" | |
defaultTheme="dark" | |
> | |
<Component {...pageProps} /> | |
</ThemeProvider> | |
) | |
} | |
export default MyApp |
import React from 'react' | |
import { useTheme } from 'next-themes' | |
import { useHasMounted } from '@lib/helpers' | |
const themes = [ | |
{ title: 'Light Mode', name: 'light' }, | |
{ title: 'Dark Mode', name: 'dark' }, | |
{ title: 'Metal Mode', name: 'metal' }, | |
] | |
const ThemeSwitcher = () => { | |
const hasMounted = useHasMounted() | |
const { theme, setTheme } = useTheme() | |
// store our current and next theme objects (will be first theme, if undefined) | |
const currentIndex = Math.max( | |
0, | |
themes.findIndex((t) => t.name === theme) | |
) | |
const currentTheme = themes[currentIndex] | |
const nextIndex = (currentIndex + 1) % themes.length | |
const nextTheme = themes[nextIndex] | |
// Make sure it's only rendered on the client | |
if (!hasMounted || !theme) return null | |
return ( | |
<div> | |
<p> | |
Current: <strong>{currentTheme.title}</strong> | |
</p> | |
<button onClick={() => setTheme(nextTheme.name)}> | |
Switch to {nextTheme.title} | |
</button> | |
</div> | |
) | |
} | |
export default ThemeSwitcher |