From 385be776873ce20b8a1d7f60aae1c351d77d5645 Mon Sep 17 00:00:00 2001 From: Alex Khomenko Date: Tue, 10 Mar 2020 10:23:35 +0200 Subject: [PATCH] Storybook: Forms.Form docs (#22654) * Add Select error message * Update Form docs * Tweak examples * Fix docs --- .../grafana-ui/src/components/Forms/Form.mdx | 42 ++++++++++++++++--- .../src/components/Forms/Form.story.tsx | 2 +- .../grafana-ui/src/components/Forms/Form.tsx | 4 +- 3 files changed, 40 insertions(+), 8 deletions(-) diff --git a/packages/grafana-ui/src/components/Forms/Form.mdx b/packages/grafana-ui/src/components/Forms/Form.mdx index b49fe4fd0e8..1ef5f9e2595 100644 --- a/packages/grafana-ui/src/components/Forms/Form.mdx +++ b/packages/grafana-ui/src/components/Forms/Form.mdx @@ -25,7 +25,7 @@ const defaultUser: Partial = { await createrUser(user)} + onSubmit={async (user: UserDTO) => await createUser(user)} >{({register, errors}) => { return ( @@ -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 `` 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 `` component and pass `invalid` and `error` props to it: ```jsx - + ``` #### `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'; @@ -106,11 +108,41 @@ import { Forms } from '@grafana/ui'; )} +``` +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 }; +} + + + + + ``` ### 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 diff --git a/packages/grafana-ui/src/components/Forms/Form.story.tsx b/packages/grafana-ui/src/components/Forms/Form.story.tsx index b014d407f63..889488d1928 100644 --- a/packages/grafana-ui/src/components/Forms/Form.story.tsx +++ b/packages/grafana-ui/src/components/Forms/Form.story.tsx @@ -98,7 +98,7 @@ const renderForm = (defaultValues?: Partial) => ( - + { children: (api: FormAPI) => React.ReactNode; } -export function Form({ validateOn, defaultValues, onSubmit, children }: FormProps) { +export function Form({ defaultValues, onSubmit, children, validateOn = 'onSubmit' }: FormProps) { const { handleSubmit, register, errors, control, reset, getValues } = useForm({ - mode: validateOn || 'onSubmit', + mode: validateOn, defaultValues, });