@better-auth-ui/heroui 1.6.27 → 1.6.29

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 (31) hide show
  1. package/dist/components/auth/forgot-password.d.ts +3 -1
  2. package/dist/components/auth/last-login-method/last-used-badge.d.ts +13 -0
  3. package/dist/components/auth/magic-link/magic-link-sent.d.ts +20 -0
  4. package/dist/components/auth/provider-button.d.ts +3 -1
  5. package/dist/components/auth/provider-buttons.d.ts +3 -1
  6. package/dist/components/auth/reset-link-sent.d.ts +20 -0
  7. package/dist/index.d.ts +1 -0
  8. package/dist/index.js +280 -220
  9. package/dist/lib/auth/last-login-method-plugin.d.ts +12 -0
  10. package/dist/lib/auth/magic-link-plugin.d.ts +4 -0
  11. package/dist/plugins.d.ts +3 -0
  12. package/dist/plugins.js +1070 -1005
  13. package/dist/user-view-D9ial2fQ.js +150 -0
  14. package/package.json +1 -1
  15. package/src/components/auth/auth.tsx +8 -1
  16. package/src/components/auth/forgot-password.tsx +9 -6
  17. package/src/components/auth/last-login-method/last-used-badge.tsx +40 -0
  18. package/src/components/auth/magic-link/magic-link-sent.tsx +84 -0
  19. package/src/components/auth/magic-link/magic-link.tsx +12 -8
  20. package/src/components/auth/provider-button.tsx +17 -3
  21. package/src/components/auth/provider-buttons.tsx +5 -1
  22. package/src/components/auth/reset-link-sent.tsx +80 -0
  23. package/src/components/auth/settings/security/change-password.tsx +32 -14
  24. package/src/components/auth/sign-in.tsx +10 -3
  25. package/src/components/auth/sign-up.tsx +2 -2
  26. package/src/components/auth/username/sign-in-username.tsx +6 -3
  27. package/src/index.tsx +1 -0
  28. package/src/lib/auth/last-login-method-plugin.ts +12 -0
  29. package/src/lib/auth/magic-link-plugin.ts +2 -1
  30. package/src/plugins.ts +3 -0
  31. package/dist/user-view--47tVtJ3.js +0 -113
@@ -19,6 +19,7 @@ import { useIsMutating } from "@tanstack/react-query"
19
19
  import { type SyntheticEvent, useState } from "react"
20
20
 
21
21
  import { FieldSeparator } from "./field-separator"
22
+ import { LastUsedBadge } from "./last-login-method/last-used-badge"
22
23
  import { ProviderButtons, type SocialLayout } from "./provider-buttons"
23
24
 
24
25
  export interface SignInProps {
@@ -118,7 +119,7 @@ export function SignIn({
118
119
  {socialPosition === "top" && (
119
120
  <>
120
121
  {!!socialProviders?.length && (
121
- <ProviderButtons socialLayout={socialLayout} />
122
+ <ProviderButtons socialLayout={socialLayout} view="signIn" />
122
123
  )}
123
124
 
124
125
  {showSeparator && (
@@ -206,10 +207,16 @@ export function SignIn({
206
207
  {Captcha && <div className="flex justify-center">{Captcha}</div>}
207
208
 
208
209
  <div className="flex flex-col gap-3">
209
- <Button type="submit" className="w-full" isPending={isPending}>
210
+ <Button
211
+ type="submit"
212
+ className="relative w-full overflow-visible"
213
+ isPending={isPending}
214
+ >
210
215
  {signInEmailPending && <Spinner color="current" size="sm" />}
211
216
 
212
217
  {localization.auth.signIn}
218
+
219
+ <LastUsedBadge method="email" floating />
213
220
  </Button>
214
221
 
215
222
  {plugins.flatMap((plugin) =>
@@ -231,7 +238,7 @@ export function SignIn({
231
238
  )}
232
239
 
233
240
  {!!socialProviders?.length && (
234
- <ProviderButtons socialLayout={socialLayout} />
241
+ <ProviderButtons socialLayout={socialLayout} view="signIn" />
235
242
  )}
236
243
  </>
237
244
  )}
@@ -168,7 +168,7 @@ export function SignUp({
168
168
  {socialPosition === "top" && (
169
169
  <>
170
170
  {!!socialProviders?.length && (
171
- <ProviderButtons socialLayout={socialLayout} />
171
+ <ProviderButtons socialLayout={socialLayout} view="signUp" />
172
172
  )}
173
173
 
174
174
  {showSeparator && (
@@ -396,7 +396,7 @@ export function SignUp({
396
396
  )}
397
397
 
398
398
  {!!socialProviders?.length && (
399
- <ProviderButtons socialLayout={socialLayout} />
399
+ <ProviderButtons socialLayout={socialLayout} view="signUp" />
400
400
  )}
401
401
  </>
402
402
  )}
@@ -26,6 +26,7 @@ import { useIsMutating } from "@tanstack/react-query"
26
26
  import { type SyntheticEvent, useState } from "react"
27
27
  import { usernamePlugin } from "../../../lib/auth/username-plugin"
28
28
  import { FieldSeparator } from "../field-separator"
29
+ import { LastUsedBadge } from "../last-login-method/last-used-badge"
29
30
  import { ProviderButtons, type SocialLayout } from "../provider-buttons"
30
31
 
31
32
  export interface SignInUsernameProps {
@@ -163,7 +164,7 @@ export function SignInUsername({
163
164
  {socialPosition === "top" && (
164
165
  <>
165
166
  {!!socialProviders?.length && (
166
- <ProviderButtons socialLayout={socialLayout} />
167
+ <ProviderButtons socialLayout={socialLayout} view="signIn" />
167
168
  )}
168
169
 
169
170
  {showSeparator && (
@@ -251,12 +252,14 @@ export function SignInUsername({
251
252
  <div className="flex flex-col gap-3">
252
253
  <Button
253
254
  type="submit"
254
- className="w-full"
255
+ className="relative w-full overflow-visible"
255
256
  isPending={isSignInPending || isPending}
256
257
  >
257
258
  {isSignInPending && <Spinner color="current" size="sm" />}
258
259
 
259
260
  {localization.auth.signIn}
261
+
262
+ <LastUsedBadge method={["email", "username"]} floating />
260
263
  </Button>
261
264
 
262
265
  {plugins.flatMap((plugin) =>
@@ -278,7 +281,7 @@ export function SignInUsername({
278
281
  )}
279
282
 
280
283
  {!!socialProviders?.length && (
281
- <ProviderButtons socialLayout={socialLayout} />
284
+ <ProviderButtons socialLayout={socialLayout} view="signIn" />
282
285
  )}
283
286
  </>
284
287
  )}
package/src/index.tsx CHANGED
@@ -7,6 +7,7 @@ export * from "./components/auth/forgot-password"
7
7
  export * from "./components/auth/open-email-button"
8
8
  export * from "./components/auth/provider-button"
9
9
  export * from "./components/auth/provider-buttons"
10
+ export * from "./components/auth/reset-link-sent"
10
11
  export * from "./components/auth/reset-password"
11
12
  export * from "./components/auth/settings/account/account-settings"
12
13
  export * from "./components/auth/settings/account/change-email"
@@ -0,0 +1,12 @@
1
+ import { createAuthPlugin } from "@better-auth-ui/core"
2
+ import {
3
+ lastLoginMethodPlugin as coreLastLoginMethodPlugin,
4
+ type LastLoginMethodPluginOptions
5
+ } from "@better-auth-ui/core/plugins"
6
+
7
+ export const lastLoginMethodPlugin = createAuthPlugin(
8
+ coreLastLoginMethodPlugin.id,
9
+ (options: LastLoginMethodPluginOptions = {}) => ({
10
+ ...coreLastLoginMethodPlugin(options)
11
+ })
12
+ )
@@ -6,6 +6,7 @@ import {
6
6
 
7
7
  import { MagicLink } from "../../components/auth/magic-link/magic-link"
8
8
  import { MagicLinkButton } from "../../components/auth/magic-link/magic-link-button"
9
+ import { MagicLinkSent } from "../../components/auth/magic-link/magic-link-sent"
9
10
 
10
11
  export const magicLinkPlugin = createAuthPlugin(
11
12
  coreMagicLinkPlugin.id,
@@ -13,7 +14,7 @@ export const magicLinkPlugin = createAuthPlugin(
13
14
  ...coreMagicLinkPlugin(options),
14
15
  authButtons: [MagicLinkButton],
15
16
  views: {
16
- auth: { magicLink: MagicLink }
17
+ auth: { magicLink: MagicLink, magicLinkSent: MagicLinkSent }
17
18
  },
18
19
  // Conditional, not an override: when `emailAndPassword.enabled === false`
19
20
  // the `<Auth>` router renders this at `/auth/sign-in` instead of the
package/src/plugins.ts CHANGED
@@ -4,8 +4,10 @@ export * from "./components/auth/api-key/api-keys"
4
4
  export * from "./components/auth/api-key/organization-api-keys"
5
5
  export * from "./components/auth/delete-user/danger-zone"
6
6
  export * from "./components/auth/delete-user/delete-account"
7
+ export * from "./components/auth/last-login-method/last-used-badge"
7
8
  // Plugin-contributed components that may be used standalone
8
9
  export * from "./components/auth/magic-link/magic-link"
10
+ export * from "./components/auth/magic-link/magic-link-sent"
9
11
  export * from "./components/auth/multi-session/manage-account"
10
12
  export * from "./components/auth/multi-session/manage-accounts"
11
13
  export * from "./components/auth/multi-session/switch-account-submenu"
@@ -41,6 +43,7 @@ export * from "./components/auth/username/username-field"
41
43
  export * from "./lib/auth/api-key-plugin"
42
44
  export * from "./lib/auth/auth-plugin"
43
45
  export * from "./lib/auth/delete-user-plugin"
46
+ export * from "./lib/auth/last-login-method-plugin"
44
47
  export * from "./lib/auth/magic-link-plugin"
45
48
  export * from "./lib/auth/multi-session-plugin"
46
49
  export * from "./lib/auth/organization-plugin"
@@ -1,113 +0,0 @@
1
- import { authMutationKeys as e, getProviderName as t } from "@better-auth-ui/core";
2
- import { providerIcons as n, useAuth as r, useSession as i, useSignInSocial as a } from "@better-auth-ui/react";
3
- import { Person as o } from "@gravity-ui/icons";
4
- import { Avatar as s, Button as c, Separator as l, Skeleton as u, Spinner as d, cn as f } from "@heroui/react";
5
- import { useMemo as p } from "react";
6
- import { jsx as m, jsxs as h } from "react/jsx-runtime";
7
- import { useIsMutating as g } from "@tanstack/react-query";
8
- //#region src/components/auth/field-separator.tsx
9
- function _({ children: e }) {
10
- return /* @__PURE__ */ h("div", {
11
- className: "flex items-center gap-4",
12
- children: [
13
- /* @__PURE__ */ m(l, { className: "flex-1" }),
14
- /* @__PURE__ */ m("p", {
15
- className: "text-xs text-muted shrink-0",
16
- children: e
17
- }),
18
- /* @__PURE__ */ m(l, { className: "flex-1" })
19
- ]
20
- });
21
- }
22
- //#endregion
23
- //#region src/components/auth/provider-button.tsx
24
- function v({ provider: i, display: o = "full", variant: s = "tertiary", ...l }) {
25
- let { authClient: u, baseURL: f, localization: p, redirectTo: _ } = r(), v = `${f}${_}`, { mutate: y, isPending: b } = a(u), x = n[i];
26
- return /* @__PURE__ */ h(c, {
27
- variant: s,
28
- isPending: g({ mutationKey: e.signIn.all }) + g({ mutationKey: e.signUp.all }) > 0,
29
- onPress: () => y({
30
- provider: i,
31
- callbackURL: v
32
- }),
33
- ...l,
34
- "aria-label": t(i),
35
- children: [b ? /* @__PURE__ */ m(d, {
36
- color: "current",
37
- size: "sm"
38
- }) : /* @__PURE__ */ m(x, {}), o === "full" ? p.auth.continueWith.replace("{{provider}}", t(i)) : o === "name" ? t(i) : null]
39
- });
40
- }
41
- //#endregion
42
- //#region src/components/auth/provider-buttons.tsx
43
- function y({ socialLayout: e = "auto" }) {
44
- let { socialProviders: t } = r(), n = p(() => e === "auto" ? t?.length && t.length >= 4 ? "horizontal" : "vertical" : e, [e, t?.length]);
45
- return /* @__PURE__ */ m("div", {
46
- className: f("gap-3", n === "grid" && "grid grid-cols-2", n === "vertical" && "flex flex-col", n === "horizontal" && "flex flex-wrap"),
47
- children: t?.map((e) => /* @__PURE__ */ m(v, {
48
- provider: e,
49
- display: n === "vertical" ? "full" : n === "grid" ? "name" : "icon",
50
- className: f("w-full", n === "horizontal" && "flex-1")
51
- }, e))
52
- });
53
- }
54
- //#endregion
55
- //#region src/components/auth/user/user-avatar.tsx
56
- function b({ className: e, fallback: t, isPending: n, user: a, size: c = "sm", style: l, ...d }) {
57
- let { authClient: p } = r(), { data: g, isPending: _ } = i(p, { enabled: !a && !n });
58
- if ((n || _) && !a) return /* @__PURE__ */ m(u, {
59
- className: f("rounded-full", c === "sm" ? "size-8" : c === "md" ? "size-10" : "size-12", e),
60
- style: l
61
- });
62
- let v = a ?? g?.user, y = (v?.username || v?.name || v?.email)?.slice(0, 2).toUpperCase();
63
- return /* @__PURE__ */ h(s, {
64
- size: c,
65
- className: f("rounded-full", e),
66
- style: l,
67
- ...d,
68
- children: [/* @__PURE__ */ m(s.Image, {
69
- alt: v?.displayUsername || v?.name || v?.email,
70
- src: v?.image ?? void 0
71
- }), /* @__PURE__ */ m(s.Fallback, {
72
- className: f(c === "lg" ? "text-xl" : c === "md" ? "text-base" : "text-sm"),
73
- delayMs: v?.image ? 600 : void 0,
74
- children: t || y || /* @__PURE__ */ m(o, { className: "size-4" })
75
- })]
76
- });
77
- }
78
- //#endregion
79
- //#region src/components/auth/user/user-view.tsx
80
- function x({ className: e, isPending: t, size: n = "md", hideSubtitle: a = !1, user: o, ...s }) {
81
- let { authClient: c } = r(), { data: l, isPending: d } = i(c, { enabled: !o && !t }), p = o ?? l?.user;
82
- return (t || d) && !o ? /* @__PURE__ */ h("div", {
83
- className: f("flex items-center gap-2 min-w-0", e),
84
- ...s,
85
- children: [/* @__PURE__ */ m(b, {
86
- isPending: !0,
87
- className: n === "sm" ? "size-5 [&>span]:text-xs" : void 0,
88
- size: n === "lg" ? "md" : "sm"
89
- }), /* @__PURE__ */ h("div", {
90
- className: "flex flex-col gap-1 min-w-0",
91
- children: [/* @__PURE__ */ m(u, { className: "h-3.5 w-24 rounded-lg" }), a ? null : /* @__PURE__ */ m(u, { className: "h-3 w-32 rounded-lg" })]
92
- })]
93
- }) : /* @__PURE__ */ h("div", {
94
- className: f("flex items-center gap-2 min-w-0", e),
95
- ...s,
96
- children: [/* @__PURE__ */ m(b, {
97
- className: n === "sm" ? "size-5 [&>span]:text-xs" : void 0,
98
- user: p,
99
- size: n === "lg" ? "md" : "sm"
100
- }), /* @__PURE__ */ h("div", {
101
- className: "flex flex-col min-w-0",
102
- children: [/* @__PURE__ */ m("p", {
103
- className: "text-foreground text-sm font-medium leading-tight truncate",
104
- children: p?.displayUsername || p?.name || p?.email
105
- }), !a && (p?.displayUsername || p?.name) ? /* @__PURE__ */ m("p", {
106
- className: "text-muted text-xs leading-tight truncate overflow-x-hidden",
107
- children: p?.email
108
- }) : null]
109
- })]
110
- });
111
- }
112
- //#endregion
113
- export { _ as a, v as i, b as n, y as r, x as t };