CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-final-form

Framework-agnostic, high-performance form state management library with subscription-based updates.

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

form-creation.mddocs/

Form Creation

Core form creation functionality for initializing form instances with comprehensive configuration and lifecycle management capabilities.

Capabilities

Create Form

Creates a new form instance with the specified configuration.

/**
 * Creates a new form instance with the specified configuration
 * @param config - Form configuration object
 * @returns FormApi instance for interacting with the form
 */
function createForm<
  FormValues = Record<string, any>,
  InitialFormValues extends Partial<FormValues> = Partial<FormValues>
>(config: Config<FormValues, InitialFormValues>): FormApi<FormValues, InitialFormValues>;

Usage Example:

import { createForm } from "final-form";

const form = createForm({
  onSubmit: async (values) => {
    // Handle form submission
    const response = await fetch('/api/submit', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(values)
    });
    
    if (!response.ok) {
      // Return submission errors
      return { email: 'Email already exists' };
    }
  },
  initialValues: {
    firstName: '',
    lastName: '',
    email: ''
  },
  validate: (values) => {
    const errors = {};
    if (!values.email) {
      errors.email = 'Required';
    }
    return errors;
  }
});

Configuration Interface

Complete configuration options for form creation.

interface Config<
  FormValues = Record<string, any>,
  InitialFormValues extends Partial<FormValues> = Partial<FormValues>
> {
  /** Required submission handler function */
  onSubmit: (
    values: FormValues,
    form: FormApi<FormValues, InitialFormValues>,
    callback?: (errors?: SubmissionErrors) => void
  ) => SubmissionErrors | Promise<SubmissionErrors> | void;
  
  /** Optional debug callback for form state changes */
  debug?: DebugFunction<FormValues, InitialFormValues>;
  
  /** Whether to destroy field state when field is unregistered (default: false) */
  destroyOnUnregister?: boolean;
  
  /** Initial values for form fields */
  initialValues?: InitialFormValues;
  
  /** Keep dirty state when form is reinitialized (default: false) */
  keepDirtyOnReinitialize?: boolean;
  
  /** Custom mutator functions for advanced form state manipulation */
  mutators?: { [key: string]: Mutator<FormValues, InitialFormValues> };
  
  /** Form-level validation function */
  validate?: (values: FormValues) => ValidationErrors | Promise<ValidationErrors>;
  
  /** Whether to validate fields on blur (default: false) */
  validateOnBlur?: boolean;
  
  /** Custom callback scheduler for controlling when callbacks are executed */
  callbackScheduler?: (callback: () => void) => void;
}

Configuration Examples:

// Basic form with validation
const basicForm = createForm({
  onSubmit: (values) => console.log(values),
  validate: (values) => {
    const errors = {};
    if (!values.name?.trim()) {
      errors.name = 'Name is required';
    }
    if (values.age && values.age < 18) {
      errors.age = 'Must be 18 or older';
    }
    return errors;
  }
});

// Form with async validation
const asyncForm = createForm({
  onSubmit: async (values) => {
    await submitToAPI(values);
  },
  validate: async (values) => {
    if (values.username) {
      const available = await checkUsernameAvailability(values.username);
      if (!available) {
        return { username: 'Username already taken' };
      }
    }
  }
});

// Form with custom mutators
const mutatorForm = createForm({
  onSubmit: (values) => console.log(values),
  mutators: {
    setValue: (args, state, tools) => {
      const [field, value] = args;
      tools.changeValue(state, field, () => value);
    },
    clearAll: (args, state, tools) => {
      const registeredFields = Object.keys(state.fields);
      registeredFields.forEach(field => {
        tools.changeValue(state, field, () => undefined);
      });
    }
  }
});

Configuration Options

Available configuration option keys for runtime form configuration.

const configOptions: ConfigKey[];

type ConfigKey = 
  | "debug"
  | "destroyOnUnregister"
  | "initialValues"
  | "keepDirtyOnReinitialize"
  | "mutators"
  | "onSubmit"
  | "validate"
  | "validateOnBlur"
  | "callbackScheduler";

Debug Function Type

Type definition for debug callback functions.

type DebugFunction<
  FormValues = Record<string, any>,
  InitialFormValues extends Partial<FormValues> = Partial<FormValues>
> = (
  state: FormState<FormValues, InitialFormValues>,
  fieldStates: { [key: string]: FieldState<any> }
) => void;

Debug Usage Example:

const form = createForm({
  onSubmit: (values) => console.log(values),
  debug: (formState, fieldStates) => {
    console.log('Form State:', formState);
    console.log('Field States:', fieldStates);
  }
});

Mutator Function Type

Type definition for custom mutator functions that can modify form state.

type Mutator<
  FormValues = Record<string, any>,
  InitialFormValues extends Partial<FormValues> = Partial<FormValues>
> = (
  args: any[],
  state: MutableState<FormValues, InitialFormValues>,
  tools: Tools<FormValues, InitialFormValues>
) => any;

interface Tools<FormValues, InitialFormValues> {
  changeValue: ChangeValue<FormValues, InitialFormValues>;
  getIn: GetIn;
  renameField: RenameField<FormValues, InitialFormValues>;
  resetFieldState: (name: string) => void;
  setIn: SetIn;
  shallowEqual: IsEqual;
}

Mutator Usage Example:

const form = createForm({
  onSubmit: (values) => console.log(values),
  mutators: {
    // Custom mutator to set multiple fields at once
    setFields: (args, state, tools) => {
      const [fieldsObject] = args;
      Object.keys(fieldsObject).forEach(fieldName => {
        tools.changeValue(state, fieldName, () => fieldsObject[fieldName]);
      });
    },
    // Custom mutator to increment a numeric field
    increment: (args, state, tools) => {
      const [fieldName, amount = 1] = args;
      tools.changeValue(state, fieldName, (value) => (value || 0) + amount);
    }
  }
});

// Use the custom mutators
form.mutators.setFields({ firstName: 'John', lastName: 'Doe' });
form.mutators.increment('counter', 5);

docs

field-registration.md

form-actions.md

form-creation.md

index.md

state-management.md

utilities.md

validation.md

tile.json