Слияние кода завершено, страница обновится автоматически
import React, {
Children,
cloneElement,
FunctionComponent,
isValidElement,
ReactElement,
ReactNode,
useCallback,
useContext,
useEffect,
useMemo,
useRef,
} from 'react';
import { isArrayLike } from 'mobx';
import classNames from 'classnames';
import { observer } from 'mobx-react-lite';
import ConfigContext from 'choerodon-ui/lib/config-provider/ConfigContext';
import FormContext from './FormContext';
import { defaultLabelWidth, FIELD_SUFFIX, getProperty, normalizeLabelWidth, getPropertyDSFirst, getRequiredMarkAlign } from './utils';
import { LabelLayout } from './enum';
import { FormFieldProps } from '../field/FormField';
import Row from '../row';
import Col from '../col';
import { Tooltip as LabelTooltip } from '../core/enum';
import { hide, show } from '../tooltip/singleton';
import { TooltipProps } from '../tooltip/Tooltip';
import isOverflow from '../overflow-tip/util';
import { ShowHelp } from '../field/enum';
import Icon from '../icon';
export interface ItemProps extends FormFieldProps {
children: ReactElement<FormFieldProps>;
}
export interface LabelProps {
className?: string;
children?: ReactNode;
tooltip?: LabelTooltip | [LabelTooltip, TooltipProps];
width?: number;
help?: ReactNode;
}
export interface LabelHelpProps {
help?: ReactNode;
}
export interface IItem extends FunctionComponent<ItemProps> {
__PRO_FORM_ITEM?: boolean;
}
const Label: FunctionComponent<LabelProps> = (props) => {
const { children, className, tooltip, width, help } = props;
const { getTooltipTheme, getTooltipPlacement } = useContext(ConfigContext);
const tooltipRef = useRef<boolean>(false);
const style = useMemo(() => width ? ({ width }) : undefined, [width]);
const handleMouseEnter = useCallback((e) => {
const { currentTarget } = e;
if (tooltip === LabelTooltip.always || (tooltip === LabelTooltip.overflow && isOverflow(currentTarget))) {
show(currentTarget, {
title: children,
theme: getTooltipTheme('label'),
placement: getTooltipPlacement('label'),
});
tooltipRef.current = true;
} else if (isArrayLike(tooltip)) {
const tooltipType = tooltip[0];
const labelTooltipProps = tooltip[1] || {};
const duration: number = (labelTooltipProps.mouseEnterDelay || 0.1) * 1000;
if (tooltipType === LabelTooltip.always || (tooltipType === LabelTooltip.overflow && isOverflow(currentTarget))) {
show(currentTarget, {
theme: getTooltipTheme('label'),
placement: getTooltipPlacement('label'),
title: labelTooltipProps.title ? labelTooltipProps.title : children,
...labelTooltipProps,
}, duration);
tooltipRef.current = true;
}
}
}, [children, tooltip, tooltipRef]);
const handleMouseLeave = useCallback(() => {
if (tooltipRef.current) {
hide();
tooltipRef.current = false;
}
}, [tooltipRef]);
useEffect(() => () => {
if (tooltipRef.current) {
hide();
tooltipRef.current = false;
}
}, [tooltipRef]);
return (
<label
className={className}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
style={style}
>
{children}
{help}
</label>
);
};
Label.displayName = 'Label';
const LabelHelp: FunctionComponent<LabelHelpProps> = (props) => {
const { help } = props;
const { getTooltipTheme, getTooltipPlacement } = useContext(ConfigContext);
const tooltipRef = useRef<boolean>(false);
useEffect(() => {
return () => {
if (tooltipRef.current) {
hide();
tooltipRef.current = false;
}
};
}, []);
const handleHelpMouseEnter = useCallback((e, help) => {
const { target } = e;
show(target as HTMLElement, {
title: help,
theme: getTooltipTheme('help'),
placement: getTooltipPlacement('help'),
});
tooltipRef.current = true;
}, []);
const handleHelpMouseLeave = useCallback(() => {
hide();
tooltipRef.current = false;
}, []);
if (help) {
return (
<Icon
type="help"
onMouseEnter={(e) => handleHelpMouseEnter(e, help)}
onMouseLeave={handleHelpMouseLeave}
/>
);
}
return null;
}
LabelHelp.displayName = 'LabelHelp';
const Item: IItem = observer((props: ItemProps): ReactElement<any> | null => {
const { getConfig, dataSet, record, labelLayout = getConfig('labelLayout'), labelAlign, labelWidth: contextLabelWidth = defaultLabelWidth, labelTooltip, useColon, requiredMarkAlign, getProPrefixCls, showHelp } = useContext(FormContext);
const { children, useColon: fieldUseColon = useColon, requiredMarkAlign: fieldRequiredMarkAlign = requiredMarkAlign, ...rest } = props;
const child = Children.only<ReactElement<FormFieldProps>>(children);
if (isValidElement<FormFieldProps>(child)) {
const prefixCls = getProPrefixCls(FIELD_SUFFIX);
const { props: childrenProps } = child;
const { className, fieldClassName, ...otherProps } = childrenProps;
const fieldProps: FormFieldProps = { ...rest, ...otherProps };
const fieldElementProps: any = {
className: classNames(props.className, className, prefixCls),
...fieldProps,
};
const intlFieldOutput = (child.type as any).displayName === 'IntlField' && (fieldProps as any).displayOutput;
if ([LabelLayout.none, LabelLayout.float, LabelLayout.placeholder].includes(labelLayout)) {
return (
<div className={`${prefixCls}-wrapper`}>
{cloneElement<FormFieldProps>(child, fieldElementProps)}
</div>
);
}
const label = getProperty(fieldProps, 'label', dataSet, record);
const required = getPropertyDSFirst(fieldProps, 'required', dataSet, record);
const readOnly = getProperty(fieldProps, 'readOnly', dataSet, record);
const help = getProperty(fieldProps, 'help', dataSet, record);
const isLabelShowHelp = (fieldElementProps.showHelp || showHelp || getConfig('showHelp')) === ShowHelp.label;
const isOutput = labelLayout === LabelLayout.horizontal && ((child.type as any).displayName === 'Output' || intlFieldOutput);
const labelClassName = classNames(`${prefixCls}-label`, `${prefixCls}-label-grid`, `${prefixCls}-label-${labelAlign}`, fieldClassName, {
[`${prefixCls}-required`]: required && !((child.type as any).displayName === 'Output' || intlFieldOutput),
[`${prefixCls}-readonly`]: readOnly,
[`${prefixCls}-label-vertical`]: labelLayout === LabelLayout.vertical,
[`${prefixCls}-label-output`]: isOutput,
[`${prefixCls}-label-useColon`]: label && fieldUseColon,
[`${prefixCls}-label-required-mark-${getRequiredMarkAlign(fieldRequiredMarkAlign)}`]: labelLayout === LabelLayout.horizontal && required && !((child.type as any).displayName === 'Output' || intlFieldOutput) && getRequiredMarkAlign(fieldRequiredMarkAlign),
[`${prefixCls}-label-help`]: isLabelShowHelp,
});
const wrapperClassName = classNames(`${prefixCls}-wrapper`, {
[`${prefixCls}-output`]: isOutput,
});
const tooltip = props.labelTooltip || labelTooltip;
const helpWrap = isLabelShowHelp ? <LabelHelp help={help} /> : undefined;
if (labelLayout === LabelLayout.vertical) {
return (
<>
<Label className={labelClassName} tooltip={tooltip} help={helpWrap}>{label}</Label>
<div className={wrapperClassName}>{cloneElement(child, fieldElementProps)}</div>
</>
);
}
const fieldLabelWidth = getProperty(fieldProps, 'labelWidth', dataSet, record);
const columnLabelWidth = normalizeLabelWidth(contextLabelWidth, 1)[0];
const labelWidth = columnLabelWidth === 'auto' ? undefined : Math.max(columnLabelWidth, isNaN(fieldLabelWidth) ? 0 : fieldLabelWidth);
return (
<Row className={`${prefixCls}-row`}>
<Col className={`${prefixCls}-col`}>
<Label className={labelClassName} width={labelWidth} tooltip={tooltip} help={helpWrap}><span>{label}</span></Label>
</Col>
<Col className={`${prefixCls}-col ${prefixCls}-col-control`}>
<div className={wrapperClassName}>{cloneElement(child, fieldElementProps)}</div>
</Col>
</Row>
);
}
if (child) {
return child;
}
return null;
});
Item.displayName = 'FormItem';
Item.__PRO_FORM_ITEM = true;
export default Item;
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарий ( 0 )