From 7f1c984ac9bc856035d1b3764915b803c2f9fdff Mon Sep 17 00:00:00 2001 From: Mayank Date: Fri, 23 Feb 2024 16:28:20 +0000 Subject: [PATCH 01/11] fix lite and scope --- README.md | 2 +- lib/nthul/lite.js | 2 +- lib/nthul/scope.js | 7 ++++--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 069b76ef..2b9f52d8 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Nextjs-Themes-Ultralight -[![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/) +[![test](https://github.com/react18-tools/nextjs-themes-ultralight/actions/workflows/test.yml/badge.svg)](https://github.com/react18-tools/nextjs-themes-ultralight/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/) 🤟 👉 [Unleash the Power of React Server Components](https://medium.com/javascript-in-plain-english/unleash-the-power-of-react-server-components-eb3fe7201231) diff --git a/lib/nthul/lite.js b/lib/nthul/lite.js index 07ce6b5c..1850b551 100644 --- a/lib/nthul/lite.js +++ b/lib/nthul/lite.js @@ -18,5 +18,5 @@ const owner = process.env.OWNER; readMe = readMe.replace(new RegExp(`$${owner}/${ref}`, "g"), tmp); readMe = readMe.replace(new RegExp(ref, "g"), packageJson.name); readMe = readMe.replace(new RegExp(tmp, "g"), `$${owner}/${ref}`); -readMe = readMe.replace(/## Want Lite Version.*> You need r18gs as a peer-dependency/m, ""); +readMe = readMe.replace(/## Want Lite Version(.|\n|\r)*You need r18gs as a peer-dependency/m, ""); fs.writeFileSync(readMePath, readMe); diff --git a/lib/nthul/scope.js b/lib/nthul/scope.js index e66622b6..2cc693eb 100644 --- a/lib/nthul/scope.js +++ b/lib/nthul/scope.js @@ -5,12 +5,13 @@ const fs = require("node:fs"); const path = require("node:path"); const owner = "mayank1513"; -const packageJson = require(path.resolve(process.cwd(), "package.json")); +const pkgPath = path.resolve(__dirname, "dist", "package.json"); +const packageJson = require(pkgPath); const ref = packageJson.name; if (!ref.startsWith(`@${owner}`)) { packageJson.name = `@${owner}/${packageJson.name}`; - fs.writeFileSync(path.resolve(process.cwd(), "package.json"), JSON.stringify(packageJson, null, 2)); - const readMePath = path.resolve(process.cwd(), "README.md"); + fs.writeFileSync(pkgPath, JSON.stringify(packageJson, null, 2)); + const readMePath = path.resolve(__dirname, "dist", "README.md"); let readMe = fs.readFileSync(readMePath, { encoding: "utf8" }); const tmp = "!--|--!"; readMe = readMe.replace(new RegExp(`$${owner}/${ref}`, "g"), tmp); From 9017f3b43ce2f193331703a2dc241cd2fb2c17d7 Mon Sep 17 00:00:00 2001 From: Mayank Date: Fri, 23 Feb 2024 18:16:29 +0000 Subject: [PATCH 02/11] support CSS modules --- .tkb | 19 ++++++--- .../client/theme-switcher/theme-switcher.tsx | 41 +++++++++++++------ 2 files changed, 42 insertions(+), 18 deletions(-) diff --git a/.tkb b/.tkb index e2b3fbd7..cd814f18 100644 --- a/.tkb +++ b/.tkb @@ -24,11 +24,16 @@ "-FlzW8htLo-6jz5-ZqjEx": { "id": "-FlzW8htLo-6jz5-ZqjEx", "description": "update examples to showcase edge cases", + "columnId": "column-doing" + }, + "p1R-Q4atxMo-29mSa7mb6": { + "id": "p1R-Q4atxMo-29mSa7mb6", + "description": "Remove scoped packages from turborepo-template", "columnId": "column-todo" }, - "5fLtFF1sHPxsPjq-wWOxv": { - "id": "5fLtFF1sHPxsPjq-wWOxv", - "description": "Fix turbo-repo template bug - replacing only first doc link in readme --- look at the [doc] with [TypeDoc]", + "a7ksr41sN7kQNaH8Io-dV": { + "id": "a7ksr41sN7kQNaH8Io-dV", + "description": "Add support for css modules", "columnId": "column-todo" } }, @@ -37,14 +42,16 @@ "id": "column-todo", "title": "To do", "tasksIds": [ - "-FlzW8htLo-6jz5-ZqjEx", - "5fLtFF1sHPxsPjq-wWOxv" + "p1R-Q4atxMo-29mSa7mb6", + "a7ksr41sN7kQNaH8Io-dV" ] }, { "id": "column-doing", "title": "Doing", - "tasksIds": [] + "tasksIds": [ + "-FlzW8htLo-6jz5-ZqjEx" + ] }, { "id": "column-done", diff --git a/lib/nthul/src/client/theme-switcher/theme-switcher.tsx b/lib/nthul/src/client/theme-switcher/theme-switcher.tsx index 53bd64f6..dd9983e8 100644 --- a/lib/nthul/src/client/theme-switcher/theme-switcher.tsx +++ b/lib/nthul/src/client/theme-switcher/theme-switcher.tsx @@ -11,6 +11,8 @@ export interface ThemeSwitcherProps { dontSync?: boolean; /** force apply CSS transition property to all the elements during theme switching. E.g., `all .3s` */ themeTransition?: string; + /** provide styles object if you are using CSS/SCSS modules. */ + styles?: Record; } function useMediaQuery(setThemeState: SetStateAction) { @@ -77,13 +79,36 @@ function modifyTransition(themeTransition = "none", targetId?: string) { }; } +export interface ApplyClassesProps { + targets: (HTMLElement | null)[]; + theme: string; + resolvedColorScheme: "light" | "dark"; + styles?: Record; +} + +function applyClasses({ targets, theme, resolvedColorScheme, styles }: ApplyClassesProps) { + let cls = ["dark", "light", theme, resolvedColorScheme]; + if (styles) cls = cls.map(c => styles[c]); + + targets.forEach(t => { + t?.classList.remove(cls[0]); // dark + t?.classList.remove(cls[1]); // light + t?.classList.forEach(cls => { + if (cls.match(/(^|_)th-/)) t.classList.remove(cls); + }); + t?.classList.add(`th-${cls[2]}`); // theme + t?.classList.add(cls[3]); // resolvedColorScheme + }); +} + export interface UpdateDOMProps { targetId?: string; themeState: ThemeState; dontSync?: boolean; + styles?: Record; } -function updateDOM({ targetId, themeState, dontSync }: UpdateDOMProps) { +function updateDOM({ targetId, themeState, dontSync, styles }: UpdateDOMProps) { const { theme, colorSchemePreference: csp, systemColorScheme: scs } = themeState; const resolvedColorScheme = csp === "system" ? scs : csp; const key = targetId ?? DEFAULT_ID; @@ -95,15 +120,7 @@ function updateDOM({ targetId, themeState, dontSync }: UpdateDOMProps) { /** do not update documentElement for local targets */ const targets = targetId ? [target] : [target, document.documentElement]; - targets.forEach(t => { - t?.classList.remove("dark"); - t?.classList.remove("light"); - t?.classList.forEach(cls => { - if (cls.startsWith("th-")) t.classList.remove(cls); - }); - t?.classList.add(`th-${theme}`); - t?.classList.add(resolvedColorScheme); - }); + applyClasses({ targets, styles, resolvedColorScheme, theme }); if (shoulCreateCookie) document.cookie = `${key}=${theme},${resolvedColorScheme}; max-age=31536000; SameSite=Strict;`; } @@ -112,7 +129,7 @@ function updateDOM({ targetId, themeState, dontSync }: UpdateDOMProps) { * The core ThemeSwitcher component wich applies classes and transitions. * Cookies are set only if corresponding ServerTarget is detected. */ -export function ThemeSwitcher({ targetId, dontSync, themeTransition }: ThemeSwitcherProps) { +export function ThemeSwitcher({ targetId, dontSync, themeTransition, styles }: ThemeSwitcherProps) { if (targetId === "") throw new Error("id can not be an empty string"); const [themeState, setThemeState] = useRGS(targetId ?? DEFAULT_ID, DEFAULT_THEME_STATE); @@ -123,7 +140,7 @@ export function ThemeSwitcher({ targetId, dontSync, themeTransition }: ThemeSwit /** update DOM and storage */ React.useEffect(() => { const restoreTransitions = modifyTransition(themeTransition, targetId); - updateDOM({ targetId, themeState, dontSync }); + updateDOM({ targetId, themeState, dontSync, styles }); if (!dontSync && tInit < Date.now() - 300) { // save to localStorage const { theme, colorSchemePreference } = themeState; From bb06c15f76b7b925195bfba39431e623fc226acc Mon Sep 17 00:00:00 2001 From: Mayank Date: Fri, 23 Feb 2024 18:17:50 +0000 Subject: [PATCH 03/11] changeset --- .changeset/silly-impalas-fry.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/silly-impalas-fry.md diff --git a/.changeset/silly-impalas-fry.md b/.changeset/silly-impalas-fry.md new file mode 100644 index 00000000..da2a3b94 --- /dev/null +++ b/.changeset/silly-impalas-fry.md @@ -0,0 +1,5 @@ +--- +"nthul": minor +--- + +Support CSS Modules for scoped theming. From 8b34c79112524f668cda9053e109ff96b6bc27df Mon Sep 17 00:00:00 2001 From: Mayank Date: Sat, 24 Feb 2024 06:14:06 +0000 Subject: [PATCH 04/11] tmp --- .tkb | 6 ++--- packages/shared-ui/src/lib-examples/index.tsx | 3 ++- .../src/lib-examples/lib-examples.module.css | 23 ++++++++++++++++ .../simple-color-switch/index.tsx | 15 ++++++++++- .../lib-examples/theme-switching/index.tsx | 27 +++++++++++++++++-- packages/shared-ui/src/root-layout.tsx | 2 ++ 6 files changed, 69 insertions(+), 7 deletions(-) create mode 100644 packages/shared-ui/src/lib-examples/lib-examples.module.css diff --git a/.tkb b/.tkb index cd814f18..cc7961a0 100644 --- a/.tkb +++ b/.tkb @@ -34,7 +34,7 @@ "a7ksr41sN7kQNaH8Io-dV": { "id": "a7ksr41sN7kQNaH8Io-dV", "description": "Add support for css modules", - "columnId": "column-todo" + "columnId": "column-done" } }, "columns": [ @@ -42,8 +42,7 @@ "id": "column-todo", "title": "To do", "tasksIds": [ - "p1R-Q4atxMo-29mSa7mb6", - "a7ksr41sN7kQNaH8Io-dV" + "p1R-Q4atxMo-29mSa7mb6" ] }, { @@ -57,6 +56,7 @@ "id": "column-done", "title": "Done", "tasksIds": [ + "a7ksr41sN7kQNaH8Io-dV", "RtA7NBfPOlfnVHqk54rMD", "fqhes_YS14GQopOUs7K-7", "task-ZJpp-dpxx3KxRMsAPNuMC", diff --git a/packages/shared-ui/src/lib-examples/index.tsx b/packages/shared-ui/src/lib-examples/index.tsx index 4607073f..9017a5bd 100644 --- a/packages/shared-ui/src/lib-examples/index.tsx +++ b/packages/shared-ui/src/lib-examples/index.tsx @@ -1,10 +1,11 @@ import { Logo } from "../common/logo"; import SimpleColorSwitch from "./simple-color-switch"; import ThemeSwitching from "./theme-switching"; +import styles from "./lib-examples.module.css"; export default function LibExamples() { return ( -
+

examples.

diff --git a/packages/shared-ui/src/lib-examples/lib-examples.module.css b/packages/shared-ui/src/lib-examples/lib-examples.module.css new file mode 100644 index 00000000..bf2715d7 --- /dev/null +++ b/packages/shared-ui/src/lib-examples/lib-examples.module.css @@ -0,0 +1,23 @@ +.lib-example-container { + display: flex; + align-items: center; + gap: 20px; + flex-wrap: wrap; +} + +.example { + min-width: 200px; + min-height: 200px; + flex-grow: 1; + border-radius: 20px; +} + +.example * { + background: var(--bg-color); +} + + +.lib-example-container h1 { + text-align: center; + width: 100%; +} diff --git a/packages/shared-ui/src/lib-examples/simple-color-switch/index.tsx b/packages/shared-ui/src/lib-examples/simple-color-switch/index.tsx index f10e36d1..730195d7 100644 --- a/packages/shared-ui/src/lib-examples/simple-color-switch/index.tsx +++ b/packages/shared-ui/src/lib-examples/simple-color-switch/index.tsx @@ -1,3 +1,16 @@ +import { ColorSwitch, ThemeSwitcher } from "nthul"; +import { ServerTarget } from "nthul/server"; +import styles from "../lib-examples.module.css"; + +const targetId = "simple-color-switch"; export default function SimpleColorSwitch() { - return
; + return ( +
+ + +
+ +
+
+ ); } diff --git a/packages/shared-ui/src/lib-examples/theme-switching/index.tsx b/packages/shared-ui/src/lib-examples/theme-switching/index.tsx index 9c236600..4e336e93 100644 --- a/packages/shared-ui/src/lib-examples/theme-switching/index.tsx +++ b/packages/shared-ui/src/lib-examples/theme-switching/index.tsx @@ -1,3 +1,26 @@ -export default function ThemeSwitching() { - return
; +import { ColorSwitch, ThemeSwitcher } from "nthul"; +import { ServerTarget } from "nthul/server"; +import styles from "../lib-examples.module.css"; + +const targetId = "theme-switching"; +const themes = ["theme1", "theme2"]; +export default function SimpleColorSwitch() { + return ( +
+ + +
+ +
+
+ +
+
+ ); } diff --git a/packages/shared-ui/src/root-layout.tsx b/packages/shared-ui/src/root-layout.tsx index fdfa7acf..7a72a412 100644 --- a/packages/shared-ui/src/root-layout.tsx +++ b/packages/shared-ui/src/root-layout.tsx @@ -8,6 +8,7 @@ import { Cards } from "./cards"; import { Description } from "./root/description"; import { Hero } from "./root/hero"; import { Footer } from "./root/footer"; +import LibExamples from "./lib-examples"; export type SharedRootLayoutProps = HTMLProps; @@ -19,6 +20,7 @@ export function SharedRootLayout({ children, className = "", ...props }: SharedR {children} +
From 6023a4751151d0e5d81c7f7bf9b4f6aa3b70ca79 Mon Sep 17 00:00:00 2001 From: Mayank Kumar Chaudhari Date: Sat, 24 Feb 2024 13:51:44 +0530 Subject: [PATCH 05/11] Add theme buttons --- packages/shared-ui/src/globals.css | 65 ++++++++++++++++--- .../src/lib-examples/lib-examples.module.css | 58 +++++++++++++++-- .../simple-color-switch/index.tsx | 1 + .../lib-examples/theme-switching/index.tsx | 15 +++-- .../theme-switching/theme-button.tsx | 19 ++++++ 5 files changed, 134 insertions(+), 24 deletions(-) create mode 100644 packages/shared-ui/src/lib-examples/theme-switching/theme-button.tsx diff --git a/packages/shared-ui/src/globals.css b/packages/shared-ui/src/globals.css index 3beee0d9..9f2a64ff 100644 --- a/packages/shared-ui/src/globals.css +++ b/packages/shared-ui/src/globals.css @@ -3,12 +3,29 @@ } :root { + /* colors */ + --bg-light: #fff; + --color-light: #000; + --bg-dark: #000; + --color-dark: #fff; + + --th1-bg-light: #aaf; + --th1-color-light: #00f; + --th1-bg-dark: #008; + --th1-color-dark: #aaf; + + --th2-bg-light: #faa; + --th2-color-light: #f00; + --th2-bg-dark: #800; + --th2-color-dark: #fbb; + + /* root style variables */ --max-width: 1100px; --border-radius: 12px; --font-mono: ui-monospace, Menlo, Monaco, "Cascadia Mono", "Segoe UI Mono", "Roboto Mono", "Oxygen Mono", "Ubuntu Monospace", "Source Code Pro", "Fira Mono", "Droid Sans Mono", "Courier New", monospace; - --bg-color: #fff; - --text-color: #000; + --bg-color: var(--bg-light); + --text-color: var(--color-light); --primary-glow: conic-gradient( from 180deg at 50% 50%, @@ -28,10 +45,12 @@ } /* dark themes */ -.dark, -.dark ~ * { - --bg-color: #000; - --text-color: #fff; +.th-.dark, +.th-.dark *, +.th-.dark ~ *, +.th-.dark ~ * * { + --bg-color: var(--bg-dark); + --text-color: var(--color-dark); } .dark, @@ -48,10 +67,36 @@ /* light themes */ -.light, -.light ~ * { - --bg-color: #fff; - --text-color: #000; +.th-.light, +.th-.light *, +.th-.light ~ *, +.th-.light ~ * * { + --bg-color: var(--bg-light); + --text-color: var(--color-light); +} + +.th-theme1.light ~ *, +.th-theme1.light ~ * * { + --bg-color: var(--th1-bg-light); + --text-color: var(--th1-color-light); +} + +.th-theme1.dark ~ *, +.th-theme1.dark ~ * * { + --bg-color: var(--th1-bg-dark); + --text-color: var(--th1-color-dark); +} + +.th-theme2.light ~ *, +.th-theme2.light ~ * * { + --bg-color: var(--th2-bg-light); + --text-color: var(--th2-color-light); +} + +.th-theme2.dark ~ *, +.th-theme2.dark ~ * * { + --bg-color: var(--th2-bg-dark); + --text-color: var(--th2-color-dark); } html { diff --git a/packages/shared-ui/src/lib-examples/lib-examples.module.css b/packages/shared-ui/src/lib-examples/lib-examples.module.css index bf2715d7..2b06575b 100644 --- a/packages/shared-ui/src/lib-examples/lib-examples.module.css +++ b/packages/shared-ui/src/lib-examples/lib-examples.module.css @@ -3,21 +3,65 @@ align-items: center; gap: 20px; flex-wrap: wrap; + justify-content: space-evenly; +} + +.lib-example-container h1 { + text-align: center; + width: 100%; } .example { - min-width: 200px; - min-height: 200px; - flex-grow: 1; - border-radius: 20px; + border-radius: 10px; + box-shadow: 0 0 10px gray; + overflow: hidden; + margin-bottom: 50px; + background: var(--bg-color); } .example * { background: var(--bg-color); } +.example header { + padding: 10px; + text-align: end; +} -.lib-example-container h1 { - text-align: center; - width: 100%; +.example main { + width: 300px; + height: 100px; + padding: 10px; +} + +.themes { + --bg1: var(--bg-dark); + --bg2: var(--bg-light); + list-style-type: none; + padding: 10px; + display: flex; + gap: 10px; + justify-content: space-evenly; + align-items: center; + flex-wrap: wrap; +} + +.themes button { + all: reset; + height: 30px; + width: 30px; + border-radius: 5px; + background: linear-gradient(-45deg, var(--bg1), var(--bg1) 45%, var(--bg2) 55%, var(--bg2)); + box-shadow: 0 0 10px gray; + cursor: pointer; +} + +.theme1 { + --bg1: var(--th1-bg-dark); + --bg2: var(--th1-bg-light); +} + +.theme2 { + --bg1: var(--th2-bg-dark); + --bg2: var(--th2-bg-light); } diff --git a/packages/shared-ui/src/lib-examples/simple-color-switch/index.tsx b/packages/shared-ui/src/lib-examples/simple-color-switch/index.tsx index 730195d7..9b4192d5 100644 --- a/packages/shared-ui/src/lib-examples/simple-color-switch/index.tsx +++ b/packages/shared-ui/src/lib-examples/simple-color-switch/index.tsx @@ -11,6 +11,7 @@ export default function SimpleColorSwitch() {
+
Simple dark/light scopped theme.
); } diff --git a/packages/shared-ui/src/lib-examples/theme-switching/index.tsx b/packages/shared-ui/src/lib-examples/theme-switching/index.tsx index 4e336e93..19c50d66 100644 --- a/packages/shared-ui/src/lib-examples/theme-switching/index.tsx +++ b/packages/shared-ui/src/lib-examples/theme-switching/index.tsx @@ -1,9 +1,11 @@ import { ColorSwitch, ThemeSwitcher } from "nthul"; import { ServerTarget } from "nthul/server"; import styles from "../lib-examples.module.css"; +import ThemeButton from "./theme-button"; + +export const targetId = "theme-switching"; +const themes = ["", "theme1", "theme2"]; -const targetId = "theme-switching"; -const themes = ["theme1", "theme2"]; export default function SimpleColorSwitch() { return (
@@ -13,13 +15,12 @@ export default function SimpleColorSwitch() {
- +
); diff --git a/packages/shared-ui/src/lib-examples/theme-switching/theme-button.tsx b/packages/shared-ui/src/lib-examples/theme-switching/theme-button.tsx new file mode 100644 index 00000000..3c100203 --- /dev/null +++ b/packages/shared-ui/src/lib-examples/theme-switching/theme-button.tsx @@ -0,0 +1,19 @@ +"use client"; + +import { useTheme } from "nthul/src/hooks"; +import styles from "../lib-examples.module.css"; + +export default function ThemeButton({ th, targetId }: { th: string; targetId: string }) { + const { setTheme } = useTheme(targetId); + return ( +
  • +
  • + ); +} From 2434174dd353052a5652282543d4c9e9f7d8c8e6 Mon Sep 17 00:00:00 2001 From: Mayank Kumar Chaudhari Date: Sat, 24 Feb 2024 14:40:02 +0530 Subject: [PATCH 06/11] 1. add support for CSS modules 2. Add nth-scoped class to increase specificity for scoped containers. --- .../src/server/server-target/server-target.tsx | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/lib/nthul/src/server/server-target/server-target.tsx b/lib/nthul/src/server/server-target/server-target.tsx index 745d17ae..6536e8e8 100644 --- a/lib/nthul/src/server/server-target/server-target.tsx +++ b/lib/nthul/src/server/server-target/server-target.tsx @@ -9,6 +9,8 @@ interface ServerTargetProps { * make sure you pass same targetId to corresponding `ThemeSwitcher`, `ColorSwitch` and `useTheme` hook as well. * @defaultValue undefined*/ targetId?: string; + /** provide styles object if you are using CSS/SCSS modules. */ + styles?: Record; } /** @@ -24,12 +26,20 @@ interface ServerTargetProps { * * ``` */ -export function ServerTarget({ tag, targetId }: ServerTargetProps) { +export function ServerTarget({ tag, targetId, styles }: ServerTargetProps) { const key = targetId || DEFAULT_ID; const val = cookies().get(key)?.value ?? ",light"; - const [theme, cs] = val.split(",") as [string, "dark" | "light"]; + let [theme, cs] = val.split(",") as [string, string]; + /** to increase specificity for scoped targets. */ + let specificity = targetId ? "nth-scoped" : ""; - const cls = `th-${theme} ${cs}`; + if (styles) { + theme = styles[theme]; + cs = styles[cs]; + specificity = styles[specificity]; + } + + const cls = `th-${theme} ${cs} ${specificity}`; const Tag = tag ?? "div"; return ; From e1f42144135846cfd68b2a32335e555ce7b12d28 Mon Sep 17 00:00:00 2001 From: Mayank Kumar Chaudhari Date: Sat, 24 Feb 2024 14:48:28 +0530 Subject: [PATCH 07/11] Complete Examples --- .../client/theme-switcher/theme-switcher.tsx | 6 +-- packages/shared-ui/src/globals.css | 51 +++++++++++++------ packages/shared-ui/src/lib-examples/index.tsx | 5 ++ .../src/lib-examples/lib-examples.module.css | 3 +- .../index.tsx => simple-color-switch.tsx} | 2 +- .../{theme-switching => }/theme-button.tsx | 4 +- .../index.tsx => theme-switching.tsx} | 13 ++--- .../src/lib-examples/themes-list.tsx | 14 +++++ 8 files changed, 67 insertions(+), 31 deletions(-) rename packages/shared-ui/src/lib-examples/{simple-color-switch/index.tsx => simple-color-switch.tsx} (90%) rename packages/shared-ui/src/lib-examples/{theme-switching => }/theme-button.tsx (81%) rename packages/shared-ui/src/lib-examples/{theme-switching/index.tsx => theme-switching.tsx} (56%) create mode 100644 packages/shared-ui/src/lib-examples/themes-list.tsx diff --git a/lib/nthul/src/client/theme-switcher/theme-switcher.tsx b/lib/nthul/src/client/theme-switcher/theme-switcher.tsx index dd9983e8..9f2fbb69 100644 --- a/lib/nthul/src/client/theme-switcher/theme-switcher.tsx +++ b/lib/nthul/src/client/theme-switcher/theme-switcher.tsx @@ -93,8 +93,8 @@ function applyClasses({ targets, theme, resolvedColorScheme, styles }: ApplyClas targets.forEach(t => { t?.classList.remove(cls[0]); // dark t?.classList.remove(cls[1]); // light - t?.classList.forEach(cls => { - if (cls.match(/(^|_)th-/)) t.classList.remove(cls); + t?.classList.forEach(c => { + if (/(?:^|_)th-/.exec(c)) t.classList.remove(c); }); t?.classList.add(`th-${cls[2]}`); // theme t?.classList.add(cls[3]); // resolvedColorScheme @@ -149,6 +149,6 @@ export function ThemeSwitcher({ targetId, dontSync, themeTransition, styles }: T localStorage.setItem(key, stateToSave); } restoreTransitions(); - }, [dontSync, targetId, themeState, themeTransition]); + }, [dontSync, styles, targetId, themeState, themeTransition]); return null; } diff --git a/packages/shared-ui/src/globals.css b/packages/shared-ui/src/globals.css index 9f2a64ff..4c1a1c3f 100644 --- a/packages/shared-ui/src/globals.css +++ b/packages/shared-ui/src/globals.css @@ -44,15 +44,6 @@ --tile-border: conic-gradient(#00000080, #00000040, #00000030, #00000020, #00000010, #00000010, #00000080); } -/* dark themes */ -.th-.dark, -.th-.dark *, -.th-.dark ~ *, -.th-.dark ~ * * { - --bg-color: var(--bg-dark); - --text-color: var(--color-dark); -} - .dark, .dark ~ * { --primary-glow: radial-gradient(rgba(1, 65, 255, 0.4), rgba(1, 65, 255, 0)); @@ -65,36 +56,66 @@ --tile-border: conic-gradient(#ffffff80, #ffffff40, #ffffff30, #ffffff20, #ffffff10, #ffffff10, #ffffff80); } -/* light themes */ +/* dark themes */ +.th-.dark, +.th-.dark *, +.th-.dark ~ *, +.th-.dark ~ * *, +/* for increased specificity of localized themes */ +.nth-scoped.th-.dark, +.nth-scoped.th-.dark *, +.nth-scoped.th-.dark ~ *, +.nth-scoped.th-.dark ~ * * { + --bg-color: var(--bg-dark); + --text-color: var(--color-dark); +} +/* light themes */ .th-.light, .th-.light *, .th-.light ~ *, -.th-.light ~ * * { +.th-.light ~ * *, +/* for increased specificity of localized themes */ +.nth-scoped.th-.light, +.nth-scoped.th-.light *, +.nth-scoped.th-.light ~ *, +.nth-scoped.th-.light ~ * * { --bg-color: var(--bg-light); --text-color: var(--color-light); } .th-theme1.light ~ *, -.th-theme1.light ~ * * { +.th-theme1.light ~ * *, +/* for increased specificity of localized themes */ +.nth-scoped.th-theme1.light ~ *, +.nth-scoped.th-theme1.light ~ * * { --bg-color: var(--th1-bg-light); --text-color: var(--th1-color-light); } .th-theme1.dark ~ *, -.th-theme1.dark ~ * * { +.th-theme1.dark ~ * * , +/* for increased specificity of localized themes */ +.nth-scoped.th-theme1.dark ~ *, +.nth-scoped.th-theme1.dark ~ * * { --bg-color: var(--th1-bg-dark); --text-color: var(--th1-color-dark); } .th-theme2.light ~ *, -.th-theme2.light ~ * * { +.th-theme2.light ~ * *, +/* for increased specificity of localized themes */ +.nth-scoped.th-theme2.light ~ *, +.nth-scoped.th-theme2.light ~ * * { --bg-color: var(--th2-bg-light); --text-color: var(--th2-color-light); } .th-theme2.dark ~ *, -.th-theme2.dark ~ * * { +.th-theme2.dark ~ * *, +/* for increased specificity of localized themes */ +.nth-scoped.th-theme2.dark ~ *, +.nth-scoped.th-theme2.dark ~ * * { --bg-color: var(--th2-bg-dark); --text-color: var(--th2-color-dark); } diff --git a/packages/shared-ui/src/lib-examples/index.tsx b/packages/shared-ui/src/lib-examples/index.tsx index 9017a5bd..25e7cee7 100644 --- a/packages/shared-ui/src/lib-examples/index.tsx +++ b/packages/shared-ui/src/lib-examples/index.tsx @@ -2,6 +2,7 @@ import { Logo } from "../common/logo"; import SimpleColorSwitch from "./simple-color-switch"; import ThemeSwitching from "./theme-switching"; import styles from "./lib-examples.module.css"; +import ThemesList from "./themes-list"; export default function LibExamples() { return ( @@ -9,6 +10,10 @@ export default function LibExamples() {

    examples.

    +
    +

    Global Themes

    + +
    diff --git a/packages/shared-ui/src/lib-examples/lib-examples.module.css b/packages/shared-ui/src/lib-examples/lib-examples.module.css index 2b06575b..0fc76247 100644 --- a/packages/shared-ui/src/lib-examples/lib-examples.module.css +++ b/packages/shared-ui/src/lib-examples/lib-examples.module.css @@ -6,7 +6,8 @@ justify-content: space-evenly; } -.lib-example-container h1 { +.lib-example-container h1, +.globalThemes { text-align: center; width: 100%; } diff --git a/packages/shared-ui/src/lib-examples/simple-color-switch/index.tsx b/packages/shared-ui/src/lib-examples/simple-color-switch.tsx similarity index 90% rename from packages/shared-ui/src/lib-examples/simple-color-switch/index.tsx rename to packages/shared-ui/src/lib-examples/simple-color-switch.tsx index 9b4192d5..c6b15577 100644 --- a/packages/shared-ui/src/lib-examples/simple-color-switch/index.tsx +++ b/packages/shared-ui/src/lib-examples/simple-color-switch.tsx @@ -1,6 +1,6 @@ import { ColorSwitch, ThemeSwitcher } from "nthul"; import { ServerTarget } from "nthul/server"; -import styles from "../lib-examples.module.css"; +import styles from "./lib-examples.module.css"; const targetId = "simple-color-switch"; export default function SimpleColorSwitch() { diff --git a/packages/shared-ui/src/lib-examples/theme-switching/theme-button.tsx b/packages/shared-ui/src/lib-examples/theme-button.tsx similarity index 81% rename from packages/shared-ui/src/lib-examples/theme-switching/theme-button.tsx rename to packages/shared-ui/src/lib-examples/theme-button.tsx index 3c100203..b8f6ec50 100644 --- a/packages/shared-ui/src/lib-examples/theme-switching/theme-button.tsx +++ b/packages/shared-ui/src/lib-examples/theme-button.tsx @@ -1,9 +1,9 @@ "use client"; import { useTheme } from "nthul/src/hooks"; -import styles from "../lib-examples.module.css"; +import styles from "./lib-examples.module.css"; -export default function ThemeButton({ th, targetId }: { th: string; targetId: string }) { +export default function ThemeButton({ th, targetId }: { th: string; targetId?: string }) { const { setTheme } = useTheme(targetId); return (
  • diff --git a/packages/shared-ui/src/lib-examples/theme-switching/index.tsx b/packages/shared-ui/src/lib-examples/theme-switching.tsx similarity index 56% rename from packages/shared-ui/src/lib-examples/theme-switching/index.tsx rename to packages/shared-ui/src/lib-examples/theme-switching.tsx index 19c50d66..837a5146 100644 --- a/packages/shared-ui/src/lib-examples/theme-switching/index.tsx +++ b/packages/shared-ui/src/lib-examples/theme-switching.tsx @@ -1,10 +1,9 @@ import { ColorSwitch, ThemeSwitcher } from "nthul"; import { ServerTarget } from "nthul/server"; -import styles from "../lib-examples.module.css"; -import ThemeButton from "./theme-button"; +import styles from "./lib-examples.module.css"; +import ThemesList from "./themes-list"; -export const targetId = "theme-switching"; -const themes = ["", "theme1", "theme2"]; +const targetId = "theme-switching"; export default function SimpleColorSwitch() { return ( @@ -16,11 +15,7 @@ export default function SimpleColorSwitch() {
    Simple scoped multi-theme. -
      - {themes.map(th => ( - - ))} -
    +
    ); diff --git a/packages/shared-ui/src/lib-examples/themes-list.tsx b/packages/shared-ui/src/lib-examples/themes-list.tsx new file mode 100644 index 00000000..ce4b5fbb --- /dev/null +++ b/packages/shared-ui/src/lib-examples/themes-list.tsx @@ -0,0 +1,14 @@ +import ThemeButton from "./theme-button"; +import styles from "./lib-examples.module.css"; + +const themes = ["", "theme1", "theme2"]; + +export default function ThemesList({ targetId }: { targetId?: string }) { + return ( +
      + {themes.map(th => ( + + ))} +
    + ); +} From f9498193e3b09d085ea628030205391c6286ff66 Mon Sep 17 00:00:00 2001 From: Mayank Kumar Chaudhari Date: Sat, 24 Feb 2024 14:55:02 +0530 Subject: [PATCH 08/11] touch up --- packages/shared-ui/src/lib-examples/index.tsx | 2 +- packages/shared-ui/src/lib-examples/lib-examples.module.css | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/shared-ui/src/lib-examples/index.tsx b/packages/shared-ui/src/lib-examples/index.tsx index 25e7cee7..14670d4a 100644 --- a/packages/shared-ui/src/lib-examples/index.tsx +++ b/packages/shared-ui/src/lib-examples/index.tsx @@ -8,7 +8,7 @@ export default function LibExamples() { return (

    - examples. + examples

    Global Themes

    diff --git a/packages/shared-ui/src/lib-examples/lib-examples.module.css b/packages/shared-ui/src/lib-examples/lib-examples.module.css index 0fc76247..8fb0de71 100644 --- a/packages/shared-ui/src/lib-examples/lib-examples.module.css +++ b/packages/shared-ui/src/lib-examples/lib-examples.module.css @@ -45,10 +45,11 @@ justify-content: space-evenly; align-items: center; flex-wrap: wrap; + max-width: 400px; + margin: auto; } .themes button { - all: reset; height: 30px; width: 30px; border-radius: 5px; From 8ac2cb5c3e31952caf9467ac7915eafc6d58ecd9 Mon Sep 17 00:00:00 2001 From: Mayank Kumar Chaudhari Date: Sat, 24 Feb 2024 14:58:59 +0530 Subject: [PATCH 09/11] Update Changeset --- .changeset/silly-impalas-fry.md | 5 ----- examples/nextjs/CHANGELOG.md | 9 +++++++++ examples/nextjs/package.json | 2 +- examples/vite/CHANGELOG.md | 9 +++++++++ examples/vite/package.json | 2 +- lib/nthul/CHANGELOG.md | 7 +++++++ lib/nthul/package.json | 2 +- 7 files changed, 28 insertions(+), 8 deletions(-) delete mode 100644 .changeset/silly-impalas-fry.md diff --git a/.changeset/silly-impalas-fry.md b/.changeset/silly-impalas-fry.md deleted file mode 100644 index da2a3b94..00000000 --- a/.changeset/silly-impalas-fry.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"nthul": minor ---- - -Support CSS Modules for scoped theming. diff --git a/examples/nextjs/CHANGELOG.md b/examples/nextjs/CHANGELOG.md index 8bf7481f..06b7582d 100644 --- a/examples/nextjs/CHANGELOG.md +++ b/examples/nextjs/CHANGELOG.md @@ -1,5 +1,14 @@ # nextjs-example +## 0.0.2 + +### Patch Changes + +- Updated dependencies +- Updated dependencies [bb06c15] + - nthul@0.1.0 + - shared-ui@0.0.0 + ## 0.0.1 ### Patch Changes diff --git a/examples/nextjs/package.json b/examples/nextjs/package.json index c7d1eb6d..e616b241 100644 --- a/examples/nextjs/package.json +++ b/examples/nextjs/package.json @@ -1,6 +1,6 @@ { "name": "nextjs-example", - "version": "0.0.1", + "version": "0.0.2", "private": true, "scripts": { "dev": "next dev", diff --git a/examples/vite/CHANGELOG.md b/examples/vite/CHANGELOG.md index 28203971..68a8b01f 100644 --- a/examples/vite/CHANGELOG.md +++ b/examples/vite/CHANGELOG.md @@ -1,5 +1,14 @@ # vite-example +## 0.0.2 + +### Patch Changes + +- Updated dependencies +- Updated dependencies [bb06c15] + - nthul@0.1.0 + - shared-ui@0.0.0 + ## 0.0.1 ### Patch Changes diff --git a/examples/vite/package.json b/examples/vite/package.json index 6ace8ce9..205a669c 100644 --- a/examples/vite/package.json +++ b/examples/vite/package.json @@ -1,7 +1,7 @@ { "name": "vite-example", "private": true, - "version": "0.0.1", + "version": "0.0.2", "type": "module", "scripts": { "dev": "vite --port 3001", diff --git a/lib/nthul/CHANGELOG.md b/lib/nthul/CHANGELOG.md index acd6f1a0..ba737b62 100644 --- a/lib/nthul/CHANGELOG.md +++ b/lib/nthul/CHANGELOG.md @@ -1,5 +1,12 @@ # @mayank1513/fork-me +## 0.1.0 + +### Minor Changes + +- Add `nth-scoped` class to increase CSS specificity when applying themes only to specific container. +- bb06c15: Support CSS Modules for scoped theming. + ## 0.0.1 ### Patch Changes diff --git a/lib/nthul/package.json b/lib/nthul/package.json index deebae81..66ffb46d 100644 --- a/lib/nthul/package.json +++ b/lib/nthul/package.json @@ -2,7 +2,7 @@ "name": "nthul", "author": "Mayank Kumar Chaudhari ", "private": false, - "version": "0.0.1", + "version": "0.1.0", "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", From 69455ebcae349cba6e734d5cf189e8ee2951a9c3 Mon Sep 17 00:00:00 2001 From: Mayank Kumar Chaudhari Date: Sat, 24 Feb 2024 15:02:36 +0530 Subject: [PATCH 10/11] touchup --- packages/shared-ui/src/root-layout.module.css | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/shared-ui/src/root-layout.module.css b/packages/shared-ui/src/root-layout.module.css index 756f94e1..feb20e0f 100644 --- a/packages/shared-ui/src/root-layout.module.css +++ b/packages/shared-ui/src/root-layout.module.css @@ -57,6 +57,7 @@ .center > div { position: relative; + text-align: center; } .center::before { From cdd30f3c53cc0c95faf4d100237e3b2f0349da39 Mon Sep 17 00:00:00 2001 From: Mayank Kumar Chaudhari Date: Sat, 24 Feb 2024 15:10:25 +0530 Subject: [PATCH 11/11] fix tests --- .../server-target/server-target.test.tsx | 21 +++++++++++++++++-- .../server/server-target/server-target.tsx | 2 +- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/lib/nthul/src/server/server-target/server-target.test.tsx b/lib/nthul/src/server/server-target/server-target.test.tsx index 0ffffec5..926f423d 100644 --- a/lib/nthul/src/server/server-target/server-target.test.tsx +++ b/lib/nthul/src/server/server-target/server-target.test.tsx @@ -1,7 +1,7 @@ import { cleanup, render, screen } from "@testing-library/react"; import { afterEach, describe, test } from "vitest"; -import { ServerTarget } from "./server-target"; import { DEFAULT_ID } from "../../constants"; +import { ServerTarget } from "./server-target"; describe("server-target", () => { afterEach(cleanup); @@ -25,6 +25,23 @@ describe("server-target", () => { }, }; render(); - expect(screen.getByTestId("server-target").className).toBe(`th-${THEME} ${COLOR_SCHEME}`); + expect(screen.getByTestId("server-target").className).toBe(`th-${THEME} ${COLOR_SCHEME} `); + }); + + test("test classes from styles", ({ expect }) => { + const THEME = "my-theme"; + const COLOR_SCHEME = "dark"; + globalThis.cookies = { + [DEFAULT_ID]: { + value: `${THEME},${COLOR_SCHEME}`, + }, + }; + const styles = { + [THEME]: `moduled-${THEME}`, + dark: `moduled-dark`, + light: `moduled-light`, + }; + render(); + expect(screen.getByTestId("server-target").className).toBe(`th-${styles[THEME]} ${styles[COLOR_SCHEME]} `); }); }); diff --git a/lib/nthul/src/server/server-target/server-target.tsx b/lib/nthul/src/server/server-target/server-target.tsx index 6536e8e8..dbfe9a31 100644 --- a/lib/nthul/src/server/server-target/server-target.tsx +++ b/lib/nthul/src/server/server-target/server-target.tsx @@ -36,7 +36,7 @@ export function ServerTarget({ tag, targetId, styles }: ServerTargetProps) { if (styles) { theme = styles[theme]; cs = styles[cs]; - specificity = styles[specificity]; + specificity = styles[specificity] ?? ""; } const cls = `th-${theme} ${cs} ${specificity}`;