From 8591e1fb09ba83db48c8b4764f90139a061b7fb2 Mon Sep 17 00:00:00 2001 From: Mayank Kumar Chaudhari Date: Mon, 26 Feb 2024 14:04:57 +0530 Subject: [PATCH 1/6] fix keys on server side for scoped themes --- .../nextjs/server-side-wrapper/server-side-wrapper.tsx | 5 +++-- lib/nextjs-themes/vitest.setup.ts | 5 +---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/lib/nextjs-themes/src/server/nextjs/server-side-wrapper/server-side-wrapper.tsx b/lib/nextjs-themes/src/server/nextjs/server-side-wrapper/server-side-wrapper.tsx index 2866c6e9..5df71e61 100644 --- a/lib/nextjs-themes/src/server/nextjs/server-side-wrapper/server-side-wrapper.tsx +++ b/lib/nextjs-themes/src/server/nextjs/server-side-wrapper/server-side-wrapper.tsx @@ -23,7 +23,8 @@ function sharedServerComponentRenderer( defaultTag: "div" | "html", ) { const Tag: keyof JSX.IntrinsicElements = tag || defaultTag; - const state = cookies().get(DEFAULT_ID)?.value; + const key = targetId ? `#${targetId}` : DEFAULT_ID; + const state = cookies().get(key)?.value; const path = headers().get("referer"); const forcedPage = forcedPages?.find(forcedPage => @@ -35,7 +36,7 @@ function sharedServerComponentRenderer( const themeState = state ? (parseState(state) as ThemeStoreType) : undefined; const resolvedData = resolveTheme(themeState, forcedPageProps); const dataProps = getDataProps(resolvedData); - if(targetId) dataProps.className += " nth-scoped"; + if (targetId) dataProps.className += " nth-scoped"; return ( // @ts-expect-error -> svg props and html element props conflict diff --git a/lib/nextjs-themes/vitest.setup.ts b/lib/nextjs-themes/vitest.setup.ts index 6480d5d5..42546a0b 100644 --- a/lib/nextjs-themes/vitest.setup.ts +++ b/lib/nextjs-themes/vitest.setup.ts @@ -1,7 +1,4 @@ -import useRGS from "r18gs"; -import { vi, beforeEach } from "vitest"; -import { DEFAULT_ID, initialState } from "./src/constants"; -import { act, renderHook } from "@testing-library/react"; +import { vi } from "vitest"; // mock matchMedia Object.defineProperty(window, "matchMedia", { From dc835f1d7e838e085a36772c5c02743c13421233 Mon Sep 17 00:00:00 2001 From: Mayank Kumar Chaudhari Date: Mon, 26 Feb 2024 14:50:45 +0530 Subject: [PATCH 2/6] fix lint --- lib/nextjs-themes/src/client/color-switch/color-switch.test.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/nextjs-themes/src/client/color-switch/color-switch.test.tsx b/lib/nextjs-themes/src/client/color-switch/color-switch.test.tsx index ad553107..e7140ab3 100644 --- a/lib/nextjs-themes/src/client/color-switch/color-switch.test.tsx +++ b/lib/nextjs-themes/src/client/color-switch/color-switch.test.tsx @@ -1,6 +1,7 @@ import { act, cleanup, fireEvent, render, renderHook, screen } from "@testing-library/react"; import { ColorSwitch } from "./color-switch"; import { useTheme } from "../../hooks"; +import { afterEach, describe, test } from "vitest"; describe("color-switch", () => { afterEach(cleanup); From 83576e33fd3795d6ed570556274685eb8f0874aa Mon Sep 17 00:00:00 2001 From: Mayank Kumar Chaudhari Date: Tue, 27 Feb 2024 15:51:48 +0530 Subject: [PATCH 3/6] fix lite package badges --- .github/workflows/publish.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 3aafa510..37270207 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -45,6 +45,7 @@ jobs: - run: node lite.js && pnpm build && pnpm publish-package && node scope.js && pnpm publish-package env: NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }} + OWNER: ${{ github.event.repository.owner.login }} - name: Mark scoped package as deprecated run: | From 8dca4068b33e163a05b047fc3a009b348c1d29ea Mon Sep 17 00:00:00 2001 From: Mayank Kumar Chaudhari Date: Tue, 27 Feb 2024 20:30:37 +0530 Subject: [PATCH 4/6] support CSS modules --- .../client/theme-switcher/theme-switcher.tsx | 12 +++++++---- .../server-side-wrapper.tsx | 21 ++++++++++++------- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/lib/nextjs-themes/src/client/theme-switcher/theme-switcher.tsx b/lib/nextjs-themes/src/client/theme-switcher/theme-switcher.tsx index 7eb9281b..6a050d91 100644 --- a/lib/nextjs-themes/src/client/theme-switcher/theme-switcher.tsx +++ b/lib/nextjs-themes/src/client/theme-switcher/theme-switcher.tsx @@ -10,6 +10,8 @@ export interface ThemeSwitcherProps { forcedColorScheme?: ColorSchemeType; targetSelector?: string; themeTransition?: string; + /** provide styles object imported from CSS/SCSS modules, if you are using CSS/SCSS modules. */ + styles?: Record; } function useMediaQuery(setThemeState: SetStateAction) { @@ -63,14 +65,16 @@ export interface UpdateProps { const updateDOM = ( { resolvedTheme, resolvedColorScheme, resolvedColorSchemePref, th }: UpdateProps, - targetSelector?: string, + props: ThemeSwitcherProps, ) => { + const { targetSelector, styles } = props; const target = document.querySelector(targetSelector || `#${DEFAULT_ID}`); + let classes = [resolvedColorScheme, `theme-${resolvedTheme}`, `th-${th}`, `csp-${resolvedColorSchemePref}`]; + if (styles) classes = classes.map(cls => styles[cls] ?? cls); /** don't apply theme to documentElement for localized targets */ [target, targetSelector && target ? null : document.documentElement].forEach(target => { /** ensuring that class 'dark' is always present when dark color scheme is applied to support Tailwind */ - if (target) - target.className = `${resolvedColorScheme} theme-${resolvedTheme} th-${th} csp-${resolvedColorSchemePref}`; + if (target) target.className = classes.join(" "); target?.setAttribute("data-th", th); target?.setAttribute("data-theme", resolvedTheme); target?.setAttribute("data-color-scheme", resolvedColorScheme); @@ -112,7 +116,7 @@ export function useThemeSwitcher(props: ThemeSwitcherProps) { const restoreTransitions = disableAnimation(props.themeTransition); const resolvedData = resolveTheme(themeState, props); - const shouldCreateCookie = updateDOM(resolvedData, props.targetSelector); + const shouldCreateCookie = updateDOM(resolvedData, props); if (tInit < Date.now() - 300) { const stateStr = encodeState(themeState); const key = props.targetSelector || DEFAULT_ID; diff --git a/lib/nextjs-themes/src/server/nextjs/server-side-wrapper/server-side-wrapper.tsx b/lib/nextjs-themes/src/server/nextjs/server-side-wrapper/server-side-wrapper.tsx index 5df71e61..06fce3a2 100644 --- a/lib/nextjs-themes/src/server/nextjs/server-side-wrapper/server-side-wrapper.tsx +++ b/lib/nextjs-themes/src/server/nextjs/server-side-wrapper/server-side-wrapper.tsx @@ -16,10 +16,12 @@ export interface NextJsSSRThemeSwitcherProps extends HTMLProps { forcedPages?: ForcedPage[]; /** id of target element to apply classes to. This is useful when you want to apply theme only to specific container. */ targetId?: string; + /** provide styles object imported from CSS/SCSS modules, if you are using CSS/SCSS modules. */ + styles?: Record; } function sharedServerComponentRenderer( - { children, tag, forcedPages, targetId, ...props }: NextJsSSRThemeSwitcherProps, + { children, tag, forcedPages, targetId, styles, ...props }: NextJsSSRThemeSwitcherProps, defaultTag: "div" | "html", ) { const Tag: keyof JSX.IntrinsicElements = tag || defaultTag; @@ -35,8 +37,8 @@ function sharedServerComponentRenderer( : forcedPage?.props; const themeState = state ? (parseState(state) as ThemeStoreType) : undefined; const resolvedData = resolveTheme(themeState, forcedPageProps); - const dataProps = getDataProps(resolvedData); - if (targetId) dataProps.className += " nth-scoped"; + const dataProps = getDataProps(resolvedData, styles); + if (targetId) dataProps.className += styles?.[" nth-scoped"] ?? " nth-scoped"; return ( // @ts-expect-error -> svg props and html element props conflict @@ -46,24 +48,27 @@ function sharedServerComponentRenderer( ); } -function getDataProps(resolvedData: UpdateProps) { +function getDataProps(resolvedData: UpdateProps, styles?: Record) { const dataProps: DataProps = { className: "" }; + let classeNames = []; if (resolvedData.resolvedColorScheme !== undefined) { dataProps["data-color-scheme"] = resolvedData.resolvedColorScheme; - dataProps.className = resolvedData.resolvedColorScheme; + classeNames.push(resolvedData.resolvedColorScheme); } if (resolvedData.resolvedTheme !== undefined) { dataProps["data-theme"] = resolvedData.resolvedTheme; - dataProps.className += `theme-${resolvedData.resolvedTheme}`; + classeNames.push(`theme-${resolvedData.resolvedTheme}`); } if (resolvedData.th) { dataProps["data-th"] = resolvedData.th; - dataProps.className += ` th-${resolvedData.th}`; + classeNames.push(`th-${resolvedData.th}`); } if (resolvedData.resolvedColorSchemePref !== undefined) { dataProps["data-csp"] = resolvedData.resolvedColorSchemePref; - dataProps.className += ` csp-${resolvedData.resolvedColorSchemePref}`; + classeNames.push(`csp-${resolvedData.resolvedColorSchemePref}`); } + if (styles) classeNames = classeNames.map(cls => styles[cls] ?? cls); + dataProps.className = classeNames.join(" "); return dataProps; } From f94ccfcdee9ed2fd08cb3029b81f58fedd0d76d3 Mon Sep 17 00:00:00 2001 From: Mayank Kumar Chaudhari Date: Tue, 27 Feb 2024 20:31:51 +0530 Subject: [PATCH 5/6] Changeset --- examples/app-router/CHANGELOG.md | 8 ++++++++ examples/app-router/package.json | 2 +- examples/pages-router/CHANGELOG.md | 8 ++++++++ examples/pages-router/package.json | 2 +- examples/simple-multi-theme/CHANGELOG.md | 8 ++++++++ examples/simple-multi-theme/package.json | 2 +- examples/tailwind/CHANGELOG.md | 7 +++++++ examples/tailwind/package.json | 2 +- examples/vite/CHANGELOG.md | 8 ++++++++ examples/vite/package.json | 2 +- lib/nextjs-themes/CHANGELOG.md | 6 ++++++ lib/nextjs-themes/package.json | 2 +- 12 files changed, 51 insertions(+), 6 deletions(-) diff --git a/examples/app-router/CHANGELOG.md b/examples/app-router/CHANGELOG.md index 19341c26..5f10688f 100644 --- a/examples/app-router/CHANGELOG.md +++ b/examples/app-router/CHANGELOG.md @@ -1,5 +1,13 @@ # app-router +## 0.0.20 + +### Patch Changes + +- Updated dependencies + - nextjs-themes@3.1.0 + - shared-ui@1.0.2 + ## 0.0.19 ### Patch Changes diff --git a/examples/app-router/package.json b/examples/app-router/package.json index 6d43cd7f..860922b8 100644 --- a/examples/app-router/package.json +++ b/examples/app-router/package.json @@ -1,6 +1,6 @@ { "name": "app-router", - "version": "0.0.19", + "version": "0.0.20", "private": true, "scripts": { "dev": "next dev --port 3002", diff --git a/examples/pages-router/CHANGELOG.md b/examples/pages-router/CHANGELOG.md index 8d9e7dac..7f3a3af7 100644 --- a/examples/pages-router/CHANGELOG.md +++ b/examples/pages-router/CHANGELOG.md @@ -1,5 +1,13 @@ # nextjs-pages-router +## 1.0.15 + +### Patch Changes + +- Updated dependencies + - nextjs-themes@3.1.0 + - shared-ui@1.0.2 + ## 1.0.14 ### Patch Changes diff --git a/examples/pages-router/package.json b/examples/pages-router/package.json index cf1ce40b..acd16fa4 100644 --- a/examples/pages-router/package.json +++ b/examples/pages-router/package.json @@ -1,6 +1,6 @@ { "name": "pages-router", - "version": "1.0.14", + "version": "1.0.15", "private": true, "scripts": { "dev": "next dev --port 3003", diff --git a/examples/simple-multi-theme/CHANGELOG.md b/examples/simple-multi-theme/CHANGELOG.md index 19bb4580..1653e749 100644 --- a/examples/simple-multi-theme/CHANGELOG.md +++ b/examples/simple-multi-theme/CHANGELOG.md @@ -1,5 +1,13 @@ # simple-multi-theme +## 1.0.15 + +### Patch Changes + +- Updated dependencies + - nextjs-themes@3.1.0 + - shared-ui@1.0.2 + ## 1.0.14 ### Patch Changes diff --git a/examples/simple-multi-theme/package.json b/examples/simple-multi-theme/package.json index 3b05aa87..43b9b8a0 100644 --- a/examples/simple-multi-theme/package.json +++ b/examples/simple-multi-theme/package.json @@ -1,6 +1,6 @@ { "name": "simple-multi-theme", - "version": "1.0.14", + "version": "1.0.15", "private": true, "scripts": { "dev": "next dev --port 3001", diff --git a/examples/tailwind/CHANGELOG.md b/examples/tailwind/CHANGELOG.md index d9f79b42..bd4a4fd2 100644 --- a/examples/tailwind/CHANGELOG.md +++ b/examples/tailwind/CHANGELOG.md @@ -1,5 +1,12 @@ # tailwind +## 0.1.9 + +### Patch Changes + +- Updated dependencies + - nextjs-themes@3.1.0 + ## 0.1.8 ### Patch Changes diff --git a/examples/tailwind/package.json b/examples/tailwind/package.json index afd5d7d0..c683f19d 100644 --- a/examples/tailwind/package.json +++ b/examples/tailwind/package.json @@ -1,6 +1,6 @@ { "name": "tailwind", - "version": "0.1.8", + "version": "0.1.9", "private": true, "scripts": { "dev": "next dev", diff --git a/examples/vite/CHANGELOG.md b/examples/vite/CHANGELOG.md index 0c7a1b4c..487bf2b1 100644 --- a/examples/vite/CHANGELOG.md +++ b/examples/vite/CHANGELOG.md @@ -1,5 +1,13 @@ # vite-example +## 0.0.20 + +### Patch Changes + +- Updated dependencies + - nextjs-themes@3.1.0 + - shared-ui@1.0.2 + ## 0.0.19 ### Patch Changes diff --git a/examples/vite/package.json b/examples/vite/package.json index 265f0de3..eddc052b 100644 --- a/examples/vite/package.json +++ b/examples/vite/package.json @@ -1,7 +1,7 @@ { "name": "vite-example", "private": true, - "version": "0.0.19", + "version": "0.0.20", "type": "module", "scripts": { "dev": "vite --port 3001", diff --git a/lib/nextjs-themes/CHANGELOG.md b/lib/nextjs-themes/CHANGELOG.md index 82697214..93fe3c7f 100644 --- a/lib/nextjs-themes/CHANGELOG.md +++ b/lib/nextjs-themes/CHANGELOG.md @@ -1,5 +1,11 @@ # nextjs-themes +## 3.1.0 + +### Minor Changes + +- Add support for CSS modules and minor fixes. + ## 3.0.0 ### Major Changes diff --git a/lib/nextjs-themes/package.json b/lib/nextjs-themes/package.json index 7e9d9365..944da822 100644 --- a/lib/nextjs-themes/package.json +++ b/lib/nextjs-themes/package.json @@ -2,7 +2,7 @@ "name": "nextjs-themes", "author": "Mayank Kumar Chaudhari ", "private": false, - "version": "3.0.0", + "version": "3.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 6bc0dfd6ddc7f1609b1d0afc00958e52c54f9788 Mon Sep 17 00:00:00 2001 From: Mayank Kumar Chaudhari Date: Tue, 27 Feb 2024 20:39:01 +0530 Subject: [PATCH 6/6] fix deepsource - anti-pattern --- .../server-side-wrapper.tsx | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/lib/nextjs-themes/src/server/nextjs/server-side-wrapper/server-side-wrapper.tsx b/lib/nextjs-themes/src/server/nextjs/server-side-wrapper/server-side-wrapper.tsx index 06fce3a2..6be0eaf5 100644 --- a/lib/nextjs-themes/src/server/nextjs/server-side-wrapper/server-side-wrapper.tsx +++ b/lib/nextjs-themes/src/server/nextjs/server-side-wrapper/server-side-wrapper.tsx @@ -20,6 +20,30 @@ export interface NextJsSSRThemeSwitcherProps extends HTMLProps { styles?: Record; } +function getDataProps(resolvedData: UpdateProps, styles?: Record) { + const dataProps: DataProps = { className: "" }; + let classeNames = []; + if (resolvedData.resolvedColorScheme !== undefined) { + dataProps["data-color-scheme"] = resolvedData.resolvedColorScheme; + classeNames.push(resolvedData.resolvedColorScheme); + } + if (resolvedData.resolvedTheme !== undefined) { + dataProps["data-theme"] = resolvedData.resolvedTheme; + classeNames.push(`theme-${resolvedData.resolvedTheme}`); + } + if (resolvedData.th) { + dataProps["data-th"] = resolvedData.th; + classeNames.push(`th-${resolvedData.th}`); + } + if (resolvedData.resolvedColorSchemePref !== undefined) { + dataProps["data-csp"] = resolvedData.resolvedColorSchemePref; + classeNames.push(`csp-${resolvedData.resolvedColorSchemePref}`); + } + if (styles) classeNames = classeNames.map(cls => styles[cls] ?? cls); + dataProps.className = classeNames.join(" "); + return dataProps; +} + function sharedServerComponentRenderer( { children, tag, forcedPages, targetId, styles, ...props }: NextJsSSRThemeSwitcherProps, defaultTag: "div" | "html", @@ -48,30 +72,6 @@ function sharedServerComponentRenderer( ); } -function getDataProps(resolvedData: UpdateProps, styles?: Record) { - const dataProps: DataProps = { className: "" }; - let classeNames = []; - if (resolvedData.resolvedColorScheme !== undefined) { - dataProps["data-color-scheme"] = resolvedData.resolvedColorScheme; - classeNames.push(resolvedData.resolvedColorScheme); - } - if (resolvedData.resolvedTheme !== undefined) { - dataProps["data-theme"] = resolvedData.resolvedTheme; - classeNames.push(`theme-${resolvedData.resolvedTheme}`); - } - if (resolvedData.th) { - dataProps["data-th"] = resolvedData.th; - classeNames.push(`th-${resolvedData.th}`); - } - if (resolvedData.resolvedColorSchemePref !== undefined) { - dataProps["data-csp"] = resolvedData.resolvedColorSchemePref; - classeNames.push(`csp-${resolvedData.resolvedColorSchemePref}`); - } - if (styles) classeNames = classeNames.map(cls => styles[cls] ?? cls); - dataProps.className = classeNames.join(" "); - return dataProps; -} - /** * @example * ```tsx