0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2025-03-10 22:22:45 -05:00

fix(ui): theme adaption (#3350)

This commit is contained in:
Xiao Yijun 2023-03-13 11:08:08 +08:00 committed by GitHub
parent 16b3c580e6
commit e89b82d27a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 26 additions and 22 deletions

View file

@ -29,9 +29,10 @@ import './scss/normalized.scss';
const App = () => {
const { context, Provider } = usePageContext();
const { experienceSettings, setLoading, setExperienceSettings } = context;
const { isPreview, experienceSettings, setLoading, setExperienceSettings } = context;
const customCssRef = useRef(document.createElement('style'));
const [isPreview] = usePreview(context);
usePreview(context);
useEffect(() => {
document.head.append(customCssRef.current);

View file

@ -3,6 +3,7 @@ import { useState, useMemo, createContext } from 'react';
import { isMobile } from 'react-device-detect';
import type { SignInExperienceResponse, Platform, Theme } from '@/types';
import { parseQueryParameters } from '@/utils';
export type Context = {
theme: Theme;
@ -11,6 +12,7 @@ export type Context = {
platform: Platform;
termsAgreement: boolean;
experienceSettings: SignInExperienceResponse | undefined;
isPreview: boolean;
setTheme: React.Dispatch<React.SetStateAction<Theme>>;
setToast: React.Dispatch<React.SetStateAction<string>>;
setLoading: React.Dispatch<React.SetStateAction<boolean>>;
@ -26,6 +28,7 @@ export const PageContext = createContext<Context>({
platform: isMobile ? 'mobile' : 'web',
termsAgreement: false,
experienceSettings: undefined,
isPreview: false,
setTheme: noop,
setToast: noop,
setLoading: noop,
@ -42,6 +45,9 @@ const usePageContext = () => {
const [experienceSettings, setExperienceSettings] = useState<SignInExperienceResponse>();
const [termsAgreement, setTermsAgreement] = useState(false);
const { preview } = parseQueryParameters(window.location.search);
const isPreview = preview === 'true';
const context = useMemo(
() => ({
theme,
@ -50,6 +56,7 @@ const usePageContext = () => {
platform,
termsAgreement,
experienceSettings,
isPreview,
setTheme,
setLoading,
setToast,
@ -57,7 +64,7 @@ const usePageContext = () => {
setTermsAgreement,
setExperienceSettings,
}),
[experienceSettings, loading, platform, termsAgreement, theme, toast]
[experienceSettings, isPreview, loading, platform, termsAgreement, theme, toast]
);
return {

View file

@ -3,28 +3,15 @@ import { conditionalString } from '@silverhand/essentials';
import { useEffect, useState } from 'react';
import * as styles from '@/Layout/AppLayout/index.module.scss';
import * as appStyles from '@/Providers/AppBoundary/index.module.scss';
import type { Context } from '@/hooks/use-page-context';
import initI18n from '@/i18n/init';
import { changeLanguage } from '@/i18n/utils';
import type { SignInExperienceResponse, PreviewConfig, Theme } from '@/types';
import { parseQueryParameters } from '@/utils';
import type { SignInExperienceResponse, PreviewConfig } from '@/types';
import { filterPreviewSocialConnectors } from '@/utils/social-connectors';
const applyTheme = (theme: Theme) => {
document.body.classList.remove(
conditionalString(appStyles.light),
conditionalString(appStyles.dark)
);
document.body.classList.add(conditionalString(appStyles[theme]));
};
const usePreview = (context: Context): [boolean, PreviewConfig?] => {
const [previewConfig, setPreviewConfig] = useState<PreviewConfig>();
const { setExperienceSettings, setPlatform } = context;
const { preview } = parseQueryParameters(window.location.search);
const isPreview = preview === 'true';
const { isPreview, setExperienceSettings, setPlatform, setTheme } = context;
useEffect(() => {
if (!isPreview) {
@ -80,13 +67,13 @@ const usePreview = (context: Context): [boolean, PreviewConfig?] => {
};
(async () => {
applyTheme(mode);
setTheme(mode);
setPlatform(platform);
setExperienceSettings(experienceSettings);
})();
}, [isPreview, previewConfig, setExperienceSettings, setPlatform]);
}, [isPreview, previewConfig, setExperienceSettings, setPlatform, setTheme]);
useEffect(() => {
if (!isPreview || !previewConfig?.language) {

View file

@ -8,9 +8,18 @@ const darkThemeWatchMedia = window.matchMedia('(prefers-color-scheme: dark)');
const getThemeBySystemConfiguration = (): Theme => (darkThemeWatchMedia.matches ? 'dark' : 'light');
export default function useTheme(): Theme {
const { experienceSettings, theme, setTheme } = useContext(PageContext);
const { isPreview, experienceSettings, theme, setTheme } = useContext(PageContext);
useEffect(() => {
/**
* Note:
* In preview mode, the theme of the page is controlled by the preview options and does not follow system changes.
* The `usePreview` hook changes the theme of the page by calling the `setTheme` API of the `PageContext`.
*/
if (isPreview) {
return;
}
if (!experienceSettings?.color.isDarkModeEnabled) {
return;
}
@ -26,7 +35,7 @@ export default function useTheme(): Theme {
return () => {
darkThemeWatchMedia.removeEventListener('change', changeTheme);
};
}, [experienceSettings, setTheme]);
}, [experienceSettings, isPreview, setTheme]);
return theme;
}