Skip to content

Commit a878ca3

Browse files
committed
Field component
1 parent a2269e4 commit a878ca3

File tree

5 files changed

+50
-1
lines changed

5 files changed

+50
-1
lines changed

src/elements/Field.tsx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { FormState } from "../form";
2+
import React, { useCallback } from "react";
3+
import { useListener } from "../hooks";
4+
5+
export function Field<T extends object, K extends keyof T, C extends keyof JSX.IntrinsicElements | React.FunctionComponent<any>>(
6+
props: {
7+
form: FormState<T>;
8+
name: K;
9+
component?: C;
10+
} & Omit<
11+
(C extends React.FunctionComponent<infer P> ? P : {}) & (C extends keyof JSX.IntrinsicElements ? JSX.IntrinsicElements[C] : {}),
12+
"form" | "name" | "component" | "value" | "onChange"
13+
>
14+
) {
15+
const { form, component = "input", ...rest } = props;
16+
const { value, setValue } = useListener(form, props.name);
17+
const onChange = useCallback((ev: any) => setValue(ev.target?.value ?? ev), []);
18+
return React.createElement(component, { ...rest, value, onChange });
19+
}

src/elements/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,5 @@ export * from "./FormError";
55
export * from "./serializer";
66

77
export type StyledFix<T, Props = {}> = T | ((props: Props) => JSX.Element);
8+
9+
export * from "./Field";

src/hooks.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ export function useListener<T extends object, K extends keyof T, State = Default
8282
name: K
8383
) {
8484
const [, setRender] = useState(0);
85+
const setValue = useCallback((value: T[K]) => form.setValue(name, value), [name, form]);
8586

8687
useEffect(() => {
8788
let id = form.listen(name, () => {
@@ -93,7 +94,7 @@ export function useListener<T extends object, K extends keyof T, State = Default
9394
return {
9495
value: form.values[name],
9596
defaultValue: form.defaultValues[name],
96-
setValue: (value: T[K]) => form.setValue(name, value),
97+
setValue: setValue,
9798
dirty: form.dirtyMap[name],
9899
error: form.errorMap[name],
99100
state: form.state,

testing/src/Fieldform.tsx

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import React from "react";
2+
import { useForm, Field, AnyListener } from "typed-react-form";
3+
4+
function Input(props: { value?: string; onChange?: (value: string) => void; style: React.CSSProperties }) {
5+
return <input value={props.value} onChange={(ev) => props.onChange?.(ev.target.value)} style={props.style} />;
6+
}
7+
8+
export function FieldForm() {
9+
const form = useForm({ email: "", firstName: "", gender: "male" as "male" | "female" });
10+
11+
return (
12+
<form>
13+
<Field form={form} name="email" component="textarea" />
14+
<Field form={form} name="email" />
15+
<Field form={form} name="email" component={Input} style={{ margin: "1em" }} />
16+
<Field form={form} name="gender" component="select">
17+
<option value="male">male</option>
18+
<option value="female">female</option>
19+
</Field>
20+
<pre>
21+
<AnyListener form={form} render={() => JSON.stringify(form.values, null, 2)} />
22+
</pre>
23+
</form>
24+
);
25+
}

testing/src/index.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { StyledForm } from "./StyledForm";
99
import { ExampleForm } from "./ExampleForm";
1010
import App from "./App";
1111
import { CustomInputsForm } from "./CustomInput";
12+
import { FieldForm } from "./Fieldform";
1213

1314
function Router() {
1415
return (
@@ -19,6 +20,7 @@ function Router() {
1920
<Route path="/styled-form" component={StyledForm} />
2021
<Route path="/test" component={App} />
2122
<Route path="/custom-inputs" component={CustomInputsForm} />
23+
<Route path="/field" component={FieldForm} />
2224
<Route path="/" component={ExampleForm} />
2325
</Switch>
2426
</BrowserRouter>

0 commit comments

Comments
 (0)