From 0bd346bc6d38a6186c4b6ad8a3d528455231e9b4 Mon Sep 17 00:00:00 2001 From: Mayank Date: Fri, 23 Feb 2024 09:13:33 +0000 Subject: [PATCH 1/4] update README --- README.md | 365 +++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 305 insertions(+), 60 deletions(-) diff --git a/README.md b/README.md index f726d774..ddfe1a8f 100644 --- a/README.md +++ b/README.md @@ -1,53 +1,61 @@ # Nextjs-Themes-Ultralight -[![test](https://github.com/react18-tools/nthul/actions/workflows/test.yml/badge.svg)](https://github.com/react18-tools/nthul/actions/workflows/test.yml) [![Maintainability](https://api.codeclimate.com/v1/badges/aa896ec14c570f3bb274/maintainability)](https://codeclimate.com/github/react18-tools/nthul/maintainability) [![codecov](https://codecov.io/gh/react18-tools/nthul/graph/badge.svg)](https://codecov.io/gh/react18-tools/nthul) [![Version](https://img.shields.io/npm/v/nthul.svg?colorB=green)](https://www.npmjs.com/package/nthul) [![Downloads](https://img.jsdelivr.com/img.shields.io/npm/dt/nthul.svg)](https://www.npmjs.com/package/nthul) ![npm bundle size](https://img.shields.io/bundlephobia/minzip/nthul) [![Gitpod ready-to-code](https://img.shields.io/badge/Gitpod-ready--to--code-blue?logo=gitpod)](https://gitpod.io/from-referrer/) +[![test](https://github.com/react18-tools/nextjs-themes-ultralight/actions/workflows/test.yml/badge.svg)](https://github.com/react18-tools/nthul/actions/workflows/test.yml) [![Maintainability](https://api.codeclimate.com/v1/badges/85f6447e649201924a2c/maintainability)](https://codeclimate.com/github/react18-tools/nextjs-themes-ultralight/maintainability) [![codecov](https://codecov.io/gh/react18-tools/nextjs-themes-ultralight/graph/badge.svg)](https://codecov.io/gh/react18-tools/nextjs-themes-ultralight) [![Version](https://img.shields.io/npm/v/nthul.svg?colorB=green)](https://www.npmjs.com/package/nthul) [![Downloads](https://img.jsdelivr.com/img.shields.io/npm/dt/nthul.svg)](https://www.npmjs.com/package/nthul) ![npm bundle size](https://img.shields.io/bundlephobia/minzip/nthul) [![Gitpod ready-to-code](https://img.shields.io/badge/Gitpod-ready--to--code-blue?logo=gitpod)](https://gitpod.io/from-referrer/) -## Features +🤟 👉 [Unleash the Power of React Server Components](https://medium.com/javascript-in-plain-english/unleash-the-power-of-react-server-components-eb3fe7201231) -This template offers following pre-configured features. Additionally, your repo will automatically be rebranded with help of workflow and post install scripts. +> A canonical package with a longer and more descriptive name is also published - `nextjs-themes-ultralight` -✅ Monorepo powered by turbo repo to build, test and deploy your library +## Motivation -✅ Next.js, Vite and Remix examples to demonstrate how your library can be used (Feel free to remove Remix as it is still unstable when it comes to monorepo setup and importing from folders) +I created `nextjs-themes` library to achieve functionality like `next-themes` with React Server Components. It worked well, however, I noticed issues with tree-shaking and also found that some functions that are rarely used can be removed or replaced to improve overall performance and readability. -✅ Examples pre-configured to use Light/Dark theme according to user preference +I will update the main library [`nextjs-themes`](https://github.com/react18-tools/nextjs-themes). However, it requires ensuring minimal changes to the existing APIs. And thus I created a new library, which has the potential to be a better alternative in most cases. -✅ The examples provided are ready to be deployed to Vercel +## Features -✅ Typedoc setup to automatically create documentation for your library based on tsdoc comments +✅ Perfect dark mode in 2 lines of code -✅ Code of Conduct and contributing files that you can always update +✅ Works with Tailwind CSS -✅ Prettier and linter configured as per the modern best practices (Feel free to add your flavour) +✅ Fully Treeshakable (`import from nthul/client/theme-switcher`) -✅ Recommended VSCode extensions - Prettier and [Kanban board](https://github.com/mayank1513/vscode-extension-trello-kanban-board) to auto-format your code and manage your project priorities right within your IDE +✅ Designed for excellence -✅ Powerful code generators - try yarn turbo gen +✅ Full TypeScript Support -✅ Test setup with Vitest - A modern and fast testing framework supporting Jest like APIs +✅ Unleash the full power of React18 Server components -✅ Workflows to automate running tests on every pull-request or code push events +✅ System setting with prefers-color-scheme -✅ Workflow to automatically publish and create a GitHub release when you update your librari's `package.json` file. +✅ Themed browser UI with color-scheme -✅ Workflow to automatically rebrand entire template based on the name of the repo you create from this template. (As soon as you create a repo from this template, setup workflow is triggered which renames nthul to your repo name and does lots of other fixes to set you up and running.) +✅ Support for Next.js 13 & Next.js 14 `appDir` -✅ With all these features, this readme file contains a quick checklist for you to configure Codecov and other badges, setup your docs website on GitHub pages, etc. See [Checklist](https://github.com/react18-tools/nthul/#checklist). +✅ No flash on load (for all - SSG, SSR, ISG, Server Components) -#### Create a library that is +✅ Sync theme across tabs and windows - can opt-out by passing dontSync to ThemeSwitcher -✅ Fully Treeshakable (import from nthul/client/component) +✅ Apply custom transition when changing themes -✅ Full TypeScript Support +✅ Force pages to specific themes - requires assigning className (detailed techniques comming soon...) -✅ Unleash the full power of React18 Server components +✅ Manipulate theme via `useTheme` hook + +✅ Documented with [Typedoc](https://react18-tools.github.io/nextjs-themes-ultralight) ([Docs](https://react18-tools.github.io/nextjs-themes-ultralight)) + +✅ Use combinations of `th-` and `dark` or `light` classes for dark/light variants of themes + +✅ Automatically avoids storing cookies when not using the corresponding `ServerTarget` ✅ Works with all build systems/tools/frameworks for React18 -✅ Doccumented with [Typedoc](https://react18-tools.github.io/nthul) ([Docs](https://react18-tools.github.io/nthul)) +> Feel free to [request](https://github.com/react18-tools/nextjs-themes-ultralight/issues/new?assignees=&labels=&projects=&template=feature_request.md&title=) or [discuss](https://github.com/react18-tools/nextjs-themes-ultralight/discussions) new features or [report bugs](https://github.com/react18-tools/nextjs-themes-ultralight/issues/new?assignees=&labels=&projects=&template=bug_report.md&title=). ## Install +> A canonical package with a longer and more descriptive name is also published - `nextjs-themes-ultralight` + ```bash $ pnpm add nthul ``` @@ -64,32 +72,280 @@ or $ yarn add nthul ``` -## Step by Step Instructions and Checklist - -- [ ] Install dependencies using `pnpm` - - [ ] Run `turbo gen react-component`, and follow prompts to generate server or client components for your library - - [ ] Use `snake-case` for your component name - it will be automatically converted to `PascalCase` - - [ ] Your component and test files will be created in `**/src/client/` or `**/src/server/` directory depending on whether you choose `client` or `server` component -- [ ] Set up `CodeCov` - - [ ] Visit codecov and setup your repo - - [ ] Create repository secrets for `CODECOV_TOKEN` -- [ ] Set up `CodeClimate` - - [ ] Visit CodeClimate and setup your repo - - [ ] Create repository secrets for `CC_TEST_REPORTER_ID` - - [ ] add `*.test.*` to ignore patterns on the website - - [ ] update code climate badge -- [ ] Add `NPM_AUTH_TOKEN` to repository secrets to automate publishing package - - [ ] login to your `npm` account and create automation token - - [ ] Create a new repository secrets `NPM_AUTH_TOKEN` -- [ ] Update description in `lib/nthul/package.json` -- [ ] Update Repo Stats by visiting and setting up [repobeats](https://repobeats.axiom.co/) -- [ ] Create your library and update examples -- [ ] Update README -- [ ] Setup GitHub pages to deploy docs - - [ ] Go to [repo settings](https://github.com/react18-tools/nthul/settings/pages) -> pages (On left panel); Select deploy from a branch; Then Select `main` and `/docs` -- [ ] Push your changes/Create PR and see your library being automatically tested and published -- [ ] Optionally deploy your example(s) to Vercel. -- [ ] You are most welcome to star this template, contribute, and/or sponsor the `terbo-repo-template` project or my other open-source work +## Usage + +> Please explore `examples` and `packages/shared-ui` for working examples. (updates coming soon...) + +### SPA (e.g., Vite, CRA) and Next.js pages directory (No server components) + +The best way is to add a [Custom `App`](https://nextjs.org/docs/advanced-features/custom-app) to use by modifying `_app` as follows: + +Adding dark mode support takes 2 lines of code: + +```js +import { ThemeSwitcher, ColorSwitch } from "nthul/client"; // for better tree-shaking + +function MyApp({ Component, pageProps }) { + return ( + <> + + {/* to add a switch */} +
+ +
+ + + ); +} + +export default MyApp; +``` + +⚡🎉Boom! Just a couple of lines and your dark mode is ready! That too with an awesome color switch for user preferred settings. + +Check out examples for advanced usage. + +> For `vite` or any other build tool you can find a similar root component. E.g., component in `CRA` and `vite`. + +### With Next.js `app` router (Server Components) + +> If your app is mostly serving static content, you do not want the overhead of SSR. +> +> When using this approach, you need to use CSS general sibling Combinator (~) to make sure your themed CSS is properly applied. See (HTML & CSS)[#html--css]. + +Update your `app/layout.jsx` to add `ThemeSwitcher`, and `ServerTarget`. `ServerTarget` is required to avoid a flash of un-themed content on reload. + +```tsx +// app/layout.jsx +import { ThemeSwitcher } from "nthul/client/theme-switcher"; // for better tree-shaking +import { ServerTarget } from "nthul/server/nextjs"; + +export default function Layout({ children }) { + return ( + + + + /** use ServerTarget as first element inside body */ + + + {children} + + + ); +} +``` + +⚡🎉 Woohoo! You just added multiple theme and color-scheme modes and you can also use Server Component! Isn't that awesome? + +### HTML & CSS + +That's it, your Next.js app fully supports dark mode, including System preference with `prefers-color-scheme`. The theme is also immediately synced between tabs. By default, `nextjs-themes-ultralight` modifies the className on the `html` element, which you can easily use to style your app: + +```css +:root { + /* Your default theme */ + --background: white; + --foreground: black; +} + +.dark { + --background: black; + --foreground: white; +} + +// for custom themes + +.th-theme1 { + --background: red; + --foreground: yellow; +} + +// for custom theme with dark and light variants + +.dark.th-theme2 { + --background: blue; + --foreground: white; +} + +.light.th-theme2 { + --background: white; + --foreground: blue; +} +``` + +#### When using `ServerTarget` + +when using `ServerTarget`, you need to use CSS general sibling Combinator (~) as `ServerTarget` is not wrapping your app. + +> Replace `.selector` with a combination of selectors from the description above. + +```css +/* +for the target element itself, e.g., the html tag. +in most cases, this is inherited by all child elements. +*/ +.selector, + +/* for forcing to the child elements. */ +.selector *, + +/* when using ServerTarget */ + +.selector ~ *, // for all following siblings + +.selector ~ * * // for all the children of the following siblings +{ + // ...your styles +} + +``` + +Please note that we have not added a comma (',') after the last selector. + +Without comments, it should look like following. + +```css +.selector, +.selector *, +.selector ~ *, +.selector ~ * * { + --th-variable: value; +} +``` + +We encourage you to use this pattern for defining your theme variables in CSS to avoid any unwanted overrides. + +## Images + +You can also show different images based on the current theme. + +```jsx +import Image from "next/image"; +import { useTheme } from "nthul/hooks"; + +function ThemedImage() { + const { theme, resolvedColorScheme } = useTheme(); + let src; + + switch (resolvedTheme) { + case "light": + src = "/light.png"; + break; + case "dark": + src = "/dark.png"; + break; + default: + src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"; + break; + } + + return ; +} + +export default ThemedImage; +``` + +### useTheme + +In case your components need to know the current theme and be able to change it. The `useTheme` hook provides theme information: + +```js +import { useTheme } from "nthul"; + +const ThemeChanger = () => { + const { theme, setTheme } = useTheme(); + + return ( +
+ The current theme is: {theme} + + +
+ ); +}; +``` + +`useTheme` hook will return following object. + +```ts +interface UseTheme { + theme: string; + colorSchemePreference: "dark" | "light" | "system"; + systemColorScheme: "dark" | "light"; + resolvedColorScheme: "dark" | "light"; + setColorSchemePreference: (colorSchemePreference: ColorSchemePreference) => void; + setTheme: (theme: string) => void; +} +``` + +## Force per page theme and color-scheme + +We have not added any components or hooks for forcing `theme` and `color-scheme` per page or per element basis. As this is a rarely used scenario. However, you can acheive this by applying appropreate calssNames. + +```tsx +// force a theme for the page +export default function Page() { + return
...
; +} +``` + +> We are open to listening your feedback - [Discussions](https://github.com/react18-tools/nextjs-themes-ultralight/discussions) + +### With Styled Components and any CSS-in-JS + +Next Themes is completely CSS independent, it will work with any library. For example, with Styled Components you just need to `createGlobalStyle` in your custom App: + +```js +// pages/_app.js +import { createGlobalStyle } from "styled-components"; +import { ThemeSwitcher } from "nthul"; + +// Your themeing variables +const GlobalStyle = createGlobalStyle` + :root { + --fg: #000; + --bg: #fff; + } + + [data-theme="dark"] { + --fg: #fff; + --bg: #000; + } +`; + +function MyApp({ Component, pageProps }) { + return ( + <> + + + + + ); +} +``` + +### With Tailwind + +In your `tailwind.config.js`, set the dark mode property to class: + +```js +// tailwind.config.js +module.exports = { + darkMode: "class", +}; +``` + +⚡🎉Boom! You are ready to use darkTheme in tailwind. + +> Caution! Your class must be set to `"dark"`, which is the default value we have used for this library. Tailwind, as of now, requires that class name must be `"dark"` for dark-theme. + +That's it! Now you can use dark-mode specific classes: + +```tsx +

+``` + +# Contributing ## What's inside? @@ -133,22 +389,11 @@ cd nthul pnpm dev ``` -## Useful Links - -Learn more about the power of Turborepo: - -- [Tasks](https://turbo.build/repo/docs/core-concepts/monorepos/running-tasks) -- [Caching](https://turbo.build/repo/docs/core-concepts/caching) -- [Remote Caching](https://turbo.build/repo/docs/core-concepts/remote-caching) -- [Filtering](https://turbo.build/repo/docs/core-concepts/monorepos/filtering) -- [Configuration Options](https://turbo.build/repo/docs/reference/configuration) -- [CLI Usage](https://turbo.build/repo/docs/reference/command-line-reference) - ### 🤩 Don't forger to start [this repo](https://github.com/react18-tools/nthul)! Want hands-on course for getting started with Turborepo? Check out [React and Next.js with TypeScript](https://mayank-chaudhari.vercel.app/courses/react-and-next-js-with-typescript) and [The Game of Chess with Next.js, React and TypeScrypt](https://www.udemy.com/course/game-of-chess-with-nextjs-react-and-typescrypt/?referralCode=851A28F10B254A8523FE) -![Repo Stats](https://repobeats.axiom.co/api/embed/2ef1a24385037998386148afe5a98ded6006f410.svg "Repobeats analytics image") +![Repo Stats](https://repobeats.axiom.co/api/embed/85eec5cd9a0ede65ac366f834ada1a170ef775c8.svg "Repobeats analytics image") ## License From ef63b4e8bd0dd355dd82f740078194c33ba83658 Mon Sep 17 00:00:00 2001 From: Mayank Date: Fri, 23 Feb 2024 09:15:00 +0000 Subject: [PATCH 2/4] fix package.json --- lib/nthul/package.json | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/lib/nthul/package.json b/lib/nthul/package.json index ca88ed67..21fbdc94 100644 --- a/lib/nthul/package.json +++ b/lib/nthul/package.json @@ -3,17 +3,17 @@ "author": "Mayank Kumar Chaudhari ", "private": false, "version": "0.0.0", - "description": "An intuitive React.js fork me ribbon component for promoting open source project forks.", + "description": "Unleash the Power of React Server Components! Use multiple themes on your site with confidence, without losing any advantages of React Server Components.", "main": "./index.ts", "types": "./index.ts", "repository": { "type": "git", - "url": "git+https://github.com/react18-tools/nthul.git" + "url": "git+https://github.com/react18-tools/nextjs-themes-ultralight.git" }, "bugs": { - "url": "https://github.com/react18-tools/nthul/issues" + "url": "https://github.com/react18-tools/nextjs-themes-ultralight/issues" }, - "homepage": "https://github.com/react18-tools/nthul/tree/main/lib/fork-me#readme", + "homepage": "https://github.com/react18-tools/nextjs-themes-ultralight/tree/main/lib/fork-me#readme", "sideEffects": false, "license": "MIT", "scripts": { @@ -59,14 +59,27 @@ "url": "https://github.com/sponsors/mayank1513" }, "keywords": [ - "fork-me", - "GitHub", "nextjs", "nextjs13", + "nextjs14", + "nextjs-themes", + "nextjs-themes-ultralight", + "nextjs13-themes", + "nextjs14-themes", + "tailwind", + "tailwindcss", + "tailwindcss-support", "react", "react18", + "react18-tools", + "react-themes", + "react18-themes", "react-server-components", "react-client-components", + "themes", + "dark-mode", + "dark-theme", + "dark-themes", "typescript", "javascript", "mayank1513", From a70c4a38109e1e487b3ba2dde573d1bf0740b9ed Mon Sep 17 00:00:00 2001 From: Mayank Date: Fri, 23 Feb 2024 09:15:52 +0000 Subject: [PATCH 3/4] update packages --- .tkb | 4 ++-- examples/nextjs/package.json | 4 ++-- examples/vite/package.json | 2 +- lib/nthul/package.json | 6 +++--- packages/shared-ui/package.json | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.tkb b/.tkb index 6ef0e895..e2b3fbd7 100644 --- a/.tkb +++ b/.tkb @@ -14,7 +14,7 @@ "RtA7NBfPOlfnVHqk54rMD": { "id": "RtA7NBfPOlfnVHqk54rMD", "description": "update readme", - "columnId": "column-todo" + "columnId": "column-done" }, "fqhes_YS14GQopOUs7K-7": { "id": "fqhes_YS14GQopOUs7K-7", @@ -37,7 +37,6 @@ "id": "column-todo", "title": "To do", "tasksIds": [ - "RtA7NBfPOlfnVHqk54rMD", "-FlzW8htLo-6jz5-ZqjEx", "5fLtFF1sHPxsPjq-wWOxv" ] @@ -51,6 +50,7 @@ "id": "column-done", "title": "Done", "tasksIds": [ + "RtA7NBfPOlfnVHqk54rMD", "fqhes_YS14GQopOUs7K-7", "task-ZJpp-dpxx3KxRMsAPNuMC", "4CTOhRPjKrEAW5AHYsV7P" diff --git a/examples/nextjs/package.json b/examples/nextjs/package.json index d88e4e16..e36cb247 100644 --- a/examples/nextjs/package.json +++ b/examples/nextjs/package.json @@ -19,8 +19,8 @@ }, "devDependencies": { "@next/eslint-plugin-next": "^14.1.0", - "@types/node": "^20.11.19", - "@types/react": "^18.2.57", + "@types/node": "^20.11.20", + "@types/react": "^18.2.58", "@types/react-dom": "^18.2.19", "eslint-config-custom": "workspace:*", "tsconfig": "workspace:*", diff --git a/examples/vite/package.json b/examples/vite/package.json index 30e22e9c..255e43b9 100644 --- a/examples/vite/package.json +++ b/examples/vite/package.json @@ -17,7 +17,7 @@ "shared-ui": "workspace:*" }, "devDependencies": { - "@types/react": "^18.2.57", + "@types/react": "^18.2.58", "@types/react-dom": "^18.2.19", "@typescript-eslint/eslint-plugin": "^7.0.2", "@typescript-eslint/parser": "^7.0.2", diff --git a/lib/nthul/package.json b/lib/nthul/package.json index 21fbdc94..b19a2702 100644 --- a/lib/nthul/package.json +++ b/lib/nthul/package.json @@ -26,8 +26,8 @@ "devDependencies": { "@testing-library/react": "^14.2.1", "@turbo/gen": "^1.12.4", - "@types/node": "^20.11.19", - "@types/react": "^18.2.57", + "@types/node": "^20.11.20", + "@types/react": "^18.2.58", "@types/react-dom": "^18.2.19", "@vitejs/plugin-react": "^4.2.1", "@vitest/coverage-v8": "^1.3.1", @@ -86,6 +86,6 @@ "turborepo-trmplate" ], "dependencies": { - "r18gs": "^0.0.2" + "r18gs": "^0.0.3" } } diff --git a/packages/shared-ui/package.json b/packages/shared-ui/package.json index 37db0d7b..5e234888 100644 --- a/packages/shared-ui/package.json +++ b/packages/shared-ui/package.json @@ -11,8 +11,8 @@ }, "devDependencies": { "@mayank1513/fork-me": "^2.0.1", - "@types/node": "^20.11.19", - "@types/react": "^18.2.57", + "@types/node": "^20.11.20", + "@types/react": "^18.2.58", "@types/react-dom": "^18.2.19", "eslint-config-custom": "workspace:*", "next": "^14.1.0", From e583d8ea9a04da20f867584fc75fee0ce954e782 Mon Sep 17 00:00:00 2001 From: Mayank Date: Fri, 23 Feb 2024 09:19:53 +0000 Subject: [PATCH 4/4] update publish workflow --- .github/workflows/publish.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 299e4344..1353244d 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -8,9 +8,7 @@ on: jobs: publish: - # Don't run just after creating repo from template - # Also avoid running after merging set-up PR - if: github.run_number > 2 && github.event.repository.owner.login == 'react18-tools' + if: github.event.repository.owner.login == 'react18-tools' runs-on: ubuntu-latest permissions: packages: write