@better-auth-ui/heroui 1.6.0 → 1.6.2

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 (221) hide show
  1. package/dist/components/auth/auth-provider.d.ts +1 -1
  2. package/dist/components/auth/auth-provider.js +15 -11
  3. package/dist/components/auth/auth.d.ts +3 -3
  4. package/dist/components/auth/auth.js +36 -41
  5. package/dist/components/auth/field-separator.d.ts +1 -1
  6. package/dist/components/auth/field-separator.js +17 -4
  7. package/dist/components/auth/forgot-password.d.ts +1 -1
  8. package/dist/components/auth/forgot-password.js +69 -27
  9. package/dist/components/auth/magic-link-button.d.ts +1 -1
  10. package/dist/components/auth/magic-link-button.js +15 -18
  11. package/dist/components/auth/magic-link.d.ts +2 -2
  12. package/dist/components/auth/magic-link.js +110 -42
  13. package/dist/components/auth/passkey-button.d.ts +4 -0
  14. package/dist/components/auth/passkey-button.js +24 -0
  15. package/dist/components/auth/provider-buttons.d.ts +1 -1
  16. package/dist/components/auth/provider-buttons.js +26 -33
  17. package/dist/components/auth/reset-password.d.ts +1 -1
  18. package/dist/components/auth/reset-password.js +146 -57
  19. package/dist/components/auth/sign-in.d.ts +2 -2
  20. package/dist/components/auth/sign-in.js +163 -63
  21. package/dist/components/auth/sign-out.js +26 -32
  22. package/dist/components/auth/sign-up.d.ts +2 -2
  23. package/dist/components/auth/sign-up.js +240 -70
  24. package/dist/components/email/email-changed-email.d.ts +2 -2
  25. package/dist/components/email/email-changed-email.js +29 -22
  26. package/dist/components/email/email-verification-email.d.ts +2 -2
  27. package/dist/components/email/email-verification-email.js +29 -22
  28. package/dist/components/email/magic-link-email.d.ts +2 -2
  29. package/dist/components/email/magic-link-email.js +29 -22
  30. package/dist/components/email/new-device-email.d.ts +2 -2
  31. package/dist/components/email/new-device-email.js +29 -22
  32. package/dist/components/email/otp-email.d.ts +2 -2
  33. package/dist/components/email/otp-email.js +28 -21
  34. package/dist/components/email/password-changed-email.d.ts +2 -2
  35. package/dist/components/email/password-changed-email.js +29 -22
  36. package/dist/components/email/reset-password-email.d.ts +2 -2
  37. package/dist/components/email/reset-password-email.js +29 -22
  38. package/dist/components/settings/account/account-settings.d.ts +2 -2
  39. package/dist/components/settings/account/account-settings.js +22 -19
  40. package/dist/components/settings/account/appearance.d.ts +1 -1
  41. package/dist/components/settings/account/appearance.js +70 -27
  42. package/dist/components/settings/account/change-avatar.js +88 -55
  43. package/dist/components/settings/account/change-email.d.ts +1 -1
  44. package/dist/components/settings/account/change-email.js +56 -28
  45. package/dist/components/settings/account/manage-account.d.ts +1 -1
  46. package/dist/components/settings/account/manage-account.js +50 -31
  47. package/dist/components/settings/account/manage-accounts.d.ts +1 -1
  48. package/dist/components/settings/account/manage-accounts.js +32 -36
  49. package/dist/components/settings/account/user-profile.d.ts +3 -3
  50. package/dist/components/settings/account/user-profile.js +105 -22
  51. package/dist/components/settings/security/active-session.d.ts +1 -1
  52. package/dist/components/settings/security/active-session.js +60 -51
  53. package/dist/components/settings/security/active-sessions.d.ts +1 -1
  54. package/dist/components/settings/security/active-sessions.js +32 -26
  55. package/dist/components/settings/security/change-password.d.ts +1 -1
  56. package/dist/components/settings/security/change-password.js +189 -76
  57. package/dist/components/settings/security/danger-zone.d.ts +2 -2
  58. package/dist/components/settings/security/danger-zone.js +17 -11
  59. package/dist/components/settings/security/delete-user.d.ts +1 -1
  60. package/dist/components/settings/security/delete-user.js +96 -46
  61. package/dist/components/settings/security/linked-account.d.ts +1 -1
  62. package/dist/components/settings/security/linked-account.js +61 -47
  63. package/dist/components/settings/security/linked-accounts.d.ts +1 -1
  64. package/dist/components/settings/security/linked-accounts.js +43 -40
  65. package/dist/components/settings/security/passkey.d.ts +8 -0
  66. package/dist/components/settings/security/passkey.js +43 -0
  67. package/dist/components/settings/security/passkeys.d.ts +6 -0
  68. package/dist/components/settings/security/passkeys.js +53 -0
  69. package/dist/components/settings/security/security-settings.d.ts +2 -2
  70. package/dist/components/settings/security/security-settings.js +24 -20
  71. package/dist/components/settings/settings.d.ts +3 -3
  72. package/dist/components/settings/settings.js +44 -27
  73. package/dist/components/user/switch-account-item.d.ts +1 -1
  74. package/dist/components/user/switch-account-item.js +19 -15
  75. package/dist/components/user/switch-account-menu.js +27 -28
  76. package/dist/components/user/user-avatar.d.ts +3 -3
  77. package/dist/components/user/user-avatar.js +28 -30
  78. package/dist/components/user/user-button.d.ts +1 -1
  79. package/dist/components/user/user-button.js +90 -23
  80. package/dist/components/user/user-view.d.ts +3 -3
  81. package/dist/components/user/user-view.js +36 -23
  82. package/dist/core.d.ts +1 -1
  83. package/dist/index.d.ts +35 -33
  84. package/dist/index.js +36 -33
  85. package/dist/react-exports.d.ts +1 -1
  86. package/package.json +17 -10
  87. package/src/components/auth/auth.tsx +1 -1
  88. package/src/components/auth/magic-link.tsx +4 -0
  89. package/src/components/auth/passkey-button.tsx +36 -0
  90. package/src/components/auth/sign-in.tsx +67 -30
  91. package/src/components/auth/sign-up.tsx +97 -3
  92. package/src/components/settings/account/user-profile.tsx +121 -6
  93. package/src/components/settings/security/passkey.tsx +51 -0
  94. package/src/components/settings/security/passkeys.tsx +104 -0
  95. package/src/components/settings/security/security-settings.tsx +3 -1
  96. package/src/components/settings/settings.tsx +1 -1
  97. package/src/index.tsx +2 -0
  98. package/dist/components/account/account.d.ts +0 -18
  99. package/dist/components/account/account.js +0 -24
  100. package/dist/components/account/settings/account-settings.d.ts +0 -5
  101. package/dist/components/account/settings/account-settings.js +0 -6
  102. package/dist/components/account/settings/settings.d.ts +0 -5
  103. package/dist/components/account/settings/settings.js +0 -5
  104. package/dist/components/account/settings/user-profile.d.ts +0 -5
  105. package/dist/components/account/settings/user-profile.js +0 -20
  106. package/dist/components/settings/account/accounts.d.ts +0 -14
  107. package/dist/components/settings/account/accounts.js +0 -26
  108. package/dist/components/settings/account/theme-selector.d.ts +0 -16
  109. package/dist/components/settings/account/theme-selector.js +0 -33
  110. package/dist/components/settings/account/theme-settings.d.ts +0 -16
  111. package/dist/components/settings/account/theme-settings.js +0 -31
  112. package/dist/components/settings/account-settings.d.ts +0 -5
  113. package/dist/components/settings/account-settings.js +0 -6
  114. package/dist/components/settings/account.d.ts +0 -18
  115. package/dist/components/settings/account.js +0 -24
  116. package/dist/components/settings/security/connected-account.d.ts +0 -16
  117. package/dist/components/settings/security/connected-account.js +0 -46
  118. package/dist/components/settings/security/connected-accounts.d.ts +0 -15
  119. package/dist/components/settings/security/connected-accounts.js +0 -31
  120. package/dist/components/settings/security/sessions.d.ts +0 -14
  121. package/dist/components/settings/security/sessions.js +0 -40
  122. package/dist/components/settings/settings/account-settings.d.ts +0 -5
  123. package/dist/components/settings/settings/account-settings.js +0 -6
  124. package/dist/components/settings/settings/user-profile.d.ts +0 -5
  125. package/dist/components/settings/settings/user-profile.js +0 -20
  126. package/dist/components/settings/user-profile.d.ts +0 -5
  127. package/dist/components/settings/user-profile.js +0 -20
  128. package/dist/components/user/switch-account-popover.d.ts +0 -10
  129. package/dist/components/user/switch-account-popover.js +0 -25
  130. package/dist/components/user/switch-account-submenu.d.ts +0 -10
  131. package/dist/components/user/switch-account-submenu.js +0 -25
  132. package/dist/hooks/use-auth.d.ts +0 -2
  133. package/dist/hooks/use-auth.js +0 -8
  134. package/dist/hooks/use-redirect-to.d.ts +0 -8
  135. package/dist/hooks/use-redirect-to.js +0 -19
  136. package/dist/hooks/use-sign-in.d.ts +0 -8
  137. package/dist/hooks/use-sign-in.js +0 -53
  138. package/dist/lib/utils.d.ts +0 -2
  139. package/dist/lib/utils.js +0 -5
  140. package/dist/server.d.ts +0 -1
  141. package/dist/server.js +0 -1
  142. package/dist/src/components/auth/auth-provider.d.ts +0 -8
  143. package/dist/src/components/auth/auth-provider.js +0 -13
  144. package/dist/src/components/auth/auth.d.ts +0 -22
  145. package/dist/src/components/auth/auth.js +0 -42
  146. package/dist/src/components/auth/field-separator.d.ts +0 -4
  147. package/dist/src/components/auth/field-separator.js +0 -5
  148. package/dist/src/components/auth/forgot-password.d.ts +0 -15
  149. package/dist/src/components/auth/forgot-password.js +0 -29
  150. package/dist/src/components/auth/magic-link-button.d.ts +0 -13
  151. package/dist/src/components/auth/magic-link-button.js +0 -20
  152. package/dist/src/components/auth/magic-link.d.ts +0 -17
  153. package/dist/src/components/auth/magic-link.js +0 -37
  154. package/dist/src/components/auth/provider-buttons.d.ts +0 -19
  155. package/dist/src/components/auth/provider-buttons.js +0 -35
  156. package/dist/src/components/auth/reset-password.d.ts +0 -11
  157. package/dist/src/components/auth/reset-password.js +0 -59
  158. package/dist/src/components/auth/sign-in.d.ts +0 -14
  159. package/dist/src/components/auth/sign-in.js +0 -58
  160. package/dist/src/components/auth/sign-out.d.ts +0 -11
  161. package/dist/src/components/auth/sign-out.js +0 -34
  162. package/dist/src/components/auth/sign-up.d.ts +0 -19
  163. package/dist/src/components/auth/sign-up.js +0 -65
  164. package/dist/src/components/email/email-changed-email.d.ts +0 -3
  165. package/dist/src/components/email/email-changed-email.js +0 -23
  166. package/dist/src/components/email/email-verification-email.d.ts +0 -3
  167. package/dist/src/components/email/email-verification-email.js +0 -23
  168. package/dist/src/components/email/magic-link-email.d.ts +0 -3
  169. package/dist/src/components/email/magic-link-email.js +0 -23
  170. package/dist/src/components/email/new-device-email.d.ts +0 -3
  171. package/dist/src/components/email/new-device-email.js +0 -23
  172. package/dist/src/components/email/otp-email.d.ts +0 -3
  173. package/dist/src/components/email/otp-email.js +0 -22
  174. package/dist/src/components/email/password-changed-email.d.ts +0 -3
  175. package/dist/src/components/email/password-changed-email.js +0 -23
  176. package/dist/src/components/email/reset-password-email.d.ts +0 -3
  177. package/dist/src/components/email/reset-password-email.js +0 -23
  178. package/dist/src/components/settings/account/account-settings.d.ts +0 -13
  179. package/dist/src/components/settings/account/account-settings.js +0 -19
  180. package/dist/src/components/settings/account/appearance.d.ts +0 -16
  181. package/dist/src/components/settings/account/appearance.js +0 -28
  182. package/dist/src/components/settings/account/change-email.d.ts +0 -15
  183. package/dist/src/components/settings/account/change-email.js +0 -35
  184. package/dist/src/components/settings/account/manage-account.d.ts +0 -19
  185. package/dist/src/components/settings/account/manage-account.js +0 -27
  186. package/dist/src/components/settings/account/manage-accounts.d.ts +0 -14
  187. package/dist/src/components/settings/account/manage-accounts.js +0 -27
  188. package/dist/src/components/settings/account/user-profile.d.ts +0 -13
  189. package/dist/src/components/settings/account/user-profile.js +0 -29
  190. package/dist/src/components/settings/security/active-session.d.ts +0 -14
  191. package/dist/src/components/settings/security/active-session.js +0 -35
  192. package/dist/src/components/settings/security/active-sessions.d.ts +0 -14
  193. package/dist/src/components/settings/security/active-sessions.js +0 -29
  194. package/dist/src/components/settings/security/change-password.d.ts +0 -15
  195. package/dist/src/components/settings/security/change-password.js +0 -57
  196. package/dist/src/components/settings/security/linked-account.d.ts +0 -16
  197. package/dist/src/components/settings/security/linked-account.js +0 -46
  198. package/dist/src/components/settings/security/linked-accounts.d.ts +0 -15
  199. package/dist/src/components/settings/security/linked-accounts.js +0 -31
  200. package/dist/src/components/settings/security/security-settings.d.ts +0 -15
  201. package/dist/src/components/settings/security/security-settings.js +0 -18
  202. package/dist/src/components/settings/settings.d.ts +0 -29
  203. package/dist/src/components/settings/settings.js +0 -39
  204. package/dist/src/components/user/switch-account-item.d.ts +0 -16
  205. package/dist/src/components/user/switch-account-item.js +0 -14
  206. package/dist/src/components/user/switch-account-menu.d.ts +0 -10
  207. package/dist/src/components/user/switch-account-menu.js +0 -23
  208. package/dist/src/components/user/user-avatar.d.ts +0 -24
  209. package/dist/src/components/user/user-avatar.js +0 -31
  210. package/dist/src/components/user/user-button.d.ts +0 -21
  211. package/dist/src/components/user/user-button.js +0 -24
  212. package/dist/src/components/user/user-view.d.ts +0 -21
  213. package/dist/src/components/user/user-view.js +0 -24
  214. package/dist/src/core.d.ts +0 -1
  215. package/dist/src/core.js +0 -1
  216. package/dist/src/index.d.ts +0 -31
  217. package/dist/src/index.js +0 -32
  218. package/dist/src/lib/utils.d.ts +0 -2
  219. package/dist/src/lib/utils.js +0 -5
  220. package/dist/src/react-exports.d.ts +0 -1
  221. package/dist/src/react-exports.js +0 -1
@@ -1,27 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useAuth, useListDeviceSessions, useSession } from "@better-auth-ui/react";
3
- import { CirclePlus } from "@gravity-ui/icons";
4
- import { buttonVariants, Card, cn, Link, toast } from "@heroui/react";
5
- import { ManageAccount } from "./manage-account";
6
- /**
7
- * Render a card that lists and manages all device sessions for the current user.
8
- *
9
- * Shows each session with user information and actions to switch to or revoke a session.
10
- * When device session data is loading, a pending placeholder row is displayed.
11
- *
12
- * @returns A JSX element containing the accounts management card
13
- */
14
- export function ManageAccounts({ className, ...props }) {
15
- const { basePaths, localization, viewPaths } = useAuth();
16
- const { data: sessionData } = useSession();
17
- const { data: deviceSessions, isPending } = useListDeviceSessions({
18
- throwOnError: (error) => {
19
- if (error.error)
20
- toast.danger(error.error.message);
21
- return false;
22
- }
23
- });
24
- return (_jsxs(Card, { className: cn("p-4 md:p-6 gap-4", className), ...props, children: [_jsx(Card.Header, { children: _jsx(Card.Title, { className: "text-xl", children: localization.settings.manageAccounts }) }), _jsxs(Card.Content, { className: "gap-3", children: [_jsx(ManageAccount, { isPending: isPending, deviceSession: !isPending ? sessionData : null }), deviceSessions
25
- ?.filter((deviceSession) => deviceSession.session.id !== sessionData?.session.id)
26
- .map((deviceSession) => (_jsx(ManageAccount, { deviceSession: deviceSession }, deviceSession.session.id)))] }), _jsx(Card.Footer, { children: _jsxs(Link, { href: `${basePaths.auth}/${viewPaths.auth.signIn}`, className: cn("gap-2", buttonVariants({ variant: "secondary" })), children: [_jsx(CirclePlus, {}), localization.auth.addAccount] }) })] }));
27
- }
@@ -1,13 +0,0 @@
1
- import { type CardProps } from "@heroui/react";
2
- export type UserProfileProps = {
3
- className?: string;
4
- variant?: CardProps["variant"];
5
- };
6
- /**
7
- * Render a profile card that lets the authenticated user view and update their display name.
8
- *
9
- * The component uses auth localization for labels, reflects session loading state with skeletons, shows the best-available user identifier (display username, name, or email), and wires the form submission to the user update action from auth hooks.
10
- *
11
- * @returns A JSX element containing the user profile card and an editable name form
12
- */
13
- export declare function UserProfile({ className, variant, ...props }: UserProfileProps & CardProps): import("react/jsx-runtime").JSX.Element;
@@ -1,29 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useAuth, useSession, useUpdateUser } from "@better-auth-ui/react";
3
- import { FloppyDisk, Pencil } from "@gravity-ui/icons";
4
- import { Button, Card, cn, FieldError, Fieldset, Form, Input, Label, Skeleton, Spinner, TextField, toast } from "@heroui/react";
5
- import { UserAvatar } from "../../user/user-avatar";
6
- /**
7
- * Render a profile card that lets the authenticated user view and update their display name.
8
- *
9
- * The component uses auth localization for labels, reflects session loading state with skeletons, shows the best-available user identifier (display username, name, or email), and wires the form submission to the user update action from auth hooks.
10
- *
11
- * @returns A JSX element containing the user profile card and an editable name form
12
- */
13
- export function UserProfile({ className, variant, ...props }) {
14
- const { localization } = useAuth();
15
- const { data: sessionData } = useSession();
16
- const { mutate: updateUser, isPending } = useUpdateUser({
17
- onError: (error) => toast.danger(error.error?.message || error.message),
18
- onSuccess: () => toast.success(localization.settings.profileUpdatedSuccess)
19
- });
20
- function handleSubmit(e) {
21
- e.preventDefault();
22
- const formData = new FormData(e.currentTarget);
23
- updateUser({ name: formData.get("name") });
24
- }
25
- return (_jsxs(Card, { className: cn("p-4 md:p-6 gap-4", className), variant: variant, ...props, children: [_jsx(Card.Header, { children: _jsx(Card.Title, { className: "text-xl", children: localization.settings.profile }) }), _jsx(Card.Content, { children: _jsx(Form, { onSubmit: handleSubmit, children: _jsxs(Fieldset, { className: "w-full gap-4", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsxs(Button, { type: "button", isIconOnly: true, variant: "ghost", className: "p-0 h-auto w-auto rounded-full", isDisabled: !sessionData, children: [_jsx(UserAvatar, { size: "lg" }), _jsx("span", { className: "absolute right-0 bottom-0 size-4 rounded-full bg-background ring ring-2 ring-border flex items-center justify-center", children: _jsx(Pencil, { className: "size-2.5 text-muted" }) })] }), sessionData ? (_jsxs("div", { className: "flex flex-col", children: [_jsx("p", { className: "text-sm font-medium leading-tight", children: sessionData?.user?.displayUsername ||
26
- sessionData?.user?.name ||
27
- sessionData?.user?.email }), (sessionData?.user?.displayUsername ||
28
- sessionData?.user?.name) && (_jsx("p", { className: "text-muted text-xs", children: sessionData?.user?.email }))] })) : (_jsxs("div", { className: "flex flex-col gap-1", children: [_jsx(Skeleton, { className: "h-3.5 w-24 rounded-lg" }), _jsx(Skeleton, { className: "h-3 w-32 rounded-lg" })] }))] }), _jsx(Fieldset.Group, { children: _jsxs(TextField, { name: "name", defaultValue: sessionData?.user?.name, isDisabled: isPending || !sessionData, children: [_jsx(Label, { children: localization.auth.name }), sessionData ? (_jsx(Input, { autoComplete: "name", placeholder: localization.auth.name, variant: variant === "transparent" ? "primary" : "secondary" })) : (_jsx(Skeleton, { className: "h-10 md:h-9 w-full rounded-xl" })), _jsx(FieldError, {})] }, sessionData?.user?.name) }), _jsx(Fieldset.Actions, { children: _jsxs(Button, { type: "submit", isPending: isPending, isDisabled: !sessionData, children: [isPending ? (_jsx(Spinner, { color: "current", size: "sm" })) : (_jsx(FloppyDisk, {})), localization.settings.saveChanges] }) })] }) }) })] }));
29
- }
@@ -1,14 +0,0 @@
1
- import type { Session } from "better-auth";
2
- export type ActiveSessionProps = {
3
- session: Session;
4
- };
5
- /**
6
- * Render a single active session card with device info and revoke control.
7
- *
8
- * Shows the session's browser, OS, IP address, and creation time. The current session is marked
9
- * and navigates to sign-out on click, while other sessions can be revoked individually.
10
- *
11
- * @param session - The session object containing id, token, userAgent, ipAddress, and createdAt
12
- * @returns A JSX element containing the active session card
13
- */
14
- export declare function ActiveSession({ session }: ActiveSessionProps): import("react/jsx-runtime").JSX.Element;
@@ -1,35 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { useAuth, useRevokeSession, useSession } from "@better-auth-ui/react";
3
- import { ArrowRightFromSquare, Display, Smartphone } from "@gravity-ui/icons";
4
- import { Button, Card, Chip, Spinner, toast } from "@heroui/react";
5
- import { UAParser } from "ua-parser-js";
6
- /**
7
- * Render a single active session card with device info and revoke control.
8
- *
9
- * Shows the session's browser, OS, IP address, and creation time. The current session is marked
10
- * and navigates to sign-out on click, while other sessions can be revoked individually.
11
- *
12
- * @param session - The session object containing id, token, userAgent, ipAddress, and createdAt
13
- * @returns A JSX element containing the active session card
14
- */
15
- export function ActiveSession({ session }) {
16
- const { basePaths, localization, viewPaths, navigate } = useAuth();
17
- const { data: sessionData } = useSession();
18
- const { mutate: revokeSession, isPending: isRevoking } = useRevokeSession({
19
- onError: (error) => toast.danger(error.error?.message || error.message),
20
- onSuccess: () => toast.success(localization.settings.revokeSessionSuccess)
21
- });
22
- const isCurrentSession = session.token === sessionData?.session.token;
23
- const ua = new UAParser(session.userAgent || "").getResult();
24
- const isMobile = ua.device.type === "mobile" ||
25
- ua.device.type === "tablet" ||
26
- ua.device.type === "wearable";
27
- return (_jsxs(Card, { className: "flex-row border items-center p-3 shadow-none", children: [_jsx("div", { className: "flex size-10 items-center justify-center rounded-xl bg-surface-secondary", children: isMobile ? (_jsx(Smartphone, { className: "size-5" })) : (_jsx(Display, { className: "size-5" })) }), _jsxs("div", { className: "flex flex-col", children: [_jsxs("div", { className: "flex items-center gap-1.5", children: [_jsxs("span", { className: "text-sm font-medium truncate", children: [ua.browser.name || "Unknown Browser", ua.os.name ? `, ${ua.os.name}` : ""] }), isCurrentSession && (_jsx(Chip, { color: "accent", size: "sm", className: "px-1.5", children: localization.settings.currentSession }))] }), _jsxs("div", { className: "flex items-center gap-1.5 text-xs text-muted", children: [session.ipAddress && _jsx("span", { children: session.ipAddress }), session.createdAt && (_jsxs(_Fragment, { children: [session.ipAddress && _jsx("span", { children: "\u2022" }), _jsx("span", { children: session.createdAt.toLocaleString([], {
28
- dateStyle: "short",
29
- timeStyle: "short"
30
- }) })] }))] })] }), _jsx(Button, { isIconOnly: true, className: "ml-auto", variant: "ghost", size: "sm", onPress: () => isCurrentSession
31
- ? navigate({
32
- to: `${basePaths.auth}/${viewPaths.auth.signOut}`
33
- })
34
- : revokeSession({ token: session.token }), isPending: isRevoking, "aria-label": localization.settings.revokeSession, children: isRevoking ? (_jsx(Spinner, { color: "current", size: "sm" })) : (_jsx(ArrowRightFromSquare, {})) })] }));
35
- }
@@ -1,14 +0,0 @@
1
- import { type CardProps } from "@heroui/react";
2
- export type ActiveSessionsProps = {
3
- className?: string;
4
- variant?: CardProps["variant"];
5
- };
6
- /**
7
- * Render a card listing all active sessions for the current user with revoke controls.
8
- *
9
- * Shows each session's browser, OS, IP address, and creation time. The current session is marked
10
- * and navigates to sign-out on click, while other sessions can be revoked individually.
11
- *
12
- * @returns A JSX element containing the sessions card
13
- */
14
- export declare function ActiveSessions({ className, ...props }: ActiveSessionsProps & CardProps): import("react/jsx-runtime").JSX.Element;
@@ -1,29 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useAuth, useListSessions, useSession } from "@better-auth-ui/react";
3
- import { Card, cn, Skeleton, toast } from "@heroui/react";
4
- import { ActiveSession } from "./active-session";
5
- /**
6
- * Render a card listing all active sessions for the current user with revoke controls.
7
- *
8
- * Shows each session's browser, OS, IP address, and creation time. The current session is marked
9
- * and navigates to sign-out on click, while other sessions can be revoked individually.
10
- *
11
- * @returns A JSX element containing the sessions card
12
- */
13
- export function ActiveSessions({ className, ...props }) {
14
- const { localization } = useAuth();
15
- const { data: sessionData } = useSession();
16
- const { data: sessions, isPending } = useListSessions({
17
- throwOnError: (error) => {
18
- if (error.error)
19
- toast.danger(error.error.message);
20
- return false;
21
- }
22
- });
23
- return (_jsxs(Card, { className: cn("p-4 md:p-6 gap-4", className), ...props, children: [_jsx(Card.Header, { children: _jsx(Card.Title, { className: "text-xl", children: localization.settings.activeSessions }) }), _jsx(Card.Content, { className: "gap-3", children: isPending ? (_jsx(SessionRowSkeleton, {})) : (sessions
24
- ?.toSorted((session) => session.id === sessionData?.session.id ? -1 : 1)
25
- .map((session) => (_jsx(ActiveSession, { session: session }, session.id)))) })] }));
26
- }
27
- function SessionRowSkeleton() {
28
- return (_jsx("div", { className: "flex items-center rounded-3xl border p-3 justify-between", children: _jsxs("div", { className: "flex items-center gap-3", children: [_jsx(Skeleton, { className: "size-10 rounded-xl" }), _jsxs("div", { className: "flex flex-col gap-1", children: [_jsx(Skeleton, { className: "h-4 w-32 rounded-lg" }), _jsx(Skeleton, { className: "h-3 w-24 rounded-lg" })] })] }) }));
29
- }
@@ -1,15 +0,0 @@
1
- import { type CardProps } from "@heroui/react";
2
- export type ChangePasswordProps = {
3
- className?: string;
4
- variant?: CardProps["variant"];
5
- };
6
- /**
7
- * Render a card form for changing the authenticated user's password.
8
- *
9
- * Displays a card with fields for current password, new password, and optionally
10
- * confirm password (based on `emailAndPassword.confirmPassword`). All other sessions
11
- * are revoked upon successful password change.
12
- *
13
- * @returns A JSX element containing the change-password card and form
14
- */
15
- export declare function ChangePassword({ className, variant, ...props }: ChangePasswordProps & CardProps): import("react/jsx-runtime").JSX.Element;
@@ -1,57 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useAuth, useChangePassword, useSession } from "@better-auth-ui/react";
3
- import { Check, Eye, EyeSlash } from "@gravity-ui/icons";
4
- import { Button, Card, cn, FieldError, Fieldset, Form, Input, InputGroup, Label, Skeleton, Spinner, TextField, toast } from "@heroui/react";
5
- import { useState } from "react";
6
- /**
7
- * Render a card form for changing the authenticated user's password.
8
- *
9
- * Displays a card with fields for current password, new password, and optionally
10
- * confirm password (based on `emailAndPassword.confirmPassword`). All other sessions
11
- * are revoked upon successful password change.
12
- *
13
- * @returns A JSX element containing the change-password card and form
14
- */
15
- export function ChangePassword({ className, variant, ...props }) {
16
- const { emailAndPassword, localization } = useAuth();
17
- const { data: sessionData } = useSession();
18
- const [currentPassword, setCurrentPassword] = useState("");
19
- const [newPassword, setNewPassword] = useState("");
20
- const [confirmPassword, setConfirmPassword] = useState("");
21
- const { mutate: changePassword, isPending } = useChangePassword({
22
- onError: (error) => {
23
- setCurrentPassword("");
24
- setNewPassword("");
25
- setConfirmPassword("");
26
- toast.danger(error.error?.message || error.message);
27
- },
28
- onSuccess: () => {
29
- setCurrentPassword("");
30
- setNewPassword("");
31
- setConfirmPassword("");
32
- toast.success(localization.settings.changePasswordSuccess);
33
- }
34
- });
35
- const [isNewPasswordVisible, setIsNewPasswordVisible] = useState(false);
36
- const [isConfirmPasswordVisible, setIsConfirmPasswordVisible] = useState(false);
37
- const handleSubmit = (e) => {
38
- e.preventDefault();
39
- if (emailAndPassword?.confirmPassword && newPassword !== confirmPassword) {
40
- setCurrentPassword("");
41
- setNewPassword("");
42
- setConfirmPassword("");
43
- toast.danger(localization.auth.passwordsDoNotMatch);
44
- return;
45
- }
46
- changePassword({
47
- currentPassword,
48
- newPassword,
49
- revokeOtherSessions: true
50
- });
51
- };
52
- return (_jsxs(Card, { className: cn("p-4 md:p-6 gap-4", className), variant: variant, ...props, children: [_jsx(Card.Header, { children: _jsx(Card.Title, { className: "text-xl", children: localization.settings.changePassword }) }), _jsx(Card.Content, { children: _jsx(Form, { onSubmit: handleSubmit, children: _jsxs(Fieldset, { className: "w-full gap-4", children: [_jsxs(Fieldset.Group, { children: [_jsxs(TextField, { name: "currentPassword", type: "password", isDisabled: isPending || !sessionData, value: currentPassword, onChange: setCurrentPassword, children: [_jsx(Label, { children: localization.settings.currentPassword }), sessionData ? (_jsx(Input, { autoComplete: "current-password", placeholder: localization.settings.currentPasswordPlaceholder, required: true, variant: variant === "transparent" ? "primary" : "secondary" })) : (_jsx(Skeleton, { className: "h-10 md:h-9 w-full rounded-xl" })), _jsx(FieldError, {})] }), _jsxs(TextField, { minLength: emailAndPassword?.minPasswordLength, maxLength: emailAndPassword?.maxPasswordLength, isDisabled: isPending || !sessionData, value: newPassword, onChange: setNewPassword, children: [_jsx(Label, { children: localization.auth.newPassword }), sessionData ? (_jsxs(InputGroup, { variant: variant === "transparent" ? "primary" : "secondary", children: [_jsx(InputGroup.Input, { name: "newPassword", type: isNewPasswordVisible ? "text" : "password", autoComplete: "new-password", placeholder: localization.auth.newPasswordPlaceholder, required: true }), _jsx(InputGroup.Suffix, { className: "px-0", children: _jsx(Button, { isIconOnly: true, "aria-label": isNewPasswordVisible
53
- ? localization.auth.hidePassword
54
- : localization.auth.showPassword, size: "sm", variant: "ghost", onPress: () => setIsNewPasswordVisible(!isNewPasswordVisible), isDisabled: isPending, children: isNewPasswordVisible ? _jsx(EyeSlash, {}) : _jsx(Eye, {}) }) })] })) : (_jsx(Skeleton, { className: "h-10 md:h-9 w-full rounded-xl" })), _jsx(FieldError, {})] }), emailAndPassword?.confirmPassword && (_jsxs(TextField, { minLength: emailAndPassword?.minPasswordLength, maxLength: emailAndPassword?.maxPasswordLength, isDisabled: isPending || !sessionData, isRequired: true, value: confirmPassword, onChange: setConfirmPassword, children: [_jsx(Label, { children: localization.auth.confirmPassword }), sessionData ? (_jsxs(InputGroup, { variant: variant === "transparent" ? "primary" : "secondary", children: [_jsx(InputGroup.Input, { name: "confirmPassword", type: isConfirmPasswordVisible ? "text" : "password", autoComplete: "new-password", placeholder: localization.auth.confirmPasswordPlaceholder, required: true }), _jsx(InputGroup.Suffix, { className: "px-0", children: _jsx(Button, { isIconOnly: true, "aria-label": isConfirmPasswordVisible
55
- ? localization.auth.hidePassword
56
- : localization.auth.showPassword, size: "sm", variant: "ghost", onPress: () => setIsConfirmPasswordVisible(!isConfirmPasswordVisible), isDisabled: isPending, children: isConfirmPasswordVisible ? _jsx(EyeSlash, {}) : _jsx(Eye, {}) }) })] })) : (_jsx(Skeleton, { className: "h-10 md:h-9 w-full rounded-xl" })), _jsx(FieldError, {})] }))] }), _jsx(Fieldset.Actions, { children: _jsxs(Button, { type: "submit", isPending: isPending, isDisabled: !sessionData, children: [isPending ? _jsx(Spinner, { color: "current", size: "sm" }) : _jsx(Check, {}), localization.settings.updatePassword] }) })] }) }) })] }));
57
- }
@@ -1,16 +0,0 @@
1
- import type { Account, SocialProvider } from "better-auth";
2
- export type LinkedAccountProps = {
3
- account?: Account;
4
- provider: SocialProvider;
5
- };
6
- /**
7
- * Render a single linked social account card with provider info and unlink control.
8
- *
9
- * Fetches additional account information from the provider using the accountInfo API
10
- * and displays the provider name, account details, and an unlink button.
11
- *
12
- * @param account - The account object containing id, accountId, and providerId
13
- * @param provider - The provider id
14
- * @returns A JSX element containing the linked account card
15
- */
16
- export declare function LinkedAccount({ account, provider }: LinkedAccountProps): import("react/jsx-runtime").JSX.Element;
@@ -1,46 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { getProviderName } from "@better-auth-ui/core";
3
- import { providerIcons, useAccountInfo, useAuth, useLinkSocial, useUnlinkAccount } from "@better-auth-ui/react";
4
- import { Link, PlugConnection, Xmark } from "@gravity-ui/icons";
5
- import { Button, Card, cn, Skeleton, Spinner, toast } from "@heroui/react";
6
- /**
7
- * Render a single linked social account card with provider info and unlink control.
8
- *
9
- * Fetches additional account information from the provider using the accountInfo API
10
- * and displays the provider name, account details, and an unlink button.
11
- *
12
- * @param account - The account object containing id, accountId, and providerId
13
- * @param provider - The provider id
14
- * @returns A JSX element containing the linked account card
15
- */
16
- export function LinkedAccount({ account, provider }) {
17
- const { baseURL, localization } = useAuth();
18
- const { data: accountInfo, isPending: isLoadingInfo } = useAccountInfo(account?.accountId, {
19
- enabled: !!account,
20
- throwOnError: (error) => {
21
- if (error.error)
22
- toast.danger(error.error.message);
23
- return false;
24
- }
25
- });
26
- const { mutate: linkSocial, isPending: isLinking } = useLinkSocial({
27
- onError: (error) => toast.danger(error.error?.message || error.message)
28
- });
29
- const { mutate: unlinkAccount, isPending: isUnlinking } = useUnlinkAccount({
30
- onError: (error) => toast.danger(error.error?.message || error.message),
31
- onSuccess: () => toast.success(localization.settings.accountUnlinked)
32
- });
33
- const ProviderIcon = providerIcons[provider];
34
- const providerName = getProviderName(provider);
35
- const displayName = accountInfo?.data?.login ||
36
- accountInfo?.data?.username ||
37
- accountInfo?.user?.email ||
38
- accountInfo?.user?.name ||
39
- account?.accountId;
40
- return (_jsxs(Card, { className: cn("flex-row items-center border p-3 shadow-none", !account && "border-dashed"), children: [_jsx("div", { className: "flex size-10 items-center justify-center rounded-xl bg-surface-secondary", children: ProviderIcon ? (_jsx(ProviderIcon, { className: cn("size-5", !account && "opacity-50") })) : (_jsx(PlugConnection, { className: cn("size-5", !account && "opacity-50") })) }), _jsxs("div", { className: "flex flex-col", children: [_jsx("span", { className: "text-sm font-medium leading-tight", children: providerName }), account && isLoadingInfo ? (_jsx(Skeleton, { className: "h-3 w-24 my-0.5 rounded-lg" })) : (_jsx("span", { className: "text-xs text-muted", children: account
41
- ? displayName
42
- : localization.settings.linkProvider.replace("{{provider}}", providerName) }))] }), account ? (_jsx(Button, { className: "ml-auto", isIconOnly: true, variant: "ghost", size: "sm", onPress: () => unlinkAccount({ providerId: account.providerId }), isPending: isUnlinking, "aria-label": localization.settings.unlinkProvider.replace("{{provider}}", providerName), children: isUnlinking ? _jsx(Spinner, { color: "current", size: "sm" }) : _jsx(Xmark, {}) })) : (_jsxs(Button, { className: "ml-auto", variant: "secondary", size: "sm", onPress: () => linkSocial({
43
- provider,
44
- callbackURL: `${baseURL}${window.location.pathname}`
45
- }), isPending: isLinking, "aria-label": localization.settings.linkProvider.replace("{{provider}}", providerName), children: [isLinking ? _jsx(Spinner, { color: "current", size: "sm" }) : _jsx(Link, {}), localization.settings.link] }))] }));
46
- }
@@ -1,15 +0,0 @@
1
- import { type CardProps } from "@heroui/react";
2
- export type LinkedAccountsProps = {
3
- className?: string;
4
- variant?: CardProps["variant"];
5
- };
6
- /**
7
- * Render a card showing linked social accounts and available social providers to link.
8
- *
9
- * Linked accounts (excluding the "credential" provider) are shown with an unlink control;
10
- * available providers are shown with a link control. Button states and labels reflect
11
- * ongoing link/unlink activity and use localization for provider-specific text.
12
- *
13
- * @returns A JSX element containing the linked accounts card
14
- */
15
- export declare function LinkedAccounts({ className, ...props }: LinkedAccountsProps & CardProps): import("react/jsx-runtime").JSX.Element;
@@ -1,31 +0,0 @@
1
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useAuth, useListAccounts } from "@better-auth-ui/react";
3
- import { Card, cn, Skeleton, toast } from "@heroui/react";
4
- import { LinkedAccount } from "./linked-account";
5
- /**
6
- * Render a card showing linked social accounts and available social providers to link.
7
- *
8
- * Linked accounts (excluding the "credential" provider) are shown with an unlink control;
9
- * available providers are shown with a link control. Button states and labels reflect
10
- * ongoing link/unlink activity and use localization for provider-specific text.
11
- *
12
- * @returns A JSX element containing the linked accounts card
13
- */
14
- export function LinkedAccounts({ className, ...props }) {
15
- const { localization, socialProviders } = useAuth();
16
- const { data: accounts, isPending } = useListAccounts({
17
- throwOnError: (error) => {
18
- if (error.error)
19
- toast.danger(error.error.message);
20
- return false;
21
- }
22
- });
23
- return (_jsxs(Card, { className: cn("p-4 md:p-6 gap-4", className), ...props, children: [_jsx(Card.Header, { children: _jsx(Card.Title, { className: "text-xl", children: localization.settings.linkedAccounts }) }), _jsx(Card.Content, { className: "gap-3", children: isPending ? (_jsx(AccountRowSkeleton, {})) : (_jsxs(_Fragment, { children: [accounts
24
- ?.filter((account) => account.providerId !== "credential")
25
- .map((account) => (_jsx(LinkedAccount, { account: account, provider: account.providerId }, account.id))), socialProviders?.map((provider) => {
26
- return _jsx(LinkedAccount, { provider: provider }, provider);
27
- })] })) })] }));
28
- }
29
- function AccountRowSkeleton() {
30
- return (_jsx("div", { className: "flex items-center rounded-3xl border p-3 justify-between", children: _jsxs("div", { className: "flex items-center gap-3", children: [_jsx(Skeleton, { className: "size-10 rounded-xl" }), _jsxs("div", { className: "flex flex-col gap-1", children: [_jsx(Skeleton, { className: "h-4 w-20 rounded-lg" }), _jsx(Skeleton, { className: "h-3 w-32 rounded-lg" })] })] }) }));
31
- }
@@ -1,15 +0,0 @@
1
- import type { CardProps } from "@heroui/react";
2
- import type { ComponentProps } from "react";
3
- export type SecuritySettingsProps = {
4
- className?: string;
5
- variant?: CardProps["variant"];
6
- };
7
- /**
8
- * Renders the security settings layout including password management, linked accounts, and active sessions.
9
- *
10
- * ChangePassword is rendered when password authentication is enabled; LinkedAccounts is rendered when social providers are present.
11
- *
12
- * @param className - Optional additional CSS class names for the outer container.
13
- * @returns The security settings container as a JSX element.
14
- */
15
- export declare function SecuritySettings({ className, ...props }: SecuritySettingsProps & ComponentProps<"div">): import("react/jsx-runtime").JSX.Element;
@@ -1,18 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useAuth } from "@better-auth-ui/react";
3
- import { cn } from "../../../lib/utils";
4
- import { ActiveSessions } from "./active-sessions";
5
- import { ChangePassword } from "./change-password";
6
- import { LinkedAccounts } from "./linked-accounts";
7
- /**
8
- * Renders the security settings layout including password management, linked accounts, and active sessions.
9
- *
10
- * ChangePassword is rendered when password authentication is enabled; LinkedAccounts is rendered when social providers are present.
11
- *
12
- * @param className - Optional additional CSS class names for the outer container.
13
- * @returns The security settings container as a JSX element.
14
- */
15
- export function SecuritySettings({ className, ...props }) {
16
- const { emailAndPassword, socialProviders } = useAuth();
17
- return (_jsxs("div", { className: cn("flex w-full flex-col gap-4 md:gap-6", className), ...props, children: [emailAndPassword?.enabled && _jsx(ChangePassword, {}), socialProviders?.length && _jsx(LinkedAccounts, {}), _jsx(ActiveSessions, {})] }));
18
- }
@@ -1,29 +0,0 @@
1
- import type { SettingsView } from "@better-auth-ui/react/core";
2
- import { type TabsProps } from "@heroui/react";
3
- import { type ComponentProps } from "react";
4
- export type SettingsProps = {
5
- className?: string;
6
- hideNav?: boolean;
7
- path?: string;
8
- view?: SettingsView;
9
- };
10
- /**
11
- * Renders the settings UI and activates the appropriate settings view based on `view` or `path`.
12
- *
13
- * @param className - Additional CSS class names applied to the root container
14
- * @param path - Route path used to resolve which settings view to activate when `view` is not provided
15
- * @param view - Explicit settings view to activate, e.g. `"account"` or `"security"`
16
- * @param hideNav - When `true`, hide the navigation tabs
17
- * @returns A DOM tree containing the responsive settings tabs and the currently selected settings panel
18
- *
19
- * @throws Error if neither `view` nor `path` is provided
20
- */
21
- export declare function Settings({ className, hideNav, path, view, ...props }: SettingsProps & ComponentProps<"div">): import("react/jsx-runtime").JSX.Element;
22
- /**
23
- * Renders a responsive pair of Tabs components: horizontal on small screens and vertical on medium-and-up screens.
24
- *
25
- * @param className - Additional CSS classes applied to both responsive tab containers.
26
- * @param props - All other props are forwarded to each underlying Tabs component.
27
- * @returns A JSX element containing the responsive Tabs pair.
28
- */
29
- export declare function ResponsiveTabs({ className, ...props }: TabsProps): import("react/jsx-runtime").JSX.Element;
@@ -1,39 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { useAuth, useAuthenticate } from "@better-auth-ui/react";
3
- import { Person, Shield } from "@gravity-ui/icons";
4
- import { cn, Tabs, useIsHydrated } from "@heroui/react";
5
- import { useMemo } from "react";
6
- import { AccountSettings } from "./account/account-settings";
7
- import { SecuritySettings } from "./security/security-settings";
8
- /**
9
- * Renders the settings UI and activates the appropriate settings view based on `view` or `path`.
10
- *
11
- * @param className - Additional CSS class names applied to the root container
12
- * @param path - Route path used to resolve which settings view to activate when `view` is not provided
13
- * @param view - Explicit settings view to activate, e.g. `"account"` or `"security"`
14
- * @param hideNav - When `true`, hide the navigation tabs
15
- * @returns A DOM tree containing the responsive settings tabs and the currently selected settings panel
16
- *
17
- * @throws Error if neither `view` nor `path` is provided
18
- */
19
- export function Settings({ className, hideNav, path, view, ...props }) {
20
- const { basePaths, localization, viewPaths } = useAuth();
21
- useAuthenticate();
22
- if (!view && !path) {
23
- throw new Error("[Better Auth UI] Either `view` or `path` must be provided");
24
- }
25
- const settingsPathViews = useMemo(() => Object.fromEntries(Object.entries(viewPaths.settings).map(([k, v]) => [v, k])), [viewPaths.settings]);
26
- const currentView = view || (path ? settingsPathViews[path] : undefined);
27
- const isHydrated = useIsHydrated();
28
- return (_jsxs("div", { className: cn("w-full flex flex-col md:flex-row gap-4 md:gap-6", className), ...props, children: [_jsx(ResponsiveTabs, { selectedKey: currentView, className: cn(hideNav && "hidden"), children: _jsx(Tabs.ListContainer, { children: _jsxs(Tabs.List, { "aria-label": localization.settings.settings, className: "overflow-auto md:w-64 lg:w-72 xl:w-80", children: [_jsxs(Tabs.Tab, { id: "account", href: `${basePaths.settings}/${viewPaths.settings.account}`, className: "gap-2", children: [_jsx(Person, {}), localization.settings.account, _jsx(Tabs.Indicator, {})] }), _jsxs(Tabs.Tab, { id: "security", href: `${basePaths.settings}/${viewPaths.settings.security}`, className: "gap-2", children: [_jsx(Shield, {}), localization.settings.security, _jsx(Tabs.Indicator, {})] })] }) }) }), currentView === "account" && _jsx(AccountSettings, {}), currentView === "security" && _jsx(SecuritySettings, {})] }, `settings-${isHydrated}`));
29
- }
30
- /**
31
- * Renders a responsive pair of Tabs components: horizontal on small screens and vertical on medium-and-up screens.
32
- *
33
- * @param className - Additional CSS classes applied to both responsive tab containers.
34
- * @param props - All other props are forwarded to each underlying Tabs component.
35
- * @returns A JSX element containing the responsive Tabs pair.
36
- */
37
- export function ResponsiveTabs({ className, ...props }) {
38
- return (_jsxs(_Fragment, { children: [_jsx(Tabs, { className: cn("md:hidden", className), orientation: "horizontal", ...props }), _jsx(Tabs, { className: cn("hidden md:flex", className), orientation: "vertical", ...props })] }));
39
- }
@@ -1,16 +0,0 @@
1
- import type { Session, User } from "better-auth";
2
- type DeviceSession = {
3
- session: Session;
4
- user: User;
5
- };
6
- export type SwitchAccountItemProps = {
7
- deviceSession: DeviceSession;
8
- };
9
- /**
10
- * Render a dropdown item for switching to a different authenticated session.
11
- *
12
- * @param deviceSession - The device session to display and switch to when pressed
13
- * @returns The switch account dropdown item as a JSX element
14
- */
15
- export declare function SwitchAccountItem({ deviceSession }: SwitchAccountItemProps): import("react/jsx-runtime").JSX.Element;
16
- export {};
@@ -1,14 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useSetActiveSession } from "@better-auth-ui/react";
3
- import { Dropdown, Spinner } from "@heroui/react";
4
- import { UserView } from "./user-view";
5
- /**
6
- * Render a dropdown item for switching to a different authenticated session.
7
- *
8
- * @param deviceSession - The device session to display and switch to when pressed
9
- * @returns The switch account dropdown item as a JSX element
10
- */
11
- export function SwitchAccountItem({ deviceSession }) {
12
- const { mutate: setActiveSession, isPending } = useSetActiveSession();
13
- return (_jsxs(Dropdown.Item, { className: "px-2", isDisabled: isPending, onPress: () => setActiveSession({ sessionToken: deviceSession.session.token }), children: [_jsx(UserView, { user: deviceSession.user }), isPending && _jsx(Spinner, { color: "current", size: "sm", className: "ml-auto" })] }));
14
- }
@@ -1,10 +0,0 @@
1
- /**
2
- * Render the menu content for switching between multiple authenticated sessions.
3
- *
4
- * Shows the current session with a checkmark, lists other device sessions that can be activated,
5
- * and provides an option to add a new account. This component should be rendered inside a
6
- * Dropdown.SubmenuTrigger to defer the useListDeviceSessions query until the submenu is opened.
7
- *
8
- * @returns The switch account menu content as a JSX element
9
- */
10
- export declare function SwitchAccountMenu(): import("react/jsx-runtime").JSX.Element;
@@ -1,23 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useAuth, useListDeviceSessions, useSession } from "@better-auth-ui/react";
3
- import { Check, CirclePlus } from "@gravity-ui/icons";
4
- import { Dropdown, Label, Separator } from "@heroui/react";
5
- import { SwitchAccountItem } from "./switch-account-item";
6
- import { UserView } from "./user-view";
7
- /**
8
- * Render the menu content for switching between multiple authenticated sessions.
9
- *
10
- * Shows the current session with a checkmark, lists other device sessions that can be activated,
11
- * and provides an option to add a new account. This component should be rendered inside a
12
- * Dropdown.SubmenuTrigger to defer the useListDeviceSessions query until the submenu is opened.
13
- *
14
- * @returns The switch account menu content as a JSX element
15
- */
16
- export function SwitchAccountMenu() {
17
- const { basePaths, viewPaths, localization } = useAuth();
18
- const { data: sessionData } = useSession();
19
- const { data: deviceSessions, isPending } = useListDeviceSessions();
20
- return (_jsx(Dropdown.Popover, { className: "min-w-40 md:min-w-56 max-w-[48svw]", children: _jsxs(Dropdown.Menu, { children: [_jsxs(Dropdown.Item, { className: "px-2", children: [_jsx(UserView, { isPending: isPending }), !isPending && _jsx(Check, { className: "ml-auto" })] }), deviceSessions
21
- ?.filter((deviceSession) => deviceSession.session.id !== sessionData?.session?.id)
22
- .map((deviceSession) => (_jsx(SwitchAccountItem, { deviceSession: deviceSession }, deviceSession.session.id))), _jsx(Separator, {}), _jsxs(Dropdown.Item, { textValue: localization.auth.addAccount, href: `${basePaths.auth}/${viewPaths.auth.signIn}`, children: [_jsx(CirclePlus, { className: "text-muted" }), _jsx(Label, { children: localization.auth.addAccount })] })] }) }));
23
- }
@@ -1,24 +0,0 @@
1
- import { type AvatarProps } from "@heroui/react";
2
- import type { User } from "better-auth";
3
- import type { ReactNode } from "react";
4
- export type UserAvatarProps = {
5
- className?: string;
6
- fallback?: ReactNode;
7
- isPending?: boolean;
8
- user?: User & {
9
- username?: string | null;
10
- displayUsername?: string | null;
11
- };
12
- size?: AvatarProps["size"];
13
- };
14
- /**
15
- * 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.
16
- *
17
- * @param className - Additional CSS classes applied to the outer avatar container
18
- * @param fallback - Custom fallback content to render when no image or initials are available
19
- * @param isPending - When true, force rendering of the loading skeleton (unless an explicit `user` prop is provided)
20
- * @param user - Optional user object to display; when omitted the current session user is used if available
21
- * @param size - Visual size of the avatar; one of `"sm"`, `"md"`, or `"lg"` (default: `"sm"`)
22
- * @returns A React element that displays the user's avatar image, initials, or the provided fallback; renders a circular skeleton while loading
23
- */
24
- export declare function UserAvatar({ className, fallback, isPending, user, size, style, ...props }: UserAvatarProps & AvatarProps): import("react/jsx-runtime").JSX.Element;
@@ -1,31 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { 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 { data: sessionData, isPending: sessionPending } = useSession({
17
- enabled: !user && !isPending
18
- });
19
- if ((isPending || sessionPending) && !user) {
20
- return (_jsx(Skeleton, { className: cn("rounded-full", size === "sm" ? "size-8" : size === "md" ? "size-10" : "size-12", className), style: style }));
21
- }
22
- const resolvedUser = user ?? sessionData?.user;
23
- const initials = (resolvedUser?.username ||
24
- resolvedUser?.name ||
25
- resolvedUser?.email)
26
- ?.slice(0, 2)
27
- .toUpperCase();
28
- return (_jsxs(Avatar, { size: size, className: cn("rounded-full", className), style: style, ...props, children: [_jsx(Avatar.Image, { alt: resolvedUser?.displayUsername ||
29
- resolvedUser?.name ||
30
- 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" }) })] }));
31
- }