next-react-theme
Version:
A flexible theme provider for Next.js and react applications
219 lines (157 loc) โข 5.68 kB
Markdown
# ๐ ThemeProvider
> <sub>โ ๏ธ **SSR is not supported.** This package is intended for client-side usage only.</sub>
A lightweight and extensible **React context-based Theme Provider** for managing theme (`light` / `dark`) and optional color schemes (e.g., `"green"`, `"red"`, `"blue"`, `"yellow"`) with persistence in `localStorage`. Ideal for modern apps using Tailwind CSS or CSS variables with theme and color support.
## ๐ฆ Features
- ๐จ Light/Dark mode toggle
- ๐ Optional color scheme support
- ๐พ Persistent settings using `localStorage`
- ๐ง System preference fallback (`prefers-color-scheme`)
- โ๏ธ React Context + Hooks (`useContext`)
- ๐งช Built-in `useTheme` hook
- ๐ Applies classes/attributes directly to `<html>`
## ๐ Installation
```bash
# npm
npm install next-react-theme
# or pnpm
pnpm add next-react-theme
# or yarn
yarn install next-react-theme
```
Check [๐ **Live Demo App**](https://next-react-theme.vercel.app/)
## ๐จ Integration with shadcn/ui
1. Import the themes CSS in your `global.css` above base:
```css
@import "next-react-theme/themes.css";
```
This will add support for all shadcn/ui themes including:
- zinc
- slate
- stone
- gray
- neutral
- red
- rose
- orange
- green
- blue
- yellow
- violet
## ๐ Usage
Place this provider inside your root layout or `_app.tsx`.
### 1. Wrap Your App
```tsx
// app/layout.tsx or pages/_app.tsx
import { ThemeProvider } from "next-react-theme";
export default function App({ children }) {
// Basic usage - only light/dark theme
return <ThemeProvider>{children}</ThemeProvider>;
// color scheme support using default themes
return <ThemeProvider colorScheme={true}>{children}</ThemeProvider>;
// color scheme and custom colors
return <ThemeProvider colorScheme={true} colors={["red", "blue"]}>{children}</ThemeProvider>;
// disabled transition
return <ThemeProvider colorScheme disableTransition>{children}</ThemeProvider>;
}
```
### 2. Access Theme
```tsx
import { useTheme } from "next-react-theme";
const ThemeSwitcher = () => {
const { theme, setTheme, color, setColor } = useTheme();
return (
<div>
<button onClick={() => setTheme(theme === "dark" ? "light" : "dark")}>
Toggle Theme ({theme})
</button>
{setColor && (
<select onChange={(e) => setColor(e.target.value)} value={color}>
<option value="green">Green</option>
<option value="red">Red</option>
</select>
)}
</div>
);
};
```
## ๐งฌ API Reference
### `<ThemeProvider />`
| Prop | Type | Required | Description |
|--------------|-------------|----------|-----------------------------------------------------------------------------|
| `children` | `ReactNode` | โ
| Children components |
| `colorScheme?`| `boolean` | | Enable color scheme support. When `true`, sets a `data-color` attribute. |
| `colors?` | `string[]` | | set available colors |
| `disableTransition?` | `boolean` | `false` | Set to `true` to disable smooth background and text color transitions. This makes theme changes instant, with no animation. Useful for accessibility or if you want immediate theme switching. |
### `useTheme()`
Returns theme context values.
#### Returns
| Name | Type | Description |
|------------|----------------------|---------------------------------------------------|
| `theme` | `string` | Current theme (`"light"` or `"dark"`) |
| `setTheme` | `(t: string) => void`| Function to update the theme |
| `color` | `string` | Current color applied (`"red"`, `"green"`, etc.) |
| `setColor`| `(c: string) => void`| Function to update color scheme (if enabled) |
| `colors` | `string[]` | Available Colors if colorscheme enabled |
## ๐พ Theme Persistence
- Stores `theme` under key: `"theme"`
- Stores `color` under key: `"color"` (if `colorScheme` is `true`)
On first load:
- Tries to load from `localStorage`
- Falls back to system preference (`prefers-color-scheme`)
## ๐งฉ Dependencies
- React (>= 17)
- Tailwind (recommended for class-based theming)
- Optional: CSS variables or `data-color` attribute for accent themes
## ๐ File Structure
```bash
src/
โ
โโโ ThemeProvider.tsx # Contains ThemeProvider and useTheme
โโโ utils.ts # getFromLS / setToLS (localStorage helpers)
โโโ types.ts # Type for ThemeContextType
```
## ๐งช Example: CSS Integration
```css
/* Tailwind example */
:root {
/* default fallback */
--primary: oklch(0.205 0 0);
--secondary: oklch(0.97 0 0);
--background: oklch(1 0 0);
}
.dark {
--primary: oklch(0.922 0 0);
--secondary: oklch(0.269 0 0);
--background: oklch(0.145 0 0);
/* Light mode red theme */
[data-theme="red"] {
--primary: oklch(50.6% 0.201 29.5);
--secondary: oklch(96.1% 0 0);
--background: oklch(98% 0.12 27);
}
/* Dark mode red theme */
.dark[data-theme="red"] {
--primary: oklch(50.6% 0.201 29.5);
--secondary: oklch(14.9% 0 0);
--background: oklch(15% 0.05 27);
}
```
## ๐ง Tips
- Ensure your HTML supports the `dark` class (e.g., Tailwind dark mode is set to `"class"`)
- Use the `data-color` attribute in CSS for dynamic theming
## ๐ License
MIT โ Feel free to use, adapt, and contribute.