@better-auth-ui/heroui 1.6.4 → 1.6.6
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.
- package/dist/components/auth/delete-user/danger-zone.d.ts +3 -2
- package/dist/components/auth/delete-user/danger-zone.js +1 -1
- package/dist/components/auth/delete-user/delete-user.js +53 -53
- package/dist/components/auth/forgot-password.js +67 -48
- package/dist/components/auth/sign-in.js +72 -67
- package/dist/components/auth/sign-up.js +82 -77
- package/dist/components/auth/theme/theme-toggle-item.js +50 -46
- package/dist/components/auth/user/user-button.d.ts +27 -2
- package/dist/components/auth/user/user-button.js +48 -29
- package/dist/components/auth/username/sign-in-username.js +80 -74
- package/dist/components/auth/username/username-field.js +4 -2
- package/package.json +12 -12
- package/src/components/auth/delete-user/danger-zone.tsx +10 -3
- package/src/components/auth/delete-user/delete-user.tsx +2 -7
- package/src/components/auth/forgot-password.tsx +29 -7
- package/src/components/auth/sign-in.tsx +13 -1
- package/src/components/auth/sign-up.tsx +12 -2
- package/src/components/auth/theme/theme-toggle-item.tsx +2 -1
- package/src/components/auth/user/user-button.tsx +80 -13
- package/src/components/auth/username/sign-in-username.tsx +40 -24
- package/src/components/auth/username/username-field.tsx +4 -2
|
@@ -2,197 +2,202 @@ import { AdditionalField as e } from "./additional-field.js";
|
|
|
2
2
|
import { FieldSeparator as t } from "./field-separator.js";
|
|
3
3
|
import { ProviderButtons as n } from "./provider-buttons.js";
|
|
4
4
|
import { authMutationKeys as r, parseAdditionalFieldValue as i } from "@better-auth-ui/core";
|
|
5
|
-
import { useAuth as a,
|
|
5
|
+
import { useAuth as a, useFetchOptions as o, useSignUpEmail as ee } from "@better-auth-ui/react";
|
|
6
6
|
import { Eye as s, EyeSlash as c } from "@gravity-ui/icons";
|
|
7
|
-
import { Button as l, Card as u, Description as d, FieldError as f, Form as
|
|
8
|
-
import { useState as
|
|
9
|
-
import { Fragment as
|
|
10
|
-
import { useIsMutating as
|
|
7
|
+
import { Button as l, Card as u, Description as d, FieldError as f, Form as te, Input as p, InputGroup as m, Label as h, Link as g, Spinner as _, TextField as v, cn as y, toast as b } from "@heroui/react";
|
|
8
|
+
import { useState as x } from "react";
|
|
9
|
+
import { Fragment as S, jsx as C, jsxs as w } from "react/jsx-runtime";
|
|
10
|
+
import { useIsMutating as T } from "@tanstack/react-query";
|
|
11
11
|
//#region src/components/auth/sign-up.tsx
|
|
12
|
-
function
|
|
13
|
-
let { additionalFields:
|
|
12
|
+
function E({ className: E, socialLayout: D, socialPosition: O = "bottom", variant: k, ...A }) {
|
|
13
|
+
let { additionalFields: j, authClient: M, basePaths: N, emailAndPassword: P, localization: F, plugins: I, redirectTo: L, socialProviders: R, viewPaths: z, navigate: B } = a(), { fetchOptions: V, resetFetchOptions: H } = o(), [U, W] = x(""), [G, K] = x(""), { mutate: q, isPending: J } = ee(M, {
|
|
14
14
|
onError: (e) => {
|
|
15
|
-
|
|
15
|
+
W(""), K(""), b.danger(e.error?.message || e.message), H();
|
|
16
16
|
},
|
|
17
17
|
onSuccess: () => {
|
|
18
|
-
P?.requireEmailVerification ? (
|
|
18
|
+
P?.requireEmailVerification ? (b.success(F.auth.verifyYourEmail), B({ to: `${N.auth}/${z.auth.signIn}` })) : B({ to: L });
|
|
19
19
|
}
|
|
20
|
-
}), [
|
|
20
|
+
}), [Y, ne] = x(!1), [X, re] = x(!1), Z = T({ mutationKey: r.signIn.all }) + T({ mutationKey: r.signUp.all }) > 0, Q = I.find((e) => e.captchaComponent)?.captchaComponent, ie = async (e) => {
|
|
21
21
|
e.preventDefault();
|
|
22
22
|
let t = new FormData(e.currentTarget), n = t.get("name") ?? "", r = t.get("email");
|
|
23
|
-
if (P?.confirmPassword &&
|
|
24
|
-
|
|
23
|
+
if (P?.confirmPassword && U !== G) {
|
|
24
|
+
b.danger(F.auth.passwordsDoNotMatch), W(""), K("");
|
|
25
25
|
return;
|
|
26
26
|
}
|
|
27
27
|
let a = {};
|
|
28
|
-
for (let e of
|
|
28
|
+
for (let e of j ?? []) {
|
|
29
29
|
if (!e.signUp || e.readOnly) continue;
|
|
30
30
|
let n = i(e, t.get(e.name));
|
|
31
31
|
if (e.validate) try {
|
|
32
32
|
await e.validate(n);
|
|
33
33
|
} catch (e) {
|
|
34
|
-
|
|
34
|
+
b.danger(e instanceof Error ? e.message : String(e));
|
|
35
35
|
return;
|
|
36
36
|
}
|
|
37
37
|
n !== void 0 && (a[e.name] = n);
|
|
38
38
|
}
|
|
39
|
-
|
|
39
|
+
q({
|
|
40
40
|
name: n,
|
|
41
41
|
email: r,
|
|
42
|
-
password:
|
|
43
|
-
...a
|
|
42
|
+
password: U,
|
|
43
|
+
...a,
|
|
44
|
+
fetchOptions: V
|
|
44
45
|
});
|
|
45
46
|
}, $ = P?.enabled && !!R?.length;
|
|
46
|
-
return /* @__PURE__ */
|
|
47
|
-
className:
|
|
48
|
-
variant:
|
|
49
|
-
...
|
|
47
|
+
return /* @__PURE__ */ w(u, {
|
|
48
|
+
className: y("w-full max-w-sm gap-4 md:p-6", E),
|
|
49
|
+
variant: k,
|
|
50
|
+
...A,
|
|
50
51
|
children: [
|
|
51
|
-
/* @__PURE__ */
|
|
52
|
+
/* @__PURE__ */ C(u.Header, { children: /* @__PURE__ */ C(u.Title, {
|
|
52
53
|
className: "text-xl font-semibold mb-1",
|
|
53
54
|
children: F.auth.signUp
|
|
54
55
|
}) }),
|
|
55
|
-
/* @__PURE__ */
|
|
56
|
+
/* @__PURE__ */ w(u.Content, {
|
|
56
57
|
className: "gap-4",
|
|
57
58
|
children: [
|
|
58
|
-
|
|
59
|
-
P?.enabled && /* @__PURE__ */
|
|
60
|
-
onSubmit:
|
|
59
|
+
O === "top" && /* @__PURE__ */ w(S, { children: [!!R?.length && /* @__PURE__ */ C(n, { socialLayout: D }), $ && /* @__PURE__ */ C(t, { children: F.auth.or })] }),
|
|
60
|
+
P?.enabled && /* @__PURE__ */ w(te, {
|
|
61
|
+
onSubmit: ie,
|
|
61
62
|
className: "flex flex-col gap-4",
|
|
62
63
|
children: [
|
|
63
|
-
P.name !== !1 && /* @__PURE__ */
|
|
64
|
+
P.name !== !1 && /* @__PURE__ */ w(v, {
|
|
64
65
|
name: "name",
|
|
65
66
|
type: "text",
|
|
66
67
|
autoComplete: "name",
|
|
67
68
|
isDisabled: Z,
|
|
68
69
|
children: [
|
|
69
|
-
/* @__PURE__ */
|
|
70
|
-
/* @__PURE__ */
|
|
70
|
+
/* @__PURE__ */ C(h, { children: F.auth.name }),
|
|
71
|
+
/* @__PURE__ */ C(p, {
|
|
71
72
|
placeholder: F.auth.namePlaceholder,
|
|
72
73
|
required: !0,
|
|
73
|
-
variant:
|
|
74
|
+
variant: k === "transparent" ? "primary" : "secondary"
|
|
74
75
|
}),
|
|
75
|
-
/* @__PURE__ */
|
|
76
|
+
/* @__PURE__ */ C(f, {})
|
|
76
77
|
]
|
|
77
78
|
}),
|
|
78
|
-
/* @__PURE__ */
|
|
79
|
+
/* @__PURE__ */ w(v, {
|
|
79
80
|
name: "email",
|
|
80
81
|
type: "email",
|
|
81
82
|
autoComplete: "email",
|
|
82
83
|
isDisabled: Z,
|
|
83
84
|
children: [
|
|
84
|
-
/* @__PURE__ */
|
|
85
|
-
/* @__PURE__ */
|
|
85
|
+
/* @__PURE__ */ C(h, { children: F.auth.email }),
|
|
86
|
+
/* @__PURE__ */ C(p, {
|
|
86
87
|
placeholder: F.auth.emailPlaceholder,
|
|
87
88
|
required: !0,
|
|
88
|
-
variant:
|
|
89
|
+
variant: k === "transparent" ? "primary" : "secondary"
|
|
89
90
|
}),
|
|
90
|
-
/* @__PURE__ */
|
|
91
|
+
/* @__PURE__ */ C(f, {})
|
|
91
92
|
]
|
|
92
93
|
}),
|
|
93
|
-
|
|
94
|
+
j?.map((t) => t.signUp === "above" && /* @__PURE__ */ C(e, {
|
|
94
95
|
name: t.name,
|
|
95
96
|
field: t,
|
|
96
97
|
isPending: Z,
|
|
97
|
-
variant:
|
|
98
|
+
variant: k
|
|
98
99
|
}, t.name)),
|
|
99
|
-
/* @__PURE__ */
|
|
100
|
+
/* @__PURE__ */ w(v, {
|
|
100
101
|
minLength: P?.minPasswordLength,
|
|
101
102
|
maxLength: P?.maxPasswordLength,
|
|
102
103
|
name: "password",
|
|
103
104
|
autoComplete: "new-password",
|
|
104
105
|
isDisabled: Z,
|
|
105
|
-
value:
|
|
106
|
-
onChange:
|
|
106
|
+
value: U,
|
|
107
|
+
onChange: W,
|
|
107
108
|
children: [
|
|
108
|
-
/* @__PURE__ */
|
|
109
|
-
/* @__PURE__ */
|
|
110
|
-
variant:
|
|
111
|
-
children: [/* @__PURE__ */
|
|
109
|
+
/* @__PURE__ */ C(h, { children: F.auth.password }),
|
|
110
|
+
/* @__PURE__ */ w(m, {
|
|
111
|
+
variant: k === "transparent" ? "primary" : "secondary",
|
|
112
|
+
children: [/* @__PURE__ */ C(m.Input, {
|
|
112
113
|
placeholder: F.auth.passwordPlaceholder,
|
|
113
|
-
type:
|
|
114
|
+
type: Y ? "text" : "password",
|
|
114
115
|
name: "password",
|
|
115
116
|
required: !0
|
|
116
|
-
}), /* @__PURE__ */
|
|
117
|
+
}), /* @__PURE__ */ C(m.Suffix, {
|
|
117
118
|
className: "px-0",
|
|
118
|
-
children: /* @__PURE__ */
|
|
119
|
+
children: /* @__PURE__ */ C(l, {
|
|
119
120
|
isIconOnly: !0,
|
|
120
|
-
"aria-label":
|
|
121
|
+
"aria-label": Y ? F.auth.hidePassword : F.auth.showPassword,
|
|
121
122
|
size: "sm",
|
|
122
123
|
variant: "ghost",
|
|
123
|
-
onPress: () =>
|
|
124
|
+
onPress: () => ne(!Y),
|
|
124
125
|
isDisabled: Z,
|
|
125
|
-
children:
|
|
126
|
+
children: C(Y ? c : s, {})
|
|
126
127
|
})
|
|
127
128
|
})]
|
|
128
129
|
}),
|
|
129
|
-
/* @__PURE__ */
|
|
130
|
+
/* @__PURE__ */ C(f, {})
|
|
130
131
|
]
|
|
131
132
|
}),
|
|
132
|
-
P?.confirmPassword && /* @__PURE__ */
|
|
133
|
+
P?.confirmPassword && /* @__PURE__ */ w(v, {
|
|
133
134
|
minLength: P?.minPasswordLength,
|
|
134
135
|
maxLength: P?.maxPasswordLength,
|
|
135
136
|
name: "confirmPassword",
|
|
136
137
|
autoComplete: "new-password",
|
|
137
138
|
isDisabled: Z,
|
|
138
|
-
value:
|
|
139
|
-
onChange:
|
|
139
|
+
value: G,
|
|
140
|
+
onChange: K,
|
|
140
141
|
children: [
|
|
141
|
-
/* @__PURE__ */
|
|
142
|
-
/* @__PURE__ */
|
|
143
|
-
variant:
|
|
144
|
-
children: [/* @__PURE__ */
|
|
142
|
+
/* @__PURE__ */ C(h, { children: F.auth.confirmPassword }),
|
|
143
|
+
/* @__PURE__ */ w(m, {
|
|
144
|
+
variant: k === "transparent" ? "primary" : "secondary",
|
|
145
|
+
children: [/* @__PURE__ */ C(m.Input, {
|
|
145
146
|
name: "confirmPassword",
|
|
146
147
|
placeholder: F.auth.confirmPasswordPlaceholder,
|
|
147
|
-
type:
|
|
148
|
+
type: X ? "text" : "password",
|
|
148
149
|
required: !0
|
|
149
|
-
}), /* @__PURE__ */
|
|
150
|
+
}), /* @__PURE__ */ C(m.Suffix, {
|
|
150
151
|
className: "px-0",
|
|
151
|
-
children: /* @__PURE__ */
|
|
152
|
+
children: /* @__PURE__ */ C(l, {
|
|
152
153
|
isIconOnly: !0,
|
|
153
|
-
"aria-label":
|
|
154
|
+
"aria-label": X ? F.auth.hidePassword : F.auth.showPassword,
|
|
154
155
|
size: "sm",
|
|
155
156
|
variant: "ghost",
|
|
156
|
-
onPress: () =>
|
|
157
|
+
onPress: () => re(!X),
|
|
157
158
|
isDisabled: Z,
|
|
158
|
-
children:
|
|
159
|
+
children: C(X ? c : s, {})
|
|
159
160
|
})
|
|
160
161
|
})]
|
|
161
162
|
}),
|
|
162
|
-
/* @__PURE__ */
|
|
163
|
+
/* @__PURE__ */ C(f, {})
|
|
163
164
|
]
|
|
164
165
|
}),
|
|
165
|
-
|
|
166
|
+
j?.map((t) => t.signUp && t.signUp !== "above" && /* @__PURE__ */ C(e, {
|
|
166
167
|
name: t.name,
|
|
167
168
|
field: t,
|
|
168
169
|
isPending: Z,
|
|
169
|
-
variant:
|
|
170
|
+
variant: k
|
|
170
171
|
}, t.name)),
|
|
171
|
-
/* @__PURE__ */
|
|
172
|
+
Q && /* @__PURE__ */ C("div", {
|
|
173
|
+
className: "flex justify-center",
|
|
174
|
+
children: Q
|
|
175
|
+
}),
|
|
176
|
+
/* @__PURE__ */ w("div", {
|
|
172
177
|
className: "flex flex-col gap-3",
|
|
173
|
-
children: [/* @__PURE__ */
|
|
178
|
+
children: [/* @__PURE__ */ w(l, {
|
|
174
179
|
type: "submit",
|
|
175
180
|
className: "w-full",
|
|
176
181
|
isPending: Z,
|
|
177
|
-
children: [
|
|
182
|
+
children: [J && /* @__PURE__ */ C(_, {
|
|
178
183
|
color: "current",
|
|
179
184
|
size: "sm"
|
|
180
185
|
}), F.auth.signUp]
|
|
181
|
-
}), I.flatMap((e) => e.authButtons?.map((t, n) => /* @__PURE__ */
|
|
186
|
+
}), I.flatMap((e) => e.authButtons?.map((t, n) => /* @__PURE__ */ C(t, { view: "signUp" }, `${e.id}-${n.toString()}`)))]
|
|
182
187
|
})
|
|
183
188
|
]
|
|
184
189
|
}),
|
|
185
|
-
|
|
190
|
+
O === "bottom" && /* @__PURE__ */ w(S, { children: [$ && /* @__PURE__ */ C(t, { children: F.auth.or }), !!R?.length && /* @__PURE__ */ C(n, { socialLayout: D })] })
|
|
186
191
|
]
|
|
187
192
|
}),
|
|
188
|
-
/* @__PURE__ */
|
|
193
|
+
/* @__PURE__ */ C(u.Footer, {
|
|
189
194
|
className: "flex-col gap-3",
|
|
190
|
-
children: /* @__PURE__ */
|
|
195
|
+
children: /* @__PURE__ */ w(d, {
|
|
191
196
|
className: "text-sm",
|
|
192
197
|
children: [
|
|
193
198
|
F.auth.alreadyHaveAnAccount,
|
|
194
199
|
" ",
|
|
195
|
-
/* @__PURE__ */
|
|
200
|
+
/* @__PURE__ */ C(g, {
|
|
196
201
|
href: `${N.auth}/${z.auth.signIn}`,
|
|
197
202
|
className: "text-accent no-underline hover:underline decoration-accent-hover",
|
|
198
203
|
children: F.auth.signIn
|
|
@@ -204,4 +209,4 @@ function D({ className: D, socialLayout: O, socialPosition: k = "bottom", varian
|
|
|
204
209
|
});
|
|
205
210
|
}
|
|
206
211
|
//#endregion
|
|
207
|
-
export {
|
|
212
|
+
export { E as SignUp };
|
|
@@ -1,58 +1,62 @@
|
|
|
1
1
|
import { themePlugin as e } from "../../../lib/auth/theme-plugin.js";
|
|
2
2
|
import { useAuthPlugin as t } from "@better-auth-ui/react";
|
|
3
|
-
import { Display as n, Moon as r,
|
|
4
|
-
import { Dropdown as
|
|
5
|
-
import { jsx as
|
|
3
|
+
import { Display as n, Moon as r, Palette as i, Sun as a } from "@gravity-ui/icons";
|
|
4
|
+
import { Dropdown as o, Label as s, Tabs as c } from "@heroui/react";
|
|
5
|
+
import { jsx as l, jsxs as u } from "react/jsx-runtime";
|
|
6
6
|
//#region src/components/auth/theme/theme-toggle-item.tsx
|
|
7
|
-
var
|
|
8
|
-
function
|
|
9
|
-
let { useTheme:
|
|
10
|
-
return /* @__PURE__ */
|
|
7
|
+
var d = "[role=\"tab\"][aria-selected=\"true\"]";
|
|
8
|
+
function f() {
|
|
9
|
+
let { useTheme: f, localization: p } = t(e), { theme: m, setTheme: h, themes: g = [] } = f();
|
|
10
|
+
return /* @__PURE__ */ u(o.Item, {
|
|
11
11
|
className: "py-1 pe-2",
|
|
12
12
|
onFocus: (e) => {
|
|
13
|
-
e.target === e.currentTarget && e.currentTarget.querySelector(
|
|
13
|
+
e.target === e.currentTarget && e.currentTarget.querySelector(d)?.focus({ preventScroll: !0 });
|
|
14
14
|
},
|
|
15
15
|
shouldCloseOnSelect: !1,
|
|
16
|
-
children: [
|
|
17
|
-
className: "
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
children:
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
16
|
+
children: [
|
|
17
|
+
/* @__PURE__ */ l(i, { className: "text-muted" }),
|
|
18
|
+
/* @__PURE__ */ l(s, { children: p.theme }),
|
|
19
|
+
/* @__PURE__ */ l(c, {
|
|
20
|
+
className: "ml-auto",
|
|
21
|
+
selectedKey: m,
|
|
22
|
+
onSelectionChange: (e) => h(e),
|
|
23
|
+
children: /* @__PURE__ */ l(c.ListContainer, {
|
|
24
|
+
onKeyDown: (e) => {
|
|
25
|
+
if (e.key !== "ArrowUp" && e.key !== "ArrowDown") return;
|
|
26
|
+
let t = e.target;
|
|
27
|
+
if (t.getAttribute("role") !== "tab") return;
|
|
28
|
+
let n = t.closest("[role=\"menuitem\"]"), r = n?.closest("[role=\"menu\"]");
|
|
29
|
+
if (!n || !r) return;
|
|
30
|
+
let i = Array.from(r.querySelectorAll("[role=\"menuitem\"]:not([data-disabled])")), a = i.indexOf(n);
|
|
31
|
+
if (a === -1) return;
|
|
32
|
+
let o = i[e.key === "ArrowDown" ? a + 1 : a - 1];
|
|
33
|
+
o && (e.preventDefault(), o.focus());
|
|
34
|
+
},
|
|
35
|
+
children: /* @__PURE__ */ u(c.List, {
|
|
36
|
+
"aria-label": p.theme,
|
|
37
|
+
className: "*:h-5 *:w-5 *:p-0",
|
|
38
|
+
children: [
|
|
39
|
+
g.includes("system") && /* @__PURE__ */ u(c.Tab, {
|
|
40
|
+
id: "system",
|
|
41
|
+
"aria-label": p.system,
|
|
42
|
+
children: [/* @__PURE__ */ l(n, { className: "size-3" }), /* @__PURE__ */ l(c.Indicator, {})]
|
|
43
|
+
}),
|
|
44
|
+
g.includes("light") && /* @__PURE__ */ u(c.Tab, {
|
|
45
|
+
id: "light",
|
|
46
|
+
"aria-label": p.light,
|
|
47
|
+
children: [/* @__PURE__ */ l(a, { className: "size-3" }), /* @__PURE__ */ l(c.Indicator, {})]
|
|
48
|
+
}),
|
|
49
|
+
g.includes("dark") && /* @__PURE__ */ u(c.Tab, {
|
|
50
|
+
id: "dark",
|
|
51
|
+
"aria-label": p.dark,
|
|
52
|
+
children: [/* @__PURE__ */ l(r, { className: "size-3" }), /* @__PURE__ */ l(c.Indicator, {})]
|
|
53
|
+
})
|
|
54
|
+
]
|
|
55
|
+
})
|
|
52
56
|
})
|
|
53
57
|
})
|
|
54
|
-
|
|
58
|
+
]
|
|
55
59
|
});
|
|
56
60
|
}
|
|
57
61
|
//#endregion
|
|
58
|
-
export {
|
|
62
|
+
export { f as ThemeToggleItem };
|
|
@@ -1,4 +1,23 @@
|
|
|
1
|
-
import { ButtonProps, DropdownPopoverProps } from '@heroui/react';
|
|
1
|
+
import { ButtonProps, DropdownItemProps, DropdownPopoverProps } from '@heroui/react';
|
|
2
|
+
import { ReactElement, ReactNode } from 'react';
|
|
3
|
+
/** Auth states a `UserButton` link can be visible in. */
|
|
4
|
+
export type UserButtonLinkVisibility = "authenticated" | "unauthenticated" | "always";
|
|
5
|
+
/** A simple link entry rendered as a `Dropdown.Item` in the `UserButton` menu. */
|
|
6
|
+
export type UserButtonLink = {
|
|
7
|
+
/** Visible label. */
|
|
8
|
+
label: ReactNode;
|
|
9
|
+
/** Destination URL. */
|
|
10
|
+
href: string;
|
|
11
|
+
/** Optional leading icon. Sized/coloured to match built-in items. */
|
|
12
|
+
icon?: ReactNode;
|
|
13
|
+
/** Forwarded to the underlying `Dropdown.Item`. */
|
|
14
|
+
variant?: DropdownItemProps["variant"];
|
|
15
|
+
/**
|
|
16
|
+
* When this link is visible based on auth state.
|
|
17
|
+
* @default "always"
|
|
18
|
+
*/
|
|
19
|
+
visibility?: UserButtonLinkVisibility;
|
|
20
|
+
};
|
|
2
21
|
export type UserButtonProps = {
|
|
3
22
|
className?: string;
|
|
4
23
|
size?: "default" | "icon";
|
|
@@ -8,6 +27,10 @@ export type UserButtonProps = {
|
|
|
8
27
|
*/
|
|
9
28
|
placement?: DropdownPopoverProps["placement"];
|
|
10
29
|
variant?: ButtonProps["variant"];
|
|
30
|
+
/** Additional menu entries rendered above the built-in items. */
|
|
31
|
+
links?: (UserButtonLink | ReactElement)[];
|
|
32
|
+
/** Hide the built-in "Settings" link. Useful when replacing it via `links`. */
|
|
33
|
+
hideSettings?: boolean;
|
|
11
34
|
};
|
|
12
35
|
/**
|
|
13
36
|
* Render a user account dropdown button that shows account actions.
|
|
@@ -16,6 +39,8 @@ export type UserButtonProps = {
|
|
|
16
39
|
* @param placement - Dropdown popover placement (e.g., "bottom", "top-start", "bottom-end")
|
|
17
40
|
* @param size - "icon" renders an avatar-only trigger; "default" renders a button with label and chevron
|
|
18
41
|
* @param variant - Button visual variant passed to the underlying Button component
|
|
42
|
+
* @param links - Additional menu entries rendered above the built-in items
|
|
43
|
+
* @param hideSettings - Hide the built-in "Settings" link
|
|
19
44
|
* @returns The user button and its dropdown menu as a JSX element
|
|
20
45
|
*/
|
|
21
|
-
export declare function UserButton({ className, placement, size, variant }: UserButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
46
|
+
export declare function UserButton({ className, placement, size, variant, links, hideSettings }: UserButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -2,54 +2,73 @@ import { UserAvatar as e } from "./user-avatar.js";
|
|
|
2
2
|
import { UserView as t } from "./user-view.js";
|
|
3
3
|
import { useAuth as n, useSession as r } from "@better-auth-ui/react";
|
|
4
4
|
import { ArrowRightFromSquare as i, ArrowRightToSquare as a, ChevronsExpandVertical as o, Gear as s, PersonPlus as c } from "@gravity-ui/icons";
|
|
5
|
-
import { Button as l, Dropdown as u, Label as d,
|
|
5
|
+
import { Button as l, Dropdown as u, Label as d, cn as f } from "@heroui/react";
|
|
6
|
+
import { isValidElement as p } from "react";
|
|
6
7
|
import { Fragment as m, jsx as h, jsxs as g } from "react/jsx-runtime";
|
|
7
8
|
//#region src/components/auth/user/user-button.tsx
|
|
8
|
-
function _(
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
function _(e, t) {
|
|
10
|
+
if (p(e)) return e;
|
|
11
|
+
let { label: n, href: r, icon: i, variant: a } = e;
|
|
12
|
+
return /* @__PURE__ */ g(u.Item, {
|
|
13
|
+
href: r,
|
|
14
|
+
variant: a,
|
|
15
|
+
textValue: typeof n == "string" ? n : void 0,
|
|
16
|
+
children: [i, /* @__PURE__ */ h(d, { children: n })]
|
|
17
|
+
}, t);
|
|
18
|
+
}
|
|
19
|
+
function v({ className: v, placement: y = "bottom", size: b = "default", variant: x = "ghost", links: S, hideSettings: C = !1 }) {
|
|
20
|
+
let { authClient: w, basePaths: T, viewPaths: E, localization: D, plugins: O } = n(), { data: k, isPending: A } = r(w), j = O.flatMap((e) => e.userMenuItems?.map((t, n) => /* @__PURE__ */ h(t, {}, `${e.id}-${n.toString()}`)) ?? []), M = S?.flatMap((e, t) => {
|
|
21
|
+
if (!p(e)) {
|
|
22
|
+
let t = e.visibility ?? "always";
|
|
23
|
+
if (t === "authenticated" && !k || t === "unauthenticated" && k) return [];
|
|
24
|
+
}
|
|
25
|
+
return [_(e, `user-button-link-${t.toString()}`)];
|
|
26
|
+
});
|
|
27
|
+
return /* @__PURE__ */ g(u, { children: [b === "icon" ? /* @__PURE__ */ h(u.Trigger, {
|
|
28
|
+
className: f("rounded-full", v),
|
|
12
29
|
children: /* @__PURE__ */ h(e, {})
|
|
13
30
|
}) : /* @__PURE__ */ g(l, {
|
|
14
|
-
variant:
|
|
15
|
-
className:
|
|
16
|
-
children: [
|
|
31
|
+
variant: x,
|
|
32
|
+
className: f("h-auto font-normal justify-start px-3 py-2 text-left", v),
|
|
33
|
+
children: [k || A ? /* @__PURE__ */ h(t, { isPending: A }) : /* @__PURE__ */ g(m, { children: [/* @__PURE__ */ h(e, {}), /* @__PURE__ */ h("p", {
|
|
17
34
|
className: "text-sm font-medium",
|
|
18
|
-
children:
|
|
35
|
+
children: D.auth.account
|
|
19
36
|
})] }), /* @__PURE__ */ h(o, { className: "ml-auto size-3.5" })]
|
|
20
37
|
}), /* @__PURE__ */ g(u.Popover, {
|
|
21
|
-
placement:
|
|
38
|
+
placement: y,
|
|
22
39
|
className: "min-w-40 md:min-w-56 max-w-[48svw]",
|
|
23
|
-
children: [
|
|
40
|
+
children: [k && /* @__PURE__ */ h("div", {
|
|
24
41
|
className: "px-3 pt-3 pb-1",
|
|
25
42
|
children: /* @__PURE__ */ h(t, {})
|
|
26
|
-
}), /* @__PURE__ */ h(u.Menu, { children:
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
43
|
+
}), /* @__PURE__ */ h(u.Menu, { children: k ? /* @__PURE__ */ g(m, { children: [
|
|
44
|
+
M,
|
|
45
|
+
!C && /* @__PURE__ */ g(u.Item, {
|
|
46
|
+
textValue: D.settings.settings,
|
|
47
|
+
href: `${T.settings}/${E.settings.account}`,
|
|
48
|
+
children: [/* @__PURE__ */ h(s, { className: "text-muted" }), /* @__PURE__ */ h(d, { children: D.settings.settings })]
|
|
31
49
|
}),
|
|
32
|
-
|
|
33
|
-
/* @__PURE__ */ h(f, {}),
|
|
50
|
+
j,
|
|
34
51
|
/* @__PURE__ */ g(u.Item, {
|
|
35
|
-
textValue:
|
|
36
|
-
href: `${
|
|
37
|
-
|
|
52
|
+
textValue: D.auth.signOut,
|
|
53
|
+
href: `${T.auth}/${E.auth.signOut}`,
|
|
54
|
+
variant: "danger",
|
|
55
|
+
children: [/* @__PURE__ */ h(i, { className: "text-danger" }), /* @__PURE__ */ h(d, { children: D.auth.signOut })]
|
|
38
56
|
})
|
|
39
57
|
] }) : /* @__PURE__ */ g(m, { children: [
|
|
58
|
+
M,
|
|
40
59
|
/* @__PURE__ */ g(u.Item, {
|
|
41
|
-
textValue:
|
|
42
|
-
href: `${
|
|
43
|
-
children: [/* @__PURE__ */ h(a, { className: "text-muted" }), /* @__PURE__ */ h(d, { children:
|
|
60
|
+
textValue: D.auth.signIn,
|
|
61
|
+
href: `${T.auth}/${E.auth.signIn}`,
|
|
62
|
+
children: [/* @__PURE__ */ h(a, { className: "text-muted" }), /* @__PURE__ */ h(d, { children: D.auth.signIn })]
|
|
44
63
|
}),
|
|
45
64
|
/* @__PURE__ */ g(u.Item, {
|
|
46
|
-
textValue:
|
|
47
|
-
href: `${
|
|
48
|
-
children: [/* @__PURE__ */ h(c, { className: "text-muted" }), /* @__PURE__ */ h(d, { children:
|
|
65
|
+
textValue: D.auth.signUp,
|
|
66
|
+
href: `${T.auth}/${E.auth.signUp}`,
|
|
67
|
+
children: [/* @__PURE__ */ h(c, { className: "text-muted" }), /* @__PURE__ */ h(d, { children: D.auth.signUp })]
|
|
49
68
|
}),
|
|
50
|
-
|
|
69
|
+
j
|
|
51
70
|
] }) })]
|
|
52
71
|
})] });
|
|
53
72
|
}
|
|
54
73
|
//#endregion
|
|
55
|
-
export {
|
|
74
|
+
export { v as UserButton };
|