Skip to content

Commit 5451e5d

Browse files
committed
Support setting parent error from child
1 parent 8a453b1 commit 5451e5d

File tree

3 files changed

+17
-5
lines changed

3 files changed

+17
-5
lines changed

example/src/App.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ export function Form() {
288288
<hr />
289289
<h3>Togglable object field</h3>
290290
<label>
291-
<FormInput form={form} name="author" type="checkbox" setNullOnUncheck value={{ name: "", age: 0 }} />
291+
<FormInput form={form} name="author" type="checkbox" setUndefinedOnUncheck value={{ name: "", age: 0 }} />
292292
Enable author
293293
</label>
294294
<ChildForm
@@ -301,6 +301,10 @@ export function Form() {
301301
<FormInput form={form} name="name" />
302302
<p>Age</p>
303303
<FormInput form={form} name="age" type="number" />
304+
<button type="button" onClick={() => form.setErrors("This is a parent error")}>
305+
Set parent error
306+
</button>
307+
j
304308
</div>
305309
</VisualRender>
306310
)}

example/src/index.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import OneOfObjectArrayForm from "./OneOfObjectArrayForm";
77
import { BrowserRouter, Route, Switch } from "react-router-dom";
88
import { StyledForm } from "./StyledForm";
99
import { ExampleForm } from "./ExampleForm";
10+
import App from "./App";
1011

1112
function Router() {
1213
return (
@@ -15,6 +16,7 @@ function Router() {
1516
<Route path="/object-types" component={OneOfObjectForm} />
1617
<Route path="/object-types-array" component={OneOfObjectArrayForm} />
1718
<Route path="/styled-form" component={StyledForm} />
19+
<Route path="/test" component={App} />
1820
<Route path="/" component={ExampleForm} />
1921
</Switch>
2022
</BrowserRouter>

src/form.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
export type ListenerCallback = () => void;
22
export type ListenerMap = { [T in string]?: ListenerCallback };
3-
export type Validator<T, Error> = (values: T) => ErrorMap<T, Error> | Promise<ErrorMap<T, Error>>;
3+
export type Validator<T, Error> = (values: T) => ErrorType<T, Error> | Promise<ErrorType<T, Error>>;
44

55
export type ChildFormMap<T, State, Error extends string> = {
66
[Key in keyof T]?: ChildFormState<T, Key, State, Error>;
@@ -10,7 +10,7 @@ export type DirtyMap<T> = {
1010
[Key in keyof T]?: boolean;
1111
};
1212

13-
export type ErrorType<T, Error> = T extends object ? ErrorMap<T, Error> | Error : Error;
13+
export type ErrorType<T, Error> = Error | (T extends {} ? ErrorMap<T, Error> : never);
1414

1515
export type ErrorMap<T, Error> = {
1616
[Key in keyof T]?: ErrorType<T[Key], Error>;
@@ -329,7 +329,7 @@ export class FormState<T, State = DefaultState, Error extends string = DefaultEr
329329
let changed = this.childMap[key]!.setErrors((error as any) ?? {}, true, false);
330330
if (!changed) return false;
331331
} else {
332-
this.childMap[key]!.setErrors({}, true, false);
332+
this.childMap[key]!.setErrors({} as any, true, false);
333333
}
334334
}
335335

@@ -345,7 +345,13 @@ export class FormState<T, State = DefaultState, Error extends string = DefaultEr
345345
* @param notifyChild Should this form notify the child form about this change?
346346
* @param notifyParent Should this form notify the parent form about this change?
347347
*/
348-
public setErrors(errors: ErrorMap<T, Error>, notifyChild: boolean = true, notifyParent: boolean = true) {
348+
public setErrors(errors: ErrorType<T, Error>, notifyChild: boolean = true, notifyParent: boolean = true) {
349+
if (typeof errors === "string") {
350+
if (notifyParent && this instanceof ChildFormState) {
351+
this.parent.setError(this.name, errors, false, true);
352+
}
353+
return;
354+
}
349355
let keys = Object.keys(this.errorMap);
350356
let newKeys = Object.keys(errors);
351357
for (let i = 0; i < newKeys.length; i++) {

0 commit comments

Comments
 (0)