import React, { useContext } from 'react'; import { Avatar } from 'antd'; import type { ProFieldValueType, ProFieldValueObjectType, BaseProFieldFC, ProRenderFieldPropsType, ProFieldFCRenderProps, ProFieldTextType, ProFieldRequestData, } from '@ant-design/pro-utils'; import { pickProProps, omitUndefined } from '@ant-design/pro-utils'; import ConfigContext, { useIntl } from '@ant-design/pro-provider'; import FieldPercent from './components/Percent'; import FieldIndexColumn from './components/IndexColumn'; import FieldProgress from './components/Progress'; import FieldMoney from './components/Money'; import FieldDatePicker from './components/DatePicker'; import FieldFromNow from './components/FromNow'; import FieldRangePicker from './components/RangePicker'; import FieldCode from './components/Code'; import FieldTimePicker, { FieldTimeRangePicker } from './components/TimePicker'; import FieldText from './components/Text'; import FieldTextArea from './components/TextArea'; import FieldPassword from './components/Password'; import FieldStatus from './components/Status'; import FieldOptions from './components/Options'; import FieldSelect, { proFieldParsingText, proFieldParsingValueEnumToArray, } from './components/Select'; import FieldCheckbox from './components/Checkbox'; import FieldRate from './components/Rate'; import FieldSwitch from './components/Switch'; import FieldDigit from './components/Digit'; import FieldSecond from './components/Second'; import FieldRadio from './components/Radio'; import FieldImage from './components/Image'; import FieldColorPicker from './components/ColorPicker'; export type ProFieldEmptyText = string | false; /** 默认的 Field 需要实现的功能 */ export type ProFieldFC = React.ForwardRefRenderFunction< any, BaseProFieldFC & ProRenderFieldPropsType & T >; /** Value type by function */ export type ProFieldValueTypeFunction = (item: T) => ProFieldValueType | ProFieldValueObjectType; type RenderProps = Omit & ProRenderFieldPropsType & { /** 从服务器读取选项 */ request?: ProFieldRequestData; emptyText?: React.ReactNode; visible?: boolean; onVisible?: (visible: boolean) => void; [key: string]: any; }; /** * Render valueType object * * @param text String | number * @param valueType ProColumnsValueObjectType */ const defaultRenderTextByObject = ( text: ProFieldTextType, valueType: ProFieldValueObjectType, props: RenderProps, ) => { const pickFormItemProps = pickProProps(props.fieldProps); if (valueType.type === 'progress') { return ( ); } if (valueType.type === 'money') { return ( ); } if (valueType.type === 'percent') { return ( ); } if (valueType.type === 'image') { return ; } return text; }; /** * 根据不同的类型来转化数值 * * @param text * @param valueType */ const defaultRenderText = ( text: ProFieldTextType, valueType: ProFieldValueType | ProFieldValueObjectType, props: RenderProps, valueTypeMap: Record, ): React.ReactNode => { const { mode = 'read', emptyText = '-' } = props; if (emptyText !== false && mode === 'read' && valueType !== 'option' && valueType !== 'switch') { if (typeof text !== 'boolean' && typeof text !== 'number' && !text) { const { fieldProps, render } = props; if (render) { return render(text, { mode, ...fieldProps }, <>{emptyText}); } return <>{emptyText}; } } // eslint-disable-next-line no-param-reassign delete props.emptyText; if (typeof valueType === 'object') { return defaultRenderTextByObject(text, valueType, props); } const customValueTypeConfig = valueTypeMap && valueTypeMap[valueType as string]; if (customValueTypeConfig) { // eslint-disable-next-line no-param-reassign delete props.ref; if (mode === 'read') { return customValueTypeConfig.render?.( text, { text, ...props, mode: mode || 'read', }, <>{text}, ); } if (mode === 'update' || mode === 'edit') { return customValueTypeConfig.renderFormItem?.( text, { text, ...props, }, <>{text}, ); } } /** 如果是金额的值 */ if (valueType === 'money') { return ; } /** 如果是日期的值 */ if (valueType === 'date') { return ; } /** 如果是周的值 */ if (valueType === 'dateWeek') { return ; } /** 如果是月的值 */ if (valueType === 'dateMonth') { return ; } /** 如果是季度的值 */ if (valueType === 'dateQuarter') { return ; } /** 如果是年的值 */ if (valueType === 'dateYear') { return ; } /** 如果是日期范围的值 */ if (valueType === 'dateRange') { return ; } /** 如果是日期加时间类型的值 */ if (valueType === 'dateTime') { return ( ); } /** 如果是日期加时间类型的值的值 */ if (valueType === 'dateTimeRange') { // 值不存在的时候显示 "-" return ( ); } /** 如果是时间类型的值 */ if (valueType === 'time') { return ; } /** 如果是时间类型的值 */ if (valueType === 'timeRange') { return ; } if (valueType === 'fromNow') { return ; } if (valueType === 'index') { return {(text as number) + 1}; } if (valueType === 'indexBorder') { return {(text as number) + 1}; } if (valueType === 'progress') { return ; } /** 百分比, 默认展示符号, 不展示小数位 */ if (valueType === 'percent') { return ; } if (valueType === 'avatar' && typeof text === 'string' && props.mode === 'read') { return ; } if (valueType === 'code') { return ; } if (valueType === 'jsonCode') { return ; } if (valueType === 'textarea') { return ; } if (valueType === 'digit') { return ; } if (valueType === 'second') { return ; } if (valueType === 'select' || (valueType === 'text' && (props.valueEnum || props.request))) { return ; } if (valueType === 'checkbox') { return ; } if (valueType === 'radio') { return ; } if (valueType === 'radioButton') { return ; } if (valueType === 'rate') { return ; } if (valueType === 'switch') { return ; } if (valueType === 'option') { return ; } if (valueType === 'password') { return ; } if (valueType === 'image') { return ; } if (valueType === 'color') { return ; } return ; }; export { defaultRenderText }; /** ProField 的类型 */ export type ProFieldPropsType = { text?: ProFieldTextType; valueType?: ProFieldValueType | ProFieldValueObjectType; } & RenderProps; const ProField: React.ForwardRefRenderFunction = ( { text, valueType = 'text', onChange, renderFormItem, value, ...rest }, ref, ) => { const intl = useIntl(); const context = useContext(ConfigContext); const fieldProps = (value !== undefined || onChange || rest?.fieldProps) && { value, // fieldProps 优先级更高,在类似 LightFilter 场景下需要覆盖默认的 value 和 onChange ...omitUndefined(rest?.fieldProps), onChange: (...restParams: any[]) => { onChange?.(...restParams); rest?.fieldProps?.onChange?.(...restParams); }, }; return ( {defaultRenderText( text ?? fieldProps?.value ?? '', valueType || 'text', { ...rest, mode: rest.mode || 'read', ref, renderFormItem: renderFormItem ? (...restProps) => { const newDom = renderFormItem(...restProps); // renderFormItem 之后的dom可能没有props,这里会帮忙注入一下 if (React.isValidElement(newDom)) return React.cloneElement(newDom, { placeholder: rest.placeholder || intl.getMessage('tableForm.inputPlaceholder', '请输入'), ...fieldProps, ...((newDom.props as any) || {}), }); return newDom; } : undefined, placeholder: rest.placeholder || intl.getMessage('tableForm.inputPlaceholder', '请输入'), fieldProps: pickProProps(fieldProps), }, context.valueTypeMap, )} ); }; export { FieldPercent, FieldIndexColumn, FieldProgress, FieldMoney, FieldDatePicker, FieldRangePicker, FieldCode, FieldTimePicker, FieldText, FieldStatus, FieldSelect, proFieldParsingText, proFieldParsingValueEnumToArray, }; export type { ProFieldValueType }; export default React.forwardRef(ProField) as typeof ProField;