Skip to content

Commit e27199a

Browse files
committed
while not perfect, add dark theme support based on browser preference
Signed-off-by: Andre Nogueira <[email protected]>
1 parent 9994f12 commit e27199a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+1330
-154
lines changed

src/login/KcPage.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,15 @@ export default function KcPage(props: { kcContext: KcContext }) {
376376

377377
const classes = {
378378
kcInputGroup: "relative",
379+
kcFormHeaderClass: "text-primary-800 dark:text-primary-400 bg-white dark:bg-black",
380+
kcLabelClass: "text-primary-800 dark:text-primary-400",
381+
kcInputErrorMessageClass: "text-red-800 dark:text-red-400",
382+
kcRecoveryCodesList: "list-disc pl-5 text-primary-800 dark:text-primary-400 mb-2 break-words whitespace-pre-wrap border border-gray-300 dark:border-gray-700 rounded-md p-2 overflow-x-auto",
383+
kcRecoveryCodesWarning: "mb-4",
384+
kcFormOptionsClass: "text-primary-800 dark:text-primary-400 col-xs-12 col-sm-12 col-md-12 col-lg-12",
385+
kcSelectAuthListItemClass: "select-auth-box-parent pf-l-split text-primary-800 dark:text-primary-400 hover:bg-primary-100 dark:hover:bg-primary-800",
386+
kcLocaleItemClass: "pf-c-dropdown__menu-item text-primary-800 dark:text-primary-400 hover:bg-primary-100 dark:hover:bg-primary-800 bg-white dark:bg-black",
387+
kcInputWrapperClass: "text-primary-800 dark:text-primary-400",
379388
kcFormSocialAccountSectionClass: "",
380389
kcFormSocialAccountListClass: "",
381390
kcFormSocialAccountListGridClass: "",

src/login/Template.tsx

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@ import type { I18n } from "./i18n";
99
import type { KcContext } from "./KcContext";
1010
import useSetCookieConsent from "./useSetCookieConsent.tsx";
1111
// import logo from "./assets/logo.svg";
12-
import icon from "./assets/favicon.svg";
12+
import iconLightTheme from "./assets/favicon-light-theme.svg";
13+
import iconDarkTheme from "./assets/favicon-dark-theme.svg";
1314

1415
import Lottie from "lottie-react";
15-
import animationData from "./assets/logo.json"; // path to your Lottie JSON file
16+
import animationDataLightTheme from "./assets/logo-light-theme.json"; // path to your Lottie JSON file
17+
import animationDataDarkTheme from "./assets/logo-dark-theme.json"; // path to your Lottie JSON file
1618

1719
export default function Template(props: TemplateProps<KcContext, I18n>) {
1820
const {
@@ -35,7 +37,16 @@ export default function Template(props: TemplateProps<KcContext, I18n>) {
3537

3638
const { msg, msgStr, advancedMsgStr, currentLanguage, enabledLanguages } = i18n;
3739

38-
const { realm, auth, url, message, isAppInitiatedAction } = kcContext;
40+
let icon = iconDarkTheme;
41+
let animationData = animationDataDarkTheme;
42+
43+
const { auth, url, message, isAppInitiatedAction } = kcContext;
44+
45+
const darkThemeMq = window.matchMedia("(prefers-color-scheme: dark)");
46+
if (!darkThemeMq.matches) {
47+
icon = iconLightTheme;
48+
animationData = animationDataLightTheme;
49+
}
3950

4051
useEffect(() => {
4152
document.title = documentTitle ?? msgStr("loginTitle", kcContext.realm.displayName);
@@ -142,7 +153,7 @@ export default function Template(props: TemplateProps<KcContext, I18n>) {
142153

143154
useSetClassName({
144155
qualifiedName: "body",
145-
className: bodyClassName ?? kcClsx("kcBodyClass")
156+
className: bodyClassName ?? clsx(kcClsx("kcBodyClass"), darkThemeMq.matches ? "dark" : "light")
146157
});
147158

148159
const footerImprintUrl = advancedMsgStr("footerImprintUrl") !== "footerImprintUrl" ? advancedMsgStr("footerImprintUrl") : null;
@@ -162,7 +173,7 @@ export default function Template(props: TemplateProps<KcContext, I18n>) {
162173
<div
163174
className={clsx(
164175
kcClsx("kcLoginClass"),
165-
"bg-background flex flex-col items-center justify-center min-h-screen sm:py-16 overflow-x-hidden"
176+
"bg-background dark:bg-background-dark flex flex-col items-center justify-center min-h-screen sm:py-16 overflow-x-hidden"
166177
)}
167178
>
168179
<div id="kc-header">
@@ -196,8 +207,9 @@ export default function Template(props: TemplateProps<KcContext, I18n>) {
196207
)}
197208
</div>
198209

199-
<div className={clsx(kcClsx("kcFormCardClass"), "relative z-10 max-w-md w-full rounded-lg")}>
200-
<div className={"font-bold text-center text-2xl"}>{msg("loginTitleHtml", realm.displayNameHtml)}</div>
210+
<div className={clsx(kcClsx("kcFormCardClass"), "bg-white dark:bg-black relative z-10 max-w-md w-full rounded-lg")}>
211+
{/* Hide Realm */}
212+
{/* <div className={"text-primary-800 dark:text-primary-400 font-bold text-center text-2xl"}>{msg("loginTitleHtml", realm.displayNameHtml)}</div> */}
201213
<header className={clsx(kcClsx("kcFormHeaderClass"))}>
202214
{(() => {
203215
const node = !(auth !== undefined && auth.showUsername && !auth.showResetCredentials) ? (
@@ -270,7 +282,7 @@ export default function Template(props: TemplateProps<KcContext, I18n>) {
270282
document.forms["kc-select-try-another-way-form" as never].submit();
271283
return false;
272284
}}
273-
className="bg-secondary-100 text-secondary-600 focus:ring-secondary-600 hover:bg-secondary-200 hover:text-secondary-900 px-4 py-2 text-sm flex justify-center relative rounded-lg w-full focus:outline-none focus:ring-2 focus:ring-offset-2"
285+
className="bg-secondary-100 dark:bg-secondary-800 text-secondary-600 dark:text-secondary-300 focus:ring-secondary-600 dark:focus:ring-secondary-300 hover:bg-secondary-300 dark:hover:bg-secondary-600 hover:text-secondary-900 dark:hover:text-secondary-100 px-4 py-2 text-sm flex justify-center relative rounded-lg w-full focus:outline-none focus:ring-2 focus:ring-offset-2"
274286
>
275287
{msg("doTryAnotherWay")}
276288
</button>
@@ -279,7 +291,7 @@ export default function Template(props: TemplateProps<KcContext, I18n>) {
279291
)}
280292
{socialProvidersNode}
281293
{displayInfo && (
282-
<div className={"space-y-4"}>
294+
<div>
283295
<div id="kc-info-wrapper">{infoNode}</div>
284296
</div>
285297
)}
@@ -291,7 +303,7 @@ export default function Template(props: TemplateProps<KcContext, I18n>) {
291303
<section className={"flex flex-col ml-5"}>
292304
{(footerImprintUrl || kcContext.properties["TAILCLOAKIFY_FOOTER_IMPRINT_URL"]) && (
293305
<a
294-
className={"text-secondary-600 hover:text-secondary-900 text-sm inline-flex no-underline hover:no-underline"}
306+
className={"text-secondary-600 dark:text-secondary-300 hover:text-secondary-900 text-sm inline-flex no-underline hover:no-underline"}
295307
target={"_blank"}
296308
rel={"noopener noreferrer"}
297309
href={footerImprintUrl || kcContext.properties["TAILCLOAKIFY_FOOTER_IMPRINT_URL"]}
@@ -301,7 +313,7 @@ export default function Template(props: TemplateProps<KcContext, I18n>) {
301313
)}
302314
{(footerDataprotectionUrl || kcContext.properties["TAILCLOAKIFY_FOOTER_DATAPROTECTION_URL"]) && (
303315
<a
304-
className={"text-secondary-600 hover:text-secondary-900 text-sm inline-flex no-underline hover:no-underline"}
316+
className={"text-secondary-600 dark:text-secondary-300 hover:text-secondary-900 text-sm inline-flex no-underline hover:no-underline"}
305317
target={"_blank"}
306318
rel={"noopener noreferrer"}
307319
href={footerDataprotectionUrl || kcContext.properties["TAILCLOAKIFY_FOOTER_DATAPROTECTION_URL"]}
@@ -311,7 +323,7 @@ export default function Template(props: TemplateProps<KcContext, I18n>) {
311323
)}
312324
{kcContext.properties["TAILCLOAKIFY_FOOTER_ORESTBIDACOOKIECONSENT"] && (
313325
<a
314-
className={"text-secondary-600 hover:text-secondary-900 text-sm inline-flex no-underline hover:no-underline"}
326+
className={"text-secondary-600 dark:text-secondary-300 hover:text-secondary-900 text-sm inline-flex no-underline hover:no-underline"}
315327
target={"_blank"}
316328
rel={"noopener noreferrer"}
317329
type={"button"}

src/login/UserProfileFormFields.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ function PasswordWrapper(props: { kcClsx: KcClsx; i18n: I18n; passwordInputId: s
265265
{children}
266266
<button
267267
type="button"
268-
className={"absolute text-secondary-400 right-3 top-1 text-xl"}
268+
className={"absolute text-secondary-400 dark:text-secondary-200 right-3 top-1 text-xl"}
269269
aria-label={msgStr(isPasswordRevealed ? "hidePassword" : "showPassword")}
270270
aria-controls={passwordInputId}
271271
onClick={toggleIsPasswordRevealed}
@@ -309,7 +309,8 @@ function InputTag(props: InputFieldByTypeProps & { fieldIndex: number | undefine
309309
})()}
310310
className={clsx(
311311
kcClsx("kcInputClass"),
312-
"block focus:outline-none border-secondary-200 mt-1 rounded-md w-full focus:border-primary-300 focus:ring focus:ring-primary-200 focus:ring-opacity-50 sm:text-sm"
312+
"block focus:outline-none border-secondary-200 dark:border-secondary-400 mt-1 rounded-md w-full focus:border-primary-300 dark:focus:border-primary-500 focus:ring focus:ring-primary-200 dark:focus:ring-primary-100 focus:ring-opacity-50 sm:text-sm"
313+
313314
)}
314315
aria-invalid={displayableErrors.find(error => error.fieldIndex === fieldIndex) !== undefined}
315316
disabled={attribute.readOnly}
@@ -566,7 +567,7 @@ function TextareaTag(props: InputFieldByTypeProps) {
566567
name={attribute.name}
567568
className={clsx(
568569
kcClsx("kcInputClass"),
569-
"block p-2.5 focus:outline-none border-secondary-200 mt-1 rounded-md w-full focus:border-primary-300 focus:ring focus:ring-primary-200 focus:ring-opacity-50 sm:text-sm"
570+
"block p-2.5 focus:outline-none border-secondary-200 dark:border-secondary-400 mt-1 rounded-md w-full focus:border-primary-300 dark:focus:border-primary-500 focus:ring focus:ring-primary-200 dark:focus:ring-primary-100 focus:ring-opacity-50 sm:text-sm"
570571
)}
571572
aria-invalid={displayableErrors.length !== 0}
572573
disabled={attribute.readOnly}
@@ -603,7 +604,7 @@ function SelectTag(props: InputFieldByTypeProps) {
603604
name={attribute.name}
604605
className={clsx(
605606
kcClsx("kcInputClass"),
606-
"block focus:outline-none border-secondary-200 mt-1 rounded-md w-full focus:border-primary-300 focus:ring focus:ring-primary-200 focus:ring-opacity-50 sm:text-sm"
607+
"block focus:outline-none border-secondary-200 dark:border-secondary-400 mt-1 rounded-md w-full focus:border-primary-300 dark:focus:border-primary-500 focus:ring focus:ring-primary-200 dark:focus:ring-primary-100 focus:ring-opacity-50 sm:text-sm"
607608
)}
608609
aria-invalid={displayableErrors.length !== 0}
609610
disabled={attribute.readOnly}
Lines changed: 132 additions & 0 deletions
Loading

0 commit comments

Comments
 (0)