@keycloakify/svelte 0.0.1-rc.1

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 (284) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +50 -0
  3. package/dist/account/DefaultPage.svelte +42 -0
  4. package/dist/account/DefaultPage.svelte.d.ts +6 -0
  5. package/dist/account/KcContext/KcContext.d.ts +1 -0
  6. package/dist/account/KcContext/KcContext.js +1 -0
  7. package/dist/account/KcContext/index.d.ts +1 -0
  8. package/dist/account/KcContext/index.js +1 -0
  9. package/dist/account/Template.svelte +143 -0
  10. package/dist/account/Template.svelte.d.ts +6 -0
  11. package/dist/account/Template.useInitialize.d.ts +12 -0
  12. package/dist/account/Template.useInitialize.js +19 -0
  13. package/dist/account/TemplateProps.d.ts +12 -0
  14. package/dist/account/TemplateProps.js +1 -0
  15. package/dist/account/i18n/i18n.d.ts +15 -0
  16. package/dist/account/i18n/i18n.js +1 -0
  17. package/dist/account/i18n/i18nBuilder.d.ts +18 -0
  18. package/dist/account/i18n/i18nBuilder.js +26 -0
  19. package/dist/account/i18n/index.d.ts +1 -0
  20. package/dist/account/i18n/index.js +1 -0
  21. package/dist/account/i18n/useI18n.d.ts +28 -0
  22. package/dist/account/i18n/useI18n.js +65 -0
  23. package/dist/account/index.d.ts +2 -0
  24. package/dist/account/index.js +1 -0
  25. package/dist/account/pages/Account.svelte +182 -0
  26. package/dist/account/pages/Account.svelte.d.ts +6 -0
  27. package/dist/account/pages/Applications.svelte +173 -0
  28. package/dist/account/pages/Applications.svelte.d.ts +6 -0
  29. package/dist/account/pages/FederatedIdentity.svelte +114 -0
  30. package/dist/account/pages/FederatedIdentity.svelte.d.ts +6 -0
  31. package/dist/account/pages/Log.svelte +68 -0
  32. package/dist/account/pages/Log.svelte.d.ts +6 -0
  33. package/dist/account/pages/PageProps.d.ts +10 -0
  34. package/dist/account/pages/PageProps.js +1 -0
  35. package/dist/account/pages/Password.svelte +233 -0
  36. package/dist/account/pages/Password.svelte.d.ts +6 -0
  37. package/dist/account/pages/Sessions.svelte +88 -0
  38. package/dist/account/pages/Sessions.svelte.d.ts +6 -0
  39. package/dist/account/pages/Totp.svelte +287 -0
  40. package/dist/account/pages/Totp.svelte.d.ts +6 -0
  41. package/dist/additional-svelte-typings.d.ts +6 -0
  42. package/dist/bin/197.index.js +13 -0
  43. package/dist/bin/381.index.js +13 -0
  44. package/dist/bin/504.index.js +13 -0
  45. package/dist/bin/87.index.js +13 -0
  46. package/dist/bin/main.js +230 -0
  47. package/dist/bin/package.json +3 -0
  48. package/dist/login/DefaultPage.svelte +135 -0
  49. package/dist/login/DefaultPage.svelte.d.ts +12 -0
  50. package/dist/login/KcContext/KcContext.d.ts +1 -0
  51. package/dist/login/KcContext/KcContext.js +1 -0
  52. package/dist/login/KcContext/index.d.ts +1 -0
  53. package/dist/login/KcContext/index.js +1 -0
  54. package/dist/login/Template.svelte +223 -0
  55. package/dist/login/Template.svelte.d.ts +6 -0
  56. package/dist/login/Template.useInitialize.d.ts +14 -0
  57. package/dist/login/Template.useInitialize.js +55 -0
  58. package/dist/login/TemplateProps.d.ts +20 -0
  59. package/dist/login/TemplateProps.js +1 -0
  60. package/dist/login/components/AddRemoveButtonsMultiValuedAttribute.svelte +57 -0
  61. package/dist/login/components/AddRemoveButtonsMultiValuedAttribute.svelte.d.ts +18 -0
  62. package/dist/login/components/FieldErrors.svelte +31 -0
  63. package/dist/login/components/FieldErrors.svelte.d.ts +12 -0
  64. package/dist/login/components/GroupLabel.svelte +68 -0
  65. package/dist/login/components/GroupLabel.svelte.d.ts +15 -0
  66. package/dist/login/components/InputFieldByType.svelte +58 -0
  67. package/dist/login/components/InputFieldByType.svelte.d.ts +4 -0
  68. package/dist/login/components/InputFieldByTypeProps.d.ts +16 -0
  69. package/dist/login/components/InputFieldByTypeProps.js +1 -0
  70. package/dist/login/components/InputTag.svelte +107 -0
  71. package/dist/login/components/InputTag.svelte.d.ts +7 -0
  72. package/dist/login/components/InputTagSelects.svelte +111 -0
  73. package/dist/login/components/InputTagSelects.svelte.d.ts +4 -0
  74. package/dist/login/components/LogoutOtherSessions.svelte +29 -0
  75. package/dist/login/components/LogoutOtherSessions.svelte.d.ts +10 -0
  76. package/dist/login/components/PasswordWrapper.svelte +43 -0
  77. package/dist/login/components/PasswordWrapper.svelte.d.ts +13 -0
  78. package/dist/login/components/SelectTag.svelte +72 -0
  79. package/dist/login/components/SelectTag.svelte.d.ts +4 -0
  80. package/dist/login/components/TermsAcceptance.svelte +56 -0
  81. package/dist/login/components/TermsAcceptance.svelte.d.ts +13 -0
  82. package/dist/login/components/TextareaTag.svelte +40 -0
  83. package/dist/login/components/TextareaTag.svelte.d.ts +4 -0
  84. package/dist/login/components/UserProfileFormFields.svelte +123 -0
  85. package/dist/login/components/UserProfileFormFields.svelte.d.ts +6 -0
  86. package/dist/login/components/UserProfileFormFieldsProps.d.ts +27 -0
  87. package/dist/login/components/UserProfileFormFieldsProps.js +2 -0
  88. package/dist/login/components/inputLabel.d.ts +3 -0
  89. package/dist/login/components/inputLabel.js +12 -0
  90. package/dist/login/i18n/i18n.d.ts +15 -0
  91. package/dist/login/i18n/i18n.js +1 -0
  92. package/dist/login/i18n/i18nBuilder.d.ts +18 -0
  93. package/dist/login/i18n/i18nBuilder.js +26 -0
  94. package/dist/login/i18n/index.d.ts +1 -0
  95. package/dist/login/i18n/index.js +1 -0
  96. package/dist/login/i18n/useI18n.d.ts +28 -0
  97. package/dist/login/i18n/useI18n.js +65 -0
  98. package/dist/login/index.d.ts +2 -0
  99. package/dist/login/index.js +1 -0
  100. package/dist/login/lib/useUserProfileForm.d.ts +66 -0
  101. package/dist/login/lib/useUserProfileForm.js +63 -0
  102. package/dist/login/pages/Code.svelte +46 -0
  103. package/dist/login/pages/Code.svelte.d.ts +6 -0
  104. package/dist/login/pages/DeleteAccountConfirm.svelte +77 -0
  105. package/dist/login/pages/DeleteAccountConfirm.svelte.d.ts +6 -0
  106. package/dist/login/pages/DeleteCredential.svelte +58 -0
  107. package/dist/login/pages/DeleteCredential.svelte.d.ts +6 -0
  108. package/dist/login/pages/Error.svelte +43 -0
  109. package/dist/login/pages/Error.svelte.d.ts +6 -0
  110. package/dist/login/pages/FrontchannelLogout.svelte +57 -0
  111. package/dist/login/pages/FrontchannelLogout.svelte.d.ts +6 -0
  112. package/dist/login/pages/IdpReviewUserProfile.svelte +80 -0
  113. package/dist/login/pages/IdpReviewUserProfile.svelte.d.ts +11 -0
  114. package/dist/login/pages/Info.svelte +66 -0
  115. package/dist/login/pages/Info.svelte.d.ts +6 -0
  116. package/dist/login/pages/Login.svelte +225 -0
  117. package/dist/login/pages/Login.svelte.d.ts +6 -0
  118. package/dist/login/pages/LoginConfigTotp.svelte +217 -0
  119. package/dist/login/pages/LoginConfigTotp.svelte.d.ts +6 -0
  120. package/dist/login/pages/LoginIdpLinkConfirm.svelte +60 -0
  121. package/dist/login/pages/LoginIdpLinkConfirm.svelte.d.ts +6 -0
  122. package/dist/login/pages/LoginIdpLinkConfirmOverride.svelte +59 -0
  123. package/dist/login/pages/LoginIdpLinkConfirmOverride.svelte.d.ts +6 -0
  124. package/dist/login/pages/LoginIdpLinkEmail.svelte +50 -0
  125. package/dist/login/pages/LoginIdpLinkEmail.svelte.d.ts +6 -0
  126. package/dist/login/pages/LoginOauth2DeviceVerifyUserCode.svelte +85 -0
  127. package/dist/login/pages/LoginOauth2DeviceVerifyUserCode.svelte.d.ts +6 -0
  128. package/dist/login/pages/LoginOauthGrant.svelte +126 -0
  129. package/dist/login/pages/LoginOauthGrant.svelte.d.ts +6 -0
  130. package/dist/login/pages/LoginOtp.svelte +128 -0
  131. package/dist/login/pages/LoginOtp.svelte.d.ts +6 -0
  132. package/dist/login/pages/LoginPageExpired.svelte +50 -0
  133. package/dist/login/pages/LoginPageExpired.svelte.d.ts +6 -0
  134. package/dist/login/pages/LoginPasskeysConditionalAuthenticate.svelte +240 -0
  135. package/dist/login/pages/LoginPasskeysConditionalAuthenticate.svelte.d.ts +6 -0
  136. package/dist/login/pages/LoginPasskeysConditionalAuthenticate.useScript.d.ts +21 -0
  137. package/dist/login/pages/LoginPasskeysConditionalAuthenticate.useScript.js +57 -0
  138. package/dist/login/pages/LoginPassword.svelte +120 -0
  139. package/dist/login/pages/LoginPassword.svelte.d.ts +6 -0
  140. package/dist/login/pages/LoginRecoveryAuthnCodeConfig.svelte +179 -0
  141. package/dist/login/pages/LoginRecoveryAuthnCodeConfig.svelte.d.ts +6 -0
  142. package/dist/login/pages/LoginRecoveryAuthnCodeConfig.useScript.d.ts +10 -0
  143. package/dist/login/pages/LoginRecoveryAuthnCodeConfig.useScript.js +141 -0
  144. package/dist/login/pages/LoginRecoveryAuthnCodeInput.svelte +94 -0
  145. package/dist/login/pages/LoginRecoveryAuthnCodeInput.svelte.d.ts +6 -0
  146. package/dist/login/pages/LoginResetOtp.svelte +86 -0
  147. package/dist/login/pages/LoginResetOtp.svelte.d.ts +6 -0
  148. package/dist/login/pages/LoginResetPassword.svelte +109 -0
  149. package/dist/login/pages/LoginResetPassword.svelte.d.ts +6 -0
  150. package/dist/login/pages/LoginUpdatePassword.svelte +149 -0
  151. package/dist/login/pages/LoginUpdatePassword.svelte.d.ts +6 -0
  152. package/dist/login/pages/LoginUpdateProfile.svelte +98 -0
  153. package/dist/login/pages/LoginUpdateProfile.svelte.d.ts +11 -0
  154. package/dist/login/pages/LoginUsername.svelte +182 -0
  155. package/dist/login/pages/LoginUsername.svelte.d.ts +6 -0
  156. package/dist/login/pages/LoginVerifyEmail.svelte +39 -0
  157. package/dist/login/pages/LoginVerifyEmail.svelte.d.ts +6 -0
  158. package/dist/login/pages/LoginX509Info.svelte +123 -0
  159. package/dist/login/pages/LoginX509Info.svelte.d.ts +6 -0
  160. package/dist/login/pages/LogoutConfirm.svelte +77 -0
  161. package/dist/login/pages/LogoutConfirm.svelte.d.ts +6 -0
  162. package/dist/login/pages/PageProps.d.ts +10 -0
  163. package/dist/login/pages/PageProps.js +1 -0
  164. package/dist/login/pages/Register.svelte +136 -0
  165. package/dist/login/pages/Register.svelte.d.ts +11 -0
  166. package/dist/login/pages/SamlPostForm.svelte +80 -0
  167. package/dist/login/pages/SamlPostForm.svelte.d.ts +6 -0
  168. package/dist/login/pages/SelectAuthenticator.svelte +63 -0
  169. package/dist/login/pages/SelectAuthenticator.svelte.d.ts +6 -0
  170. package/dist/login/pages/Terms.svelte +57 -0
  171. package/dist/login/pages/Terms.svelte.d.ts +6 -0
  172. package/dist/login/pages/UpdateEmail.svelte +104 -0
  173. package/dist/login/pages/UpdateEmail.svelte.d.ts +11 -0
  174. package/dist/login/pages/WebauthnAuthenticate.svelte +182 -0
  175. package/dist/login/pages/WebauthnAuthenticate.svelte.d.ts +6 -0
  176. package/dist/login/pages/WebauthnAuthenticate.useScript.d.ts +22 -0
  177. package/dist/login/pages/WebauthnAuthenticate.useScript.js +49 -0
  178. package/dist/login/pages/WebauthnError.svelte +86 -0
  179. package/dist/login/pages/WebauthnError.svelte.d.ts +6 -0
  180. package/dist/login/pages/WebauthnRegister.svelte +109 -0
  181. package/dist/login/pages/WebauthnRegister.svelte.d.ts +6 -0
  182. package/dist/login/pages/WebauthnRegister.useScript.d.ts +28 -0
  183. package/dist/login/pages/WebauthnRegister.useScript.js +57 -0
  184. package/dist/tools/useConst.d.ts +1 -0
  185. package/dist/tools/useConst.js +4 -0
  186. package/dist/tools/useInsertLinkTags.d.ts +12 -0
  187. package/dist/tools/useInsertLinkTags.js +62 -0
  188. package/dist/tools/useInsertScriptTags.d.ts +29 -0
  189. package/dist/tools/useInsertScriptTags.js +77 -0
  190. package/dist/tools/useReducer.d.ts +2 -0
  191. package/dist/tools/useReducer.js +7 -0
  192. package/dist/tools/useSetClassName.d.ts +4 -0
  193. package/dist/tools/useSetClassName.js +15 -0
  194. package/dist/tools/useState.d.ts +2 -0
  195. package/dist/tools/useState.js +7 -0
  196. package/package.json +468 -0
  197. package/src/account/DefaultPage.svelte +42 -0
  198. package/src/account/KcContext/KcContext.ts +1 -0
  199. package/src/account/KcContext/index.ts +1 -0
  200. package/src/account/Template.svelte +143 -0
  201. package/src/account/Template.useInitialize.ts +32 -0
  202. package/src/account/TemplateProps.ts +15 -0
  203. package/src/account/i18n/i18n.ts +18 -0
  204. package/src/account/i18n/i18nBuilder.ts +101 -0
  205. package/src/account/i18n/index.ts +1 -0
  206. package/src/account/i18n/useI18n.ts +140 -0
  207. package/src/account/index.ts +2 -0
  208. package/src/account/pages/Account.svelte +182 -0
  209. package/src/account/pages/Applications.svelte +173 -0
  210. package/src/account/pages/FederatedIdentity.svelte +114 -0
  211. package/src/account/pages/Log.svelte +68 -0
  212. package/src/account/pages/PageProps.ts +11 -0
  213. package/src/account/pages/Password.svelte +233 -0
  214. package/src/account/pages/Sessions.svelte +88 -0
  215. package/src/account/pages/Totp.svelte +287 -0
  216. package/src/additional-svelte-typings.d.ts +6 -0
  217. package/src/login/DefaultPage.svelte +135 -0
  218. package/src/login/KcContext/KcContext.ts +1 -0
  219. package/src/login/KcContext/index.ts +1 -0
  220. package/src/login/Template.svelte +223 -0
  221. package/src/login/Template.useInitialize.ts +72 -0
  222. package/src/login/TemplateProps.ts +23 -0
  223. package/src/login/components/AddRemoveButtonsMultiValuedAttribute.svelte +57 -0
  224. package/src/login/components/FieldErrors.svelte +31 -0
  225. package/src/login/components/GroupLabel.svelte +68 -0
  226. package/src/login/components/InputFieldByType.svelte +58 -0
  227. package/src/login/components/InputFieldByTypeProps.ts +15 -0
  228. package/src/login/components/InputTag.svelte +107 -0
  229. package/src/login/components/InputTagSelects.svelte +111 -0
  230. package/src/login/components/LogoutOtherSessions.svelte +29 -0
  231. package/src/login/components/PasswordWrapper.svelte +43 -0
  232. package/src/login/components/SelectTag.svelte +72 -0
  233. package/src/login/components/TermsAcceptance.svelte +56 -0
  234. package/src/login/components/TextareaTag.svelte +40 -0
  235. package/src/login/components/UserProfileFormFields.svelte +123 -0
  236. package/src/login/components/UserProfileFormFieldsProps.ts +25 -0
  237. package/src/login/components/inputLabel.ts +19 -0
  238. package/src/login/i18n/i18n.ts +18 -0
  239. package/src/login/i18n/i18nBuilder.ts +101 -0
  240. package/src/login/i18n/index.ts +1 -0
  241. package/src/login/i18n/useI18n.ts +140 -0
  242. package/src/login/index.ts +2 -0
  243. package/src/login/lib/useUserProfileForm.ts +166 -0
  244. package/src/login/pages/Code.svelte +46 -0
  245. package/src/login/pages/DeleteAccountConfirm.svelte +77 -0
  246. package/src/login/pages/DeleteCredential.svelte +58 -0
  247. package/src/login/pages/Error.svelte +43 -0
  248. package/src/login/pages/FrontchannelLogout.svelte +57 -0
  249. package/src/login/pages/IdpReviewUserProfile.svelte +80 -0
  250. package/src/login/pages/Info.svelte +66 -0
  251. package/src/login/pages/Login.svelte +225 -0
  252. package/src/login/pages/LoginConfigTotp.svelte +217 -0
  253. package/src/login/pages/LoginIdpLinkConfirm.svelte +60 -0
  254. package/src/login/pages/LoginIdpLinkConfirmOverride.svelte +59 -0
  255. package/src/login/pages/LoginIdpLinkEmail.svelte +50 -0
  256. package/src/login/pages/LoginOauth2DeviceVerifyUserCode.svelte +85 -0
  257. package/src/login/pages/LoginOauthGrant.svelte +126 -0
  258. package/src/login/pages/LoginOtp.svelte +128 -0
  259. package/src/login/pages/LoginPageExpired.svelte +50 -0
  260. package/src/login/pages/LoginPasskeysConditionalAuthenticate.svelte +240 -0
  261. package/src/login/pages/LoginPasskeysConditionalAuthenticate.useScript.ts +82 -0
  262. package/src/login/pages/LoginPassword.svelte +120 -0
  263. package/src/login/pages/LoginRecoveryAuthnCodeConfig.svelte +179 -0
  264. package/src/login/pages/LoginRecoveryAuthnCodeConfig.useScript.ts +157 -0
  265. package/src/login/pages/LoginRecoveryAuthnCodeInput.svelte +94 -0
  266. package/src/login/pages/LoginResetOtp.svelte +86 -0
  267. package/src/login/pages/LoginResetPassword.svelte +109 -0
  268. package/src/login/pages/LoginUpdatePassword.svelte +149 -0
  269. package/src/login/pages/LoginUpdateProfile.svelte +98 -0
  270. package/src/login/pages/LoginUsername.svelte +182 -0
  271. package/src/login/pages/LoginVerifyEmail.svelte +39 -0
  272. package/src/login/pages/LoginX509Info.svelte +123 -0
  273. package/src/login/pages/LogoutConfirm.svelte +77 -0
  274. package/src/login/pages/PageProps.ts +11 -0
  275. package/src/login/pages/Register.svelte +136 -0
  276. package/src/login/pages/SamlPostForm.svelte +80 -0
  277. package/src/login/pages/SelectAuthenticator.svelte +63 -0
  278. package/src/login/pages/Terms.svelte +57 -0
  279. package/src/login/pages/UpdateEmail.svelte +104 -0
  280. package/src/login/pages/WebauthnAuthenticate.svelte +182 -0
  281. package/src/login/pages/WebauthnAuthenticate.useScript.ts +74 -0
  282. package/src/login/pages/WebauthnError.svelte +86 -0
  283. package/src/login/pages/WebauthnRegister.svelte +109 -0
  284. package/src/login/pages/WebauthnRegister.useScript.ts +107 -0
@@ -0,0 +1,72 @@
1
+ import type { KcContext } from '@keycloakify/svelte/login/KcContext';
2
+ import { useInsertLinkTags } from '@keycloakify/svelte/tools/useInsertLinkTags';
3
+ import { useInsertScriptTags } from '@keycloakify/svelte/tools/useInsertScriptTags';
4
+ import { assert } from 'keycloakify/tools/assert';
5
+ import { onMount } from 'svelte';
6
+
7
+ export type KcContextLike = {
8
+ url: {
9
+ resourcesCommonPath: string;
10
+ resourcesPath: string;
11
+ ssoLoginInOtherTabsUrl: string;
12
+ };
13
+ scripts?: string[];
14
+ };
15
+
16
+ assert<keyof KcContextLike extends keyof KcContext ? true : false>();
17
+ assert<KcContext extends KcContextLike ? true : false>();
18
+
19
+ export function useInitialize(params: { kcContext: KcContextLike; doUseDefaultCss: boolean }) {
20
+ const { kcContext, doUseDefaultCss } = params;
21
+
22
+ const { url, scripts } = kcContext;
23
+
24
+ const { areAllStyleSheetsLoaded } = useInsertLinkTags({
25
+ componentOrHookName: 'Template',
26
+ hrefs: !doUseDefaultCss
27
+ ? []
28
+ : [
29
+ `${url.resourcesCommonPath}/node_modules/@patternfly/patternfly/patternfly.min.css`,
30
+ `${url.resourcesCommonPath}/node_modules/patternfly/dist/css/patternfly.min.css`,
31
+ `${url.resourcesCommonPath}/node_modules/patternfly/dist/css/patternfly-additions.min.css`,
32
+ `${url.resourcesCommonPath}/lib/pficon/pficon.css`,
33
+ `${url.resourcesPath}/css/login.css`,
34
+ ],
35
+ });
36
+
37
+ const { insertScriptTags } = useInsertScriptTags({
38
+ componentOrHookName: 'Template',
39
+ scriptTags: [
40
+ // NOTE: The importmap is added in by the FTL script because it's too late to add it here.
41
+ {
42
+ type: 'module',
43
+ src: `${url.resourcesPath}/js/menu-button-links.js`,
44
+ },
45
+ ...(scripts === undefined
46
+ ? []
47
+ : scripts.map((src) => ({
48
+ type: 'text/javascript' as const,
49
+ src,
50
+ }))),
51
+ {
52
+ type: 'module',
53
+ textContent: `
54
+ import { checkCookiesAndSetTimer } from "${url.resourcesPath}/js/authChecker.js";
55
+
56
+ checkCookiesAndSetTimer("${url.ssoLoginInOtherTabsUrl}");
57
+ `,
58
+ },
59
+ ],
60
+ });
61
+
62
+ onMount(() => {
63
+ const unsubscriber = areAllStyleSheetsLoaded.subscribe((isReadyToRender) => {
64
+ if (isReadyToRender) {
65
+ insertScriptTags();
66
+ }
67
+ });
68
+ return () => unsubscriber();
69
+ });
70
+
71
+ return { isReadyToRender: areAllStyleSheetsLoaded };
72
+ }
@@ -0,0 +1,23 @@
1
+ import type { ClassKey } from 'keycloakify/login/lib/kcClsx';
2
+ import type { Snippet } from 'svelte';
3
+ import type { Readable } from 'svelte/store';
4
+
5
+ export type TemplateProps<KcContext, I18n> = {
6
+ kcContext: KcContext;
7
+ i18n: Readable<I18n>;
8
+ doUseDefaultCss: boolean;
9
+ classes?: Partial<Record<ClassKey, string>>;
10
+ children: Snippet;
11
+
12
+ displayInfo?: boolean;
13
+ displayMessage?: boolean;
14
+ displayRequiredFields?: boolean;
15
+ showAnotherWayIfPresent?: boolean;
16
+ headerNode: Snippet;
17
+ socialProvidersNode?: Snippet | null;
18
+ infoNode?: Snippet | null;
19
+ documentTitle?: string;
20
+ bodyClassName?: string;
21
+ };
22
+
23
+ export type { ClassKey };
@@ -0,0 +1,57 @@
1
+ <script lang="ts">
2
+ import {
3
+ getButtonToDisplayForMultivaluedAttributeField,
4
+ type FormAction,
5
+ } from '@keycloakify/svelte/login/lib/useUserProfileForm';
6
+ import type { Attribute } from 'keycloakify/login/KcContext';
7
+ import type { EventDispatcher } from 'svelte';
8
+ import type { Readable } from 'svelte/store';
9
+ import type { I18n } from '../i18n';
10
+
11
+ type AddRemoveButtonsMultiValuedAttributeProps = {
12
+ attribute: Attribute;
13
+ values: string[];
14
+ fieldIndex: number;
15
+ dispatchFormAction: EventDispatcher<{ formAction: Extract<FormAction, { action: 'update' }> }>;
16
+ i18n: Readable<I18n>;
17
+ };
18
+ const { attribute, values, fieldIndex, dispatchFormAction, i18n }: AddRemoveButtonsMultiValuedAttributeProps =
19
+ $props();
20
+ const { msg } = $i18n;
21
+
22
+ const { hasAdd, hasRemove } = getButtonToDisplayForMultivaluedAttributeField({ attribute, values, fieldIndex });
23
+
24
+ const idPostfix = `-${attribute.name}-${fieldIndex + 1}`;
25
+ </script>
26
+
27
+ {#if hasRemove}
28
+ <button
29
+ id={`kc-remove${idPostfix}`}
30
+ type="button"
31
+ class="pf-c-button pf-m-inline pf-m-link"
32
+ onclick={() =>
33
+ dispatchFormAction('formAction', {
34
+ action: 'update',
35
+ name: attribute.name,
36
+ valueOrValues: values.filter((_, i) => i !== fieldIndex),
37
+ })}
38
+ >
39
+ {@render msg('remove')()}
40
+ </button>
41
+ {#if hasAdd}&nbsp;|&nbsp;{/if}
42
+ {/if}
43
+ {#if hasAdd}
44
+ <button
45
+ id={`kc-add${idPostfix}`}
46
+ type="button"
47
+ class="pf-c-button pf-m-inline pf-m-link"
48
+ onclick={() =>
49
+ dispatchFormAction('formAction', {
50
+ action: 'update',
51
+ name: attribute.name,
52
+ valueOrValues: [...values, ''],
53
+ })}
54
+ >
55
+ {@render msg('addValue')()}
56
+ </button>
57
+ {/if}
@@ -0,0 +1,31 @@
1
+ <script lang="ts">
2
+ import type { FormFieldError } from '@keycloakify/svelte/login/lib/useUserProfileForm';
3
+ import type { Attribute } from 'keycloakify/login/KcContext';
4
+ import type { KcClsx } from 'keycloakify/login/lib/kcClsx';
5
+
6
+ type FieldErrorProps = {
7
+ attribute: Attribute;
8
+ displayableErrors: FormFieldError[];
9
+ fieldIndex?: number;
10
+ kcClsx: KcClsx;
11
+ };
12
+ let { attribute, fieldIndex, kcClsx, displayableErrors = $bindable([]) }: FieldErrorProps = $props();
13
+ </script>
14
+
15
+ {#snippet fieldErrors()}
16
+ {@const _displayableErrors = displayableErrors.filter((error) => error.fieldIndex === fieldIndex)}
17
+ {#if _displayableErrors.length !== 0}
18
+ <span
19
+ id={`input-error-${attribute.name}${fieldIndex === undefined ? '' : `-${fieldIndex}`}`}
20
+ class={kcClsx('kcInputErrorMessageClass')}
21
+ aria-live="polite"
22
+ >
23
+ {#each _displayableErrors as displayableError, i}
24
+ {@const { errorMessage } = displayableError}
25
+ {@render errorMessage()}
26
+ {#if _displayableErrors.length - 1 !== i}<br />{/if}
27
+ {/each}
28
+ </span>
29
+ {/if}
30
+ {/snippet}
31
+ {@render fieldErrors()}
@@ -0,0 +1,68 @@
1
+ <script lang="ts">
2
+ import type { Attribute } from 'keycloakify/login/KcContext';
3
+ import type { KcClsx } from 'keycloakify/login/lib/kcClsx';
4
+ import { assert } from 'keycloakify/tools/assert';
5
+ import { createRawSnippet } from 'svelte';
6
+ import type { I18n } from '../i18n';
7
+ import type { Readable } from 'svelte/store';
8
+
9
+ type GroupLabelProps = {
10
+ attribute: Attribute;
11
+ groupNameRef: {
12
+ current: string;
13
+ };
14
+ i18n: Readable<I18n>;
15
+ kcClsx: KcClsx;
16
+ };
17
+ const { attribute, groupNameRef, i18n, kcClsx }: GroupLabelProps = $props();
18
+ const { advancedMsg } = $i18n;
19
+
20
+ let isGrouplabel = $state<boolean>(false);
21
+ if (attribute.group?.name !== groupNameRef.current) {
22
+ groupNameRef.current = attribute.group?.name ?? '';
23
+
24
+ if (groupNameRef.current !== '') {
25
+ assert(attribute.group !== undefined);
26
+ isGrouplabel = true;
27
+ }
28
+ }
29
+
30
+ const html5DataAnnotations = {
31
+ ...Object.fromEntries(
32
+ Object.entries(attribute.group?.html5DataAnnotations ?? {}).map(([key, value]) => [`data-${key}`, value]),
33
+ ),
34
+ };
35
+ </script>
36
+
37
+ {#if isGrouplabel}
38
+ {@const groupDisplayHeader = attribute.group?.displayHeader ?? ''}
39
+ {@const groupDisplayDescription = attribute.group?.displayDescription ?? ''}
40
+ {@const groupHeaderText =
41
+ groupDisplayHeader !== ''
42
+ ? advancedMsg(groupDisplayHeader)
43
+ : createRawSnippet(() => ({ render: () => attribute.group?.name ?? '' }))}
44
+ <div
45
+ class={kcClsx('kcFormGroupClass')}
46
+ {...html5DataAnnotations}
47
+ >
48
+ <div class={kcClsx('kcContentWrapperClass')}>
49
+ <label
50
+ id={`header-${attribute.group?.name}`}
51
+ class={kcClsx('kcFormGroupHeader')}
52
+ >
53
+ {@render groupHeaderText()}
54
+ </label>
55
+ </div>
56
+ {#if groupDisplayDescription !== ''}
57
+ {@const groupDescriptionText = advancedMsg(groupDisplayDescription)}
58
+ <div class={kcClsx('kcLabelWrapperClass')}>
59
+ <label
60
+ id={`description-${attribute.group?.name}`}
61
+ class={kcClsx('kcLabelClass')}
62
+ >
63
+ {@render groupDescriptionText()}
64
+ </label>
65
+ </div>
66
+ {/if}
67
+ </div>
68
+ {/if}
@@ -0,0 +1,58 @@
1
+ <script lang="ts">
2
+ import type { InputFieldByTypeProps } from '@keycloakify/svelte/login/components/InputFieldByTypeProps';
3
+ import InputTag from '@keycloakify/svelte/login/components/InputTag.svelte';
4
+ import InputTagSelects from '@keycloakify/svelte/login/components/InputTagSelects.svelte';
5
+ import PasswordWrapper from '@keycloakify/svelte/login/components/PasswordWrapper.svelte';
6
+ import SelectTag from '@keycloakify/svelte/login/components/SelectTag.svelte';
7
+ import TextareaTag from '@keycloakify/svelte/login/components/TextareaTag.svelte';
8
+
9
+ let { displayableErrors, ...props }: InputFieldByTypeProps = $props();
10
+ const { attribute, valueOrValues } = props;
11
+ const inputType = attribute.annotations.inputType ?? '';
12
+ </script>
13
+
14
+ {#if inputType === 'textarea'}
15
+ <TextareaTag
16
+ {...props}
17
+ {displayableErrors}
18
+ />
19
+ {:else if ['select', 'multiselect'].includes(inputType)}
20
+ <SelectTag
21
+ {...props}
22
+ {displayableErrors}
23
+ />
24
+ {:else if ['select-radiobuttons', 'multiselect-checkboxes'].includes(inputType)}
25
+ <InputTagSelects
26
+ {...props}
27
+ {displayableErrors}
28
+ />
29
+ {:else}
30
+ <!-- default -->
31
+ {#if valueOrValues instanceof Array}
32
+ {#each valueOrValues as _, i}
33
+ <InputTag
34
+ {...props}
35
+ bind:displayableErrors
36
+ fieldIndex={i}
37
+ />
38
+ {/each}
39
+ {:else}
40
+ {#snippet inputNode()}
41
+ <InputTag
42
+ {...props}
43
+ bind:displayableErrors
44
+ />
45
+ {/snippet}
46
+ {#if ['password', 'password-confirm'].includes(attribute.name)}
47
+ <PasswordWrapper
48
+ kcClsx={props.kcClsx}
49
+ i18n={props.i18n}
50
+ passwordInputId={attribute.name}
51
+ >
52
+ {@render inputNode()}
53
+ </PasswordWrapper>
54
+ {:else}
55
+ {@render inputNode()}
56
+ {/if}
57
+ {/if}
58
+ {/if}
@@ -0,0 +1,15 @@
1
+ import type { FormAction, FormFieldError } from '@keycloakify/svelte/login/lib/useUserProfileForm';
2
+ import type { Attribute } from 'keycloakify/login/KcContext';
3
+ import type { KcClsx } from 'keycloakify/login/lib/kcClsx';
4
+ import type { EventDispatcher } from 'svelte';
5
+ import type { I18n } from '../i18n';
6
+ import type { Readable } from 'svelte/store';
7
+
8
+ export type InputFieldByTypeProps = {
9
+ attribute: Attribute;
10
+ valueOrValues: string | string[];
11
+ displayableErrors: FormFieldError[];
12
+ dispatchFormAction: EventDispatcher<{ formAction: FormAction }>;
13
+ i18n: Readable<I18n>;
14
+ kcClsx: KcClsx;
15
+ };
@@ -0,0 +1,107 @@
1
+ <script lang="ts">
2
+ import AddRemoveButtonsMultiValuedAttribute from '@keycloakify/svelte/login/components/AddRemoveButtonsMultiValuedAttribute.svelte';
3
+ import FieldErrors from '@keycloakify/svelte/login/components/FieldErrors.svelte';
4
+ import type { InputFieldByTypeProps } from '@keycloakify/svelte/login/components/InputFieldByTypeProps';
5
+ import { assert } from 'keycloakify/tools/assert';
6
+
7
+ type InputTagProps = InputFieldByTypeProps & { fieldIndex?: number };
8
+ let {
9
+ attribute,
10
+ fieldIndex,
11
+ kcClsx,
12
+ dispatchFormAction,
13
+ valueOrValues,
14
+ i18n,
15
+ displayableErrors = $bindable([]),
16
+ }: InputTagProps = $props();
17
+
18
+ const { advancedMsgStr } = $i18n;
19
+ const { inputType } = attribute.annotations;
20
+ let value = $state(
21
+ (() => {
22
+ if (fieldIndex !== undefined) {
23
+ assert(valueOrValues instanceof Array);
24
+ return valueOrValues[fieldIndex];
25
+ }
26
+
27
+ assert(typeof valueOrValues === 'string');
28
+
29
+ return valueOrValues;
30
+ })(),
31
+ );
32
+ const html5DataAnnotations = {
33
+ ...Object.fromEntries(
34
+ Object.entries(attribute.group?.html5DataAnnotations ?? {}).map(([key, value]) => [`data-${key}`, value]),
35
+ ),
36
+ };
37
+ </script>
38
+
39
+ <input
40
+ type={inputType?.startsWith('html5-') ? inputType.slice(6) : (inputType ?? 'text')}
41
+ id={attribute.name}
42
+ name={attribute.name}
43
+ bind:value
44
+ class={kcClsx('kcInputClass')}
45
+ aria-invalid={displayableErrors.find((error) => error.fieldIndex === fieldIndex) !== undefined}
46
+ disabled={attribute.readOnly}
47
+ autocomplete={attribute.autocomplete as 'on'}
48
+ placeholder={attribute.annotations.inputTypePlaceholder === undefined
49
+ ? undefined
50
+ : advancedMsgStr(attribute.annotations.inputTypePlaceholder)}
51
+ pattern={attribute.annotations.inputTypePattern}
52
+ size={attribute.annotations.inputTypeSize === undefined
53
+ ? undefined
54
+ : parseInt(`${attribute.annotations.inputTypeSize}`)}
55
+ maxlength={attribute.annotations.inputTypeMaxlength === undefined
56
+ ? undefined
57
+ : parseInt(`${attribute.annotations.inputTypeMaxlength}`)}
58
+ minlength={attribute.annotations.inputTypeMinlength === undefined
59
+ ? undefined
60
+ : parseInt(`${attribute.annotations.inputTypeMinlength}`)}
61
+ max={attribute.annotations.inputTypeMax}
62
+ min={attribute.annotations.inputTypeMin}
63
+ step={attribute.annotations.inputTypeStep}
64
+ {...html5DataAnnotations}
65
+ onchange={(event) =>
66
+ dispatchFormAction('formAction', {
67
+ action: 'update',
68
+ name: attribute.name,
69
+ valueOrValues: (() => {
70
+ if (fieldIndex !== undefined) {
71
+ assert(valueOrValues instanceof Array);
72
+
73
+ return (valueOrValues as string[]).map((value, i) => {
74
+ if (i === fieldIndex) {
75
+ return event.currentTarget.value;
76
+ }
77
+
78
+ return value;
79
+ });
80
+ }
81
+
82
+ return event.currentTarget.value;
83
+ })(),
84
+ })}
85
+ onblur={() =>
86
+ dispatchFormAction('formAction', {
87
+ action: 'focus lost',
88
+ name: attribute.name,
89
+ fieldIndex: fieldIndex,
90
+ })}
91
+ />
92
+ {#if fieldIndex !== undefined && valueOrValues instanceof Array}
93
+ {@const values = valueOrValues}
94
+ <FieldErrors
95
+ {attribute}
96
+ {kcClsx}
97
+ bind:displayableErrors
98
+ {fieldIndex}
99
+ ></FieldErrors>
100
+ <AddRemoveButtonsMultiValuedAttribute
101
+ {attribute}
102
+ {values}
103
+ {fieldIndex}
104
+ {dispatchFormAction}
105
+ {i18n}
106
+ ></AddRemoveButtonsMultiValuedAttribute>
107
+ {/if}
@@ -0,0 +1,111 @@
1
+ <script lang="ts">
2
+ import type { InputFieldByTypeProps } from '@keycloakify/svelte/login/components/InputFieldByTypeProps';
3
+ import { inputLabel } from '@keycloakify/svelte/login/components/inputLabel';
4
+ import { assert } from 'keycloakify/tools/assert';
5
+
6
+ const { attribute, dispatchFormAction, kcClsx, i18n, valueOrValues, displayableErrors }: InputFieldByTypeProps =
7
+ $props();
8
+
9
+ const { classDiv, classInput, classLabel, inputType } = (() => {
10
+ const { inputType } = attribute.annotations;
11
+
12
+ assert(inputType === 'select-radiobuttons' || inputType === 'multiselect-checkboxes');
13
+
14
+ switch (inputType) {
15
+ case 'select-radiobuttons':
16
+ return {
17
+ inputType: 'radio',
18
+ classDiv: kcClsx('kcInputClassRadio'),
19
+ classInput: kcClsx('kcInputClassRadioInput'),
20
+ classLabel: kcClsx('kcInputClassRadioLabel'),
21
+ };
22
+ case 'multiselect-checkboxes':
23
+ return {
24
+ inputType: 'checkbox',
25
+ classDiv: kcClsx('kcInputClassCheckbox'),
26
+ classInput: kcClsx('kcInputClassCheckboxInput'),
27
+ classLabel: kcClsx('kcInputClassCheckboxLabel'),
28
+ };
29
+ default:
30
+ return {
31
+ inputType: '',
32
+ classDiv: '',
33
+ classInput: '',
34
+ classLabel: '',
35
+ };
36
+ }
37
+ })();
38
+
39
+ const options = (() => {
40
+ walk: {
41
+ const { inputOptionsFromValidation } = attribute.annotations;
42
+
43
+ if (inputOptionsFromValidation === undefined) {
44
+ break walk;
45
+ }
46
+
47
+ const validator = (attribute.validators as Record<string, { options?: string[] }>)[inputOptionsFromValidation];
48
+
49
+ if (validator === undefined) {
50
+ break walk;
51
+ }
52
+
53
+ if (validator.options === undefined) {
54
+ break walk;
55
+ }
56
+
57
+ return validator.options;
58
+ }
59
+
60
+ return attribute.validators.options?.options ?? [];
61
+ })();
62
+ </script>
63
+
64
+ {#each options as option}
65
+ <div class={classDiv}>
66
+ <input
67
+ type={inputType}
68
+ id={`${attribute.name}-${option}`}
69
+ name={attribute.name}
70
+ value={option}
71
+ class={classInput}
72
+ aria-invalid={displayableErrors.length !== 0}
73
+ disabled={attribute.readOnly}
74
+ checked={valueOrValues instanceof Array ? valueOrValues.includes(option) : valueOrValues === option}
75
+ onchange={(event) =>
76
+ dispatchFormAction('formAction', {
77
+ action: 'update',
78
+ name: attribute.name,
79
+ valueOrValues: (() => {
80
+ const isChecked = event.currentTarget.checked;
81
+
82
+ if (valueOrValues instanceof Array) {
83
+ const newValues = [...valueOrValues];
84
+
85
+ if (isChecked) {
86
+ newValues.push(option);
87
+ } else {
88
+ newValues.splice(newValues.indexOf(option), 1);
89
+ }
90
+
91
+ return newValues;
92
+ }
93
+
94
+ return event.currentTarget.checked ? option : '';
95
+ })(),
96
+ })}
97
+ onblur={() =>
98
+ dispatchFormAction('formAction', {
99
+ action: 'focus lost',
100
+ name: attribute.name,
101
+ fieldIndex: undefined,
102
+ })}
103
+ />
104
+ <label
105
+ for={`${attribute.name}-${option}`}
106
+ class={`${classLabel}${attribute.readOnly ? ` ${kcClsx('kcInputClassRadioCheckboxLabelDisabled')}` : ''}`}
107
+ >
108
+ {@render inputLabel($i18n, attribute, option)()}
109
+ </label>
110
+ </div>
111
+ {/each}
@@ -0,0 +1,29 @@
1
+ <script lang="ts">
2
+ import type { KcClsx } from 'keycloakify/login/lib/kcClsx';
3
+ import type { I18n } from '../i18n';
4
+ import type { Readable } from 'svelte/store';
5
+
6
+ const { kcClsx, i18n }: { kcClsx: KcClsx; i18n: Readable<I18n> } = $props();
7
+
8
+ const { msg } = $i18n;
9
+ </script>
10
+
11
+ <div
12
+ id="kc-form-options"
13
+ class={kcClsx('kcFormOptionsClass')}
14
+ >
15
+ <div class={kcClsx('kcFormOptionsWrapperClass')}>
16
+ <div class="checkbox">
17
+ <label>
18
+ <input
19
+ type="checkbox"
20
+ id="logout-sessions"
21
+ name="logout-sessions"
22
+ value="on"
23
+ checked={true}
24
+ />
25
+ {@render msg('logoutOtherSessions')()}
26
+ </label>
27
+ </div>
28
+ </div>
29
+ </div>
@@ -0,0 +1,43 @@
1
+ <script lang="ts">
2
+ import { useReducer } from '@keycloakify/svelte/tools/useReducer';
3
+ import type { KcClsx } from 'keycloakify/login/lib/kcClsx';
4
+ import { assert } from 'keycloakify/tools/assert';
5
+ import { onMount, type Snippet } from 'svelte';
6
+ import type { I18n } from '../i18n';
7
+ import type { Readable } from 'svelte/store';
8
+
9
+ const props: { kcClsx: KcClsx; i18n: Readable<I18n>; passwordInputId: string; children: Snippet } = $props();
10
+ const { kcClsx, i18n, passwordInputId, children } = props;
11
+
12
+ const { msgStr } = $i18n;
13
+
14
+ const [isPasswordRevealed, toggleIsPasswordRevealed] = useReducer<boolean, boolean>(
15
+ (isPasswordRevealed: boolean) => !isPasswordRevealed,
16
+ false,
17
+ );
18
+ onMount(() => {
19
+ const unsubscribe = isPasswordRevealed.subscribe(($isPasswordRevealed) => {
20
+ const passwordInputElement: HTMLInputElement = document.getElementById(passwordInputId) as HTMLInputElement;
21
+
22
+ assert(passwordInputElement instanceof HTMLInputElement);
23
+ passwordInputElement.type = $isPasswordRevealed ? 'text' : 'password';
24
+ });
25
+ return () => unsubscribe();
26
+ });
27
+ </script>
28
+
29
+ <div class={kcClsx('kcInputGroup')}>
30
+ {@render children?.()}
31
+ <button
32
+ type="button"
33
+ class={kcClsx('kcFormPasswordVisibilityButtonClass')}
34
+ aria-label={msgStr($isPasswordRevealed ? 'hidePassword' : 'showPassword')}
35
+ aria-controls={passwordInputId}
36
+ onclick={() => toggleIsPasswordRevealed($isPasswordRevealed)}
37
+ >
38
+ <i
39
+ class={kcClsx($isPasswordRevealed ? 'kcFormPasswordVisibilityIconHide' : 'kcFormPasswordVisibilityIconShow')}
40
+ aria-hidden="true"
41
+ ></i>
42
+ </button>
43
+ </div>