@better-auth-ui/heroui 1.6.2 → 1.6.4

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 (213) hide show
  1. package/dist/components/auth/additional-field.d.ts +4 -0
  2. package/dist/components/auth/additional-field.js +270 -0
  3. package/dist/components/auth/auth-provider.d.ts +4 -6
  4. package/dist/components/auth/auth-provider.js +12 -11
  5. package/dist/components/auth/auth.d.ts +1 -1
  6. package/dist/components/auth/auth.js +54 -28
  7. package/dist/components/{settings/security → auth/delete-user}/danger-zone.d.ts +3 -4
  8. package/dist/components/{settings/security → auth/delete-user}/danger-zone.js +1 -1
  9. package/dist/components/{settings/security → auth/delete-user}/delete-user.d.ts +1 -1
  10. package/dist/components/auth/delete-user/delete-user.js +95 -0
  11. package/dist/components/{email → auth/email}/email-changed-email.d.ts +2 -2
  12. package/dist/components/{email → auth/email}/email-changed-email.js +7 -7
  13. package/dist/components/{email → auth/email}/email-verification-email.d.ts +2 -2
  14. package/dist/components/{email → auth/email}/email-verification-email.js +7 -7
  15. package/dist/components/auth/email/magic-link-email.d.ts +3 -0
  16. package/dist/components/{email → auth/email}/magic-link-email.js +7 -7
  17. package/dist/components/auth/email/new-device-email.d.ts +3 -0
  18. package/dist/components/{email → auth/email}/new-device-email.js +7 -7
  19. package/dist/components/auth/email/otp-email.d.ts +3 -0
  20. package/dist/components/{email → auth/email}/otp-email.js +6 -6
  21. package/dist/components/{email → auth/email}/password-changed-email.d.ts +2 -2
  22. package/dist/components/{email → auth/email}/password-changed-email.js +7 -7
  23. package/dist/components/{email → auth/email}/reset-password-email.d.ts +2 -2
  24. package/dist/components/{email → auth/email}/reset-password-email.js +7 -7
  25. package/dist/components/auth/error-toaster.d.ts +1 -0
  26. package/dist/components/auth/error-toaster.js +17 -0
  27. package/dist/components/auth/forgot-password.d.ts +2 -2
  28. package/dist/components/auth/forgot-password.js +42 -42
  29. package/dist/components/auth/magic-link/magic-link-button.d.ts +11 -0
  30. package/dist/components/auth/magic-link/magic-link-button.js +20 -0
  31. package/dist/components/auth/magic-link/magic-link.d.ts +16 -0
  32. package/dist/components/auth/magic-link/magic-link.js +87 -0
  33. package/dist/components/{settings/account → auth/multi-session}/manage-account.d.ts +2 -6
  34. package/dist/components/auth/multi-session/manage-account.js +49 -0
  35. package/dist/components/{settings/account → auth/multi-session}/manage-accounts.d.ts +1 -1
  36. package/dist/components/auth/multi-session/manage-accounts.js +34 -0
  37. package/dist/components/{user/switch-account-menu.d.ts → auth/multi-session/switch-account-submenu-content.d.ts} +3 -3
  38. package/dist/components/auth/multi-session/switch-account-submenu-content.js +29 -0
  39. package/dist/components/{user/switch-account-item.d.ts → auth/multi-session/switch-account-submenu-item.d.ts} +2 -2
  40. package/dist/components/auth/multi-session/switch-account-submenu-item.js +20 -0
  41. package/dist/components/auth/multi-session/switch-account-submenu.d.ts +13 -0
  42. package/dist/components/auth/multi-session/switch-account-submenu.js +24 -0
  43. package/dist/components/auth/passkey/passkey-button.d.ts +6 -0
  44. package/dist/components/auth/passkey/passkey-button.js +24 -0
  45. package/dist/components/auth/passkey/passkey.js +45 -0
  46. package/dist/components/{settings/security → auth/passkey}/passkeys.d.ts +1 -1
  47. package/dist/components/auth/passkey/passkeys.js +106 -0
  48. package/dist/components/auth/provider-button.d.ts +13 -0
  49. package/dist/components/auth/provider-button.js +25 -0
  50. package/dist/components/auth/provider-buttons.d.ts +3 -10
  51. package/dist/components/auth/provider-buttons.js +14 -22
  52. package/dist/components/auth/reset-password.d.ts +1 -1
  53. package/dist/components/auth/reset-password.js +110 -110
  54. package/dist/components/{settings → auth/settings}/account/account-settings.d.ts +5 -2
  55. package/dist/components/auth/settings/account/account-settings.js +20 -0
  56. package/dist/components/auth/settings/account/change-avatar.js +89 -0
  57. package/dist/components/{settings → auth/settings}/account/change-email.d.ts +1 -1
  58. package/dist/components/{settings → auth/settings}/account/change-email.js +17 -20
  59. package/dist/components/{settings → auth/settings}/account/user-profile.d.ts +3 -4
  60. package/dist/components/auth/settings/account/user-profile.js +86 -0
  61. package/dist/components/auth/settings/security/active-session.js +59 -0
  62. package/dist/components/{settings → auth/settings}/security/active-sessions.d.ts +1 -1
  63. package/dist/components/auth/settings/security/active-sessions.js +34 -0
  64. package/dist/components/{settings → auth/settings}/security/change-password.d.ts +1 -1
  65. package/dist/components/auth/settings/security/change-password.js +189 -0
  66. package/dist/components/auth/settings/security/linked-account.js +56 -0
  67. package/dist/components/{settings → auth/settings}/security/linked-accounts.d.ts +1 -1
  68. package/dist/components/auth/settings/security/linked-accounts.js +45 -0
  69. package/dist/components/{settings → auth/settings}/security/security-settings.d.ts +1 -1
  70. package/dist/components/auth/settings/security/security-settings.js +22 -0
  71. package/dist/components/auth/settings/settings.js +45 -0
  72. package/dist/components/auth/sign-in.d.ts +1 -1
  73. package/dist/components/auth/sign-in.js +64 -100
  74. package/dist/components/auth/sign-out.js +11 -11
  75. package/dist/components/auth/sign-up.d.ts +1 -1
  76. package/dist/components/auth/sign-up.js +123 -157
  77. package/dist/components/{settings/account → auth/theme}/appearance.d.ts +3 -6
  78. package/dist/components/auth/theme/appearance.js +72 -0
  79. package/dist/components/auth/theme/theme-toggle-item.d.ts +5 -0
  80. package/dist/components/auth/theme/theme-toggle-item.js +58 -0
  81. package/dist/components/auth/user/user-avatar.js +29 -0
  82. package/dist/components/{user → auth/user}/user-button.d.ts +2 -6
  83. package/dist/components/auth/user/user-button.js +55 -0
  84. package/dist/components/auth/user/user-view.js +37 -0
  85. package/dist/components/auth/username/sign-in-username.d.ts +14 -0
  86. package/dist/components/auth/username/sign-in-username.js +142 -0
  87. package/dist/components/auth/username/username-field.d.ts +8 -0
  88. package/dist/components/auth/username/username-field.js +51 -0
  89. package/dist/email.d.ts +7 -0
  90. package/dist/email.js +9 -0
  91. package/dist/index.d.ts +13 -27
  92. package/dist/index.js +22 -36
  93. package/dist/lib/auth/auth-plugin.d.ts +44 -0
  94. package/dist/lib/auth/delete-user-plugin.d.ts +17 -0
  95. package/dist/lib/auth/delete-user-plugin.js +10 -0
  96. package/dist/lib/auth/magic-link-plugin.d.ts +31 -0
  97. package/dist/lib/auth/magic-link-plugin.js +13 -0
  98. package/dist/lib/auth/multi-session-plugin.d.ts +18 -0
  99. package/dist/lib/auth/multi-session-plugin.js +12 -0
  100. package/dist/lib/auth/passkey-plugin.d.ts +20 -0
  101. package/dist/lib/auth/passkey-plugin.js +12 -0
  102. package/dist/lib/auth/theme-plugin.d.ts +68 -0
  103. package/dist/lib/auth/theme-plugin.js +23 -0
  104. package/dist/lib/auth/username-plugin.d.ts +63 -0
  105. package/dist/lib/auth/username-plugin.js +18 -0
  106. package/dist/plugins.d.ts +20 -0
  107. package/dist/plugins.js +21 -0
  108. package/package.json +22 -22
  109. package/src/components/auth/additional-field.tsx +554 -0
  110. package/src/components/auth/auth-provider.tsx +8 -5
  111. package/src/components/auth/auth.tsx +100 -36
  112. package/src/components/{settings/security → auth/delete-user}/danger-zone.tsx +3 -10
  113. package/src/components/{settings/security → auth/delete-user}/delete-user.tsx +31 -24
  114. package/src/components/{email → auth/email}/email-changed-email.tsx +2 -2
  115. package/src/components/{email → auth/email}/email-verification-email.tsx +2 -2
  116. package/src/components/{email → auth/email}/magic-link-email.tsx +2 -2
  117. package/src/components/{email → auth/email}/new-device-email.tsx +2 -2
  118. package/src/components/{email → auth/email}/otp-email.tsx +2 -2
  119. package/src/components/{email → auth/email}/password-changed-email.tsx +2 -2
  120. package/src/components/{email → auth/email}/reset-password-email.tsx +2 -2
  121. package/src/components/auth/error-toaster.tsx +25 -0
  122. package/src/components/auth/forgot-password.tsx +15 -13
  123. package/src/components/auth/magic-link/magic-link-button.tsx +61 -0
  124. package/src/components/auth/{magic-link.tsx → magic-link/magic-link.tsx} +52 -57
  125. package/src/components/{settings/account → auth/multi-session}/manage-account.tsx +15 -15
  126. package/src/components/{settings/account → auth/multi-session}/manage-accounts.tsx +16 -12
  127. package/src/components/{user/switch-account-menu.tsx → auth/multi-session/switch-account-submenu-content.tsx} +19 -17
  128. package/src/components/{user/switch-account-item.tsx → auth/multi-session/switch-account-submenu-item.tsx} +18 -8
  129. package/src/components/auth/multi-session/switch-account-submenu.tsx +50 -0
  130. package/src/components/auth/passkey/passkey-button.tsx +56 -0
  131. package/src/components/{settings/security → auth/passkey}/passkey.tsx +21 -9
  132. package/src/components/auth/passkey/passkeys.tsx +196 -0
  133. package/src/components/auth/provider-button.tsx +65 -0
  134. package/src/components/auth/provider-buttons.tsx +23 -45
  135. package/src/components/auth/reset-password.tsx +14 -9
  136. package/src/components/{settings → auth/settings}/account/account-settings.tsx +15 -13
  137. package/src/components/{settings → auth/settings}/account/change-avatar.tsx +4 -5
  138. package/src/components/{settings → auth/settings}/account/change-email.tsx +5 -6
  139. package/src/components/auth/settings/account/user-profile.tsx +171 -0
  140. package/src/components/{settings → auth/settings}/security/active-session.tsx +8 -6
  141. package/src/components/{settings → auth/settings}/security/active-sessions.tsx +5 -10
  142. package/src/components/{settings → auth/settings}/security/change-password.tsx +22 -14
  143. package/src/components/{settings → auth/settings}/security/linked-account.tsx +10 -16
  144. package/src/components/{settings → auth/settings}/security/linked-accounts.tsx +4 -9
  145. package/src/components/{settings → auth/settings}/security/security-settings.tsx +7 -6
  146. package/src/components/{settings → auth/settings}/settings.tsx +2 -2
  147. package/src/components/auth/sign-in.tsx +39 -80
  148. package/src/components/auth/sign-out.tsx +2 -2
  149. package/src/components/auth/sign-up.tsx +110 -147
  150. package/src/components/{settings/account → auth/theme}/appearance.tsx +18 -25
  151. package/src/components/auth/theme/theme-toggle-item.tsx +110 -0
  152. package/src/components/{user → auth/user}/user-avatar.tsx +12 -4
  153. package/src/components/{user → auth/user}/user-button.tsx +15 -88
  154. package/src/components/{user → auth/user}/user-view.tsx +12 -4
  155. package/src/components/auth/username/sign-in-username.tsx +283 -0
  156. package/src/components/auth/username/username-field.tsx +122 -0
  157. package/src/email.ts +9 -0
  158. package/src/index.tsx +13 -27
  159. package/src/lib/auth/auth-plugin.ts +67 -0
  160. package/src/lib/auth/delete-user-plugin.ts +15 -0
  161. package/src/lib/auth/magic-link-plugin.ts +26 -0
  162. package/src/lib/auth/multi-session-plugin.ts +17 -0
  163. package/src/lib/auth/passkey-plugin.ts +17 -0
  164. package/src/lib/auth/theme-plugin.ts +86 -0
  165. package/src/lib/auth/username-plugin.tsx +30 -0
  166. package/src/plugins.ts +23 -0
  167. package/dist/components/auth/magic-link-button.d.ts +0 -13
  168. package/dist/components/auth/magic-link-button.js +0 -16
  169. package/dist/components/auth/magic-link.d.ts +0 -17
  170. package/dist/components/auth/magic-link.js +0 -111
  171. package/dist/components/auth/passkey-button.d.ts +0 -4
  172. package/dist/components/auth/passkey-button.js +0 -24
  173. package/dist/components/email/magic-link-email.d.ts +0 -3
  174. package/dist/components/email/new-device-email.d.ts +0 -3
  175. package/dist/components/email/otp-email.d.ts +0 -3
  176. package/dist/components/settings/account/account-settings.js +0 -23
  177. package/dist/components/settings/account/appearance.js +0 -71
  178. package/dist/components/settings/account/change-avatar.js +0 -89
  179. package/dist/components/settings/account/manage-account.js +0 -51
  180. package/dist/components/settings/account/manage-accounts.js +0 -33
  181. package/dist/components/settings/account/user-profile.js +0 -106
  182. package/dist/components/settings/security/active-session.js +0 -62
  183. package/dist/components/settings/security/active-sessions.js +0 -34
  184. package/dist/components/settings/security/change-password.js +0 -192
  185. package/dist/components/settings/security/delete-user.js +0 -97
  186. package/dist/components/settings/security/linked-account.js +0 -62
  187. package/dist/components/settings/security/linked-accounts.js +0 -45
  188. package/dist/components/settings/security/passkey.js +0 -43
  189. package/dist/components/settings/security/passkeys.js +0 -53
  190. package/dist/components/settings/security/security-settings.js +0 -25
  191. package/dist/components/settings/settings.js +0 -45
  192. package/dist/components/user/switch-account-item.js +0 -20
  193. package/dist/components/user/switch-account-menu.js +0 -28
  194. package/dist/components/user/user-avatar.js +0 -29
  195. package/dist/components/user/user-button.js +0 -91
  196. package/dist/components/user/user-view.js +0 -37
  197. package/dist/core.d.ts +0 -1
  198. package/dist/core.js +0 -1
  199. package/dist/react-exports.d.ts +0 -1
  200. package/dist/react-exports.js +0 -1
  201. package/src/components/auth/magic-link-button.tsx +0 -43
  202. package/src/components/auth/passkey-button.tsx +0 -36
  203. package/src/components/settings/account/user-profile.tsx +0 -218
  204. package/src/components/settings/security/passkeys.tsx +0 -104
  205. package/src/core.ts +0 -1
  206. package/src/react-exports.ts +0 -1
  207. /package/dist/components/{settings/security → auth/passkey}/passkey.d.ts +0 -0
  208. /package/dist/components/{settings → auth/settings}/account/change-avatar.d.ts +0 -0
  209. /package/dist/components/{settings → auth/settings}/security/active-session.d.ts +0 -0
  210. /package/dist/components/{settings → auth/settings}/security/linked-account.d.ts +0 -0
  211. /package/dist/components/{settings → auth/settings}/settings.d.ts +0 -0
  212. /package/dist/components/{user → auth/user}/user-avatar.d.ts +0 -0
  213. /package/dist/components/{user → auth/user}/user-view.d.ts +0 -0
@@ -46,13 +46,15 @@ export type ActiveSessionProps = {
46
46
  * @returns A JSX element containing the active session row
47
47
  */
48
48
  export function ActiveSession({ activeSession }: ActiveSessionProps) {
49
- const { basePaths, localization, viewPaths, navigate } = useAuth()
50
- const { data: session } = useSession({ refetchOnMount: false })
49
+ const { authClient, basePaths, localization, viewPaths, navigate } = useAuth()
50
+ const { data: session } = useSession(authClient, { refetchOnMount: false })
51
51
 
52
- const { mutate: revokeSession, isPending: isRevoking } = useRevokeSession({
53
- onError: (error) => toast.danger(error.error?.message || error.message),
54
- onSuccess: () => toast.success(localization.settings.revokeSessionSuccess)
55
- })
52
+ const { mutate: revokeSession, isPending: isRevoking } = useRevokeSession(
53
+ authClient,
54
+ {
55
+ onSuccess: () => toast.success(localization.settings.revokeSessionSuccess)
56
+ }
57
+ )
56
58
 
57
59
  const isCurrentSession = activeSession.token === session?.session.token
58
60
  const ua = Bowser.parse(activeSession.userAgent || "")
@@ -1,5 +1,5 @@
1
1
  import { useAuth, useListSessions, useSession } from "@better-auth-ui/react"
2
- import { Card, type CardProps, cn, Skeleton, toast } from "@heroui/react"
2
+ import { Card, type CardProps, cn, Skeleton } from "@heroui/react"
3
3
  import { ActiveSession } from "./active-session"
4
4
 
5
5
  export type ActiveSessionsProps = {
@@ -19,16 +19,11 @@ export function ActiveSessions({
19
19
  className,
20
20
  variant,
21
21
  ...props
22
- }: ActiveSessionsProps & CardProps) {
23
- const { localization } = useAuth()
24
- const { data: session } = useSession()
22
+ }: ActiveSessionsProps & Omit<CardProps, "children">) {
23
+ const { authClient, localization } = useAuth()
24
+ const { data: session } = useSession(authClient)
25
25
 
26
- const { data: sessions, isPending } = useListSessions({
27
- throwOnError: (error) => {
28
- if (error.error) toast.danger(error.error.message)
29
- return false
30
- }
31
- })
26
+ const { data: sessions, isPending } = useListSessions(authClient)
32
27
 
33
28
  const activeSessions = sessions?.toSorted((activeSession) =>
34
29
  activeSession.id === session?.session.id ? -1 : 1
@@ -42,10 +42,11 @@ export function ChangePassword({
42
42
  className,
43
43
  variant,
44
44
  ...props
45
- }: ChangePasswordProps & CardProps) {
46
- const { emailAndPassword, localization } = useAuth()
47
- const { data: session } = useSession()
48
- const { data: accounts, isPending: isAccountsPending } = useListAccounts()
45
+ }: ChangePasswordProps & Omit<CardProps, "children">) {
46
+ const { authClient, emailAndPassword, localization } = useAuth()
47
+ const { data: session } = useSession(authClient)
48
+ const { data: accounts, isPending: isAccountsPending } =
49
+ useListAccounts(authClient)
49
50
 
50
51
  const hasCredentialAccount = accounts?.some(
51
52
  (account) => account.providerId === "credential"
@@ -67,14 +68,20 @@ export function ChangePassword({
67
68
  )
68
69
  }
69
70
 
70
- function SetPassword({ className, variant, ...props }: CardProps) {
71
- const { localization } = useAuth()
72
- const { data: session } = useSession()
73
-
74
- const { mutate: requestPasswordReset, isPending } = useRequestPasswordReset({
75
- onError: (error) => toast.danger(error.error?.message || error.message),
76
- onSuccess: () => toast.success(localization.auth.passwordResetEmailSent)
77
- })
71
+ function SetPassword({
72
+ className,
73
+ variant,
74
+ ...props
75
+ }: Omit<CardProps, "children">) {
76
+ const { authClient, localization } = useAuth()
77
+ const { data: session } = useSession(authClient)
78
+
79
+ const { mutate: requestPasswordReset, isPending } = useRequestPasswordReset(
80
+ authClient,
81
+ {
82
+ onSuccess: () => toast.success(localization.auth.passwordResetEmailSent)
83
+ }
84
+ )
78
85
 
79
86
  const handleSetPassword = () => {
80
87
  if (!session?.user.email) return
@@ -125,12 +132,13 @@ function ChangePasswordForm({
125
132
  emailAndPassword: ReturnType<typeof useAuth>["emailAndPassword"]
126
133
  localization: ReturnType<typeof useAuth>["localization"]
127
134
  session: ReturnType<typeof useSession>["data"]
128
- } & CardProps) {
135
+ } & Omit<CardProps, "children">) {
136
+ const { authClient } = useAuth()
129
137
  const [currentPassword, setCurrentPassword] = useState("")
130
138
  const [newPassword, setNewPassword] = useState("")
131
139
  const [confirmPassword, setConfirmPassword] = useState("")
132
140
 
133
- const { mutate: changePassword, isPending } = useChangePassword({
141
+ const { mutate: changePassword, isPending } = useChangePassword(authClient, {
134
142
  onError: (error) => {
135
143
  setCurrentPassword("")
136
144
  setNewPassword("")
@@ -26,27 +26,21 @@ export type LinkedAccountProps = {
26
26
  * @returns A JSX element containing the linked account row
27
27
  */
28
28
  export function LinkedAccount({ account, provider }: LinkedAccountProps) {
29
- const { baseURL, localization } = useAuth()
29
+ const { authClient, baseURL, localization } = useAuth()
30
30
 
31
31
  const { data: accountInfo, isPending: isLoadingInfo } = useAccountInfo(
32
- account?.accountId,
33
- {
34
- enabled: !!account,
35
- throwOnError: (error) => {
36
- if (error.error) toast.danger(error.error.message)
37
- return false
38
- }
39
- }
32
+ authClient,
33
+ { query: { accountId: account?.accountId } }
40
34
  )
41
35
 
42
- const { mutate: linkSocial, isPending: isLinking } = useLinkSocial({
43
- onError: (error) => toast.danger(error.error?.message || error.message)
44
- })
36
+ const { mutate: linkSocial, isPending: isLinking } = useLinkSocial(authClient)
45
37
 
46
- const { mutate: unlinkAccount, isPending: isUnlinking } = useUnlinkAccount({
47
- onError: (error) => toast.danger(error.error?.message || error.message),
48
- onSuccess: () => toast.success(localization.settings.accountUnlinked)
49
- })
38
+ const { mutate: unlinkAccount, isPending: isUnlinking } = useUnlinkAccount(
39
+ authClient,
40
+ {
41
+ onSuccess: () => toast.success(localization.settings.accountUnlinked)
42
+ }
43
+ )
50
44
 
51
45
  const ProviderIcon = providerIcons[provider]
52
46
  const providerName = getProviderName(provider)
@@ -1,5 +1,5 @@
1
1
  import { useAuth, useListAccounts } from "@better-auth-ui/react"
2
- import { Card, type CardProps, cn, Skeleton, toast } from "@heroui/react"
2
+ import { Card, type CardProps, cn, Skeleton } from "@heroui/react"
3
3
  import { LinkedAccount } from "./linked-account"
4
4
 
5
5
  export type LinkedAccountsProps = {
@@ -20,15 +20,10 @@ export function LinkedAccounts({
20
20
  className,
21
21
  variant,
22
22
  ...props
23
- }: LinkedAccountsProps & CardProps) {
24
- const { localization, socialProviders } = useAuth()
23
+ }: LinkedAccountsProps & Omit<CardProps, "children">) {
24
+ const { authClient, localization, socialProviders } = useAuth()
25
25
 
26
- const { data: accounts, isPending } = useListAccounts({
27
- throwOnError: (error) => {
28
- if (error.error) toast.danger(error.error.message)
29
- return false
30
- }
31
- })
26
+ const { data: accounts, isPending } = useListAccounts(authClient)
32
27
 
33
28
  const linkedAccounts = accounts?.filter(
34
29
  (account) => account.providerId !== "credential"
@@ -4,9 +4,7 @@ import type { ComponentProps } from "react"
4
4
 
5
5
  import { ActiveSessions } from "./active-sessions"
6
6
  import { ChangePassword } from "./change-password"
7
- import { DangerZone } from "./danger-zone"
8
7
  import { LinkedAccounts } from "./linked-accounts"
9
- import { Passkeys } from "./passkeys"
10
8
 
11
9
  export type SecuritySettingsProps = {
12
10
  className?: string
@@ -17,7 +15,7 @@ export type SecuritySettingsProps = {
17
15
  * Renders the security settings layout including password management, linked accounts, and active sessions.
18
16
  *
19
17
  * ChangePassword is rendered when password authentication is enabled; LinkedAccounts is rendered when social providers are present.
20
- * DangerZone is rendered when `deleteUser.enabled` is true in auth config.
18
+ * Each registered auth plugin may contribute `securityCards` (for example delete-user, passkeys).
21
19
  *
22
20
  * @param className - Optional additional CSS class names for the outer container.
23
21
  * @param variant - Card variant forwarded to each security settings card.
@@ -28,7 +26,7 @@ export function SecuritySettings({
28
26
  variant,
29
27
  ...props
30
28
  }: SecuritySettingsProps & ComponentProps<"div">) {
31
- const { deleteUser, emailAndPassword, passkey, socialProviders } = useAuth()
29
+ const { emailAndPassword, plugins, socialProviders } = useAuth()
32
30
 
33
31
  return (
34
32
  <div
@@ -37,9 +35,12 @@ export function SecuritySettings({
37
35
  >
38
36
  {emailAndPassword?.enabled && <ChangePassword variant={variant} />}
39
37
  {!!socialProviders?.length && <LinkedAccounts variant={variant} />}
40
- {passkey && <Passkeys variant={variant} />}
41
38
  <ActiveSessions variant={variant} />
42
- {deleteUser?.enabled && <DangerZone variant={variant} />}
39
+ {plugins.flatMap((plugin) =>
40
+ plugin.securityCards?.map((Card, index) => (
41
+ <Card key={`${plugin.id}-${index.toString()}`} variant={variant} />
42
+ ))
43
+ )}
43
44
  </div>
44
45
  )
45
46
  }
@@ -35,8 +35,8 @@ export function Settings({
35
35
  view,
36
36
  ...props
37
37
  }: SettingsProps & ComponentProps<"div">) {
38
- const { basePaths, localization, viewPaths } = useAuth()
39
- useAuthenticate()
38
+ const { authClient, basePaths, localization, viewPaths } = useAuth()
39
+ useAuthenticate(authClient)
40
40
 
41
41
  if (!view && !path) {
42
42
  throw new Error("[Better Auth UI] Either `view` or `path` must be provided")
@@ -1,9 +1,8 @@
1
+ import { authMutationKeys } from "@better-auth-ui/core"
1
2
  import {
2
3
  useAuth,
3
4
  useSendVerificationEmail,
4
- useSignInEmail,
5
- useSignInSocial,
6
- useSignInUsername
5
+ useSignInEmail
7
6
  } from "@better-auth-ui/react"
8
7
  import {
9
8
  Button,
@@ -21,11 +20,10 @@ import {
21
20
  TextField,
22
21
  toast
23
22
  } from "@heroui/react"
23
+ import { useIsMutating } from "@tanstack/react-query"
24
24
  import { type SyntheticEvent, useState } from "react"
25
25
 
26
26
  import { FieldSeparator } from "./field-separator"
27
- import { MagicLinkButton } from "./magic-link-button"
28
- import { PasskeyButton } from "./passkey-button"
29
27
  import { ProviderButtons, type SocialLayout } from "./provider-buttons"
30
28
 
31
29
  export interface SignInProps {
@@ -35,10 +33,6 @@ export interface SignInProps {
35
33
  variant?: CardProps["variant"]
36
34
  }
37
35
 
38
- function isEmail(value: string): boolean {
39
- return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)
40
- }
41
-
42
36
  /**
43
37
  * Render the sign-in UI using auth context for configuration and localization.
44
38
  *
@@ -50,29 +44,31 @@ export function SignIn({
50
44
  socialPosition = "bottom",
51
45
  variant,
52
46
  ...props
53
- }: SignInProps & CardProps) {
47
+ }: SignInProps & Omit<CardProps, "children">) {
54
48
  const {
49
+ authClient,
55
50
  basePaths,
56
51
  baseURL,
57
52
  emailAndPassword,
58
53
  localization,
59
- magicLink,
60
- passkey,
54
+ plugins,
61
55
  redirectTo,
62
56
  socialProviders,
63
- username: usernameConfig,
64
57
  viewPaths,
65
58
  navigate
66
59
  } = useAuth()
67
60
 
68
61
  const [password, setPassword] = useState("")
69
62
 
70
- const { mutate: sendVerificationEmail } = useSendVerificationEmail({
71
- onError: (error) => toast.danger(error.error?.message || error.message),
72
- onSuccess: () => toast.success(localization.auth.verificationEmailSent)
73
- })
63
+ const { mutate: sendVerificationEmail } = useSendVerificationEmail(
64
+ authClient,
65
+ {
66
+ onSuccess: () => toast.success(localization.auth.verificationEmailSent)
67
+ }
68
+ )
74
69
 
75
70
  const { mutate: signInEmail, isPending: signInEmailPending } = useSignInEmail(
71
+ authClient,
76
72
  {
77
73
  onError: (error, { email }) => {
78
74
  setPassword("")
@@ -96,28 +92,6 @@ export function SignIn({
96
92
  }
97
93
  )
98
94
 
99
- const { mutate: signInUsername, isPending: signInUsernamePending } =
100
- useSignInUsername({
101
- onError: (error) => {
102
- setPassword("")
103
- toast.danger(error.error?.message || error.message)
104
- },
105
- onSuccess: () => navigate({ to: redirectTo })
106
- })
107
-
108
- const [socialRedirecting, setSocialRedirecting] = useState(false)
109
-
110
- const { mutate: signInSocial, isPending: socialPending } = useSignInSocial({
111
- onError: (error) => toast.danger(error.error?.message || error.message),
112
- onSuccess: () => {
113
- setSocialRedirecting(true)
114
-
115
- setTimeout(() => {
116
- setSocialRedirecting(false)
117
- }, 5000)
118
- }
119
- })
120
-
121
95
  const handleSubmit = (e: SyntheticEvent<HTMLFormElement>) => {
122
96
  e.preventDefault()
123
97
 
@@ -125,22 +99,20 @@ export function SignIn({
125
99
  const email = formData.get("email") as string
126
100
  const rememberMe = formData.get("rememberMe") === "on"
127
101
 
128
- if (usernameConfig?.enabled && !isEmail(email)) {
129
- signInUsername({
130
- username: email,
131
- password
132
- })
133
- } else {
134
- signInEmail({
135
- email,
136
- password,
137
- ...(emailAndPassword?.rememberMe ? { rememberMe } : {})
138
- })
139
- }
102
+ signInEmail({
103
+ email,
104
+ password,
105
+ ...(emailAndPassword?.rememberMe ? { rememberMe } : {})
106
+ })
140
107
  }
141
108
 
142
- const signInPending = signInEmailPending || signInUsernamePending
143
- const isPending = signInPending || socialPending || socialRedirecting
109
+ const signInMutating = useIsMutating({
110
+ mutationKey: authMutationKeys.signIn.all
111
+ })
112
+ const signUpMutating = useIsMutating({
113
+ mutationKey: authMutationKeys.signUp.all
114
+ })
115
+ const isPending = signInMutating + signUpMutating > 0
144
116
 
145
117
  const showSeparator = emailAndPassword?.enabled && !!socialProviders?.length
146
118
 
@@ -160,11 +132,7 @@ export function SignIn({
160
132
  {socialPosition === "top" && (
161
133
  <>
162
134
  {!!socialProviders?.length && (
163
- <ProviderButtons
164
- socialLayout={socialLayout}
165
- signInSocial={signInSocial}
166
- isPending={isPending}
167
- />
135
+ <ProviderButtons socialLayout={socialLayout} />
168
136
  )}
169
137
 
170
138
  {showSeparator && (
@@ -177,22 +145,14 @@ export function SignIn({
177
145
  <Form onSubmit={handleSubmit} className="flex flex-col gap-4">
178
146
  <TextField
179
147
  name="email"
180
- type={usernameConfig?.enabled ? "text" : "email"}
181
- autoComplete={usernameConfig?.enabled ? "username" : "email"}
148
+ type="email"
149
+ autoComplete="email"
182
150
  isDisabled={isPending}
183
151
  >
184
- <Label>
185
- {usernameConfig?.enabled
186
- ? localization.auth.username
187
- : localization.auth.email}
188
- </Label>
152
+ <Label>{localization.auth.email}</Label>
189
153
 
190
154
  <Input
191
- placeholder={
192
- usernameConfig?.enabled
193
- ? localization.auth.usernameOrEmailPlaceholder
194
- : localization.auth.emailPlaceholder
195
- }
155
+ placeholder={localization.auth.emailPlaceholder}
196
156
  variant={variant === "transparent" ? "primary" : "secondary"}
197
157
  required
198
158
  />
@@ -239,16 +199,19 @@ export function SignIn({
239
199
 
240
200
  <div className="flex flex-col gap-3">
241
201
  <Button type="submit" className="w-full" isPending={isPending}>
242
- {isPending && <Spinner color="current" size="sm" />}
202
+ {signInEmailPending && <Spinner color="current" size="sm" />}
243
203
 
244
204
  {localization.auth.signIn}
245
205
  </Button>
246
206
 
247
- {magicLink && (
248
- <MagicLinkButton view="signIn" isPending={isPending} />
207
+ {plugins.flatMap((plugin) =>
208
+ plugin.authButtons?.map((AuthButton, index) => (
209
+ <AuthButton
210
+ key={`${plugin.id}-${index.toString()}`}
211
+ view="signIn"
212
+ />
213
+ ))
249
214
  )}
250
-
251
- {passkey && <PasskeyButton isPending={isPending} />}
252
215
  </div>
253
216
  </Form>
254
217
  )}
@@ -260,11 +223,7 @@ export function SignIn({
260
223
  )}
261
224
 
262
225
  {!!socialProviders?.length && (
263
- <ProviderButtons
264
- socialLayout={socialLayout}
265
- signInSocial={signInSocial}
266
- isPending={isPending}
267
- />
226
+ <ProviderButtons socialLayout={socialLayout} />
268
227
  )}
269
228
  </>
270
229
  )}
@@ -12,9 +12,9 @@ export type SignOutProps = {
12
12
  * @returns A Card containing a centered Spinner shown during the sign-out process
13
13
  */
14
14
  export function SignOut({ className }: SignOutProps) {
15
- const { basePaths, navigate, viewPaths } = useAuth()
15
+ const { authClient, basePaths, navigate, viewPaths } = useAuth()
16
16
 
17
- const { mutate: signOut } = useSignOut({
17
+ const { mutate: signOut } = useSignOut(authClient, {
18
18
  onError: (error) => {
19
19
  toast.danger(error.error?.message || error.message)
20
20
  navigate({