Skip to content

Commit bace10e

Browse files
authored
Merge pull request #1 from mayank1513/touchup
Touchup
2 parents 52c073a + 03e2a18 commit bace10e

File tree

10 files changed

+121
-40
lines changed

10 files changed

+121
-40
lines changed

.tkb

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
{
2+
"scope": "Workspace",
3+
"tasks": {
4+
"task-ZJpp-dpxx3KxRMsAPNuMC": {
5+
"id": "task-ZJpp-dpxx3KxRMsAPNuMC",
6+
"description": "Implement tests",
7+
"columnId": "column-done"
8+
},
9+
"4CTOhRPjKrEAW5AHYsV7P": {
10+
"id": "4CTOhRPjKrEAW5AHYsV7P",
11+
"description": "Update doc comments",
12+
"columnId": "column-done"
13+
},
14+
"RtA7NBfPOlfnVHqk54rMD": {
15+
"id": "RtA7NBfPOlfnVHqk54rMD",
16+
"description": "update readme",
17+
"columnId": "column-todo"
18+
},
19+
"fqhes_YS14GQopOUs7K-7": {
20+
"id": "fqhes_YS14GQopOUs7K-7",
21+
"description": "update workflows to replace mayank1513",
22+
"columnId": "column-todo"
23+
},
24+
"-FlzW8htLo-6jz5-ZqjEx": {
25+
"id": "-FlzW8htLo-6jz5-ZqjEx",
26+
"description": "update examples to showcase edge cases",
27+
"columnId": "column-todo"
28+
}
29+
},
30+
"columns": [
31+
{
32+
"id": "column-todo",
33+
"title": "To do",
34+
"tasksIds": [
35+
"RtA7NBfPOlfnVHqk54rMD",
36+
"fqhes_YS14GQopOUs7K-7",
37+
"-FlzW8htLo-6jz5-ZqjEx"
38+
]
39+
},
40+
{
41+
"id": "column-doing",
42+
"title": "Doing",
43+
"tasksIds": []
44+
},
45+
{
46+
"id": "column-done",
47+
"title": "Done",
48+
"tasksIds": [
49+
"task-ZJpp-dpxx3KxRMsAPNuMC",
50+
"4CTOhRPjKrEAW5AHYsV7P"
51+
]
52+
}
53+
]
54+
}

.vscode/settings.json

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,32 @@
11
{
2-
// Formatting using Prettier by default for all languages
3-
"editor.defaultFormatter": "esbenp.prettier-vscode",
4-
// Formatting using Prettier for JavaScript, overrides VSCode default.
5-
"[javascript]": {
6-
"editor.defaultFormatter": "esbenp.prettier-vscode"
7-
},
2+
// Formatting using Prettier by default for all languages
3+
"editor.defaultFormatter": "esbenp.prettier-vscode",
4+
// Formatting using Prettier for JavaScript, overrides VSCode default.
5+
"[javascript]": {
6+
"editor.defaultFormatter": "esbenp.prettier-vscode"
7+
},
88

9-
// Ensure enough terminal history is preserved when running tests.
10-
"terminal.integrated.scrollback": 10000,
9+
// Ensure enough terminal history is preserved when running tests.
10+
"terminal.integrated.scrollback": 10000,
1111

12-
// Configure todo-tree to exclude node_modules, dist, and compiled.
13-
"todo-tree.filtering.excludeGlobs": ["**/node_modules", "**/dist", "**/compiled"],
14-
// Match TODO-APP in addition to other TODOs.
15-
"todo-tree.general.tags": ["BUG", "HACK", "FIXME", "TODO", "XXX", "[ ]", "[x]", "TODO-APP"],
12+
// Configure todo-tree to exclude node_modules, dist, and compiled.
13+
"todo-tree.filtering.excludeGlobs": ["**/node_modules", "**/dist", "**/compiled"],
14+
// Match TODO-APP in addition to other TODOs.
15+
"todo-tree.general.tags": ["BUG", "HACK", "FIXME", "TODO", "XXX", "[ ]", "[x]", "TODO-APP"],
1616

17-
// Disable TypeScript surveys.
18-
"typescript.surveys.enabled": false,
17+
// Disable TypeScript surveys.
18+
"typescript.surveys.enabled": false,
1919

20-
"grammarly.selectors": [
21-
{
22-
"language": "markdown",
23-
"scheme": "file"
24-
}
25-
],
26-
"editor.tabSize": 2,
27-
"editor.wordWrap": "on",
28-
"editor.formatOnSave": true,
29-
"editor.formatOnPaste": true,
30-
"editor.formatOnSaveMode": "file"
20+
"grammarly.selectors": [
21+
{
22+
"language": "markdown",
23+
"scheme": "file"
24+
}
25+
],
26+
"editor.tabSize": 2,
27+
"editor.wordWrap": "on",
28+
"editor.formatOnSave": true,
29+
"editor.formatOnPaste": true,
30+
"editor.formatOnSaveMode": "file",
31+
"mayank1513.trello-kanban.Workspace.filePath": ".tkb"
3132
}

lib/nthul/src/client/color-switch/color-switch.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { act, cleanup, fireEvent, render, renderHook, screen } from "@testing-library/react";
22
import { afterEach, describe, test } from "vitest";
3-
import { useTheme } from "../../hooks/use-theme";
3+
import { useTheme } from "../../hooks";
44
import { ColorSwitch } from "./color-switch";
55

66
describe("color-switch", () => {

lib/nthul/src/client/color-switch/color-switch.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import * as React from "react";
2-
import { useTheme } from "../../hooks/use-theme";
2+
import { useTheme } from "../../hooks";
33

44
export interface ColorSwitchProps {
5-
/** id of target element if you are applying theme only to specific container. */
5+
/** id of target element if you are applying theme only to specific container. Should be same as corresponding ThemeSwitcher, etc. */
66
targetId?: string;
77
/** Diameter of the color switch */
88
size?: number;
@@ -11,7 +11,8 @@ export interface ColorSwitchProps {
1111
}
1212

1313
/**
14-
* Color switch button to quickly set user preference
14+
* Color switch button to quickly set user preference.
15+
* Use same targetId for corresponding components and hooks if you are using themes for specific container only.
1516
*
1617
* @example
1718
* ```ts

lib/nthul/src/client/theme-switcher/theme-switcher.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { act, cleanup, fireEvent, render, renderHook } from "@testing-library/react";
22
import { afterEach, beforeEach, describe, test } from "vitest";
3-
import { useTheme } from "../../hooks/use-theme";
3+
import { useTheme } from "../../hooks";
44
import { DEFAULT_ID } from "../../constants";
55
import { ServerTarget } from "../../server";
66
import { ThemeSwitcher } from "./theme-switcher";

lib/nthul/src/client/theme-switcher/theme-switcher.tsx

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,15 @@ function useLoadSyncedState({ dontSync, targetId, setThemeState }: LoadSyncedSta
5555
}, [dontSync, setThemeState, targetId]);
5656
}
5757

58-
function modifyTransition(themeTransition = "none") {
58+
function modifyTransition(themeTransition = "none", targetId?: string) {
5959
const css = document.createElement("style");
6060
/** split by ';' to prevent CSS injection */
6161
const transition = `transition: ${themeTransition.split(";")[0]} !important;`;
62+
const targetSelector = targetId ? `#${targetId},#${targetId} *,#${targetId} ~ *,#${targetId} ~ * *` : "*";
6263
css.appendChild(
63-
document.createTextNode(`*{-webkit-${transition}-moz-${transition}-o-${transition}-ms-${transition}${transition}}`),
64+
document.createTextNode(
65+
`${targetSelector}{-webkit-${transition}-moz-${transition}-o-${transition}-ms-${transition}${transition}}`,
66+
),
6467
);
6568
document.head.appendChild(css);
6669

@@ -105,6 +108,10 @@ function updateDOM({ targetId, themeState, dontSync }: UpdateDOMProps) {
105108
if (shoulCreateCookie) document.cookie = `${key}=${theme},${resolvedColorScheme}; max-age=31536000; SameSite=Strict;`;
106109
}
107110

111+
/**
112+
* The core ThemeSwitcher component wich applies classes and transitions.
113+
* Cookies are set only if corresponding ServerTarget is detected.
114+
*/
108115
export function ThemeSwitcher({ targetId, dontSync, themeTransition }: ThemeSwitcherProps) {
109116
if (targetId === "") throw new Error("id can not be an empty string");
110117
const [themeState, setThemeState] = useRGS<ThemeState>(targetId ?? DEFAULT_ID, DEFAULT_THEME_STATE);
@@ -115,7 +122,7 @@ export function ThemeSwitcher({ targetId, dontSync, themeTransition }: ThemeSwit
115122

116123
/** update DOM and storage */
117124
React.useEffect(() => {
118-
const restoreTransitions = modifyTransition(themeTransition);
125+
const restoreTransitions = modifyTransition(themeTransition, targetId);
119126
updateDOM({ targetId, themeState, dontSync });
120127
if (!dontSync && tInit < Date.now() - 300) {
121128
// save to localStorage

lib/nthul/src/hooks/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from "./use-theme";

lib/nthul/src/hooks/use-theme.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,13 @@ export interface UseTheme {
1111
setTheme: (theme: string) => void;
1212
}
1313

14-
export function useTheme(id?: string): UseTheme {
15-
const [themeState, setState] = useRGS<ThemeState>(id ?? DEFAULT_ID, DEFAULT_THEME_STATE);
14+
/**
15+
* use this hook to gain access to theme state and setters from your components.
16+
* @param targetId - targetId corresponding to `ThemeSwitcher` and others tied to specific container.
17+
* @returns themeState and setter fucntions
18+
*/
19+
export function useTheme(targetId?: string): UseTheme {
20+
const [themeState, setState] = useRGS<ThemeState>(targetId ?? DEFAULT_ID, DEFAULT_THEME_STATE);
1621
const { colorSchemePreference: csp, systemColorScheme: scs } = themeState;
1722
return {
1823
...themeState,

lib/nthul/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
"use client";
22
// client component exports
33
export * from "./client";
4+
// client side hooks
5+
export * from "./hooks";

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

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,26 @@ import { cookies } from "next/headers";
33
import { DEFAULT_ID } from "../../constants";
44

55
interface ServerTargetProps {
6+
/** @defaultValue 'div' */
67
tag?: keyof JSX.IntrinsicElements;
8+
/** id of target element if you are applying theme only to specific container.
9+
* make sure you pass same targetId to corresponding `ThemeSwitcher`, `ColorSwitch` and `useTheme` hook as well.
10+
* @defaultValue undefined*/
711
targetId?: string;
812
}
913

1014
/**
11-
* # ServerTarget
12-
* --todo
13-
* update comments
14-
* create colorswitch
15-
* update examples
15+
* Server Side target for avoiding flash of un-themed content.
16+
* @example
17+
* ```tsx
18+
* <html>
19+
* ...
20+
* <body>
21+
* <ServerTarget />
22+
* ...
23+
* </body>
24+
* </html>
25+
* ```
1626
*/
1727
export function ServerTarget({ tag, targetId }: ServerTargetProps) {
1828
const key = targetId || DEFAULT_ID;

0 commit comments

Comments
 (0)