@tempots/beatui 1.6.1 → 1.7.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.
- package/dist/auth/index.cjs.js +1 -1
- package/dist/auth/index.es.js +1 -1
- package/dist/auth-divider-CjcrgXmq.cjs +1 -0
- package/dist/{auth-divider-qnJuYK-x.js → auth-divider-D9KnNeyF.js} +239 -230
- package/dist/better-auth/index.cjs.js +1 -1
- package/dist/better-auth/index.es.js +396 -347
- package/dist/{custom-validation-BetUqAEz.js → custom-validation-7por5nJN.js} +1 -1
- package/dist/{deep-merge-ZVigk5Qf.js → deep-merge-DT2H9AGq.js} +1 -1
- package/dist/{duration-input-GMBmT1BE.js → duration-input-D4V_PHIg.js} +1 -1
- package/dist/index.cjs.js +4 -4
- package/dist/index.es.js +2325 -2263
- package/dist/json-schema/index.es.js +5 -5
- package/dist/json-structure/index.es.js +3 -3
- package/dist/{notice-B6ojfenv.js → notice-CQGJyZ8o.js} +1 -1
- package/dist/types/better-auth/callbacks.d.ts +4 -4
- package/dist/types/better-auth/components/authenticated.d.ts +27 -2
- package/dist/types/better-auth/components/better-auth-container.d.ts +6 -0
- package/dist/types/better-auth/index.d.ts +2 -1
- package/dist/types/better-auth/provider.d.ts +1 -1
- package/dist/types/better-auth/types.d.ts +22 -0
- package/dist/types/components/auth/auth-email-prop.d.ts +6 -12
- package/dist/types/components/auth/types.d.ts +7 -6
- package/dist/types/components/auth/utils.d.ts +4 -2
- package/dist/types/components/query/index.d.ts +2 -0
- package/dist/types/components/query/query-data-source.d.ts +73 -0
- package/dist/types/components/query/query-data-table.d.ts +62 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/{use-form-NfobsGNl.js → use-form-8NnZ-KHk.js} +9 -9
- package/dist/{widget-customization-BtkexHgm.js → widget-customization-BIBva3f-.js} +2 -2
- package/package.json +1 -1
- package/dist/auth-divider-DewHpITQ.cjs +0 -1
|
@@ -2,13 +2,13 @@ import { attr as O, Value as j, Fragment as ce, Empty as U, WithElement as Te, U
|
|
|
2
2
|
import { m as ve, c as Le, g as We, a as Be, r as De, e as gt, f as Oe, S as ht, b as bt, h as we, i as vt } from "../oneof-branch-detection-Q_jxvJIA.js";
|
|
3
3
|
import { j as Nr, k as Rr, l as Fr, n as Vr, o as Er, p as Tr, q as Mr } from "../oneof-branch-detection-Q_jxvJIA.js";
|
|
4
4
|
import { B as q } from "../translations-BCMP-h52.js";
|
|
5
|
-
import { P as wt, E as St, N as xe } from "../notice-
|
|
6
|
-
import { g as je, B as At, N as H, a as fe, b as Ot, C as jt, c as kt, d as Ct, e as Pt, f as It, h as Nt, i as Rt, S as Ft, j as Vt, R as Et, k as Tt, E as _e, W as Mt } from "../widget-customization-
|
|
7
|
-
import { l as Lr, m as Wr, n as Br, o as Dr } from "../widget-customization-
|
|
5
|
+
import { P as wt, E as St, N as xe } from "../notice-CQGJyZ8o.js";
|
|
6
|
+
import { g as je, B as At, N as H, a as fe, b as Ot, C as jt, c as kt, d as Ct, e as Pt, f as It, h as Nt, i as Rt, S as Ft, j as Vt, R as Et, k as Tt, E as _e, W as Mt } from "../widget-customization-BIBva3f-.js";
|
|
7
|
+
import { l as Lr, m as Wr, n as Br, o as Dr } from "../widget-customization-BIBva3f-.js";
|
|
8
8
|
import { S as _, L as ee, M as $t } from "../stack-BLMteGTn.js";
|
|
9
|
-
import { F as ie,
|
|
9
|
+
import { F as ie, c as A, M as de, b as ke, C as Ue, O as Lt, A as Wt, g as Bt } from "../use-form-8NnZ-KHk.js";
|
|
10
10
|
import { objectEntries as Ke, upperCaseFirst as qe, Validation as L } from "@tempots/std";
|
|
11
|
-
import { S as Dt, b as xt, N as Je, W as _t, c as Ut, t as te, e as Q, T as Kt, U as qt, f as pe, g as Jt, M as ae, G as zt, h as Ht, L as Gt, i as Xt, j as Yt } from "../deep-merge-
|
|
11
|
+
import { S as Dt, b as xt, N as Je, W as _t, c as Ut, t as te, e as Q, T as Kt, U as qt, f as pe, g as Jt, M as ae, G as zt, h as Ht, L as Gt, i as Xt, j as Yt } from "../deep-merge-DT2H9AGq.js";
|
|
12
12
|
import { r as F } from "../utils-vUtP6iPG.js";
|
|
13
13
|
import { m as Zt, T as Qt } from "../text-input-NJypZSnE.js";
|
|
14
14
|
import { B as ze } from "../input-container-8JFB11xN.js";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { html as p, attr as f, Empty as Z, MapSignal as B, Fragment as P, Value as x, computedOf as M, When as Ke, prop as Je, WithElement as Ze, OnDispose as He } from "@tempots/dom";
|
|
2
2
|
import { upperCaseFirst as H, humanize as Xe, objectEntries as Ye, Validation as re } from "@tempots/std";
|
|
3
|
-
import { b,
|
|
4
|
-
import { e as X, N as tt, f as de, g as fe, U as nt, c as rt, a as it, T as st, L as me, b as ye, h as at, G as ut, i as ot, S as ct, j as lt } from "../deep-merge-
|
|
3
|
+
import { c as b, b as ie, F as W, e as Qe, O as se, A as G, g as et } from "../use-form-8NnZ-KHk.js";
|
|
4
|
+
import { e as X, N as tt, f as de, g as fe, U as nt, c as rt, a as it, T as st, L as me, b as ye, h as at, G as ut, i as ot, S as ct, j as lt } from "../deep-merge-DT2H9AGq.js";
|
|
5
5
|
import { T as pt } from "../text-input-NJypZSnE.js";
|
|
6
|
-
import { N as dt, B as ft, D as mt, a as yt, P as gt, b as ht, c as bt, d as vt, e as xt, F as $t } from "../duration-input-
|
|
6
|
+
import { N as dt, B as ft, D as mt, a as yt, P as gt, b as ht, c as bt, d as vt, e as xt, F as $t } from "../duration-input-D4V_PHIg.js";
|
|
7
7
|
import { B as U } from "../input-container-8JFB11xN.js";
|
|
8
8
|
import { L as ge, S as K, M as Tt } from "../stack-BLMteGTn.js";
|
|
9
9
|
function It(e) {
|
|
@@ -2,7 +2,7 @@ import { C as x } from "./text-input-NJypZSnE.js";
|
|
|
2
2
|
import { Use as E, input as j, attr as t, coalesce as A, Empty as g, on as p, emitValue as w, prop as O, computedOf as y, html as u, aria as D, When as B, Fragment as F, Value as h, Unless as M, Ensure as R } from "@tempots/dom";
|
|
3
3
|
import { a as S, I as k } from "./input-container-8JFB11xN.js";
|
|
4
4
|
import { B as V, I as z } from "./translations-BCMP-h52.js";
|
|
5
|
-
import { C as W } from "./use-form-
|
|
5
|
+
import { C as W } from "./use-form-8NnZ-KHk.js";
|
|
6
6
|
const Y = (o) => {
|
|
7
7
|
const l = {
|
|
8
8
|
name: "email",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { SignInData, SignUpData, ResetPasswordData } from '../components/auth';
|
|
2
|
-
import { BetterAuthClient, BetterAuthBridgeOptions } from './types';
|
|
3
|
-
export declare function createSignInCallback(client: BetterAuthClient, opts: BetterAuthBridgeOptions, onSuccess: () => Promise<void
|
|
4
|
-
export declare function createSignUpCallback(client: BetterAuthClient, opts: BetterAuthBridgeOptions, onSuccess: () => Promise<void
|
|
5
|
-
export declare function createResetPasswordCallback(client: BetterAuthClient, opts: BetterAuthBridgeOptions): (data: ResetPasswordData) => Promise<
|
|
2
|
+
import { BetterAuthClient, BetterAuthBridgeOptions, BetterAuthUser, AuthError } from './types';
|
|
3
|
+
export declare function createSignInCallback(client: BetterAuthClient, opts: BetterAuthBridgeOptions, onSuccess: () => Promise<void>, onAuthSuccess?: (user: BetterAuthUser) => void): (data: SignInData) => Promise<AuthError | null>;
|
|
4
|
+
export declare function createSignUpCallback(client: BetterAuthClient, opts: BetterAuthBridgeOptions, onSuccess: () => Promise<void>, onAuthSuccess?: (user: BetterAuthUser) => void): (data: SignUpData) => Promise<AuthError | null>;
|
|
5
|
+
export declare function createResetPasswordCallback(client: BetterAuthClient, opts: BetterAuthBridgeOptions): (data: ResetPasswordData) => Promise<AuthError | null>;
|
|
6
6
|
export declare function createSocialLoginHandler(client: BetterAuthClient, opts: BetterAuthBridgeOptions): (provider: string) => Promise<void>;
|
|
@@ -1,4 +1,29 @@
|
|
|
1
1
|
import { TNode } from '@tempots/dom';
|
|
2
2
|
import { BetterAuthBridge } from '../types';
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Options for {@link Authenticated} and {@link Unauthenticated} guard components.
|
|
5
|
+
*/
|
|
6
|
+
export interface AuthGuardOptions {
|
|
7
|
+
/** Content to render when the guard condition is met. */
|
|
8
|
+
children: () => TNode;
|
|
9
|
+
/** Content to render while the initial session fetch is in progress. */
|
|
10
|
+
loading?: () => TNode;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Renders children only when the user is authenticated.
|
|
14
|
+
*
|
|
15
|
+
* While the session is pending (initial fetch), renders the `loading` fallback
|
|
16
|
+
* or nothing (`Empty`) by default.
|
|
17
|
+
*/
|
|
18
|
+
export declare function Authenticated(auth: BetterAuthBridge, options: AuthGuardOptions): import("@tempots/core").Renderable<import("@tempots/dom").DOMContext, typeof import("@tempots/dom").DOM_RENDERABLE_TYPE>;
|
|
19
|
+
/**
|
|
20
|
+
* Renders children only when the user is NOT authenticated.
|
|
21
|
+
*
|
|
22
|
+
* While the session is pending, renders children by default (showing the
|
|
23
|
+
* sign-in form during loading is a reasonable default). Provide a `loading`
|
|
24
|
+
* fallback to show a spinner instead.
|
|
25
|
+
*
|
|
26
|
+
* Note: The default behavior causes a brief flash of unauthenticated content
|
|
27
|
+
* if the user is actually authenticated. Use `loading` to avoid this.
|
|
28
|
+
*/
|
|
29
|
+
export declare function Unauthenticated(auth: BetterAuthBridge, options: AuthGuardOptions): import("@tempots/core").Renderable<import("@tempots/dom").DOMContext, typeof import("@tempots/dom").DOM_RENDERABLE_TYPE>;
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
import { TNode } from '@tempots/dom';
|
|
2
2
|
import { AuthContainerOptions } from '../../components/auth';
|
|
3
3
|
import { BetterAuthBridge } from '../types';
|
|
4
|
+
/**
|
|
5
|
+
* Better-auth wrapper around {@link AuthContainer}.
|
|
6
|
+
*
|
|
7
|
+
* Automatically provides the `AuthI18n` context via lazy import,
|
|
8
|
+
* so consumers don't need to wrap in `BeatUI({ includeAuthI18n: true })`.
|
|
9
|
+
*/
|
|
4
10
|
export declare function BetterAuthContainer(auth: BetterAuthBridge, overrides?: Partial<AuthContainerOptions>, ...children: TNode[]): import("@tempots/core").Renderable<import("@tempots/dom").DOMContext, typeof import("@tempots/dom").DOM_RENDERABLE_TYPE>;
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
*
|
|
12
12
|
* @module
|
|
13
13
|
*/
|
|
14
|
-
export type { BetterAuthClient, BetterAuthResult, BetterAuthUser, BetterAuthSession, BetterAuthBridge, BetterAuthBridgeOptions, TwoFactorClient, PasskeyClient, PasskeyInfo, } from './types';
|
|
14
|
+
export type { BetterAuthClient, BetterAuthResult, BetterAuthUser, BetterAuthSession, BetterAuthBridge, BetterAuthBridgeOptions, TwoFactorClient, PasskeyClient, PasskeyInfo, AuthFieldError, AuthError, } from './types';
|
|
15
15
|
export { createBetterAuthBridge } from './bridge';
|
|
16
16
|
export { createSessionManager } from './session';
|
|
17
17
|
export type { SessionManager } from './session';
|
|
@@ -21,6 +21,7 @@ export type { BetterAuthProviderOptions } from './provider';
|
|
|
21
21
|
export { BetterAuthContainer } from './components/better-auth-container';
|
|
22
22
|
export { BetterAuthModal } from './components/better-auth-modal';
|
|
23
23
|
export { Authenticated, Unauthenticated } from './components/authenticated';
|
|
24
|
+
export type { AuthGuardOptions } from './components/authenticated';
|
|
24
25
|
export { TwoFactorSetup } from './components/two-factor-setup';
|
|
25
26
|
export type { TwoFactorSetupOptions } from './components/two-factor-setup';
|
|
26
27
|
export { TwoFactorVerify } from './components/two-factor-verify';
|
|
@@ -29,7 +29,7 @@ export interface BetterAuthProviderOptions extends BetterAuthBridgeOptions {
|
|
|
29
29
|
* import { Provide, Use } from '@tempots/dom'
|
|
30
30
|
* import { BetterAuth } from '@tempots/beatui/auth'
|
|
31
31
|
*
|
|
32
|
-
* Provide(BetterAuth, { client: authClient, socialProviders: ['google'] },
|
|
32
|
+
* Provide(BetterAuth, { client: authClient, socialProviders: ['google'] }, () =>
|
|
33
33
|
* Use(BetterAuth, (bridge) =>
|
|
34
34
|
* AuthContainer(bridge.containerOptions)
|
|
35
35
|
* )
|
|
@@ -222,6 +222,12 @@ export interface BetterAuthBridgeOptions {
|
|
|
222
222
|
}) => void;
|
|
223
223
|
/** Custom label overrides for all auth form text. */
|
|
224
224
|
labels?: AuthContainerLabels;
|
|
225
|
+
/**
|
|
226
|
+
* Callback invoked after successful sign-in or sign-up.
|
|
227
|
+
* Use this to trigger navigation (e.g., redirect to dashboard).
|
|
228
|
+
* @param user - The authenticated user.
|
|
229
|
+
*/
|
|
230
|
+
onAuthSuccess?: (user: BetterAuthUser) => void;
|
|
225
231
|
}
|
|
226
232
|
/**
|
|
227
233
|
* Represents an active authentication session.
|
|
@@ -235,6 +241,22 @@ export interface BetterAuthSession {
|
|
|
235
241
|
/** Additional session properties from the backend. */
|
|
236
242
|
[key: string]: unknown;
|
|
237
243
|
}
|
|
244
|
+
/**
|
|
245
|
+
* Describes an error associated with a specific form field.
|
|
246
|
+
*/
|
|
247
|
+
export interface AuthFieldError {
|
|
248
|
+
/** The form field name this error applies to (e.g., 'email', 'password'). */
|
|
249
|
+
field: string;
|
|
250
|
+
/** The human-readable error message. */
|
|
251
|
+
message: string;
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Error returned by auth callbacks.
|
|
255
|
+
*
|
|
256
|
+
* - `string` — a generic error message displayed at the form root
|
|
257
|
+
* - `AuthFieldError[]` — field-specific errors for per-field highlighting
|
|
258
|
+
*/
|
|
259
|
+
export type AuthError = string | AuthFieldError[];
|
|
238
260
|
/**
|
|
239
261
|
* The bridge object returned by {@link createBetterAuthBridge}.
|
|
240
262
|
*
|
|
@@ -5,22 +5,16 @@
|
|
|
5
5
|
* user's email address across sessions. Used by the "remember me" checkbox
|
|
6
6
|
* in sign-in and reset password forms.
|
|
7
7
|
*
|
|
8
|
+
* SSR-safe: returns a plain in-memory prop when `window` is not available.
|
|
9
|
+
*
|
|
8
10
|
* @module auth/auth-email-prop
|
|
9
11
|
*/
|
|
10
12
|
/**
|
|
11
|
-
* Creates a reactive
|
|
12
|
-
*
|
|
13
|
-
* When the "remember me" checkbox is checked, the email is stored under the key
|
|
14
|
-
* `'bui_auth_email'`. When unchecked, the value is set to `null`, removing it
|
|
15
|
-
* from storage.
|
|
13
|
+
* Creates a reactive property for persisting the user's email.
|
|
16
14
|
*
|
|
17
|
-
*
|
|
15
|
+
* In browser environments, backed by `localStorage` (key `'bui_auth_email'`).
|
|
16
|
+
* In SSR environments, returns a plain in-memory `Prop<string | null>`.
|
|
18
17
|
*
|
|
19
|
-
* @
|
|
20
|
-
* ```ts
|
|
21
|
-
* const emailProp = useAuthEmailProp()
|
|
22
|
-
* emailProp.value = 'user@example.com' // persists to localStorage
|
|
23
|
-
* emailProp.value = null // removes from localStorage
|
|
24
|
-
* ```
|
|
18
|
+
* @returns A reactive `Prop<string | null>`.
|
|
25
19
|
*/
|
|
26
20
|
export declare const useAuthEmailProp: () => import("@tempots/core").Prop<string | null>;
|
|
@@ -12,6 +12,7 @@ import { TNode, Value } from '@tempots/dom';
|
|
|
12
12
|
import { ControlSize } from '../theme';
|
|
13
13
|
import { ThemeColorName } from '../../tokens';
|
|
14
14
|
import { AuthProviderInfo } from './social-login-button';
|
|
15
|
+
import type { AuthError } from '../../better-auth/types';
|
|
15
16
|
/**
|
|
16
17
|
* Supported social authentication provider names.
|
|
17
18
|
*
|
|
@@ -235,19 +236,19 @@ export interface AuthContainerOptions {
|
|
|
235
236
|
* @param data - The sign-in form data.
|
|
236
237
|
* @returns An error message string to display, or `null` on success.
|
|
237
238
|
*/
|
|
238
|
-
onSignIn?: (data: SignInData) => Promise<
|
|
239
|
+
onSignIn?: (data: SignInData) => Promise<AuthError | null>;
|
|
239
240
|
/**
|
|
240
241
|
* Callback invoked when the sign-up form is submitted.
|
|
241
242
|
* @param data - The sign-up form data.
|
|
242
243
|
* @returns An error message string to display, or `null` on success.
|
|
243
244
|
*/
|
|
244
|
-
onSignUp?: (data: SignUpData) => Promise<
|
|
245
|
+
onSignUp?: (data: SignUpData) => Promise<AuthError | null>;
|
|
245
246
|
/**
|
|
246
247
|
* Callback invoked when the reset password form is submitted.
|
|
247
248
|
* @param data - The reset password form data.
|
|
248
249
|
* @returns An error message string to display, or `null` on success.
|
|
249
250
|
*/
|
|
250
|
-
onResetPassword?: (data: ResetPasswordData) => Promise<
|
|
251
|
+
onResetPassword?: (data: ResetPasswordData) => Promise<AuthError | null>;
|
|
251
252
|
/**
|
|
252
253
|
* Callback invoked when the user switches between auth modes.
|
|
253
254
|
* @param mode - The new authentication mode.
|
|
@@ -311,7 +312,7 @@ export interface SignInFormOptions {
|
|
|
311
312
|
* @param data - The sign-in form data.
|
|
312
313
|
* @returns An error message string to display, or `null` on success.
|
|
313
314
|
*/
|
|
314
|
-
onSignIn?: (data: SignInData) => Promise<
|
|
315
|
+
onSignIn?: (data: SignInData) => Promise<AuthError | null>;
|
|
315
316
|
/** Password validation rules for the password field. */
|
|
316
317
|
passwordRules?: PasswordRules;
|
|
317
318
|
/** Custom label overrides for form text. */
|
|
@@ -355,7 +356,7 @@ export interface SignUpFormOptions {
|
|
|
355
356
|
* @param data - The sign-up form data (without confirmPassword).
|
|
356
357
|
* @returns An error message string to display, or `null` on success.
|
|
357
358
|
*/
|
|
358
|
-
onSignUp?: (data: SignUpData) => Promise<
|
|
359
|
+
onSignUp?: (data: SignUpData) => Promise<AuthError | null>;
|
|
359
360
|
/** Whether to show the password strength indicator. */
|
|
360
361
|
showPasswordStrength?: Value<boolean>;
|
|
361
362
|
/** Whether to show the "already have an account?" link. */
|
|
@@ -391,7 +392,7 @@ export interface ResetPasswordFormOptions {
|
|
|
391
392
|
* @param data - The reset password form data containing the email.
|
|
392
393
|
* @returns An error message string to display, or `null` on success.
|
|
393
394
|
*/
|
|
394
|
-
onResetPassword?: (data: ResetPasswordData) => Promise<
|
|
395
|
+
onResetPassword?: (data: ResetPasswordData) => Promise<AuthError | null>;
|
|
395
396
|
/** Custom label overrides for form text. */
|
|
396
397
|
labels?: ResetPasswordFormLabels;
|
|
397
398
|
}
|
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
* @module auth/utils
|
|
9
9
|
*/
|
|
10
10
|
import { AuthProviderName, PasswordRules } from './types';
|
|
11
|
+
import { ControllerValidation } from '../form';
|
|
12
|
+
import type { AuthError } from '../../better-auth/types';
|
|
11
13
|
/**
|
|
12
14
|
* Mapping of every supported social provider name to its display metadata.
|
|
13
15
|
*
|
|
@@ -214,8 +216,8 @@ export declare function isBrowser(): boolean;
|
|
|
214
216
|
* ```
|
|
215
217
|
*/
|
|
216
218
|
export declare function requestToControllerValidation<T>({ task, message, onStart, onEnd, }: {
|
|
217
|
-
task: undefined | ((value: T) => Promise<
|
|
219
|
+
task: undefined | ((value: T) => Promise<AuthError | null>);
|
|
218
220
|
message: string;
|
|
219
221
|
onStart?: () => void;
|
|
220
222
|
onEnd?: () => void;
|
|
221
|
-
}): (value: T) => Promise<
|
|
223
|
+
}): (value: T) => Promise<ControllerValidation>;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { Signal, Value } from '@tempots/dom';
|
|
2
|
+
import { type QueryResourceLoadOptions } from '@tempots/ui';
|
|
3
|
+
import type { AsyncResult } from '@tempots/std';
|
|
4
|
+
/**
|
|
5
|
+
* Options for {@link createQueryDataSource}.
|
|
6
|
+
*
|
|
7
|
+
* @typeParam Req - The request signal type that triggers loading.
|
|
8
|
+
* @typeParam T - The row type in the data array.
|
|
9
|
+
* @typeParam E - The error type (defaults to `unknown`).
|
|
10
|
+
*/
|
|
11
|
+
export interface QueryDataSourceOptions<Req, T, E = unknown> {
|
|
12
|
+
/** Signal whose changes trigger a new load. */
|
|
13
|
+
request: Value<Req>;
|
|
14
|
+
/** Async function that fetches data. Receives an AbortSignal for cancellation. */
|
|
15
|
+
load: (opts: QueryResourceLoadOptions<Req, T[], E>) => Promise<T[]>;
|
|
16
|
+
/** Converts unknown errors into the error type E. Required by makeQueryResource. */
|
|
17
|
+
convertError: (error: unknown) => E;
|
|
18
|
+
/** Called on successful load. */
|
|
19
|
+
onSuccess?: (value: T[], req: Req) => void;
|
|
20
|
+
/** Called on failed load. */
|
|
21
|
+
onError?: (error: E, req: Req) => void;
|
|
22
|
+
/** Called after load completes (success or failure). */
|
|
23
|
+
onSettled?: (result: AsyncResult<T[], E>, req: Req) => void;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* The result of {@link createQueryDataSource}.
|
|
27
|
+
*
|
|
28
|
+
* @typeParam T - The row type in the data array.
|
|
29
|
+
* @typeParam E - The error type.
|
|
30
|
+
*/
|
|
31
|
+
export interface QueryDataSourceResult<T, E> {
|
|
32
|
+
/** Stable data signal — updated in-place on successful loads. */
|
|
33
|
+
readonly data: Signal<T[]>;
|
|
34
|
+
/** Whether a request is in flight. */
|
|
35
|
+
readonly loading: Signal<boolean>;
|
|
36
|
+
/** Last error, or undefined if last load succeeded. */
|
|
37
|
+
readonly error: Signal<E | undefined>;
|
|
38
|
+
/** Re-trigger the load with the current request value. */
|
|
39
|
+
readonly reload: () => void;
|
|
40
|
+
/** Clean up the QueryResource and all subscriptions. */
|
|
41
|
+
readonly dispose: () => void;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Creates a query-to-signal bridge for use with {@link DataTable}.
|
|
45
|
+
*
|
|
46
|
+
* Wraps `makeQueryResource` and exposes a stable `prop<T[]>` that updates
|
|
47
|
+
* in-place when data arrives. The data signal never changes identity, so
|
|
48
|
+
* DataTable's internal DataSource (and its sort/filter/selection state)
|
|
49
|
+
* is preserved across reloads.
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* ```ts
|
|
53
|
+
* const search = prop({ query: '' })
|
|
54
|
+
* const qds = createQueryDataSource({
|
|
55
|
+
* request: search,
|
|
56
|
+
* load: async ({ request, abortSignal }) => {
|
|
57
|
+
* const res = await fetch(`/api/users?q=${request.query}`, { signal: abortSignal })
|
|
58
|
+
* return res.json()
|
|
59
|
+
* },
|
|
60
|
+
* convertError: String,
|
|
61
|
+
* })
|
|
62
|
+
*
|
|
63
|
+
* DataTable({
|
|
64
|
+
* data: qds.data,
|
|
65
|
+
* loading: qds.loading,
|
|
66
|
+
* columns: [...],
|
|
67
|
+
* rowId: u => u.id,
|
|
68
|
+
* })
|
|
69
|
+
*
|
|
70
|
+
* OnDispose(() => qds.dispose())
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
export declare function createQueryDataSource<Req, T, E = unknown>(options: QueryDataSourceOptions<Req, T, E>): QueryDataSourceResult<T, E>;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { Signal, TNode, Value } from '@tempots/dom';
|
|
2
|
+
import type { QueryResourceLoadOptions } from '@tempots/ui';
|
|
3
|
+
import type { AsyncResult } from '@tempots/std';
|
|
4
|
+
import type { DataTableOptions } from '../data/data-table-types';
|
|
5
|
+
/**
|
|
6
|
+
* Options for {@link QueryDataTable}.
|
|
7
|
+
*
|
|
8
|
+
* Combines all {@link DataTableOptions} (except `data` and `loading`, which are
|
|
9
|
+
* managed internally) with query options from {@link QueryDataSourceOptions}.
|
|
10
|
+
*
|
|
11
|
+
* @typeParam Req - The request signal type that triggers loading.
|
|
12
|
+
* @typeParam T - The row type in the data array.
|
|
13
|
+
* @typeParam C - Column ID string union.
|
|
14
|
+
* @typeParam E - The error type (defaults to `unknown`).
|
|
15
|
+
*/
|
|
16
|
+
export type QueryDataTableOptions<Req, T, C extends string = string, E = unknown> = Omit<DataTableOptions<T, C>, 'data' | 'loading'> & {
|
|
17
|
+
/** Signal whose changes trigger a new load. */
|
|
18
|
+
request: Value<Req>;
|
|
19
|
+
/** Async function that fetches data. */
|
|
20
|
+
load: (opts: QueryResourceLoadOptions<Req, T[], E>) => Promise<T[]>;
|
|
21
|
+
/** Converts unknown errors into the error type E. */
|
|
22
|
+
convertError: (error: unknown) => E;
|
|
23
|
+
/** Called on successful load. */
|
|
24
|
+
onSuccess?: (value: T[], req: Req) => void;
|
|
25
|
+
/** Called on failed load. */
|
|
26
|
+
onError?: (error: E, req: Req) => void;
|
|
27
|
+
/** Called after load completes (success or failure). */
|
|
28
|
+
onSettled?: (result: AsyncResult<T[], E>, req: Req) => void;
|
|
29
|
+
/**
|
|
30
|
+
* Custom error rendering. When provided, shown instead of default error UI.
|
|
31
|
+
* Only displayed when no data has been loaded yet (first-load failure).
|
|
32
|
+
* On reload failures, stale data remains visible.
|
|
33
|
+
*/
|
|
34
|
+
errorContent?: (error: Signal<E | undefined>, reload: () => void) => TNode;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* A DataTable that loads data asynchronously via a query.
|
|
38
|
+
*
|
|
39
|
+
* Combines {@link createQueryDataSource} with {@link DataTable} into a single
|
|
40
|
+
* component. The DataTable is always mounted (so sort/filter/selection state
|
|
41
|
+
* persists across reloads), and loading/error states are handled automatically.
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```ts
|
|
45
|
+
* QueryDataTable({
|
|
46
|
+
* request: searchParams,
|
|
47
|
+
* load: async ({ request, abortSignal }) => {
|
|
48
|
+
* const res = await fetch(`/api/users?q=${request.query}`, { signal: abortSignal })
|
|
49
|
+
* return res.json()
|
|
50
|
+
* },
|
|
51
|
+
* convertError: String,
|
|
52
|
+
* columns: [
|
|
53
|
+
* { id: 'name', header: 'Name', cell: row => row.map(r => r.name) },
|
|
54
|
+
* { id: 'email', header: 'Email', cell: row => row.map(r => r.email) },
|
|
55
|
+
* ],
|
|
56
|
+
* rowId: u => u.id,
|
|
57
|
+
* pagination: { pageSize: 20 },
|
|
58
|
+
* sortable: true,
|
|
59
|
+
* })
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
export declare function QueryDataTable<Req, T, C extends string = string, E = unknown>(options: QueryDataTableOptions<Req, T, C, E>): TNode;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -18,6 +18,7 @@ export * from './components/beatui';
|
|
|
18
18
|
export * from './components/button';
|
|
19
19
|
export * from './components/content';
|
|
20
20
|
export * from './components/data';
|
|
21
|
+
export * from './components/query';
|
|
21
22
|
export * from './components/format';
|
|
22
23
|
export * from './components/form';
|
|
23
24
|
export * from './components/i18n';
|
|
@@ -1065,15 +1065,15 @@ export {
|
|
|
1065
1065
|
We as M,
|
|
1066
1066
|
Ce as O,
|
|
1067
1067
|
pe as R,
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1068
|
+
Pe as a,
|
|
1069
|
+
Be as b,
|
|
1070
|
+
Oe as c,
|
|
1071
|
+
z as d,
|
|
1072
|
+
E as e,
|
|
1073
|
+
A as f,
|
|
1074
|
+
Ie as g,
|
|
1075
|
+
j as h,
|
|
1076
|
+
ye as i,
|
|
1077
1077
|
ue as j,
|
|
1078
1078
|
K as k,
|
|
1079
1079
|
$e as l,
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { Value as h, prop as _t, computedOf as V, html as v, attr as u, svg as yt, svgAttr as st, Empty as T, on as $, When as Q, Fragment as Z, aria as E, emitValue as pt, Use as se, input as Ft, emitValueAsNullableDate as $t, emitValueAsNullableDateTime as kt, Repeat as le, emit as oe, style as ie, emitValueAsNumber as z } from "@tempots/dom";
|
|
2
|
-
import { F as ce, N as J, T as ue, U as he, a as pe } from "./deep-merge-
|
|
2
|
+
import { F as ce, N as J, T as ue, U as he, a as pe } from "./deep-merge-DT2H9AGq.js";
|
|
3
3
|
import { decodeBase64 as de } from "@tempots/std";
|
|
4
4
|
import { I as X } from "./input-container-8JFB11xN.js";
|
|
5
5
|
import { C as Y, m as Ct, T as ge } from "./text-input-NJypZSnE.js";
|
|
6
6
|
import { B as be, I as ut, b as Mt, a as me } from "./translations-BCMP-h52.js";
|
|
7
7
|
import { AutoSelect as fe } from "@tempots/ui";
|
|
8
|
-
import { E as we, P as ye } from "./notice-
|
|
8
|
+
import { E as we, P as ye } from "./notice-CQGJyZ8o.js";
|
|
9
9
|
import { s as $e } from "./session-id-3KiilioY.js";
|
|
10
10
|
import { r as ke } from "./utils-vUtP6iPG.js";
|
|
11
11
|
async function Me(t) {
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";const e=require("@tempots/dom"),q=require("./stack-dwLevGa2.cjs"),_=require("./use-form-Dcra7GeE.cjs"),f=require("./custom-validation-CLscGHY4.cjs"),X=require("@tempots/std"),m=require("./translations-BqWc0ZHz.cjs"),y=require("./notice-p2IqXS5-.cjs"),T=require("./input-container-CyOgiiQD.cjs"),ae=require("./text-input-DS5zlXb2.cjs"),ne=require("./translations-EwEmHe3v.cjs"),re=require("@tempots/ui"),$={google:{name:"Google",icon:"logos:google-icon",color:"#4285f4"},github:{name:"GitHub",icon:"logos:github-icon",color:"#333"},apple:{name:"Apple",icon:"logos:apple",color:"#000"},facebook:{name:"Facebook",icon:"logos:facebook",color:"#1877f2"},twitter:{name:"Twitter",icon:"logos:twitter",color:"#1da1f2"},microsoft:{name:"Microsoft",icon:"logos:microsoft-icon",color:"#00a4ef"},discord:{name:"Discord",icon:"logos:discord-icon",color:"#5865f2"},linkedin:{name:"LinkedIn",icon:"logos:linkedin-icon",color:"#0077b5"},instagram:{name:"Instagram",icon:"logos:instagram-icon",color:"#e4405f"},tiktok:{name:"TikTok",icon:"logos:tiktok-icon",color:"#000"},snapchat:{name:"Snapchat",icon:"logos:snapchat-icon",color:"#fffc00"},reddit:{name:"Reddit",icon:"logos:reddit-icon",color:"#ff4500"},pinterest:{name:"Pinterest",icon:"logos:pinterest-icon",color:"#bd081c"},twitch:{name:"Twitch",icon:"logos:twitch",color:"#9146ff"},steam:{name:"Steam",icon:"logos:steam-icon",color:"#000"},epic:{name:"Epic Games",icon:"simple-icons:epicgames",color:"#313131"},playstation:{name:"PlayStation",icon:"logos:playstation-icon",color:"#003791"},xbox:{name:"Xbox",icon:"logos:xbox-icon",color:"#107c10"},whatsapp:{name:"WhatsApp",icon:"logos:whatsapp-icon",color:"#25d366"},wechat:{name:"WeChat",icon:"logos:wechat-icon",color:"#1aad19"},amazon:{name:"Amazon",icon:"logos:amazon-icon",color:"#ff9900"},yahoo:{name:"Yahoo",icon:"logos:yahoo-icon",color:"#720e9e"},paypal:{name:"PayPal",icon:"logos:paypal",color:"#0070ba"},x:{name:"X",icon:"simple-icons:x",color:"#000"}};function Y(t){return $[t]?.name||t}function se(t){return $[t]?.icon||"mdi:account"}function ie(t){return $[t]?.color||"#666"}function ce(t,o="Continue with {provider}"){return o.replace("{provider}",Y(t))}const B={minLength:8,requireUppercase:!0,requireLowercase:!0,requireNumbers:!0,requireSymbols:!1};function le(t){return/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(t)}function Z(t=32){const o="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";let r="";for(let a=0;a<t;a++)r+=o.charAt(Math.floor(Math.random()*o.length));return r}function ue(t,o,r,a=[],c={}){const s={google:"https://accounts.google.com/oauth/authorize",github:"https://github.com/login/oauth/authorize",apple:"https://appleid.apple.com/auth/authorize",facebook:"https://www.facebook.com/v18.0/dialog/oauth",twitter:"https://twitter.com/i/oauth2/authorize",microsoft:"https://login.microsoftonline.com/common/oauth2/v2.0/authorize",discord:"https://discord.com/api/oauth2/authorize",linkedin:"https://www.linkedin.com/oauth/v2/authorization",instagram:"https://api.instagram.com/oauth/authorize",tiktok:"https://www.tiktok.com/v2/auth/authorize",snapchat:"https://accounts.snapchat.com/accounts/oauth2/authorize",reddit:"https://www.reddit.com/api/v1/authorize",pinterest:"https://api.pinterest.com/oauth/",twitch:"https://id.twitch.tv/oauth2/authorize",steam:"https://steamcommunity.com/oauth/authorize",epic:"https://auth.epicgames.com/authorize",playstation:"https://auth.api.sonyentertainmentnetwork.com/oauth/authorize",xbox:"https://login.live.com/oauth20_authorize.srf",whatsapp:"https://web.whatsapp.com/oauth/authorize",wechat:"https://open.weixin.qq.com/connect/qrconnect",amazon:"https://www.amazon.com/ap/oa",yahoo:"https://api.login.yahoo.com/oauth2/request_auth",paypal:"https://www.paypal.com/signin/authorize",x:"https://api.twitter.com/oauth2/authorize"},u={google:["openid","email","profile"],github:["user:email"],apple:["email","name"],facebook:["email"],twitter:["users.read"],microsoft:["openid","email","profile"],discord:["identify","email"],linkedin:["r_liteprofile","r_emailaddress"],instagram:["user_profile","user_media"],tiktok:["user.info.basic","user.external.id"],snapchat:["user.info.basic","user.external.id"],reddit:["identity","email"],pinterest:["read_public","read_relationships"],twitch:["openid","email","profile"],steam:["openid","email","profile"],epic:["openid","email","profile"],playstation:["openid","email","profile"],xbox:["openid","email","profile"],whatsapp:["openid","email","profile"],wechat:["openid","email","profile"],amazon:["openid","email","profile"],yahoo:["openid","email","profile"],paypal:["openid","email","profile"],x:["openid","email","profile"]},n=s[t];if(!n)throw new Error(`Unsupported provider: ${t}`);const l=a.length>0?a:u[t],i=Z(),h=new URLSearchParams({client_id:o,redirect_uri:r,scope:l.join(" "),state:i,response_type:"code",...c});return`${n}?${h.toString()}`}function me(t,o,r,a){const c=window.open(t,`${o}_login`,"width=500,height=600,scrollbars=yes,resizable=yes");if(!c){a?.(new Error("Failed to open popup window"));return}const s=setInterval(()=>{c.closed&&(clearInterval(s),a?.(new Error("Login cancelled")))},1e3),u=n=>{n.origin===window.location.origin&&(n.data.type==="SOCIAL_LOGIN_SUCCESS"?(clearInterval(s),c.close(),window.removeEventListener("message",u),r?.(n.data.result)):n.data.type==="SOCIAL_LOGIN_ERROR"&&(clearInterval(s),c.close(),window.removeEventListener("message",u),a?.(new Error(n.data.error))))};window.addEventListener("message",u)}function de(t){return t instanceof Error?t.message:typeof t=="string"?t:t&&typeof t=="object"&&"message"in t?String(t.message):"An unexpected error occurred"}function pe(){return typeof window<"u"&&typeof document<"u"}function E({task:t,message:o,onStart:r,onEnd:a}){return async c=>{r?.();const s=await _.taskToValidation({task:t!=null?()=>t(c):async()=>null,errorMessage:o,errorPath:["root"],validation:u=>u!=null?X.Validation.invalid({message:u}):X.Validation.valid});return a?.(),s}}function M(t=B,o){const r=o??m.defaultMessages;let a=f.string();return t.minLength&&(a=a.min(t.minLength,(r.passwordMinLength??m.defaultMessages.passwordMinLength)(t.minLength))),t.requireUppercase&&(a=a.regex(/[A-Z]/,r.passwordRequireUppercase??m.defaultMessages.passwordRequireUppercase)),t.requireLowercase&&(a=a.regex(/[a-z]/,r.passwordRequireLowercase??m.defaultMessages.passwordRequireLowercase)),t.requireNumbers&&(a=a.regex(/[0-9]/,r.passwordRequireNumber??m.defaultMessages.passwordRequireNumber)),t.requireSymbols&&(a=a.regex(/[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?]/,r.passwordRequireSpecialChar??m.defaultMessages.passwordRequireSpecialChar)),t.customValidation&&(a=a.refine(c=>t.customValidation(c))),a}function C(t){const o=t??m.defaultMessages;return f.string().min(1,o.emailRequired??m.defaultMessages.emailRequired).email(o.invalidEmail??m.defaultMessages.invalidEmail)}const G=C();function z(t,o){const r=o??m.defaultMessages,a=t?M(t,o):f.string().refine(c=>c.length>0?null:r.passwordRequired??m.defaultMessages.passwordRequired);return f.object({email:C(o),password:a,rememberMe:f.boolean().default(!1)}).schema()}function U(t=B,o,r){const a=r??m.defaultMessages,c=M(t,r),s=o?.showNameField!==!1,u=o?.showConfirmPassword!==!1,n=o?.showAcceptTermsAndConditions!==!1,l={name:s?f.string().min(1,a.nameRequired??m.defaultMessages.nameRequired).optional():f.string().optional(),email:C(r),password:c,confirmPassword:u?f.string().min(1,a.confirmPasswordRequired??m.defaultMessages.confirmPasswordRequired):f.string(),acceptTerms:n?f.boolean().refine(h=>h===!0,a.acceptTermsRequired??m.defaultMessages.acceptTermsRequired):f.boolean().default(!0)},i=f.object(l);return u?i.refine(h=>h.password===h.confirmPassword?null:a.passwordsDoNotMatch??m.defaultMessages.passwordsDoNotMatch,{path:["confirmPassword"]}).schema():i.schema()}const j=f.object({email:G}).schema(),he=z(),ge=U(),fe={signIn:z,signUp:U,resetPassword:()=>j};function be(t,o){const r=o??m.defaultMessages,c=(o?C(o):G).validate(t);return c.success?null:c.errors[0]?.message||(r.invalidEmailAddress??m.defaultMessages.invalidEmailAddress)}function we(t,o=B,r){const a=r??m.defaultMessages,s=M(o,r).validate(t);return s.success?null:s.errors[0]?.message||(a.invalidPassword??m.defaultMessages.invalidPassword)}function R(t,o=B){const r={length:t.length>=(o.minLength||8),uppercase:/[A-Z]/.test(t),lowercase:/[a-z]/.test(t),numbers:/[0-9]/.test(t),symbols:/[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?]/.test(t),custom:o.customValidation?o.customValidation(t)===null:t.length>0},a=[!0,o.requireUppercase,o.requireLowercase,o.requireNumbers,o.requireSymbols,!!o.customValidation].filter(Boolean).length,c=[r.length,o.requireUppercase?r.uppercase:null,o.requireLowercase?r.lowercase:null,o.requireNumbers?r.numbers:null,o.requireSymbols?r.symbols:null,o.customValidation?r.custom:null].filter(n=>n===!0).length,s=a>0?Math.round(c/a*100):0;let u;return s<40?u="weak":s<60?u="fair":s<80?u="good":u="strong",{strength:u,score:s,checks:r}}const H=()=>e.localStorageProp({key:"bui_auth_email",defaultValue:null});function J({onSignIn:t,passwordRules:o,labels:r,showRememberMe:a}){const c=e.prop(!1),s=H(),u=z(o),n=_.useForm({schema:u,onSubmit:E({task:t,message:"Sign in failed",onStart:()=>{c.set(!0),n.controller.disable()},onEnd:()=>{c.set(!1),n.controller.enable()}}),initialValue:{email:"",password:""}}),{controller:l,submit:i}=n;c.on(l.setDisabled);const h=l.field("email"),b=l.field("password");return s.on(w=>{w!=null&&h.change(w)}),h.signal.on(w=>{s.value!=null&&(s.value=w)}),e.Use(m.AuthI18n,w=>e.html.form(e.attr.class("bc-auth-form__form"),e.on.submit(i),q.Stack(e.attr.class("bc-auth-form__fields"),e.Ensure(l.error,v=>y.Notice({variant:"danger",tone:"prominent",role:"alert"},e.html.div(v))),_.Control(y.EmailInput,{controller:h,label:e.coalesce(r?.emailLabel,w.$.emailLabel)}),_.Control(y.PasswordInput,{controller:b,label:e.coalesce(r?.passwordLabel,w.$.passwordLabel)}),e.When(a??!0,()=>e.html.div(e.attr.class("bc-auth-form__remember-me"),e.html.label(e.attr.class("bc-auth-form__checkbox-label"),_.CheckboxInput({value:s.map(v=>v!=null),after:e.html.span(e.coalesce(r?.rememberMeLabel,w.$.rememberMeLabel)),onChange:v=>{v?s.value=h.signal.value??"":s.value=null}}))))),T.Button({type:"submit",variant:"filled",color:"primary",loading:c,disabled:l.disabledOrHasErrors},e.attr.class("bc-auth-form__submit"),e.coalesce(r?.signInButton,w.$.signInButton))))}function K({password:t,rules:o=B,showLabel:r=!0,className:a}){const c=e.computedOf(t)(i=>!i||i.length===0?{strength:"weak",score:0,checks:{length:!1,uppercase:!1,lowercase:!1,numbers:!1,symbols:!1,custom:!1}}:R(i,o)),s=c.map(i=>i.strength),u=c.map(i=>i.score),n=c.map(i=>i.checks),l=e.computedOf(s,a)((i,h)=>["bc-password-strength",`bc-password-strength--${i}`,h].filter(Boolean).join(" "));return e.html.div(e.attr.class(l),e.html.div(e.attr.class("bc-password-strength__bar"),e.html.div(e.attr.class("bc-password-strength__fill"),e.attr.style(u.map(i=>`width: ${i}%`)))),e.When(r,()=>e.Use(m.AuthI18n,i=>e.html.div(e.attr.class("bc-password-strength__label"),e.computedOf(s,i)((h,b)=>{switch(h){case"weak":return b.passwordStrengthWeak;case"fair":return b.passwordStrengthFair;case"good":return b.passwordStrengthGood;case"strong":return b.passwordStrengthStrong;default:return b.passwordStrengthWeak}})))),e.html.div(e.attr.class("bc-password-strength__requirements"),e.When(o.minLength!==void 0,()=>e.html.div(e.attr.class("bc-password-strength__requirement"),e.attr.class(e.computedOf(n)(i=>i.length?"bc-password-strength__requirement--met":"")),e.html.span(e.attr.class("bc-password-strength__requirement-icon"),e.computedOf(n)(i=>i.length?"✓":"○")),e.html.span(e.attr.class("bc-password-strength__requirement-text"),`At least ${o.minLength} characters`))),e.When(o.requireUppercase===!0,()=>e.html.div(e.attr.class("bc-password-strength__requirement"),e.attr.class(e.computedOf(n)(i=>i.uppercase?"bc-password-strength__requirement--met":"")),e.html.span(e.attr.class("bc-password-strength__requirement-icon"),e.computedOf(n)(i=>i.uppercase?"✓":"○")),e.html.span(e.attr.class("bc-password-strength__requirement-text"),"One uppercase letter"))),e.When(o.requireLowercase===!0,()=>e.html.div(e.attr.class("bc-password-strength__requirement"),e.attr.class(e.computedOf(n)(i=>i.lowercase?"bc-password-strength__requirement--met":"")),e.html.span(e.attr.class("bc-password-strength__requirement-icon"),e.computedOf(n)(i=>i.lowercase?"✓":"○")),e.html.span(e.attr.class("bc-password-strength__requirement-text"),"One lowercase letter"))),e.When(o.requireNumbers===!0,()=>e.html.div(e.attr.class("bc-password-strength__requirement"),e.attr.class(e.computedOf(n)(i=>i.numbers?"bc-password-strength__requirement--met":"")),e.html.span(e.attr.class("bc-password-strength__requirement-icon"),e.computedOf(n)(i=>i.numbers?"✓":"○")),e.html.span(e.attr.class("bc-password-strength__requirement-text"),"One number"))),e.When(o.requireSymbols===!0,()=>e.html.div(e.attr.class("bc-password-strength__requirement"),e.attr.class(e.computedOf(n)(i=>i.symbols?"bc-password-strength__requirement--met":"")),e.html.span(e.attr.class("bc-password-strength__requirement-icon"),e.computedOf(n)(i=>i.symbols?"✓":"○")),e.html.span(e.attr.class("bc-password-strength__requirement-text"),"One special character")))))}function Le({password:t,rules:o=B,className:r}){const a=e.computedOf(t)(n=>!n||n.length===0?{strength:"weak",score:0}:R(n,o)),c=a.map(n=>n.strength),s=a.map(n=>n.score),u=e.computedOf(c,r)((n,l)=>["bc-password-strength-bar",`bc-password-strength-bar--${n}`,l].filter(Boolean).join(" "));return e.html.div(e.attr.class(u),e.html.div(e.attr.class("bc-password-strength-bar__fill"),e.attr.style(s.map(n=>`width: ${n}%`))))}function _e({password:t,rules:o=B,className:r}){const a=e.computedOf(t)(s=>!s||s.length===0?"weak":R(s,o).strength),c=e.computedOf(a,r)((s,u)=>["bc-password-strength-text",`bc-password-strength-text--${s}`,u].filter(Boolean).join(" "));return e.Use(m.AuthI18n,s=>e.html.span(e.attr.class(c),e.computedOf(a,s)((u,n)=>{switch(u){case"weak":return n.passwordStrengthWeak;case"fair":return n.passwordStrengthFair;case"good":return n.passwordStrengthGood;case"strong":return n.passwordStrengthStrong;default:return n.passwordStrengthWeak}})))}function Q({passwordRules:t,labels:o,initialEmail:r,initialName:a,showPasswordStrength:c,onSignUp:s,showNameField:u,showConfirmPassword:n,showAcceptTermsAndConditions:l,termsAndConditions:i}){const h=e.prop(!1),b=t||B,w=typeof n=="boolean"?n:n!=null?n.value:!1,v=typeof l=="boolean"?l:l!=null?l.value:!1,O=U(b,{showNameField:u!==!1,showConfirmPassword:w,showAcceptTermsAndConditions:v}),x=_.useForm({schema:O,onSubmit:E({task:s!=null?L=>s({email:L.email,password:L.password,name:L.name,acceptTerms:L.acceptTerms}):void 0,message:"Sign up failed",onStart:()=>{h.set(!0),x.controller.disable()},onEnd:()=>{h.set(!1),x.controller.enable()}}),initialValue:{name:a??"",email:r??"",password:"",confirmPassword:"",acceptTerms:!1}}),{controller:k,submit:W}=x;h.on(k.setDisabled);const F=k.field("name"),V=k.field("email"),P=k.field("password"),S=k.field("confirmPassword"),I=k.field("acceptTerms");return e.Use(m.AuthI18n,L=>e.html.form(e.attr.class("bc-auth-form__form"),e.on.submit(W),q.Stack(e.attr.class("bc-auth-form__fields"),e.Ensure(k.error,g=>y.Notice({variant:"danger",tone:"prominent",role:"alert"},e.html.div(g))),e.When(u!==!1,()=>_.Control(ae.TextInput,{controller:F.transform(g=>g??"",g=>g===""?void 0:g),label:e.coalesce(o?.nameLabel,L.$.nameLabel)})),_.Control(y.EmailInput,{controller:V,label:e.coalesce(o?.emailLabel,L.$.emailLabel)}),_.Control(y.PasswordInput,{controller:P,label:e.coalesce(o?.passwordLabel,L.$.passwordLabel)}),e.When(c??!1,()=>K({password:P.signal,rules:b,showLabel:!0})),e.When(n??!1,()=>_.Control(y.PasswordInput,{controller:S,label:e.coalesce(o?.confirmPasswordLabel,L.$.confirmPasswordLabel)})),e.When(l??!1,()=>e.html.div(e.attr.class("bc-auth-form__terms"),e.html.label(e.attr.class("bc-auth-form__checkbox-label"),_.CheckboxInput({value:I.signal.map(g=>g??!1),onChange:g=>I.change(g)}),e.html.span(i||e.coalesce(o?.acceptTermsLabel,L.$.acceptTermsLabel))),e.When(I.errorVisible,()=>e.html.div(e.attr.class("bc-auth-form__field-error"),I.error.map(g=>g||"")))))),T.Button({type:"submit",variant:"filled",color:"primary",loading:h,disabled:k.disabledOrHasErrors},e.attr.class("bc-auth-form__submit"),e.coalesce(o?.signUpButton,L.$.signUpButton))))}function ee({onResetPassword:t,labels:o={}}){const r=H(),a=e.prop(!1),c=_.useForm({schema:j,onSubmit:E({task:t,message:"Reset password failed",onStart:()=>{a.set(!0),c.controller.disable()},onEnd:()=>{a.set(!1),c.controller.enable()}}),initialValue:{email:""}}),{controller:s,submit:u}=c;a.on(s.setDisabled);const n=s.field("email");return r.on(l=>{l!=null&&n.change(l)}),e.Use(m.AuthI18n,l=>e.html.form(e.attr.class("bc-auth-form__form"),e.Ensure(s.error,i=>y.Notice({variant:"danger",tone:"prominent",role:"alert"},e.html.div(i))),e.html.p(e.attr.class("bc-auth-form__description"),e.coalesce(o?.resetPasswordDescription,l.$.resetPasswordDescription)),e.on.submit(u),q.Stack(e.attr.class("bc-auth-form__fields"),_.Control(y.EmailInput,{controller:n,label:e.coalesce(o?.emailLabel,l.$.emailLabel)})),T.Button({loading:a,type:"submit",variant:"filled",color:"primary",disabled:s.disabledOrHasErrors},e.attr.class("bc-auth-form__submit"),e.coalesce(o?.resetPasswordButton,l.$.resetPasswordButton))))}function p({provider:t,onClick:o,size:r="md",name:a,icon:c,color:s,flow:u,labels:n}){const l=async()=>{if(o)try{u==="popup"?await o():await o()}catch(i){console.error(`Social login error for ${t} (${u||"redirect"} flow):`,i)}};return T.Button({type:"button",variant:"filled",size:r,color:s,onClick:l,roundedness:"full"},e.attr.class("bc-social-login-button"),e.attr.class(e.computedOf(t)(i=>`bc-social-login-button--${i}`)),e.html.span(e.attr.class("bc-social-login-button__inner"),e.html.span(e.attr.class("bc-social-login-button__icon"),ne.Icon({icon:c,size:r},e.attr.class("bc-social-login-button__icon-inner"))),e.Use(m.AuthI18n,i=>e.html.span(e.attr.class("bc-social-login-button__label"),e.bind(e.coalesce(n?.continueWithProvider,i.$.continueWithProvider))(a)))))}function te({providers:t,onProviderClick:o,size:r="md",className:a}){return q.Stack(e.attr.class("bc-social-login-buttons"),e.attr.class(a),e.ForEach(t,c=>p({provider:c.$.provider,flow:c.$.flow,color:c.map(({provider:s})=>d[s].color),name:c.map(({provider:s})=>d[s].name),icon:c.map(({provider:s})=>d[s].icon),onClick:async()=>{o&&await o(c.$.provider.value)},size:r})))}const d={google:{name:"Google",icon:"logos:google-icon",color:"red"},github:{name:"GitHub",icon:"logos:github-icon",color:"black"},apple:{name:"Apple",icon:"logos:apple",color:"stone"},facebook:{name:"Facebook",icon:"logos:facebook",color:"blue"},twitter:{name:"Twitter",icon:"logos:twitter",color:"sky"},x:{name:"X",icon:"logos:x",color:"zinc"},microsoft:{name:"Microsoft",icon:"logos:microsoft-icon",color:"amber"},discord:{name:"Discord",icon:"logos:discord-icon",color:"indigo"},linkedin:{name:"LinkedIn",icon:"logos:linkedin-icon",color:"cyan"},instagram:{name:"Instagram",icon:"logos:instagram-icon",color:"fuchsia"},tiktok:{name:"TikTok",icon:"logos:tiktok-icon",color:"teal"},snapchat:{name:"Snapchat",icon:"simple-icons:snapchat",color:"yellow"},reddit:{name:"Reddit",icon:"logos:reddit-icon",color:"orange"},pinterest:{name:"Pinterest",icon:"logos:pinterest",color:"rose"},twitch:{name:"Twitch",icon:"logos:twitch",color:"purple"},steam:{name:"Steam",icon:"logos:steam",color:"slate"},epic:{name:"Epic Games",icon:"simple-icons:epicgames",color:"neutral"},playstation:{name:"PlayStation",icon:"simple-icons:playstation",color:"violet"},xbox:{name:"Xbox",icon:"simple-icons:xbox",color:"green"},whatsapp:{name:"WhatsApp",icon:"logos:whatsapp-icon",color:"emerald"},wechat:{name:"WeChat",icon:"simple-icons:wechat",color:"lime"},amazon:{name:"Amazon",icon:"simple-icons:amazon",color:"red"},yahoo:{name:"Yahoo",icon:"logos:yahoo",color:"rose"},paypal:{name:"PayPal",icon:"logos:paypal",color:"blue"}},ve=t=>p({...t,...d.google,provider:"google"}),ke=t=>p({...t,...d.github,provider:"github"}),Se=t=>p({...t,...d.apple,provider:"apple"}),Pe=t=>p({...t,...d.facebook,provider:"facebook"}),ye=t=>p({...t,...d.x,provider:"x"}),Be=t=>p({...t,...d.twitter,provider:"twitter"}),qe=t=>p({...t,...d.microsoft,provider:"microsoft"}),Ie=t=>p({...t,...d.discord,provider:"discord"}),xe=t=>p({...t,...d.linkedin,provider:"linkedin"}),Ae=t=>p({...t,...d.instagram,provider:"instagram"}),Ce=t=>p({...t,...d.tiktok,provider:"tiktok"}),Te=t=>p({...t,...d.snapchat,provider:"snapchat"}),$e=t=>p({...t,...d.reddit,provider:"reddit"}),Ee=t=>p({...t,...d.pinterest,provider:"pinterest"}),Me=t=>p({...t,...d.twitch,provider:"twitch"}),ze=t=>p({...t,...d.steam,provider:"steam"}),Ue=t=>p({...t,...d.epic,provider:"epic"}),Re=t=>p({...t,...d.playstation,provider:"playstation"}),Oe=t=>p({...t,...d.xbox,provider:"xbox"}),We=t=>p({...t,...d.whatsapp,provider:"whatsapp"}),Fe=t=>p({...t,...d.wechat,provider:"wechat"}),Ve=t=>p({...t,...d.amazon,provider:"amazon"}),Ne=t=>p({...t,...d.yahoo,provider:"yahoo"}),De=t=>p({...t,...d.paypal,provider:"paypal"});function N({providers:t,onSocialLogin:o}){return q.Stack(te({providers:t,onProviderClick:o}))}function oe({mode:t,socialProviders:o,initialName:r,initialEmail:a,passwordRules:c,showRememberMe:s,showSocialDivider:u,showPasswordStrength:n,labels:l,onSignIn:i,onSignUp:h,onResetPassword:b,onModeChange:w,onSocialLogin:v,showContainer:O,showNameField:x,showConfirmPassword:k,showAcceptTermsAndConditions:W,termsAndConditions:F},...V){const P=t!=null?e.Value.deriveProp(t):e.prop("signin");return P.on(S=>w?.(S)),e.Use(m.AuthI18n,S=>{function I(){const A=e.coalesce(l?.hasAccountLink,S.$.hasAccountLink);return e.html.button(e.attr.type("button"),e.attr.class("bc-auth-form__link"),e.on.click(()=>P.set("signin")),A)}function L(){return e.html.button(e.attr.type("button"),e.attr.class("bc-auth-form__link"),e.on.click(()=>P.set("signup")),e.coalesce(l?.noAccountLink,S.$.noAccountLink))}function g(){return e.html.button(e.attr.type("button"),e.attr.class("bc-auth-form__link"),e.on.click(()=>P.set("reset-password")),e.coalesce(l?.forgotPasswordLink,S.$.forgotPasswordLink))}return e.html.div(re.classes({"bc-auth-container":!0,"bc-auth-container--styled":e.Value.map(O??!0,A=>A)}),e.attr.class(P.map(A=>`bc-auth-container--${A}`)),e.attr.class("bc-auth-form"),e.OneOfValue(P,{signin:()=>e.Fragment(e.html.h2(e.attr.class("bc-auth-form__title"),e.coalesce(l?.signInTitle,S.$.signInTitle)),o!=null?e.Fragment(N({providers:o,onSocialLogin:v}),e.When(u??!1,D)):null,J({onSignIn:i,showRememberMe:s,passwordRules:c,labels:{emailLabel:l?.emailLabel,passwordLabel:l?.passwordLabel,rememberMeLabel:l?.rememberMeLabel,signInButton:l?.signInButton,forgotPasswordLink:l?.forgotPasswordLink,noAccountLink:l?.noAccountLink}}),q.Stack(e.attr.class("bc-auth-form__footer"),L(),g())),signup:()=>e.Fragment(e.html.h2(e.attr.class("bc-auth-form__title"),e.coalesce(l?.signUpTitle,S.$.signUpTitle)),o!=null?e.Fragment(N({providers:o,onSocialLogin:v}),e.When(u??!1,D)):null,Q({labels:{nameLabel:l?.nameLabel,emailLabel:l?.emailLabel,passwordLabel:l?.passwordLabel,confirmPasswordLabel:l?.confirmPasswordLabel,acceptTermsLabel:l?.acceptTermsLabel,signUpButton:l?.signUpButton,hasAccountLink:l?.hasAccountLink},initialEmail:a,initialName:r,onSignUp:h,passwordRules:c,showPasswordStrength:n,showNameField:x,showConfirmPassword:k,showAcceptTermsAndConditions:W,termsAndConditions:F}),q.Stack(e.attr.class("bc-auth-form__footer"),I())),"reset-password":()=>e.Fragment(e.html.h2(e.attr.class("bc-auth-form__title"),e.coalesce(l?.resetPasswordTitle,S.$.resetPasswordTitle)),ee({labels:{backToSignInLink:l?.backToSignInLink,emailLabel:l?.emailLabel,resetPasswordButton:l?.resetPasswordButton,resetPasswordDescription:l?.resetPasswordDescription},onResetPassword:b}),q.Stack(e.attr.class("bc-auth-form__footer"),I()))}),...V)})}function Ge(t){return f.Modal({size:"sm",dismissable:!0,showCloseButton:!0},(o,r)=>t(a=>o({body:oe({showContainer:!1,...a}),header:e.Use(m.AuthI18n,c=>e.coalesce(a.modalTitle,c.$.authenticationTitle))})))}function D({labels:t,className:o}={}){return e.html.div(e.attr.class("bc-auth-divider"),e.attr.class(o),e.html.div(e.attr.class("bc-auth-divider__line")),e.Use(m.AuthI18n,r=>e.html.span(e.attr.class("bc-auth-divider__text"),e.coalesce(t?.text,r.$.orDivider))),e.html.div(e.attr.class("bc-auth-divider__line")))}exports.AmazonLoginButton=Ve;exports.AppleLoginButton=Se;exports.AuthContainer=oe;exports.AuthDivider=D;exports.AuthModal=Ge;exports.DiscordLoginButton=Ie;exports.EpicLoginButton=Ue;exports.FacebookLoginButton=Pe;exports.GitHubLoginButton=ke;exports.GoogleLoginButton=ve;exports.InstagramLoginButton=Ae;exports.LinkedInLoginButton=xe;exports.MicrosoftLoginButton=qe;exports.PasswordStrengthBar=Le;exports.PasswordStrengthIndicator=K;exports.PasswordStrengthText=_e;exports.PayPalLoginButton=De;exports.PinterestLoginButton=Ee;exports.PlayStationLoginButton=Re;exports.RedditLoginButton=$e;exports.ResetPasswordForm=ee;exports.SignInForm=J;exports.SignUpForm=Q;exports.SnapchatLoginButton=Te;exports.SocialLoginButton=p;exports.SocialLoginButtons=te;exports.SocialProviders=N;exports.SteamLoginButton=ze;exports.TiktokLoginButton=Ce;exports.TwitchLoginButton=Me;exports.TwitterLoginButton=Be;exports.WeChatLoginButton=Fe;exports.WhatsAppLoginButton=We;exports.XLoginButtin=ye;exports.XboxLoginButton=Oe;exports.YahooLoginButton=Ne;exports.authSchemas=fe;exports.calculatePasswordStrength=R;exports.createEmailSchema=C;exports.createPasswordSchema=M;exports.createSignInSchema=z;exports.createSignUpSchema=U;exports.createSocialLoginUrl=ue;exports.defaultPasswordRules=B;exports.defaultSignInSchema=he;exports.defaultSignUpSchema=ge;exports.emailSchema=G;exports.formatAuthError=de;exports.formatProviderName=Y;exports.formatSocialLoginText=ce;exports.generateRandomString=Z;exports.getProviderColor=ie;exports.getProviderIcon=se;exports.isBrowser=pe;exports.isValidEmail=le;exports.openSocialLoginPopup=me;exports.providerInfo=$;exports.requestToControllerValidation=E;exports.resetPasswordSchema=j;exports.socialProviderInfo=d;exports.useAuthEmailProp=H;exports.validateEmail=be;exports.validatePassword=we;
|