Commit 385be776 by Alex Khomenko Committed by GitHub

Storybook: Forms.Form docs (#22654)

* Add Select error message

* Update Form docs

* Tweak examples

* Fix docs
parent cc813d71
......@@ -25,7 +25,7 @@ const defaultUser: Partial<UserDTO> = {
<Forms.Form
defaultValues={defaultUser}
onSubmit={async (user: UserDTO) => await createrUser(user)}
onSubmit={async (user: UserDTO) => await createUser(user)}
>{({register, errors}) => {
return (
<Forms.Field>
......@@ -64,17 +64,19 @@ Register accepts an object which describes validation rules for a given input:
#### `errors`
`errors` in an object that contains validation errors of the form. To show error message and invalid input indication in your form, wrap input element with `<Forms.Field ...>` component and pass `invalid` and `error` props to it:
`errors` is an object that contains validation errors of the form. To show error message and invalid input indication in your form, wrap input element with `<Forms.Field ...>` component and pass `invalid` and `error` props to it:
```jsx
<Forms.Field label="Name" invalid={!!errors.name} error={!!errors.name && 'Name is required'}>
<Forms.Field label="Name" invalid={!!errors.name} error='Name is required'>
<Forms.Input name="name" ref={register({ required: true })} />
</Forms.Field>
```
#### `control`
By default `Form` component assumes form elements are uncontrolled (https://reactjs.org/docs/glossary.html#controlled-vs-uncontrolled-components). There are some components like `RadioButton` or `Select` that are controlled-only and require some extra work. To make them work with the form, you need to render those using `Forms.InputControl` component:
By default `Form` component assumes form elements are uncontrolled (https://reactjs.org/docs/glossary.html#controlled-vs-uncontrolled-components).
There are some components like `RadioButton` or `Select` that are controlled-only and require some extra work. To make
them work with the form, you need to render those using `Forms.InputControl` component:
```jsx
import { Forms } from '@grafana/ui';
......@@ -107,10 +109,40 @@ import { Forms } from '@grafana/ui';
)}
</Forms.Form>
```
Note that when using `Forms.InputControl`, it expects the name of the prop that handles input change to be called `onChange`.
If the property is named differently for any specific component, additional `onChangeName` prop has to be provided, specifying the name.
Additionally, the `onChange` arguments passed as an array. Check [react-hook-form docs](https://react-hook-form.com/api/#Controller)
for more prop options.
```jsx
{/* DashboardPicker has onSelected prop instead of onChange */}
import { DashboardPicker } from 'app/core/components/Select/DashboardPicker';
{/* In case of Select the value has to be returned as an object with a `value` key for the value to be saved to form data */}
const onSelectChange = ([value]) => {
// ...
return { value };
}
<Field label="SelectExample">
<Forms.InputControl
as={DashboardPicker}
control={control}
name="select"
onSelected={onSelectChange}
{/* Pass the name of the onChange handler */}
onChangeName='onSelected'
/>
</Field>
```
### Default values
Default values of the form can be passed either via `defaultValues` property on the `Form` element, or directly on form's input via `defaultValue` prop:
Default values of the form can be passed either via `defaultValues` property on the `Form` element, or directly on
form's input via `defaultValue` prop.
Note that changing/updating `defaultValues` passed to the form will reset the form's state, which might be undesirable in
case it has both controlled and uncontrolled components. In that case it's better to pass `defaultValue` to each form component separately.
```jsx
// Passing default values to the Form
......
......@@ -98,7 +98,7 @@ const renderForm = (defaultValues?: Partial<FormDTO>) => (
<Forms.InputControl name="radio" control={control} options={selectOptions} as={RadioButtonGroup} />
</Field>
<Field label="Select" invalid={!!errors.select}>
<Field label="Select" invalid={!!errors.select} error="Select is required">
<Forms.InputControl
name="select"
control={control}
......
......@@ -10,9 +10,9 @@ interface FormProps<T> {
children: (api: FormAPI<T>) => React.ReactNode;
}
export function Form<T>({ validateOn, defaultValues, onSubmit, children }: FormProps<T>) {
export function Form<T>({ defaultValues, onSubmit, children, validateOn = 'onSubmit' }: FormProps<T>) {
const { handleSubmit, register, errors, control, reset, getValues } = useForm<T>({
mode: validateOn || 'onSubmit',
mode: validateOn,
defaultValues,
});
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment