2023-09-04 10:03:12 +08:00
|
|
|
import type { PropsWithChildren, ReactNode } from 'react';
|
|
|
|
import * as React from 'react';
|
2019-07-03 20:14:39 +08:00
|
|
|
import { FormProvider as RcFormProvider } from 'rc-field-form';
|
2022-05-07 14:31:54 +08:00
|
|
|
import type { FormProviderProps as RcFormProviderProps } from 'rc-field-form/lib/FormContext';
|
2023-06-15 10:26:56 +08:00
|
|
|
import type { Meta } from 'rc-field-form/lib/interface';
|
2022-06-06 23:39:00 +08:00
|
|
|
import omit from 'rc-util/lib/omit';
|
2023-09-04 10:03:12 +08:00
|
|
|
|
2022-05-07 14:31:54 +08:00
|
|
|
import type { ColProps } from '../grid/col';
|
|
|
|
import type { FormInstance, RequiredMark } from './Form';
|
2024-04-08 14:04:08 +08:00
|
|
|
import type { FeedbackIcons, ValidateStatus } from './FormItem';
|
2024-06-21 17:47:09 +08:00
|
|
|
import type { Variant } from '../config-provider';
|
2024-04-08 14:04:08 +08:00
|
|
|
import type { FormLabelAlign } from './interface';
|
2019-07-03 20:14:39 +08:00
|
|
|
|
2020-12-28 15:30:18 +08:00
|
|
|
/** Form Context. Set top form style and pass to Form Item usage. */
|
2019-07-03 20:14:39 +08:00
|
|
|
export interface FormContextProps {
|
|
|
|
vertical: boolean;
|
|
|
|
name?: string;
|
|
|
|
colon?: boolean;
|
|
|
|
labelAlign?: FormLabelAlign;
|
2021-11-26 18:15:59 +08:00
|
|
|
labelWrap?: boolean;
|
2019-07-03 20:14:39 +08:00
|
|
|
labelCol?: ColProps;
|
|
|
|
wrapperCol?: ColProps;
|
2020-08-21 12:58:14 +08:00
|
|
|
requiredMark?: RequiredMark;
|
2020-06-05 18:06:52 +08:00
|
|
|
itemRef: (name: (string | number)[]) => (node: React.ReactElement) => void;
|
2022-04-15 15:51:09 +08:00
|
|
|
form?: FormInstance;
|
2023-09-04 20:36:45 +08:00
|
|
|
feedbackIcons?: FeedbackIcons;
|
2019-07-03 20:14:39 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
export const FormContext = React.createContext<FormContextProps>({
|
|
|
|
labelAlign: 'right',
|
|
|
|
vertical: false,
|
2020-06-05 18:06:52 +08:00
|
|
|
itemRef: (() => {}) as any,
|
2019-07-03 20:14:39 +08:00
|
|
|
});
|
|
|
|
|
2021-06-04 14:44:41 +08:00
|
|
|
/** `noStyle` Form Item Context. Used for error collection */
|
|
|
|
export type ReportMetaChange = (meta: Meta, uniqueKeys: React.Key[]) => void;
|
|
|
|
export const NoStyleItemContext = React.createContext<ReportMetaChange | null>(null);
|
2019-07-03 20:14:39 +08:00
|
|
|
|
2020-12-28 15:30:18 +08:00
|
|
|
/** Form Provider */
|
2021-01-13 21:00:30 +08:00
|
|
|
export interface FormProviderProps extends Omit<RcFormProviderProps, 'validateMessages'> {
|
|
|
|
prefixCls?: string;
|
|
|
|
}
|
2019-07-03 20:14:39 +08:00
|
|
|
|
2022-11-19 13:47:33 +08:00
|
|
|
export const FormProvider: React.FC<FormProviderProps> = (props) => {
|
2019-07-03 20:14:39 +08:00
|
|
|
const providerProps = omit(props, ['prefixCls']);
|
|
|
|
return <RcFormProvider {...providerProps} />;
|
|
|
|
};
|
2020-09-11 21:27:51 +08:00
|
|
|
|
2020-12-28 15:30:18 +08:00
|
|
|
/** Used for ErrorList only */
|
2020-09-11 21:27:51 +08:00
|
|
|
export interface FormItemPrefixContextProps {
|
|
|
|
prefixCls: string;
|
|
|
|
status?: ValidateStatus;
|
|
|
|
}
|
|
|
|
|
|
|
|
export const FormItemPrefixContext = React.createContext<FormItemPrefixContextProps>({
|
|
|
|
prefixCls: '',
|
|
|
|
});
|
2022-02-14 17:09:35 +08:00
|
|
|
|
|
|
|
export interface FormItemStatusContextProps {
|
2022-03-24 21:54:20 +08:00
|
|
|
isFormItemInput?: boolean;
|
2022-02-14 17:09:35 +08:00
|
|
|
status?: ValidateStatus;
|
2023-03-31 11:42:34 +08:00
|
|
|
errors?: React.ReactNode[];
|
|
|
|
warnings?: React.ReactNode[];
|
2022-02-14 17:09:35 +08:00
|
|
|
hasFeedback?: boolean;
|
2022-03-25 17:48:12 +08:00
|
|
|
feedbackIcon?: ReactNode;
|
2022-02-14 17:09:35 +08:00
|
|
|
}
|
|
|
|
|
2022-03-24 21:54:20 +08:00
|
|
|
export const FormItemInputContext = React.createContext<FormItemStatusContextProps>({});
|
2022-03-10 19:04:51 +08:00
|
|
|
|
2023-09-04 10:03:12 +08:00
|
|
|
if (process.env.NODE_ENV !== 'production') {
|
|
|
|
FormItemInputContext.displayName = 'FormItemInputContext';
|
|
|
|
}
|
|
|
|
|
2022-06-06 23:39:00 +08:00
|
|
|
export type NoFormStyleProps = PropsWithChildren<{
|
|
|
|
status?: boolean;
|
|
|
|
override?: boolean;
|
|
|
|
}>;
|
|
|
|
|
2023-07-25 19:47:05 +08:00
|
|
|
export const NoFormStyle: React.FC<NoFormStyleProps> = ({ children, status, override }) => {
|
2024-12-15 15:53:51 +08:00
|
|
|
const formItemInputContext = React.useContext(FormItemInputContext);
|
2022-06-06 23:39:00 +08:00
|
|
|
|
2024-12-15 15:53:51 +08:00
|
|
|
const newFormItemInputContext = React.useMemo(() => {
|
2022-06-06 23:39:00 +08:00
|
|
|
const newContext = { ...formItemInputContext };
|
|
|
|
if (override) {
|
|
|
|
delete newContext.isFormItemInput;
|
|
|
|
}
|
|
|
|
if (status) {
|
|
|
|
delete newContext.status;
|
|
|
|
delete newContext.hasFeedback;
|
|
|
|
delete newContext.feedbackIcon;
|
|
|
|
}
|
|
|
|
return newContext;
|
|
|
|
}, [status, override, formItemInputContext]);
|
2022-03-10 19:04:51 +08:00
|
|
|
|
|
|
|
return (
|
2022-06-06 23:39:00 +08:00
|
|
|
<FormItemInputContext.Provider value={newFormItemInputContext}>
|
|
|
|
{children}
|
|
|
|
</FormItemInputContext.Provider>
|
2022-03-10 19:04:51 +08:00
|
|
|
);
|
|
|
|
};
|
2023-12-22 10:05:15 +08:00
|
|
|
|
2024-12-15 15:53:51 +08:00
|
|
|
export const VariantContext = React.createContext<Variant | undefined>(undefined);
|