A better use:enhance
experience with automatic state management.
Requires Svelte v5 and runes mode.
standby
, submitting
, and submitted
statesonBeforeRequest
and onAfterResponse
callbackspnpm add svelte-form-enhanced -D
npm i svelte-form-enhanced -D
<script lang="ts">
import { enhance } from '$app/forms';
import { createFormHelper } from 'svelte-form-enhanced';
const f = createFormHelper();
</script>
<!-- Maintains submitting state for 1 second (customizable) -->
<form method="post" use:enhance={f.submitFunction}>
<!-- Use the submitting state to show loading UI: -->
<button disabled={f.state === 'submitting'} class="disabled:btn-spinner">
{f.state === 'submitting' ? 'Submitting' : 'Submit'}
</button>
</form>
type FormState = 'standby' | 'submitting' | 'submitted';
<script lang="ts">
import { createFormHelper } from 'svelte-form-enhanced';
import type { SubmitFunction } from './$types.js';
const f = createFormHelper<SubmitFunction>({
// The `ActionResult` object is now typed.
onAfterSubmit: ({ result }) => {}
});
</script>
const f = createFormHelper({ /* options */ });
type Options = Partial<{
minSubmitDuration: number; // defaults to 1000(ms)
onBeforeSubmit: (param) => void;
onAfterSubmit: (param) => void;
updateOptions: { reset?: boolean; invalidateAll?: boolean };
}>;
The function provided to the use:enhance
has been separated into two:
<script>
const f = createFormHelper({
onBeforeSubmit: () => {
console.log('Before submit');
},
onAfterSubmit: async ({ update }) => {
await update(); // default logic
console.log('After submit');
}
});
</script>
<form use:enhance={f.submitFunction}></form>
<form
use:enhance={() => {
console.log('Before submit');
return async ({ update }) => {
await update(); // default logic
console.log('After submit');
};
}}
></form>
Show spinner on the submit button during submission:
<script lang="ts">
const f = createFormHelper({
onBeforeSubmit: ({ submitter }) => {
submitter?.classList.add('disabled:btn-spinner');
},
onAfterSubmit: async ({ submitter, update }) => {
await update();
submitter?.classList.remove('disabled:btn-spinner');
}
});
</script>