123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197 |
- /* eslint-disable prefer-destructuring */
- /* eslint-disable prefer-const */
- /* eslint-disable @typescript-eslint/no-unused-vars */
- import AsyncValidator from 'async-validator';
- import { cloneDeep, toPath } from 'lodash';
- import { FieldValidateTriggerType, BasicTriggerType, ComponentProps, WithFieldOption } from './interface';
- /**
- *
- * @param WrappedComponent React.ComponentType | any
- */
- export function getDisplayName(WrappedComponent: any) {
- const originName = WrappedComponent.displayName || WrappedComponent.name;
- return originName ? `SemiField${originName}` : 'SemiField';
- }
- export function generateValidatesFromRules(field: string, rules: any[] = []) {
- const descriptor = {};
- descriptor[field] = rules;
- const validator = new AsyncValidator(descriptor);
- return validator;
- }
- export function isRequired(rules: any[] | Record<string, any> = []): boolean {
- let required = false;
- if (typeof rules === 'object' && 'required' in rules) {
- required = rules.required;
- } else if (Array.isArray(rules) && rules.length) {
- rules.forEach(rule => {
- rule.required ? (required = true) : null;
- });
- }
- return required;
- }
- export function isValid(errors: any): boolean {
- let valid = true;
- if (typeof errors === 'string' && errors.length) {
- valid = false;
- } else if (Array.isArray(errors) && errors.length) {
- valid = errors.every(error => isValid(error));
- } else if (typeof errors === 'boolean') {
- valid = errors;
- } else if (
- errors &&
- typeof errors.$$typeof === 'symbol' &&
- errors.$$typeof.toString() === 'Symbol(react.element)'
- ) {
- // when error message is reactNode
- valid = false;
- }
- return valid;
- }
- // Compatible with String and Array
- function transformTrigger(trigger: FieldValidateTriggerType): Array<BasicTriggerType> {
- let result: BasicTriggerType[] = [];
- if (Array.isArray(trigger)) {
- result = trigger;
- }
- if (typeof trigger === 'string') {
- result[0] = trigger;
- }
- return result;
- }
- export function mergeOptions(opts: WithFieldOption, props: ComponentProps) {
- // Opts: different types of component identification value, value change callback function may be inconsistent, used to adapt 1, input, select 2, radio, checkbox 3, switch
- // valueKey: input, select class component control value props are value, and checkbox, switch is checked
- // eg:checkbox、radio { valueKey: 'checked', onKeyChangeFnName: 'onChange', valuePath: 'target.value' }
- const defaultOpts = {
- valueKey: 'value',
- onKeyChangeFnName: 'onChange',
- valuePath: '',
- maintainCursor: false,
- shouldInject: true,
- shouldMemo: true,
- };
- const options = { ...defaultOpts, ...opts };
- // If the field attribute is declared, then the injection is carried out (mainly used to deal with the case where Checkbox and Radio are used separately from the Group); other cases are subject to options
- const shouldInject = 'field' in props ? true : options.shouldInject;
- return { options, shouldInject };
- }
- export function mergeProps(props: any) {
- const defaultProps = {
- trigger: 'change',
- // validateStatus: 'default',
- allowEmptyString: false,
- allowEmpty: false,
- emptyValue: '',
- noLabel: false,
- noErrorMessage: false,
- isInInputGroup: false,
- stopValidateWithError: false,
- };
- let {
- field,
- label,
- labelPosition,
- labelWidth,
- labelAlign,
- labelCol,
- wrapperCol,
- initValue,
- validate,
- /**
- * error、warning、default、success
- */
- validateStatus,
- /**
- * change、blur、custom、mount
- */
- trigger,
- allowEmptyString,
- allowEmpty,
- emptyValue,
- rules,
- onChange,
- keepState,
- // Conversion before validation
- transform,
- name,
- fieldClassName,
- fieldStyle,
- noLabel,
- noErrorMessage,
- isInInputGroup,
- stopValidateWithError,
- convert,
- showValidateIcon,
- helpText,
- extraText,
- extraTextPosition,
- pure,
- id,
- ...rest
- }: any = { ...defaultProps, ...props };
- // Form中的任何类型组件,初始值都统一通过initValue字段来传入,同时将可能会导致组件行为错误的props抽取出来,防止透传到组件中
- // For any type of field component in Form, the initial value is uniformly passed in through the initValue field.
- // At the same time, the props that may cause component behavior errors are extracted to prevent transparent transmission to the component.
- delete rest.defaultChecked;
- delete rest.defaultValue;
- delete rest.checked;
- if (typeof initValue !== 'undefined') {
- initValue = cloneDeep(initValue);
- }
- const required = isRequired(rules);
- trigger = transformTrigger(trigger);
- emptyValue = typeof emptyValue !== 'undefined' ? emptyValue : '';
- return {
- field,
- label,
- labelPosition,
- labelWidth,
- labelAlign,
- labelCol,
- wrapperCol,
- noLabel,
- noErrorMessage,
- isInInputGroup,
- initValue,
- validate,
- validateStatus,
- trigger,
- allowEmptyString,
- allowEmpty,
- emptyValue,
- rules,
- required,
- keepState,
- transform,
- name,
- fieldClassName,
- fieldStyle,
- convert,
- stopValidateWithError,
- showValidateIcon,
- helpText,
- extraText,
- extraTextPosition,
- pure,
- rest,
- id
- };
- }
- function bothEmptyArray(val: any, otherVal: any) {
- return Array.isArray(val) && Array.isArray(otherVal) && !val.length && !otherVal.length;
- }
|