refactor: usetheme hook (#7112)
* refactor: useTheme hook * feat: add mounted state hook * feat: add mounted hook * fix: add commentspull/7181/head
parent
ce01537fe6
commit
485619602f
|
@ -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;
|
||||
}
|
|
@ -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(),
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue