Skip to content

Commit 5558307

Browse files
authored
Merge pull request #9 from react18-tools/feat/support-wrapping-html
Feat/support wrapping html
2 parents 1f3bf89 + b1fe1a4 commit 5558307

File tree

15 files changed

+106
-38
lines changed

15 files changed

+106
-38
lines changed

lib/CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
11
# nextjs-darkmode
22

3+
## 0.2.0
4+
5+
### Minor Changes
6+
7+
- 05568cb: Support children in Switch element. Use case: Theme Switch with mode label.
8+
- 59dbc4f: Support passing tag to server-target. Use case: replace html element in case SSR is preferred over SSG.
9+
10+
### Patch Changes
11+
12+
- 05568cb: Override pseudo element transitions as well to avoid patched theme transition
13+
- 05568cb: Refactor: refactor code hoping better minzip size
14+
315
## 0.1.1
416

517
### Patch Changes

lib/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "nextjs-darkmode",
33
"author": "Mayank Kumar Chaudhari <https://mayank-chaudhari.vercel.app>",
44
"private": false,
5-
"version": "0.1.1",
5+
"version": "0.2.0",
66
"description": "Unleash the Power of React Server Components! Use dark/light mode on your site with confidence, without losing any advantages of React Server Components",
77
"license": "MPL-2.0",
88
"main": "./dist/index.js",

lib/src/client/core/core.tsx

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export interface CoreProps {
1313
const modifyTransition = (themeTransition = "none", nonce = "") => {
1414
const css = document.createElement("style");
1515
/** split by ';' to prevent CSS injection */
16-
css.textContent = `*{transition:${themeTransition.split(";")[0]} !important;}`;
16+
css.textContent = `*,*:after,*:before{transition:${themeTransition.split(";")[0]} !important;}`;
1717
nonce && css.setAttribute("nonce", nonce);
1818
document.head.appendChild(css);
1919

@@ -60,16 +60,16 @@ export const Core = ({ t, nonce }: CoreProps) => {
6060
// We need to always update documentElement to support Tailwind configuration
6161
// skipcq: JS-D008, JS-0042 -> map keyword is shorter
6262
[document.documentElement, serverTargetEl].map(el => {
63-
// skipcq: JS-0042
64-
if (!el) return;
65-
const clsList = el.classList;
66-
modes.forEach(mode => clsList.remove(mode));
67-
clsList.add(resolvedMode);
68-
[
69-
["sm", systemMode],
70-
["rm", resolvedMode],
71-
["m", mode],
72-
].forEach(([dataLabel, value]) => el.setAttribute(`data-${dataLabel}`, value));
63+
if (el) {
64+
const clsList = el.classList;
65+
modes.forEach(mode => clsList.remove(mode));
66+
clsList.add(resolvedMode);
67+
[
68+
["sm", systemMode],
69+
["rm", resolvedMode],
70+
["m", mode],
71+
].forEach(([dataLabel, value]) => el.setAttribute(`data-${dataLabel}`, value));
72+
}
7373
});
7474
restoreTransitions();
7575
// System mode is decided by current system state and need not be stored in localStorage

lib/src/client/switch/switch.module.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
.switch {
22
all: unset;
33
position: relative;
4+
display: inline-block;
45
color: currentColor;
56
border-radius: 50%;
67
border: 1px dashed currentColor;

lib/src/client/switch/switch.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ describe("switch", () => {
2626
act(() => {
2727
hook.result.current.setMode(SYSTEM);
2828
});
29-
render(<Switch skipSystem />);
29+
render(<Switch skipSystem>Switch with children</Switch>);
3030
const element = screen.getByTestId("switch");
3131
await act(() => fireEvent.click(element));
3232
expect(hook.result.current.mode).toBe(DARK);

lib/src/client/switch/switch.tsx

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import styles from "./switch.module.scss";
33
import { useStore } from "../../utils";
44
import { modes } from "../../constants";
55

6-
export interface SwitchProps extends HTMLProps<HTMLElement> {
6+
export interface SwitchProps extends HTMLProps<HTMLButtonElement> {
77
/** html tag @defaultValue 'button' */
88
tag?: "button" | "div";
99
/** Diameter of the color switch */
@@ -22,7 +22,13 @@ export interface SwitchProps extends HTMLProps<HTMLElement> {
2222
*
2323
* @source - Source code
2424
*/
25-
export const Switch = ({ tag: Tag = "button", size = 24, skipSystem, ...props }: SwitchProps) => {
25+
export const Switch = ({
26+
tag: Tag = "button",
27+
size = 24,
28+
skipSystem,
29+
children,
30+
...props
31+
}: SwitchProps) => {
2632
const [state, setState] = useStore();
2733
/** toggle mode */
2834
const handleModeSwitch = () => {
@@ -34,11 +40,27 @@ export const Switch = ({ tag: Tag = "button", size = 24, skipSystem, ...props }:
3440
m: modes[(index + 1) % n],
3541
});
3642
};
37-
const className = [props.className, styles["switch"]].filter(Boolean).join(" ");
43+
if (children) {
44+
return (
45+
// @ts-expect-error -- too complex types
46+
<Tag
47+
suppressHydrationWarning
48+
{...props}
49+
data-testid="switch"
50+
// skipcq: JS-0417
51+
onClick={handleModeSwitch}>
52+
{/* @ts-expect-error -> we are setting the CSS variable */}
53+
<div className={styles.switch} style={{ "--size": `${size}px` }} />
54+
{children}
55+
</Tag>
56+
);
57+
}
3858
return (
3959
<Tag
60+
// Hydration warning is caused when the data from localStorage differs from the default data provided while rendering on server
61+
suppressHydrationWarning
4062
{...props}
41-
className={className}
63+
className={[props.className, styles.switch].join(" ")}
4264
// @ts-expect-error -> we are setting the CSS variable
4365
style={{ "--size": `${size}px` }}
4466
data-testid="switch"

lib/src/server/server-target/server-target.tsx

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
import { cookies } from "next/headers";
22
import { COOKIE_KEY, LIGHT } from "../../constants";
3+
import { HTMLProps } from "react";
4+
5+
export interface ServerTargetProps extends HTMLProps<HTMLHtmlElement | HTMLDivElement> {
6+
tag?: "html" | "div";
7+
}
38

49
/**
510
* Server Side target for avoiding flash of un-themed content.
@@ -15,9 +20,22 @@ import { COOKIE_KEY, LIGHT } from "../../constants";
1520
* </html>
1621
* ```
1722
*
23+
* If you prefer SSR over SSG, you can replace `html` element with `ServerTarget`. This way you can avoid having to write sybling selectors.
24+
*
25+
* @example
26+
* ```tsx
27+
* <ServerTarget tag="html">
28+
* ...
29+
* </ServerTarget>
30+
* ```
31+
*
32+
* @param tag - Tag to use for the target. Defaults to `div`.
33+
* ```
34+
*
1835
* @source - Source code
1936
*/
20-
export const ServerTarget = () => {
37+
export const ServerTarget = ({ tag: Tag = "div", ...props }: ServerTargetProps) => {
2138
const rm = cookies().get(COOKIE_KEY)?.value ?? LIGHT;
22-
return <div className={rm} data-rm={rm} data-ndm="ndm" data-testid="server-target" />;
39+
// @ts-expect-error -- too complex types
40+
return <Tag className={rm} data-rm={rm} data-ndm="ndm" data-testid="server-target" {...props} />;
2341
};

lib/src/utils.ts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,12 @@ export interface Store {
88
s: ResolvedScheme;
99
}
1010

11-
const DEFAULT_STORE_VAL: Store = {
12-
m: SYSTEM,
13-
s: DARK as ResolvedScheme,
14-
};
15-
1611
/** local abstaction of RGS to avoid multiple imports */
1712
export const useStore = () =>
1813
useRGS<Store>("ndm", () =>
1914
typeof localStorage === "undefined"
2015
? /* v8 ignore next */
21-
DEFAULT_STORE_VAL
16+
{ m: SYSTEM, s: DARK as ResolvedScheme }
2217
: {
2318
m: (localStorage.getItem(COOKIE_KEY) ?? SYSTEM) as ColorSchemePreference,
2419
s: (matchMedia(MEDIA).matches ? DARK : LIGHT) as ResolvedScheme,

packages/shared/CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
# @repo/shared
22

3+
## 0.0.6
4+
5+
### Patch Changes
6+
7+
- Updated dependencies [05568cb]
8+
- Updated dependencies [05568cb]
9+
- Updated dependencies [05568cb]
10+
- Updated dependencies [59dbc4f]
11+
12+
313
## 0.0.5
414

515
### Patch Changes

packages/shared/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@repo/shared",
3-
"version": "0.0.5",
3+
"version": "0.0.6",
44
"private": true,
55
"sideEffects": false,
66
"main": "./dist/index.js",

0 commit comments

Comments
 (0)