@better-auth-ui/heroui 1.6.1 → 1.6.3

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 (117) hide show
  1. package/dist/components/auth/auth-provider.d.ts +1 -1
  2. package/dist/components/auth/auth-provider.js +16 -11
  3. package/dist/components/auth/auth.d.ts +4 -4
  4. package/dist/components/auth/auth.js +36 -41
  5. package/dist/components/auth/error-toaster.d.ts +1 -0
  6. package/dist/components/auth/error-toaster.js +17 -0
  7. package/dist/components/auth/field-separator.d.ts +1 -1
  8. package/dist/components/auth/field-separator.js +17 -4
  9. package/dist/components/auth/forgot-password.d.ts +2 -2
  10. package/dist/components/auth/forgot-password.js +66 -27
  11. package/dist/components/auth/magic-link-button.d.ts +1 -1
  12. package/dist/components/auth/magic-link-button.js +15 -18
  13. package/dist/components/auth/magic-link.d.ts +3 -3
  14. package/dist/components/auth/magic-link.js +98 -43
  15. package/dist/components/auth/passkey-button.js +20 -12
  16. package/dist/components/auth/provider-button.d.ts +15 -0
  17. package/dist/components/auth/provider-button.js +29 -0
  18. package/dist/components/auth/provider-buttons.d.ts +4 -10
  19. package/dist/components/auth/provider-buttons.js +19 -33
  20. package/dist/components/auth/reset-password.d.ts +2 -2
  21. package/dist/components/auth/reset-password.js +143 -57
  22. package/dist/components/auth/sign-in.d.ts +3 -3
  23. package/dist/components/auth/sign-in.js +151 -64
  24. package/dist/components/auth/sign-out.js +26 -32
  25. package/dist/components/auth/sign-up.d.ts +3 -3
  26. package/dist/components/auth/sign-up.js +231 -70
  27. package/dist/components/email/email-changed-email.d.ts +2 -2
  28. package/dist/components/email/email-changed-email.js +29 -22
  29. package/dist/components/email/email-verification-email.d.ts +2 -2
  30. package/dist/components/email/email-verification-email.js +29 -22
  31. package/dist/components/email/magic-link-email.d.ts +2 -2
  32. package/dist/components/email/magic-link-email.js +29 -22
  33. package/dist/components/email/new-device-email.d.ts +2 -2
  34. package/dist/components/email/new-device-email.js +29 -22
  35. package/dist/components/email/otp-email.d.ts +2 -2
  36. package/dist/components/email/otp-email.js +28 -21
  37. package/dist/components/email/password-changed-email.d.ts +2 -2
  38. package/dist/components/email/password-changed-email.js +29 -22
  39. package/dist/components/email/reset-password-email.d.ts +2 -2
  40. package/dist/components/email/reset-password-email.js +29 -22
  41. package/dist/components/settings/account/account-settings.d.ts +2 -2
  42. package/dist/components/settings/account/account-settings.js +22 -19
  43. package/dist/components/settings/account/appearance.d.ts +2 -2
  44. package/dist/components/settings/account/appearance.js +70 -27
  45. package/dist/components/settings/account/change-avatar.js +88 -55
  46. package/dist/components/settings/account/change-email.d.ts +2 -2
  47. package/dist/components/settings/account/change-email.js +53 -28
  48. package/dist/components/settings/account/manage-account.d.ts +1 -1
  49. package/dist/components/settings/account/manage-account.js +47 -31
  50. package/dist/components/settings/account/manage-accounts.d.ts +2 -2
  51. package/dist/components/settings/account/manage-accounts.js +32 -36
  52. package/dist/components/settings/account/user-profile.d.ts +4 -4
  53. package/dist/components/settings/account/user-profile.js +102 -22
  54. package/dist/components/settings/security/active-session.d.ts +1 -1
  55. package/dist/components/settings/security/active-session.js +57 -51
  56. package/dist/components/settings/security/active-sessions.d.ts +2 -2
  57. package/dist/components/settings/security/active-sessions.js +32 -26
  58. package/dist/components/settings/security/change-password.d.ts +2 -2
  59. package/dist/components/settings/security/change-password.js +186 -76
  60. package/dist/components/settings/security/danger-zone.d.ts +2 -2
  61. package/dist/components/settings/security/danger-zone.js +17 -11
  62. package/dist/components/settings/security/delete-user.d.ts +2 -2
  63. package/dist/components/settings/security/delete-user.js +91 -46
  64. package/dist/components/settings/security/linked-account.d.ts +1 -1
  65. package/dist/components/settings/security/linked-account.js +55 -47
  66. package/dist/components/settings/security/linked-accounts.d.ts +2 -2
  67. package/dist/components/settings/security/linked-accounts.js +43 -40
  68. package/dist/components/settings/security/passkey.js +42 -13
  69. package/dist/components/settings/security/passkeys.d.ts +2 -2
  70. package/dist/components/settings/security/passkeys.js +51 -19
  71. package/dist/components/settings/security/security-settings.d.ts +2 -2
  72. package/dist/components/settings/security/security-settings.js +24 -21
  73. package/dist/components/settings/settings.d.ts +3 -3
  74. package/dist/components/settings/settings.js +44 -27
  75. package/dist/components/user/switch-account-item.d.ts +1 -1
  76. package/dist/components/user/switch-account-item.js +19 -15
  77. package/dist/components/user/switch-account-menu.js +27 -28
  78. package/dist/components/user/user-avatar.d.ts +3 -3
  79. package/dist/components/user/user-avatar.js +28 -30
  80. package/dist/components/user/user-button.d.ts +1 -1
  81. package/dist/components/user/user-button.js +90 -23
  82. package/dist/components/user/user-view.d.ts +3 -3
  83. package/dist/components/user/user-view.js +36 -23
  84. package/dist/core.d.ts +1 -1
  85. package/dist/index.d.ts +36 -35
  86. package/dist/index.js +37 -35
  87. package/dist/react-exports.d.ts +1 -1
  88. package/package.json +15 -11
  89. package/src/components/auth/auth-provider.tsx +4 -0
  90. package/src/components/auth/auth.tsx +2 -2
  91. package/src/components/auth/error-toaster.tsx +25 -0
  92. package/src/components/auth/forgot-password.tsx +1 -2
  93. package/src/components/auth/magic-link.tsx +3 -23
  94. package/src/components/auth/passkey-button.tsx +1 -2
  95. package/src/components/auth/provider-button.tsx +67 -0
  96. package/src/components/auth/provider-buttons.tsx +26 -43
  97. package/src/components/auth/reset-password.tsx +1 -2
  98. package/src/components/auth/sign-in.tsx +63 -48
  99. package/src/components/auth/sign-up.tsx +99 -20
  100. package/src/components/settings/account/appearance.tsx +1 -1
  101. package/src/components/settings/account/change-avatar.tsx +1 -3
  102. package/src/components/settings/account/change-email.tsx +2 -3
  103. package/src/components/settings/account/manage-account.tsx +1 -4
  104. package/src/components/settings/account/manage-accounts.tsx +3 -8
  105. package/src/components/settings/account/user-profile.tsx +122 -8
  106. package/src/components/settings/security/active-session.tsx +0 -1
  107. package/src/components/settings/security/active-sessions.tsx +3 -8
  108. package/src/components/settings/security/change-password.tsx +7 -4
  109. package/src/components/settings/security/delete-user.tsx +1 -4
  110. package/src/components/settings/security/linked-account.tsx +4 -14
  111. package/src/components/settings/security/linked-accounts.tsx +3 -8
  112. package/src/components/settings/security/passkey.tsx +2 -4
  113. package/src/components/settings/security/passkeys.tsx +4 -12
  114. package/src/components/settings/settings.tsx +1 -1
  115. package/src/components/user/switch-account-item.tsx +2 -4
  116. package/src/components/user/switch-account-menu.tsx +2 -7
  117. package/src/index.tsx +1 -0
@@ -1,79 +1,189 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useAuth, useChangePassword, useListAccounts, useRequestPasswordReset, useSession } from "@better-auth-ui/react";
3
- import { 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
- * When the user has a credential account, displays fields for current password,
10
- * new password, and optionally confirm password. When the user only has social
11
- * accounts, displays a prompt to set a password via the reset flow.
12
- *
13
- * @returns A JSX element containing the change-password or set-password card
14
- */
15
- export function ChangePassword({ className, variant, ...props }) {
16
- const { emailAndPassword, localization } = useAuth();
17
- const { data: session } = useSession();
18
- const { data: accounts, isPending: isAccountsPending } = useListAccounts();
19
- const hasCredentialAccount = accounts?.some((account) => account.providerId === "credential");
20
- if (!isAccountsPending && !hasCredentialAccount) {
21
- return _jsx(SetPassword, { className: className, variant: variant, ...props });
22
- }
23
- return (_jsx(ChangePasswordForm, { className: className, variant: variant, emailAndPassword: emailAndPassword, localization: localization, session: isAccountsPending ? undefined : session, ...props }));
1
+ import { useAuth as e, useChangePassword as t, useListAccounts as n, useRequestPasswordReset as r, useSession as i } from "@better-auth-ui/react";
2
+ import { Button as a, Card as o, FieldError as s, Fieldset as c, Form as l, Input as u, InputGroup as d, Label as f, Skeleton as p, Spinner as m, TextField as h, cn as g, toast as _ } from "@heroui/react";
3
+ import { jsx as v, jsxs as y } from "react/jsx-runtime";
4
+ import { useState as b } from "react";
5
+ import { Eye as x, EyeSlash as S } from "@gravity-ui/icons";
6
+ //#region src/components/settings/security/change-password.tsx
7
+ function C({ className: t, variant: r, ...a }) {
8
+ let { emailAndPassword: o, localization: s } = e(), { data: c } = i(), { data: l, isPending: u } = n(), d = l?.some((e) => e.providerId === "credential");
9
+ return !u && !d ? /* @__PURE__ */ v(w, {
10
+ className: t,
11
+ variant: r,
12
+ ...a
13
+ }) : /* @__PURE__ */ v(T, {
14
+ className: t,
15
+ variant: r,
16
+ emailAndPassword: o,
17
+ localization: s,
18
+ session: u ? void 0 : c,
19
+ ...a
20
+ });
24
21
  }
25
- function SetPassword({ className, variant, ...props }) {
26
- const { localization } = useAuth();
27
- const { data: session } = useSession();
28
- const { mutate: requestPasswordReset, isPending } = useRequestPasswordReset({
29
- onError: (error) => toast.danger(error.error?.message || error.message),
30
- onSuccess: () => toast.success(localization.auth.passwordResetEmailSent)
31
- });
32
- const handleSetPassword = () => {
33
- if (!session?.user.email)
34
- return;
35
- requestPasswordReset({ email: session.user.email });
36
- };
37
- return (_jsxs("div", { children: [_jsx("h2", { className: cn("text-sm font-semibold mb-3"), children: localization.settings.changePassword }), _jsx(Card, { className: cn(className), variant: variant, ...props, children: _jsxs(Card.Content, { className: "flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between", children: [_jsxs("div", { children: [_jsx("p", { className: "text-sm font-medium leading-tight", children: localization.settings.setPassword }), _jsx("p", { className: "text-muted text-xs mt-0.5", children: localization.settings.setPasswordDescription })] }), _jsxs(Button, { size: "sm", isPending: isPending, isDisabled: !session, onPress: handleSetPassword, children: [isPending && _jsx(Spinner, { color: "current", size: "sm" }), localization.auth.sendResetLink] })] }) })] }));
22
+ function w({ className: t, variant: n, ...s }) {
23
+ let { localization: c } = e(), { data: l } = i(), { mutate: u, isPending: d } = r({ onSuccess: () => _.success(c.auth.passwordResetEmailSent) }), f = () => {
24
+ l?.user.email && u({ email: l.user.email });
25
+ };
26
+ return /* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("h2", {
27
+ className: g("text-sm font-semibold mb-3"),
28
+ children: c.settings.changePassword
29
+ }), /* @__PURE__ */ v(o, {
30
+ className: g(t),
31
+ variant: n,
32
+ ...s,
33
+ children: /* @__PURE__ */ y(o.Content, {
34
+ className: "flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between",
35
+ children: [/* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("p", {
36
+ className: "text-sm font-medium leading-tight",
37
+ children: c.settings.setPassword
38
+ }), /* @__PURE__ */ v("p", {
39
+ className: "text-muted text-xs mt-0.5",
40
+ children: c.settings.setPasswordDescription
41
+ })] }), /* @__PURE__ */ y(a, {
42
+ size: "sm",
43
+ isPending: d,
44
+ isDisabled: !l,
45
+ onPress: f,
46
+ children: [d && /* @__PURE__ */ v(m, {
47
+ color: "current",
48
+ size: "sm"
49
+ }), c.auth.sendResetLink]
50
+ })]
51
+ })
52
+ })] });
38
53
  }
39
- function ChangePasswordForm({ className, variant, emailAndPassword, localization, session, ...props }) {
40
- const [currentPassword, setCurrentPassword] = useState("");
41
- const [newPassword, setNewPassword] = useState("");
42
- const [confirmPassword, setConfirmPassword] = useState("");
43
- const { mutate: changePassword, isPending } = useChangePassword({
44
- onError: (error) => {
45
- setCurrentPassword("");
46
- setNewPassword("");
47
- setConfirmPassword("");
48
- toast.danger(error.error?.message || error.message);
49
- },
50
- onSuccess: () => {
51
- setCurrentPassword("");
52
- setNewPassword("");
53
- setConfirmPassword("");
54
- toast.success(localization.settings.changePasswordSuccess);
55
- }
56
- });
57
- const [isNewPasswordVisible, setIsNewPasswordVisible] = useState(false);
58
- const [isConfirmPasswordVisible, setIsConfirmPasswordVisible] = useState(false);
59
- const handleSubmit = (e) => {
60
- e.preventDefault();
61
- if (emailAndPassword?.confirmPassword && newPassword !== confirmPassword) {
62
- setCurrentPassword("");
63
- setNewPassword("");
64
- setConfirmPassword("");
65
- toast.danger(localization.auth.passwordsDoNotMatch);
66
- return;
67
- }
68
- changePassword({
69
- currentPassword,
70
- newPassword,
71
- revokeOtherSessions: true
72
- });
73
- };
74
- return (_jsxs("div", { children: [_jsx("h2", { className: cn("text-sm font-semibold mb-3"), children: localization.settings.changePassword }), _jsx(Card, { className: cn("p-4 gap-4", className), variant: variant, ...props, children: _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 || !session, defaultValue: "", value: currentPassword, onChange: setCurrentPassword, children: [_jsx(Label, { children: localization.settings.currentPassword }), _jsx(Input, { className: cn(!session && "hidden"), autoComplete: "current-password", placeholder: localization.settings.currentPasswordPlaceholder, required: true, variant: variant === "transparent" ? "primary" : "secondary" }), !session && (_jsx(Skeleton, { className: "h-10 md:h-9 w-full rounded-xl" })), _jsx(FieldError, {})] }), _jsxs(TextField, { minLength: emailAndPassword?.minPasswordLength, maxLength: emailAndPassword?.maxPasswordLength, isDisabled: isPending || !session, value: newPassword, onChange: setNewPassword, children: [_jsx(Label, { children: localization.auth.newPassword }), _jsxs(InputGroup, { className: cn(!session && "hidden"), 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
75
- ? localization.auth.hidePassword
76
- : localization.auth.showPassword, size: "sm", variant: "ghost", onPress: () => setIsNewPasswordVisible(!isNewPasswordVisible), isDisabled: isPending, children: isNewPasswordVisible ? _jsx(EyeSlash, {}) : _jsx(Eye, {}) }) })] }), !session && (_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 || !session, isRequired: true, value: confirmPassword, onChange: setConfirmPassword, children: [_jsx(Label, { children: localization.auth.confirmPassword }), _jsxs(InputGroup, { className: cn(!session && "hidden"), 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
77
- ? localization.auth.hidePassword
78
- : localization.auth.showPassword, size: "sm", variant: "ghost", onPress: () => setIsConfirmPasswordVisible(!isConfirmPasswordVisible), isDisabled: isPending, children: isConfirmPasswordVisible ? _jsx(EyeSlash, {}) : _jsx(Eye, {}) }) })] }), !session && (_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: !session, size: "sm", children: [isPending && _jsx(Spinner, { color: "current", size: "sm" }), localization.settings.updatePassword] }) })] }) }) }) })] }));
54
+ function T({ className: e, variant: n, emailAndPassword: r, localization: i, session: C, ...w }) {
55
+ let [T, E] = b(""), [D, O] = b(""), [k, A] = b(""), { mutate: j, isPending: M } = t({
56
+ onError: (e) => {
57
+ E(""), O(""), A(""), _.danger(e.error?.message || e.message);
58
+ },
59
+ onSuccess: () => {
60
+ E(""), O(""), A(""), _.success(i.settings.changePasswordSuccess);
61
+ }
62
+ }), [N, P] = b(!1), [F, I] = b(!1), L = (e) => {
63
+ if (e.preventDefault(), r?.confirmPassword && D !== k) {
64
+ E(""), O(""), A(""), _.danger(i.auth.passwordsDoNotMatch);
65
+ return;
66
+ }
67
+ j({
68
+ currentPassword: T,
69
+ newPassword: D,
70
+ revokeOtherSessions: !0
71
+ });
72
+ };
73
+ return /* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("h2", {
74
+ className: g("text-sm font-semibold mb-3"),
75
+ children: i.settings.changePassword
76
+ }), /* @__PURE__ */ v(o, {
77
+ className: g("p-4 gap-4", e),
78
+ variant: n,
79
+ ...w,
80
+ children: /* @__PURE__ */ v(o.Content, { children: /* @__PURE__ */ v(l, {
81
+ onSubmit: L,
82
+ children: /* @__PURE__ */ y(c, {
83
+ className: "w-full gap-4",
84
+ children: [/* @__PURE__ */ y(c.Group, { children: [
85
+ /* @__PURE__ */ y(h, {
86
+ name: "currentPassword",
87
+ type: "password",
88
+ isDisabled: M || !C,
89
+ defaultValue: "",
90
+ value: T,
91
+ onChange: E,
92
+ children: [
93
+ /* @__PURE__ */ v(f, { children: i.settings.currentPassword }),
94
+ /* @__PURE__ */ v(u, {
95
+ className: g(!C && "hidden"),
96
+ autoComplete: "current-password",
97
+ placeholder: i.settings.currentPasswordPlaceholder,
98
+ required: !0,
99
+ variant: n === "transparent" ? "primary" : "secondary"
100
+ }),
101
+ !C && /* @__PURE__ */ v(p, { className: "h-10 md:h-9 w-full rounded-xl" }),
102
+ /* @__PURE__ */ v(s, {})
103
+ ]
104
+ }),
105
+ /* @__PURE__ */ y(h, {
106
+ minLength: r?.minPasswordLength,
107
+ maxLength: r?.maxPasswordLength,
108
+ isDisabled: M || !C,
109
+ value: D,
110
+ onChange: O,
111
+ children: [
112
+ /* @__PURE__ */ v(f, { children: i.auth.newPassword }),
113
+ /* @__PURE__ */ y(d, {
114
+ className: g(!C && "hidden"),
115
+ variant: n === "transparent" ? "primary" : "secondary",
116
+ children: [/* @__PURE__ */ v(d.Input, {
117
+ name: "newPassword",
118
+ type: N ? "text" : "password",
119
+ autoComplete: "new-password",
120
+ placeholder: i.auth.newPasswordPlaceholder,
121
+ required: !0
122
+ }), /* @__PURE__ */ v(d.Suffix, {
123
+ className: "px-0",
124
+ children: /* @__PURE__ */ v(a, {
125
+ isIconOnly: !0,
126
+ "aria-label": N ? i.auth.hidePassword : i.auth.showPassword,
127
+ size: "sm",
128
+ variant: "ghost",
129
+ onPress: () => P(!N),
130
+ isDisabled: M,
131
+ children: v(N ? S : x, {})
132
+ })
133
+ })]
134
+ }),
135
+ !C && /* @__PURE__ */ v(p, { className: "h-10 md:h-9 w-full rounded-xl" }),
136
+ /* @__PURE__ */ v(s, {})
137
+ ]
138
+ }),
139
+ r?.confirmPassword && /* @__PURE__ */ y(h, {
140
+ minLength: r?.minPasswordLength,
141
+ maxLength: r?.maxPasswordLength,
142
+ isDisabled: M || !C,
143
+ isRequired: !0,
144
+ value: k,
145
+ onChange: A,
146
+ children: [
147
+ /* @__PURE__ */ v(f, { children: i.auth.confirmPassword }),
148
+ /* @__PURE__ */ y(d, {
149
+ className: g(!C && "hidden"),
150
+ variant: n === "transparent" ? "primary" : "secondary",
151
+ children: [/* @__PURE__ */ v(d.Input, {
152
+ name: "confirmPassword",
153
+ type: F ? "text" : "password",
154
+ autoComplete: "new-password",
155
+ placeholder: i.auth.confirmPasswordPlaceholder,
156
+ required: !0
157
+ }), /* @__PURE__ */ v(d.Suffix, {
158
+ className: "px-0",
159
+ children: /* @__PURE__ */ v(a, {
160
+ isIconOnly: !0,
161
+ "aria-label": F ? i.auth.hidePassword : i.auth.showPassword,
162
+ size: "sm",
163
+ variant: "ghost",
164
+ onPress: () => I(!F),
165
+ isDisabled: M,
166
+ children: v(F ? S : x, {})
167
+ })
168
+ })]
169
+ }),
170
+ !C && /* @__PURE__ */ v(p, { className: "h-10 md:h-9 w-full rounded-xl" }),
171
+ /* @__PURE__ */ v(s, {})
172
+ ]
173
+ })
174
+ ] }), /* @__PURE__ */ v(c.Actions, { children: /* @__PURE__ */ y(a, {
175
+ type: "submit",
176
+ isPending: M,
177
+ isDisabled: !C,
178
+ size: "sm",
179
+ children: [M && /* @__PURE__ */ v(m, {
180
+ color: "current",
181
+ size: "sm"
182
+ }), i.settings.updatePassword]
183
+ }) })]
184
+ })
185
+ }) })
186
+ })] });
79
187
  }
188
+ //#endregion
189
+ export { C as ChangePassword };
@@ -1,5 +1,5 @@
1
- import { type CardProps } from "@heroui/react";
2
- import type { ComponentProps } from "react";
1
+ import { CardProps } from '@heroui/react';
2
+ import { ComponentProps } from 'react';
3
3
  export type DangerZoneProps = {
4
4
  className?: string;
5
5
  variant?: CardProps["variant"];
@@ -1,12 +1,18 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useAuth } from "@better-auth-ui/react";
3
- import { cn } from "@heroui/react";
4
- import { DeleteUser } from "./delete-user";
5
- /**
6
- * Renders the danger zone heading and {@link DeleteUser}.
7
- * Gate with `deleteUser.enabled` at the call site (e.g. {@link SecuritySettings}).
8
- */
9
- export function DangerZone({ className, variant, ...props }) {
10
- const { localization } = useAuth();
11
- return (_jsxs("div", { className: cn("flex w-full flex-col", className), ...props, children: [_jsx("h2", { className: cn("text-sm font-semibold mb-3"), children: localization.settings.dangerZone }), _jsx(DeleteUser, { variant: variant })] }));
1
+ import { DeleteUser as e } from "./delete-user.js";
2
+ import { useAuth as t } from "@better-auth-ui/react";
3
+ import { cn as n } from "@heroui/react";
4
+ import { jsx as r, jsxs as i } from "react/jsx-runtime";
5
+ //#region src/components/settings/security/danger-zone.tsx
6
+ function a({ className: a, variant: o, ...s }) {
7
+ let { localization: c } = t();
8
+ return /* @__PURE__ */ i("div", {
9
+ className: n("flex w-full flex-col", a),
10
+ ...s,
11
+ children: [/* @__PURE__ */ r("h2", {
12
+ className: n("text-sm font-semibold mb-3"),
13
+ children: c.settings.dangerZone
14
+ }), /* @__PURE__ */ r(e, { variant: o })]
15
+ });
12
16
  }
17
+ //#endregion
18
+ export { a as DangerZone };
@@ -1,4 +1,4 @@
1
- import { type CardProps } from "@heroui/react";
1
+ import { CardProps } from '@heroui/react';
2
2
  export type DeleteUserProps = {
3
3
  className?: string;
4
4
  variant?: CardProps["variant"];
@@ -6,4 +6,4 @@ export type DeleteUserProps = {
6
6
  /**
7
7
  * Danger-zone card to delete the authenticated account, with a confirmation dialog and toasts.
8
8
  */
9
- export declare function DeleteUser({ className, variant, ...props }: DeleteUserProps & CardProps): import("react/jsx-runtime").JSX.Element;
9
+ export declare function DeleteUser({ className, variant, ...props }: DeleteUserProps & Omit<CardProps, "children">): import("react/jsx-runtime").JSX.Element;
@@ -1,47 +1,92 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useAuth, useDeleteUser, useListAccounts } from "@better-auth-ui/react";
3
- import { TriangleExclamation } from "@gravity-ui/icons";
4
- import { AlertDialog, Button, Card, cn, FieldError, Form, Input, Label, Spinner, TextField, toast } from "@heroui/react";
5
- import { useState } from "react";
6
- /**
7
- * Danger-zone card to delete the authenticated account, with a confirmation dialog and toasts.
8
- */
9
- export function DeleteUser({ className, variant, ...props }) {
10
- const { basePaths, deleteUser: deleteUserConfig, localization, navigate, viewPaths } = useAuth();
11
- const { data: accounts } = useListAccounts();
12
- const [confirmOpen, setConfirmOpen] = useState(false);
13
- const [password, setPassword] = useState("");
14
- const hasCredentialAccount = accounts?.some((account) => account.providerId === "credential");
15
- const needsPassword = !deleteUserConfig?.sendDeleteAccountVerification && hasCredentialAccount;
16
- const { mutate: deleteUser, isPending } = useDeleteUser();
17
- const handleDialogOpenChange = (open) => {
18
- setConfirmOpen(open);
19
- setPassword("");
20
- };
21
- const handleSubmit = async (e) => {
22
- e.preventDefault();
23
- const params = {
24
- ...(needsPassword ? { password } : {})
25
- };
26
- deleteUser(params, {
27
- onSuccess: () => {
28
- setConfirmOpen(false);
29
- setPassword("");
30
- if (deleteUserConfig?.sendDeleteAccountVerification) {
31
- toast.success(localization.settings.deleteUserVerificationSent);
32
- }
33
- else {
34
- toast.success(localization.settings.deleteUserSuccess);
35
- navigate({
36
- to: `${basePaths.auth}/${viewPaths.auth.signIn}`,
37
- replace: true
38
- });
39
- }
40
- },
41
- onError: (error) => {
42
- toast.danger(error.error?.message || error.message);
43
- }
44
- });
45
- };
46
- return (_jsx(Card, { className: cn("border border-danger", className), variant: variant, ...props, children: _jsxs(Card.Content, { className: "flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between", children: [_jsxs("div", { children: [_jsx("p", { className: "text-sm font-medium leading-tight", children: localization.settings.deleteUser }), _jsx("p", { className: "text-muted text-xs mt-0.5", children: localization.settings.deleteUserDescription })] }), _jsxs(AlertDialog, { children: [_jsx(Button, { isDisabled: !accounts, size: "sm", variant: "danger", onPress: () => setConfirmOpen(true), children: localization.settings.deleteUser }), _jsx(AlertDialog.Backdrop, { isOpen: confirmOpen, onOpenChange: handleDialogOpenChange, children: _jsx(AlertDialog.Container, { children: _jsx(AlertDialog.Dialog, { children: _jsxs(Form, { onSubmit: handleSubmit, children: [_jsx(AlertDialog.CloseTrigger, {}), _jsxs(AlertDialog.Header, { children: [_jsx(AlertDialog.Icon, { status: "danger", children: _jsx(TriangleExclamation, {}) }), _jsx(AlertDialog.Heading, { children: localization.settings.deleteUser })] }), _jsxs(AlertDialog.Body, { className: "overflow-visible", children: [_jsx("p", { className: "text-muted text-sm", children: localization.settings.deleteUserDescription }), needsPassword && (_jsxs(TextField, { className: "mt-4", name: "password", type: "password", isDisabled: isPending, value: password, onChange: setPassword, children: [_jsx(Label, { children: localization.auth.password }), _jsx(Input, { autoComplete: "current-password", placeholder: localization.auth.passwordPlaceholder, required: true, variant: "secondary" }), _jsx(FieldError, {})] }))] }), _jsxs(AlertDialog.Footer, { children: [_jsx(Button, { slot: "close", variant: "tertiary", isDisabled: isPending, children: localization.settings.cancel }), _jsxs(Button, { type: "submit", variant: "danger", isPending: isPending, children: [isPending && _jsx(Spinner, { color: "current", size: "sm" }), localization.settings.deleteUser] })] })] }) }) }) })] })] }) }));
1
+ import { useAuth as e, useDeleteUser as t, useListAccounts as n } from "@better-auth-ui/react";
2
+ import { AlertDialog as r, Button as i, Card as a, FieldError as o, Form as s, Input as c, Label as l, Spinner as u, TextField as d, cn as f, toast as p } from "@heroui/react";
3
+ import { jsx as m, jsxs as h } from "react/jsx-runtime";
4
+ import { useState as g } from "react";
5
+ import { TriangleExclamation as _ } from "@gravity-ui/icons";
6
+ //#region src/components/settings/security/delete-user.tsx
7
+ function v({ className: v, variant: y, ...b }) {
8
+ let { basePaths: x, deleteUser: S, localization: C, navigate: w, viewPaths: T } = e(), { data: E } = n(), [D, O] = g(!1), [k, A] = g(""), j = E?.some((e) => e.providerId === "credential"), M = !S?.sendDeleteAccountVerification && j, { mutate: N, isPending: P } = t(), F = (e) => {
9
+ O(e), A("");
10
+ }, I = async (e) => {
11
+ e.preventDefault(), N({ ...M ? { password: k } : {} }, { onSuccess: () => {
12
+ O(!1), A(""), S?.sendDeleteAccountVerification ? p.success(C.settings.deleteUserVerificationSent) : (p.success(C.settings.deleteUserSuccess), w({
13
+ to: `${x.auth}/${T.auth.signIn}`,
14
+ replace: !0
15
+ }));
16
+ } });
17
+ };
18
+ return /* @__PURE__ */ m(a, {
19
+ className: f("border border-danger", v),
20
+ variant: y,
21
+ ...b,
22
+ children: /* @__PURE__ */ h(a.Content, {
23
+ className: "flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between",
24
+ children: [/* @__PURE__ */ h("div", { children: [/* @__PURE__ */ m("p", {
25
+ className: "text-sm font-medium leading-tight",
26
+ children: C.settings.deleteUser
27
+ }), /* @__PURE__ */ m("p", {
28
+ className: "text-muted text-xs mt-0.5",
29
+ children: C.settings.deleteUserDescription
30
+ })] }), /* @__PURE__ */ h(r, { children: [/* @__PURE__ */ m(i, {
31
+ isDisabled: !E,
32
+ size: "sm",
33
+ variant: "danger",
34
+ onPress: () => O(!0),
35
+ children: C.settings.deleteUser
36
+ }), /* @__PURE__ */ m(r.Backdrop, {
37
+ isOpen: D,
38
+ onOpenChange: F,
39
+ children: /* @__PURE__ */ m(r.Container, { children: /* @__PURE__ */ m(r.Dialog, { children: /* @__PURE__ */ h(s, {
40
+ onSubmit: I,
41
+ children: [
42
+ /* @__PURE__ */ m(r.CloseTrigger, {}),
43
+ /* @__PURE__ */ h(r.Header, { children: [/* @__PURE__ */ m(r.Icon, {
44
+ status: "danger",
45
+ children: /* @__PURE__ */ m(_, {})
46
+ }), /* @__PURE__ */ m(r.Heading, { children: C.settings.deleteUser })] }),
47
+ /* @__PURE__ */ h(r.Body, {
48
+ className: "overflow-visible",
49
+ children: [/* @__PURE__ */ m("p", {
50
+ className: "text-muted text-sm",
51
+ children: C.settings.deleteUserDescription
52
+ }), M && /* @__PURE__ */ h(d, {
53
+ className: "mt-4",
54
+ name: "password",
55
+ type: "password",
56
+ isDisabled: P,
57
+ value: k,
58
+ onChange: A,
59
+ children: [
60
+ /* @__PURE__ */ m(l, { children: C.auth.password }),
61
+ /* @__PURE__ */ m(c, {
62
+ autoComplete: "current-password",
63
+ placeholder: C.auth.passwordPlaceholder,
64
+ required: !0,
65
+ variant: "secondary"
66
+ }),
67
+ /* @__PURE__ */ m(o, {})
68
+ ]
69
+ })]
70
+ }),
71
+ /* @__PURE__ */ h(r.Footer, { children: [/* @__PURE__ */ m(i, {
72
+ slot: "close",
73
+ variant: "tertiary",
74
+ isDisabled: P,
75
+ children: C.settings.cancel
76
+ }), /* @__PURE__ */ h(i, {
77
+ type: "submit",
78
+ variant: "danger",
79
+ isPending: P,
80
+ children: [P && /* @__PURE__ */ m(u, {
81
+ color: "current",
82
+ size: "sm"
83
+ }), C.settings.deleteUser]
84
+ })] })
85
+ ]
86
+ }) }) })
87
+ })] })]
88
+ })
89
+ });
47
90
  }
91
+ //#endregion
92
+ export { v as DeleteUser };
@@ -1,4 +1,4 @@
1
- import type { Account, SocialProvider } from "better-auth";
1
+ import { Account, SocialProvider } from 'better-auth';
2
2
  export type LinkedAccountProps = {
3
3
  account?: Account;
4
4
  provider: SocialProvider;
@@ -1,48 +1,56 @@
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, LinkSlash, PlugConnection } from "@gravity-ui/icons";
5
- import { Button, cn, Skeleton, Spinner, toast } from "@heroui/react";
6
- /**
7
- * Render a single linked social account row with provider info and link/unlink control.
8
- *
9
- * Fetches additional account information from the provider using the accountInfo API
10
- * and displays the provider name, account details, and a link/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 row
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("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: cn("flex size-10 shrink-0 items-center justify-center rounded-xl bg-surface-secondary"), children: ProviderIcon ? (_jsx(ProviderIcon, { className: cn("size-4.5", !account && "opacity-50") })) : (_jsx(PlugConnection, { className: cn("size-4.5", !account && "opacity-50") })) }), _jsxs("div", { className: "flex flex-col min-w-0", 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 truncate", children: account
41
- ? displayName
42
- : localization.settings.linkProvider.replace("{{provider}}", providerName) }))] }), account ? (_jsxs(Button, { className: "ml-auto shrink-0", variant: "outline", 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(LinkSlash, {}), localization.settings.unlinkProvider
43
- .replace("{{provider}}", "")
44
- .trim()] })) : (_jsxs(Button, { className: "ml-auto shrink-0", variant: "outline", size: "sm", onPress: () => linkSocial({
45
- provider,
46
- callbackURL: `${baseURL}${window.location.pathname}`
47
- }), isPending: isLinking, "aria-label": localization.settings.linkProvider.replace("{{provider}}", providerName), children: [isLinking ? _jsx(Spinner, { color: "current", size: "sm" }) : _jsx(Link, {}), localization.settings.link] }))] }));
1
+ import { providerIcons as e, useAccountInfo as t, useAuth as n, useLinkSocial as r, useUnlinkAccount as i } from "@better-auth-ui/react";
2
+ import { Button as a, Skeleton as o, Spinner as s, cn as c, toast as l } from "@heroui/react";
3
+ import { jsx as u, jsxs as d } from "react/jsx-runtime";
4
+ import { Link as f, LinkSlash as p, PlugConnection as m } from "@gravity-ui/icons";
5
+ import { getProviderName as h } from "@better-auth-ui/core";
6
+ //#region src/components/settings/security/linked-account.tsx
7
+ function g({ account: g, provider: _ }) {
8
+ let { baseURL: v, localization: y } = n(), { data: b, isPending: x } = t({ query: { accountId: g?.accountId } }), { mutate: S, isPending: C } = r(), { mutate: w, isPending: T } = i({ onSuccess: () => l.success(y.settings.accountUnlinked) }), E = e[_], D = h(_), O = b?.data?.login || b?.data?.username || b?.user?.email || b?.user?.name || g?.accountId;
9
+ return /* @__PURE__ */ d("div", {
10
+ className: "flex items-center gap-3",
11
+ children: [
12
+ /* @__PURE__ */ u("div", {
13
+ className: c("flex size-10 shrink-0 items-center justify-center rounded-xl bg-surface-secondary"),
14
+ children: u(E || m, { className: c("size-4.5", !g && "opacity-50") })
15
+ }),
16
+ /* @__PURE__ */ d("div", {
17
+ className: "flex flex-col min-w-0",
18
+ children: [/* @__PURE__ */ u("span", {
19
+ className: "text-sm font-medium leading-tight",
20
+ children: D
21
+ }), g && x ? /* @__PURE__ */ u(o, { className: "h-3 w-24 my-0.5 rounded-lg" }) : /* @__PURE__ */ u("span", {
22
+ className: "text-xs text-muted truncate",
23
+ children: g ? O : y.settings.linkProvider.replace("{{provider}}", D)
24
+ })]
25
+ }),
26
+ g ? /* @__PURE__ */ d(a, {
27
+ className: "ml-auto shrink-0",
28
+ variant: "outline",
29
+ size: "sm",
30
+ onPress: () => w({ providerId: g.providerId }),
31
+ isPending: T,
32
+ "aria-label": y.settings.unlinkProvider.replace("{{provider}}", D),
33
+ children: [T ? /* @__PURE__ */ u(s, {
34
+ color: "current",
35
+ size: "sm"
36
+ }) : /* @__PURE__ */ u(p, {}), y.settings.unlinkProvider.replace("{{provider}}", "").trim()]
37
+ }) : /* @__PURE__ */ d(a, {
38
+ className: "ml-auto shrink-0",
39
+ variant: "outline",
40
+ size: "sm",
41
+ onPress: () => S({
42
+ provider: _,
43
+ callbackURL: `${v}${window.location.pathname}`
44
+ }),
45
+ isPending: C,
46
+ "aria-label": y.settings.linkProvider.replace("{{provider}}", D),
47
+ children: [C ? /* @__PURE__ */ u(s, {
48
+ color: "current",
49
+ size: "sm"
50
+ }) : /* @__PURE__ */ u(f, {}), y.settings.link]
51
+ })
52
+ ]
53
+ });
48
54
  }
55
+ //#endregion
56
+ export { g as LinkedAccount };
@@ -1,4 +1,4 @@
1
- import { type CardProps } from "@heroui/react";
1
+ import { CardProps } from '@heroui/react';
2
2
  export type LinkedAccountsProps = {
3
3
  className?: string;
4
4
  variant?: CardProps["variant"];
@@ -12,4 +12,4 @@ export type LinkedAccountsProps = {
12
12
  *
13
13
  * @returns A JSX element containing the linked accounts card
14
14
  */
15
- export declare function LinkedAccounts({ className, variant, ...props }: LinkedAccountsProps & CardProps): import("react/jsx-runtime").JSX.Element;
15
+ export declare function LinkedAccounts({ className, variant, ...props }: LinkedAccountsProps & Omit<CardProps, "children">): import("react/jsx-runtime").JSX.Element;