refactor: usetheme hook (#7112)

* refactor: useTheme hook

* feat: add mounted state hook

* feat: add mounted hook

* fix: add comments
pull/7181/head
Nafees Nazik 2023-02-17 16:48:54 +05:30 committed by GitHub
parent ce01537fe6
commit 485619602f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 36 additions and 10 deletions

View File

@ -0,0 +1,22 @@
import { useCallback, useEffect, useRef } from "react";
// credits: https://github.com/streamich/react-use/blob/master/src/useMountedState.ts
// jsdoc generated by chat-gpt :)
/**
* A custom React hook that returns a function to check if the component is mounted.
* @returns {function(): boolean} A function that returns `true` if the component is mounted and `false` otherwise.
*/
export default function useMountedState(): () => boolean {
const mountedRef = useRef<boolean>(false);
const get = useCallback(() => mountedRef.current, []);
useEffect(() => {
mountedRef.current = true;
return () => {
mountedRef.current = false;
};
}, []);
return get;
}

View File

@ -1,29 +1,33 @@
import { useTheme as useNextTheme } from "next-themes";
import { useEffect, useState } from "react";
import { useEffect } from "react";
import { useEmbedTheme } from "@calcom/embed-core/embed-iframe";
import type { Maybe } from "@calcom/trpc/server";
import useMountedState from "./useMountedState";
// makes sure the ui doesn't flash
export default function useTheme(theme?: Maybe<string>) {
theme = theme || "system";
const { resolvedTheme, setTheme, forcedTheme } = useNextTheme();
const [isReady, setIsReady] = useState<boolean>(false);
let currentTheme: Maybe<string> = theme || "system";
const { resolvedTheme, setTheme, forcedTheme, theme: activeTheme } = useNextTheme();
const embedTheme = useEmbedTheme();
const isMounted = useMountedState();
// Embed UI configuration takes more precedence over App Configuration
theme = embedTheme || theme;
currentTheme = embedTheme || theme;
useEffect(() => {
if (theme) {
setTheme(theme);
if (currentTheme !== activeTheme && typeof currentTheme === "string") {
setTheme(currentTheme);
}
setIsReady(true);
}, [theme, setTheme]);
// eslint-disable-next-line react-hooks/exhaustive-deps -- we do not want activeTheme to re-render this effect
}, [currentTheme, setTheme]);
return {
resolvedTheme,
setTheme,
isReady,
forcedTheme,
activeTheme,
isReady: isMounted(),
};
}