Skip to content

Commit

Permalink
Merge pull request #23 from stevent-team/feat/watch-and-setValue
Browse files Browse the repository at this point in the history
Add helper functions for getting and setting values
  • Loading branch information
GRA0007 authored Jul 10, 2023
2 parents ff0b02f + e99c254 commit 42b41e2
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 5 deletions.
5 changes: 5 additions & 0 deletions .changeset/violet-bees-wait.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@stevent-team/react-zoom-form": minor
---

Add helper functions for watching a value and directly setting a value
8 changes: 4 additions & 4 deletions example/App.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { SubmitHandler, useForm, Field, controlled, fieldErrors, FieldControls } from '@stevent-team/react-zoom-form'
import { SubmitHandler, useForm, Field, controlled, fieldErrors, FieldControls, getValue } from '@stevent-team/react-zoom-form'
import { z } from 'zod'

// Define the structure and validation of your form
Expand Down Expand Up @@ -36,7 +36,7 @@ const initialValues = {
}

const App = () => {
const { fields, handleSubmit, isDirty, reset, value } = useForm({ schema, initialValues })
const { fields, handleSubmit, isDirty, reset } = useForm({ schema, initialValues })

const onSubmit: SubmitHandler<typeof schema> = values => {
console.log(values)
Expand Down Expand Up @@ -77,7 +77,7 @@ const App = () => {
</label>
<Error field={fields.condition} />

{value.condition && <>
{getValue(fields.condition) && <>
<label htmlFor={fields.conditional.name()}>Conditional field</label>
<input {...fields.conditional.register()} id={fields.conditional.name()} type="text" />
<Error field={fields.conditional} />
Expand All @@ -102,7 +102,7 @@ const App = () => {

<output>
<div>isDirty: {isDirty ? 'true' : 'false'}</div>
<div>value: {JSON.stringify(value, null, 2)}</div>
<div>value: {JSON.stringify(getValue(fields), null, 2)}</div>
<div>errors: {JSON.stringify(fieldErrors(fields), null, 2)}</div>
</output>
</form>
Expand Down
32 changes: 32 additions & 0 deletions lib/field.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,3 +103,35 @@ export const controlled = <T>({ _field }: { _field: FieldControls<z.ZodType<NonN
*/
export const fieldErrors = <T>({ _field: { formErrors, path } }: { _field: FieldControls<z.ZodType<T>> }): z.ZodIssue[] =>
formErrors?.issues?.filter(issue => arrayStartsWith(issue.path, path.map(p => p.key))) ?? []

/**
* Get the value of a field. You can also use the base `fields` object to
* watch all values in the form.
*
* @example
* ```ts
* const myInputValue = getValue(fields.myInput)
* const formValue = getValue(fields)
* ```
*/
export const getValue = <T>({ _field: { formValue, path } }: { _field: FieldControls<z.ZodType<T>> }) =>
getDeepProp(formValue, path) as PartialObject<NonNullable<T>> | undefined

/**
* Set the value of a field directly.
*
* @example
* ```ts
* setValue(fields.myInput, 'Hi there!')
* ```
*/
export const setValue = <T>(
{ _field: { setFormValue, path } }: { _field: FieldControls<z.ZodType<T>> },
newValue: PartialObject<NonNullable<T>> | undefined | ((currentValue: PartialObject<NonNullable<T>> | undefined) => PartialObject<NonNullable<T>> | undefined)
) => {
if (typeof newValue === 'function') {
setFormValue(v => setDeepProp(v, path, newValue(getDeepProp(v, path) as PartialObject<NonNullable<T>> | undefined)) as typeof v)
} else {
setFormValue(v => setDeepProp(v, path, newValue) as typeof v)
}
}
1 change: 0 additions & 1 deletion lib/useForm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,5 @@ export const useForm = <Schema extends z.AnyZodObject>({
isDirty,
/** Reset the form with provided values, or with initialValues if nothing is passed. */
reset,
value: formValue,
}
}

0 comments on commit 42b41e2

Please sign in to comment.