Framework-agnostic, high-performance form state management library with subscription-based updates.
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Core form creation functionality for initializing form instances with comprehensive configuration and lifecycle management capabilities.
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;
}
});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);
});
}
}
});Available configuration option keys for runtime form configuration.
const configOptions: ConfigKey[];
type ConfigKey =
| "debug"
| "destroyOnUnregister"
| "initialValues"
| "keepDirtyOnReinitialize"
| "mutators"
| "onSubmit"
| "validate"
| "validateOnBlur"
| "callbackScheduler";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);
}
});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);