From b4ac146d8e543a4a631c541afda53c9ca65b97ef Mon Sep 17 00:00:00 2001 From: Avram Walden Date: Sun, 14 Apr 2024 14:23:21 -0700 Subject: [PATCH] feat: removeInput returns the removed record (#16) --- src/useDynamicInputs.ts | 12 +++++++----- src/utils.ts | 30 +++++------------------------- tests/utils.test.ts | 19 +++---------------- 3 files changed, 15 insertions(+), 46 deletions(-) diff --git a/src/useDynamicInputs.ts b/src/useDynamicInputs.ts index d71c714..71cdc7b 100644 --- a/src/useDynamicInputs.ts +++ b/src/useDynamicInputs.ts @@ -4,18 +4,18 @@ import { get, set } from 'lodash' import { useNestedAttribute } from './NestedFields' import { NestedObject } from './useInertiaForm' -export interface DynamicInputsProps { +export interface DynamicInputsProps { model?: string - emptyData: Record + emptyData: T } -type DynamicInputsReturn = { +type DynamicInputsReturn = { addInput: () => void - removeInput: (i: number) => void + removeInput: (i: number) => T paths: string[] } -const useDynamicInputs = ({ model, emptyData }: DynamicInputsProps): DynamicInputsReturn => { +const useDynamicInputs = ({ model, emptyData }: DynamicInputsProps): DynamicInputsReturn => { const { setData, unsetData, getData } = useForm() const { model: formModel } = useFormMeta() let inputModel = formModel ?? '' @@ -45,7 +45,9 @@ const useDynamicInputs = ({ model, emptyData }: DynamicInputsProps): DynamicInpu }, []) const handleRemoveInputs = useCallback((i: number) => { + const record = getData(`${inputModel}[${i}]`) as T unsetData(`${inputModel}[${i}]`) + return record }, []) const data = getData(inputModel) diff --git a/src/utils.ts b/src/utils.ts index 2fb4e17..dec0716 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -53,32 +53,15 @@ export const fillEmptyValues = (data: TForm) => { } /** - * Appends a string to the end of parts of a dot notated string, - * excepting those with array notation, and the first and last elements - */ -export const renameWithAttributes = (str: string, append = '_attributes') => { - const parts = str.split('.') - - if(parts.length < 2) return str - - for(let i = parts.length - 2; i > 0; i--) { - if(parts[i].charAt(parts[i].length - 1) !== ']') { - parts[i] = `${parts[i]}${append}` - } else { - parts[i].replace('[', '_attributes[') - } - } - - return parts.join('.') -} - -/** - * Removes appended string '_attributes' from dot notation + * Removes appended string (default of '_attributes') from dot notation */ export const stripAttributes = (str: string, attribute = '_attributes') => { return str.replace(new RegExp(`${attribute}\\.`), '.') } +/** + * Append string (default of '_attributes') to keys of nested records + */ export const renameObjectWithAttributes = (data: T, str = '_attributes') => { const clone = structuredClone(data) @@ -110,10 +93,7 @@ const renameKey = (obj, oldKey, newKey) => { } } -export const coerceArray = (arg: string | string[]) => { - if(Array.isArray(arg)) return arg - return [arg] -} +export const coerceArray = (arg: T | T[]) => Array.isArray(arg) ? arg : [arg] /** * Returns whether a value should be considered empty in the context of a form input diff --git a/tests/utils.test.ts b/tests/utils.test.ts index 7c37132..8a4deeb 100644 --- a/tests/utils.test.ts +++ b/tests/utils.test.ts @@ -1,5 +1,5 @@ import { NestedObject } from '../src/useInertiaForm' -import { coerceArray, fillEmptyValues, renameObjectWithAttributes, renameWithAttributes, stripAttributes, unsetCompact } from '../src/utils' +import { coerceArray, fillEmptyValues, renameObjectWithAttributes, stripAttributes, unsetCompact } from '../src/utils' const nestedData: NestedObject = { one: 'one', @@ -78,23 +78,10 @@ describe('fillEmptyValues', () => { }) }) -describe('renameWithAttributes', () => { - it('should add _attributes where appropriate to dot notation strings', () => { - expect(renameWithAttributes('user.person.name')).toEqual('user.person_attributes.name') - expect(renameWithAttributes('user.contact.phones[2].number')).toEqual('user.contact_attributes.phones[2].number') - expect(renameWithAttributes('user.person.manager.name')).toEqual('user.person_attributes.manager_attributes.name') - }) - - it('accepts another string to use in place of _attributes', () => { - expect(renameWithAttributes('user.person.name', '_input')).toEqual('user.person_input.name') - }) -}) - describe('stripAttributes', () => { it('should remove _attributes from dot notation strings', () => { - const key = 'user.person.name' - const attributed = renameWithAttributes('user.person.name') - expect(stripAttributes(attributed)).toEqual(key) + const key = 'user.person_attributes.name' + expect(stripAttributes(key)).toEqual('user.person.name') }) it('should not remove the word attributes without the _ or not at the end of a segment', () => {