Core Concepts
Relevant source files
The following files were used as context for generating this wiki page:The @opensky/remotes package provides two primary helper utilities, createValidation and createEnhancedForm, designed to improve the developer and user experience when working with SvelteKit's remote form functions. These helpers introduce reactive state management for form submissions, lifecycle callbacks, and a more intuitive validation flow.
The core goal is to simplify complex form handling by providing structured, reusable logic for validation feedback and tracking the submission state, including pending, delayed, and timeout states. The two helpers can be used independently but are designed to integrate seamlessly for a comprehensive form management solution.
Sources: README.md, packages/remotes/src/lib/index.ts, packages/remotes/package.json:3
createValidation
This helper is focused on providing a better user experience for form field validation. It implements a logic where validation issues are shown when a user leaves a field (onblur) but are cleared as soon as the user starts typing again (oninput). This prevents validation errors from appearing distractingly during input.
Sources: README.md:5-8, packages/remotes/CHANGELOG.md:30-32
API and Methods
createValidation is a function that accepts a SvelteKit RemoteForm instance and returns an object with methods to manage validation state.
Sources: packages/remotes/src/lib/validation.svelte.ts:10-13
| Method | Description |
|---|---|
fields(path) | Returns onblur and oninput event handlers for a given field path (e.g., 'name' or 'address.city'). This registers the path for validation. |
issues(path) | Returns an array of validation issue strings for a field path, or null if there are no issues. |
allIssues() | Returns an object containing all current validation issues for all registered fields. |
addIssue(path, issue) | Manually adds a custom validation error message to a specific field. Useful for client-side-only validation logic. |
reset() | Clears all validation issues from the state. |
validateAll() | Triggers validation for all registered fields against the server, not just a preflight check. |
updateIssues() | Populates the local issue state from the RemoteForm's issues, typically after a form submission returns validation errors. |
Sources: README.md:14-22, packages/remotes/src/lib/validation.svelte.ts:100-169
Validation Flow
The fields(path) method returns handlers that control the validation logic. The onblur event triggers a debounced remote validation call, while the oninput event clears existing errors if the field becomes valid.
The diagram below illustrates the event handling logic for a field managed by createValidation.
Usage Example
To use createValidation, you pass the remote form instance to it and then spread the returned handlers onto your input elements.
<script lang="ts">
import { createValidation } from '@opensky/remotes';
import { myForm } from './myForm.remote';
const valid = createValidation(myForm);
</script>
<input
{...myForm.fields.name.as('text')}
{...valid.fields('name')}
class:error={valid.issues('name')}
/>
{#if valid.issues('name')}
{#each valid.issues('name') as issue}
<p class="error">{issue}</p>
{/each}
{/if}
Sources: README.md:140-155
createEnhancedForm
This utility creates a state machine for a remote form, tracking its lifecycle from submission to completion. It provides reactive state getters and a structured way to define callbacks for different stages of the form submission process.
Sources: README.md:63-65, packages/remotes/CHANGELOG.md:25-27
Creation Options
When calling createEnhancedForm, you can provide an options object to configure its behavior.
| Option | Type | Description |
|---|---|---|
validation | Validation | An optional instance returned from createValidation. If provided, createEnhancedForm will automatically call updateIssues() and validateAll() at the appropriate times. |
delayMs | number | Milliseconds to wait before the form state transitions to 'delayed'. Enables the delayed state getter and onDelay callback. |
timeoutMs | number | Milliseconds to wait before the form state transitions to 'timeout'. Enables the timeout state getter and onTimeout callback. |
Sources: packages/remotes/src/lib/enhance.svelte.ts:50-58, commit-message.txt:3-12
Form State Machine
The createEnhancedForm helper manages the form's state through a defined lifecycle. The state property reflects the current stage of the submission. The availability of delayed and timeout states is conditional on the delayMs and timeoutMs options being provided at creation.
This diagram shows the possible state transitions during a form submission.
API and Callbacks
The function returns an object containing the enhance handler, a reset method, and several reactive boolean getters for the form's state.
Returned Object:
| Property | Description |
|---|---|
enhance(params, callbacks) | The form enhancement handler to be used with SvelteKit's enhance action. |
reset() | A method to manually reset the form's state back to 'idle'. |
state | A string representing the current state (e.g., 'idle', 'pending', 'result'). |
idle, pending, issues, error, result | Boolean getters for the corresponding states. |
delayed | A boolean getter that is only available if delayMs was provided. |
timeout | A boolean getter that is only available if timeoutMs was provided. |
Sources: README.md:72-79, packages/remotes/src/lib/enhance.svelte.ts:140-220
Enhance Callbacks:
| Callback | Description |
|---|---|
onSubmit | Called before submission. Receives cancel() to stop submission and updates() for optimistic UI. |
onDelay | Called if submission exceeds delayMs. Only available if delayMs is set. |
onTimeout | Called if submission exceeds timeoutMs. Only available if timeoutMs is set. |
onReturn | Called on a successful submission that returns a result. |
onIssues | Called when the submission returns with validation issues. |
onError | Called when the submission throws an error. |
Sources: README.md:82-92, packages/remotes/src/lib/enhance.svelte.ts:93-138
Submission Sequence
The following diagram shows the sequence of events and callbacks managed by the enhance handler.
Integration Example
createValidation and createEnhancedForm are designed to work together. By passing the validation instance to createEnhancedForm, the form's lifecycle will automatically trigger the correct validation methods.
<script lang="ts">
import { createValidation, createEnhancedForm } from '@opensky/remotes'
import { myForm } from './myForm.remote'
import { z } from 'zod'
const schema = z.object({
name: z.string().min(4, 'Too short'),
address: z.object({ state: z.string() })
});
// 1. Create validation helper
const valid = createValidation(myForm);
// 2. Create enhanced form, passing the validation helper
const form = createEnhancedForm(myForm, {
validation: valid,
delayMs: 500,
timeoutMs: 3500
});
</script>
<p>State: {form.state}</p>
<!-- 3. Use the enhance handler -->
<form {...myForm.preflight(schema).enhance(opts =>
form.enhance(opts, {
onReturn: ({ result }) => console.log('success', result)
})
)}>
<input
{...myForm.fields.name.as('text')}
{...valid.fields('name')}
class:error={valid.issues('name')}
/>
{#if valid.issues('name')}
{#each valid.issues('name') as issue}
<p class="error">{issue}</p>
{/each}
{/if}
<button disabled={form.pending || form.delayed}>
{form.delayed ? 'Loading...' : 'Submit'}
</button>
</form>
Sources: README.md:120-169