S

Types Reference

Comprehensive reference for all TypeScript types exported by @saastro/forms.

Types Reference

All types are exported from @saastro/forms. This page documents every type file and its key exports. Types that have dedicated guide pages link to them for detailed usage.


types/common.ts

Core form configuration types.

FormConfig

The top-level configuration object returned by FormBuilder.build().

interface FormConfig {
  formId: string;
  fields: Record<string, FieldConfig>;
  steps: Record<string, Step>;
  initialStep?: string;
  layout?: FormLayout;
  buttons?: FormButtons;
  submitConfirmation?: SubmitConfirmationConfig;
  pluginManager?: PluginManager;
  successMessage?: string | ((values: Record<string, unknown>) => string);
  errorMessage?: string | ((error: Error, values: Record<string, unknown>) => string);
  redirect?: string | ((values: Record<string, unknown>) => string);
  submitActions?: Record<string, SubmitActionNode>;
  submitExecution?: SubmitExecutionConfig;
  onStepChange?: (step: string) => void;
  onSuccess?: (values: Record<string, unknown>) => void;
  onError?: (error: Error, values: Record<string, unknown>) => void;
}

See: FormBuilder API

FormLayout

Controls the form grid system.

interface FormLayout {
  mode: 'auto' | 'manual';
  gap?: GapValue; // 0-12
  minFieldWidth?: number; // Pixels, auto mode only (default: 240)
  columns?: ColumnsValue; // 1-12
  className?: string; // Extra CSS classes for grid container
}

See: Layout System

Breakpoint

type Breakpoint = 'default' | 'sm' | 'md' | 'lg' | 'xl' | '2xl';

SubmitConfirmationConfig

Double-click confirmation for forms with optional fields.

interface SubmitConfirmationConfig {
  optionalFields: Array<{ name: string; message: string }>;
  buttonBehavior: {
    defaultText?: string;
    warningText: string;
    warningVariant?: ButtonConfig['variant'];
    warningEffect?: ButtonConfig['effect'];
    resetDelay?: number; // ms, default: 3000
  };
  applyOn: 'submit' | 'steps' | 'both';
  showOnce?: boolean; // default: true
}

See: FormBuilder API


types/fields.ts

The discriminated union of all 21+ field types.

FieldConfig

type FieldConfig =
  | TextFieldProps // type: 'text' | 'email' | 'tel'
  | TextareaFieldProps // type: 'textarea'
  | SliderFieldProps // type: 'slider'
  | SelectFieldProps // type: 'select'
  | ComboboxFieldProps // type: 'combobox'
  | NativeSelectFieldProps // type: 'native-select'
  | RadioFieldProps // type: 'radio'
  | ButtonRadioFieldProps // type: 'button-radio'
  | CheckboxFieldProps // type: 'checkbox'
  | SwitchFieldProps // type: 'switch'
  | CheckboxGroupFieldProps // type: 'checkbox-group'
  | SwitchGroupFieldProps // type: 'switch-group'
  | ButtonCheckboxFieldProps // type: 'button-checkbox'
  | DateFieldProps // type: 'date'
  | DateRangeFieldProps // type: 'daterange'
  | HtmlFieldProps // type: 'html'
  | ButtonCardFieldProps // type: 'button-card'
  | OtpFieldProps // type: 'otp'
  | CommandFieldProps // type: 'command'
  | InputGroupFieldProps // type: 'input-group'
  | ButtonConfig; // type: 'button' | 'submit' | 'next' | 'back'

BaseFieldProps

All field types extend this base:

interface BaseFieldProps
  extends
    LabelProps,
    LayoutProps,
    InputProps,
    ValidationProps,
    StateProps,
    TransformProps,
    AdvancedProps {}

Key properties inherited by all fields:

CategoryProperties
Labellabel, hideLabel, label_className, description
Layoutlayout, columns, gridSpan, order, wrapper_className, className
Inputinput_className, value, defaultValue, placeholder, autocomplete, required, size, icon, iconProps
Validationschema, customValidators, error_className, helperText, helper_className, tooltip
Statehidden, disabled, readOnly
Transformtransform
AdvancedtrackingKey

FieldLayoutConfig

interface FieldLayoutConfig {
  columns?: Partial<Record<Breakpoint, number>>; // 1-12 per breakpoint
  order?: number | Partial<Record<Breakpoint, number>>;
}

Option

Used by select, radio, combobox, command, button-radio, checkbox-group, switch-group, button-checkbox:

type Option = {
  label: string;
  value: string;
  icon?: ReactNode;
  iconProps?: Record<string, unknown>;
};

ButtonCardOption

Used by button-card:

type ButtonCardOption = {
  value: string;
  text: string;
  description?: string;
  icon?: ReactNode;
  iconProps?: Record<string, unknown>;
};

types/buttons.ts

ButtonConfig

interface ButtonConfig extends BaseFieldProps {
  type: 'button' | 'submit' | 'next' | 'back';
  action?: () => void;
  loading?: boolean;
  icon?: ReactNode;
  iconPosition?: 'left' | 'right';
  variant?: 'default' | 'destructive' | 'outline' | 'secondary' | 'ghost' | 'link';
  size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
  effect?:
    | 'default'
    | 'expandIcon'
    | 'ringHover'
    | 'shine'
    | 'shineHover'
    | 'gooeyRight'
    | 'gooeyLeft'
    | 'underline'
    | 'hoverUnderline';
  rounded?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl';
  label?: string;
}

FormButtons

interface FormButtons {
  submit?: ButtonConfig;
  next?: ButtonConfig;
  back?: ButtonConfig;
  align?: 'start' | 'center' | 'end' | 'between' | 'responsive';
  inline?: boolean;
}

See: Buttons


types/steps.ts

Step

type Step = {
  id?: string; // Optional — key serves as id in Record<string, Step>
  fields: string[]; // Field names in this step
  next?: StepCondition[];
  defaultNext?: string; // Fallback if no condition matches
};

StepCondition

type StepCondition = ConditionGroup & {
  target: string; // Step id to navigate to
};

See: Multi-Step Forms


types/logic.ts

ConditionOperator

type ConditionOperator =
  | 'equals'
  | 'notEquals'
  | 'contains'
  | 'notContains'
  | 'greaterThan'
  | 'lessThan'
  | 'greaterThanOrEqual'
  | 'lessThanOrEqual'
  | 'isTrue'
  | 'isFalse'
  | 'isEmpty'
  | 'isNotEmpty';

Condition

type Condition = {
  field: string;
  operator: ConditionOperator;
  value?: string | number | boolean | null;
};

ConditionGroup

type ConditionGroup = {
  conditions: Condition[];
  operator: 'AND' | 'OR';
};

See: Conditional Logic, Multi-Step Forms


types/submitActions.ts

SubmitActionNode

The complete configuration for a single submit action:

interface SubmitActionNode {
  id: string;
  action: SubmitAction;
  trigger: SubmitTrigger;
  condition?: SubmitActionCondition;
  order?: number;
  continueOnError?: boolean;
  disabled?: boolean;
  fieldMapping?: FieldMappingConfig;
}

SubmitAction (union)

type SubmitAction =
  | HttpSubmitAction // type: 'http'
  | WebhookSubmitAction // type: 'webhook'
  | EmailSubmitAction // type: 'email'
  | CustomSubmitAction; // type: 'custom'

SubmitTrigger

type SubmitTriggerType =
  | 'onSubmit'
  | 'onStepEnter'
  | 'onStepExit'
  | 'onFieldChange'
  | 'onFieldBlur'
  | 'onDelay'
  | 'manual';

interface SubmitTrigger {
  type: SubmitTriggerType;
  stepId?: string;
  fieldName?: string;
  delayMs?: number;
  debounceMs?: number;
}

FieldMapping

interface FieldMapping {
  fields?: Record<string, string | FieldMapEntry>;
  inject?: Record<string, unknown>;
  exclude?: string[];
  passthrough?: boolean; // default: true
}

interface FieldMapEntry {
  to: string;
  transform?: BuiltinTransform | FieldTransformFn;
}

type BuiltinTransform =
  | 'toString'
  | 'toNumber'
  | 'toBoolean'
  | 'booleanString'
  | 'dateISO'
  | 'dateYMD'
  | 'dateDMY'
  | 'dateTimestamp'
  | 'trim'
  | 'lowercase'
  | 'uppercase'
  | 'emptyToNull';

FieldResolver

type FieldResolver =
  | { $resolver: 'timestamp' }
  | { $resolver: 'hostname' }
  | { $resolver: 'urlParam'; param: string; fallback?: string }
  | { $resolver: 'custom'; fn: () => unknown };

SubmitExecutionConfig

interface SubmitExecutionConfig {
  mode: 'sequential' | 'parallel';
  stopOnFirstError?: boolean;
  globalTimeout?: number;
}

SubmitActionsResult

interface SubmitActionsResult {
  results: SubmitActionResult[];
  allSuccessful: boolean;
  successCount: number;
  failureCount: number;
  totalDurationMs: number;
}

interface SubmitActionResult {
  actionId: string;
  actionName: string;
  success: boolean;
  data?: unknown;
  error?: Error;
  durationMs: number;
  startedAt: Date;
  completedAt: Date;
}

See: Submit & Actions


types/plugin.ts

FormPlugin

interface FormPlugin {
  name: string;
  version: string;
  description?: string;
  options?: Record<string, unknown>;
  init?: (options?) => void;
  cleanup?: () => void;
  onFormInit?: (config: FormConfig) => void;
  onFieldChange?: (fieldName: string, value: unknown, allValues: Record<string, unknown>) => void;
  onStepChange?: (stepId: string, values: Record<string, unknown>) => void;
  onBeforeSubmit?: (values: Record<string, unknown>) => void | Promise<void>;
  onAfterSubmit?: (values: Record<string, unknown>, response: unknown) => void;
  onError?: (error: Error, values?: Record<string, unknown>) => void;
  transformConfig?: (config: FormConfig) => FormConfig;
  transformValues?: (
    values: Record<string, unknown>,
  ) => Record<string, unknown> | Promise<Record<string, unknown>>;
  registerFields?: () => Record<string, FieldRenderer>;
  validators?: Record<
    string,
    (value: unknown, context: ValidationContext) => boolean | string | Promise<boolean | string>
  >;
}

ValidationContext

interface ValidationContext {
  fieldName: string;
  allValues: Record<string, unknown>;
  abortSignal?: AbortSignal;
}

FieldRenderer

type FieldRenderer = React.ComponentType<{
  name: string;
  fieldConfig: any;
  control: any;
  colSpanItem: string;
}>;

definePlugin()

function definePlugin(plugin: FormPlugin): FormPlugin;

See: Plugins


types/validation.ts

ValidationRules

Serializable validation rules compiled to Zod at runtime:

type ValidationRules = {
  required?: boolean;
  requiredMessage?: string;
  minLength?: number;
  minLengthMessage?: string;
  maxLength?: number;
  maxLengthMessage?: string;
  pattern?: string;
  patternMessage?: string;
  format?: 'email' | 'url' | 'uuid' | 'cuid' | 'emoji';
  formatMessage?: string;
  min?: number;
  minMessage?: string;
  max?: number;
  maxMessage?: string;
  integer?: boolean;
  integerMessage?: string;
  positive?: boolean;
  positiveMessage?: string;
  minItems?: number;
  minItemsMessage?: string;
  maxItems?: number;
  maxItemsMessage?: string;
  mustBeTrue?: boolean;
  mustBeTrueMessage?: string;
  minDate?: string;
  minDateMessage?: string;
  maxDate?: string;
  maxDateMessage?: string;
  mustBeFuture?: boolean;
  mustBeFutureMessage?: string;
  mustBePast?: boolean;
  mustBePastMessage?: string;
  preset?: string;
};

SchemaType

type SchemaType = z.ZodType | ValidationRules;

See: Validation


types/components.ts

ComponentRegistry

The full 49-slot interface for UI component injection. See Component System for the complete table.

interface ComponentRegistry {
  // Inputs (4): Input, Textarea, Button, Label
  // Checkbox & Switch (2): Checkbox, Switch
  // Radio (2): RadioGroup, RadioGroupItem
  // Select (5): Select, SelectTrigger, SelectContent, SelectItem, SelectValue
  // Native Select (1): NativeSelect
  // Slider (1): Slider
  // Popover (3): Popover, PopoverTrigger, PopoverContent
  // Tooltip (4): Tooltip, TooltipTrigger, TooltipContent, TooltipProvider
  // Separator (1): Separator
  // Dialog (6): Dialog, DialogTrigger, DialogContent, DialogHeader, DialogTitle, DialogDescription
  // Command (6): Command, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem
  // Input OTP (3): InputOTP, InputOTPGroup, InputOTPSlot
  // Accordion (4): Accordion, AccordionItem, AccordionTrigger, AccordionContent
  // Calendar (1): Calendar
  // Form (2): FormField, FormControl
  // Field (4): Field, FieldLabel, FieldDescription, FieldError
}

Helper Types

type PartialComponentRegistry = Partial<ComponentRegistry>;
type ComponentRegistryInput = { [K in keyof ComponentRegistry]: React.ComponentType<any> };
type ComponentOverrides = Partial<{ [K in keyof ComponentRegistry]: React.ComponentType<any> }>;

See: Component System