import React from "react"; import classNames from "classnames"; import { StyledProps } from "../_type"; import { FormControlProps, FormControl } from "./FormControl"; import { FormContext } from "./FormContext"; import { useConfig } from "../_util/config-context"; import { Bubble } from "../bubble"; import { Icon } from "../icon"; export interface FormItemProps extends StyledProps { /** * 表单项说明 */ label?: React.ReactNode; /** * 表单控件内容,可以容纳任意表单组件,如 Input, CheckGroup 等 * 如果是只读表单内容,则可传入字符串 */ children?: React.ReactNode; /** * 控件和标签对齐方式 * * - `auto` 自动根据传入的控件类型决定对齐方式 * - `top` 增加间距以实现标签文本和控件内容顶部对齐 * - `middle` 标签文本对齐到控件的中间 * * @default "auto" */ align?: "auto" | "top" | "middle"; /** * 表单项状态 */ status?: FormControlProps["status"]; /** * 是否展示 icon * @default true */ showStatusIcon?: boolean; /** * 表单项提示信息/校验信息 */ message?: FormControlProps["message"]; /** * 表单额外说明信息 * * *可与 `message` 信息同时存在* * @since 2.6.8 */ extra?: FormControlProps["extra"]; /** * 是否为必填项(样式) * * @default false */ required?: boolean; /** * 是否展示表单项提示 * * *图标气泡形式展示在 label 右侧* * * @since 2.6.8 */ tips?: React.ReactNode; /** * 表单控件后的装饰内容 */ suffix?: React.ReactNode; /** * HTML for 属性 * * 包含 `label` 时生效 */ htmlFor?: string; } export const FormItem = React.forwardRef(function FormItem( { htmlFor, label, children, status, message, extra, align, required, tips, showStatusIcon = true, suffix, className, ...props }: FormItemProps, ref: React.Ref ) { const { classPrefix } = useConfig(); return ( {({ hideLabel, fixedLabelWidth }) => (
{!hideLabel && (
{typeof label !== "undefined" && ( )}
)} {children} {suffix && (
{suffix}
)}
)}
); }); FormItem.displayName = "FormItem"; function isAlignLabelTop( align: "auto" | "top" | "middle", children: React.ReactNode ): boolean { if (align === "top") { return true; } if (align === "middle") { return false; } return getDefaultAlign(children) === "top"; } function getDefaultAlign(control: React.ReactNode) { if ( React.isValidElement(control) && // 普通组件是 function, forwaredRef 是 object (typeof control.type === "function" || typeof control.type === "object") && "defaultLabelAlign" in control.type ) { return control.type["defaultLabelAlign"]; // eslint-disable-line dot-notation } return "top"; }