From b3a76c14ca77a7b06ae08a2f632be61089b24e0f Mon Sep 17 00:00:00 2001 From: zombieJ Date: Thu, 4 Jul 2019 15:00:11 +0800 Subject: [PATCH] feat: Form support `scrollToField` (#17457) * support scroll & label htmlFor * update snapshot * add test case * doc update * add decleare * adjust logic of label id * clean ts error --- components/form/Form.tsx | 14 ++++- components/form/FormItem.tsx | 13 ++-- components/form/FormItemLabel.tsx | 2 +- .../__tests__/__snapshots__/demo.test.js.snap | 44 ++++++++++++++ components/form/__tests__/index.test.js | 58 ++++++++++++++++++ components/form/demo/register.md | 8 +++ components/form/index.en-US.md | 1 + components/form/index.zh-CN.md | 1 + components/form/util.ts | 60 +++++++++++++++++++ components/form/v3.en-US.md | 22 +++++++ components/form/v3.zh-CN.md | 22 +++++++ .../__tests__/__snapshots__/demo.test.js.snap | 1 + .../__tests__/__snapshots__/demo.test.js.snap | 1 + package.json | 1 + typings/custom-typings.d.ts | 2 + 15 files changed, 242 insertions(+), 8 deletions(-) diff --git a/components/form/Form.tsx b/components/form/Form.tsx index 6aa0d0556144..a014577dad69 100644 --- a/components/form/Form.tsx +++ b/components/form/Form.tsx @@ -1,16 +1,17 @@ import * as React from 'react'; import omit from 'omit.js'; import classNames from 'classnames'; -import FieldForm, { FormInstance, useForm, List } from 'rc-field-form'; +import FieldForm, { List } from 'rc-field-form'; import { FormProps as RcFormProps } from 'rc-field-form/lib/Form'; import { ColProps } from '../grid/col'; import { ConfigContext, ConfigConsumerProps } from '../config-provider'; import { FormContext } from './context'; import { FormLabelAlign } from './interface'; +import { useForm, FormInstance } from './util'; export type FormLayout = 'horizontal' | 'inline' | 'vertical'; -interface FormProps extends RcFormProps { +interface FormProps extends Omit { prefixCls?: string; hideRequiredMark?: boolean; colon?: boolean; @@ -19,12 +20,14 @@ interface FormProps extends RcFormProps { labelAlign?: FormLabelAlign; labelCol?: ColProps; wrapperCol?: ColProps; + form?: FormInstance; } const InternalForm: React.FC = (props, ref) => { const { getPrefixCls }: ConfigConsumerProps = React.useContext(ConfigContext); const { + form, colon, name, labelAlign, @@ -57,6 +60,11 @@ const InternalForm: React.FC = (props, ref) => { 'colon', ]); + const [wrapForm] = useForm(form); + wrapForm.__INTERNAL__.name = name; + + React.useImperativeHandle(ref, () => wrapForm); + return ( = (props, ref) => { colon, }} > - + ); }; diff --git a/components/form/FormItem.tsx b/components/form/FormItem.tsx index 9c810b95bb60..91e6214ae512 100644 --- a/components/form/FormItem.tsx +++ b/components/form/FormItem.tsx @@ -10,7 +10,7 @@ import warning from '../_util/warning'; import FormItemLabel, { FormItemLabelProps } from './FormItemLabel'; import FormItemInput, { FormItemInputProps } from './FormItemInput'; import { FormContext, FormItemContext } from './context'; -import { toArray } from './util'; +import { toArray, getFieldId } from './util'; const ValidateStatuses = tuple('success', 'warning', 'error', 'validating', ''); export type ValidateStatus = (typeof ValidateStatuses)[number]; @@ -154,10 +154,10 @@ const FormItem: React.FC = (props: FormItemProps) => { : !!(rules && rules.some(rule => typeof rule === 'object' && rule.required)); // ======================= Children ======================= - const mergedId = mergedName.join('_'); + const fieldId = getFieldId(mergedName, formName); const mergedControl: typeof control = { ...control, - id: formName ? `${formName}_${mergedId}` : mergedId, + id: fieldId, }; let childNode; @@ -195,7 +195,12 @@ const FormItem: React.FC = (props: FormItemProps) => { return ( {/* Label */} - + {/* Input Group */}