@better-auth-ui/heroui 1.6.28 → 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.
@@ -0,0 +1,150 @@
1
+ import { authMutationKeys as e, getEmailProviderLink as t, getProviderName as n } from "@better-auth-ui/core";
2
+ import { providerIcons as r, useAuth as i, useLastLoginMethod as a, useSession as o, useSignInSocial as s } from "@better-auth-ui/react";
3
+ import { ArrowUpRightFromSquare as c, Person as l } from "@gravity-ui/icons";
4
+ import { Avatar as u, Button as d, Chip as f, Link as p, Separator as m, Skeleton as h, Spinner as g, cn as _ } from "@heroui/react";
5
+ import { useMemo as v } from "react";
6
+ import { jsx as y, jsxs as b } from "react/jsx-runtime";
7
+ import { buttonVariants as x } from "@heroui/styles";
8
+ import { useIsMutating as S } from "@tanstack/react-query";
9
+ //#region src/components/auth/open-email-button.tsx
10
+ function C({ email: e, className: n }) {
11
+ let { localization: r } = i(), a = t(e);
12
+ return a ? /* @__PURE__ */ b(p, {
13
+ href: a.loginUrl,
14
+ target: "_blank",
15
+ rel: "noopener noreferrer",
16
+ className: _(x({ variant: "primary" }), "w-full gap-2", n),
17
+ children: [r.auth.openEmailProvider.replace("{{provider}}", a.companyProvider), /* @__PURE__ */ y(c, { className: "size-3" })]
18
+ }) : null;
19
+ }
20
+ //#endregion
21
+ //#region src/components/auth/field-separator.tsx
22
+ function w({ children: e }) {
23
+ return /* @__PURE__ */ b("div", {
24
+ className: "flex items-center gap-4",
25
+ children: [
26
+ /* @__PURE__ */ y(m, { className: "flex-1" }),
27
+ /* @__PURE__ */ y("p", {
28
+ className: "text-xs text-muted shrink-0",
29
+ children: e
30
+ }),
31
+ /* @__PURE__ */ y(m, { className: "flex-1" })
32
+ ]
33
+ });
34
+ }
35
+ //#endregion
36
+ //#region src/components/auth/last-login-method/last-used-badge.tsx
37
+ function T({ method: e, compact: t, floating: n }) {
38
+ let { method: r, localization: i } = a();
39
+ return !r || !(Array.isArray(e) ? e : [e]).includes(r) ? null : /* @__PURE__ */ y(f, {
40
+ className: _(n && "pointer-events-none absolute top-0 right-0 z-10 translate-x-1/4 -translate-y-1/2 shadow-sm"),
41
+ color: n ? "accent" : "default",
42
+ size: "sm",
43
+ variant: n ? "primary" : "secondary",
44
+ children: t || n ? i.lastUsedShort : i.lastUsed
45
+ });
46
+ }
47
+ //#endregion
48
+ //#region src/components/auth/provider-button.tsx
49
+ function E({ provider: t, display: a = "full", view: o = "signIn", variant: c = "tertiary", className: l, ...u }) {
50
+ let { authClient: f, baseURL: p, localization: m, redirectTo: h } = i(), v = `${p}${h}`, { mutate: x, isPending: C } = s(f), w = r[t];
51
+ return /* @__PURE__ */ b(d, {
52
+ variant: c,
53
+ isPending: S({ mutationKey: e.signIn.all }) + S({ mutationKey: e.signUp.all }) > 0,
54
+ onPress: () => x({
55
+ provider: t,
56
+ callbackURL: v
57
+ }),
58
+ className: _("relative overflow-visible", l),
59
+ ...u,
60
+ children: [
61
+ C ? /* @__PURE__ */ y(g, {
62
+ color: "current",
63
+ size: "sm"
64
+ }) : /* @__PURE__ */ y(w, {}),
65
+ a === "full" ? m.auth.continueWith.replace("{{provider}}", n(t)) : a === "name" ? n(t) : null,
66
+ a === "icon" && /* @__PURE__ */ y("span", {
67
+ className: "sr-only",
68
+ children: n(t)
69
+ }),
70
+ o !== "signUp" && /* @__PURE__ */ y(T, {
71
+ method: t,
72
+ floating: !0
73
+ })
74
+ ]
75
+ });
76
+ }
77
+ //#endregion
78
+ //#region src/components/auth/provider-buttons.tsx
79
+ function D({ socialLayout: e = "auto", view: t = "signIn" }) {
80
+ let { socialProviders: n } = i(), r = v(() => e === "auto" ? n?.length && n.length >= 4 ? "horizontal" : "vertical" : e, [e, n?.length]);
81
+ return /* @__PURE__ */ y("div", {
82
+ className: _("gap-3", r === "grid" && "grid grid-cols-2", r === "vertical" && "flex flex-col", r === "horizontal" && "flex flex-wrap"),
83
+ children: n?.map((e) => /* @__PURE__ */ y(E, {
84
+ provider: e,
85
+ view: t,
86
+ display: r === "vertical" ? "full" : r === "grid" ? "name" : "icon",
87
+ className: _("w-full", r === "horizontal" && "flex-1")
88
+ }, e))
89
+ });
90
+ }
91
+ //#endregion
92
+ //#region src/components/auth/user/user-avatar.tsx
93
+ function O({ className: e, fallback: t, isPending: n, user: r, size: a = "sm", style: s, ...c }) {
94
+ let { authClient: d } = i(), { data: f, isPending: p } = o(d, { enabled: !r && !n });
95
+ if ((n || p) && !r) return /* @__PURE__ */ y(h, {
96
+ className: _("rounded-full", a === "sm" ? "size-8" : a === "md" ? "size-10" : "size-12", e),
97
+ style: s
98
+ });
99
+ let m = r ?? f?.user, g = (m?.username || m?.name || m?.email)?.slice(0, 2).toUpperCase();
100
+ return /* @__PURE__ */ b(u, {
101
+ size: a,
102
+ className: _("rounded-full", e),
103
+ style: s,
104
+ ...c,
105
+ children: [/* @__PURE__ */ y(u.Image, {
106
+ alt: m?.displayUsername || m?.name || m?.email,
107
+ src: m?.image ?? void 0
108
+ }), /* @__PURE__ */ y(u.Fallback, {
109
+ className: _(a === "lg" ? "text-xl" : a === "md" ? "text-base" : "text-sm"),
110
+ delayMs: m?.image ? 600 : void 0,
111
+ children: t || g || /* @__PURE__ */ y(l, { className: "size-4" })
112
+ })]
113
+ });
114
+ }
115
+ //#endregion
116
+ //#region src/components/auth/user/user-view.tsx
117
+ function k({ className: e, isPending: t, size: n = "md", hideSubtitle: r = !1, user: a, ...s }) {
118
+ let { authClient: c } = i(), { data: l, isPending: u } = o(c, { enabled: !a && !t }), d = a ?? l?.user;
119
+ return (t || u) && !a ? /* @__PURE__ */ b("div", {
120
+ className: _("flex items-center gap-2 min-w-0", e),
121
+ ...s,
122
+ children: [/* @__PURE__ */ y(O, {
123
+ isPending: !0,
124
+ className: n === "sm" ? "size-5 [&>span]:text-xs" : void 0,
125
+ size: n === "lg" ? "md" : "sm"
126
+ }), /* @__PURE__ */ b("div", {
127
+ className: "flex flex-col gap-1 min-w-0",
128
+ children: [/* @__PURE__ */ y(h, { className: "h-3.5 w-24 rounded-lg" }), r ? null : /* @__PURE__ */ y(h, { className: "h-3 w-32 rounded-lg" })]
129
+ })]
130
+ }) : /* @__PURE__ */ b("div", {
131
+ className: _("flex items-center gap-2 min-w-0", e),
132
+ ...s,
133
+ children: [/* @__PURE__ */ y(O, {
134
+ className: n === "sm" ? "size-5 [&>span]:text-xs" : void 0,
135
+ user: d,
136
+ size: n === "lg" ? "md" : "sm"
137
+ }), /* @__PURE__ */ b("div", {
138
+ className: "flex flex-col min-w-0",
139
+ children: [/* @__PURE__ */ y("p", {
140
+ className: "text-foreground text-sm font-medium leading-tight truncate",
141
+ children: d?.displayUsername || d?.name || d?.email
142
+ }), !r && (d?.displayUsername || d?.name) ? /* @__PURE__ */ y("p", {
143
+ className: "text-muted text-xs leading-tight truncate overflow-x-hidden",
144
+ children: d?.email
145
+ }) : null]
146
+ })]
147
+ });
148
+ }
149
+ //#endregion
150
+ export { T as a, E as i, O as n, w as o, D as r, C as s, k as t };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@better-auth-ui/heroui",
3
- "version": "1.6.28",
3
+ "version": "1.6.29",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "build": "vite build",
@@ -0,0 +1,40 @@
1
+ import { useLastLoginMethod } from "@better-auth-ui/react"
2
+ import { Chip, cn } from "@heroui/react"
3
+
4
+ export type LastUsedBadgeProps = {
5
+ /** Login method IDs that should display the indicator. */
6
+ method: string | string[]
7
+ /** Use the shorter label in constrained layouts. */
8
+ compact?: boolean
9
+ /** Float the compact indicator over the top-right edge of its container. */
10
+ floating?: boolean
11
+ }
12
+
13
+ /**
14
+ * Displays an indicator when one of the supplied method IDs matches Better
15
+ * Auth's stored last login method.
16
+ */
17
+ export function LastUsedBadge({
18
+ method,
19
+ compact,
20
+ floating
21
+ }: LastUsedBadgeProps) {
22
+ const { method: lastLoginMethod, localization } = useLastLoginMethod()
23
+ const methods = Array.isArray(method) ? method : [method]
24
+
25
+ if (!lastLoginMethod || !methods.includes(lastLoginMethod)) return null
26
+
27
+ return (
28
+ <Chip
29
+ className={cn(
30
+ floating &&
31
+ "pointer-events-none absolute top-0 right-0 z-10 translate-x-1/4 -translate-y-1/2 shadow-sm"
32
+ )}
33
+ color={floating ? "accent" : "default"}
34
+ size="sm"
35
+ variant={floating ? "primary" : "secondary"}
36
+ >
37
+ {compact || floating ? localization.lastUsedShort : localization.lastUsed}
38
+ </Chip>
39
+ )
40
+ }
@@ -104,7 +104,7 @@ export function MagicLink({
104
104
  {socialPosition === "top" && (
105
105
  <>
106
106
  {!!socialProviders?.length && (
107
- <ProviderButtons socialLayout={socialLayout} />
107
+ <ProviderButtons socialLayout={socialLayout} view="magicLink" />
108
108
  )}
109
109
 
110
110
  {showSeparator && (
@@ -158,7 +158,7 @@ export function MagicLink({
158
158
  )}
159
159
 
160
160
  {!!socialProviders?.length && (
161
- <ProviderButtons socialLayout={socialLayout} />
161
+ <ProviderButtons socialLayout={socialLayout} view="magicLink" />
162
162
  )}
163
163
  </>
164
164
  )}
@@ -1,12 +1,18 @@
1
- import { authMutationKeys, getProviderName } from "@better-auth-ui/core"
1
+ import {
2
+ type AuthView,
3
+ authMutationKeys,
4
+ getProviderName
5
+ } from "@better-auth-ui/core"
2
6
  import { providerIcons, useAuth, useSignInSocial } from "@better-auth-ui/react"
3
- import { Button, type ButtonProps, Spinner } from "@heroui/react"
7
+ import { Button, type ButtonProps, cn, Spinner } from "@heroui/react"
4
8
  import { useIsMutating } from "@tanstack/react-query"
5
9
  import type { SocialProvider } from "better-auth/social-providers"
10
+ import { LastUsedBadge } from "./last-login-method/last-used-badge"
6
11
 
7
12
  export type ProviderButtonProps = {
8
13
  provider: SocialProvider
9
14
  display?: "full" | "name" | "icon"
15
+ view?: AuthView
10
16
  } & Omit<ButtonProps, "children" | "onPress" | "isPending" | "isDisabled">
11
17
 
12
18
  /**
@@ -18,7 +24,9 @@ export type ProviderButtonProps = {
18
24
  export function ProviderButton({
19
25
  provider,
20
26
  display = "full",
27
+ view = "signIn",
21
28
  variant = "tertiary",
29
+ className,
22
30
  ...props
23
31
  }: ProviderButtonProps) {
24
32
  const { authClient, baseURL, localization, redirectTo } = useAuth()
@@ -43,8 +51,8 @@ export function ProviderButton({
43
51
  variant={variant}
44
52
  isPending={isPending}
45
53
  onPress={() => signInSocial({ provider, callbackURL })}
54
+ className={cn("relative overflow-visible", className)}
46
55
  {...props}
47
- aria-label={getProviderName(provider)}
48
56
  >
49
57
  {signInSocialPending ? (
50
58
  <Spinner color="current" size="sm" />
@@ -60,6 +68,12 @@ export function ProviderButton({
60
68
  : display === "name"
61
69
  ? getProviderName(provider)
62
70
  : null}
71
+
72
+ {display === "icon" && (
73
+ <span className="sr-only">{getProviderName(provider)}</span>
74
+ )}
75
+
76
+ {view !== "signUp" && <LastUsedBadge method={provider} floating />}
63
77
  </Button>
64
78
  )
65
79
  }
@@ -1,9 +1,11 @@
1
+ import type { AuthView } from "@better-auth-ui/core"
1
2
  import { useAuth } from "@better-auth-ui/react"
2
3
  import { cn } from "@heroui/react"
3
4
  import { useMemo } from "react"
4
5
  import { ProviderButton } from "./provider-button"
5
6
  export type ProviderButtonsProps = {
6
7
  socialLayout?: SocialLayout
8
+ view?: AuthView
7
9
  }
8
10
 
9
11
  export type SocialLayout = "auto" | "horizontal" | "vertical" | "grid"
@@ -16,7 +18,8 @@ export type SocialLayout = "auto" | "horizontal" | "vertical" | "grid"
16
18
  * @returns The JSX element that renders the configured social provider buttons.
17
19
  */
18
20
  export function ProviderButtons({
19
- socialLayout = "auto"
21
+ socialLayout = "auto",
22
+ view = "signIn"
20
23
  }: ProviderButtonsProps) {
21
24
  const { socialProviders } = useAuth()
22
25
 
@@ -45,6 +48,7 @@ export function ProviderButtons({
45
48
  <ProviderButton
46
49
  key={provider}
47
50
  provider={provider}
51
+ view={view}
48
52
  display={
49
53
  resolvedSocialLayout === "vertical"
50
54
  ? "full"
@@ -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
  )}
@@ -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
+ )
package/src/plugins.ts CHANGED
@@ -4,6 +4,7 @@ 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"
9
10
  export * from "./components/auth/magic-link/magic-link-sent"
@@ -42,6 +43,7 @@ export * from "./components/auth/username/username-field"
42
43
  export * from "./lib/auth/api-key-plugin"
43
44
  export * from "./lib/auth/auth-plugin"
44
45
  export * from "./lib/auth/delete-user-plugin"
46
+ export * from "./lib/auth/last-login-method-plugin"
45
47
  export * from "./lib/auth/magic-link-plugin"
46
48
  export * from "./lib/auth/multi-session-plugin"
47
49
  export * from "./lib/auth/organization-plugin"
@@ -1,126 +0,0 @@
1
- import { authMutationKeys as e, getEmailProviderLink as t, getProviderName as n } from "@better-auth-ui/core";
2
- import { providerIcons as r, useAuth as i, useSession as a, useSignInSocial as o } from "@better-auth-ui/react";
3
- import { ArrowUpRightFromSquare as s, Person as c } from "@gravity-ui/icons";
4
- import { Avatar as l, Button as u, Link as d, Separator as f, Skeleton as p, Spinner as m, cn as h } from "@heroui/react";
5
- import { useMemo as g } from "react";
6
- import { jsx as _, jsxs as v } from "react/jsx-runtime";
7
- import { buttonVariants as y } from "@heroui/styles";
8
- import { useIsMutating as b } from "@tanstack/react-query";
9
- //#region src/components/auth/open-email-button.tsx
10
- function x({ email: e, className: n }) {
11
- let { localization: r } = i(), a = t(e);
12
- return a ? /* @__PURE__ */ v(d, {
13
- href: a.loginUrl,
14
- target: "_blank",
15
- rel: "noopener noreferrer",
16
- className: h(y({ variant: "primary" }), "w-full gap-2", n),
17
- children: [r.auth.openEmailProvider.replace("{{provider}}", a.companyProvider), /* @__PURE__ */ _(s, { className: "size-3" })]
18
- }) : null;
19
- }
20
- //#endregion
21
- //#region src/components/auth/field-separator.tsx
22
- function S({ children: e }) {
23
- return /* @__PURE__ */ v("div", {
24
- className: "flex items-center gap-4",
25
- children: [
26
- /* @__PURE__ */ _(f, { className: "flex-1" }),
27
- /* @__PURE__ */ _("p", {
28
- className: "text-xs text-muted shrink-0",
29
- children: e
30
- }),
31
- /* @__PURE__ */ _(f, { className: "flex-1" })
32
- ]
33
- });
34
- }
35
- //#endregion
36
- //#region src/components/auth/provider-button.tsx
37
- function C({ provider: t, display: a = "full", variant: s = "tertiary", ...c }) {
38
- let { authClient: l, baseURL: d, localization: f, redirectTo: p } = i(), h = `${d}${p}`, { mutate: g, isPending: y } = o(l), x = r[t];
39
- return /* @__PURE__ */ v(u, {
40
- variant: s,
41
- isPending: b({ mutationKey: e.signIn.all }) + b({ mutationKey: e.signUp.all }) > 0,
42
- onPress: () => g({
43
- provider: t,
44
- callbackURL: h
45
- }),
46
- ...c,
47
- "aria-label": n(t),
48
- children: [y ? /* @__PURE__ */ _(m, {
49
- color: "current",
50
- size: "sm"
51
- }) : /* @__PURE__ */ _(x, {}), a === "full" ? f.auth.continueWith.replace("{{provider}}", n(t)) : a === "name" ? n(t) : null]
52
- });
53
- }
54
- //#endregion
55
- //#region src/components/auth/provider-buttons.tsx
56
- function w({ socialLayout: e = "auto" }) {
57
- let { socialProviders: t } = i(), n = g(() => e === "auto" ? t?.length && t.length >= 4 ? "horizontal" : "vertical" : e, [e, t?.length]);
58
- return /* @__PURE__ */ _("div", {
59
- className: h("gap-3", n === "grid" && "grid grid-cols-2", n === "vertical" && "flex flex-col", n === "horizontal" && "flex flex-wrap"),
60
- children: t?.map((e) => /* @__PURE__ */ _(C, {
61
- provider: e,
62
- display: n === "vertical" ? "full" : n === "grid" ? "name" : "icon",
63
- className: h("w-full", n === "horizontal" && "flex-1")
64
- }, e))
65
- });
66
- }
67
- //#endregion
68
- //#region src/components/auth/user/user-avatar.tsx
69
- function T({ className: e, fallback: t, isPending: n, user: r, size: o = "sm", style: s, ...u }) {
70
- let { authClient: d } = i(), { data: f, isPending: m } = a(d, { enabled: !r && !n });
71
- if ((n || m) && !r) return /* @__PURE__ */ _(p, {
72
- className: h("rounded-full", o === "sm" ? "size-8" : o === "md" ? "size-10" : "size-12", e),
73
- style: s
74
- });
75
- let g = r ?? f?.user, y = (g?.username || g?.name || g?.email)?.slice(0, 2).toUpperCase();
76
- return /* @__PURE__ */ v(l, {
77
- size: o,
78
- className: h("rounded-full", e),
79
- style: s,
80
- ...u,
81
- children: [/* @__PURE__ */ _(l.Image, {
82
- alt: g?.displayUsername || g?.name || g?.email,
83
- src: g?.image ?? void 0
84
- }), /* @__PURE__ */ _(l.Fallback, {
85
- className: h(o === "lg" ? "text-xl" : o === "md" ? "text-base" : "text-sm"),
86
- delayMs: g?.image ? 600 : void 0,
87
- children: t || y || /* @__PURE__ */ _(c, { className: "size-4" })
88
- })]
89
- });
90
- }
91
- //#endregion
92
- //#region src/components/auth/user/user-view.tsx
93
- function E({ className: e, isPending: t, size: n = "md", hideSubtitle: r = !1, user: o, ...s }) {
94
- let { authClient: c } = i(), { data: l, isPending: u } = a(c, { enabled: !o && !t }), d = o ?? l?.user;
95
- return (t || u) && !o ? /* @__PURE__ */ v("div", {
96
- className: h("flex items-center gap-2 min-w-0", e),
97
- ...s,
98
- children: [/* @__PURE__ */ _(T, {
99
- isPending: !0,
100
- className: n === "sm" ? "size-5 [&>span]:text-xs" : void 0,
101
- size: n === "lg" ? "md" : "sm"
102
- }), /* @__PURE__ */ v("div", {
103
- className: "flex flex-col gap-1 min-w-0",
104
- children: [/* @__PURE__ */ _(p, { className: "h-3.5 w-24 rounded-lg" }), r ? null : /* @__PURE__ */ _(p, { className: "h-3 w-32 rounded-lg" })]
105
- })]
106
- }) : /* @__PURE__ */ v("div", {
107
- className: h("flex items-center gap-2 min-w-0", e),
108
- ...s,
109
- children: [/* @__PURE__ */ _(T, {
110
- className: n === "sm" ? "size-5 [&>span]:text-xs" : void 0,
111
- user: d,
112
- size: n === "lg" ? "md" : "sm"
113
- }), /* @__PURE__ */ v("div", {
114
- className: "flex flex-col min-w-0",
115
- children: [/* @__PURE__ */ _("p", {
116
- className: "text-foreground text-sm font-medium leading-tight truncate",
117
- children: d?.displayUsername || d?.name || d?.email
118
- }), !r && (d?.displayUsername || d?.name) ? /* @__PURE__ */ _("p", {
119
- className: "text-muted text-xs leading-tight truncate overflow-x-hidden",
120
- children: d?.email
121
- }) : null]
122
- })]
123
- });
124
- }
125
- //#endregion
126
- export { S as a, C as i, T as n, x as o, w as r, E as t };