🔀 merge master into feature

This commit is contained in:
afc163 2020-03-11 15:41:51 +08:00
commit d03ac85f36
113 changed files with 5307 additions and 7117 deletions

View File

@ -0,0 +1,18 @@
import React from 'react';
export type RenderFunction = () => React.ReactNode;
export const getRenderPropValue = (
propValue?: React.ReactNode | RenderFunction,
): React.ReactNode => {
if (!propValue) {
return null;
}
const isRenderFunction = typeof propValue === 'function';
if (isRenderFunction) {
return (propValue as RenderFunction)();
}
return propValue;
};

View File

@ -10,6 +10,7 @@ export interface BreadcrumbItemProps {
separator?: React.ReactNode;
href?: string;
overlay?: DropDownProps['overlay'];
dropdownProps?: DropDownProps;
onClick?: React.MouseEventHandler<HTMLAnchorElement | HTMLSpanElement>;
}
@ -58,10 +59,10 @@ export default class BreadcrumbItem extends React.Component<BreadcrumbItemProps,
* Wrap a DropDown
*/
renderBreadcrumbNode = (breadcrumbItem: React.ReactNode, prefixCls: string) => {
const { overlay } = this.props;
const { overlay, dropdownProps } = this.props;
if (overlay) {
return (
<DropDown overlay={overlay} placement="bottomCenter">
<DropDown overlay={overlay} placement="bottomCenter" {...dropdownProps}>
<span className={`${prefixCls}-overlay-link`}>
{breadcrumbItem}
<DownOutlined />

View File

@ -30,6 +30,7 @@ A breadcrumb displays the current location within a hierarchy. It allows going b
| href | Target of hyperlink | string | - | |
| overlay | The dropdown menu | [Menu](/components/menu) \| () => Menu | - | |
| onClick | Set the handler to handle `click` event | (e:MouseEvent)=>void | - | |
| dropdownProps | The dropdown props | [Dropdown](/components/dropdown) | - | |
### Breadcrumb.Separator

View File

@ -26,11 +26,12 @@ title: Breadcrumb
### Breadcrumb.Item
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| ------- | -------------- | -------------------------------------- | ------ | ---- |
| href | 链接的目的地 | string | - | |
| overlay | 下拉菜单的内容 | [Menu](/components/menu) \| () => Menu | - | |
| onClick | 单击事件 | (e:MouseEvent)=>void | - | |
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| href | 链接的目的地 | string | - | |
| overlay | 下拉菜单的内容 | [Menu](/components/menu) \| () => Menu | - | |
| onClick | 单击事件 | (e:MouseEvent)=>void | - | |
| dropdownProps | 弹出下拉菜单的自定义配置 | [Dropdown](/components/dropdown) | - | |
### Breadcrumb.Separator

View File

@ -204,9 +204,7 @@ exports[`renders ./components/calendar/demo/basic.md correctly 1`] = `
</tr>
</thead>
<tbody>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell"
title="2016-10-30"
@ -327,9 +325,7 @@ exports[`renders ./components/calendar/demo/basic.md correctly 1`] = `
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2016-11-06"
@ -450,9 +446,7 @@ exports[`renders ./components/calendar/demo/basic.md correctly 1`] = `
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2016-11-13"
@ -573,9 +567,7 @@ exports[`renders ./components/calendar/demo/basic.md correctly 1`] = `
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2016-11-20"
@ -696,9 +688,7 @@ exports[`renders ./components/calendar/demo/basic.md correctly 1`] = `
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2016-11-27"
@ -819,9 +809,7 @@ exports[`renders ./components/calendar/demo/basic.md correctly 1`] = `
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell"
title="2016-12-04"
@ -1157,9 +1145,7 @@ exports[`renders ./components/calendar/demo/card.md correctly 1`] = `
</tr>
</thead>
<tbody>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell"
title="2016-10-30"
@ -1280,9 +1266,7 @@ exports[`renders ./components/calendar/demo/card.md correctly 1`] = `
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2016-11-06"
@ -1403,9 +1387,7 @@ exports[`renders ./components/calendar/demo/card.md correctly 1`] = `
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2016-11-13"
@ -1526,9 +1508,7 @@ exports[`renders ./components/calendar/demo/card.md correctly 1`] = `
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2016-11-20"
@ -1649,9 +1629,7 @@ exports[`renders ./components/calendar/demo/card.md correctly 1`] = `
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2016-11-27"
@ -1772,9 +1750,7 @@ exports[`renders ./components/calendar/demo/card.md correctly 1`] = `
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell"
title="2016-12-04"
@ -2136,9 +2112,7 @@ exports[`renders ./components/calendar/demo/customize-header.md correctly 1`] =
</tr>
</thead>
<tbody>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell"
title="2016-10-30"
@ -2259,9 +2233,7 @@ exports[`renders ./components/calendar/demo/customize-header.md correctly 1`] =
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2016-11-06"
@ -2382,9 +2354,7 @@ exports[`renders ./components/calendar/demo/customize-header.md correctly 1`] =
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2016-11-13"
@ -2505,9 +2475,7 @@ exports[`renders ./components/calendar/demo/customize-header.md correctly 1`] =
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2016-11-20"
@ -2628,9 +2596,7 @@ exports[`renders ./components/calendar/demo/customize-header.md correctly 1`] =
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2016-11-27"
@ -2751,9 +2717,7 @@ exports[`renders ./components/calendar/demo/customize-header.md correctly 1`] =
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell"
title="2016-12-04"
@ -3087,9 +3051,7 @@ exports[`renders ./components/calendar/demo/notice-calendar.md correctly 1`] = `
</tr>
</thead>
<tbody>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell"
title="2016-10-30"
@ -3238,9 +3200,7 @@ exports[`renders ./components/calendar/demo/notice-calendar.md correctly 1`] = `
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2016-11-06"
@ -3461,9 +3421,7 @@ exports[`renders ./components/calendar/demo/notice-calendar.md correctly 1`] = `
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2016-11-13"
@ -3697,9 +3655,7 @@ exports[`renders ./components/calendar/demo/notice-calendar.md correctly 1`] = `
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2016-11-20"
@ -3848,9 +3804,7 @@ exports[`renders ./components/calendar/demo/notice-calendar.md correctly 1`] = `
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2016-11-27"
@ -3999,9 +3953,7 @@ exports[`renders ./components/calendar/demo/notice-calendar.md correctly 1`] = `
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell"
title="2016-12-04"
@ -4448,9 +4400,7 @@ exports[`renders ./components/calendar/demo/select.md correctly 1`] = `
</tr>
</thead>
<tbody>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2017-01-01"
@ -4571,9 +4521,7 @@ exports[`renders ./components/calendar/demo/select.md correctly 1`] = `
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2017-01-08"
@ -4694,9 +4642,7 @@ exports[`renders ./components/calendar/demo/select.md correctly 1`] = `
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2017-01-15"
@ -4817,9 +4763,7 @@ exports[`renders ./components/calendar/demo/select.md correctly 1`] = `
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2017-01-22"
@ -4940,9 +4884,7 @@ exports[`renders ./components/calendar/demo/select.md correctly 1`] = `
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2017-01-29"
@ -5063,9 +5005,7 @@ exports[`renders ./components/calendar/demo/select.md correctly 1`] = `
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell"
title="2017-02-05"

View File

@ -206,9 +206,7 @@ exports[`Calendar Calendar should support locale 1`] = `
</tr>
</thead>
<tbody>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2018-10-01"
@ -329,9 +327,7 @@ exports[`Calendar Calendar should support locale 1`] = `
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2018-10-08"
@ -452,9 +448,7 @@ exports[`Calendar Calendar should support locale 1`] = `
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2018-10-15"
@ -575,9 +569,7 @@ exports[`Calendar Calendar should support locale 1`] = `
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2018-10-22"
@ -698,9 +690,7 @@ exports[`Calendar Calendar should support locale 1`] = `
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2018-10-29"
@ -821,9 +811,7 @@ exports[`Calendar Calendar should support locale 1`] = `
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell"
title="2018-11-05"
@ -1156,9 +1144,7 @@ exports[`Calendar rtl render component should be rendered correctly in RTL direc
</tr>
</thead>
<tbody>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell"
title="2000-08-27"
@ -1279,9 +1265,7 @@ exports[`Calendar rtl render component should be rendered correctly in RTL direc
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2000-09-03"
@ -1402,9 +1386,7 @@ exports[`Calendar rtl render component should be rendered correctly in RTL direc
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2000-09-10"
@ -1525,9 +1507,7 @@ exports[`Calendar rtl render component should be rendered correctly in RTL direc
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2000-09-17"
@ -1648,9 +1628,7 @@ exports[`Calendar rtl render component should be rendered correctly in RTL direc
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2000-09-24"
@ -1771,9 +1749,7 @@ exports[`Calendar rtl render component should be rendered correctly in RTL direc
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell"
title="2000-10-01"

View File

@ -126,4 +126,18 @@ describe('Carousel', () => {
).toBeTruthy();
});
});
describe('dots precise control by plain object', () => {
it('use dots to provide dotsClasse', () => {
const wrapper = mount(
<Carousel dots={{ className: 'customDots' }}>
<div>1</div>
<div>2</div>
<div>3</div>
</Carousel>,
);
wrapper.update();
expect(wrapper.find('.slick-dots').hasClass('customDots')).toBeTruthy();
});
});
});

View File

@ -20,7 +20,7 @@ A carousel component. Scales with its container.
| autoplay | Whether to scroll automatically | boolean | `false` | |
| beforeChange | Callback function called before the current index changes | function(from, to) | - | |
| dotPosition | The position of the dots, which can be one of `top` `bottom` `left` `right` | string | bottom | |
| dots | Whether to show the dots at the bottom of the gallery | boolean | `true` | |
| dots | Whether to show the dots at the bottom of the gallery, `object` for `dotsClass` and any others | boolean \| { className?:string } | `true` | |
| easing | Transition interpolation function name | string | `linear` | |
| effect | Transition effect | `scrollx` \| `fade` | `scrollx` | |

View File

@ -1,4 +1,5 @@
import * as React from 'react';
import isPlainObject from 'lodash/isPlainObject';
import debounce from 'lodash/debounce';
import { Settings } from '@ant-design/react-slick';
import classNames from 'classnames';
@ -14,13 +15,18 @@ export type CarouselEffect = 'scrollx' | 'fade';
export type DotPosition = 'top' | 'bottom' | 'left' | 'right';
// Carousel
export interface CarouselProps extends Settings {
export interface CarouselProps extends Omit<Settings, 'dots' | 'dotsClass'> {
effect?: CarouselEffect;
style?: React.CSSProperties;
prefixCls?: string;
slickGoTo?: number;
dotPosition?: DotPosition;
children?: React.ReactNode;
dots?:
| boolean
| {
className?: string;
};
}
export default class Carousel extends React.Component<CarouselProps, {}> {
@ -106,7 +112,13 @@ export default class Carousel extends React.Component<CarouselProps, {}> {
const dotsClass = 'slick-dots';
const dotPosition = this.getDotPosition();
props.vertical = dotPosition === 'left' || dotPosition === 'right';
props.dotsClass = `${dotsClass} ${dotsClass}-${dotPosition || 'bottom'}`;
const enableDots = props.dots === true || isPlainObject(props.dots);
const dsClass = classNames(
dotsClass,
`${dotsClass}-${dotPosition || 'bottom'}`,
typeof props.dots === 'boolean' ? false : props.dots?.className,
);
const className = classNames(prefixCls, {
[`${prefixCls}-rtl`]: direction === 'rtl',
@ -115,7 +127,7 @@ export default class Carousel extends React.Component<CarouselProps, {}> {
return (
<div className={className}>
<SlickCarousel ref={this.saveSlick} {...props} />
<SlickCarousel ref={this.saveSlick} {...props} dots={enableDots} dotsClass={dsClass} />
</div>
);
};

View File

@ -21,7 +21,7 @@ subtitle: 走马灯
| autoplay | 是否自动切换 | boolean | false | | |
| beforeChange | 切换面板的回调 | function(from, to) | 无 | | |
| dotPosition | 面板指示点位置,可选 `top` `bottom` `left` `right` | string | bottom | |
| dots | 是否显示面板指示点 | boolean | true | | |
| dots | 是否显示面板指示点,如果为 `object` 则同时可以指定 `dotsClass` 或者 | boolean \| { className?:string } | true | | |
| easing | 动画效果 | string | linear | | |
| effect | 动画效果函数,可取 scrollx, fade | string | scrollx | | |

View File

@ -1255,9 +1255,7 @@ exports[`ConfigProvider components Calendar configProvider 1`] = `
</tr>
</thead>
<tbody>
<tr
class=""
>
<tr>
<td
class="config-picker-cell"
title="2000-08-27"
@ -1378,9 +1376,7 @@ exports[`ConfigProvider components Calendar configProvider 1`] = `
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="config-picker-cell config-picker-cell-in-view config-picker-cell-selected"
title="2000-09-03"
@ -1501,9 +1497,7 @@ exports[`ConfigProvider components Calendar configProvider 1`] = `
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="config-picker-cell config-picker-cell-in-view"
title="2000-09-10"
@ -1624,9 +1618,7 @@ exports[`ConfigProvider components Calendar configProvider 1`] = `
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="config-picker-cell config-picker-cell-in-view"
title="2000-09-17"
@ -1747,9 +1739,7 @@ exports[`ConfigProvider components Calendar configProvider 1`] = `
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="config-picker-cell config-picker-cell-in-view"
title="2000-09-24"
@ -1870,9 +1860,7 @@ exports[`ConfigProvider components Calendar configProvider 1`] = `
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="config-picker-cell"
title="2000-10-01"
@ -2262,7 +2250,7 @@ exports[`ConfigProvider components Calendar configProvider 1`] = `
</div>
</td>
<td
class="config-picker-cell config-picker-cell-selected config-picker-cell-in-view"
class="config-picker-cell config-picker-cell-in-view config-picker-cell-selected"
title="2000-09"
>
<div
@ -2546,9 +2534,7 @@ exports[`ConfigProvider components Calendar normal 1`] = `
</tr>
</thead>
<tbody>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell"
title="2000-08-27"
@ -2669,9 +2655,7 @@ exports[`ConfigProvider components Calendar normal 1`] = `
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view ant-picker-cell-selected"
title="2000-09-03"
@ -2792,9 +2776,7 @@ exports[`ConfigProvider components Calendar normal 1`] = `
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2000-09-10"
@ -2915,9 +2897,7 @@ exports[`ConfigProvider components Calendar normal 1`] = `
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2000-09-17"
@ -3038,9 +3018,7 @@ exports[`ConfigProvider components Calendar normal 1`] = `
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2000-09-24"
@ -3161,9 +3139,7 @@ exports[`ConfigProvider components Calendar normal 1`] = `
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell"
title="2000-10-01"
@ -3553,7 +3529,7 @@ exports[`ConfigProvider components Calendar normal 1`] = `
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-selected ant-picker-cell-in-view"
class="ant-picker-cell ant-picker-cell-in-view ant-picker-cell-selected"
title="2000-09"
>
<div
@ -3837,9 +3813,7 @@ exports[`ConfigProvider components Calendar prefixCls 1`] = `
</tr>
</thead>
<tbody>
<tr
class=""
>
<tr>
<td
class="prefix-Calendar-cell"
title="2000-08-27"
@ -3960,9 +3934,7 @@ exports[`ConfigProvider components Calendar prefixCls 1`] = `
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="prefix-Calendar-cell prefix-Calendar-cell-in-view prefix-Calendar-cell-selected"
title="2000-09-03"
@ -4083,9 +4055,7 @@ exports[`ConfigProvider components Calendar prefixCls 1`] = `
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="prefix-Calendar-cell prefix-Calendar-cell-in-view"
title="2000-09-10"
@ -4206,9 +4176,7 @@ exports[`ConfigProvider components Calendar prefixCls 1`] = `
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="prefix-Calendar-cell prefix-Calendar-cell-in-view"
title="2000-09-17"
@ -4329,9 +4297,7 @@ exports[`ConfigProvider components Calendar prefixCls 1`] = `
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="prefix-Calendar-cell prefix-Calendar-cell-in-view"
title="2000-09-24"
@ -4452,9 +4418,7 @@ exports[`ConfigProvider components Calendar prefixCls 1`] = `
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="prefix-Calendar-cell"
title="2000-10-01"
@ -4844,7 +4808,7 @@ exports[`ConfigProvider components Calendar prefixCls 1`] = `
</div>
</td>
<td
class="prefix-Calendar-cell prefix-Calendar-cell-selected prefix-Calendar-cell-in-view"
class="prefix-Calendar-cell prefix-Calendar-cell-in-view prefix-Calendar-cell-selected"
title="2000-09"
>
<div
@ -9271,57 +9235,55 @@ exports[`ConfigProvider components Popconfirm configProvider 1`] = `
class="config-popover-inner"
role="tooltip"
>
<div>
<div
class="config-popover-inner-content"
>
<div
class="config-popover-inner-content"
class="config-popover-message"
>
<div
class="config-popover-message"
<span
aria-label="exclamation-circle"
class="anticon anticon-exclamation-circle"
role="img"
>
<span
aria-label="exclamation-circle"
class="anticon anticon-exclamation-circle"
role="img"
<svg
aria-hidden="true"
class=""
data-icon="exclamation-circle"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<svg
aria-hidden="true"
class=""
data-icon="exclamation-circle"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm-32 232c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v272c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8V296zm32 440a48.01 48.01 0 010-96 48.01 48.01 0 010 96z"
/>
</svg>
<path
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm-32 232c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v272c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8V296zm32 440a48.01 48.01 0 010-96 48.01 48.01 0 010 96z"
/>
</svg>
</span>
<div
class="config-popover-message-title"
/>
</div>
<div
class="config-popover-buttons"
>
<button
class="config-btn config-btn-sm"
type="button"
>
<span>
Cancel
</span>
<div
class="config-popover-message-title"
/>
</div>
<div
class="config-popover-buttons"
</button>
<button
class="config-btn config-btn-primary config-btn-sm"
type="button"
>
<button
class="config-btn config-btn-sm"
type="button"
>
<span>
Cancel
</span>
</button>
<button
class="config-btn config-btn-primary config-btn-sm"
type="button"
>
<span>
OK
</span>
</button>
</div>
<span>
OK
</span>
</button>
</div>
</div>
</div>
@ -9353,57 +9315,55 @@ exports[`ConfigProvider components Popconfirm normal 1`] = `
class="ant-popover-inner"
role="tooltip"
>
<div>
<div
class="ant-popover-inner-content"
>
<div
class="ant-popover-inner-content"
class="ant-popover-message"
>
<div
class="ant-popover-message"
<span
aria-label="exclamation-circle"
class="anticon anticon-exclamation-circle"
role="img"
>
<span
aria-label="exclamation-circle"
class="anticon anticon-exclamation-circle"
role="img"
<svg
aria-hidden="true"
class=""
data-icon="exclamation-circle"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<svg
aria-hidden="true"
class=""
data-icon="exclamation-circle"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm-32 232c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v272c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8V296zm32 440a48.01 48.01 0 010-96 48.01 48.01 0 010 96z"
/>
</svg>
<path
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm-32 232c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v272c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8V296zm32 440a48.01 48.01 0 010-96 48.01 48.01 0 010 96z"
/>
</svg>
</span>
<div
class="ant-popover-message-title"
/>
</div>
<div
class="ant-popover-buttons"
>
<button
class="ant-btn ant-btn-sm"
type="button"
>
<span>
Cancel
</span>
<div
class="ant-popover-message-title"
/>
</div>
<div
class="ant-popover-buttons"
</button>
<button
class="ant-btn ant-btn-primary ant-btn-sm"
type="button"
>
<button
class="ant-btn ant-btn-sm"
type="button"
>
<span>
Cancel
</span>
</button>
<button
class="ant-btn ant-btn-primary ant-btn-sm"
type="button"
>
<span>
OK
</span>
</button>
</div>
<span>
OK
</span>
</button>
</div>
</div>
</div>
@ -9435,57 +9395,55 @@ exports[`ConfigProvider components Popconfirm prefixCls 1`] = `
class="prefix-Popconfirm-inner"
role="tooltip"
>
<div>
<div
class="prefix-Popconfirm-inner-content"
>
<div
class="prefix-Popconfirm-inner-content"
class="prefix-Popconfirm-message"
>
<div
class="prefix-Popconfirm-message"
<span
aria-label="exclamation-circle"
class="anticon anticon-exclamation-circle"
role="img"
>
<span
aria-label="exclamation-circle"
class="anticon anticon-exclamation-circle"
role="img"
<svg
aria-hidden="true"
class=""
data-icon="exclamation-circle"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<svg
aria-hidden="true"
class=""
data-icon="exclamation-circle"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm-32 232c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v272c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8V296zm32 440a48.01 48.01 0 010-96 48.01 48.01 0 010 96z"
/>
</svg>
<path
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm-32 232c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v272c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8V296zm32 440a48.01 48.01 0 010-96 48.01 48.01 0 010 96z"
/>
</svg>
</span>
<div
class="prefix-Popconfirm-message-title"
/>
</div>
<div
class="prefix-Popconfirm-buttons"
>
<button
class="ant-btn ant-btn-sm"
type="button"
>
<span>
Cancel
</span>
<div
class="prefix-Popconfirm-message-title"
/>
</div>
<div
class="prefix-Popconfirm-buttons"
</button>
<button
class="ant-btn ant-btn-primary ant-btn-sm"
type="button"
>
<button
class="ant-btn ant-btn-sm"
type="button"
>
<span>
Cancel
</span>
</button>
<button
class="ant-btn ant-btn-primary ant-btn-sm"
type="button"
>
<span>
OK
</span>
</button>
</div>
<span>
OK
</span>
</button>
</div>
</div>
</div>
@ -9517,11 +9475,9 @@ exports[`ConfigProvider components Popover configProvider 1`] = `
class="config-popover-inner"
role="tooltip"
>
<div>
<div
class="config-popover-inner-content"
/>
</div>
<div
class="config-popover-inner-content"
/>
</div>
</div>
</div>
@ -9551,11 +9507,9 @@ exports[`ConfigProvider components Popover normal 1`] = `
class="ant-popover-inner"
role="tooltip"
>
<div>
<div
class="ant-popover-inner-content"
/>
</div>
<div
class="ant-popover-inner-content"
/>
</div>
</div>
</div>
@ -9585,11 +9539,9 @@ exports[`ConfigProvider components Popover prefixCls 1`] = `
class="prefix-Popover-inner"
role="tooltip"
>
<div>
<div
class="prefix-Popover-inner-content"
/>
</div>
<div
class="prefix-Popover-inner-content"
/>
</div>
</div>
</div>
@ -11811,16 +11763,23 @@ exports[`ConfigProvider components Table configProvider 1`] = `
<div
class="config-table-filter-dropdown-btns"
>
<a
class="config-table-filter-dropdown-link confirm"
<button
class="config-btn config-btn-link config-btn-sm"
disabled=""
type="button"
>
OK
</a>
<a
class="config-table-filter-dropdown-link clear"
<span>
Reset
</span>
</button>
<button
class="config-btn config-btn-primary config-btn-sm"
type="button"
>
Reset
</a>
<span>
OK
</span>
</button>
</div>
</div>
</div>
@ -12150,16 +12109,23 @@ exports[`ConfigProvider components Table normal 1`] = `
<div
class="ant-table-filter-dropdown-btns"
>
<a
class="ant-table-filter-dropdown-link confirm"
<button
class="ant-btn ant-btn-link ant-btn-sm"
disabled=""
type="button"
>
OK
</a>
<a
class="ant-table-filter-dropdown-link clear"
<span>
Reset
</span>
</button>
<button
class="ant-btn ant-btn-primary ant-btn-sm"
type="button"
>
Reset
</a>
<span>
OK
</span>
</button>
</div>
</div>
</div>
@ -12489,16 +12455,23 @@ exports[`ConfigProvider components Table prefixCls 1`] = `
<div
class="prefix-Table-filter-dropdown-btns"
>
<a
class="prefix-Table-filter-dropdown-link confirm"
<button
class="ant-btn ant-btn-link ant-btn-sm"
disabled=""
type="button"
>
OK
</a>
<a
class="prefix-Table-filter-dropdown-link clear"
<span>
Reset
</span>
</button>
<button
class="ant-btn ant-btn-primary ant-btn-sm"
type="button"
>
Reset
</a>
<span>
OK
</span>
</button>
</div>
</div>
</div>

View File

@ -146,9 +146,7 @@ Array [
</tr>
</thead>
<tbody>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell ant-picker-cell-disabled"
title="2016-10-30"
@ -220,9 +218,7 @@ Array [
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell ant-picker-cell-disabled ant-picker-cell-in-view"
title="2016-11-06"
@ -294,9 +290,7 @@ Array [
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell ant-picker-cell-disabled ant-picker-cell-in-view"
title="2016-11-13"
@ -368,9 +362,7 @@ Array [
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell ant-picker-cell-disabled ant-picker-cell-in-view"
title="2016-11-20"
@ -442,9 +434,7 @@ Array [
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2016-11-27"
@ -516,9 +506,7 @@ Array [
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell"
title="2016-12-04"
@ -780,9 +768,7 @@ Array [
</tr>
</thead>
<tbody>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell"
title="1999-12-27"
@ -854,9 +840,7 @@ Array [
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2000-01-03"
@ -928,9 +912,7 @@ Array [
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2000-01-10"
@ -1002,9 +984,7 @@ Array [
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2000-01-17"
@ -1076,9 +1056,7 @@ Array [
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2000-01-24"
@ -1150,9 +1128,7 @@ Array [
</div>
</td>
</tr>
<tr
class=""
>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2000-01-31"

View File

@ -53,7 +53,7 @@ exports[`MonthPicker and WeekPicker render MonthPicker 1`] = `
<tbody>
<tr>
<td
class="ant-picker-cell ant-picker-cell-selected ant-picker-cell-in-view"
class="ant-picker-cell ant-picker-cell-in-view ant-picker-cell-selected"
title="2000-01"
>
<div

View File

@ -94,7 +94,7 @@
ul {
margin-right: 0.3em;
margin-left: 0.3em;
padding: 0;
padding: @dropdown-edge-child-vertical-padding 0;
}
}

View File

@ -77,6 +77,7 @@ function FormItem(props: FormItemProps): React.ReactElement {
validateStatus,
children,
required,
label,
trigger = 'onChange',
validateTrigger = 'onChange',
...restProps
@ -235,9 +236,15 @@ function FormItem(props: FormItemProps): React.ReactElement {
return renderLayout(children);
}
const variables: Record<string, string> = {};
if (typeof label === 'string') {
variables.label = label;
}
return (
<Field
{...props}
messageVariables={variables}
trigger={trigger}
validateTrigger={validateTrigger}
onReset={() => {

View File

@ -596,6 +596,28 @@ describe('Form', () => {
expect(errorSpy).not.toHaveBeenCalled();
});
it('`label` support template', async () => {
const wrapper = mount(
// eslint-disable-next-line no-template-curly-in-string
<Form validateMessages={{ required: '${label} is good!' }}>
<Form.Item name="test" label="Bamboo" rules={[{ required: true }]}>
<input />
</Form.Item>
</Form>,
);
wrapper.find('form').simulate('submit');
await delay(50);
wrapper.update();
expect(
wrapper
.find('.ant-form-item-explain')
.first()
.text(),
).toEqual('Bamboo is good!');
});
it('return same form instance', () => {
const instances = new Set();

View File

@ -22,13 +22,13 @@ const layout = {
};
const validateMessages = {
required: 'This field is required!',
required: '${label} is required!',
types: {
email: 'Not a validate email!',
number: 'Not a validate number!',
email: '${label} is not validate email!',
number: '${label} is not a validate number!',
},
number: {
range: 'Must be between ${min} and ${max}',
range: '${label} must be between ${min} and ${max}',
},
};

View File

@ -372,7 +372,7 @@ exports[`List.pagination should change page size work 2`] = `
<div>
<div
class="ant-select-dropdown"
style="width: 0px; opacity: 0;"
style="min-width: 0; opacity: 0;"
>
<div>
<div

View File

@ -1,22 +1,34 @@
import * as React from 'react';
import * as PropTypes from 'prop-types';
import { ModalLocale, changeConfirmLocale } from '../modal/locale';
import warning from '../_util/warning';
import { ModalLocale, changeConfirmLocale } from '../modal/locale';
import { TransferLocale as TransferLocaleForEmpty } from '../empty';
import { PaginationLocale } from '../pagination/Pagination';
import { TableLocale } from '../table/interface';
import { PopconfirmLocale } from '../popconfirm';
import { UploadLocale } from '../upload/interface';
import { TransferLocale } from '../transfer';
export const ANT_MARK = 'internalMark';
export interface Locale {
locale: string;
Pagination?: Object;
Pagination?: PaginationLocale;
DatePicker?: Object;
TimePicker?: Object;
Calendar?: Object;
Table?: Object;
Table?: TableLocale;
Modal?: ModalLocale;
Popconfirm?: Object;
Transfer?: Object;
Popconfirm?: PopconfirmLocale;
Transfer?: Partial<TransferLocale>;
Select?: Object;
Upload?: Object;
Upload?: UploadLocale;
Empty?: TransferLocaleForEmpty;
global?: Object;
PageHeader?: Object;
Icon?: Object;
Text?: Object;
}
export interface LocaleProviderProps {

View File

@ -2,8 +2,9 @@ import Pagination from 'rc-pagination/lib/locale/ar_EG';
import DatePicker from '../date-picker/locale/ar_EG';
import TimePicker from '../time-picker/locale/ar_EG';
import Calendar from '../calendar/locale/ar_EG';
import { Locale } from '../locale-provider';
export default {
const localeValues: Locale = {
locale: 'ar',
Pagination,
DatePicker,
@ -41,3 +42,5 @@ export default {
description: 'لا توجد بيانات',
},
};
export default localeValues;

View File

@ -2,8 +2,9 @@ import Pagination from 'rc-pagination/lib/locale/az_AZ';
import DatePicker from '../date-picker/locale/az_AZ';
import TimePicker from '../time-picker/locale/az_AZ';
import Calendar from '../calendar/locale/az_AZ';
import { Locale } from '../locale-provider';
export default {
const localeValues: Locale = {
locale: 'az',
Pagination,
DatePicker,
@ -43,3 +44,5 @@ export default {
previewFile: 'Fayla önbaxış',
},
};
export default localeValues;

View File

@ -2,8 +2,9 @@ import Pagination from 'rc-pagination/lib/locale/bg_BG';
import DatePicker from '../date-picker/locale/bg_BG';
import TimePicker from '../time-picker/locale/bg_BG';
import Calendar from '../calendar/locale/bg_BG';
import { Locale } from '../locale-provider';
export default {
const localeValues: Locale = {
locale: 'bg',
Pagination,
DatePicker,
@ -41,3 +42,5 @@ export default {
description: 'Няма данни',
},
};
export default localeValues;

View File

@ -2,8 +2,9 @@ import Pagination from 'rc-pagination/lib/locale/ca_ES';
import DatePicker from '../date-picker/locale/ca_ES';
import TimePicker from '../time-picker/locale/ca_ES';
import Calendar from '../calendar/locale/ca_ES';
import { Locale } from '../locale-provider';
export default {
const localeValues: Locale = {
locale: 'ca',
Pagination,
DatePicker,
@ -39,3 +40,5 @@ export default {
description: 'Sense dades',
},
};
export default localeValues;

View File

@ -2,8 +2,9 @@ import Pagination from 'rc-pagination/lib/locale/cs_CZ';
import DatePicker from '../date-picker/locale/cs_CZ';
import TimePicker from '../time-picker/locale/cs_CZ';
import Calendar from '../calendar/locale/cs_CZ';
import { Locale } from '../locale-provider';
export default {
const localeValues: Locale = {
locale: 'cs',
Pagination,
DatePicker,
@ -39,3 +40,5 @@ export default {
description: 'Žádná data',
},
};
export default localeValues;

View File

@ -2,8 +2,9 @@ import Pagination from 'rc-pagination/lib/locale/da_DK';
import DatePicker from '../date-picker/locale/da_DK';
import TimePicker from '../time-picker/locale/da_DK';
import Calendar from '../calendar/locale/da_DK';
import { Locale } from '../locale-provider';
export default {
const localeValues: Locale = {
locale: 'da',
DatePicker,
TimePicker,
@ -41,3 +42,5 @@ export default {
description: 'Ingen data',
},
};
export default localeValues;

View File

@ -2,8 +2,9 @@ import Pagination from 'rc-pagination/lib/locale/de_DE';
import DatePicker from '../date-picker/locale/de_DE';
import TimePicker from '../time-picker/locale/de_DE';
import Calendar from '../calendar/locale/de_DE';
import { Locale } from '../locale-provider';
export default {
const localeValues: Locale = {
locale: 'de',
Pagination,
DatePicker,
@ -41,3 +42,5 @@ export default {
description: 'Keine Daten',
},
};
export default localeValues;

View File

@ -2,8 +2,9 @@ import Pagination from 'rc-pagination/lib/locale/en_US';
import DatePicker from '../date-picker/locale/en_US';
import TimePicker from '../time-picker/locale/en_US';
import Calendar from '../calendar/locale/en_US';
import { Locale } from '../locale-provider';
export default {
const localeValues: Locale = {
locale: 'en',
Pagination,
DatePicker,
@ -22,6 +23,9 @@ export default {
sortTitle: 'Sort',
expand: 'Expand row',
collapse: 'Collapse row',
triggerDesc: 'Click sort by descend',
triggerAsc: 'Click sort by ascend',
cancelSort: 'Click to cancel sort',
},
Modal: {
okText: 'OK',
@ -61,3 +65,5 @@ export default {
back: 'Back',
},
};
export default localeValues;

View File

@ -2,8 +2,9 @@ import Pagination from 'rc-pagination/lib/locale/el_GR';
import DatePicker from '../date-picker/locale/el_GR';
import TimePicker from '../time-picker/locale/el_GR';
import Calendar from '../calendar/locale/el_GR';
import { Locale } from '../locale-provider';
export default {
const localeValues: Locale = {
locale: 'el',
Pagination,
DatePicker,
@ -41,3 +42,5 @@ export default {
description: 'Δεν υπάρχουν δεδομένα',
},
};
export default localeValues;

View File

@ -2,8 +2,9 @@ import Pagination from 'rc-pagination/lib/locale/en_GB';
import DatePicker from '../date-picker/locale/en_GB';
import TimePicker from '../time-picker/locale/en_GB';
import Calendar from '../calendar/locale/en_GB';
import { Locale } from '../locale-provider';
export default {
const localeValues: Locale = {
locale: 'en-gb',
Pagination,
DatePicker,
@ -41,3 +42,5 @@ export default {
description: 'No data',
},
};
export default localeValues;

View File

@ -2,8 +2,9 @@ import Pagination from 'rc-pagination/lib/locale/es_ES';
import DatePicker from '../date-picker/locale/es_ES';
import TimePicker from '../time-picker/locale/es_ES';
import Calendar from '../calendar/locale/es_ES';
import { Locale } from '../locale-provider';
export default {
const localeValues: Locale = {
locale: 'es',
Pagination,
DatePicker,
@ -57,3 +58,5 @@ export default {
back: 'volver',
},
};
export default localeValues;

View File

@ -2,8 +2,9 @@ import Pagination from 'rc-pagination/lib/locale/et_EE';
import DatePicker from '../date-picker/locale/et_EE';
import TimePicker from '../time-picker/locale/et_EE';
import Calendar from '../calendar/locale/et_EE';
import { Locale } from '../locale-provider';
export default {
const localeValues: Locale = {
locale: 'et',
Pagination,
DatePicker,
@ -41,3 +42,5 @@ export default {
description: 'Andmed puuduvad',
},
};
export default localeValues;

View File

@ -2,8 +2,9 @@ import Pagination from 'rc-pagination/lib/locale/fa_IR';
import DatePicker from '../date-picker/locale/fa_IR';
import TimePicker from '../time-picker/locale/fa_IR';
import Calendar from '../calendar/locale/fa_IR';
import { Locale } from '../locale-provider';
export default {
const localeValues: Locale = {
locale: 'fa',
Pagination,
DatePicker,
@ -41,3 +42,5 @@ export default {
description: 'داده‌ای موجود نیست',
},
};
export default localeValues;

View File

@ -2,8 +2,9 @@ import Pagination from 'rc-pagination/lib/locale/fi_FI';
import DatePicker from '../date-picker/locale/fi_FI';
import TimePicker from '../time-picker/locale/fi_FI';
import Calendar from '../calendar/locale/fi_FI';
import { Locale } from '../locale-provider';
export default {
const localeValues: Locale = {
locale: 'fi',
Pagination,
DatePicker,
@ -42,3 +43,5 @@ export default {
description: 'Ei kohteita',
},
};
export default localeValues;

View File

@ -2,8 +2,9 @@ import Pagination from 'rc-pagination/lib/locale/fr_BE';
import DatePicker from '../date-picker/locale/fr_BE';
import TimePicker from '../time-picker/locale/fr_BE';
import Calendar from '../calendar/locale/fr_BE';
import { Locale } from '../locale-provider';
export default {
const localeValues: Locale = {
locale: 'fr',
Pagination,
DatePicker,
@ -45,3 +46,5 @@ export default {
expand: 'développer',
},
};
export default localeValues;

View File

@ -2,8 +2,9 @@ import Pagination from 'rc-pagination/lib/locale/fr_FR';
import DatePicker from '../date-picker/locale/fr_FR';
import TimePicker from '../time-picker/locale/fr_FR';
import Calendar from '../calendar/locale/fr_FR';
import { Locale } from '../locale-provider';
export default {
const localeValues: Locale = {
locale: 'fr',
Pagination,
DatePicker,
@ -45,3 +46,5 @@ export default {
expand: 'développer',
},
};
export default localeValues;

View File

@ -2,8 +2,9 @@ import Pagination from 'rc-pagination/lib/locale/he_IL';
import DatePicker from '../date-picker/locale/he_IL';
import TimePicker from '../time-picker/locale/he_IL';
import Calendar from '../calendar/locale/he_IL';
import { Locale } from '../locale-provider';
export default {
const localeValues: Locale = {
locale: 'he',
Pagination,
DatePicker,
@ -41,3 +42,5 @@ export default {
description: 'אין מידע',
},
};
export default localeValues;

View File

@ -2,8 +2,9 @@ import Pagination from 'rc-pagination/lib/locale/hi_IN';
import DatePicker from '../date-picker/locale/hi_IN';
import TimePicker from '../time-picker/locale/hi_IN';
import Calendar from '../calendar/locale/hi_IN';
import { Locale } from '../locale-provider';
export default {
const localeValues: Locale = {
locale: 'hi',
Pagination,
DatePicker,
@ -49,3 +50,5 @@ export default {
downloadFile: 'फ़ाइल डाउनलोड करें',
},
};
export default localeValues;

View File

@ -2,8 +2,9 @@ import Pagination from 'rc-pagination/lib/locale/hr_HR';
import DatePicker from '../date-picker/locale/hr_HR';
import TimePicker from '../time-picker/locale/hr_HR';
import Calendar from '../calendar/locale/hr_HR';
import { Locale } from '../locale-provider';
export default {
const localeValues: Locale = {
locale: 'hr',
Pagination,
DatePicker,
@ -55,3 +56,5 @@ export default {
expand: 'proširi',
},
};
export default localeValues;

View File

@ -2,8 +2,9 @@ import Pagination from 'rc-pagination/lib/locale/hu_HU';
import DatePicker from '../date-picker/locale/hu_HU';
import TimePicker from '../time-picker/locale/hu_HU';
import Calendar from '../calendar/locale/hu_HU';
import { Locale } from '../locale-provider';
export default {
const localeValues: Locale = {
locale: 'hu',
Pagination,
DatePicker,
@ -42,3 +43,5 @@ export default {
description: 'Nincs adat',
},
};
export default localeValues;

View File

@ -1,3 +1,5 @@
import { Locale } from '../locale-provider';
const datePickerLocale = {
lang: {
locale: 'hy-am',
@ -35,7 +37,7 @@ const datePickerLocale = {
},
};
export default {
const localeValues: Locale = {
locale: 'hy-am',
Pagination: {
// Options.jsx
@ -108,3 +110,5 @@ export default {
back: 'Հետ',
},
};
export default localeValues;

View File

@ -2,8 +2,9 @@ import Pagination from 'rc-pagination/lib/locale/id_ID';
import DatePicker from '../date-picker/locale/id_ID';
import TimePicker from '../time-picker/locale/id_ID';
import Calendar from '../calendar/locale/id_ID';
import { Locale } from '../locale-provider';
export default {
const localeValues: Locale = {
locale: 'id',
Pagination,
DatePicker,
@ -43,3 +44,5 @@ export default {
description: 'Tidak ada data',
},
};
export default localeValues;

View File

@ -2,8 +2,9 @@ import Pagination from 'rc-pagination/lib/locale/is_IS';
import DatePicker from '../date-picker/locale/is_IS';
import TimePicker from '../time-picker/locale/is_IS';
import Calendar from '../calendar/locale/is_IS';
import { Locale } from '../locale-provider';
export default {
const localeValues: Locale = {
locale: 'is',
Pagination,
DatePicker,
@ -41,3 +42,5 @@ export default {
description: 'Engin gögn',
},
};
export default localeValues;

View File

@ -2,8 +2,9 @@ import Pagination from 'rc-pagination/lib/locale/it_IT';
import DatePicker from '../date-picker/locale/it_IT';
import TimePicker from '../time-picker/locale/it_IT';
import Calendar from '../calendar/locale/it_IT';
import { Locale } from '../locale-provider';
export default {
const localeValues: Locale = {
locale: 'it',
Pagination,
DatePicker,
@ -54,3 +55,5 @@ export default {
expand: 'espandi',
},
};
export default localeValues;

View File

@ -2,8 +2,9 @@ import Pagination from 'rc-pagination/lib/locale/ja_JP';
import DatePicker from '../date-picker/locale/ja_JP';
import TimePicker from '../time-picker/locale/ja_JP';
import Calendar from '../calendar/locale/ja_JP';
import { Locale } from '../locale-provider';
export default {
const localeValues: Locale = {
locale: 'ja',
Pagination,
DatePicker,
@ -41,3 +42,5 @@ export default {
description: 'データがありません',
},
};
export default localeValues;

View File

@ -2,8 +2,9 @@ import Pagination from 'rc-pagination/lib/locale/kn_IN';
import DatePicker from '../date-picker/locale/kn_IN';
import TimePicker from '../time-picker/locale/kn_IN';
import Calendar from '../calendar/locale/kn_IN';
import { Locale } from '../locale-provider';
export default {
const localeValues: Locale = {
locale: 'kn',
Pagination,
DatePicker,
@ -49,3 +50,5 @@ export default {
downloadFile: 'ಫೈಲ್ ಡೌನ್‌ಲೋಡ್ ಮಾಡಿ',
},
};
export default localeValues;

View File

@ -2,8 +2,9 @@ import Pagination from 'rc-pagination/lib/locale/ko_KR';
import DatePicker from '../date-picker/locale/ko_KR';
import TimePicker from '../time-picker/locale/ko_KR';
import Calendar from '../calendar/locale/ko_KR';
import { Locale } from '../locale-provider';
export default {
const localeValues: Locale = {
locale: 'ko',
Pagination,
DatePicker,
@ -41,3 +42,5 @@ export default {
description: '데이터 없음',
},
};
export default localeValues;

View File

@ -2,8 +2,9 @@ import Pagination from 'rc-pagination/lib/locale/ku_IQ';
import DatePicker from '../date-picker/locale/ku_IQ';
import TimePicker from '../time-picker/locale/ku_IQ';
import Calendar from '../calendar/locale/ku_IQ';
import { Locale } from '../locale-provider';
export default {
const localeValues: Locale = {
locale: 'ku-iq',
Pagination,
DatePicker,
@ -41,3 +42,5 @@ export default {
description: 'Agahî tune',
},
};
export default localeValues;

View File

@ -2,8 +2,9 @@ import Pagination from 'rc-pagination/lib/locale/lv_LV';
import DatePicker from '../date-picker/locale/lv_LV';
import TimePicker from '../time-picker/locale/lv_LV';
import Calendar from '../calendar/locale/lv_LV';
import { Locale } from '../locale-provider';
export default {
const localeValues: Locale = {
locale: 'lv',
Pagination,
DatePicker,
@ -41,3 +42,5 @@ export default {
description: 'Nav datu',
},
};
export default localeValues;

View File

@ -2,8 +2,9 @@ import Pagination from 'rc-pagination/lib/locale/mk_MK';
import DatePicker from '../date-picker/locale/mk_MK';
import TimePicker from '../time-picker/locale/mk_MK';
import Calendar from '../calendar/locale/mk_MK';
import { Locale } from '../locale-provider';
export default {
const localeValues: Locale = {
locale: 'mk',
Pagination,
DatePicker,
@ -56,3 +57,5 @@ export default {
back: 'Назад',
},
};
export default localeValues;

View File

@ -2,8 +2,9 @@ import Pagination from 'rc-pagination/lib/locale/mn_MN';
import DatePicker from '../date-picker/locale/mn_MN';
import TimePicker from '../time-picker/locale/mn_MN';
import Calendar from '../calendar/locale/mn_MN';
import { Locale } from '../locale-provider';
export default {
const localeValues: Locale = {
locale: 'mn-mn',
Pagination,
DatePicker,
@ -41,3 +42,5 @@ export default {
description: 'Мэдээлэл байхгүй байна',
},
};
export default localeValues;

View File

@ -2,8 +2,9 @@ import Pagination from 'rc-pagination/lib/locale/ms_MY';
import DatePicker from '../date-picker/locale/ms_MY';
import TimePicker from '../time-picker/locale/ms_MY';
import Calendar from '../calendar/locale/ms_MY';
import { Locale } from '../locale-provider';
export default {
const localeValues: Locale = {
locale: 'ms-my',
Pagination,
DatePicker,
@ -61,3 +62,5 @@ export default {
downloadFile: 'Muat turun fail',
},
};
export default localeValues;

View File

@ -2,8 +2,9 @@ import Pagination from 'rc-pagination/lib/locale/nb_NO';
import DatePicker from '../date-picker/locale/nb_NO';
import TimePicker from '../time-picker/locale/nb_NO';
import Calendar from '../calendar/locale/nb_NO';
import { Locale } from '../locale-provider';
export default {
const localeValues: Locale = {
locale: 'nb',
DatePicker,
TimePicker,
@ -41,3 +42,5 @@ export default {
description: 'Ingen data',
},
};
export default localeValues;

View File

@ -2,8 +2,9 @@ import Pagination from 'rc-pagination/lib/locale/en_US';
import DatePicker from '../date-picker/locale/en_US';
import TimePicker from '../time-picker/locale/en_US';
import Calendar from '../calendar/locale/en_US';
import { Locale } from '../locale-provider';
export default {
const localeValues: Locale = {
locale: 'ne-np',
Pagination,
DatePicker,
@ -42,3 +43,5 @@ export default {
description: 'डाटा छैन',
},
};
export default localeValues;

View File

@ -2,8 +2,9 @@ import Pagination from 'rc-pagination/lib/locale/nl_BE';
import DatePicker from '../date-picker/locale/nl_BE';
import TimePicker from '../time-picker/locale/nl_BE';
import Calendar from '../calendar/locale/nl_BE';
import { Locale } from '../locale-provider';
export default {
const localeValues: Locale = {
locale: 'nl-be',
Pagination,
DatePicker,
@ -41,3 +42,5 @@ export default {
description: 'Geen gegevens',
},
};
export default localeValues;

View File

@ -2,8 +2,9 @@ import Pagination from 'rc-pagination/lib/locale/nl_NL';
import DatePicker from '../date-picker/locale/nl_NL';
import TimePicker from '../time-picker/locale/nl_NL';
import Calendar from '../calendar/locale/nl_NL';
import { Locale } from '../locale-provider';
export default {
const localeValues: Locale = {
locale: 'nl',
Pagination,
DatePicker,
@ -60,3 +61,5 @@ export default {
back: 'Terug',
},
};
export default localeValues;

View File

@ -2,8 +2,9 @@ import Pagination from 'rc-pagination/lib/locale/pl_PL';
import DatePicker from '../date-picker/locale/pl_PL';
import TimePicker from '../time-picker/locale/pl_PL';
import Calendar from '../calendar/locale/pl_PL';
import { Locale } from '../locale-provider';
export default {
const localeValues: Locale = {
locale: 'pl',
Pagination,
DatePicker,
@ -41,3 +42,5 @@ export default {
description: 'Brak danych',
},
};
export default localeValues;

View File

@ -2,8 +2,9 @@ import Pagination from 'rc-pagination/lib/locale/pt_BR';
import DatePicker from '../date-picker/locale/pt_BR';
import TimePicker from '../time-picker/locale/pt_BR';
import Calendar from '../calendar/locale/pt_BR';
import { Locale } from '../locale-provider';
export default {
const localeValues: Locale = {
locale: 'pt-br',
Pagination,
DatePicker,
@ -47,3 +48,5 @@ export default {
expand: 'expandir',
},
};
export default localeValues;

View File

@ -2,8 +2,9 @@ import Pagination from 'rc-pagination/lib/locale/pt_PT';
import DatePicker from '../date-picker/locale/pt_PT';
import TimePicker from '../time-picker/locale/pt_PT';
import Calendar from '../calendar/locale/pt_PT';
import { Locale } from '../locale-provider';
export default {
const localeValues: Locale = {
locale: 'pt',
Pagination,
DatePicker,
@ -42,3 +43,5 @@ export default {
description: 'Sem resultados',
},
};
export default localeValues;

View File

@ -2,8 +2,9 @@ import Pagination from 'rc-pagination/lib/locale/ro_RO';
import DatePicker from '../date-picker/locale/ro_RO';
import TimePicker from '../time-picker/locale/ro_RO';
import Calendar from '../calendar/locale/ro_RO';
import { Locale } from '../locale-provider';
export default {
const localeValues: Locale = {
locale: 'ro',
Pagination,
DatePicker,
@ -60,3 +61,5 @@ export default {
back: 'înapoi',
},
};
export default localeValues;

View File

@ -2,8 +2,9 @@ import Pagination from 'rc-pagination/lib/locale/ru_RU';
import DatePicker from '../date-picker/locale/ru_RU';
import TimePicker from '../time-picker/locale/ru_RU';
import Calendar from '../calendar/locale/ru_RU';
import { Locale } from '../locale-provider';
export default {
const localeValues: Locale = {
locale: 'ru',
Pagination,
DatePicker,
@ -51,3 +52,5 @@ export default {
back: 'назад',
},
};
export default localeValues;

View File

@ -2,8 +2,9 @@ import Pagination from 'rc-pagination/lib/locale/sk_SK';
import DatePicker from '../date-picker/locale/sk_SK';
import TimePicker from '../time-picker/locale/sk_SK';
import Calendar from '../calendar/locale/sk_SK';
import { Locale } from '../locale-provider';
export default {
const localeValues: Locale = {
locale: 'sk',
Pagination,
DatePicker,
@ -60,3 +61,5 @@ export default {
back: 'Späť',
},
};
export default localeValues;

View File

@ -2,8 +2,9 @@ import Pagination from 'rc-pagination/lib/locale/sl_SI';
import DatePicker from '../date-picker/locale/sl_SI';
import TimePicker from '../time-picker/locale/sl_SI';
import Calendar from '../calendar/locale/sl_SI';
import { Locale } from '../locale-provider';
export default {
const localeValues: Locale = {
locale: 'sl',
Pagination,
DatePicker,
@ -41,3 +42,5 @@ export default {
description: 'Ni podatkov',
},
};
export default localeValues;

View File

@ -2,8 +2,9 @@ import Pagination from 'rc-pagination/lib/locale/sr_RS';
import DatePicker from '../date-picker/locale/sr_RS';
import TimePicker from '../time-picker/locale/sr_RS';
import Calendar from '../calendar/locale/sr_RS';
import { Locale } from '../locale-provider';
export default {
const localeValues: Locale = {
locale: 'sr',
Pagination,
DatePicker,
@ -41,3 +42,5 @@ export default {
description: 'Nema podataka',
},
};
export default localeValues;

View File

@ -2,8 +2,9 @@ import Pagination from 'rc-pagination/lib/locale/sv_SE';
import DatePicker from '../date-picker/locale/sv_SE';
import TimePicker from '../time-picker/locale/sv_SE';
import Calendar from '../calendar/locale/sv_SE';
import { Locale } from '../locale-provider';
export default {
const localeValues: Locale = {
locale: 'sv',
Pagination,
DatePicker,
@ -45,3 +46,5 @@ export default {
downloadFile: 'Nedladdning fil',
},
};
export default localeValues;

View File

@ -2,8 +2,9 @@ import Pagination from 'rc-pagination/lib/locale/ta_IN';
import DatePicker from '../date-picker/locale/ta_IN';
import TimePicker from '../time-picker/locale/ta_IN';
import Calendar from '../calendar/locale/ta_IN';
import { Locale } from '../locale-provider';
export default {
const localeValues: Locale = {
locale: 'ta',
Pagination,
DatePicker,
@ -61,3 +62,5 @@ export default {
back: 'பின் செல்லவும்',
},
};
export default localeValues;

View File

@ -2,8 +2,9 @@ import Pagination from 'rc-pagination/lib/locale/th_TH';
import DatePicker from '../date-picker/locale/th_TH';
import TimePicker from '../time-picker/locale/th_TH';
import Calendar from '../calendar/locale/th_TH';
import { Locale } from '../locale-provider';
export default {
const localeValues: Locale = {
locale: 'th',
Pagination,
DatePicker,
@ -60,3 +61,5 @@ export default {
back: 'ย้อนกลับ',
},
};
export default localeValues;

View File

@ -2,8 +2,9 @@ import Pagination from 'rc-pagination/lib/locale/tr_TR';
import DatePicker from '../date-picker/locale/tr_TR';
import TimePicker from '../time-picker/locale/tr_TR';
import Calendar from '../calendar/locale/tr_TR';
import { Locale } from '../locale-provider';
export default {
const localeValues: Locale = {
locale: 'tr',
Pagination,
DatePicker,
@ -55,3 +56,5 @@ export default {
expand: 'genişlet',
},
};
export default localeValues;

View File

@ -2,8 +2,9 @@ import Pagination from 'rc-pagination/lib/locale/uk_UA';
import DatePicker from '../date-picker/locale/uk_UA';
import TimePicker from '../time-picker/locale/uk_UA';
import Calendar from '../calendar/locale/uk_UA';
import { Locale } from '../locale-provider';
export default {
const localeValues: Locale = {
locale: 'uk',
Pagination,
DatePicker,
@ -41,3 +42,5 @@ export default {
description: 'Даних немає',
},
};
export default localeValues;

View File

@ -2,8 +2,9 @@ import Pagination from 'rc-pagination/lib/locale/vi_VN';
import DatePicker from '../date-picker/locale/vi_VN';
import TimePicker from '../time-picker/locale/vi_VN';
import Calendar from '../calendar/locale/vi_VN';
import { Locale } from '../locale-provider';
export default {
const localeValues: Locale = {
locale: 'vi',
Pagination,
DatePicker,
@ -41,3 +42,5 @@ export default {
description: 'Trống',
},
};
export default localeValues;

View File

@ -2,8 +2,9 @@ import Pagination from 'rc-pagination/lib/locale/zh_CN';
import DatePicker from '../date-picker/locale/zh_CN';
import TimePicker from '../time-picker/locale/zh_CN';
import Calendar from '../calendar/locale/zh_CN';
import { Locale } from '../locale-provider';
export default {
const localeValues: Locale = {
locale: 'zh-cn',
Pagination,
DatePicker,
@ -23,6 +24,9 @@ export default {
sortTitle: '排序',
expand: '展开行',
collapse: '关闭行',
triggerDesc: '点击降序',
triggerAsc: '点击升序',
cancelSort: '取消排序',
},
Modal: {
okText: '确定',
@ -61,3 +65,5 @@ export default {
back: '返回',
},
};
export default localeValues;

View File

@ -2,8 +2,9 @@ import Pagination from 'rc-pagination/lib/locale/zh_TW';
import DatePicker from '../date-picker/locale/zh_TW';
import TimePicker from '../time-picker/locale/zh_TW';
import Calendar from '../calendar/locale/zh_TW';
import { Locale } from '../locale-provider';
export default {
const localeValues: Locale = {
locale: 'zh-tw',
Pagination,
DatePicker,
@ -44,3 +45,5 @@ export default {
back: '返回',
},
};
export default localeValues;

View File

@ -7,7 +7,7 @@ export interface ModalLocale {
}
let runtimeLocale: ModalLocale = {
...defaultLocale.Modal,
...(defaultLocale.Modal as ModalLocale),
};
export function changeConfirmLocale(newLocale?: ModalLocale) {
@ -18,7 +18,7 @@ export function changeConfirmLocale(newLocale?: ModalLocale) {
};
} else {
runtimeLocale = {
...defaultLocale.Modal,
...(defaultLocale.Modal as ModalLocale),
};
}
}

View File

@ -7,6 +7,7 @@ import RightOutlined from '@ant-design/icons/RightOutlined';
import DoubleLeftOutlined from '@ant-design/icons/DoubleLeftOutlined';
import DoubleRightOutlined from '@ant-design/icons/DoubleRightOutlined';
import ResponsiveObserve from '../_util/responsiveObserve';
import MiniSelect from './MiniSelect';
import Select from '../select';
import LocaleReceiver from '../locale-provider/LocaleReceiver';
@ -26,7 +27,8 @@ export interface PaginationProps {
onShowSizeChange?: (current: number, size: number) => void;
showQuickJumper?: boolean | { goButton?: React.ReactNode };
showTotal?: (total: number, range: [number, number]) => React.ReactNode;
size?: string;
size?: 'default' | 'small';
responsive?: boolean;
simple?: boolean;
style?: React.CSSProperties;
locale?: Object;
@ -49,6 +51,26 @@ export interface PaginationConfig extends PaginationProps {
export type PaginationLocale = any;
export default class Pagination extends React.Component<PaginationProps, {}> {
private token: string;
private inferredSmall: boolean = false;
componentDidMount() {
this.token = ResponsiveObserve.subscribe(screens => {
const { xs } = screens;
const { size, responsive } = this.props;
const inferredSmall = !!(xs && !size && responsive);
if (this.inferredSmall !== inferredSmall) {
this.inferredSmall = inferredSmall;
this.forceUpdate();
}
});
}
componentWillUnmount() {
ResponsiveObserve.unsubscribe(this.token);
}
getIconsProps = (prefixCls: string, direction: 'ltr' | 'rtl' | undefined) => {
let prevIcon = (
<a className={`${prefixCls}-item-link`}>
@ -108,7 +130,7 @@ export default class Pagination extends React.Component<PaginationProps, {}> {
...restProps
} = this.props;
const locale = { ...contextLocale, ...customLocale };
const isSmall = size === 'small';
const isSmall = size === 'small' || this.inferredSmall;
return (
<ConfigConsumer>
{({ getPrefixCls, direction }: ConfigConsumerProps) => {

View File

@ -36,4 +36,14 @@ describe('Pagination', () => {
.props().disabled,
).toBe(true);
});
it('should autometically be small when size is not specified', async () => {
const wrapper = mount(<Pagination responsive />);
expect(
wrapper
.find('ul')
.at(0)
.hasClass('mini'),
).toBe(true);
});
});

View File

@ -34,7 +34,8 @@ A long list can be divided into several pages using `Pagination`, and only one p
| showTitle | Show page item's title | boolean | true | |
| showTotal | To display the total number and range | Function(total, range) | - | |
| simple | Whether to use simple mode | boolean | - | |
| size | Specify the size of `Pagination`, can be set to `small` | string | "" | |
| size | Specify the size of `Pagination`, can be set to `small`. | 'default' \| 'small'. | "" | |
| responsive | If `size` is not specified, `Pagination` would resize according to the width of the window | boolean | - | |
| total | Total number of data items | number | 0 | |
| onChange | Called when the page number is changed, and it takes the resulting page number and pageSize as its arguments | Function(page, pageSize) | noop | |
| onShowSizeChange | Called when `pageSize` is changed | Function(current, size) | noop | |

View File

@ -34,7 +34,8 @@ cols: 1
| showSizeChanger | 是否可以改变 pageSize | boolean | false | |
| showTotal | 用于显示数据总量和当前数据顺序 | Function(total, range) | - | |
| simple | 当添加该属性时,显示为简单分页 | boolean | - | |
| size | 当为「small」时是小尺寸分页 | string | "" | |
| size | 当为「small」时是小尺寸分页 | 'default' \| 'small' | "" | |
| responsive | 当 size 未指定时,根据屏幕宽度自动调整尺寸 | boolean | - | |
| total | 数据总数 | number | 0 | |
| onChange | 页码改变的回调,参数是改变后的页码及每页条数 | Function(page, pageSize) | noop | |
| onShowSizeChange | pageSize 变化的回调 | Function(current, size) | noop | |

View File

@ -2,6 +2,8 @@
exports[`Popconfirm rtl render component should be rendered correctly in RTL direction 1`] = `<span />`;
exports[`Popconfirm should show overlay when trigger is clicked 1`] = `"<div class=\\"ant-popover-content\\"><div class=\\"ant-popover-arrow\\"></div><div class=\\"ant-popover-inner\\" role=\\"tooltip\\"><div><div class=\\"ant-popover-inner-content\\"><div class=\\"ant-popover-message\\"><span role=\\"img\\" aria-label=\\"exclamation-circle\\" class=\\"anticon anticon-exclamation-circle\\"><svg viewBox=\\"64 64 896 896\\" focusable=\\"false\\" class=\\"\\" data-icon=\\"exclamation-circle\\" width=\\"1em\\" height=\\"1em\\" fill=\\"currentColor\\" aria-hidden=\\"true\\"><path d=\\"M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm-32 232c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v272c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8V296zm32 440a48.01 48.01 0 010-96 48.01 48.01 0 010 96z\\"></path></svg></span><div class=\\"ant-popover-message-title\\">code</div></div><div class=\\"ant-popover-buttons\\"><button type=\\"button\\" class=\\"ant-btn ant-btn-sm\\"><span>Cancel</span></button><button type=\\"button\\" class=\\"ant-btn ant-btn-primary ant-btn-sm\\"><span>OK</span></button></div></div></div></div></div>"`;
exports[`Popconfirm should show overlay when trigger is clicked 1`] = `"<div class=\\"ant-popover-content\\"><div class=\\"ant-popover-arrow\\"></div><div class=\\"ant-popover-inner\\" role=\\"tooltip\\"><div class=\\"ant-popover-inner-content\\"><div class=\\"ant-popover-message\\"><span role=\\"img\\" aria-label=\\"exclamation-circle\\" class=\\"anticon anticon-exclamation-circle\\"><svg viewBox=\\"64 64 896 896\\" focusable=\\"false\\" class=\\"\\" data-icon=\\"exclamation-circle\\" width=\\"1em\\" height=\\"1em\\" fill=\\"currentColor\\" aria-hidden=\\"true\\"><path d=\\"M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm-32 232c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v272c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8V296zm32 440a48.01 48.01 0 010-96 48.01 48.01 0 010 96z\\"></path></svg></span><div class=\\"ant-popover-message-title\\">code</div></div><div class=\\"ant-popover-buttons\\"><button type=\\"button\\" class=\\"ant-btn ant-btn-sm\\"><span>Cancel</span></button><button type=\\"button\\" class=\\"ant-btn ant-btn-primary ant-btn-sm\\"><span>OK</span></button></div></div></div></div>"`;
exports[`Popconfirm should show overlay when trigger is clicked 2`] = `"<div class=\\"ant-popover-content\\"><div class=\\"ant-popover-arrow\\"></div><div class=\\"ant-popover-inner\\" role=\\"tooltip\\"><div><div class=\\"ant-popover-inner-content\\"><div class=\\"ant-popover-message\\"><span role=\\"img\\" aria-label=\\"exclamation-circle\\" class=\\"anticon anticon-exclamation-circle\\"><svg viewBox=\\"64 64 896 896\\" focusable=\\"false\\" class=\\"\\" data-icon=\\"exclamation-circle\\" width=\\"1em\\" height=\\"1em\\" fill=\\"currentColor\\" aria-hidden=\\"true\\"><path d=\\"M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm-32 232c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v272c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8V296zm32 440a48.01 48.01 0 010-96 48.01 48.01 0 010 96z\\"></path></svg></span><div class=\\"ant-popover-message-title\\">code</div></div><div class=\\"ant-popover-buttons\\"><button type=\\"button\\" class=\\"ant-btn ant-btn-sm\\"><span>Cancel</span></button><button type=\\"button\\" class=\\"ant-btn ant-btn-primary ant-btn-sm\\"><span>OK</span></button></div></div></div></div></div>"`;
exports[`Popconfirm should show overlay when trigger is clicked 2`] = `"<div class=\\"ant-popover-content\\"><div class=\\"ant-popover-arrow\\"></div><div class=\\"ant-popover-inner\\" role=\\"tooltip\\"><div class=\\"ant-popover-inner-content\\"><div class=\\"ant-popover-message\\"><span role=\\"img\\" aria-label=\\"exclamation-circle\\" class=\\"anticon anticon-exclamation-circle\\"><svg viewBox=\\"64 64 896 896\\" focusable=\\"false\\" class=\\"\\" data-icon=\\"exclamation-circle\\" width=\\"1em\\" height=\\"1em\\" fill=\\"currentColor\\" aria-hidden=\\"true\\"><path d=\\"M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm-32 232c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v272c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8V296zm32 440a48.01 48.01 0 010-96 48.01 48.01 0 010 96z\\"></path></svg></span><div class=\\"ant-popover-message-title\\">code</div></div><div class=\\"ant-popover-buttons\\"><button type=\\"button\\" class=\\"ant-btn ant-btn-sm\\"><span>Cancel</span></button><button type=\\"button\\" class=\\"ant-btn ant-btn-primary ant-btn-sm\\"><span>OK</span></button></div></div></div></div>"`;
exports[`Popconfirm shows content for render functions 1`] = `"<div class=\\"ant-popover-content\\"><div class=\\"ant-popover-arrow\\"></div><div class=\\"ant-popover-inner\\" role=\\"tooltip\\"><div class=\\"ant-popover-inner-content\\"><div class=\\"ant-popover-message\\"><span role=\\"img\\" aria-label=\\"exclamation-circle\\" class=\\"anticon anticon-exclamation-circle\\"><svg viewBox=\\"64 64 896 896\\" focusable=\\"false\\" class=\\"\\" data-icon=\\"exclamation-circle\\" width=\\"1em\\" height=\\"1em\\" fill=\\"currentColor\\" aria-hidden=\\"true\\"><path d=\\"M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm-32 232c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v272c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8V296zm32 440a48.01 48.01 0 010-96 48.01 48.01 0 010 96z\\"></path></svg></span><div class=\\"ant-popover-message-title\\">some-title</div></div><div class=\\"ant-popover-buttons\\"><button type=\\"button\\" class=\\"ant-btn ant-btn-sm\\"><span>Cancel</span></button><button type=\\"button\\" class=\\"ant-btn ant-btn-primary ant-btn-sm\\"><span>OK</span></button></div></div></div></div>"`;

View File

@ -58,6 +58,26 @@ describe('Popconfirm', () => {
expect(popup.innerHTML).toMatchSnapshot();
});
it('shows content for render functions', async () => {
const makeRenderFunction = content => () => content;
const popconfirm = mount(
<Popconfirm title={makeRenderFunction('some-title')}>
<span>show me your code</span>
</Popconfirm>,
);
expect(popconfirm.instance().getPopupDomNode()).toBe(null);
popconfirm.find('span').simulate('click');
await sleep(100);
const popup = popconfirm.instance().getPopupDomNode();
expect(popup).not.toBe(null);
expect(popup.innerHTML).toContain('some-title');
expect(popup.innerHTML).toMatchSnapshot();
});
it('should be controlled by visible', () => {
jest.useFakeTimers();
const popconfirm = mount(

View File

@ -19,7 +19,7 @@ The difference with the `confirm` modal dialog is that it's more lightweight tha
| cancelText | text of the Cancel button | string | `Cancel` |
| okText | text of the Confirm button | string | `OK` |
| okType | Button `type` of the Confirm button | string | `primary` |
| title | title of the confirmation box | string\|ReactNode | - |
| title | title of the confirmation box | string\|ReactNode\|() => ReactNode | - |
| onCancel | callback of cancel | function(e) | - |
| onConfirm | callback of confirmation | function(e) | - |
| icon | customize icon of confirmation | ReactNode | `<ExclamationCircle />` |

View File

@ -1,15 +1,15 @@
import * as React from 'react';
import ExclamationCircleFilled from '@ant-design/icons/ExclamationCircleFilled';
import Tooltip, { AbstractTooltipProps } from '../tooltip';
import Button from '../button';
import { ButtonType, NativeButtonProps } from '../button/button';
import LocaleReceiver from '../locale-provider/LocaleReceiver';
import defaultLocale from '../locale/default';
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
import { getRenderPropValue, RenderFunction } from '../_util/getRenderPropValue';
export interface PopconfirmProps extends AbstractTooltipProps {
title: React.ReactNode;
title: React.ReactNode | RenderFunction;
disabled?: boolean;
onConfirm?: (e?: React.MouseEvent<HTMLElement>) => void;
onCancel?: (e?: React.MouseEvent<HTMLElement>) => void;
@ -118,20 +118,18 @@ class Popconfirm extends React.Component<PopconfirmProps, PopconfirmState> {
icon,
} = this.props;
return (
<div>
<div className={`${prefixCls}-inner-content`}>
<div className={`${prefixCls}-message`}>
{icon}
<div className={`${prefixCls}-message-title`}>{title}</div>
</div>
<div className={`${prefixCls}-buttons`}>
<Button onClick={this.onCancel} size="small" {...cancelButtonProps}>
{cancelText || popconfirmLocale.cancelText}
</Button>
<Button onClick={this.onConfirm} type={okType} size="small" {...okButtonProps}>
{okText || popconfirmLocale.okText}
</Button>
</div>
<div className={`${prefixCls}-inner-content`}>
<div className={`${prefixCls}-message`}>
{icon}
<div className={`${prefixCls}-message-title`}>{getRenderPropValue(title)}</div>
</div>
<div className={`${prefixCls}-buttons`}>
<Button onClick={this.onCancel} size="small" {...cancelButtonProps}>
{cancelText || popconfirmLocale.cancelText}
</Button>
<Button onClick={this.onConfirm} type={okType} size="small" {...okButtonProps}>
{okText || popconfirmLocale.okText}
</Button>
</div>
</div>
);

View File

@ -20,7 +20,7 @@ title: Popconfirm
| cancelText | 取消按钮文字 | string | 取消 |
| okText | 确认按钮文字 | string | 确定 |
| okType | 确认按钮类型 | string | primary |
| title | 确认框的描述 | string\|ReactNode | - |
| title | 确认框的描述 | string\|ReactNode\|() => ReactNode | - |
| onCancel | 点击取消的回调 | function(e) | - |
| onConfirm | 点击确认的回调 | function(e) | - |
| icon | 自定义弹出气泡 Icon 图标 | ReactNode | `<ExclamationCircle />` |

View File

@ -1,5 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Popover handles empty title/content props safely 1`] = `"<div class=\\"ant-popover-content\\"><div class=\\"ant-popover-arrow\\"></div><div class=\\"ant-popover-inner\\" role=\\"tooltip\\"><div class=\\"ant-popover-inner-content\\"></div></div></div>"`;
exports[`Popover should be rendered correctly in RTL direction 1`] = `
Array [
<span
@ -22,16 +24,14 @@ Array [
class="ant-popover-inner"
role="tooltip"
>
<div>
<div
class="ant-popover-title"
>
RTL
</div>
<div
class="ant-popover-inner-content"
/>
<div
class="ant-popover-title"
>
RTL
</div>
<div
class="ant-popover-inner-content"
/>
</div>
</div>
</div>
@ -39,6 +39,6 @@ Array [
]
`;
exports[`Popover should show overlay when trigger is clicked 1`] = `"<div class=\\"ant-popover-content\\"><div class=\\"ant-popover-arrow\\"></div><div class=\\"ant-popover-inner\\" role=\\"tooltip\\"><div><div class=\\"ant-popover-title\\">code</div><div class=\\"ant-popover-inner-content\\">console.log('hello world')</div></div></div></div>"`;
exports[`Popover should show overlay when trigger is clicked 1`] = `"<div class=\\"ant-popover-content\\"><div class=\\"ant-popover-arrow\\"></div><div class=\\"ant-popover-inner\\" role=\\"tooltip\\"><div class=\\"ant-popover-title\\">code</div><div class=\\"ant-popover-inner-content\\">console.log('hello world')</div></div></div>"`;
exports[`Popover should show overlay when trigger is clicked 2`] = `"<div class=\\"ant-popover-content\\"><div class=\\"ant-popover-arrow\\"></div><div class=\\"ant-popover-inner\\" role=\\"tooltip\\"><div><div class=\\"ant-popover-title\\">code</div><div class=\\"ant-popover-inner-content\\">console.log('hello world')</div></div></div></div>"`;
exports[`Popover shows content for render functions 1`] = `"<div class=\\"ant-popover-content\\"><div class=\\"ant-popover-arrow\\"></div><div class=\\"ant-popover-inner\\" role=\\"tooltip\\"><div class=\\"ant-popover-title\\">some-title</div><div class=\\"ant-popover-inner-content\\">some-content</div></div></div>"`;

View File

@ -24,6 +24,38 @@ describe('Popover', () => {
expect(popup).not.toBe(null);
expect(popup.className).toContain('ant-popover-placement-top');
expect(popup.innerHTML).toMatchSnapshot();
});
it('shows content for render functions', () => {
const renderTitle = () => 'some-title';
const renderContent = () => 'some-content';
const popover = mount(
<Popover content={renderContent} title={renderTitle} trigger="click">
<span>show me your code</span>
</Popover>,
);
popover.find('span').simulate('click');
const popup = popover.instance().getPopupDomNode();
expect(popup).not.toBe(null);
expect(popup.innerHTML).toContain('some-title');
expect(popup.innerHTML).toContain('some-content');
expect(popup.innerHTML).toMatchSnapshot();
});
it('handles empty title/content props safely', () => {
const popover = mount(
<Popover trigger="click">
<span>show me your code</span>
</Popover>,
);
popover.find('span').simulate('click');
const popup = popover.instance().getPopupDomNode();
expect(popup).not.toBe(null);
expect(popup.innerHTML).toMatchSnapshot();
});

View File

@ -14,10 +14,10 @@ Comparing with `Tooltip`, besides information `Popover` card can also provide ac
## API
| Param | Description | Type | Default value | Version |
| ------- | ------------------- | ----------------- | ------------- | ------- |
| content | Content of the card | string\|ReactNode | - | |
| title | Title of the card | string\|ReactNode | - | |
| Param | Description | Type | Default value | Version |
| ------- | ------------------- | ---------------------------------- | ------------- | ------- |
| content | Content of the card | string\|ReactNode\|() => ReactNode | - | |
| title | Title of the card | string\|ReactNode\|() => ReactNode | - | |
Consult [Tooltip's documentation](https://ant.design/components/tooltip/#API) to find more APIs.

View File

@ -1,10 +1,11 @@
import * as React from 'react';
import Tooltip, { AbstractTooltipProps, TooltipPlacement } from '../tooltip';
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
import { getRenderPropValue, RenderFunction } from '../_util/getRenderPropValue';
export interface PopoverProps extends AbstractTooltipProps {
title?: React.ReactNode;
content?: React.ReactNode;
title?: React.ReactNode | RenderFunction;
content?: React.ReactNode | RenderFunction;
}
export default class Popover extends React.Component<PopoverProps, {}> {
@ -26,10 +27,10 @@ export default class Popover extends React.Component<PopoverProps, {}> {
getOverlay(prefixCls: string) {
const { title, content } = this.props;
return (
<div>
{title && <div className={`${prefixCls}-title`}>{title}</div>}
<div className={`${prefixCls}-inner-content`}>{content}</div>
</div>
<>
{title && <div className={`${prefixCls}-title`}>{getRenderPropValue(title)}</div>}
<div className={`${prefixCls}-inner-content`}>{getRenderPropValue(content)}</div>
</>
);
}

View File

@ -15,10 +15,10 @@ title: Popover
## API
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| ------- | -------- | ----------------- | ------ | ---- |
| content | 卡片内容 | string\|ReactNode | 无 | |
| title | 卡片标题 | string\|ReactNode | 无 | |
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| ------- | -------- | ---------------------------------- | ------ | ---- |
| content | 卡片内容 | string\|ReactNode\|() => ReactNode | 无 | |
| title | 卡片标题 | string\|ReactNode\|() => ReactNode | 无 | |
更多属性请参考 [Tooltip](/components/tooltip/#API)。

View File

@ -30,7 +30,7 @@ Select component to select value from options.
| defaultValue | Initial selected option. | string\|string\[]<br />number\|number\[]<br />LabeledValue\|LabeledValue[] | - | |
| disabled | Whether disabled select | boolean | false | |
| dropdownClassName | className of dropdown menu | string | - | |
| dropdownMatchSelectWidth | Whether dropdown's width is same with select. | boolean | true | |
| dropdownMatchSelectWidth | Determine whether the dropdown menu and the select input are the same width. Default set `min-width` same as input. `false` will disable virtual scroll | boolean \| number | true | |
| dropdownRender | Customize dropdown content | (menuNode: ReactNode, props) => ReactNode | - | |
| dropdownStyle | style of dropdown menu | object | - | |
| dropdownMenuStyle | additional style applied to dropdown menu | object | - | |
@ -56,6 +56,7 @@ Select component to select value from options.
| menuItemSelectedIcon | The custom menuItemSelected icon with multiple options | ReactNode | - | |
| tokenSeparators | Separator used to tokenize on tag/multiple mode | string\[] | | |
| value | Current selected option. | string\|string\[]\<br />number\|number\[]\<br />LabeledValue\|LabeledValue[] | - | |
| virtual | Disable virtual scroll when set to `false` | boolean | - | 4.1.0 |
| onBlur | Called when blur | function | - | |
| onChange | Called when select an option or input value change, or value of input is changed in combobox mode | function(value, option:Option/Array&lt;Option>) | - | |
| onDeselect | Called when a option is deselected, param is the selected option's value. Only called for multiple or tags, effective in multiple or tags mode only. | function(string\|number\|LabeledValue) | - | |
@ -81,12 +82,12 @@ Select component to select value from options.
### Option props
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| disabled | Disable this option | boolean | false | |
| title | `title` of Select after select this Option | string | - | |
| value | default to filter with this property | string\|number | - | |
| className | additional class to option | string | - | |
| Property | Description | Type | Default | Version |
| --------- | ------------------------------------------ | -------------- | ------- | ------- |
| disabled | Disable this option | boolean | false | |
| title | `title` of Select after select this Option | string | - | |
| value | default to filter with this property | string\|number | - | |
| className | additional class to option | string | - | |
### OptGroup props

View File

@ -31,7 +31,7 @@ title: Select
| defaultValue | 指定默认选中的条目 | string\|string\[]\<br />number\|number\[]\<br />LabeledValue\|LabeledValue[] | - | |
| disabled | 是否禁用 | boolean | false | |
| dropdownClassName | 下拉菜单的 className 属性 | string | - | |
| dropdownMatchSelectWidth | 下拉菜单和选择器同宽 | boolean | true | |
| dropdownMatchSelectWidth | 下拉菜单和选择器同宽。默认将设置 `min-width`。`false` 时会关闭虚拟滚动 | boolean \| number | true | |
| dropdownRender | 自定义下拉框内容 | (menuNode: ReactNode, props) => ReactNode | - | |
| dropdownStyle | 下拉菜单的 style 属性 | object | - | |
| dropdownMenuStyle | dropdown 菜单自定义样式 | object | - | |
@ -57,6 +57,7 @@ title: Select
| menuItemSelectedIcon | 自定义多选时当前选中的条目图标 | ReactNode | - | |
| tokenSeparators | 在 tags 和 multiple 模式下自动分词的分隔符 | string\[] | | |
| value | 指定当前选中的条目 | string\|string\[]\<br />number\|number\[]\<br />LabeledValue\|LabeledValue[] | - | |
| virtual | 设置 `false` 时关闭虚拟滚动 | boolean | - | 4.1.0 |
| onBlur | 失去焦点时回调 | function | - | |
| onChange | 选中 option或 input 的 value 变化combobox 模式下)时,调用此函数 | function(value, option:Option/Array&lt;Option>) | - | |
| onDeselect | 取消选中时调用,参数为选中项的 value (或 key) 值,仅在 multiple 或 tags 模式下生效 | function(string\|number\|LabeledValue) | - | |
@ -84,12 +85,12 @@ title: Select
### Option props
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| disabled | 是否禁用 | boolean | false | |
| title | 选中该 Option 后Select 的 title | string | - | |
| value | 默认根据此属性值进行筛选 | string\|number | - | |
| className | Option 器类名 | string | - | |
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --------- | --------------------------------- | -------------- | ------ | ---- |
| disabled | 是否禁用 | boolean | false | |
| title | 选中该 Option 后Select 的 title | string | - | |
| value | 默认根据此属性值进行筛选 | string\|number | - | |
| className | Option 器类名 | string | - | |
### OptGroup props

View File

@ -79,6 +79,7 @@ export interface TableProps<RecordType>
scrollToFirstRowOnChange?: boolean;
};
sortDirections?: SortOrder[];
showSorterTooltip?: boolean;
}
function Table<RecordType extends object = any>(props: TableProps<RecordType>) {
@ -108,6 +109,7 @@ function Table<RecordType extends object = any>(props: TableProps<RecordType>) {
scroll,
sortDirections,
locale,
showSorterTooltip = true,
} = props;
const tableProps = omit(props, ['className', 'style']) as TableProps<RecordType>;
@ -214,13 +216,14 @@ function Table<RecordType extends object = any>(props: TableProps<RecordType>) {
false,
);
};
const [transformSorterColumns, sortStates, sorterTitleProps, getSorters] = useSorter<RecordType>({
prefixCls,
columns,
children,
onSorterChange,
sortDirections: sortDirections || ['ascend', 'descend'],
tableLocale,
showSorterTooltip,
});
const sortedData = React.useMemo(() => getSortData(rawData, sortStates, childrenColumnName), [
rawData,

View File

@ -10,6 +10,15 @@ import ConfigProvider from '../../config-provider';
// https://github.com/Semantic-Org/Semantic-UI-React/blob/72c45080e4f20b531fda2e3e430e384083d6766b/test/specs/modules/Dropdown/Dropdown-test.js#L73
const nativeEvent = { nativeEvent: { stopImmediatePropagation: () => {} } };
function getDropdownWrapper(wrapper) {
return mount(
wrapper
.find('Trigger')
.instance()
.getComponent(),
);
}
describe('Table.filter', () => {
const filterFn = (value, record) => record.name.indexOf(value) !== -1;
const column = {
@ -235,7 +244,7 @@ describe('Table.filter', () => {
.simulate('click');
wrapper
.find('FilterDropdown')
.find('.confirm')
.find('.ant-table-filter-dropdown-btns .ant-btn-primary')
.simulate('click');
expect(wrapper.find('FilterDropdown').props().filterState.filteredKeys).toEqual(['boy']);
wrapper.setProps({ dataSource: [...data, { key: 999, name: 'Chris' }] });
@ -379,7 +388,7 @@ describe('Table.filter', () => {
.simulate('click');
wrapper
.find('FilterDropdown')
.find('.confirm')
.find('.ant-table-filter-dropdown-btns .ant-btn-primary')
.simulate('click');
expect(handleChange).toHaveBeenCalledWith(
@ -400,75 +409,73 @@ describe('Table.filter', () => {
.find('.ant-dropdown-trigger')
.first()
.simulate('click');
wrapper.find('.clear').simulate('click');
wrapper.find('.ant-table-filter-dropdown-btns .ant-btn-link').simulate('click');
expect(handleChange).not.toHaveBeenCalled();
});
// enzyme not correct update function component under mini store.
// It's correct in `instance().props` but failed in `props()`
// it.skip('three levels menu', () => {
// const filters = [
// { text: 'Upper', value: 'Upper' },
// { text: 'Lower', value: 'Lower' },
// {
// text: 'Level2',
// value: 'Level2',
// children: [
// { text: 'Large', value: 'Large' },
// { text: 'Small', value: 'Small' },
// {
// text: 'Level3',
// value: 'Level3',
// children: [
// { text: 'Black', value: 'Black' },
// { text: 'White', value: 'White' },
// { text: 'Jack', value: 'Jack' },
// ],
// },
// ],
// },
// ];
// const wrapper = mount(
// createTable({
// columns: [
// {
// ...column,
// filters,
// },
// ],
// }),
// );
// jest.useFakeTimers();
// const dropdownWrapper = getDropdownWrapper(wrapper);
// expect(renderedNames(wrapper)).toEqual(['Jack', 'Lucy', 'Tom', 'Jerry']);
it('three levels menu', () => {
const filters = [
{ text: 'Upper', value: 'Upper' },
{ text: 'Lower', value: 'Lower' },
{
text: 'Level2',
value: 'Level2',
children: [
{ text: 'Large', value: 'Large' },
{ text: 'Small', value: 'Small' },
{
text: 'Level3',
value: 'Level3',
children: [
{ text: 'Black', value: 'Black' },
{ text: 'White', value: 'White' },
{ text: 'Jack', value: 'Jack' },
],
},
],
},
];
const wrapper = mount(
createTable({
columns: [
{
...column,
filters,
},
],
}),
);
jest.useFakeTimers();
// // select
// dropdownWrapper
// .find('.ant-dropdown-menu-submenu-title')
// .at(0)
// .simulate('mouseEnter');
// jest.runAllTimers();
// dropdownWrapper.update();
// dropdownWrapper
// .find('.ant-dropdown-menu-submenu-title')
// .at(1)
// .simulate('mouseEnter');
// jest.runAllTimers();
// dropdownWrapper.update();
// dropdownWrapper
// .find('MenuItem')
// .last()
// .simulate('click');
// dropdownWrapper.find('.confirm').simulate('click');
// wrapper.update();
// expect(renderedNames(wrapper)).toEqual(['Jack']);
// dropdownWrapper
// .find('MenuItem')
// .last()
// .simulate('click');
// jest.useRealTimers();
// });
let dropdownWrapper = getDropdownWrapper(wrapper);
expect(renderedNames(wrapper)).toEqual(['Jack', 'Lucy', 'Tom', 'Jerry']);
// select
dropdownWrapper
.find('.ant-dropdown-menu-submenu-title')
.at(0)
.simulate('mouseEnter');
jest.runAllTimers();
dropdownWrapper = getDropdownWrapper(wrapper);
dropdownWrapper
.find('.ant-dropdown-menu-submenu-title')
.at(1)
.simulate('mouseEnter');
jest.runAllTimers();
dropdownWrapper = getDropdownWrapper(wrapper);
dropdownWrapper
.find('MenuItem')
.last()
.simulate('click');
dropdownWrapper.find('.ant-table-filter-dropdown-btns .ant-btn-primary').simulate('click');
wrapper.update();
expect(renderedNames(wrapper)).toEqual(['Jack']);
dropdownWrapper
.find('MenuItem')
.last()
.simulate('click');
jest.useRealTimers();
});
describe('should support value types', () => {
[
@ -501,7 +508,7 @@ describe('Table.filter', () => {
.first()
.simulate('click');
// This test can be remove if refactor
wrapper.find('.confirm').simulate('click');
wrapper.find('.ant-table-filter-dropdown-btns .ant-btn-primary').simulate('click');
wrapper.update();
expect(
@ -581,11 +588,11 @@ describe('Table.filter', () => {
.find('MenuItem')
.first()
.simulate('click');
wrapper.find('.confirm').simulate('click');
wrapper.find('.ant-table-filter-dropdown-btns .ant-btn-primary').simulate('click');
wrapper.update();
expect(renderedNames(wrapper)).toEqual(['Jack']);
wrapper.find('.clear').simulate('click');
wrapper.find('.ant-table-filter-dropdown-btns .ant-btn-link').simulate('click');
wrapper.update();
expect(renderedNames(wrapper)).toEqual(['Jack', 'Lucy', 'Tom', 'Jerry']);
});
@ -872,7 +879,7 @@ describe('Table.filter', () => {
.find('MenuItem')
.first()
.simulate('click');
wrapper.find('.confirm').simulate('click');
wrapper.find('.ant-table-filter-dropdown-btns .ant-btn-primary').simulate('click');
expect(onChange).toHaveBeenCalled();
onChange.mockReset();
expect(onChange).not.toHaveBeenCalled();
@ -890,7 +897,7 @@ describe('Table.filter', () => {
.find('MenuItem')
.first()
.simulate('click');
wrapper.find('.confirm').simulate('click');
wrapper.find('.ant-table-filter-dropdown-btns .ant-btn-primary').simulate('click');
expect(onChange).toHaveBeenCalled();
});
@ -1025,7 +1032,7 @@ describe('Table.filter', () => {
.find('MenuItem')
.first()
.simulate('click');
wrapper.find('.confirm').simulate('click');
wrapper.find('.ant-table-filter-dropdown-btns .ant-btn-primary').simulate('click');
expect(handleChange).toHaveBeenCalledWith(
{
@ -1062,7 +1069,7 @@ describe('Table.filter', () => {
.find('MenuItem')
.first()
.simulate('click');
wrapper.find('.confirm').simulate('click');
wrapper.find('.ant-table-filter-dropdown-btns .ant-btn-primary').simulate('click');
expect(handleChange).toHaveBeenCalledWith(
{
@ -1155,7 +1162,7 @@ describe('Table.filter', () => {
.find('.ant-dropdown-menu-item')
.first()
.simulate('click');
wrapper.find('.ant-table-filter-dropdown-link.confirm').simulate('click');
wrapper.find('.ant-table-filter-dropdown-btns .ant-btn-primary').simulate('click');
expect(onChange).toHaveBeenCalledWith(
expect.anything(),
{
@ -1185,15 +1192,12 @@ describe('Table.filter', () => {
}),
);
expect(wrapper.find('.ant-table-filter-dropdown-btns .ant-btn-primary').text()).toEqual(
'Bamboo',
);
expect(
wrapper
.find('.ant-table-filter-dropdown-link')
.first()
.text(),
).toEqual('Bamboo');
expect(
wrapper
.find('.ant-table-filter-dropdown-link')
.find('.ant-table-filter-dropdown-btns .ant-btn-link')
.last()
.text(),
).toEqual('Reset');

View File

@ -638,7 +638,7 @@ describe('Table.rowSelection', () => {
.simulate('click');
});
wrapper
.find('.ant-table-filter-dropdown-btns .ant-table-filter-dropdown-link.confirm')
.find('.ant-table-filter-dropdown-btns .ant-btn-primary')
.simulate('click');
}

View File

@ -150,6 +150,45 @@ describe('Table.sorter', () => {
expect(sorter3.columnKey).toBe('name');
});
it('hover header show sorter tooltip', () => {
// tooltip has delay
jest.useFakeTimers();
const wrapper = mount(createTable({}));
// default show sorter tooltip
wrapper.find('.ant-table-column-sorters').simulate('mouseenter');
jest.runAllTimers();
wrapper.update();
expect(wrapper.find('.ant-tooltip-open').length).toBeTruthy();
wrapper.find('.ant-table-column-sorters').simulate('mouseout');
// set table props showSorterTooltip is false
wrapper.setProps({ showSorterTooltip: false });
wrapper.find('.ant-table-column-sorters').simulate('mouseenter');
jest.runAllTimers();
wrapper.update();
expect(wrapper.find('.ant-tooltip-open').length).toBeFalsy();
wrapper.find('.ant-table-column-sorters').simulate('mouseout');
// set table props showSorterTooltip is false, column showSorterTooltip is true
wrapper.setProps({
showSorterTooltip: false,
columns: [{ ...column, showSorterTooltip: true }],
});
wrapper.find('.ant-table-column-sorters').simulate('mouseenter');
jest.runAllTimers();
wrapper.update();
expect(wrapper.find('.ant-tooltip-open').length).toBeTruthy();
wrapper.find('.ant-table-column-sorters').simulate('mouseout');
// set table props showSorterTooltip is true, column showSorterTooltip is false
wrapper.setProps({
showSorterTooltip: true,
columns: [{ ...column, showSorterTooltip: false }],
});
wrapper.find('.ant-table-column-sorters').simulate('mouseenter');
jest.runAllTimers();
wrapper.update();
expect(wrapper.find('.ant-tooltip-open').length).toBeFalsy();
wrapper.find('.ant-table-column-sorters').simulate('mouseout');
});
it('works with grouping columns in controlled mode', () => {
const columns = [
{

View File

@ -508,16 +508,23 @@ exports[`Table.filter renders menu correctly 1`] = `
<div
class="ant-table-filter-dropdown-btns"
>
<a
class="ant-table-filter-dropdown-link confirm"
<button
class="ant-btn ant-btn-link ant-btn-sm"
disabled=""
type="button"
>
OK
</a>
<a
class="ant-table-filter-dropdown-link clear"
<span>
Reset
</span>
</button>
<button
class="ant-btn ant-btn-primary ant-btn-sm"
type="button"
>
Reset
</a>
<span>
OK
</span>
</button>
</div>
</div>
</div>
@ -605,16 +612,23 @@ exports[`Table.filter renders radio filter correctly 1`] = `
<div
class="ant-table-filter-dropdown-btns"
>
<a
class="ant-table-filter-dropdown-link confirm"
<button
class="ant-btn ant-btn-link ant-btn-sm"
disabled=""
type="button"
>
OK
</a>
<a
class="ant-table-filter-dropdown-link clear"
<span>
Reset
</span>
</button>
<button
class="ant-btn ant-btn-primary ant-btn-sm"
type="button"
>
Reset
</a>
<span>
OK
</span>
</button>
</div>
</div>
</div>
@ -769,16 +783,23 @@ exports[`Table.filter should support getPopupContainer 1`] = `
<div
class="ant-table-filter-dropdown-btns"
>
<a
class="ant-table-filter-dropdown-link confirm"
<button
class="ant-btn ant-btn-link ant-btn-sm"
disabled=""
type="button"
>
OK
</a>
<a
class="ant-table-filter-dropdown-link clear"
<span>
Reset
</span>
</button>
<button
class="ant-btn ant-btn-primary ant-btn-sm"
type="button"
>
Reset
</a>
<span>
OK
</span>
</button>
</div>
</div>
</div>
@ -995,16 +1016,23 @@ exports[`Table.filter should support getPopupContainer from ConfigProvider 1`] =
<div
class="ant-table-filter-dropdown-btns"
>
<a
class="ant-table-filter-dropdown-link confirm"
<button
class="ant-btn ant-btn-link ant-btn-sm"
disabled=""
type="button"
>
OK
</a>
<a
class="ant-table-filter-dropdown-link clear"
<span>
Reset
</span>
</button>
<button
class="ant-btn ant-btn-primary ant-btn-sm"
type="button"
>
Reset
</a>
<span>
OK
</span>
</button>
</div>
</div>
</div>

View File

@ -12217,6 +12217,396 @@ exports[`renders ./components/table/demo/row-selection-custom.md correctly 1`] =
</div>
`;
exports[`renders ./components/table/demo/row-selection-custom-debug.md correctly 1`] = `
<div
class="ant-table-wrapper"
>
<div
class="ant-spin-nested-loading"
>
<div
class="ant-spin-container"
>
<div
class="ant-table"
>
<div
class="ant-table-container"
>
<div
class="ant-table-content"
>
<table
style="table-layout:auto"
>
<colgroup>
<col
style="width:60px;min-width:60px"
/>
<col />
</colgroup>
<thead>
<tr>
<th
class="ant-table-cell ant-table-selection-column"
>
<div
class="ant-table-selection"
>
<label
class="ant-checkbox-wrapper"
>
<span
class="ant-checkbox"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
</div>
</th>
<th
class="ant-table-cell"
>
Name
</th>
</tr>
</thead>
<tbody
class="ant-table-tbody"
>
<tr
class="ant-table-row ant-table-row-level-0"
data-row-key="0"
>
<td
class="ant-table-cell ant-table-selection-column"
rowspan="2"
>
false:
<label
class="ant-checkbox-wrapper"
>
<span
class="ant-checkbox"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
</td>
<td
class="ant-table-cell"
>
Edward King 0
</td>
</tr>
<tr
class="ant-table-row ant-table-row-level-0"
data-row-key="1"
>
<td
class="ant-table-cell"
>
Another Row
</td>
</tr>
<tr
class="ant-table-row ant-table-row-level-0"
data-row-key="2"
>
<td
class="ant-table-cell ant-table-selection-column"
rowspan="2"
>
false:
<label
class="ant-checkbox-wrapper"
>
<span
class="ant-checkbox"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
</td>
<td
class="ant-table-cell"
>
Edward King 2
</td>
</tr>
<tr
class="ant-table-row ant-table-row-level-0"
data-row-key="3"
>
<td
class="ant-table-cell"
>
Another Row
</td>
</tr>
<tr
class="ant-table-row ant-table-row-level-0"
data-row-key="4"
>
<td
class="ant-table-cell ant-table-selection-column"
rowspan="2"
>
false:
<label
class="ant-checkbox-wrapper"
>
<span
class="ant-checkbox"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
</td>
<td
class="ant-table-cell"
>
Edward King 4
</td>
</tr>
<tr
class="ant-table-row ant-table-row-level-0"
data-row-key="5"
>
<td
class="ant-table-cell"
>
Another Row
</td>
</tr>
<tr
class="ant-table-row ant-table-row-level-0"
data-row-key="6"
>
<td
class="ant-table-cell ant-table-selection-column"
rowspan="2"
>
false:
<label
class="ant-checkbox-wrapper"
>
<span
class="ant-checkbox"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
</td>
<td
class="ant-table-cell"
>
Edward King 6
</td>
</tr>
<tr
class="ant-table-row ant-table-row-level-0"
data-row-key="7"
>
<td
class="ant-table-cell"
>
Another Row
</td>
</tr>
<tr
class="ant-table-row ant-table-row-level-0"
data-row-key="8"
>
<td
class="ant-table-cell ant-table-selection-column"
rowspan="2"
>
false:
<label
class="ant-checkbox-wrapper"
>
<span
class="ant-checkbox"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
</td>
<td
class="ant-table-cell"
>
Edward King 8
</td>
</tr>
<tr
class="ant-table-row ant-table-row-level-0"
data-row-key="9"
>
<td
class="ant-table-cell"
>
Another Row
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<ul
class="ant-pagination ant-table-pagination"
unselectable="unselectable"
>
<li
aria-disabled="true"
class="ant-pagination-prev ant-pagination-disabled"
title="Previous Page"
>
<a
class="ant-pagination-item-link"
disabled=""
>
<span
aria-label="left"
class="anticon anticon-left"
role="img"
>
<svg
aria-hidden="true"
class=""
data-icon="left"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M724 218.3V141c0-6.7-7.7-10.4-12.9-6.3L260.3 486.8a31.86 31.86 0 000 50.3l450.8 352.1c5.3 4.1 12.9.4 12.9-6.3v-77.3c0-4.9-2.3-9.6-6.1-12.6l-360-281 360-281.1c3.8-3 6.1-7.7 6.1-12.6z"
/>
</svg>
</span>
</a>
</li>
<li
class="ant-pagination-item ant-pagination-item-1 ant-pagination-item-active"
tabindex="0"
title="1"
>
<a>
1
</a>
</li>
<li
class="ant-pagination-item ant-pagination-item-2"
tabindex="0"
title="2"
>
<a>
2
</a>
</li>
<li
class="ant-pagination-item ant-pagination-item-3"
tabindex="0"
title="3"
>
<a>
3
</a>
</li>
<li
class="ant-pagination-item ant-pagination-item-4"
tabindex="0"
title="4"
>
<a>
4
</a>
</li>
<li
class="ant-pagination-item ant-pagination-item-5"
tabindex="0"
title="5"
>
<a>
5
</a>
</li>
<li
aria-disabled="false"
class="ant-pagination-next"
tabindex="0"
title="Next Page"
>
<a
class="ant-pagination-item-link"
>
<span
aria-label="right"
class="anticon anticon-right"
role="img"
>
<svg
aria-hidden="true"
class=""
data-icon="right"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z"
/>
</svg>
</span>
</a>
</li>
</ul>
</div>
</div>
</div>
`;
exports[`renders ./components/table/demo/size.md correctly 1`] = `
<div>
<h4>

View File

@ -0,0 +1,50 @@
---
order: 99
title:
en-US: Custom selection group
zh-CN: 自定义选择项组
debug: true
---
## zh-CN
自定义选项分组。
## en-US
Customize selection group.
```jsx
import { Table } from 'antd';
const columns = [
{
title: 'Name',
dataIndex: 'name',
},
];
const data = [];
for (let i = 0; i < 46; i++) {
data.push({
key: i,
name: i % 2 === 0 ? `Edward King ${i}` : 'Another Row',
});
}
const App = () => {
const rowSelection = {
renderCell: (checked, record, index, node) => ({
props: { rowSpan: index % 2 === 0 ? 2 : 0 },
children: (
<>
{String(checked)}: {node}
</>
),
}),
};
return <Table rowSelection={rowSelection} columns={columns} dataSource={data} />;
};
ReactDOM.render(<App />, mountNode);
```

View File

@ -1,6 +1,7 @@
import * as React from 'react';
import classNames from 'classnames';
import FilterFilled from '@ant-design/icons/FilterFilled';
import Button from '../../../button';
import Menu from '../../../menu';
import Checkbox from '../../../checkbox';
import Radio from '../../../radio';
@ -173,6 +174,7 @@ function FilterDropdown<RecordType>(props: FilterDropdownProps<RecordType>) {
} else if (column.filterDropdown) {
dropdownContent = column.filterDropdown;
} else {
const selectedKeys = (getFilteredKeysSync() || []) as any;
dropdownContent = (
<>
<Menu
@ -182,7 +184,7 @@ function FilterDropdown<RecordType>(props: FilterDropdownProps<RecordType>) {
onClick={onMenuClick}
onSelect={onSelectKeys}
onDeselect={onSelectKeys}
selectedKeys={(getFilteredKeysSync() || []) as any}
selectedKeys={selectedKeys}
getPopupContainer={getPopupContainer}
openKeys={openKeys}
onOpenChange={onOpenChange}
@ -190,12 +192,12 @@ function FilterDropdown<RecordType>(props: FilterDropdownProps<RecordType>) {
{renderFilterItems(column.filters || [], prefixCls, getFilteredKeysSync(), filterMultiple)}
</Menu>
<div className={`${prefixCls}-dropdown-btns`}>
<a className={`${prefixCls}-dropdown-link confirm`} onClick={onConfirm}>
{locale.filterConfirm}
</a>
<a className={`${prefixCls}-dropdown-link clear`} onClick={onReset}>
<Button type="link" size="small" disabled={selectedKeys.length === 0} onClick={onReset}>
{locale.filterReset}
</a>
</Button>
<Button type="primary" size="small" onClick={onConfirm}>
{locale.filterConfirm}
</Button>
</div>
</>
);

View File

@ -76,6 +76,7 @@ export default function useSelection<RecordType>(
type: selectionType,
selections,
fixed,
renderCell: customizeRenderCell,
} = rowSelection || {};
const {
@ -305,111 +306,132 @@ export default function useSelection<RecordType>(
}
// Body Cell
let renderCell: (_: RecordType, record: RecordType, index: number) => React.ReactNode;
let renderCell: (
_: RecordType,
record: RecordType,
index: number,
) => { node: React.ReactNode; checked: boolean };
if (selectionType === 'radio') {
renderCell = (_, record, index) => {
const key = getRowKey(record, index);
const checked = keySet.has(key);
return (
<Radio
{...checkboxPropsMap.get(key)}
checked={keySet.has(key)}
onChange={event => {
if (!keySet.has(key)) {
triggerSingleSelection(key, true, [key], event.nativeEvent);
}
}}
/>
);
return {
node: (
<Radio
{...checkboxPropsMap.get(key)}
checked={checked}
onChange={event => {
if (!keySet.has(key)) {
triggerSingleSelection(key, true, [key], event.nativeEvent);
}
}}
/>
),
checked,
};
};
} else {
renderCell = (_, record, index) => {
const key = getRowKey(record, index);
const hasKey = keySet.has(key);
const checked = keySet.has(key);
// Record checked
return (
<Checkbox
{...checkboxPropsMap.get(key)}
checked={hasKey}
onChange={({ nativeEvent }) => {
const { shiftKey } = nativeEvent;
return {
node: (
<Checkbox
{...checkboxPropsMap.get(key)}
checked={checked}
onChange={({ nativeEvent }) => {
const { shiftKey } = nativeEvent;
let startIndex: number = -1;
let endIndex: number = -1;
let startIndex: number = -1;
let endIndex: number = -1;
// Get range of this
if (shiftKey) {
const pointKeys = new Set([lastSelectedKey, key]);
// Get range of this
if (shiftKey) {
const pointKeys = new Set([lastSelectedKey, key]);
recordKeys.some((recordKey, recordIndex) => {
if (pointKeys.has(recordKey)) {
if (startIndex === -1) {
startIndex = recordIndex;
} else {
endIndex = recordIndex;
return true;
recordKeys.some((recordKey, recordIndex) => {
if (pointKeys.has(recordKey)) {
if (startIndex === -1) {
startIndex = recordIndex;
} else {
endIndex = recordIndex;
return true;
}
}
return false;
});
}
if (endIndex !== -1 && startIndex !== endIndex) {
// Batch update selections
const rangeKeys = recordKeys.slice(startIndex, endIndex + 1);
const changedKeys: Key[] = [];
if (checked) {
rangeKeys.forEach(recordKey => {
if (keySet.has(recordKey)) {
changedKeys.push(recordKey);
keySet.delete(recordKey);
}
});
} else {
rangeKeys.forEach(recordKey => {
if (!keySet.has(recordKey)) {
changedKeys.push(recordKey);
keySet.add(recordKey);
}
});
}
return false;
});
}
if (endIndex !== -1 && startIndex !== endIndex) {
// Batch update selections
const rangeKeys = recordKeys.slice(startIndex, endIndex + 1);
const changedKeys: Key[] = [];
if (hasKey) {
rangeKeys.forEach(recordKey => {
if (keySet.has(recordKey)) {
changedKeys.push(recordKey);
keySet.delete(recordKey);
}
});
const keys = Array.from(keySet);
setSelectedKeys(keys);
if (onSelectMultiple) {
onSelectMultiple(
!checked,
keys.map(recordKey => getRecordByKey(recordKey)),
changedKeys.map(recordKey => getRecordByKey(recordKey)),
);
}
} else {
rangeKeys.forEach(recordKey => {
if (!keySet.has(recordKey)) {
changedKeys.push(recordKey);
keySet.add(recordKey);
}
});
// Single record selected
if (checked) {
keySet.delete(key);
} else {
keySet.add(key);
}
triggerSingleSelection(key, !checked, Array.from(keySet), nativeEvent);
}
const keys = Array.from(keySet);
setSelectedKeys(keys);
if (onSelectMultiple) {
onSelectMultiple(
!hasKey,
keys.map(recordKey => getRecordByKey(recordKey)),
changedKeys.map(recordKey => getRecordByKey(recordKey)),
);
}
} else {
// Single record selected
if (hasKey) {
keySet.delete(key);
} else {
keySet.add(key);
}
triggerSingleSelection(key, !hasKey, Array.from(keySet), nativeEvent);
}
setLastSelectedKey(key);
}}
/>
);
setLastSelectedKey(key);
}}
/>
),
checked,
};
};
}
const renderSelectionCell = (_: any, record: RecordType, index: number) => {
const { node, checked } = renderCell(_, record, index);
if (customizeRenderCell) {
return customizeRenderCell(checked, record, index, node);
}
return node;
};
// Columns
const selectionColumn = {
width: selectionColWidth,
className: `${prefixCls}-selection-column`,
title: rowSelection.columnTitle || title,
render: renderCell,
render: renderSelectionCell,
};
if (expandType === 'row' && columns.length && !expandIconColumnIndex) {

View File

@ -12,9 +12,14 @@ import {
CompareFn,
ColumnTitleProps,
SorterResult,
TableLocale,
} from '../interface';
import Tooltip from '../../tooltip';
import { getColumnKey, getColumnPos, renderColumnTitle } from '../util';
const ASCEND = 'ascend';
const DESCEND = 'descend';
function getMultiplePriority<RecordType>(column: ColumnType<RecordType>): number | false {
if (typeof column.sorter === 'object' && typeof column.sorter.multiple === 'number') {
return column.sorter.multiple;
@ -91,6 +96,8 @@ function injectSorter<RecordType>(
sorterSates: SortState<RecordType>[],
triggerSorter: (sorterSates: SortState<RecordType>) => void,
defaultSortDirections: SortOrder[],
tableLocale?: TableLocale,
tableShowSorterTooltip?: boolean,
pos?: string,
): ColumnsType<RecordType> {
return (columns || []).map((column, index) => {
@ -99,53 +106,69 @@ function injectSorter<RecordType>(
if (newColumn.sorter) {
const sortDirections: SortOrder[] = newColumn.sortDirections || defaultSortDirections;
const showSorterTooltip =
newColumn.showSorterTooltip === undefined
? tableShowSorterTooltip
: newColumn.showSorterTooltip;
const columnKey = getColumnKey(newColumn, columnPos);
const sorterState = sorterSates.find(({ key }) => key === columnKey);
const sorterOrder = sorterState ? sorterState.sortOrder : null;
const upNode: React.ReactNode = sortDirections.includes('ascend') && (
const nextSortOrder = nextSortDirection(sortDirections, sorterOrder);
const upNode: React.ReactNode = sortDirections.includes(ASCEND) && (
<CaretUpOutlined
className={classNames(`${prefixCls}-column-sorter-up`, {
active: sorterOrder === 'ascend',
active: sorterOrder === ASCEND,
})}
/>
);
const downNode: React.ReactNode = sortDirections.includes('descend') && (
const downNode: React.ReactNode = sortDirections.includes(DESCEND) && (
<CaretDownOutlined
className={classNames(`${prefixCls}-column-sorter-down`, {
active: sorterOrder === 'descend',
active: sorterOrder === DESCEND,
})}
/>
);
const { cancelSort, triggerAsc, triggerDesc } = tableLocale || {};
let sortTip: string | undefined = cancelSort;
if (nextSortOrder === DESCEND) {
sortTip = triggerDesc;
} else if (nextSortOrder === ASCEND) {
sortTip = triggerAsc;
}
newColumn = {
...newColumn,
className: classNames(newColumn.className, { [`${prefixCls}-column-sort`]: sorterOrder }),
title: (renderProps: ColumnTitleProps<RecordType>) => (
<div className={`${prefixCls}-column-sorters`}>
<span>{renderColumnTitle(column.title, renderProps)}</span>
<span
className={classNames(`${prefixCls}-column-sorter`, {
[`${prefixCls}-column-sorter-full`]: upNode && downNode,
})}
>
<span className={`${prefixCls}-column-sorter-inner`}>
{upNode}
{downNode}
title: (renderProps: ColumnTitleProps<RecordType>) => {
const renderSortTitle = (
<div className={`${prefixCls}-column-sorters`}>
<span>{renderColumnTitle(column.title, renderProps)}</span>
<span
className={classNames(`${prefixCls}-column-sorter`, {
[`${prefixCls}-column-sorter-full`]: upNode && downNode,
})}
>
<span className={`${prefixCls}-column-sorter-inner`}>
{upNode}
{downNode}
</span>
</span>
</span>
</div>
),
</div>
);
return showSorterTooltip ? (
<Tooltip title={sortTip}>{renderSortTitle}</Tooltip>
) : (
renderSortTitle
);
},
onHeaderCell: col => {
const cell: React.HTMLAttributes<HTMLElement> =
(column.onHeaderCell && column.onHeaderCell(col)) || {};
const originOnClick = cell.onClick;
cell.onClick = (event: React.MouseEvent<HTMLElement>) => {
triggerSorter({
column,
key: columnKey,
sortOrder: nextSortDirection(sortDirections, sorterOrder),
sortOrder: nextSortOrder,
multiplePriority: getMultiplePriority(column),
});
@ -170,6 +193,8 @@ function injectSorter<RecordType>(
sorterSates,
triggerSorter,
defaultSortDirections,
tableLocale,
tableShowSorterTooltip,
columnPos,
),
};
@ -240,7 +265,7 @@ export function getSortData<RecordType>(
const compareResult = compareFn(record1, record2, sortOrder);
if (compareResult !== 0) {
return sortOrder === 'ascend' ? compareResult : -compareResult;
return sortOrder === ASCEND ? compareResult : -compareResult;
}
}
}
@ -268,6 +293,8 @@ interface SorterConfig<RecordType> {
sortStates: SortState<RecordType>[],
) => void;
sortDirections: SortOrder[];
tableLocale?: TableLocale;
showSorterTooltip?: boolean;
}
export default function useFilterSorter<RecordType>({
@ -276,6 +303,8 @@ export default function useFilterSorter<RecordType>({
children,
onSorterChange,
sortDirections,
tableLocale,
showSorterTooltip,
}: SorterConfig<RecordType>): [
TransformColumns<RecordType>,
SortState<RecordType>[],
@ -371,7 +400,15 @@ export default function useFilterSorter<RecordType>({
}
const transformColumns = (innerColumns: ColumnsType<RecordType>) =>
injectSorter(prefixCls, innerColumns, mergedSorterStates, triggerSorter, sortDirections);
injectSorter(
prefixCls,
innerColumns,
mergedSorterStates,
triggerSorter,
sortDirections,
tableLocale,
showSorterTooltip,
);
const getSorters = () => {
return generateSorterInfo(mergedSorterStates);

View File

@ -82,6 +82,7 @@ const columns = [
| onRow | Set props on per row | Function(record, index) | - |
| getPopupContainer | the render container of dropdowns in table | (triggerNode) => HTMLElement | `() => TableHtmlElement` |
| sortDirections | supported sort way, could be `'ascend'`, `'descend'` | Array | `['ascend', 'descend']` |
| showSorterTooltip | header show next sorter direction tooltip | boolean | `true` |
#### onRow usage
@ -138,6 +139,7 @@ One of the Table `columns` prop for describing the table's columns, Column has t
| onFilter | Callback executed when the confirm filter button is clicked | Function | - |
| onFilterDropdownVisibleChange | Callback executed when `filterDropdownVisible` is changed | function(visible) {} | - |
| onHeaderCell | Set props on per header cell | Function(column) | - |
| showSorterTooltip | header show next sorter direction tooltip, override `showSorterTooltip` in table | boolean | `true` |
### ColumnGroup
@ -178,20 +180,21 @@ Properties for expandable.
Properties for row selection.
| Property | Description | Type | Default |
| --- | --- | --- | --- |
| columnWidth | Set the width of the selection column | string\|number | `60px` |
| columnTitle | Set the title of the selection column | string\|React.ReactNode | - |
| fixed | Fixed selection column on the left | boolean | - |
| getCheckboxProps | Get Checkbox or Radio props | Function(record) | - |
| hideDefaultSelections | Remove the default `Select All` and `Select Invert` selections when [custom selection](#components-table-demo-row-selection-custom) | boolean | `false` |
| selectedRowKeys | Controlled selected row keys | string\[]\|number[] | \[] |
| selections | Custom selection [config](#rowSelection), only displays default selections when set to `true` | object\[]\|boolean | - |
| type | `checkbox` or `radio` | `checkbox` \| `radio` | `checkbox` |
| onChange | Callback executed when selected rows change | Function(selectedRowKeys, selectedRows) | - |
| onSelect | Callback executed when select/deselect one row | Function(record, selected, selectedRows, nativeEvent) | - |
| onSelectAll | Callback executed when select/deselect all rows | Function(selected, selectedRows, changeRows) | - |
| onSelectInvert | Callback executed when row selection is inverted | Function(selectedRows) | - |
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| columnWidth | Set the width of the selection column | string\|number | `60px` | 4.0 |
| columnTitle | Set the title of the selection column | string\|React.ReactNode | - | 4.0 |
| fixed | Fixed selection column on the left | boolean | - | 4.0 |
| getCheckboxProps | Get Checkbox or Radio props | Function(record) | - | 4.0 |
| hideDefaultSelections | Remove the default `Select All` and `Select Invert` selections when [custom selection](#components-table-demo-row-selection-custom) | boolean | `false` | 4.0 |
| renderCell | Renderer of the table cell. Same as `render` in column | Function(checked, record, index, originNode) {} | - | 4.1 |
| selectedRowKeys | Controlled selected row keys | string\[]\|number[] | \[] | 4.0 |
| selections | Custom selection [config](#rowSelection), only displays default selections when set to `true` | object\[]\|boolean | - | 4.0 |
| type | `checkbox` or `radio` | `checkbox` \| `radio` | `checkbox` | 4.0 |
| onChange | Callback executed when selected rows change | Function(selectedRowKeys, selectedRows) | - | 4.0 |
| onSelect | Callback executed when select/deselect one row | Function(record, selected, selectedRows, nativeEvent) | - | 4.0 |
| onSelectAll | Callback executed when select/deselect all rows | Function(selected, selectedRows, changeRows) | - | 4.0 |
| onSelectInvert | Callback executed when row selection is inverted | Function(selectedRows) | - | 4.0 |
### scroll

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