@@ -32,11 +32,11 @@ const ToggleThemeButton = ({
className={classNames(styles.button, className)}
icon={}
onClick={() => {
- onToggle(value === Theme.LightMode ? Theme.DarkMode : Theme.LightMode);
+ onToggle(value === Theme.Light ? Theme.Dark : Theme.Light);
}}
/>
);
};
-export default ToggleThemeButton;
+export default ToggleUiThemeButton;
diff --git a/packages/console/src/components/SignInExperiencePreview/index.tsx b/packages/console/src/components/SignInExperiencePreview/index.tsx
index 5b926e0d8..6250481e2 100644
--- a/packages/console/src/components/SignInExperiencePreview/index.tsx
+++ b/packages/console/src/components/SignInExperiencePreview/index.tsx
@@ -1,6 +1,6 @@
import type { LanguageTag } from '@logto/language-kit';
import type { ConnectorMetadata, ConnectorResponse, SignInExperience } from '@logto/schemas';
-import { ConnectorType } from '@logto/schemas';
+import { Theme, ConnectorType } from '@logto/schemas';
import { conditional } from '@silverhand/essentials';
import classNames from 'classnames';
import { format } from 'date-fns';
@@ -12,11 +12,12 @@ import PhoneInfo from '@/assets/images/phone-info.svg';
import { AppEndpointsContext } from '@/contexts/AppEndpointsProvider';
import type { RequestError } from '@/hooks/use-api';
import useUiLanguages from '@/hooks/use-ui-languages';
-import { Theme } from '@/types/theme';
import * as styles from './index.module.scss';
import { PreviewPlatform } from './types';
+export { default as ToggleUiThemeButton } from './components/ToggleUiThemeButton';
+
type Props = {
platform: PreviewPlatform;
mode: Theme;
@@ -114,7 +115,7 @@ const SignInExperiencePreview = ({ platform, mode, language = 'en', signInExperi
style={conditional(
platform === PreviewPlatform.DesktopWeb && {
// Set background color to match iframe's background color on both dark and light mode.
- backgroundColor: mode === Theme.DarkMode ? '#000' : '#e5e1ec',
+ backgroundColor: mode === Theme.Dark ? '#000' : '#e5e1ec',
}
)}
>
diff --git a/packages/console/src/components/Table/TableError.tsx b/packages/console/src/components/Table/TableError.tsx
index 17e92e13c..070ba1c83 100644
--- a/packages/console/src/components/Table/TableError.tsx
+++ b/packages/console/src/components/Table/TableError.tsx
@@ -1,10 +1,9 @@
-import { useContext } from 'react';
+import { Theme } from '@logto/schemas';
import { useTranslation } from 'react-i18next';
import RequestErrorDarkImage from '@/assets/images/request-error-dark.svg';
import RequestErrorImage from '@/assets/images/request-error.svg';
-import { AppThemeContext } from '@/contexts/AppThemeProvider';
-import { Theme } from '@/types/theme';
+import useTheme from '@/hooks/use-theme';
import Button from '../Button';
import * as styles from './TableError.module.scss';
@@ -18,13 +17,13 @@ type Props = {
const TableError = ({ title, content, onRetry, columns }: Props) => {
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
- const { theme } = useContext(AppThemeContext);
+ const theme = useTheme();
return (
- {theme === Theme.LightMode ? : }
+ {theme === Theme.Light ? : }
{title ?? t('errors.something_went_wrong')}
{content ?? t('errors.unknown_server_error')}
{onRetry && }
diff --git a/packages/console/src/components/Table/TablePlaceholder.tsx b/packages/console/src/components/Table/TablePlaceholder.tsx
index ee0785207..7cc9152ea 100644
--- a/packages/console/src/components/Table/TablePlaceholder.tsx
+++ b/packages/console/src/components/Table/TablePlaceholder.tsx
@@ -1,10 +1,9 @@
import type { AdminConsoleKey } from '@logto/phrases';
+import { Theme } from '@logto/schemas';
import type { ReactNode } from 'react';
-import { useContext } from 'react';
import { useTranslation } from 'react-i18next';
-import { AppThemeContext } from '@/contexts/AppThemeProvider';
-import { Theme } from '@/types/theme';
+import useTheme from '@/hooks/use-theme';
import TextLink from '../TextLink';
import * as styles from './TablePlaceholder.module.scss';
@@ -27,11 +26,11 @@ const TablePlaceholder = ({
action,
}: Props) => {
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
- const { theme } = useContext(AppThemeContext);
+ const theme = useTheme();
return (
- {theme === Theme.LightMode ? image : imageDark}
+ {theme === Theme.Light ? image : imageDark}
{t(title)}
{t(description)}
diff --git a/packages/console/src/components/UserAvatar/index.tsx b/packages/console/src/components/UserAvatar/index.tsx
index b274be97b..c4f94eabd 100644
--- a/packages/console/src/components/UserAvatar/index.tsx
+++ b/packages/console/src/components/UserAvatar/index.tsx
@@ -1,11 +1,10 @@
+import { Theme } from '@logto/schemas';
import type { Nullable } from '@silverhand/essentials';
import classNames from 'classnames';
-import { useContext } from 'react';
import DarkAvatar from '@/assets/images/default-avatar-dark.svg';
import LightAvatar from '@/assets/images/default-avatar-light.svg';
-import { AppThemeContext } from '@/contexts/AppThemeProvider';
-import { Theme } from '@/types/theme';
+import useTheme from '@/hooks/use-theme';
import ImageWithErrorFallback from '../ImageWithErrorFallback';
import * as styles from './index.module.scss';
@@ -17,8 +16,8 @@ type Props = {
};
const UserAvatar = ({ className, url, size = 'medium' }: Props) => {
- const { theme } = useContext(AppThemeContext);
- const DefaultAvatar = theme === Theme.LightMode ? LightAvatar : DarkAvatar;
+ const theme = useTheme();
+ const DefaultAvatar = theme === Theme.Light ? LightAvatar : DarkAvatar;
const avatarClassName = classNames(styles.avatar, styles[size], className);
if (url) {
diff --git a/packages/console/src/consts/index.ts b/packages/console/src/consts/index.ts
index 370139ff0..b6d3dc70e 100644
--- a/packages/console/src/consts/index.ts
+++ b/packages/console/src/consts/index.ts
@@ -6,7 +6,7 @@ export * from './tenants';
export * from './page-tabs';
export * from './external-links';
-export const themeStorageKey = 'logto:admin_console:theme';
+export const appearanceModeStorageKey = 'logto:admin_console:appearance_mode';
export const profileSocialLinkingKeyPrefix = 'logto:admin_console:linking_social_connector';
export const requestTimeout = 20_000;
export const defaultPageSize = 20;
diff --git a/packages/console/src/containers/AppContent/components/UserInfo/index.tsx b/packages/console/src/containers/AppContent/components/UserInfo/index.tsx
index 371699f6a..ae5e68815 100644
--- a/packages/console/src/containers/AppContent/components/UserInfo/index.tsx
+++ b/packages/console/src/containers/AppContent/components/UserInfo/index.tsx
@@ -1,6 +1,6 @@
import { builtInLanguageOptions as consoleBuiltInLanguageOptions } from '@logto/phrases';
import { useLogto } from '@logto/react';
-import { AppearanceMode } from '@logto/schemas';
+import { Theme } from '@logto/schemas';
import classNames from 'classnames';
import { useRef, useState } from 'react';
import { useTranslation } from 'react-i18next';
@@ -19,6 +19,7 @@ import UserInfoCard from '@/components/UserInfoCard';
import { getSignOutRedirectPathname } from '@/consts';
import useCurrentUser from '@/hooks/use-current-user';
import useUserPreferences from '@/hooks/use-user-preferences';
+import { DynamicAppearanceMode } from '@/types/appearance-mode';
import { onKeyDownHandler } from '@/utils/a11y';
import SubMenu from '../SubMenu';
@@ -98,15 +99,15 @@ const UserInfo = () => {
title="menu.appearance.label"
options={[
{
- value: AppearanceMode.SyncWithSystem,
+ value: DynamicAppearanceMode.System,
title: t('menu.appearance.system'),
},
{
- value: AppearanceMode.LightMode,
+ value: Theme.Light,
title: t('menu.appearance.light'),
},
{
- value: AppearanceMode.DarkMode,
+ value: Theme.Dark,
title: t('menu.appearance.dark'),
},
]}
diff --git a/packages/console/src/containers/ConsoleContent/Sidebar/components/Contact/hook.tsx b/packages/console/src/containers/ConsoleContent/Sidebar/components/Contact/hook.tsx
index 2d82ad9e3..e3640f7b1 100644
--- a/packages/console/src/containers/ConsoleContent/Sidebar/components/Contact/hook.tsx
+++ b/packages/console/src/containers/ConsoleContent/Sidebar/components/Contact/hook.tsx
@@ -1,5 +1,5 @@
import type { AdminConsoleKey } from '@logto/phrases';
-import { useContext } from 'react';
+import { Theme } from '@logto/schemas';
import DiscordDark from '@/assets/images/discord-dark.svg';
import Discord from '@/assets/images/discord.svg';
@@ -8,8 +8,7 @@ import Email from '@/assets/images/email.svg';
import GithubDark from '@/assets/images/github-dark.svg';
import Github from '@/assets/images/github.svg';
import { contactEmailLink, discordLink, githubIssuesLink } from '@/consts';
-import { AppThemeContext } from '@/contexts/AppThemeProvider';
-import { Theme } from '@/types/theme';
+import useTheme from '@/hooks/use-theme';
type ContactItem = {
icon: SvgComponent;
@@ -20,8 +19,8 @@ type ContactItem = {
};
export const useContacts = (): ContactItem[] => {
- const { theme } = useContext(AppThemeContext);
- const isLightMode = theme === Theme.LightMode;
+ const theme = useTheme();
+ const isLightMode = theme === Theme.Light;
return [
{
diff --git a/packages/console/src/contexts/AppThemeProvider/index.tsx b/packages/console/src/contexts/AppThemeProvider/index.tsx
index d2d8216a8..244e1a496 100644
--- a/packages/console/src/contexts/AppThemeProvider/index.tsx
+++ b/packages/console/src/contexts/AppThemeProvider/index.tsx
@@ -1,10 +1,10 @@
-import { AppearanceMode } from '@logto/schemas';
+import { Theme } from '@logto/schemas';
import { conditionalString } from '@silverhand/essentials';
import type { ReactNode } from 'react';
import { useEffect, useMemo, useState, createContext } from 'react';
import useUserPreferences from '@/hooks/use-user-preferences';
-import { Theme } from '@/types/theme';
+import { DynamicAppearanceMode } from '@/types/appearance-mode';
import * as styles from './index.module.scss';
@@ -17,16 +17,18 @@ type AppTheme = {
theme: Theme;
};
+const defaultTheme: Theme = Theme.Light;
+
const darkThemeWatchMedia = window.matchMedia('(prefers-color-scheme: dark)');
const getThemeBySystemConfiguration = (): Theme =>
- darkThemeWatchMedia.matches ? Theme.DarkMode : Theme.LightMode;
+ darkThemeWatchMedia.matches ? Theme.Dark : Theme.Light;
export const AppThemeContext = createContext ({
- theme: Theme.LightMode,
+ theme: defaultTheme,
});
export const AppThemeProvider = ({ fixedTheme, children }: Props) => {
- const [theme, setTheme] = useState(Theme.LightMode);
+ const [theme, setTheme] = useState(defaultTheme);
const {
data: { appearanceMode },
@@ -39,8 +41,8 @@ export const AppThemeProvider = ({ fixedTheme, children }: Props) => {
return;
}
- if (appearanceMode !== AppearanceMode.SyncWithSystem) {
- setTheme(appearanceMode === AppearanceMode.LightMode ? Theme.LightMode : Theme.DarkMode);
+ if (appearanceMode !== DynamicAppearanceMode.System) {
+ setTheme(appearanceMode);
return;
}
diff --git a/packages/console/src/hooks/use-theme.ts b/packages/console/src/hooks/use-theme.ts
new file mode 100644
index 000000000..8549a5edc
--- /dev/null
+++ b/packages/console/src/hooks/use-theme.ts
@@ -0,0 +1,11 @@
+import { useContext } from 'react';
+
+import { AppThemeContext } from '@/contexts/AppThemeProvider';
+
+const useTheme = () => {
+ const { theme } = useContext(AppThemeContext);
+
+ return theme;
+};
+
+export default useTheme;
diff --git a/packages/console/src/hooks/use-user-preferences.ts b/packages/console/src/hooks/use-user-preferences.ts
index 1c2a54bd9..8e8f49e91 100644
--- a/packages/console/src/hooks/use-user-preferences.ts
+++ b/packages/console/src/hooks/use-user-preferences.ts
@@ -1,10 +1,10 @@
import { builtInLanguages as builtInConsoleLanguages } from '@logto/phrases';
-import { AppearanceMode } from '@logto/schemas';
-import type { Nullable, Optional } from '@silverhand/essentials';
import { useEffect, useMemo } from 'react';
import { z } from 'zod';
-import { themeStorageKey } from '@/consts';
+import { appearanceModeStorageKey } from '@/consts';
+import { appearanceModeGuard } from '@/types/appearance-mode';
+import { getAppearanceModeFromLocalStorage } from '@/utils/theme';
import useMeCustomData from './use-me-custom-data';
@@ -12,7 +12,7 @@ const adminConsolePreferencesKey = 'adminConsolePreferences';
const userPreferencesGuard = z.object({
language: z.enum(builtInConsoleLanguages).optional(),
- appearanceMode: z.nativeEnum(AppearanceMode),
+ appearanceMode: appearanceModeGuard,
experienceNoticeConfirmed: z.boolean().optional(),
getStartedHidden: z.boolean().optional(),
connectorSieNoticeConfirmed: z.boolean().optional(),
@@ -20,11 +20,6 @@ const userPreferencesGuard = z.object({
export type UserPreferences = z.infer;
-const getEnumFromArray = (
- array: T[],
- value: Nullable>
-): Optional => array.find((element) => element === value);
-
const useUserPreferences = () => {
const { data, error, isLoading, isLoaded, update: updateMeCustomData } = useMeCustomData();
@@ -34,11 +29,7 @@ const useUserPreferences = () => {
return parsed.success
? parsed.data[adminConsolePreferencesKey]
: {
- appearanceMode:
- getEnumFromArray(
- Object.values(AppearanceMode),
- localStorage.getItem(themeStorageKey)
- ) ?? AppearanceMode.SyncWithSystem,
+ appearanceMode: getAppearanceModeFromLocalStorage(),
};
}, [data]);
@@ -52,7 +43,7 @@ const useUserPreferences = () => {
};
useEffect(() => {
- localStorage.setItem(themeStorageKey, userPreferences.appearanceMode);
+ localStorage.setItem(appearanceModeStorageKey, userPreferences.appearanceMode);
}, [userPreferences.appearanceMode]);
return {
diff --git a/packages/console/src/onboarding/App.tsx b/packages/console/src/onboarding/App.tsx
index 5d5ef9b6b..68dd49a11 100644
--- a/packages/console/src/onboarding/App.tsx
+++ b/packages/console/src/onboarding/App.tsx
@@ -1,3 +1,4 @@
+import { Theme } from '@logto/schemas';
import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom';
import { SWRConfig } from 'swr';
@@ -8,7 +9,6 @@ import AppBoundary from '@/containers/AppBoundary';
import { AppThemeProvider } from '@/contexts/AppThemeProvider';
import useSwrOptions from '@/hooks/use-swr-options';
import NotFound from '@/pages/NotFound';
-import { Theme } from '@/types/theme';
import * as styles from './App.module.scss';
import AppContent from './containers/AppContent';
@@ -38,7 +38,7 @@ const App = () => {
-
+
diff --git a/packages/console/src/onboarding/pages/SignInExperience/components/Preview/index.tsx b/packages/console/src/onboarding/pages/SignInExperience/components/Preview/index.tsx
index d980c36b5..6e339b79d 100644
--- a/packages/console/src/onboarding/pages/SignInExperience/components/Preview/index.tsx
+++ b/packages/console/src/onboarding/pages/SignInExperience/components/Preview/index.tsx
@@ -1,4 +1,5 @@
import type { SignInExperience } from '@logto/schemas';
+import { Theme } from '@logto/schemas';
import { conditional } from '@silverhand/essentials';
import classNames from 'classnames';
import { useState } from 'react';
@@ -6,7 +7,6 @@ import { useState } from 'react';
import LivePreviewButton from '@/components/LivePreviewButton';
import SignInExperiencePreview from '@/components/SignInExperiencePreview';
import { PreviewPlatform } from '@/components/SignInExperiencePreview/types';
-import { Theme } from '@/types/theme';
import PlatformTabs from '../PlatformTabs';
import * as styles from './index.module.scss';
@@ -32,7 +32,7 @@ const Preview = ({ signInExperience, isLivePreviewDisabled = false, className }:
diff --git a/packages/console/src/pages/ApiResourceDetails/index.tsx b/packages/console/src/pages/ApiResourceDetails/index.tsx
index dff4dc02b..9e66614f1 100644
--- a/packages/console/src/pages/ApiResourceDetails/index.tsx
+++ b/packages/console/src/pages/ApiResourceDetails/index.tsx
@@ -1,7 +1,7 @@
import type { Resource } from '@logto/schemas';
-import { defaultManagementApi } from '@logto/schemas';
+import { defaultManagementApi, Theme } from '@logto/schemas';
import classNames from 'classnames';
-import { useContext, useEffect, useState } from 'react';
+import { useEffect, useState } from 'react';
import { toast } from 'react-hot-toast';
import { Trans, useTranslation } from 'react-i18next';
import { Outlet, useLocation, useNavigate, useParams } from 'react-router-dom';
@@ -21,11 +21,10 @@ import RequestDataError from '@/components/RequestDataError';
import TabNav, { TabNavItem } from '@/components/TabNav';
import TextLink from '@/components/TextLink';
import { ApiResourceDetailsTabs } from '@/consts/page-tabs';
-import { AppThemeContext } from '@/contexts/AppThemeProvider';
import type { RequestError } from '@/hooks/use-api';
import useApi from '@/hooks/use-api';
+import useTheme from '@/hooks/use-theme';
import * as detailsStyles from '@/scss/details.module.scss';
-import { Theme } from '@/types/theme';
import * as styles from './index.module.scss';
import { ApiResourceDetailsOutletContext } from './types';
@@ -37,8 +36,8 @@ const ApiResourceDetails = () => {
const navigate = useNavigate();
const { data, error, mutate } = useSWR (id && `api/resources/${id}`);
const isLoading = !data && !error;
- const { theme } = useContext(AppThemeContext);
- const Icon = theme === Theme.LightMode ? ApiResource : ApiResourceDark;
+ const theme = useTheme();
+ const Icon = theme === Theme.Light ? ApiResource : ApiResourceDark;
const isOnPermissionPage = pathname.endsWith(ApiResourceDetailsTabs.Permissions);
const isLogtoManagementApiResource = data?.indicator === defaultManagementApi.resource.indicator;
diff --git a/packages/console/src/pages/ApiResources/index.tsx b/packages/console/src/pages/ApiResources/index.tsx
index 37df4019a..089673433 100644
--- a/packages/console/src/pages/ApiResources/index.tsx
+++ b/packages/console/src/pages/ApiResources/index.tsx
@@ -1,5 +1,5 @@
import type { Resource } from '@logto/schemas';
-import { useContext } from 'react';
+import { Theme } from '@logto/schemas';
import { toast } from 'react-hot-toast';
import { useTranslation } from 'react-i18next';
import Modal from 'react-modal';
@@ -18,12 +18,11 @@ import Pagination from '@/components/Pagination';
import Table from '@/components/Table';
import { defaultPageSize } from '@/consts';
import { ApiResourceDetailsTabs } from '@/consts/page-tabs';
-import { AppThemeContext } from '@/contexts/AppThemeProvider';
import type { RequestError } from '@/hooks/use-api';
import useSearchParametersWatcher from '@/hooks/use-search-parameters-watcher';
+import useTheme from '@/hooks/use-theme';
import * as modalStyles from '@/scss/modal.module.scss';
import * as resourcesStyles from '@/scss/resources.module.scss';
-import { Theme } from '@/types/theme';
import { buildUrl } from '@/utils/url';
import CreateForm from './components/CreateForm';
@@ -53,10 +52,10 @@ const ApiResources = () => {
const isLoading = !data && !error;
const navigate = useNavigate();
- const { theme } = useContext(AppThemeContext);
+ const theme = useTheme();
const [apiResources, totalCount] = data ?? [];
- const ResourceIcon = theme === Theme.LightMode ? ApiResource : ApiResourceDark;
+ const ResourceIcon = theme === Theme.Light ? ApiResource : ApiResourceDark;
return (
diff --git a/packages/console/src/pages/Applications/components/SdkSelector/index.tsx b/packages/console/src/pages/Applications/components/SdkSelector/index.tsx
index bad07c4f3..5b3689105 100644
--- a/packages/console/src/pages/Applications/components/SdkSelector/index.tsx
+++ b/packages/console/src/pages/Applications/components/SdkSelector/index.tsx
@@ -1,5 +1,6 @@
+import { Theme } from '@logto/schemas';
import classNames from 'classnames';
-import { useContext, useState } from 'react';
+import { useState } from 'react';
import { useTranslation } from 'react-i18next';
import CongratsDark from '@/assets/images/congrats-dark.svg';
@@ -11,9 +12,8 @@ import Card from '@/components/Card';
import RadioGroup, { Radio } from '@/components/RadioGroup';
import Select from '@/components/Select';
import Spacer from '@/components/Spacer';
-import { AppThemeContext } from '@/contexts/AppThemeProvider';
+import useTheme from '@/hooks/use-theme';
import type { SupportedSdk } from '@/types/applications';
-import { Theme } from '@/types/theme';
import * as styles from './index.module.scss';
@@ -36,8 +36,8 @@ const SdkSelector = ({
}: Props) => {
const [isFolded, setIsFolded] = useState(isCompact);
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
- const { theme } = useContext(AppThemeContext);
- const isLightMode = theme === Theme.LightMode;
+ const theme = useTheme();
+ const isLightMode = theme === Theme.Light;
const CongratsIcon = isLightMode ? Congrats : CongratsDark;
const TadaIcon = isLightMode ? Tada : TadaDark;
diff --git a/packages/console/src/pages/GetStarted/components/GetStartedProgress/index.tsx b/packages/console/src/pages/GetStarted/components/GetStartedProgress/index.tsx
index 33041b652..4a600077e 100644
--- a/packages/console/src/pages/GetStarted/components/GetStartedProgress/index.tsx
+++ b/packages/console/src/pages/GetStarted/components/GetStartedProgress/index.tsx
@@ -1,14 +1,14 @@
+import { Theme } from '@logto/schemas';
import classNames from 'classnames';
-import { useContext, useRef, useState } from 'react';
+import { useRef, useState } from 'react';
import { useTranslation } from 'react-i18next';
import TadaDark from '@/assets/images/tada-dark.svg';
import Tada from '@/assets/images/tada.svg';
import Dropdown, { DropdownItem } from '@/components/Dropdown';
import Index from '@/components/Index';
-import { AppThemeContext } from '@/contexts/AppThemeProvider';
+import useTheme from '@/hooks/use-theme';
import useUserPreferences from '@/hooks/use-user-preferences';
-import { Theme } from '@/types/theme';
import { onKeyDownHandler } from '@/utils/a11y';
import useGetStartedMetadata from '../../hook';
@@ -19,8 +19,8 @@ const GetStartedProgress = () => {
const {
data: { getStartedHidden },
} = useUserPreferences();
- const { theme } = useContext(AppThemeContext);
- const Icon = theme === Theme.LightMode ? Tada : TadaDark;
+ const theme = useTheme();
+ const Icon = theme === Theme.Light ? Tada : TadaDark;
const anchorRef = useRef (null);
const [showDropdown, setShowDropdown] = useState(false);
const { data, completedCount, totalCount } = useGetStartedMetadata();
diff --git a/packages/console/src/pages/GetStarted/hook.ts b/packages/console/src/pages/GetStarted/hook.ts
index e328a174a..f2d5aa93a 100644
--- a/packages/console/src/pages/GetStarted/hook.ts
+++ b/packages/console/src/pages/GetStarted/hook.ts
@@ -1,4 +1,5 @@
import type { AdminConsoleKey } from '@logto/phrases';
+import { Theme } from '@logto/schemas';
import { useContext, useMemo } from 'react';
import { useNavigate } from 'react-router-dom';
@@ -20,9 +21,8 @@ import { discordLink, githubLink } from '@/consts';
import { isCloud } from '@/consts/cloud';
import { ConnectorsTabs } from '@/consts/page-tabs';
import { AppEndpointsContext } from '@/contexts/AppEndpointsProvider';
-import { AppThemeContext } from '@/contexts/AppThemeProvider';
import useConfigs from '@/hooks/use-configs';
-import { Theme } from '@/types/theme';
+import useTheme from '@/hooks/use-theme';
type GetStartedMetadata = {
id: string;
@@ -38,8 +38,8 @@ type GetStartedMetadata = {
const useGetStartedMetadata = () => {
const { configs, updateConfigs } = useConfigs();
const { userEndpoint } = useContext(AppEndpointsContext);
- const { theme } = useContext(AppThemeContext);
- const isLightMode = theme === Theme.LightMode;
+ const theme = useTheme();
+ const isLightMode = theme === Theme.Light;
const navigate = useNavigate();
const data = useMemo(() => {
diff --git a/packages/console/src/pages/NotFound/index.tsx b/packages/console/src/pages/NotFound/index.tsx
index 48c6a90bb..3505224c0 100644
--- a/packages/console/src/pages/NotFound/index.tsx
+++ b/packages/console/src/pages/NotFound/index.tsx
@@ -1,22 +1,21 @@
-import { useContext } from 'react';
+import { Theme } from '@logto/schemas';
import { useTranslation } from 'react-i18next';
import NotFoundDarkImage from '@/assets/images/not-found-dark.svg';
import NotFoundImage from '@/assets/images/not-found.svg';
import Card from '@/components/Card';
-import { AppThemeContext } from '@/contexts/AppThemeProvider';
-import { Theme } from '@/types/theme';
+import useTheme from '@/hooks/use-theme';
import * as styles from './index.module.scss';
const NotFound = () => {
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
- const { theme } = useContext(AppThemeContext);
+ const theme = useTheme();
return (
- {theme === Theme.LightMode ? : }
+ {theme === Theme.Light ? : }
{t('errors.page_not_found')}
diff --git a/packages/console/src/pages/Profile/components/LinkAccountSection/index.tsx b/packages/console/src/pages/Profile/components/LinkAccountSection/index.tsx
index 72b661016..e9d002386 100644
--- a/packages/console/src/pages/Profile/components/LinkAccountSection/index.tsx
+++ b/packages/console/src/pages/Profile/components/LinkAccountSection/index.tsx
@@ -1,8 +1,9 @@
import { buildIdGenerator } from '@logto/core-kit';
import type { ConnectorResponse, UserInfo } from '@logto/schemas';
+import { Theme } from '@logto/schemas';
import type { Optional } from '@silverhand/essentials';
import { appendPath, conditional } from '@silverhand/essentials';
-import { useCallback, useContext, useMemo } from 'react';
+import { useCallback, useMemo } from 'react';
import { Trans, useTranslation } from 'react-i18next';
import { useNavigate } from 'react-router-dom';
import { is } from 'superstruct';
@@ -13,12 +14,11 @@ import ImageWithErrorFallback from '@/components/ImageWithErrorFallback';
import UnnamedTrans from '@/components/UnnamedTrans';
import UserInfoCard from '@/components/UserInfoCard';
import { adminTenantEndpoint, getBasename, meApi, profileSocialLinkingKeyPrefix } from '@/consts';
-import { AppThemeContext } from '@/contexts/AppThemeProvider';
import { useStaticApi } from '@/hooks/use-api';
import { useConfirmModal } from '@/hooks/use-confirm-modal';
+import useTheme from '@/hooks/use-theme';
import type { SocialUserInfo } from '@/types/profile';
import { socialUserInfoGuard } from '@/types/profile';
-import { Theme } from '@/types/theme';
import { popupWindow } from '../../utils';
import type { Row } from '../CardContent';
@@ -35,7 +35,7 @@ type Props = {
const LinkAccountSection = ({ user, connectors, onUpdate }: Props) => {
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
const navigate = useNavigate();
- const { theme } = useContext(AppThemeContext);
+ const theme = useTheme();
const { show: showConfirm } = useConfirmModal();
const api = useStaticApi({ prefixUrl: adminTenantEndpoint, resourceIndicator: meApi.indicator });
@@ -61,7 +61,7 @@ const LinkAccountSection = ({ user, connectors, onUpdate }: Props) => {
}
return connectors.map(({ id, name, logo, logoDark, target }) => {
- const logoSrc = theme === Theme.DarkMode && logoDark ? logoDark : logo;
+ const logoSrc = theme === Theme.Dark && logoDark ? logoDark : logo;
const relatedUserDetails = user.identities?.[target]?.details;
const hasLinked = is(relatedUserDetails, socialUserInfoGuard);
diff --git a/packages/console/src/pages/SignInExperience/components/Preview/index.tsx b/packages/console/src/pages/SignInExperience/components/Preview/index.tsx
index 6a5f923d2..75693b23b 100644
--- a/packages/console/src/pages/SignInExperience/components/Preview/index.tsx
+++ b/packages/console/src/pages/SignInExperience/components/Preview/index.tsx
@@ -1,18 +1,17 @@
import type { LanguageTag } from '@logto/language-kit';
import { languages as uiLanguageNameMapping } from '@logto/language-kit';
import type { SignInExperience } from '@logto/schemas';
+import { Theme } from '@logto/schemas';
import classNames from 'classnames';
import { useEffect, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import LivePreviewButton from '@/components/LivePreviewButton';
import Select from '@/components/Select';
-import SignInExperiencePreview from '@/components/SignInExperiencePreview';
+import SignInExperiencePreview, { ToggleUiThemeButton } from '@/components/SignInExperiencePreview';
import { PreviewPlatform } from '@/components/SignInExperiencePreview/types';
import TabNav, { TabNavItem } from '@/components/TabNav';
-import ToggleThemeButton from '@/components/ToggleThemeButton';
import useUiLanguages from '@/hooks/use-ui-languages';
-import { Theme } from '@/types/theme';
import * as styles from './index.module.scss';
@@ -31,13 +30,13 @@ const Preview = ({
}: Props) => {
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
const [language, setLanguage] = useState('en');
- const [mode, setMode] = useState(Theme.LightMode);
+ const [mode, setMode] = useState(Theme.Light);
const [platform, setPlatform] = useState(PreviewPlatform.DesktopWeb);
const { languages } = useUiLanguages();
useEffect(() => {
if (!signInExperience?.color.isDarkModeEnabled) {
- setMode(Theme.LightMode);
+ setMode(Theme.Light);
}
}, [mode, signInExperience]);
@@ -71,7 +70,7 @@ const Preview = ({
{t('sign_in_exp.preview.title')}
{signInExperience?.color.isDarkModeEnabled && (
-
+
)}
|