getClassName -> kcClsx

This commit is contained in:
Joseph Garrone
2024-06-09 08:27:07 +02:00
parent 8f006f0009
commit 1a48681591
61 changed files with 878 additions and 1056 deletions

View File

@ -1,4 +1,4 @@
import { useGetClassName } from "keycloakify/login/lib/useGetClassName";
import { getKcClsx } from "keycloakify/login/lib/kcClsx";
import type { PageProps } from "keycloakify/login/pages/PageProps";
import type { KcContext } from "../KcContext";
import { useI18n } from "../i18n";
@ -6,7 +6,7 @@ import { useI18n } from "../i18n";
export default function Code(props: PageProps<Extract<KcContext, { pageId: "code.ftl" }>>) {
const { kcContext, doUseDefaultCss, Template, classes } = props;
const { getClassName } = useGetClassName({
const { kcClsx } = getKcClsx({
doUseDefaultCss,
classes
});
@ -17,14 +17,16 @@ export default function Code(props: PageProps<Extract<KcContext, { pageId: "code
return (
<Template
{...{ kcContext, doUseDefaultCss, classes }}
kcContext={kcContext}
doUseDefaultCss={doUseDefaultCss}
classes={classes}
headerNode={code.success ? msg("codeSuccessTitle") : msg("codeErrorTitle", code.error)}
>
<div id="kc-code">
{code.success ? (
<>
<p>{msg("copyCodeInstruction")}</p>
<input id="code" className={getClassName("kcTextareaClass")} defaultValue={code.code} />
<input id="code" className={kcClsx("kcTextareaClass")} defaultValue={code.code} />
</>
) : (
<p id="error">{code.error}</p>

View File

@ -1,5 +1,4 @@
import { clsx } from "keycloakify/tools/clsx";
import { useGetClassName } from "keycloakify/login/lib/useGetClassName";
import { getKcClsx } from "keycloakify/login/lib/kcClsx";
import type { PageProps } from "keycloakify/login/pages/PageProps";
import type { KcContext } from "../KcContext";
import { useI18n } from "../i18n";
@ -7,7 +6,7 @@ import { useI18n } from "../i18n";
export default function DeleteAccountConfirm(props: PageProps<Extract<KcContext, { pageId: "delete-account-confirm.ftl" }>>) {
const { kcContext, doUseDefaultCss, Template, classes } = props;
const { getClassName } = useGetClassName({
const { kcClsx } = getKcClsx({
doUseDefaultCss,
classes
});
@ -17,7 +16,7 @@ export default function DeleteAccountConfirm(props: PageProps<Extract<KcContext,
const { msg, msgStr } = useI18n({ kcContext });
return (
<Template {...{ kcContext, doUseDefaultCss, classes }} headerNode={msg("deleteAccountConfirm")}>
<Template kcContext={kcContext} doUseDefaultCss={doUseDefaultCss} classes={classes} headerNode={msg("deleteAccountConfirm")}>
<form action={url.loginAction} className="form-vertical" method="post">
<div className="alert alert-warning" style={{ marginTop: "0", marginBottom: "30px" }}>
<span className="pficon pficon-warning-triangle-o"></span>
@ -37,13 +36,13 @@ export default function DeleteAccountConfirm(props: PageProps<Extract<KcContext,
<p className="delete-account-text">{msg("finalDeletionConfirmation")}</p>
<div id="kc-form-buttons">
<input
className={clsx(getClassName("kcButtonClass"), getClassName("kcButtonPrimaryClass"), getClassName("kcButtonLargeClass"))}
className={kcClsx("kcButtonClass", "kcButtonPrimaryClass", "kcButtonLargeClass")}
type="submit"
value={msgStr("doConfirmDelete")}
/>
{triggered_from_aia && (
<button
className={clsx(getClassName("kcButtonClass"), getClassName("kcButtonDefaultClass"), getClassName("kcButtonLargeClass"))}
className={kcClsx("kcButtonClass", "kcButtonDefaultClass", "kcButtonLargeClass")}
style={{ marginLeft: "calc(100% - 220px)" }}
type="submit"
name="cancel-aia"

View File

@ -1,5 +1,4 @@
import { clsx } from "keycloakify/tools/clsx";
import { useGetClassName } from "keycloakify/login/lib/useGetClassName";
import { getKcClsx } from "keycloakify/login/lib/kcClsx";
import type { PageProps } from "keycloakify/login/pages/PageProps";
import type { KcContext } from "../KcContext";
import { useI18n } from "../i18n";
@ -9,7 +8,7 @@ export default function DeleteCredential(props: PageProps<Extract<KcContext, { p
const { msgStr, msg } = useI18n({ kcContext });
const { getClassName } = useGetClassName({
const { kcClsx } = getKcClsx({
doUseDefaultCss,
classes
});
@ -17,18 +16,24 @@ export default function DeleteCredential(props: PageProps<Extract<KcContext, { p
const { url, credentialLabel } = kcContext;
return (
<Template {...{ kcContext, doUseDefaultCss, classes }} displayMessage={false} headerNode={msg("deleteCredentialTitle", credentialLabel)}>
<Template
kcContext={kcContext}
doUseDefaultCss={doUseDefaultCss}
classes={classes}
displayMessage={false}
headerNode={msg("deleteCredentialTitle", credentialLabel)}
>
<div id="kc-delete-text">{msg("deleteCredentialMessage", credentialLabel)}</div>
<form className="form-actions" action={url.loginAction} method="POST">
<input
className={clsx(getClassName("kcButtonClass"), getClassName("kcButtonPrimaryClass"), getClassName("kcButtonLargeClass"))}
className={kcClsx("kcButtonClass", "kcButtonPrimaryClass", "kcButtonLargeClass")}
name="accept"
id="kc-accept"
type="submit"
value={msgStr("doConfirmDelete")}
/>
<input
className={clsx(getClassName("kcButtonClass"), getClassName("kcButtonDefaultClass"), getClassName("kcButtonLargeClass"))}
className={kcClsx("kcButtonClass", "kcButtonDefaultClass", "kcButtonLargeClass")}
name="cancel-aia"
value={msgStr("doCancel")}
id="kc-decline"

View File

@ -10,7 +10,7 @@ export default function Error(props: PageProps<Extract<KcContext, { pageId: "err
const { msg } = useI18n({ kcContext });
return (
<Template {...{ kcContext, doUseDefaultCss, classes }} displayMessage={false} headerNode={msg("errorTitle")}>
<Template kcContext={kcContext} doUseDefaultCss={doUseDefaultCss} classes={classes} displayMessage={false} headerNode={msg("errorTitle")}>
<div id="kc-error-message">
<p className="instruction">{message.summary}</p>
{!skipLink && client !== undefined && client.baseUrl !== undefined && (

View File

@ -18,7 +18,9 @@ export default function FrontchannelLogout(props: PageProps<Extract<KcContext, {
return (
<Template
{...{ kcContext, doUseDefaultCss, classes }}
kcContext={kcContext}
doUseDefaultCss={doUseDefaultCss}
classes={classes}
documentTitle={msgStr("frontchannel-logout.title")}
headerNode={msg("frontchannel-logout.title")}
>

View File

@ -1,7 +1,6 @@
import { useState } from "react";
import { clsx } from "keycloakify/tools/clsx";
import type { LazyOrNot } from "keycloakify/tools/LazyOrNot";
import { useGetClassName } from "keycloakify/login/lib/useGetClassName";
import { getKcClsx } from "keycloakify/login/lib/kcClsx";
import type { PageProps } from "keycloakify/login/pages/PageProps";
import type { UserProfileFormFieldsProps } from "keycloakify/login/UserProfileFormFields";
import type { KcContext } from "../KcContext";
@ -14,7 +13,7 @@ type IdpReviewUserProfileProps = PageProps<Extract<KcContext, { pageId: "idp-rev
export default function IdpReviewUserProfile(props: IdpReviewUserProfileProps) {
const { kcContext, doUseDefaultCss, Template, classes, UserProfileFormFields } = props;
const { getClassName } = useGetClassName({
const { kcClsx } = getKcClsx({
doUseDefaultCss,
classes
});
@ -27,25 +26,22 @@ export default function IdpReviewUserProfile(props: IdpReviewUserProfileProps) {
return (
<Template
{...{ kcContext, doUseDefaultCss, classes }}
kcContext={kcContext}
doUseDefaultCss={doUseDefaultCss}
classes={classes}
displayMessage={messagesPerField.exists("global")}
displayRequiredFields
headerNode={msg("loginIdpReviewProfileTitle")}
>
<form id="kc-idp-review-profile-form" className={getClassName("kcFormClass")} action={url.loginAction} method="post">
<UserProfileFormFields kcContext={kcContext} onIsFormSubmittableValueChange={setIsFomSubmittable} getClassName={getClassName} />
<div className={getClassName("kcFormGroupClass")}>
<div id="kc-form-options" className={getClassName("kcFormOptionsClass")}>
<div className={getClassName("kcFormOptionsWrapperClass")} />
<form id="kc-idp-review-profile-form" className={kcClsx("kcFormClass")} action={url.loginAction} method="post">
<UserProfileFormFields kcContext={kcContext} onIsFormSubmittableValueChange={setIsFomSubmittable} kcClsx={kcClsx} />
<div className={kcClsx("kcFormGroupClass")}>
<div id="kc-form-options" className={kcClsx("kcFormOptionsClass")}>
<div className={kcClsx("kcFormOptionsWrapperClass")} />
</div>
<div id="kc-form-buttons" className={getClassName("kcFormButtonsClass")}>
<div id="kc-form-buttons" className={kcClsx("kcFormButtonsClass")}>
<input
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonPrimaryClass"),
getClassName("kcButtonBlockClass"),
getClassName("kcButtonLargeClass")
)}
className={kcClsx("kcButtonClass", "kcButtonPrimaryClass", "kcButtonBlockClass", "kcButtonLargeClass")}
type="submit"
value={msgStr("doSubmit")}
disabled={!isFomSubmittable}

View File

@ -17,7 +17,9 @@ export default function Info(props: PageProps<Extract<KcContext, { pageId: "info
return (
<Template
{...{ kcContext, doUseDefaultCss, classes }}
kcContext={kcContext}
doUseDefaultCss={doUseDefaultCss}
classes={classes}
displayMessage={false}
headerNode={messageHeader !== undefined ? <>{messageHeader}</> : <>{message.summary}</>}
>

View File

@ -2,14 +2,14 @@ import { useState, useEffect, useReducer } from "react";
import { assert } from "tsafe/assert";
import { clsx } from "keycloakify/tools/clsx";
import type { PageProps } from "keycloakify/login/pages/PageProps";
import { useGetClassName } from "keycloakify/login/lib/useGetClassName";
import { getKcClsx, type KcClsx } from "keycloakify/login/lib/kcClsx";
import type { KcContext } from "../KcContext";
import { useI18n, type I18n } from "../i18n";
export default function Login(props: PageProps<Extract<KcContext, { pageId: "login.ftl" }>>) {
const { kcContext, doUseDefaultCss, Template, classes } = props;
const { getClassName } = useGetClassName({
const { kcClsx } = getKcClsx({
doUseDefaultCss,
classes
});
@ -23,7 +23,9 @@ export default function Login(props: PageProps<Extract<KcContext, { pageId: "log
return (
<Template
{...{ kcContext, doUseDefaultCss, classes }}
kcContext={kcContext}
doUseDefaultCss={doUseDefaultCss}
classes={classes}
displayMessage={!messagesPerField.existsError("username", "password")}
headerNode={msg("loginAccountTitle")}
displayInfo={realm.password && realm.registrationAllowed && !registrationDisabled}
@ -42,32 +44,23 @@ export default function Login(props: PageProps<Extract<KcContext, { pageId: "log
socialProvidersNode={
<>
{realm.password && social.providers?.length && (
<div id="kc-social-providers" className={getClassName("kcFormSocialAccountSectionClass")}>
<div id="kc-social-providers" className={kcClsx("kcFormSocialAccountSectionClass")}>
<hr />
<h2>{msg("identity-provider-login-label")}</h2>
<ul
className={clsx(
getClassName("kcFormSocialAccountListClass"),
social.providers.length > 3 && getClassName("kcFormSocialAccountListGridClass")
)}
>
<ul className={kcClsx("kcFormSocialAccountListClass", social.providers.length > 3 && "kcFormSocialAccountListGridClass")}>
{social.providers.map((...[p, , providers]) => (
<li key={p.alias}>
<a
id={`social-${p.alias}`}
className={clsx(
getClassName("kcFormSocialAccountListButtonClass"),
providers.length > 3 && getClassName("kcFormSocialAccountGridItem")
className={kcClsx(
"kcFormSocialAccountListButtonClass",
providers.length > 3 && "kcFormSocialAccountGridItem"
)}
type="button"
href={p.loginUrl}
>
{p.iconClasses && (
<i className={clsx(getClassName("kcCommonLogoIdP"), p.iconClasses)} aria-hidden="true"></i>
)}
<span
className={clsx(getClassName("kcFormSocialAccountNameClass"), p.iconClasses && "kc-social-icon-text")}
>
{p.iconClasses && <i className={clsx(kcClsx("kcCommonLogoIdP"), p.iconClasses)} aria-hidden="true"></i>}
<span className={clsx(kcClsx("kcFormSocialAccountNameClass"), p.iconClasses && "kc-social-icon-text")}>
{p.displayName}
</span>
</a>
@ -92,8 +85,8 @@ export default function Login(props: PageProps<Extract<KcContext, { pageId: "log
method="post"
>
{!usernameHidden && (
<div className={getClassName("kcFormGroupClass")}>
<label htmlFor="username" className={getClassName("kcLabelClass")}>
<div className={kcClsx("kcFormGroupClass")}>
<label htmlFor="username" className={kcClsx("kcLabelClass")}>
{!realm.loginWithEmailAllowed
? msg("username")
: !realm.registrationEmailAsUsername
@ -103,7 +96,7 @@ export default function Login(props: PageProps<Extract<KcContext, { pageId: "log
<input
tabIndex={2}
id="username"
className={getClassName("kcInputClass")}
className={kcClsx("kcInputClass")}
name="username"
defaultValue={login.username ?? ""}
type="text"
@ -112,22 +105,22 @@ export default function Login(props: PageProps<Extract<KcContext, { pageId: "log
aria-invalid={messagesPerField.existsError("username", "password")}
/>
{messagesPerField.existsError("username", "password") && (
<span id="input-error" className={getClassName("kcInputErrorMessageClass")} aria-live="polite">
<span id="input-error" className={kcClsx("kcInputErrorMessageClass")} aria-live="polite">
{messagesPerField.getFirstError("username", "password")}
</span>
)}
</div>
)}
<div className={getClassName("kcFormGroupClass")}>
<label htmlFor="password" className={getClassName("kcLabelClass")}>
<div className={kcClsx("kcFormGroupClass")}>
<label htmlFor="password" className={kcClsx("kcLabelClass")}>
{msg("password")}
</label>
<PasswordWrapper getClassName={getClassName} i18n={i18n} passwordInputId="password">
<PasswordWrapper kcClsx={kcClsx} i18n={i18n} passwordInputId="password">
<input
tabIndex={3}
id="password"
className={getClassName("kcInputClass")}
className={kcClsx("kcInputClass")}
name="password"
type="password"
autoComplete="current-password"
@ -135,13 +128,13 @@ export default function Login(props: PageProps<Extract<KcContext, { pageId: "log
/>
</PasswordWrapper>
{usernameHidden && messagesPerField.existsError("username", "password") && (
<span id="input-error" className={getClassName("kcInputErrorMessageClass")} aria-live="polite">
<span id="input-error" className={kcClsx("kcInputErrorMessageClass")} aria-live="polite">
{messagesPerField.getFirstError("username", "password")}
</span>
)}
</div>
<div className={clsx(getClassName("kcFormGroupClass"), getClassName("kcFormSettingClass"))}>
<div className={kcClsx("kcFormGroupClass", "kcFormSettingClass")}>
<div id="kc-form-options">
{realm.rememberMe && !usernameHidden && (
<div className="checkbox">
@ -158,7 +151,7 @@ export default function Login(props: PageProps<Extract<KcContext, { pageId: "log
</div>
)}
</div>
<div className={getClassName("kcFormOptionsWrapperClass")}>
<div className={kcClsx("kcFormOptionsWrapperClass")}>
{realm.resetPasswordAllowed && (
<span>
<a tabIndex={6} href={url.loginResetCredentialsUrl}>
@ -169,17 +162,12 @@ export default function Login(props: PageProps<Extract<KcContext, { pageId: "log
</div>
</div>
<div id="kc-form-buttons" className={getClassName("kcFormGroupClass")}>
<div id="kc-form-buttons" className={kcClsx("kcFormGroupClass")}>
<input type="hidden" id="id-hidden-input" name="credentialId" value={auth.selectedCredential} />
<input
tabIndex={7}
disabled={isLoginButtonDisabled}
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonPrimaryClass"),
getClassName("kcButtonBlockClass"),
getClassName("kcButtonLargeClass")
)}
className={kcClsx("kcButtonClass", "kcButtonPrimaryClass", "kcButtonBlockClass", "kcButtonLargeClass")}
name="login"
id="kc-login"
type="submit"
@ -194,13 +182,8 @@ export default function Login(props: PageProps<Extract<KcContext, { pageId: "log
);
}
function PasswordWrapper(props: {
getClassName: ReturnType<typeof useGetClassName>["getClassName"];
i18n: I18n;
passwordInputId: string;
children: JSX.Element;
}) {
const { getClassName, i18n, passwordInputId, children } = props;
function PasswordWrapper(props: { kcClsx: KcClsx; i18n: I18n; passwordInputId: string; children: JSX.Element }) {
const { kcClsx, i18n, passwordInputId, children } = props;
const { msgStr } = i18n;
@ -215,19 +198,16 @@ function PasswordWrapper(props: {
}, [isPasswordRevealed]);
return (
<div className={getClassName("kcInputGroup")}>
<div className={kcClsx("kcInputGroup")}>
{children}
<button
type="button"
className={getClassName("kcFormPasswordVisibilityButtonClass")}
className={kcClsx("kcFormPasswordVisibilityButtonClass")}
aria-label={msgStr(isPasswordRevealed ? "hidePassword" : "showPassword")}
aria-controls={passwordInputId}
onClick={toggleIsPasswordRevealed}
>
<i
className={getClassName(isPasswordRevealed ? "kcFormPasswordVisibilityIconHide" : "kcFormPasswordVisibilityIconShow")}
aria-hidden
/>
<i className={kcClsx(isPasswordRevealed ? "kcFormPasswordVisibilityIconHide" : "kcFormPasswordVisibilityIconShow")} aria-hidden />
</button>
</div>
);

View File

@ -1,5 +1,4 @@
import { clsx } from "keycloakify/tools/clsx";
import { useGetClassName, type ClassKey } from "keycloakify/login/lib/useGetClassName";
import { getKcClsx, KcClsx } from "keycloakify/login/lib/kcClsx";
import type { PageProps } from "keycloakify/login/pages/PageProps";
import type { KcContext } from "../KcContext";
import { useI18n, type I18n } from "../i18n";
@ -7,7 +6,7 @@ import { useI18n, type I18n } from "../i18n";
export default function LoginConfigTotp(props: PageProps<Extract<KcContext, { pageId: "login-config-totp.ftl" }>>) {
const { kcContext, doUseDefaultCss, Template, classes } = props;
const { getClassName } = useGetClassName({
const { kcClsx } = getKcClsx({
doUseDefaultCss,
classes
});
@ -19,7 +18,7 @@ export default function LoginConfigTotp(props: PageProps<Extract<KcContext, { pa
const { msg, msgStr, advancedMsg } = i18n;
return (
<Template {...{ kcContext, doUseDefaultCss, classes }} headerNode={msg("loginTotpTitle")}>
<Template kcContext={kcContext} doUseDefaultCss={doUseDefaultCss} classes={classes} headerNode={msg("loginTotpTitle")}>
<>
<ol id="kc-totp-settings">
<li>
@ -89,26 +88,26 @@ export default function LoginConfigTotp(props: PageProps<Extract<KcContext, { pa
</li>
</ol>
<form action={url.loginAction} className={getClassName("kcFormClass")} id="kc-totp-settings-form" method="post">
<div className={getClassName("kcFormGroupClass")}>
<div className={getClassName("kcInputWrapperClass")}>
<label htmlFor="totp" className={getClassName("kcLabelClass")}>
<form action={url.loginAction} className={kcClsx("kcFormClass")} id="kc-totp-settings-form" method="post">
<div className={kcClsx("kcFormGroupClass")}>
<div className={kcClsx("kcInputWrapperClass")}>
<label htmlFor="totp" className={kcClsx("kcLabelClass")}>
{msg("authenticatorCode")}
</label>{" "}
<span className="required">*</span>
</div>
<div className={getClassName("kcInputWrapperClass")}>
<div className={kcClsx("kcInputWrapperClass")}>
<input
type="text"
id="totp"
name="totp"
autoComplete="off"
className={getClassName("kcInputClass")}
className={kcClsx("kcInputClass")}
aria-invalid={messagesPerField.existsError("totp")}
/>
{messagesPerField.existsError("totp") && (
<span id="input-error-otp-code" className={getClassName("kcInputErrorMessageClass")} aria-live="polite">
<span id="input-error-otp-code" className={kcClsx("kcInputErrorMessageClass")} aria-live="polite">
{messagesPerField.get("totp")}
</span>
)}
@ -117,54 +116,45 @@ export default function LoginConfigTotp(props: PageProps<Extract<KcContext, { pa
{mode && <input type="hidden" id="mode" value={mode} />}
</div>
<div className={getClassName("kcFormGroupClass")}>
<div className={getClassName("kcInputWrapperClass")}>
<label htmlFor="userLabel" className={getClassName("kcLabelClass")}>
<div className={kcClsx("kcFormGroupClass")}>
<div className={kcClsx("kcInputWrapperClass")}>
<label htmlFor="userLabel" className={kcClsx("kcLabelClass")}>
{msg("loginTotpDeviceName")}
</label>{" "}
{totp.otpCredentials.length >= 1 && <span className="required">*</span>}
</div>
<div className={getClassName("kcInputWrapperClass")}>
<div className={kcClsx("kcInputWrapperClass")}>
<input
type="text"
id="userLabel"
name="userLabel"
autoComplete="off"
className={getClassName("kcInputClass")}
className={kcClsx("kcInputClass")}
aria-invalid={messagesPerField.existsError("userLabel")}
/>
{messagesPerField.existsError("userLabel") && (
<span id="input-error-otp-label" className={getClassName("kcInputErrorMessageClass")} aria-live="polite">
<span id="input-error-otp-label" className={kcClsx("kcInputErrorMessageClass")} aria-live="polite">
{messagesPerField.get("userLabel")}
</span>
)}
</div>
</div>
<div className={getClassName("kcFormGroupClass")}>
<LogoutOtherSessions {...{ getClassName, i18n }} />
<div className={kcClsx("kcFormGroupClass")}>
<LogoutOtherSessions kcClsx={kcClsx} i18n={i18n} />
</div>
{isAppInitiatedAction ? (
<>
<input
type="submit"
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonPrimaryClass"),
getClassName("kcButtonLargeClass")
)}
className={kcClsx("kcButtonClass", "kcButtonPrimaryClass", "kcButtonLargeClass")}
id="saveTOTPBtn"
value={msgStr("doSubmit")}
/>
<button
type="submit"
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonDefaultClass"),
getClassName("kcButtonLargeClass"),
getClassName("kcButtonLargeClass")
)}
className={kcClsx("kcButtonClass", "kcButtonDefaultClass", "kcButtonLargeClass", "kcButtonLargeClass")}
id="cancelTOTPBtn"
name="cancel-aia"
value="true"
@ -175,7 +165,7 @@ export default function LoginConfigTotp(props: PageProps<Extract<KcContext, { pa
) : (
<input
type="submit"
className={clsx(getClassName("kcButtonClass"), getClassName("kcButtonPrimaryClass"), getClassName("kcButtonLargeClass"))}
className={kcClsx("kcButtonClass", "kcButtonPrimaryClass", "kcButtonLargeClass")}
id="saveTOTPBtn"
value={msgStr("doSubmit")}
/>
@ -186,14 +176,14 @@ export default function LoginConfigTotp(props: PageProps<Extract<KcContext, { pa
);
}
function LogoutOtherSessions(props: { getClassName: (key: ClassKey) => string; i18n: I18n }) {
const { getClassName, i18n } = props;
function LogoutOtherSessions(props: { kcClsx: KcClsx; i18n: I18n }) {
const { kcClsx, i18n } = props;
const { msg } = i18n;
return (
<div id="kc-form-options" className={getClassName("kcFormOptionsClass")}>
<div className={getClassName("kcFormOptionsWrapperClass")}>
<div id="kc-form-options" className={kcClsx("kcFormOptionsClass")}>
<div className={kcClsx("kcFormOptionsWrapperClass")}>
<div className="checkbox">
<label>
<input type="checkbox" id="logout-sessions" name="logout-sessions" value="on" defaultChecked={true} />

View File

@ -1,5 +1,4 @@
import { clsx } from "keycloakify/tools/clsx";
import { useGetClassName } from "keycloakify/login/lib/useGetClassName";
import { getKcClsx } from "keycloakify/login/lib/kcClsx";
import type { PageProps } from "keycloakify/login/pages/PageProps";
import type { KcContext } from "../KcContext";
import { useI18n } from "../i18n";
@ -7,7 +6,7 @@ import { useI18n } from "../i18n";
export default function LoginIdpLinkConfirm(props: PageProps<Extract<KcContext, { pageId: "login-idp-link-confirm.ftl" }>>) {
const { kcContext, doUseDefaultCss, Template, classes } = props;
const { getClassName } = useGetClassName({
const { kcClsx } = getKcClsx({
doUseDefaultCss,
classes
});
@ -17,17 +16,12 @@ export default function LoginIdpLinkConfirm(props: PageProps<Extract<KcContext,
const { msg } = useI18n({ kcContext });
return (
<Template {...{ kcContext, doUseDefaultCss, classes }} headerNode={msg("confirmLinkIdpTitle")}>
<Template kcContext={kcContext} doUseDefaultCss={doUseDefaultCss} classes={classes} headerNode={msg("confirmLinkIdpTitle")}>
<form id="kc-register-form" action={url.loginAction} method="post">
<div className={getClassName("kcFormGroupClass")}>
<div className={kcClsx("kcFormGroupClass")}>
<button
type="submit"
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonDefaultClass"),
getClassName("kcButtonBlockClass"),
getClassName("kcButtonLargeClass")
)}
className={kcClsx("kcButtonClass", "kcButtonDefaultClass", "kcButtonBlockClass", "kcButtonLargeClass")}
name="submitAction"
id="updateProfile"
value="updateProfile"
@ -36,12 +30,7 @@ export default function LoginIdpLinkConfirm(props: PageProps<Extract<KcContext,
</button>
<button
type="submit"
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonDefaultClass"),
getClassName("kcButtonBlockClass"),
getClassName("kcButtonLargeClass")
)}
className={kcClsx("kcButtonClass", "kcButtonDefaultClass", "kcButtonBlockClass", "kcButtonLargeClass")}
name="submitAction"
id="linkAccount"
value="linkAccount"

View File

@ -10,7 +10,7 @@ export default function LoginIdpLinkEmail(props: PageProps<Extract<KcContext, {
const { msg } = useI18n({ kcContext });
return (
<Template {...{ kcContext, doUseDefaultCss, classes }} headerNode={msg("emailLinkIdpTitle", idpAlias)}>
<Template kcContext={kcContext} doUseDefaultCss={doUseDefaultCss} classes={classes} headerNode={msg("emailLinkIdpTitle", idpAlias)}>
<p id="instruction1" className="instruction">
{msg("emailLinkIdp1", idpAlias, brokerContext.username, realm.displayName)}
</p>

View File

@ -1,5 +1,4 @@
import { clsx } from "keycloakify/tools/clsx";
import { useGetClassName } from "keycloakify/login/lib/useGetClassName";
import { getKcClsx } from "keycloakify/login/lib/kcClsx";
import { PageProps } from "keycloakify/login/pages/PageProps";
import { KcContext } from "../KcContext";
import { useI18n } from "../i18n";
@ -12,51 +11,47 @@ export default function LoginOauth2DeviceVerifyUserCode(
const { msg, msgStr } = useI18n({ kcContext });
const { getClassName } = useGetClassName({
const { kcClsx } = getKcClsx({
doUseDefaultCss,
classes
});
return (
<Template {...{ kcContext, doUseDefaultCss, classes }} headerNode={msg("oauth2DeviceVerificationTitle")}>
<Template kcContext={kcContext} doUseDefaultCss={doUseDefaultCss} classes={classes} headerNode={msg("oauth2DeviceVerificationTitle")}>
<form
id="kc-user-verify-device-user-code-form"
className={getClassName("kcFormClass")}
className={kcClsx("kcFormClass")}
action={url.oauth2DeviceVerificationAction}
method="post"
>
<div className={getClassName("kcFormGroupClass")}>
<div className={getClassName("kcLabelWrapperClass")}>
<label htmlFor="device-user-code" className={getClassName("kcLabelClass")}>
<div className={kcClsx("kcFormGroupClass")}>
<div className={kcClsx("kcLabelWrapperClass")}>
<label htmlFor="device-user-code" className={kcClsx("kcLabelClass")}>
{msg("verifyOAuth2DeviceUserCode")}
</label>
</div>
<div className={getClassName("kcInputWrapperClass")}>
<div className={kcClsx("kcInputWrapperClass")}>
<input
id="device-user-code"
name="device_user_code"
autoComplete="off"
type="text"
className={getClassName("kcInputClass")}
className={kcClsx("kcInputClass")}
autoFocus
/>
</div>
</div>
<div className={getClassName("kcFormGroupClass")}>
<div id="kc-form-options" className={getClassName("kcFormOptionsClass")}>
<div className={getClassName("kcFormOptionsWrapperClass")}></div>
<div className={kcClsx("kcFormGroupClass")}>
<div id="kc-form-options" className={kcClsx("kcFormOptionsClass")}>
<div className={kcClsx("kcFormOptionsWrapperClass")}></div>
</div>
<div id="kc-form-buttons" className={getClassName("kcFormButtonsClass")}>
<div className={getClassName("kcFormButtonsWrapperClass")}>
<div id="kc-form-buttons" className={kcClsx("kcFormButtonsClass")}>
<div className={kcClsx("kcFormButtonsWrapperClass")}>
<input
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonPrimaryClass"),
getClassName("kcButtonLargeClass")
)}
className={kcClsx("kcButtonClass", "kcButtonPrimaryClass", "kcButtonLargeClass")}
type="submit"
value={msgStr("doSubmit")}
/>

View File

@ -1,5 +1,4 @@
import { clsx } from "keycloakify/tools/clsx";
import { useGetClassName } from "keycloakify/login/lib/useGetClassName";
import { getKcClsx } from "keycloakify/login/lib/kcClsx";
import { PageProps } from "keycloakify/login/pages/PageProps";
import { KcContext } from "../KcContext";
import { useI18n } from "../i18n";
@ -10,14 +9,16 @@ export default function LoginOauthGrant(props: PageProps<Extract<KcContext, { pa
const { msg, msgStr, advancedMsg, advancedMsgStr } = useI18n({ kcContext });
const { getClassName } = useGetClassName({
const { kcClsx } = getKcClsx({
doUseDefaultCss,
classes
});
return (
<Template
{...{ kcContext, doUseDefaultCss, classes }}
kcContext={kcContext}
doUseDefaultCss={doUseDefaultCss}
classes={classes}
bodyClassName="oauth"
headerNode={
<>
@ -68,30 +69,22 @@ export default function LoginOauthGrant(props: PageProps<Extract<KcContext, { pa
<form className="form-actions" action={url.oauthAction} method="POST">
<input type="hidden" name="code" value={oauth.code} />
<div className={getClassName("kcFormGroupClass")}>
<div className={kcClsx("kcFormGroupClass")}>
<div id="kc-form-options">
<div className={getClassName("kcFormOptionsWrapperClass")}></div>
<div className={kcClsx("kcFormOptionsWrapperClass")}></div>
</div>
<div id="kc-form-buttons">
<div className={getClassName("kcFormButtonsWrapperClass")}>
<div className={kcClsx("kcFormButtonsWrapperClass")}>
<input
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonPrimaryClass"),
getClassName("kcButtonLargeClass")
)}
className={kcClsx("kcButtonClass", "kcButtonPrimaryClass", "kcButtonLargeClass")}
name="accept"
id="kc-login"
type="submit"
value={msgStr("doYes")}
/>
<input
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonDefaultClass"),
getClassName("kcButtonLargeClass")
)}
className={kcClsx("kcButtonClass", "kcButtonDefaultClass", "kcButtonLargeClass")}
name="cancel"
id="kc-cancel"
type="submit"

View File

@ -1,6 +1,5 @@
import { Fragment } from "react";
import { clsx } from "keycloakify/tools/clsx";
import { useGetClassName } from "keycloakify/login/lib/useGetClassName";
import { getKcClsx } from "keycloakify/login/lib/kcClsx";
import type { PageProps } from "keycloakify/login/pages/PageProps";
import type { KcContext } from "../KcContext";
import { useI18n } from "../i18n";
@ -8,7 +7,7 @@ import { useI18n } from "../i18n";
export default function LoginOtp(props: PageProps<Extract<KcContext, { pageId: "login-otp.ftl" }>>) {
const { kcContext, doUseDefaultCss, Template, classes } = props;
const { getClassName } = useGetClassName({
const { kcClsx } = getKcClsx({
doUseDefaultCss,
classes
});
@ -18,27 +17,33 @@ export default function LoginOtp(props: PageProps<Extract<KcContext, { pageId: "
const { msg, msgStr } = useI18n({ kcContext });
return (
<Template {...{ kcContext, doUseDefaultCss, classes }} displayMessage={!messagesPerField.existsError("totp")} headerNode={msg("doLogIn")}>
<form id="kc-otp-login-form" className={clsx(getClassName("kcFormClass"))} action={url.loginAction} method="post">
<Template
kcContext={kcContext}
doUseDefaultCss={doUseDefaultCss}
classes={classes}
displayMessage={!messagesPerField.existsError("totp")}
headerNode={msg("doLogIn")}
>
<form id="kc-otp-login-form" className={kcClsx("kcFormClass")} action={url.loginAction} method="post">
{otpLogin.userOtpCredentials.length > 1 && (
<div className={getClassName("kcFormGroupClass")}>
<div className={getClassName("kcInputWrapperClass")}>
<div className={kcClsx("kcFormGroupClass")}>
<div className={kcClsx("kcInputWrapperClass")}>
{otpLogin.userOtpCredentials.map((otpCredential, index) => (
<Fragment key={index}>
<input
id={`kc-otp-credential-${index}`}
className={getClassName("kcLoginOTPListInputClass")}
className={kcClsx("kcLoginOTPListInputClass")}
type="radio"
name="selectedCredentialId"
value={otpCredential.id}
defaultChecked={otpCredential.id === otpLogin.selectedCredentialId}
/>
<label htmlFor={`kc-otp-credential-${index}`} className={getClassName("kcLoginOTPListClass")} tabIndex={index}>
<span className={getClassName("kcLoginOTPListItemHeaderClass")}>
<span className={getClassName("kcLoginOTPListItemIconBodyClass")}>
<i className={getClassName("kcLoginOTPListItemIconClass")} aria-hidden="true"></i>
<label htmlFor={`kc-otp-credential-${index}`} className={kcClsx("kcLoginOTPListClass")} tabIndex={index}>
<span className={kcClsx("kcLoginOTPListItemHeaderClass")}>
<span className={kcClsx("kcLoginOTPListItemIconBodyClass")}>
<i className={kcClsx("kcLoginOTPListItemIconClass")} aria-hidden="true"></i>
</span>
<span className={getClassName("kcLoginOTPListItemTitleClass")}>{otpCredential.userLabel}</span>
<span className={kcClsx("kcLoginOTPListItemTitleClass")}>{otpCredential.userLabel}</span>
</span>
</label>
</Fragment>
@ -47,42 +52,37 @@ export default function LoginOtp(props: PageProps<Extract<KcContext, { pageId: "
</div>
)}
<div className={getClassName("kcFormGroupClass")}>
<div className={getClassName("kcLabelWrapperClass")}>
<label htmlFor="otp" className={getClassName("kcLabelClass")}>
<div className={kcClsx("kcFormGroupClass")}>
<div className={kcClsx("kcLabelWrapperClass")}>
<label htmlFor="otp" className={kcClsx("kcLabelClass")}>
{msg("loginOtpOneTime")}
</label>
</div>
<div className={getClassName("kcInputWrapperClass")}>
<div className={kcClsx("kcInputWrapperClass")}>
<input
id="otp"
name="otp"
autoComplete="off"
type="text"
className={getClassName("kcInputClass")}
className={kcClsx("kcInputClass")}
autoFocus
aria-invalid={messagesPerField.existsError("totp")}
/>
{messagesPerField.existsError("totp") && (
<span id="input-error-otp-code" className={getClassName("kcInputErrorMessageClass")} aria-live="polite">
<span id="input-error-otp-code" className={kcClsx("kcInputErrorMessageClass")} aria-live="polite">
{messagesPerField.get("totp")}
</span>
)}
</div>
</div>
<div className={getClassName("kcFormGroupClass")}>
<div id="kc-form-options" className={getClassName("kcFormOptionsClass")}>
<div className={getClassName("kcFormOptionsWrapperClass")}></div>
<div className={kcClsx("kcFormGroupClass")}>
<div id="kc-form-options" className={kcClsx("kcFormOptionsClass")}>
<div className={kcClsx("kcFormOptionsWrapperClass")}></div>
</div>
<div id="kc-form-buttons" className={getClassName("kcFormButtonsClass")}>
<div id="kc-form-buttons" className={kcClsx("kcFormButtonsClass")}>
<input
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonPrimaryClass"),
getClassName("kcButtonBlockClass"),
getClassName("kcButtonLargeClass")
)}
className={kcClsx("kcButtonClass", "kcButtonPrimaryClass", "kcButtonBlockClass", "kcButtonLargeClass")}
name="login"
id="kc-login"
type="submit"

View File

@ -10,7 +10,7 @@ export default function LoginPageExpired(props: PageProps<Extract<KcContext, { p
const { msg } = useI18n({ kcContext });
return (
<Template {...{ kcContext, doUseDefaultCss, classes }} headerNode={msg("pageExpiredTitle")}>
<Template kcContext={kcContext} doUseDefaultCss={doUseDefaultCss} classes={classes} headerNode={msg("pageExpiredTitle")}>
<p id="instruction1" className="instruction">
{msg("pageExpiredMsg1")}
<a id="loginRestartLink" href={url.loginRestartFlowUrl}>

View File

@ -1,7 +1,7 @@
import { useState, useEffect, useReducer } from "react";
import { clsx } from "keycloakify/tools/clsx";
import { assert } from "tsafe/assert";
import { useGetClassName } from "keycloakify/login/lib/useGetClassName";
import { getKcClsx, type KcClsx } from "keycloakify/login/lib/kcClsx";
import type { PageProps } from "keycloakify/login/pages/PageProps";
import type { KcContext } from "../KcContext";
import { useI18n, type I18n } from "../i18n";
@ -9,7 +9,7 @@ import { useI18n, type I18n } from "../i18n";
export default function LoginPassword(props: PageProps<Extract<KcContext, { pageId: "login-password.ftl" }>>) {
const { kcContext, doUseDefaultCss, Template, classes } = props;
const { getClassName } = useGetClassName({
const { kcClsx } = getKcClsx({
doUseDefaultCss,
classes
});
@ -22,7 +22,13 @@ export default function LoginPassword(props: PageProps<Extract<KcContext, { page
const [isLoginButtonDisabled, setIsLoginButtonDisabled] = useState(false);
return (
<Template {...{ kcContext, doUseDefaultCss, classes }} headerNode={msg("doLogIn")} displayMessage={!messagesPerField.existsError("password")}>
<Template
kcContext={kcContext}
doUseDefaultCss={doUseDefaultCss}
classes={classes}
headerNode={msg("doLogIn")}
displayMessage={!messagesPerField.existsError("password")}
>
<div id="kc-form">
<div id="kc-form-wrapper">
<form
@ -34,17 +40,17 @@ export default function LoginPassword(props: PageProps<Extract<KcContext, { page
action={url.loginAction}
method="post"
>
<div className={clsx(getClassName("kcFormGroupClass"), "no-bottom-margin")}>
<div className={clsx(kcClsx("kcFormGroupClass"), "no-bottom-margin")}>
<hr />
<label htmlFor="password" className={getClassName("kcLabelClass")}>
<label htmlFor="password" className={kcClsx("kcLabelClass")}>
{msg("password")}
</label>
<PasswordWrapper getClassName={getClassName} i18n={i18n} passwordInputId="password">
<PasswordWrapper kcClsx={kcClsx} i18n={i18n} passwordInputId="password">
<input
tabIndex={2}
id="password"
className={getClassName("kcInputClass")}
className={kcClsx("kcInputClass")}
name="password"
type="password"
autoFocus
@ -54,14 +60,14 @@ export default function LoginPassword(props: PageProps<Extract<KcContext, { page
</PasswordWrapper>
{messagesPerField.existsError("password") && (
<span id="input-error-password" className={getClassName("kcInputErrorMessageClass")} aria-live="polite">
<span id="input-error-password" className={kcClsx("kcInputErrorMessageClass")} aria-live="polite">
{messagesPerField.get("password")}
</span>
)}
</div>
<div className={clsx(getClassName("kcFormGroupClass"), getClassName("kcFormSettingClass"))}>
<div className={kcClsx("kcFormGroupClass", "kcFormSettingClass")}>
<div id="kc-form-options" />
<div className={getClassName("kcFormOptionsWrapperClass")}>
<div className={kcClsx("kcFormOptionsWrapperClass")}>
{realm.resetPasswordAllowed && (
<span>
<a tabIndex={5} href={url.loginResetCredentialsUrl}>
@ -71,15 +77,10 @@ export default function LoginPassword(props: PageProps<Extract<KcContext, { page
)}
</div>
</div>
<div id="kc-form-buttons" className={getClassName("kcFormGroupClass")}>
<div id="kc-form-buttons" className={kcClsx("kcFormGroupClass")}>
<input
tabIndex={4}
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonPrimaryClass"),
getClassName("kcButtonBlockClass"),
getClassName("kcButtonLargeClass")
)}
className={kcClsx("kcButtonClass", "kcButtonPrimaryClass", "kcButtonBlockClass", "kcButtonLargeClass")}
name="login"
id="kc-login"
type="submit"
@ -94,13 +95,8 @@ export default function LoginPassword(props: PageProps<Extract<KcContext, { page
);
}
function PasswordWrapper(props: {
getClassName: ReturnType<typeof useGetClassName>["getClassName"];
i18n: I18n;
passwordInputId: string;
children: JSX.Element;
}) {
const { getClassName, i18n, passwordInputId, children } = props;
function PasswordWrapper(props: { kcClsx: KcClsx; i18n: I18n; passwordInputId: string; children: JSX.Element }) {
const { kcClsx, i18n, passwordInputId, children } = props;
const { msgStr } = i18n;
@ -115,19 +111,16 @@ function PasswordWrapper(props: {
}, [isPasswordRevealed]);
return (
<div className={getClassName("kcInputGroup")}>
<div className={kcClsx("kcInputGroup")}>
{children}
<button
type="button"
className={getClassName("kcFormPasswordVisibilityButtonClass")}
className={kcClsx("kcFormPasswordVisibilityButtonClass")}
aria-label={msgStr(isPasswordRevealed ? "hidePassword" : "showPassword")}
aria-controls={passwordInputId}
onClick={toggleIsPasswordRevealed}
>
<i
className={getClassName(isPasswordRevealed ? "kcFormPasswordVisibilityIconHide" : "kcFormPasswordVisibilityIconShow")}
aria-hidden
/>
<i className={kcClsx(isPasswordRevealed ? "kcFormPasswordVisibilityIconHide" : "kcFormPasswordVisibilityIconShow")} aria-hidden />
</button>
</div>
);

View File

@ -1,6 +1,6 @@
import { useEffect } from "react";
import { clsx } from "keycloakify/tools/clsx";
import { useGetClassName } from "keycloakify/login/lib/useGetClassName";
import { getKcClsx, type KcClsx } from "keycloakify/login/lib/kcClsx";
import { useInsertScriptTags } from "keycloakify/tools/useInsertScriptTags";
import type { PageProps } from "keycloakify/login/pages/PageProps";
import type { KcContext } from "../KcContext";
@ -9,7 +9,7 @@ import { useI18n, type I18n } from "../i18n";
export default function LoginRecoveryAuthnCodeConfig(props: PageProps<Extract<KcContext, { pageId: "login-recovery-authn-code-config.ftl" }>>) {
const { kcContext, doUseDefaultCss, Template, classes } = props;
const { getClassName } = useGetClassName({
const { kcClsx } = getKcClsx({
doUseDefaultCss,
classes
});
@ -145,8 +145,8 @@ export default function LoginRecoveryAuthnCodeConfig(props: PageProps<Extract<Kc
}, []);
return (
<Template {...{ kcContext, doUseDefaultCss, classes }} headerNode={msg("recovery-code-config-header")}>
<div className={clsx("pf-c-alert", "pf-m-warning", "pf-m-inline", getClassName("kcRecoveryCodesWarning"))} aria-label="Warning alert">
<Template kcContext={kcContext} doUseDefaultCss={doUseDefaultCss} classes={classes} headerNode={msg("recovery-code-config-header")}>
<div className={clsx("pf-c-alert", "pf-m-warning", "pf-m-inline", kcClsx("kcRecoveryCodesWarning"))} aria-label="Warning alert">
<div className="pf-c-alert__icon">
<i className="pficon-warning-triangle-o" aria-hidden="true" />
</div>
@ -159,7 +159,7 @@ export default function LoginRecoveryAuthnCodeConfig(props: PageProps<Extract<Kc
</div>
</div>
<ol id="kc-recovery-codes-list" className={getClassName("kcRecoveryCodesList")}>
<ol id="kc-recovery-codes-list" className={kcClsx("kcRecoveryCodesList")}>
{recoveryAuthnCodesConfigBean.generatedRecoveryAuthnCodesList.map((code, index) => (
<li key={index}>
<span>{index + 1}:</span> {code.slice(0, 4)}-{code.slice(4, 8)}-{code.slice(8)}
@ -168,7 +168,7 @@ export default function LoginRecoveryAuthnCodeConfig(props: PageProps<Extract<Kc
</ol>
{/* actions */}
<div className={getClassName("kcRecoveryCodesActions")}>
<div className={kcClsx("kcRecoveryCodesActions")}>
<button id="printRecoveryCodes" className={clsx("pf-c-button", "pf-m-link")} type="button">
<i className="pficon-print" aria-hidden="true" /> {msg("recovery-codes-print")}
</button>
@ -181,9 +181,9 @@ export default function LoginRecoveryAuthnCodeConfig(props: PageProps<Extract<Kc
</div>
{/* confirmation checkbox */}
<div className={getClassName("kcFormOptionsClass")}>
<div className={kcClsx("kcFormOptionsClass")}>
<input
className={getClassName("kcCheckInputClass")}
className={kcClsx("kcCheckInputClass")}
type="checkbox"
id="kcRecoveryCodesConfirmationCheck"
name="kcRecoveryCodesConfirmationCheck"
@ -195,25 +195,25 @@ export default function LoginRecoveryAuthnCodeConfig(props: PageProps<Extract<Kc
<label htmlFor="kcRecoveryCodesConfirmationCheck">{msg("recovery-codes-confirmation-message")}</label>
</div>
<form action={kcContext.url.loginAction} className={getClassName("kcFormGroupClass")} id="kc-recovery-codes-settings-form" method="post">
<form action={kcContext.url.loginAction} className={kcClsx("kcFormGroupClass")} id="kc-recovery-codes-settings-form" method="post">
<input type="hidden" name="generatedRecoveryAuthnCodes" value={recoveryAuthnCodesConfigBean.generatedRecoveryAuthnCodesAsString} />
<input type="hidden" name="generatedAt" value={recoveryAuthnCodesConfigBean.generatedAt} />
<input type="hidden" id="userLabel" name="userLabel" value={msgStr("recovery-codes-label-default")} />
<LogoutOtherSessions {...{ getClassName, i18n }} />
<LogoutOtherSessions kcClsx={kcClsx} i18n={i18n} />
{isAppInitiatedAction ? (
<>
<input
type="submit"
className={clsx(getClassName("kcButtonClass"), getClassName("kcButtonPrimaryClass"), getClassName("kcButtonLargeClass"))}
className={kcClsx("kcButtonClass", "kcButtonPrimaryClass", "kcButtonLargeClass")}
id="saveRecoveryAuthnCodesBtn"
value={msgStr("recovery-codes-action-complete")}
disabled
/>
<button
type="submit"
className={clsx(getClassName("kcButtonClass"), getClassName("kcButtonDefaultClass"), getClassName("kcButtonLargeClass"))}
className={kcClsx("kcButtonClass", "kcButtonDefaultClass", "kcButtonLargeClass")}
id="cancelRecoveryAuthnCodesBtn"
name="cancel-aia"
value="true"
@ -224,12 +224,7 @@ export default function LoginRecoveryAuthnCodeConfig(props: PageProps<Extract<Kc
) : (
<input
type="submit"
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonPrimaryClass"),
getClassName("kcButtonBlockClass"),
getClassName("kcButtonLargeClass")
)}
className={kcClsx("kcButtonClass", "kcButtonPrimaryClass", "kcButtonBlockClass", "kcButtonLargeClass")}
id="saveRecoveryAuthnCodesBtn"
value={msgStr("recovery-codes-action-complete")}
disabled
@ -240,14 +235,14 @@ export default function LoginRecoveryAuthnCodeConfig(props: PageProps<Extract<Kc
);
}
function LogoutOtherSessions(props: { getClassName: ReturnType<typeof useGetClassName>["getClassName"]; i18n: I18n }) {
const { getClassName, i18n } = props;
function LogoutOtherSessions(props: { kcClsx: KcClsx; i18n: I18n }) {
const { kcClsx, i18n } = props;
const { msg } = i18n;
return (
<div id="kc-form-options" className={getClassName("kcFormOptionsClass")}>
<div className={getClassName("kcFormOptionsWrapperClass")}>
<div id="kc-form-options" className={kcClsx("kcFormOptionsClass")}>
<div className={kcClsx("kcFormOptionsWrapperClass")}>
<div className="checkbox">
<label>
<input type="checkbox" id="logout-sessions" name="logout-sessions" value="on" defaultChecked={true} />

View File

@ -1,5 +1,4 @@
import { clsx } from "keycloakify/tools/clsx";
import { useGetClassName } from "keycloakify/login/lib/useGetClassName";
import { getKcClsx } from "keycloakify/login/lib/kcClsx";
import type { PageProps } from "keycloakify/login/pages/PageProps";
import type { KcContext } from "../KcContext";
import { useI18n } from "../i18n";
@ -7,7 +6,7 @@ import { useI18n } from "../i18n";
export default function LoginRecoveryAuthnCodeInput(props: PageProps<Extract<KcContext, { pageId: "login-recovery-authn-code-input.ftl" }>>) {
const { kcContext, doUseDefaultCss, Template, classes } = props;
const { getClassName } = useGetClassName({
const { kcClsx } = getKcClsx({
doUseDefaultCss,
classes
});
@ -18,18 +17,20 @@ export default function LoginRecoveryAuthnCodeInput(props: PageProps<Extract<KcC
return (
<Template
{...{ kcContext, doUseDefaultCss, classes }}
kcContext={kcContext}
doUseDefaultCss={doUseDefaultCss}
classes={classes}
headerNode={msg("auth-recovery-code-header")}
displayMessage={!messagesPerField.existsError("recoveryCodeInput")}
>
<form id="kc-recovery-code-login-form" className={getClassName("kcFormClass")} action={url.loginAction} method="post">
<div className={getClassName("kcFormGroupClass")}>
<div className={getClassName("kcLabelWrapperClass")}>
<label htmlFor="recoveryCodeInput" className={getClassName("kcLabelClass")}>
<form id="kc-recovery-code-login-form" className={kcClsx("kcFormClass")} action={url.loginAction} method="post">
<div className={kcClsx("kcFormGroupClass")}>
<div className={kcClsx("kcLabelWrapperClass")}>
<label htmlFor="recoveryCodeInput" className={kcClsx("kcLabelClass")}>
{msg("auth-recovery-code-prompt", `${recoveryAuthnCodesInputBean.codeNumber}`)}
</label>
</div>
<div className={getClassName("kcInputWrapperClass")}>
<div className={kcClsx("kcInputWrapperClass")}>
<input
tabIndex={1}
id="recoveryCodeInput"
@ -37,29 +38,24 @@ export default function LoginRecoveryAuthnCodeInput(props: PageProps<Extract<KcC
aria-invalid={messagesPerField.existsError("recoveryCodeInput")}
autoComplete="off"
type="text"
className={getClassName("kcInputClass")}
className={kcClsx("kcInputClass")}
autoFocus
/>
{messagesPerField.existsError("recoveryCodeInput") && (
<span id="input-error" className={getClassName("kcInputErrorMessageClass")} aria-live="polite">
<span id="input-error" className={kcClsx("kcInputErrorMessageClass")} aria-live="polite">
{messagesPerField.get("recoveryCodeInput")}
</span>
)}
</div>
</div>
<div className={getClassName("kcFormGroupClass")}>
<div id="kc-form-options" className={getClassName("kcFormOptionsWrapperClass")}>
<div className={getClassName("kcFormOptionsWrapperClass")} />
<div className={kcClsx("kcFormGroupClass")}>
<div id="kc-form-options" className={kcClsx("kcFormOptionsWrapperClass")}>
<div className={kcClsx("kcFormOptionsWrapperClass")} />
</div>
<div id="kc-form-buttons" className={getClassName("kcFormButtonsClass")}>
<div id="kc-form-buttons" className={kcClsx("kcFormButtonsClass")}>
<input
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonPrimaryClass"),
getClassName("kcButtonBlockClass"),
getClassName("kcButtonLargeClass")
)}
className={kcClsx("kcButtonClass", "kcButtonPrimaryClass", "kcButtonBlockClass", "kcButtonLargeClass")}
name="login"
id="kc-login"
type="submit"

View File

@ -1,6 +1,5 @@
import { Fragment } from "react";
import { clsx } from "keycloakify/tools/clsx";
import { useGetClassName } from "keycloakify/login/lib/useGetClassName";
import { getKcClsx } from "keycloakify/login/lib/kcClsx";
import type { PageProps } from "keycloakify/login/pages/PageProps";
import type { KcContext } from "../KcContext";
import { useI18n } from "../i18n";
@ -8,7 +7,7 @@ import { useI18n } from "../i18n";
export default function LoginResetOtp(props: PageProps<Extract<KcContext, { pageId: "login-reset-otp.ftl" }>>) {
const { kcContext, doUseDefaultCss, Template, classes } = props;
const { getClassName } = useGetClassName({
const { kcClsx } = getKcClsx({
doUseDefaultCss,
classes
});
@ -18,41 +17,42 @@ export default function LoginResetOtp(props: PageProps<Extract<KcContext, { page
const { msg, msgStr } = useI18n({ kcContext });
return (
<Template {...{ kcContext, doUseDefaultCss, classes }} displayMessage={!messagesPerField.existsError("totp")} headerNode={msg("doLogIn")}>
<form id="kc-otp-reset-form" className={getClassName("kcFormClass")} action={url.loginAction} method="post">
<div className={getClassName("kcInputWrapperClass")}>
<div className={getClassName("kcInfoAreaWrapperClass")}>
<Template
kcContext={kcContext}
doUseDefaultCss={doUseDefaultCss}
classes={classes}
displayMessage={!messagesPerField.existsError("totp")}
headerNode={msg("doLogIn")}
>
<form id="kc-otp-reset-form" className={kcClsx("kcFormClass")} action={url.loginAction} method="post">
<div className={kcClsx("kcInputWrapperClass")}>
<div className={kcClsx("kcInfoAreaWrapperClass")}>
<p id="kc-otp-reset-form-description">{msg("otp-reset-description")}</p>
{configuredOtpCredentials.userOtpCredentials.map((otpCredential, index) => (
<Fragment key={otpCredential.id}>
<input
id={`kc-otp-credential-${index}`}
className={getClassName("kcLoginOTPListInputClass")}
className={kcClsx("kcLoginOTPListInputClass")}
type="radio"
name="selectedCredentialId"
value={otpCredential.id}
defaultChecked={otpCredential.id === configuredOtpCredentials.selectedCredentialId}
/>
<label htmlFor={`kc-otp-credential-${index}`} className={getClassName("kcLoginOTPListClass")} tabIndex={index}>
<span className={getClassName("kcLoginOTPListItemHeaderClass")}>
<span className={getClassName("kcLoginOTPListItemIconBodyClass")}>
<i className={getClassName("kcLoginOTPListItemIconClass")} aria-hidden="true"></i>
<label htmlFor={`kc-otp-credential-${index}`} className={kcClsx("kcLoginOTPListClass")} tabIndex={index}>
<span className={kcClsx("kcLoginOTPListItemHeaderClass")}>
<span className={kcClsx("kcLoginOTPListItemIconBodyClass")}>
<i className={kcClsx("kcLoginOTPListItemIconClass")} aria-hidden="true"></i>
</span>
<span className={getClassName("kcLoginOTPListItemTitleClass")}>{otpCredential.userLabel}</span>
<span className={kcClsx("kcLoginOTPListItemTitleClass")}>{otpCredential.userLabel}</span>
</span>
</label>
</Fragment>
))}
<div className={getClassName("kcFormGroupClass")}>
<div id="kc-form-buttons" className={getClassName("kcFormButtonsClass")}>
<div className={kcClsx("kcFormGroupClass")}>
<div id="kc-form-buttons" className={kcClsx("kcFormButtonsClass")}>
<input
id="kc-otp-reset-form-submit"
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonPrimaryClass"),
getClassName("kcButtonBlockClass"),
getClassName("kcButtonLargeClass")
)}
className={kcClsx("kcButtonClass", "kcButtonPrimaryClass", "kcButtonBlockClass", "kcButtonLargeClass")}
type="submit"
value={msgStr("doSubmit")}
/>

View File

@ -1,5 +1,4 @@
import { clsx } from "keycloakify/tools/clsx";
import { useGetClassName } from "keycloakify/login/lib/useGetClassName";
import { getKcClsx } from "keycloakify/login/lib/kcClsx";
import type { PageProps } from "keycloakify/login/pages/PageProps";
import type { KcContext } from "../KcContext";
import { useI18n } from "../i18n";
@ -7,7 +6,7 @@ import { useI18n } from "../i18n";
export default function LoginResetPassword(props: PageProps<Extract<KcContext, { pageId: "login-reset-password.ftl" }>>) {
const { kcContext, doUseDefaultCss, Template, classes } = props;
const { getClassName } = useGetClassName({
const { kcClsx } = getKcClsx({
doUseDefaultCss,
classes
});
@ -18,16 +17,18 @@ export default function LoginResetPassword(props: PageProps<Extract<KcContext, {
return (
<Template
{...{ kcContext, doUseDefaultCss, classes }}
kcContext={kcContext}
doUseDefaultCss={doUseDefaultCss}
classes={classes}
displayInfo
displayMessage={!messagesPerField.existsError("username")}
infoNode={realm.duplicateEmailsAllowed ? msg("emailInstructionUsername") : msg("emailInstruction")}
headerNode={msg("emailForgotTitle")}
>
<form id="kc-reset-password-form" className={getClassName("kcFormClass")} action={url.loginAction} method="post">
<div className={getClassName("kcFormGroupClass")}>
<div className={getClassName("kcLabelWrapperClass")}>
<label htmlFor="username" className={getClassName("kcLabelClass")}>
<form id="kc-reset-password-form" className={kcClsx("kcFormClass")} action={url.loginAction} method="post">
<div className={kcClsx("kcFormGroupClass")}>
<div className={kcClsx("kcLabelWrapperClass")}>
<label htmlFor="username" className={kcClsx("kcLabelClass")}>
{!realm.loginWithEmailAllowed
? msg("username")
: !realm.registrationEmailAsUsername
@ -35,40 +36,35 @@ export default function LoginResetPassword(props: PageProps<Extract<KcContext, {
: msg("email")}
</label>
</div>
<div className={getClassName("kcInputWrapperClass")}>
<div className={kcClsx("kcInputWrapperClass")}>
<input
type="text"
id="username"
name="username"
className={getClassName("kcInputClass")}
className={kcClsx("kcInputClass")}
autoFocus
defaultValue={auth.attemptedUsername ?? ""}
aria-invalid={messagesPerField.existsError("username")}
/>
{messagesPerField.existsError("username") && (
<span id="input-error-username" className={getClassName("kcInputErrorMessageClass")} aria-live="polite">
<span id="input-error-username" className={kcClsx("kcInputErrorMessageClass")} aria-live="polite">
{messagesPerField.get("username")}
</span>
)}
</div>
</div>
<div className={clsx(getClassName("kcFormGroupClass"), getClassName("kcFormSettingClass"))}>
<div id="kc-form-options" className={getClassName("kcFormOptionsClass")}>
<div className={getClassName("kcFormOptionsWrapperClass")}>
<div className={kcClsx("kcFormGroupClass", "kcFormSettingClass")}>
<div id="kc-form-options" className={kcClsx("kcFormOptionsClass")}>
<div className={kcClsx("kcFormOptionsWrapperClass")}>
<span>
<a href={url.loginUrl}>{msg("backToLogin")}</a>
</span>
</div>
</div>
<div id="kc-form-buttons" className={getClassName("kcFormButtonsClass")}>
<div id="kc-form-buttons" className={kcClsx("kcFormButtonsClass")}>
<input
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonPrimaryClass"),
getClassName("kcButtonBlockClass"),
getClassName("kcButtonLargeClass")
)}
className={kcClsx("kcButtonClass", "kcButtonPrimaryClass", "kcButtonBlockClass", "kcButtonLargeClass")}
type="submit"
value={msgStr("doSubmit")}
/>

View File

@ -1,7 +1,6 @@
import { useEffect, useReducer } from "react";
import { clsx } from "keycloakify/tools/clsx";
import { assert } from "tsafe/assert";
import { useGetClassName } from "keycloakify/login/lib/useGetClassName";
import { getKcClsx, type KcClsx } from "keycloakify/login/lib/kcClsx";
import type { PageProps } from "keycloakify/login/pages/PageProps";
import type { KcContext } from "../KcContext";
import { useI18n, type I18n } from "../i18n";
@ -9,7 +8,7 @@ import { useI18n, type I18n } from "../i18n";
export default function LoginUpdatePassword(props: PageProps<Extract<KcContext, { pageId: "login-update-password.ftl" }>>) {
const { kcContext, doUseDefaultCss, Template, classes } = props;
const { getClassName } = useGetClassName({
const { kcClsx } = getKcClsx({
doUseDefaultCss,
classes
});
@ -21,23 +20,25 @@ export default function LoginUpdatePassword(props: PageProps<Extract<KcContext,
return (
<Template
{...{ kcContext, doUseDefaultCss, classes }}
kcContext={kcContext}
doUseDefaultCss={doUseDefaultCss}
classes={classes}
displayMessage={!messagesPerField.existsError("password", "password-confirm")}
headerNode={msg("updatePasswordTitle")}
>
<form id="kc-passwd-update-form" className={getClassName("kcFormClass")} action={url.loginAction} method="post">
<div className={getClassName("kcFormGroupClass")}>
<div className={getClassName("kcLabelWrapperClass")}>
<label htmlFor="password-new" className={getClassName("kcLabelClass")}>
<form id="kc-passwd-update-form" className={kcClsx("kcFormClass")} action={url.loginAction} method="post">
<div className={kcClsx("kcFormGroupClass")}>
<div className={kcClsx("kcLabelWrapperClass")}>
<label htmlFor="password-new" className={kcClsx("kcLabelClass")}>
{msg("passwordNew")}
</label>
<div className={getClassName("kcInputWrapperClass")}>
<PasswordWrapper {...{ getClassName, i18n }} passwordInputId="password-new">
<div className={kcClsx("kcInputWrapperClass")}>
<PasswordWrapper kcClsx={kcClsx} i18n={i18n} passwordInputId="password-new">
<input
type="password"
id="password-new"
name="password-new"
className={getClassName("kcInputClass")}
className={kcClsx("kcInputClass")}
autoFocus
autoComplete="new-password"
aria-invalid={messagesPerField.existsError("password", "password-confirm")}
@ -45,7 +46,7 @@ export default function LoginUpdatePassword(props: PageProps<Extract<KcContext,
</PasswordWrapper>
{messagesPerField.existsError("password") && (
<span id="input-error-password" className={getClassName("kcInputErrorMessageClass")} aria-live="polite">
<span id="input-error-password" className={kcClsx("kcInputErrorMessageClass")} aria-live="polite">
{messagesPerField.get("password")}
</span>
)}
@ -53,19 +54,19 @@ export default function LoginUpdatePassword(props: PageProps<Extract<KcContext,
</div>
</div>
<div className={getClassName("kcFormGroupClass")}>
<div className={getClassName("kcLabelWrapperClass")}>
<label htmlFor="password-confirm" className={getClassName("kcLabelClass")}>
<div className={kcClsx("kcFormGroupClass")}>
<div className={kcClsx("kcLabelWrapperClass")}>
<label htmlFor="password-confirm" className={kcClsx("kcLabelClass")}>
{msg("passwordConfirm")}
</label>
</div>
<div className={getClassName("kcInputWrapperClass")}>
<PasswordWrapper {...{ getClassName, i18n }} passwordInputId="password-confirm">
<div className={kcClsx("kcInputWrapperClass")}>
<PasswordWrapper kcClsx={kcClsx} i18n={i18n} passwordInputId="password-confirm">
<input
type="password"
id="password-confirm"
name="password-confirm"
className={getClassName("kcInputClass")}
className={kcClsx("kcInputClass")}
autoFocus
autoComplete="new-password"
aria-invalid={messagesPerField.existsError("password", "password-confirm")}
@ -73,33 +74,29 @@ export default function LoginUpdatePassword(props: PageProps<Extract<KcContext,
</PasswordWrapper>
{messagesPerField.existsError("password-confirm") && (
<span id="input-error-password-confirm" className={getClassName("kcInputErrorMessageClass")} aria-live="polite">
<span id="input-error-password-confirm" className={kcClsx("kcInputErrorMessageClass")} aria-live="polite">
{messagesPerField.get("password-confirm")}
</span>
)}
</div>
<div className={getClassName("kcFormGroupClass")}>
<LogoutOtherSessions {...{ getClassName, i18n }} />
<div className={kcClsx("kcFormGroupClass")}>
<LogoutOtherSessions kcClsx={kcClsx} i18n={i18n} />
<div id="kc-form-buttons" className={getClassName("kcFormButtonsClass")}>
<div id="kc-form-buttons" className={kcClsx("kcFormButtonsClass")}>
<input
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonPrimaryClass"),
isAppInitiatedAction && getClassName("kcButtonBlockClass"),
getClassName("kcButtonLargeClass")
className={kcClsx(
"kcButtonClass",
"kcButtonPrimaryClass",
isAppInitiatedAction && "kcButtonBlockClass",
"kcButtonLargeClass"
)}
type="submit"
value={msgStr("doSubmit")}
/>
{isAppInitiatedAction && (
<button
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonDefaultClass"),
getClassName("kcButtonLargeClass")
)}
className={kcClsx("kcButtonClass", "kcButtonDefaultClass", "kcButtonLargeClass")}
type="submit"
name="cancel-aia"
value="true"
@ -115,14 +112,14 @@ export default function LoginUpdatePassword(props: PageProps<Extract<KcContext,
);
}
function LogoutOtherSessions(props: { getClassName: ReturnType<typeof useGetClassName>["getClassName"]; i18n: I18n }) {
const { getClassName, i18n } = props;
function LogoutOtherSessions(props: { kcClsx: KcClsx; i18n: I18n }) {
const { kcClsx, i18n } = props;
const { msg } = i18n;
return (
<div id="kc-form-options" className={getClassName("kcFormOptionsClass")}>
<div className={getClassName("kcFormOptionsWrapperClass")}>
<div id="kc-form-options" className={kcClsx("kcFormOptionsClass")}>
<div className={kcClsx("kcFormOptionsWrapperClass")}>
<div className="checkbox">
<label>
<input type="checkbox" id="logout-sessions" name="logout-sessions" value="on" defaultChecked={true} />
@ -134,13 +131,8 @@ function LogoutOtherSessions(props: { getClassName: ReturnType<typeof useGetClas
);
}
function PasswordWrapper(props: {
getClassName: ReturnType<typeof useGetClassName>["getClassName"];
i18n: I18n;
passwordInputId: string;
children: JSX.Element;
}) {
const { getClassName, i18n, passwordInputId, children } = props;
function PasswordWrapper(props: { kcClsx: KcClsx; i18n: I18n; passwordInputId: string; children: JSX.Element }) {
const { kcClsx, i18n, passwordInputId, children } = props;
const { msgStr } = i18n;
@ -155,19 +147,16 @@ function PasswordWrapper(props: {
}, [isPasswordRevealed]);
return (
<div className={getClassName("kcInputGroup")}>
<div className={kcClsx("kcInputGroup")}>
{children}
<button
type="button"
className={getClassName("kcFormPasswordVisibilityButtonClass")}
className={kcClsx("kcFormPasswordVisibilityButtonClass")}
aria-label={msgStr(isPasswordRevealed ? "hidePassword" : "showPassword")}
aria-controls={passwordInputId}
onClick={toggleIsPasswordRevealed}
>
<i
className={getClassName(isPasswordRevealed ? "kcFormPasswordVisibilityIconHide" : "kcFormPasswordVisibilityIconShow")}
aria-hidden
/>
<i className={kcClsx(isPasswordRevealed ? "kcFormPasswordVisibilityIconHide" : "kcFormPasswordVisibilityIconShow")} aria-hidden />
</button>
</div>
);

View File

@ -1,7 +1,6 @@
import { useState } from "react";
import { clsx } from "keycloakify/tools/clsx";
import type { LazyOrNot } from "keycloakify/tools/LazyOrNot";
import { useGetClassName } from "keycloakify/login/lib/useGetClassName";
import { getKcClsx } from "keycloakify/login/lib/kcClsx";
import type { UserProfileFormFieldsProps } from "keycloakify/login/UserProfileFormFields";
import type { PageProps } from "keycloakify/login/pages/PageProps";
import type { KcContext } from "../KcContext";
@ -14,51 +13,46 @@ type LoginUpdateProfileProps = PageProps<Extract<KcContext, { pageId: "login-upd
export default function LoginUpdateProfile(props: LoginUpdateProfileProps) {
const { kcContext, doUseDefaultCss, Template, classes, UserProfileFormFields } = props;
const { getClassName } = useGetClassName({
const { kcClsx } = getKcClsx({
doUseDefaultCss,
classes
});
const { url, messagesPerField, isAppInitiatedAction } = kcContext;
const { url, isAppInitiatedAction } = kcContext;
const { msg, msgStr } = useI18n({ kcContext });
const [isFormSubmittable, setIsFormSubmittable] = useState(false);
return (
<Template {...{ kcContext, doUseDefaultCss, classes }} displayRequiredFields headerNode={msg("loginProfileTitle")}>
<form id="kc-update-profile-form" className={getClassName("kcFormClass")} action={url.loginAction} method="post">
<UserProfileFormFields
{...{
kcContext,
getClassName,
messagesPerField
}}
onIsFormSubmittableValueChange={setIsFormSubmittable}
/>
<div className={getClassName("kcFormGroupClass")}>
<div id="kc-form-options" className={getClassName("kcFormOptionsClass")}>
<div className={getClassName("kcFormOptionsWrapperClass")} />
<Template
kcContext={kcContext}
doUseDefaultCss={doUseDefaultCss}
classes={classes}
displayRequiredFields
headerNode={msg("loginProfileTitle")}
>
<form id="kc-update-profile-form" className={kcClsx("kcFormClass")} action={url.loginAction} method="post">
<UserProfileFormFields kcContext={kcContext} kcClsx={kcClsx} onIsFormSubmittableValueChange={setIsFormSubmittable} />
<div className={kcClsx("kcFormGroupClass")}>
<div id="kc-form-options" className={kcClsx("kcFormOptionsClass")}>
<div className={kcClsx("kcFormOptionsWrapperClass")} />
</div>
<div id="kc-form-buttons" className={getClassName("kcFormButtonsClass")}>
<div id="kc-form-buttons" className={kcClsx("kcFormButtonsClass")}>
<input
disabled={!isFormSubmittable}
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonPrimaryClass"),
!isAppInitiatedAction && getClassName("kcButtonBlockClass"),
getClassName("kcButtonLargeClass")
className={kcClsx(
"kcButtonClass",
"kcButtonPrimaryClass",
!isAppInitiatedAction && "kcButtonBlockClass",
"kcButtonLargeClass"
)}
type="submit"
value={msgStr("doSubmit")}
/>
{isAppInitiatedAction && (
<button
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonDefaultClass"),
getClassName("kcButtonLargeClass")
)}
className={kcClsx("kcButtonClass", "kcButtonDefaultClass", "kcButtonLargeClass")}
type="submit"
name="cancel-aia"
value="true"

View File

@ -1,6 +1,6 @@
import { useState } from "react";
import { clsx } from "keycloakify/tools/clsx";
import { useGetClassName } from "keycloakify/login/lib/useGetClassName";
import { getKcClsx } from "keycloakify/login/lib/kcClsx";
import type { PageProps } from "keycloakify/login/pages/PageProps";
import type { KcContext } from "../KcContext";
import { useI18n } from "../i18n";
@ -8,7 +8,7 @@ import { useI18n } from "../i18n";
export default function LoginUsername(props: PageProps<Extract<KcContext, { pageId: "login-username.ftl" }>>) {
const { kcContext, doUseDefaultCss, Template, classes } = props;
const { getClassName } = useGetClassName({
const { kcClsx } = getKcClsx({
doUseDefaultCss,
classes
});
@ -21,7 +21,9 @@ export default function LoginUsername(props: PageProps<Extract<KcContext, { page
return (
<Template
{...{ kcContext, doUseDefaultCss, classes }}
kcContext={kcContext}
doUseDefaultCss={doUseDefaultCss}
classes={classes}
displayMessage={!messagesPerField.existsError("username")}
displayInfo={realm.password && realm.registrationAllowed && !registrationDisabled}
infoNode={
@ -38,32 +40,23 @@ export default function LoginUsername(props: PageProps<Extract<KcContext, { page
socialProvidersNode={
<>
{realm.password && social.providers?.length && (
<div id="kc-social-providers" className={getClassName("kcFormSocialAccountSectionClass")}>
<div id="kc-social-providers" className={kcClsx("kcFormSocialAccountSectionClass")}>
<hr />
<h2>{msg("identity-provider-login-label")}</h2>
<ul
className={clsx(
getClassName("kcFormSocialAccountListClass"),
social.providers.length > 3 && getClassName("kcFormSocialAccountListGridClass")
)}
>
<ul className={kcClsx("kcFormSocialAccountListClass", social.providers.length > 3 && "kcFormSocialAccountListGridClass")}>
{social.providers.map((...[p, , providers]) => (
<li key={p.alias}>
<a
id={`social-${p.alias}`}
className={clsx(
getClassName("kcFormSocialAccountListButtonClass"),
providers.length > 3 && getClassName("kcFormSocialAccountGridItem")
className={kcClsx(
"kcFormSocialAccountListButtonClass",
providers.length > 3 && "kcFormSocialAccountGridItem"
)}
type="button"
href={p.loginUrl}
>
{p.iconClasses && (
<i className={clsx(getClassName("kcCommonLogoIdP"), p.iconClasses)} aria-hidden="true"></i>
)}
<span
className={clsx(getClassName("kcFormSocialAccountNameClass"), p.iconClasses && "kc-social-icon-text")}
>
{p.iconClasses && <i className={clsx(kcClsx("kcCommonLogoIdP"), p.iconClasses)} aria-hidden="true"></i>}
<span className={clsx(kcClsx("kcFormSocialAccountNameClass"), p.iconClasses && "kc-social-icon-text")}>
{p.displayName}
</span>
</a>
@ -88,8 +81,8 @@ export default function LoginUsername(props: PageProps<Extract<KcContext, { page
method="post"
>
{!usernameHidden && (
<div className={getClassName("kcFormGroupClass")}>
<label htmlFor="username" className={getClassName("kcLabelClass")}>
<div className={kcClsx("kcFormGroupClass")}>
<label htmlFor="username" className={kcClsx("kcLabelClass")}>
{!realm.loginWithEmailAllowed
? msg("username")
: !realm.registrationEmailAsUsername
@ -99,7 +92,7 @@ export default function LoginUsername(props: PageProps<Extract<KcContext, { page
<input
tabIndex={2}
id="username"
className={getClassName("kcInputClass")}
className={kcClsx("kcInputClass")}
name="username"
defaultValue={login.username ?? ""}
type="text"
@ -108,14 +101,14 @@ export default function LoginUsername(props: PageProps<Extract<KcContext, { page
aria-invalid={messagesPerField.existsError("username")}
/>
{messagesPerField.existsError("username") && (
<span id="input-error" className={getClassName("kcInputErrorMessageClass")} aria-live="polite">
<span id="input-error" className={kcClsx("kcInputErrorMessageClass")} aria-live="polite">
{messagesPerField.getFirstError("username")}
</span>
)}
</div>
)}
<div className={clsx(getClassName("kcFormGroupClass"), getClassName("kcFormSettingClass"))}>
<div className={kcClsx("kcFormGroupClass", "kcFormSettingClass")}>
<div id="kc-form-options">
{realm.rememberMe && !usernameHidden && (
<div className="checkbox">
@ -134,16 +127,11 @@ export default function LoginUsername(props: PageProps<Extract<KcContext, { page
</div>
</div>
<div id="kc-form-buttons" className={getClassName("kcFormGroupClass")}>
<div id="kc-form-buttons" className={kcClsx("kcFormGroupClass")}>
<input
tabIndex={4}
disabled={isLoginButtonDisabled}
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonPrimaryClass"),
getClassName("kcButtonBlockClass"),
getClassName("kcButtonLargeClass")
)}
className={kcClsx("kcButtonClass", "kcButtonPrimaryClass", "kcButtonBlockClass", "kcButtonLargeClass")}
name="login"
id="kc-login"
type="submit"

View File

@ -11,7 +11,9 @@ export default function LoginVerifyEmail(props: PageProps<Extract<KcContext, { p
return (
<Template
{...{ kcContext, doUseDefaultCss, classes }}
kcContext={kcContext}
doUseDefaultCss={doUseDefaultCss}
classes={classes}
displayInfo
headerNode={msg("emailVerifyTitle")}
infoNode={

View File

@ -1,5 +1,4 @@
import { clsx } from "keycloakify/tools/clsx";
import { useGetClassName } from "keycloakify/login/lib/useGetClassName";
import { getKcClsx } from "keycloakify/login/lib/kcClsx";
import type { PageProps } from "keycloakify/login/pages/PageProps";
import type { KcContext } from "../KcContext";
import { useI18n } from "../i18n";
@ -7,7 +6,7 @@ import { useI18n } from "../i18n";
export default function LoginX509Info(props: PageProps<Extract<KcContext, { pageId: "login-x509-info.ftl" }>>) {
const { kcContext, doUseDefaultCss, Template, classes } = props;
const { getClassName } = useGetClassName({
const { kcClsx } = getKcClsx({
doUseDefaultCss,
classes
});
@ -17,56 +16,52 @@ export default function LoginX509Info(props: PageProps<Extract<KcContext, { page
const { msg, msgStr } = useI18n({ kcContext });
return (
<Template {...{ kcContext, doUseDefaultCss, classes }} headerNode={msg("doLogIn")}>
<form id="kc-x509-login-info" className={getClassName("kcFormClass")} action={url.loginAction} method="post">
<div className={getClassName("kcFormGroupClass")}>
<div className={getClassName("kcLabelWrapperClass")}>
<label htmlFor="certificate_subjectDN" className={getClassName("kcLabelClass")}>
<Template kcContext={kcContext} doUseDefaultCss={doUseDefaultCss} classes={classes} headerNode={msg("doLogIn")}>
<form id="kc-x509-login-info" className={kcClsx("kcFormClass")} action={url.loginAction} method="post">
<div className={kcClsx("kcFormGroupClass")}>
<div className={kcClsx("kcLabelWrapperClass")}>
<label htmlFor="certificate_subjectDN" className={kcClsx("kcLabelClass")}>
{msg("clientCertificate")}
</label>
</div>
{x509.formData.subjectDN ? (
<div className={getClassName("kcLabelWrapperClass")}>
<label id="certificate_subjectDN" className={getClassName("kcLabelClass")}>
<div className={kcClsx("kcLabelWrapperClass")}>
<label id="certificate_subjectDN" className={kcClsx("kcLabelClass")}>
{x509.formData.subjectDN}
</label>
</div>
) : (
<div className={getClassName("kcLabelWrapperClass")}>
<label id="certificate_subjectDN" className={getClassName("kcLabelClass")}>
<div className={kcClsx("kcLabelWrapperClass")}>
<label id="certificate_subjectDN" className={kcClsx("kcLabelClass")}>
{msg("noCertificate")}
</label>
</div>
)}
</div>
<div className={getClassName("kcFormGroupClass")}>
<div className={kcClsx("kcFormGroupClass")}>
{x509.formData.isUserEnabled && (
<>
<div className={getClassName("kcLabelWrapperClass")}>
<label htmlFor="username" className={getClassName("kcLabelClass")}>
<div className={kcClsx("kcLabelWrapperClass")}>
<label htmlFor="username" className={kcClsx("kcLabelClass")}>
{msg("doX509Login")}
</label>
</div>
<div className={getClassName("kcLabelWrapperClass")}>
<label id="username" className={getClassName("kcLabelClass")}>
<div className={kcClsx("kcLabelWrapperClass")}>
<label id="username" className={kcClsx("kcLabelClass")}>
{x509.formData.username}
</label>
</div>
</>
)}
</div>
<div className={getClassName("kcFormGroupClass")}>
<div id="kc-form-options" className={getClassName("kcFormOptionsClass")}>
<div className={getClassName("kcFormOptionsWrapperClass")} />
<div className={kcClsx("kcFormGroupClass")}>
<div id="kc-form-options" className={kcClsx("kcFormOptionsClass")}>
<div className={kcClsx("kcFormOptionsWrapperClass")} />
</div>
<div id="kc-form-buttons" className={getClassName("kcFormButtonsClass")}>
<div className={getClassName("kcFormButtonsWrapperClass")}>
<div id="kc-form-buttons" className={kcClsx("kcFormButtonsClass")}>
<div className={kcClsx("kcFormButtonsWrapperClass")}>
<input
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonPrimaryClass"),
getClassName("kcButtonLargeClass")
)}
className={kcClsx("kcButtonClass", "kcButtonPrimaryClass", "kcButtonLargeClass")}
name="login"
id="kc-login"
type="submit"
@ -74,11 +69,7 @@ export default function LoginX509Info(props: PageProps<Extract<KcContext, { page
/>
{x509.formData.isUserEnabled && (
<input
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonDefaultClass"),
getClassName("kcButtonLargeClass")
)}
className={kcClsx("kcButtonClass", "kcButtonDefaultClass", "kcButtonLargeClass")}
name="cancel"
id="kc-cancel"
type="submit"

View File

@ -1,5 +1,4 @@
import { clsx } from "keycloakify/tools/clsx";
import { useGetClassName } from "keycloakify/login/lib/useGetClassName";
import { getKcClsx } from "keycloakify/login/lib/kcClsx";
import type { PageProps } from "keycloakify/login/pages/PageProps";
import type { KcContext } from "../KcContext";
import { useI18n } from "../i18n";
@ -7,7 +6,7 @@ import { useI18n } from "../i18n";
export default function LogoutConfirm(props: PageProps<Extract<KcContext, { pageId: "logout-confirm.ftl" }>>) {
const { kcContext, doUseDefaultCss, Template, classes } = props;
const { getClassName } = useGetClassName({
const { kcClsx } = getKcClsx({
doUseDefaultCss,
classes
});
@ -17,24 +16,19 @@ export default function LogoutConfirm(props: PageProps<Extract<KcContext, { page
const { msg, msgStr } = useI18n({ kcContext });
return (
<Template {...{ kcContext, doUseDefaultCss, classes }} headerNode={msg("logoutConfirmTitle")}>
<Template kcContext={kcContext} doUseDefaultCss={doUseDefaultCss} classes={classes} headerNode={msg("logoutConfirmTitle")}>
<div id="kc-logout-confirm" className="content-area">
<p className="instruction">{msg("logoutConfirmHeader")}</p>
<form className="form-actions" action={url.logoutConfirmAction} method="POST">
<input type="hidden" name="session_code" value={logoutConfirm.code} />
<div className={getClassName("kcFormGroupClass")}>
<div className={kcClsx("kcFormGroupClass")}>
<div id="kc-form-options">
<div className={getClassName("kcFormOptionsWrapperClass")}></div>
<div className={kcClsx("kcFormOptionsWrapperClass")}></div>
</div>
<div id="kc-form-buttons" className={getClassName("kcFormGroupClass")}>
<div id="kc-form-buttons" className={kcClsx("kcFormGroupClass")}>
<input
tabIndex={4}
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonPrimaryClass"),
getClassName("kcButtonBlockClass"),
getClassName("kcButtonLargeClass")
)}
className={kcClsx("kcButtonClass", "kcButtonPrimaryClass", "kcButtonBlockClass", "kcButtonLargeClass")}
name="confirmLogout"
id="kc-logout"
type="submit"

View File

@ -1,9 +1,8 @@
import { useState } from "react";
import { clsx } from "keycloakify/tools/clsx";
import { Markdown } from "keycloakify/tools/Markdown";
import type { LazyOrNot } from "keycloakify/tools/LazyOrNot";
import { useTermsMarkdown } from "keycloakify/login/lib/useDownloadTerms";
import { useGetClassName } from "keycloakify/login/lib/useGetClassName";
import { getKcClsx, type KcClsx } from "keycloakify/login/lib/kcClsx";
import type { UserProfileFormFieldsProps } from "keycloakify/login/UserProfileFormFields";
import type { PageProps } from "keycloakify/login/pages/PageProps";
import type { KcContext } from "../KcContext";
@ -16,7 +15,7 @@ type RegisterProps = PageProps<Extract<KcContext, { pageId: "register.ftl" }>> &
export default function Register(props: RegisterProps) {
const { kcContext, doUseDefaultCss, Template, classes, UserProfileFormFields } = props;
const { getClassName } = useGetClassName({
const { kcClsx } = getKcClsx({
doUseDefaultCss,
classes
});
@ -29,49 +28,29 @@ export default function Register(props: RegisterProps) {
const [isFormSubmittable, setIsFormSubmittable] = useState(false);
return (
<Template {...{ kcContext, doUseDefaultCss, classes }} headerNode={msg("registerTitle")} displayRequiredFields>
<form id="kc-register-form" className={getClassName("kcFormClass")} action={url.registrationAction} method="post">
<UserProfileFormFields
{...{
kcContext,
getClassName,
messagesPerField
}}
onIsFormSubmittableValueChange={setIsFormSubmittable}
/>
{termsAcceptanceRequired && (
<TermsAcceptance
{...{
i18n,
getClassName,
messagesPerField
}}
/>
)}
<Template kcContext={kcContext} doUseDefaultCss={doUseDefaultCss} classes={classes} headerNode={msg("registerTitle")} displayRequiredFields>
<form id="kc-register-form" className={kcClsx("kcFormClass")} action={url.registrationAction} method="post">
<UserProfileFormFields kcContext={kcContext} kcClsx={kcClsx} onIsFormSubmittableValueChange={setIsFormSubmittable} />
{termsAcceptanceRequired && <TermsAcceptance i18n={i18n} kcClsx={kcClsx} messagesPerField={messagesPerField} />}
{recaptchaRequired && (
<div className="form-group">
<div className={getClassName("kcInputWrapperClass")}>
<div className={kcClsx("kcInputWrapperClass")}>
<div className="g-recaptcha" data-size="compact" data-sitekey={recaptchaSiteKey}></div>
</div>
</div>
)}
<div className={getClassName("kcFormGroupClass")}>
<div id="kc-form-options" className={getClassName("kcFormOptionsClass")}>
<div className={getClassName("kcFormOptionsWrapperClass")}>
<div className={kcClsx("kcFormGroupClass")}>
<div id="kc-form-options" className={kcClsx("kcFormOptionsClass")}>
<div className={kcClsx("kcFormOptionsWrapperClass")}>
<span>
<a href={url.loginUrl}>{msg("backToLogin")}</a>
</span>
</div>
</div>
<div id="kc-form-buttons" className={getClassName("kcFormButtonsClass")}>
<div id="kc-form-buttons" className={kcClsx("kcFormButtonsClass")}>
<input
disabled={!isFormSubmittable}
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonPrimaryClass"),
getClassName("kcButtonBlockClass"),
getClassName("kcButtonLargeClass")
)}
className={kcClsx("kcButtonClass", "kcButtonPrimaryClass", "kcButtonBlockClass", "kcButtonLargeClass")}
type="submit"
value={msgStr("doRegister")}
/>
@ -82,12 +61,8 @@ export default function Register(props: RegisterProps) {
);
}
function TermsAcceptance(props: {
i18n: I18n;
getClassName: ReturnType<typeof useGetClassName>["getClassName"];
messagesPerField: Pick<KcContext["messagesPerField"], "existsError" | "get">;
}) {
const { i18n, getClassName, messagesPerField } = props;
function TermsAcceptance(props: { i18n: I18n; kcClsx: KcClsx; messagesPerField: Pick<KcContext["messagesPerField"], "existsError" | "get"> }) {
const { i18n, kcClsx, messagesPerField } = props;
const { msg } = i18n;
@ -101,7 +76,7 @@ function TermsAcceptance(props: {
return (
<>
<div className="form-group">
<div className={getClassName("kcInputWrapperClass")}>
<div className={kcClsx("kcInputWrapperClass")}>
{msg("termsTitle")}
<div id="kc-registration-terms-text">
<Markdown>{termsMarkdown}</Markdown>
@ -109,21 +84,21 @@ function TermsAcceptance(props: {
</div>
</div>
<div className="form-group">
<div className={getClassName("kcLabelWrapperClass")}>
<div className={kcClsx("kcLabelWrapperClass")}>
<input
type="checkbox"
id="termsAccepted"
name="termsAccepted"
className={getClassName("kcCheckboxInputClass")}
className={kcClsx("kcCheckboxInputClass")}
aria-invalid={messagesPerField.existsError("termsAccepted")}
/>
<label htmlFor="termsAccepted" className={getClassName("kcLabelClass")}>
<label htmlFor="termsAccepted" className={kcClsx("kcLabelClass")}>
{msg("acceptTerms")}
</label>
</div>
{messagesPerField.existsError("termsAccepted") && (
<div className={getClassName("kcLabelWrapperClass")}>
<span id="input-error-terms-accepted" className={getClassName("kcInputErrorMessageClass")} aria-live="polite">
<div className={kcClsx("kcLabelWrapperClass")}>
<span id="input-error-terms-accepted" className={kcClsx("kcInputErrorMessageClass")} aria-live="polite">
{messagesPerField.get("termsAccepted")}
</span>
</div>

View File

@ -26,7 +26,7 @@ export default function SamlPostForm(props: PageProps<Extract<KcContext, { pageI
htmlFormElement.submit();
}, [htmlFormElement]);
return (
<Template {...{ kcContext, doUseDefaultCss, classes }} headerNode={msg("saml.post-form.title")}>
<Template kcContext={kcContext} doUseDefaultCss={doUseDefaultCss} classes={classes} headerNode={msg("saml.post-form.title")}>
<p>{msg("saml.post-form.message")}</p>
<form name="saml-post-binding" method="post" action={samlPost.url} ref={setHtmlFormElement}>
{samlPost.SAMLRequest && <input type="hidden" name="SAMLRequest" value={samlPost.SAMLRequest} />}

View File

@ -1,5 +1,4 @@
import { clsx } from "keycloakify/tools/clsx";
import { useGetClassName } from "keycloakify/login/lib/useGetClassName";
import { getKcClsx } from "keycloakify/login/lib/kcClsx";
import type { PageProps } from "keycloakify/login/pages/PageProps";
import type { KcContext } from "../KcContext";
import { useI18n } from "../i18n";
@ -8,36 +7,37 @@ export default function SelectAuthenticator(props: PageProps<Extract<KcContext,
const { kcContext, doUseDefaultCss, Template, classes } = props;
const { url, auth } = kcContext;
const { getClassName } = useGetClassName({ doUseDefaultCss, classes });
const { kcClsx } = getKcClsx({ doUseDefaultCss, classes });
const { msg } = useI18n({ kcContext });
return (
<Template {...{ kcContext, doUseDefaultCss, classes }} displayInfo={false} headerNode={msg("loginChooseAuthenticator")}>
<form id="kc-select-credential-form" className={getClassName("kcFormClass")} action={url.loginAction} method="post">
<div className={getClassName("kcSelectAuthListClass")}>
<Template
kcContext={kcContext}
doUseDefaultCss={doUseDefaultCss}
classes={classes}
displayInfo={false}
headerNode={msg("loginChooseAuthenticator")}
>
<form id="kc-select-credential-form" className={kcClsx("kcFormClass")} action={url.loginAction} method="post">
<div className={kcClsx("kcSelectAuthListClass")}>
{auth.authenticationSelections.map((authenticationSelection, i) => (
<button
key={i}
className={getClassName("kcSelectAuthListItemClass")}
className={kcClsx("kcSelectAuthListItemClass")}
type="submit"
name="authenticationExecution"
value={authenticationSelection.authExecId}
>
<div className={getClassName("kcSelectAuthListItemIconClass")}>
<i
className={clsx(
getClassName(authenticationSelection.iconCssClass),
getClassName("kcSelectAuthListItemIconPropertyClass")
)}
/>
<div className={kcClsx("kcSelectAuthListItemIconClass")}>
<i className={kcClsx(authenticationSelection.iconCssClass, "kcSelectAuthListItemIconPropertyClass")} />
</div>
<div className={getClassName("kcSelectAuthListItemBodyClass")}>
<div className={getClassName("kcSelectAuthListItemHeadingClass")}>{msg(authenticationSelection.displayName)}</div>
<div className={getClassName("kcSelectAuthListItemDescriptionClass")}>{msg(authenticationSelection.helpText)}</div>
<div className={kcClsx("kcSelectAuthListItemBodyClass")}>
<div className={kcClsx("kcSelectAuthListItemHeadingClass")}>{msg(authenticationSelection.displayName)}</div>
<div className={kcClsx("kcSelectAuthListItemDescriptionClass")}>{msg(authenticationSelection.helpText)}</div>
</div>
<div className={getClassName("kcSelectAuthListItemFillClass")} />
<div className={getClassName("kcSelectAuthListItemArrowClass")}>
<i className={getClassName("kcSelectAuthListItemArrowIconClass")} />
<div className={kcClsx("kcSelectAuthListItemFillClass")} />
<div className={kcClsx("kcSelectAuthListItemArrowClass")}>
<i className={kcClsx("kcSelectAuthListItemArrowIconClass")} />
</div>
</button>
))}

View File

@ -1,6 +1,5 @@
import { clsx } from "keycloakify/tools/clsx";
import { Markdown } from "keycloakify/tools/Markdown";
import { useGetClassName } from "keycloakify/login/lib/useGetClassName";
import { getKcClsx } from "keycloakify/login/lib/kcClsx";
import { useTermsMarkdown } from "keycloakify/login/lib/useDownloadTerms";
import type { PageProps } from "keycloakify/login/pages/PageProps";
import type { KcContext } from "../KcContext";
@ -9,7 +8,7 @@ import { useI18n } from "../i18n";
export default function Terms(props: PageProps<Extract<KcContext, { pageId: "terms.ftl" }>>) {
const { kcContext, doUseDefaultCss, Template, classes } = props;
const { getClassName } = useGetClassName({
const { kcClsx } = getKcClsx({
doUseDefaultCss,
classes
});
@ -25,26 +24,20 @@ export default function Terms(props: PageProps<Extract<KcContext, { pageId: "ter
}
return (
<Template {...{ kcContext, doUseDefaultCss, classes }} displayMessage={false} headerNode={msg("termsTitle")}>
<Template kcContext={kcContext} doUseDefaultCss={doUseDefaultCss} classes={classes} displayMessage={false} headerNode={msg("termsTitle")}>
<div id="kc-terms-text" lang={termsLanguageTag !== locale?.currentLanguageTag ? termsLanguageTag : undefined}>
<Markdown>{termsMarkdown}</Markdown>
</div>
<form className="form-actions" action={url.loginAction} method="POST">
<input
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonClass"),
getClassName("kcButtonClass"),
getClassName("kcButtonPrimaryClass"),
getClassName("kcButtonLargeClass")
)}
className={kcClsx("kcButtonClass", "kcButtonClass", "kcButtonClass", "kcButtonPrimaryClass", "kcButtonLargeClass")}
name="accept"
id="kc-accept"
type="submit"
value={msgStr("doAccept")}
/>
<input
className={clsx(getClassName("kcButtonClass"), getClassName("kcButtonDefaultClass"), getClassName("kcButtonLargeClass"))}
className={kcClsx("kcButtonClass", "kcButtonDefaultClass", "kcButtonLargeClass")}
name="cancel"
id="kc-decline"
type="submit"

View File

@ -1,7 +1,6 @@
import { useState } from "react";
import { clsx } from "keycloakify/tools/clsx";
import type { LazyOrNot } from "keycloakify/tools/LazyOrNot";
import { useGetClassName } from "keycloakify/login/lib/useGetClassName";
import { getKcClsx, type KcClsx } from "keycloakify/login/lib/kcClsx";
import type { UserProfileFormFieldsProps } from "keycloakify/login/UserProfileFormFields";
import type { PageProps } from "keycloakify/login/pages/PageProps";
import type { KcContext } from "../KcContext";
@ -14,7 +13,7 @@ type UpdateEmailProps = PageProps<Extract<KcContext, { pageId: "update-email.ftl
export default function UpdateEmail(props: UpdateEmailProps) {
const { kcContext, doUseDefaultCss, Template, classes, UserProfileFormFields } = props;
const { getClassName } = useGetClassName({
const { kcClsx } = getKcClsx({
doUseDefaultCss,
classes
});
@ -28,47 +27,38 @@ export default function UpdateEmail(props: UpdateEmailProps) {
return (
<Template
{...{ kcContext, doUseDefaultCss, classes }}
kcContext={kcContext}
doUseDefaultCss={doUseDefaultCss}
classes={classes}
displayMessage={messagesPerField.exists("global")}
displayRequiredFields
headerNode={msg("updateEmailTitle")}
>
<form id="kc-update-email-form" className={getClassName("kcFormClass")} action={url.loginAction} method="post">
<UserProfileFormFields
{...{
kcContext,
getClassName,
messagesPerField
}}
onIsFormSubmittableValueChange={setIsFormSubmittable}
/>
<form id="kc-update-email-form" className={kcClsx("kcFormClass")} action={url.loginAction} method="post">
<UserProfileFormFields kcContext={kcContext} kcClsx={kcClsx} onIsFormSubmittableValueChange={setIsFormSubmittable} />
<div className={getClassName("kcFormGroupClass")}>
<div id="kc-form-options" className={getClassName("kcFormOptionsClass")}>
<div className={getClassName("kcFormOptionsWrapperClass")} />
<div className={kcClsx("kcFormGroupClass")}>
<div id="kc-form-options" className={kcClsx("kcFormOptionsClass")}>
<div className={kcClsx("kcFormOptionsWrapperClass")} />
</div>
<LogoutOtherSessions {...{ getClassName, i18n }} />
<LogoutOtherSessions kcClsx={kcClsx} i18n={i18n} />
<div id="kc-form-buttons" className={getClassName("kcFormButtonsClass")}>
<div id="kc-form-buttons" className={kcClsx("kcFormButtonsClass")}>
<input
disabled={!isFormSubmittable}
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonPrimaryClass"),
isAppInitiatedAction && getClassName("kcButtonBlockClass"),
getClassName("kcButtonLargeClass")
className={kcClsx(
"kcButtonClass",
"kcButtonPrimaryClass",
isAppInitiatedAction && "kcButtonBlockClass",
"kcButtonLargeClass"
)}
type="submit"
value={msgStr("doSubmit")}
/>
{isAppInitiatedAction && (
<button
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonDefaultClass"),
getClassName("kcButtonLargeClass")
)}
className={kcClsx("kcButtonClass", "kcButtonDefaultClass", "kcButtonLargeClass")}
type="submit"
name="cancel-aia"
value="true"
@ -83,14 +73,14 @@ export default function UpdateEmail(props: UpdateEmailProps) {
);
}
function LogoutOtherSessions(props: { getClassName: ReturnType<typeof useGetClassName>["getClassName"]; i18n: I18n }) {
const { getClassName, i18n } = props;
function LogoutOtherSessions(props: { kcClsx: KcClsx; i18n: I18n }) {
const { kcClsx, i18n } = props;
const { msg } = i18n;
return (
<div id="kc-form-options" className={getClassName("kcFormOptionsClass")}>
<div className={getClassName("kcFormOptionsWrapperClass")}>
<div id="kc-form-options" className={kcClsx("kcFormOptionsClass")}>
<div className={kcClsx("kcFormOptionsWrapperClass")}>
<div className="checkbox">
<label>
<input type="checkbox" id="logout-sessions" name="logout-sessions" value="on" defaultChecked={true} />

View File

@ -2,7 +2,7 @@ import { useEffect, Fragment } from "react";
import { assert } from "tsafe/assert";
import { clsx } from "keycloakify/tools/clsx";
import { useInsertScriptTags } from "keycloakify/tools/useInsertScriptTags";
import { useGetClassName } from "keycloakify/login/lib/useGetClassName";
import { getKcClsx } from "keycloakify/login/lib/kcClsx";
import type { PageProps } from "keycloakify/login/pages/PageProps";
import type { KcContext } from "../KcContext";
import { useI18n } from "../i18n";
@ -10,7 +10,7 @@ import { useI18n } from "../i18n";
export default function WebauthnAuthenticate(props: PageProps<Extract<KcContext, { pageId: "webauthn-authenticate.ftl" }>>) {
const { kcContext, doUseDefaultCss, Template, classes } = props;
const { getClassName } = useGetClassName({ doUseDefaultCss, classes });
const { kcClsx } = getKcClsx({ doUseDefaultCss, classes });
const {
url,
@ -136,7 +136,9 @@ export default function WebauthnAuthenticate(props: PageProps<Extract<KcContext,
return (
<Template
{...{ kcContext, doUseDefaultCss, classes }}
kcContext={kcContext}
doUseDefaultCss={doUseDefaultCss}
classes={classes}
displayMessage={!messagesPerField.existsError("username")}
displayInfo={realm.password && realm.registrationAllowed && !registrationDisabled}
infoNode={
@ -151,7 +153,7 @@ export default function WebauthnAuthenticate(props: PageProps<Extract<KcContext,
}
headerNode={msg("webauthn-login-title")}
>
<div id="kc-form-webauthn" className={getClassName("kcFormClass")}>
<div id="kc-form-webauthn" className={kcClsx("kcFormClass")}>
<form id="webauth" action={url.loginAction} method="post">
<input type="hidden" id="clientDataJSON" name="clientDataJSON" />
<input type="hidden" id="authenticatorData" name="authenticatorData" />
@ -160,10 +162,10 @@ export default function WebauthnAuthenticate(props: PageProps<Extract<KcContext,
<input type="hidden" id="userHandle" name="userHandle" />
<input type="hidden" id="error" name="error" />
</form>
<div className={clsx(getClassName("kcFormGroupClass"), "no-bottom-margin")}>
<div className={clsx(kcClsx("kcFormGroupClass"), "no-bottom-margin")}>
{authenticators && (
<>
<form id="authn_select" className={getClassName("kcFormClass")}>
<form id="authn_select" className={kcClsx("kcFormClass")}>
{authenticators.authenticators.map(authenticator => (
<input type="hidden" name="authn_use_chk" value={authenticator.credentialId} />
))}
@ -172,36 +174,33 @@ export default function WebauthnAuthenticate(props: PageProps<Extract<KcContext,
{shouldDisplayAuthenticators && (
<>
{authenticators.authenticators.length > 1 && (
<p className={getClassName("kcSelectAuthListItemTitle")}>{msg("webauthn-available-authenticators")}</p>
<p className={kcClsx("kcSelectAuthListItemTitle")}>{msg("webauthn-available-authenticators")}</p>
)}
<div className={getClassName("kcFormOptionsClass")}>
<div className={kcClsx("kcFormOptionsClass")}>
{authenticators.authenticators.map((authenticator, i) => (
<div key={i} id="kc-webauthn-authenticator" className={getClassName("kcSelectAuthListItemClass")}>
<div className={getClassName("kcSelectAuthListItemIconClass")}>
<div key={i} id="kc-webauthn-authenticator" className={kcClsx("kcSelectAuthListItemClass")}>
<div className={kcClsx("kcSelectAuthListItemIconClass")}>
<i
className={clsx(
(() => {
const className = getClassName(authenticator.transports.iconClass as any);
const className = kcClsx(authenticator.transports.iconClass as any);
if (className === authenticator.transports.iconClass) {
return getClassName("kcWebAuthnDefaultIcon");
return kcClsx("kcWebAuthnDefaultIcon");
}
return className;
})(),
getClassName("kcSelectAuthListItemIconPropertyClass")
kcClsx("kcSelectAuthListItemIconPropertyClass")
)}
/>
</div>
<div className={getClassName("kcSelectAuthListItemArrowIconClass")}>
<div
id="kc-webauthn-authenticator-label"
className={getClassName("kcSelectAuthListItemHeadingClass")}
>
<div className={kcClsx("kcSelectAuthListItemArrowIconClass")}>
<div id="kc-webauthn-authenticator-label" className={kcClsx("kcSelectAuthListItemHeadingClass")}>
{advancedMsg(authenticator.label)}
</div>
{authenticator.transports.displayNameProperties?.length && (
<div
id="kc-webauthn-authenticator-transport"
className={getClassName("kcSelectAuthListItemDescriptionClass")}
className={kcClsx("kcSelectAuthListItemDescriptionClass")}
>
{authenticator.transports.displayNameProperties
.map((nameProperty, i, arr) => ({
@ -216,11 +215,11 @@ export default function WebauthnAuthenticate(props: PageProps<Extract<KcContext,
))}
</div>
)}
<div className={getClassName("kcSelectAuthListItemDescriptionClass")}>
<div className={kcClsx("kcSelectAuthListItemDescriptionClass")}>
<span id="kc-webauthn-authenticator-created-label">{msg("webauthn-createdAt-label")}</span>
<span id="kc-webauthn-authenticator-created">{authenticator.createdAt}</span>
</div>
<div className={getClassName("kcSelectAuthListItemFillClass")} />
<div className={kcClsx("kcSelectAuthListItemFillClass")} />
</div>
</div>
))}
@ -230,7 +229,7 @@ export default function WebauthnAuthenticate(props: PageProps<Extract<KcContext,
</>
)}
<div id="kc-form-buttons" className={getClassName("kcFormButtonsClass")}>
<div id="kc-form-buttons" className={kcClsx("kcFormButtonsClass")}>
<input
id="authenticateWebAuthnButton"
type="button"
@ -241,12 +240,7 @@ export default function WebauthnAuthenticate(props: PageProps<Extract<KcContext,
}}
autoFocus
value={msgStr("webauthn-doAuthenticate")}
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonPrimaryClass"),
getClassName("kcButtonBlockClass"),
getClassName("kcButtonLargeClass")
)}
className={kcClsx("kcButtonClass", "kcButtonPrimaryClass", "kcButtonBlockClass", "kcButtonLargeClass")}
/>
</div>
</div>

View File

@ -1,5 +1,4 @@
import { clsx } from "keycloakify/tools/clsx";
import { useGetClassName } from "keycloakify/login/lib/useGetClassName";
import { getKcClsx } from "keycloakify/login/lib/kcClsx";
import type { PageProps } from "keycloakify/login/pages/PageProps";
import type { KcContext } from "../KcContext";
import { useI18n } from "../i18n";
@ -11,14 +10,14 @@ export default function WebauthnError(props: PageProps<Extract<KcContext, { page
const { msg, msgStr } = useI18n({ kcContext });
const { getClassName } = useGetClassName({
const { kcClsx } = getKcClsx({
doUseDefaultCss,
classes
});
return (
<Template {...{ kcContext, doUseDefaultCss, classes }} displayMessage headerNode={msg("webauthn-error-title")}>
<form id="kc-error-credential-form" className={getClassName("kcFormClass")} action={url.loginAction} method="post">
<Template kcContext={kcContext} doUseDefaultCss={doUseDefaultCss} classes={classes} displayMessage headerNode={msg("webauthn-error-title")}>
<form id="kc-error-credential-form" className={kcClsx("kcFormClass")} action={url.loginAction} method="post">
<input type="hidden" id="executionValue" name="authenticationExecution" />
<input type="hidden" id="isSetRetry" name="isSetRetry" />
</form>
@ -33,26 +32,16 @@ export default function WebauthnError(props: PageProps<Extract<KcContext, { page
document.getElementById("kc-error-credential-form").submit();
}}
type="button"
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonPrimaryClass"),
getClassName("kcButtonBlockClass"),
getClassName("kcButtonLargeClass")
)}
className={kcClsx("kcButtonClass", "kcButtonPrimaryClass", "kcButtonBlockClass", "kcButtonLargeClass")}
name="try-again"
id="kc-try-again"
value={msgStr("doTryAgain")}
/>
{isAppInitiatedAction && (
<form action={url.loginAction} className={getClassName("kcFormClass")} id="kc-webauthn-settings-form" method="post">
<form action={url.loginAction} className={kcClsx("kcFormClass")} id="kc-webauthn-settings-form" method="post">
<button
type="submit"
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonDefaultClass"),
getClassName("kcButtonBlockClass"),
getClassName("kcButtonLargeClass")
)}
className={kcClsx("kcButtonClass", "kcButtonDefaultClass", "kcButtonBlockClass", "kcButtonLargeClass")}
id="cancelWebAuthnAIA"
name="cancel-aia"
value="true"

View File

@ -1,7 +1,6 @@
import { useEffect } from "react";
import { assert } from "tsafe/assert";
import { clsx } from "keycloakify/tools/clsx";
import { useGetClassName } from "keycloakify/login/lib/useGetClassName";
import { getKcClsx, type KcClsx } from "keycloakify/login/lib/kcClsx";
import { useInsertScriptTags } from "keycloakify/tools/useInsertScriptTags";
import type { PageProps } from "keycloakify/login/pages/PageProps";
import type { KcContext } from "../KcContext";
@ -10,7 +9,7 @@ import { useI18n, type I18n } from "../i18n";
export default function WebauthnRegister(props: PageProps<Extract<KcContext, { pageId: "webauthn-register.ftl" }>>) {
const { kcContext, doUseDefaultCss, Template, classes } = props;
const { getClassName } = useGetClassName({ doUseDefaultCss, classes });
const { kcClsx } = getKcClsx({ doUseDefaultCss, classes });
const {
url,
@ -207,33 +206,30 @@ export default function WebauthnRegister(props: PageProps<Extract<KcContext, { p
return (
<Template
{...{ kcContext, doUseDefaultCss, classes }}
kcContext={kcContext}
doUseDefaultCss={doUseDefaultCss}
classes={classes}
headerNode={
<>
<span className={getClassName("kcWebAuthnKeyIcon")} />
<span className={kcClsx("kcWebAuthnKeyIcon")} />
{msg("webauthn-registration-title")}
</>
}
>
<form id="register" className={getClassName("kcFormClass")} action={url.loginAction} method="post">
<div className={getClassName("kcFormGroupClass")}>
<form id="register" className={kcClsx("kcFormClass")} action={url.loginAction} method="post">
<div className={kcClsx("kcFormGroupClass")}>
<input type="hidden" id="clientDataJSON" name="clientDataJSON" />
<input type="hidden" id="attestationObject" name="attestationObject" />
<input type="hidden" id="publicKeyCredentialId" name="publicKeyCredentialId" />
<input type="hidden" id="authenticatorLabel" name="authenticatorLabel" />
<input type="hidden" id="transports" name="transports" />
<input type="hidden" id="error" name="error" />
<LogoutOtherSessions {...{ i18n, getClassName }} />
<LogoutOtherSessions kcClsx={kcClsx} i18n={i18n} />
</div>
</form>
<input
type="submit"
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonPrimaryClass"),
getClassName("kcButtonBlockClass"),
getClassName("kcButtonLargeClass")
)}
className={kcClsx("kcButtonClass", "kcButtonPrimaryClass", "kcButtonBlockClass", "kcButtonLargeClass")}
id="registerWebAuthn"
value={msgStr("doRegisterSecurityKey")}
onClick={() => {
@ -244,15 +240,10 @@ export default function WebauthnRegister(props: PageProps<Extract<KcContext, { p
/>
{!isSetRetry && isAppInitiatedAction && (
<form action={url.loginAction} className={getClassName("kcFormClass")} id="kc-webauthn-settings-form" method="post">
<form action={url.loginAction} className={kcClsx("kcFormClass")} id="kc-webauthn-settings-form" method="post">
<button
type="submit"
className={clsx(
getClassName("kcButtonClass"),
getClassName("kcButtonDefaultClass"),
getClassName("kcButtonBlockClass"),
getClassName("kcButtonLargeClass")
)}
className={kcClsx("kcButtonClass", "kcButtonDefaultClass", "kcButtonBlockClass", "kcButtonLargeClass")}
id="cancelWebAuthnAIA"
name="cancel-aia"
value="true"
@ -265,14 +256,14 @@ export default function WebauthnRegister(props: PageProps<Extract<KcContext, { p
);
}
function LogoutOtherSessions(props: { i18n: I18n; getClassName: ReturnType<typeof useGetClassName>["getClassName"] }) {
const { getClassName, i18n } = props;
function LogoutOtherSessions(props: { kcClsx: KcClsx; i18n: I18n }) {
const { kcClsx, i18n } = props;
const { msg } = i18n;
return (
<div id="kc-form-options" className={getClassName("kcFormOptionsClass")}>
<div className={getClassName("kcFormOptionsWrapperClass")}>
<div id="kc-form-options" className={kcClsx("kcFormOptionsClass")}>
<div className={kcClsx("kcFormOptionsWrapperClass")}>
<div className="checkbox">
<label>
<input type="checkbox" id="logout-sessions" name="logout-sessions" value="on" defaultChecked={true} />