import type { RemoteForm, RemoteFormInput, RemoteFormIssue } from '@sveltejs/kit'; export type { RemoteForm, RemoteFormInput, RemoteFormIssue }; export declare const FORM_CONTEXT_KEY = "r2-form"; export type FormErrors = Record; export type FormDataValues = Record; export type FormFieldStatus = 'default' | 'error' | 'success' | 'warning'; /** * Build a dotted path for nested form errors / remote issues * (e.g. `items.0.email`). */ export declare function fieldPath(...segments: Array): string; /** * Spreadable remote form binding: a Kit `RemoteForm` or the object returned by `.enhance(...)`. * * @example * ```ts * remote={createPost} * remote={createPost.enhance(async (form) => { ... })} * ``` */ export type FormRemote = RemoteForm | ReturnType['enhance']>; /** @deprecated Use `FormRemote` (or `RemoteForm` from `@sveltejs/kit`) */ export type RemoteFormSpread = FormRemote; export interface FormContext { /** Current field values (bindable from `
`) */ data: TData; errors: FormErrors; submitted: boolean; loading: boolean; disabled: boolean; /** Last result from a remote form / submit handler, if any */ result: TResult | undefined; /** * Full Kit `RemoteForm` when `` received one * (not an `.enhance(...)` return). Used by fields to call `.as()`. */ remote: RemoteForm | null; /** Stable Kit form id (`1p9kxmo/login_user`) for encoding input names */ remoteFormId: string | null; setError: (name: string, message: string) => void; clearError: (name: string) => void; clearErrors: () => void; setData: (name: K, value: TData[K]) => void; getError: (name: string) => string | undefined; getData: (name: K) => TData[K] | undefined; } /** * Props safe to spread onto library `` / `` for Kit remote forms. * Omits Kit `value` getters/setters so they do not fight `bind:value`. */ export type ResolvedRemoteInputProps = { name?: string; }; /** * Extract Kit remote form id from `remote.action` (`?/remote=`). * Pass `untrack(() => remote.action)` from callers inside effects/derived. */ export declare function getRemoteFormId(action: string | undefined | null): string | null; /** * Resolve HTML input props for a field inside a Kit remote form. * * Kit 2.70+ `.as()` emits the logical path only (`email`, `n:age`, `b:active`). * The remote id lives on the form `action` (`?/remote=…`), not on each field name. * Appending `/${formId}` breaks `convert_formdata` / `split_path` — especially with * keyed instances (`.for(key)` → `…/"default"`), which surfaces as: * `Invalid path status/…/updateProduct_remote/"default"`. * * `formId` is kept for call-site compatibility / legacy stripping in * {@link parseRemoteFieldName}; it is not appended to `name`. */ export declare function resolveRemoteInputProps(_formId: string | null | undefined, logicalName: string | undefined, type?: string): ResolvedRemoteInputProps; export type ParsedRemoteFieldName = { /** Field path for errors / `form.data` (`email`, `items[0].name`) */ logicalName: string | undefined; /** Exact HTML `name` to put on the input (Kit-encoded or plain) */ htmlName: string | undefined; /** True when `name` still has a legacy `/${formId}` suffix */ isEncoded: boolean; }; /** * Split a (possibly legacy) HTML `name` into logical + html parts. * Plain Kit 2.70+ names (`email`, `n:age`) pass through unchanged. * * Still strips a legacy `/${formId}` suffix when present (older lib builds * appended the remote action id to every field name). */ export declare function parseRemoteFieldName(name: string | undefined, formId?: string | null): ParsedRemoteFieldName; /** * Safe props to spread onto `FormField` / `FormPasswordInput` from Kit `.as(...)`. * Keeps `name` (+ `type`) and drops Kit `value` / `defaultValue` accessors that * fight library `$bindable` and can cause `effect_update_depth_exceeded`. * * @example * ```svelte * * ``` */ export declare function remoteAsProps(asProps: { name: string; type?: string; }): { name: string; type?: string; }; /** * Access the nearest `` context from a child component. * Returns `null` when used outside a Form. * * @example * ```ts * const form = getFormContext<{ email: string }, { ok: boolean }>(); * form?.getData('email'); * form?.result?.ok; * ``` */ export declare function getFormContext(): FormContext | null; /** * Map Kit `RemoteFormIssue[]` → `{ field: message }` for ``. * * @example * ```ts * errors = remoteIssuesToErrors(createPost.fields.allIssues()); * ``` */ export declare function remoteIssuesToErrors(issues: RemoteFormIssue[] | null | undefined): FormErrors; /** True when the spread value is a full `RemoteForm` (has `fields` / `pending`). */ export declare function isRemoteForm(remote: FormRemote | null | undefined): remote is RemoteForm; /** * Shared resolution for form-aware controls (error / status / disabled). */ export declare function resolveFormFieldState(options: { name?: string; errorMessage?: string; helperText?: string; status?: FormFieldStatus; disabled?: boolean; form?: FormContext | null; }): { error?: string; status: FormFieldStatus; helperText?: string; disabled: boolean; }; /** * Push context → local inside an `$effect` that tracks `form.data[name]`. * Local value is read under `untrack` so user input is not overwritten when * the local state updates before `setData` lands. * * @example * ```ts * $effect(() => { * if (!bindData || !name || !form) return; * applyFormDataSync({ * fromCtx: form.data[name], * getLocal: () => value, * setLocal: (v) => { value = v; }, * map: (raw) => (raw !== undefined ? String(raw) : undefined) * }); * }); * ``` */ export declare function applyFormDataSync(options: { fromCtx: unknown; getLocal: () => T; setLocal: (next: T) => void; map: (raw: unknown) => T | undefined; equals?: (a: T, b: T) => boolean; }): void; export declare function sameStringArray(a: string[], b: string[]): boolean;