Dark Mode
Adding dark mode to your Next.js app, it's a one-time process. We use next-themes and CSS variables for a seamless dark mode experience.
Install next-themesโ
Install next-themes by running the following command:
npm i next-themes
Create a theme providerโ
Create a theme provider component, components/theme-provider.tsx
"use client";
import { ThemeProvider as NextThemeProvider } from "next-themes";
export function ThemeProvider({ children }: React.PropsWithChildren<{}>) {
return (
<NextThemeProvider
enableSystem
defaultTheme="system"
disableTransitionOnChange
>
{children}
</NextThemeProvider>
);
}
Wrap your root layoutโ
Add the ThemeProvider component to your root layout, app/layout.tsx
import { ThemeProvider } from "@/components/theme-provider";
import "@/app/globals.css";
export const metadata = {
title: "App Name",
description: "Write your app description",
};
export default async function RootLayout({ children }: RootLayoutProps) {
return (
<html
// ๐ก Prevent next-themes hydration warning
suppressHydrationWarning
>
<body
// ๐ก Prevent hydration warnings caused by third-party extensions, such as Grammarly.
suppressHydrationWarning
>
<ThemeProvider>{children}</ThemeProvider>
</body>
</html>
);
}
Add theme-switcherโ
Add a theme switcher components, components/theme-switcher.tsx
"use client";
import React from "react";
import { useTheme } from "next-themes";
import { ActionIcon, DropdownMenu } from "rizzui";
import { MoonIcon, SunIcon } from "@heroicons/react/24/outline";
export function ThemeSwitcher() {
const { setTheme } = useTheme();
return (
<Dropdown>
<Dropdown.Trigger>
<ActionIcon variant="outline">
<SunIcon className="h-5 w-5 dark:hidden" />
<MoonIcon className="absolute h-5 w-5 hidden dark:block" />
<span className="sr-only">Toggle theme</span>
</ActionIcon>
</Dropdown.Trigger>
<Dropdown.Menu>
<Dropdown.Item onClick={() => setTheme("light")}>Light</Dropdown.Item>
<Dropdown.Item onClick={() => setTheme("dark")}>Dark</Dropdown.Item>
<Dropdown.Item onClick={() => setTheme("system")}>System</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
);
}
Configure globals.cssโ
We are using rgb formated CSS variables to define our light & dark mode theme. Why we are not using hex code directly? Because opacity modifiers won't work according to the TailwindCSS documentation. Please copy and paste this code in to your app style file.
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
/* --------------------------------- */
/* light theme */
/* --------------------------------- */
:root {
--background: 255 255 255; /* #ffffff */
--foreground: 72 72 72; /* #484848 */
--muted: 227 227 227; /* #e3e3e3 */
--muted-foreground: 146 146 146; /* #929292 */
/*
* primary colors
*/
--primary-lighter: 227 227 227; /* #e3e3e3 */
--primary-default: 34 34 34; /* #222222 */
--primary-dark: 0 0 0; /* #000000 */
--primary-foreground: 255 255 255; /* #ffffff */
/*
* secondary colors
*/
--secondary-lighter: 221 227 255; /* #dde3ff */
--secondary-default: 78 54 245; /* #4e36f5 */
--secondary-dark: 67 42 216; /* #432ad8 */
--secondary-foreground: 255 255 255; /* #ffffff */
/*
* danger colors
*/
--red-lighter: 247 212 214; /* #f7d4d6 */
--red-default: 238 0 0; /* #e00 */
--red-dark: 197 0 0; /* #c50000 */
/*
* warning colors
*/
--orange-lighter: 255 239 207; /* #ffefcf */
--orange-default: 245 166 35; /* #f5a623 */
--orange-dark: 171 87 10; /* #ab570a */
/*
* info colors
*/
--blue-lighter: 211 229 255; /* #d3e5ff */
--blue-default: 0 112 243; /* #0070f3 */
--blue-dark: 7 97 209; /* #0761d1 */
/*
* success colors
*/
--green-lighter: 185 249 207; /* #b9f9cf */
--green-default: 17 168 73; /* #11a849 */
--green-dark: 17 132 60; /* #11843c */
}
/* --------------------------------- */
/* dark theme */
/* --------------------------------- */
[data-theme="dark"] {
--background: 8 9 14; /* #08090e */
--foreground: 223 223 223; /* #dfdfdf */
--muted: 51 51 51; /* #333333 */
--muted-foreground: 102 102 102; /* #666666 */
/*
* primary colors
*/
--primary-lighter: 34 34 34; /* #222222 */
--primary-default: 241 241 241; /* #f1f1f1 */
--primary-dark: 255 255 255; /* #ffffff */
--primary-foreground: 0 0 0; /* #000000 */
/*
* secondary colors
*/
--secondary-lighter: 31 22 90; /* #1f165a */
--secondary-dark: 193 203 255; /* #c1cbff */
/*
* danger colors
*/
--red-lighter: 80 0 0; /* #500000 */
--red-dark: 255 193 193; /* #ffc1c1 */
/*
* warning colors
*/
--orange-lighter: 68 29 4; /* #441d04 */
--orange-dark: 252 234 139; /* #fcea8b */
/*
* info colors
*/
--blue-lighter: 13 51 94; /* #0d335e */
--blue-dark: 181 233 255; /* #b5e9ff */
/*
* success colors
*/
--green-lighter: 3 48 22; /* #033016 */
--green-dark: 185 249 207; /* #b9f9cf */
/* here you can customize other colors for dark theme if design required */
}
}
- Note: use our theming tools to customize these CSS variables
Configure tailwind.config.jsโ
You need to copy and paste the following tailwind configuration in your tailwind.config.js file. Check-out their offical documentation to configure other things like borderRadius, boxShadow, zIndex, and etc...
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
"./node_modules/rizzui/dist/*.{js,ts,jsx,tsx}", // โ ๏ธ Required this line to compile RizzUI style
...// ๐กโ configure your components, and any other source files path that contain Tailwind class names.
],
darkMode: ["class", '[data-theme="dark"]'], // โ ๏ธ Required this line for dark mode implementation
theme: {
extend: {
colors: {
/*
* body, modal, drawer background & ring-offset-color
*/
background: 'rgb(var(--background) / <alpha-value>)',
/*
* body text color
*/
foreground: 'rgb(var(--foreground) / <alpha-value>)',
/*
* border, default flat bg color for input components, tab & dropdown hover color
*/
muted: 'rgb(var(--muted) / <alpha-value>)',
/*
* disable foreground color
*/
'muted-foreground': 'rgb(var(--muted-foreground) / <alpha-value>)',
/*
* primary colors
*/
primary: {
lighter: "rgb(var(--primary-lighter) / <alpha-value>)",
DEFAULT: "rgb(var(--primary-default) / <alpha-value>)",
dark: "rgb(var(--primary-dark) / <alpha-value>)",
foreground: "rgb(var(--primary-foreground) / <alpha-value>)",
},
/*
* secondary colors
*/
secondary: {
lighter: "rgb(var(--secondary-lighter) / <alpha-value>)",
DEFAULT: "rgb(var(--secondary-default) / <alpha-value>)",
dark: "rgb(var(--secondary-dark) / <alpha-value>)",
foreground: "rgb(var(--secondary-foreground) / <alpha-value>)",
},
/*
* danger colors
*/
red: {
lighter: "rgb(var(--red-lighter) / <alpha-value>)",
DEFAULT: "rgb(var(--red-default) / <alpha-value>)",
dark: "rgb(var(--red-dark) / <alpha-value>)",
},
/*
* warning colors
*/
orange: {
lighter: "rgb(var(--orange-lighter) / <alpha-value>)",
DEFAULT: "rgb(var(--orange-default) / <alpha-value>)",
dark: "rgb(var(--orange-dark) / <alpha-value>)",
},
/*
* info colors
*/
blue: {
lighter: "rgb(var(--blue-lighter) / <alpha-value>)",
DEFAULT: "rgb(var(--blue-default) / <alpha-value>)",
dark: "rgb(var(--blue-dark) / <alpha-value>)",
},
/*
* success colors
*/
green: {
lighter: "rgb(var(--green-lighter) / <alpha-value>)",
DEFAULT: "rgb(var(--green-default) / <alpha-value>)",
dark: "rgb(var(--green-dark) / <alpha-value>)",
},
},
... // here goes your additional configuration
},
},
plugins: [require("@tailwindcss/forms")], // โ ๏ธ Required @tailwindcss/forms plugin.
};
โ๐โ You are all set to use our components in your application.
Usageโ
For Next.js 13 app routing, ensure the "use client" directive is defined at the top of a file before any rizzui imports.
"use client";
import { Button } from "rizzui";
export default function App() {
return <Button>Default</Button>;
}