From 9fa13a24ae2e1b3024b3ef2169736d27847f04eb Mon Sep 17 00:00:00 2001 From: simeng-li Date: Thu, 19 May 2022 14:21:14 +0800 Subject: [PATCH] feat(ui): add darkmode logo (#880) * feat(ui): add darkmode logo add darkmode logo * fix(ui): cr fix cr fix --- packages/ui/src/hooks/use-page-context.ts | 11 +++++++++-- packages/ui/src/hooks/use-theme.ts | 21 ++++++++++++--------- packages/ui/src/pages/SignIn/index.tsx | 20 +++++++++++++------- packages/ui/src/types/index.ts | 2 ++ 4 files changed, 36 insertions(+), 18 deletions(-) diff --git a/packages/ui/src/hooks/use-page-context.ts b/packages/ui/src/hooks/use-page-context.ts index a27090cfa..2e9a7924f 100644 --- a/packages/ui/src/hooks/use-page-context.ts +++ b/packages/ui/src/hooks/use-page-context.ts @@ -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({ 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({ const usePageContext = () => { const [loading, setLoading] = useState(false); const [toast, setToast] = useState(''); + const [theme, setTheme] = useState('light'); const [platform, setPlatform] = useState(isMobile ? 'mobile' : 'web'); const [experienceSettings, setExperienceSettings] = useState(); 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 { diff --git a/packages/ui/src/hooks/use-theme.ts b/packages/ui/src/hooks/use-theme.ts index c6bf52734..e20e869b9 100644 --- a/packages/ui/src/hooks/use-theme.ts +++ b/packages/ui/src/hooks/use-theme.ts @@ -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( - 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; } diff --git a/packages/ui/src/pages/SignIn/index.tsx b/packages/ui/src/pages/SignIn/index.tsx index 2c0ed2b5f..472a3a899 100644 --- a/packages/ui/src/pages/SignIn/index.tsx +++ b/packages/ui/src/pages/SignIn/index.tsx @@ -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 (
- + - +
); }; diff --git a/packages/ui/src/types/index.ts b/packages/ui/src/types/index.ts index e4088d84f..6379ba3c7 100644 --- a/packages/ui/src/types/index.ts +++ b/packages/ui/src/types/index.ts @@ -16,6 +16,8 @@ export enum SearchParameters { export type Platform = 'web' | 'mobile'; +export type Theme = 'dark' | 'light'; + export interface ConnectorData extends ConnectorMetadata { id: string; }