Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/form update options #11

Merged
merged 4 commits into from
Apr 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/reference/react/useForm.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ declare function useForm<
TData,
TAdapter extends ValidatorAdapter | undefined = undefined,
>(
options: FormLogicOptions<TData, TAdapter>,
options?: FormLogicOptions<TData, TAdapter>,
): FormContextType<TData, TAdapter>;
```

Expand Down
73 changes: 72 additions & 1 deletion packages/form-core/src/FormLogic.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,12 @@ const adapter: ValidatorAdapter = {
describe('FormLogic', () => {
it('should have the correct initial state', () => {
const form = new FormLogic()

expect(form.isMounted.value).toBeFalsy()
form.mount()
expect(form.isMounted.value).toBeTruthy()

expect(form.fields.peek().length).toBe(0)
expect(form.fields.value.length).toBe(0)

expect(form.data.value).toStrictEqual({})
expect(form.json.value).toStrictEqual({})
Expand Down Expand Up @@ -470,6 +473,42 @@ describe('FormLogic', () => {
form.updateOptions({ defaultValues: { name: 'another' } })
expect(form.data.value.name.value).toBe('another')
})
it('should be able to remove fields of dynamic objects or items from an array when updating the options', () => {
const form = new FormLogic<{
obj: { [key: string]: string }
array: number[]
}>({
defaultValues: {
obj: {
stay: 'stay',
go: 'go',
},
array: [1, 2, 3],
},
})
form.mount()

expect(form.json.value).toEqual({
obj: {
stay: 'stay',
go: 'go',
},
array: [1, 2, 3],
})
form.updateOptions({
defaultValues: {
obj: { stay: 'stay(changed)', new: 'new' },
array: [2],
},
})
expect(form.json.value).toEqual({
obj: {
stay: 'stay(changed)',
new: 'new',
},
array: [2],
})
})

it('should update the data when using the handleChange method', () => {
const form = new FormLogic<{ name: string }>()
Expand Down Expand Up @@ -1804,6 +1843,22 @@ describe('FormLogic', () => {
expect(form.data.value.deep.value.new.value).toBe(2)
expect(fn).toHaveBeenCalledTimes(1)
})
it('should touch a field when adding a new key to an object if configured', () => {
const form = new FormLogic<{ deep: { [key: string]: number } }>({
defaultValues: {
deep: {
value: 1,
},
},
})
form.mount()
const field = new FieldLogic(form, 'deep')
field.mount()

expect(field.isTouched.value).toBe(false)
form.setValueInObject('deep', 'new', 2, { shouldTouch: true })
expect(field.isTouched.value).toBe(true)
})
it('should update a value in an object that already has the key', () => {
const form = new FormLogic<{ deep: { [key: string]: number } }>({
defaultValues: {
Expand Down Expand Up @@ -1881,6 +1936,22 @@ describe('FormLogic', () => {
expect(form.data.value.deep.value.value).toBeUndefined()
expect(fn).toHaveBeenCalledTimes(1)
})
it('should touch a field when removing a key from an object if configured', () => {
const form = new FormLogic<{ deep: { value?: number } }>({
defaultValues: {
deep: {
value: 1,
},
},
})
form.mount()
const field = new FieldLogic(form, 'deep')
field.mount()

expect(field.isTouched.value).toBe(false)
form.removeValueInObject('deep', 'value', { shouldTouch: true })
expect(field.isTouched.value).toBe(true)
})
it('should do nothing when trying to remove a key to a value that is not an object or a date', () => {
const form = new FormLogic({
defaultValues: {
Expand Down
5 changes: 2 additions & 3 deletions packages/form-core/src/FormLogic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import {
isEqualDeep,
makeArrayEntry,
removeSignalValueAtPath,
removeValueAtPath,
setSignalValueAtPath,
setSignalValuesFromObject,
setValueAtPath,
Expand Down Expand Up @@ -394,9 +393,9 @@ export class FormLogic<
// We do not want to update dirty field values, since we do not want to reset the form, but just override the default values
const newDefaultValues = { ...options.defaultValues }
for (const dirtyField of dirtyFields) {
removeValueAtPath(newDefaultValues, dirtyField as never)
setValueAtPath(newDefaultValues, dirtyField as never, undefined)
}
setSignalValuesFromObject(this._data, newDefaultValues, true)
setSignalValuesFromObject(this._data, newDefaultValues)
}

/**
Expand Down
2 changes: 1 addition & 1 deletion packages/form-react/src/form/form.hooks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export function useForm<
TData,
TAdapter extends ValidatorAdapter | undefined = undefined,
>(
options: FormLogicOptions<TData, TAdapter>,
options?: FormLogicOptions<TData, TAdapter>,
): FormContextType<TData, TAdapter> {
// biome-ignore lint/correctness/useExhaustiveDependencies: We only ever want to create a form once
const finalForm = React.useMemo(() => {
Expand Down
Loading