createEnhancedForm Overview
Relevant source files
The following files were used as context for generating this wiki page:The createEnhancedForm function is a helper utility within the @opensky/remotes package designed to improve the experience of working with SvelteKit's remote form functions. It creates a tracked, reactive state for a form and provides semantic callbacks for various stages of the form submission lifecycle. This simplifies state management, allowing developers to easily handle loading states, delays, timeouts, validation issues, and successful results.
This utility can be used in conjunction with createValidation to automate validation feedback. It is exported from the main package entry point.
Sources: packages/remotes/README.md, packages/remotes/src/lib/index.ts:2, packages/remotes/src/lib/enhance.svelte.ts:241-246
Initialization
To use createEnhancedForm, you import it and call it with a SvelteKit RemoteForm instance and an optional configuration object. The configuration allows for integrating a validation helper and setting up timed state transitions.
Sources: packages/remotes/README.md:66-71, packages/remotes/src/lib/enhance.svelte.ts:241-259
import { createEnhancedForm } from '@opensky/remotes';
import { createValidation } from '@opensky/remotes';
import { myForm } from './myForm.remote';
const valid = createValidation(myForm);
const form = createEnhancedForm(myForm, {
validation: valid,
delayMs: 500,
timeoutMs: 3500
});
Sources: packages/remotes/README.md:129-139
Creation Options
The function accepts an options object with the following properties:
| Option | Type | Description |
|---|---|---|
validation | Validation | An optional instance returned from createValidation. If provided, updateIssues() and validateAll() will be called automatically at appropriate times. |
delayMs | number | Optional. Milliseconds to wait before the form state transitions to 'delayed'. Enables the delayed state and onDelay callback. |
timeoutMs | number | Optional. Milliseconds to wait before the form state transitions to 'timeout'. Enables the timeout state and onTimeout callback. |
Sources: packages/remotes/src/lib/enhance.svelte.ts:55-64, packages/remotes/README.md:82-86
The function is overloaded to provide type-safe return values. The presence of delayMs and timeoutMs in the options conditionally adds delayed and timeout properties to the returned object and allows the use of onDelay and onTimeout callbacks. This was a breaking change in version 0.0.3, where these options were moved from the enhance callback to the creation options.
Sources: packages/remotes/src/lib/enhance.svelte.ts:241-259, packages/remotes/CHANGELOG.md:12-14
State Management
createEnhancedForm manages the form's lifecycle through a reactive state property, which is implemented as a Svelte 5 $state rune. This state can transition between several values, and convenient boolean getters are provided for each state.
Sources: packages/remotes/src/lib/enhance.svelte.ts:265-266, packages/remotes/README.md:76-80
Form States
The state property can hold one of the following string values:
| State | Description |
|---|---|
idle | The initial state, and the state after a successful submission or cancellation. |
pending | The state immediately after submission begins. |
delayed | (Conditional) The state after delayMs has passed without a response. |
timeout | (Conditional) The state after timeoutMs has passed without a response. |
issues | The state when the server returns validation issues. |
error | The state when the submission promise rejects or an error is thrown. |
result | The state when the submission is successful and returns a result. Formerly named success. |
Sources: packages/remotes/src/lib/enhance.svelte.ts:34-45, packages/remotes/CHANGELOG.md:9
State Transition Flow
The following diagram illustrates the possible state transitions during a form submission.
This diagram shows the flow of the state property based on form submission outcomes.
Sources: packages/remotes/src/lib/enhance.svelte.ts:289-354
Reactive State Properties
The object returned by createEnhancedForm includes the state property and several boolean getters for easily checking the current state.
| Property | Type | Description |
|---|---|---|
state | FormState | The current state of the form as a string. |
idle | boolean | true if state === 'idle'. |
pending | boolean | true if state === 'pending'. |
delayed | boolean | (Conditional) true if state === 'delayed'. Only available if delayMs is set. |
timeout | boolean | (Conditional) true if state === 'timeout'. Only available if timeoutMs is set. |
issues | boolean | true if state === 'issues'. |
error | boolean | true if state === 'error'. |
result | boolean | true if state === 'result'. |
reset() | () => void | A method to manually reset the form state to 'idle'. |
Sources: packages/remotes/src/lib/enhance.svelte.ts:356-455, packages/remotes/README.md:76-80, packages/remotes/CHANGELOG.md:5
The enhance Handler
The core of the utility is the enhance method on the returned object. This method should be used within SvelteKit's native use:enhance or remoteForm.enhance() callback to manage the submission lifecycle.
Sources: packages/remotes/README.md:74, packages/remotes/src/lib/enhance.svelte.ts:272-354
Callbacks
The enhance method accepts a callbacks object to hook into different lifecycle events.
| Callback | Context | Description |
|---|---|---|
onSubmit | SubmitContext | Called when submission begins. Receives cancel() and updates() functions for client-side validation and optimistic updates. |
onDelay | BaseEnhanceContext | (Conditional) Called if delayMs is reached. |
onTimeout | BaseEnhanceContext | (Conditional) Called if timeoutMs is reached. |
onReturn | { result } | Called on a successful submission. |
onIssues | BaseEnhanceContext | Called when validation issues are returned from the server. |
onError | { error } | Called when an error occurs during submission. |
Sources: packages/remotes/README.md:88-99, packages/remotes/src/lib/enhance.svelte.ts:100-120
Submission Lifecycle Sequence
The sequence diagram below details the internal flow when a form is submitted using the enhance handler.
This diagram shows the sequence of events from form submission to final state within the enhance handler.
Sources: packages/remotes/src/lib/enhance.svelte.ts:272-354
Integration with createValidation
When a validation instance is passed during creation, createEnhancedForm automatically handles communication with the validation helper:
- On
onIssues, it callsvalidation.updateIssues()to populate the local validation state with issues returned from the server. - On
onError, it callsvalidation.validateAll()to re-validate fields, which can be useful if a server error occurs after some client-side changes.
Sources: packages/remotes/src/lib/enhance.svelte.ts:335-336, 346-347, packages/remotes/src/lib/validation.svelte.ts:86-94, 73-84
Example Usage
The following example demonstrates how createEnhancedForm and createValidation work together.
<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').max(10, 'Too long'),
address: z.object({
state: z.string()
})
})
const valid = createValidation(myForm)
const form = createEnhancedForm(myForm, {
validation: valid,
delayMs: 500,
timeoutMs: 3500
})
</script>
<p>State: {form.state}</p>
<form {...myForm.preflight(schema).enhance(opts =>
form.enhance(opts, {
onDelay: () => console.log('showing loader'),
onTimeout: () => console.log('request timeout'),
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>
{#if form.timeout}
<p>Request timed out</p>
{/if}
Sources: packages/remotes/README.md:125-177
Summary
createEnhancedForm is a powerful utility that abstracts away the complexity of managing form submission state in SvelteKit. By providing a reactive state machine, timed state transitions, and a structured callback system, it allows developers to build robust and user-friendly forms with minimal boilerplate. Its seamless integration with createValidation further streamlines the process of handling form validation logic.
Sources: README.md:55-60