@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
@@ -1,4 +1,3 @@
1
-
2
1
  import type { Attribute } from "@keycloakify/login-ui/KcContext";
3
2
  import { useI18n } from "../../i18n";
4
3
 
@@ -1,5 +1,4 @@
1
-
2
- import { Input } from '@/components/ui/input';
1
+ import { Input } from "@/components/ui/input";
3
2
  import { assert } from "tsafe/assert";
4
3
  import { useI18n } from "../../i18n";
5
4
  import { AddRemoveButtonsMultiValuedAttribute } from "./AddRemoveButtonsMultiValuedAttribute";
@@ -47,20 +46,34 @@ export function InputTag(
47
46
  disabled={attribute.readOnly}
48
47
  autoComplete={attribute.autocomplete}
49
48
  placeholder={
50
- attribute.annotations.inputTypePlaceholder === undefined ? undefined : advancedMsgStr(attribute.annotations.inputTypePlaceholder)
49
+ attribute.annotations.inputTypePlaceholder === undefined
50
+ ? undefined
51
+ : advancedMsgStr(attribute.annotations.inputTypePlaceholder)
51
52
  }
52
53
  pattern={attribute.annotations.inputTypePattern}
53
- size={attribute.annotations.inputTypeSize === undefined ? undefined : parseInt(`${attribute.annotations.inputTypeSize}`)}
54
+ size={
55
+ attribute.annotations.inputTypeSize === undefined
56
+ ? undefined
57
+ : parseInt(`${attribute.annotations.inputTypeSize}`)
58
+ }
54
59
  maxLength={
55
- attribute.annotations.inputTypeMaxlength === undefined ? undefined : parseInt(`${attribute.annotations.inputTypeMaxlength}`)
60
+ attribute.annotations.inputTypeMaxlength === undefined
61
+ ? undefined
62
+ : parseInt(`${attribute.annotations.inputTypeMaxlength}`)
56
63
  }
57
64
  minLength={
58
- attribute.annotations.inputTypeMinlength === undefined ? undefined : parseInt(`${attribute.annotations.inputTypeMinlength}`)
65
+ attribute.annotations.inputTypeMinlength === undefined
66
+ ? undefined
67
+ : parseInt(`${attribute.annotations.inputTypeMinlength}`)
59
68
  }
60
69
  max={attribute.annotations.inputTypeMax}
61
70
  min={attribute.annotations.inputTypeMin}
62
71
  step={attribute.annotations.inputTypeStep}
63
- {...Object.fromEntries(Object.entries(attribute.html5DataAnnotations ?? {}).map(([key, value]) => [`data-${key}`, value]))}
72
+ {...Object.fromEntries(
73
+ Object.entries(attribute.html5DataAnnotations ?? {}).map(
74
+ ([key, value]) => [`data-${key}`, value]
75
+ )
76
+ )}
64
77
  onChange={event =>
65
78
  dispatchFormAction({
66
79
  action: "update",
@@ -101,7 +114,11 @@ export function InputTag(
101
114
 
102
115
  return (
103
116
  <>
104
- <FieldErrors attribute={attribute} displayableErrors={displayableErrors} fieldIndex={fieldIndex} />
117
+ <FieldErrors
118
+ attribute={attribute}
119
+ displayableErrors={displayableErrors}
120
+ fieldIndex={fieldIndex}
121
+ />
105
122
  <AddRemoveButtonsMultiValuedAttribute
106
123
  attribute={attribute}
107
124
  values={values}
@@ -1,21 +1,20 @@
1
-
2
- import { cn } from '@/components/lib/utils';
3
- import { Checkbox } from '@/components/ui/checkbox';
4
- import { Label } from '@/components/ui/label';
5
- import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group';
6
- import { assert } from 'tsafe/assert';
1
+ import { cn } from "@/components/lib/utils";
2
+ import { Checkbox } from "@/components/ui/checkbox";
3
+ import { Label } from "@/components/ui/label";
4
+ import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
5
+ import { assert } from "tsafe/assert";
7
6
  import type { InputFieldByTypeProps } from "./InputFieldByType";
8
- import { InputLabel } from './InputLabel';
7
+ import { InputLabel } from "./InputLabel";
9
8
 
10
9
  export function InputTagSelects(props: InputFieldByTypeProps) {
11
10
  const { attribute, dispatchFormAction, valueOrValues } = props;
12
11
 
13
-
14
-
15
12
  const isRadio = (() => {
16
13
  const { inputType } = attribute.annotations;
17
14
 
18
- assert(inputType === "select-radiobuttons" || inputType === "multiselect-checkboxes");
15
+ assert(
16
+ inputType === "select-radiobuttons" || inputType === "multiselect-checkboxes"
17
+ );
19
18
 
20
19
  return inputType === "select-radiobuttons";
21
20
  })();
@@ -28,7 +27,9 @@ export function InputTagSelects(props: InputFieldByTypeProps) {
28
27
  break walk;
29
28
  }
30
29
 
31
- const validator = (attribute.validators as Record<string, { options?: string[] }>)[inputOptionsFromValidation];
30
+ const validator = (
31
+ attribute.validators as Record<string, { options?: string[] }>
32
+ )[inputOptionsFromValidation];
32
33
 
33
34
  if (validator === undefined) {
34
35
  break walk;
@@ -74,7 +75,10 @@ export function InputTagSelects(props: InputFieldByTypeProps) {
74
75
  />
75
76
  <Label
76
77
  htmlFor={`${attribute.name}-${option}`}
77
- className={cn("text-sm font-normal", attribute.readOnly && "opacity-50 cursor-not-allowed")}
78
+ className={cn(
79
+ "text-sm font-normal",
80
+ attribute.readOnly && "opacity-50 cursor-not-allowed"
81
+ )}
78
82
  >
79
83
  <InputLabel attribute={attribute} option={option} />
80
84
  </Label>
@@ -90,7 +94,11 @@ export function InputTagSelects(props: InputFieldByTypeProps) {
90
94
  <div key={option} className="flex items-center space-x-2">
91
95
  <Checkbox
92
96
  id={`${attribute.name}-${option}`}
93
- checked={valueOrValues instanceof Array ? valueOrValues.includes(option) : valueOrValues === option}
97
+ checked={
98
+ valueOrValues instanceof Array
99
+ ? valueOrValues.includes(option)
100
+ : valueOrValues === option
101
+ }
94
102
  disabled={attribute.readOnly}
95
103
  onCheckedChange={checked =>
96
104
  dispatchFormAction({
@@ -105,7 +113,10 @@ export function InputTagSelects(props: InputFieldByTypeProps) {
105
113
  if (isChecked) {
106
114
  newValues.push(option);
107
115
  } else {
108
- newValues.splice(newValues.indexOf(option), 1);
116
+ newValues.splice(
117
+ newValues.indexOf(option),
118
+ 1
119
+ );
109
120
  }
110
121
 
111
122
  return newValues;
@@ -125,7 +136,10 @@ export function InputTagSelects(props: InputFieldByTypeProps) {
125
136
  />
126
137
  <Label
127
138
  htmlFor={`${attribute.name}-${option}`}
128
- className={cn("text-sm font-normal", attribute.readOnly && "opacity-50 cursor-not-allowed")}
139
+ className={cn(
140
+ "text-sm font-normal",
141
+ attribute.readOnly && "opacity-50 cursor-not-allowed"
142
+ )}
129
143
  >
130
144
  <InputLabel attribute={attribute} option={option} />
131
145
  </Label>
@@ -133,4 +147,4 @@ export function InputTagSelects(props: InputFieldByTypeProps) {
133
147
  ))}
134
148
  </div>
135
149
  );
136
- }
150
+ }
@@ -1,10 +1,14 @@
1
-
2
-
3
- import { cn } from '@/components/lib/utils';
4
- import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
1
+ import { cn } from "@/components/lib/utils";
2
+ import {
3
+ Select,
4
+ SelectContent,
5
+ SelectItem,
6
+ SelectTrigger,
7
+ SelectValue
8
+ } from "@/components/ui/select";
5
9
  import { assert } from "tsafe/assert";
6
10
  import type { InputFieldByTypeProps } from "./InputFieldByType";
7
- import { InputLabel } from './InputLabel';
11
+ import { InputLabel } from "./InputLabel";
8
12
 
9
13
  export function SelectTag(props: InputFieldByTypeProps) {
10
14
  const { attribute, dispatchFormAction, displayableErrors, valueOrValues } = props;
@@ -21,7 +25,9 @@ export function SelectTag(props: InputFieldByTypeProps) {
21
25
 
22
26
  assert(typeof inputOptionsFromValidation === "string");
23
27
 
24
- const validator = (attribute.validators as Record<string, { options?: string[] }>)[inputOptionsFromValidation];
28
+ const validator = (
29
+ attribute.validators as Record<string, { options?: string[] }>
30
+ )[inputOptionsFromValidation];
25
31
 
26
32
  if (validator === undefined) {
27
33
  break walk;
@@ -45,18 +51,25 @@ export function SelectTag(props: InputFieldByTypeProps) {
45
51
  name={attribute.name}
46
52
  className={cn(
47
53
  "flex min-h-25 h-auto w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
48
- displayableErrors.length !== 0 && "border-destructive ring-destructive/20 focus:ring-destructive"
54
+ displayableErrors.length !== 0 &&
55
+ "border-destructive ring-destructive/20 focus:ring-destructive"
49
56
  )}
50
57
  aria-invalid={displayableErrors.length !== 0}
51
58
  disabled={attribute.readOnly}
52
59
  multiple={true}
53
- size={attribute.annotations.inputTypeSize === undefined ? undefined : parseInt(`${attribute.annotations.inputTypeSize}`)}
60
+ size={
61
+ attribute.annotations.inputTypeSize === undefined
62
+ ? undefined
63
+ : parseInt(`${attribute.annotations.inputTypeSize}`)
64
+ }
54
65
  value={valueOrValues}
55
66
  onChange={event =>
56
67
  dispatchFormAction({
57
68
  action: "update",
58
69
  name: attribute.name,
59
- valueOrValues: Array.from(event.target.selectedOptions).map(option => option.value)
70
+ valueOrValues: Array.from(event.target.selectedOptions).map(
71
+ option => option.value
72
+ )
60
73
  })
61
74
  }
62
75
  onBlur={() =>
@@ -78,7 +91,11 @@ export function SelectTag(props: InputFieldByTypeProps) {
78
91
 
79
92
  return (
80
93
  <Select
81
- value={typeof valueOrValues === "string" && valueOrValues !== "" ? valueOrValues : undefined}
94
+ value={
95
+ typeof valueOrValues === "string" && valueOrValues !== ""
96
+ ? valueOrValues
97
+ : undefined
98
+ }
82
99
  onValueChange={value =>
83
100
  dispatchFormAction({
84
101
  action: "update",
@@ -90,7 +107,11 @@ export function SelectTag(props: InputFieldByTypeProps) {
90
107
  >
91
108
  <SelectTrigger
92
109
  id={attribute.name}
93
- className={cn("w-full", displayableErrors.length !== 0 && "border-destructive ring-destructive/20 focus-visible:ring-destructive")}
110
+ className={cn(
111
+ "w-full",
112
+ displayableErrors.length !== 0 &&
113
+ "border-destructive ring-destructive/20 focus-visible:ring-destructive"
114
+ )}
94
115
  aria-invalid={displayableErrors.length !== 0}
95
116
  onBlur={() =>
96
117
  dispatchFormAction({
@@ -1,5 +1,4 @@
1
-
2
- import { cn } from '@/components/lib/utils';
1
+ import { cn } from "@/components/lib/utils";
3
2
  import { assert } from "tsafe/assert";
4
3
  import type { InputFieldByTypeProps } from "./InputFieldByType";
5
4
 
@@ -16,13 +15,26 @@ export function TextareaTag(props: InputFieldByTypeProps) {
16
15
  name={attribute.name}
17
16
  className={cn(
18
17
  "flex min-h-20 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
19
- displayableErrors.length !== 0 && "border-destructive ring-destructive/20 focus-visible:ring-destructive"
18
+ displayableErrors.length !== 0 &&
19
+ "border-destructive ring-destructive/20 focus-visible:ring-destructive"
20
20
  )}
21
21
  aria-invalid={displayableErrors.length !== 0}
22
22
  disabled={attribute.readOnly}
23
- cols={attribute.annotations.inputTypeCols === undefined ? undefined : parseInt(`${attribute.annotations.inputTypeCols}`)}
24
- rows={attribute.annotations.inputTypeRows === undefined ? undefined : parseInt(`${attribute.annotations.inputTypeRows}`)}
25
- maxLength={attribute.annotations.inputTypeMaxlength === undefined ? undefined : parseInt(`${attribute.annotations.inputTypeMaxlength}`)}
23
+ cols={
24
+ attribute.annotations.inputTypeCols === undefined
25
+ ? undefined
26
+ : parseInt(`${attribute.annotations.inputTypeCols}`)
27
+ }
28
+ rows={
29
+ attribute.annotations.inputTypeRows === undefined
30
+ ? undefined
31
+ : parseInt(`${attribute.annotations.inputTypeRows}`)
32
+ }
33
+ maxLength={
34
+ attribute.annotations.inputTypeMaxlength === undefined
35
+ ? undefined
36
+ : parseInt(`${attribute.annotations.inputTypeMaxlength}`)
37
+ }
26
38
  value={value}
27
39
  onChange={event =>
28
40
  dispatchFormAction({
@@ -40,4 +52,4 @@ export function TextareaTag(props: InputFieldByTypeProps) {
40
52
  }
41
53
  />
42
54
  );
43
- }
55
+ }
@@ -1,4 +1,3 @@
1
-
2
1
  import { Field, FieldDescription, FieldLabel } from "@/components/ui/field";
3
2
  import type { Attribute } from "@keycloakify/login-ui/KcContext";
4
3
  import type { JSX } from "@keycloakify/login-ui/tools/JSX";
@@ -70,7 +69,9 @@ export function UserProfileFormFields(props: UserProfileFormFieldsProps) {
70
69
  />
71
70
  )}
72
71
  <Field
73
- data-invalid={displayableErrors.length > 0 ? "true" : undefined}
72
+ data-invalid={
73
+ displayableErrors.length > 0 ? "true" : undefined
74
+ }
74
75
  style={{
75
76
  display:
76
77
  attribute.annotations.inputType === "hidden"
@@ -82,12 +83,15 @@ export function UserProfileFormFields(props: UserProfileFormFieldsProps) {
82
83
  {advancedMsg(attribute.displayName ?? "")}
83
84
  {attribute.required && <> *</>}
84
85
  </FieldLabel>
85
- {attribute.annotations.inputHelperTextBefore !== undefined && (
86
+ {attribute.annotations.inputHelperTextBefore !==
87
+ undefined && (
86
88
  <FieldDescription
87
89
  id={`form-help-text-before-${attribute.name}`}
88
90
  aria-live="polite"
89
91
  >
90
- {advancedMsg(attribute.annotations.inputHelperTextBefore)}
92
+ {advancedMsg(
93
+ attribute.annotations.inputHelperTextBefore
94
+ )}
91
95
  </FieldDescription>
92
96
  )}
93
97
  <InputFieldByType
@@ -106,7 +110,9 @@ export function UserProfileFormFields(props: UserProfileFormFieldsProps) {
106
110
  id={`form-help-text-after-${attribute.name}`}
107
111
  aria-live="polite"
108
112
  >
109
- {advancedMsg(attribute.annotations.inputHelperTextAfter)}
113
+ {advancedMsg(
114
+ attribute.annotations.inputHelperTextAfter
115
+ )}
110
116
  </FieldDescription>
111
117
  )}
112
118
  {AfterField !== undefined && (
@@ -4,10 +4,14 @@ import type { KcContext } from "../KcContext";
4
4
  import KcPage from "../KcPage";
5
5
  export type { Meta, StoryObj } from "../../kc.gen";
6
6
 
7
- export function createKcPageStory<PageId extends KcContext["pageId"]>(params: { pageId: PageId }) {
7
+ export function createKcPageStory<PageId extends KcContext["pageId"]>(params: {
8
+ pageId: PageId;
9
+ }) {
8
10
  const { pageId } = params;
9
11
 
10
- function KcPageStory(props: { kcContext?: DeepPartial<Extract<KcContext, { pageId: PageId }>> }) {
12
+ function KcPageStory(props: {
13
+ kcContext?: DeepPartial<Extract<KcContext, { pageId: PageId }>>;
14
+ }) {
11
15
  const { kcContext: overrides } = props;
12
16
 
13
17
  const kcContextMock = getKcContextMock({
@@ -1,8 +1,6 @@
1
-
2
1
  import { Suspense, lazy } from "react";
3
2
  import { useKcContext } from "../KcContext";
4
3
 
5
-
6
4
  const Page_login = lazy(() => import("./login"));
7
5
  const Page_register = lazy(() => import("./register"));
8
6
  const Page_info = lazy(() => import("./info"));
@@ -46,7 +44,6 @@ export function PageIndex() {
46
44
  const { kcContext } = useKcContext();
47
45
 
48
46
  return (
49
-
50
47
  <Suspense>
51
48
  {(() => {
52
49
  switch (kcContext.pageId) {
@@ -127,7 +124,6 @@ export function PageIndex() {
127
124
  case "select-organization.ftl":
128
125
  return <Page_select_organization />;
129
126
  }
130
-
131
127
  })()}
132
128
  </Suspense>
133
129
  );
@@ -35,13 +35,12 @@ export const French: Story = {
35
35
  }
36
36
  };
37
37
 
38
-
39
38
  /**
40
- * This reflects the state when "Dark Theme" is set to "Disabled" in the realm settings
39
+ * This reflects the state when "Dark Theme" is set to "Disabled" in the realm settings
41
40
  * (Theme configuration tab of the Keycloak Admin UI).
42
- *
43
- * You should enable this configuration if you want to hide the "dark mode switch"
44
- * and ensure that the theme always renders in light mode, even if the user's system
41
+ *
42
+ * You should enable this configuration if you want to hide the "dark mode switch"
43
+ * and ensure that the theme always renders in light mode, even if the user's system
45
44
  * preference is set to dark.
46
45
  */
47
46
  export const WithDarkModeForbidden: Story = {
@@ -6,15 +6,14 @@ import { Button } from "@/components/ui/button";
6
6
 
7
7
  import { MdContentCopy } from "react-icons/md";
8
8
 
9
- import { useI18n } from '@/login/i18n';
10
- import { useKcContext } from '@/login/KcContext';
11
- import { useState } from 'react';
9
+ import { useI18n } from "@/login/i18n";
10
+ import { useKcContext } from "@/login/KcContext";
11
+ import { useState } from "react";
12
12
  import { MdCheck } from "react-icons/md";
13
13
  import { assert } from "tsafe/assert";
14
14
  import { Template } from "../../components/Template";
15
15
 
16
16
  export function Page() {
17
-
18
17
  const { kcContext } = useKcContext();
19
18
  assert(kcContext.pageId === "code.ftl");
20
19
 
@@ -22,7 +21,6 @@ export function Page() {
22
21
 
23
22
  const { msg } = useI18n();
24
23
 
25
-
26
24
  const handleCopy = async () => {
27
25
  try {
28
26
  await navigator.clipboard.writeText(kcContext.code.code ?? "");
@@ -36,7 +34,9 @@ export function Page() {
36
34
  return (
37
35
  <Template
38
36
  headerNode={
39
- kcContext.code.success ? msg("codeSuccessTitle") : msg("codeErrorTitle", kcContext.code.error)
37
+ kcContext.code.success
38
+ ? msg("codeSuccessTitle")
39
+ : msg("codeErrorTitle", kcContext.code.error)
40
40
  }
41
41
  >
42
42
  <div id="kc-code">
@@ -1,4 +1,3 @@
1
-
2
1
  import { createKcPageStory, type Meta, type StoryObj } from "../../mocks/KcPageStory";
3
2
 
4
3
  const { KcPageStory } = createKcPageStory({ pageId: "delete-account-confirm.ftl" });
@@ -14,7 +13,6 @@ type Story = StoryObj<typeof meta>;
14
13
 
15
14
  export const Default: Story = {};
16
15
 
17
-
18
16
  export const Arabic: Story = {
19
17
  args: {
20
18
  kcContext: {
@@ -1,21 +1,18 @@
1
1
  import { Alert, AlertDescription } from "@/components/ui/alert";
2
2
  import { Button } from "@/components/ui/button";
3
- import { useI18n } from '@/login/i18n';
4
- import { useKcContext } from '@/login/KcContext';
3
+ import { useI18n } from "@/login/i18n";
4
+ import { useKcContext } from "@/login/KcContext";
5
5
  import { assert } from "tsafe/assert";
6
6
  import { Template } from "../../components/Template";
7
7
 
8
8
  export function Page() {
9
-
10
9
  const { kcContext } = useKcContext();
11
10
  assert(kcContext.pageId === "delete-account-confirm.ftl");
12
11
 
13
12
  const { msg, msgStr } = useI18n();
14
13
 
15
14
  return (
16
- <Template
17
- headerNode={msg("deleteAccountConfirm")}
18
- >
15
+ <Template headerNode={msg("deleteAccountConfirm")}>
19
16
  <form action={kcContext.url.loginAction} className="space-y-6" method="post">
20
17
  <Alert variant="warning" className="my-3">
21
18
  <AlertDescription>
@@ -7,7 +7,6 @@ const meta = {
7
7
  component: KcPageStory
8
8
  } satisfies Meta<typeof KcPageStory>;
9
9
 
10
-
11
10
  export default meta;
12
11
 
13
12
  type Story = StoryObj<typeof meta>;
@@ -1,12 +1,11 @@
1
1
  import { Alert, AlertDescription } from "@/components/ui/alert";
2
2
  import { Button } from "@/components/ui/button";
3
- import { useI18n } from '@/login/i18n';
4
- import { useKcContext } from '@/login/KcContext';
3
+ import { useI18n } from "@/login/i18n";
4
+ import { useKcContext } from "@/login/KcContext";
5
5
  import { assert } from "tsafe/assert";
6
6
  import { Template } from "../../components/Template";
7
7
 
8
- export function Page(
9
- ) {
8
+ export function Page() {
10
9
  const { kcContext } = useKcContext();
11
10
  assert(kcContext.pageId === "delete-credential.ftl");
12
11
 
@@ -19,11 +18,17 @@ export function Page(
19
18
  >
20
19
  <Alert variant="warning" className=" my-3">
21
20
  <AlertDescription>
22
- <span>{msg("deleteCredentialMessage", kcContext.credentialLabel)}</span>
21
+ <span>
22
+ {msg("deleteCredentialMessage", kcContext.credentialLabel)}
23
+ </span>
23
24
  </AlertDescription>
24
25
  </Alert>
25
26
 
26
- <form className="form-actions" action={kcContext.url.loginAction} method="POST">
27
+ <form
28
+ className="form-actions"
29
+ action={kcContext.url.loginAction}
30
+ method="POST"
31
+ >
27
32
  <div className="flex flex-col sm:flex-row gap-3 sm:justify-between mt-6">
28
33
  <Button
29
34
  variant="outline"
@@ -13,7 +13,6 @@ type Story = StoryObj<typeof meta>;
13
13
 
14
14
  export const Default: Story = {};
15
15
 
16
-
17
16
  export const Arabic: Story = {
18
17
  args: {
19
18
  kcContext: {
@@ -1,6 +1,5 @@
1
-
2
- import { Alert, AlertDescription } from '@/components/ui/alert';
3
- import { Button } from '@/components/ui/button';
1
+ import { Alert, AlertDescription } from "@/components/ui/alert";
2
+ import { Button } from "@/components/ui/button";
4
3
  import { kcSanitize } from "@keycloakify/login-ui/kcSanitize";
5
4
  import { assert } from "tsafe/assert";
6
5
  import { useKcContext } from "../../KcContext";
@@ -27,15 +26,17 @@ export function Page() {
27
26
  </AlertDescription>
28
27
  </Alert>
29
28
 
30
- {!kcContext.skipLink && kcContext.client !== undefined && kcContext.client.baseUrl !== undefined && (
31
- <div className="mt-2 flex justify-end">
32
- <Button type="button">
33
- <a id="backToApplication" href={kcContext.client.baseUrl}>
34
- {msg("backToApplication")}
35
- </a>
36
- </Button>
37
- </div>
38
- )}
29
+ {!kcContext.skipLink &&
30
+ kcContext.client !== undefined &&
31
+ kcContext.client.baseUrl !== undefined && (
32
+ <div className="mt-2 flex justify-end">
33
+ <Button type="button">
34
+ <a id="backToApplication" href={kcContext.client.baseUrl}>
35
+ {msg("backToApplication")}
36
+ </a>
37
+ </Button>
38
+ </div>
39
+ )}
39
40
  </div>
40
41
  </Template>
41
42
  );
@@ -1,14 +1,13 @@
1
1
  import { Alert, AlertDescription } from "@/components/ui/alert";
2
2
  import { Button } from "@/components/ui/button";
3
- import { useI18n } from '@/login/i18n';
4
- import { useKcContext } from '@/login/KcContext';
3
+ import { useI18n } from "@/login/i18n";
4
+ import { useKcContext } from "@/login/KcContext";
5
5
  import { useEffect, useState } from "react";
6
6
  import { FiCheck, FiExternalLink } from "react-icons/fi";
7
7
  import { assert } from "tsafe/assert";
8
8
  import { Template } from "../../components/Template";
9
9
 
10
10
  export function Page() {
11
-
12
11
  const { kcContext } = useKcContext();
13
12
  assert(kcContext.pageId === "frontchannel-logout.ftl");
14
13
 
@@ -27,7 +26,6 @@ export function Page() {
27
26
  window.location.replace(kcContext.logout.logoutRedirectUri);
28
27
  }, [iframeLoadCount]);
29
28
 
30
-
31
29
  return (
32
30
  <Template
33
31
  documentTitle={msgStr("frontchannel-logout.title")}
@@ -1,6 +1,5 @@
1
1
  import { createKcPageStory, type Meta, type StoryObj } from "../../mocks/KcPageStory";
2
2
 
3
-
4
3
  const { KcPageStory } = createKcPageStory({ pageId: "idp-review-user-profile.ftl" });
5
4
 
6
5
  const meta = {
@@ -6,10 +6,7 @@ import { Template } from "../../components/Template";
6
6
  import { UserProfileFormFields } from "../../components/UserProfileFormFields";
7
7
  import { useI18n } from "../../i18n";
8
8
 
9
-
10
9
  export function Page() {
11
-
12
-
13
10
  const { kcContext } = useKcContext();
14
11
  assert(kcContext.pageId === "idp-review-user-profile.ftl");
15
12
 
@@ -32,8 +29,8 @@ export function Page() {
32
29
  <UserProfileFormFields
33
30
  onIsFormSubmittableValueChange={setIsFomSubmittable}
34
31
  />
35
- <div >
36
- <div id="kc-form-options" >
32
+ <div>
33
+ <div id="kc-form-options">
37
34
  <div />
38
35
  </div>
39
36
  <div id="kc-form-buttons">