使用基础表单组件#
#布局组件
import { Fragment } from 'react';
import type { FairysValtioFormLayoutAttrsProps } from '@fairys/valtio-form-basic';
import { FairysValtioFormLayoutContext, useFairysValtioFormLayoutAttrs } from '@fairys/valtio-form-basic';
export interface FormLayoutProps extends FairysValtioFormLayoutAttrsProps { }
export function FormLayout(props: FormLayoutProps) {
const { children, title, extra } = props;
const {
formLayoutInstance,
layoutName,
layoutStyle,
headerName,
headerStyle,
headerTitleName,
headerExtraName,
bodyName,
bodyStyle,
} = useFairysValtioFormLayoutAttrs(props);
return (
<FairysValtioFormLayoutContext.Provider value={formLayoutInstance}>
<div className={layoutName} style={layoutStyle}>
{title || extra ? (
<div style={headerStyle} className={headerName}>
<div className={headerTitleName}>{title}</div>
<div className={headerExtraName}>{extra}</div>
</div>
) : (
<Fragment />
)}
<div className={bodyName} style={bodyStyle}>
{children}
</div>
</div>
</FairysValtioFormLayoutContext.Provider>
);
}
#表单组件
import React from 'react';
import { FormLayout } from './layout';
import {
useFairysValtioForm,
FairysValtioFormInstanceContext,
useFairysValtioFormInstance,
useFairysValtioFormInstanceContext,
useFairysValtioFormInstanceContextState,
useFairysValtioFormInstanceContextHideState,
} from '@fairys/valtio-form-basic';
import type { FairysValtioFormAttrsProps, FairysValtioFormInstance, MObject } from '@fairys/valtio-form-basic';
export interface FormProps<T extends MObject<T> = Record<string, any>> extends FairysValtioFormAttrsProps<T> {}
function FormBase<T extends MObject<T> = Record<string, any>>(
props: FormProps<T>,
ref: React.Ref<FairysValtioFormInstance<T>>,
) {
const {
formInstance,
children,
colCount = 4,
labelMode = 'top',
errorLayout = 'bottom-left',
itemBorderType = 'none',
platform = 'pc',
...rest
} = useFairysValtioForm(props, ref);
return (
<FairysValtioFormInstanceContext.Provider value={formInstance}>
<FormLayout
{...rest}
colCount={colCount}
labelMode={labelMode}
itemBorderType={itemBorderType}
errorLayout={errorLayout}
platform={platform}
>
{children}
</FormLayout>
</FairysValtioFormInstanceContext.Provider>
);
}
export const Form = React.forwardRef(FormBase)
#表单项
import { Fragment } from 'react';
import type { FairysValtioFormItemAttrsProps, MObject } from '@fairys/valtio-form-basic';
import {
useFairysValtioFormItemAttrs,
useFairysValtioFormInstanceContextHideState,
useFairysValtioFormItemNoStyleAttrs,
FairysValtioFormParentAttrsContext,
} from '@fairys/valtio-form-basic';
export interface FormItemProps<T extends MObject<T> = Record<string, any>>
extends React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>,
FairysValtioFormItemAttrsProps {
/**是否使用控制隐藏的表单项*/
isHide?: boolean;
/**是否使用无样式表单项*/
noStyle?: boolean;
}
/**普通表单项*/
export function FormItemBase<T extends MObject<T> = Record<string, any>>(
props: Omit<FormItemProps<T>, 'isHide' | 'noStyle'>,
) {
const { label, extra, helpText } = props;
const {
itemClassName,
itemStyle,
containerClassName,
itemLabelClassName,
itemLabelStyle,
itemBodyClassName,
itemBodyStyle,
itemInputClassName,
itemExtraClassName,
errorClassName,
helpClassName,
isInvalid,
children,
error,
formAttrsNameInstance,
id,
} = useFairysValtioFormItemAttrs(props);
return (
<div className={itemClassName} style={itemStyle}>
<div className={containerClassName}>
{label ? (
<label htmlFor={id} className={itemLabelClassName} style={itemLabelStyle}>
{label}
</label>
) : (
<Fragment />
)}
<div className={itemBodyClassName} style={itemBodyStyle}>
<FairysValtioFormParentAttrsContext.Provider value={formAttrsNameInstance}>
<div className={itemInputClassName}>{children}</div>
</FairysValtioFormParentAttrsContext.Provider>
{extra ? <div className={itemExtraClassName}>{extra}</div> : <Fragment />}
</div>
</div>
{helpText ? <div className={helpClassName}>{helpText}</div> : <Fragment />}
{isInvalid ? <div className={errorClassName}>{error}</div> : <Fragment />}
</div>
);
}
/**控制隐藏的表单项*/
export function FormHideItem<T extends MObject<T> = Record<string, any>>(
props: Omit<FormItemProps<T>, 'isHide' | 'noStyle'>,
) {
const [state] = useFairysValtioFormInstanceContextHideState();
const isHide = state[props.name];
if (isHide) {
return <Fragment />;
}
return <FormItemBase<T> {...props} />;
}
/**无样式表单项*/
export function FormItemNoStyle<T extends MObject<T> = Record<string, any>>(
props: Omit<FormItemProps<T>, 'isHide' | 'noStyle'>,
) {
const { children, formAttrsNameInstance } = useFairysValtioFormItemNoStyleAttrs(props);
return (
<FairysValtioFormParentAttrsContext.Provider value={formAttrsNameInstance}>
{children}
</FairysValtioFormParentAttrsContext.Provider>
);
}
/**表单项基础组件(根据isHide和noStyle判断是否使用控制隐藏的表单项和无样式表单项)*/
export function FormItem<T extends MObject<T> = Record<string, any>>(props: FormItemProps<T>) {
const { isHide, noStyle, ...rest } = props;
if (isHide) {
return <FormHideItem<T> {...rest} />;
}
if (noStyle) {
return <FormItemNoStyle<T> {...rest} />;
}
return <FormItemBase<T> {...rest} />;
}
