From 5e5f1337639b3042a34eef2d598ad88a1c2dc598 Mon Sep 17 00:00:00 2001 From: Elijah Duffy Date: Wed, 4 Feb 2026 11:19:03 -0800 Subject: [PATCH] statemachine: add onsubmit callback --- src/lib/StateMachine.svelte | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/src/lib/StateMachine.svelte b/src/lib/StateMachine.svelte index b5f5645..d62086a 100644 --- a/src/lib/StateMachine.svelte +++ b/src/lib/StateMachine.svelte @@ -40,7 +40,7 @@ import { tweened } from 'svelte/motion'; import { fade, fly } from 'svelte/transition'; import { validateForm } from '@svelte-toolkit/validate'; - import { ArrowLeft, Check, CheckFat } from 'phosphor-svelte'; + import { ArrowLeft, CheckFat } from 'phosphor-svelte'; import type { IconDef } from './util'; interface Props { @@ -49,6 +49,13 @@ failure: StateMachinePage; index?: number; action?: string; + /** + * Called when the form is submitted at the end of the state machine. + * Receives the collated form data as a key-value object. + * If you wish to prevent the submission, return false. + * If you wish to indicate a failure, you can also throw an error. + */ + onsubmit?: (data: Record) => Promise | boolean; } let { @@ -57,7 +64,8 @@ success, failure, index = $bindable(0), - action + action, + onsubmit }: Props = $props(); // add success and failure pages to the end of the pages array @@ -250,6 +258,22 @@ // update button state buttonLoading = true; + if (onsubmit) { + try { + const res = await onsubmit(collatedFormData); + if (res === false) { + buttonLoading = false; + index = pages.length - 2; + return; + } + } catch (e) { + console.log('onsubmit handler failed, submission prevented', e); + buttonLoading = false; + index = pages.length - 1; + return; + } + } + const form_data = new FormData(); for (const [key, value] of Object.entries(collatedFormData)) { form_data.append(key, value);