Skip to content

Commit

Permalink
Merge pull request #9315 from ZachSelindh/add-helptertext-section-to-…
Browse files Browse the repository at this point in the history
…inputs

Add i18n InputHelpterText section to Inputs/useInputs docs
  • Loading branch information
djhi authored Sep 28, 2023
2 parents 98ae9a4 + b8baede commit 7b8186f
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 13 deletions.
48 changes: 47 additions & 1 deletion docs/Inputs.md
Original file line number Diff line number Diff line change
Expand Up @@ -774,6 +774,7 @@ const BoundedTextField = ({ name, label }: { name: string; label: string }) => {
fieldState: { isTouched, invalid, error },
formState: { isSubmitted }
} = useController({ name, defaultValue: '' });

return (
<TextField
{...field}
Expand Down Expand Up @@ -832,7 +833,7 @@ import { useInput, required, InputProps } from "react-admin";
interface BoundedTextFieldProps
extends Omit<
TextFieldProps,
"label" | "helperText" | "onChange" | "onBlur" | "type" | "defaultValue"
"label" | "onChange" | "onBlur" | "type" | "defaultValue"
>,
InputProps {}

Expand Down Expand Up @@ -935,6 +936,51 @@ const { isDirty } = useFormState(); // ✅
const formState = useFormState(); // ❌ should deconstruct the formState
```

## i18n

In order to properly format the input's `helperText` and error messages from `useInput()`, custom inputs should make use of the react-admin component `<InputHelperText>`, which ensures that the text below the input returns consistently whether it's a string or a React component, and whether it's a simple message or an error. Importantly, react-admin messages from `useInput()` are passed through `useTranslate()` inside `<InputHelperText>`, which makes this component important for localization.

```jsx
import TextField from '@mui/material/TextField';
import { useInput, InputHelperText } from 'react-admin';

const BoundedTextField = (props: BoundedTextFieldProps) => {
const { onChange, onBlur, label, helperText, ...rest } = props;
const {
field,
fieldState: { isTouched, invalid, error },
formState: { isSubmitted },
isRequired,
} = useInput({
onChange,
onBlur,
...rest,
});

const renderHelperText =
helperText !== false || ((isTouched || isSubmitted) && invalid);

return (
<TextField
{...field}
label={label}
error={(isTouched || isSubmitted) && invalid}
helperText={
renderHelperText ? (
<InputHelperText
touched={isTouched || isSubmitted}
error={error?.message}
helperText={helperText}
/>
) : null
}
required={isRequired}
{...rest}
/>
);
};
```
## Third-Party Components
You can find components for react-admin in third-party repositories.
Expand Down
29 changes: 17 additions & 12 deletions docs/useInput.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ import TextField from '@mui/material/TextField';
import { useInput, required } from 'react-admin';

const BoundedTextField = (props) => {
const { onChange, onBlur, ...rest } = props;
const { onChange, onBlur, label, ...rest } = props;
const {
field,
fieldState: { isTouched, invalid, error },
Expand All @@ -73,13 +73,13 @@ const BoundedTextField = (props) => {
// useInput will call the provided onChange and onBlur in addition to the default needed by react-hook-form.
onChange,
onBlur,
...props,
...rest,
});

return (
<TextField
{...field}
label={props.label}
label={label}
error={(isTouched || isSubmitted) && invalid}
helperText={(isTouched || isSubmitted) && invalid ? error : ''}
required={isRequired}
Expand All @@ -99,14 +99,6 @@ const LatLngInput = props => {
);
};
```

**Reminder:** [react-hook-form's `formState` is wrapped with a Proxy](https://react-hook-form.com/docs/useformstate/#rules) to improve render performance and skip extra computation if specific state is not subscribed. So, make sure you deconstruct or read the `formState` before render in order to enable the subscription.

```js
const { isDirty } = useFormState(); //
const formState = useFormState(); // ❌ should deconstruct the formState
```

## Usage with Material UI `<Select>`

```jsx
Expand Down Expand Up @@ -154,9 +146,22 @@ const PersonEdit = () => (
);
```

**Reminder:** [react-hook-form's `formState` is wrapped with a Proxy](https://react-hook-form.com/docs/useformstate/#rules) to improve render performance and skip extra computation if specific state is not subscribed. So, make sure you deconstruct or read the `formState` before render in order to enable the subscription.
**Tip**: Remember to use react-admin's `<InputHelperText>` component in custom inputs to properly translate and render messages and errors coming from `useInput()`.

## Important note about formState

[react-hook-form's `formState` is wrapped with a Proxy](https://react-hook-form.com/docs/useformstate/#rules) to improve render performance and skip extra computation if specific state is not subscribed. So, make sure you deconstruct or read the `formState` before render in order to enable the subscription.

```js
const { isDirty } = useFormState(); //
const formState = useFormState(); // ❌ should deconstruct the formState
```

This pattern should be followed when writing a custom input with `useInput()`.

```jsx
const { formState: { isSubmitted }} = useInput(props); //

const { formState } = useInput(props);
const submitted = formState.isSubmitted; //
```

0 comments on commit 7b8186f

Please sign in to comment.