Repository: nodejs/nodejs.dev
Pull request #2880 (2022-10-05 03:15:31)

feat(useSetDocumentColorScheme): set document color scheme css hook
## Description

Introduced a react hook to set document color scheme css.

## Related Issues

#2674

### Check List

- [X] I have read the [Contributing Guidelines](https://github.com/nodejs/nodejs.dev/blob/main/CONTRIBUTING.md) and made commit messages that follow the guideline.
- [X] I have run `npm run lint:js -- --fix` and/or `npm run lint:md -- --fix` for my JavaScript and/or Markdown changes.
  - This is important as most of the cases your code changes might not be correctly linted
- [X] I have run `npm run test` to check if all tests are passing, and/or `npm run test -- -u` to update snapshots if I created and/or updated React Components.
- [X] I have checked that the build works locally and that `npm run build` work fine.
- [X] I've covered new added functionality with unit tests if necessary.


codecov-commenter: # [Codecov](https://codecov.io/gh/nodejs/nodejs.dev/pull/2880?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) Report
Base: **66.02**% // Head: **63.87**% // Decreases project coverage by **`-2.15%`** :warning:
> Coverage data is based on head [(`c21c194`)](https://codecov.io/gh/nodejs/nodejs.dev/pull/2880?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) compared to base [(`fd57b87`)](https://codecov.io/gh/nodejs/nodejs.dev/commit/fd57b871c2b1ad2f6fb812ed066dec074d76db22?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None).
> Patch has no changes to coverable lines.

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##             main    #2880      +/-   ##
==========================================
- Coverage   66.02%   63.87%   -2.16%     
==========================================
  Files         118      125       +7     
  Lines        1351     1467     +116     
  Branches      342      367      +25     
==========================================
+ Hits          892      937      +45     
- Misses        422      490      +68     
- Partials       37       40       +3     
```


| [Impacted Files](https://codecov.io/gh/nodejs/nodejs.dev/pull/2880?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) | Coverage Δ | |
|---|---|---|
| [src/\_\_fixtures\_\_/hooks.tsx](https://codecov.io/gh/nodejs/nodejs.dev/pull/2880/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-c3JjL19fZml4dHVyZXNfXy9ob29rcy50c3g=) | `100.00% <ø> (ø)` | |
| [src/\_\_fixtures\_\_/page.tsx](https://codecov.io/gh/nodejs/nodejs.dev/pull/2880/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-c3JjL19fZml4dHVyZXNfXy9wYWdlLnRzeA==) | `94.11% <ø> (-5.89%)` | :arrow_down: |
| [...components/ApiComponents/Components/ApiHeading.tsx](https://codecov.io/gh/nodejs/nodejs.dev/pull/2880/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-c3JjL2NvbXBvbmVudHMvQXBpQ29tcG9uZW50cy9Db21wb25lbnRzL0FwaUhlYWRpbmcudHN4) | `0.00% <ø> (ø)` | |
| [...rc/components/ApiComponents/Components/ApiLink.tsx](https://codecov.io/gh/nodejs/nodejs.dev/pull/2880/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-c3JjL2NvbXBvbmVudHMvQXBpQ29tcG9uZW50cy9Db21wb25lbnRzL0FwaUxpbmsudHN4) | `0.00% <ø> (ø)` | |
| [...ents/ApiComponents/Components/SourceLink/index.tsx](https://codecov.io/gh/nodejs/nodejs.dev/pull/2880/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-c3JjL2NvbXBvbmVudHMvQXBpQ29tcG9uZW50cy9Db21wb25lbnRzL1NvdXJjZUxpbmsvaW5kZXgudHN4) | `0.00% <ø> (ø)` | |
| [...ApiComponents/Components/VersionSelector/index.tsx](https://codecov.io/gh/nodejs/nodejs.dev/pull/2880/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-c3JjL2NvbXBvbmVudHMvQXBpQ29tcG9uZW50cy9Db21wb25lbnRzL1ZlcnNpb25TZWxlY3Rvci9pbmRleC50c3g=) | `0.00% <ø> (ø)` | |
| [src/components/ApiComponents/index.tsx](https://codecov.io/gh/nodejs/nodejs.dev/pull/2880/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-c3JjL2NvbXBvbmVudHMvQXBpQ29tcG9uZW50cy9pbmRleC50c3g=) | `0.00% <ø> (ø)` | |
| [src/components/Article/index.tsx](https://codecov.io/gh/nodejs/nodejs.dev/pull/2880/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-c3JjL2NvbXBvbmVudHMvQXJ0aWNsZS9pbmRleC50c3g=) | `100.00% <ø> (ø)` | |
| [src/components/Banner/index.tsx](https://codecov.io/gh/nodejs/nodejs.dev/pull/2880/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-c3JjL2NvbXBvbmVudHMvQmFubmVyL2luZGV4LnRzeA==) | `100.00% <ø> (ø)` | |
| [src/components/Codebox/index.tsx](https://codecov.io/gh/nodejs/nodejs.dev/pull/2880/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-c3JjL2NvbXBvbmVudHMvQ29kZWJveC9pbmRleC50c3g=) | `100.00% <ø> (ø)` | |
| ... and [83 more](https://codecov.io/gh/nodejs/nodejs.dev/pull/2880/diff?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) | |

Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None)

</details>

[:umbrella: View full report at Codecov](https://codecov.io/gh/nodejs/nodejs.dev/pull/2880?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None).   
:loudspeaker: Do you have feedback about the report comment? [Let us know in this issue](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None).

junwen-k: @ovflowd Thanks for the feedback :) I've updated the code to match the requirements. It just look a bit odd to have to keep track of two theme states though 👀
ovflowd: It might sound odd because those two things are separate. One is the actual theme class and other is the color scheme 👀 but they should indeed be separated.

Patch:
diff --git a/src/components/DarkModeToggle/index.tsx b/src/components/DarkModeToggle/index.tsx
index 2867baee..ad120243 100644
--- a/src/components/DarkModeToggle/index.tsx
+++ b/src/components/DarkModeToggle/index.tsx
@@ -1,25 +1,23 @@
-import React, { useEffect } from 'react';
+import React from 'react';
 import { useTheme } from '@skagami/gatsby-plugin-dark-mode';
 import ModeNightIcon from '@mui/icons-material/ModeNight';
 import BrightnessMediumIcon from '@mui/icons-material/BrightnessMedium';
+import { useUpdateDocumentColorScheme } from '../../hooks/useUpdateDocumentColorScheme';
 import styles from './index.module.scss';
 
 const DarkModeToggle = () => {
   const [theme, toggleTheme] = useTheme();
-
-  useEffect(() => {
-    // This is responsible for setting the color-scheme of the scroll-bars
-    if (typeof document === 'object' && document.documentElement) {
-      document.documentElement.style['color-scheme'] = theme;
-    }
-  }, [theme]);
+  const updateColorScheme = useUpdateDocumentColorScheme(theme);
 
   const handleThemeOnClick = (isKeyPress = false): void => {
     if (isKeyPress) {
       return;
     }
 
-    toggleTheme(theme === 'light' ? 'dark' : 'light');
+    const newTheme = theme === 'light' ? 'dark' : 'light';
+
+    toggleTheme(newTheme);
+    updateColorScheme(newTheme);
   };
 
   return (
diff --git a/src/hooks/useUpdateDocumentColorScheme.ts b/src/hooks/useUpdateDocumentColorScheme.ts
new file mode 100644
index 00000000..1b650537
--- /dev/null
+++ b/src/hooks/useUpdateDocumentColorScheme.ts
@@ -0,0 +1,16 @@
+import { useEffect, useState } from 'react';
+
+export const useUpdateDocumentColorScheme = (
+  defaultTheme: string | null = null
+) => {
+  const [currentTheme, setCurrentTheme] = useState(defaultTheme);
+
+  useEffect(() => {
+    // This is responsible for setting the color-scheme of the scroll-bars
+    if (typeof document === 'object' && document.documentElement) {
+      document.documentElement.style['color-scheme'] = currentTheme;
+    }
+  }, [currentTheme]);
+
+  return (theme: string | null) => setCurrentTheme(theme);
+};


Test patch:
diff --git a/src/hooks/__tests__/useUpdateDocumentColorScheme.test.tsx b/src/hooks/__tests__/useUpdateDocumentColorScheme.test.tsx
new file mode 100644
index 00000000..19676942
--- /dev/null
+++ b/src/hooks/__tests__/useUpdateDocumentColorScheme.test.tsx
@@ -0,0 +1,20 @@
+import React from 'react';
+import { fireEvent, render, screen } from '@testing-library/react';
+import { useUpdateDocumentColorScheme } from '../useUpdateDocumentColorScheme';
+
+describe('useUpdateDocumentColorScheme', () => {
+  const HookRenderer = ({ theme }: { theme: string | null }): JSX.Element => {
+    const updateColorScheme = useUpdateDocumentColorScheme();
+
+    return <button type="button" onClick={() => updateColorScheme(theme)} />;
+  };
+
+  it('should update color scheme of document', () => {
+    render(<HookRenderer theme="testTheme" />);
+
+    const button = screen.getByRole('button');
+    fireEvent.click(button);
+
+    expect(document.documentElement.style['color-scheme']).toEqual('testTheme');
+  });
+});