@oussemasahbeni/keycloakify-login-shadcn 250004.0.7 → 250004.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/keycloak-theme/components/langauges.tsx +1 -1
  2. package/keycloak-theme/components/theme-toggle.tsx +0 -1
  3. package/keycloak-theme/components/ui/alert.tsx +1 -2
  4. package/keycloak-theme/components/ui/button.tsx +1 -2
  5. package/keycloak-theme/components/ui/card.tsx +0 -1
  6. package/keycloak-theme/components/ui/checkbox.tsx +0 -1
  7. package/keycloak-theme/components/ui/dropdown-menu.tsx +14 -4
  8. package/keycloak-theme/components/ui/field.tsx +0 -1
  9. package/keycloak-theme/components/ui/input-otp.tsx +0 -1
  10. package/keycloak-theme/components/ui/input.tsx +0 -1
  11. package/keycloak-theme/components/ui/label.tsx +1 -2
  12. package/keycloak-theme/components/ui/radio-group.tsx +0 -1
  13. package/keycloak-theme/components/ui/select.tsx +12 -4
  14. package/keycloak-theme/components/ui/separator.tsx +0 -1
  15. package/keycloak-theme/components/ui/tooltip.tsx +0 -1
  16. package/keycloak-theme/login/KcPage.tsx +2 -4
  17. package/keycloak-theme/login/components/LogoutOtherSessions.tsx +3 -5
  18. package/keycloak-theme/login/components/PasswordWrapper.tsx +4 -4
  19. package/keycloak-theme/login/components/Template/Template.tsx +108 -56
  20. package/keycloak-theme/login/components/UserProfileFormFields/AddRemoveButtonsMultiValuedAttribute.tsx +7 -3
  21. package/keycloak-theme/login/components/UserProfileFormFields/FieldErrors.tsx +8 -4
  22. package/keycloak-theme/login/components/UserProfileFormFields/GroupLabel.tsx +33 -14
  23. package/keycloak-theme/login/components/UserProfileFormFields/InputFieldByType.tsx +9 -2
  24. package/keycloak-theme/login/components/UserProfileFormFields/InputLabel.tsx +0 -1
  25. package/keycloak-theme/login/components/UserProfileFormFields/InputTag.tsx +25 -8
  26. package/keycloak-theme/login/components/UserProfileFormFields/InputTagSelects.tsx +30 -16
  27. package/keycloak-theme/login/components/UserProfileFormFields/SelectTag.tsx +32 -11
  28. package/keycloak-theme/login/components/UserProfileFormFields/TextareaTag.tsx +19 -7
  29. package/keycloak-theme/login/components/UserProfileFormFields/UserProfileFormFields.tsx +11 -5
  30. package/keycloak-theme/login/mocks/KcPageStory.tsx +6 -2
  31. package/keycloak-theme/login/pages/PageIndex.tsx +0 -4
  32. package/keycloak-theme/login/pages/code/Page.stories.tsx +4 -5
  33. package/keycloak-theme/login/pages/code/Page.tsx +6 -6
  34. package/keycloak-theme/login/pages/delete-account-confirm/Page.stories.tsx +0 -2
  35. package/keycloak-theme/login/pages/delete-account-confirm/Page.tsx +3 -6
  36. package/keycloak-theme/login/pages/delete-credential/Page.stories.tsx +0 -1
  37. package/keycloak-theme/login/pages/delete-credential/Page.tsx +11 -6
  38. package/keycloak-theme/login/pages/error/Page.stories.tsx +0 -1
  39. package/keycloak-theme/login/pages/error/Page.tsx +13 -12
  40. package/keycloak-theme/login/pages/frontchannel-logout/Page.tsx +2 -4
  41. package/keycloak-theme/login/pages/idp-review-user-profile/Page.stories.tsx +0 -1
  42. package/keycloak-theme/login/pages/idp-review-user-profile/Page.tsx +2 -5
  43. package/keycloak-theme/login/pages/info/Page.tsx +8 -6
  44. package/keycloak-theme/login/pages/link-idp-action/Page.tsx +5 -3
  45. package/keycloak-theme/login/pages/login/Form.tsx +52 -52
  46. package/keycloak-theme/login/pages/login/Page.stories.tsx +4 -3
  47. package/keycloak-theme/login/pages/login/Page.tsx +0 -1
  48. package/keycloak-theme/login/pages/login/SocialProviders.tsx +8 -22
  49. package/keycloak-theme/login/pages/login-config-totp/Page.stories.tsx +0 -1
  50. package/keycloak-theme/login/pages/login-config-totp/Page.tsx +25 -12
  51. package/keycloak-theme/login/pages/login-idp-link-confirm/Page.stories.tsx +0 -1
  52. package/keycloak-theme/login/pages/login-idp-link-confirm/Page.tsx +4 -7
  53. package/keycloak-theme/login/pages/login-idp-link-confirm-override/Page.stories.tsx +0 -1
  54. package/keycloak-theme/login/pages/login-idp-link-confirm-override/Page.tsx +4 -7
  55. package/keycloak-theme/login/pages/login-idp-link-email/Page.stories.tsx +0 -1
  56. package/keycloak-theme/login/pages/login-idp-link-email/Page.tsx +4 -7
  57. package/keycloak-theme/login/pages/login-oauth-grant/Page.tsx +21 -11
  58. package/keycloak-theme/login/pages/login-oauth2-device-verify-user-code/Page.tsx +5 -7
  59. package/keycloak-theme/login/pages/login-otp/Page.stories.tsx +0 -1
  60. package/keycloak-theme/login/pages/login-otp/Page.tsx +35 -26
  61. package/keycloak-theme/login/pages/login-page-expired/Page.stories.tsx +0 -1
  62. package/keycloak-theme/login/pages/login-page-expired/Page.tsx +4 -6
  63. package/keycloak-theme/login/pages/login-passkeys-conditional-authenticate/Page.tsx +153 -96
  64. package/keycloak-theme/login/pages/login-password/Page.tsx +14 -15
  65. package/keycloak-theme/login/pages/login-password/useScript.tsx +0 -1
  66. package/keycloak-theme/login/pages/login-recovery-authn-code-config/Page.tsx +5 -8
  67. package/keycloak-theme/login/pages/login-recovery-authn-code-input/Page.tsx +2 -3
  68. package/keycloak-theme/login/pages/login-reset-otp/Page.stories.tsx +0 -1
  69. package/keycloak-theme/login/pages/login-reset-otp/Page.tsx +3 -4
  70. package/keycloak-theme/login/pages/login-reset-password/Form.tsx +5 -6
  71. package/keycloak-theme/login/pages/login-reset-password/Page.stories.tsx +0 -1
  72. package/keycloak-theme/login/pages/login-reset-password/Page.tsx +3 -3
  73. package/keycloak-theme/login/pages/login-update-password/Page.stories.tsx +0 -1
  74. package/keycloak-theme/login/pages/login-update-password/Page.tsx +5 -7
  75. package/keycloak-theme/login/pages/login-update-profile/Page.stories.tsx +0 -1
  76. package/keycloak-theme/login/pages/login-update-profile/Page.tsx +6 -7
  77. package/keycloak-theme/login/pages/login-username/Page.stories.tsx +0 -1
  78. package/keycloak-theme/login/pages/login-username/Page.tsx +6 -6
  79. package/keycloak-theme/login/pages/login-verify-email/Page.stories.tsx +0 -1
  80. package/keycloak-theme/login/pages/login-verify-email/Page.tsx +3 -4
  81. package/keycloak-theme/login/pages/login-x509-info/Page.stories.tsx +0 -1
  82. package/keycloak-theme/login/pages/login-x509-info/Page.tsx +3 -6
  83. package/keycloak-theme/login/pages/logout-confirm/Page.stories.tsx +0 -1
  84. package/keycloak-theme/login/pages/logout-confirm/Page.tsx +3 -6
  85. package/keycloak-theme/login/pages/register/Form.tsx +8 -7
  86. package/keycloak-theme/login/pages/register/Page.stories.tsx +17 -8
  87. package/keycloak-theme/login/pages/register/TermsAcceptance.tsx +6 -7
  88. package/keycloak-theme/login/pages/saml-post-form/Page.stories.tsx +0 -1
  89. package/keycloak-theme/login/pages/saml-post-form/Page.tsx +4 -6
  90. package/keycloak-theme/login/pages/select-authenticator/Page.stories.tsx +0 -1
  91. package/keycloak-theme/login/pages/select-authenticator/Page.tsx +3 -6
  92. package/keycloak-theme/login/pages/select-organization/Page.tsx +5 -8
  93. package/keycloak-theme/login/pages/terms/Page.tsx +1 -3
  94. package/keycloak-theme/login/pages/update-email/Page.stories.tsx +0 -1
  95. package/keycloak-theme/login/pages/update-email/Page.tsx +6 -7
  96. package/keycloak-theme/login/pages/webauthn-authenticate/Page.stories.tsx +0 -1
  97. package/keycloak-theme/login/pages/webauthn-authenticate/Page.tsx +50 -46
  98. package/keycloak-theme/login/pages/webauthn-error/Page.stories.tsx +2 -5
  99. package/keycloak-theme/login/pages/webauthn-error/Page.tsx +3 -6
  100. package/keycloak-theme/login/pages/webauthn-register/Page.stories.tsx +0 -1
  101. package/keycloak-theme/login/pages/webauthn-register/Page.tsx +4 -4
  102. package/keycloak-theme/login/styleLevelCustomization.tsx +4 -6
  103. package/keycloak-theme/public/site.webmanifest +11 -1
  104. package/package.json +2 -2
@@ -4,7 +4,7 @@ import {
4
4
  DropdownMenuItem,
5
5
  DropdownMenuTrigger
6
6
  } from "@/components/ui/dropdown-menu";
7
- import { useI18n } from '@/login/i18n';
7
+ import { useI18n } from "@/login/i18n";
8
8
  import { IoCheckmark, IoLanguage } from "react-icons/io5";
9
9
  import { Button } from "./ui/button";
10
10
 
@@ -17,7 +17,6 @@ export function ModeToggle() {
17
17
  <Button variant="outline" size="icon" onClick={toggleTheme}>
18
18
  <Sun className="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
19
19
  <Moon className="absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
20
- <span className="sr-only">Toggle theme</span>
21
20
  </Button>
22
21
  );
23
22
  }
@@ -27,7 +27,7 @@ const alertVariants = cva(
27
27
  const Alert = React.forwardRef<
28
28
  HTMLDivElement,
29
29
  React.HTMLAttributes<HTMLDivElement> &
30
- VariantProps<typeof alertVariants> & { showIcon?: boolean }
30
+ VariantProps<typeof alertVariants> & { showIcon?: boolean }
31
31
  >(({ className, showIcon = true, variant, ...props }, ref) => (
32
32
  <div
33
33
  ref={ref}
@@ -79,4 +79,3 @@ const AlertDescription = React.forwardRef<
79
79
  AlertDescription.displayName = "AlertDescription";
80
80
 
81
81
  export { Alert, AlertDescription, AlertTitle };
82
-
@@ -35,7 +35,7 @@ const buttonVariants = cva(
35
35
 
36
36
  export interface ButtonProps
37
37
  extends React.ButtonHTMLAttributes<HTMLButtonElement>,
38
- VariantProps<typeof buttonVariants> {
38
+ VariantProps<typeof buttonVariants> {
39
39
  asChild?: boolean;
40
40
  }
41
41
 
@@ -54,4 +54,3 @@ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
54
54
  Button.displayName = "Button";
55
55
 
56
56
  export { Button, buttonVariants };
57
-
@@ -70,4 +70,3 @@ const CardFooter = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDiv
70
70
  CardFooter.displayName = "CardFooter";
71
71
 
72
72
  export { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle };
73
-
@@ -26,4 +26,3 @@ const Checkbox = React.forwardRef<
26
26
  Checkbox.displayName = CheckboxPrimitive.Root.displayName;
27
27
 
28
28
  export { Checkbox };
29
-
@@ -174,9 +174,19 @@ const DropdownMenuShortcut = ({
174
174
  DropdownMenuShortcut.displayName = "DropdownMenuShortcut";
175
175
 
176
176
  export {
177
- DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator,
178
- DropdownMenuShortcut, DropdownMenuSub,
177
+ DropdownMenu,
178
+ DropdownMenuCheckboxItem,
179
+ DropdownMenuContent,
180
+ DropdownMenuGroup,
181
+ DropdownMenuItem,
182
+ DropdownMenuLabel,
183
+ DropdownMenuPortal,
184
+ DropdownMenuRadioGroup,
185
+ DropdownMenuRadioItem,
186
+ DropdownMenuSeparator,
187
+ DropdownMenuShortcut,
188
+ DropdownMenuSub,
179
189
  DropdownMenuSubContent,
180
- DropdownMenuSubTrigger, DropdownMenuTrigger
190
+ DropdownMenuSubTrigger,
191
+ DropdownMenuTrigger
181
192
  };
182
-
@@ -237,4 +237,3 @@ export {
237
237
  FieldSet,
238
238
  FieldTitle
239
239
  };
240
-
@@ -67,4 +67,3 @@ const InputOTPSeparator = React.forwardRef<
67
67
  InputOTPSeparator.displayName = "InputOTPSeparator";
68
68
 
69
69
  export { InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot };
70
-
@@ -22,4 +22,3 @@ const Input = React.forwardRef<HTMLInputElement, React.ComponentProps<"input">>(
22
22
  Input.displayName = "Input";
23
23
 
24
24
  export { Input };
25
-
@@ -11,7 +11,7 @@ const labelVariants = cva(
11
11
  const Label = React.forwardRef<
12
12
  React.ElementRef<typeof LabelPrimitive.Root>,
13
13
  React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root> &
14
- VariantProps<typeof labelVariants>
14
+ VariantProps<typeof labelVariants>
15
15
  >(({ className, ...props }, ref) => (
16
16
  <LabelPrimitive.Root
17
17
  ref={ref}
@@ -22,4 +22,3 @@ const Label = React.forwardRef<
22
22
  Label.displayName = LabelPrimitive.Root.displayName;
23
23
 
24
24
  export { Label };
25
-
@@ -40,4 +40,3 @@ const RadioGroupItem = React.forwardRef<
40
40
  RadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName;
41
41
 
42
42
  export { RadioGroup, RadioGroupItem };
43
-
@@ -68,7 +68,7 @@ const SelectContent = React.forwardRef<
68
68
  className={cn(
69
69
  "relative z-50 max-h-[--radix-select-content-available-height] min-w-32 overflow-y-auto overflow-x-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[--radix-select-content-transform-origin]",
70
70
  position === "popper" &&
71
- "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
71
+ "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
72
72
  className
73
73
  )}
74
74
  position={position}
@@ -79,7 +79,7 @@ const SelectContent = React.forwardRef<
79
79
  className={cn(
80
80
  "p-1",
81
81
  position === "popper" &&
82
- "h-(--radix-select-trigger-height) w-full min-w-(--radix-select-trigger-width)"
82
+ "h-(--radix-select-trigger-height) w-full min-w-(--radix-select-trigger-width)"
83
83
  )}
84
84
  >
85
85
  {children}
@@ -137,6 +137,14 @@ const SelectSeparator = React.forwardRef<
137
137
  SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
138
138
 
139
139
  export {
140
- Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue
140
+ Select,
141
+ SelectContent,
142
+ SelectGroup,
143
+ SelectItem,
144
+ SelectLabel,
145
+ SelectScrollDownButton,
146
+ SelectScrollUpButton,
147
+ SelectSeparator,
148
+ SelectTrigger,
149
+ SelectValue
141
150
  };
142
-
@@ -24,4 +24,3 @@ const Separator = React.forwardRef<
24
24
  Separator.displayName = SeparatorPrimitive.Root.displayName;
25
25
 
26
26
  export { Separator };
27
-
@@ -28,4 +28,3 @@ const TooltipContent = React.forwardRef<
28
28
  TooltipContent.displayName = TooltipPrimitive.Content.displayName;
29
29
 
30
30
  export { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger };
31
-
@@ -8,9 +8,6 @@ import "./index.css";
8
8
  import { PageIndex } from "./pages/PageIndex";
9
9
  import { useStyleLevelCustomization } from "./styleLevelCustomization";
10
10
 
11
-
12
-
13
-
14
11
  export default function KcPage(props: { kcContext: KcContext }) {
15
12
  const { kcContext } = props;
16
13
 
@@ -28,7 +25,8 @@ export default function KcPage(props: { kcContext: KcContext }) {
28
25
  function StyleLevelCustomization(props: { children: ReactNode }) {
29
26
  const { children } = props;
30
27
 
31
- const { doUseDefaultCss, classes, loadCustomStylesheet, Provider } = useStyleLevelCustomization();
28
+ const { doUseDefaultCss, classes, loadCustomStylesheet, Provider } =
29
+ useStyleLevelCustomization();
32
30
 
33
31
  useExclusiveAppInstanceEffect({
34
32
  effectId: "loadCustomStylesheet",
@@ -1,10 +1,8 @@
1
- import { Checkbox } from '@/components/ui/checkbox';
2
- import { useI18n } from '@/login/i18n';
3
- import { Label } from '@radix-ui/react-label';
4
-
1
+ import { Checkbox } from "@/components/ui/checkbox";
2
+ import { useI18n } from "@/login/i18n";
3
+ import { Label } from "@radix-ui/react-label";
5
4
 
6
5
  export function LogoutOtherSessions() {
7
-
8
6
  const { msg } = useI18n();
9
7
 
10
8
  return (
@@ -1,8 +1,10 @@
1
- import { useI18n } from '@/login/i18n';
2
- import { useKcContext } from '@/login/KcContext';
1
+ import { useI18n } from "@/login/i18n";
2
+ import { useKcContext } from "@/login/KcContext";
3
3
  import { useIsPasswordRevealed } from "keycloakify/tools/useIsPasswordRevealed";
4
+ import type { JSX } from 'react';
4
5
  import { FiEye, FiEyeOff } from "react-icons/fi";
5
6
 
7
+
6
8
  export function PasswordWrapper(props: {
7
9
  passwordInputId: string;
8
10
  children: JSX.Element;
@@ -12,12 +14,10 @@ export function PasswordWrapper(props: {
12
14
 
13
15
  const { msgStr } = useI18n();
14
16
 
15
-
16
17
  const { isPasswordRevealed, toggleIsPasswordRevealed } = useIsPasswordRevealed({
17
18
  passwordInputId
18
19
  });
19
20
 
20
-
21
21
  return (
22
22
  <div className="relative">
23
23
  {children}
@@ -1,17 +1,22 @@
1
- import { Languages } from '@/components/langauges';
2
- import { ModeToggle } from '@/components/theme-toggle';
3
- import { Alert, AlertDescription } from '@/components/ui/alert';
4
- import { Button } from '@/components/ui/button';
5
- import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
6
- import { redirectUrlOrigin } from '@/login/shared/redirectUrlOrigin';
1
+ import { Languages } from "@/components/langauges";
2
+ import { ModeToggle } from "@/components/theme-toggle";
3
+ import { Alert, AlertDescription } from "@/components/ui/alert";
4
+ import { Button } from "@/components/ui/button";
5
+ import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
6
+ import { redirectUrlOrigin } from "@/login/shared/redirectUrlOrigin";
7
7
  import { kcSanitize } from "@keycloakify/login-ui/kcSanitize";
8
8
  import { useKcClsx } from "@keycloakify/login-ui/useKcClsx";
9
- import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@radix-ui/react-tooltip';
9
+ import {
10
+ Tooltip,
11
+ TooltipContent,
12
+ TooltipProvider,
13
+ TooltipTrigger
14
+ } from "@radix-ui/react-tooltip";
10
15
  import { useSetClassName } from "keycloakify/tools/useSetClassName";
11
- import { RotateCcw } from 'lucide-react';
16
+ import { RotateCcw } from "lucide-react";
12
17
  import type { ReactNode } from "react";
13
18
  import { useEffect } from "react";
14
- import { FiHome } from 'react-icons/fi';
19
+ import { FiHome } from "react-icons/fi";
15
20
  import { useI18n } from "../../i18n";
16
21
  import { useKcContext } from "../../KcContext";
17
22
  import companylogo from "./../../assets/img/auth-logo.svg";
@@ -47,7 +52,6 @@ export function Template(props: {
47
52
 
48
53
  const { auth, url, message, isAppInitiatedAction } = kcContext;
49
54
 
50
-
51
55
  const { msg, msgStr, enabledLanguages } = useI18n();
52
56
 
53
57
  const { kcClsx } = useKcClsx();
@@ -79,20 +83,15 @@ export function Template(props: {
79
83
  <div className="flex flex-col gap-4 px-0 py-0 pb-6 lg:p-6 lg:md:p-10 lg:pt-10 min-h-screen lg:min-h-0">
80
84
  {/* navigation */}
81
85
  <div className="absolute top-4 right-4 lg:left-4 z-20 flex gap-2">
82
- <Button variant="outline" size="icon" >
86
+ <Button variant="outline" size="icon">
83
87
  <a href={kcContext.client.baseUrl ?? redirectUrlOrigin}>
84
88
  <FiHome />
85
89
  </a>
86
90
  </Button>
87
91
 
88
- {enabledLanguages.length > 1 && (
89
- <Languages />
90
- )}
91
-
92
+ {enabledLanguages.length > 1 && <Languages />}
92
93
 
93
- {kcContext.darkMode !== false && (
94
- <ModeToggle />
95
- )}
94
+ {kcContext.darkMode !== false && <ModeToggle />}
96
95
  </div>
97
96
 
98
97
  {/* Mobile header with logo */}
@@ -112,29 +111,51 @@ export function Template(props: {
112
111
  <CardHeader className="text-center mb-3 px-6 pt-8 pb-4 lg:pt-6">
113
112
  <CardTitle>
114
113
  {(() => {
115
- const node = !(auth !== undefined && auth.showUsername && !auth.showResetCredentials) ? (
114
+ const node = !(
115
+ auth !== undefined &&
116
+ auth.showUsername &&
117
+ !auth.showResetCredentials
118
+ ) ? (
116
119
  <h1 className="text-xl">{headerNode}</h1>
117
120
  ) : (
118
- <div id="kc-username" className="flex items-center justify-center gap-2">
119
- <label className="font-semibold text-lg" id="kc-attempted-username">
121
+ <div
122
+ id="kc-username"
123
+ className="flex items-center justify-center gap-2"
124
+ >
125
+ <label
126
+ className="font-semibold text-lg"
127
+ id="kc-attempted-username"
128
+ >
120
129
  {auth.attemptedUsername}
121
130
  </label>
122
131
 
123
132
  <TooltipProvider>
124
133
  <Tooltip>
125
134
  <TooltipTrigger asChild>
126
- <Button variant="outline" size="icon" asChild>
135
+ <Button
136
+ variant="outline"
137
+ size="icon"
138
+ asChild
139
+ >
127
140
  <a
128
141
  id="reset-login"
129
- href={url.loginRestartFlowUrl}
130
- aria-label={msgStr("restartLoginTooltip")}
142
+ href={
143
+ url.loginRestartFlowUrl
144
+ }
145
+ aria-label={msgStr(
146
+ "restartLoginTooltip"
147
+ )}
131
148
  >
132
149
  <RotateCcw className="h-4 w-4" />
133
150
  </a>
134
151
  </Button>
135
152
  </TooltipTrigger>
136
153
  <TooltipContent>
137
- <p>{msg("restartLoginTooltip")}</p>
154
+ <p>
155
+ {msg(
156
+ "restartLoginTooltip"
157
+ )}
158
+ </p>
138
159
  </TooltipContent>
139
160
  </Tooltip>
140
161
  </TooltipProvider>
@@ -147,7 +168,9 @@ export function Template(props: {
147
168
  <div>{node}</div>
148
169
  <div>
149
170
  <span className="subtitle">
150
- <span className="text-red-500">*</span>
171
+ <span className="text-red-500">
172
+ *
173
+ </span>
151
174
  {msg("requiredFields")}
152
175
  </span>
153
176
  </div>
@@ -162,39 +185,66 @@ export function Template(props: {
162
185
  <CardContent className="px-6 pb-8">
163
186
  <div id="kc-content">
164
187
  <div id="kc-content-wrapper">
165
- {displayMessage && message !== undefined && (message.type !== "warning" || !isAppInitiatedAction) && (
166
- <Alert variant={message.type} className="my-3">
167
- <AlertDescription>
168
- <div>
169
- <span
170
- dangerouslySetInnerHTML={{
171
- __html: kcSanitize(message.summary)
172
- }}
173
- />
174
- </div>
175
- </AlertDescription>
176
- </Alert>
177
- )}
188
+ {displayMessage &&
189
+ message !== undefined &&
190
+ (message.type !== "warning" ||
191
+ !isAppInitiatedAction) && (
192
+ <Alert
193
+ variant={message.type}
194
+ className="my-3"
195
+ >
196
+ <AlertDescription>
197
+ <div>
198
+ <span
199
+ dangerouslySetInnerHTML={{
200
+ __html: kcSanitize(
201
+ message.summary
202
+ )
203
+ }}
204
+ />
205
+ </div>
206
+ </AlertDescription>
207
+ </Alert>
208
+ )}
178
209
  <div className="children">{children}</div>
179
210
  {socialProvidersNode}
180
- {auth !== undefined && auth.showTryAnotherWayLink && (
181
- <form id="kc-select-try-another-way-form" action={url.loginAction} method="post">
182
- <div className={kcClsx("kcFormGroupClass")}>
183
- <input type="hidden" name="tryAnotherWay" value="on" />
184
- <a
185
- href="#"
186
- id="try-another-way"
187
- onClick={() => {
188
- document.forms["kc-select-try-another-way-form" as never].submit();
189
- return false;
190
- }}
211
+ {auth !== undefined &&
212
+ auth.showTryAnotherWayLink && (
213
+ <form
214
+ id="kc-select-try-another-way-form"
215
+ action={url.loginAction}
216
+ method="post"
217
+ >
218
+ <div
219
+ className={kcClsx(
220
+ "kcFormGroupClass"
221
+ )}
191
222
  >
192
- {msg("doTryAnotherWay")}
193
- </a>
194
- </div>
195
- </form>
223
+ <input
224
+ type="hidden"
225
+ name="tryAnotherWay"
226
+ value="on"
227
+ />
228
+ <a
229
+ href="#"
230
+ id="try-another-way"
231
+ onClick={() => {
232
+ document.forms[
233
+ "kc-select-try-another-way-form" as never
234
+ ].submit();
235
+ return false;
236
+ }}
237
+ >
238
+ {msg("doTryAnotherWay")}
239
+ </a>
240
+ </div>
241
+ </form>
242
+ )}
243
+ {displayInfo && (
244
+ <div className="text-center text-sm mt-4">
245
+ {infoNode}
246
+ </div>
196
247
  )}
197
- {displayInfo && <div className="text-center text-sm mt-4">{infoNode}</div>}
198
248
  </div>
199
249
  </div>
200
250
  </CardContent>
@@ -218,7 +268,9 @@ export function Template(props: {
218
268
  <span className="text-white text-xl"> {APP_NAME}</span>
219
269
  </div>
220
270
 
221
- <p className="text-center text-gray-400 dark:text-white/60">{msg("welcomeMessage")}</p>
271
+ <p className="text-center text-gray-400 dark:text-white/60">
272
+ {msg("welcomeMessage")}
273
+ </p>
222
274
  </div>
223
275
  </div>
224
276
  </div>
@@ -1,5 +1,5 @@
1
- import { Button } from '@/components/ui/button';
2
- import { useI18n } from '@/login/i18n';
1
+ import { Button } from "@/components/ui/button";
2
+ import { useI18n } from "@/login/i18n";
3
3
  import type { Attribute } from "@keycloakify/login-ui/KcContext";
4
4
  import {
5
5
  getButtonToDisplayForMultivaluedAttributeField,
@@ -16,7 +16,11 @@ export function AddRemoveButtonsMultiValuedAttribute(props: {
16
16
 
17
17
  const { msg } = useI18n();
18
18
 
19
- const { hasAdd, hasRemove } = getButtonToDisplayForMultivaluedAttributeField({ attribute, values, fieldIndex });
19
+ const { hasAdd, hasRemove } = getButtonToDisplayForMultivaluedAttributeField({
20
+ attribute,
21
+ values,
22
+ fieldIndex
23
+ });
20
24
 
21
25
  const idPostfix = `-${attribute.name}-${fieldIndex + 1}`;
22
26
 
@@ -1,4 +1,4 @@
1
- import { FieldError } from '@/components/ui/field';
1
+ import { FieldError } from "@/components/ui/field";
2
2
  import type { Attribute } from "@keycloakify/login-ui/KcContext";
3
3
  import type { FormFieldError } from "@keycloakify/login-ui/useUserProfileForm";
4
4
  import { Fragment } from "react";
@@ -10,14 +10,18 @@ export function FieldErrors(props: {
10
10
  }) {
11
11
  const { attribute, fieldIndex } = props;
12
12
 
13
- const displayableErrors = props.displayableErrors.filter(error => error.fieldIndex === fieldIndex);
13
+ const displayableErrors = props.displayableErrors.filter(
14
+ error => error.fieldIndex === fieldIndex
15
+ );
14
16
 
15
17
  if (displayableErrors.length === 0) {
16
18
  return null;
17
19
  }
18
20
 
19
21
  return (
20
- <FieldError id={`input-error-${attribute.name}${fieldIndex === undefined ? "" : `-${fieldIndex}`}`}>
22
+ <FieldError
23
+ id={`input-error-${attribute.name}${fieldIndex === undefined ? "" : `-${fieldIndex}`}`}
24
+ >
21
25
  {displayableErrors.map(({ errorMessage }, i, arr) => (
22
26
  <Fragment key={i}>
23
27
  {errorMessage}
@@ -26,4 +30,4 @@ export function FieldErrors(props: {
26
30
  ))}
27
31
  </FieldError>
28
32
  );
29
- }
33
+ }
@@ -1,9 +1,7 @@
1
-
2
-
3
- import { cn } from '@/components/lib/utils';
4
- import { useI18n } from '@/login/i18n';
1
+ import { cn } from "@/components/lib/utils";
2
+ import { useI18n } from "@/login/i18n";
5
3
  import type { Attribute } from "@keycloakify/login-ui/KcContext";
6
- import { useKcClsx } from '@keycloakify/login-ui/useKcClsx';
4
+ import { useKcClsx } from "@keycloakify/login-ui/useKcClsx";
7
5
  import { assert } from "tsafe/assert";
8
6
 
9
7
  export function GroupLabel(props: {
@@ -18,7 +16,6 @@ export function GroupLabel(props: {
18
16
 
19
17
  const { kcClsx } = useKcClsx();
20
18
 
21
-
22
19
  if (attribute.group?.name !== groupNameRef.current) {
23
20
  groupNameRef.current = attribute.group?.name ?? "";
24
21
 
@@ -27,32 +24,54 @@ export function GroupLabel(props: {
27
24
 
28
25
  return (
29
26
  <div
30
- className={cn("space-y-4 p-4 border rounded-lg bg-card", kcClsx("kcFormGroupClass"))}
31
- {...Object.fromEntries(Object.entries(attribute.group.html5DataAnnotations).map(([key, value]) => [`data-${key}`, value]))}
27
+ className={cn(
28
+ "space-y-4 p-4 border rounded-lg bg-card",
29
+ kcClsx("kcFormGroupClass")
30
+ )}
31
+ {...Object.fromEntries(
32
+ Object.entries(attribute.group.html5DataAnnotations).map(
33
+ ([key, value]) => [`data-${key}`, value]
34
+ )
35
+ )}
32
36
  >
33
37
  {(() => {
34
38
  const groupDisplayHeader = attribute.group.displayHeader ?? "";
35
- const groupHeaderText = groupDisplayHeader !== "" ? advancedMsg(groupDisplayHeader) : attribute.group.name;
39
+ const groupHeaderText =
40
+ groupDisplayHeader !== ""
41
+ ? advancedMsg(groupDisplayHeader)
42
+ : attribute.group.name;
36
43
 
37
44
  return (
38
45
  <div className={cn("", kcClsx("kcContentWrapperClass"))}>
39
- <h3 id={`header-${attribute.group.name}`} className={cn("text-lg font-semibold", kcClsx("kcFormGroupHeader"))}>
46
+ <h3
47
+ id={`header-${attribute.group.name}`}
48
+ className={cn(
49
+ "text-lg font-semibold",
50
+ kcClsx("kcFormGroupHeader")
51
+ )}
52
+ >
40
53
  {groupHeaderText}
41
54
  </h3>
42
55
  </div>
43
56
  );
44
57
  })()}
45
58
  {(() => {
46
- const groupDisplayDescription = attribute.group.displayDescription ?? "";
59
+ const groupDisplayDescription =
60
+ attribute.group.displayDescription ?? "";
47
61
 
48
62
  if (groupDisplayDescription !== "") {
49
- const groupDescriptionText = advancedMsg(groupDisplayDescription);
63
+ const groupDescriptionText = advancedMsg(
64
+ groupDisplayDescription
65
+ );
50
66
 
51
67
  return (
52
68
  <div className={cn("", kcClsx("kcLabelWrapperClass"))}>
53
69
  <p
54
70
  id={`description-${attribute.group.name}`}
55
- className={cn("text-sm text-muted-foreground", kcClsx("kcLabelClass"))}
71
+ className={cn(
72
+ "text-sm text-muted-foreground",
73
+ kcClsx("kcLabelClass")
74
+ )}
56
75
  >
57
76
  {groupDescriptionText}
58
77
  </p>
@@ -68,4 +87,4 @@ export function GroupLabel(props: {
68
87
  }
69
88
 
70
89
  return null;
71
- }
90
+ }
@@ -23,7 +23,14 @@ export function InputFieldByType(props: InputFieldByTypeProps) {
23
23
  // NOTE: Unfortunately, keycloak won't let you define input type="hidden" in the Admin Console.
24
24
  // sometimes in the future it might.
25
25
  case "hidden":
26
- return <input type="hidden" id={attribute.name} name={attribute.name} value={valueOrValues as string} />;
26
+ return (
27
+ <input
28
+ type="hidden"
29
+ id={attribute.name}
30
+ name={attribute.name}
31
+ value={valueOrValues as string}
32
+ />
33
+ );
27
34
  case "textarea":
28
35
  return <TextareaTag {...props} />;
29
36
  case "select":
@@ -56,4 +63,4 @@ export function InputFieldByType(props: InputFieldByTypeProps) {
56
63
  return inputNode;
57
64
  }
58
65
  }
59
- }
66
+ }