UNPKG

@modular-forms/react

Version:

The modular and type-safe form library for React

55 lines (54 loc) 2.87 kB
import { batch } from '@preact/signals-react'; import { getFieldArrayNames, getFieldArrayState, getFieldArrayStore, getFieldNames, getFieldState, getPathIndex, setFieldArrayState, setFieldState, sortArrayPathIndex, updateFieldArrayDirty, validateIfRequired, } from '../utils'; /** * Removes a item of the field array. * * @param form The form of the field array. * @param name The name of field array. * @param options The remove options. */ export function remove(form, name, { at: index }) { // Get store of specified field array const fieldArray = getFieldArrayStore(form, name); // Continue if specified field array exists if (fieldArray) { // Get last index of field array const lastIndex = fieldArray.items.peek().length - 1; // Continue if specified index is valid if (index >= 0 && index <= lastIndex) { // Create function to filter a name const filterName = (value) => value.startsWith(`${name}.`) && getPathIndex(name, value) > index; // Create function to get previous index name const getPrevIndexName = (fieldOrFieldArrayName, fieldOrFieldArrayIndex) => fieldOrFieldArrayName.replace(`${name}.${fieldOrFieldArrayIndex}`, `${name}.${fieldOrFieldArrayIndex - 1}`); batch(() => { // Move state of each field after the removed index back by one index getFieldNames(form) .filter(filterName) .sort(sortArrayPathIndex(name)) .forEach((fieldName) => { setFieldState(form, getPrevIndexName(fieldName, getPathIndex(name, fieldName)), getFieldState(form, fieldName)); }); // Move state of each field array after the removed index back by one index getFieldArrayNames(form) .filter(filterName) .sort(sortArrayPathIndex(name)) .forEach((fieldArrayName) => { setFieldArrayState(form, getPrevIndexName(fieldArrayName, getPathIndex(name, fieldArrayName)), getFieldArrayState(form, fieldArrayName)); }); // Delete item from field array const nextItems = [...fieldArray.items.peek()]; nextItems.splice(index, 1); fieldArray.items.value = nextItems; // Set touched at field array and form to true fieldArray.touched.value = true; form.touched.value = true; // Update dirty state at field array and form updateFieldArrayDirty(form, fieldArray); // Validate field array if necessary validateIfRequired(form, fieldArray, name, { on: ['touched', 'change'], }); }); } } }