@better-auth-ui/heroui 1.6.7 → 1.6.9

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 (280) hide show
  1. package/dist/components/auth/additional-field.d.ts +2 -2
  2. package/dist/components/auth/additional-field.js +133 -266
  3. package/dist/components/auth/api-key/api-key-skeleton.js +4 -20
  4. package/dist/components/auth/api-key/api-key.d.ts +6 -2
  5. package/dist/components/auth/api-key/api-key.js +16 -54
  6. package/dist/components/auth/api-key/api-keys-empty.d.ts +3 -1
  7. package/dist/components/auth/api-key/api-keys-empty.js +8 -34
  8. package/dist/components/auth/api-key/api-keys.d.ts +10 -2
  9. package/dist/components/auth/api-key/api-keys.js +21 -40
  10. package/dist/components/auth/api-key/create-api-key-dialog.d.ts +3 -1
  11. package/dist/components/auth/api-key/create-api-key-dialog.js +43 -73
  12. package/dist/components/auth/api-key/delete-api-key-dialog.d.ts +4 -2
  13. package/dist/components/auth/api-key/delete-api-key-dialog.js +16 -50
  14. package/dist/components/auth/api-key/new-api-key-dialog.js +23 -59
  15. package/dist/components/auth/api-key/organization-api-keys.d.ts +14 -0
  16. package/dist/components/auth/api-key/organization-api-keys.js +22 -0
  17. package/dist/components/auth/auth-provider.d.ts +1 -1
  18. package/dist/components/auth/auth-provider.js +10 -16
  19. package/dist/components/auth/auth.d.ts +3 -3
  20. package/dist/components/auth/auth.js +86 -61
  21. package/dist/components/auth/delete-user/danger-zone.d.ts +3 -3
  22. package/dist/components/auth/delete-user/danger-zone.js +11 -17
  23. package/dist/components/auth/delete-user/delete-account.d.ts +9 -0
  24. package/dist/components/auth/delete-user/delete-account.js +50 -0
  25. package/dist/components/auth/email/email-changed-email.d.ts +2 -2
  26. package/dist/components/auth/email/email-changed-email.js +22 -29
  27. package/dist/components/auth/email/email-verification-email.d.ts +2 -2
  28. package/dist/components/auth/email/email-verification-email.js +22 -29
  29. package/dist/components/auth/email/magic-link-email.d.ts +2 -2
  30. package/dist/components/auth/email/magic-link-email.js +22 -29
  31. package/dist/components/auth/email/new-device-email.d.ts +2 -2
  32. package/dist/components/auth/email/new-device-email.js +22 -29
  33. package/dist/components/auth/email/organization-invitation-email.d.ts +3 -0
  34. package/dist/components/auth/email/organization-invitation-email.js +23 -0
  35. package/dist/components/auth/email/otp-email.d.ts +2 -2
  36. package/dist/components/auth/email/otp-email.js +21 -28
  37. package/dist/components/auth/email/password-changed-email.d.ts +2 -2
  38. package/dist/components/auth/email/password-changed-email.js +22 -29
  39. package/dist/components/auth/email/reset-password-email.d.ts +2 -2
  40. package/dist/components/auth/email/reset-password-email.js +22 -29
  41. package/dist/components/auth/error-toaster.js +32 -16
  42. package/dist/components/auth/field-separator.d.ts +1 -1
  43. package/dist/components/auth/field-separator.js +4 -17
  44. package/dist/components/auth/forgot-password.d.ts +1 -1
  45. package/dist/components/auth/forgot-password.js +36 -88
  46. package/dist/components/auth/magic-link/magic-link-button.d.ts +1 -1
  47. package/dist/components/auth/magic-link/magic-link-button.js +33 -19
  48. package/dist/components/auth/magic-link/magic-link.d.ts +2 -2
  49. package/dist/components/auth/magic-link/magic-link.js +39 -86
  50. package/dist/components/auth/multi-session/manage-account.d.ts +1 -1
  51. package/dist/components/auth/multi-session/manage-account.js +32 -48
  52. package/dist/components/auth/multi-session/manage-accounts.d.ts +1 -1
  53. package/dist/components/auth/multi-session/manage-accounts.js +32 -33
  54. package/dist/components/auth/multi-session/switch-account-submenu-content.d.ts +3 -1
  55. package/dist/components/auth/multi-session/switch-account-submenu-content.js +24 -27
  56. package/dist/components/auth/multi-session/switch-account-submenu-item.d.ts +3 -2
  57. package/dist/components/auth/multi-session/switch-account-submenu-item.js +16 -19
  58. package/dist/components/auth/multi-session/switch-account-submenu.d.ts +2 -1
  59. package/dist/components/auth/multi-session/switch-account-submenu.js +23 -23
  60. package/dist/components/auth/organization/change-organization-logo.d.ts +4 -0
  61. package/dist/components/auth/organization/change-organization-logo.js +69 -0
  62. package/dist/components/auth/organization/create-organization-dialog.d.ts +13 -0
  63. package/dist/components/auth/organization/create-organization-dialog.js +37 -0
  64. package/dist/components/auth/organization/delete-organization-dialog.d.ts +7 -0
  65. package/dist/components/auth/organization/delete-organization-dialog.js +25 -0
  66. package/dist/components/auth/organization/delete-organization-skeleton.d.ts +4 -0
  67. package/dist/components/auth/organization/delete-organization-skeleton.js +8 -0
  68. package/dist/components/auth/organization/delete-organization.d.ts +5 -0
  69. package/dist/components/auth/organization/delete-organization.js +27 -0
  70. package/dist/components/auth/organization/invite-member-dialog.d.ts +13 -0
  71. package/dist/components/auth/organization/invite-member-dialog.js +47 -0
  72. package/dist/components/auth/organization/leave-organization-dialog.d.ts +7 -0
  73. package/dist/components/auth/organization/leave-organization-dialog.js +21 -0
  74. package/dist/components/auth/organization/leave-organization.d.ts +4 -0
  75. package/dist/components/auth/organization/leave-organization.js +16 -0
  76. package/dist/components/auth/organization/organization-danger-zone.d.ts +16 -0
  77. package/dist/components/auth/organization/organization-danger-zone.js +23 -0
  78. package/dist/components/auth/organization/organization-invitation-row-skeleton.d.ts +5 -0
  79. package/dist/components/auth/organization/organization-invitation-row-skeleton.js +9 -0
  80. package/dist/components/auth/organization/organization-invitation-row.d.ts +5 -0
  81. package/dist/components/auth/organization/organization-invitation-row.js +31 -0
  82. package/dist/components/auth/organization/organization-invitations-empty.d.ts +8 -0
  83. package/dist/components/auth/organization/organization-invitations-empty.js +13 -0
  84. package/dist/components/auth/organization/organization-invitations.d.ts +9 -0
  85. package/dist/components/auth/organization/organization-invitations.js +66 -0
  86. package/dist/components/auth/organization/organization-logo.d.ts +15 -0
  87. package/dist/components/auth/organization/organization-logo.js +14 -0
  88. package/dist/components/auth/organization/organization-member-row-skeleton.d.ts +4 -0
  89. package/dist/components/auth/organization/organization-member-row-skeleton.js +9 -0
  90. package/dist/components/auth/organization/organization-member-row.d.ts +9 -0
  91. package/dist/components/auth/organization/organization-member-row.js +34 -0
  92. package/dist/components/auth/organization/organization-members.d.ts +9 -0
  93. package/dist/components/auth/organization/organization-members.js +67 -0
  94. package/dist/components/auth/organization/organization-people.d.ts +10 -0
  95. package/dist/components/auth/organization/organization-people.js +11 -0
  96. package/dist/components/auth/organization/organization-profile.d.ts +9 -0
  97. package/dist/components/auth/organization/organization-profile.js +34 -0
  98. package/dist/components/auth/organization/organization-row.d.ts +8 -0
  99. package/dist/components/auth/organization/organization-row.js +31 -0
  100. package/dist/components/auth/organization/organization-settings.d.ts +12 -0
  101. package/dist/components/auth/organization/organization-settings.js +13 -0
  102. package/dist/components/auth/organization/organization-switcher.d.ts +20 -0
  103. package/dist/components/auth/organization/organization-switcher.js +48 -0
  104. package/dist/components/auth/organization/organization-view-skeleton.d.ts +6 -0
  105. package/dist/components/auth/organization/organization-view-skeleton.js +9 -0
  106. package/dist/components/auth/organization/organization-view.d.ts +15 -0
  107. package/dist/components/auth/organization/organization-view.js +31 -0
  108. package/dist/components/auth/organization/organization.d.ts +17 -0
  109. package/dist/components/auth/organization/organization.js +60 -0
  110. package/dist/components/auth/organization/organizations-empty.d.ts +4 -0
  111. package/dist/components/auth/organization/organizations-empty.js +9 -0
  112. package/dist/components/auth/organization/organizations-settings.d.ts +17 -0
  113. package/dist/components/auth/organization/organizations-settings.js +17 -0
  114. package/dist/components/auth/organization/organizations.d.ts +10 -0
  115. package/dist/components/auth/organization/organizations.js +21 -0
  116. package/dist/components/auth/organization/remove-member-dialog.d.ts +9 -0
  117. package/dist/components/auth/organization/remove-member-dialog.js +20 -0
  118. package/dist/components/auth/organization/slug-field.d.ts +19 -0
  119. package/dist/components/auth/organization/slug-field.js +38 -0
  120. package/dist/components/auth/organization/user-invitation-row-skeleton.d.ts +4 -0
  121. package/dist/components/auth/organization/user-invitation-row-skeleton.js +8 -0
  122. package/dist/components/auth/organization/user-invitation-row.d.ts +10 -0
  123. package/dist/components/auth/organization/user-invitation-row.js +22 -0
  124. package/dist/components/auth/organization/user-invitations-empty.d.ts +4 -0
  125. package/dist/components/auth/organization/user-invitations-empty.js +12 -0
  126. package/dist/components/auth/organization/user-invitations.d.ts +10 -0
  127. package/dist/components/auth/organization/user-invitations.js +18 -0
  128. package/dist/components/auth/passkey/add-passkey-dialog.d.ts +5 -0
  129. package/dist/components/auth/passkey/add-passkey-dialog.js +22 -0
  130. package/dist/components/auth/passkey/delete-passkey-dialog.d.ts +11 -0
  131. package/dist/components/auth/passkey/delete-passkey-dialog.js +14 -0
  132. package/dist/components/auth/passkey/passkey-button.d.ts +1 -1
  133. package/dist/components/auth/passkey/passkey-button.js +24 -23
  134. package/dist/components/auth/passkey/passkey-skeleton.d.ts +1 -0
  135. package/dist/components/auth/passkey/passkey-skeleton.js +5 -0
  136. package/dist/components/auth/passkey/passkey.d.ts +2 -5
  137. package/dist/components/auth/passkey/passkey.js +16 -44
  138. package/dist/components/auth/passkey/passkeys-empty.d.ts +4 -0
  139. package/dist/components/auth/passkey/passkeys-empty.js +9 -0
  140. package/dist/components/auth/passkey/passkeys.d.ts +1 -1
  141. package/dist/components/auth/passkey/passkeys.js +15 -105
  142. package/dist/components/auth/provider-button.d.ts +2 -2
  143. package/dist/components/auth/provider-button.js +28 -24
  144. package/dist/components/auth/provider-buttons.js +28 -18
  145. package/dist/components/auth/reset-password.d.ts +1 -1
  146. package/dist/components/auth/reset-password.js +56 -146
  147. package/dist/components/auth/settings/account/account-settings.d.ts +2 -2
  148. package/dist/components/auth/settings/account/account-settings.js +21 -19
  149. package/dist/components/auth/settings/account/change-avatar.js +53 -88
  150. package/dist/components/auth/settings/account/change-email.d.ts +1 -1
  151. package/dist/components/auth/settings/account/change-email.js +27 -53
  152. package/dist/components/auth/settings/account/user-profile.d.ts +1 -1
  153. package/dist/components/auth/settings/account/user-profile.js +64 -85
  154. package/dist/components/auth/settings/security/active-session.d.ts +1 -1
  155. package/dist/components/auth/settings/security/active-session.js +50 -57
  156. package/dist/components/auth/settings/security/active-sessions.d.ts +1 -1
  157. package/dist/components/auth/settings/security/active-sessions.js +21 -32
  158. package/dist/components/auth/settings/security/change-password.d.ts +1 -1
  159. package/dist/components/auth/settings/security/change-password.js +76 -186
  160. package/dist/components/auth/settings/security/linked-account.d.ts +1 -1
  161. package/dist/components/auth/settings/security/linked-account.js +37 -55
  162. package/dist/components/auth/settings/security/linked-accounts.d.ts +1 -1
  163. package/dist/components/auth/settings/security/linked-accounts.js +34 -43
  164. package/dist/components/auth/settings/security/security-settings.d.ts +2 -2
  165. package/dist/components/auth/settings/security/security-settings.js +19 -21
  166. package/dist/components/auth/settings/settings.d.ts +4 -4
  167. package/dist/components/auth/settings/settings.js +52 -44
  168. package/dist/components/auth/sign-in.d.ts +2 -2
  169. package/dist/components/auth/sign-in.js +63 -132
  170. package/dist/components/auth/sign-out.js +32 -26
  171. package/dist/components/auth/sign-up.d.ts +2 -2
  172. package/dist/components/auth/sign-up.js +97 -211
  173. package/dist/components/auth/theme/appearance.d.ts +1 -1
  174. package/dist/components/auth/theme/appearance.js +23 -71
  175. package/dist/components/auth/theme/theme-toggle-item.js +56 -61
  176. package/dist/components/auth/user/user-avatar.d.ts +4 -4
  177. package/dist/components/auth/user/user-avatar.js +31 -28
  178. package/dist/components/auth/user/user-button.d.ts +6 -7
  179. package/dist/components/auth/user/user-button.js +38 -72
  180. package/dist/components/auth/user/user-view.d.ts +13 -7
  181. package/dist/components/auth/user/user-view.js +26 -36
  182. package/dist/components/auth/username/sign-in-username.d.ts +2 -2
  183. package/dist/components/auth/username/sign-in-username.js +87 -147
  184. package/dist/components/auth/username/username-field.d.ts +1 -1
  185. package/dist/components/auth/username/username-field.js +44 -52
  186. package/dist/email.d.ts +8 -7
  187. package/dist/email.js +8 -8
  188. package/dist/index.d.ts +21 -21
  189. package/dist/index.js +21 -22
  190. package/dist/lib/auth/api-key-plugin.d.ts +7 -4
  191. package/dist/lib/auth/api-key-plugin.js +12 -10
  192. package/dist/lib/auth/auth-plugin.d.ts +10 -6
  193. package/dist/lib/auth/auth-plugin.js +1 -0
  194. package/dist/lib/auth/delete-user-plugin.d.ts +6 -6
  195. package/dist/lib/auth/delete-user-plugin.js +6 -9
  196. package/dist/lib/auth/magic-link-plugin.d.ts +5 -5
  197. package/dist/lib/auth/magic-link-plugin.js +17 -12
  198. package/dist/lib/auth/multi-session-plugin.d.ts +5 -5
  199. package/dist/lib/auth/multi-session-plugin.js +8 -11
  200. package/dist/lib/auth/organization-plugin.d.ts +37 -0
  201. package/dist/lib/auth/organization-plugin.js +19 -0
  202. package/dist/lib/auth/passkey-plugin.d.ts +9 -6
  203. package/dist/lib/auth/passkey-plugin.js +8 -11
  204. package/dist/lib/auth/theme-plugin.d.ts +6 -6
  205. package/dist/lib/auth/theme-plugin.js +25 -22
  206. package/dist/lib/auth/username-plugin.d.ts +11 -11
  207. package/dist/lib/auth/username-plugin.js +18 -17
  208. package/dist/plugins.d.ts +46 -22
  209. package/dist/plugins.js +47 -22
  210. package/package.json +25 -19
  211. package/src/components/auth/api-key/api-key.tsx +25 -16
  212. package/src/components/auth/api-key/api-keys-empty.tsx +8 -4
  213. package/src/components/auth/api-key/api-keys.tsx +52 -14
  214. package/src/components/auth/api-key/create-api-key-dialog.tsx +17 -4
  215. package/src/components/auth/api-key/delete-api-key-dialog.tsx +10 -2
  216. package/src/components/auth/api-key/organization-api-keys.tsx +55 -0
  217. package/src/components/auth/delete-user/danger-zone.tsx +3 -3
  218. package/src/components/auth/delete-user/{delete-user.tsx → delete-account.tsx} +9 -9
  219. package/src/components/auth/email/organization-invitation-email.tsx +38 -0
  220. package/src/components/auth/error-toaster.tsx +28 -10
  221. package/src/components/auth/forgot-password.tsx +10 -2
  222. package/src/components/auth/multi-session/manage-accounts.tsx +1 -1
  223. package/src/components/auth/multi-session/switch-account-submenu-content.tsx +7 -2
  224. package/src/components/auth/multi-session/switch-account-submenu-item.tsx +4 -2
  225. package/src/components/auth/multi-session/switch-account-submenu.tsx +8 -4
  226. package/src/components/auth/organization/change-organization-logo.tsx +171 -0
  227. package/src/components/auth/organization/create-organization-dialog.tsx +133 -0
  228. package/src/components/auth/organization/delete-organization-dialog.tsx +97 -0
  229. package/src/components/auth/organization/delete-organization-skeleton.tsx +17 -0
  230. package/src/components/auth/organization/delete-organization.tsx +77 -0
  231. package/src/components/auth/organization/invite-member-dialog.tsx +177 -0
  232. package/src/components/auth/organization/leave-organization-dialog.tsx +95 -0
  233. package/src/components/auth/organization/leave-organization.tsx +59 -0
  234. package/src/components/auth/organization/organization-danger-zone.tsx +68 -0
  235. package/src/components/auth/organization/organization-invitation-row-skeleton.tsx +29 -0
  236. package/src/components/auth/organization/organization-invitation-row.tsx +97 -0
  237. package/src/components/auth/organization/organization-invitations-empty.tsx +39 -0
  238. package/src/components/auth/organization/organization-invitations.tsx +351 -0
  239. package/src/components/auth/organization/organization-logo.tsx +64 -0
  240. package/src/components/auth/organization/organization-member-row-skeleton.tsx +24 -0
  241. package/src/components/auth/organization/organization-member-row.tsx +157 -0
  242. package/src/components/auth/organization/organization-members.tsx +284 -0
  243. package/src/components/auth/organization/organization-people.tsx +26 -0
  244. package/src/components/auth/organization/organization-profile.tsx +141 -0
  245. package/src/components/auth/organization/organization-row.tsx +66 -0
  246. package/src/components/auth/organization/organization-settings.tsx +38 -0
  247. package/src/components/auth/organization/organization-switcher.tsx +233 -0
  248. package/src/components/auth/organization/organization-view-skeleton.tsx +36 -0
  249. package/src/components/auth/organization/organization-view.tsx +109 -0
  250. package/src/components/auth/organization/organization.tsx +162 -0
  251. package/src/components/auth/organization/organizations-empty.tsx +35 -0
  252. package/src/components/auth/organization/organizations-settings.tsx +36 -0
  253. package/src/components/auth/organization/organizations.tsx +80 -0
  254. package/src/components/auth/organization/remove-member-dialog.tsx +95 -0
  255. package/src/components/auth/organization/slug-field.tsx +111 -0
  256. package/src/components/auth/organization/user-invitation-row-skeleton.tsx +17 -0
  257. package/src/components/auth/organization/user-invitation-row.tsx +90 -0
  258. package/src/components/auth/organization/user-invitations-empty.tsx +30 -0
  259. package/src/components/auth/organization/user-invitations.tsx +59 -0
  260. package/src/components/auth/passkey/add-passkey-dialog.tsx +109 -0
  261. package/src/components/auth/passkey/delete-passkey-dialog.tsx +95 -0
  262. package/src/components/auth/passkey/passkey-skeleton.tsx +16 -0
  263. package/src/components/auth/passkey/passkey.tsx +23 -22
  264. package/src/components/auth/passkey/passkeys-empty.tsx +35 -0
  265. package/src/components/auth/passkey/passkeys.tsx +33 -154
  266. package/src/components/auth/settings/account/change-email.tsx +1 -1
  267. package/src/components/auth/settings/account/user-profile.tsx +5 -5
  268. package/src/components/auth/settings/security/active-sessions.tsx +6 -4
  269. package/src/components/auth/settings/security/linked-accounts.tsx +2 -2
  270. package/src/components/auth/settings/settings.tsx +77 -14
  271. package/src/components/auth/user/user-avatar.tsx +4 -1
  272. package/src/components/auth/user/user-button.tsx +14 -11
  273. package/src/components/auth/user/user-view.tsx +32 -12
  274. package/src/email.ts +1 -0
  275. package/src/lib/auth/api-key-plugin.ts +10 -4
  276. package/src/lib/auth/auth-plugin.ts +6 -1
  277. package/src/lib/auth/organization-plugin.tsx +32 -0
  278. package/src/plugins.ts +25 -1
  279. package/dist/components/auth/delete-user/delete-user.d.ts +0 -9
  280. package/dist/components/auth/delete-user/delete-user.js +0 -95
@@ -1,29 +1,32 @@
1
- import { useAuth as e, useSession as t } from "@better-auth-ui/react";
2
- import { Person as n } from "@gravity-ui/icons";
3
- import { Avatar as r, Skeleton as i, cn as a } from "@heroui/react";
4
- import { jsx as o, jsxs as s } from "react/jsx-runtime";
5
- //#region src/components/auth/user/user-avatar.tsx
6
- function c({ className: c, fallback: l, isPending: u, user: d, size: f = "sm", style: p, ...m }) {
7
- let { authClient: h } = e(), { data: g, isPending: _ } = t(h, { enabled: !d && !u });
8
- if ((u || _) && !d) return /* @__PURE__ */ o(i, {
9
- className: a("rounded-full", f === "sm" ? "size-8" : f === "md" ? "size-10" : "size-12", c),
10
- style: p
11
- });
12
- let v = d ?? g?.user, y = (v?.username || v?.name || v?.email)?.slice(0, 2).toUpperCase();
13
- return /* @__PURE__ */ s(r, {
14
- size: f,
15
- className: a("rounded-full", c),
16
- style: p,
17
- ...m,
18
- children: [/* @__PURE__ */ o(r.Image, {
19
- alt: v?.displayUsername || v?.name || v?.email,
20
- src: v?.image ?? void 0
21
- }), /* @__PURE__ */ o(r.Fallback, {
22
- className: a(f === "lg" ? "text-xl" : f === "md" ? "text-base" : "text-sm"),
23
- delayMs: v?.image ? 600 : void 0,
24
- children: l || y || /* @__PURE__ */ o(n, { className: "size-4" })
25
- })]
26
- });
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useAuth, useSession } from "@better-auth-ui/react";
3
+ import { Person } from "@gravity-ui/icons";
4
+ import { Avatar, cn, Skeleton } from "@heroui/react";
5
+ /**
6
+ * Render a user avatar that shows the user's image, initials, or a custom fallback; displays a circular skeleton while the session (or explicit pending flag) is pending.
7
+ *
8
+ * @param className - Additional CSS classes applied to the outer avatar container
9
+ * @param fallback - Custom fallback content to render when no image or initials are available
10
+ * @param isPending - When true, force rendering of the loading skeleton (unless an explicit `user` prop is provided)
11
+ * @param user - Optional user object to display; when omitted the current session user is used if available
12
+ * @param size - Visual size of the avatar; one of `"sm"`, `"md"`, or `"lg"` (default: `"sm"`)
13
+ * @returns A React element that displays the user's avatar image, initials, or the provided fallback; renders a circular skeleton while loading
14
+ */
15
+ export function UserAvatar({ className, fallback, isPending, user, size = "sm", style, ...props }) {
16
+ const { authClient } = useAuth();
17
+ const { data: session, isPending: sessionPending } = useSession(authClient, {
18
+ enabled: !user && !isPending
19
+ });
20
+ if ((isPending || sessionPending) && !user) {
21
+ return (_jsx(Skeleton, { className: cn("rounded-full", size === "sm" ? "size-8" : size === "md" ? "size-10" : "size-12", className), style: style }));
22
+ }
23
+ const resolvedUser = user ?? session?.user;
24
+ const initials = (resolvedUser?.username ||
25
+ resolvedUser?.name ||
26
+ resolvedUser?.email)
27
+ ?.slice(0, 2)
28
+ .toUpperCase();
29
+ return (_jsxs(Avatar, { size: size, className: cn("rounded-full", className), style: style, ...props, children: [_jsx(Avatar.Image, { alt: resolvedUser?.displayUsername ||
30
+ resolvedUser?.name ||
31
+ resolvedUser?.email, src: resolvedUser?.image ?? undefined }), _jsx(Avatar.Fallback, { className: cn(size === "lg" ? "text-xl" : size === "md" ? "text-base" : "text-sm"), delayMs: resolvedUser?.image ? 600 : undefined, children: fallback || initials || _jsx(Person, { className: "size-4" }) })] }));
27
32
  }
28
- //#endregion
29
- export { c as UserAvatar };
@@ -1,5 +1,5 @@
1
- import { ButtonProps, DropdownItemProps, DropdownPopoverProps } from '@heroui/react';
2
- import { ReactElement, ReactNode } from 'react';
1
+ import { type ButtonProps, type DropdownItemProps, type DropdownPopoverProps } from "@heroui/react";
2
+ import { type ReactElement, type ReactNode } from "react";
3
3
  /** Auth states a `UserButton` link can be visible in. */
4
4
  export type UserButtonLinkVisibility = "authenticated" | "unauthenticated" | "always";
5
5
  /** A simple link entry rendered as a `Dropdown.Item` in the `UserButton` menu. */
@@ -21,16 +21,15 @@ export type UserButtonLink = {
21
21
  export type UserButtonProps = {
22
22
  className?: string;
23
23
  size?: "default" | "icon";
24
- /**
25
- * The placement of the element with respect to its anchor element.
26
- * @default "bottom"
27
- */
24
+ /** The placement of the element with respect to its anchor element. */
28
25
  placement?: DropdownPopoverProps["placement"];
29
26
  variant?: ButtonProps["variant"];
30
27
  /** Additional menu entries rendered above the built-in items. */
31
28
  links?: (UserButtonLink | ReactElement)[];
32
29
  /** Hide the built-in "Settings" link. Useful when replacing it via `links`. */
33
30
  hideSettings?: boolean;
31
+ /** When true, the subtitle line (email when name/username is shown) is hidden. */
32
+ hideSubtitle?: boolean;
34
33
  };
35
34
  /**
36
35
  * Render a user account dropdown button that shows account actions.
@@ -43,4 +42,4 @@ export type UserButtonProps = {
43
42
  * @param hideSettings - Hide the built-in "Settings" link
44
43
  * @returns The user button and its dropdown menu as a JSX element
45
44
  */
46
- export declare function UserButton({ className, placement, size, variant, links, hideSettings }: UserButtonProps): import("react/jsx-runtime").JSX.Element;
45
+ export declare function UserButton({ className, placement, size, variant, links, hideSettings, hideSubtitle }: UserButtonProps): import("react/jsx-runtime").JSX.Element;
@@ -1,74 +1,40 @@
1
- import { UserAvatar as e } from "./user-avatar.js";
2
- import { UserView as t } from "./user-view.js";
3
- import { useAuth as n, useSession as r } from "@better-auth-ui/react";
4
- import { ArrowRightFromSquare as i, ArrowRightToSquare as a, ChevronsExpandVertical as o, Gear as s, PersonPlus as c } from "@gravity-ui/icons";
5
- import { Button as l, Dropdown as u, Label as d, cn as f } from "@heroui/react";
6
- import { isValidElement as p } from "react";
7
- import { Fragment as m, jsx as h, jsxs as g } from "react/jsx-runtime";
8
- //#region src/components/auth/user/user-button.tsx
9
- function _(e, t) {
10
- if (p(e)) return e;
11
- let { label: n, href: r, icon: i, variant: a } = e;
12
- return /* @__PURE__ */ g(u.Item, {
13
- href: r,
14
- variant: a,
15
- textValue: typeof n == "string" ? n : void 0,
16
- children: [i, /* @__PURE__ */ h(d, { children: n })]
17
- }, t);
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useAuth, useSession } from "@better-auth-ui/react";
3
+ import { ArrowRightFromSquare, ArrowRightToSquare, ChevronsExpandVertical, Gear, PersonPlus } from "@gravity-ui/icons";
4
+ import { Button, cn, Dropdown, Label } from "@heroui/react";
5
+ import { isValidElement } from "react";
6
+ import { UserAvatar } from "./user-avatar";
7
+ import { UserView } from "./user-view";
8
+ function renderUserLink(link, fallbackKey) {
9
+ if (isValidElement(link))
10
+ return link;
11
+ const { label, href, icon, variant } = link;
12
+ return (_jsxs(Dropdown.Item, { href: href, variant: variant, textValue: typeof label === "string" ? label : undefined, children: [icon, _jsx(Label, { children: label })] }, fallbackKey));
18
13
  }
19
- function v({ className: v, placement: y = "bottom", size: b = "default", variant: x = "ghost", links: S, hideSettings: C = !1 }) {
20
- let { authClient: w, basePaths: T, viewPaths: E, localization: D, plugins: O } = n(), { data: k, isPending: A } = r(w), j = O.flatMap((e) => e.userMenuItems?.map((t, n) => /* @__PURE__ */ h(t, {}, `${e.id}-${n.toString()}`)) ?? []), M = S?.flatMap((e, t) => {
21
- if (!p(e)) {
22
- let t = e.visibility ?? "always";
23
- if (t === "authenticated" && !k || t === "unauthenticated" && k) return [];
24
- }
25
- return [_(e, `user-button-link-${t.toString()}`)];
26
- });
27
- return /* @__PURE__ */ g(u, { children: [b === "icon" ? /* @__PURE__ */ h(u.Trigger, {
28
- className: f("rounded-full", v),
29
- children: /* @__PURE__ */ h(e, {})
30
- }) : /* @__PURE__ */ g(l, {
31
- variant: x,
32
- className: f("h-auto font-normal justify-start px-3 py-2 text-left", v),
33
- children: [k || A ? /* @__PURE__ */ h(t, { isPending: A }) : /* @__PURE__ */ g(m, { children: [/* @__PURE__ */ h(e, {}), /* @__PURE__ */ h("p", {
34
- className: "text-sm font-medium",
35
- children: D.auth.account
36
- })] }), /* @__PURE__ */ h(o, { className: "ml-auto size-3.5" })]
37
- }), /* @__PURE__ */ g(u.Popover, {
38
- placement: y,
39
- className: "min-w-40 md:min-w-56 max-w-[48svw]",
40
- children: [k && /* @__PURE__ */ h("div", {
41
- className: "px-3 pt-3 pb-1",
42
- children: /* @__PURE__ */ h(t, {})
43
- }), /* @__PURE__ */ h(u.Menu, { children: k ? /* @__PURE__ */ g(m, { children: [
44
- M,
45
- !C && /* @__PURE__ */ g(u.Item, {
46
- textValue: D.settings.settings,
47
- href: `${T.settings}/${E.settings.account}`,
48
- children: [/* @__PURE__ */ h(s, { className: "text-muted" }), /* @__PURE__ */ h(d, { children: D.settings.settings })]
49
- }),
50
- j,
51
- /* @__PURE__ */ g(u.Item, {
52
- textValue: D.auth.signOut,
53
- href: `${T.auth}/${E.auth.signOut}`,
54
- variant: "danger",
55
- children: [/* @__PURE__ */ h(i, { className: "text-danger" }), /* @__PURE__ */ h(d, { children: D.auth.signOut })]
56
- })
57
- ] }) : /* @__PURE__ */ g(m, { children: [
58
- M,
59
- /* @__PURE__ */ g(u.Item, {
60
- textValue: D.auth.signIn,
61
- href: `${T.auth}/${E.auth.signIn}`,
62
- children: [/* @__PURE__ */ h(a, { className: "text-muted" }), /* @__PURE__ */ h(d, { children: D.auth.signIn })]
63
- }),
64
- /* @__PURE__ */ g(u.Item, {
65
- textValue: D.auth.signUp,
66
- href: `${T.auth}/${E.auth.signUp}`,
67
- children: [/* @__PURE__ */ h(c, { className: "text-muted" }), /* @__PURE__ */ h(d, { children: D.auth.signUp })]
68
- }),
69
- j
70
- ] }) })]
71
- })] });
14
+ /**
15
+ * Render a user account dropdown button that shows account actions.
16
+ *
17
+ * @param className - Additional CSS classes applied to the trigger element
18
+ * @param placement - Dropdown popover placement (e.g., "bottom", "top-start", "bottom-end")
19
+ * @param size - "icon" renders an avatar-only trigger; "default" renders a button with label and chevron
20
+ * @param variant - Button visual variant passed to the underlying Button component
21
+ * @param links - Additional menu entries rendered above the built-in items
22
+ * @param hideSettings - Hide the built-in "Settings" link
23
+ * @returns The user button and its dropdown menu as a JSX element
24
+ */
25
+ export function UserButton({ className, placement, size = "default", variant = "ghost", links, hideSettings, hideSubtitle }) {
26
+ const { authClient, basePaths, viewPaths, localization, plugins } = useAuth();
27
+ const { data: session, isPending: sessionPending } = useSession(authClient);
28
+ const userMenuItems = plugins.flatMap((plugin) => plugin.userMenuItems?.map((Item, index) => (_jsx(Item, { hideSubtitle: hideSubtitle }, `${plugin.id}-${index.toString()}`))) ?? []);
29
+ const userLinks = links?.flatMap((link, index) => {
30
+ if (!isValidElement(link)) {
31
+ const visibility = link.visibility ?? "always";
32
+ if (visibility === "authenticated" && !session)
33
+ return [];
34
+ if (visibility === "unauthenticated" && session)
35
+ return [];
36
+ }
37
+ return [renderUserLink(link, `user-button-link-${index.toString()}`)];
38
+ });
39
+ return (_jsxs(Dropdown, { children: [size === "icon" ? (_jsx(Dropdown.Trigger, { className: cn("rounded-full", className), children: _jsx(UserAvatar, {}) })) : (_jsxs(Button, { variant: variant, className: cn("h-auto font-normal justify-start px-2 py-2 text-left", className), children: [session || sessionPending ? (_jsx(UserView, { isPending: sessionPending, hideSubtitle: hideSubtitle })) : (_jsxs(_Fragment, { children: [_jsx(UserAvatar, {}), _jsx("p", { className: "text-sm font-medium", children: localization.auth.account })] })), _jsx(ChevronsExpandVertical, { className: "ml-auto size-3 text-muted" })] })), _jsxs(Dropdown.Popover, { placement: placement, className: "min-w-40 md:min-w-56 max-w-[48svw]", children: [session && (_jsx("div", { className: "px-3 pt-3 pb-1", children: _jsx(UserView, { hideSubtitle: hideSubtitle }) })), _jsx(Dropdown.Menu, { children: session ? (_jsxs(_Fragment, { children: [userLinks, !hideSettings && (_jsxs(Dropdown.Item, { textValue: localization.settings.settings, href: `${basePaths.settings}/${viewPaths.settings.account}`, children: [_jsx(Gear, { className: "text-muted" }), _jsx(Label, { children: localization.settings.settings })] })), userMenuItems, _jsxs(Dropdown.Item, { textValue: localization.auth.signOut, href: `${basePaths.auth}/${viewPaths.auth.signOut}`, variant: "danger", children: [_jsx(ArrowRightFromSquare, { className: "text-danger" }), _jsx(Label, { children: localization.auth.signOut })] })] })) : (_jsxs(_Fragment, { children: [userLinks, _jsxs(Dropdown.Item, { textValue: localization.auth.signIn, href: `${basePaths.auth}/${viewPaths.auth.signIn}`, children: [_jsx(ArrowRightToSquare, { className: "text-muted" }), _jsx(Label, { children: localization.auth.signIn })] }), _jsxs(Dropdown.Item, { textValue: localization.auth.signUp, href: `${basePaths.auth}/${viewPaths.auth.signUp}`, children: [_jsx(PersonPlus, { className: "text-muted" }), _jsx(Label, { children: localization.auth.signUp })] }), userMenuItems] })) })] })] }));
72
40
  }
73
- //#endregion
74
- export { v as UserButton };
@@ -1,22 +1,28 @@
1
- import { AvatarProps } from '@heroui/react';
2
- import { User } from 'better-auth';
3
- import { ComponentProps } from 'react';
1
+ import { type AvatarProps } from "@heroui/react";
2
+ import type { User } from "better-auth";
3
+ import type { ComponentProps } from "react";
4
4
  export type UserViewProps = {
5
5
  className?: string;
6
6
  isPending?: boolean;
7
7
  size?: AvatarProps["size"];
8
+ /**
9
+ * When true, the subtitle line (email when name/username is shown) is hidden.
10
+ * @default false
11
+ */
12
+ hideSubtitle?: boolean;
8
13
  /** @remarks `User` */
9
- user?: User & {
14
+ user?: Partial<User> & {
10
15
  username?: string | null;
11
16
  displayUsername?: string | null;
12
17
  };
13
18
  };
14
19
  /**
15
- * Render a compact user item with an avatar, a primary label (display username, name, or email), and an optional secondary email line.
20
+ * Render a compact user item with an avatar, a primary label (display username, name, or email), and an optional subtitle (email).
16
21
  *
17
22
  * @param isPending - If true and no `user` prop is provided, renders a loading skeleton instead of user details
18
- * @param size - Avatar size variant; defaults to `"sm"`
23
+ * @param size - Avatar size variant; defaults to `"md"`
24
+ * @param hideSubtitle - When true, omits the muted subtitle row under the primary label
19
25
  * @param user - Optional user to display; when omitted the current session user is used if available
20
26
  * @returns A React element containing the user's avatar and text labels
21
27
  */
22
- export declare function UserView({ className, isPending, size, user, ...props }: UserViewProps & ComponentProps<"div">): import("react/jsx-runtime").JSX.Element;
28
+ export declare function UserView({ className, isPending, size, hideSubtitle, user, ...props }: UserViewProps & ComponentProps<"div">): import("react/jsx-runtime").JSX.Element;
@@ -1,37 +1,27 @@
1
- import { UserAvatar as e } from "./user-avatar.js";
2
- import { useAuth as t, useSession as n } from "@better-auth-ui/react";
3
- import { Skeleton as r, cn as i } from "@heroui/react";
4
- import { jsx as a, jsxs as o } from "react/jsx-runtime";
5
- //#region src/components/auth/user/user-view.tsx
6
- function s({ className: s, isPending: c, size: l = "sm", user: u, ...d }) {
7
- let { authClient: f } = t(), { data: p, isPending: m } = n(f, { enabled: !u && !c }), h = u ?? p?.user;
8
- return (c || m) && !u ? /* @__PURE__ */ o("div", {
9
- className: i("flex items-center gap-2 min-w-0", s),
10
- ...d,
11
- children: [/* @__PURE__ */ a(e, {
12
- isPending: !0,
13
- size: l
14
- }), /* @__PURE__ */ o("div", {
15
- className: "flex flex-col gap-1 min-w-0",
16
- children: [/* @__PURE__ */ a(r, { className: "h-3.5 w-24 rounded-lg" }), /* @__PURE__ */ a(r, { className: "h-3 w-32 rounded-lg" })]
17
- })]
18
- }) : /* @__PURE__ */ o("div", {
19
- className: i("flex items-center gap-2 min-w-0", s),
20
- ...d,
21
- children: [/* @__PURE__ */ a(e, {
22
- user: h,
23
- size: l
24
- }), /* @__PURE__ */ o("div", {
25
- className: "min-w-0",
26
- children: [/* @__PURE__ */ a("p", {
27
- className: "text-sm font-medium truncate leading-tight",
28
- children: h?.displayUsername || h?.name || h?.email
29
- }), (h?.displayUsername || h?.name) && /* @__PURE__ */ a("p", {
30
- className: "text-muted text-xs mb-0.5 truncate overflow-x-hidden",
31
- children: h?.email
32
- })]
33
- })]
34
- });
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useAuth, useSession } from "@better-auth-ui/react";
3
+ import { cn, Skeleton } from "@heroui/react";
4
+ import { UserAvatar } from "./user-avatar";
5
+ /**
6
+ * Render a compact user item with an avatar, a primary label (display username, name, or email), and an optional subtitle (email).
7
+ *
8
+ * @param isPending - If true and no `user` prop is provided, renders a loading skeleton instead of user details
9
+ * @param size - Avatar size variant; defaults to `"md"`
10
+ * @param hideSubtitle - When true, omits the muted subtitle row under the primary label
11
+ * @param user - Optional user to display; when omitted the current session user is used if available
12
+ * @returns A React element containing the user's avatar and text labels
13
+ */
14
+ export function UserView({ className, isPending, size = "md", hideSubtitle = false, user, ...props }) {
15
+ const { authClient } = useAuth();
16
+ const { data: session, isPending: sessionPending } = useSession(authClient, {
17
+ enabled: !user && !isPending
18
+ });
19
+ const resolvedUser = user ?? session?.user;
20
+ if ((isPending || sessionPending) && !user) {
21
+ return (_jsxs("div", { className: cn("flex items-center gap-2 min-w-0", className), ...props, children: [_jsx(UserAvatar, { isPending: true, className: size === "sm" ? "size-5 [&>span]:text-xs" : undefined, size: size === "lg" ? "md" : "sm" }), _jsxs("div", { className: "flex flex-col gap-1 min-w-0", children: [_jsx(Skeleton, { className: "h-3.5 w-24 rounded-lg" }), !hideSubtitle ? _jsx(Skeleton, { className: "h-3 w-32 rounded-lg" }) : null] })] }));
22
+ }
23
+ return (_jsxs("div", { className: cn("flex items-center gap-2 min-w-0", className), ...props, children: [_jsx(UserAvatar, { className: size === "sm" ? "size-5 [&>span]:text-xs" : undefined, user: resolvedUser, size: size === "lg" ? "md" : "sm" }), _jsxs("div", { className: "flex flex-col min-w-0", children: [_jsx("p", { className: "text-foreground text-sm font-medium leading-tight truncate", children: resolvedUser?.displayUsername ||
24
+ resolvedUser?.name ||
25
+ resolvedUser?.email }), !hideSubtitle &&
26
+ (resolvedUser?.displayUsername || resolvedUser?.name) ? (_jsx("p", { className: "text-muted text-xs leading-tight truncate overflow-x-hidden", children: resolvedUser?.email })) : null] })] }));
35
27
  }
36
- //#endregion
37
- export { s as UserView };
@@ -1,5 +1,5 @@
1
- import { CardProps } from '@heroui/react';
2
- import { SocialLayout } from '../provider-buttons';
1
+ import { type CardProps } from "@heroui/react";
2
+ import { type SocialLayout } from "../provider-buttons";
3
3
  export interface SignInUsernameProps {
4
4
  className?: string;
5
5
  socialLayout?: SocialLayout;
@@ -1,148 +1,88 @@
1
- import { FieldSeparator as e } from "../field-separator.js";
2
- import { ProviderButtons as t } from "../provider-buttons.js";
3
- import { usernamePlugin as n } from "../../../lib/auth/username-plugin.js";
4
- import { authMutationKeys as r } from "@better-auth-ui/core";
5
- import { useAuth as i, useAuthPlugin as a, useFetchOptions as o, useSendVerificationEmail as s, useSignInEmail as c, useSignInUsername as l } from "@better-auth-ui/react";
6
- import { Button as ee, Card as u, Checkbox as d, Description as f, FieldError as p, Form as te, Input as m, Label as h, Link as g, Spinner as ne, TextField as _, cn as v, toast as y } from "@heroui/react";
7
- import { useState as re } from "react";
8
- import { Fragment as b, jsx as x, jsxs as S } from "react/jsx-runtime";
9
- import { useIsMutating as C } from "@tanstack/react-query";
10
- //#region src/components/auth/username/sign-in-username.tsx
11
- function w({ className: w, socialLayout: T, socialPosition: E = "bottom", variant: D, ...O }) {
12
- let { authClient: k, basePaths: A, baseURL: j, emailAndPassword: M, localization: N, plugins: P, redirectTo: F, socialProviders: I, viewPaths: L, navigate: R } = i(), { fetchOptions: z, resetFetchOptions: B } = o(), { localization: V } = a(n), [H, U] = re(""), { mutate: W } = s(k, { onSuccess: () => y.success(N.auth.verificationEmailSent) });
13
- function G(e) {
14
- return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e);
15
- }
16
- let { mutate: K, isPending: q } = c(k, {
17
- onError: (e, { email: t }) => {
18
- U(""), e.error?.code === "EMAIL_NOT_VERIFIED" ? y.danger(e.error?.message || e.message, { actionProps: {
19
- children: N.auth.resend,
20
- onClick: () => W({
21
- email: t,
22
- callbackURL: `${j}${F}`
23
- })
24
- } }) : y.danger(e.error?.message || e.message), B();
25
- },
26
- onSuccess: () => R({ to: F })
27
- }), { mutate: J, isPending: Y } = l(k, {
28
- onError: (e) => {
29
- U(""), y.danger(e.error?.message || e.message), B();
30
- },
31
- onSuccess: () => R({ to: F })
32
- }), ie = (e) => {
33
- e.preventDefault();
34
- let t = new FormData(e.currentTarget), n = t.get("email"), r = t.get("rememberMe") === "on";
35
- G(n) ? K({
36
- email: n,
37
- password: H,
38
- ...M?.rememberMe ? { rememberMe: r } : {},
39
- fetchOptions: z
40
- }) : J({
41
- username: n,
42
- password: H,
43
- ...M?.rememberMe ? { rememberMe: r } : {},
44
- fetchOptions: z
45
- });
46
- }, X = C({ mutationKey: r.signIn.all }) + C({ mutationKey: r.signUp.all }) > 0, Z = q || Y, Q = P.find((e) => e.captchaComponent)?.captchaComponent, $ = M?.enabled && !!I?.length;
47
- return /* @__PURE__ */ S(u, {
48
- className: v("w-full max-w-sm gap-4 md:p-6", w),
49
- variant: D,
50
- ...O,
51
- children: [
52
- /* @__PURE__ */ x(u.Header, { children: /* @__PURE__ */ x(u.Title, {
53
- className: "text-xl font-semibold mb-1",
54
- children: N.auth.signIn
55
- }) }),
56
- /* @__PURE__ */ S(u.Content, {
57
- className: "gap-4",
58
- children: [
59
- E === "top" && /* @__PURE__ */ S(b, { children: [!!I?.length && /* @__PURE__ */ x(t, { socialLayout: T }), $ && /* @__PURE__ */ x(e, { children: N.auth.or })] }),
60
- M?.enabled && /* @__PURE__ */ S(te, {
61
- onSubmit: ie,
62
- className: "flex flex-col gap-4",
63
- children: [
64
- /* @__PURE__ */ S(_, {
65
- name: "email",
66
- type: "text",
67
- autoComplete: "username email",
68
- isDisabled: X,
69
- children: [
70
- /* @__PURE__ */ x(h, { children: V.username }),
71
- /* @__PURE__ */ x(m, {
72
- placeholder: V.usernameOrEmailPlaceholder,
73
- variant: D === "transparent" ? "primary" : "secondary",
74
- required: !0
75
- }),
76
- /* @__PURE__ */ x(p, {})
77
- ]
78
- }),
79
- /* @__PURE__ */ S(_, {
80
- minLength: M?.minPasswordLength,
81
- maxLength: M?.maxPasswordLength,
82
- name: "password",
83
- type: "password",
84
- autoComplete: "current-password",
85
- isDisabled: X,
86
- value: H,
87
- onChange: U,
88
- children: [
89
- /* @__PURE__ */ x(h, { children: N.auth.password }),
90
- /* @__PURE__ */ x(m, {
91
- placeholder: N.auth.passwordPlaceholder,
92
- variant: D === "transparent" ? "primary" : "secondary",
93
- required: !0
94
- }),
95
- /* @__PURE__ */ x(p, {})
96
- ]
97
- }),
98
- M?.rememberMe && /* @__PURE__ */ S(d, {
99
- name: "rememberMe",
100
- isDisabled: X,
101
- variant: D === "transparent" ? "primary" : "secondary",
102
- children: [/* @__PURE__ */ x(d.Control, { children: /* @__PURE__ */ x(d.Indicator, {}) }), /* @__PURE__ */ x(d.Content, { children: /* @__PURE__ */ x(h, { children: N.auth.rememberMe }) })]
103
- }),
104
- Q && /* @__PURE__ */ x("div", {
105
- className: "flex justify-center",
106
- children: Q
107
- }),
108
- /* @__PURE__ */ S("div", {
109
- className: "flex flex-col gap-3",
110
- children: [/* @__PURE__ */ S(ee, {
111
- type: "submit",
112
- className: "w-full",
113
- isPending: Z || X,
114
- children: [Z && /* @__PURE__ */ x(ne, {
115
- color: "current",
116
- size: "sm"
117
- }), N.auth.signIn]
118
- }), P.flatMap((e) => e.authButtons?.map((t, n) => /* @__PURE__ */ x(t, { view: "signIn" }, `${e.id}-${n.toString()}`)))]
119
- })
120
- ]
121
- }),
122
- E === "bottom" && /* @__PURE__ */ S(b, { children: [$ && /* @__PURE__ */ x(e, { children: N.auth.or }), !!I?.length && /* @__PURE__ */ x(t, { socialLayout: T })] })
123
- ]
124
- }),
125
- /* @__PURE__ */ S(u.Footer, {
126
- className: "flex-col gap-3",
127
- children: [M?.forgotPassword && /* @__PURE__ */ x(g, {
128
- href: `${A.auth}/${L.auth.forgotPassword}`,
129
- className: "no-underline hover:underline",
130
- children: N.auth.forgotPasswordLink
131
- }), M?.enabled && /* @__PURE__ */ S(f, {
132
- className: "text-sm",
133
- children: [
134
- N.auth.needToCreateAnAccount,
135
- " ",
136
- /* @__PURE__ */ x(g, {
137
- href: `${A.auth}/${L.auth.signUp}`,
138
- className: "text-accent no-underline hover:underline decoration-accent-hover",
139
- children: N.auth.signUp
140
- })
141
- ]
142
- })]
143
- })
144
- ]
145
- });
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { authMutationKeys } from "@better-auth-ui/core";
3
+ import { useAuth, useAuthPlugin, useFetchOptions, useSendVerificationEmail, useSignInEmail, useSignInUsername } from "@better-auth-ui/react";
4
+ import { Button, Card, Checkbox, cn, Description, FieldError, Form, Input, Label, Link, Spinner, TextField, toast } from "@heroui/react";
5
+ import { useIsMutating } from "@tanstack/react-query";
6
+ import { useState } from "react";
7
+ import { usernamePlugin } from "../../../lib/auth/username-plugin";
8
+ import { FieldSeparator } from "../field-separator";
9
+ import { ProviderButtons } from "../provider-buttons";
10
+ /**
11
+ * Render the username-based sign-in UI.
12
+ *
13
+ * @returns The sign-in JSX element containing username/password fields, optional magic-link button, and social provider buttons.
14
+ */
15
+ export function SignInUsername({ className, socialLayout, socialPosition = "bottom", variant, ...props }) {
16
+ const { authClient, basePaths, baseURL, emailAndPassword, localization, plugins, redirectTo, socialProviders, viewPaths, navigate } = useAuth();
17
+ const { fetchOptions, resetFetchOptions } = useFetchOptions();
18
+ const { localization: usernameLocalization } = useAuthPlugin(usernamePlugin);
19
+ const [password, setPassword] = useState("");
20
+ const { mutate: sendVerificationEmail } = useSendVerificationEmail(authClient, {
21
+ onSuccess: () => toast.success(localization.auth.verificationEmailSent)
22
+ });
23
+ function isEmail(value) {
24
+ return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value);
25
+ }
26
+ const { mutate: signInEmail, isPending: isSignInEmailPending } = useSignInEmail(authClient, {
27
+ onError: (error, { email }) => {
28
+ setPassword("");
29
+ if (error.error?.code === "EMAIL_NOT_VERIFIED") {
30
+ toast.danger(error.error?.message || error.message, {
31
+ actionProps: {
32
+ children: localization.auth.resend,
33
+ onClick: () => sendVerificationEmail({
34
+ email,
35
+ callbackURL: `${baseURL}${redirectTo}`
36
+ })
37
+ }
38
+ });
39
+ }
40
+ else {
41
+ toast.danger(error.error?.message || error.message);
42
+ }
43
+ resetFetchOptions();
44
+ },
45
+ onSuccess: () => navigate({ to: redirectTo })
46
+ });
47
+ const { mutate: signInUsername, isPending: isSignInUsernamePending } = useSignInUsername(authClient, {
48
+ onError: (error) => {
49
+ setPassword("");
50
+ toast.danger(error.error?.message || error.message);
51
+ resetFetchOptions();
52
+ },
53
+ onSuccess: () => navigate({ to: redirectTo })
54
+ });
55
+ const handleSubmit = (e) => {
56
+ e.preventDefault();
57
+ const formData = new FormData(e.currentTarget);
58
+ const email = formData.get("email");
59
+ const rememberMe = formData.get("rememberMe") === "on";
60
+ if (isEmail(email)) {
61
+ signInEmail({
62
+ email,
63
+ password,
64
+ ...(emailAndPassword?.rememberMe ? { rememberMe } : {}),
65
+ fetchOptions
66
+ });
67
+ }
68
+ else {
69
+ signInUsername({
70
+ username: email,
71
+ password,
72
+ ...(emailAndPassword?.rememberMe ? { rememberMe } : {}),
73
+ fetchOptions
74
+ });
75
+ }
76
+ };
77
+ const signInMutating = useIsMutating({
78
+ mutationKey: authMutationKeys.signIn.all
79
+ });
80
+ const signUpMutating = useIsMutating({
81
+ mutationKey: authMutationKeys.signUp.all
82
+ });
83
+ const isPending = signInMutating + signUpMutating > 0;
84
+ const isSignInPending = isSignInEmailPending || isSignInUsernamePending;
85
+ const Captcha = plugins.find((plugin) => plugin.captchaComponent)?.captchaComponent;
86
+ const showSeparator = emailAndPassword?.enabled && !!socialProviders?.length;
87
+ return (_jsxs(Card, { className: cn("w-full max-w-sm gap-4 md:p-6", className), variant: variant, ...props, children: [_jsx(Card.Header, { children: _jsx(Card.Title, { className: "text-xl font-semibold mb-1", children: localization.auth.signIn }) }), _jsxs(Card.Content, { className: "gap-4", children: [socialPosition === "top" && (_jsxs(_Fragment, { children: [!!socialProviders?.length && (_jsx(ProviderButtons, { socialLayout: socialLayout })), showSeparator && (_jsx(FieldSeparator, { children: localization.auth.or }))] })), emailAndPassword?.enabled && (_jsxs(Form, { onSubmit: handleSubmit, className: "flex flex-col gap-4", children: [_jsxs(TextField, { name: "email", type: "text", autoComplete: "username email", isDisabled: isPending, children: [_jsx(Label, { children: usernameLocalization.username }), _jsx(Input, { placeholder: usernameLocalization.usernameOrEmailPlaceholder, variant: variant === "transparent" ? "primary" : "secondary", required: true }), _jsx(FieldError, {})] }), _jsxs(TextField, { minLength: emailAndPassword?.minPasswordLength, maxLength: emailAndPassword?.maxPasswordLength, name: "password", type: "password", autoComplete: "current-password", isDisabled: isPending, value: password, onChange: setPassword, children: [_jsx(Label, { children: localization.auth.password }), _jsx(Input, { placeholder: localization.auth.passwordPlaceholder, variant: variant === "transparent" ? "primary" : "secondary", required: true }), _jsx(FieldError, {})] }), emailAndPassword?.rememberMe && (_jsxs(Checkbox, { name: "rememberMe", isDisabled: isPending, variant: variant === "transparent" ? "primary" : "secondary", children: [_jsx(Checkbox.Control, { children: _jsx(Checkbox.Indicator, {}) }), _jsx(Checkbox.Content, { children: _jsx(Label, { children: localization.auth.rememberMe }) })] })), Captcha && _jsx("div", { className: "flex justify-center", children: Captcha }), _jsxs("div", { className: "flex flex-col gap-3", children: [_jsxs(Button, { type: "submit", className: "w-full", isPending: isSignInPending || isPending, children: [isSignInPending && _jsx(Spinner, { color: "current", size: "sm" }), localization.auth.signIn] }), plugins.flatMap((plugin) => plugin.authButtons?.map((AuthButton, index) => (_jsx(AuthButton, { view: "signIn" }, `${plugin.id}-${index.toString()}`))))] })] })), socialPosition === "bottom" && (_jsxs(_Fragment, { children: [showSeparator && (_jsx(FieldSeparator, { children: localization.auth.or })), !!socialProviders?.length && (_jsx(ProviderButtons, { socialLayout: socialLayout }))] }))] }), _jsxs(Card.Footer, { className: "flex-col gap-3", children: [emailAndPassword?.forgotPassword && (_jsx(Link, { href: `${basePaths.auth}/${viewPaths.auth.forgotPassword}`, className: "no-underline hover:underline", children: localization.auth.forgotPasswordLink })), emailAndPassword?.enabled && (_jsxs(Description, { className: "text-sm", children: [localization.auth.needToCreateAnAccount, " ", _jsx(Link, { href: `${basePaths.auth}/${viewPaths.auth.signUp}`, className: "text-accent no-underline hover:underline decoration-accent-hover", children: localization.auth.signUp })] }))] })] }));
146
88
  }
147
- //#endregion
148
- export { w as SignInUsername };
@@ -1,4 +1,4 @@
1
- import { AdditionalFieldProps } from '../additional-field';
1
+ import type { AdditionalFieldProps } from "../additional-field";
2
2
  /**
3
3
  * Renderer for the `username` additional field. Owns availability checking,
4
4
  * length limits, and visual indicators. `FieldError` automatically surfaces