diff --git a/.changeset/violet-bees-wait.md b/.changeset/violet-bees-wait.md new file mode 100644 index 0000000..2eb7aef --- /dev/null +++ b/.changeset/violet-bees-wait.md @@ -0,0 +1,5 @@ +--- +"@stevent-team/react-zoom-form": minor +--- + +Add helper functions for watching a value and directly setting a value diff --git a/example/App.tsx b/example/App.tsx index 1cc832f..6cd4ab5 100644 --- a/example/App.tsx +++ b/example/App.tsx @@ -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 @@ -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 = values => { console.log(values) @@ -77,7 +77,7 @@ const App = () => { - {value.condition && <> + {getValue(fields.condition) && <> @@ -102,7 +102,7 @@ const App = () => {
isDirty: {isDirty ? 'true' : 'false'}
-
value: {JSON.stringify(value, null, 2)}
+
value: {JSON.stringify(getValue(fields), null, 2)}
errors: {JSON.stringify(fieldErrors(fields), null, 2)}
diff --git a/lib/field.ts b/lib/field.ts index 7f8b11a..83f4298 100644 --- a/lib/field.ts +++ b/lib/field.ts @@ -103,3 +103,35 @@ export const controlled = ({ _field }: { _field: FieldControls({ _field: { formErrors, path } }: { _field: FieldControls> }): 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 = ({ _field: { formValue, path } }: { _field: FieldControls> }) => + getDeepProp(formValue, path) as PartialObject> | undefined + +/** + * Set the value of a field directly. + * + * @example + * ```ts + * setValue(fields.myInput, 'Hi there!') + * ``` + */ +export const setValue = ( + { _field: { setFormValue, path } }: { _field: FieldControls> }, + newValue: PartialObject> | undefined | ((currentValue: PartialObject> | undefined) => PartialObject> | undefined) +) => { + if (typeof newValue === 'function') { + setFormValue(v => setDeepProp(v, path, newValue(getDeepProp(v, path) as PartialObject> | undefined)) as typeof v) + } else { + setFormValue(v => setDeepProp(v, path, newValue) as typeof v) + } +} diff --git a/lib/useForm.ts b/lib/useForm.ts index b3cf866..c9ec791 100644 --- a/lib/useForm.ts +++ b/lib/useForm.ts @@ -119,6 +119,5 @@ export const useForm = ({ isDirty, /** Reset the form with provided values, or with initialValues if nothing is passed. */ reset, - value: formValue, } }