0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2025-01-27 21:39:16 -05:00

feat(ui): add darkmode logo (#880)

* feat(ui): add darkmode logo

add darkmode logo

* fix(ui): cr fix

cr fix
This commit is contained in:
simeng-li 2022-05-19 14:21:14 +08:00 committed by GitHub
parent a2cd983d97
commit 9fa13a24ae
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 36 additions and 18 deletions

View file

@ -1,15 +1,17 @@
import { useState, useMemo, createContext } from 'react';
import { isMobile } from 'react-device-detect';
import { SignInExperienceSettings, Platform } from '@/types';
import { SignInExperienceSettings, Platform, Theme } from '@/types';
type Context = {
theme: Theme;
toast: string;
loading: boolean;
platform: Platform;
termsAgreement: boolean;
showTermsModal: boolean;
experienceSettings: SignInExperienceSettings | undefined;
setTheme: (theme: Theme) => void;
setToast: (message: string) => void;
setLoading: (loading: boolean) => void;
setPlatform: (platform: Platform) => void;
@ -24,11 +26,13 @@ const noop = () => {
export const PageContext = createContext<Context>({
toast: '',
theme: 'light',
loading: false,
platform: isMobile ? 'mobile' : 'web',
termsAgreement: false,
showTermsModal: false,
experienceSettings: undefined,
setTheme: noop,
setToast: noop,
setLoading: noop,
setPlatform: noop,
@ -40,6 +44,7 @@ export const PageContext = createContext<Context>({
const usePageContext = () => {
const [loading, setLoading] = useState(false);
const [toast, setToast] = useState('');
const [theme, setTheme] = useState<Theme>('light');
const [platform, setPlatform] = useState<Platform>(isMobile ? 'mobile' : 'web');
const [experienceSettings, setExperienceSettings] = useState<SignInExperienceSettings>();
const [termsAgreement, setTermsAgreement] = useState(false);
@ -47,12 +52,14 @@ const usePageContext = () => {
const context = useMemo(
() => ({
theme,
toast,
loading,
platform,
termsAgreement,
showTermsModal,
experienceSettings,
setTheme,
setLoading,
setToast,
setPlatform,
@ -60,7 +67,7 @@ const usePageContext = () => {
setShowTermsModal,
setExperienceSettings,
}),
[experienceSettings, loading, platform, showTermsModal, termsAgreement, toast]
[experienceSettings, loading, platform, showTermsModal, termsAgreement, theme, toast]
);
return {

View file

@ -1,21 +1,24 @@
import { AppearanceMode } from '@logto/schemas';
import { useState, useEffect, useContext } from 'react';
import { useEffect, useContext } from 'react';
import { Theme } from '@/types';
import { PageContext } from './use-page-context';
export type Theme = 'dark' | 'light';
const darkThemeWatchMedia = window.matchMedia('(prefers-color-scheme: dark)');
const getThemeBySystemConfiguration = (): Theme => (darkThemeWatchMedia.matches ? 'dark' : 'light');
export default function useTheme(mode: AppearanceMode = AppearanceMode.SyncWithSystem): Theme {
const { experienceSettings } = useContext(PageContext);
const [theme, setTheme] = useState<Theme>(
mode === AppearanceMode.SyncWithSystem ? 'light' : mode
);
const { experienceSettings, theme, setTheme } = useContext(PageContext);
useEffect(() => {
if (mode !== AppearanceMode.SyncWithSystem || !experienceSettings?.branding.isDarkModeEnabled) {
if (mode !== AppearanceMode.SyncWithSystem) {
setTheme(mode);
return;
}
if (!experienceSettings?.branding.isDarkModeEnabled) {
return;
}
@ -30,7 +33,7 @@ export default function useTheme(mode: AppearanceMode = AppearanceMode.SyncWithS
return () => {
darkThemeWatchMedia.removeEventListener('change', changeTheme);
};
}, [experienceSettings, mode]);
}, [experienceSettings, mode, setTheme]);
return theme;
}

View file

@ -9,22 +9,28 @@ import * as styles from './index.module.scss';
import { PrimarySection, SecondarySection, CreateAccountLink } from './registry';
const SignIn = () => {
const { experienceSettings } = useContext(PageContext);
const { slogan, logoUrl = '', style } = experienceSettings?.branding ?? {};
const { experienceSettings, theme } = useContext(PageContext);
if (!experienceSettings) {
return null;
}
const { slogan, logoUrl, darkLogoUrl, style } = experienceSettings.branding;
const logo = theme === 'light' ? logoUrl : darkLogoUrl ?? logoUrl;
return (
<div className={classNames(styles.wrapper)}>
<BrandingHeader
className={styles.header}
headline={style === BrandingStyle.Logo_Slogan ? slogan : undefined}
logo={logoUrl}
logo={logo}
/>
<PrimarySection signInMethod={experienceSettings?.primarySignInMethod} />
<PrimarySection signInMethod={experienceSettings.primarySignInMethod} />
<SecondarySection
primarySignInMethod={experienceSettings?.primarySignInMethod}
secondarySignInMethods={experienceSettings?.secondarySignInMethods}
primarySignInMethod={experienceSettings.primarySignInMethod}
secondarySignInMethods={experienceSettings.secondarySignInMethods}
/>
<CreateAccountLink primarySignInMethod={experienceSettings?.primarySignInMethod} />
<CreateAccountLink primarySignInMethod={experienceSettings.primarySignInMethod} />
</div>
);
};

View file

@ -16,6 +16,8 @@ export enum SearchParameters {
export type Platform = 'web' | 'mobile';
export type Theme = 'dark' | 'light';
export interface ConnectorData extends ConnectorMetadata {
id: string;
}