From ecff04baba3b7233dc4fc94d8d5572d7a29012d7 Mon Sep 17 00:00:00 2001 From: aliakrem Date: Tue, 8 Apr 2025 15:12:09 +0100 Subject: [PATCH 1/6] feat: integrate theme-change library for theme toggling --- package-lock.json | 9 ++++++++- web/package.json | 3 ++- web/src/components/top-bar.tsx | 27 +++++++++++++++++++++++++-- 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 712720ea..b5e28c54 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25804,6 +25804,12 @@ "dev": true, "license": "MIT" }, + "node_modules/theme-change": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/theme-change/-/theme-change-2.5.0.tgz", + "integrity": "sha512-B/UdsgdHAGhSKHTAQnxg/etN0RaMDpehuJmZIjLMDVJ6DGIliRHGD6pODi1CXLQAN9GV0GSyB3G6yCuK05PkPQ==", + "license": "MIT" + }, "node_modules/thenify": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", @@ -28492,7 +28498,8 @@ "@sentry/react": "^8.27.0", "react": "^18.3.1", "react-dom": "^18.3.1", - "react-helmet-async": "^2.0.5" + "react-helmet-async": "^2.0.5", + "theme-change": "^2.5.0" }, "devDependencies": { "@loadable/component": "^5.16.4", diff --git a/web/package.json b/web/package.json index b04bd2fa..86305d9c 100644 --- a/web/package.json +++ b/web/package.json @@ -18,7 +18,8 @@ "@sentry/react": "^8.27.0", "react": "^18.3.1", "react-dom": "^18.3.1", - "react-helmet-async": "^2.0.5" + "react-helmet-async": "^2.0.5", + "theme-change": "^2.5.0" }, "devDependencies": { "@loadable/component": "^5.16.4", diff --git a/web/src/components/top-bar.tsx b/web/src/components/top-bar.tsx index 3d295686..9ef894e4 100644 --- a/web/src/components/top-bar.tsx +++ b/web/src/components/top-bar.tsx @@ -1,5 +1,5 @@ import React from "react"; -import { useMemo } from "react"; +import { useMemo, useLayoutEffect, useState } from "react"; import { useLocation } from "react-router-dom"; import logoWide from "src/assets/svg/logo-wide.svg"; import logoSquare from "src/assets/svg/logo-square.svg"; @@ -12,7 +12,7 @@ import { useAppSelector } from "src/redux/store"; import { stripLanguageCodeFromHRef } from "src/utils/website-language"; import { useSearchModal } from "src/utils/search-modal"; import { Language, LANGUAGES } from "@dzcode.io/models/dist/language"; - +import { themeChange } from "theme-change"; export interface TopBarProps { version: string; links: Array<{ localeKey: DictionaryKeys<"navbar-section">; href: string }>; @@ -41,6 +41,27 @@ export function TopBar({ version, links }: TopBarProps): JSX.Element { const { localize } = useLocale(); + const [isDark, setIsDark] = useState(() => { + const savedTheme = localStorage.getItem("theme"); + const isDark = savedTheme === "dark"; + return savedTheme ? isDark : true; // default should be dark + }); + + useLayoutEffect(() => { + themeChange(true); + const theme = localStorage.getItem("theme"); + if (theme) { + document.documentElement.setAttribute("data-theme", theme); + } + }, []); + + function toggleTheme() { + const newTheme = isDark ? "light" : "dark"; + setIsDark(!isDark); + localStorage.setItem("theme", newTheme); + document.documentElement.setAttribute("data-theme", newTheme); + } + return (
@@ -113,10 +134,12 @@ export function TopBar({ version, links }: TopBarProps): JSX.Element { Date: Tue, 8 Apr 2025 19:18:58 +0100 Subject: [PATCH 2/6] refactor: memoize toggleTheme function --- web/src/components/top-bar.tsx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/web/src/components/top-bar.tsx b/web/src/components/top-bar.tsx index 9ef894e4..d7d09c28 100644 --- a/web/src/components/top-bar.tsx +++ b/web/src/components/top-bar.tsx @@ -1,5 +1,5 @@ import React from "react"; -import { useMemo, useLayoutEffect, useState } from "react"; +import { useMemo, useLayoutEffect, useState, useCallback } from "react"; import { useLocation } from "react-router-dom"; import logoWide from "src/assets/svg/logo-wide.svg"; import logoSquare from "src/assets/svg/logo-square.svg"; @@ -55,12 +55,12 @@ export function TopBar({ version, links }: TopBarProps): JSX.Element { } }, []); - function toggleTheme() { + const toggleTheme = useCallback(() => { const newTheme = isDark ? "light" : "dark"; setIsDark(!isDark); localStorage.setItem("theme", newTheme); document.documentElement.setAttribute("data-theme", newTheme); - } + }, [isDark]); return (
@@ -134,7 +134,9 @@ export function TopBar({ version, links }: TopBarProps): JSX.Element { { + toggleTheme(); + }} id="theme-toggle" type="checkbox" value="dzcodeLight" From ea6db24cb1c0f451909f83b8cdc7e099041cc94d Mon Sep 17 00:00:00 2001 From: aliakrem Date: Tue, 8 Apr 2025 19:24:17 +0100 Subject: [PATCH 3/6] chore: format code --- web/src/components/top-bar.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/web/src/components/top-bar.tsx b/web/src/components/top-bar.tsx index d7d09c28..6a23f445 100644 --- a/web/src/components/top-bar.tsx +++ b/web/src/components/top-bar.tsx @@ -134,9 +134,7 @@ export function TopBar({ version, links }: TopBarProps): JSX.Element { { - toggleTheme(); - }} + onClick={toggleTheme} id="theme-toggle" type="checkbox" value="dzcodeLight" From b7c36ee89e525bfbff1fb8b54949379278e2d1e0 Mon Sep 17 00:00:00 2001 From: aliakrem Date: Tue, 8 Apr 2025 19:38:25 +0100 Subject: [PATCH 4/6] refactor: remove unused package theme-change --- package-lock.json | 9 +-------- web/package.json | 3 +-- web/src/components/top-bar.tsx | 3 +-- 3 files changed, 3 insertions(+), 12 deletions(-) diff --git a/package-lock.json b/package-lock.json index b5e28c54..712720ea 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25804,12 +25804,6 @@ "dev": true, "license": "MIT" }, - "node_modules/theme-change": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/theme-change/-/theme-change-2.5.0.tgz", - "integrity": "sha512-B/UdsgdHAGhSKHTAQnxg/etN0RaMDpehuJmZIjLMDVJ6DGIliRHGD6pODi1CXLQAN9GV0GSyB3G6yCuK05PkPQ==", - "license": "MIT" - }, "node_modules/thenify": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", @@ -28498,8 +28492,7 @@ "@sentry/react": "^8.27.0", "react": "^18.3.1", "react-dom": "^18.3.1", - "react-helmet-async": "^2.0.5", - "theme-change": "^2.5.0" + "react-helmet-async": "^2.0.5" }, "devDependencies": { "@loadable/component": "^5.16.4", diff --git a/web/package.json b/web/package.json index 86305d9c..b04bd2fa 100644 --- a/web/package.json +++ b/web/package.json @@ -18,8 +18,7 @@ "@sentry/react": "^8.27.0", "react": "^18.3.1", "react-dom": "^18.3.1", - "react-helmet-async": "^2.0.5", - "theme-change": "^2.5.0" + "react-helmet-async": "^2.0.5" }, "devDependencies": { "@loadable/component": "^5.16.4", diff --git a/web/src/components/top-bar.tsx b/web/src/components/top-bar.tsx index 6a23f445..465dc1af 100644 --- a/web/src/components/top-bar.tsx +++ b/web/src/components/top-bar.tsx @@ -12,7 +12,7 @@ import { useAppSelector } from "src/redux/store"; import { stripLanguageCodeFromHRef } from "src/utils/website-language"; import { useSearchModal } from "src/utils/search-modal"; import { Language, LANGUAGES } from "@dzcode.io/models/dist/language"; -import { themeChange } from "theme-change"; + export interface TopBarProps { version: string; links: Array<{ localeKey: DictionaryKeys<"navbar-section">; href: string }>; @@ -48,7 +48,6 @@ export function TopBar({ version, links }: TopBarProps): JSX.Element { }); useLayoutEffect(() => { - themeChange(true); const theme = localStorage.getItem("theme"); if (theme) { document.documentElement.setAttribute("data-theme", theme); From 4f8a59a63ac65cc1e6850008d33d1310a8385990 Mon Sep 17 00:00:00 2001 From: aliakrem Date: Tue, 8 Apr 2025 20:51:07 +0100 Subject: [PATCH 5/6] fix: update dependencies in toggleTheme --- web/src/components/top-bar.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/web/src/components/top-bar.tsx b/web/src/components/top-bar.tsx index 465dc1af..44118eb5 100644 --- a/web/src/components/top-bar.tsx +++ b/web/src/components/top-bar.tsx @@ -59,7 +59,7 @@ export function TopBar({ version, links }: TopBarProps): JSX.Element { setIsDark(!isDark); localStorage.setItem("theme", newTheme); document.documentElement.setAttribute("data-theme", newTheme); - }, [isDark]); + }, [isDark, setIsDark]); return (
@@ -133,7 +133,9 @@ export function TopBar({ version, links }: TopBarProps): JSX.Element { { + toggleTheme(); + }} id="theme-toggle" type="checkbox" value="dzcodeLight" From d797ff59583f6b8148e5c4e094fcb4598696fb3d Mon Sep 17 00:00:00 2001 From: Omar Date: Wed, 9 Apr 2025 11:41:48 +0200 Subject: [PATCH 6/6] Update web/src/components/top-bar.tsx --- web/src/components/top-bar.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/web/src/components/top-bar.tsx b/web/src/components/top-bar.tsx index 44118eb5..f891bc93 100644 --- a/web/src/components/top-bar.tsx +++ b/web/src/components/top-bar.tsx @@ -133,9 +133,7 @@ export function TopBar({ version, links }: TopBarProps): JSX.Element { { - toggleTheme(); - }} + onClick={toggleTheme} id="theme-toggle" type="checkbox" value="dzcodeLight"