mirror of
https://gitee.com/ant-design/ant-design.git
synced 2024-12-03 04:30:06 +08:00
merge master
This commit is contained in:
commit
9f38c46039
@ -1,8 +1,17 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
|
||||||
// eslint-disable-next-line import/prefer-default-export
|
export const isValidElement = React.isValidElement;
|
||||||
export function cloneElement(element: React.ReactNode, ...restArgs: any[]) {
|
|
||||||
if (!React.isValidElement(element)) return element;
|
|
||||||
|
|
||||||
return React.cloneElement(element, ...restArgs);
|
export function replaceElement(
|
||||||
|
element: React.ReactNode,
|
||||||
|
replacement: React.ReactNode,
|
||||||
|
props: any,
|
||||||
|
): React.ReactNode {
|
||||||
|
if (!isValidElement(element)) return replacement;
|
||||||
|
|
||||||
|
return React.cloneElement(element, typeof props === 'function' ? props() : props);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function cloneElement(element: React.ReactNode, props?: any): React.ReactElement {
|
||||||
|
return replaceElement(element, element, props) as React.ReactElement;
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@ import classNames from 'classnames';
|
|||||||
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
||||||
import getDataOrAriaProps from '../_util/getDataOrAriaProps';
|
import getDataOrAriaProps from '../_util/getDataOrAriaProps';
|
||||||
import ErrorBoundary from './ErrorBoundary';
|
import ErrorBoundary from './ErrorBoundary';
|
||||||
|
import { replaceElement } from '../_util/reactNode';
|
||||||
|
|
||||||
export interface AlertProps {
|
export interface AlertProps {
|
||||||
/**
|
/**
|
||||||
@ -127,15 +128,11 @@ export default class Alert extends React.Component<AlertProps, AlertState> {
|
|||||||
const { icon } = this.props;
|
const { icon } = this.props;
|
||||||
const iconType = this.getIconType();
|
const iconType = this.getIconType();
|
||||||
if (icon) {
|
if (icon) {
|
||||||
return React.isValidElement<{ className?: string }>(icon) ? (
|
return replaceElement(icon, <span className={`${prefixCls}-icon`}>{icon}</span>, () => ({
|
||||||
React.cloneElement(icon, {
|
|
||||||
className: classNames(`${prefixCls}-icon`, {
|
className: classNames(`${prefixCls}-icon`, {
|
||||||
[icon.props.className as string]: icon.props.className,
|
[(icon as any).props.className]: (icon as any).props.className,
|
||||||
}),
|
}),
|
||||||
})
|
}));
|
||||||
) : (
|
|
||||||
<span className={`${prefixCls}-icon`}>{icon}</span>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return React.createElement(iconType, { className: `${prefixCls}-icon` });
|
return React.createElement(iconType, { className: `${prefixCls}-icon` });
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ import omit from 'omit.js';
|
|||||||
import Select, { InternalSelectProps, OptionType } from '../select';
|
import Select, { InternalSelectProps, OptionType } from '../select';
|
||||||
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
||||||
import devWarning from '../_util/devWarning';
|
import devWarning from '../_util/devWarning';
|
||||||
|
import { isValidElement } from '../_util/reactNode';
|
||||||
|
|
||||||
const { Option } = Select;
|
const { Option } = Select;
|
||||||
|
|
||||||
@ -49,7 +50,7 @@ const AutoComplete: React.RefForwardingComponent<Select, AutoCompleteProps> = (p
|
|||||||
|
|
||||||
if (
|
if (
|
||||||
childNodes.length === 1 &&
|
childNodes.length === 1 &&
|
||||||
React.isValidElement(childNodes[0]) &&
|
isValidElement(childNodes[0]) &&
|
||||||
!isSelectOptionOrSelectOptGroup(childNodes[0])
|
!isSelectOptionOrSelectOptGroup(childNodes[0])
|
||||||
) {
|
) {
|
||||||
customizeInput = childNodes[0];
|
customizeInput = childNodes[0];
|
||||||
@ -66,7 +67,7 @@ const AutoComplete: React.RefForwardingComponent<Select, AutoCompleteProps> = (p
|
|||||||
} else {
|
} else {
|
||||||
optionChildren = dataSource
|
optionChildren = dataSource
|
||||||
? dataSource.map(item => {
|
? dataSource.map(item => {
|
||||||
if (React.isValidElement(item)) {
|
if (isValidElement(item)) {
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
switch (typeof item) {
|
switch (typeof item) {
|
||||||
|
@ -2,6 +2,7 @@ import * as React from 'react';
|
|||||||
import omit from 'omit.js';
|
import omit from 'omit.js';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
||||||
|
import { cloneElement } from '../_util/reactNode';
|
||||||
|
|
||||||
function getNumberArray(num: string | number | undefined | null) {
|
function getNumberArray(num: string | number | undefined | null) {
|
||||||
return num
|
return num
|
||||||
@ -175,7 +176,7 @@ const ScrollNumber: React.FC<ScrollNumberProps> = props => {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (displayComponent) {
|
if (displayComponent) {
|
||||||
return React.cloneElement(displayComponent, {
|
return cloneElement(displayComponent, {
|
||||||
className: classNames(
|
className: classNames(
|
||||||
`${prefixCls}-custom-component`,
|
`${prefixCls}-custom-component`,
|
||||||
displayComponent.props && displayComponent.props.className,
|
displayComponent.props && displayComponent.props.className,
|
||||||
|
@ -6,6 +6,7 @@ import ScrollNumber from './ScrollNumber';
|
|||||||
import { PresetColorTypes, PresetColorType, PresetStatusColorType } from '../_util/colors';
|
import { PresetColorTypes, PresetColorType, PresetStatusColorType } from '../_util/colors';
|
||||||
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
||||||
import { LiteralUnion } from '../_util/type';
|
import { LiteralUnion } from '../_util/type';
|
||||||
|
import { cloneElement } from '../_util/reactNode';
|
||||||
|
|
||||||
export { ScrollNumberProps } from './ScrollNumber';
|
export { ScrollNumberProps } from './ScrollNumber';
|
||||||
|
|
||||||
@ -110,7 +111,7 @@ const Badge: React.FC<BadgeProps> = props => {
|
|||||||
if (!customNode || typeof customNode !== 'object') {
|
if (!customNode || typeof customNode !== 'object') {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
return React.cloneElement(customNode, {
|
return cloneElement(customNode, {
|
||||||
style: {
|
style: {
|
||||||
...getStyleWithOffset(),
|
...getStyleWithOffset(),
|
||||||
...(customNode.props && customNode.props.style),
|
...(customNode.props && customNode.props.style),
|
||||||
|
@ -8,6 +8,7 @@ import Menu from '../menu';
|
|||||||
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
||||||
import devWarning from '../_util/devWarning';
|
import devWarning from '../_util/devWarning';
|
||||||
import { Omit } from '../_util/type';
|
import { Omit } from '../_util/type';
|
||||||
|
import { cloneElement } from '../_util/reactNode';
|
||||||
|
|
||||||
export interface Route {
|
export interface Route {
|
||||||
path: string;
|
path: string;
|
||||||
@ -138,9 +139,9 @@ export default class Breadcrumb extends React.Component<BreadcrumbProps, any> {
|
|||||||
"Only accepts Breadcrumb.Item and Breadcrumb.Separator as it's children",
|
"Only accepts Breadcrumb.Item and Breadcrumb.Separator as it's children",
|
||||||
);
|
);
|
||||||
|
|
||||||
return React.cloneElement(element, {
|
return cloneElement(element, {
|
||||||
separator,
|
separator,
|
||||||
key: index, // eslint-disable-line react/no-array-index-key
|
key: index,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ import { Omit, tuple } from '../_util/type';
|
|||||||
import devWarning from '../_util/devWarning';
|
import devWarning from '../_util/devWarning';
|
||||||
import SizeContext, { SizeType } from '../config-provider/SizeContext';
|
import SizeContext, { SizeType } from '../config-provider/SizeContext';
|
||||||
import LoadingIcon from './LoadingIcon';
|
import LoadingIcon from './LoadingIcon';
|
||||||
|
import { cloneElement } from '../_util/reactNode';
|
||||||
|
|
||||||
const rxTwoCNChar = /^[\u4e00-\u9fa5]{2}$/;
|
const rxTwoCNChar = /^[\u4e00-\u9fa5]{2}$/;
|
||||||
const isTwoCNChar = rxTwoCNChar.test.bind(rxTwoCNChar);
|
const isTwoCNChar = rxTwoCNChar.test.bind(rxTwoCNChar);
|
||||||
@ -31,7 +32,9 @@ function insertSpace(child: React.ReactChild, needInserted: boolean) {
|
|||||||
isString(child.type) &&
|
isString(child.type) &&
|
||||||
isTwoCNChar(child.props.children)
|
isTwoCNChar(child.props.children)
|
||||||
) {
|
) {
|
||||||
return React.cloneElement(child, {}, child.props.children.split('').join(SPACE));
|
return cloneElement(child, {
|
||||||
|
children: child.props.children.split('').join(SPACE),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
if (typeof child === 'string') {
|
if (typeof child === 'string') {
|
||||||
if (isTwoCNChar(child)) {
|
if (isTwoCNChar(child)) {
|
||||||
|
@ -16,6 +16,7 @@ import { ConfigConsumer, ConfigConsumerProps, RenderEmptyHandler } from '../conf
|
|||||||
import LocaleReceiver from '../locale-provider/LocaleReceiver';
|
import LocaleReceiver from '../locale-provider/LocaleReceiver';
|
||||||
import devWarning from '../_util/devWarning';
|
import devWarning from '../_util/devWarning';
|
||||||
import SizeContext, { SizeType } from '../config-provider/SizeContext';
|
import SizeContext, { SizeType } from '../config-provider/SizeContext';
|
||||||
|
import { replaceElement } from '../_util/reactNode';
|
||||||
|
|
||||||
export interface CascaderOptionType {
|
export interface CascaderOptionType {
|
||||||
value?: string;
|
value?: string;
|
||||||
@ -554,17 +555,21 @@ class Cascader extends React.Component<CascaderProps, CascaderState> {
|
|||||||
dropdownMenuColumnStyle.width = this.input.input.offsetWidth;
|
dropdownMenuColumnStyle.width = this.input.input.offsetWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
const inputIcon = (suffixIcon &&
|
let inputIcon: React.ReactNode;
|
||||||
(React.isValidElement<{ className?: string }>(suffixIcon) ? (
|
if (suffixIcon) {
|
||||||
React.cloneElement(suffixIcon, {
|
inputIcon = replaceElement(
|
||||||
|
suffixIcon,
|
||||||
|
<span className={`${prefixCls}-picker-arrow`}>{suffixIcon}</span>,
|
||||||
|
() => ({
|
||||||
className: classNames({
|
className: classNames({
|
||||||
[suffixIcon.props.className!]: suffixIcon.props.className,
|
[(suffixIcon as any).props.className!]: (suffixIcon as any).props.className,
|
||||||
[`${prefixCls}-picker-arrow`]: true,
|
[`${prefixCls}-picker-arrow`]: true,
|
||||||
}),
|
}),
|
||||||
})
|
}),
|
||||||
) : (
|
);
|
||||||
<span className={`${prefixCls}-picker-arrow`}>{suffixIcon}</span>
|
} else {
|
||||||
))) || <DownOutlined className={arrowCls} />;
|
inputIcon = <DownOutlined className={arrowCls} />;
|
||||||
|
}
|
||||||
|
|
||||||
const input = children || (
|
const input = children || (
|
||||||
<span style={style} className={pickerCls}>
|
<span style={style} className={pickerCls}>
|
||||||
|
@ -6,6 +6,7 @@ import RightOutlined from '@ant-design/icons/RightOutlined';
|
|||||||
import CollapsePanel from './CollapsePanel';
|
import CollapsePanel from './CollapsePanel';
|
||||||
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
||||||
import animation from '../_util/openAnimation';
|
import animation from '../_util/openAnimation';
|
||||||
|
import { cloneElement } from '../_util/reactNode';
|
||||||
|
|
||||||
export type ExpandIconPosition = 'left' | 'right' | undefined;
|
export type ExpandIconPosition = 'left' | 'right' | undefined;
|
||||||
|
|
||||||
@ -58,11 +59,9 @@ export default class Collapse extends React.Component<CollapseProps, any> {
|
|||||||
<RightOutlined rotate={panelProps.isActive ? 90 : undefined} />
|
<RightOutlined rotate={panelProps.isActive ? 90 : undefined} />
|
||||||
)) as React.ReactNode;
|
)) as React.ReactNode;
|
||||||
|
|
||||||
return React.isValidElement(icon)
|
return cloneElement(icon, () => ({
|
||||||
? React.cloneElement(icon as any, {
|
className: classNames((icon as any).props.className, `${prefixCls}-arrow`),
|
||||||
className: classNames(icon.props.className, `${prefixCls}-arrow`),
|
}));
|
||||||
})
|
|
||||||
: icon;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
renderCollapse = ({ getPrefixCls, direction }: ConfigConsumerProps) => {
|
renderCollapse = ({ getPrefixCls, direction }: ConfigConsumerProps) => {
|
||||||
|
@ -11,6 +11,7 @@ import devWarning from '../_util/devWarning';
|
|||||||
import { ConfigContext } from '../config-provider';
|
import { ConfigContext } from '../config-provider';
|
||||||
import Row from './Row';
|
import Row from './Row';
|
||||||
import DescriptionsItem from './Item';
|
import DescriptionsItem from './Item';
|
||||||
|
import { cloneElement } from '../_util/reactNode';
|
||||||
|
|
||||||
const DEFAULT_COLUMN_MAP: Record<Breakpoint, number> = {
|
const DEFAULT_COLUMN_MAP: Record<Breakpoint, number> = {
|
||||||
xxl: 3,
|
xxl: 3,
|
||||||
@ -46,7 +47,7 @@ function getFilledItem(
|
|||||||
let clone = node;
|
let clone = node;
|
||||||
|
|
||||||
if (span === undefined || span > rowRestCol) {
|
if (span === undefined || span > rowRestCol) {
|
||||||
clone = React.cloneElement(node, {
|
clone = cloneElement(node, {
|
||||||
span: rowRestCol,
|
span: rowRestCol,
|
||||||
});
|
});
|
||||||
devWarning(
|
devWarning(
|
||||||
|
@ -7,6 +7,7 @@ import DropdownButton from './dropdown-button';
|
|||||||
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
||||||
import devWarning from '../_util/devWarning';
|
import devWarning from '../_util/devWarning';
|
||||||
import { tuple } from '../_util/type';
|
import { tuple } from '../_util/type';
|
||||||
|
import { cloneElement } from '../_util/reactNode';
|
||||||
|
|
||||||
const Placements = tuple(
|
const Placements = tuple(
|
||||||
'topLeft',
|
'topLeft',
|
||||||
@ -107,7 +108,7 @@ export default class Dropdown extends React.Component<DropDownProps, any> {
|
|||||||
const fixedModeOverlay =
|
const fixedModeOverlay =
|
||||||
typeof overlayNode.type === 'string'
|
typeof overlayNode.type === 'string'
|
||||||
? overlay
|
? overlay
|
||||||
: React.cloneElement(overlayNode, {
|
: cloneElement(overlayNode, {
|
||||||
mode: 'vertical',
|
mode: 'vertical',
|
||||||
selectable,
|
selectable,
|
||||||
focusable,
|
focusable,
|
||||||
@ -142,7 +143,7 @@ export default class Dropdown extends React.Component<DropDownProps, any> {
|
|||||||
const prefixCls = getPrefixCls('dropdown', customizePrefixCls);
|
const prefixCls = getPrefixCls('dropdown', customizePrefixCls);
|
||||||
const child = React.Children.only(children) as React.ReactElement<any>;
|
const child = React.Children.only(children) as React.ReactElement<any>;
|
||||||
|
|
||||||
const dropdownTrigger = React.cloneElement(child, {
|
const dropdownTrigger = cloneElement(child, {
|
||||||
className: classNames(child.props.className, `${prefixCls}-trigger`, {
|
className: classNames(child.props.className, `${prefixCls}-trigger`, {
|
||||||
[`${prefixCls}-rtl`]: direction === 'rtl',
|
[`${prefixCls}-rtl`]: direction === 'rtl',
|
||||||
}),
|
}),
|
||||||
|
@ -13,6 +13,7 @@ import FormItemLabel, { FormItemLabelProps } from './FormItemLabel';
|
|||||||
import FormItemInput, { FormItemInputProps } from './FormItemInput';
|
import FormItemInput, { FormItemInputProps } from './FormItemInput';
|
||||||
import { FormContext, FormItemContext } from './context';
|
import { FormContext, FormItemContext } from './context';
|
||||||
import { toArray, getFieldId, useFrameState } from './util';
|
import { toArray, getFieldId, useFrameState } from './util';
|
||||||
|
import { cloneElement, isValidElement } from '../_util/reactNode';
|
||||||
|
|
||||||
const ValidateStatuses = tuple('success', 'warning', 'error', 'validating', '');
|
const ValidateStatuses = tuple('success', 'warning', 'error', 'validating', '');
|
||||||
export type ValidateStatus = typeof ValidateStatuses[number];
|
export type ValidateStatus = typeof ValidateStatuses[number];
|
||||||
@ -306,7 +307,7 @@ function FormItem(props: FormItemProps): React.ReactElement {
|
|||||||
'Form.Item',
|
'Form.Item',
|
||||||
'Must set `name` or use render props when `dependencies` is set.',
|
'Must set `name` or use render props when `dependencies` is set.',
|
||||||
);
|
);
|
||||||
} else if (React.isValidElement(children)) {
|
} else if (isValidElement(children)) {
|
||||||
devWarning(
|
devWarning(
|
||||||
children.props.defaultValue === undefined,
|
children.props.defaultValue === undefined,
|
||||||
'Form.Item',
|
'Form.Item',
|
||||||
@ -330,7 +331,7 @@ function FormItem(props: FormItemProps): React.ReactElement {
|
|||||||
value={mergedControl[props.valuePropName || 'value']}
|
value={mergedControl[props.valuePropName || 'value']}
|
||||||
update={updateRef.current}
|
update={updateRef.current}
|
||||||
>
|
>
|
||||||
{React.cloneElement(children, childProps)}
|
{cloneElement(children, childProps)}
|
||||||
</MemoInput>
|
</MemoInput>
|
||||||
);
|
);
|
||||||
} else if (isRenderProps && shouldUpdate && !hasName) {
|
} else if (isRenderProps && shouldUpdate && !hasName) {
|
||||||
|
@ -4,6 +4,7 @@ import CloseCircleFilled from '@ant-design/icons/CloseCircleFilled';
|
|||||||
import { tuple } from '../_util/type';
|
import { tuple } from '../_util/type';
|
||||||
import { InputProps, getInputClassName } from './Input';
|
import { InputProps, getInputClassName } from './Input';
|
||||||
import { SizeType } from '../config-provider/SizeContext';
|
import { SizeType } from '../config-provider/SizeContext';
|
||||||
|
import { cloneElement } from '../_util/reactNode';
|
||||||
|
|
||||||
const ClearableInputType = tuple('text', 'input');
|
const ClearableInputType = tuple('text', 'input');
|
||||||
|
|
||||||
@ -103,7 +104,7 @@ class ClearableLabeledInput extends React.Component<ClearableInputProps> {
|
|||||||
} = this.props;
|
} = this.props;
|
||||||
const suffixNode = this.renderSuffix(prefixCls);
|
const suffixNode = this.renderSuffix(prefixCls);
|
||||||
if (!hasPrefixSuffix(this.props)) {
|
if (!hasPrefixSuffix(this.props)) {
|
||||||
return React.cloneElement(element, {
|
return cloneElement(element, {
|
||||||
value,
|
value,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -126,7 +127,7 @@ class ClearableLabeledInput extends React.Component<ClearableInputProps> {
|
|||||||
onMouseUp={this.onInputMouseUp}
|
onMouseUp={this.onInputMouseUp}
|
||||||
>
|
>
|
||||||
{prefixNode}
|
{prefixNode}
|
||||||
{React.cloneElement(element, {
|
{cloneElement(element, {
|
||||||
style: null,
|
style: null,
|
||||||
value,
|
value,
|
||||||
className: getInputClassName(prefixCls, size, disabled),
|
className: getInputClassName(prefixCls, size, disabled),
|
||||||
@ -167,7 +168,7 @@ class ClearableLabeledInput extends React.Component<ClearableInputProps> {
|
|||||||
<span className={mergedGroupClassName} style={style}>
|
<span className={mergedGroupClassName} style={style}>
|
||||||
<span className={mergedWrapperClassName}>
|
<span className={mergedWrapperClassName}>
|
||||||
{addonBeforeNode}
|
{addonBeforeNode}
|
||||||
{React.cloneElement(labeledElement, { style: null })}
|
{cloneElement(labeledElement, { style: null })}
|
||||||
{addonAfterNode}
|
{addonAfterNode}
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
@ -177,7 +178,7 @@ class ClearableLabeledInput extends React.Component<ClearableInputProps> {
|
|||||||
renderTextAreaWithClearIcon(prefixCls: string, element: React.ReactElement<any>) {
|
renderTextAreaWithClearIcon(prefixCls: string, element: React.ReactElement<any>) {
|
||||||
const { value, allowClear, className, style, direction } = this.props;
|
const { value, allowClear, className, style, direction } = this.props;
|
||||||
if (!allowClear) {
|
if (!allowClear) {
|
||||||
return React.cloneElement(element, {
|
return cloneElement(element, {
|
||||||
value,
|
value,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -189,7 +190,7 @@ class ClearableLabeledInput extends React.Component<ClearableInputProps> {
|
|||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
<span className={affixWrapperCls} style={style}>
|
<span className={affixWrapperCls} style={style}>
|
||||||
{React.cloneElement(element, {
|
{cloneElement(element, {
|
||||||
style: null,
|
style: null,
|
||||||
value,
|
value,
|
||||||
})}
|
})}
|
||||||
|
@ -6,6 +6,7 @@ import Input, { InputProps } from './Input';
|
|||||||
import Button from '../button';
|
import Button from '../button';
|
||||||
import SizeContext, { SizeType } from '../config-provider/SizeContext';
|
import SizeContext, { SizeType } from '../config-provider/SizeContext';
|
||||||
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
||||||
|
import { replaceElement, cloneElement } from '../_util/reactNode';
|
||||||
|
|
||||||
export interface SearchProps extends InputProps {
|
export interface SearchProps extends InputProps {
|
||||||
inputPrefixCls?: string;
|
inputPrefixCls?: string;
|
||||||
@ -97,11 +98,9 @@ export default class Search extends React.Component<SearchProps, any> {
|
|||||||
|
|
||||||
if (suffix) {
|
if (suffix) {
|
||||||
return [
|
return [
|
||||||
React.isValidElement(suffix)
|
replaceElement(suffix, null, {
|
||||||
? React.cloneElement(suffix, {
|
|
||||||
key: 'suffix',
|
key: 'suffix',
|
||||||
})
|
}),
|
||||||
: null,
|
|
||||||
icon,
|
icon,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@ -125,7 +124,7 @@ export default class Search extends React.Component<SearchProps, any> {
|
|||||||
enterButtonAsElement.type &&
|
enterButtonAsElement.type &&
|
||||||
(enterButtonAsElement.type as typeof Button).__ANT_BUTTON === true;
|
(enterButtonAsElement.type as typeof Button).__ANT_BUTTON === true;
|
||||||
if (isAntdButton || enterButtonAsElement.type === 'button') {
|
if (isAntdButton || enterButtonAsElement.type === 'button') {
|
||||||
button = React.cloneElement(enterButtonAsElement, {
|
button = cloneElement(enterButtonAsElement, {
|
||||||
onMouseDown: this.onMouseDown,
|
onMouseDown: this.onMouseDown,
|
||||||
onClick: this.onSearch,
|
onClick: this.onSearch,
|
||||||
key: 'enterButton',
|
key: 'enterButton',
|
||||||
@ -155,11 +154,9 @@ export default class Search extends React.Component<SearchProps, any> {
|
|||||||
if (addonAfter) {
|
if (addonAfter) {
|
||||||
return [
|
return [
|
||||||
button,
|
button,
|
||||||
React.isValidElement(addonAfter)
|
replaceElement(addonAfter, null, {
|
||||||
? React.cloneElement(addonAfter, {
|
|
||||||
key: 'addonAfter',
|
key: 'addonAfter',
|
||||||
})
|
}),
|
||||||
: null,
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ import { RenderEmptyHandler, ConfigContext } from '../config-provider';
|
|||||||
import Pagination, { PaginationConfig } from '../pagination';
|
import Pagination, { PaginationConfig } from '../pagination';
|
||||||
import { Row } from '../grid';
|
import { Row } from '../grid';
|
||||||
import Item from './Item';
|
import Item from './Item';
|
||||||
|
import { cloneElement } from '../_util/reactNode';
|
||||||
|
|
||||||
export { ListItemProps, ListItemMetaProps } from './Item';
|
export { ListItemProps, ListItemMetaProps } from './Item';
|
||||||
|
|
||||||
@ -247,7 +248,7 @@ function List<T>({ pagination, ...props }: ListProps<T>) {
|
|||||||
if (splitDataSource.length > 0) {
|
if (splitDataSource.length > 0) {
|
||||||
const items = splitDataSource.map((item: any, index: number) => renderItem(item, index));
|
const items = splitDataSource.map((item: any, index: number) => renderItem(item, index));
|
||||||
const childrenList = React.Children.map(items, (child: any, index) =>
|
const childrenList = React.Children.map(items, (child: any, index) =>
|
||||||
React.cloneElement(child, {
|
cloneElement(child, {
|
||||||
key: keys[index],
|
key: keys[index],
|
||||||
colStyle,
|
colStyle,
|
||||||
}),
|
}),
|
||||||
|
@ -6,6 +6,7 @@ import { ClickParam } from '.';
|
|||||||
import MenuContext, { MenuContextProps } from './MenuContext';
|
import MenuContext, { MenuContextProps } from './MenuContext';
|
||||||
import Tooltip, { TooltipProps } from '../tooltip';
|
import Tooltip, { TooltipProps } from '../tooltip';
|
||||||
import { SiderContext, SiderContextProps } from '../layout/Sider';
|
import { SiderContext, SiderContextProps } from '../layout/Sider';
|
||||||
|
import { isValidElement } from '../_util/reactNode';
|
||||||
|
|
||||||
export interface MenuItemProps
|
export interface MenuItemProps
|
||||||
extends Omit<
|
extends Omit<
|
||||||
@ -43,7 +44,7 @@ export default class MenuItem extends React.Component<MenuItemProps> {
|
|||||||
const { icon, children } = this.props;
|
const { icon, children } = this.props;
|
||||||
// inline-collapsed.md demo 依赖 span 来隐藏文字,有 icon 属性,则内部包裹一个 span
|
// inline-collapsed.md demo 依赖 span 来隐藏文字,有 icon 属性,则内部包裹一个 span
|
||||||
// ref: https://github.com/ant-design/ant-design/pull/23456
|
// ref: https://github.com/ant-design/ant-design/pull/23456
|
||||||
if (!icon || (React.isValidElement(children) && children.type === 'span')) {
|
if (!icon || (isValidElement(children) && children.type === 'span')) {
|
||||||
return children;
|
return children;
|
||||||
}
|
}
|
||||||
return <span>{children}</span>;
|
return <span>{children}</span>;
|
||||||
|
@ -4,6 +4,7 @@ import { SubMenu as RcSubMenu } from 'rc-menu';
|
|||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import omit from 'omit.js';
|
import omit from 'omit.js';
|
||||||
import MenuContext, { MenuContextProps } from './MenuContext';
|
import MenuContext, { MenuContextProps } from './MenuContext';
|
||||||
|
import { isValidElement } from '../_util/reactNode';
|
||||||
|
|
||||||
interface TitleEventEntity {
|
interface TitleEventEntity {
|
||||||
key: string;
|
key: string;
|
||||||
@ -49,7 +50,7 @@ class SubMenu extends React.Component<SubMenuProps, any> {
|
|||||||
}
|
}
|
||||||
// inline-collapsed.md demo 依赖 span 来隐藏文字,有 icon 属性,则内部包裹一个 span
|
// inline-collapsed.md demo 依赖 span 来隐藏文字,有 icon 属性,则内部包裹一个 span
|
||||||
// ref: https://github.com/ant-design/ant-design/pull/23456
|
// ref: https://github.com/ant-design/ant-design/pull/23456
|
||||||
const titleIsSpan = React.isValidElement(title) && title.type === 'span';
|
const titleIsSpan = isValidElement(title) && title.type === 'span';
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{icon}
|
{icon}
|
||||||
|
@ -4,6 +4,7 @@ import omit from 'omit.js';
|
|||||||
import debounce from 'lodash/debounce';
|
import debounce from 'lodash/debounce';
|
||||||
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
||||||
import { tuple } from '../_util/type';
|
import { tuple } from '../_util/type';
|
||||||
|
import { isValidElement, cloneElement } from '../_util/reactNode';
|
||||||
|
|
||||||
const SpinSizes = tuple('small', 'default', 'large');
|
const SpinSizes = tuple('small', 'default', 'large');
|
||||||
export type SpinSize = typeof SpinSizes[number];
|
export type SpinSize = typeof SpinSizes[number];
|
||||||
@ -38,14 +39,14 @@ function renderIndicator(prefixCls: string, props: SpinProps): React.ReactNode {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (React.isValidElement(indicator)) {
|
if (isValidElement(indicator)) {
|
||||||
return React.cloneElement(indicator, {
|
return cloneElement(indicator, {
|
||||||
className: classNames(indicator.props.className, dotClassName),
|
className: classNames(indicator.props.className, dotClassName),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (React.isValidElement(defaultIndicator)) {
|
if (isValidElement(defaultIndicator)) {
|
||||||
return React.cloneElement(defaultIndicator as SpinIndicator, {
|
return cloneElement(defaultIndicator as SpinIndicator, {
|
||||||
className: classNames((defaultIndicator as SpinIndicator).props.className, dotClassName),
|
className: classNames((defaultIndicator as SpinIndicator).props.className, dotClassName),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import Statistic, { StatisticProps } from './Statistic';
|
import Statistic, { StatisticProps } from './Statistic';
|
||||||
import { formatCountdown, countdownValueType, FormatConfig } from './utils';
|
import { formatCountdown, countdownValueType, FormatConfig } from './utils';
|
||||||
|
import { cloneElement } from '../_util/reactNode';
|
||||||
|
|
||||||
const REFRESH_INTERVAL = 1000 / 30;
|
const REFRESH_INTERVAL = 1000 / 30;
|
||||||
|
|
||||||
@ -72,7 +73,7 @@ class Countdown extends React.Component<CountdownProps, {}> {
|
|||||||
|
|
||||||
// Countdown do not need display the timestamp
|
// Countdown do not need display the timestamp
|
||||||
valueRender = (node: React.ReactElement<HTMLDivElement>) =>
|
valueRender = (node: React.ReactElement<HTMLDivElement>) =>
|
||||||
React.cloneElement(node, {
|
cloneElement(node, {
|
||||||
title: undefined,
|
title: undefined,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ import RightOutlined from '@ant-design/icons/RightOutlined';
|
|||||||
|
|
||||||
import { TabsProps } from './index';
|
import { TabsProps } from './index';
|
||||||
import { ConfigConsumerProps, ConfigConsumer } from '../config-provider';
|
import { ConfigConsumerProps, ConfigConsumer } from '../config-provider';
|
||||||
|
import { cloneElement } from '../_util/reactNode';
|
||||||
|
|
||||||
export default class TabBar extends React.Component<TabsProps> {
|
export default class TabBar extends React.Component<TabsProps> {
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
@ -81,7 +82,7 @@ export default class TabBar extends React.Component<TabsProps> {
|
|||||||
RenderTabBar = <ScrollableInkTabBar {...renderProps} />;
|
RenderTabBar = <ScrollableInkTabBar {...renderProps} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
return React.cloneElement(RenderTabBar);
|
return cloneElement(RenderTabBar);
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
@ -10,6 +10,7 @@ import TabBar from './TabBar';
|
|||||||
|
|
||||||
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
||||||
import { isFlexSupported } from '../_util/styleChecker';
|
import { isFlexSupported } from '../_util/styleChecker';
|
||||||
|
import { cloneElement, isValidElement } from '../_util/reactNode';
|
||||||
|
|
||||||
export type TabsType = 'line' | 'card' | 'editable-card';
|
export type TabsType = 'line' | 'card' | 'editable-card';
|
||||||
export type TabsPosition = 'top' | 'right' | 'bottom' | 'left';
|
export type TabsPosition = 'top' | 'right' | 'bottom' | 'left';
|
||||||
@ -129,7 +130,7 @@ export default class Tabs extends React.Component<TabsProps, any> {
|
|||||||
if (type === 'editable-card') {
|
if (type === 'editable-card') {
|
||||||
childrenWithClose = [];
|
childrenWithClose = [];
|
||||||
React.Children.forEach(children as React.ReactNode, (child, index) => {
|
React.Children.forEach(children as React.ReactNode, (child, index) => {
|
||||||
if (!React.isValidElement(child)) return child;
|
if (!isValidElement(child)) return child;
|
||||||
let { closable } = child.props;
|
let { closable } = child.props;
|
||||||
const { closeIcon: customCloseIcon } = child.props;
|
const { closeIcon: customCloseIcon } = child.props;
|
||||||
closable = typeof closable === 'undefined' ? true : closable;
|
closable = typeof closable === 'undefined' ? true : closable;
|
||||||
@ -146,7 +147,7 @@ export default class Tabs extends React.Component<TabsProps, any> {
|
|||||||
);
|
);
|
||||||
const closeIcon = closable ? customIcon : null;
|
const closeIcon = closable ? customIcon : null;
|
||||||
childrenWithClose.push(
|
childrenWithClose.push(
|
||||||
React.cloneElement(child, {
|
cloneElement(child, {
|
||||||
tab: (
|
tab: (
|
||||||
<div className={closable ? undefined : `${prefixCls}-tab-unclosable`}>
|
<div className={closable ? undefined : `${prefixCls}-tab-unclosable`}>
|
||||||
{child.props.tab}
|
{child.props.tab}
|
||||||
|
@ -4,6 +4,7 @@ import LoadingOutlined from '@ant-design/icons/LoadingOutlined';
|
|||||||
|
|
||||||
import TimelineItem, { TimeLineItemProps } from './TimelineItem';
|
import TimelineItem, { TimeLineItemProps } from './TimelineItem';
|
||||||
import { ConfigContext } from '../config-provider';
|
import { ConfigContext } from '../config-provider';
|
||||||
|
import { cloneElement } from '../_util/reactNode';
|
||||||
|
|
||||||
export interface TimelineProps {
|
export interface TimelineProps {
|
||||||
prefixCls?: string;
|
prefixCls?: string;
|
||||||
@ -64,7 +65,7 @@ const Timeline: TimelineType = props => {
|
|||||||
const items = React.Children.map(truthyItems, (ele: React.ReactElement<any>, idx) => {
|
const items = React.Children.map(truthyItems, (ele: React.ReactElement<any>, idx) => {
|
||||||
const pendingClass = idx === itemsCount - 2 ? lastCls : '';
|
const pendingClass = idx === itemsCount - 2 ? lastCls : '';
|
||||||
const readyClass = idx === itemsCount - 1 ? lastCls : '';
|
const readyClass = idx === itemsCount - 1 ? lastCls : '';
|
||||||
return React.cloneElement(ele, {
|
return cloneElement(ele, {
|
||||||
className: classNames([
|
className: classNames([
|
||||||
ele.props.className,
|
ele.props.className,
|
||||||
!reverse && !!pending ? pendingClass : readyClass,
|
!reverse && !!pending ? pendingClass : readyClass,
|
||||||
|
@ -5,6 +5,7 @@ import classNames from 'classnames';
|
|||||||
import { BuildInPlacements } from 'rc-trigger/lib/interface';
|
import { BuildInPlacements } from 'rc-trigger/lib/interface';
|
||||||
import getPlacements, { AdjustOverflow, PlacementsConfig } from './placements';
|
import getPlacements, { AdjustOverflow, PlacementsConfig } from './placements';
|
||||||
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
||||||
|
import { cloneElement, isValidElement } from '../_util/reactNode';
|
||||||
|
|
||||||
export { AdjustOverflow, PlacementsConfig };
|
export { AdjustOverflow, PlacementsConfig };
|
||||||
|
|
||||||
@ -105,7 +106,7 @@ function getDisabledCompatibleChildren(element: React.ReactElement<any>, prefixC
|
|||||||
...omitted,
|
...omitted,
|
||||||
pointerEvents: 'none',
|
pointerEvents: 'none',
|
||||||
};
|
};
|
||||||
const child = React.cloneElement(element, {
|
const child = cloneElement(element, {
|
||||||
style: buttonStyle,
|
style: buttonStyle,
|
||||||
className: null,
|
className: null,
|
||||||
});
|
});
|
||||||
@ -243,7 +244,7 @@ class Tooltip extends React.Component<TooltipProps, any> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const child = getDisabledCompatibleChildren(
|
const child = getDisabledCompatibleChildren(
|
||||||
React.isValidElement(children) ? children : <span>{children}</span>,
|
isValidElement(children) ? children : <span>{children}</span>,
|
||||||
prefixCls,
|
prefixCls,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -268,7 +269,7 @@ class Tooltip extends React.Component<TooltipProps, any> {
|
|||||||
onVisibleChange={this.onVisibleChange}
|
onVisibleChange={this.onVisibleChange}
|
||||||
onPopupAlign={this.onPopupAlign}
|
onPopupAlign={this.onPopupAlign}
|
||||||
>
|
>
|
||||||
{visible ? React.cloneElement(child, { className: childCls }) : child}
|
{visible ? cloneElement(child, { className: childCls }) : child}
|
||||||
</RcTooltip>
|
</RcTooltip>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -16,13 +16,14 @@ import {
|
|||||||
import Search from './search';
|
import Search from './search';
|
||||||
import DefaultListBody, { TransferListBodyProps, OmitProps } from './ListBody';
|
import DefaultListBody, { TransferListBodyProps, OmitProps } from './ListBody';
|
||||||
import { PaginationType } from './interface';
|
import { PaginationType } from './interface';
|
||||||
|
import { isValidElement } from '../_util/reactNode';
|
||||||
|
|
||||||
const defaultRender = () => null;
|
const defaultRender = () => null;
|
||||||
|
|
||||||
function isRenderResultPlainObject(result: RenderResult) {
|
function isRenderResultPlainObject(result: RenderResult) {
|
||||||
return (
|
return (
|
||||||
result &&
|
result &&
|
||||||
!React.isValidElement(result) &&
|
!isValidElement(result) &&
|
||||||
Object.prototype.toString.call(result) === '[object Object]'
|
Object.prototype.toString.call(result) === '[object Object]'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import MinusSquareOutlined from '@ant-design/icons/MinusSquareOutlined';
|
|||||||
import PlusSquareOutlined from '@ant-design/icons/PlusSquareOutlined';
|
import PlusSquareOutlined from '@ant-design/icons/PlusSquareOutlined';
|
||||||
import CaretDownFilled from '@ant-design/icons/CaretDownFilled';
|
import CaretDownFilled from '@ant-design/icons/CaretDownFilled';
|
||||||
import { AntTreeNodeProps } from '../Tree';
|
import { AntTreeNodeProps } from '../Tree';
|
||||||
|
import { isValidElement, cloneElement } from '../../_util/reactNode';
|
||||||
|
|
||||||
export default function renderSwitcherIcon(
|
export default function renderSwitcherIcon(
|
||||||
prefixCls: string,
|
prefixCls: string,
|
||||||
@ -20,8 +21,8 @@ export default function renderSwitcherIcon(
|
|||||||
return showLine ? <FileOutlined className={`${prefixCls}-switcher-line-icon`} /> : null;
|
return showLine ? <FileOutlined className={`${prefixCls}-switcher-line-icon`} /> : null;
|
||||||
}
|
}
|
||||||
const switcherCls = `${prefixCls}-switcher-icon`;
|
const switcherCls = `${prefixCls}-switcher-icon`;
|
||||||
if (React.isValidElement(switcherIcon)) {
|
if (isValidElement(switcherIcon)) {
|
||||||
return React.cloneElement(switcherIcon, {
|
return cloneElement(switcherIcon, {
|
||||||
className: classNames(switcherIcon.props.className || '', switcherCls),
|
className: classNames(switcherIcon.props.className || '', switcherCls),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ import { previewImage, isImageUrl } from './utils';
|
|||||||
import Tooltip from '../tooltip';
|
import Tooltip from '../tooltip';
|
||||||
import Progress from '../progress';
|
import Progress from '../progress';
|
||||||
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
||||||
|
import { cloneElement, isValidElement } from '../_util/reactNode';
|
||||||
|
|
||||||
export default class UploadList extends React.Component<UploadListProps, any> {
|
export default class UploadList extends React.Component<UploadListProps, any> {
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
@ -98,8 +99,8 @@ export default class UploadList extends React.Component<UploadListProps, any> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
handleActionIconRender = (customIcon: React.ReactNode, callback: () => void, title?: string) => {
|
handleActionIconRender = (customIcon: React.ReactNode, callback: () => void, title?: string) => {
|
||||||
if (React.isValidElement(customIcon)) {
|
if (isValidElement(customIcon)) {
|
||||||
return React.cloneElement(customIcon, {
|
return cloneElement(customIcon, {
|
||||||
...customIcon.props,
|
...customIcon.props,
|
||||||
title,
|
title,
|
||||||
onClick: (e: React.MouseEvent<HTMLElement>) => {
|
onClick: (e: React.MouseEvent<HTMLElement>) => {
|
||||||
|
@ -56,7 +56,6 @@ function processWebpackThemeConfig(themeConfig, theme, vars) {
|
|||||||
themeConfig.forEach(config => {
|
themeConfig.forEach(config => {
|
||||||
ignoreMomentLocale(config);
|
ignoreMomentLocale(config);
|
||||||
externalMoment(config);
|
externalMoment(config);
|
||||||
injectWarningCondition(config);
|
|
||||||
|
|
||||||
// rename default entry to ${theme} entry
|
// rename default entry to ${theme} entry
|
||||||
Object.keys(config.entry).forEach(entryName => {
|
Object.keys(config.entry).forEach(entryName => {
|
||||||
@ -87,6 +86,10 @@ const webpackConfig = getWebpackConfig(false);
|
|||||||
const webpackDarkConfig = getWebpackConfig(false);
|
const webpackDarkConfig = getWebpackConfig(false);
|
||||||
const webpackCompactConfig = getWebpackConfig(false);
|
const webpackCompactConfig = getWebpackConfig(false);
|
||||||
|
|
||||||
|
webpackConfig.forEach(config => {
|
||||||
|
injectWarningCondition(config);
|
||||||
|
});
|
||||||
|
|
||||||
if (process.env.RUN_ENV === 'PRODUCTION') {
|
if (process.env.RUN_ENV === 'PRODUCTION') {
|
||||||
webpackConfig.forEach(config => {
|
webpackConfig.forEach(config => {
|
||||||
ignoreMomentLocale(config);
|
ignoreMomentLocale(config);
|
||||||
|
Loading…
Reference in New Issue
Block a user