Skip to content

Commit

Permalink
Add sanitizeField method (#24)
Browse files Browse the repository at this point in the history
* Add sanitizeField method

* Bump version number
  • Loading branch information
zoontek authored Jul 19, 2023
1 parent edd66ff commit bb65b93
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 8 deletions.
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ const {
setFieldError,
focusField,
resetField,
sanitizeField,
validateField,
listenFields,
resetForm,
Expand Down Expand Up @@ -259,6 +260,14 @@ type resetField = (
) => void;
```

#### sanitizeField

Sanitize the field value.

```tsx
type sanitizeField = (name: FieldName) => void;
```

#### validateField

Once you manually call validation, the field automatically switches to _talkative_ state.
Expand Down
54 changes: 54 additions & 0 deletions __tests__/sanitization.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { fireEvent, render, screen } from "@testing-library/react";
import * as React from "react";
import { test } from "vitest";
import { useForm } from "../src";

test("input sanitization is perform onBlur", async () => {
const Test = () => {
const { Field, sanitizeField } = useForm({
firstName: {
initialValue: "",
sanitize: (value) => value.trim(),
},
});

return (
<form onSubmit={(e) => e.preventDefault()}>
<Field name="firstName">
{({ ref, onBlur, onChange, value }) => (
<>
<label htmlFor="firstName">First name</label>

<input
ref={ref}
type="text"
id="firstName"
value={value}
onBlur={() => {
sanitizeField("firstName");
onBlur();
}}
onChange={(e) => {
e.preventDefault();
onChange(e.target.value);
}}
/>

<span>Sanitized value: "{value}"</span>
</>
)}
</Field>
</form>
);
};

render(<Test />);

const input = await screen.findByLabelText("First name");

fireEvent.focus(input);
fireEvent.input(input, { target: { value: " Nicolas " } });
fireEvent.blur(input);

await screen.findByText('Sanitized value: "Nicolas"');
});
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-ux-form",
"version": "1.3.0",
"version": "1.4.0",
"license": "MIT",
"description": "A simple, fast and opinionated form library for React & React Native focusing on UX.",
"author": "Mathieu Acthernoene <mathieu.acthernoene@swan.io>",
Expand Down
29 changes: 22 additions & 7 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ export type Form<Values extends AnyRecord, ErrorMessage = string> = {

focusField: (name: keyof Values) => void;
resetField: (name: keyof Values, options?: { feedbackOnly?: boolean }) => void;
sanitizeField: (name: keyof Values) => void;
validateField: (name: keyof Values) => Promise<ErrorMessage | void>;

listenFields: <N extends keyof Values>(
Expand Down Expand Up @@ -268,7 +269,7 @@ export const useForm = <Values extends AnyRecord, ErrorMessage = string>(
return debounced;
};

const runCallbacks = (name: Name): void => {
const runRenderCallbacks = (name: Name): void => {
callbacks.current[name].forEach((callback) => callback());
};

Expand Down Expand Up @@ -335,14 +336,14 @@ export const useForm = <Values extends AnyRecord, ErrorMessage = string>(
}

setError(name, error);
runCallbacks(name);
runRenderCallbacks(name);

return error;
}

if (!debounced) {
setValidating(name);
runCallbacks(name);
runRenderCallbacks(name);
}

return promiseOrError
Expand All @@ -358,7 +359,7 @@ export const useForm = <Values extends AnyRecord, ErrorMessage = string>(
}

setError(name, error);
runCallbacks(name);
runRenderCallbacks(name);

return error;
})
Expand Down Expand Up @@ -390,7 +391,7 @@ export const useForm = <Values extends AnyRecord, ErrorMessage = string>(
const setFieldError: Contract["setFieldError"] = (name, error) => {
setError(name, error);
setTalkative(name);
runCallbacks(name);
runRenderCallbacks(name);
};

const focusField: Contract["focusField"] = (name) => {
Expand All @@ -410,7 +411,19 @@ export const useForm = <Values extends AnyRecord, ErrorMessage = string>(
validity: { tag: "unknown" },
}));

runCallbacks(name);
runRenderCallbacks(name);
};

const sanitizeField: Contract["sanitizeField"] = (name) => {
const sanitize = getSanitize(name);

setState(name, ({ talkative, value, validity }) => ({
value: sanitize(value),
talkative,
validity,
}));

runRenderCallbacks(name);
};

const validateField: Contract["validateField"] = (name) => {
Expand Down Expand Up @@ -468,7 +481,7 @@ export const useForm = <Values extends AnyRecord, ErrorMessage = string>(
}

setValidating(name);
runCallbacks(name);
runRenderCallbacks(name);

timeouts.current[name] = setTimeout(() => {
if (isMounted(name)) {
Expand Down Expand Up @@ -618,6 +631,7 @@ export const useForm = <Values extends AnyRecord, ErrorMessage = string>(
setFieldError,
focusField,
resetField,
sanitizeField,
validateField,
listenFields,

Expand Down Expand Up @@ -750,6 +764,7 @@ export const useForm = <Values extends AnyRecord, ErrorMessage = string>(
setFieldError: api.setFieldError,
focusField: api.focusField,
resetField: api.resetField,
sanitizeField: api.sanitizeField,
validateField: api.validateField,
listenFields: api.listenFields,

Expand Down

0 comments on commit bb65b93

Please sign in to comment.