import type { PropsWithChildren, ReactNode } from 'react'; import * as React from 'react'; import { createContext, useContext, useMemo } from 'react'; import { FormProvider as RcFormProvider } from 'rc-field-form'; import type { FormProviderProps as RcFormProviderProps } from 'rc-field-form/lib/FormContext'; import type { Meta } from 'rc-field-form/lib/interface'; import omit from 'rc-util/lib/omit'; import type { ColProps } from '../grid/col'; import type { FormInstance, RequiredMark } from './Form'; import type { FeedbackIcons, ValidateStatus } from './FormItem'; import type { Variant } from '../config-provider'; import type { FormLabelAlign } from './interface'; /** Form Context. Set top form style and pass to Form Item usage. */ export interface FormContextProps { vertical: boolean; name?: string; colon?: boolean; labelAlign?: FormLabelAlign; labelWrap?: boolean; labelCol?: ColProps; wrapperCol?: ColProps; requiredMark?: RequiredMark; itemRef: (name: (string | number)[]) => (node: React.ReactElement) => void; form?: FormInstance; feedbackIcons?: FeedbackIcons; } export const FormContext = React.createContext({ labelAlign: 'right', vertical: false, itemRef: (() => {}) as any, }); /** `noStyle` Form Item Context. Used for error collection */ export type ReportMetaChange = (meta: Meta, uniqueKeys: React.Key[]) => void; export const NoStyleItemContext = React.createContext(null); /** Form Provider */ export interface FormProviderProps extends Omit { prefixCls?: string; } export const FormProvider: React.FC = (props) => { const providerProps = omit(props, ['prefixCls']); return ; }; /** Used for ErrorList only */ export interface FormItemPrefixContextProps { prefixCls: string; status?: ValidateStatus; } export const FormItemPrefixContext = React.createContext({ prefixCls: '', }); export interface FormItemStatusContextProps { isFormItemInput?: boolean; status?: ValidateStatus; errors?: React.ReactNode[]; warnings?: React.ReactNode[]; hasFeedback?: boolean; feedbackIcon?: ReactNode; } export const FormItemInputContext = React.createContext({}); if (process.env.NODE_ENV !== 'production') { FormItemInputContext.displayName = 'FormItemInputContext'; } export type NoFormStyleProps = PropsWithChildren<{ status?: boolean; override?: boolean; }>; export const NoFormStyle: React.FC = ({ children, status, override }) => { const formItemInputContext = useContext(FormItemInputContext); const newFormItemInputContext = useMemo(() => { const newContext = { ...formItemInputContext }; if (override) { delete newContext.isFormItemInput; } if (status) { delete newContext.status; delete newContext.hasFeedback; delete newContext.feedbackIcon; } return newContext; }, [status, override, formItemInputContext]); return ( {children} ); }; export const VariantContext = createContext(undefined);