import React, { useState } from 'react';
import { Form, Popover, Progress, Space } from 'antd';
import type { FormItemProps, PopoverProps, ProgressProps, FormInstance } from 'antd';
import { CheckCircleFilled, CloseCircleFilled, LoadingOutlined } from '@ant-design/icons';
import type { Rule, NamePath, RuleObject } from 'rc-field-form/lib/interface';
const RED = '#ff4d4f';
const YELLOW = '#faad14';
const GREEN = '#52c41a';
const PRIMARY = '#1890ff';
const COLORS = { RED, YELLOW, GREEN, PRIMARY };
const getStrokeColor = (percent: number) => {
if (percent < 50) {
return COLORS.RED;
}
if (percent < 100) {
return COLORS.YELLOW;
}
return COLORS.GREEN;
};
const CircleRender = () => {
return (
);
};
const getIcon = (
fieldError: string[],
rule: Rule,
isTouched: boolean,
requiredChecked: boolean,
) => {
if (!isTouched) {
return ;
}
if (!requiredChecked) {
return ;
}
if (fieldError.includes((rule as any).message)) {
return ;
}
return ;
};
const Content: React.FC<{
fieldError: string[];
value: any;
isValidating: boolean;
isTouched: boolean;
rules: Rule[];
progressProps?: ProgressProps | false;
}> = ({ rules, isTouched, isValidating, value, fieldError, progressProps }) => {
const percent = Math.max(
0,
Math.min(100, ((rules.length - fieldError.length) / rules.length) * 100),
);
const isSingleRule = rules.length === 1;
const requiredRule = rules.filter((_) => (_ as RuleObject).required)[0] as RuleObject;
const hasRequired = !!requiredRule;
const requiredChecked = hasRequired && !fieldError.includes(requiredRule?.message as string);
return (
{(progressProps === undefined || progressProps) && (
)}
{rules?.map((rule, idx) => (
-
{isValidating ? (
) : (
getIcon(fieldError, rule, isTouched, hasRequired ? requiredChecked : true)
)}
{(rule as any).message}
))}
);
};
interface InlineErrorFormItemProps extends FormItemProps {
errorType?: 'popover' | 'default';
popoverProps?: PopoverProps;
progressProps?: ProgressProps | false;
}
interface InternalProps extends InlineErrorFormItemProps {
name: NamePath;
rules: Rule[];
}
const FIX_INLINE_STYLE = {
marginTop: -5,
marginBottom: -5,
marginLeft: 0,
marginRight: 0,
};
const InternalFormItem: React.FC<
InternalProps & {
form: Omit;
}
> = ({ label, rules, name, children, popoverProps, progressProps, form, ...rest }) => {
const fieldError = form.getFieldError(name);
const value = form.getFieldValue(name);
const isValidating = form.isFieldValidating(name);
const isTouched = form.isFieldTouched(name);
const [visible, setVisible] = useState(undefined);
return (
{
return (
}
>
{input}
{extra}
);
},
}}
{...rest}
>
{children}
);
};
const InlineErrorFormItem: React.FC = (props) => {
return (
{(form) => {
return ;
}}
);
};
export default (props: InlineErrorFormItemProps) => {
const { errorType, rules, name, popoverProps, children, progressProps, ...rest } = props;
if (name && rules?.length && errorType === 'popover') {
return (
1 ? progressProps : false}
{...rest}
>
{children}
);
}
return (
{children}
);
};