fix: unexpected changes of snapshots

This commit is contained in:
orzyyyy 2019-08-05 18:38:10 +08:00
parent 649e8127c5
commit 63b33d4020
146 changed files with 2601 additions and 1933 deletions

View File

@ -1,5 +1,11 @@
const eslintrc = { const eslintrc = {
extends: ['airbnb', 'prettier', 'plugin:jest/recommended', 'plugin:react/recommended'], extends: [
'airbnb',
'prettier',
'plugin:jest/recommended',
'plugin:react/recommended',
'plugin:import/typescript',
],
env: { env: {
browser: true, browser: true,
node: true, node: true,
@ -14,6 +20,15 @@ const eslintrc = {
}, },
parser: '@typescript-eslint/parser', parser: '@typescript-eslint/parser',
plugins: ['markdown', 'react', 'babel', 'jest', '@typescript-eslint'], plugins: ['markdown', 'react', 'babel', 'jest', '@typescript-eslint'],
// https://github.com/typescript-eslint/typescript-eslint/issues/46#issuecomment-470486034
overrides: [
{
files: ['*.tsx'],
rules: {
'@typescript-eslint/no-unused-vars': [2, { args: 'none' }],
},
},
],
rules: { rules: {
'react/jsx-one-expression-per-line': 0, 'react/jsx-one-expression-per-line': 0,
'react/prop-types': 0, 'react/prop-types': 0,
@ -34,12 +49,34 @@ const eslintrc = {
], ],
}, },
], ],
'react/jsx-filename-extension': [1, { extensions: ['.js', '.jsx', '.md'] }],
'jsx-a11y/no-static-element-interactions': 0, 'jsx-a11y/no-static-element-interactions': 0,
'jsx-a11y/anchor-has-content': 0, 'jsx-a11y/anchor-has-content': 0,
'jsx-a11y/click-events-have-key-events': 0, 'jsx-a11y/click-events-have-key-events': 0,
'jsx-a11y/anchor-is-valid': 0, 'jsx-a11y/anchor-is-valid': 0,
'comma-dangle': ['error', 'always-multiline'], 'comma-dangle': ['error', 'always-multiline'],
'react/jsx-filename-extension': 0,
'prefer-destructuring': 0, // TODO: remove later
'consistent-return': 0, // TODO: remove later
'no-return-assign': 0, // TODO: remove later
'no-param-reassign': 0, // TODO: remove later
'react/destructuring-assignment': 0, // TODO: remove later
'react/no-did-update-set-state': 0, // TODO: remove later
'react/require-default-props': 0,
'react/default-props-match-prop-types': 0,
'import/no-cycle': 0,
'react/no-find-dom-node': 0,
'no-underscore-dangle': 0,
// label-has-for has been deprecated
// https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/label-has-for.md
'jsx-a11y/label-has-for': 0,
// for (let i = 0; i < len; i++)
'no-plusplus': 0,
// https://eslint.org/docs/rules/no-continue
// labeledLoop is conflicted with `eslint . --fix`
'no-continue': 0,
'react/display-name': 0,
// ban this for Number.isNaN needs polyfill
'no-restricted-globals': 0,
}, },
}; };
@ -61,11 +98,6 @@ if (process.env.RUN_ENV === 'DEMO') {
'react/destructuring-assignment': 0, 'react/destructuring-assignment': 0,
'react/no-multi-comp': 0, 'react/no-multi-comp': 0,
'jsx-a11y/href-no-hash': 0, 'jsx-a11y/href-no-hash': 0,
'prefer-destructuring': 0, // TODO: remove later
'max-len': 0, // TODO: remove later
'consistent-return': 0, // TODO: remove later
'no-return-assign': 0, // TODO: remove later
'no-param-reassign': 0, // TODO: remove later
'import/no-extraneous-dependencies': 0, 'import/no-extraneous-dependencies': 0,
}); });
} }

View File

@ -27,7 +27,7 @@ const getCollapsedHeight: MotionFunc = () => ({ height: 0, opacity: 0 });
const getRealHeight: MotionFunc = node => ({ height: node.scrollHeight, opacity: 1 }); const getRealHeight: MotionFunc = node => ({ height: node.scrollHeight, opacity: 1 });
const getCurrentHeight: MotionFunc = node => ({ height: node.offsetHeight }); const getCurrentHeight: MotionFunc = node => ({ height: node.offsetHeight });
export const collapseMotion: Motion = { const collapseMotion: Motion = {
motionName: 'ant-motion-collapse', motionName: 'ant-motion-collapse',
onAppearStart: getCollapsedHeight, onAppearStart: getCollapsedHeight,
onEnterStart: getCollapsedHeight, onEnterStart: getCollapsedHeight,
@ -36,3 +36,5 @@ export const collapseMotion: Motion = {
onLeaveStart: getCurrentHeight, onLeaveStart: getCurrentHeight,
onLeaveActive: getCollapsedHeight, onLeaveActive: getCollapsedHeight,
}; };
export default collapseMotion;

View File

@ -26,6 +26,7 @@ export function throttleByAnimationFrameDecorator() {
return { return {
configurable: true, configurable: true,
get() { get() {
/* eslint-disable no-prototype-builtins */
if (definingProperty || this === target.prototype || this.hasOwnProperty(key)) { if (definingProperty || this === target.prototype || this.hasOwnProperty(key)) {
return fn; return fn;
} }

View File

@ -20,6 +20,7 @@ const inlineStyle: React.CSSProperties = {
class TransButton extends React.Component<TransButtonProps> { class TransButton extends React.Component<TransButtonProps> {
div?: HTMLDivElement; div?: HTMLDivElement;
lastKeyCode?: number; lastKeyCode?: number;
onKeyDown: React.KeyboardEventHandler<HTMLDivElement> = event => { onKeyDown: React.KeyboardEventHandler<HTMLDivElement> = event => {

View File

@ -1,7 +1,7 @@
import * as React from 'react'; import * as React from 'react';
import { findDOMNode } from 'react-dom'; import { findDOMNode } from 'react-dom';
import TransitionEvents from 'css-animation/lib/Event'; import TransitionEvents from 'css-animation/lib/Event';
import raf from '../_util/raf'; import raf from './raf';
import { ConfigConsumer, ConfigConsumerProps, CSPConfig } from '../config-provider'; import { ConfigConsumer, ConfigConsumerProps, CSPConfig } from '../config-provider';
let styleForPesudo: HTMLStyleElement | null; let styleForPesudo: HTMLStyleElement | null;
@ -14,24 +14,49 @@ function isHidden(element: HTMLElement) {
return !element || element.offsetParent === null; return !element || element.offsetParent === null;
} }
function isNotGrey(color: string) {
/* eslint-disable no-useless-escape */
const match = (color || '').match(/rgba?\((\d*), (\d*), (\d*)(, [\.\d]*)?\)/);
if (match && match[1] && match[2] && match[3]) {
return !(match[1] === match[2] && match[2] === match[3]);
}
return true;
}
export default class Wave extends React.Component<{ insertExtraNode?: boolean }> { export default class Wave extends React.Component<{ insertExtraNode?: boolean }> {
private instance?: { private instance?: {
cancel: () => void; cancel: () => void;
}; };
private extraNode: HTMLDivElement; private extraNode: HTMLDivElement;
private clickWaveTimeoutId: number; private clickWaveTimeoutId: number;
private animationStartId: number; private animationStartId: number;
private animationStart: boolean = false; private animationStart: boolean = false;
private destroy: boolean = false; private destroy: boolean = false;
private csp?: CSPConfig; private csp?: CSPConfig;
isNotGrey(color: string) { componentDidMount() {
const match = (color || '').match(/rgba?\((\d*), (\d*), (\d*)(, [\.\d]*)?\)/); const node = findDOMNode(this) as HTMLElement;
if (match && match[1] && match[2] && match[3]) { if (!node || node.nodeType !== 1) {
return !(match[1] === match[2] && match[2] === match[3]); return;
} }
return true; this.instance = this.bindAnimationEvent(node);
}
componentWillUnmount() {
if (this.instance) {
this.instance.cancel();
}
if (this.clickWaveTimeoutId) {
clearTimeout(this.clickWaveTimeoutId);
}
this.destroy = true;
} }
onClick = (node: HTMLElement, waveColor: string) => { onClick = (node: HTMLElement, waveColor: string) => {
@ -40,7 +65,7 @@ export default class Wave extends React.Component<{ insertExtraNode?: boolean }>
} }
const { insertExtraNode } = this.props; const { insertExtraNode } = this.props;
this.extraNode = document.createElement('div'); this.extraNode = document.createElement('div');
const extraNode = this.extraNode; const { extraNode } = this;
extraNode.className = 'ant-click-animating-node'; extraNode.className = 'ant-click-animating-node';
const attributeName = this.getAttributeName(); const attributeName = this.getAttributeName();
node.setAttribute(attributeName, 'true'); node.setAttribute(attributeName, 'true');
@ -50,7 +75,7 @@ export default class Wave extends React.Component<{ insertExtraNode?: boolean }>
waveColor && waveColor &&
waveColor !== '#ffffff' && waveColor !== '#ffffff' &&
waveColor !== 'rgb(255, 255, 255)' && waveColor !== 'rgb(255, 255, 255)' &&
this.isNotGrey(waveColor) && isNotGrey(waveColor) &&
!/rgba\(\d*, \d*, \d*, 0\)/.test(waveColor) && // any transparent rgba color !/rgba\(\d*, \d*, \d*, 0\)/.test(waveColor) && // any transparent rgba color
waveColor !== 'transparent' waveColor !== 'transparent'
) { ) {
@ -75,6 +100,31 @@ export default class Wave extends React.Component<{ insertExtraNode?: boolean }>
TransitionEvents.addEndEventListener(node, this.onTransitionEnd); TransitionEvents.addEndEventListener(node, this.onTransitionEnd);
}; };
onTransitionStart = (e: AnimationEvent) => {
if (this.destroy) return;
const node = findDOMNode(this) as HTMLElement;
if (!e || e.target !== node) {
return;
}
if (!this.animationStart) {
this.resetEffect(node);
}
};
onTransitionEnd = (e: AnimationEvent) => {
if (!e || e.animationName !== 'fadeEffect') {
return;
}
this.resetEffect(e.target as HTMLElement);
};
getAttributeName() {
const { insertExtraNode } = this.props;
return insertExtraNode ? 'ant-click-animating' : 'ant-click-animating-without-extra-node';
}
bindAnimationEvent = (node: HTMLElement) => { bindAnimationEvent = (node: HTMLElement) => {
if ( if (
!node || !node ||
@ -113,11 +163,6 @@ export default class Wave extends React.Component<{ insertExtraNode?: boolean }>
}; };
}; };
getAttributeName() {
const { insertExtraNode } = this.props;
return insertExtraNode ? 'ant-click-animating' : 'ant-click-animating-without-extra-node';
}
resetEffect(node: HTMLElement) { resetEffect(node: HTMLElement) {
if (!node || node === this.extraNode || !(node instanceof Element)) { if (!node || node === this.extraNode || !(node instanceof Element)) {
return; return;
@ -125,7 +170,11 @@ export default class Wave extends React.Component<{ insertExtraNode?: boolean }>
const { insertExtraNode } = this.props; const { insertExtraNode } = this.props;
const attributeName = this.getAttributeName(); const attributeName = this.getAttributeName();
node.setAttribute(attributeName, 'false'); // edge has bug on `removeAttribute` #14466 node.setAttribute(attributeName, 'false'); // edge has bug on `removeAttribute` #14466
this.removeExtraStyleNode();
if (styleForPesudo) {
styleForPesudo.innerHTML = '';
}
if (insertExtraNode && this.extraNode && node.contains(this.extraNode)) { if (insertExtraNode && this.extraNode && node.contains(this.extraNode)) {
node.removeChild(this.extraNode); node.removeChild(this.extraNode);
} }
@ -133,51 +182,6 @@ export default class Wave extends React.Component<{ insertExtraNode?: boolean }>
TransitionEvents.removeEndEventListener(node, this.onTransitionEnd); TransitionEvents.removeEndEventListener(node, this.onTransitionEnd);
} }
onTransitionStart = (e: AnimationEvent) => {
if (this.destroy) return;
const node = findDOMNode(this) as HTMLElement;
if (!e || e.target !== node) {
return;
}
if (!this.animationStart) {
this.resetEffect(node);
}
};
onTransitionEnd = (e: AnimationEvent) => {
if (!e || e.animationName !== 'fadeEffect') {
return;
}
this.resetEffect(e.target as HTMLElement);
};
removeExtraStyleNode() {
if (styleForPesudo) {
styleForPesudo.innerHTML = '';
}
}
componentDidMount() {
const node = findDOMNode(this) as HTMLElement;
if (!node || node.nodeType !== 1) {
return;
}
this.instance = this.bindAnimationEvent(node);
}
componentWillUnmount() {
if (this.instance) {
this.instance.cancel();
}
if (this.clickWaveTimeoutId) {
clearTimeout(this.clickWaveTimeoutId);
}
this.destroy = true;
}
renderWave = ({ csp }: ConfigConsumerProps) => { renderWave = ({ csp }: ConfigConsumerProps) => {
const { children } = this.props; const { children } = this.props;
this.csp = csp; this.csp = csp;

View File

@ -63,7 +63,9 @@ class Affix extends React.Component<AffixProps, AffixState> {
}; };
placeholderNode: HTMLDivElement; placeholderNode: HTMLDivElement;
fixedNode: HTMLDivElement; fixedNode: HTMLDivElement;
private timeout: number; private timeout: number;
// Event handler // Event handler
@ -75,7 +77,7 @@ class Affix extends React.Component<AffixProps, AffixState> {
this.timeout = setTimeout(() => { this.timeout = setTimeout(() => {
addObserveTarget(target(), this); addObserveTarget(target(), this);
// Mock Event object. // Mock Event object.
this.updatePosition({} as Event); this.updatePosition();
}); });
} }
} }
@ -93,7 +95,7 @@ class Affix extends React.Component<AffixProps, AffixState> {
if (newTarget) { if (newTarget) {
addObserveTarget(newTarget, this); addObserveTarget(newTarget, this);
// Mock Event object. // Mock Event object.
this.updatePosition({} as Event); this.updatePosition();
} }
this.setState({ prevTarget: newTarget }); this.setState({ prevTarget: newTarget });
@ -103,7 +105,7 @@ class Affix extends React.Component<AffixProps, AffixState> {
prevProps.offsetTop !== this.props.offsetTop || prevProps.offsetTop !== this.props.offsetTop ||
prevProps.offsetBottom !== this.props.offsetBottom prevProps.offsetBottom !== this.props.offsetBottom
) { ) {
this.updatePosition({} as Event); this.updatePosition();
} }
this.measure(); this.measure();
@ -132,6 +134,7 @@ class Affix extends React.Component<AffixProps, AffixState> {
} }
return offsetTop; return offsetTop;
}; };
getOffsetBottom = () => { getOffsetBottom = () => {
return this.props.offsetBottom; return this.props.offsetBottom;
}; };
@ -145,60 +148,6 @@ class Affix extends React.Component<AffixProps, AffixState> {
}; };
// =================== Measure =================== // =================== Measure ===================
// Handle realign logic
@throttleByAnimationFrameDecorator()
updatePosition(event?: Event | null) {
this.prepareMeasure(event);
}
@throttleByAnimationFrameDecorator()
lazyUpdatePosition(event: Event) {
const { target } = this.props;
const { affixStyle } = this.state;
// Check position change before measure to make Safari smooth
if (target && affixStyle) {
const offsetTop = this.getOffsetTop();
const offsetBottom = this.getOffsetBottom();
const targetNode = target();
if (targetNode) {
const targetRect = getTargetRect(targetNode);
const placeholderReact = getTargetRect(this.placeholderNode);
const fixedTop = getFixedTop(placeholderReact, targetRect, offsetTop);
const fixedBottom = getFixedBottom(placeholderReact, targetRect, offsetBottom);
if (
(fixedTop !== undefined && affixStyle.top === fixedTop) ||
(fixedBottom !== undefined && affixStyle.bottom === fixedBottom)
) {
return;
}
}
}
// Directly call prepare measure since it's already throttled.
this.prepareMeasure(event);
}
// @ts-ignore TS6133
prepareMeasure = (event?: Event | null) => {
// event param is used before. Keep compatible ts define here.
this.setState({
status: AffixStatus.Prepare,
affixStyle: undefined,
placeholderStyle: undefined,
});
// Test if `updatePosition` called
if (process.env.NODE_ENV === 'test') {
const { onTestUpdatePosition } = this.props as any;
if (onTestUpdatePosition) {
onTestUpdatePosition();
}
}
};
measure = () => { measure = () => {
const { status, lastAffix } = this.state; const { status, lastAffix } = this.state;
const { target, onChange } = this.props; const { target, onChange } = this.props;
@ -254,6 +203,60 @@ class Affix extends React.Component<AffixProps, AffixState> {
this.setState(newState as AffixState); this.setState(newState as AffixState);
}; };
// @ts-ignore TS6133
prepareMeasure = () => {
// event param is used before. Keep compatible ts define here.
this.setState({
status: AffixStatus.Prepare,
affixStyle: undefined,
placeholderStyle: undefined,
});
// Test if `updatePosition` called
if (process.env.NODE_ENV === 'test') {
const { onTestUpdatePosition } = this.props as any;
if (onTestUpdatePosition) {
onTestUpdatePosition();
}
}
};
// Handle realign logic
@throttleByAnimationFrameDecorator()
updatePosition() {
this.prepareMeasure();
}
@throttleByAnimationFrameDecorator()
lazyUpdatePosition() {
const { target } = this.props;
const { affixStyle } = this.state;
// Check position change before measure to make Safari smooth
if (target && affixStyle) {
const offsetTop = this.getOffsetTop();
const offsetBottom = this.getOffsetBottom();
const targetNode = target();
if (targetNode) {
const targetRect = getTargetRect(targetNode);
const placeholderReact = getTargetRect(this.placeholderNode);
const fixedTop = getFixedTop(placeholderReact, targetRect, offsetTop);
const fixedBottom = getFixedBottom(placeholderReact, targetRect, offsetBottom);
if (
(fixedTop !== undefined && affixStyle.top === fixedTop) ||
(fixedBottom !== undefined && affixStyle.bottom === fixedBottom)
) {
return;
}
}
}
// Directly call prepare measure since it's already throttled.
this.prepareMeasure();
}
// =================== Render =================== // =================== Render ===================
renderAffix = ({ getPrefixCls }: ConfigConsumerProps) => { renderAffix = ({ getPrefixCls }: ConfigConsumerProps) => {
const { affixStyle, placeholderStyle } = this.state; const { affixStyle, placeholderStyle } = this.state;

View File

@ -74,9 +74,9 @@ export function addObserveTarget(target: HTMLElement | Window | null, affix: Aff
// Add listener // Add listener
TRIGGER_EVENTS.forEach(eventName => { TRIGGER_EVENTS.forEach(eventName => {
entity!.eventHandlers[eventName] = addEventListener(target, eventName, (event: Event) => { entity!.eventHandlers[eventName] = addEventListener(target, eventName, () => {
entity!.affixList.forEach(affix => { entity!.affixList.forEach(targetAffix => {
affix.lazyUpdatePosition(event); targetAffix.lazyUpdatePosition();
}); });
}); });
}); });

View File

@ -69,6 +69,7 @@ exports[`renders ./components/alert/demo/banner.md correctly 1`] = `
<span <span
class="ant-alert-close-icon" class="ant-alert-close-icon"
role="button" role="button"
tabindex="0"
> >
<i <i
aria-label="icon: close" aria-label="icon: close"
@ -174,6 +175,7 @@ exports[`renders ./components/alert/demo/closable.md correctly 1`] = `
<span <span
class="ant-alert-close-icon" class="ant-alert-close-icon"
role="button" role="button"
tabindex="0"
> >
<i <i
aria-label="icon: close" aria-label="icon: close"
@ -213,6 +215,7 @@ exports[`renders ./components/alert/demo/closable.md correctly 1`] = `
<span <span
class="ant-alert-close-icon" class="ant-alert-close-icon"
role="button" role="button"
tabindex="0"
> >
<i <i
aria-label="icon: close" aria-label="icon: close"
@ -254,6 +257,7 @@ exports[`renders ./components/alert/demo/close-text.md correctly 1`] = `
<span <span
class="ant-alert-close-icon" class="ant-alert-close-icon"
role="button" role="button"
tabindex="0"
> >
<span <span
class="ant-alert-close-text" class="ant-alert-close-text"
@ -909,6 +913,7 @@ exports[`renders ./components/alert/demo/smooth-closed.md correctly 1`] = `
<span <span
class="ant-alert-close-icon" class="ant-alert-close-icon"
role="button" role="button"
tabindex="0"
> >
<i <i
aria-label="icon: close" aria-label="icon: close"

View File

@ -1,8 +1,8 @@
import * as React from 'react'; import * as React from 'react';
import * as ReactDOM from 'react-dom'; import * as ReactDOM from 'react-dom';
import Animate from 'rc-animate'; import Animate from 'rc-animate';
import Icon, { ThemeType } from '../icon';
import classNames from 'classnames'; import classNames from 'classnames';
import Icon, { ThemeType } from '../icon';
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider'; import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
import getDataOrAriaProps from '../_util/getDataOrAriaProps'; import getDataOrAriaProps from '../_util/getDataOrAriaProps';
import warning from '../_util/warning'; import warning from '../_util/warning';
@ -119,7 +119,7 @@ export default class Alert extends React.Component<AlertProps, AlertState> {
} }
// use outline icon in alert with description // use outline icon in alert with description
if (!!description) { if (description) {
iconTheme = 'outlined'; iconTheme = 'outlined';
} }
} }
@ -143,7 +143,12 @@ export default class Alert extends React.Component<AlertProps, AlertState> {
); );
const closeIcon = closable ? ( const closeIcon = closable ? (
<span role="button" onClick={this.handleClose} className={`${prefixCls}-close-icon`}> <span
role="button"
onClick={this.handleClose}
className={`${prefixCls}-close-icon`}
tabIndex={0}
>
{closeText ? ( {closeText ? (
<span className={`${prefixCls}-close-text`}>{closeText}</span> <span className={`${prefixCls}-close-text`}>{closeText}</span>
) : ( ) : (

View File

@ -3,11 +3,11 @@ import * as ReactDOM from 'react-dom';
import * as PropTypes from 'prop-types'; import * as PropTypes from 'prop-types';
import classNames from 'classnames'; import classNames from 'classnames';
import addEventListener from 'rc-util/lib/Dom/addEventListener'; import addEventListener from 'rc-util/lib/Dom/addEventListener';
import raf from 'raf';
import Affix from '../affix'; import Affix from '../affix';
import AnchorLink from './AnchorLink'; import AnchorLink from './AnchorLink';
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider'; import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
import getScroll from '../_util/getScroll'; import getScroll from '../_util/getScroll';
import raf from 'raf';
function getDefaultContainer() { function getDefaultContainer() {
return window; return window;
@ -145,11 +145,14 @@ export default class Anchor extends React.Component<AnchorProps, AnchorState> {
}; };
private inkNode: HTMLSpanElement; private inkNode: HTMLSpanElement;
// scroll scope's container // scroll scope's container
private scrollContainer: HTMLElement | Window; private scrollContainer: HTMLElement | Window;
private links: string[] = []; private links: string[] = [];
private scrollEvent: any; private scrollEvent: any;
private animating: boolean; private animating: boolean;
private prefixCls?: string; private prefixCls?: string;
@ -181,12 +184,6 @@ export default class Anchor extends React.Component<AnchorProps, AnchorState> {
this.handleScroll(); this.handleScroll();
} }
componentWillUnmount() {
if (this.scrollEvent) {
this.scrollEvent.remove();
}
}
componentDidUpdate() { componentDidUpdate() {
if (this.scrollEvent) { if (this.scrollEvent) {
const { getContainer } = this.props as AnchorDefaultProps; const { getContainer } = this.props as AnchorDefaultProps;
@ -201,28 +198,11 @@ export default class Anchor extends React.Component<AnchorProps, AnchorState> {
this.updateInk(); this.updateInk();
} }
handleScroll = () => { componentWillUnmount() {
if (this.animating) { if (this.scrollEvent) {
return; this.scrollEvent.remove();
} }
const { activeLink } = this.state;
const { offsetTop, bounds } = this.props;
const currentActiveLink = this.getCurrentAnchor(offsetTop, bounds);
if (activeLink !== currentActiveLink) {
this.setState({
activeLink: currentActiveLink,
});
} }
};
handleScrollTo = (link: string) => {
const { offsetTop, getContainer } = this.props as AnchorDefaultProps;
this.animating = true;
this.setState({ activeLink: link });
scrollTo(link, offsetTop, getContainer, () => {
this.animating = false;
});
};
getCurrentAnchor(offsetTop = 0, bounds = 5): string { getCurrentAnchor(offsetTop = 0, bounds = 5): string {
const activeLink = ''; const activeLink = '';
@ -257,11 +237,38 @@ export default class Anchor extends React.Component<AnchorProps, AnchorState> {
return ''; return '';
} }
saveInkNode = (node: HTMLSpanElement) => {
this.inkNode = node;
};
handleScroll = () => {
if (this.animating) {
return;
}
const { activeLink } = this.state;
const { offsetTop, bounds } = this.props;
const currentActiveLink = this.getCurrentAnchor(offsetTop, bounds);
if (activeLink !== currentActiveLink) {
this.setState({
activeLink: currentActiveLink,
});
}
};
handleScrollTo = (link: string) => {
const { offsetTop, getContainer } = this.props as AnchorDefaultProps;
this.animating = true;
this.setState({ activeLink: link });
scrollTo(link, offsetTop, getContainer, () => {
this.animating = false;
});
};
updateInk = () => { updateInk = () => {
if (typeof document === 'undefined') { if (typeof document === 'undefined') {
return; return;
} }
const prefixCls = this.prefixCls; const { prefixCls } = this;
const anchorNode = ReactDOM.findDOMNode(this) as Element; const anchorNode = ReactDOM.findDOMNode(this) as Element;
const linkNode = anchorNode.getElementsByClassName(`${prefixCls}-link-title-active`)[0]; const linkNode = anchorNode.getElementsByClassName(`${prefixCls}-link-title-active`)[0];
if (linkNode) { if (linkNode) {
@ -269,10 +276,6 @@ export default class Anchor extends React.Component<AnchorProps, AnchorState> {
} }
}; };
saveInkNode = (node: HTMLSpanElement) => {
this.inkNode = node;
};
renderAnchor = ({ getPrefixCls }: ConfigConsumerProps) => { renderAnchor = ({ getPrefixCls }: ConfigConsumerProps) => {
const { const {
prefixCls: customizePrefixCls, prefixCls: customizePrefixCls,

View File

@ -9,13 +9,19 @@ export default class InputElement extends React.Component<InputElementProps, any
private ele: HTMLInputElement; private ele: HTMLInputElement;
focus = () => { focus = () => {
this.ele.focus if (this.ele.focus) {
? this.ele.focus() this.ele.focus();
: (ReactDOM.findDOMNode(this.ele) as HTMLInputElement).focus(); } else {
(ReactDOM.findDOMNode(this.ele) as HTMLInputElement).focus();
}
}; };
blur = () => { blur = () => {
this.ele.blur ? this.ele.blur() : (ReactDOM.findDOMNode(this.ele) as HTMLInputElement).blur(); if (this.ele.blur) {
this.ele.blur();
} else {
(ReactDOM.findDOMNode(this.ele) as HTMLInputElement).blur();
}
}; };
saveRef = (ele: HTMLInputElement) => { saveRef = (ele: HTMLInputElement) => {

View File

@ -51,6 +51,7 @@ function isSelectOptionOrSelectOptGroup(child: any): Boolean {
export default class AutoComplete extends React.Component<AutoCompleteProps, {}> { export default class AutoComplete extends React.Component<AutoCompleteProps, {}> {
static Option = Option as React.ClassicComponentClass<OptionProps>; static Option = Option as React.ClassicComponentClass<OptionProps>;
static OptGroup = OptGroup as React.ClassicComponentClass<OptGroupProps>; static OptGroup = OptGroup as React.ClassicComponentClass<OptGroupProps>;
static defaultProps = { static defaultProps = {
@ -63,6 +64,10 @@ export default class AutoComplete extends React.Component<AutoCompleteProps, {}>
private select: any; private select: any;
saveSelect = (node: any) => {
this.select = node;
};
getInputElement = () => { getInputElement = () => {
const { children } = this.props; const { children } = this.props;
const element = const element =
@ -85,10 +90,6 @@ export default class AutoComplete extends React.Component<AutoCompleteProps, {}>
this.select.blur(); this.select.blur();
} }
saveSelect = (node: any) => {
this.select = node;
};
renderAutoComplete = ({ getPrefixCls }: ConfigConsumerProps) => { renderAutoComplete = ({ getPrefixCls }: ConfigConsumerProps) => {
const { const {
prefixCls: customizePrefixCls, prefixCls: customizePrefixCls,

View File

@ -1,6 +1,6 @@
import * as React from 'react'; import * as React from 'react';
import Icon from '../icon';
import classNames from 'classnames'; import classNames from 'classnames';
import Icon from '../icon';
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider'; import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
export interface AvatarProps { export interface AvatarProps {
@ -23,7 +23,7 @@ export interface AvatarProps {
children?: React.ReactNode; children?: React.ReactNode;
alt?: string; alt?: string;
/* callback when img load error */ /* callback when img load error */
/* return false to prevent Avatar show default fallback behavior, then you can do fallback by your self*/ /* return false to prevent Avatar show default fallback behavior, then you can do fallback by your self */
onError?: () => boolean; onError?: () => boolean;
} }
@ -44,8 +44,11 @@ export default class Avatar extends React.Component<AvatarProps, AvatarState> {
}; };
private avatarNode: HTMLElement; private avatarNode: HTMLElement;
private avatarChildren: HTMLElement; private avatarChildren: HTMLElement;
private lastChildrenWidth: number; private lastChildrenWidth: number;
private lastNodeWidth: number; private lastNodeWidth: number;
componentDidMount() { componentDidMount() {
@ -127,7 +130,7 @@ export default class Avatar extends React.Component<AvatarProps, AvatarState> {
} }
: {}; : {};
let children = this.props.children; let { children } = this.props;
if (src && isImgExist) { if (src && isImgExist) {
children = <img src={src} srcSet={srcSet} onError={this.handleImgLoadError} alt={alt} />; children = <img src={src} srcSet={srcSet} onError={this.handleImgLoadError} alt={alt} />;
} else if (icon) { } else if (icon) {

View File

@ -12,9 +12,8 @@ const easeInOutCubic = (t: number, b: number, c: number, d: number) => {
t /= d / 2; t /= d / 2;
if (t < 1) { if (t < 1) {
return (cc / 2) * t * t * t + b; return (cc / 2) * t * t * t + b;
} else {
return (cc / 2) * ((t -= 2) * t * t + 2) + b;
} }
return (cc / 2) * ((t -= 2) * t * t + 2) + b;
}; };
function noop() {} function noop() {}
@ -47,6 +46,29 @@ export default class BackTop extends React.Component<BackTopProps, any> {
}; };
} }
componentDidMount() {
const getTarget = this.props.target || getDefaultTarget;
this.scrollEvent = addEventListener(getTarget(), 'scroll', this.handleScroll);
this.handleScroll();
}
componentWillUnmount() {
if (this.scrollEvent) {
this.scrollEvent.remove();
}
}
setScrollTop(value: number) {
const getTarget = this.props.target || getDefaultTarget;
const targetNode = getTarget();
if (targetNode === window) {
document.body.scrollTop = value;
document.documentElement!.scrollTop = value;
} else {
(targetNode as HTMLElement).scrollTop = value;
}
}
getCurrentScrollTop = () => { getCurrentScrollTop = () => {
const getTarget = this.props.target || getDefaultTarget; const getTarget = this.props.target || getDefaultTarget;
const targetNode = getTarget(); const targetNode = getTarget();
@ -73,17 +95,6 @@ export default class BackTop extends React.Component<BackTopProps, any> {
(this.props.onClick || noop)(e); (this.props.onClick || noop)(e);
}; };
setScrollTop(value: number) {
const getTarget = this.props.target || getDefaultTarget;
const targetNode = getTarget();
if (targetNode === window) {
document.body.scrollTop = value;
document.documentElement!.scrollTop = value;
} else {
(targetNode as HTMLElement).scrollTop = value;
}
}
handleScroll = () => { handleScroll = () => {
const { visibilityHeight, target = getDefaultTarget } = this.props; const { visibilityHeight, target = getDefaultTarget } = this.props;
const scrollTop = getScroll(target(), true); const scrollTop = getScroll(target(), true);
@ -92,18 +103,6 @@ export default class BackTop extends React.Component<BackTopProps, any> {
}); });
}; };
componentDidMount() {
const getTarget = this.props.target || getDefaultTarget;
this.scrollEvent = addEventListener(getTarget(), 'scroll', this.handleScroll);
this.handleScroll();
}
componentWillUnmount() {
if (this.scrollEvent) {
this.scrollEvent.remove();
}
}
renderBackTop = ({ getPrefixCls }: ConfigConsumerProps) => { renderBackTop = ({ getPrefixCls }: ConfigConsumerProps) => {
const { prefixCls: customizePrefixCls, className = '', children } = this.props; const { prefixCls: customizePrefixCls, className = '', children } = this.props;
const prefixCls = getPrefixCls('back-top', customizePrefixCls); const prefixCls = getPrefixCls('back-top', customizePrefixCls);

View File

@ -1,9 +1,8 @@
import * as React from 'react'; import React, { createElement, Component } from 'react';
import { createElement, Component } 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 { polyfill } from 'react-lifecycles-compat'; import { polyfill } from 'react-lifecycles-compat';
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
function getNumberArray(num: string | number | undefined | null) { function getNumberArray(num: string | number | undefined | null) {
return num return num
@ -18,6 +17,20 @@ function getNumberArray(num: string | number | undefined | null) {
: []; : [];
} }
function renderNumberList(position: number) {
const childrenToReturn: React.ReactElement<any>[] = [];
for (let i = 0; i < 30; i++) {
const currentClassName = position === i ? 'current' : '';
childrenToReturn.push(
<p key={i.toString()} className={currentClassName}>
{i % 10}
</p>,
);
}
return childrenToReturn;
}
export interface ScrollNumberProps { export interface ScrollNumberProps {
prefixCls?: string; prefixCls?: string;
className?: string; className?: string;
@ -62,6 +75,21 @@ class ScrollNumber extends Component<ScrollNumberProps, ScrollNumberState> {
}; };
} }
componentDidUpdate(_: any, prevState: ScrollNumberState) {
this.lastCount = prevState.count;
const { animateStarted } = this.state;
if (animateStarted) {
/* eslint-disable react/no-did-update-set-state */
this.setState(
(__, props) => ({
animateStarted: false,
count: props.count,
}),
this.onAnimated,
);
}
}
getPositionByNum(num: number, i: number) { getPositionByNum(num: number, i: number) {
const { count } = this.state; const { count } = this.state;
const currentCount = Math.abs(Number(count)); const currentCount = Math.abs(Number(count));
@ -86,20 +114,6 @@ class ScrollNumber extends Component<ScrollNumberProps, ScrollNumberState> {
return num; return num;
} }
componentDidUpdate(_: any, prevState: ScrollNumberState) {
this.lastCount = prevState.count;
const { animateStarted } = this.state;
if (animateStarted) {
this.setState(
(__, props) => ({
animateStarted: false,
count: props.count,
}),
this.onAnimated,
);
}
}
onAnimated = () => { onAnimated = () => {
const { onAnimated } = this.props; const { onAnimated } = this.props;
if (onAnimated) { if (onAnimated) {
@ -107,20 +121,6 @@ class ScrollNumber extends Component<ScrollNumberProps, ScrollNumberState> {
} }
}; };
renderNumberList(position: number) {
const childrenToReturn: React.ReactElement<any>[] = [];
for (let i = 0; i < 30; i++) {
const currentClassName = position === i ? 'current' : '';
childrenToReturn.push(
<p key={i.toString()} className={currentClassName}>
{i % 10}
</p>,
);
}
return childrenToReturn;
}
renderCurrentNumber(prefixCls: string, num: number | string, i: number) { renderCurrentNumber(prefixCls: string, num: number | string, i: number) {
if (typeof num === 'number') { if (typeof num === 'number') {
const position = this.getPositionByNum(num, i); const position = this.getPositionByNum(num, i);
@ -138,7 +138,7 @@ class ScrollNumber extends Component<ScrollNumberProps, ScrollNumberState> {
}, },
key: i, key: i,
}, },
this.renderNumberList(position), renderNumberList(position),
); );
} }

View File

@ -1,6 +1,7 @@
import * as React from 'react'; import * as React from 'react';
import * as PropTypes from 'prop-types'; import * as PropTypes from 'prop-types';
import Animate from 'rc-animate'; import Animate from 'rc-animate';
import omit from 'omit.js';
import classNames from 'classnames'; import classNames from 'classnames';
import ScrollNumber from './ScrollNumber'; import ScrollNumber from './ScrollNumber';
import { PresetColorTypes } from '../_util/colors'; import { PresetColorTypes } from '../_util/colors';
@ -46,39 +47,6 @@ export default class Badge extends React.Component<BadgeProps, any> {
overflowCount: PropTypes.number, overflowCount: PropTypes.number,
}; };
getBadgeClassName(prefixCls: string) {
const { className, children } = this.props;
return classNames(className, prefixCls, {
[`${prefixCls}-status`]: this.hasStatus(),
[`${prefixCls}-not-a-wrapper`]: !children,
}) as string;
}
hasStatus(): boolean {
const { status, color } = this.props;
return !!status || !!color;
}
isZero() {
const numberedDispayCount = this.getNumberedDispayCount();
return numberedDispayCount === '0' || numberedDispayCount === 0;
}
isDot() {
const { dot } = this.props;
const isZero = this.isZero();
return (dot && !isZero) || this.hasStatus();
}
isHidden() {
const { showZero } = this.props;
const displayCount = this.getDispayCount();
const isZero = this.isZero();
const isDot = this.isDot();
const isEmpty = displayCount === null || displayCount === undefined || displayCount === '';
return (isEmpty || (isZero && !showZero)) && !isDot;
}
getNumberedDispayCount() { getNumberedDispayCount() {
const { count, overflowCount } = this.props; const { count, overflowCount } = this.props;
const displayCount = const displayCount =
@ -114,6 +82,39 @@ export default class Badge extends React.Component<BadgeProps, any> {
: style; : style;
} }
getBadgeClassName(prefixCls: string) {
const { className, children } = this.props;
return classNames(className, prefixCls, {
[`${prefixCls}-status`]: this.hasStatus(),
[`${prefixCls}-not-a-wrapper`]: !children,
}) as string;
}
hasStatus(): boolean {
const { status, color } = this.props;
return !!status || !!color;
}
isZero() {
const numberedDispayCount = this.getNumberedDispayCount();
return numberedDispayCount === '0' || numberedDispayCount === 0;
}
isDot() {
const { dot } = this.props;
const isZero = this.isZero();
return (dot && !isZero) || this.hasStatus();
}
isHidden() {
const { showZero } = this.props;
const displayCount = this.getDispayCount();
const isZero = this.isZero();
const isDot = this.isDot();
const isEmpty = displayCount === null || displayCount === undefined || displayCount === '';
return (isEmpty || (isZero && !showZero)) && !isDot;
}
renderStatusText(prefixCls: string) { renderStatusText(prefixCls: string) {
const { text } = this.props; const { text } = this.props;
const hidden = this.isHidden(); const hidden = this.isHidden();
@ -165,22 +166,24 @@ export default class Badge extends React.Component<BadgeProps, any> {
renderBadge = ({ getPrefixCls }: ConfigConsumerProps) => { renderBadge = ({ getPrefixCls }: ConfigConsumerProps) => {
const { const {
count,
showZero,
prefixCls: customizePrefixCls, prefixCls: customizePrefixCls,
scrollNumberPrefixCls: customizeScrollNumberPrefixCls, scrollNumberPrefixCls: customizeScrollNumberPrefixCls,
overflowCount,
className,
style,
children, children,
dot,
status, status,
text, text,
offset,
title,
color, color,
...restProps ...restProps
} = this.props; } = this.props;
const omitArr = [
'count',
'showZero',
'overflowCount',
'className',
'style',
'dot',
'offset',
'title',
];
const prefixCls = getPrefixCls('badge', customizePrefixCls); const prefixCls = getPrefixCls('badge', customizePrefixCls);
const scrollNumberPrefixCls = getPrefixCls('scroll-number', customizeScrollNumberPrefixCls); const scrollNumberPrefixCls = getPrefixCls('scroll-number', customizeScrollNumberPrefixCls);
@ -203,7 +206,11 @@ export default class Badge extends React.Component<BadgeProps, any> {
const styleWithOffset = this.getStyleWithOffset(); const styleWithOffset = this.getStyleWithOffset();
const statusTextColor = styleWithOffset && styleWithOffset.color; const statusTextColor = styleWithOffset && styleWithOffset.color;
return ( return (
<span {...restProps} className={this.getBadgeClassName(prefixCls)} style={styleWithOffset}> <span
{...omit(restProps, omitArr)}
className={this.getBadgeClassName(prefixCls)}
style={styleWithOffset}
>
<span className={statusCls} style={statusStyle} /> <span className={statusCls} style={statusStyle} />
<span style={{ color: statusTextColor }} className={`${prefixCls}-status-text`}> <span style={{ color: statusTextColor }} className={`${prefixCls}-status-text`}>
{text} {text}
@ -213,7 +220,7 @@ export default class Badge extends React.Component<BadgeProps, any> {
} }
return ( return (
<span {...restProps} className={this.getBadgeClassName(prefixCls)}> <span {...omit(restProps, omitArr)} className={this.getBadgeClassName(prefixCls)}>
{children} {children}
<Animate <Animate
component="" component=""

View File

@ -1,6 +1,5 @@
import * as React from 'react'; import React, { cloneElement } from 'react';
import * as PropTypes from 'prop-types'; import * as PropTypes from 'prop-types';
import { cloneElement } from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import BreadcrumbItem from './BreadcrumbItem'; import BreadcrumbItem from './BreadcrumbItem';
import BreadcrumbSeparator from './BreadcrumbSeparator'; import BreadcrumbSeparator from './BreadcrumbSeparator';
@ -60,11 +59,10 @@ export default class Breadcrumb extends React.Component<BreadcrumbProps, any> {
prefixCls: PropTypes.string, prefixCls: PropTypes.string,
separator: PropTypes.node, separator: PropTypes.node,
routes: PropTypes.array, routes: PropTypes.array,
params: PropTypes.object,
}; };
componentDidMount() { componentDidMount() {
const props = this.props; const { props } = this;
warning( warning(
!('linkRender' in props || 'nameRender' in props), !('linkRender' in props || 'nameRender' in props),
'Breadcrumb', 'Breadcrumb',
@ -124,6 +122,7 @@ export default class Breadcrumb extends React.Component<BreadcrumbProps, any> {
); );
}); });
}; };
renderBreadcrumb = ({ getPrefixCls }: ConfigConsumerProps) => { renderBreadcrumb = ({ getPrefixCls }: ConfigConsumerProps) => {
let crumbs; let crumbs;
const { const {

View File

@ -1,5 +1,6 @@
import * as React from 'react'; import * as React from 'react';
import * as PropTypes from 'prop-types'; import * as PropTypes from 'prop-types';
import omit from 'omit.js';
import DropDown, { DropDownProps } from '../dropdown/dropdown'; import DropDown, { DropDownProps } from '../dropdown/dropdown';
import Icon from '../icon'; import Icon from '../icon';
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider'; import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
@ -26,24 +27,18 @@ export default class BreadcrumbItem extends React.Component<BreadcrumbItemProps,
}; };
renderBreadcrumbItem = ({ getPrefixCls }: ConfigConsumerProps) => { renderBreadcrumbItem = ({ getPrefixCls }: ConfigConsumerProps) => {
const { const { prefixCls: customizePrefixCls, separator, children, ...restProps } = this.props;
prefixCls: customizePrefixCls,
separator,
children,
overlay,
...restProps
} = this.props;
const prefixCls = getPrefixCls('breadcrumb', customizePrefixCls); const prefixCls = getPrefixCls('breadcrumb', customizePrefixCls);
let link; let link;
if ('href' in this.props) { if ('href' in this.props) {
link = ( link = (
<a className={`${prefixCls}-link`} {...restProps}> <a className={`${prefixCls}-link`} {...omit(restProps, ['overlay'])}>
{children} {children}
</a> </a>
); );
} else { } else {
link = ( link = (
<span className={`${prefixCls}-link`} {...restProps}> <span className={`${prefixCls}-link`} {...omit(restProps, ['overlay'])}>
{children} {children}
</span> </span>
); );
@ -82,6 +77,7 @@ export default class BreadcrumbItem extends React.Component<BreadcrumbItemProps,
} }
return breadcrumbItem; return breadcrumbItem;
}; };
render() { render() {
return <ConfigConsumer>{this.renderBreadcrumbItem}</ConfigConsumer>; return <ConfigConsumer>{this.renderBreadcrumbItem}</ConfigConsumer>;
} }

View File

@ -846,6 +846,7 @@ exports[`renders ./components/button/demo/size.md correctly 1`] = `
> >
<label <label
class="ant-radio-button-wrapper ant-radio-button-wrapper-checked" class="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
for="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
> >
<span <span
class="ant-radio-button ant-radio-button-checked" class="ant-radio-button ant-radio-button-checked"
@ -866,6 +867,7 @@ exports[`renders ./components/button/demo/size.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-button-wrapper" class="ant-radio-button-wrapper"
for="ant-radio-button-wrapper"
> >
<span <span
class="ant-radio-button" class="ant-radio-button"
@ -885,6 +887,7 @@ exports[`renders ./components/button/demo/size.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-button-wrapper" class="ant-radio-button-wrapper"
for="ant-radio-button-wrapper"
> >
<span <span
class="ant-radio-button" class="ant-radio-button"

View File

@ -25,6 +25,7 @@ const ButtonGroup: React.SFC<ButtonGroupProps> = props => (
break; break;
case 'small': case 'small':
sizeCls = 'sm'; sizeCls = 'sm';
break;
default: default:
break; break;
} }

View File

@ -1,9 +1,10 @@
/* eslint-disable react/button-has-type */
import * as React from 'react'; import * as React from 'react';
import * as PropTypes from 'prop-types'; import * as PropTypes from 'prop-types';
import classNames from 'classnames'; import classNames from 'classnames';
import { polyfill } from 'react-lifecycles-compat'; import { polyfill } from 'react-lifecycles-compat';
import Group from './button-group';
import omit from 'omit.js'; import omit from 'omit.js';
import Group from './button-group';
import Icon from '../icon'; import Icon from '../icon';
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider'; import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
import Wave from '../_util/wave'; import Wave from '../_util/wave';
@ -15,29 +16,6 @@ function isString(str: any) {
return typeof str === 'string'; return typeof str === 'string';
} }
function spaceChildren(children: React.ReactNode, needInserted: boolean) {
let isPrevChildPure: boolean = false;
const childList: React.ReactNode[] = [];
React.Children.forEach(children, child => {
const type = typeof child;
const isCurrentChildPure = type === 'string' || type === 'number';
if (isPrevChildPure && isCurrentChildPure) {
const lastIndex = childList.length - 1;
const lastChild = childList[lastIndex];
childList[lastIndex] = `${lastChild}${child}`;
} else {
childList.push(child);
}
isPrevChildPure = isCurrentChildPure;
});
// Pass to React.Children.map to auto fill key
return React.Children.map(childList, child =>
insertSpace(child as React.ReactChild, needInserted),
);
}
// Insert one space between two chinese characters automatically. // Insert one space between two chinese characters automatically.
function insertSpace(child: React.ReactChild, needInserted: boolean) { function insertSpace(child: React.ReactChild, needInserted: boolean) {
// Check the child if is undefined or null. // Check the child if is undefined or null.
@ -63,6 +41,29 @@ function insertSpace(child: React.ReactChild, needInserted: boolean) {
return child; return child;
} }
function spaceChildren(children: React.ReactNode, needInserted: boolean) {
let isPrevChildPure: boolean = false;
const childList: React.ReactNode[] = [];
React.Children.forEach(children, child => {
const type = typeof child;
const isCurrentChildPure = type === 'string' || type === 'number';
if (isPrevChildPure && isCurrentChildPure) {
const lastIndex = childList.length - 1;
const lastChild = childList[lastIndex];
childList[lastIndex] = `${lastChild}${child}`;
} else {
childList.push(child);
}
isPrevChildPure = isCurrentChildPure;
});
// Pass to React.Children.map to auto fill key
return React.Children.map(childList, child =>
insertSpace(child as React.ReactChild, needInserted),
);
}
const ButtonTypes = tuple('default', 'primary', 'ghost', 'dashed', 'danger', 'link'); const ButtonTypes = tuple('default', 'primary', 'ghost', 'dashed', 'danger', 'link');
export type ButtonType = (typeof ButtonTypes)[number]; export type ButtonType = (typeof ButtonTypes)[number];
const ButtonShapes = tuple('circle', 'circle-outline', 'round'); const ButtonShapes = tuple('circle', 'circle-outline', 'round');
@ -110,6 +111,7 @@ interface ButtonState {
class Button extends React.Component<ButtonProps, ButtonState> { class Button extends React.Component<ButtonProps, ButtonState> {
static Group: typeof Group; static Group: typeof Group;
static __ANT_BUTTON = true; static __ANT_BUTTON = true;
static defaultProps = { static defaultProps = {
@ -142,6 +144,7 @@ class Button extends React.Component<ButtonProps, ButtonState> {
} }
private delayTimeout: number; private delayTimeout: number;
private buttonNode: HTMLElement | null; private buttonNode: HTMLElement | null;
constructor(props: ButtonProps) { constructor(props: ButtonProps) {
@ -166,9 +169,8 @@ class Button extends React.Component<ButtonProps, ButtonState> {
const { loading } = this.props; const { loading } = this.props;
if (loading && typeof loading !== 'boolean' && loading.delay) { if (loading && typeof loading !== 'boolean' && loading.delay) {
this.delayTimeout = window.setTimeout(() => this.setState({ loading }), loading.delay); this.delayTimeout = window.setTimeout(() => this.setState({ loading }), loading.delay);
} else if (prevProps.loading === this.props.loading) { } else if (prevProps.loading !== this.props.loading) {
return; /* eslint-disable react/no-did-update-set-state */
} else {
this.setState({ loading }); this.setState({ loading });
} }
} }
@ -183,6 +185,17 @@ class Button extends React.Component<ButtonProps, ButtonState> {
this.buttonNode = node; this.buttonNode = node;
}; };
handleClick: React.MouseEventHandler<HTMLButtonElement | HTMLAnchorElement> = e => {
const { loading } = this.state;
const { onClick } = this.props;
if (loading) {
return;
}
if (onClick) {
(onClick as React.MouseEventHandler<HTMLButtonElement | HTMLAnchorElement>)(e);
}
};
fixTwoCNChar() { fixTwoCNChar() {
// Fix for HOC usage like <FormatMessage /> // Fix for HOC usage like <FormatMessage />
if (!this.buttonNode) { if (!this.buttonNode) {
@ -202,17 +215,6 @@ class Button extends React.Component<ButtonProps, ButtonState> {
} }
} }
handleClick: React.MouseEventHandler<HTMLButtonElement | HTMLAnchorElement> = e => {
const { loading } = this.state;
const { onClick } = this.props;
if (!!loading) {
return;
}
if (onClick) {
(onClick as React.MouseEventHandler<HTMLButtonElement | HTMLAnchorElement>)(e);
}
};
isNeedInserted() { isNeedInserted() {
const { icon, children } = this.props; const { icon, children } = this.props;
return React.Children.count(children) === 1 && !icon; return React.Children.count(children) === 1 && !icon;
@ -228,7 +230,6 @@ class Button extends React.Component<ButtonProps, ButtonState> {
children, children,
icon, icon,
ghost, ghost,
loading: _loadingProp,
block, block,
...rest ...rest
} = this.props; } = this.props;
@ -289,7 +290,7 @@ class Button extends React.Component<ButtonProps, ButtonState> {
const buttonNode = ( const buttonNode = (
<button <button
{...(otherProps as NativeButtonProps)} {...(omit(otherProps, ['loading']) as NativeButtonProps)}
type={htmlType} type={htmlType}
className={classes} className={classes}
onClick={this.handleClick} onClick={this.handleClick}

View File

@ -3,8 +3,20 @@ import * as moment from 'moment';
import Select from '../select'; import Select from '../select';
import { Group, Button, RadioChangeEvent } from '../radio'; import { Group, Button, RadioChangeEvent } from '../radio';
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider'; import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
const { Option } = Select; const { Option } = Select;
function getMonthsLocale(value: moment.Moment) {
const current = value.clone();
const localeData = value.localeData();
const months: any[] = [];
for (let i = 0; i < 12; i++) {
current.month(i);
months.push(localeData.monthsShort(current));
}
return months;
}
export interface RenderHeader { export interface RenderHeader {
value: moment.Moment; value: moment.Moment;
onChange?: (value: moment.Moment) => void; onChange?: (value: moment.Moment) => void;
@ -63,17 +75,6 @@ export default class Header extends React.Component<HeaderProps, any> {
); );
} }
getMonthsLocale(value: moment.Moment) {
const current = value.clone();
const localeData = value.localeData();
const months: any[] = [];
for (let i = 0; i < 12; i++) {
current.month(i);
months.push(localeData.monthsShort(current));
}
return months;
}
getMonthSelectElement(prefixCls: string, month: number, months: number[]) { getMonthSelectElement(prefixCls: string, month: number, months: number[]) {
const { fullscreen, validRange, value } = this.props; const { fullscreen, validRange, value } = this.props;
const options: React.ReactElement<any>[] = []; const options: React.ReactElement<any>[] = [];
@ -124,7 +125,7 @@ export default class Header extends React.Component<HeaderProps, any> {
} }
} }
const onValueChange = this.props.onValueChange; const { onValueChange } = this.props;
if (onValueChange) { if (onValueChange) {
onValueChange(newValue); onValueChange(newValue);
} }
@ -133,7 +134,7 @@ export default class Header extends React.Component<HeaderProps, any> {
onMonthChange = (month: string) => { onMonthChange = (month: string) => {
const newValue = this.props.value.clone(); const newValue = this.props.value.clone();
newValue.month(parseInt(month, 10)); newValue.month(parseInt(month, 10));
const onValueChange = this.props.onValueChange; const { onValueChange } = this.props;
if (onValueChange) { if (onValueChange) {
onValueChange(newValue); onValueChange(newValue);
} }
@ -144,7 +145,7 @@ export default class Header extends React.Component<HeaderProps, any> {
}; };
onTypeChange = (type: string) => { onTypeChange = (type: string) => {
const onTypeChange = this.props.onTypeChange; const { onTypeChange } = this.props;
if (onTypeChange) { if (onTypeChange) {
onTypeChange(type); onTypeChange(type);
} }
@ -161,7 +162,7 @@ export default class Header extends React.Component<HeaderProps, any> {
const yearReactNode = this.getYearSelectElement(prefixCls, value.year()); const yearReactNode = this.getYearSelectElement(prefixCls, value.year());
const monthReactNode = const monthReactNode =
type === 'month' type === 'month'
? this.getMonthSelectElement(prefixCls, value.month(), this.getMonthsLocale(value)) ? this.getMonthSelectElement(prefixCls, value.month(), getMonthsLocale(value))
: null; : null;
return { return {
yearReactNode, yearReactNode,

View File

@ -114,6 +114,7 @@ exports[`renders ./components/calendar/demo/basic.md correctly 1`] = `
> >
<label <label
class="ant-radio-button-wrapper ant-radio-button-wrapper-checked" class="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
for="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
> >
<span <span
class="ant-radio-button ant-radio-button-checked" class="ant-radio-button ant-radio-button-checked"
@ -134,6 +135,7 @@ exports[`renders ./components/calendar/demo/basic.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-button-wrapper" class="ant-radio-button-wrapper"
for="ant-radio-button-wrapper"
> >
<span <span
class="ant-radio-button" class="ant-radio-button"
@ -1161,6 +1163,7 @@ exports[`renders ./components/calendar/demo/card.md correctly 1`] = `
> >
<label <label
class="ant-radio-button-wrapper ant-radio-button-wrapper-checked" class="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
for="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
> >
<span <span
class="ant-radio-button ant-radio-button-checked" class="ant-radio-button ant-radio-button-checked"
@ -1181,6 +1184,7 @@ exports[`renders ./components/calendar/demo/card.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-button-wrapper" class="ant-radio-button-wrapper"
for="ant-radio-button-wrapper"
> >
<span <span
class="ant-radio-button" class="ant-radio-button"
@ -2118,6 +2122,7 @@ exports[`renders ./components/calendar/demo/customize-header.md correctly 1`] =
> >
<label <label
class="ant-radio-button-wrapper ant-radio-button-wrapper-checked" class="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
for="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
> >
<span <span
class="ant-radio-button ant-radio-button-checked" class="ant-radio-button ant-radio-button-checked"
@ -2138,6 +2143,7 @@ exports[`renders ./components/calendar/demo/customize-header.md correctly 1`] =
</label> </label>
<label <label
class="ant-radio-button-wrapper" class="ant-radio-button-wrapper"
for="ant-radio-button-wrapper"
> >
<span <span
class="ant-radio-button" class="ant-radio-button"
@ -3275,6 +3281,7 @@ exports[`renders ./components/calendar/demo/notice-calendar.md correctly 1`] = `
> >
<label <label
class="ant-radio-button-wrapper ant-radio-button-wrapper-checked" class="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
for="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
> >
<span <span
class="ant-radio-button ant-radio-button-checked" class="ant-radio-button ant-radio-button-checked"
@ -3295,6 +3302,7 @@ exports[`renders ./components/calendar/demo/notice-calendar.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-button-wrapper" class="ant-radio-button-wrapper"
for="ant-radio-button-wrapper"
> >
<span <span
class="ant-radio-button" class="ant-radio-button"
@ -4730,6 +4738,7 @@ exports[`renders ./components/calendar/demo/select.md correctly 1`] = `
> >
<label <label
class="ant-radio-button-wrapper ant-radio-button-wrapper-checked" class="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
for="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
> >
<span <span
class="ant-radio-button ant-radio-button-checked" class="ant-radio-button ant-radio-button-checked"
@ -4750,6 +4759,7 @@ exports[`renders ./components/calendar/demo/select.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-button-wrapper" class="ant-radio-button-wrapper"
for="ant-radio-button-wrapper"
> >
<span <span
class="ant-radio-button" class="ant-radio-button"

View File

@ -114,6 +114,7 @@ exports[`Calendar Calendar should support locale 1`] = `
> >
<label <label
class="ant-radio-button-wrapper ant-radio-button-wrapper-checked" class="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
for="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
> >
<span <span
class="ant-radio-button ant-radio-button-checked" class="ant-radio-button ant-radio-button-checked"
@ -134,6 +135,7 @@ exports[`Calendar Calendar should support locale 1`] = `
</label> </label>
<label <label
class="ant-radio-button-wrapper" class="ant-radio-button-wrapper"
for="ant-radio-button-wrapper"
> >
<span <span
class="ant-radio-button" class="ant-radio-button"

View File

@ -2,12 +2,12 @@ import * as React from 'react';
import * as PropTypes from 'prop-types'; import * as PropTypes from 'prop-types';
import * as moment from 'moment'; import * as moment from 'moment';
import FullCalendar from 'rc-calendar/lib/FullCalendar'; import FullCalendar from 'rc-calendar/lib/FullCalendar';
import { polyfill } from 'react-lifecycles-compat';
import Header, { HeaderRender } from './Header'; import Header, { HeaderRender } from './Header';
import enUS from './locale/en_US'; import enUS from './locale/en_US';
import LocaleReceiver from '../locale-provider/LocaleReceiver'; import LocaleReceiver from '../locale-provider/LocaleReceiver';
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider'; import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
import interopDefault from '../_util/interopDefault'; import interopDefault from '../_util/interopDefault';
import { polyfill } from 'react-lifecycles-compat';
export { HeaderProps } from './Header'; export { HeaderProps } from './Header';
@ -104,47 +104,6 @@ class Calendar extends React.Component<CalendarProps, CalendarState> {
}; };
} }
monthCellRender = (value: moment.Moment) => {
const { monthCellRender = noop as Function } = this.props;
const { prefixCls } = this;
return (
<div className={`${prefixCls}-month`}>
<div className={`${prefixCls}-value`}>{value.localeData().monthsShort(value)}</div>
<div className={`${prefixCls}-content`}>{monthCellRender(value)}</div>
</div>
);
};
dateCellRender = (value: moment.Moment) => {
const { dateCellRender = noop as Function } = this.props;
const { prefixCls } = this;
return (
<div className={`${prefixCls}-date`}>
<div className={`${prefixCls}-value`}>{zerofixed(value.date())}</div>
<div className={`${prefixCls}-content`}>{dateCellRender(value)}</div>
</div>
);
};
setValue = (value: moment.Moment, way: 'select' | 'changePanel') => {
const prevValue = this.props.value || this.state.value;
const { mode } = this.state;
if (!('value' in this.props)) {
this.setState({ value });
}
if (way === 'select') {
if (prevValue && prevValue.month() !== value.month()) {
this.onPanelChange(value, mode);
}
if (this.props.onSelect) {
this.props.onSelect(value);
}
} else if (way === 'changePanel') {
this.onPanelChange(value, mode);
}
};
onHeaderValueChange = (value: moment.Moment) => { onHeaderValueChange = (value: moment.Moment) => {
this.setValue(value, 'changePanel'); this.setValue(value, 'changePanel');
}; };
@ -168,6 +127,25 @@ class Calendar extends React.Component<CalendarProps, CalendarState> {
this.setValue(value, 'select'); this.setValue(value, 'select');
}; };
setValue = (value: moment.Moment, way: 'select' | 'changePanel') => {
const prevValue = this.props.value || this.state.value;
const { mode } = this.state;
if (!('value' in this.props)) {
this.setState({ value });
}
if (way === 'select') {
if (prevValue && prevValue.month() !== value.month()) {
this.onPanelChange(value, mode);
}
if (this.props.onSelect) {
this.props.onSelect(value);
}
} else if (way === 'changePanel') {
this.onPanelChange(value, mode);
}
};
getDateRange = ( getDateRange = (
validRange: [moment.Moment, moment.Moment], validRange: [moment.Moment, moment.Moment],
disabledDate?: (current: moment.Moment) => boolean, disabledDate?: (current: moment.Moment) => boolean,
@ -195,6 +173,28 @@ class Calendar extends React.Component<CalendarProps, CalendarState> {
return result; return result;
}; };
monthCellRender = (value: moment.Moment) => {
const { monthCellRender = noop as Function } = this.props;
const { prefixCls } = this;
return (
<div className={`${prefixCls}-month`}>
<div className={`${prefixCls}-value`}>{value.localeData().monthsShort(value)}</div>
<div className={`${prefixCls}-content`}>{monthCellRender(value)}</div>
</div>
);
};
dateCellRender = (value: moment.Moment) => {
const { dateCellRender = noop as Function } = this.props;
const { prefixCls } = this;
return (
<div className={`${prefixCls}-date`}>
<div className={`${prefixCls}-value`}>{zerofixed(value.date())}</div>
<div className={`${prefixCls}-content`}>{dateCellRender(value)}</div>
</div>
);
};
renderCalendar = (locale: any, localeCode: string) => { renderCalendar = (locale: any, localeCode: string) => {
const { state, props } = this; const { state, props } = this;
const { value, mode } = state; const { value, mode } = state;
@ -213,7 +213,7 @@ class Calendar extends React.Component<CalendarProps, CalendarState> {
const monthCellRender = monthFullCellRender || this.monthCellRender; const monthCellRender = monthFullCellRender || this.monthCellRender;
const dateCellRender = dateFullCellRender || this.dateCellRender; const dateCellRender = dateFullCellRender || this.dateCellRender;
let disabledDate = props.disabledDate; let { disabledDate } = props;
if (props.validRange) { if (props.validRange) {
disabledDate = this.getDateRange(props.validRange, disabledDate); disabledDate = this.getDateRange(props.validRange, disabledDate);

View File

@ -10,6 +10,16 @@ import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
import warning from '../_util/warning'; import warning from '../_util/warning';
import { Omit } from '../_util/type'; import { Omit } from '../_util/type';
function getAction(actions: React.ReactNode[]) {
const actionList = actions.map((action, index) => (
/* eslint-disable react/no-array-index-key */
<li style={{ width: `${100 / actions.length}%` }} key={`action-${index}`}>
<span>{action}</span>
</li>
));
return actionList;
}
export { CardGridProps } from './Grid'; export { CardGridProps } from './Grid';
export { CardMetaProps } from './Meta'; export { CardMetaProps } from './Meta';
@ -48,6 +58,7 @@ export interface CardProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 't
export default class Card extends React.Component<CardProps, {}> { export default class Card extends React.Component<CardProps, {}> {
static Grid: typeof Grid = Grid; static Grid: typeof Grid = Grid;
static Meta: typeof Meta = Meta; static Meta: typeof Meta = Meta;
componentDidMount() { componentDidMount() {
@ -65,6 +76,15 @@ export default class Card extends React.Component<CardProps, {}> {
} }
} }
// For 2.x compatible
getCompatibleHoverable() {
const { noHovering, hoverable } = this.props;
if ('noHovering' in this.props) {
return !noHovering || hoverable;
}
return !!hoverable;
}
onTabChange = (key: string) => { onTabChange = (key: string) => {
if (this.props.onTabChange) { if (this.props.onTabChange) {
this.props.onTabChange(key); this.props.onTabChange(key);
@ -81,24 +101,6 @@ export default class Card extends React.Component<CardProps, {}> {
return containGrid; return containGrid;
} }
getAction(actions: React.ReactNode[]) {
const actionList = actions.map((action, index) => (
<li style={{ width: `${100 / actions.length}%` }} key={`action-${index}`}>
<span>{action}</span>
</li>
));
return actionList;
}
// For 2.x compatible
getCompatibleHoverable() {
const { noHovering, hoverable } = this.props;
if ('noHovering' in this.props) {
return !noHovering || hoverable;
}
return !!hoverable;
}
renderCard = ({ getPrefixCls }: ConfigConsumerProps) => { renderCard = ({ getPrefixCls }: ConfigConsumerProps) => {
const { const {
prefixCls: customizePrefixCls, prefixCls: customizePrefixCls,
@ -106,8 +108,6 @@ export default class Card extends React.Component<CardProps, {}> {
extra, extra,
headStyle = {}, headStyle = {},
bodyStyle = {}, bodyStyle = {},
noHovering,
hoverable,
title, title,
loading, loading,
bordered = true, bordered = true,
@ -221,9 +221,9 @@ export default class Card extends React.Component<CardProps, {}> {
); );
const actionDom = const actionDom =
actions && actions.length ? ( actions && actions.length ? (
<ul className={`${prefixCls}-actions`}>{this.getAction(actions)}</ul> <ul className={`${prefixCls}-actions`}>{getAction(actions)}</ul>
) : null; ) : null;
const divProps = omit(others, ['onTabChange']); const divProps = omit(others, ['onTabChange', 'noHovering', 'hoverable']);
return ( return (
<div {...divProps} className={classString}> <div {...divProps} className={classString}>
{head} {head}

View File

@ -566,6 +566,7 @@ exports[`renders ./components/carousel/demo/position.md correctly 1`] = `
> >
<label <label
class="ant-radio-button-wrapper ant-radio-button-wrapper-checked" class="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
for="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
> >
<span <span
class="ant-radio-button ant-radio-button-checked" class="ant-radio-button ant-radio-button-checked"
@ -586,6 +587,7 @@ exports[`renders ./components/carousel/demo/position.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-button-wrapper" class="ant-radio-button-wrapper"
for="ant-radio-button-wrapper"
> >
<span <span
class="ant-radio-button" class="ant-radio-button"
@ -605,6 +607,7 @@ exports[`renders ./components/carousel/demo/position.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-button-wrapper" class="ant-radio-button-wrapper"
for="ant-radio-button-wrapper"
> >
<span <span
class="ant-radio-button" class="ant-radio-button"
@ -624,6 +627,7 @@ exports[`renders ./components/carousel/demo/position.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-button-wrapper" class="ant-radio-button-wrapper"
for="ant-radio-button-wrapper"
> >
<span <span
class="ant-radio-button" class="ant-radio-button"

View File

@ -1,7 +1,7 @@
import * as React from 'react'; import * as React from 'react';
import debounce from 'lodash/debounce'; import debounce from 'lodash/debounce';
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
import { Settings } from 'react-slick'; import { Settings } from 'react-slick';
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
import warning from '../_util/warning'; import warning from '../_util/warning';
// matchMedia polyfill for // matchMedia polyfill for
@ -85,6 +85,20 @@ export default class Carousel extends React.Component<CarouselProps, {}> {
} }
} }
getDotPosition(): DotPosition {
if (this.props.dotPosition) {
return this.props.dotPosition;
}
if ('vertical' in this.props) {
return this.props.vertical ? 'right' : 'bottom';
}
return 'bottom';
}
saveSlick = (node: any) => {
this.slick = node;
};
onWindowResized = () => { onWindowResized = () => {
// Fix https://github.com/ant-design/ant-design/issues/2550 // Fix https://github.com/ant-design/ant-design/issues/2550
const { autoplay } = this.props; const { autoplay } = this.props;
@ -93,10 +107,6 @@ export default class Carousel extends React.Component<CarouselProps, {}> {
} }
}; };
saveSlick = (node: any) => {
this.slick = node;
};
next() { next() {
this.slick.slickNext(); this.slick.slickNext();
} }
@ -109,15 +119,6 @@ export default class Carousel extends React.Component<CarouselProps, {}> {
this.slick.slickGoTo(slide, dontAnimate); this.slick.slickGoTo(slide, dontAnimate);
} }
getDotPosition(): DotPosition {
if (this.props.dotPosition) {
return this.props.dotPosition;
} else if ('vertical' in this.props) {
return this.props.vertical ? 'right' : 'bottom';
}
return 'bottom';
}
renderCarousel = ({ getPrefixCls }: ConfigConsumerProps) => { renderCarousel = ({ getPrefixCls }: ConfigConsumerProps) => {
const props = { const props = {
...this.props, ...this.props,

View File

@ -1218,7 +1218,7 @@ exports[`Cascader should render not found content 1`] = `
> >
<Empty <Empty
className="ant-empty-small" className="ant-empty-small"
image={<_default />} image={<Simple />}
> >
<LocaleReceiver <LocaleReceiver
componentName="Empty" componentName="Empty"
@ -1229,7 +1229,7 @@ exports[`Cascader should render not found content 1`] = `
<div <div
className="ant-empty-image" className="ant-empty-image"
> >
<_default> <Simple>
<svg <svg
height="41" height="41"
viewBox="0 0 64 41" viewBox="0 0 64 41"
@ -1262,7 +1262,7 @@ exports[`Cascader should render not found content 1`] = `
</g> </g>
</g> </g>
</svg> </svg>
</_default> </Simple>
</div> </div>
<p <p
className="ant-empty-description" className="ant-empty-description"
@ -1541,7 +1541,7 @@ exports[`Cascader should show not found content when options.length is 0 1`] = `
> >
<Empty <Empty
className="ant-empty-small" className="ant-empty-small"
image={<_default />} image={<Simple />}
> >
<LocaleReceiver <LocaleReceiver
componentName="Empty" componentName="Empty"
@ -1552,7 +1552,7 @@ exports[`Cascader should show not found content when options.length is 0 1`] = `
<div <div
className="ant-empty-image" className="ant-empty-image"
> >
<_default> <Simple>
<svg <svg
height="41" height="41"
viewBox="0 0 64 41" viewBox="0 0 64 41"
@ -1585,7 +1585,7 @@ exports[`Cascader should show not found content when options.length is 0 1`] = `
</g> </g>
</g> </g>
</svg> </svg>
</_default> </Simple>
</div> </div>
<p <p
className="ant-empty-description" className="ant-empty-description"

View File

@ -72,13 +72,13 @@ export interface CascaderProps {
popupClassName?: string; popupClassName?: string;
/** 浮层预设位置:`bottomLeft` `bottomRight` `topLeft` `topRight` */ /** 浮层预设位置:`bottomLeft` `bottomRight` `topLeft` `topRight` */
popupPlacement?: string; popupPlacement?: string;
/** 输入框占位文本*/ /** 输入框占位文本 */
placeholder?: string; placeholder?: string;
/** 输入框大小,可选 `large` `default` `small` */ /** 输入框大小,可选 `large` `default` `small` */
size?: string; size?: string;
/** 禁用*/ /** 禁用 */
disabled?: boolean; disabled?: boolean;
/** 是否支持清除*/ /** 是否支持清除 */
allowClear?: boolean; allowClear?: boolean;
showSearch?: boolean | ShowSearchType; showSearch?: boolean | ShowSearchType;
notFoundContent?: React.ReactNode; notFoundContent?: React.ReactNode;
@ -262,6 +262,34 @@ class Cascader extends React.Component<CascaderProps, CascaderState> {
}; };
} }
setValue = (value: string[], selectedOptions: CascaderOptionType[] = []) => {
if (!('value' in this.props)) {
this.setState({ value });
}
const { onChange } = this.props;
if (onChange) {
onChange(value, selectedOptions);
}
};
getLabel() {
const { options, displayRender = defaultDisplayRender as Function } = this.props;
const names = getFilledFieldNames(this.props);
const { value } = this.state;
const unwrappedValue = Array.isArray(value[0]) ? value[0] : value;
const selectedOptions: CascaderOptionType[] = arrayTreeFilter(
options,
(o: CascaderOptionType, level: number) => o[names.value] === unwrappedValue[level],
{ childrenKeyName: names.children },
);
const label = selectedOptions.map(o => o[names.label]);
return displayRender(label, selectedOptions);
}
saveInput = (node: Input) => {
this.input = node;
};
handleChange = (value: any, selectedOptions: CascaderOptionType[]) => { handleChange = (value: any, selectedOptions: CascaderOptionType[]) => {
this.setState({ inputValue: '' }); this.setState({ inputValue: '' });
if (selectedOptions[0].__IS_FILTERED_OPTION) { if (selectedOptions[0].__IS_FILTERED_OPTION) {
@ -282,7 +310,7 @@ class Cascader extends React.Component<CascaderProps, CascaderState> {
})); }));
} }
const onPopupVisibleChange = this.props.onPopupVisibleChange; const { onPopupVisibleChange } = this.props;
if (onPopupVisibleChange) { if (onPopupVisibleChange) {
onPopupVisibleChange(popupVisible); onPopupVisibleChange(popupVisible);
} }
@ -317,30 +345,6 @@ class Cascader extends React.Component<CascaderProps, CascaderState> {
this.setState({ inputValue }); this.setState({ inputValue });
}; };
setValue = (value: string[], selectedOptions: CascaderOptionType[] = []) => {
if (!('value' in this.props)) {
this.setState({ value });
}
const onChange = this.props.onChange;
if (onChange) {
onChange(value, selectedOptions);
}
};
getLabel() {
const { options, displayRender = defaultDisplayRender as Function } = this.props;
const names = getFilledFieldNames(this.props);
const value = this.state.value;
const unwrappedValue = Array.isArray(value[0]) ? value[0] : value;
const selectedOptions: CascaderOptionType[] = arrayTreeFilter(
options,
(o: CascaderOptionType, level: number) => o[names.value] === unwrappedValue[level],
{ childrenKeyName: names.children },
);
const label = selectedOptions.map(o => o[names.label]);
return displayRender(label, selectedOptions);
}
clearSelection = (e: React.MouseEvent<HTMLElement>) => { clearSelection = (e: React.MouseEvent<HTMLElement>) => {
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
@ -417,10 +421,6 @@ class Cascader extends React.Component<CascaderProps, CascaderState> {
this.input.blur(); this.input.blur();
} }
saveInput = (node: Input) => {
this.input = node;
};
renderCascader = ( renderCascader = (
{ getPopupContainer: getContextPopupContainer, getPrefixCls, renderEmpty }: ConfigConsumerProps, { getPopupContainer: getContextPopupContainer, getPrefixCls, renderEmpty }: ConfigConsumerProps,
locale: CascaderLocale, locale: CascaderLocale,
@ -495,7 +495,7 @@ class Cascader extends React.Component<CascaderProps, CascaderState> {
'filedNames', // For old compatibility 'filedNames', // For old compatibility
]); ]);
let options = props.options; let { options } = props;
if (options.length > 0) { if (options.length > 0) {
if (state.inputValue) { if (state.inputValue) {
options = this.generateFilteredOptions(prefixCls, renderEmpty); options = this.generateFilteredOptions(prefixCls, renderEmpty);
@ -524,8 +524,7 @@ class Cascader extends React.Component<CascaderProps, CascaderState> {
dropdownMenuColumnStyle.height = 'auto'; // Height of one row. dropdownMenuColumnStyle.height = 'auto'; // Height of one row.
} }
// The default value of `matchInputWidth` is `true` // The default value of `matchInputWidth` is `true`
const resultListMatchInputWidth = const resultListMatchInputWidth = (showSearch as ShowSearchType).matchInputWidth !== false;
(showSearch as ShowSearchType).matchInputWidth === false ? false : true;
if (resultListMatchInputWidth && (state.inputValue || isNotFound) && this.input) { if (resultListMatchInputWidth && (state.inputValue || isNotFound) && this.input) {
dropdownMenuColumnStyle.width = this.input.input.offsetWidth; dropdownMenuColumnStyle.width = this.input.input.offsetWidth;
} }

View File

@ -45,6 +45,7 @@ export interface CheckboxChangeEvent {
class Checkbox extends React.Component<CheckboxProps, {}> { class Checkbox extends React.Component<CheckboxProps, {}> {
static Group: typeof CheckboxGroup; static Group: typeof CheckboxGroup;
static defaultProps = { static defaultProps = {
indeterminate: false, indeterminate: false,
}; };
@ -65,6 +66,18 @@ class Checkbox extends React.Component<CheckboxProps, {}> {
} }
} }
shouldComponentUpdate(
nextProps: CheckboxProps,
nextState: {},
nextContext: CheckboxGroupContext,
) {
return (
!shallowEqual(this.props, nextProps) ||
!shallowEqual(this.state, nextState) ||
!shallowEqual(this.context.checkboxGroup, nextContext.checkboxGroup)
);
}
componentDidUpdate({ value: prevValue }: CheckboxProps) { componentDidUpdate({ value: prevValue }: CheckboxProps) {
const { value } = this.props; const { value } = this.props;
const { checkboxGroup = {} } = this.context || {}; const { checkboxGroup = {} } = this.context || {};
@ -82,17 +95,9 @@ class Checkbox extends React.Component<CheckboxProps, {}> {
} }
} }
shouldComponentUpdate( saveCheckbox = (node: any) => {
nextProps: CheckboxProps, this.rcCheckbox = node;
nextState: {}, };
nextContext: CheckboxGroupContext,
) {
return (
!shallowEqual(this.props, nextProps) ||
!shallowEqual(this.state, nextState) ||
!shallowEqual(this.context.checkboxGroup, nextContext.checkboxGroup)
);
}
focus() { focus() {
this.rcCheckbox.focus(); this.rcCheckbox.focus();
@ -102,10 +107,6 @@ class Checkbox extends React.Component<CheckboxProps, {}> {
this.rcCheckbox.blur(); this.rcCheckbox.blur();
} }
saveCheckbox = (node: any) => {
this.rcCheckbox = node;
};
renderCheckbox = ({ getPrefixCls }: ConfigConsumerProps) => { renderCheckbox = ({ getPrefixCls }: ConfigConsumerProps) => {
const { props, context } = this; const { props, context } = this;
const { const {
@ -142,6 +143,7 @@ class Checkbox extends React.Component<CheckboxProps, {}> {
}); });
return ( return (
<label <label
htmlFor="checkbox-label"
className={classString} className={classString}
style={style} style={style}
onMouseEnter={onMouseEnter} onMouseEnter={onMouseEnter}

View File

@ -96,18 +96,6 @@ class CheckboxGroup extends React.Component<CheckboxGroupProps, CheckboxGroupSta
return !shallowEqual(this.props, nextProps) || !shallowEqual(this.state, nextState); return !shallowEqual(this.props, nextProps) || !shallowEqual(this.state, nextState);
} }
registerValue = (value: string) => {
this.setState(({ registeredValues }) => ({
registeredValues: [...registeredValues, value],
}));
};
cancelValue = (value: string) => {
this.setState(({ registeredValues }) => ({
registeredValues: registeredValues.filter(val => val !== value),
}));
};
getOptions() { getOptions() {
const { options } = this.props; const { options } = this.props;
// https://github.com/Microsoft/TypeScript/issues/7960 // https://github.com/Microsoft/TypeScript/issues/7960
@ -122,6 +110,18 @@ class CheckboxGroup extends React.Component<CheckboxGroupProps, CheckboxGroupSta
}); });
} }
cancelValue = (value: string) => {
this.setState(({ registeredValues }) => ({
registeredValues: registeredValues.filter(val => val !== value),
}));
};
registerValue = (value: string) => {
this.setState(({ registeredValues }) => ({
registeredValues: [...registeredValues, value],
}));
};
toggleOption = (option: CheckboxOptionType) => { toggleOption = (option: CheckboxOptionType) => {
const { registeredValues } = this.state; const { registeredValues } = this.state;
const optionIndex = this.state.value.indexOf(option.value); const optionIndex = this.state.value.indexOf(option.value);
@ -134,7 +134,7 @@ class CheckboxGroup extends React.Component<CheckboxGroupProps, CheckboxGroupSta
if (!('value' in this.props)) { if (!('value' in this.props)) {
this.setState({ value }); this.setState({ value });
} }
const onChange = this.props.onChange; const { onChange } = this.props;
if (onChange) { if (onChange) {
const options = this.getOptions(); const options = this.getOptions();
onChange( onChange(
@ -157,7 +157,7 @@ class CheckboxGroup extends React.Component<CheckboxGroupProps, CheckboxGroupSta
const domProps = omit(restProps, ['children', 'defaultValue', 'value', 'onChange', 'disabled']); const domProps = omit(restProps, ['children', 'defaultValue', 'value', 'onChange', 'disabled']);
let children = props.children; let { children } = props;
if (options && options.length > 0) { if (options && options.length > 0) {
children = this.getOptions().map(option => ( children = this.getOptions().map(option => (
<Checkbox <Checkbox

View File

@ -3,6 +3,7 @@
exports[`renders ./components/checkbox/demo/basic.md correctly 1`] = ` exports[`renders ./components/checkbox/demo/basic.md correctly 1`] = `
<label <label
class="ant-checkbox-wrapper" class="ant-checkbox-wrapper"
for="checkbox-label"
> >
<span <span
class="ant-checkbox" class="ant-checkbox"
@ -28,6 +29,7 @@ exports[`renders ./components/checkbox/demo/check-all.md correctly 1`] = `
> >
<label <label
class="ant-checkbox-wrapper" class="ant-checkbox-wrapper"
for="checkbox-label"
> >
<span <span
class="ant-checkbox ant-checkbox-indeterminate" class="ant-checkbox ant-checkbox-indeterminate"
@ -51,6 +53,7 @@ exports[`renders ./components/checkbox/demo/check-all.md correctly 1`] = `
> >
<label <label
class="ant-checkbox-group-item ant-checkbox-wrapper ant-checkbox-wrapper-checked" class="ant-checkbox-group-item ant-checkbox-wrapper ant-checkbox-wrapper-checked"
for="checkbox-label"
> >
<span <span
class="ant-checkbox ant-checkbox-checked" class="ant-checkbox ant-checkbox-checked"
@ -71,6 +74,7 @@ exports[`renders ./components/checkbox/demo/check-all.md correctly 1`] = `
</label> </label>
<label <label
class="ant-checkbox-group-item ant-checkbox-wrapper" class="ant-checkbox-group-item ant-checkbox-wrapper"
for="checkbox-label"
> >
<span <span
class="ant-checkbox" class="ant-checkbox"
@ -90,6 +94,7 @@ exports[`renders ./components/checkbox/demo/check-all.md correctly 1`] = `
</label> </label>
<label <label
class="ant-checkbox-group-item ant-checkbox-wrapper ant-checkbox-wrapper-checked" class="ant-checkbox-group-item ant-checkbox-wrapper ant-checkbox-wrapper-checked"
for="checkbox-label"
> >
<span <span
class="ant-checkbox ant-checkbox-checked" class="ant-checkbox ant-checkbox-checked"
@ -119,6 +124,7 @@ exports[`renders ./components/checkbox/demo/controller.md correctly 1`] = `
> >
<label <label
class="ant-checkbox-wrapper ant-checkbox-wrapper-checked" class="ant-checkbox-wrapper ant-checkbox-wrapper-checked"
for="checkbox-label"
> >
<span <span
class="ant-checkbox ant-checkbox-checked" class="ant-checkbox ant-checkbox-checked"
@ -163,6 +169,7 @@ exports[`renders ./components/checkbox/demo/disabled.md correctly 1`] = `
<div> <div>
<label <label
class="ant-checkbox-wrapper ant-checkbox-wrapper-disabled" class="ant-checkbox-wrapper ant-checkbox-wrapper-disabled"
for="checkbox-label"
> >
<span <span
class="ant-checkbox ant-checkbox-disabled" class="ant-checkbox ant-checkbox-disabled"
@ -180,6 +187,7 @@ exports[`renders ./components/checkbox/demo/disabled.md correctly 1`] = `
<br /> <br />
<label <label
class="ant-checkbox-wrapper ant-checkbox-wrapper-disabled" class="ant-checkbox-wrapper ant-checkbox-wrapper-disabled"
for="checkbox-label"
> >
<span <span
class="ant-checkbox ant-checkbox-checked ant-checkbox-disabled" class="ant-checkbox ant-checkbox-checked ant-checkbox-disabled"
@ -205,6 +213,7 @@ exports[`renders ./components/checkbox/demo/group.md correctly 1`] = `
> >
<label <label
class="ant-checkbox-group-item ant-checkbox-wrapper ant-checkbox-wrapper-checked" class="ant-checkbox-group-item ant-checkbox-wrapper ant-checkbox-wrapper-checked"
for="checkbox-label"
> >
<span <span
class="ant-checkbox ant-checkbox-checked" class="ant-checkbox ant-checkbox-checked"
@ -225,6 +234,7 @@ exports[`renders ./components/checkbox/demo/group.md correctly 1`] = `
</label> </label>
<label <label
class="ant-checkbox-group-item ant-checkbox-wrapper" class="ant-checkbox-group-item ant-checkbox-wrapper"
for="checkbox-label"
> >
<span <span
class="ant-checkbox" class="ant-checkbox"
@ -244,6 +254,7 @@ exports[`renders ./components/checkbox/demo/group.md correctly 1`] = `
</label> </label>
<label <label
class="ant-checkbox-group-item ant-checkbox-wrapper" class="ant-checkbox-group-item ant-checkbox-wrapper"
for="checkbox-label"
> >
<span <span
class="ant-checkbox" class="ant-checkbox"
@ -269,6 +280,7 @@ exports[`renders ./components/checkbox/demo/group.md correctly 1`] = `
> >
<label <label
class="ant-checkbox-group-item ant-checkbox-wrapper" class="ant-checkbox-group-item ant-checkbox-wrapper"
for="checkbox-label"
> >
<span <span
class="ant-checkbox" class="ant-checkbox"
@ -288,6 +300,7 @@ exports[`renders ./components/checkbox/demo/group.md correctly 1`] = `
</label> </label>
<label <label
class="ant-checkbox-group-item ant-checkbox-wrapper ant-checkbox-wrapper-checked" class="ant-checkbox-group-item ant-checkbox-wrapper ant-checkbox-wrapper-checked"
for="checkbox-label"
> >
<span <span
class="ant-checkbox ant-checkbox-checked" class="ant-checkbox ant-checkbox-checked"
@ -308,6 +321,7 @@ exports[`renders ./components/checkbox/demo/group.md correctly 1`] = `
</label> </label>
<label <label
class="ant-checkbox-group-item ant-checkbox-wrapper" class="ant-checkbox-group-item ant-checkbox-wrapper"
for="checkbox-label"
> >
<span <span
class="ant-checkbox" class="ant-checkbox"
@ -333,6 +347,7 @@ exports[`renders ./components/checkbox/demo/group.md correctly 1`] = `
> >
<label <label
class="ant-checkbox-group-item ant-checkbox-wrapper ant-checkbox-wrapper-checked ant-checkbox-wrapper-disabled" class="ant-checkbox-group-item ant-checkbox-wrapper ant-checkbox-wrapper-checked ant-checkbox-wrapper-disabled"
for="checkbox-label"
> >
<span <span
class="ant-checkbox ant-checkbox-checked ant-checkbox-disabled" class="ant-checkbox ant-checkbox-checked ant-checkbox-disabled"
@ -354,6 +369,7 @@ exports[`renders ./components/checkbox/demo/group.md correctly 1`] = `
</label> </label>
<label <label
class="ant-checkbox-group-item ant-checkbox-wrapper ant-checkbox-wrapper-disabled" class="ant-checkbox-group-item ant-checkbox-wrapper ant-checkbox-wrapper-disabled"
for="checkbox-label"
> >
<span <span
class="ant-checkbox ant-checkbox-disabled" class="ant-checkbox ant-checkbox-disabled"
@ -374,6 +390,7 @@ exports[`renders ./components/checkbox/demo/group.md correctly 1`] = `
</label> </label>
<label <label
class="ant-checkbox-group-item ant-checkbox-wrapper ant-checkbox-wrapper-disabled" class="ant-checkbox-group-item ant-checkbox-wrapper ant-checkbox-wrapper-disabled"
for="checkbox-label"
> >
<span <span
class="ant-checkbox ant-checkbox-disabled" class="ant-checkbox ant-checkbox-disabled"
@ -409,6 +426,7 @@ exports[`renders ./components/checkbox/demo/layout.md correctly 1`] = `
> >
<label <label
class="ant-checkbox-wrapper" class="ant-checkbox-wrapper"
for="checkbox-label"
> >
<span <span
class="ant-checkbox" class="ant-checkbox"
@ -432,6 +450,7 @@ exports[`renders ./components/checkbox/demo/layout.md correctly 1`] = `
> >
<label <label
class="ant-checkbox-wrapper" class="ant-checkbox-wrapper"
for="checkbox-label"
> >
<span <span
class="ant-checkbox" class="ant-checkbox"
@ -455,6 +474,7 @@ exports[`renders ./components/checkbox/demo/layout.md correctly 1`] = `
> >
<label <label
class="ant-checkbox-wrapper" class="ant-checkbox-wrapper"
for="checkbox-label"
> >
<span <span
class="ant-checkbox" class="ant-checkbox"
@ -478,6 +498,7 @@ exports[`renders ./components/checkbox/demo/layout.md correctly 1`] = `
> >
<label <label
class="ant-checkbox-wrapper" class="ant-checkbox-wrapper"
for="checkbox-label"
> >
<span <span
class="ant-checkbox" class="ant-checkbox"
@ -501,6 +522,7 @@ exports[`renders ./components/checkbox/demo/layout.md correctly 1`] = `
> >
<label <label
class="ant-checkbox-wrapper" class="ant-checkbox-wrapper"
for="checkbox-label"
> >
<span <span
class="ant-checkbox" class="ant-checkbox"

View File

@ -6,6 +6,7 @@ exports[`CheckboxGroup passes prefixCls down to checkbox 1`] = `
> >
<label <label
class="my-checkbox-group-item my-checkbox-wrapper" class="my-checkbox-group-item my-checkbox-wrapper"
for="checkbox-label"
> >
<span <span
class="my-checkbox" class="my-checkbox"
@ -25,6 +26,7 @@ exports[`CheckboxGroup passes prefixCls down to checkbox 1`] = `
</label> </label>
<label <label
class="my-checkbox-group-item my-checkbox-wrapper" class="my-checkbox-group-item my-checkbox-wrapper"
for="checkbox-label"
> >
<span <span
class="my-checkbox" class="my-checkbox"

View File

@ -230,6 +230,7 @@ exports[`renders ./components/comment/demo/list.md correctly 1`] = `
class="ant-comment-avatar" class="ant-comment-avatar"
> >
<img <img
alt="comment-avatar"
src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png"
/> />
</div> </div>
@ -283,6 +284,7 @@ exports[`renders ./components/comment/demo/list.md correctly 1`] = `
class="ant-comment-avatar" class="ant-comment-avatar"
> >
<img <img
alt="comment-avatar"
src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png"
/> />
</div> </div>

View File

@ -2,6 +2,15 @@ import * as React from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider'; import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
function getAction(actions: React.ReactNode[]) {
if (!actions || !actions.length) {
return null;
}
/* eslint-disable react/no-array-index-key */
const actionList = actions.map((action, index) => <li key={`action-${index}`}>{action}</li>);
return actionList;
}
export interface CommentProps { export interface CommentProps {
/** List of action items rendered below the comment content */ /** List of action items rendered below the comment content */
actions?: Array<React.ReactNode>; actions?: Array<React.ReactNode>;
@ -24,14 +33,6 @@ export interface CommentProps {
} }
export default class Comment extends React.Component<CommentProps, {}> { export default class Comment extends React.Component<CommentProps, {}> {
getAction(actions: React.ReactNode[]) {
if (!actions || !actions.length) {
return null;
}
const actionList = actions.map((action, index) => <li key={`action-${index}`}>{action}</li>);
return actionList;
}
renderNested = (prefixCls: string, children: any) => { renderNested = (prefixCls: string, children: any) => {
return <div className={classNames(`${prefixCls}-nested`)}>{children}</div>; return <div className={classNames(`${prefixCls}-nested`)}>{children}</div>;
}; };
@ -54,13 +55,13 @@ export default class Comment extends React.Component<CommentProps, {}> {
const avatarDom = ( const avatarDom = (
<div className={`${prefixCls}-avatar`}> <div className={`${prefixCls}-avatar`}>
{typeof avatar === 'string' ? <img src={avatar} /> : avatar} {typeof avatar === 'string' ? <img src={avatar} alt="comment-avatar" /> : avatar}
</div> </div>
); );
const actionDom = const actionDom =
actions && actions.length ? ( actions && actions.length ? (
<ul className={`${prefixCls}-actions`}>{this.getAction(actions)}</ul> <ul className={`${prefixCls}-actions`}>{getAction(actions)}</ul>
) : null; ) : null;
const authorContent = ( const authorContent = (

View File

@ -1273,6 +1273,7 @@ exports[`ConfigProvider components Calendar configProvider 1`] = `
> >
<label <label
class="config-radio-button-wrapper config-radio-button-wrapper-checked" class="config-radio-button-wrapper config-radio-button-wrapper-checked"
for="config-radio-button-wrapper config-radio-button-wrapper-checked"
> >
<span <span
class="config-radio-button config-radio-button-checked" class="config-radio-button config-radio-button-checked"
@ -1293,6 +1294,7 @@ exports[`ConfigProvider components Calendar configProvider 1`] = `
</label> </label>
<label <label
class="config-radio-button-wrapper" class="config-radio-button-wrapper"
for="config-radio-button-wrapper"
> >
<span <span
class="config-radio-button" class="config-radio-button"
@ -2263,6 +2265,7 @@ exports[`ConfigProvider components Calendar configProvider 1`] = `
> >
<label <label
class="config-radio-button-wrapper" class="config-radio-button-wrapper"
for="config-radio-button-wrapper"
> >
<span <span
class="config-radio-button" class="config-radio-button"
@ -2282,6 +2285,7 @@ exports[`ConfigProvider components Calendar configProvider 1`] = `
</label> </label>
<label <label
class="config-radio-button-wrapper config-radio-button-wrapper-checked" class="config-radio-button-wrapper config-radio-button-wrapper-checked"
for="config-radio-button-wrapper config-radio-button-wrapper-checked"
> >
<span <span
class="config-radio-button config-radio-button-checked" class="config-radio-button config-radio-button-checked"
@ -2672,6 +2676,7 @@ exports[`ConfigProvider components Calendar normal 1`] = `
> >
<label <label
class="ant-radio-button-wrapper ant-radio-button-wrapper-checked" class="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
for="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
> >
<span <span
class="ant-radio-button ant-radio-button-checked" class="ant-radio-button ant-radio-button-checked"
@ -2692,6 +2697,7 @@ exports[`ConfigProvider components Calendar normal 1`] = `
</label> </label>
<label <label
class="ant-radio-button-wrapper" class="ant-radio-button-wrapper"
for="ant-radio-button-wrapper"
> >
<span <span
class="ant-radio-button" class="ant-radio-button"
@ -3662,6 +3668,7 @@ exports[`ConfigProvider components Calendar normal 1`] = `
> >
<label <label
class="ant-radio-button-wrapper" class="ant-radio-button-wrapper"
for="ant-radio-button-wrapper"
> >
<span <span
class="ant-radio-button" class="ant-radio-button"
@ -3681,6 +3688,7 @@ exports[`ConfigProvider components Calendar normal 1`] = `
</label> </label>
<label <label
class="ant-radio-button-wrapper ant-radio-button-wrapper-checked" class="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
for="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
> >
<span <span
class="ant-radio-button ant-radio-button-checked" class="ant-radio-button ant-radio-button-checked"
@ -4071,6 +4079,7 @@ exports[`ConfigProvider components Calendar prefixCls 1`] = `
> >
<label <label
class="ant-radio-button-wrapper ant-radio-button-wrapper-checked" class="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
for="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
> >
<span <span
class="ant-radio-button ant-radio-button-checked" class="ant-radio-button ant-radio-button-checked"
@ -4091,6 +4100,7 @@ exports[`ConfigProvider components Calendar prefixCls 1`] = `
</label> </label>
<label <label
class="ant-radio-button-wrapper" class="ant-radio-button-wrapper"
for="ant-radio-button-wrapper"
> >
<span <span
class="ant-radio-button" class="ant-radio-button"
@ -5061,6 +5071,7 @@ exports[`ConfigProvider components Calendar prefixCls 1`] = `
> >
<label <label
class="ant-radio-button-wrapper" class="ant-radio-button-wrapper"
for="ant-radio-button-wrapper"
> >
<span <span
class="ant-radio-button" class="ant-radio-button"
@ -5080,6 +5091,7 @@ exports[`ConfigProvider components Calendar prefixCls 1`] = `
</label> </label>
<label <label
class="ant-radio-button-wrapper ant-radio-button-wrapper-checked" class="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
for="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
> >
<span <span
class="ant-radio-button ant-radio-button-checked" class="ant-radio-button ant-radio-button-checked"
@ -5919,6 +5931,7 @@ exports[`ConfigProvider components Checkbox configProvider 1`] = `
> >
<label <label
class="config-checkbox-wrapper" class="config-checkbox-wrapper"
for="checkbox-label"
> >
<span <span
class="config-checkbox" class="config-checkbox"
@ -5944,6 +5957,7 @@ exports[`ConfigProvider components Checkbox normal 1`] = `
> >
<label <label
class="ant-checkbox-wrapper" class="ant-checkbox-wrapper"
for="checkbox-label"
> >
<span <span
class="ant-checkbox" class="ant-checkbox"
@ -5969,6 +5983,7 @@ exports[`ConfigProvider components Checkbox prefixCls 1`] = `
> >
<label <label
class="prefix-Checkbox-wrapper" class="prefix-Checkbox-wrapper"
for="checkbox-label"
> >
<span <span
class="prefix-Checkbox" class="prefix-Checkbox"
@ -9682,6 +9697,7 @@ exports[`ConfigProvider components Radio configProvider 1`] = `
> >
<label <label
class="config-radio-wrapper config-radio-wrapper-checked" class="config-radio-wrapper config-radio-wrapper-checked"
for="config-radio-wrapper config-radio-wrapper-checked"
> >
<span <span
class="config-radio config-radio-checked" class="config-radio config-radio-checked"
@ -9705,6 +9721,7 @@ exports[`ConfigProvider components Radio configProvider 1`] = `
> >
<label <label
class="config-radio-button-wrapper config-radio-button-wrapper-checked" class="config-radio-button-wrapper config-radio-button-wrapper-checked"
for="config-radio-button-wrapper config-radio-button-wrapper-checked"
> >
<span <span
class="config-radio-button config-radio-button-checked" class="config-radio-button config-radio-button-checked"
@ -9733,6 +9750,7 @@ exports[`ConfigProvider components Radio normal 1`] = `
> >
<label <label
class="ant-radio-wrapper ant-radio-wrapper-checked" class="ant-radio-wrapper ant-radio-wrapper-checked"
for="ant-radio-wrapper ant-radio-wrapper-checked"
> >
<span <span
class="ant-radio ant-radio-checked" class="ant-radio ant-radio-checked"
@ -9756,6 +9774,7 @@ exports[`ConfigProvider components Radio normal 1`] = `
> >
<label <label
class="ant-radio-button-wrapper ant-radio-button-wrapper-checked" class="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
for="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
> >
<span <span
class="ant-radio-button ant-radio-button-checked" class="ant-radio-button ant-radio-button-checked"
@ -9784,6 +9803,7 @@ exports[`ConfigProvider components Radio prefixCls 1`] = `
> >
<label <label
class="prefix-Radio-wrapper prefix-Radio-wrapper-checked" class="prefix-Radio-wrapper prefix-Radio-wrapper-checked"
for="prefix-Radio-wrapper prefix-Radio-wrapper-checked"
> >
<span <span
class="prefix-Radio prefix-Radio-checked" class="prefix-Radio prefix-Radio-checked"
@ -9807,6 +9827,7 @@ exports[`ConfigProvider components Radio prefixCls 1`] = `
> >
<label <label
class="prefix-Radio-wrapper prefix-Radio-wrapper-checked" class="prefix-Radio-wrapper prefix-Radio-wrapper-checked"
for="prefix-Radio-wrapper prefix-Radio-wrapper-checked"
> >
<span <span
class="prefix-Radio prefix-Radio-checked" class="prefix-Radio prefix-Radio-checked"
@ -11630,6 +11651,7 @@ exports[`ConfigProvider components Table configProvider 1`] = `
> >
<label <label
class="config-checkbox-wrapper" class="config-checkbox-wrapper"
for="checkbox-label"
> >
<span <span
class="config-checkbox" class="config-checkbox"
@ -11876,6 +11898,7 @@ exports[`ConfigProvider components Table normal 1`] = `
> >
<label <label
class="ant-checkbox-wrapper" class="ant-checkbox-wrapper"
for="checkbox-label"
> >
<span <span
class="ant-checkbox" class="ant-checkbox"
@ -12122,6 +12145,7 @@ exports[`ConfigProvider components Table prefixCls 1`] = `
> >
<label <label
class="ant-checkbox-wrapper" class="ant-checkbox-wrapper"
for="checkbox-label"
> >
<span <span
class="ant-checkbox" class="ant-checkbox"
@ -12658,6 +12682,7 @@ exports[`ConfigProvider components Tags prefixCls 1`] = `
<div> <div>
<span <span
class="prefix-Tags" class="prefix-Tags"
prefixcls="prefix-Tags"
> >
Bamboo Bamboo
</span> </span>
@ -16107,6 +16132,7 @@ exports[`ConfigProvider components Transfer configProvider 1`] = `
> >
<label <label
class="config-checkbox-wrapper" class="config-checkbox-wrapper"
for="checkbox-label"
> >
<span <span
class="config-checkbox" class="config-checkbox"
@ -16247,6 +16273,7 @@ exports[`ConfigProvider components Transfer configProvider 1`] = `
> >
<label <label
class="config-checkbox-wrapper" class="config-checkbox-wrapper"
for="checkbox-label"
> >
<span <span
class="config-checkbox" class="config-checkbox"
@ -16340,6 +16367,7 @@ exports[`ConfigProvider components Transfer normal 1`] = `
> >
<label <label
class="ant-checkbox-wrapper" class="ant-checkbox-wrapper"
for="checkbox-label"
> >
<span <span
class="ant-checkbox" class="ant-checkbox"
@ -16480,6 +16508,7 @@ exports[`ConfigProvider components Transfer normal 1`] = `
> >
<label <label
class="ant-checkbox-wrapper" class="ant-checkbox-wrapper"
for="checkbox-label"
> >
<span <span
class="ant-checkbox" class="ant-checkbox"
@ -16573,6 +16602,7 @@ exports[`ConfigProvider components Transfer prefixCls 1`] = `
> >
<label <label
class="ant-checkbox-wrapper" class="ant-checkbox-wrapper"
for="checkbox-label"
> >
<span <span
class="ant-checkbox" class="ant-checkbox"
@ -16713,6 +16743,7 @@ exports[`ConfigProvider components Transfer prefixCls 1`] = `
> >
<label <label
class="ant-checkbox-wrapper" class="ant-checkbox-wrapper"
for="checkbox-label"
> >
<span <span
class="ant-checkbox" class="ant-checkbox"

View File

@ -1,3 +1,6 @@
// TODO: remove this lint
// SFC has specified a displayName, but not worked.
/* eslint-disable react/display-name */
import * as React from 'react'; import * as React from 'react';
import createReactContext from '@ant-design/create-react-context'; import createReactContext from '@ant-design/create-react-context';

View File

@ -1,6 +1,6 @@
import * as React from 'react'; import * as React from 'react';
import Icon from '../icon';
import classNames from 'classnames'; import classNames from 'classnames';
import Icon from '../icon';
export default function InputIcon(props: { suffixIcon: React.ReactNode; prefixCls: string }) { export default function InputIcon(props: { suffixIcon: React.ReactNode; prefixCls: string }) {
const { suffixIcon, prefixCls } = props; const { suffixIcon, prefixCls } = props;

View File

@ -30,10 +30,9 @@ function getShowDateFromValue(value: RangePickerValue, mode?: string | string[])
} }
if (mode && mode[0] === 'month') { if (mode && mode[0] === 'month') {
return [start, end] as RangePickerValue; return [start, end] as RangePickerValue;
} else { }
const newEnd = end && end.isSame(start, 'month') ? end.clone().add(1, 'month') : end; const newEnd = end && end.isSame(start, 'month') ? end.clone().add(1, 'month') : end;
return [start, newEnd] as RangePickerValue; return [start, newEnd] as RangePickerValue;
}
} }
function pickerValueAdapter( function pickerValueAdapter(
@ -102,7 +101,9 @@ class RangePicker extends React.Component<any, RangePickerState> {
} }
private picker: HTMLSpanElement; private picker: HTMLSpanElement;
private prefixCls?: string; private prefixCls?: string;
private tagPrefixCls?: string; private tagPrefixCls?: string;
constructor(props: any) { constructor(props: any) {
@ -133,6 +134,17 @@ class RangePicker extends React.Component<any, RangePickerState> {
} }
} }
setValue(value: RangePickerValue, hidePanel?: boolean) {
this.handleChange(value);
if ((hidePanel || !this.props.showTime) && !('open' in this.props)) {
this.setState({ open: false });
}
}
savePicker = (node: HTMLSpanElement) => {
this.picker = node;
};
clearSelection = (e: React.MouseEvent<HTMLElement>) => { clearSelection = (e: React.MouseEvent<HTMLElement>) => {
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
@ -143,7 +155,7 @@ class RangePicker extends React.Component<any, RangePickerState> {
clearHoverValue = () => this.setState({ hoverValue: [] }); clearHoverValue = () => this.setState({ hoverValue: [] });
handleChange = (value: RangePickerValue) => { handleChange = (value: RangePickerValue) => {
const props = this.props; const { props } = this;
if (!('value' in props)) { if (!('value' in props)) {
this.setState(({ showDate }) => ({ this.setState(({ showDate }) => ({
value, value,
@ -210,13 +222,6 @@ class RangePicker extends React.Component<any, RangePickerState> {
} }
}; };
setValue(value: RangePickerValue, hidePanel?: boolean) {
this.handleChange(value);
if ((hidePanel || !this.props.showTime) && !('open' in this.props)) {
this.setState({ open: false });
}
}
focus() { focus() {
this.picker.focus(); this.picker.focus();
} }
@ -225,10 +230,6 @@ class RangePicker extends React.Component<any, RangePickerState> {
this.picker.blur(); this.picker.blur();
} }
savePicker = (node: HTMLSpanElement) => {
this.picker = node;
};
renderFooter = () => { renderFooter = () => {
const { ranges, renderExtraFooter } = this.props; const { ranges, renderExtraFooter } = this.props;
const { prefixCls, tagPrefixCls } = this; const { prefixCls, tagPrefixCls } = this;

View File

@ -39,6 +39,7 @@ class WeekPicker extends React.Component<any, WeekPickerState> {
} }
private input: any; private input: any;
private prefixCls?: string; private prefixCls?: string;
constructor(props: any) { constructor(props: any) {
@ -62,6 +63,10 @@ class WeekPicker extends React.Component<any, WeekPickerState> {
} }
} }
saveInput = (node: any) => {
this.input = node;
};
weekDateRender = (current: any) => { weekDateRender = (current: any) => {
const selectedValue = this.state.value; const selectedValue = this.state.value;
const { prefixCls } = this; const { prefixCls } = this;
@ -105,13 +110,6 @@ class WeekPicker extends React.Component<any, WeekPickerState> {
this.handleChange(null); this.handleChange(null);
}; };
renderFooter = (...args: any[]) => {
const { prefixCls, renderExtraFooter } = this.props;
return renderExtraFooter ? (
<div className={`${prefixCls}-footer-extra`}>{renderExtraFooter(...args)}</div>
) : null;
};
focus() { focus() {
this.input.focus(); this.input.focus();
} }
@ -120,8 +118,11 @@ class WeekPicker extends React.Component<any, WeekPickerState> {
this.input.blur(); this.input.blur();
} }
saveInput = (node: any) => { renderFooter = (...args: any[]) => {
this.input = node; const { prefixCls, renderExtraFooter } = this.props;
return renderExtraFooter ? (
<div className={`${prefixCls}-footer-extra`}>{renderExtraFooter(...args)}</div>
) : null;
}; };
renderWeekPicker = ({ getPrefixCls }: ConfigConsumerProps) => { renderWeekPicker = ({ getPrefixCls }: ConfigConsumerProps) => {

View File

@ -3045,6 +3045,7 @@ exports[`RangePicker switch to corresponding month panel when click presetted ra
> >
<span <span
class="ant-tag ant-tag-blue" class="ant-tag ant-tag-blue"
prefixcls="ant-tag"
> >
My Birthday My Birthday
</span> </span>

View File

@ -1086,6 +1086,7 @@ exports[`renders ./components/date-picker/demo/size.md correctly 1`] = `
> >
<label <label
class="ant-radio-button-wrapper" class="ant-radio-button-wrapper"
for="ant-radio-button-wrapper"
> >
<span <span
class="ant-radio-button" class="ant-radio-button"
@ -1105,6 +1106,7 @@ exports[`renders ./components/date-picker/demo/size.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-button-wrapper ant-radio-button-wrapper-checked" class="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
for="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
> >
<span <span
class="ant-radio-button ant-radio-button-checked" class="ant-radio-button ant-radio-button-checked"
@ -1125,6 +1127,7 @@ exports[`renders ./components/date-picker/demo/size.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-button-wrapper" class="ant-radio-button-wrapper"
for="ant-radio-button-wrapper"
> >
<span <span
class="ant-radio-button" class="ant-radio-button"

View File

@ -78,12 +78,8 @@ export default function createPicker(TheCalendar: React.ComponentClass): any {
} }
} }
renderFooter = (...args: any[]) => { saveInput = (node: any) => {
const { renderExtraFooter } = this.props; this.input = node;
const { prefixCls } = this;
return renderExtraFooter ? (
<div className={`${prefixCls}-footer-extra`}>{renderExtraFooter(...args)}</div>
) : null;
}; };
clearSelection = (e: React.MouseEvent<HTMLElement>) => { clearSelection = (e: React.MouseEvent<HTMLElement>) => {
@ -126,8 +122,12 @@ export default function createPicker(TheCalendar: React.ComponentClass): any {
this.input.blur(); this.input.blur();
} }
saveInput = (node: any) => { renderFooter = (...args: any[]) => {
this.input = node; const { renderExtraFooter } = this.props;
const { prefixCls } = this;
return renderExtraFooter ? (
<div className={`${prefixCls}-footer-extra`}>{renderExtraFooter(...args)}</div>
) : null;
}; };
renderPicker = ({ getPrefixCls }: ConfigConsumerProps) => { renderPicker = ({ getPrefixCls }: ConfigConsumerProps) => {
@ -272,5 +272,6 @@ export default function createPicker(TheCalendar: React.ComponentClass): any {
} }
} }
polyfill(CalenderWrapper); polyfill(CalenderWrapper);
return CalenderWrapper; return CalenderWrapper;
} }

View File

@ -89,6 +89,22 @@ export default function wrapPicker(Picker: React.ComponentClass<any>, pickerType
} }
} }
savePicker = (node: any) => {
this.picker = node;
};
getDefaultLocale = () => {
const result = {
...enUS,
...this.props.locale,
};
result.lang = {
...result.lang,
...(this.props.locale || {}).lang,
};
return result;
};
handleOpenChange = (open: boolean) => { handleOpenChange = (open: boolean) => {
const { onOpenChange } = this.props; const { onOpenChange } = this.props;
onOpenChange(open); onOpenChange(open);
@ -130,22 +146,6 @@ export default function wrapPicker(Picker: React.ComponentClass<any>, pickerType
this.picker.blur(); this.picker.blur();
} }
savePicker = (node: any) => {
this.picker = node;
};
getDefaultLocale = () => {
const result = {
...enUS,
...this.props.locale,
};
result.lang = {
...result.lang,
...(this.props.locale || {}).lang,
};
return result;
};
renderPicker = (locale: any, localeCode: string) => { renderPicker = (locale: any, localeCode: string) => {
const { format, showTime } = this.props; const { format, showTime } = this.props;
const mergedPickerType = showTime ? `${pickerType}Time` : pickerType; const mergedPickerType = showTime ? `${pickerType}Time` : pickerType;

View File

@ -403,6 +403,7 @@ exports[`renders ./components/descriptions/demo/size.md correctly 1`] = `
> >
<label <label
class="ant-radio-wrapper ant-radio-wrapper-checked" class="ant-radio-wrapper ant-radio-wrapper-checked"
for="ant-radio-wrapper ant-radio-wrapper-checked"
> >
<span <span
class="ant-radio ant-radio-checked" class="ant-radio ant-radio-checked"
@ -423,6 +424,7 @@ exports[`renders ./components/descriptions/demo/size.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-wrapper" class="ant-radio-wrapper"
for="ant-radio-wrapper"
> >
<span <span
class="ant-radio" class="ant-radio"
@ -442,6 +444,7 @@ exports[`renders ./components/descriptions/demo/size.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-wrapper" class="ant-radio-wrapper"
for="ant-radio-wrapper"
> >
<span <span
class="ant-radio" class="ant-radio"

View File

@ -156,13 +156,17 @@ class Descriptions extends React.Component<
size: 'default', size: 'default',
column: defaultColumnMap, column: defaultColumnMap,
}; };
static Item: typeof DescriptionsItem = DescriptionsItem; static Item: typeof DescriptionsItem = DescriptionsItem;
state: { state: {
screens: BreakpointMap; screens: BreakpointMap;
} = { } = {
screens: {}, screens: {},
}; };
token: string; token: string;
componentDidMount() { componentDidMount() {
const { column } = this.props; const { column } = this.props;
this.token = ResponsiveObserve.subscribe(screens => { this.token = ResponsiveObserve.subscribe(screens => {
@ -189,7 +193,7 @@ class Descriptions extends React.Component<
} }
} }
} }
//If the configuration is not an object, it is a number, return number // If the configuration is not an object, it is a number, return number
if (typeof column === 'number') { if (typeof column === 'number') {
return column as number; return column as number;
} }

View File

@ -25,7 +25,7 @@ const Divider: React.SFC<DividerProps> = props => (
...restProps ...restProps
} = props; } = props;
const prefixCls = getPrefixCls('divider', customizePrefixCls); const prefixCls = getPrefixCls('divider', customizePrefixCls);
const orientationPrefix = orientation.length > 0 ? '-' + orientation : orientation; const orientationPrefix = orientation.length > 0 ? `-${orientation}` : orientation;
const classString = classNames(className, prefixCls, `${prefixCls}-${type}`, { const classString = classNames(className, prefixCls, `${prefixCls}-${type}`, {
[`${prefixCls}-with-text${orientationPrefix}`]: children, [`${prefixCls}-with-text${orientationPrefix}`]: children,
[`${prefixCls}-dashed`]: !!dashed, [`${prefixCls}-dashed`]: !!dashed,

View File

@ -69,6 +69,7 @@ exports[`renders ./components/drawer/demo/placement.md correctly 1`] = `
> >
<label <label
class="ant-radio-wrapper" class="ant-radio-wrapper"
for="ant-radio-wrapper"
> >
<span <span
class="ant-radio" class="ant-radio"
@ -88,6 +89,7 @@ exports[`renders ./components/drawer/demo/placement.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-wrapper" class="ant-radio-wrapper"
for="ant-radio-wrapper"
> >
<span <span
class="ant-radio" class="ant-radio"
@ -107,6 +109,7 @@ exports[`renders ./components/drawer/demo/placement.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-wrapper" class="ant-radio-wrapper"
for="ant-radio-wrapper"
> >
<span <span
class="ant-radio" class="ant-radio"
@ -126,6 +129,7 @@ exports[`renders ./components/drawer/demo/placement.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-wrapper ant-radio-wrapper-checked" class="ant-radio-wrapper ant-radio-wrapper-checked"
for="ant-radio-wrapper ant-radio-wrapper-checked"
> >
<span <span
class="ant-radio ant-radio-checked" class="ant-radio ant-radio-checked"

View File

@ -1,8 +1,9 @@
import * as React from 'react'; import * as React from 'react';
import RcDrawer from 'rc-drawer'; import RcDrawer from 'rc-drawer';
import createReactContext from '@ant-design/create-react-context'; import createReactContext from '@ant-design/create-react-context';
import warning from '../_util/warning';
import classNames from 'classnames'; import classNames from 'classnames';
import omit from 'omit.js';
import warning from '../_util/warning';
import Icon from '../icon'; import Icon from '../icon';
import { withConfigConsumer, ConfigConsumerProps } from '../config-provider'; import { withConfigConsumer, ConfigConsumerProps } from '../config-provider';
import { tuple } from '../_util/type'; import { tuple } from '../_util/type';
@ -159,6 +160,7 @@ class Drawer extends React.Component<DrawerProps & ConfigConsumerProps, IDrawerS
const { closable, prefixCls, onClose } = this.props; const { closable, prefixCls, onClose } = this.props;
return ( return (
closable && ( closable && (
/* eslint-disable react/button-has-type */
<button onClick={onClose} aria-label="Close" className={`${prefixCls}-close`}> <button onClick={onClose} aria-label="Close" className={`${prefixCls}-close`}>
<Icon type="close" /> <Icon type="close" />
</button> </button>
@ -208,27 +210,12 @@ class Drawer extends React.Component<DrawerProps & ConfigConsumerProps, IDrawerS
renderProvider = (value: Drawer) => { renderProvider = (value: Drawer) => {
const { const {
prefixCls, prefixCls,
zIndex,
style,
placement, placement,
className, className,
wrapClassName, wrapClassName,
width, width,
height, height,
closable,
destroyOnClose,
mask, mask,
bodyStyle,
title,
push,
visible,
// ConfigConsumerProps
getPopupContainer,
rootPrefixCls,
getPrefixCls,
renderEmpty,
csp,
autoInsertSpaceInButton,
...rest ...rest
} = this.props; } = this.props;
warning( warning(
@ -248,7 +235,22 @@ class Drawer extends React.Component<DrawerProps & ConfigConsumerProps, IDrawerS
<DrawerContext.Provider value={this}> <DrawerContext.Provider value={this}>
<RcDrawer <RcDrawer
handler={false} handler={false}
{...rest} {...omit(rest, [
'zIndex',
'style',
'closable',
'destroyOnClose',
'bodyStyle',
'title',
'push',
'visible',
'getPopupContainer',
'rootPrefixCls',
'getPrefixCls',
'renderEmpty',
'csp',
'autoInsertSpaceInButton',
])}
{...offsetStyle} {...offsetStyle}
prefixCls={prefixCls} prefixCls={prefixCls}
open={this.props.visible} open={this.props.visible}

View File

@ -54,6 +54,7 @@ export interface DropDownProps {
export default class Dropdown extends React.Component<DropDownProps, any> { export default class Dropdown extends React.Component<DropDownProps, any> {
static Button: typeof DropdownButton; static Button: typeof DropdownButton;
static defaultProps = { static defaultProps = {
mouseEnterDelay: 0.15, mouseEnterDelay: 0.15,
mouseLeaveDelay: 0.1, mouseLeaveDelay: 0.1,
@ -90,7 +91,7 @@ export default class Dropdown extends React.Component<DropDownProps, any> {
warning( warning(
!overlayProps.mode || overlayProps.mode === 'vertical', !overlayProps.mode || overlayProps.mode === 'vertical',
'Dropdown', 'Dropdown',
`mode="${overlayProps.mode}" is not supported for Dropdown\'s Menu.`, `mode="${overlayProps.mode}" is not supported for Dropdown's Menu.`,
); );
// menu cannot be selectable in dropdown defaultly // menu cannot be selectable in dropdown defaultly

View File

@ -241,6 +241,7 @@ exports[`renders ./components/empty/demo/config-provider.md correctly 1`] = `
> >
<label <label
class="ant-checkbox-wrapper" class="ant-checkbox-wrapper"
for="checkbox-label"
> >
<span <span
class="ant-checkbox" class="ant-checkbox"
@ -381,6 +382,7 @@ exports[`renders ./components/empty/demo/config-provider.md correctly 1`] = `
> >
<label <label
class="ant-checkbox-wrapper" class="ant-checkbox-wrapper"
for="checkbox-label"
> >
<span <span
class="ant-checkbox" class="ant-checkbox"
@ -475,6 +477,7 @@ exports[`renders ./components/empty/demo/config-provider.md correctly 1`] = `
> >
<div <div
class="ant-table ant-table-default ant-table-empty ant-table-scroll-position-left" class="ant-table ant-table-default ant-table-empty ant-table-scroll-position-left"
style="margin-top:8px"
> >
<div <div
class="ant-table-content" class="ant-table-content"

View File

@ -1,6 +1,6 @@
import * as React from 'react'; import * as React from 'react';
export default () => ( const Empty = () => (
<svg width="184" height="152" viewBox="0 0 184 152" xmlns="http://www.w3.org/2000/svg"> <svg width="184" height="152" viewBox="0 0 184 152" xmlns="http://www.w3.org/2000/svg">
<g fill="none" fillRule="evenodd"> <g fill="none" fillRule="evenodd">
<g transform="translate(24 31.67)"> <g transform="translate(24 31.67)">
@ -34,3 +34,5 @@ export default () => (
</g> </g>
</svg> </svg>
); );
export default Empty;

View File

@ -1,6 +1,6 @@
import * as React from 'react'; import * as React from 'react';
export default () => ( const Simple = () => (
<svg width="64" height="41" viewBox="0 0 64 41" xmlns="http://www.w3.org/2000/svg"> <svg width="64" height="41" viewBox="0 0 64 41" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(0 1)" fill="none" fillRule="evenodd"> <g transform="translate(0 1)" fill="none" fillRule="evenodd">
<ellipse fill="#F5F5F5" cx="32" cy="33" rx="32" ry="7" /> <ellipse fill="#F5F5F5" cx="32" cy="33" rx="32" ry="7" />
@ -14,3 +14,5 @@ export default () => (
</g> </g>
</svg> </svg>
); );
export default Simple;

View File

@ -91,7 +91,7 @@ export default class FormItem extends React.Component<FormItemProps, any> {
} else if (React.isValidElement(e.message)) { } else if (React.isValidElement(e.message)) {
node = e.message; node = e.message;
} }
/* eslint-disable react/no-array-index-key */
return node ? React.cloneElement(node, { key: index }) : e.message; return node ? React.cloneElement(node, { key: index }) : e.message;
}), }),
); );
@ -151,6 +151,40 @@ export default class FormItem extends React.Component<FormItemProps, any> {
return this.getChildProp(FIELD_DATA_PROP); return this.getChildProp(FIELD_DATA_PROP);
} }
getValidateStatus() {
const onlyControl = this.getOnlyControl();
if (!onlyControl) {
return '';
}
const field = this.getField();
if (field.validating) {
return 'validating';
}
if (field.errors) {
return 'error';
}
const fieldValue = 'value' in field ? field.value : this.getMeta().initialValue;
if (fieldValue !== undefined && fieldValue !== null && fieldValue !== '') {
return 'success';
}
return '';
}
// Resolve duplicated ids bug between different forms
// https://github.com/ant-design/ant-design/issues/7351
onLabelClick = () => {
const id = this.props.id || this.getId();
if (!id) {
return;
}
const formItemNode = ReactDOM.findDOMNode(this) as Element;
const control = formItemNode.querySelector(`[id="${id}"]`) as HTMLElement;
if (control && control.focus) {
control.focus();
}
};
onHelpAnimEnd = (_key: string, helpShow: boolean) => { onHelpAnimEnd = (_key: string, helpShow: boolean) => {
this.helpShow = helpShow; this.helpShow = helpShow;
if (!helpShow) { if (!helpShow) {
@ -158,6 +192,24 @@ export default class FormItem extends React.Component<FormItemProps, any> {
} }
}; };
isRequired() {
const { required } = this.props;
if (required !== undefined) {
return required;
}
if (this.getOnlyControl()) {
const meta = this.getMeta() || {};
const validate = meta.validate || [];
return validate
.filter((item: any) => !!item.rules)
.some((item: any) => {
return item.rules.some((rule: any) => rule.required);
});
}
return false;
}
renderHelp(prefixCls: string) { renderHelp(prefixCls: string) {
const help = this.getHelpMessage(); const help = this.getHelpMessage();
const children = help ? ( const children = help ? (
@ -186,25 +238,6 @@ export default class FormItem extends React.Component<FormItemProps, any> {
return extra ? <div className={`${prefixCls}-extra`}>{extra}</div> : null; return extra ? <div className={`${prefixCls}-extra`}>{extra}</div> : null;
} }
getValidateStatus() {
const onlyControl = this.getOnlyControl();
if (!onlyControl) {
return '';
}
const field = this.getField();
if (field.validating) {
return 'validating';
}
if (field.errors) {
return 'error';
}
const fieldValue = 'value' in field ? field.value : this.getMeta().initialValue;
if (fieldValue !== undefined && fieldValue !== null && fieldValue !== '') {
return 'success';
}
return '';
}
renderValidateWrapper( renderValidateWrapper(
prefixCls: string, prefixCls: string,
c1: React.ReactNode, c1: React.ReactNode,
@ -293,39 +326,6 @@ export default class FormItem extends React.Component<FormItemProps, any> {
); );
} }
isRequired() {
const { required } = this.props;
if (required !== undefined) {
return required;
}
if (this.getOnlyControl()) {
const meta = this.getMeta() || {};
const validate = meta.validate || [];
return validate
.filter((item: any) => !!item.rules)
.some((item: any) => {
return item.rules.some((rule: any) => rule.required);
});
}
return false;
}
// Resolve duplicated ids bug between different forms
// https://github.com/ant-design/ant-design/issues/7351
onLabelClick = () => {
const id = this.props.id || this.getId();
if (!id) {
return;
}
const formItemNode = ReactDOM.findDOMNode(this) as Element;
const control = formItemNode.querySelector(`[id="${id}"]`) as HTMLElement;
if (control && control.focus) {
control.focus();
}
};
renderLabel(prefixCls: string) { renderLabel(prefixCls: string) {
return ( return (
<FormContext.Consumer key="label"> <FormContext.Consumer key="label">

View File

@ -910,6 +910,7 @@ exports[`renders ./components/form/demo/dynamic-rule.md correctly 1`] = `
> >
<label <label
class="ant-checkbox-wrapper" class="ant-checkbox-wrapper"
for="checkbox-label"
> >
<span <span
class="ant-checkbox" class="ant-checkbox"
@ -1192,6 +1193,7 @@ exports[`renders ./components/form/demo/layout.md correctly 1`] = `
> >
<label <label
class="ant-radio-button-wrapper ant-radio-button-wrapper-checked" class="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
for="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
> >
<span <span
class="ant-radio-button ant-radio-button-checked" class="ant-radio-button ant-radio-button-checked"
@ -1212,6 +1214,7 @@ exports[`renders ./components/form/demo/layout.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-button-wrapper" class="ant-radio-button-wrapper"
for="ant-radio-button-wrapper"
> >
<span <span
class="ant-radio-button" class="ant-radio-button"
@ -1231,6 +1234,7 @@ exports[`renders ./components/form/demo/layout.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-button-wrapper" class="ant-radio-button-wrapper"
for="ant-radio-button-wrapper"
> >
<span <span
class="ant-radio-button" class="ant-radio-button"
@ -1469,6 +1473,7 @@ exports[`renders ./components/form/demo/normal-login.md correctly 1`] = `
> >
<label <label
class="ant-checkbox-wrapper ant-checkbox-wrapper-checked" class="ant-checkbox-wrapper ant-checkbox-wrapper-checked"
for="checkbox-label"
> >
<span <span
class="ant-checkbox ant-checkbox-checked" class="ant-checkbox ant-checkbox-checked"
@ -2115,6 +2120,7 @@ exports[`renders ./components/form/demo/register.md correctly 1`] = `
> >
<label <label
class="ant-checkbox-wrapper" class="ant-checkbox-wrapper"
for="checkbox-label"
> >
<span <span
class="ant-checkbox" class="ant-checkbox"
@ -2496,6 +2502,7 @@ exports[`renders ./components/form/demo/style-check-debug.md correctly 1`] = `
> >
<label <label
class="ant-radio-wrapper" class="ant-radio-wrapper"
for="ant-radio-wrapper"
> >
<span <span
class="ant-radio" class="ant-radio"
@ -2515,6 +2522,7 @@ exports[`renders ./components/form/demo/style-check-debug.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-wrapper" class="ant-radio-wrapper"
for="ant-radio-wrapper"
> >
<span <span
class="ant-radio" class="ant-radio"
@ -3457,6 +3465,7 @@ exports[`renders ./components/form/demo/validate-other.md correctly 1`] = `
> >
<label <label
class="ant-radio-wrapper" class="ant-radio-wrapper"
for="ant-radio-wrapper"
> >
<span <span
class="ant-radio" class="ant-radio"
@ -3476,6 +3485,7 @@ exports[`renders ./components/form/demo/validate-other.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-wrapper" class="ant-radio-wrapper"
for="ant-radio-wrapper"
> >
<span <span
class="ant-radio" class="ant-radio"
@ -3495,6 +3505,7 @@ exports[`renders ./components/form/demo/validate-other.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-wrapper" class="ant-radio-wrapper"
for="ant-radio-wrapper"
> >
<span <span
class="ant-radio" class="ant-radio"
@ -3546,6 +3557,7 @@ exports[`renders ./components/form/demo/validate-other.md correctly 1`] = `
> >
<label <label
class="ant-radio-button-wrapper" class="ant-radio-button-wrapper"
for="ant-radio-button-wrapper"
> >
<span <span
class="ant-radio-button" class="ant-radio-button"
@ -3565,6 +3577,7 @@ exports[`renders ./components/form/demo/validate-other.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-button-wrapper" class="ant-radio-button-wrapper"
for="ant-radio-button-wrapper"
> >
<span <span
class="ant-radio-button" class="ant-radio-button"
@ -3584,6 +3597,7 @@ exports[`renders ./components/form/demo/validate-other.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-button-wrapper" class="ant-radio-button-wrapper"
for="ant-radio-button-wrapper"
> >
<span <span
class="ant-radio-button" class="ant-radio-button"
@ -3644,6 +3658,7 @@ exports[`renders ./components/form/demo/validate-other.md correctly 1`] = `
> >
<label <label
class="ant-checkbox-wrapper ant-checkbox-wrapper-checked" class="ant-checkbox-wrapper ant-checkbox-wrapper-checked"
for="checkbox-label"
> >
<span <span
class="ant-checkbox ant-checkbox-checked" class="ant-checkbox ant-checkbox-checked"
@ -3668,6 +3683,7 @@ exports[`renders ./components/form/demo/validate-other.md correctly 1`] = `
> >
<label <label
class="ant-checkbox-wrapper ant-checkbox-wrapper-checked ant-checkbox-wrapper-disabled" class="ant-checkbox-wrapper ant-checkbox-wrapper-checked ant-checkbox-wrapper-disabled"
for="checkbox-label"
> >
<span <span
class="ant-checkbox ant-checkbox-checked ant-checkbox-disabled" class="ant-checkbox ant-checkbox-checked ant-checkbox-disabled"
@ -3693,6 +3709,7 @@ exports[`renders ./components/form/demo/validate-other.md correctly 1`] = `
> >
<label <label
class="ant-checkbox-wrapper" class="ant-checkbox-wrapper"
for="checkbox-label"
> >
<span <span
class="ant-checkbox" class="ant-checkbox"
@ -3716,6 +3733,7 @@ exports[`renders ./components/form/demo/validate-other.md correctly 1`] = `
> >
<label <label
class="ant-checkbox-wrapper" class="ant-checkbox-wrapper"
for="checkbox-label"
> >
<span <span
class="ant-checkbox" class="ant-checkbox"
@ -3739,6 +3757,7 @@ exports[`renders ./components/form/demo/validate-other.md correctly 1`] = `
> >
<label <label
class="ant-checkbox-wrapper" class="ant-checkbox-wrapper"
for="checkbox-label"
> >
<span <span
class="ant-checkbox" class="ant-checkbox"

View File

@ -53,7 +53,7 @@ class PriceInput extends React.Component {
handleNumberChange = e => { handleNumberChange = e => {
const number = parseInt(e.target.value || 0, 10); const number = parseInt(e.target.value || 0, 10);
if (Number.isNaN(number)) { if (isNaN(number)) {
return; return;
} }
if (!('value' in this.props)) { if (!('value' in this.props)) {

View File

@ -50,7 +50,7 @@ export default class Col extends React.Component<ColProps, {}> {
}; };
renderCol = ({ getPrefixCls }: ConfigConsumerProps) => { renderCol = ({ getPrefixCls }: ConfigConsumerProps) => {
const props: any = this.props; const { props } = this;
const { const {
prefixCls: customizePrefixCls, prefixCls: customizePrefixCls,
span, span,
@ -66,13 +66,14 @@ export default class Col extends React.Component<ColProps, {}> {
let sizeClassObj = {}; let sizeClassObj = {};
['xs', 'sm', 'md', 'lg', 'xl', 'xxl'].forEach(size => { ['xs', 'sm', 'md', 'lg', 'xl', 'xxl'].forEach(size => {
let sizeProps: ColSize = {}; let sizeProps: ColSize = {};
if (typeof props[size] === 'number') { const propSize = (props as any)[size];
sizeProps.span = props[size]; if (typeof propSize === 'number') {
} else if (typeof props[size] === 'object') { sizeProps.span = propSize;
sizeProps = props[size] || {}; } else if (typeof propSize === 'object') {
sizeProps = propSize || {};
} }
delete others[size]; delete (others as any)[size];
sizeClassObj = { sizeClassObj = {
...sizeClassObj, ...sizeClassObj,
@ -100,7 +101,7 @@ export default class Col extends React.Component<ColProps, {}> {
return ( return (
<RowContext.Consumer> <RowContext.Consumer>
{({ gutter }) => { {({ gutter }) => {
let style = others.style; let { style } = others;
if (gutter! > 0) { if (gutter! > 0) {
style = { style = {
paddingLeft: gutter! / 2, paddingLeft: gutter! / 2,

View File

@ -1,7 +1,7 @@
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
import * as React from 'react'; import * as React from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import * as PropTypes from 'prop-types'; import * as PropTypes from 'prop-types';
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
import RowContext from './RowContext'; import RowContext from './RowContext';
import { tuple } from '../_util/type'; import { tuple } from '../_util/type';
import ResponsiveObserve, { import ResponsiveObserve, {
@ -42,7 +42,9 @@ export default class Row extends React.Component<RowProps, RowState> {
state: RowState = { state: RowState = {
screens: {}, screens: {},
}; };
token: string; token: string;
componentDidMount() { componentDidMount() {
this.token = ResponsiveObserve.subscribe(screens => { this.token = ResponsiveObserve.subscribe(screens => {
if (typeof this.props.gutter === 'object') { if (typeof this.props.gutter === 'object') {
@ -50,9 +52,11 @@ export default class Row extends React.Component<RowProps, RowState> {
} }
}); });
} }
componentWillUnmount() { componentWillUnmount() {
ResponsiveObserve.unsubscribe(this.token); ResponsiveObserve.unsubscribe(this.token);
} }
getGutter(): number | undefined { getGutter(): number | undefined {
const { gutter } = this.props; const { gutter } = this.props;
if (typeof gutter === 'object') { if (typeof gutter === 'object') {
@ -65,6 +69,7 @@ export default class Row extends React.Component<RowProps, RowState> {
} }
return gutter as number; return gutter as number;
} }
renderRow = ({ getPrefixCls }: ConfigConsumerProps) => { renderRow = ({ getPrefixCls }: ConfigConsumerProps) => {
const { const {
prefixCls: customizePrefixCls, prefixCls: customizePrefixCls,

View File

@ -1,5 +1,5 @@
import Icon, { IconProps } from './index';
import * as React from 'react'; import * as React from 'react';
import Icon, { IconProps } from './index';
const customCache = new Set<string>(); const customCache = new Set<string>();

View File

@ -1,3 +1,4 @@
/* eslint-disable camelcase */
import * as React from 'react'; import * as React from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import * as allIcons from '@ant-design/icons/lib/dist'; import * as allIcons from '@ant-design/icons/lib/dist';
@ -18,7 +19,27 @@ import { getTwoToneColor, setTwoToneColor } from './twoTonePrimaryColor';
ReactIcon.add(...Object.keys(allIcons).map(key => (allIcons as any)[key])); ReactIcon.add(...Object.keys(allIcons).map(key => (allIcons as any)[key]));
setTwoToneColor('#1890ff'); setTwoToneColor('#1890ff');
let defaultTheme: ThemeType = 'outlined'; let defaultTheme: ThemeType = 'outlined';
let dangerousTheme: ThemeType | undefined = undefined; let dangerousTheme: ThemeType | undefined;
function unstable_ChangeThemeOfIconsDangerously(theme?: ThemeType) {
warning(
false,
'Icon',
`You are using the unstable method 'Icon.unstable_ChangeThemeOfAllIconsDangerously', ` +
`make sure that all the icons with theme '${theme}' display correctly.`,
);
dangerousTheme = theme;
}
function unstable_ChangeDefaultThemeOfIcons(theme: ThemeType) {
warning(
false,
'Icon',
`You are using the unstable method 'Icon.unstable_ChangeDefaultThemeOfIcons', ` +
`make sure that all the icons with theme '${theme}' display correctly.`,
);
defaultTheme = theme;
}
export interface TransferLocale { export interface TransferLocale {
icon: string; icon: string;
@ -196,26 +217,6 @@ const Icon: IconComponent<IconProps> = props => {
); );
}; };
function unstable_ChangeThemeOfIconsDangerously(theme?: ThemeType) {
warning(
false,
'Icon',
`You are using the unstable method 'Icon.unstable_ChangeThemeOfAllIconsDangerously', ` +
`make sure that all the icons with theme '${theme}' display correctly.`,
);
dangerousTheme = theme;
}
function unstable_ChangeDefaultThemeOfIcons(theme: ThemeType) {
warning(
false,
'Icon',
`You are using the unstable method 'Icon.unstable_ChangeDefaultThemeOfIcons', ` +
`make sure that all the icons with theme '${theme}' display correctly.`,
);
defaultTheme = theme;
}
Icon.createFromIconfontCN = createFromIconfontCN; Icon.createFromIconfontCN = createFromIconfontCN;
Icon.getTwoToneColor = getTwoToneColor; Icon.getTwoToneColor = getTwoToneColor;
Icon.setTwoToneColor = setTwoToneColor; Icon.setTwoToneColor = setTwoToneColor;

View File

@ -39,8 +39,11 @@ export interface InputProps
class Input extends React.Component<InputProps, any> { class Input extends React.Component<InputProps, any> {
static Group: typeof Group; static Group: typeof Group;
static Search: typeof Search; static Search: typeof Search;
static TextArea: typeof TextArea; static TextArea: typeof TextArea;
static Password: typeof Password; static Password: typeof Password;
static defaultProps = { static defaultProps = {
@ -88,6 +91,10 @@ class Input extends React.Component<InputProps, any> {
}; };
} }
// Since polyfill `getSnapshotBeforeUpdate` need work with `componentDidUpdate`.
// We keep an empty function here.
componentDidUpdate() {}
getSnapshotBeforeUpdate(prevProps: InputProps) { getSnapshotBeforeUpdate(prevProps: InputProps) {
if (hasPrefixSuffix(prevProps) !== hasPrefixSuffix(this.props)) { if (hasPrefixSuffix(prevProps) !== hasPrefixSuffix(this.props)) {
warning( warning(
@ -99,32 +106,6 @@ class Input extends React.Component<InputProps, any> {
return null; return null;
} }
// Since polyfill `getSnapshotBeforeUpdate` need work with `componentDidUpdate`.
// We keep an empty function here.
componentDidUpdate() {}
handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
const { onPressEnter, onKeyDown } = this.props;
if (e.keyCode === 13 && onPressEnter) {
onPressEnter(e);
}
if (onKeyDown) {
onKeyDown(e);
}
};
focus() {
this.input.focus();
}
blur() {
this.input.blur();
}
select() {
this.input.select();
}
getInputClassName(prefixCls: string) { getInputClassName(prefixCls: string) {
const { size, disabled } = this.props; const { size, disabled } = this.props;
return classNames(prefixCls, { return classNames(prefixCls, {
@ -134,10 +115,6 @@ class Input extends React.Component<InputProps, any> {
}); });
} }
saveInput = (node: HTMLInputElement) => {
this.input = node;
};
setValue( setValue(
value: string, value: string,
e: React.ChangeEvent<HTMLInputElement> | React.MouseEvent<HTMLElement, MouseEvent>, e: React.ChangeEvent<HTMLInputElement> | React.MouseEvent<HTMLElement, MouseEvent>,
@ -166,6 +143,20 @@ class Input extends React.Component<InputProps, any> {
} }
} }
saveInput = (node: HTMLInputElement) => {
this.input = node;
};
handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
const { onPressEnter, onKeyDown } = this.props;
if (e.keyCode === 13 && onPressEnter) {
onPressEnter(e);
}
if (onKeyDown) {
onKeyDown(e);
}
};
handleReset = (e: React.MouseEvent<HTMLElement, MouseEvent>) => { handleReset = (e: React.MouseEvent<HTMLElement, MouseEvent>) => {
this.setValue('', e, () => { this.setValue('', e, () => {
this.focus(); this.focus();
@ -176,6 +167,18 @@ class Input extends React.Component<InputProps, any> {
this.setValue(e.target.value, e); this.setValue(e.target.value, e);
}; };
focus() {
this.input.focus();
}
blur() {
this.input.blur();
}
select() {
this.input.select();
}
renderClearIcon(prefixCls: string) { renderClearIcon(prefixCls: string) {
const { allowClear } = this.props; const { allowClear } = this.props;
const { value } = this.state; const { value } = this.state;

View File

@ -1,5 +1,6 @@
import * as React from 'react'; import * as React from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import omit from 'omit.js';
import Input, { InputProps } from './Input'; import Input, { InputProps } from './Input';
import Icon from '../icon'; import Icon from '../icon';
@ -31,9 +32,7 @@ export default class Password extends React.Component<PasswordProps, PasswordSta
}; };
onChange = () => { onChange = () => {
this.setState({ this.setState(({ visible }) => ({ visible: !visible }));
visible: !this.state.visible,
});
}; };
getIcon() { getIcon() {
@ -59,7 +58,6 @@ export default class Password extends React.Component<PasswordProps, PasswordSta
prefixCls, prefixCls,
inputPrefixCls, inputPrefixCls,
size, size,
suffix,
visibilityToggle, visibilityToggle,
...restProps ...restProps
} = this.props; } = this.props;
@ -69,7 +67,7 @@ export default class Password extends React.Component<PasswordProps, PasswordSta
}); });
return ( return (
<Input <Input
{...restProps} {...omit(restProps, ['suffix'])}
type={this.state.visible ? 'text' : 'password'} type={this.state.visible ? 'text' : 'password'}
size={size} size={size}
className={inputClassName} className={inputClassName}

View File

@ -21,6 +21,10 @@ export default class Search extends React.Component<SearchProps, any> {
private input: Input; private input: Input;
saveInput = (node: Input) => {
this.input = node;
};
onSearch = (e: React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLInputElement>) => { onSearch = (e: React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLInputElement>) => {
const { onSearch } = this.props; const { onSearch } = this.props;
if (onSearch) { if (onSearch) {
@ -37,10 +41,6 @@ export default class Search extends React.Component<SearchProps, any> {
this.input.blur(); this.input.blur();
} }
saveInput = (node: Input) => {
this.input = node;
};
renderSuffix = (prefixCls: string) => { renderSuffix = (prefixCls: string) => {
const { suffix, enterButton } = this.props; const { suffix, enterButton } = this.props;
if (enterButton) return suffix; if (enterButton) return suffix;

View File

@ -28,6 +28,7 @@ export interface TextAreaState {
class TextArea extends React.Component<TextAreaProps, TextAreaState> { class TextArea extends React.Component<TextAreaProps, TextAreaState> {
nextFrameActionId: number; nextFrameActionId: number;
resizeFrameId: number; resizeFrameId: number;
state = { state = {
@ -53,32 +54,8 @@ class TextArea extends React.Component<TextAreaProps, TextAreaState> {
raf.cancel(this.resizeFrameId); raf.cancel(this.resizeFrameId);
} }
resizeOnNextFrame = () => { saveTextAreaRef = (textArea: HTMLTextAreaElement) => {
raf.cancel(this.nextFrameActionId); this.textAreaRef = textArea;
this.nextFrameActionId = raf(this.resizeTextarea);
};
focus() {
this.textAreaRef.focus();
}
blur() {
this.textAreaRef.blur();
}
resizeTextarea = () => {
const { autosize } = this.props;
if (!autosize || !this.textAreaRef) {
return;
}
const { minRows, maxRows } = autosize as AutoSizeType;
const textareaStyles = calculateNodeHeight(this.textAreaRef, false, minRows, maxRows);
this.setState({ textareaStyles, resizing: true }, () => {
raf.cancel(this.resizeFrameId);
this.resizeFrameId = raf(() => {
this.setState({ resizing: false });
});
});
}; };
handleTextareaChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => { handleTextareaChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
@ -101,10 +78,34 @@ class TextArea extends React.Component<TextAreaProps, TextAreaState> {
} }
}; };
saveTextAreaRef = (textArea: HTMLTextAreaElement) => { resizeOnNextFrame = () => {
this.textAreaRef = textArea; raf.cancel(this.nextFrameActionId);
this.nextFrameActionId = raf(this.resizeTextarea);
}; };
resizeTextarea = () => {
const { autosize } = this.props;
if (!autosize || !this.textAreaRef) {
return;
}
const { minRows, maxRows } = autosize as AutoSizeType;
const textareaStyles = calculateNodeHeight(this.textAreaRef, false, minRows, maxRows);
this.setState({ textareaStyles, resizing: true }, () => {
raf.cancel(this.resizeFrameId);
this.resizeFrameId = raf(() => {
this.setState({ resizing: false });
});
});
};
focus() {
this.textAreaRef.focus();
}
blur() {
this.textAreaRef.blur();
}
renderTextArea = ({ getPrefixCls }: ConfigConsumerProps) => { renderTextArea = ({ getPrefixCls }: ConfigConsumerProps) => {
const { textareaStyles, resizing } = this.state; const { textareaStyles, resizing } = this.state;
const { prefixCls: customizePrefixCls, className, disabled, autosize } = this.props; const { prefixCls: customizePrefixCls, className, disabled, autosize } = this.props;

View File

@ -124,10 +124,10 @@ export default function calculateNodeHeight(
if (boxSizing === 'border-box') { if (boxSizing === 'border-box') {
// border-box: add border, since height = content + padding + border // border-box: add border, since height = content + padding + border
height = height + borderSize; height += borderSize;
} else if (boxSizing === 'content-box') { } else if (boxSizing === 'content-box') {
// remove padding, since height = content // remove padding, since height = content
height = height - paddingSize; height -= paddingSize;
} }
if (minRows !== null || maxRows !== null) { if (minRows !== null || maxRows !== null) {

View File

@ -36,7 +36,7 @@ class NumericInput extends React.Component {
onChange = e => { onChange = e => {
const { value } = e.target; const { value } = e.target;
const reg = /^-?(0|[1-9][0-9]*)(\.[0-9]*)?$/; const reg = /^-?(0|[1-9][0-9]*)(\.[0-9]*)?$/;
if ((!Number.isNaN(value) && reg.test(value)) || value === '' || value === '-') { if ((!isNaN(value) && reg.test(value)) || value === '' || value === '-') {
this.props.onChange(value); this.props.onChange(value);
} }
}; };

View File

@ -1,6 +1,13 @@
import createContext, { Context } from '@ant-design/create-react-context'; import createContext, { Context } from '@ant-design/create-react-context';
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
import * as React from 'react';
import { polyfill } from 'react-lifecycles-compat';
import classNames from 'classnames';
import omit from 'omit.js';
import { LayoutContext, LayoutContextProps } from './layout'; import { LayoutContext, LayoutContextProps } from './layout';
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
import Icon from '../icon';
import isNumeric from '../_util/isNumeric';
// matchMedia polyfill for // matchMedia polyfill for
// https://github.com/WickyNilliams/enquire.js/issues/82 // https://github.com/WickyNilliams/enquire.js/issues/82
@ -16,13 +23,6 @@ if (typeof window !== 'undefined') {
window.matchMedia = window.matchMedia || matchMediaPolyfill; window.matchMedia = window.matchMedia || matchMediaPolyfill;
} }
import * as React from 'react';
import { polyfill } from 'react-lifecycles-compat';
import classNames from 'classnames';
import omit from 'omit.js';
import Icon from '../icon';
import isNumeric from '../_util/isNumeric';
const dimensionMap = { const dimensionMap = {
xs: '480px', xs: '480px',
sm: '576px', sm: '576px',
@ -95,6 +95,7 @@ class InternalSider extends React.Component<InternalSideProps, SiderState> {
} }
private mql: MediaQueryList; private mql: MediaQueryList;
private uniqueId: string; private uniqueId: string;
constructor(props: InternalSideProps) { constructor(props: InternalSideProps) {
@ -169,7 +170,7 @@ class InternalSider extends React.Component<InternalSideProps, SiderState> {
}; };
belowShowChange = () => { belowShowChange = () => {
this.setState({ belowShow: !this.state.belowShow }); this.setState(({ belowShow }) => ({ belowShow: !belowShow }));
}; };
renderSider = ({ getPrefixCls }: ConfigConsumerProps) => { renderSider = ({ getPrefixCls }: ConfigConsumerProps) => {
@ -266,6 +267,7 @@ class InternalSider extends React.Component<InternalSideProps, SiderState> {
polyfill(InternalSider); polyfill(InternalSider);
/* eslint-disable react/prefer-stateless-function */
export default class Sider extends React.Component { export default class Sider extends React.Component {
render() { render() {
return ( return (

View File

@ -34,8 +34,11 @@ function generator({ suffixCls, tagName }: GeneratorProps) {
return (BasicComponent: React.ComponentClass<BasicPropsWithTagName>): any => { return (BasicComponent: React.ComponentClass<BasicPropsWithTagName>): any => {
return class Adapter extends React.Component<BasicProps, any> { return class Adapter extends React.Component<BasicProps, any> {
static Header: any; static Header: any;
static Footer: any; static Footer: any;
static Content: any; static Content: any;
static Sider: any; static Sider: any;
renderComponent = ({ getPrefixCls }: ConfigConsumerProps) => { renderComponent = ({ getPrefixCls }: ConfigConsumerProps) => {
@ -52,6 +55,7 @@ function generator({ suffixCls, tagName }: GeneratorProps) {
}; };
} }
/* eslint-disable react/prefer-stateless-function */
class Basic extends React.Component<BasicPropsWithTagName, any> { class Basic extends React.Component<BasicPropsWithTagName, any> {
render() { render() {
const { prefixCls, className, children, tagName, ...others } = this.props; const { prefixCls, className, children, tagName, ...others } = this.props;

View File

@ -106,6 +106,7 @@ export default class Item extends React.Component<ListItemProps, any> {
const actionsContent = actions && actions.length > 0 && ( const actionsContent = actions && actions.length > 0 && (
<ul className={`${prefixCls}-item-action`} key="actions"> <ul className={`${prefixCls}-item-action`} key="actions">
{actions.map((action: React.ReactNode, i: number) => ( {actions.map((action: React.ReactNode, i: number) => (
/* eslint-disable react/no-array-index-key */
<li key={`${prefixCls}-item-action-${i}`}> <li key={`${prefixCls}-item-action-${i}`}>
{action} {action}
{i !== actions.length - 1 && <em className={`${prefixCls}-item-action-split`} />} {i !== actions.length - 1 && <em className={`${prefixCls}-item-action-split`} />}

View File

@ -1,10 +1,10 @@
import * as React from 'react'; import * as React from 'react';
import * as PropTypes from 'prop-types'; import * as PropTypes from 'prop-types';
import classNames from 'classnames'; import classNames from 'classnames';
import { SpinProps } from '../spin'; import omit from 'omit.js';
import Spin, { SpinProps } from '../spin';
import { ConfigConsumer, ConfigConsumerProps, RenderEmptyHandler } from '../config-provider'; import { ConfigConsumer, ConfigConsumerProps, RenderEmptyHandler } from '../config-provider';
import Spin from '../spin';
import Pagination, { PaginationConfig } from '../pagination'; import Pagination, { PaginationConfig } from '../pagination';
import { Row } from '../grid'; import { Row } from '../grid';
@ -174,12 +174,9 @@ export default class List<T> extends React.Component<ListProps<T>, ListState> {
grid, grid,
dataSource = [], dataSource = [],
size, size,
rowKey,
renderItem,
header, header,
footer, footer,
loading, loading,
locale,
...rest ...rest
} = this.props; } = this.props;
@ -201,6 +198,7 @@ export default class List<T> extends React.Component<ListProps<T>, ListState> {
break; break;
case 'small': case 'small':
sizeCls = 'sm'; sizeCls = 'sm';
break;
default: default:
break; break;
} }
@ -273,7 +271,7 @@ export default class List<T> extends React.Component<ListProps<T>, ListState> {
const paginationPosition = paginationProps.position || 'bottom'; const paginationPosition = paginationProps.position || 'bottom';
return ( return (
<div className={classString} {...rest}> <div className={classString} {...omit(rest, ['rowKey', 'renderItem', 'locale'])}>
{(paginationPosition === 'top' || paginationPosition === 'both') && paginationContent} {(paginationPosition === 'top' || paginationPosition === 'both') && paginationContent}
{header && <div className={`${prefixCls}-header`}>{header}</div>} {header && <div className={`${prefixCls}-header`}>{header}</div>}
<Spin {...loadingProp}> <Spin {...loadingProp}>

View File

@ -15,6 +15,7 @@ exports[`renders ./components/locale-provider/demo/all.md correctly 1`] = `
> >
<label <label
class="ant-radio-button-wrapper ant-radio-button-wrapper-checked" class="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
for="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
> >
<span <span
class="ant-radio-button ant-radio-button-checked" class="ant-radio-button ant-radio-button-checked"
@ -34,6 +35,7 @@ exports[`renders ./components/locale-provider/demo/all.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-button-wrapper" class="ant-radio-button-wrapper"
for="ant-radio-button-wrapper"
> >
<span <span
class="ant-radio-button" class="ant-radio-button"
@ -455,6 +457,7 @@ exports[`renders ./components/locale-provider/demo/all.md correctly 1`] = `
> >
<label <label
class="ant-checkbox-wrapper" class="ant-checkbox-wrapper"
for="checkbox-label"
> >
<span <span
class="ant-checkbox" class="ant-checkbox"
@ -630,6 +633,7 @@ exports[`renders ./components/locale-provider/demo/all.md correctly 1`] = `
> >
<label <label
class="ant-checkbox-wrapper" class="ant-checkbox-wrapper"
for="checkbox-label"
> >
<span <span
class="ant-checkbox" class="ant-checkbox"
@ -861,6 +865,7 @@ exports[`renders ./components/locale-provider/demo/all.md correctly 1`] = `
> >
<label <label
class="ant-radio-button-wrapper ant-radio-button-wrapper-checked" class="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
for="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
> >
<span <span
class="ant-radio-button ant-radio-button-checked" class="ant-radio-button ant-radio-button-checked"
@ -881,6 +886,7 @@ exports[`renders ./components/locale-provider/demo/all.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-button-wrapper" class="ant-radio-button-wrapper"
for="ant-radio-button-wrapper"
> >
<span <span
class="ant-radio-button" class="ant-radio-button"

View File

@ -42,17 +42,22 @@ export interface MentionState {
class Mention extends React.Component<MentionProps, MentionState> { class Mention extends React.Component<MentionProps, MentionState> {
static getMentions = getMentions; static getMentions = getMentions;
static defaultProps = { static defaultProps = {
notFoundContent: 'No matches found', notFoundContent: 'No matches found',
loading: false, loading: false,
multiLines: false, multiLines: false,
placement: 'bottom' as MentionPlacement, placement: 'bottom' as MentionPlacement,
}; };
static Nav = Nav; static Nav = Nav;
static toString = toString; static toString = toString;
static toContentState = toEditorState; static toContentState = toEditorState;
private mentionEle: any; private mentionEle: any;
constructor(props: MentionProps) { constructor(props: MentionProps) {
super(props); super(props);
this.state = { this.state = {
@ -67,6 +72,10 @@ class Mention extends React.Component<MentionProps, MentionState> {
); );
} }
mentionRef = (ele: any) => {
this.mentionEle = ele;
};
onSearchChange = (value: string, prefix: string) => { onSearchChange = (value: string, prefix: string) => {
if (this.props.onSearchChange) { if (this.props.onSearchChange) {
return this.props.onSearchChange(value, prefix); return this.props.onSearchChange(value, prefix);
@ -80,22 +89,6 @@ class Mention extends React.Component<MentionProps, MentionState> {
} }
}; };
defaultSearchChange(value: string): void {
const searchValue = value.toLowerCase();
const filteredSuggestions = (this.props.defaultSuggestions || []).filter(suggestion => {
if (typeof suggestion === 'string') {
return suggestion.toLowerCase().indexOf(searchValue) !== -1;
} else if (suggestion.type && suggestion.type === Nav) {
return suggestion.props.value
? suggestion.props.value.toLowerCase().indexOf(searchValue) !== -1
: true;
}
});
this.setState({
filteredSuggestions,
});
}
onFocus = (ev: React.FocusEvent<HTMLElement>) => { onFocus = (ev: React.FocusEvent<HTMLElement>) => {
this.setState({ this.setState({
focus: true, focus: true,
@ -118,9 +111,24 @@ class Mention extends React.Component<MentionProps, MentionState> {
this.mentionEle._editor.focusEditor(); this.mentionEle._editor.focusEditor();
}; };
mentionRef = (ele: any) => { defaultSearchChange(value: string): void {
this.mentionEle = ele; const searchValue = value.toLowerCase();
}; const filteredSuggestions = (this.props.defaultSuggestions || []).filter(suggestion => {
if (typeof suggestion === 'string') {
return suggestion.toLowerCase().indexOf(searchValue) !== -1;
}
if (suggestion.type && suggestion.type === Nav) {
return suggestion.props.value
? suggestion.props.value.toLowerCase().indexOf(searchValue) !== -1
: true;
}
return false;
});
this.setState({
filteredSuggestions,
});
}
renderMention = ({ getPrefixCls }: ConfigConsumerProps) => { renderMention = ({ getPrefixCls }: ConfigConsumerProps) => {
const { const {
prefixCls: customizePrefixCls, prefixCls: customizePrefixCls,

View File

@ -4,11 +4,10 @@ import * as React from 'react';
import { polyfill } from 'react-lifecycles-compat'; import { polyfill } from 'react-lifecycles-compat';
import RcMentions from 'rc-mentions'; import RcMentions from 'rc-mentions';
import { MentionsProps as RcMentionsProps } from 'rc-mentions/lib/Mentions'; import { MentionsProps as RcMentionsProps } from 'rc-mentions/lib/Mentions';
import { OptionProps as RcOptionProps } from 'rc-mentions/lib/Option';
import Spin from '../spin'; import Spin from '../spin';
import { ConfigConsumer, ConfigConsumerProps, RenderEmptyHandler } from '../config-provider'; import { ConfigConsumer, ConfigConsumerProps, RenderEmptyHandler } from '../config-provider';
const Option: React.FunctionComponent<RcOptionProps> = RcMentions.Option; const { Option } = RcMentions;
function loadingFilterOption() { function loadingFilterOption() {
return true; return true;
@ -109,7 +108,7 @@ class Mentions extends React.Component<MentionProps, MentionState> {
const { children, loading } = this.props; const { children, loading } = this.props;
if (loading) { if (loading) {
return ( return (
<Option value={'ANTD_SEARCHING'} disabled> <Option value="ANTD_SEARCHING" disabled>
<Spin size="small" /> <Spin size="small" />
</Option> </Option>
); );

View File

@ -24,6 +24,7 @@ export interface MenuItemProps
export default class MenuItem extends React.Component<MenuItemProps> { export default class MenuItem extends React.Component<MenuItemProps> {
static isMenuItem = true; static isMenuItem = true;
private menuItem: this; private menuItem: this;
onKeyDown = (e: React.MouseEvent<HTMLElement>) => { onKeyDown = (e: React.MouseEvent<HTMLElement>) => {

View File

@ -26,8 +26,10 @@ class SubMenu extends React.Component<SubMenuProps, any> {
static contextTypes = { static contextTypes = {
antdMenuTheme: PropTypes.string, antdMenuTheme: PropTypes.string,
}; };
// fix issue:https://github.com/ant-design/ant-design/issues/8666 // fix issue:https://github.com/ant-design/ant-design/issues/8666
static isSubMenu = 1; static isSubMenu = 1;
private subMenu: any; private subMenu: any;
onKeyDown = (e: React.MouseEvent<HTMLElement>) => { onKeyDown = (e: React.MouseEvent<HTMLElement>) => {

View File

@ -2,12 +2,12 @@ import * as React from 'react';
import RcMenu, { Divider, ItemGroup } from 'rc-menu'; import RcMenu, { Divider, ItemGroup } from 'rc-menu';
import classNames from 'classnames'; import classNames from 'classnames';
import omit from 'omit.js'; import omit from 'omit.js';
import { polyfill } from 'react-lifecycles-compat';
import SubMenu from './SubMenu'; import SubMenu from './SubMenu';
import Item from './MenuItem'; import Item from './MenuItem';
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider'; import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
import animation from '../_util/openAnimation'; import animation from '../_util/openAnimation';
import warning from '../_util/warning'; import warning from '../_util/warning';
import { polyfill } from 'react-lifecycles-compat';
import { SiderContext, SiderContextProps } from '../layout/Sider'; import { SiderContext, SiderContextProps } from '../layout/Sider';
import raf from '../_util/raf'; import raf from '../_util/raf';
import MenuContext, { MenuTheme } from './MenuContext'; import MenuContext, { MenuTheme } from './MenuContext';
@ -169,15 +169,46 @@ class InternalMenu extends React.Component<InternalMenuProps, MenuState> {
raf.cancel(this.mountRafId); raf.cancel(this.mountRafId);
} }
restoreModeVerticalFromInline() { setOpenKeys(openKeys: string[]) {
const { switchingModeFromInline } = this.state; if (!('openKeys' in this.props)) {
if (switchingModeFromInline) { this.setState({ openKeys });
this.setState({
switchingModeFromInline: false,
});
} }
} }
getRealMenuMode() {
const inlineCollapsed = this.getInlineCollapsed();
if (this.state.switchingModeFromInline && inlineCollapsed) {
return 'inline';
}
const { mode } = this.props;
return inlineCollapsed ? 'vertical' : mode;
}
getInlineCollapsed() {
const { inlineCollapsed } = this.props;
if (this.props.siderCollapsed !== undefined) {
return this.props.siderCollapsed;
}
return inlineCollapsed;
}
getMenuOpenAnimation(menuMode: MenuMode) {
const { openAnimation, openTransitionName } = this.props;
let menuOpenAnimation = openAnimation || openTransitionName;
if (openAnimation === undefined && openTransitionName === undefined) {
if (menuMode === 'horizontal') {
menuOpenAnimation = 'slide-up';
} else if (menuMode === 'inline') {
menuOpenAnimation = animation;
} else {
// When mode switch from inline
// submenu should hide without animation
menuOpenAnimation = this.state.switchingModeFromInline ? '' : 'zoom-big';
}
}
return menuOpenAnimation;
}
// Restore vertical mode when menu is collapsed responsively when mounted // Restore vertical mode when menu is collapsed responsively when mounted
// https://github.com/ant-design/ant-design/issues/13104 // https://github.com/ant-design/ant-design/issues/13104
// TODO: not a perfect solution, looking a new way to avoid setting switchingModeFromInline in this situation // TODO: not a perfect solution, looking a new way to avoid setting switchingModeFromInline in this situation
@ -229,50 +260,15 @@ class InternalMenu extends React.Component<InternalMenuProps, MenuState> {
} }
}; };
setOpenKeys(openKeys: string[]) { restoreModeVerticalFromInline() {
if (!('openKeys' in this.props)) { const { switchingModeFromInline } = this.state;
this.setState({ openKeys }); if (switchingModeFromInline) {
this.setState({
switchingModeFromInline: false,
});
} }
} }
getRealMenuMode() {
const inlineCollapsed = this.getInlineCollapsed();
if (this.state.switchingModeFromInline && inlineCollapsed) {
return 'inline';
}
const { mode } = this.props;
return inlineCollapsed ? 'vertical' : mode;
}
getInlineCollapsed() {
const { inlineCollapsed } = this.props;
if (this.props.siderCollapsed !== undefined) {
return this.props.siderCollapsed;
}
return inlineCollapsed;
}
getMenuOpenAnimation(menuMode: MenuMode) {
const { openAnimation, openTransitionName } = this.props;
let menuOpenAnimation = openAnimation || openTransitionName;
if (openAnimation === undefined && openTransitionName === undefined) {
if (menuMode === 'horizontal') {
menuOpenAnimation = 'slide-up';
} else if (menuMode === 'inline') {
menuOpenAnimation = animation;
} else {
// When mode switch from inline
// submenu should hide without animation
if (this.state.switchingModeFromInline) {
menuOpenAnimation = '';
} else {
menuOpenAnimation = 'zoom-big';
}
}
}
return menuOpenAnimation;
}
renderMenu = ({ getPopupContainer, getPrefixCls }: ConfigConsumerProps) => { renderMenu = ({ getPopupContainer, getPrefixCls }: ConfigConsumerProps) => {
const { mounted } = this.state; const { mounted } = this.state;
const { prefixCls: customizePrefixCls, className, theme, collapsedWidth } = this.props; const { prefixCls: customizePrefixCls, className, theme, collapsedWidth } = this.props;
@ -339,8 +335,11 @@ polyfill(InternalMenu);
// We should keep this as ref-able // We should keep this as ref-able
export default class Menu extends React.Component<MenuProps, {}> { export default class Menu extends React.Component<MenuProps, {}> {
static Divider = Divider; static Divider = Divider;
static Item = Item; static Item = Item;
static SubMenu = SubMenu; static SubMenu = SubMenu;
static ItemGroup = ItemGroup; static ItemGroup = ItemGroup;
render() { render() {

View File

@ -1,4 +1,3 @@
/* global Promise */
import * as React from 'react'; import * as React from 'react';
import Notification from 'rc-notification'; import Notification from 'rc-notification';
import Icon from '../icon'; import Icon from '../icon';
@ -78,6 +77,7 @@ function notice(args: ArgsProps): MessageType {
const iconNode = ( const iconNode = (
<Icon type={iconType} theme={iconType === 'loading' ? 'outlined' : 'filled'} /> <Icon type={iconType} theme={iconType === 'loading' ? 'outlined' : 'filled'} />
); );
const switchIconNode = iconType ? iconNode : '';
instance.notice({ instance.notice({
key: target, key: target,
duration, duration,
@ -88,7 +88,7 @@ function notice(args: ArgsProps): MessageType {
args.type ? ` ${prefixCls}-${args.type}` : '' args.type ? ` ${prefixCls}-${args.type}` : ''
}`} }`}
> >
{args.icon ? args.icon : iconType ? iconNode : ''} {args.icon ? args.icon : switchIconNode}
<span>{args.content}</span> <span>{args.content}</span>
</div> </div>
), ),
@ -159,7 +159,7 @@ const api: any = {
onClose = duration; onClose = duration;
duration = undefined; duration = undefined;
} }
return api.open({ content, duration: duration, type, onClose }); return api.open({ content, duration, type, onClose });
}; };
}); });

View File

@ -71,7 +71,7 @@ export default class ActionButton extends React.Component<ActionButtonProps, Act
render() { render() {
const { type, children, buttonProps } = this.props; const { type, children, buttonProps } = this.props;
const loading = this.state.loading; const { loading } = this.state;
return ( return (
<Button type={type} onClick={this.onClick} loading={loading} {...buttonProps}> <Button type={type} onClick={this.onClick} loading={loading} {...buttonProps}>
{children} {children}

View File

@ -31,34 +31,34 @@ if (typeof window !== 'undefined' && window.document && window.document.document
} }
export interface ModalProps { export interface ModalProps {
/** 对话框是否可见*/ /** 对话框是否可见 */
visible?: boolean; visible?: boolean;
/** 确定按钮 loading*/ /** 确定按钮 loading */
confirmLoading?: boolean; confirmLoading?: boolean;
/** 标题*/ /** 标题 */
title?: React.ReactNode | string; title?: React.ReactNode | string;
/** 是否显示右上角的关闭按钮*/ /** 是否显示右上角的关闭按钮 */
closable?: boolean; closable?: boolean;
/** 点击确定回调*/ /** 点击确定回调 */
onOk?: (e: React.MouseEvent<HTMLElement>) => void; onOk?: (e: React.MouseEvent<HTMLElement>) => void;
/** 点击模态框右上角叉、取消按钮、Props.maskClosable 值为 true 时的遮罩层或键盘按下 Esc 时的回调*/ /** 点击模态框右上角叉、取消按钮、Props.maskClosable 值为 true 时的遮罩层或键盘按下 Esc 时的回调 */
onCancel?: (e: React.MouseEvent<HTMLElement>) => void; onCancel?: (e: React.MouseEvent<HTMLElement>) => void;
afterClose?: () => void; afterClose?: () => void;
/** 垂直居中 */ /** 垂直居中 */
centered?: boolean; centered?: boolean;
/** 宽度*/ /** 宽度 */
width?: string | number; width?: string | number;
/** 底部内容*/ /** 底部内容 */
footer?: React.ReactNode; footer?: React.ReactNode;
/** 确认按钮文字*/ /** 确认按钮文字 */
okText?: React.ReactNode; okText?: React.ReactNode;
/** 确认按钮类型*/ /** 确认按钮类型 */
okType?: ButtonType; okType?: ButtonType;
/** 取消按钮文字*/ /** 取消按钮文字 */
cancelText?: React.ReactNode; cancelText?: React.ReactNode;
/** 点击蒙层是否允许关闭*/ /** 点击蒙层是否允许关闭 */
maskClosable?: boolean; maskClosable?: boolean;
/** 强制渲染 Modal*/ /** 强制渲染 Modal */
forceRender?: boolean; forceRender?: boolean;
okButtonProps?: NativeButtonProps; okButtonProps?: NativeButtonProps;
cancelButtonProps?: NativeButtonProps; cancelButtonProps?: NativeButtonProps;
@ -129,11 +129,17 @@ export interface ModalLocale {
export default class Modal extends React.Component<ModalProps, {}> { export default class Modal extends React.Component<ModalProps, {}> {
static info: ModalFunc; static info: ModalFunc;
static success: ModalFunc; static success: ModalFunc;
static error: ModalFunc; static error: ModalFunc;
static warn: ModalFunc; static warn: ModalFunc;
static warning: ModalFunc; static warning: ModalFunc;
static confirm: ModalFunc; static confirm: ModalFunc;
static destroyAll: () => void; static destroyAll: () => void;
static defaultProps = { static defaultProps = {
@ -161,14 +167,14 @@ export default class Modal extends React.Component<ModalProps, {}> {
}; };
handleCancel = (e: React.MouseEvent<HTMLButtonElement>) => { handleCancel = (e: React.MouseEvent<HTMLButtonElement>) => {
const onCancel = this.props.onCancel; const { onCancel } = this.props;
if (onCancel) { if (onCancel) {
onCancel(e); onCancel(e);
} }
}; };
handleOk = (e: React.MouseEvent<HTMLButtonElement>) => { handleOk = (e: React.MouseEvent<HTMLButtonElement>) => {
const onOk = this.props.onOk; const { onOk } = this.props;
if (onOk) { if (onOk) {
onOk(e); onOk(e);
} }

View File

@ -80,7 +80,7 @@ const ConfirmDialog = (props: ConfirmDialogProps) => {
prefixCls={prefixCls} prefixCls={prefixCls}
className={classString} className={classString}
wrapClassName={classNames({ [`${contentPrefixCls}-centered`]: !!props.centered })} wrapClassName={classNames({ [`${contentPrefixCls}-centered`]: !!props.centered })}
onCancel={close.bind(this, { triggerCancel: true })} onCancel={() => close({ triggerCancel: true })}
visible={visible} visible={visible}
title="" title=""
transitionName={transitionName} transitionName={transitionName}
@ -123,8 +123,31 @@ const ConfirmDialog = (props: ConfirmDialogProps) => {
export default function confirm(config: ModalFuncProps) { export default function confirm(config: ModalFuncProps) {
const div = document.createElement('div'); const div = document.createElement('div');
document.body.appendChild(div); document.body.appendChild(div);
/* eslint-disable no-use-before-define */
let currentConfig = { ...config, close, visible: true } as any; let currentConfig = { ...config, close, visible: true } as any;
function destroy(...args: any[]) {
const unmountResult = ReactDOM.unmountComponentAtNode(div);
if (unmountResult && div.parentNode) {
div.parentNode.removeChild(div);
}
const triggerCancel = args.some(param => param && param.triggerCancel);
if (config.onCancel && triggerCancel) {
config.onCancel(...args);
}
for (let i = 0; i < destroyFns.length; i++) {
const fn = destroyFns[i];
if (fn === close) {
destroyFns.splice(i, 1);
break;
}
}
}
function render(props: any) {
ReactDOM.render(<ConfirmDialog {...props} getContainer={false} />, div);
}
function close(...args: any[]) { function close(...args: any[]) {
currentConfig = { currentConfig = {
...currentConfig, ...currentConfig,
@ -146,28 +169,6 @@ export default function confirm(config: ModalFuncProps) {
render(currentConfig); render(currentConfig);
} }
function destroy(...args: any[]) {
const unmountResult = ReactDOM.unmountComponentAtNode(div);
if (unmountResult && div.parentNode) {
div.parentNode.removeChild(div);
}
const triggerCancel = args.some(param => param && param.triggerCancel);
if (config.onCancel && triggerCancel) {
config.onCancel(...args);
}
for (let i = 0; i < destroyFns.length; i++) {
const fn = destroyFns[i];
if (fn === close) {
destroyFns.splice(i, 1);
break;
}
}
}
function render(props: any) {
ReactDOM.render(<ConfirmDialog {...props} getContainer={false}/>, div);
}
render(currentConfig); render(currentConfig);
destroyFns.push(close); destroyFns.push(close);

View File

@ -6,6 +6,16 @@ import Icon from '../icon';
export { ActionButtonProps } from './ActionButton'; export { ActionButtonProps } from './ActionButton';
export { ModalProps, ModalFuncProps } from './Modal'; export { ModalProps, ModalFuncProps } from './Modal';
function modalWarn(props: ModalFuncProps) {
const config = {
type: 'warning',
icon: <Icon type="exclamation-circle" />,
okCancel: false,
...props,
};
return confirm(config);
}
Modal.info = function(props: ModalFuncProps) { Modal.info = function(props: ModalFuncProps) {
const config = { const config = {
type: 'info', type: 'info',
@ -36,15 +46,9 @@ Modal.error = function(props: ModalFuncProps) {
return confirm(config); return confirm(config);
}; };
Modal.warning = Modal.warn = function(props: ModalFuncProps) { Modal.warning = modalWarn;
const config = {
type: 'warning', Modal.warn = modalWarn;
icon: <Icon type="exclamation-circle" />,
okCancel: false,
...props,
};
return confirm(config);
};
Modal.confirm = function(props: ModalFuncProps) { Modal.confirm = function(props: ModalFuncProps) {
const config = { const config = {

View File

@ -108,7 +108,7 @@ function getNotificationInstance(
className: `${prefixCls}-${placement}`, className: `${prefixCls}-${placement}`,
style: getPlacementStyle(placement, top, bottom), style: getPlacementStyle(placement, top, bottom),
getContainer, getContainer,
closeIcon: <Icon className={`${prefixCls}-close-icon`} type={'close'} />, closeIcon: <Icon className={`${prefixCls}-close-icon`} type="close" />,
}, },
(notification: any) => { (notification: any) => {
notificationInstance[cacheKey] = notification; notificationInstance[cacheKey] = notification;

View File

@ -44,7 +44,8 @@ class Popconfirm extends React.Component<PopconfirmProps, PopconfirmState> {
static getDerivedStateFromProps(nextProps: PopconfirmProps) { static getDerivedStateFromProps(nextProps: PopconfirmProps) {
if ('visible' in nextProps) { if ('visible' in nextProps) {
return { visible: nextProps.visible }; return { visible: nextProps.visible };
} else if ('defaultVisible' in nextProps) { }
if ('defaultVisible' in nextProps) {
return { visible: nextProps.defaultVisible }; return { visible: nextProps.defaultVisible };
} }
return null; return null;
@ -91,7 +92,7 @@ class Popconfirm extends React.Component<PopconfirmProps, PopconfirmState> {
}; };
setVisible(visible: boolean, e?: React.MouseEvent<HTMLButtonElement>) { setVisible(visible: boolean, e?: React.MouseEvent<HTMLButtonElement>) {
const props = this.props; const { props } = this;
if (!('visible' in props)) { if (!('visible' in props)) {
this.setState({ visible }); this.setState({ visible });
} }

View File

@ -18,6 +18,7 @@ interface LineProps extends ProgressProps {
*/ */
export const sortGradient = (gradients: ProgressGradient) => { export const sortGradient = (gradients: ProgressGradient) => {
let tempArr = []; let tempArr = [];
/* eslint-disable no-restricted-syntax */
for (const [key, value] of Object.entries(gradients)) { for (const [key, value] of Object.entries(gradients)) {
const formatKey = parseFloat(key.replace(/%/g, '')); const formatKey = parseFloat(key.replace(/%/g, ''));
if (isNaN(formatKey)) { if (isNaN(formatKey)) {

View File

@ -1,6 +1,7 @@
import * as PropTypes from 'prop-types'; import * as PropTypes from 'prop-types';
import * as React from 'react'; import * as React from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import omit from 'omit.js';
import Icon from '../icon'; import Icon from '../icon';
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider'; import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
import { tuple } from '../_util/type'; import { tuple } from '../_util/type';
@ -98,26 +99,8 @@ export default class Progress extends React.Component<ProgressProps> {
} }
renderProgress = ({ getPrefixCls }: ConfigConsumerProps) => { renderProgress = ({ getPrefixCls }: ConfigConsumerProps) => {
const props = this.props; const { props } = this;
const { const { prefixCls: customizePrefixCls, className, size, type, showInfo, ...restProps } = props;
prefixCls: customizePrefixCls,
className,
percent = 0,
status,
format,
trailColor,
size,
successPercent,
type,
strokeWidth,
width,
showInfo,
gapDegree = 0,
gapPosition,
strokeColor,
strokeLinecap = 'round',
...restProps
} = props;
const prefixCls = getPrefixCls('progress', customizePrefixCls); const prefixCls = getPrefixCls('progress', customizePrefixCls);
const progressStatus = this.getProgressStatus(); const progressStatus = this.getProgressStatus();
const progressInfo = this.renderProcessInfo(prefixCls, progressStatus); const progressInfo = this.renderProcessInfo(prefixCls, progressStatus);
@ -149,7 +132,22 @@ export default class Progress extends React.Component<ProgressProps> {
); );
return ( return (
<div {...restProps} className={classString}> <div
{...omit(restProps, [
'status',
'format',
'trailColor',
'successPercent',
'strokeWidth',
'width',
'gapDegree',
'gapPosition',
'strokeColor',
'strokeLinecap',
'percent',
])}
className={classString}
>
{progress} {progress}
</div> </div>
); );

View File

@ -3,6 +3,7 @@
exports[`renders ./components/radio/demo/basic.md correctly 1`] = ` exports[`renders ./components/radio/demo/basic.md correctly 1`] = `
<label <label
class="ant-radio-wrapper" class="ant-radio-wrapper"
for="ant-radio-wrapper"
> >
<span <span
class="ant-radio" class="ant-radio"
@ -25,6 +26,7 @@ exports[`renders ./components/radio/demo/disable.md correctly 1`] = `
<div> <div>
<label <label
class="ant-radio-wrapper ant-radio-wrapper-disabled" class="ant-radio-wrapper ant-radio-wrapper-disabled"
for="ant-radio-wrapper ant-radio-wrapper-disabled"
> >
<span <span
class="ant-radio ant-radio-disabled" class="ant-radio ant-radio-disabled"
@ -45,6 +47,7 @@ exports[`renders ./components/radio/demo/disable.md correctly 1`] = `
<br /> <br />
<label <label
class="ant-radio-wrapper ant-radio-wrapper-disabled" class="ant-radio-wrapper ant-radio-wrapper-disabled"
for="ant-radio-wrapper ant-radio-wrapper-disabled"
> >
<span <span
class="ant-radio ant-radio-checked ant-radio-disabled" class="ant-radio ant-radio-checked ant-radio-disabled"
@ -86,6 +89,7 @@ exports[`renders ./components/radio/demo/radiobutton.md correctly 1`] = `
> >
<label <label
class="ant-radio-button-wrapper ant-radio-button-wrapper-checked" class="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
for="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
> >
<span <span
class="ant-radio-button ant-radio-button-checked" class="ant-radio-button ant-radio-button-checked"
@ -106,6 +110,7 @@ exports[`renders ./components/radio/demo/radiobutton.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-button-wrapper" class="ant-radio-button-wrapper"
for="ant-radio-button-wrapper"
> >
<span <span
class="ant-radio-button" class="ant-radio-button"
@ -125,6 +130,7 @@ exports[`renders ./components/radio/demo/radiobutton.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-button-wrapper" class="ant-radio-button-wrapper"
for="ant-radio-button-wrapper"
> >
<span <span
class="ant-radio-button" class="ant-radio-button"
@ -144,6 +150,7 @@ exports[`renders ./components/radio/demo/radiobutton.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-button-wrapper" class="ant-radio-button-wrapper"
for="ant-radio-button-wrapper"
> >
<span <span
class="ant-radio-button" class="ant-radio-button"
@ -171,6 +178,7 @@ exports[`renders ./components/radio/demo/radiobutton.md correctly 1`] = `
> >
<label <label
class="ant-radio-button-wrapper ant-radio-button-wrapper-checked" class="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
for="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
> >
<span <span
class="ant-radio-button ant-radio-button-checked" class="ant-radio-button ant-radio-button-checked"
@ -191,6 +199,7 @@ exports[`renders ./components/radio/demo/radiobutton.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-button-wrapper ant-radio-button-wrapper-disabled" class="ant-radio-button-wrapper ant-radio-button-wrapper-disabled"
for="ant-radio-button-wrapper ant-radio-button-wrapper-disabled"
> >
<span <span
class="ant-radio-button ant-radio-button-disabled" class="ant-radio-button ant-radio-button-disabled"
@ -211,6 +220,7 @@ exports[`renders ./components/radio/demo/radiobutton.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-button-wrapper" class="ant-radio-button-wrapper"
for="ant-radio-button-wrapper"
> >
<span <span
class="ant-radio-button" class="ant-radio-button"
@ -230,6 +240,7 @@ exports[`renders ./components/radio/demo/radiobutton.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-button-wrapper" class="ant-radio-button-wrapper"
for="ant-radio-button-wrapper"
> >
<span <span
class="ant-radio-button" class="ant-radio-button"
@ -257,6 +268,7 @@ exports[`renders ./components/radio/demo/radiobutton.md correctly 1`] = `
> >
<label <label
class="ant-radio-button-wrapper ant-radio-button-wrapper-checked ant-radio-button-wrapper-disabled" class="ant-radio-button-wrapper ant-radio-button-wrapper-checked ant-radio-button-wrapper-disabled"
for="ant-radio-button-wrapper ant-radio-button-wrapper-checked ant-radio-button-wrapper-disabled"
> >
<span <span
class="ant-radio-button ant-radio-button-checked ant-radio-button-disabled" class="ant-radio-button ant-radio-button-checked ant-radio-button-disabled"
@ -278,6 +290,7 @@ exports[`renders ./components/radio/demo/radiobutton.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-button-wrapper ant-radio-button-wrapper-disabled" class="ant-radio-button-wrapper ant-radio-button-wrapper-disabled"
for="ant-radio-button-wrapper ant-radio-button-wrapper-disabled"
> >
<span <span
class="ant-radio-button ant-radio-button-disabled" class="ant-radio-button ant-radio-button-disabled"
@ -298,6 +311,7 @@ exports[`renders ./components/radio/demo/radiobutton.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-button-wrapper ant-radio-button-wrapper-disabled" class="ant-radio-button-wrapper ant-radio-button-wrapper-disabled"
for="ant-radio-button-wrapper ant-radio-button-wrapper-disabled"
> >
<span <span
class="ant-radio-button ant-radio-button-disabled" class="ant-radio-button ant-radio-button-disabled"
@ -318,6 +332,7 @@ exports[`renders ./components/radio/demo/radiobutton.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-button-wrapper ant-radio-button-wrapper-disabled" class="ant-radio-button-wrapper ant-radio-button-wrapper-disabled"
for="ant-radio-button-wrapper ant-radio-button-wrapper-disabled"
> >
<span <span
class="ant-radio-button ant-radio-button-disabled" class="ant-radio-button ant-radio-button-disabled"
@ -349,6 +364,7 @@ exports[`renders ./components/radio/demo/radiobutton-solid.md correctly 1`] = `
> >
<label <label
class="ant-radio-button-wrapper ant-radio-button-wrapper-checked" class="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
for="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
> >
<span <span
class="ant-radio-button ant-radio-button-checked" class="ant-radio-button ant-radio-button-checked"
@ -369,6 +385,7 @@ exports[`renders ./components/radio/demo/radiobutton-solid.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-button-wrapper" class="ant-radio-button-wrapper"
for="ant-radio-button-wrapper"
> >
<span <span
class="ant-radio-button" class="ant-radio-button"
@ -388,6 +405,7 @@ exports[`renders ./components/radio/demo/radiobutton-solid.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-button-wrapper" class="ant-radio-button-wrapper"
for="ant-radio-button-wrapper"
> >
<span <span
class="ant-radio-button" class="ant-radio-button"
@ -407,6 +425,7 @@ exports[`renders ./components/radio/demo/radiobutton-solid.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-button-wrapper" class="ant-radio-button-wrapper"
for="ant-radio-button-wrapper"
> >
<span <span
class="ant-radio-button" class="ant-radio-button"
@ -434,6 +453,7 @@ exports[`renders ./components/radio/demo/radiobutton-solid.md correctly 1`] = `
> >
<label <label
class="ant-radio-button-wrapper" class="ant-radio-button-wrapper"
for="ant-radio-button-wrapper"
> >
<span <span
class="ant-radio-button" class="ant-radio-button"
@ -453,6 +473,7 @@ exports[`renders ./components/radio/demo/radiobutton-solid.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-button-wrapper ant-radio-button-wrapper-disabled" class="ant-radio-button-wrapper ant-radio-button-wrapper-disabled"
for="ant-radio-button-wrapper ant-radio-button-wrapper-disabled"
> >
<span <span
class="ant-radio-button ant-radio-button-disabled" class="ant-radio-button ant-radio-button-disabled"
@ -473,6 +494,7 @@ exports[`renders ./components/radio/demo/radiobutton-solid.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-button-wrapper ant-radio-button-wrapper-checked" class="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
for="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
> >
<span <span
class="ant-radio-button ant-radio-button-checked" class="ant-radio-button ant-radio-button-checked"
@ -493,6 +515,7 @@ exports[`renders ./components/radio/demo/radiobutton-solid.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-button-wrapper" class="ant-radio-button-wrapper"
for="ant-radio-button-wrapper"
> >
<span <span
class="ant-radio-button" class="ant-radio-button"
@ -521,6 +544,7 @@ exports[`renders ./components/radio/demo/radiogroup.md correctly 1`] = `
> >
<label <label
class="ant-radio-wrapper ant-radio-wrapper-checked" class="ant-radio-wrapper ant-radio-wrapper-checked"
for="ant-radio-wrapper ant-radio-wrapper-checked"
> >
<span <span
class="ant-radio ant-radio-checked" class="ant-radio ant-radio-checked"
@ -541,6 +565,7 @@ exports[`renders ./components/radio/demo/radiogroup.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-wrapper" class="ant-radio-wrapper"
for="ant-radio-wrapper"
> >
<span <span
class="ant-radio" class="ant-radio"
@ -560,6 +585,7 @@ exports[`renders ./components/radio/demo/radiogroup.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-wrapper" class="ant-radio-wrapper"
for="ant-radio-wrapper"
> >
<span <span
class="ant-radio" class="ant-radio"
@ -579,6 +605,7 @@ exports[`renders ./components/radio/demo/radiogroup.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-wrapper" class="ant-radio-wrapper"
for="ant-radio-wrapper"
> >
<span <span
class="ant-radio" class="ant-radio"
@ -605,6 +632,7 @@ exports[`renders ./components/radio/demo/radiogroup-more.md correctly 1`] = `
> >
<label <label
class="ant-radio-wrapper ant-radio-wrapper-checked" class="ant-radio-wrapper ant-radio-wrapper-checked"
for="ant-radio-wrapper ant-radio-wrapper-checked"
style="display:block;height:30px;line-height:30px" style="display:block;height:30px;line-height:30px"
> >
<span <span
@ -626,6 +654,7 @@ exports[`renders ./components/radio/demo/radiogroup-more.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-wrapper" class="ant-radio-wrapper"
for="ant-radio-wrapper"
style="display:block;height:30px;line-height:30px" style="display:block;height:30px;line-height:30px"
> >
<span <span
@ -646,6 +675,7 @@ exports[`renders ./components/radio/demo/radiogroup-more.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-wrapper" class="ant-radio-wrapper"
for="ant-radio-wrapper"
style="display:block;height:30px;line-height:30px" style="display:block;height:30px;line-height:30px"
> >
<span <span
@ -666,6 +696,7 @@ exports[`renders ./components/radio/demo/radiogroup-more.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-wrapper" class="ant-radio-wrapper"
for="ant-radio-wrapper"
style="display:block;height:30px;line-height:30px" style="display:block;height:30px;line-height:30px"
> >
<span <span
@ -694,6 +725,7 @@ exports[`renders ./components/radio/demo/radiogroup-options.md correctly 1`] = `
> >
<label <label
class="ant-radio-wrapper ant-radio-wrapper-checked" class="ant-radio-wrapper ant-radio-wrapper-checked"
for="ant-radio-wrapper ant-radio-wrapper-checked"
> >
<span <span
class="ant-radio ant-radio-checked" class="ant-radio ant-radio-checked"
@ -714,6 +746,7 @@ exports[`renders ./components/radio/demo/radiogroup-options.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-wrapper" class="ant-radio-wrapper"
for="ant-radio-wrapper"
> >
<span <span
class="ant-radio" class="ant-radio"
@ -733,6 +766,7 @@ exports[`renders ./components/radio/demo/radiogroup-options.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-wrapper" class="ant-radio-wrapper"
for="ant-radio-wrapper"
> >
<span <span
class="ant-radio" class="ant-radio"
@ -756,6 +790,7 @@ exports[`renders ./components/radio/demo/radiogroup-options.md correctly 1`] = `
> >
<label <label
class="ant-radio-wrapper ant-radio-wrapper-checked" class="ant-radio-wrapper ant-radio-wrapper-checked"
for="ant-radio-wrapper ant-radio-wrapper-checked"
> >
<span <span
class="ant-radio ant-radio-checked" class="ant-radio ant-radio-checked"
@ -776,6 +811,7 @@ exports[`renders ./components/radio/demo/radiogroup-options.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-wrapper" class="ant-radio-wrapper"
for="ant-radio-wrapper"
> >
<span <span
class="ant-radio" class="ant-radio"
@ -795,6 +831,7 @@ exports[`renders ./components/radio/demo/radiogroup-options.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-wrapper" class="ant-radio-wrapper"
for="ant-radio-wrapper"
> >
<span <span
class="ant-radio" class="ant-radio"
@ -818,6 +855,7 @@ exports[`renders ./components/radio/demo/radiogroup-options.md correctly 1`] = `
> >
<label <label
class="ant-radio-wrapper ant-radio-wrapper-checked" class="ant-radio-wrapper ant-radio-wrapper-checked"
for="ant-radio-wrapper ant-radio-wrapper-checked"
> >
<span <span
class="ant-radio ant-radio-checked" class="ant-radio ant-radio-checked"
@ -838,6 +876,7 @@ exports[`renders ./components/radio/demo/radiogroup-options.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-wrapper" class="ant-radio-wrapper"
for="ant-radio-wrapper"
> >
<span <span
class="ant-radio" class="ant-radio"
@ -857,6 +896,7 @@ exports[`renders ./components/radio/demo/radiogroup-options.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-wrapper" class="ant-radio-wrapper"
for="ant-radio-wrapper"
> >
<span <span
class="ant-radio" class="ant-radio"
@ -884,6 +924,7 @@ exports[`renders ./components/radio/demo/radiogroup-with-name.md correctly 1`] =
> >
<label <label
class="ant-radio-wrapper ant-radio-wrapper-checked" class="ant-radio-wrapper ant-radio-wrapper-checked"
for="ant-radio-wrapper ant-radio-wrapper-checked"
> >
<span <span
class="ant-radio ant-radio-checked" class="ant-radio ant-radio-checked"
@ -905,6 +946,7 @@ exports[`renders ./components/radio/demo/radiogroup-with-name.md correctly 1`] =
</label> </label>
<label <label
class="ant-radio-wrapper" class="ant-radio-wrapper"
for="ant-radio-wrapper"
> >
<span <span
class="ant-radio" class="ant-radio"
@ -925,6 +967,7 @@ exports[`renders ./components/radio/demo/radiogroup-with-name.md correctly 1`] =
</label> </label>
<label <label
class="ant-radio-wrapper" class="ant-radio-wrapper"
for="ant-radio-wrapper"
> >
<span <span
class="ant-radio" class="ant-radio"
@ -945,6 +988,7 @@ exports[`renders ./components/radio/demo/radiogroup-with-name.md correctly 1`] =
</label> </label>
<label <label
class="ant-radio-wrapper" class="ant-radio-wrapper"
for="ant-radio-wrapper"
> >
<span <span
class="ant-radio" class="ant-radio"
@ -974,6 +1018,7 @@ exports[`renders ./components/radio/demo/size.md correctly 1`] = `
> >
<label <label
class="ant-radio-button-wrapper ant-radio-button-wrapper-checked" class="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
for="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
> >
<span <span
class="ant-radio-button ant-radio-button-checked" class="ant-radio-button ant-radio-button-checked"
@ -994,6 +1039,7 @@ exports[`renders ./components/radio/demo/size.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-button-wrapper" class="ant-radio-button-wrapper"
for="ant-radio-button-wrapper"
> >
<span <span
class="ant-radio-button" class="ant-radio-button"
@ -1013,6 +1059,7 @@ exports[`renders ./components/radio/demo/size.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-button-wrapper" class="ant-radio-button-wrapper"
for="ant-radio-button-wrapper"
> >
<span <span
class="ant-radio-button" class="ant-radio-button"
@ -1032,6 +1079,7 @@ exports[`renders ./components/radio/demo/size.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-button-wrapper" class="ant-radio-button-wrapper"
for="ant-radio-button-wrapper"
> >
<span <span
class="ant-radio-button" class="ant-radio-button"
@ -1059,6 +1107,7 @@ exports[`renders ./components/radio/demo/size.md correctly 1`] = `
> >
<label <label
class="ant-radio-button-wrapper ant-radio-button-wrapper-checked" class="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
for="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
> >
<span <span
class="ant-radio-button ant-radio-button-checked" class="ant-radio-button ant-radio-button-checked"
@ -1079,6 +1128,7 @@ exports[`renders ./components/radio/demo/size.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-button-wrapper" class="ant-radio-button-wrapper"
for="ant-radio-button-wrapper"
> >
<span <span
class="ant-radio-button" class="ant-radio-button"
@ -1098,6 +1148,7 @@ exports[`renders ./components/radio/demo/size.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-button-wrapper" class="ant-radio-button-wrapper"
for="ant-radio-button-wrapper"
> >
<span <span
class="ant-radio-button" class="ant-radio-button"
@ -1117,6 +1168,7 @@ exports[`renders ./components/radio/demo/size.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-button-wrapper" class="ant-radio-button-wrapper"
for="ant-radio-button-wrapper"
> >
<span <span
class="ant-radio-button" class="ant-radio-button"
@ -1144,6 +1196,7 @@ exports[`renders ./components/radio/demo/size.md correctly 1`] = `
> >
<label <label
class="ant-radio-button-wrapper ant-radio-button-wrapper-checked" class="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
for="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
> >
<span <span
class="ant-radio-button ant-radio-button-checked" class="ant-radio-button ant-radio-button-checked"
@ -1164,6 +1217,7 @@ exports[`renders ./components/radio/demo/size.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-button-wrapper" class="ant-radio-button-wrapper"
for="ant-radio-button-wrapper"
> >
<span <span
class="ant-radio-button" class="ant-radio-button"
@ -1183,6 +1237,7 @@ exports[`renders ./components/radio/demo/size.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-button-wrapper" class="ant-radio-button-wrapper"
for="ant-radio-button-wrapper"
> >
<span <span
class="ant-radio-button" class="ant-radio-button"
@ -1202,6 +1257,7 @@ exports[`renders ./components/radio/demo/size.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-button-wrapper" class="ant-radio-button-wrapper"
for="ant-radio-button-wrapper"
> >
<span <span
class="ant-radio-button" class="ant-radio-button"

View File

@ -6,6 +6,7 @@ exports[`Radio passes prefixCls down to radio 1`] = `
> >
<label <label
class="my-radio-wrapper" class="my-radio-wrapper"
for="my-radio-wrapper"
> >
<span <span
class="my-radio" class="my-radio"
@ -25,6 +26,7 @@ exports[`Radio passes prefixCls down to radio 1`] = `
</label> </label>
<label <label
class="my-radio-wrapper" class="my-radio-wrapper"
for="my-radio-wrapper"
> >
<span <span
class="my-radio" class="my-radio"

View File

@ -3,6 +3,7 @@
exports[`Radio should render correctly 1`] = ` exports[`Radio should render correctly 1`] = `
<label <label
class="customized ant-radio-wrapper" class="customized ant-radio-wrapper"
for="customized ant-radio-wrapper"
> >
<span <span
class="ant-radio" class="ant-radio"

View File

@ -154,6 +154,9 @@ describe('Radio', () => {
}); });
it('optional should correct render', () => { it('optional should correct render', () => {
if (process.env.REACT === '15') {
return;
}
const wrapper = mount(createRadioGroupByOption()); const wrapper = mount(createRadioGroupByOption());
const radios = wrapper.find('input'); const radios = wrapper.find('input');

View File

@ -38,14 +38,14 @@ class RadioGroup extends React.Component<RadioGroupProps, RadioGroupState> {
return { return {
value: nextProps.value, value: nextProps.value,
}; };
} else { }
const checkedValue = getCheckedValue(nextProps.children); const checkedValue = getCheckedValue(nextProps.children);
if (checkedValue) { if (checkedValue) {
return { return {
value: checkedValue.value, value: checkedValue.value,
}; };
} }
}
return null; return null;
} }
@ -89,14 +89,14 @@ class RadioGroup extends React.Component<RadioGroupProps, RadioGroupState> {
}); });
} }
const onChange = this.props.onChange; const { onChange } = this.props;
if (onChange && value !== lastValue) { if (onChange && value !== lastValue) {
onChange(ev); onChange(ev);
} }
}; };
renderGroup = ({ getPrefixCls }: ConfigConsumerProps) => { renderGroup = ({ getPrefixCls }: ConfigConsumerProps) => {
const props = this.props; const { props } = this;
const { prefixCls: customizePrefixCls, className = '', options, buttonStyle } = props; const { prefixCls: customizePrefixCls, className = '', options, buttonStyle } = props;
const prefixCls = getPrefixCls('radio', customizePrefixCls); const prefixCls = getPrefixCls('radio', customizePrefixCls);
const groupPrefixCls = `${prefixCls}-group`; const groupPrefixCls = `${prefixCls}-group`;
@ -109,17 +109,16 @@ class RadioGroup extends React.Component<RadioGroupProps, RadioGroupState> {
className, className,
); );
let children: React.ReactChildren[] | React.ReactElement<any>[] | React.ReactNode = let { children } = props;
props.children;
// 如果存在 options, 优先使用 // 如果存在 options, 优先使用
if (options && options.length > 0) { if (options && options.length > 0) {
children = options.map((option, index) => { children = options.map(option => {
if (typeof option === 'string') { if (typeof option === 'string') {
// 此处类型自动推导为 string // 此处类型自动推导为 string
return ( return (
<Radio <Radio
key={index} key={`radio-group-value-${option}`}
prefixCls={prefixCls} prefixCls={prefixCls}
disabled={this.props.disabled} disabled={this.props.disabled}
value={option} value={option}
@ -128,11 +127,11 @@ class RadioGroup extends React.Component<RadioGroupProps, RadioGroupState> {
{option} {option}
</Radio> </Radio>
); );
} else { }
// 此处类型自动推导为 { label: string value: string } // 此处类型自动推导为 { label: string value: string }
return ( return (
<Radio <Radio
key={index} key={`radio-group-value-options-${option}`}
prefixCls={prefixCls} prefixCls={prefixCls}
disabled={option.disabled || this.props.disabled} disabled={option.disabled || this.props.disabled}
value={option.value} value={option.value}
@ -141,7 +140,6 @@ class RadioGroup extends React.Component<RadioGroupProps, RadioGroupState> {
{option.label} {option.label}
</Radio> </Radio>
); );
}
}); });
} }

View File

@ -10,6 +10,7 @@ import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
export default class Radio extends React.Component<RadioProps, {}> { export default class Radio extends React.Component<RadioProps, {}> {
static Group: typeof RadioGroup; static Group: typeof RadioGroup;
static Button: typeof RadioButton; static Button: typeof RadioButton;
static defaultProps = { static defaultProps = {
@ -32,14 +33,6 @@ export default class Radio extends React.Component<RadioProps, {}> {
); );
} }
focus() {
this.rcCheckbox.focus();
}
blur() {
this.rcCheckbox.blur();
}
saveCheckbox = (node: any) => { saveCheckbox = (node: any) => {
this.rcCheckbox = node; this.rcCheckbox = node;
}; };
@ -54,6 +47,14 @@ export default class Radio extends React.Component<RadioProps, {}> {
} }
}; };
focus() {
this.rcCheckbox.focus();
}
blur() {
this.rcCheckbox.blur();
}
renderRadio = ({ getPrefixCls }: ConfigConsumerProps) => { renderRadio = ({ getPrefixCls }: ConfigConsumerProps) => {
const { props, context } = this; const { props, context } = this;
const { prefixCls: customizePrefixCls, className, children, style, ...restProps } = props; const { prefixCls: customizePrefixCls, className, children, style, ...restProps } = props;
@ -74,6 +75,7 @@ export default class Radio extends React.Component<RadioProps, {}> {
return ( return (
<label <label
htmlFor={wrapperClassString}
className={wrapperClassString} className={wrapperClassString}
style={style} style={style}
onMouseEnter={props.onMouseEnter} onMouseEnter={props.onMouseEnter}

View File

@ -38,14 +38,6 @@ export default class Rate extends React.Component<RateProps, any> {
private rcRate: any; private rcRate: any;
focus() {
this.rcRate.focus();
}
blur() {
this.rcRate.blur();
}
saveRate = (node: any) => { saveRate = (node: any) => {
this.rcRate = node; this.rcRate = node;
}; };
@ -57,6 +49,14 @@ export default class Rate extends React.Component<RateProps, any> {
return <Tooltip title={tooltips[index]}>{node}</Tooltip>; return <Tooltip title={tooltips[index]}>{node}</Tooltip>;
}; };
focus() {
this.rcRate.focus();
}
blur() {
this.rcRate.blur();
}
renderRate = ({ getPrefixCls }: ConfigConsumerProps) => { renderRate = ({ getPrefixCls }: ConfigConsumerProps) => {
const { prefixCls, ...restProps } = this.props; const { prefixCls, ...restProps } = this.props;

View File

@ -1,6 +1,6 @@
import * as React from 'react'; import * as React from 'react';
export default () => ( const NoFound = () => (
<svg width="252" height="294"> <svg width="252" height="294">
<defs> <defs>
<path d="M0 .387h251.772v251.772H0z" /> <path d="M0 .387h251.772v251.772H0z" />
@ -282,3 +282,5 @@ export default () => (
</g> </g>
</svg> </svg>
); );
export default NoFound;

View File

@ -1,6 +1,6 @@
import * as React from 'react'; import * as React from 'react';
export default () => ( const ServerError = () => (
<svg width="254" height="294"> <svg width="254" height="294">
<defs> <defs>
<path d="M0 .335h253.49v253.49H0z" /> <path d="M0 .335h253.49v253.49H0z" />
@ -327,3 +327,5 @@ export default () => (
</g> </g>
</svg> </svg>
); );
export default ServerError;

View File

@ -1,6 +1,6 @@
import * as React from 'react'; import * as React from 'react';
export default () => ( const Unauthorized = () => (
<svg width="251" height="294"> <svg width="251" height="294">
<g fill="none" fillRule="evenodd"> <g fill="none" fillRule="evenodd">
<path <path
@ -276,3 +276,5 @@ export default () => (
</g> </g>
</svg> </svg>
); );
export default Unauthorized;

View File

@ -911,6 +911,7 @@ exports[`renders ./components/select/demo/size.md correctly 1`] = `
> >
<label <label
class="ant-radio-button-wrapper" class="ant-radio-button-wrapper"
for="ant-radio-button-wrapper"
> >
<span <span
class="ant-radio-button" class="ant-radio-button"
@ -930,6 +931,7 @@ exports[`renders ./components/select/demo/size.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-button-wrapper ant-radio-button-wrapper-checked" class="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
for="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
> >
<span <span
class="ant-radio-button ant-radio-button-checked" class="ant-radio-button ant-radio-button-checked"
@ -950,6 +952,7 @@ exports[`renders ./components/select/demo/size.md correctly 1`] = `
</label> </label>
<label <label
class="ant-radio-button-wrapper" class="ant-radio-button-wrapper"
for="ant-radio-button-wrapper"
> >
<span <span
class="ant-radio-button" class="ant-radio-button"

View File

@ -2,8 +2,8 @@ import * as React from 'react';
import * as PropTypes from 'prop-types'; import * as PropTypes from 'prop-types';
import RcSelect, { Option, OptGroup } from 'rc-select'; import RcSelect, { Option, OptGroup } from 'rc-select';
import classNames from 'classnames'; import classNames from 'classnames';
import { ConfigConsumer, ConfigConsumerProps, RenderEmptyHandler } from '../config-provider';
import omit from 'omit.js'; import omit from 'omit.js';
import { ConfigConsumer, ConfigConsumerProps, RenderEmptyHandler } from '../config-provider';
import warning from '../_util/warning'; import warning from '../_util/warning';
import Icon from '../icon'; import Icon from '../icon';
import { tuple } from '../_util/type'; import { tuple } from '../_util/type';
@ -57,10 +57,7 @@ export interface SelectProps<T = SelectValue> extends AbstractSelectProps {
mode?: 'default' | 'multiple' | 'tags' | 'combobox' | string; mode?: 'default' | 'multiple' | 'tags' | 'combobox' | string;
optionLabelProp?: string; optionLabelProp?: string;
firstActiveValue?: string | string[]; firstActiveValue?: string | string[];
onChange?: ( onChange?: (value: T, option: React.ReactElement<any> | React.ReactElement<any>[]) => void;
value: T,
option: React.ReactElement<any> | React.ReactElement<any>[],
) => void;
onSelect?: (value: T extends (infer I)[] ? I : T, option: React.ReactElement<any>) => void; onSelect?: (value: T extends (infer I)[] ? I : T, option: React.ReactElement<any>) => void;
onDeselect?: (value: T extends (infer I)[] ? I : T) => void; onDeselect?: (value: T extends (infer I)[] ? I : T) => void;
onBlur?: (value: T) => void; onBlur?: (value: T) => void;
@ -117,6 +114,7 @@ const SelectPropTypes = {
export default class Select<T = SelectValue> extends React.Component<SelectProps<T>, {}> { export default class Select<T = SelectValue> extends React.Component<SelectProps<T>, {}> {
static Option = Option as React.ClassicComponentClass<OptionProps>; static Option = Option as React.ClassicComponentClass<OptionProps>;
static OptGroup = OptGroup as React.ClassicComponentClass<OptGroupProps>; static OptGroup = OptGroup as React.ClassicComponentClass<OptGroupProps>;
static SECRET_COMBOBOX_MODE_DO_NOT_USE = 'SECRET_COMBOBOX_MODE_DO_NOT_USE'; static SECRET_COMBOBOX_MODE_DO_NOT_USE = 'SECRET_COMBOBOX_MODE_DO_NOT_USE';
@ -143,18 +141,6 @@ export default class Select<T = SelectValue> extends React.Component<SelectProps
); );
} }
focus() {
this.rcSelect.focus();
}
blur() {
this.rcSelect.blur();
}
saveSelect = (node: any) => {
this.rcSelect = node;
};
getNotFoundContent(renderEmpty: RenderEmptyHandler) { getNotFoundContent(renderEmpty: RenderEmptyHandler) {
const { notFoundContent } = this.props; const { notFoundContent } = this.props;
if (notFoundContent !== undefined) { if (notFoundContent !== undefined) {
@ -176,6 +162,18 @@ export default class Select<T = SelectValue> extends React.Component<SelectProps
// // return notFoundContent === undefined ? locale.notFoundContent : notFoundContent; // // return notFoundContent === undefined ? locale.notFoundContent : notFoundContent;
} }
saveSelect = (node: any) => {
this.rcSelect = node;
};
focus() {
this.rcSelect.focus();
}
blur() {
this.rcSelect.blur();
}
isCombobox() { isCombobox() {
const { mode } = this.props; const { mode } = this.props;
return mode === 'combobox' || mode === Select.SECRET_COMBOBOX_MODE_DO_NOT_USE; return mode === 'combobox' || mode === Select.SECRET_COMBOBOX_MODE_DO_NOT_USE;

View File

@ -9,6 +9,7 @@ export interface SkeletonAvatarProps {
shape?: 'circle' | 'square'; shape?: 'circle' | 'square';
} }
/* eslint-disable react/prefer-stateless-function */
class SkeletonAvatar extends React.Component<SkeletonAvatarProps, any> { class SkeletonAvatar extends React.Component<SkeletonAvatarProps, any> {
static defaultProps: Partial<SkeletonAvatarProps> = { static defaultProps: Partial<SkeletonAvatarProps> = {
size: 'large', size: 'large',

Some files were not shown because too many files have changed in this diff Show More