/** * This file is part of the NocoBase (R) project. * Copyright (c) 2020-2024 NocoBase Co., Ltd. * Authors: NocoBase Team. * * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License. * For more information, please refer to: https://www.nocobase.com/agreement. */ import React from 'react'; import { Tooltip, Form } from 'antd'; import type { FormItemProps, TooltipProps } from 'antd'; type ChildExtraProps = Record; interface ExtendedFormItemProps extends FormItemProps { labelWidth?: number | string; labelWrap?: boolean; showLabel?: boolean; } export const verticalFormItemLabelStyle = { paddingBottom: 0 }; export const formItemStyle = { marginBottom: 12 }; const formItemPropKeys: (keyof ExtendedFormItemProps)[] = [ 'colon', 'dependencies', 'extra', 'getValueFromEvent', 'getValueProps', 'hasFeedback', 'help', 'htmlFor', 'initialValue', 'label', 'labelAlign', 'labelCol', 'messageVariables', 'name', 'normalize', 'noStyle', 'preserve', 'rules', 'tooltip', 'trigger', 'validateStatus', 'validateTrigger', 'valuePropName', 'wrapperCol', 'labelWidth', 'labelWrap', 'layout', 'required', 'showLabel', ]; const modelInternalPropKeys = ['globalSort']; export const FormItem = ({ children, showLabel = true, labelWidth, ...rest }: ExtendedFormItemProps & ChildExtraProps) => { const forwardedRest = Object.fromEntries( Object.entries(rest).filter(([key]) => !modelInternalPropKeys.includes(key)), ) as ExtendedFormItemProps & ChildExtraProps; // 过滤掉 Form.Item 专用 props,只保留要传给子组件的 const childProps = Object.fromEntries( Object.entries(forwardedRest).filter(([key]) => !formItemPropKeys.includes(key as keyof ExtendedFormItemProps)), ); const processedChildren = typeof children === 'function' ? children : React.Children.map(children as React.ReactNode, (child) => { if (React.isValidElement(child)) { return React.cloneElement(child, { ...childProps }); } return child; }); const { label, labelWrap, colon = true, layout } = forwardedRest; const effectiveLabelWrap = !layout || layout === 'vertical' ? true : labelWrap; const labelColStyle = layout === 'vertical' ? { width: labelWidth, ...verticalFormItemLabelStyle } : { width: labelWidth }; const renderLabel = () => { if (!showLabel) return null; if (effectiveLabelWrap) { // 垂直布局或者 labelWrap = true,宽度100%,自动换行 return (
{label} {colon && :}
); } // labelWrap = false → 省略 + tooltip return (
{label} {colon && :}
); }; return ( {forwardedRest.extra}} tooltip={ forwardedRest.tooltip && ({ title: forwardedRest.tooltip, overlayInnerStyle: { whiteSpace: 'pre-line' }, } as TooltipProps) } > {processedChildren} ); };