Browse Source

feat: field support setting props.name to origin component (#1266)

* feat: field support setting props.name to origin component
* docs: update fieldProps name description
pointhalo 2 years ago
parent
commit
4b6e48ab6e

+ 3 - 3
content/input/form/index-en-US.md

@@ -1726,18 +1726,18 @@ import { Form, Button } from '@douyinfe/semi-ui';
 | labelAlign            | Text-align of the label text of this field                                                                                                                                                                                               | string                                 |           |
 | labelWidth            | The width of the label text of this field                                                                                                                                                                                                | string\|number                         |           |
 | noLabel               | When you don't need to add label automatically, you can set this value to true                                                                                                                                                           | boolean                                |           |
-| name                  | Field name. When passed in, the corresponding className will be automatically added to the corresponding field div, such as: money => '.semi-form-field-money'                                                                           | string                                 |           |
+| name                  | Field name. When passed in, the corresponding className will be automatically added to the field wrapper div, such as: money => '.semi-form-field-money'. After v2.24, the name will also be transparently transmitted to the underlying component for consumption. For example, you can configure the name attribute of input                                                                           | string                                 |           |
 | fieldClassName        | The className of the entire fieldWrapper is the same as the name parameter, except that the prefix is ​​not automatically appended                                                                                                       | string                                 |           |
 | fieldStyle            | The inline style of the entire fieldWrapper <br/>**since v1.9.0**                                                                                                      | object                                 |           |
 | initValue             | The initial value of the field (consumed only once when Field mounted, subsequent updates are invalid), it has higher priority than the values ​​in Form's initValues ​​                                                                 | any(type depends on current component) |           |
 | validate              | The custom validation function for this form control. Supports synchronous and asynchronous verification. <br/> Rules does not take effect when validate is set                                                                           | function(fieldValue, values)           |           | (fieldValue) => fieldValue.length>5? 'error balabala': ''          |
 | rules                 | validation rules, validation library based on [async-validator](https://github.com/yiminghe/async-validator)                                                                                                                             | array                                  |           | const rules = \[{type:' string ', message:' invalidate string'} \] |
 | validateStatus        | The validation result status of this form control, optional: `success` / `error` / `warning` / `default`                                                                                                                                 | string                                 | 'default' |
-| trigger               | The timing of triggering the verification, optional: `blur` / `change` / `custom` / `mount` <br/> 1. When set to custom, only formApi will trigger the verification <br/> 2mount (triggered once when mounting)                          | string                                 | 'change'  |
+| trigger               | The timing of triggering the verification, optional: `blur` / `change` / `custom` / `mount` <br/> 1. When set to custom, only formApi will trigger the verification <br/> 2.mount (triggered once when mounting)                          | string                                 | 'change'  |
 | onChange              | Callback invoked when this field value changes                                                                                                                                                                                           |
 | transform             | transform field values before validation                                                                                                                                                                                                 | function(fieldValue)                   |           | (value) => Number(value)                                           |
 | allowEmptyString      | Whether to allow values to be empty strings. <br/>When the value is '' by default, the key corresponding to this field will be removed from `values`. <br/>If you want to keep the key, you need to set allowEmptyString to true           | boolean                                |           | false                                                              |
-| convert               | After the field value changes, before rerender, update the value of filed                                                                                                                                                                | function(fieldValue)                   |           | (value) => newValue(value)                                         |
+| convert               | After the field value changes, before rerender, update the value of filed                                                                                                                                                                | function(fieldValue)                   |           | (value) => newValue                                        |
 | stopValidateWithError | When it is true, the rules check is used. After encountering the first rule that fails the check, it will no longer trigger the check of subsequent rules<br/>**since v0.35.0**                                                          | boolean                                |           | false                                                              |
 | helpText              | Custom prompt information, which is displayed in the same block as the verification information. When both have values, the verification information is displayed first<br/>**since v1.0.0**                                             | ReactNode                              |           |                                                                    |
 | extraText             | Additional prompt information, you can use this when both error information and prompt copy are required, after helpText/errorMessage<br/>**since v1.0.0**                                                                               | ReactNode                              |           |                                                                    |

+ 1 - 1
content/input/form/index.md

@@ -2048,7 +2048,7 @@ import { Form, Button } from '@douyinfe/semi-ui';
 | labelWidth            | 该表单控件的 label 文本的 width。在Form与Field上同时传入时,以Field props为准                                                                                                                         | string\|number                                                                                |
 | noLabel               | 当你不需要自动添加 label 时,可以将该值置为 true                                                                                                                                                                    | boolean                                                                                       |
 | noErrorMessage        | 当你不需要自动添加 ErrorMessage 模块时,可以将该值置为 true,注意此时 helpText 也不会被展示                                                                                                                         | boolean                                                                                       |
-| name                  | 控件名称,传入时会自动在对应 field 的 div 中追加对应的 className,如:abc => '.semi-form-field-abc'                                                                                                             | string                                                                                        |
+| name                  | 控件名称,传入时会自动在对应 field wrapper div 追加对应的 className,如:abc => '.semi-form-field-abc' v2.24 后,还会将 name 透传至底层组件消费,例如你可以用于配置 input的name属性                                                                                                            | string                                                                                        |
 | fieldClassName        | 整个 fieldWrapper 的 className,作用与 name 参数一致,区别是不会自动追加前缀                                                                                                                                        | string                                                                                        |
 | fieldStyle            | 整个 fieldWrapper 的 内联样式<br/> **v1.15.0开始提供**                                                                                                                                        | object                                                                                        |
 | initValue             | 该表单控件的初始值(仅在 Field mounted 时消费一次,后续更新无效),相比 Form 的 initValues 中的值,它的优先级更高                                                                                                   | any(类型取决于当前组件,详细见各组件的 api)                                                 |

+ 159 - 0
packages/semi-ui/form/_story/FieldProps/name.jsx

@@ -0,0 +1,159 @@
+/* eslint-disable no-unused-vars */
+import React, { useState, useLayoutEffect, useEffect, useRef } from 'react';
+import { storiesOf } from '@storybook/react';
+import { Button, Modal, TreeSelect, Row, Col, Avatar, Tabs, TabPane, Badge } from '@douyinfe/semi-ui';
+import {
+    Form,
+    useFormState,
+    useFormApi,
+    useFieldApi,
+    useFieldState,
+    withFormState,
+    withFormApi,
+    withField,
+    ArrayField
+} from '../../index';
+
+import {
+    UseFormApiDemo,
+    UseFormStateDemo,
+    UseFieldApiDemo,
+    UseFieldStateDemo,
+    WithFormStateDemo,
+    WithFormApiDemo,
+    ComponentUsingFormState,
+    CustomStringify
+} from '../Hook/hookDemo';
+const { Input, Select, DatePicker, Switch, Slider, CheckboxGroup, Checkbox, RadioGroup, Radio, TimePicker } = Form;
+
+const NameDemo = () => {
+    const style = { width: '90%' };
+    const helpText = <span style={{ color: 'var(--semi-color-warning)' }}>密码强度:弱</span>;
+    return (
+        <Form extraTextPosition="middle">
+            <Form.Input
+                field="b"
+                name='test'
+            />
+            <Form.Input
+                field='name'
+                label="名称"
+                name='name'
+                // initValue={'mikeya'}
+                style={style}
+                trigger='blur'
+                rules={[
+                    { required: true, message: 'required error' },
+                    { type: 'string', message: 'type error' },
+                    { validator: (rule, value) => value === 'muji', message: 'not muji' }
+                ]}
+            />
+            <Form.DatePicker field="date" name='date' label='日期' style={style} placeholder='请选择生效日期' />
+            <Form.Select field="role" name='role' style={style} label='角色' placeholder='请选择你的角色'>
+                <Form.Select.Option value="operate">运营</Form.Select.Option>
+                <Form.Select.Option value="rd">开发</Form.Select.Option>
+                <Form.Select.Option value="pm">产品</Form.Select.Option>
+                <Form.Select.Option value="ued">设计</Form.Select.Option>
+            </Form.Select>
+            <Form.Select
+                field="business"
+                name='business'
+                multiple
+                style={style}
+                placeholder='请选择业务线'
+                label="业务线(多选)"
+            >
+                <Form.Select.Option value="dy">抖音</Form.Select.Option>
+                <Form.Select.Option value="hootsoon">火山小视频</Form.Select.Option>
+                <Form.Select.Option value="toutiao">今日头条</Form.Select.Option>
+            </Form.Select>
+            <Form.Cascader
+                placeholder="请选择所在地区"
+                field='area'
+                name='area'
+                label='地区(级联选择)'
+            >
+            </Form.Cascader>    
+            <Form.TreeSelect
+                field="tree"
+                name='tree'
+                style={style}
+                label='节点(树选择)'
+                placeholder='请选择服务节点'
+                filterTreeNode
+            >
+            </Form.TreeSelect>
+            <Form.TimePicker
+                field='time'
+                name='time'
+                helpText='原则上应当在 9:00 - 18:00 之间'
+                label='时间选择'
+            >
+            </Form.TimePicker>
+            <Form.AutoComplete
+                field='typeData'
+                label='类型选择'
+                name='typeData'
+                data={['1', '2', '3']}
+            >
+            </Form.AutoComplete>
+            <Form.TagInput
+                field='tags'
+                label='tags'
+                name='tags'
+            />
+            <Form.TextArea
+                style={style}
+                field='description'
+                name='description'
+                label='申请理由'
+                placeholder='请填写申请资源理由'
+            />
+            <Form.CheckboxGroup
+                field="type"
+                name='anotherType'
+                label='申请类型'
+                initValue={['user', 'admin']}
+                rules={[
+                    { required: true }
+                ]}
+            >
+                <Form.Checkbox value="admin">管理员admin</Form.Checkbox>
+                <Form.Checkbox value="user">用户user</Form.Checkbox>
+                <Form.Checkbox value="guest">访客guest</Form.Checkbox>
+                <Form.Checkbox value="root">根用户root</Form.Checkbox>
+            </Form.CheckboxGroup>
+            <Form.RadioGroup
+                name='anotherSource'
+                field="isMonopolize" label='是否独占资源' rules={[
+                    { type: 'boolean' },
+                    { required: true, message: '必须选择是否独占 ' }
+                ]}>
+                <Form.Radio value={true}>是</Form.Radio>
+                <Form.Radio value={false}>否</Form.Radio>
+            </Form.RadioGroup>
+            <Form.InputNumber field='number' name='number' label='申请数量' initValue={20} style={style}/>
+            <Form.Slider field="range" name='range' label='资源使用报警阈值(%)' initValue={10} style={{ width: '90%' }}/>
+            <Form.Rating field="rating" name='rating' label='满意度(Rating)' initValue={2} style={{ width: '90%' }}/>
+            <Form.Switch field='switch' name='switch' label='开关(Switch)'/>
+            <Form.CheckboxGroup field="cardCheckbox" label='卡片选择' style={{ width: '90%' }} type='card' initValue={['1', '3']} direction={'horizontal'} aria-label="CheckboxGroup 示例">
+                <Form.Checkbox value={'1'} disabled extra='Semi Design 是由互娱社区前端团队与 UED 团队共同设计开发并维护的设计系统' style={{ width: 280 }}>
+                    单选框标题
+                </Form.Checkbox>
+                <Form.Checkbox value={'2'} disabled extra='Semi Design 是由互娱社区前端团队与 UED 团队共同设计开发并维护的设计系统' style={{ width: 280 }}>
+                    单选框标题
+                </Form.Checkbox>
+            </Form.CheckboxGroup>
+            <Form.RadioGroup field='buttonRadio' type='button' buttonSize='middle' defaultValue={1} aria-label="单选组合示例">
+                <Radio value={1}>即时推送</Radio>
+                <Radio value={2}>定时推送</Radio>
+                <Radio value={3}>动态推送</Radio>
+            </Form.RadioGroup>
+            <Form.Checkbox value="false" field="agree" name='agree' useOutSideGroup={true} noLabel={true}>
+                我已阅读并清楚相关规定
+            </Form.Checkbox>
+        </Form>
+    );
+};
+
+export { NameDemo };

+ 7 - 0
packages/semi-ui/form/_story/form.stories.jsx

@@ -66,6 +66,7 @@ import {
 
 // field props
 import { ConvertDemo } from './FieldProps/convert';
+import { NameDemo } from './FieldProps/name';
 import { HelpAndExtra, ExtraPositionDemo } from './FieldProps/helpAndExtra';
 import { BigNumberFieldDemo } from './FieldProps/bigNumberFieldPath';
 import { UpdateDemo, RuleupdateDemo } from './FieldProps/rulesUpdateDemo';
@@ -323,6 +324,12 @@ FiledPropConvert.story = {
   name: 'Filed Prop-convert',
 };
 
+export const FieldPropsName = () => <NameDemo />;
+
+FieldPropsName.story = {
+  name: 'Filed Prop-name',
+};
+
 export const FiledPropHelpTextExtraTextExtraTextPosition = () => (
   <>
     <HelpAndExtra />

+ 4 - 0
packages/semi-ui/form/hoc/withField.tsx

@@ -459,6 +459,10 @@ function withField<
                 'aria-labelledby': labelId,
             };
 
+            if (name) {
+                newProps['name'] = name;
+            }
+
             if (helpText) {
                 newProps['aria-describedby'] = extraText ? `${helpTextId} ${extraTextId}` : helpTextId;
             }