diff --git a/js/apps/account-ui/maven-resources/theme/keycloak.v3/account/index.ftl b/js/apps/account-ui/maven-resources/theme/keycloak.v3/account/index.ftl index f75cd0e8a7..05fac16fec 100644 --- a/js/apps/account-ui/maven-resources/theme/keycloak.v3/account/index.ftl +++ b/js/apps/account-ui/maven-resources/theme/keycloak.v3/account/index.ftl @@ -25,7 +25,8 @@ .keycloak__loading-container { height: 100vh; width: 100%; - background-color: #f0f0f0; + color: #151515; + background-color: #fff; display: flex; align-items: center; justify-content: center; @@ -33,6 +34,13 @@ margin: 0; } + @media (prefers-color-scheme: dark) { + .keycloak__loading-container { + color: #e0e0e0; + background-color: #1b1d21; + } + } + #loading-text { z-index: 1000; font-size: 20px; diff --git a/js/apps/account-ui/src/main.tsx b/js/apps/account-ui/src/main.tsx index 1955609d11..f756e540bd 100644 --- a/js/apps/account-ui/src/main.tsx +++ b/js/apps/account-ui/src/main.tsx @@ -1,13 +1,15 @@ import "@patternfly/react-core/dist/styles/base.css"; import "@patternfly/patternfly/patternfly-addons.css"; +import { initializeDarkMode } from "@keycloak/keycloak-ui-shared"; import { StrictMode } from "react"; import { createRoot } from "react-dom/client"; import { createBrowserRouter, RouterProvider } from "react-router-dom"; - import { i18n } from "./i18n"; import { routes } from "./routes"; +initializeDarkMode(); + // Initialize required components before rendering app. await i18n.init(); diff --git a/js/apps/admin-ui/maven-resources/theme/keycloak.v2/admin/index.ftl b/js/apps/admin-ui/maven-resources/theme/keycloak.v2/admin/index.ftl index 8dad4d87c2..088eaa723e 100644 --- a/js/apps/admin-ui/maven-resources/theme/keycloak.v2/admin/index.ftl +++ b/js/apps/admin-ui/maven-resources/theme/keycloak.v2/admin/index.ftl @@ -25,7 +25,8 @@ .keycloak__loading-container { height: 100vh; width: 100%; - background-color: #f0f0f0; + color: #151515; + background-color: #fff; display: flex; align-items: center; justify-content: center; @@ -33,6 +34,13 @@ margin: 0; } + @media (prefers-color-scheme: dark) { + .keycloak__loading-container { + color: #e0e0e0; + background-color: #1b1d21; + } + } + #loading-text { z-index: 1000; font-size: 20px; diff --git a/js/apps/admin-ui/src/components/dropdown-panel/DropdownPanel.tsx b/js/apps/admin-ui/src/components/dropdown-panel/DropdownPanel.tsx index b40230501d..b37951c187 100644 --- a/js/apps/admin-ui/src/components/dropdown-panel/DropdownPanel.tsx +++ b/js/apps/admin-ui/src/components/dropdown-panel/DropdownPanel.tsx @@ -1,7 +1,6 @@ import { useEffect, useRef } from "react"; import { Icon } from "@patternfly/react-core"; import { CaretDownIcon } from "@patternfly/react-icons"; -import { mediaQuery } from "../../util"; import "./dropdown-panel.css"; type DropdownPanelProps = { @@ -64,15 +63,7 @@ const DropdownPanel: React.FC = ({ {searchDropdownOpen && ( -
- {children} -
+
{children}
)} ); diff --git a/js/apps/admin-ui/src/components/dropdown-panel/dropdown-panel.css b/js/apps/admin-ui/src/components/dropdown-panel/dropdown-panel.css index 4d57ed3797..67dc48b53d 100644 --- a/js/apps/admin-ui/src/components/dropdown-panel/dropdown-panel.css +++ b/js/apps/admin-ui/src/components/dropdown-panel/dropdown-panel.css @@ -36,10 +36,8 @@ z-index: 1; } -.light-mode { - background-color: var(--pf-v5-global--Color--light-100); -} - -.dark-mode { - background-color: var(--pf-v5-global--BackgroundColor--300); +@media (prefers-color-scheme: dark) { + .kc-dropdown-panel-content { + background-color: var(--pf-v5-global--BackgroundColor--300); + } } diff --git a/js/apps/admin-ui/src/main.tsx b/js/apps/admin-ui/src/main.tsx index 76c6acb362..4219348065 100644 --- a/js/apps/admin-ui/src/main.tsx +++ b/js/apps/admin-ui/src/main.tsx @@ -1,6 +1,7 @@ import "@patternfly/patternfly/patternfly-addons.css"; import "@patternfly/react-core/dist/styles/base.css"; +import { initializeDarkMode } from "@keycloak/keycloak-ui-shared"; import { StrictMode } from "react"; import { createRoot } from "react-dom/client"; import { createHashRouter, RouterProvider } from "react-router-dom"; @@ -9,6 +10,8 @@ import { RootRoute } from "./routes"; import "./index.css"; +initializeDarkMode(); + // Initialize required components before rendering app. await i18n.init(); diff --git a/js/apps/admin-ui/src/util.ts b/js/apps/admin-ui/src/util.ts index c4965a92a2..8dbf65619f 100644 --- a/js/apps/admin-ui/src/util.ts +++ b/js/apps/admin-ui/src/util.ts @@ -179,22 +179,3 @@ export const localeToDisplayName = (locale: string, displayLocale: string) => { return locale; } }; - -const DARK_MODE_CLASS = "pf-v5-theme-dark"; -export const mediaQuery = - window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)"); - -updateDarkMode(mediaQuery?.matches); -mediaQuery?.addEventListener("change", (event: MediaQueryListEvent) => - updateDarkMode(event.matches), -); - -function updateDarkMode(isEnabled: boolean = false) { - const { classList } = document.documentElement; - - if (isEnabled) { - classList.add(DARK_MODE_CLASS); - } else { - classList.remove(DARK_MODE_CLASS); - } -} diff --git a/js/libs/ui-shared/src/main.ts b/js/libs/ui-shared/src/main.ts index 6eb7c5d760..b4334dc271 100644 --- a/js/libs/ui-shared/src/main.ts +++ b/js/libs/ui-shared/src/main.ts @@ -93,3 +93,4 @@ export { } from "./utils/ErrorBoundary"; export type { FallbackProps } from "./utils/ErrorBoundary"; export { OrganizationTable } from "./controls/OrganizationTable"; +export { initializeDarkMode } from "./utils/darkMode"; diff --git a/js/libs/ui-shared/src/utils/darkMode.ts b/js/libs/ui-shared/src/utils/darkMode.ts new file mode 100644 index 0000000000..fb845b3606 --- /dev/null +++ b/js/libs/ui-shared/src/utils/darkMode.ts @@ -0,0 +1,19 @@ +const DARK_MODE_CLASS = "pf-v5-theme-dark"; +const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)"); + +function updateDarkMode(isEnabled: boolean) { + const { classList } = document.documentElement; + + if (isEnabled) { + classList.add(DARK_MODE_CLASS); + } else { + classList.remove(DARK_MODE_CLASS); + } +} + +export function initializeDarkMode() { + updateDarkMode(mediaQuery.matches); + mediaQuery.addEventListener("change", (event) => + updateDarkMode(event.matches), + ); +}