@better-auth-ui/heroui 1.6.12 → 1.6.14

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 });
@@ -903,17 +903,19 @@ function it({ path: e, socialLayout: t, socialPosition: n, view: r, ...i }) {
903
903
  function at() {
904
904
  let e = Ge();
905
905
  return ze(() => {
906
- let t = e.getQueryCache().subscribe((e) => {
907
- if (e.type !== "updated" || e.action.type !== "error" || !Ue({ queryKey: o.all }, e.query)) return;
908
- let t = e.action.error;
909
- t?.error && Y.danger(t.error.message);
910
- }), n = e.getMutationCache().subscribe((e) => {
911
- if (e.type !== "updated" || e.action.type !== "error" || !He({ mutationKey: a.all }, e.mutation)) return;
912
- let t = e.action.error;
913
- Y.danger(t.error?.message || t.message);
914
- });
915
- return () => {
916
- t(), n();
906
+ let t = e.getQueryCache(), n = t.config.onError;
907
+ t.config.onError = (e, t) => {
908
+ if (n?.(e, t), !Ue({ queryKey: o.all }, t)) return;
909
+ let r = e;
910
+ r?.error?.code !== "EMAIL_NOT_VERIFIED" && r?.error && Y.danger(r.error.message);
911
+ };
912
+ let r = e.getMutationCache(), i = r.config.onError;
913
+ return r.config.onError = (e, t, n, r, o) => {
914
+ if (i?.(e, t, n, r, o), !He({ mutationKey: a.all }, r)) return;
915
+ let s = e;
916
+ s.error?.code !== "EMAIL_NOT_VERIFIED" && Y.danger(s.error?.message || s.message);
917
+ }, () => {
918
+ t.config.onError = n, r.config.onError = i;
917
919
  };
918
920
  }, [e]), null;
919
921
  }
@@ -1286,8 +1288,8 @@ function gt({ className: e, variant: t, ...n }) {
1286
1288
  }
1287
1289
  function _t({ className: e, variant: t, emailAndPassword: n, localization: r, session: i, ...a }) {
1288
1290
  let { authClient: o } = m(), [s, c] = X(""), [l, u] = X(""), [d, f] = X(""), { mutate: p, isPending: h } = _(o, {
1289
- onError: (e) => {
1290
- c(""), u(""), f(""), Y.danger(e.error?.message || e.message);
1291
+ onError: () => {
1292
+ c(""), u(""), f("");
1291
1293
  },
1292
1294
  onSuccess: () => {
1293
1295
  c(""), u(""), f(""), Y.success(r.settings.changePasswordSuccess);
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.12",
3
+ "version": "1.6.14",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "build": "vite build",
@@ -35,7 +35,7 @@
35
35
  "@gravity-ui/icons": "^2.18.0",
36
36
  "@heroui/react": "^3.1.0",
37
37
  "@heroui/styles": "^3.1.0",
38
- "@internationalized/date": "^3.12.1",
38
+ "@internationalized/date": "^3.12.2",
39
39
  "@tanstack/react-pacer": "^0.22.1",
40
40
  "@tanstack/react-query": "^5.100.14",
41
41
  "@testing-library/react": "^16.3.2",
@@ -56,7 +56,7 @@
56
56
  "@gravity-ui/icons": ">=2.18.0",
57
57
  "@heroui/react": ">=3.1.0",
58
58
  "@heroui/styles": ">=3.1.0",
59
- "@internationalized/date": ">=3.12.1",
59
+ "@internationalized/date": ">=3.12.2",
60
60
  "@tanstack/react-pacer": ">=0.22.1",
61
61
  "@tanstack/react-query": ">=5.100.14",
62
62
  "better-auth": ">=1.6.11",
@@ -8,6 +8,7 @@ import {
8
8
  ComboBox,
9
9
  DateField,
10
10
  DatePicker,
11
+ type DateValue,
11
12
  FieldError,
12
13
  Input,
13
14
  InputGroup,
@@ -387,7 +388,7 @@ export function AdditionalField({
387
388
  <DatePicker
388
389
  className="w-full [&[data-required=true]>.label]:after:content-none"
389
390
  name={name}
390
- defaultValue={defaultValue}
391
+ defaultValue={defaultValue as unknown as DateValue}
391
392
  granularity={isDateTime ? "minute" : "day"}
392
393
  isDisabled={isPending}
393
394
  isReadOnly={field.readOnly}
@@ -12,30 +12,49 @@ export function ErrorToaster() {
12
12
  const queryClient = useQueryClient()
13
13
 
14
14
  useEffect(() => {
15
- const unsubscribeQuery = queryClient.getQueryCache().subscribe((event) => {
16
- if (event.type !== "updated" || event.action.type !== "error") return
17
- if (!matchQuery({ queryKey: authQueryKeys.all }, event.query)) return
15
+ const queryCache = queryClient.getQueryCache()
16
+ const previousQueryOnError = queryCache.config.onError
18
17
 
19
- const err = event.action.error as BetterFetchError
18
+ queryCache.config.onError = (error, query) => {
19
+ previousQueryOnError?.(error, query)
20
+
21
+ if (!matchQuery({ queryKey: authQueryKeys.all }, query)) return
22
+
23
+ const err = error as BetterFetchError
24
+ if (err?.error?.code === "EMAIL_NOT_VERIFIED") return
20
25
  if (err?.error) toast.danger(err.error.message)
21
- })
26
+ }
22
27
 
23
- const unsubscribeMutation = queryClient
24
- .getMutationCache()
25
- .subscribe((event) => {
26
- if (event.type !== "updated" || event.action.type !== "error") return
27
- if (
28
- !matchMutation({ mutationKey: authMutationKeys.all }, event.mutation)
29
- )
30
- return
28
+ const mutationCache = queryClient.getMutationCache()
29
+ const previousMutationOnError = mutationCache.config.onError
31
30
 
32
- const err = event.action.error as BetterFetchError
33
- toast.danger(err.error?.message || err.message)
34
- })
31
+ mutationCache.config.onError = (
32
+ error,
33
+ variables,
34
+ onMutateResult,
35
+ mutation,
36
+ context
37
+ ) => {
38
+ previousMutationOnError?.(
39
+ error,
40
+ variables,
41
+ onMutateResult,
42
+ mutation,
43
+ context
44
+ )
45
+
46
+ if (!matchMutation({ mutationKey: authMutationKeys.all }, mutation)) {
47
+ return
48
+ }
49
+
50
+ const err = error as BetterFetchError
51
+ if (err.error?.code === "EMAIL_NOT_VERIFIED") return
52
+ toast.danger(err.error?.message || err.message)
53
+ }
35
54
 
36
55
  return () => {
37
- unsubscribeQuery()
38
- unsubscribeMutation()
56
+ queryCache.config.onError = previousQueryOnError
57
+ mutationCache.config.onError = previousMutationOnError
39
58
  }
40
59
  }, [queryClient])
41
60
 
@@ -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("")
@@ -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 })