Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | 50x 50x 50x 50x 50x 1x 49x 49x 30x 19x | 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"; export interface FormItemProps extends StyledProps { /** * HTML for 属性 * * 包含 `label` 时生效 */ htmlFor?: string; /** * 表单项说明 */ label?: React.ReactNode; /** * 表单控件内容,可以容纳任意表单组件,如 Input, CheckGroup 等 * 如果是只读表单内容,则可传入字符串 */ children?: React.ReactNode; /** * 表单项状态 */ status?: FormControlProps["status"]; /** * 是否展示 icon * @default true */ showStatusIcon?: boolean; /** * 表单项提示信息/校验信息 */ message?: FormControlProps["message"]; /** * 控件和标签对齐方式 * * - `auto` 自动根据传入的控件类型决定对齐方式 * - `top` 增加间距以实现标签文本和控件内容顶部对齐 * - `middle` 标签文本对齐到控件的中间 * * @default "auto" */ align?: "auto" | "top" | "middle"; /** * 是否为必填项(样式) * * @default false */ required?: boolean; /** * 表单控件后的装饰内容 */ suffix?: React.ReactNode; } export function FormItem({ htmlFor, label, children, className, style, status, message, align, required, showStatusIcon = true, suffix, }: FormItemProps) { const { classPrefix } = useConfig(); return ( <FormContext.Consumer> {({ hideLabel }) => ( <div className={classNames(`${classPrefix}-form__item`, className)} style={style} > {!hideLabel && ( <div className={classNames(`${classPrefix}-form__label`, { "is-required": required, })} > {typeof label !== "undefined" && ( <label htmlFor={htmlFor}>{label}</label> )} </div> )} <FormControl status={status} showStatusIcon={showStatusIcon} message={message} alignLabelTop={isAlignLabelTop(align, children)} > {children} {suffix && ( <div className={`${classPrefix}-form__help-text--inline`}> {suffix} </div> )} </FormControl> </div> )} </FormContext.Consumer> ); } function isAlignLabelTop( align: "auto" | "top" | "middle", children: React.ReactNode ): boolean { Iif (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"; } |