@skiddph/prui 0.1.0

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 (69) hide show
  1. package/LICENSE +201 -0
  2. package/dist/app/app.d.ts +91 -0
  3. package/dist/app/auto-pages.d.ts +20 -0
  4. package/dist/app/form.d.ts +44 -0
  5. package/dist/app/index.d.ts +8 -0
  6. package/dist/app/resource.d.ts +61 -0
  7. package/dist/app/settings.d.ts +27 -0
  8. package/dist/app/stat-row.d.ts +20 -0
  9. package/dist/app.js +18 -0
  10. package/dist/chunks/data-table-toolbar-C9likJBN.js +430 -0
  11. package/dist/chunks/settings-DUz5nyX-.js +731 -0
  12. package/dist/core/button.d.ts +14 -0
  13. package/dist/core/button.js +58 -0
  14. package/dist/core/card.d.ts +24 -0
  15. package/dist/core/card.js +122 -0
  16. package/dist/core/cn.d.ts +3 -0
  17. package/dist/core/cn.js +8 -0
  18. package/dist/core/dialog.d.ts +25 -0
  19. package/dist/core/dialog.js +102 -0
  20. package/dist/core/dropdown.d.ts +24 -0
  21. package/dist/core/dropdown.js +89 -0
  22. package/dist/core/index.d.ts +14 -0
  23. package/dist/core/input.d.ts +8 -0
  24. package/dist/core/input.js +42 -0
  25. package/dist/core/label.d.ts +12 -0
  26. package/dist/core/label.js +52 -0
  27. package/dist/core/modal.d.ts +56 -0
  28. package/dist/core/modal.js +303 -0
  29. package/dist/core/props-meta.d.ts +26 -0
  30. package/dist/core/props-meta.js +1 -0
  31. package/dist/core/scroll-area.d.ts +8 -0
  32. package/dist/core/scroll-area.js +27 -0
  33. package/dist/core/select.d.ts +38 -0
  34. package/dist/core/select.js +157 -0
  35. package/dist/core/switch.d.ts +10 -0
  36. package/dist/core/switch.js +57 -0
  37. package/dist/core/tabs.d.ts +22 -0
  38. package/dist/core/tabs.js +94 -0
  39. package/dist/core.js +64 -0
  40. package/dist/data-table/data-table-daterange-filter.d.ts +14 -0
  41. package/dist/data-table/data-table-faceted-filter.d.ts +17 -0
  42. package/dist/data-table/data-table-number-range-filter.d.ts +14 -0
  43. package/dist/data-table/data-table-pagination.d.ts +24 -0
  44. package/dist/data-table/data-table-toolbar.d.ts +38 -0
  45. package/dist/data-table/data-table.d.ts +47 -0
  46. package/dist/data-table/index.d.ts +7 -0
  47. package/dist/data-table.js +12 -0
  48. package/dist/index.d.ts +5 -0
  49. package/dist/index.js +125 -0
  50. package/dist/pages/forgot-password.d.ts +21 -0
  51. package/dist/pages/index.d.ts +18 -0
  52. package/dist/pages/login.d.ts +24 -0
  53. package/dist/pages/logout.d.ts +12 -0
  54. package/dist/pages/otp.d.ts +18 -0
  55. package/dist/pages/profile-settings.d.ts +55 -0
  56. package/dist/pages/register.d.ts +19 -0
  57. package/dist/pages/reset-password.d.ts +20 -0
  58. package/dist/pages/shared.d.ts +55 -0
  59. package/dist/pages/status.d.ts +33 -0
  60. package/dist/pages.js +806 -0
  61. package/dist/prui.css +120 -0
  62. package/dist/theme/base.css +36 -0
  63. package/dist/theme/control.css +16 -0
  64. package/dist/theme/daylight.css +16 -0
  65. package/dist/theme/ember.css +16 -0
  66. package/dist/theme/index.d.ts +55 -0
  67. package/dist/theme/workshop.css +16 -0
  68. package/dist/theme.js +63 -0
  69. package/package.json +81 -0
package/dist/pages.js ADDED
@@ -0,0 +1,806 @@
1
+ import { jsx as e, jsxs as a, Fragment as $ } from "react/jsx-runtime";
2
+ import * as v from "react";
3
+ import { Button as S } from "./core/button.js";
4
+ import { Input as P, Textarea as G } from "./core/input.js";
5
+ import { Label as C } from "./core/label.js";
6
+ import { Loader2 as Y, LogOut as H, Inbox as K, AlertTriangle as U, FileQuestion as W } from "lucide-react";
7
+ import { cn as z } from "./core/cn.js";
8
+ import { Card as Q, CardHeader as J, CardTitle as X, CardDescription as Z, CardContent as _, CardFooter as k, Avatar as ee } from "./core/card.js";
9
+ import { Switch as te } from "./core/switch.js";
10
+ function j({ title: t, description: r, brand: o, width: n = "max-w-sm", children: d, footer: i }) {
11
+ return /* @__PURE__ */ e("div", { className: "prui-page flex min-h-[100dvh] items-center justify-center bg-[var(--prui-background)] p-4", children: /* @__PURE__ */ a("div", { className: z("w-full", n), children: [
12
+ o ? /* @__PURE__ */ a("div", { className: "mb-6 flex items-center justify-center gap-2", "data-testid": "page-brand", children: [
13
+ o.mark ? /* @__PURE__ */ e("img", { src: o.mark, alt: "", className: "h-8 w-8 rounded-[var(--prui-radius-1)] object-cover" }) : null,
14
+ /* @__PURE__ */ e("span", { className: "text-lg font-semibold text-[var(--prui-fg)]", children: o.name })
15
+ ] }) : null,
16
+ /* @__PURE__ */ a("div", { className: "rounded-[var(--prui-radius)] border border-[var(--prui-line)] bg-[var(--prui-surface)] p-6", children: [
17
+ /* @__PURE__ */ a("div", { className: "mb-4 flex flex-col gap-1 text-center", children: [
18
+ /* @__PURE__ */ e("h1", { className: "text-lg font-semibold text-[var(--prui-fg)]", children: t }),
19
+ r ? /* @__PURE__ */ e("p", { className: "text-sm text-[var(--prui-dim)]", children: r }) : null
20
+ ] }),
21
+ d,
22
+ i ? /* @__PURE__ */ e("div", { className: "mt-4 text-center text-sm text-[var(--prui-dim)]", children: i }) : null
23
+ ] })
24
+ ] }) });
25
+ }
26
+ function F({ error: t }) {
27
+ return t ? /* @__PURE__ */ e(
28
+ "p",
29
+ {
30
+ role: "alert",
31
+ "data-testid": "page-error",
32
+ className: "mb-3 rounded-[var(--prui-radius)] border border-[var(--prui-danger)]/40 bg-[var(--prui-danger)]/10 px-3 py-2 text-sm text-[var(--prui-danger)]",
33
+ children: t
34
+ }
35
+ ) : null;
36
+ }
37
+ function ae({ loading: t, children: r }) {
38
+ return /* @__PURE__ */ a($, { children: [
39
+ t ? /* @__PURE__ */ e(Y, { className: "h-4 w-4 animate-spin", "aria-hidden": !0 }) : null,
40
+ r
41
+ ] });
42
+ }
43
+ function T({ providers: t }) {
44
+ return !t || t.length === 0 ? null : /* @__PURE__ */ a("div", { className: "mt-4", "data-testid": "oauth-providers", children: [
45
+ /* @__PURE__ */ a("div", { className: "relative my-3", children: [
46
+ /* @__PURE__ */ e("div", { className: "absolute inset-0 flex items-center", children: /* @__PURE__ */ e("span", { className: "w-full border-t border-[var(--prui-line)]" }) }),
47
+ /* @__PURE__ */ e("div", { className: "relative flex justify-center text-xs", children: /* @__PURE__ */ e("span", { className: "bg-[var(--prui-surface)] px-2 text-[var(--prui-dim)]", children: "or continue with" }) })
48
+ ] }),
49
+ /* @__PURE__ */ e("div", { className: "grid grid-cols-2 gap-2", children: t.map((r) => {
50
+ const o = r.icon;
51
+ return /* @__PURE__ */ a(
52
+ "button",
53
+ {
54
+ type: "button",
55
+ onClick: (n) => {
56
+ var i;
57
+ const d = (i = t.find((p) => p.id === r.id)) == null ? void 0 : i.onClick;
58
+ d == null || d(), n.preventDefault();
59
+ },
60
+ className: "inline-flex h-9 items-center justify-center gap-2 rounded-[var(--prui-radius)] border border-[var(--prui-line)] bg-[var(--prui-background)] text-sm text-[var(--prui-fg)] hover:border-[var(--prui-dim)] cursor-pointer",
61
+ children: [
62
+ o ? /* @__PURE__ */ e(o, { className: "h-4 w-4", "aria-hidden": !0 }) : null,
63
+ r.label
64
+ ]
65
+ },
66
+ r.id
67
+ );
68
+ }) })
69
+ ] });
70
+ }
71
+ const A = [
72
+ { name: "email", label: "Email", type: "email", required: !0, autoComplete: "email" },
73
+ { name: "password", label: "Password", type: "password", required: !0, autoComplete: "current-password" }
74
+ ], re = [
75
+ { name: "name", label: "Name", type: "text", required: !0, autoComplete: "name" },
76
+ { name: "email", label: "Email", type: "email", required: !0, autoComplete: "email" },
77
+ { name: "password", label: "Password", type: "password", required: !0, autoComplete: "new-password" }
78
+ ];
79
+ function ne({
80
+ onSubmit: t,
81
+ fields: r,
82
+ extraFields: o,
83
+ links: n,
84
+ oauth: d,
85
+ brand: i,
86
+ submitLabel: p = "Sign in",
87
+ loading: c = !1,
88
+ error: x,
89
+ className: g
90
+ }) {
91
+ const s = { email: !0, password: !0, remember: !1, ...r }, m = [
92
+ ...s.email !== !1 ? [A[0]] : [],
93
+ ...s.password !== !1 ? [A[1]] : [],
94
+ ...o ?? []
95
+ ], [f, y] = v.useState({}), [w, N] = v.useState(!1), [h, B] = v.useState(!1);
96
+ return /* @__PURE__ */ a(j, { title: "Welcome back", description: "Sign in to your account", brand: i, className: g, children: [
97
+ /* @__PURE__ */ e(F, { error: x }),
98
+ /* @__PURE__ */ a("form", { onSubmit: async (l) => {
99
+ l.preventDefault();
100
+ try {
101
+ const u = t == null ? void 0 : t({ ...f, remember: String(w) });
102
+ u && typeof u.then == "function" && (B(!0), await u);
103
+ } finally {
104
+ B(!1);
105
+ }
106
+ }, className: "flex flex-col gap-3", "data-testid": "login-form", children: [
107
+ m.map((l) => /* @__PURE__ */ a("div", { className: "flex flex-col gap-1.5", children: [
108
+ /* @__PURE__ */ a(C, { htmlFor: `login-${l.name}`, children: [
109
+ l.label,
110
+ l.required ? /* @__PURE__ */ e("span", { className: "ml-0.5 text-[var(--prui-danger)]", children: "*" }) : null
111
+ ] }),
112
+ /* @__PURE__ */ e(
113
+ P,
114
+ {
115
+ id: `login-${l.name}`,
116
+ type: l.type ?? "text",
117
+ placeholder: l.placeholder,
118
+ autoComplete: l.autoComplete,
119
+ required: l.required,
120
+ disabled: c || h,
121
+ value: f[l.name] ?? "",
122
+ onChange: (u) => y((b) => ({ ...b, [l.name]: u.target.value }))
123
+ }
124
+ )
125
+ ] }, l.name)),
126
+ s.remember ? /* @__PURE__ */ a("label", { className: "flex items-center gap-2 text-sm text-[var(--prui-dim)]", "data-testid": "login-remember", children: [
127
+ /* @__PURE__ */ e(
128
+ "input",
129
+ {
130
+ type: "checkbox",
131
+ checked: w,
132
+ onChange: (l) => N(l.target.checked),
133
+ className: "h-4 w-4 accent-[var(--prui-brand)]"
134
+ }
135
+ ),
136
+ "Remember me"
137
+ ] }) : null,
138
+ /* @__PURE__ */ e(S, { type: "submit", variant: "primary", loading: c || h, "data-testid": "login-submit", children: /* @__PURE__ */ e(ae, { loading: c || h, children: p }) })
139
+ ] }),
140
+ /* @__PURE__ */ e(T, { providers: d }),
141
+ (n == null ? void 0 : n.forgot) !== !1 && (n != null && n.forgot) ? /* @__PURE__ */ e("div", { className: "mt-3 text-center", children: /* @__PURE__ */ e("a", { href: n.forgot.href, className: "text-sm text-[var(--prui-brand)] hover:underline", children: n.forgot.label ?? "Forgot password?" }) }) : null,
142
+ (n == null ? void 0 : n.register) !== !1 && (n != null && n.register) ? /* @__PURE__ */ a("div", { className: "mt-1 text-center text-sm text-[var(--prui-dim)]", children: [
143
+ "No account?",
144
+ " ",
145
+ /* @__PURE__ */ e("a", { href: n.register.href, className: "text-[var(--prui-brand)] hover:underline", children: n.register.label ?? "Register" })
146
+ ] }) : null
147
+ ] });
148
+ }
149
+ const Ce = {
150
+ name: "LoginPage",
151
+ props: [
152
+ { name: "onSubmit", type: "(values) => void | Promise<void>", default: null, control: "none" },
153
+ { name: "fields", type: "{ email?, password?, remember? }", default: "all except remember", control: "object" },
154
+ { name: "links", type: "{ forgot?, register? }", default: "undefined", control: "object" },
155
+ { name: "oauth", type: "OAuthProvider[]", default: "undefined", control: "object" },
156
+ { name: "brand", type: "{ name, mark?, href? }", default: "undefined", control: "object" },
157
+ { name: "loading", type: "boolean", default: "false", control: "boolean" },
158
+ { name: "error", type: "string | null", default: "null", control: "text" }
159
+ ]
160
+ };
161
+ function le({
162
+ onSubmit: t,
163
+ fields: r,
164
+ extraFields: o,
165
+ links: n,
166
+ oauth: d,
167
+ brand: i,
168
+ submitLabel: p = "Create account",
169
+ loading: c = !1,
170
+ error: x
171
+ }) {
172
+ const g = { name: !0, email: !0, password: !0, confirm: !1, ...r }, m = [...re.filter(
173
+ (l) => l.name === "name" ? g.name !== !1 : l.name === "email" ? g.email !== !1 : g.password !== !1
174
+ ), ...o ?? []], [f, y] = v.useState({}), [w, N] = v.useState(""), [h, B] = v.useState(!1);
175
+ return /* @__PURE__ */ a(j, { title: "Create your account", description: "Get started in minutes", brand: i, width: "max-w-md", children: [
176
+ /* @__PURE__ */ e(F, { error: x }),
177
+ /* @__PURE__ */ a("form", { onSubmit: async (l) => {
178
+ l.preventDefault();
179
+ try {
180
+ const u = t == null ? void 0 : t({ ...f, confirm: w });
181
+ u && typeof u.then == "function" && (B(!0), await u);
182
+ } finally {
183
+ B(!1);
184
+ }
185
+ }, className: "flex flex-col gap-3", "data-testid": "register-form", children: [
186
+ m.map((l) => /* @__PURE__ */ a("div", { className: "flex flex-col gap-1.5", children: [
187
+ /* @__PURE__ */ a(C, { htmlFor: `register-${l.name}`, children: [
188
+ l.label,
189
+ l.required ? /* @__PURE__ */ e("span", { className: "ml-0.5 text-[var(--prui-danger)]", children: "*" }) : null
190
+ ] }),
191
+ /* @__PURE__ */ e(
192
+ P,
193
+ {
194
+ id: `register-${l.name}`,
195
+ type: l.type ?? "text",
196
+ placeholder: l.placeholder,
197
+ autoComplete: l.autoComplete,
198
+ required: l.required,
199
+ disabled: c || h,
200
+ value: f[l.name] ?? "",
201
+ onChange: (u) => y((b) => ({ ...b, [l.name]: u.target.value }))
202
+ }
203
+ )
204
+ ] }, l.name)),
205
+ g.confirm ? /* @__PURE__ */ a("div", { className: "flex flex-col gap-1.5", "data-testid": "register-confirm", children: [
206
+ /* @__PURE__ */ a(C, { htmlFor: "register-confirm-password", children: [
207
+ "Confirm password",
208
+ /* @__PURE__ */ e("span", { className: "ml-0.5 text-[var(--prui-danger)]", children: "*" })
209
+ ] }),
210
+ /* @__PURE__ */ e(
211
+ P,
212
+ {
213
+ id: "register-confirm-password",
214
+ type: "password",
215
+ autoComplete: "new-password",
216
+ required: !0,
217
+ disabled: c || h,
218
+ value: w,
219
+ onChange: (l) => N(l.target.value)
220
+ }
221
+ )
222
+ ] }) : null,
223
+ /* @__PURE__ */ e(S, { type: "submit", variant: "primary", loading: c || h, "data-testid": "register-submit", children: p })
224
+ ] }),
225
+ /* @__PURE__ */ e(T, { providers: d }),
226
+ n != null && n.login ? /* @__PURE__ */ a("div", { className: "mt-3 text-center text-sm text-[var(--prui-dim)]", "data-testid": "register-login-link", children: [
227
+ "Already have an account?",
228
+ " ",
229
+ /* @__PURE__ */ e("a", { href: n.login.href, className: "text-[var(--prui-brand)] hover:underline", children: n.login.label ?? "Sign in" })
230
+ ] }) : null
231
+ ] });
232
+ }
233
+ const Se = {
234
+ name: "RegisterPage",
235
+ props: [
236
+ { name: "onSubmit", type: "(values) => void | Promise<void>", default: null, control: "none" },
237
+ { name: "fields", type: "{ name?, email?, password?, confirm? }", default: "name, email, password", control: "object" },
238
+ { name: "links", type: "{ login? }", default: "undefined", control: "object" },
239
+ { name: "oauth", type: "OAuthProvider[]", default: "undefined", control: "object" },
240
+ { name: "brand", type: "BrandConfig", default: "undefined", control: "object" },
241
+ { name: "loading", type: "boolean", default: "false", control: "boolean" },
242
+ { name: "error", type: "string | null", default: "null", control: "text" }
243
+ ]
244
+ };
245
+ function oe({
246
+ onSubmit: t,
247
+ links: r,
248
+ brand: o,
249
+ submitLabel: n = "Send reset link",
250
+ loading: d = !1,
251
+ error: i,
252
+ sent: p = !1
253
+ }) {
254
+ const [c, x] = v.useState(""), [g, s] = v.useState(!1);
255
+ return /* @__PURE__ */ a(j, { title: "Forgot your password?", description: "Enter your email and we send you a reset link", brand: o, children: [
256
+ /* @__PURE__ */ e(F, { error: i }),
257
+ p ? /* @__PURE__ */ e("p", { "data-testid": "forgot-sent", className: "rounded-[var(--prui-radius)] border border-[var(--prui-ok)]/40 bg-[var(--prui-ok)]/10 px-3 py-3 text-center text-sm text-[var(--prui-ok)]", children: "Check your email for the reset link." }) : /* @__PURE__ */ a("form", { onSubmit: async (f) => {
258
+ f.preventDefault();
259
+ try {
260
+ const y = t == null ? void 0 : t({ email: c });
261
+ y && typeof y.then == "function" && (s(!0), await y);
262
+ } finally {
263
+ s(!1);
264
+ }
265
+ }, className: "flex flex-col gap-3", "data-testid": "forgot-form", children: [
266
+ /* @__PURE__ */ a("div", { className: "flex flex-col gap-1.5", children: [
267
+ /* @__PURE__ */ a(C, { htmlFor: "forgot-email", children: [
268
+ "Email",
269
+ /* @__PURE__ */ e("span", { className: "ml-0.5 text-[var(--prui-danger)]", children: "*" })
270
+ ] }),
271
+ /* @__PURE__ */ e(
272
+ P,
273
+ {
274
+ id: "forgot-email",
275
+ type: "email",
276
+ autoComplete: "email",
277
+ required: !0,
278
+ placeholder: "you@example.com",
279
+ disabled: d || g,
280
+ value: c,
281
+ onChange: (f) => x(f.target.value)
282
+ }
283
+ )
284
+ ] }),
285
+ /* @__PURE__ */ e(S, { type: "submit", variant: "primary", loading: d || g, "data-testid": "forgot-submit", children: n })
286
+ ] }),
287
+ (r == null ? void 0 : r.login) !== !1 && (r != null && r.login) ? /* @__PURE__ */ e("div", { className: "mt-3 text-center text-sm", children: /* @__PURE__ */ e("a", { href: r.login.href, className: "text-[var(--prui-brand)] hover:underline", children: r.login.label ?? "Back to sign in" }) }) : null
288
+ ] });
289
+ }
290
+ const je = {
291
+ name: "ForgotPasswordPage",
292
+ props: [
293
+ { name: "onSubmit", type: "({ email }) => void | Promise<void>", default: null, control: "none" },
294
+ { name: "links", type: "{ login?, register? }", default: "undefined", control: "object" },
295
+ { name: "brand", type: "BrandConfig", default: "undefined", control: "object" },
296
+ { name: "loading", type: "boolean", default: "false", control: "boolean" },
297
+ { name: "error", type: "string | null", default: "null", control: "text" },
298
+ { name: "sent", type: "boolean", default: "false", control: "boolean" }
299
+ ]
300
+ };
301
+ function ie({
302
+ onSubmit: t,
303
+ fields: r,
304
+ links: o,
305
+ brand: n,
306
+ submitLabel: d = "Reset password",
307
+ loading: i = !1,
308
+ error: p
309
+ }) {
310
+ const c = { password: !0, confirm: !0, ...r }, [x, g] = v.useState({ password: "", confirm: "" }), [s, m] = v.useState(!1);
311
+ return /* @__PURE__ */ a(j, { title: "Choose a new password", description: "Your new password must be different from previous ones", brand: n, children: [
312
+ /* @__PURE__ */ e(F, { error: p }),
313
+ /* @__PURE__ */ a("form", { onSubmit: async (y) => {
314
+ y.preventDefault();
315
+ try {
316
+ const w = t == null ? void 0 : t({ ...x });
317
+ w && typeof w.then == "function" && (m(!0), await w);
318
+ } finally {
319
+ m(!1);
320
+ }
321
+ }, className: "flex flex-col gap-3", "data-testid": "reset-form", children: [
322
+ c.password !== !1 ? /* @__PURE__ */ a("div", { className: "flex flex-col gap-1.5", children: [
323
+ /* @__PURE__ */ a(C, { htmlFor: "reset-password", children: [
324
+ "New password",
325
+ /* @__PURE__ */ e("span", { className: "ml-0.5 text-[var(--prui-danger)]", children: "*" })
326
+ ] }),
327
+ /* @__PURE__ */ e(
328
+ P,
329
+ {
330
+ id: "reset-password",
331
+ type: "password",
332
+ autoComplete: "new-password",
333
+ required: !0,
334
+ disabled: i || s,
335
+ value: x.password,
336
+ onChange: (y) => g((w) => ({ ...w, password: y.target.value }))
337
+ }
338
+ )
339
+ ] }) : null,
340
+ c.confirm !== !1 ? /* @__PURE__ */ a("div", { className: "flex flex-col gap-1.5", "data-testid": "reset-confirm", children: [
341
+ /* @__PURE__ */ a(C, { htmlFor: "reset-confirm", children: [
342
+ "Confirm password",
343
+ /* @__PURE__ */ e("span", { className: "ml-0.5 text-[var(--prui-danger)]", children: "*" })
344
+ ] }),
345
+ /* @__PURE__ */ e(
346
+ P,
347
+ {
348
+ id: "reset-confirm",
349
+ type: "password",
350
+ autoComplete: "new-password",
351
+ required: !0,
352
+ disabled: i || s,
353
+ value: x.confirm,
354
+ onChange: (y) => g((w) => ({ ...w, confirm: y.target.value }))
355
+ }
356
+ )
357
+ ] }) : null,
358
+ /* @__PURE__ */ e(S, { type: "submit", variant: "primary", loading: i || s, "data-testid": "reset-submit", children: d })
359
+ ] }),
360
+ (o == null ? void 0 : o.login) !== !1 && (o != null && o.login) ? /* @__PURE__ */ e("div", { className: "mt-3 text-center text-sm", children: /* @__PURE__ */ e("a", { href: o.login.href, className: "text-[var(--prui-brand)] hover:underline", children: o.login.label ?? "Back to sign in" }) }) : null
361
+ ] });
362
+ }
363
+ const Be = {
364
+ name: "ResetPasswordPage",
365
+ props: [
366
+ { name: "onSubmit", type: "({ password, confirm }) => void | Promise<void>", default: null, control: "none" },
367
+ { name: "fields", type: "{ password?, confirm? }", default: "both shown", control: "object" },
368
+ { name: "links", type: "{ login? }", default: "undefined", control: "object" },
369
+ { name: "brand", type: "BrandConfig", default: "undefined", control: "object" },
370
+ { name: "loading", type: "boolean", default: "false", control: "boolean" },
371
+ { name: "error", type: "string | null", default: "null", control: "text" }
372
+ ]
373
+ };
374
+ function se({
375
+ onSubmit: t,
376
+ length: r = 6,
377
+ title: o = "Enter verification code",
378
+ description: n = "We sent a code to your email",
379
+ brand: d,
380
+ submitLabel: i = "Verify",
381
+ loading: p = !1,
382
+ error: c,
383
+ onResend: x,
384
+ resendLabel: g = "Resend code"
385
+ }) {
386
+ const [s, m] = v.useState(() => Array.from({ length: r }, () => "")), f = v.useRef([]), y = s.join(""), w = (l, u) => {
387
+ var D, M;
388
+ const b = u.replace(/\D/g, "");
389
+ if (b.length > 1) {
390
+ const R = b.slice(0, r - l).split("");
391
+ m((V) => {
392
+ const L = [...V];
393
+ return R.forEach((I, O) => {
394
+ L[l + O] = I;
395
+ }), L;
396
+ });
397
+ const q = Math.min(l + R.length, r - 1);
398
+ (D = f.current[q]) == null || D.focus();
399
+ return;
400
+ }
401
+ m((R) => {
402
+ const q = [...R];
403
+ return q[l] = b, q;
404
+ }), b && l < r - 1 && ((M = f.current[l + 1]) == null || M.focus());
405
+ }, N = (l, u) => {
406
+ var b;
407
+ u.key === "Backspace" && !s[l] && l > 0 && ((b = f.current[l - 1]) == null || b.focus());
408
+ }, [h, B] = v.useState(!1);
409
+ return /* @__PURE__ */ a(j, { title: o, description: n, brand: d, children: [
410
+ /* @__PURE__ */ e(F, { error: c }),
411
+ /* @__PURE__ */ a("form", { onSubmit: async (l) => {
412
+ l.preventDefault();
413
+ try {
414
+ const u = t == null ? void 0 : t(y);
415
+ u && typeof u.then == "function" && (B(!0), await u);
416
+ } finally {
417
+ B(!1);
418
+ }
419
+ }, className: "flex flex-col gap-4", "data-testid": "otp-form", children: [
420
+ /* @__PURE__ */ e("div", { className: "flex justify-center gap-2", role: "group", "aria-label": "Verification code", children: s.map((l, u) => /* @__PURE__ */ e(
421
+ P,
422
+ {
423
+ ref: (b) => {
424
+ f.current[u] = b;
425
+ },
426
+ type: "text",
427
+ inputMode: "numeric",
428
+ autoComplete: "one-time-code",
429
+ maxLength: r,
430
+ "aria-label": `Digit ${u + 1}`,
431
+ className: "h-11 w-10 text-center text-lg",
432
+ disabled: p || h,
433
+ value: l,
434
+ onChange: (b) => w(u, b.target.value),
435
+ onKeyDown: (b) => N(u, b)
436
+ },
437
+ u
438
+ )) }),
439
+ /* @__PURE__ */ e(S, { type: "submit", variant: "primary", loading: p || h, "data-testid": "otp-submit", children: i })
440
+ ] }),
441
+ x ? /* @__PURE__ */ e("div", { className: "mt-3 text-center text-sm", children: /* @__PURE__ */ e(
442
+ "button",
443
+ {
444
+ type: "button",
445
+ onClick: () => void x(),
446
+ className: "text-[var(--prui-brand)] hover:underline cursor-pointer",
447
+ children: g
448
+ }
449
+ ) }) : null
450
+ ] });
451
+ }
452
+ const Fe = {
453
+ name: "OtpPage",
454
+ props: [
455
+ { name: "onSubmit", type: "(code: string) => void | Promise<void>", default: null, control: "none" },
456
+ { name: "length", type: "number", default: "6", control: "number" },
457
+ { name: "brand", type: "BrandConfig", default: "undefined", control: "object" },
458
+ { name: "loading", type: "boolean", default: "false", control: "boolean" },
459
+ { name: "error", type: "string | null", default: "null", control: "text" },
460
+ { name: "onResend", type: "() => void | Promise<void>", default: null, control: "none" }
461
+ ]
462
+ };
463
+ function de({ onLogout: t, brand: r, message: o, loading: n = !1 }) {
464
+ return v.useEffect(() => {
465
+ t && t();
466
+ }, [t]), /* @__PURE__ */ e(j, { title: "Signing out", brand: r, width: "max-w-xs", children: /* @__PURE__ */ a("div", { className: "flex flex-col items-center gap-3 py-4 text-[var(--prui-dim)]", "data-testid": "logout-page", children: [
467
+ /* @__PURE__ */ e(H, { className: "h-6 w-6", "aria-hidden": !0 }),
468
+ /* @__PURE__ */ e("p", { className: "text-sm text-center", children: o ?? (n ? "Signing you out..." : "You have been signed out.") })
469
+ ] }) });
470
+ }
471
+ const Re = {
472
+ name: "LogoutPage",
473
+ props: [
474
+ { name: "onLogout", type: "() => void | Promise<void>", default: null, control: "none" },
475
+ { name: "brand", type: "BrandConfig", default: "undefined", control: "object" },
476
+ { name: "message", type: "ReactNode", default: "generic", control: "text" },
477
+ { name: "loading", type: "boolean", default: "false", control: "boolean" }
478
+ ]
479
+ };
480
+ function ce({
481
+ title: t = "Page not found",
482
+ description: r = "The page you are looking for does not exist or has been moved.",
483
+ homeHref: o = "/",
484
+ onGoHome: n,
485
+ brand: d
486
+ }) {
487
+ return /* @__PURE__ */ e(j, { title: t, description: r, brand: d, width: "max-w-md", children: /* @__PURE__ */ a("div", { className: "flex flex-col items-center gap-4 py-4", "data-testid": "notfound-page", children: [
488
+ /* @__PURE__ */ e(W, { className: "h-10 w-10 text-[var(--prui-dim)]", "aria-hidden": !0 }),
489
+ /* @__PURE__ */ e("code", { className: "text-3xl font-bold text-[var(--prui-fg)]", children: "404" }),
490
+ n ? /* @__PURE__ */ e(S, { variant: "primary", onClick: n, "data-testid": "notfound-home", children: "Go home" }) : /* @__PURE__ */ e(S, { variant: "primary", asChild: !0, "data-testid": "notfound-home", children: /* @__PURE__ */ e("a", { href: o, children: "Go home" }) })
491
+ ] }) });
492
+ }
493
+ const qe = {
494
+ name: "NotFoundPage",
495
+ props: [
496
+ { name: "title", type: "string", default: "'Page not found'", control: "text" },
497
+ { name: "description", type: "ReactNode", default: "generic", control: "text" },
498
+ { name: "homeHref", type: "string", default: "'/'", control: "text" },
499
+ { name: "onGoHome", type: "() => void", default: null, control: "none" },
500
+ { name: "brand", type: "BrandConfig", default: "undefined", control: "object" }
501
+ ]
502
+ };
503
+ function ue({
504
+ title: t = "Something went wrong",
505
+ error: r,
506
+ onRetry: o,
507
+ retryLabel: n = "Try again",
508
+ brand: d
509
+ }) {
510
+ const i = r instanceof Error ? r.message : typeof r == "string" ? r : void 0;
511
+ return /* @__PURE__ */ e(j, { title: t, brand: d, width: "max-w-md", children: /* @__PURE__ */ a("div", { className: "flex flex-col items-center gap-4 py-4", "data-testid": "error-page", children: [
512
+ /* @__PURE__ */ e(U, { className: "h-10 w-10 text-[var(--prui-warn)]", "aria-hidden": !0 }),
513
+ i ? /* @__PURE__ */ e("p", { role: "alert", className: "rounded-[var(--prui-radius)] border border-[var(--prui-warn)]/40 bg-[var(--prui-warn)]/10 px-3 py-2 text-sm text-[var(--prui-warn)]", children: i }) : /* @__PURE__ */ e("p", { className: "text-sm text-[var(--prui-dim)]", children: "An unexpected error occurred." }),
514
+ o ? /* @__PURE__ */ e(S, { variant: "primary", onClick: o, "data-testid": "error-retry", children: n }) : null
515
+ ] }) });
516
+ }
517
+ const Ee = {
518
+ name: "ErrorPage",
519
+ props: [
520
+ { name: "title", type: "string", default: "'Something went wrong'", control: "text" },
521
+ { name: "error", type: "unknown", default: null, control: "text" },
522
+ { name: "onRetry", type: "() => void", default: null, control: "none" },
523
+ { name: "retryLabel", type: "string", default: "'Try again'", control: "text" },
524
+ { name: "brand", type: "BrandConfig", default: "undefined", control: "object" }
525
+ ]
526
+ };
527
+ function De({
528
+ title: t = "Nothing here yet",
529
+ description: r,
530
+ icon: o = K,
531
+ action: n,
532
+ className: d
533
+ }) {
534
+ return /* @__PURE__ */ a("div", { className: d ?? "flex flex-col items-center justify-center gap-3 rounded-[var(--prui-radius)] border border-dashed border-[var(--prui-line)] px-6 py-12 text-center", "data-testid": "empty-state", children: [
535
+ /* @__PURE__ */ e(o, { className: "h-8 w-8 text-[var(--prui-dim)]", "aria-hidden": !0 }),
536
+ /* @__PURE__ */ a("div", { children: [
537
+ /* @__PURE__ */ e("p", { className: "text-sm font-medium text-[var(--prui-fg)]", children: t }),
538
+ r ? /* @__PURE__ */ e("p", { className: "mt-1 text-sm text-[var(--prui-dim)]", children: r }) : null
539
+ ] }),
540
+ n
541
+ ] });
542
+ }
543
+ const Me = {
544
+ name: "EmptyState",
545
+ props: [
546
+ { name: "title", type: "string", default: "'Nothing here yet'", control: "text" },
547
+ { name: "description", type: "ReactNode", default: null, control: "text" },
548
+ { name: "icon", type: "LucideIcon", default: "Inbox", control: "icon" },
549
+ { name: "action", type: "ReactNode", default: null, control: "none" }
550
+ ]
551
+ };
552
+ function me({
553
+ profile: t = {},
554
+ onSubmit: r,
555
+ fields: o,
556
+ onSignOut: n,
557
+ signOutLabel: d = "Sign out",
558
+ brand: i,
559
+ submitLabel: p = "Save profile",
560
+ loading: c = !1,
561
+ error: x
562
+ }) {
563
+ const g = { name: !0, email: !0, bio: !0, ...o }, [s, m] = v.useState({
564
+ name: t.name ?? "",
565
+ email: t.email ?? "",
566
+ bio: t.bio ?? ""
567
+ }), [f, y] = v.useState(!1);
568
+ return /* @__PURE__ */ a(j, { title: "Your profile", brand: i, width: "max-w-lg", children: [
569
+ /* @__PURE__ */ e(F, { error: x }),
570
+ /* @__PURE__ */ a("form", { onSubmit: async (N) => {
571
+ N.preventDefault();
572
+ try {
573
+ const h = r == null ? void 0 : r({ ...s });
574
+ h && typeof h.then == "function" && (y(!0), await h);
575
+ } finally {
576
+ y(!1);
577
+ }
578
+ }, className: "flex flex-col gap-4", "data-testid": "profile-form", children: [
579
+ /* @__PURE__ */ a("div", { className: "flex items-center gap-3", "data-testid": "profile-avatar", children: [
580
+ /* @__PURE__ */ e(ee, { src: t.avatar, alt: s.name || "User", size: "lg" }),
581
+ /* @__PURE__ */ e("div", { className: "text-sm text-[var(--prui-dim)]", children: s.email || "No email" })
582
+ ] }),
583
+ g.name !== !1 ? /* @__PURE__ */ a("div", { className: "flex flex-col gap-1.5", children: [
584
+ /* @__PURE__ */ e(C, { htmlFor: "profile-name", children: "Name" }),
585
+ /* @__PURE__ */ e(
586
+ P,
587
+ {
588
+ id: "profile-name",
589
+ disabled: c || f,
590
+ value: s.name,
591
+ onChange: (N) => m((h) => ({ ...h, name: N.target.value }))
592
+ }
593
+ )
594
+ ] }) : null,
595
+ g.email !== !1 ? /* @__PURE__ */ a("div", { className: "flex flex-col gap-1.5", children: [
596
+ /* @__PURE__ */ e(C, { htmlFor: "profile-email", children: "Email" }),
597
+ /* @__PURE__ */ e(
598
+ P,
599
+ {
600
+ id: "profile-email",
601
+ type: "email",
602
+ disabled: c || f,
603
+ value: s.email,
604
+ onChange: (N) => m((h) => ({ ...h, email: N.target.value }))
605
+ }
606
+ )
607
+ ] }) : null,
608
+ g.bio !== !1 ? /* @__PURE__ */ a("div", { className: "flex flex-col gap-1.5", children: [
609
+ /* @__PURE__ */ e(C, { htmlFor: "profile-bio", children: "Bio" }),
610
+ /* @__PURE__ */ e(
611
+ G,
612
+ {
613
+ id: "profile-bio",
614
+ rows: 3,
615
+ disabled: c || f,
616
+ value: s.bio,
617
+ onChange: (N) => m((h) => ({ ...h, bio: N.target.value }))
618
+ }
619
+ )
620
+ ] }) : null,
621
+ /* @__PURE__ */ a("div", { className: "flex items-center justify-between", children: [
622
+ n ? /* @__PURE__ */ e(S, { type: "button", variant: "ghost", onClick: n, children: d }) : /* @__PURE__ */ e("span", {}),
623
+ /* @__PURE__ */ e(S, { type: "submit", variant: "primary", loading: c || f, "data-testid": "profile-submit", children: p })
624
+ ] })
625
+ ] })
626
+ ] });
627
+ }
628
+ const Le = {
629
+ name: "ProfilePage",
630
+ props: [
631
+ { name: "profile", type: "{ name?, email?, avatar?, bio? }", default: "{}", control: "object" },
632
+ { name: "onSubmit", type: "(values) => void | Promise<void>", default: null, control: "none" },
633
+ { name: "fields", type: "{ name?, email?, bio? }", default: "all shown", control: "object" },
634
+ { name: "onSignOut", type: "() => void", default: null, control: "none" },
635
+ { name: "brand", type: "BrandConfig", default: "undefined", control: "object" },
636
+ { name: "loading", type: "boolean", default: "false", control: "boolean" },
637
+ { name: "error", type: "string | null", default: "null", control: "text" }
638
+ ]
639
+ };
640
+ function pe({ title: t = "Settings", toggles: r = [], brand: o }) {
641
+ return /* @__PURE__ */ e(j, { title: t, brand: o, width: "max-w-lg", children: /* @__PURE__ */ a(Q, { children: [
642
+ /* @__PURE__ */ a(J, { children: [
643
+ /* @__PURE__ */ e(X, { children: "Preferences" }),
644
+ /* @__PURE__ */ e(Z, { children: "Changes apply immediately." })
645
+ ] }),
646
+ /* @__PURE__ */ e(_, { className: "flex flex-col divide-y divide-[var(--prui-line)]", children: r.length === 0 ? /* @__PURE__ */ e("p", { className: "py-3 text-sm text-[var(--prui-dim)]", children: "No settings available." }) : r.map((n) => /* @__PURE__ */ e(fe, { toggle: n }, n.id)) }),
647
+ /* @__PURE__ */ e(k, { className: "justify-end", children: /* @__PURE__ */ a("span", { className: "text-xs text-[var(--prui-dim)]", "data-testid": "settings-page", children: [
648
+ r.length,
649
+ " setting",
650
+ r.length === 1 ? "" : "s"
651
+ ] }) })
652
+ ] }) });
653
+ }
654
+ function fe({ toggle: t }) {
655
+ const [r, o] = v.useState(t.defaultChecked ?? !1), n = t.checked !== void 0, d = n ? t.checked : r;
656
+ return /* @__PURE__ */ a("div", { className: "flex items-center justify-between gap-4 py-3 first:pt-0 last:pb-0", children: [
657
+ /* @__PURE__ */ a("div", { className: "min-w-0", children: [
658
+ /* @__PURE__ */ e("p", { className: "text-sm font-medium text-[var(--prui-fg)]", children: t.label }),
659
+ t.description ? /* @__PURE__ */ e("p", { className: "text-xs text-[var(--prui-dim)]", children: t.description }) : null
660
+ ] }),
661
+ /* @__PURE__ */ e(
662
+ te,
663
+ {
664
+ "aria-label": t.label,
665
+ checked: d,
666
+ onChange: (i) => {
667
+ var p;
668
+ n || o(i), (p = t.onChange) == null || p.call(t, i);
669
+ }
670
+ }
671
+ )
672
+ ] });
673
+ }
674
+ const Ae = {
675
+ name: "SettingsPage",
676
+ props: [
677
+ { name: "title", type: "string", default: "'Settings'", control: "text" },
678
+ { name: "toggles", type: "SettingsToggle[]", default: "[]", control: "object" },
679
+ { name: "brand", type: "BrandConfig", default: "undefined", control: "object" }
680
+ ]
681
+ };
682
+ function he({
683
+ onSubmit: t,
684
+ brand: r,
685
+ description: o = "Create the first administrator account for this instance.",
686
+ loading: n = !1,
687
+ error: d
688
+ }) {
689
+ const [i, p] = v.useState({ name: "", email: "", password: "" }), [c, x] = v.useState(!1);
690
+ return /* @__PURE__ */ a(j, { title: "Set up admin", description: o, brand: r, width: "max-w-md", children: [
691
+ /* @__PURE__ */ e(F, { error: d }),
692
+ /* @__PURE__ */ a("form", { onSubmit: async (s) => {
693
+ s.preventDefault();
694
+ try {
695
+ const m = t == null ? void 0 : t({ ...i });
696
+ m && typeof m.then == "function" && (x(!0), await m);
697
+ } finally {
698
+ x(!1);
699
+ }
700
+ }, className: "flex flex-col gap-3", "data-testid": "adminsetup-form", children: [
701
+ /* @__PURE__ */ a("div", { className: "flex flex-col gap-1.5", children: [
702
+ /* @__PURE__ */ a(C, { htmlFor: "admin-name", children: [
703
+ "Name",
704
+ /* @__PURE__ */ e("span", { className: "ml-0.5 text-[var(--prui-danger)]", children: "*" })
705
+ ] }),
706
+ /* @__PURE__ */ e(
707
+ P,
708
+ {
709
+ id: "admin-name",
710
+ required: !0,
711
+ autoComplete: "name",
712
+ disabled: n || c,
713
+ value: i.name,
714
+ onChange: (s) => p((m) => ({ ...m, name: s.target.value }))
715
+ }
716
+ )
717
+ ] }),
718
+ /* @__PURE__ */ a("div", { className: "flex flex-col gap-1.5", children: [
719
+ /* @__PURE__ */ a(C, { htmlFor: "admin-email", children: [
720
+ "Email",
721
+ /* @__PURE__ */ e("span", { className: "ml-0.5 text-[var(--prui-danger)]", children: "*" })
722
+ ] }),
723
+ /* @__PURE__ */ e(
724
+ P,
725
+ {
726
+ id: "admin-email",
727
+ type: "email",
728
+ required: !0,
729
+ autoComplete: "email",
730
+ disabled: n || c,
731
+ value: i.email,
732
+ onChange: (s) => p((m) => ({ ...m, email: s.target.value }))
733
+ }
734
+ )
735
+ ] }),
736
+ /* @__PURE__ */ a("div", { className: "flex flex-col gap-1.5", children: [
737
+ /* @__PURE__ */ a(C, { htmlFor: "admin-password", children: [
738
+ "Password",
739
+ /* @__PURE__ */ e("span", { className: "ml-0.5 text-[var(--prui-danger)]", children: "*" })
740
+ ] }),
741
+ /* @__PURE__ */ e(
742
+ P,
743
+ {
744
+ id: "admin-password",
745
+ type: "password",
746
+ required: !0,
747
+ autoComplete: "new-password",
748
+ disabled: n || c,
749
+ value: i.password,
750
+ onChange: (s) => p((m) => ({ ...m, password: s.target.value }))
751
+ }
752
+ )
753
+ ] }),
754
+ /* @__PURE__ */ e(S, { type: "submit", variant: "primary", loading: n || c, "data-testid": "adminsetup-submit", children: "Create admin" })
755
+ ] })
756
+ ] });
757
+ }
758
+ const Te = {
759
+ name: "AdminSetup",
760
+ props: [
761
+ { name: "onSubmit", type: "(values) => void | Promise<void>", default: null, control: "none" },
762
+ { name: "brand", type: "BrandConfig", default: "undefined", control: "object" },
763
+ { name: "description", type: "ReactNode", default: "generic", control: "text" },
764
+ { name: "loading", type: "boolean", default: "false", control: "boolean" },
765
+ { name: "error", type: "string | null", default: "null", control: "text" }
766
+ ]
767
+ }, Ve = {
768
+ login: ne,
769
+ register: le,
770
+ forgotPassword: oe,
771
+ resetPassword: ie,
772
+ otp: se,
773
+ logout: de,
774
+ notFound: ce,
775
+ error: ue,
776
+ profile: me,
777
+ settings: pe,
778
+ adminSetup: he
779
+ };
780
+ export {
781
+ he as AdminSetup,
782
+ De as EmptyState,
783
+ ue as ErrorPage,
784
+ oe as ForgotPasswordPage,
785
+ ne as LoginPage,
786
+ de as LogoutPage,
787
+ ce as NotFoundPage,
788
+ se as OtpPage,
789
+ Ve as PagesRegistry,
790
+ me as ProfilePage,
791
+ le as RegisterPage,
792
+ ie as ResetPasswordPage,
793
+ pe as SettingsPage,
794
+ Te as adminSetupPropsMeta,
795
+ Me as emptyStatePropsMeta,
796
+ Ee as errorPagePropsMeta,
797
+ je as forgotPasswordPagePropsMeta,
798
+ Ce as loginPagePropsMeta,
799
+ Re as logoutPagePropsMeta,
800
+ qe as notFoundPagePropsMeta,
801
+ Fe as otpPagePropsMeta,
802
+ Le as profilePagePropsMeta,
803
+ Se as registerPagePropsMeta,
804
+ Be as resetPasswordPagePropsMeta,
805
+ Ae as settingsPagePropsMeta
806
+ };