Browse Source

Merge branch 'master' of github.com:ant-design/ant-design

pull/23596/head
诸岳 5 years ago
parent
commit
ac14f44f2b
  1. 4
      README.md
  2. 130
      components/badge/ScrollNumber.tsx
  3. 160
      components/badge/index.tsx
  4. 28
      components/config-provider/__tests__/container.test.js
  5. 4
      components/date-picker/generatePicker/generateRangePicker.tsx
  6. 4
      components/date-picker/generatePicker/generateSinglePicker.tsx
  7. 82
      components/slider/index.tsx
  8. 2
      package.json

4
README.md

@ -38,9 +38,9 @@ An enterprise-class UI design language and React UI library.
[help-wanted-url]: https://github.com/ant-design/ant-design/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22
[twitter-image]: https://img.shields.io/twitter/follow/AntDesignUI.svg?label=Ant%20Design&style=social
[twitter-url]: https://twitter.com/AntDesignUI
[gitter-english-image]: https://img.shields.io/gitter/room/ant-design/ant-design-english.svg?style=flat-square&logoWidth=20&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgd2lkdGg9IjEyMzUiIGhlaWdodD0iNjUwIiB2aWV3Qm94PSIwIDAgNzQxMCAzOTAwIj4NCjxyZWN0IHdpZHRoPSI3NDEwIiBoZWlnaHQ9IjM5MDAiIGZpbGw9IiNiMjIyMzQiLz4NCjxwYXRoIGQ9Ik0wLDQ1MEg3NDEwbTAsNjAwSDBtMCw2MDBINzQxMG0wLDYwMEgwbTAsNjAwSDc0MTBtMCw2MDBIMCIgc3Ryb2tlPSIjZmZmIiBzdHJva2Utd2lkdGg9IjMwMCIvPg0KPHJlY3Qgd2lkdGg9IjI5NjQiIGhlaWdodD0iMjEwMCIgZmlsbD0iIzNjM2I2ZSIvPg0KPGcgZmlsbD0iI2ZmZiI%2BDQo8ZyBpZD0iczE4Ij4NCjxnIGlkPSJzOSI%2BDQo8ZyBpZD0iczUiPg0KPGcgaWQ9InM0Ij4NCjxwYXRoIGlkPSJzIiBkPSJNMjQ3LDkwIDMxNy41MzQyMzAsMzA3LjA4MjAzOSAxMzIuODczMjE4LDE3Mi45MTc5NjFIMzYxLjEyNjc4MkwxNzYuNDY1NzcwLDMwNy4wODIwMzl6Ii8%2BDQo8dXNlIHhsaW5rOmhyZWY9IiNzIiB5PSI0MjAiLz4NCjx1c2UgeGxpbms6aHJlZj0iI3MiIHk9Ijg0MCIvPg0KPHVzZSB4bGluazpocmVmPSIjcyIgeT0iMTI2MCIvPg0KPC9nPg0KPHVzZSB4bGluazpocmVmPSIjcyIgeT0iMTY4MCIvPg0KPC9nPg0KPHVzZSB4bGluazpocmVmPSIjczQiIHg9IjI0NyIgeT0iMjEwIi8%2BDQo8L2c%2BDQo8dXNlIHhsaW5rOmhyZWY9IiNzOSIgeD0iNDk0Ii8%2BDQo8L2c%2BDQo8dXNlIHhsaW5rOmhyZWY9IiNzMTgiIHg9Ijk4OCIvPg0KPHVzZSB4bGluazpocmVmPSIjczkiIHg9IjE5NzYiLz4NCjx1c2UgeGxpbms6aHJlZj0iI3M1IiB4PSIyNDcwIi8%2BDQo8L2c%2BDQo8L3N2Zz4%3D
[gitter-english-image]: https://img.shields.io/gitter/room/ant-design/ant-design-english.svg?style=flat-square&logoWidth=18&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgd2lkdGg9IjEyMzUiIGhlaWdodD0iNjUwIiB2aWV3Qm94PSIwIDAgNzQxMCAzOTAwIj4NCjxyZWN0IHdpZHRoPSI3NDEwIiBoZWlnaHQ9IjM5MDAiIGZpbGw9IiNiMjIyMzQiLz4NCjxwYXRoIGQ9Ik0wLDQ1MEg3NDEwbTAsNjAwSDBtMCw2MDBINzQxMG0wLDYwMEgwbTAsNjAwSDc0MTBtMCw2MDBIMCIgc3Ryb2tlPSIjZmZmIiBzdHJva2Utd2lkdGg9IjMwMCIvPg0KPHJlY3Qgd2lkdGg9IjI5NjQiIGhlaWdodD0iMjEwMCIgZmlsbD0iIzNjM2I2ZSIvPg0KPGcgZmlsbD0iI2ZmZiI%2BDQo8ZyBpZD0iczE4Ij4NCjxnIGlkPSJzOSI%2BDQo8ZyBpZD0iczUiPg0KPGcgaWQ9InM0Ij4NCjxwYXRoIGlkPSJzIiBkPSJNMjQ3LDkwIDMxNy41MzQyMzAsMzA3LjA4MjAzOSAxMzIuODczMjE4LDE3Mi45MTc5NjFIMzYxLjEyNjc4MkwxNzYuNDY1NzcwLDMwNy4wODIwMzl6Ii8%2BDQo8dXNlIHhsaW5rOmhyZWY9IiNzIiB5PSI0MjAiLz4NCjx1c2UgeGxpbms6aHJlZj0iI3MiIHk9Ijg0MCIvPg0KPHVzZSB4bGluazpocmVmPSIjcyIgeT0iMTI2MCIvPg0KPC9nPg0KPHVzZSB4bGluazpocmVmPSIjcyIgeT0iMTY4MCIvPg0KPC9nPg0KPHVzZSB4bGluazpocmVmPSIjczQiIHg9IjI0NyIgeT0iMjEwIi8%2BDQo8L2c%2BDQo8dXNlIHhsaW5rOmhyZWY9IiNzOSIgeD0iNDk0Ii8%2BDQo8L2c%2BDQo8dXNlIHhsaW5rOmhyZWY9IiNzMTgiIHg9Ijk4OCIvPg0KPHVzZSB4bGluazpocmVmPSIjczkiIHg9IjE5NzYiLz4NCjx1c2UgeGxpbms6aHJlZj0iI3M1IiB4PSIyNDcwIi8%2BDQo8L2c%2BDQo8L3N2Zz4%3D
[gitter-english-url]: https://gitter.im/ant-design/ant-design-english?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge
[gitter-chinese-image]: https://img.shields.io/gitter/room/ant-design/ant-design.svg?style=flat-square&logoWidth=20&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgd2lkdGg9IjkwMCIgaGVpZ2h0PSI2MDAiIHZpZXdCb3g9IjAgMCAzMCAyMCI%2BDQo8ZGVmcz4NCjxwYXRoIGlkPSJzIiBkPSJNMCwtMSAwLjU4Nzc4NSwwLjgwOTAxNyAtMC45NTEwNTcsLTAuMzA5MDE3SDAuOTUxMDU3TC0wLjU4Nzc4NSwwLjgwOTAxN3oiIGZpbGw9IiNmZmRlMDAiLz4NCjwvZGVmcz4NCjxyZWN0IHdpZHRoPSIzMCIgaGVpZ2h0PSIyMCIgZmlsbD0iI2RlMjkxMCIvPg0KPHVzZSB4bGluazpocmVmPSIjcyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNSw1KSBzY2FsZSgzKSIvPg0KPHVzZSB4bGluazpocmVmPSIjcyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTAsMikgcm90YXRlKDIzLjAzNjI0MykiLz4NCjx1c2UgeGxpbms6aHJlZj0iI3MiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEyLDQpIHJvdGF0ZSg0NS44Njk4OTgpIi8%2BDQo8dXNlIHhsaW5rOmhyZWY9IiNzIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxMiw3KSByb3RhdGUoNjkuOTQ1Mzk2KSIvPg0KPHVzZSB4bGluazpocmVmPSIjcyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTAsOSkgcm90YXRlKDIwLjY1OTgwOCkiLz4NCjwvc3ZnPg%3D%3D
[gitter-chinese-image]: https://img.shields.io/gitter/room/ant-design/ant-design.svg?style=flat-square&logoWidth=18&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgd2lkdGg9IjkwMCIgaGVpZ2h0PSI2MDAiIHZpZXdCb3g9IjAgMCAzMCAyMCI%2BDQo8ZGVmcz4NCjxwYXRoIGlkPSJzIiBkPSJNMCwtMSAwLjU4Nzc4NSwwLjgwOTAxNyAtMC45NTEwNTcsLTAuMzA5MDE3SDAuOTUxMDU3TC0wLjU4Nzc4NSwwLjgwOTAxN3oiIGZpbGw9IiNmZmRlMDAiLz4NCjwvZGVmcz4NCjxyZWN0IHdpZHRoPSIzMCIgaGVpZ2h0PSIyMCIgZmlsbD0iI2RlMjkxMCIvPg0KPHVzZSB4bGluazpocmVmPSIjcyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNSw1KSBzY2FsZSgzKSIvPg0KPHVzZSB4bGluazpocmVmPSIjcyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTAsMikgcm90YXRlKDIzLjAzNjI0MykiLz4NCjx1c2UgeGxpbms6aHJlZj0iI3MiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEyLDQpIHJvdGF0ZSg0NS44Njk4OTgpIi8%2BDQo8dXNlIHhsaW5rOmhyZWY9IiNzIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxMiw3KSByb3RhdGUoNjkuOTQ1Mzk2KSIvPg0KPHVzZSB4bGluazpocmVmPSIjcyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTAsOSkgcm90YXRlKDIwLjY1OTgwOCkiLz4NCjwvc3ZnPg%3D%3D
[gitter-chinese-url]: https://gitter.im/ant-design/ant-design?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
[semver-stability-url]: https://dependabot.com/compatibility-score.html/?dependency-name=antd&package-manager=npm_and_yarn&new-version=latest
[semver-stability-image]: https://api.dependabot.com/badges/compatibility_score?dependency-name=antd&package-manager=npm_and_yarn&target-version=latest&version-scheme=semver

130
components/badge/ScrollNumber.tsx

@ -50,73 +50,50 @@ export interface ScrollNumberState {
count?: string | number | null;
}
class ScrollNumber extends React.Component<ScrollNumberProps, ScrollNumberState> {
static defaultProps = {
count: null,
onAnimated() {},
};
static getDerivedStateFromProps(nextProps: ScrollNumberProps, nextState: ScrollNumberState) {
if ('count' in nextProps) {
if (nextState.count === nextProps.count) {
return null;
}
return {
animateStarted: true,
};
}
return null;
}
lastCount?: string | number | null;
private timeout?: number;
constructor(props: ScrollNumberProps) {
super(props);
this.state = {
animateStarted: true,
count: props.count,
};
const ScrollNumber: React.FC<ScrollNumberProps> = props => {
const [animateStarted, setAnimateStarted] = React.useState(true);
const [count, setCount] = React.useState(props.count);
const [prevCount, setPrevCount] = React.useState(props.count);
const [lastCount, setLastCount] = React.useState(props.count);
if (prevCount !== props.count) {
setAnimateStarted(true);
setPrevCount(props.count);
}
componentDidUpdate(_: any, prevState: ScrollNumberState) {
this.lastCount = prevState.count;
const { animateStarted } = this.state;
React.useEffect(() => {
setLastCount(count);
let timeout: number;
if (animateStarted) {
this.clearTimeout();
// Let browser has time to reset the scroller before actually
// performing the transition.
this.timeout = setTimeout(() => {
// eslint-disable-next-line react/no-did-update-set-state
this.setState(
(__, props) => ({
animateStarted: false,
count: props.count,
}),
this.onAnimated,
);
timeout = setTimeout(() => {
setAnimateStarted(false);
setCount(props.count);
if (props.onAnimated) {
props.onAnimated();
}
});
}
}
componentWillUnmount() {
this.clearTimeout();
}
return () => {
if (timeout) {
clearTimeout(timeout);
}
};
}, [animateStarted, count, props.count, props.onAnimated]);
getPositionByNum(num: number, i: number) {
const { count } = this.state;
const getPositionByNum = (num: number, i: number) => {
const currentCount = Math.abs(Number(count));
const lastCount = Math.abs(Number(this.lastCount));
const currentDigit = Math.abs(getNumberArray(this.state.count)[i] as number);
const lastDigit = Math.abs(getNumberArray(this.lastCount)[i] as number);
const lstCount = Math.abs(Number(lastCount));
const currentDigit = Math.abs(getNumberArray(count)[i] as number);
const lastDigit = Math.abs(getNumberArray(lstCount)[i] as number);
if (this.state.animateStarted) {
if (animateStarted) {
return 10 + num;
}
// 同方向则在同一侧切换数字
if (currentCount > lastCount) {
if (currentCount > lstCount) {
if (currentDigit >= lastDigit) {
return 10 + num;
}
@ -126,20 +103,12 @@ class ScrollNumber extends React.Component<ScrollNumberProps, ScrollNumberState>
return 10 + num;
}
return num;
}
onAnimated = () => {
const { onAnimated } = this.props;
if (onAnimated) {
onAnimated();
}
};
renderCurrentNumber(prefixCls: string, num: number | string, i: number) {
const renderCurrentNumber = (prefixCls: string, num: number | string, i: number) => {
if (typeof num === 'number') {
const position = this.getPositionByNum(num, i);
const removeTransition =
this.state.animateStarted || getNumberArray(this.lastCount)[i] === undefined;
const position = getPositionByNum(num, i);
const removeTransition = animateStarted || getNumberArray(lastCount)[i] === undefined;
return React.createElement(
'span',
{
@ -161,19 +130,18 @@ class ScrollNumber extends React.Component<ScrollNumberProps, ScrollNumberState>
{num}
</span>
);
}
};
renderNumberElement(prefixCls: string) {
const { count } = this.state;
const renderNumberElement = (prefixCls: string) => {
if (count && Number(count) % 1 === 0) {
return getNumberArray(count)
.map((num, i) => this.renderCurrentNumber(prefixCls, num, i))
.map((num, i) => renderCurrentNumber(prefixCls, num, i))
.reverse();
}
return count;
}
};
renderScrollNumber = ({ getPrefixCls }: ConfigConsumerProps) => {
const renderScrollNumber = ({ getPrefixCls }: ConfigConsumerProps) => {
const {
prefixCls: customizePrefixCls,
className,
@ -181,9 +149,9 @@ class ScrollNumber extends React.Component<ScrollNumberProps, ScrollNumberState>
title,
component = 'sup',
displayComponent,
} = this.props;
} = props;
// fix https://fb.me/react-unknown-prop
const restProps = omit(this.props, [
const restProps = omit(props, [
'count',
'onAnimated',
'component',
@ -214,19 +182,15 @@ class ScrollNumber extends React.Component<ScrollNumberProps, ScrollNumberState>
),
});
}
return React.createElement(component as any, newProps, this.renderNumberElement(prefixCls));
return React.createElement(component as any, newProps, renderNumberElement(prefixCls));
};
render() {
return <ConfigConsumer>{this.renderScrollNumber}</ConfigConsumer>;
}
return <ConfigConsumer>{renderScrollNumber}</ConfigConsumer>;
};
private clearTimeout(): void {
if (this.timeout) {
clearTimeout(this.timeout);
this.timeout = undefined;
}
}
}
ScrollNumber.defaultProps = {
count: null,
onAnimated() {},
};
export default ScrollNumber;

160
components/badge/index.tsx

@ -32,40 +32,47 @@ function isPresetColor(color?: string): boolean {
return (PresetColorTypes as any[]).indexOf(color) !== -1;
}
export default class Badge extends React.Component<BadgeProps, any> {
static defaultProps = {
count: null,
showZero: false,
dot: false,
overflowCount: 99,
};
getNumberedDisplayCount() {
const { count, overflowCount } = this.props;
const Badge: React.FC<BadgeProps> = props => {
const getNumberedDisplayCount = () => {
const { count, overflowCount } = props;
const displayCount =
(count as number) > (overflowCount as number) ? `${overflowCount}+` : count;
return displayCount as string | number | null;
}
};
getDisplayCount() {
const isDot = this.isDot();
const hasStatus = (): boolean => {
const { status, color } = props;
return !!status || !!color;
};
const isZero = () => {
const numberedDisplayCount = getNumberedDisplayCount();
return numberedDisplayCount === '0' || numberedDisplayCount === 0;
};
const isDot = () => {
const { dot } = props;
return (dot && !isZero()) || hasStatus();
};
const getDisplayCount = () => {
// dot mode don't need count
if (isDot) {
if (isDot()) {
return '';
}
return this.getNumberedDisplayCount();
}
return getNumberedDisplayCount();
};
getScrollNumberTitle() {
const { title, count } = this.props;
const getScrollNumberTitle = () => {
const { title, count } = props;
if (title) {
return title;
}
return typeof count === 'string' || typeof count === 'number' ? count : undefined;
}
};
getStyleWithOffset() {
const { offset, style } = this.props;
const getStyleWithOffset = () => {
const { offset, style } = props;
return offset
? {
right: -parseInt(offset[0] as string, 10),
@ -73,79 +80,61 @@ export default class Badge extends React.Component<BadgeProps, any> {
...style,
}
: style;
}
};
getBadgeClassName(prefixCls: string, direction: string = 'ltr') {
const { className, children } = this.props;
const getBadgeClassName = (prefixCls: string, direction: string = 'ltr') => {
const { className, children } = props;
return classNames(className, prefixCls, {
[`${prefixCls}-status`]: this.hasStatus(),
[`${prefixCls}-status`]: hasStatus(),
[`${prefixCls}-not-a-wrapper`]: !children,
[`${prefixCls}-rtl`]: direction === 'rtl',
}) as string;
}
hasStatus(): boolean {
const { status, color } = this.props;
return !!status || !!color;
}
};
isZero() {
const numberedDisplayCount = this.getNumberedDisplayCount();
return numberedDisplayCount === '0' || numberedDisplayCount === 0;
}
isDot() {
const { dot } = this.props;
const isZero = this.isZero();
return (dot && !isZero) || this.hasStatus();
}
isHidden() {
const { showZero } = this.props;
const displayCount = this.getDisplayCount();
const isZero = this.isZero();
const isDot = this.isDot();
const isHidden = () => {
const { showZero } = props;
const displayCount = getDisplayCount();
const isEmpty = displayCount === null || displayCount === undefined || displayCount === '';
return (isEmpty || (isZero && !showZero)) && !isDot;
}
return (isEmpty || (isZero() && !showZero)) && !isDot();
};
renderStatusText(prefixCls: string) {
const { text } = this.props;
const hidden = this.isHidden();
const renderStatusText = (prefixCls: string) => {
const { text } = props;
const hidden = isHidden();
return hidden || !text ? null : <span className={`${prefixCls}-status-text`}>{text}</span>;
}
};
renderDisplayComponent() {
const { count } = this.props;
const renderDisplayComponent = () => {
const { count } = props;
const customNode = count as React.ReactElement<any>;
if (!customNode || typeof customNode !== 'object') {
return undefined;
}
return React.cloneElement(customNode, {
style: {
...this.getStyleWithOffset(),
...getStyleWithOffset(),
...(customNode.props && customNode.props.style),
},
});
}
};
renderBadgeNumber(prefixCls: string, scrollNumberPrefixCls: string) {
const { status, count, color } = this.props;
const renderBadgeNumber = (prefixCls: string, scrollNumberPrefixCls: string) => {
const { status, count, color } = props;
const displayCount = this.getDisplayCount();
const isDot = this.isDot();
const hidden = this.isHidden();
const displayCount = getDisplayCount();
const dot = isDot();
const hidden = isHidden();
const scrollNumberCls = classNames({
[`${prefixCls}-dot`]: isDot,
[`${prefixCls}-count`]: !isDot,
[`${prefixCls}-dot`]: dot,
[`${prefixCls}-count`]: !dot,
[`${prefixCls}-multiple-words`]:
!isDot && count && count.toString && count.toString().length > 1,
!dot && count && count.toString && count.toString().length > 1,
[`${prefixCls}-status-${status}`]: !!status,
[`${prefixCls}-status-${color}`]: isPresetColor(color),
});
let statusStyle: React.CSSProperties | undefined = this.getStyleWithOffset();
let statusStyle: React.CSSProperties | undefined = getStyleWithOffset();
if (color && !isPresetColor(color)) {
statusStyle = statusStyle || {};
statusStyle.background = color;
@ -157,15 +146,15 @@ export default class Badge extends React.Component<BadgeProps, any> {
data-show={!hidden}
className={scrollNumberCls}
count={displayCount}
displayComponent={this.renderDisplayComponent()} // <Badge status="success" count={<Icon type="xxx" />}></Badge>
title={this.getScrollNumberTitle()}
displayComponent={renderDisplayComponent()} // <Badge status="success" count={<Icon type="xxx" />}></Badge>
title={getScrollNumberTitle()}
style={statusStyle}
key="scrollNumber"
/>
);
}
};
renderBadge = ({ getPrefixCls, direction }: ConfigConsumerProps) => {
const renderBadge = ({ getPrefixCls, direction }: ConfigConsumerProps) => {
const {
prefixCls: customizePrefixCls,
scrollNumberPrefixCls: customizeScrollNumberPrefixCls,
@ -174,7 +163,7 @@ export default class Badge extends React.Component<BadgeProps, any> {
text,
color,
...restProps
} = this.props;
} = props;
const omitArr = [
'count',
'showZero',
@ -189,11 +178,11 @@ export default class Badge extends React.Component<BadgeProps, any> {
const prefixCls = getPrefixCls('badge', customizePrefixCls);
const scrollNumberPrefixCls = getPrefixCls('scroll-number', customizeScrollNumberPrefixCls);
const scrollNumber = this.renderBadgeNumber(prefixCls, scrollNumberPrefixCls);
const statusText = this.renderStatusText(prefixCls);
const scrollNumber = renderBadgeNumber(prefixCls, scrollNumberPrefixCls);
const statusText = renderStatusText(prefixCls);
const statusCls = classNames({
[`${prefixCls}-status-dot`]: this.hasStatus(),
[`${prefixCls}-status-dot`]: hasStatus(),
[`${prefixCls}-status-${status}`]: !!status,
[`${prefixCls}-status-${color}`]: isPresetColor(color),
});
@ -203,13 +192,13 @@ export default class Badge extends React.Component<BadgeProps, any> {
}
// <Badge status="success" />
if (!children && this.hasStatus()) {
const styleWithOffset = this.getStyleWithOffset();
if (!children && hasStatus()) {
const styleWithOffset = getStyleWithOffset();
const statusTextColor = styleWithOffset && styleWithOffset.color;
return (
<span
{...omit(restProps, omitArr)}
className={this.getBadgeClassName(prefixCls, direction)}
className={getBadgeClassName(prefixCls, direction)}
style={styleWithOffset}
>
<span className={statusCls} style={statusStyle} />
@ -221,7 +210,7 @@ export default class Badge extends React.Component<BadgeProps, any> {
}
return (
<span {...omit(restProps, omitArr)} className={this.getBadgeClassName(prefixCls, direction)}>
<span {...omit(restProps, omitArr)} className={getBadgeClassName(prefixCls, direction)}>
{children}
<Animate
component=""
@ -236,7 +225,14 @@ export default class Badge extends React.Component<BadgeProps, any> {
);
};
render() {
return <ConfigConsumer>{this.renderBadge}</ConfigConsumer>;
}
}
return <ConfigConsumer>{renderBadge}</ConfigConsumer>;
};
Badge.defaultProps = {
count: null,
showZero: false,
dot: false,
overflowCount: 99,
};
export default Badge;

28
components/config-provider/__tests__/container.test.js

@ -0,0 +1,28 @@
import React from 'react';
import { mount } from 'enzyme';
import ConfigProvider from '..';
import DatePicker from '../../date-picker';
import Slider from '../../slider';
describe('ConfigProvider.GetPopupContainer', () => {
it('Datepicker', () => {
const getPopupContainer = jest.fn(node => node.parentNode);
mount(
<ConfigProvider getPopupContainer={getPopupContainer}>
<DatePicker open />
</ConfigProvider>,
);
expect(getPopupContainer).toHaveBeenCalled();
});
it('Slider', () => {
const getPopupContainer = jest.fn(node => node.parentNode);
const wrapper = mount(
<ConfigProvider getPopupContainer={getPopupContainer}>
<Slider />
</ConfigProvider>,
);
wrapper.find('.ant-slider-handle').first().simulate('mouseenter');
expect(getPopupContainer).toHaveBeenCalled();
});
});

4
components/date-picker/generatePicker/generateRangePicker.tsx

@ -49,9 +49,10 @@ export default function generateRangePicker<DateType>(
};
renderPicker = (locale: PickerLocale) => {
const { getPrefixCls, direction } = this.context;
const { getPrefixCls, direction, getPopupContainer } = this.context;
const {
prefixCls: customizePrefixCls,
getPopupContainer: customGetPopupContainer,
className,
size: customizeSize,
bordered = true,
@ -94,6 +95,7 @@ export default function generateRangePicker<DateType>(
{...additionalOverrideProps}
locale={locale!.lang}
prefixCls={prefixCls}
getPopupContainer={customGetPopupContainer || getPopupContainer}
generateConfig={generateConfig}
prevIcon={<span className={`${prefixCls}-prev-icon`} />}
nextIcon={<span className={`${prefixCls}-next-icon`} />}

4
components/date-picker/generatePicker/generateSinglePicker.tsx

@ -62,9 +62,10 @@ export default function generatePicker<DateType>(generateConfig: GenerateConfig<
};
renderPicker = (locale: PickerLocale) => {
const { getPrefixCls, direction } = this.context;
const { getPrefixCls, direction, getPopupContainer } = this.context;
const {
prefixCls: customizePrefixCls,
getPopupContainer: customizeGetPopupContainer,
className,
size: customizeSize,
bordered = true,
@ -115,6 +116,7 @@ export default function generatePicker<DateType>(generateConfig: GenerateConfig<
[`${prefixCls}-borderless`]: !bordered,
})}
prefixCls={prefixCls}
getPopupContainer={customizeGetPopupContainer || getPopupContainer}
generateConfig={generateConfig}
prevIcon={<span className={`${prefixCls}-prev-icon`} />}
nextIcon={<span className={`${prefixCls}-next-icon`} />}

82
components/slider/index.tsx

@ -5,7 +5,7 @@ import RcHandle from 'rc-slider/lib/Handle';
import classNames from 'classnames';
import { TooltipPlacement } from '../tooltip';
import SliderTooltip from './SliderTooltip';
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
import { ConfigContext } from '../config-provider';
export interface SliderMarks {
[key: number]:
@ -60,6 +60,7 @@ export interface SliderProps {
export type Visibles = { [index: number]: boolean };
const Slider = React.forwardRef<unknown, SliderProps>((props, ref) => {
const { getPrefixCls, direction, getPopupContainer } = React.useContext(ConfigContext);
const [visibles, setVisibles] = React.useState<Visibles>({});
const toggleTooltipVisible = (index: number, visible: boolean) => {
@ -91,7 +92,7 @@ const Slider = React.forwardRef<unknown, SliderProps>((props, ref) => {
transitionName="zoom-down"
key={index}
overlayClassName={`${prefixCls}-tooltip`}
getPopupContainer={getTooltipPopupContainer || (() => document.body)}
getPopupContainer={getTooltipPopupContainer || getPopupContainer || (() => document.body)}
>
<RcHandle
{...restProps}
@ -102,44 +103,25 @@ const Slider = React.forwardRef<unknown, SliderProps>((props, ref) => {
</SliderTooltip>
);
};
const renderSlider = ({ getPrefixCls, direction }: ConfigConsumerProps) => {
const {
prefixCls: customizePrefixCls,
tooltipPrefixCls: customizeTooltipPrefixCls,
range,
className,
...restProps
} = props;
const prefixCls = getPrefixCls('slider', customizePrefixCls);
const tooltipPrefixCls = getPrefixCls('tooltip', customizeTooltipPrefixCls);
const cls = classNames(className, {
[`${prefixCls}-rtl`]: direction === 'rtl',
});
// make reverse default on rtl direction
if (direction === 'rtl' && !restProps.vertical) {
restProps.reverse = !restProps.reverse;
}
if (range) {
return (
<RcRange
{...restProps}
className={cls}
ref={ref}
handle={(info: HandleGeneratorInfo) =>
handleWithTooltip({
tooltipPrefixCls,
prefixCls,
info,
})
}
prefixCls={prefixCls}
tooltipPrefixCls={tooltipPrefixCls}
/>
);
}
const {
prefixCls: customizePrefixCls,
tooltipPrefixCls: customizeTooltipPrefixCls,
range,
className,
...restProps
} = props;
const prefixCls = getPrefixCls('slider', customizePrefixCls);
const tooltipPrefixCls = getPrefixCls('tooltip', customizeTooltipPrefixCls);
const cls = classNames(className, {
[`${prefixCls}-rtl`]: direction === 'rtl',
});
// make reverse default on rtl direction
if (direction === 'rtl' && !restProps.vertical) {
restProps.reverse = !restProps.reverse;
}
if (range) {
return (
<RcSlider
<RcRange
{...restProps}
className={cls}
ref={ref}
@ -154,11 +136,27 @@ const Slider = React.forwardRef<unknown, SliderProps>((props, ref) => {
tooltipPrefixCls={tooltipPrefixCls}
/>
);
};
return <ConfigConsumer>{renderSlider}</ConfigConsumer>;
}
return (
<RcSlider
{...restProps}
className={cls}
ref={ref}
handle={(info: HandleGeneratorInfo) =>
handleWithTooltip({
tooltipPrefixCls,
prefixCls,
info,
})
}
prefixCls={prefixCls}
tooltipPrefixCls={tooltipPrefixCls}
/>
);
});
Slider.displayName = 'Slider';
Slider.defaultProps = {
tipFormatter(value: number) {
return typeof value === 'number' ? value.toString() : '';

2
package.json

@ -191,7 +191,7 @@
"eslint-plugin-markdown": "^1.0.0",
"eslint-plugin-react": "^7.14.2",
"eslint-plugin-react-hooks": "^3.0.0",
"eslint-plugin-unicorn": "^18.0.1",
"eslint-plugin-unicorn": "^19.0.0",
"eslint-tinker": "^0.5.0",
"fetch-jsonp": "^1.1.3",
"fs-extra": "^9.0.0",

Loading…
Cancel
Save