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> = { ...@@ -25,7 +25,7 @@ const defaultUser: Partial<UserDTO> = {
<Forms.Form <Forms.Form
defaultValues={defaultUser} defaultValues={defaultUser}
onSubmit={async (user: UserDTO) => await createrUser(user)} onSubmit={async (user: UserDTO) => await createUser(user)}
>{({register, errors}) => { >{({register, errors}) => {
return ( return (
<Forms.Field> <Forms.Field>
...@@ -64,17 +64,19 @@ Register accepts an object which describes validation rules for a given input: ...@@ -64,17 +64,19 @@ Register accepts an object which describes validation rules for a given input:
#### `errors` #### `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 ```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.Input name="name" ref={register({ required: true })} />
</Forms.Field> </Forms.Field>
``` ```
#### `control` #### `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 ```jsx
import { Forms } from '@grafana/ui'; import { Forms } from '@grafana/ui';
...@@ -107,10 +109,40 @@ import { Forms } from '@grafana/ui'; ...@@ -107,10 +109,40 @@ import { Forms } from '@grafana/ui';
)} )}
</Forms.Form> </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
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 ```jsx
// Passing default values to the Form // Passing default values to the Form
......
...@@ -98,7 +98,7 @@ const renderForm = (defaultValues?: Partial<FormDTO>) => ( ...@@ -98,7 +98,7 @@ const renderForm = (defaultValues?: Partial<FormDTO>) => (
<Forms.InputControl name="radio" control={control} options={selectOptions} as={RadioButtonGroup} /> <Forms.InputControl name="radio" control={control} options={selectOptions} as={RadioButtonGroup} />
</Field> </Field>
<Field label="Select" invalid={!!errors.select}> <Field label="Select" invalid={!!errors.select} error="Select is required">
<Forms.InputControl <Forms.InputControl
name="select" name="select"
control={control} control={control}
......
...@@ -10,9 +10,9 @@ interface FormProps<T> { ...@@ -10,9 +10,9 @@ interface FormProps<T> {
children: (api: FormAPI<T>) => React.ReactNode; 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>({ const { handleSubmit, register, errors, control, reset, getValues } = useForm<T>({
mode: validateOn || 'onSubmit', mode: validateOn,
defaultValues, 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