mirror of
https://gitee.com/ant-design/ant-design.git
synced 2024-11-30 02:59:04 +08:00
Merge pull request #18324 from ant-design/master
chore: Merge master into feature
This commit is contained in:
commit
8345554cd7
16
.github/main.workflow
vendored
16
.github/main.workflow
vendored
@ -4,11 +4,13 @@ workflow "Deploy website" {
|
||||
}
|
||||
|
||||
action "Deploy" {
|
||||
uses = "docker://node:10"
|
||||
runs = [
|
||||
"sh",
|
||||
"-c",
|
||||
"git config user.name antd-actions-bot && git config --local user.email support+actions@github.com && git remote set-url origin https://${DEPLOY_TOKEN}@github.com/ant-design/ant-design.git && npm install && npm run deploy"
|
||||
],
|
||||
secrets = ["DEPLOY_TOKEN"]
|
||||
uses = "JamesIves/github-pages-deploy-action@master"
|
||||
secrets = [
|
||||
"ACCESS_TOKEN",
|
||||
]
|
||||
env = {
|
||||
BUILD_SCRIPT = "npm install && npm run predeploy"
|
||||
BRANCH = "gh-pages"
|
||||
FOLDER = "_site"
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,12 @@
|
||||
const __NULL__ = { notExist: true };
|
||||
|
||||
export function spyElementPrototypes(Element, properties) {
|
||||
const propNames = Object.keys(properties);
|
||||
const originDescriptors = {};
|
||||
|
||||
propNames.forEach(propName => {
|
||||
const originDescriptor = Object.getOwnPropertyDescriptor(Element.prototype, propName);
|
||||
originDescriptors[propName] = originDescriptor;
|
||||
originDescriptors[propName] = originDescriptor || __NULL__;
|
||||
|
||||
const spyProp = properties[propName];
|
||||
|
||||
@ -37,7 +39,9 @@ export function spyElementPrototypes(Element, properties) {
|
||||
mockRestore() {
|
||||
propNames.forEach(propName => {
|
||||
const originDescriptor = originDescriptors[propName];
|
||||
if (typeof originDescriptor === 'function') {
|
||||
if (originDescriptor === __NULL__) {
|
||||
delete Element.prototype[propName];
|
||||
} else if (typeof originDescriptor === 'function') {
|
||||
Element.prototype[propName] = originDescriptor;
|
||||
} else {
|
||||
Object.defineProperty(Element.prototype, propName, originDescriptor);
|
||||
|
@ -9,6 +9,8 @@ import triggerEvent from '../triggerEvent';
|
||||
import Wave from '../wave';
|
||||
import TransButton from '../transButton';
|
||||
import openAnimation from '../openAnimation';
|
||||
import ResizeObserver from '../resizeObserver';
|
||||
import { spyElementPrototype } from '../../__tests__/util/domHook';
|
||||
|
||||
describe('Test utils function', () => {
|
||||
beforeAll(() => {
|
||||
@ -143,7 +145,9 @@ describe('Test utils function', () => {
|
||||
it('bindAnimationEvent should return when node is null', () => {
|
||||
const wrapper = mount(
|
||||
<Wave>
|
||||
<button type="button" disabled>button</button>
|
||||
<button type="button" disabled>
|
||||
button
|
||||
</button>
|
||||
</Wave>,
|
||||
).instance();
|
||||
expect(wrapper.bindAnimationEvent()).toBe(undefined);
|
||||
@ -152,7 +156,9 @@ describe('Test utils function', () => {
|
||||
it('bindAnimationEvent.onClick should return when children is hidden', () => {
|
||||
const wrapper = mount(
|
||||
<Wave>
|
||||
<button type="button" style={{ display: 'none' }}>button</button>
|
||||
<button type="button" style={{ display: 'none' }}>
|
||||
button
|
||||
</button>
|
||||
</Wave>,
|
||||
).instance();
|
||||
expect(wrapper.bindAnimationEvent()).toBe(undefined);
|
||||
@ -220,4 +226,47 @@ describe('Test utils function', () => {
|
||||
expect(done).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('ResizeObserver', () => {
|
||||
let domMock;
|
||||
|
||||
beforeAll(() => {
|
||||
domMock = spyElementPrototype(HTMLDivElement, 'getBoundingClientRect', () => {
|
||||
return {
|
||||
width: 1128 + Math.random(),
|
||||
height: 903 + Math.random(),
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
domMock.mockRestore();
|
||||
});
|
||||
|
||||
it('should not trigger `onResize` if size shaking', () => {
|
||||
const onResize = jest.fn();
|
||||
let divNode;
|
||||
|
||||
const wrapper = mount(
|
||||
<ResizeObserver onResize={onResize}>
|
||||
<div
|
||||
ref={node => {
|
||||
divNode = node;
|
||||
}}
|
||||
/>
|
||||
</ResizeObserver>,
|
||||
);
|
||||
|
||||
// First trigger
|
||||
wrapper.instance().onResize([{ target: divNode }]);
|
||||
onResize.mockReset();
|
||||
|
||||
// Repeat trigger should not trigger outer `onResize` with shaking
|
||||
for (let i = 0; i < 10; i += 1) {
|
||||
wrapper.instance().onResize([{ target: divNode }]);
|
||||
}
|
||||
|
||||
expect(onResize).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -10,9 +10,19 @@ interface ResizeObserverProps {
|
||||
onResize?: () => void;
|
||||
}
|
||||
|
||||
class ReactResizeObserver extends React.Component<ResizeObserverProps, {}> {
|
||||
interface ResizeObserverState {
|
||||
height: number;
|
||||
width: number;
|
||||
}
|
||||
|
||||
class ReactResizeObserver extends React.Component<ResizeObserverProps, ResizeObserverState> {
|
||||
resizeObserver: ResizeObserver | null = null;
|
||||
|
||||
state = {
|
||||
width: 0,
|
||||
height: 0,
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
this.onComponentUpdated();
|
||||
}
|
||||
@ -38,10 +48,30 @@ class ReactResizeObserver extends React.Component<ResizeObserverProps, {}> {
|
||||
}
|
||||
}
|
||||
|
||||
onResize = () => {
|
||||
onResize: ResizeObserverCallback = (entries: ResizeObserverEntry[]) => {
|
||||
const { onResize } = this.props;
|
||||
if (onResize) {
|
||||
onResize();
|
||||
|
||||
const { target } = entries[0];
|
||||
|
||||
const { width, height } = target.getBoundingClientRect();
|
||||
|
||||
/**
|
||||
* Resize observer trigger when content size changed.
|
||||
* In most case we just care about element size,
|
||||
* let's use `boundary` instead of `contentRect` here to avoid shaking.
|
||||
*/
|
||||
const fixedWidth = Math.floor(width);
|
||||
const fixedHeight = Math.floor(height);
|
||||
|
||||
if (this.state.width !== fixedWidth || this.state.height !== fixedHeight) {
|
||||
this.setState({
|
||||
width: fixedWidth,
|
||||
height: fixedHeight,
|
||||
});
|
||||
|
||||
if (onResize) {
|
||||
onResize();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
7
components/_util/warning.ts
Normal file
7
components/_util/warning.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import warning, { resetWarned } from 'rc-util/lib/warning';
|
||||
|
||||
export { resetWarned };
|
||||
|
||||
export default (valid: boolean, component: string, message: string): void => {
|
||||
warning(valid, `[antd: ${component}] ${message}`);
|
||||
};
|
@ -1,14 +0,0 @@
|
||||
import warning from 'warning';
|
||||
|
||||
let warned: Record<string, boolean> = {};
|
||||
|
||||
export function resetWarned() {
|
||||
warned = {};
|
||||
}
|
||||
|
||||
export default (valid: boolean, component: string, message: string): void => {
|
||||
if (!valid && !warned[message]) {
|
||||
warning(false, `[antd: ${component}] ${message}`);
|
||||
warned[message] = true;
|
||||
}
|
||||
};
|
@ -3,6 +3,7 @@ import { mount } from 'enzyme';
|
||||
import Affix from '..';
|
||||
import { getObserverEntities } from '../utils';
|
||||
import Button from '../../button';
|
||||
import { spyElementPrototype } from '../../__tests__/util/domHook';
|
||||
|
||||
const events = {};
|
||||
|
||||
@ -40,6 +41,7 @@ class AffixMounter extends React.Component {
|
||||
|
||||
describe('Affix Render', () => {
|
||||
let wrapper;
|
||||
let domMock;
|
||||
|
||||
const classRect = {
|
||||
container: {
|
||||
@ -48,23 +50,21 @@ describe('Affix Render', () => {
|
||||
},
|
||||
};
|
||||
|
||||
const originGetBoundingClientRect = HTMLElement.prototype.getBoundingClientRect;
|
||||
HTMLElement.prototype.getBoundingClientRect = function getBoundingClientRect() {
|
||||
return (
|
||||
classRect[this.className] || {
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
beforeAll(() => {
|
||||
jest.useFakeTimers();
|
||||
domMock = spyElementPrototype(HTMLElement, 'getBoundingClientRect', function mockBounding() {
|
||||
return (
|
||||
classRect[this.className] || {
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
jest.useRealTimers();
|
||||
HTMLElement.prototype.getBoundingClientRect = originGetBoundingClientRect;
|
||||
domMock.mockRestore();
|
||||
});
|
||||
const movePlaceholder = top => {
|
||||
classRect.fixed = {
|
||||
@ -185,7 +185,7 @@ describe('Affix Render', () => {
|
||||
.find('ReactResizeObserver')
|
||||
.at(index)
|
||||
.instance()
|
||||
.onResize();
|
||||
.onResize([{ target: { getBoundingClientRect: () => ({ width: 99, height: 99 }) } }]);
|
||||
jest.runAllTimers();
|
||||
|
||||
expect(updateCalled).toHaveBeenCalled();
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { createElement, Component } from 'react';
|
||||
import * as React from 'react';
|
||||
import omit from 'omit.js';
|
||||
import classNames from 'classnames';
|
||||
import { polyfill } from 'react-lifecycles-compat';
|
||||
@ -47,7 +47,7 @@ export interface ScrollNumberState {
|
||||
count?: string | number | null;
|
||||
}
|
||||
|
||||
class ScrollNumber extends Component<ScrollNumberProps, ScrollNumberState> {
|
||||
class ScrollNumber extends React.Component<ScrollNumberProps, ScrollNumberState> {
|
||||
static defaultProps = {
|
||||
count: null,
|
||||
onAnimated() {},
|
||||
@ -126,7 +126,7 @@ class ScrollNumber extends Component<ScrollNumberProps, ScrollNumberState> {
|
||||
const position = this.getPositionByNum(num, i);
|
||||
const removeTransition =
|
||||
this.state.animateStarted || getNumberArray(this.lastCount)[i] === undefined;
|
||||
return createElement(
|
||||
return React.createElement(
|
||||
'span',
|
||||
{
|
||||
className: `${prefixCls}-only`,
|
||||
@ -200,7 +200,7 @@ class ScrollNumber extends Component<ScrollNumberProps, ScrollNumberState> {
|
||||
),
|
||||
});
|
||||
}
|
||||
return createElement(component as any, newProps, this.renderNumberElement(prefixCls));
|
||||
return React.createElement(component as any, newProps, this.renderNumberElement(prefixCls));
|
||||
};
|
||||
|
||||
render() {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { cloneElement } from 'react';
|
||||
import * as React from 'react';
|
||||
import * as PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import BreadcrumbItem from './BreadcrumbItem';
|
||||
@ -151,9 +151,9 @@ export default class Breadcrumb extends React.Component<BreadcrumbProps, any> {
|
||||
"Only accepts Breadcrumb.Item and Breadcrumb.Separator as it's children",
|
||||
);
|
||||
|
||||
return cloneElement(element, {
|
||||
return React.cloneElement(element, {
|
||||
separator,
|
||||
key: index,
|
||||
key: index, // eslint-disable-line react/no-array-index-key
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -23,6 +23,9 @@
|
||||
|
||||
& > span:last-child {
|
||||
color: @breadcrumb-last-item-color;
|
||||
a {
|
||||
color: @breadcrumb-last-item-color;
|
||||
}
|
||||
}
|
||||
|
||||
& > span:last-child &-separator {
|
||||
|
@ -349,6 +349,74 @@ exports[`Cascader can be selected 3`] = `
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Cascader have a notFoundContent that fit trigger input width 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="ant-cascader-menus ant-cascader-menus-placement-bottomLeft slide-up-appear"
|
||||
style="left: -999px; top: -995px;"
|
||||
>
|
||||
<div>
|
||||
<ul
|
||||
class="ant-cascader-menu"
|
||||
style="height: auto;"
|
||||
>
|
||||
<li
|
||||
class="ant-cascader-menu-item ant-cascader-menu-item-disabled"
|
||||
role="menuitem"
|
||||
title=""
|
||||
>
|
||||
<div
|
||||
class="ant-empty ant-empty-normal ant-empty-small"
|
||||
>
|
||||
<div
|
||||
class="ant-empty-image"
|
||||
>
|
||||
<svg
|
||||
height="41"
|
||||
viewBox="0 0 64 41"
|
||||
width="64"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g
|
||||
fill="none"
|
||||
fill-rule="evenodd"
|
||||
transform="translate(0 1)"
|
||||
>
|
||||
<ellipse
|
||||
cx="32"
|
||||
cy="33"
|
||||
fill="#F5F5F5"
|
||||
rx="32"
|
||||
ry="7"
|
||||
/>
|
||||
<g
|
||||
fill-rule="nonzero"
|
||||
stroke="#D9D9D9"
|
||||
>
|
||||
<path
|
||||
d="M55 12.76L44.854 1.258C44.367.474 43.656 0 42.907 0H21.093c-.749 0-1.46.474-1.947 1.257L9 12.761V22h46v-9.24z"
|
||||
/>
|
||||
<path
|
||||
d="M41.613 15.931c0-1.605.994-2.93 2.227-2.931H55v18.137C55 33.26 53.68 35 52.05 35h-40.1C10.32 35 9 33.259 9 31.137V13h11.16c1.233 0 2.227 1.323 2.227 2.928v.022c0 1.605 1.005 2.901 2.237 2.901h14.752c1.232 0 2.237-1.308 2.237-2.913v-.007z"
|
||||
fill="#FAFAFA"
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
<p
|
||||
class="ant-empty-description"
|
||||
>
|
||||
No Data
|
||||
</p>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Cascader popup correctly when panel is hidden 1`] = `
|
||||
<div>
|
||||
<div
|
||||
|
@ -471,4 +471,16 @@ describe('Cascader', () => {
|
||||
mount(<Cascader options={optionsWithChildrenNull} />);
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
// https://github.com/ant-design/ant-design/issues/18176
|
||||
it('have a notFoundContent that fit trigger input width', () => {
|
||||
const wrapper = mount(<Cascader popupVisible options={[]} fieldNames={{ label: 'name', value: 'code', children: 'items' }} />);
|
||||
const popupWrapper = mount(
|
||||
wrapper
|
||||
.find('Trigger')
|
||||
.instance()
|
||||
.getComponent(),
|
||||
);
|
||||
expect(popupWrapper.render()).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
@ -496,12 +496,12 @@ class Cascader extends React.Component<CascaderProps, CascaderState> {
|
||||
]);
|
||||
|
||||
let { options } = props;
|
||||
const names: FilledFieldNamesType = getFilledFieldNames(this.props);
|
||||
if (options && options.length > 0) {
|
||||
if (state.inputValue) {
|
||||
options = this.generateFilteredOptions(prefixCls, renderEmpty);
|
||||
}
|
||||
} else {
|
||||
const names: FilledFieldNamesType = getFilledFieldNames(this.props);
|
||||
options = [
|
||||
{
|
||||
[names.label]: notFoundContent || renderEmpty('Cascader'),
|
||||
@ -519,7 +519,7 @@ class Cascader extends React.Component<CascaderProps, CascaderState> {
|
||||
|
||||
const dropdownMenuColumnStyle: { width?: number; height?: string } = {};
|
||||
const isNotFound =
|
||||
(options || []).length === 1 && options[0].value === 'ANT_CASCADER_NOT_FOUND';
|
||||
(options || []).length === 1 && options[0][names.value] === 'ANT_CASCADER_NOT_FOUND';
|
||||
if (isNotFound) {
|
||||
dropdownMenuColumnStyle.height = 'auto'; // Height of one row.
|
||||
}
|
||||
@ -554,7 +554,7 @@ class Cascader extends React.Component<CascaderProps, CascaderState> {
|
||||
value={state.inputValue}
|
||||
disabled={disabled}
|
||||
readOnly={!showSearch}
|
||||
autoComplete="off"
|
||||
autoComplete={inputProps.autoComplete || 'off'}
|
||||
onClick={showSearch ? this.handleInputClick : undefined}
|
||||
onBlur={showSearch ? this.handleInputBlur : undefined}
|
||||
onKeyDown={this.handleKeyDown}
|
||||
|
@ -20,6 +20,7 @@ export interface SubMenuProps {
|
||||
onTitleMouseEnter?: (e: TitleEventEntity) => void;
|
||||
onTitleMouseLeave?: (e: TitleEventEntity) => void;
|
||||
popupOffset?: [number, number];
|
||||
popupClassName?: string;
|
||||
}
|
||||
|
||||
class SubMenu extends React.Component<SubMenuProps, any> {
|
||||
@ -41,14 +42,14 @@ class SubMenu extends React.Component<SubMenuProps, any> {
|
||||
};
|
||||
|
||||
render() {
|
||||
const { rootPrefixCls, className } = this.props;
|
||||
const { rootPrefixCls, popupClassName } = this.props;
|
||||
return (
|
||||
<MenuContext.Consumer>
|
||||
{({ antdMenuTheme }: MenuContextProps) => (
|
||||
<RcSubMenu
|
||||
{...this.props}
|
||||
ref={this.saveSubMenu}
|
||||
popupClassName={classNames(`${rootPrefixCls}-${antdMenuTheme}`, className)}
|
||||
popupClassName={classNames(`${rootPrefixCls}-${antdMenuTheme}`, popupClassName)}
|
||||
/>
|
||||
)}
|
||||
</MenuContext.Consumer>
|
||||
|
@ -62,6 +62,7 @@ More layouts with navigation: [layout](/components/layout).
|
||||
|
||||
| Param | Description | Type | Default value | Version |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| popupClassName | sub menu class name | string | | 3.21.5 |
|
||||
| children | sub menus or sub menu items | Array<MenuItem\|SubMenu> | | |
|
||||
| disabled | whether sub menu is disabled or not | boolean | false | |
|
||||
| key | unique id of the sub menu | string | | |
|
||||
|
@ -61,13 +61,14 @@ subtitle: 导航菜单
|
||||
|
||||
### Menu.SubMenu
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||
| ------------ | -------------- | --------------------------- | ------ | ---- |
|
||||
| children | 子菜单的菜单项 | Array<MenuItem\|SubMenu> | | |
|
||||
| disabled | 是否禁用 | boolean | false | |
|
||||
| key | 唯一标志 | string | | |
|
||||
| title | 子菜单项值 | string\|ReactNode | | |
|
||||
| onTitleClick | 点击子菜单标题 | function({ key, domEvent }) | | |
|
||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||
| -------------- | -------------- | --------------------------- | ------ | ------ |
|
||||
| popupClassName | 子菜单样式 | string | | 3.21.5 |
|
||||
| children | 子菜单的菜单项 | Array<MenuItem\|SubMenu> | | |
|
||||
| disabled | 是否禁用 | boolean | false | |
|
||||
| key | 唯一标志 | string | | |
|
||||
| title | 子菜单项值 | string\|ReactNode | | |
|
||||
| onTitleClick | 点击子菜单标题 | function({ key, domEvent }) | | |
|
||||
|
||||
### Menu.ItemGroup
|
||||
|
||||
|
@ -17,7 +17,7 @@ The difference with the `confirm` modal dialog is that it's more lightweight tha
|
||||
| Param | Description | Type | Default value | Version |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| cancelText | text of the Cancel button | string | `Cancel` | |
|
||||
| okText | text of the Confirm button | string | `Confirm` | |
|
||||
| okText | text of the Confirm button | string | `OK` | |
|
||||
| okType | Button `type` of the Confirm button | string | `primary` | |
|
||||
| title | title of the confirmation box | string\|ReactNode | - | |
|
||||
| onCancel | callback of cancel | function(e) | - | |
|
||||
|
@ -46,7 +46,12 @@
|
||||
|
||||
&-circle-path {
|
||||
animation: ~'@{ant-prefix}-progress-appear' 0.3s;
|
||||
stroke: @progress-default-color;
|
||||
}
|
||||
|
||||
&-inner:not(.@{ant-prefix}-progress-circle-gradient) {
|
||||
.@{ant-prefix}-progress-circle-path {
|
||||
stroke: @progress-default-color;
|
||||
}
|
||||
}
|
||||
|
||||
&-success-bg,
|
||||
@ -102,6 +107,9 @@
|
||||
.@{progress-prefix-cls}-text {
|
||||
color: @error-color;
|
||||
}
|
||||
}
|
||||
|
||||
&-status-exception &-inner:not(.@{progress-prefix-cls}-circle-gradient) {
|
||||
.@{progress-prefix-cls}-circle-path {
|
||||
stroke: @error-color;
|
||||
}
|
||||
@ -114,6 +122,9 @@
|
||||
.@{progress-prefix-cls}-text {
|
||||
color: @success-color;
|
||||
}
|
||||
}
|
||||
|
||||
&-status-success &-inner:not(.@{progress-prefix-cls}-circle-gradient) {
|
||||
.@{progress-prefix-cls}-circle-path {
|
||||
stroke: @success-color;
|
||||
}
|
||||
@ -153,12 +164,6 @@
|
||||
color: @success-color;
|
||||
}
|
||||
}
|
||||
|
||||
&-circle-gradient {
|
||||
.@{progress-prefix-cls}-circle-path {
|
||||
stroke: url(#gradient);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes ~"@{ant-prefix}-progress-active" {
|
||||
|
@ -5,6 +5,7 @@ import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
||||
export interface CheckableTagProps {
|
||||
prefixCls?: string;
|
||||
className?: string;
|
||||
style?: React.CSSProperties;
|
||||
checked: boolean;
|
||||
onChange?: (checked: boolean) => void;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { cloneElement } from 'react';
|
||||
import * as React from 'react';
|
||||
import { polyfill } from 'react-lifecycles-compat';
|
||||
import RcTooltip from 'rc-tooltip';
|
||||
import classNames from 'classnames';
|
||||
@ -115,7 +115,7 @@ function getDisabledCompatibleChildren(element: React.ReactElement<any>) {
|
||||
...omitted,
|
||||
pointerEvents: 'none',
|
||||
};
|
||||
const child = cloneElement(element, {
|
||||
const child = React.cloneElement(element, {
|
||||
style: buttonStyle,
|
||||
className: null,
|
||||
});
|
||||
@ -263,7 +263,7 @@ class Tooltip extends React.Component<TooltipProps, any> {
|
||||
onVisibleChange={this.onVisibleChange}
|
||||
onPopupAlign={this.onPopupAlign}
|
||||
>
|
||||
{visible ? cloneElement(child, { className: childCls }) : child}
|
||||
{visible ? React.cloneElement(child, { className: childCls }) : child}
|
||||
</RcTooltip>
|
||||
);
|
||||
};
|
||||
|
@ -74,7 +74,7 @@ export const isImageUrl = (file: UploadFile): boolean => {
|
||||
}
|
||||
const url: string = (file.thumbUrl || file.url) as string;
|
||||
const extension = extname(url);
|
||||
if (/^data:image\//.test(url) || /(webp|svg|png|gif|jpg|jpeg|bmp|dpg)$/i.test(extension)) {
|
||||
if (/^data:image\//.test(url) || /(webp|svg|png|gif|jpg|jpeg|jfif|bmp|dpg)$/i.test(extension)) {
|
||||
return true;
|
||||
}
|
||||
if (/^data:/.test(url)) {
|
||||
|
@ -87,7 +87,7 @@
|
||||
"rc-tree-select": "~2.9.1",
|
||||
"rc-trigger": "^2.6.2",
|
||||
"rc-upload": "~2.7.0",
|
||||
"rc-util": "^4.6.0",
|
||||
"rc-util": "^4.10.0",
|
||||
"react-lazy-load": "^3.0.13",
|
||||
"react-lifecycles-compat": "^3.0.4",
|
||||
"react-slick": "~0.25.2",
|
||||
@ -136,6 +136,7 @@
|
||||
"eslint-plugin-react": "^7.14.2",
|
||||
"eslint-tinker": "^0.5.0",
|
||||
"fetch-jsonp": "^1.1.3",
|
||||
"full-icu": "^1.3.0",
|
||||
"glob": "^7.1.4",
|
||||
"husky": "^3.0.2",
|
||||
"immutability-helper": "^3.0.0",
|
||||
@ -143,6 +144,7 @@
|
||||
"jest": "^24.8.0",
|
||||
"jsdom": "^15.1.1",
|
||||
"jsonml.js": "^0.1.0",
|
||||
"less": "~3.9.0",
|
||||
"logrocket": "^1.0.0",
|
||||
"logrocket-react": "^3.0.0",
|
||||
"lz-string": "^1.4.4",
|
||||
@ -210,7 +212,7 @@
|
||||
"tsc": "tsc",
|
||||
"start": "rimraf _site && mkdir _site && node ./scripts/generateColorLess.js && cross-env NODE_ENV=development bisheng start -c ./site/bisheng.config.js",
|
||||
"start:preact": "node ./scripts/generateColorLess.js && cross-env NODE_ENV=development REACT_ENV=preact bisheng start -c ./site/bisheng.config.js",
|
||||
"site": "bisheng build --ssr -c ./site/bisheng.config.js && node ./scripts/generateColorLess.js",
|
||||
"site": "cross-env NODE_ICU_DATA=node_modules/full-icu bisheng build --ssr -c ./site/bisheng.config.js && node ./scripts/generateColorLess.js",
|
||||
"predeploy": "antd-tools run clean && npm run site && cp netlify.toml CNAME _site && cp .circleci/config.yml _site",
|
||||
"deploy": "bisheng gh-pages --push-only",
|
||||
"deploy:china-mirror": "git checkout gh-pages && git pull origin gh-pages && git push git@gitee.com:ant-design/ant-design.git gh-pages",
|
||||
|
Loading…
Reference in New Issue
Block a user