useSubmitActionTriggers

Fires submit actions automatically on field change, field blur, step transitions, and idle timeout.

View as Markdown

useSubmitActionTriggers

Manages automatic execution of submit actions based on non-submit triggers like field changes, blur events, step transitions, and idle timeouts. This is what powers real-time features like auto-saving on field change or sending analytics on step exit.

You probably don’t need this directly. The <Form> component wires it up internally whenever your config has submitActions. Use it when building custom trigger logic on top of your own form.


Signature

import { useSubmitActionTriggers } from '@saastro/forms';

const { triggerFieldChange, triggerFieldBlur, triggerManual, hasActionsForTrigger } =
  useSubmitActionTriggers({
    config,
    getValues,
    currentStep,
    onActionExecuted,
    onActionError,
    enabled,
  });

Parameters

Parameter Type Required Description
config FormConfig Yes Form configuration with submit actions
getValues () => Record<string, unknown> Yes Function returning the current form values — pass methods.getValues itself (avoids re-renders)
currentStep string Yes Active step ID
onActionExecuted (result) => void No Called after an action completes
onActionError (error, actionName) => void No Called when an action fails
enabled boolean No Enable/disable all triggers (default: true)

getValues is a function reference, not a values object. Pass methods.getValues directly — do not call it (methods.getValues()). The hook reads values lazily at fire time, so triggers always see the latest data without subscribing to every keystroke.


Return Value

Property Type Description
triggerFieldChange (fieldName, value) => void Trigger onFieldChange actions (debounced)
triggerFieldBlur (fieldName) => void Trigger onFieldBlur actions (immediate)
triggerManual (actionIds?) => Promise<SubmitActionsResult> Manually trigger specific actions
hasActionsForTrigger (triggerType, triggerValue?) => boolean Check if any actions exist for a trigger type

Trigger Types

Trigger When It Fires Behavior
onFieldChange User changes a field value Debounced (debounceMs of the first matching action, default 300ms, per field)
onFieldBlur User leaves a field Immediate
onStepEnter User navigates to a step Automatic (via step change detection)
onStepExit User leaves a step Automatic (via step change detection)
onDelay User is idle for delayMs ms (default 30000) Automatic (listens to mousedown, keydown, touchstart, scroll; re-arms after each activity)
manual Programmatic trigger Via triggerManual() call

onSubmit actions are not handled by this hook — they run inside the submit pipeline when the form is submitted. hasActionsForTrigger('onSubmit') still reports them.


Example: Manual Trigger

import { useFormState, useSubmitActionTriggers } from '@saastro/forms';
import type { FormConfig } from '@saastro/forms';

function SaveDraftButton({ config }: { config: FormConfig }) {
  const { methods, currentStepId } = useFormState({ config, fields: config.fields });

  const { triggerManual, hasActionsForTrigger } = useSubmitActionTriggers({
    config,
    getValues: methods.getValues, // pass the function, don't call it
    currentStep: currentStepId,
  });

  const saveDraft = async () => {
    // Check if there are manual actions available
    if (hasActionsForTrigger('manual')) {
      const result = await triggerManual(['save-draft']);
      console.log('Draft saved:', result.allSuccessful);
    }
  };

  return <button onClick={saveDraft}>Save draft</button>;
}

Notes

  • triggerManual ignores enabled — it executes even when enabled is false. The automatic effects and triggerFieldChange/triggerFieldBlur do respect it.
  • triggerFieldChange ignores its value argument; values are read via getValues() when the debounced action actually fires.
  • The hook’s option and return interfaces are not exported types — only the function itself is public.
  • All debounce and idle timers are cleared on unmount.