Skip to content

Commit

Permalink
Update Readme
Browse files Browse the repository at this point in the history
  • Loading branch information
mayank1513 committed Jun 9, 2024
1 parent 194ed05 commit 01532c7
Show file tree
Hide file tree
Showing 2 changed files with 272 additions and 45 deletions.
7 changes: 4 additions & 3 deletions .tkb
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
"P_NrSJQ8m91Odgz8E1fS6": {
"id": "P_NrSJQ8m91Odgz8E1fS6",
"description": "Create your library and update examples",
"columnId": "column-todo"
"columnId": "column-doing"
},
"1dRWJhy45E1Rq5wZAmPHt": {
"id": "1dRWJhy45E1Rq5wZAmPHt",
Expand Down Expand Up @@ -143,7 +143,6 @@
"id": "column-todo",
"title": "To do",
"tasksIds": [
"P_NrSJQ8m91Odgz8E1fS6",
"1dRWJhy45E1Rq5wZAmPHt",
"5vS1JNXoMhDl5IBljwh2v",
"55DAZwduwTvlaxaJC8hlX",
Expand All @@ -156,7 +155,9 @@
{
"id": "column-doing",
"title": "Doing",
"tasksIds": []
"tasksIds": [
"P_NrSJQ8m91Odgz8E1fS6"
]
},
{
"id": "column-done",
Expand Down
310 changes: 268 additions & 42 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,34 @@

[![test](https://github.com/react18-tools/nextjs-darkmode/actions/workflows/test.yml/badge.svg)](https://github.com/react18-tools/nextjs-darkmode/actions/workflows/test.yml) [![Maintainability](https://api.codeclimate.com/v1/badges/aa896ec14c570f3bb274/maintainability)](https://codeclimate.com/github/react18-tools/nextjs-darkmode/maintainability) [![codecov](https://codecov.io/gh/react18-tools/nextjs-darkmode/graph/badge.svg)](https://codecov.io/gh/react18-tools/nextjs-darkmode) [![Version](https://img.shields.io/npm/v/nextjs-darkmode.svg?colorB=green)](https://www.npmjs.com/package/nextjs-darkmode) [![Downloads](https://img.jsdelivr.com/img.shields.io/npm/d18m/nextjs-darkmode.svg)](https://www.npmjs.com/package/nextjs-darkmode) ![npm bundle size](https://img.shields.io/bundlephobia/minzip/nextjs-darkmode) [![Gitpod ready-to-code](https://img.shields.io/badge/Gitpod-ready--to--code-blue?logo=gitpod)](https://gitpod.io/from-referrer/)

Nextjs Darkmode is a comprehensive library designed to unlock the full potential of React 18 server components. It provides customizable loading animation components and a fullscreen loader container, seamlessly integrating with React and Next.js.
Nextjs Darkmode is a versatile library crafted to fully utilize React 18 server components, ensuring a seamless dark mode experience in Next.js applications. Lightweight and efficient, it respects both user preferences and system settings through the prefers-color-scheme media query, and integrates effortlessly with React/Vite, Remix, and Next.js.

✅ Fully Treeshakable (import from `nextjs-darkmode/client/loader-container`)
## Motivation

✅ Fully TypeScript Supported
The `nextjs-themes` library was initially created to achieve a similar functionality to `next-themes` with React Server Components. While effective, it felt bulky for those supporting only dark/light mode. Thus, `nextjs-darkmode` was developed to offer a minimal footprint while utilizing Next.js Server Components, avoiding any flash of unthemed content, and ensuring theme synchronization with the server.

✅ Leverages the power of React 18 Server components
## Features

✅ Compatible with all React 18 build systems/tools/frameworks
- ✅ Simple API to toggle between dark and light modes
- ✅ Perfect dark mode with just 2 lines of code
- ✅ Compatible with Tailwind CSS
- ✅ Fully treeshakable (e.g., `import from nextjs-darkmode/hooks`)
- ✅ Full TypeScript support
- ✅ Utilizes React 18 Server components
- ✅ Compatible with all React 18 build systems/tools/frameworks
- ✅ System setting with `prefers-color-scheme`
- ✅ Supports Next.js 13 & 14 `appDir`
- ✅ No flash on load (supports SSG, SSR, ISG, and Server Components)
- ✅ Sync theme across tabs and windows
- ✅ Apply custom transitions when changing themes
- ✅ Manipulate theme via the `useMode` hook
- ✅ No cookies when not using the corresponding `ServerTarget`

✅ Documented with [Typedoc](https://react18-tools.github.io/nextjs-darkmode) ([Docs](https://react18-tools.github.io/nextjs-darkmode))
- ✅ Comprehensive documentation with [Typedoc](https://react18-tools.github.io/nextjs-darkmode)

✅ Examples for Next.js, Vite, and Remix
Feel free to [request new features](https://github.com/react18-tools/nextjs-darkmode/issues/new?assignees=&labels=&projects=&template=feature_request.md&title=), [discuss](https://github.com/react18-tools/nextjs-darkmode/discussions), or [report bugs](https://github.com/react18-tools/nextjs-darkmode/issues/new?assignees=&labels=&projects=&template=bug_report.md&title=).

> <img src="https://github.com/react18-tools/nextjs-darkmode/blob/main/popper.png?raw=true" style="height: 20px"/> Please consider starring [this repository](https://github.com/react18-tools/nextjs-darkmode) and sharing it with your friends.
Please consider starring [this repository](https://github.com/react18-tools/nextjs-darkmode) and sharing it with your friends.

## Getting Started

Expand All @@ -40,73 +53,286 @@ $ yarn add nextjs-darkmode

### Import Styles

You can import styles globally or within specific components.
Import styles globally or within layout component.

```css
/* globals.css */
@import "nextjs-darkmode/dist";
@import "nextjs-darkmode/css";
```

```tsx
// layout.tsx
import "nextjs-darkmode/dist/index.css";
import "nextjs-darkmode/css";
```

For selective imports:
## Lite Version

```css
/* globals.css */
@import "nextjs-darkmode/dist/client"; /** required if you are using LoaderContainer */
@import "nextjs-darkmode/dist/server/bars/bars1";
For a lighter version, use `nextjs-darkmode-lite`:

[![npm bundle size](https://img.shields.io/bundlephobia/minzip/nextjs-darkmode-lite)](https://www.npmjs.com/package/nextjs-darkmode-lite) [![Version](https://img.shields.io/npm/v/nextjs-darkmode-lite.svg?colorB=green)](https://www.npmjs.com/package/nextjs-darkmode-lite) [![Downloads](https://img.jsdelivr.com/img.shields.io/npm/d18m/nextjs-darkmode-lite.svg)](https://www.npmjs.com/package/nextjs-darkmode-lite)

```bash
$ pnpm add nextjs-darkmode-lite
```

### Usage
**_or_**

Using loaders is straightforward.
```bash
$ npm install nextjs-darkmode-lite
```

```tsx
import { Bars1 } from "nextjs-darkmode/dist/server/bars/bars1";
**_or_**

export default function MyComponent() {
return someCondition ? <Bars1 /> : <>Something else...</>;
```bash
$ yarn add nextjs-darkmode-lite
```

> You need `r18gs` as a peer-dependency.
## Usage

> Please explore `examples` and `packages/shared-ui` for more working examples. (updates coming soon...)
### SPA (e.g., Vite, CRA) and Next.js pages directory (No server components)

Modify `_app` to add dark mode support:

```js
import { Core } from "nextjs-darkmode"; // for better tree-shaking
import { Switch } from "nextjs-darkmode/switch";

function MyApp({ Component, pageProps }) {
return (
<>
<Core />
<header>
<Switch />
</header>
<Component {...pageProps} />
</>
);
}

export default MyApp;
```

For detailed API and options, refer to [the API documentation](https://react18-tools.github.io/nextjs-darkmode).
⚡🎉Boom! Just a couple of lines and your dark mode is ready, complete with a color switch for user preferences. Check out examples for advanced usage.

> For `vite` or any other build tool, find a similar root component, e.g., `<App />` in `CRA` and `vite`.
**Using LoaderContainer**
### With Next.js `app` router (Server Components)

`LoaderContainer` is a fullscreen component. You can add this component directly in your layout and then use `useLoader` hook to toggle its visibility.
Update `app/layout.jsx` to add `Core` and `ServerTarget` to avoid flash of un-themed content:

```tsx
// layout.tsx
<LoaderContainer />
...
// app/layout.jsx
import { Core } from "nextjs-darkmode"; // for better tree-shaking
import { ServerTarget } from "nextjs-darkmode/server";

export default function Layout({ children }) {
return (
<html lang="en">
<head />
<body>
<ServerTarget />
<Core />
{children}
</body>
</html>
);
}
```

### Switch

An elegant color switch to toggle color schemes:

```tsx
// some other page or component
import { useLoader } from "nextjs-darkmode/dist/hooks";

export default MyComponent() {
const { setLoading } = useLoader();
useCallback(()=>{
setLoading(true);
...do some work
setLoading(false);
}, [])
...
<Switch />
```

### HTML & CSS

Fully support dark mode, including system preference with `prefers-color-scheme`. The dark/light mode is synced between tabs and modifies the `className` and data-attributes on the `html` or ServerTarget element:

````css
:root {
--background: white;
--foreground: black;
}

.dark {
--background: black;
--foreground: white;
}

/* or */

[data-rm="dark"] {...}


When using `ServerTarget`, use the CSS general sibling combinator (~):

```css
.selector,
.selector *,
.selector ~ *,
.selector ~ * * {
--th-variable: value;
}
```

## License
#### data attributes

`data-rm` -> Resolved Mode
`data-m` -> User's preference
`data-sm` -> System preference

### Images

Show different images based on the current theme:

This library is licensed under the MPL-2.0 open-source license.
```jsx
import Image from "next/image";
import { useMode } from "nextjs-darkmode/hooks";

function ThemedImage() {
const { resolvedMode } = useMode();
let src;

switch (resolvedMode) {
case "light":
src = "/light-mode-image.png";
break;
case "dark":
src = "/dark-mode-image.png";
break;
default:
src = "/default-image.png";
break;
}

return <Image src={src} alt="Themed Image" />;
}
```

### useMode

The `useMode` hook provides mode information:

```js
import { useMode } from "nextjs-darkmode";

const ThemeChanger = () => {
const { resolvedMode, setMode } = useMode();

return (
<div>
The current resolved mode is: {resolvedMode}
<button onClick={() => setMode("light")}>Light Mode</button>
<button onClick={() => setMode("dark")}>Dark Mode</button>
</div>
);
};
```

`useMode` hook returns the following object:

```ts
export interface UseModeInterface {
mode: ColorSchemePreference;
systemMode: ResolvedScheme;
resolvedMode: ResolvedScheme;
setMode: (mode: ColorSchemePreference) => void;
}
```

### Force per page mode

Apply appropriate class names and data attributes to force a mode for the page:

```tsx
export default function Page() {
return <div className="dark ndm-scoped data-rm='dark'">...</div>;
}
```

### With Styled Components and any CSS-in-JS

Next Themes works with any library. For example, with Styled Components:

```js
// pages/_app.js
import { createGlobalStyle } from "styled-components";
import { Core } from "nextjs-darkmode";

// Your theming variables
const GlobalStyle = createGlobalStyle`
:root {
--fg: #000;
--bg: #fff;
}

[data-rm="dark"] {
--fg: #fff;
--bg: #000;
}
`;

function MyApp({ Component, pageProps }) {
return (
<>
<GlobalStyle />
<Core />
<Component {...pageProps} />
</>
);
}
```

### With Tailwind

In `tailwind.config.js`, set the dark mode property to class:

```js
// tailwind.config.js
module.exports = {
darkMode: "class",
};
```

Now you can use dark-mode specific classes:

```tsx
<h1 className="text-black dark:text-white">
```

## Performance

`nextjs-darkmode` is designed to be fully tree-shakable, including only the code you use. For instance, if you only use the `useMode` hook, the rest of the library's code will be removed during the build process.

## Contributing

We welcome contributions! Check out the [Contributing Guide](https://github.com/react18-tools/nextjs-darkmode/blob/main/CONTRIBUTING.md) for more details.

### 🤩 Don't forget to star [this repo](https://github.com/react18-tools/nextjs-darkmode)!

Explore hands-on courses to get started with Turborepo:

- [React and Next.js with TypeScript](https://mayank-chaudhari.vercel.app/courses/react-and-next-js-with-typescript)
- [The Game of Chess with Next.js, React, and TypeScript](https://www.udemy.com/course/game-of-chess-with-nextjs-react-and-typescrypt/?referralCode=851A28F10B254A8523FE)

![Repo Stats](https://repobeats.axiom.co/api/embed/85eec5cd9a0ede65ac366f834ada1a170ef775c8.svg "Repobeats analytics image")

## License

[MPL-2.0](https://github.com/react18-tools/nextjs-darkmode/blob/main/LICENSE)

Feel free to use, modify, and distribute this library under the MPL-2.0 license.

> <img src="https://github.com/react18-tools/nextjs-darkmode/blob/main/popper.png?raw=true" style="height: 20px"/> Please consider enrolling in [our courses](https://mayank-chaudhari.vercel.app/courses) or [sponsoring](https://github.com/sponsors/mayank1513) our work.
Please consider enrolling in [our courses](https://mayank-chaudhari.vercel.app/courses) or [sponsoring](https://github.com/sponsors/mayank1513) our work.

<hr />

<p align="center" style="text-align:center">with 💖 by <a href="https://mayank-chaudhari.vercel.app" target="_blank">Mayank Kumar Chaudhari</a></p>
````

0 comments on commit 01532c7

Please sign in to comment.