packages/form-render-mobile/src/render-core/FieldItem/main.tsx (135 lines of code) (raw):

import React, { createContext, useContext, useRef, useEffect, useState } from 'react'; import { Form, Grid, FormItemProps } from 'antd-mobile'; import { useStore } from 'zustand'; import classnames from 'classnames'; import { _get, getWidget } from '../../utils'; import { ConfigContext } from '../../models/context'; import getRuleList from 'form-render/es/models/validates'; import FieldWrapper from './field'; import { getParamValue, getFieldProps, getPath, getLabel, getExtraView, } from './module'; const UpperContext: any = createContext(() => {}); const valuePropNameMap = { checkbox: 'checked', switch: 'checked', Checkbox: 'checked', Switch: 'checked' }; export default (props: any) => { const { store, schema, path, children, dependValues, rootPath, renderCore } = props; if (schema?.hidden) { return null; } const [needOnClick, setNeedOnClick] = useState(false); const fieldRef: any = useRef(null); const formCtx: any = useStore(store, (state: any) => state.context); const upperCtx: any = useContext(UpperContext); const configCtx = useContext(ConfigContext); const { form, widgets, methods, globalProps }: any = configCtx; const { hidden, properties, dependencies, inlineMode: _inlineMode, remove, removeText, visible = true, layout, ...otherSchema } = schema; const getValueFromKey = getParamValue(formCtx, upperCtx, schema); useEffect(() => { form.setFieldRef(fieldProps.addons.dataPath, fieldRef); }, []); useEffect(() => { if (fieldRef?.current?.open) { setNeedOnClick(true); } }, [fieldRef.current]); let Widget = getWidget(widgets, schema.widget, schema) const fieldProps = getFieldProps(schema, { widgets, methods, form, dependValues, globalProps, path: getPath(path), rootPath, fieldRef }); const displayType = getValueFromKey('displayType'); const labelWidth = getValueFromKey('labelWidth'); if (['collapse'].includes(schema.widget)) { return <Widget {...fieldProps} renderCore={renderCore} /> } if (children) { fieldProps.children = ( <Grid columns={1}> {children} </Grid> ); return ( <UpperContext.Provider value={{ column: schema.column, labelCol: schema.labelCol, fieldCol: schema.fieldCol, displayType: schema.displayType, labelWidth: schema.labelWidth, noStyle: schema.noStyle, exist: true, }} > <Widget labelWidth={labelWidth} displayType={schema.displayType} {...fieldProps} {...otherSchema} /> </UpperContext.Provider> ); } // Render field components let label = getLabel(schema, displayType, widgets, fieldProps.addons); let noStyle = getValueFromKey('noStyle'); const extra = getExtraView('extra', schema, widgets); const help = getExtraView('help', schema, widgets); const tooltip = getExtraView('tooltip', schema, widgets); const ruleList = getRuleList(schema, form, methods, fieldRef); const readOnly = getValueFromKey('readOnly'); const valuePropName = schema.valuePropName || valuePropNameMap[schema.widget] || undefined; if (readOnly) { fieldProps.readOnly = readOnly; } if (readOnly) { Widget = getWidget(widgets, schema.readOnlyWidget, schema, true); } const defaultValue = schema.default ?? schema.defaultValue; const itemProps: FormItemProps = { label, valuePropName, hidden, extra, help: tooltip || help, noStyle, dependencies, name: path, initialValue: defaultValue, rules: readOnly ? [] : ruleList, className:classnames('fr-field', {'fr-field-visibility': !visible}) }; if (layout) { itemProps.layout = { column: 'vertical', row: 'horizontal', }[layout]; } if (!readOnly && needOnClick) { itemProps.onClick = () => { fieldRef.current.open(); }; } return ( <Grid.Item> <Form.Item {...itemProps}> <FieldWrapper Field={Widget} fieldProps={fieldProps} defaultValue={defaultValue} /> </Form.Item> </Grid.Item> ); }