@better-auth-ui/heroui 1.6.13 → 1.6.15

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.
@@ -7,7 +7,7 @@ export type ForgotPasswordProps = {
7
7
  * Render a card-based "Forgot Password" form that sends a password-reset email.
8
8
  *
9
9
  * The form displays an email input, submit button, and a link back to sign-in.
10
- * Toasts are displayed on success or error via the `useRequestPasswordReset` hook.
10
+ * Success toasts are shown via `useRequestPasswordReset`; errors are handled globally by `ErrorToaster`.
11
11
  *
12
12
  * @param className - Optional additional CSS class names applied to the card
13
13
  * @returns The forgot-password form UI as a JSX element
package/dist/index.js CHANGED
@@ -274,8 +274,8 @@ function Xe({ name: e, field: t, isPending: n, variant: r }) {
274
274
  //#region src/components/auth/forgot-password.tsx
275
275
  function Ze({ className: e, variant: t, ...n }) {
276
276
  let { authClient: r, baseURL: i, basePaths: a, localization: o, viewPaths: s, navigate: c, plugins: l } = m(), { fetchOptions: u, resetFetchOptions: d } = v(), { mutate: f, isPending: p } = x(r, {
277
- onError: (e) => {
278
- Y.danger(e.error?.message || e.message), d();
277
+ onError: () => {
278
+ d();
279
279
  },
280
280
  onSuccess: () => {
281
281
  Y.success(o.auth.passwordResetEmailSent), c({ to: `${a.auth}/${s.auth.signIn}` });
@@ -502,13 +502,13 @@ function Qe({ className: e, variant: t, ...n }) {
502
502
  function $e({ className: t, socialLayout: n, socialPosition: i = "bottom", variant: o, ...s }) {
503
503
  let { authClient: c, basePaths: l, baseURL: u, emailAndPassword: d, localization: f, plugins: p, redirectTo: h, socialProviders: g, viewPaths: _, navigate: y } = m(), { fetchOptions: b, resetFetchOptions: ee } = v(), [x, S] = X(""), { mutate: te } = ne(c, { onSuccess: () => Y.success(f.auth.verificationEmailSent) }), { mutate: C, isPending: ie } = re(c, {
504
504
  onError: (e, { email: t }) => {
505
- S(""), e.error?.code === "EMAIL_NOT_VERIFIED" ? Y.danger(e.error?.message || e.message, { actionProps: {
505
+ S(""), e.error?.code === "EMAIL_NOT_VERIFIED" && Y.danger(e.error?.message || e.message, { actionProps: {
506
506
  children: f.auth.resend,
507
507
  onClick: () => te({
508
508
  email: t,
509
509
  callbackURL: `${u}${h}`
510
510
  })
511
- } }) : Y.danger(e.error?.message || e.message), ee();
511
+ } }), ee();
512
512
  },
513
513
  onSuccess: () => y({ to: h })
514
514
  }), ae = (e) => {
@@ -625,8 +625,8 @@ function $e({ className: t, socialLayout: n, socialPosition: i = "bottom", varia
625
625
  //#region src/components/auth/sign-out.tsx
626
626
  function et({ className: e }) {
627
627
  let { authClient: t, basePaths: n, navigate: r, viewPaths: i } = m(), { mutate: a } = ie(t, {
628
- onError: (e) => {
629
- Y.danger(e.error?.message || e.message), r({
628
+ onError: () => {
629
+ r({
630
630
  to: `${n.auth}/${i.auth.signIn}`,
631
631
  replace: !0
632
632
  });
@@ -647,8 +647,8 @@ function et({ className: e }) {
647
647
  //#region src/components/auth/sign-up.tsx
648
648
  function tt({ className: t, socialLayout: n, socialPosition: i = "bottom", variant: o, ...s }) {
649
649
  let { additionalFields: c, authClient: u, basePaths: d, emailAndPassword: f, localization: p, plugins: h, redirectTo: g, socialProviders: _, viewPaths: y, navigate: b } = m(), { fetchOptions: ee, resetFetchOptions: x } = v(), [S, te] = X(""), [ne, C] = X(""), { mutate: re, isPending: ie } = ae(u, {
650
- onError: (e) => {
651
- te(""), C(""), Y.danger(e.error?.message || e.message), x();
650
+ onError: () => {
651
+ te(""), C(""), x();
652
652
  },
653
653
  onSuccess: () => {
654
654
  f?.requireEmailVerification ? (Y.success(p.auth.verifyYourEmail), b({ to: `${d.auth}/${y.auth.signIn}` })) : b({ to: g });
@@ -907,13 +907,13 @@ function at() {
907
907
  t.config.onError = (e, t) => {
908
908
  if (n?.(e, t), !Ue({ queryKey: o.all }, t)) return;
909
909
  let r = e;
910
- r?.error && Y.danger(r.error.message);
910
+ r?.error?.code !== "EMAIL_NOT_VERIFIED" && r?.error && Y.danger(r.error.message);
911
911
  };
912
912
  let r = e.getMutationCache(), i = r.config.onError;
913
913
  return r.config.onError = (e, t, n, r, o) => {
914
914
  if (i?.(e, t, n, r, o), !He({ mutationKey: a.all }, r)) return;
915
915
  let s = e;
916
- Y.danger(s.error?.message || s.message);
916
+ s.error?.code !== "EMAIL_NOT_VERIFIED" && Y.danger(s.error?.message || s.message);
917
917
  }, () => {
918
918
  t.config.onError = n, r.config.onError = i;
919
919
  };
@@ -1288,8 +1288,8 @@ function gt({ className: e, variant: t, ...n }) {
1288
1288
  }
1289
1289
  function _t({ className: e, variant: t, emailAndPassword: n, localization: r, session: i, ...a }) {
1290
1290
  let { authClient: o } = m(), [s, c] = X(""), [l, u] = X(""), [d, f] = X(""), { mutate: p, isPending: h } = _(o, {
1291
- onError: (e) => {
1292
- c(""), u(""), f(""), Y.danger(e.error?.message || e.message);
1291
+ onError: () => {
1292
+ c(""), u(""), f("");
1293
1293
  },
1294
1294
  onSuccess: () => {
1295
1295
  c(""), u(""), f(""), Y.success(r.settings.changePasswordSuccess);
@@ -1473,11 +1473,11 @@ function vt({ account: e, provider: t }) {
1473
1473
  //#endregion
1474
1474
  //#region src/components/auth/settings/security/linked-accounts.tsx
1475
1475
  function yt({ className: e, variant: t, ...n }) {
1476
- let { authClient: r, localization: i, socialProviders: a } = m(), { data: o, isPending: s } = b(r), c = [...(o?.filter((e) => e.providerId !== "credential"))?.map((e) => ({
1476
+ let { authClient: r, localization: i, multipleAccountsPerProvider: a, socialProviders: o } = m(), { data: s, isPending: c } = b(r), l = s?.filter((e) => e.providerId !== "credential"), u = new Set(l?.map((e) => e.providerId)), d = a === !1 ? o?.filter((e) => !u.has(e)) : o, f = [...l?.map((e) => ({
1477
1477
  key: e.id,
1478
1478
  account: e,
1479
1479
  provider: e.providerId
1480
- })) ?? [], ...a?.map((e) => ({
1480
+ })) ?? [], ...d?.map((e) => ({
1481
1481
  key: e,
1482
1482
  account: void 0,
1483
1483
  provider: e
@@ -1491,7 +1491,7 @@ function yt({ className: e, variant: t, ...n }) {
1491
1491
  ...n,
1492
1492
  children: /* @__PURE__ */ Q(j.Content, {
1493
1493
  className: "gap-0",
1494
- children: s ? a?.map((e, t) => /* @__PURE__ */ $("div", { children: [t > 0 && /* @__PURE__ */ Q("div", { className: "border-b border-dashed -mx-4 my-4" }), /* @__PURE__ */ Q(bt, {})] }, e)) : c.map((e, t) => /* @__PURE__ */ $("div", { children: [t > 0 && /* @__PURE__ */ Q("div", { className: "border-b border-dashed -mx-4 my-4" }), /* @__PURE__ */ Q(vt, {
1494
+ children: c ? o?.map((e, t) => /* @__PURE__ */ $("div", { children: [t > 0 && /* @__PURE__ */ Q("div", { className: "border-b border-dashed -mx-4 my-4" }), /* @__PURE__ */ Q(bt, {})] }, e)) : f.map((e, t) => /* @__PURE__ */ $("div", { children: [t > 0 && /* @__PURE__ */ Q("div", { className: "border-b border-dashed -mx-4 my-4" }), /* @__PURE__ */ Q(vt, {
1495
1495
  account: e.account,
1496
1496
  provider: e.provider
1497
1497
  })] }, e.key))
package/dist/plugins.js CHANGED
@@ -2692,18 +2692,18 @@ function zn({ className: n, socialLayout: i, socialPosition: a = "bottom", varia
2692
2692
  }
2693
2693
  let { mutate: ne, isPending: re } = ge(c, {
2694
2694
  onError: (e, { email: t }) => {
2695
- T(""), e.error?.code === "EMAIL_NOT_VERIFIED" ? q.danger(e.error?.message || e.message, { actionProps: {
2695
+ T(""), e.error?.code === "EMAIL_NOT_VERIFIED" && q.danger(e.error?.message || e.message, { actionProps: {
2696
2696
  children: f.auth.resend,
2697
2697
  onClick: () => ee({
2698
2698
  email: t,
2699
2699
  callbackURL: `${u}${g}`
2700
2700
  })
2701
- } }) : q.danger(e.error?.message || e.message), x();
2701
+ } }), x();
2702
2702
  },
2703
2703
  onSuccess: () => y({ to: g })
2704
2704
  }), { mutate: ie, isPending: ae } = ye(c, {
2705
- onError: (e) => {
2706
- T(""), q.danger(e.error?.message || e.message), x();
2705
+ onError: () => {
2706
+ T(""), x();
2707
2707
  },
2708
2708
  onSuccess: () => y({ to: g })
2709
2709
  }), oe = (e) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@better-auth-ui/heroui",
3
- "version": "1.6.13",
3
+ "version": "1.6.15",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "build": "vite build",
@@ -21,6 +21,7 @@ export function ErrorToaster() {
21
21
  if (!matchQuery({ queryKey: authQueryKeys.all }, query)) return
22
22
 
23
23
  const err = error as BetterFetchError
24
+ if (err?.error?.code === "EMAIL_NOT_VERIFIED") return
24
25
  if (err?.error) toast.danger(err.error.message)
25
26
  }
26
27
 
@@ -47,6 +48,7 @@ export function ErrorToaster() {
47
48
  }
48
49
 
49
50
  const err = error as BetterFetchError
51
+ if (err.error?.code === "EMAIL_NOT_VERIFIED") return
50
52
  toast.danger(err.error?.message || err.message)
51
53
  }
52
54
 
@@ -29,7 +29,7 @@ export type ForgotPasswordProps = {
29
29
  * Render a card-based "Forgot Password" form that sends a password-reset email.
30
30
  *
31
31
  * The form displays an email input, submit button, and a link back to sign-in.
32
- * Toasts are displayed on success or error via the `useRequestPasswordReset` hook.
32
+ * Success toasts are shown via `useRequestPasswordReset`; errors are handled globally by `ErrorToaster`.
33
33
  *
34
34
  * @param className - Optional additional CSS class names applied to the card
35
35
  * @returns The forgot-password form UI as a JSX element
@@ -54,8 +54,7 @@ export function ForgotPassword({
54
54
  const { mutate: requestPasswordReset, isPending } = useRequestPasswordReset(
55
55
  authClient,
56
56
  {
57
- onError: (error) => {
58
- toast.danger(error.error?.message || error.message)
57
+ onError: () => {
59
58
  resetFetchOptions()
60
59
  },
61
60
  onSuccess: () => {
@@ -139,11 +139,10 @@ function ChangePasswordForm({
139
139
  const [confirmPassword, setConfirmPassword] = useState("")
140
140
 
141
141
  const { mutate: changePassword, isPending } = useChangePassword(authClient, {
142
- onError: (error) => {
142
+ onError: () => {
143
143
  setCurrentPassword("")
144
144
  setNewPassword("")
145
145
  setConfirmPassword("")
146
- toast.danger(error.error?.message || error.message)
147
146
  },
148
147
  onSuccess: () => {
149
148
  setCurrentPassword("")
@@ -21,7 +21,12 @@ export function LinkedAccounts({
21
21
  variant,
22
22
  ...props
23
23
  }: LinkedAccountsProps & Omit<CardProps, "children">) {
24
- const { authClient, localization, socialProviders } = useAuth()
24
+ const {
25
+ authClient,
26
+ localization,
27
+ multipleAccountsPerProvider,
28
+ socialProviders
29
+ } = useAuth()
25
30
 
26
31
  const { data: accounts, isPending } = useListAccounts(authClient)
27
32
 
@@ -29,13 +34,20 @@ export function LinkedAccounts({
29
34
  (account) => account.providerId !== "credential"
30
35
  )
31
36
 
37
+ const linkedProviderIds = new Set(linkedAccounts?.map((a) => a.providerId))
38
+
39
+ const availableProviders =
40
+ multipleAccountsPerProvider === false
41
+ ? socialProviders?.filter((p) => !linkedProviderIds.has(p))
42
+ : socialProviders
43
+
32
44
  const allRows = [
33
45
  ...(linkedAccounts?.map((account) => ({
34
46
  key: account.id,
35
47
  account,
36
48
  provider: account.providerId
37
49
  })) ?? []),
38
- ...(socialProviders?.map((provider) => ({
50
+ ...(availableProviders?.map((provider) => ({
39
51
  key: provider,
40
52
  account: undefined,
41
53
  provider
@@ -87,8 +87,6 @@ export function SignIn({
87
87
  })
88
88
  }
89
89
  })
90
- } else {
91
- toast.danger(error.error?.message || error.message)
92
90
  }
93
91
 
94
92
  resetFetchOptions()
@@ -1,5 +1,5 @@
1
1
  import { useAuth, useSignOut } from "@better-auth-ui/react"
2
- import { cn, Spinner, toast } from "@heroui/react"
2
+ import { cn, Spinner } from "@heroui/react"
3
3
  import { useEffect, useRef } from "react"
4
4
 
5
5
  export type SignOutProps = {
@@ -15,8 +15,7 @@ export function SignOut({ className }: SignOutProps) {
15
15
  const { authClient, basePaths, navigate, viewPaths } = useAuth()
16
16
 
17
17
  const { mutate: signOut } = useSignOut(authClient, {
18
- onError: (error) => {
19
- toast.danger(error.error?.message || error.message)
18
+ onError: () => {
20
19
  navigate({
21
20
  to: `${basePaths.auth}/${viewPaths.auth.signIn}`,
22
21
  replace: true
@@ -71,10 +71,9 @@ export function SignUp({
71
71
  const { mutate: signUpEmail, isPending: signUpEmailPending } = useSignUpEmail(
72
72
  authClient,
73
73
  {
74
- onError: (error) => {
74
+ onError: () => {
75
75
  setPassword("")
76
76
  setConfirmPassword("")
77
- toast.danger(error.error?.message || error.message)
78
77
  resetFetchOptions()
79
78
  },
80
79
  onSuccess: () => {
@@ -95,8 +95,6 @@ export function SignInUsername({
95
95
  })
96
96
  }
97
97
  })
98
- } else {
99
- toast.danger(error.error?.message || error.message)
100
98
  }
101
99
 
102
100
  resetFetchOptions()
@@ -106,9 +104,8 @@ export function SignInUsername({
106
104
 
107
105
  const { mutate: signInUsername, isPending: isSignInUsernamePending } =
108
106
  useSignInUsername(authClient as UsernameAuthClient, {
109
- onError: (error) => {
107
+ onError: () => {
110
108
  setPassword("")
111
- toast.danger(error.error?.message || error.message)
112
109
  resetFetchOptions()
113
110
  },
114
111
  onSuccess: () => navigate({ to: redirectTo })