From 7e782daec03aad6b9e26b14c7927e1b92c89e2b3 Mon Sep 17 00:00:00 2001 From: Tom Xu Date: Sat, 24 Oct 2020 14:27:49 +0800 Subject: [PATCH] feat: ConfigProvider add form requiredMark (#27322) * feat: ConfigProvider add form requiredMark * Update Form.tsx --- .../__tests__/__snapshots__/form.test.js.snap | 247 ++++++++++++++++++ .../{form-locale.test.js => form.test.js} | 18 +- components/config-provider/context.tsx | 4 + components/config-provider/index.en-US.md | 2 +- components/config-provider/index.tsx | 7 +- components/config-provider/index.zh-CN.md | 2 +- components/form/Form.tsx | 10 +- 7 files changed, 283 insertions(+), 7 deletions(-) create mode 100644 components/config-provider/__tests__/__snapshots__/form.test.js.snap rename components/config-provider/__tests__/{form-locale.test.js => form.test.js} (80%) diff --git a/components/config-provider/__tests__/__snapshots__/form.test.js.snap b/components/config-provider/__tests__/__snapshots__/form.test.js.snap new file mode 100644 index 0000000000..00de1fbc96 --- /dev/null +++ b/components/config-provider/__tests__/__snapshots__/form.test.js.snap @@ -0,0 +1,247 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`ConfigProvider.Form form requiredMark set requiredMark optional 1`] = ` + + + + + + + +
+ + + + +
+ + +
+ +
+ +
+ + +
+
+
+ + + +
+
+ + + + + +
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+`; diff --git a/components/config-provider/__tests__/form-locale.test.js b/components/config-provider/__tests__/form.test.js similarity index 80% rename from components/config-provider/__tests__/form-locale.test.js rename to components/config-provider/__tests__/form.test.js index e4e836bb61..ea146b55c1 100644 --- a/components/config-provider/__tests__/form-locale.test.js +++ b/components/config-provider/__tests__/form.test.js @@ -5,7 +5,7 @@ import ConfigProvider from '..'; import zhCN from '../../locale/zh_CN'; import Form from '../../form'; -describe('ConfigProvider.Form.Locale', () => { +describe('ConfigProvider.Form', () => { describe('form validateMessages', () => { const wrapperComponent = ({ validateMessages }) => { const formRef = React.createRef(); @@ -75,4 +75,20 @@ describe('ConfigProvider.Form.Locale', () => { expect(wrapper.find('.ant-form-item-explain').last().text()).toEqual('年龄必须等于17'); }); }); + + describe('form requiredMark', () => { + it('set requiredMark optional', async () => { + const wrapper = mount( + +
+ + + +
+
, + ); + + expect(wrapper).toMatchSnapshot(); + }); + }); }); diff --git a/components/config-provider/context.tsx b/components/config-provider/context.tsx index cd9d8c2442..70ed033440 100644 --- a/components/config-provider/context.tsx +++ b/components/config-provider/context.tsx @@ -2,6 +2,7 @@ import * as React from 'react'; import defaultRenderEmpty, { RenderEmptyHandler } from './renderEmpty'; import { Locale } from '../locale-provider'; import { SizeType } from './SizeContext'; +import { RequiredMark } from '../form/Form'; export interface CSPConfig { nonce?: string; @@ -28,6 +29,9 @@ export interface ConfigConsumerProps { }; virtual?: boolean; dropdownMatchSelectWidth?: boolean; + form?: { + requiredMark?: RequiredMark; + }; } export const ConfigContext = React.createContext({ diff --git a/components/config-provider/index.en-US.md b/components/config-provider/index.en-US.md index 2b9e150a32..018eb75abf 100644 --- a/components/config-provider/index.en-US.md +++ b/components/config-provider/index.en-US.md @@ -43,7 +43,7 @@ Some components use dynamic style to support wave effect. You can config `csp` p | csp | Set [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) config | { nonce: string } | - | | | direction | Set direction of layout. See [demo](#components-config-provider-demo-direction) | `ltr` \| `rtl` | `ltr` | | | dropdownMatchSelectWidth | Determine whether the dropdown menu and the select input are the same width. Default set `min-width` same as input. Will ignore when value less than select width. `false` will disable virtual scroll | boolean \| number | - | 4.3.0 | -| form | Set Form common props | { validateMessages?: [ValidateMessages](/components/form/#validateMessages) } | - | | +| form | Set Form common props | { validateMessages?: [ValidateMessages](/components/form/#validateMessages), requiredMark?: boolean \| `optional` } | - | requiredMark: 4.8.0 | | getPopupContainer | To set the container of the popup element. The default is to create a `div` element in `body` | function(triggerNode) | () => document.body | | | getTargetContainer | Config Affix, Anchor scroll target container | () => HTMLElement | () => window | 4.2.0 | | input | Set Input common props | { autoComplete?: string } | - | 4.2.0 | diff --git a/components/config-provider/index.tsx b/components/config-provider/index.tsx index a05444bd10..0fbc52c209 100644 --- a/components/config-provider/index.tsx +++ b/components/config-provider/index.tsx @@ -11,6 +11,7 @@ import { ConfigConsumer, ConfigContext, CSPConfig, ConfigConsumerProps } from '. import { SizeType, SizeContextProvider } from './SizeContext'; import message from '../message'; import notification from '../notification'; +import { RequiredMark } from '../form/Form'; export { RenderEmptyHandler, ConfigContext, ConfigConsumer, CSPConfig, ConfigConsumerProps }; @@ -36,6 +37,7 @@ export interface ConfigProviderProps { autoInsertSpaceInButton?: boolean; form?: { validateMessages?: ValidateMessages; + requiredMark?: RequiredMark; }; input?: { autoComplete?: string; @@ -130,8 +132,11 @@ const ConfigProvider: React.FC & { config.input = input; } - let childNode = children; + if (form) { + config.form = form; + } + let childNode = children; // Additional Form provider let validateMessages: ValidateMessages = {}; diff --git a/components/config-provider/index.zh-CN.md b/components/config-provider/index.zh-CN.md index 107acdafef..050e77b33e 100644 --- a/components/config-provider/index.zh-CN.md +++ b/components/config-provider/index.zh-CN.md @@ -44,7 +44,7 @@ export default () => ( | csp | 设置 [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) 配置 | { nonce: string } | - | | | direction | 设置文本展示方向。 [示例](#components-config-provider-demo-direction) | `ltr` \| `rtl` | `ltr` | | | dropdownMatchSelectWidth | 下拉菜单和选择器同宽。默认将设置 `min-width`,当值小于选择框宽度时会被忽略。`false` 时会关闭虚拟滚动 | boolean \| number | - | 4.3.0 | -| form | 设置 Form 组件的通用属性 | { validateMessages?: [ValidateMessages](/components/form/#validateMessages) } | - | | +| form | 设置 Form 组件的通用属性 | { validateMessages?: [ValidateMessages](/components/form/#validateMessages), requiredMark?: boolean \| `optional` } | - | requiredMark: 4.8.0 | | getPopupContainer | 弹出框(Select, Tooltip, Menu 等等)渲染父节点,默认渲染到 body 上。 | function(triggerNode) | () => document.body | | | getTargetContainer | 配置 Affix、Anchor 滚动监听容器。 | () => HTMLElement | () => window | 4.2.0 | | input | 设置 Input 组件的通用属性 | { autoComplete?: string } | - | 4.2.0 | diff --git a/components/form/Form.tsx b/components/form/Form.tsx index 4370e7c4e1..e76cb187d1 100644 --- a/components/form/Form.tsx +++ b/components/form/Form.tsx @@ -5,7 +5,7 @@ import FieldForm, { List } from 'rc-field-form'; import { FormProps as RcFormProps } from 'rc-field-form/lib/Form'; import { ValidateErrorEntity } from 'rc-field-form/lib/interface'; import { ColProps } from '../grid/col'; -import { ConfigContext, ConfigConsumerProps } from '../config-provider'; +import { ConfigContext } from '../config-provider'; import { FormContext, FormContextProps } from './context'; import { FormLabelAlign } from './interface'; import useForm, { FormInstance } from './hooks/useForm'; @@ -32,7 +32,7 @@ export interface FormProps extends Omit, 'form const InternalForm: React.ForwardRefRenderFunction = (props, ref) => { const contextSize = React.useContext(SizeContext); - const { getPrefixCls, direction }: ConfigConsumerProps = React.useContext(ConfigContext); + const { getPrefixCls, direction, form: contextForm } = React.useContext(ConfigContext); const { name } = props; @@ -58,12 +58,16 @@ const InternalForm: React.ForwardRefRenderFunction = (props, return requiredMark; } + if (contextForm && contextForm.requiredMark !== undefined) { + return contextForm.requiredMark; + } + if (hideRequiredMark) { return false; } return true; - }, [hideRequiredMark, requiredMark]); + }, [hideRequiredMark, requiredMark, contextForm]); const prefixCls = getPrefixCls('form', customizePrefixCls);