Merge pull request #22880 from ant-design/master

chore: Feature merge master
This commit is contained in:
二货机器人 2020-04-03 13:58:35 +08:00 committed by GitHub
commit 678168a74e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
45 changed files with 7428 additions and 6999 deletions

View File

@ -207,23 +207,6 @@ exports[`Calendar Calendar should support locale 1`] = `
</thead>
<tbody>
<tr>
<td
class="ant-picker-cell"
title="2018-09-30"
>
<div
class="ant-picker-cell-inner ant-picker-calendar-date"
>
<div
class="ant-picker-calendar-date-value"
>
30
</div>
<div
class="ant-picker-calendar-date-content"
/>
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2018-10-01"
@ -326,8 +309,6 @@ exports[`Calendar Calendar should support locale 1`] = `
/>
</div>
</td>
</tr>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2018-10-07"
@ -345,6 +326,8 @@ exports[`Calendar Calendar should support locale 1`] = `
/>
</div>
</td>
</tr>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2018-10-08"
@ -447,8 +430,6 @@ exports[`Calendar Calendar should support locale 1`] = `
/>
</div>
</td>
</tr>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2018-10-14"
@ -466,6 +447,8 @@ exports[`Calendar Calendar should support locale 1`] = `
/>
</div>
</td>
</tr>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2018-10-15"
@ -568,8 +551,6 @@ exports[`Calendar Calendar should support locale 1`] = `
/>
</div>
</td>
</tr>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2018-10-21"
@ -587,6 +568,8 @@ exports[`Calendar Calendar should support locale 1`] = `
/>
</div>
</td>
</tr>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2018-10-22"
@ -689,8 +672,6 @@ exports[`Calendar Calendar should support locale 1`] = `
/>
</div>
</td>
</tr>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2018-10-28"
@ -708,6 +689,8 @@ exports[`Calendar Calendar should support locale 1`] = `
/>
</div>
</td>
</tr>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2018-10-29"
@ -810,8 +793,6 @@ exports[`Calendar Calendar should support locale 1`] = `
/>
</div>
</td>
</tr>
<tr>
<td
class="ant-picker-cell"
title="2018-11-04"
@ -829,6 +810,8 @@ exports[`Calendar Calendar should support locale 1`] = `
/>
</div>
</td>
</tr>
<tr>
<td
class="ant-picker-cell"
title="2018-11-05"
@ -931,6 +914,23 @@ exports[`Calendar Calendar should support locale 1`] = `
/>
</div>
</td>
<td
class="ant-picker-cell"
title="2018-11-11"
>
<div
class="ant-picker-cell-inner ant-picker-calendar-date"
>
<div
class="ant-picker-calendar-date-value"
>
11
</div>
<div
class="ant-picker-calendar-date-content"
/>
</div>
</td>
</tr>
</tbody>
</table>

View File

@ -6088,10 +6088,9 @@ exports[`ConfigProvider components DatePicker RangePicker configProvider 1`] = `
class="config-picker-range-separator"
>
<span
aria-label="to"
class="config-picker-separator"
>
</span>
/>
</div>
<div
class="config-picker-input"
@ -6154,10 +6153,9 @@ exports[`ConfigProvider components DatePicker RangePicker normal 1`] = `
class="ant-picker-range-separator"
>
<span
aria-label="to"
class="ant-picker-separator"
>
</span>
/>
</div>
<div
class="ant-picker-input"
@ -6220,10 +6218,9 @@ exports[`ConfigProvider components DatePicker RangePicker prefixCls 1`] = `
class="prefix-RangePicker-range-separator"
>
<span
aria-label="to"
class="prefix-RangePicker-separator"
>
</span>
/>
</div>
<div
class="prefix-RangePicker-input"
@ -11630,6 +11627,9 @@ exports[`ConfigProvider components Table configProvider 1`] = `
>
<span
class="config-table-filter-column-title"
>
<div
class="config-table-column-sorters-with-tooltip"
>
<div
class="config-table-column-sorters"
@ -11686,6 +11686,7 @@ exports[`ConfigProvider components Table configProvider 1`] = `
</span>
</span>
</div>
</div>
</span>
<span
class="config-table-filter-trigger-container config-table-filter-trigger-container-open"
@ -11900,6 +11901,9 @@ exports[`ConfigProvider components Table normal 1`] = `
>
<span
class="ant-table-filter-column-title"
>
<div
class="ant-table-column-sorters-with-tooltip"
>
<div
class="ant-table-column-sorters"
@ -11956,6 +11960,7 @@ exports[`ConfigProvider components Table normal 1`] = `
</span>
</span>
</div>
</div>
</span>
<span
class="ant-table-filter-trigger-container ant-table-filter-trigger-container-open"
@ -12170,6 +12175,9 @@ exports[`ConfigProvider components Table prefixCls 1`] = `
>
<span
class="prefix-Table-filter-column-title"
>
<div
class="prefix-Table-column-sorters-with-tooltip"
>
<div
class="prefix-Table-column-sorters"
@ -12226,6 +12234,7 @@ exports[`ConfigProvider components Table prefixCls 1`] = `
</span>
</span>
</div>
</div>
</span>
<span
class="prefix-Table-filter-trigger-container prefix-Table-filter-trigger-container-open"

View File

@ -769,16 +769,6 @@ Array [
</thead>
<tbody>
<tr>
<td
class="ant-picker-cell"
title="1999-12-26"
>
<div
class="ant-picker-cell-inner"
>
26
</div>
</td>
<td
class="ant-picker-cell"
title="1999-12-27"
@ -839,8 +829,6 @@ Array [
1
</div>
</td>
</tr>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2000-01-02"
@ -851,6 +839,8 @@ Array [
2
</div>
</td>
</tr>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2000-01-03"
@ -911,8 +901,6 @@ Array [
8
</div>
</td>
</tr>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2000-01-09"
@ -923,6 +911,8 @@ Array [
9
</div>
</td>
</tr>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2000-01-10"
@ -983,8 +973,6 @@ Array [
15
</div>
</td>
</tr>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2000-01-16"
@ -995,6 +983,8 @@ Array [
16
</div>
</td>
</tr>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2000-01-17"
@ -1055,8 +1045,6 @@ Array [
22
</div>
</td>
</tr>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2000-01-23"
@ -1067,6 +1055,8 @@ Array [
23
</div>
</td>
</tr>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2000-01-24"
@ -1127,8 +1117,6 @@ Array [
29
</div>
</td>
</tr>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2000-01-30"
@ -1139,6 +1127,8 @@ Array [
30
</div>
</td>
</tr>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2000-01-31"
@ -1199,6 +1189,16 @@ Array [
5
</div>
</td>
<td
class="ant-picker-cell"
title="2000-02-06"
>
<div
class="ant-picker-cell-inner"
>
6
</div>
</td>
</tr>
</tbody>
</table>

View File

@ -383,10 +383,9 @@ exports[`renders ./components/date-picker/demo/bordered.md correctly 1`] = `
class="ant-picker-range-separator"
>
<span
aria-label="to"
class="ant-picker-separator"
>
</span>
/>
</div>
<div
class="ant-picker-input"
@ -445,10 +444,9 @@ exports[`renders ./components/date-picker/demo/bordered.md correctly 1`] = `
class="ant-picker-range-separator"
>
<span
aria-label="to"
class="ant-picker-separator"
>
</span>
/>
</div>
<div
class="ant-picker-input"
@ -507,10 +505,9 @@ exports[`renders ./components/date-picker/demo/bordered.md correctly 1`] = `
class="ant-picker-range-separator"
>
<span
aria-label="to"
class="ant-picker-separator"
>
</span>
/>
</div>
<div
class="ant-picker-input"
@ -569,10 +566,9 @@ exports[`renders ./components/date-picker/demo/bordered.md correctly 1`] = `
class="ant-picker-range-separator"
>
<span
aria-label="to"
class="ant-picker-separator"
>
</span>
/>
</div>
<div
class="ant-picker-input"
@ -674,10 +670,9 @@ exports[`renders ./components/date-picker/demo/date-render.md correctly 1`] = `
class="ant-picker-range-separator"
>
<span
aria-label="to"
class="ant-picker-separator"
>
</span>
/>
</div>
<div
class="ant-picker-input"
@ -823,10 +818,9 @@ exports[`renders ./components/date-picker/demo/disabled.md correctly 1`] = `
class="ant-picker-range-separator"
>
<span
aria-label="to"
class="ant-picker-separator"
>
</span>
/>
</div>
<div
class="ant-picker-input"
@ -886,10 +880,9 @@ exports[`renders ./components/date-picker/demo/disabled.md correctly 1`] = `
class="ant-picker-range-separator"
>
<span
aria-label="to"
class="ant-picker-separator"
>
</span>
/>
</div>
<div
class="ant-picker-input"
@ -1057,10 +1050,9 @@ exports[`renders ./components/date-picker/demo/disabled-date.md correctly 1`] =
class="ant-picker-range-separator"
>
<span
aria-label="to"
class="ant-picker-separator"
>
</span>
/>
</div>
<div
class="ant-picker-input"
@ -1118,10 +1110,9 @@ exports[`renders ./components/date-picker/demo/disabled-date.md correctly 1`] =
class="ant-picker-range-separator"
>
<span
aria-label="to"
class="ant-picker-separator"
>
</span>
/>
</div>
<div
class="ant-picker-input"
@ -1264,10 +1255,9 @@ exports[`renders ./components/date-picker/demo/extra-footer.md correctly 1`] = `
class="ant-picker-range-separator"
>
<span
aria-label="to"
class="ant-picker-separator"
>
</span>
/>
</div>
<div
class="ant-picker-input"
@ -1326,10 +1316,9 @@ exports[`renders ./components/date-picker/demo/extra-footer.md correctly 1`] = `
class="ant-picker-range-separator"
>
<span
aria-label="to"
class="ant-picker-separator"
>
</span>
/>
</div>
<div
class="ant-picker-input"
@ -1624,10 +1613,9 @@ exports[`renders ./components/date-picker/demo/format.md correctly 1`] = `
class="ant-picker-range-separator"
>
<span
aria-label="to"
class="ant-picker-separator"
>
</span>
/>
</div>
<div
class="ant-picker-input"
@ -1754,10 +1742,9 @@ exports[`renders ./components/date-picker/demo/mode.md correctly 1`] = `
class="ant-picker-range-separator"
>
<span
aria-label="to"
class="ant-picker-separator"
>
</span>
/>
</div>
<div
class="ant-picker-input"
@ -1820,10 +1807,9 @@ exports[`renders ./components/date-picker/demo/presetted-ranges.md correctly 1`]
class="ant-picker-range-separator"
>
<span
aria-label="to"
class="ant-picker-separator"
>
</span>
/>
</div>
<div
class="ant-picker-input"
@ -1882,10 +1868,9 @@ exports[`renders ./components/date-picker/demo/presetted-ranges.md correctly 1`]
class="ant-picker-range-separator"
>
<span
aria-label="to"
class="ant-picker-separator"
>
</span>
/>
</div>
<div
class="ant-picker-input"
@ -1948,10 +1933,9 @@ exports[`renders ./components/date-picker/demo/range-picker.md correctly 1`] = `
class="ant-picker-range-separator"
>
<span
aria-label="to"
class="ant-picker-separator"
>
</span>
/>
</div>
<div
class="ant-picker-input"
@ -2010,10 +1994,9 @@ exports[`renders ./components/date-picker/demo/range-picker.md correctly 1`] = `
class="ant-picker-range-separator"
>
<span
aria-label="to"
class="ant-picker-separator"
>
</span>
/>
</div>
<div
class="ant-picker-input"
@ -2072,10 +2055,9 @@ exports[`renders ./components/date-picker/demo/range-picker.md correctly 1`] = `
class="ant-picker-range-separator"
>
<span
aria-label="to"
class="ant-picker-separator"
>
</span>
/>
</div>
<div
class="ant-picker-input"
@ -2134,10 +2116,9 @@ exports[`renders ./components/date-picker/demo/range-picker.md correctly 1`] = `
class="ant-picker-range-separator"
>
<span
aria-label="to"
class="ant-picker-separator"
>
</span>
/>
</div>
<div
class="ant-picker-input"
@ -2196,10 +2177,9 @@ exports[`renders ./components/date-picker/demo/range-picker.md correctly 1`] = `
class="ant-picker-range-separator"
>
<span
aria-label="to"
class="ant-picker-separator"
>
</span>
/>
</div>
<div
class="ant-picker-input"
@ -2261,10 +2241,9 @@ exports[`renders ./components/date-picker/demo/select-in-range.md correctly 1`]
class="ant-picker-range-separator"
>
<span
aria-label="to"
class="ant-picker-separator"
>
</span>
/>
</div>
<div
class="ant-picker-input"
@ -2470,10 +2449,9 @@ exports[`renders ./components/date-picker/demo/size.md correctly 1`] = `
class="ant-picker-range-separator"
>
<span
aria-label="to"
class="ant-picker-separator"
>
</span>
/>
</div>
<div
class="ant-picker-input"
@ -2739,10 +2717,9 @@ exports[`renders ./components/date-picker/demo/suffix.md correctly 1`] = `
class="ant-picker-range-separator"
>
<span
aria-label="to"
class="ant-picker-separator"
>
</span>
/>
</div>
<div
class="ant-picker-input"
@ -2883,10 +2860,9 @@ exports[`renders ./components/date-picker/demo/suffix.md correctly 1`] = `
class="ant-picker-range-separator"
>
<span
aria-label="to"
class="ant-picker-separator"
>
</span>
/>
</div>
<div
class="ant-picker-input"
@ -2991,10 +2967,9 @@ exports[`renders ./components/date-picker/demo/time.md correctly 1`] = `
class="ant-picker-range-separator"
>
<span
aria-label="to"
class="ant-picker-separator"
>
</span>
/>
</div>
<div
class="ant-picker-input"

View File

@ -144,10 +144,9 @@ exports[`mount rtl render component should be rendered correctly in RTL directio
class="ant-picker-range-separator"
>
<span
aria-label="to"
class="ant-picker-separator"
>
</span>
/>
</div>
<div
class="ant-picker-input"

View File

@ -304,6 +304,16 @@ exports[`MonthPicker and WeekPicker render WeekPicker 1`] = `
>
1
</td>
<td
class="ant-picker-cell"
title="1999-12-26"
>
<div
class="ant-picker-cell-inner"
>
26
</div>
</td>
<td
class="ant-picker-cell"
title="1999-12-27"
@ -364,6 +374,15 @@ exports[`MonthPicker and WeekPicker render WeekPicker 1`] = `
1
</div>
</td>
</tr>
<tr
class="ant-picker-week-panel-row"
>
<td
class="ant-picker-cell ant-picker-cell-week"
>
2
</td>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2000-01-02"
@ -374,15 +393,6 @@ exports[`MonthPicker and WeekPicker render WeekPicker 1`] = `
2
</div>
</td>
</tr>
<tr
class="ant-picker-week-panel-row"
>
<td
class="ant-picker-cell ant-picker-cell-week"
>
2
</td>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2000-01-03"
@ -443,6 +453,15 @@ exports[`MonthPicker and WeekPicker render WeekPicker 1`] = `
8
</div>
</td>
</tr>
<tr
class="ant-picker-week-panel-row"
>
<td
class="ant-picker-cell ant-picker-cell-week"
>
3
</td>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2000-01-09"
@ -453,15 +472,6 @@ exports[`MonthPicker and WeekPicker render WeekPicker 1`] = `
9
</div>
</td>
</tr>
<tr
class="ant-picker-week-panel-row"
>
<td
class="ant-picker-cell ant-picker-cell-week"
>
3
</td>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2000-01-10"
@ -522,6 +532,15 @@ exports[`MonthPicker and WeekPicker render WeekPicker 1`] = `
15
</div>
</td>
</tr>
<tr
class="ant-picker-week-panel-row"
>
<td
class="ant-picker-cell ant-picker-cell-week"
>
4
</td>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2000-01-16"
@ -532,15 +551,6 @@ exports[`MonthPicker and WeekPicker render WeekPicker 1`] = `
16
</div>
</td>
</tr>
<tr
class="ant-picker-week-panel-row"
>
<td
class="ant-picker-cell ant-picker-cell-week"
>
4
</td>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2000-01-17"
@ -601,6 +611,15 @@ exports[`MonthPicker and WeekPicker render WeekPicker 1`] = `
22
</div>
</td>
</tr>
<tr
class="ant-picker-week-panel-row"
>
<td
class="ant-picker-cell ant-picker-cell-week"
>
5
</td>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2000-01-23"
@ -611,15 +630,6 @@ exports[`MonthPicker and WeekPicker render WeekPicker 1`] = `
23
</div>
</td>
</tr>
<tr
class="ant-picker-week-panel-row"
>
<td
class="ant-picker-cell ant-picker-cell-week"
>
5
</td>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2000-01-24"
@ -680,6 +690,15 @@ exports[`MonthPicker and WeekPicker render WeekPicker 1`] = `
29
</div>
</td>
</tr>
<tr
class="ant-picker-week-panel-row"
>
<td
class="ant-picker-cell ant-picker-cell-week"
>
6
</td>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2000-01-30"
@ -690,15 +709,6 @@ exports[`MonthPicker and WeekPicker render WeekPicker 1`] = `
30
</div>
</td>
</tr>
<tr
class="ant-picker-week-panel-row"
>
<td
class="ant-picker-cell ant-picker-cell-week"
>
6
</td>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2000-01-31"
@ -759,16 +769,6 @@ exports[`MonthPicker and WeekPicker render WeekPicker 1`] = `
5
</div>
</td>
<td
class="ant-picker-cell"
title="2000-02-06"
>
<div
class="ant-picker-cell-inner"
>
6
</div>
</td>
</tr>
</tbody>
</table>

View File

@ -1,380 +0,0 @@
import * as React from 'react';
import classNames from 'classnames';
import RCPicker, { RangePicker as RCRangePicker } from 'rc-picker';
import { GenerateConfig } from 'rc-picker/lib/generate/index';
import {
PickerBaseProps as RCPickerBaseProps,
PickerDateProps as RCPickerDateProps,
PickerTimeProps as RCPickerTimeProps,
} from 'rc-picker/lib/Picker';
import { SharedTimeProps } from 'rc-picker/lib/panels/TimePanel';
import {
RangePickerBaseProps as RCRangePickerBaseProps,
RangePickerDateProps as RCRangePickerDateProps,
RangePickerTimeProps as RCRangePickerTimeProps,
} from 'rc-picker/lib/RangePicker';
import { PickerMode, Locale as RcPickerLocale } from 'rc-picker/lib/interface';
import CalendarOutlined from '@ant-design/icons/CalendarOutlined';
import ClockCircleOutlined from '@ant-design/icons/ClockCircleOutlined';
import CloseCircleFilled from '@ant-design/icons/CloseCircleFilled';
import { ConfigContext, ConfigConsumerProps } from '../config-provider';
import LocaleReceiver from '../locale-provider/LocaleReceiver';
import enUS from './locale/en_US';
import { getPlaceholder, getRangePlaceholder } from './util';
import PickerButton from './PickerButton';
import PickerTag from './PickerTag';
import SizeContext, { SizeType } from '../config-provider/SizeContext';
import { TimePickerLocale } from '../time-picker';
const Components = { button: PickerButton, rangeItem: PickerTag };
function toArray<T>(list: T | T[]): T[] {
if (!list) {
return [];
}
return Array.isArray(list) ? list : [list];
}
function getTimeProps<DateType>(
props: { format?: string; picker?: PickerMode } & SharedTimeProps<DateType>,
) {
const { format, picker, showHour, showMinute, showSecond, use12Hours } = props;
const firstFormat = toArray(format)[0];
const showTimeObj: SharedTimeProps<DateType> = { ...props };
if (firstFormat) {
if (!firstFormat.includes('s') && showSecond === undefined) {
showTimeObj.showSecond = false;
}
if (!firstFormat.includes('m') && showMinute === undefined) {
showTimeObj.showMinute = false;
}
if (!firstFormat.includes('H') && !firstFormat.includes('h') && showHour === undefined) {
showTimeObj.showHour = false;
}
if ((firstFormat.includes('a') || firstFormat.includes('A')) && use12Hours === undefined) {
showTimeObj.use12Hours = true;
}
}
if (picker === 'time') {
return showTimeObj;
}
return {
showTime: showTimeObj,
};
}
type InjectDefaultProps<Props> = Omit<
Props,
| 'locale'
| 'generateConfig'
| 'prevIcon'
| 'nextIcon'
| 'superPrevIcon'
| 'superNextIcon'
| 'hideHeader'
| 'components'
> & {
locale?: PickerLocale;
size?: SizeType;
bordered?: boolean;
};
export type PickerLocale = {
lang: RcPickerLocale & AdditionalPickerLocaleLangProps;
timePickerLocale: TimePickerLocale;
} & AdditionalPickerLocaleProps;
export type AdditionalPickerLocaleProps = {
dateFormat?: string;
dateTimeFormat?: string;
weekFormat?: string;
monthFormat?: string;
};
export type AdditionalPickerLocaleLangProps = {
placeholder: string;
yearPlaceholder?: string;
quarterPlaceholder?: string;
monthPlaceholder?: string;
weekPlaceholder?: string;
rangeYearPlaceholder?: [string, string];
rangeMonthPlaceholder?: [string, string];
rangeWeekPlaceholder?: [string, string];
rangePlaceholder?: [string, string];
};
// Picker Props
export type PickerBaseProps<DateType> = InjectDefaultProps<RCPickerBaseProps<DateType>>;
export type PickerDateProps<DateType> = InjectDefaultProps<RCPickerDateProps<DateType>>;
export type PickerTimeProps<DateType> = InjectDefaultProps<RCPickerTimeProps<DateType>>;
export type PickerProps<DateType> =
| PickerBaseProps<DateType>
| PickerDateProps<DateType>
| PickerTimeProps<DateType>;
// Range Picker Props
export type RangePickerBaseProps<DateType> = InjectDefaultProps<RCRangePickerBaseProps<DateType>>;
export type RangePickerDateProps<DateType> = InjectDefaultProps<RCRangePickerDateProps<DateType>>;
export type RangePickerTimeProps<DateType> = InjectDefaultProps<RCRangePickerTimeProps<DateType>>;
export type RangePickerProps<DateType> =
| RangePickerBaseProps<DateType>
| RangePickerDateProps<DateType>
| RangePickerTimeProps<DateType>;
function generatePicker<DateType>(generateConfig: GenerateConfig<DateType>) {
// =========================== Picker ===========================
type DatePickerProps = PickerProps<DateType>;
function getPicker<InnerPickerProps extends DatePickerProps>(
picker?: PickerMode,
displayName?: string,
) {
class Picker extends React.Component<InnerPickerProps> {
static contextType = ConfigContext;
static displayName: string;
context: ConfigConsumerProps;
pickerRef = React.createRef<RCPicker<DateType>>();
focus = () => {
if (this.pickerRef.current) {
this.pickerRef.current.focus();
}
};
blur = () => {
if (this.pickerRef.current) {
this.pickerRef.current.blur();
}
};
getDefaultLocale = () => {
const { locale } = this.props;
const result = {
...enUS,
...locale,
};
result.lang = {
...result.lang,
...((locale || {}) as PickerLocale).lang,
};
return result;
};
renderPicker = (locale: PickerLocale) => {
const { getPrefixCls, direction } = this.context;
const {
prefixCls: customizePrefixCls,
className,
size: customizeSize,
bordered = true,
...restProps
} = this.props;
const { format, showTime } = this.props as any;
const prefixCls = getPrefixCls('picker', customizePrefixCls);
const additionalProps = {
showToday: true,
};
let additionalOverrideProps: any = {};
if (picker) {
additionalOverrideProps.picker = picker;
}
const mergedPicker = picker || this.props.picker;
additionalOverrideProps = {
...additionalOverrideProps,
...(showTime ? getTimeProps({ format, picker: mergedPicker, ...showTime }) : {}),
...(mergedPicker === 'time'
? getTimeProps({ format, ...this.props, picker: mergedPicker })
: {}),
};
return (
<SizeContext.Consumer>
{size => {
const mergedSize = customizeSize || size;
return (
<RCPicker<DateType>
ref={this.pickerRef}
placeholder={getPlaceholder(mergedPicker, locale)}
suffixIcon={
mergedPicker === 'time' ? <ClockCircleOutlined /> : <CalendarOutlined />
}
clearIcon={<CloseCircleFilled />}
allowClear
transitionName="slide-up"
{...additionalProps}
{...restProps}
{...additionalOverrideProps}
locale={locale!.lang}
className={classNames(className, {
[`${prefixCls}-${mergedSize}`]: mergedSize,
[`${prefixCls}-borderless`]: !bordered,
})}
prefixCls={prefixCls}
generateConfig={generateConfig}
prevIcon={<span className={`${prefixCls}-prev-icon`} />}
nextIcon={<span className={`${prefixCls}-next-icon`} />}
superPrevIcon={<span className={`${prefixCls}-super-prev-icon`} />}
superNextIcon={<span className={`${prefixCls}-super-next-icon`} />}
components={Components}
direction={direction}
/>
);
}}
</SizeContext.Consumer>
);
};
render() {
return (
<LocaleReceiver componentName="DatePicker" defaultLocale={this.getDefaultLocale}>
{this.renderPicker}
</LocaleReceiver>
);
}
}
if (displayName) {
Picker.displayName = displayName;
}
return Picker as React.ComponentClass<InnerPickerProps>;
}
const DatePicker = getPicker<DatePickerProps>();
const WeekPicker = getPicker<Omit<PickerDateProps<DateType>, 'picker'>>('week', 'WeekPicker');
const MonthPicker = getPicker<Omit<PickerDateProps<DateType>, 'picker'>>('month', 'MonthPicker');
const YearPicker = getPicker<Omit<PickerDateProps<DateType>, 'picker'>>('year', 'YearPicker');
const TimePicker = getPicker<Omit<PickerTimeProps<DateType>, 'picker'>>('time', 'TimePicker');
// ======================== Range Picker ========================
class RangePicker extends React.Component<RangePickerProps<DateType>> {
static contextType = ConfigContext;
context: ConfigConsumerProps;
pickerRef = React.createRef<RCRangePicker<DateType>>();
focus = () => {
if (this.pickerRef.current) {
this.pickerRef.current.focus();
}
};
blur = () => {
if (this.pickerRef.current) {
this.pickerRef.current.blur();
}
};
getDefaultLocale = () => {
const { locale } = this.props;
const result = {
...enUS,
...locale,
};
result.lang = {
...result.lang,
...((locale || {}) as PickerLocale).lang,
};
return result;
};
renderPicker = (locale: PickerLocale) => {
const { getPrefixCls, direction } = this.context;
const {
prefixCls: customizePrefixCls,
className,
size: customizeSize,
bordered = true,
...restProps
} = this.props;
const { format, showTime, picker } = this.props as any;
const prefixCls = getPrefixCls('picker', customizePrefixCls);
let additionalOverrideProps: any = {};
additionalOverrideProps = {
...additionalOverrideProps,
...(showTime ? getTimeProps({ format, picker, ...showTime }) : {}),
...(picker === 'time' ? getTimeProps({ format, ...this.props, picker }) : {}),
};
return (
<SizeContext.Consumer>
{size => {
const mergedSize = customizeSize || size;
return (
<RCRangePicker<DateType>
separator={<span className={`${prefixCls}-separator`}></span>}
ref={this.pickerRef}
placeholder={getRangePlaceholder(picker, locale)}
suffixIcon={picker === 'time' ? <ClockCircleOutlined /> : <CalendarOutlined />}
clearIcon={<CloseCircleFilled />}
allowClear
transitionName="slide-up"
{...restProps}
className={classNames(className, {
[`${prefixCls}-${mergedSize}`]: mergedSize,
[`${prefixCls}-borderless`]: !bordered,
})}
{...additionalOverrideProps}
locale={locale!.lang}
prefixCls={prefixCls}
generateConfig={generateConfig}
prevIcon={<span className={`${prefixCls}-prev-icon`} />}
nextIcon={<span className={`${prefixCls}-next-icon`} />}
superPrevIcon={<span className={`${prefixCls}-super-prev-icon`} />}
superNextIcon={<span className={`${prefixCls}-super-next-icon`} />}
components={Components}
direction={direction}
/>
);
}}
</SizeContext.Consumer>
);
};
render() {
return (
<LocaleReceiver componentName="DatePicker" defaultLocale={this.getDefaultLocale}>
{this.renderPicker}
</LocaleReceiver>
);
}
}
// =========================== Export ===========================
type MergedDatePicker = typeof DatePicker & {
WeekPicker: typeof WeekPicker;
MonthPicker: typeof MonthPicker;
YearPicker: typeof YearPicker;
RangePicker: React.ComponentClass<RangePickerProps<DateType>>;
TimePicker: typeof TimePicker;
};
const MergedDatePicker = DatePicker as MergedDatePicker;
MergedDatePicker.WeekPicker = WeekPicker;
MergedDatePicker.MonthPicker = MonthPicker;
MergedDatePicker.YearPicker = YearPicker;
MergedDatePicker.RangePicker = RangePicker;
MergedDatePicker.TimePicker = TimePicker;
return MergedDatePicker;
}
export default generatePicker;

View File

@ -0,0 +1,116 @@
import * as React from 'react';
import classNames from 'classnames';
import CalendarOutlined from '@ant-design/icons/CalendarOutlined';
import ClockCircleOutlined from '@ant-design/icons/ClockCircleOutlined';
import CloseCircleFilled from '@ant-design/icons/CloseCircleFilled';
import { RangePicker as RCRangePicker } from 'rc-picker';
import { GenerateConfig } from 'rc-picker/lib/generate/index';
import enUS from '../locale/en_US';
import { ConfigContext, ConfigConsumerProps } from '../../config-provider';
import SizeContext from '../../config-provider/SizeContext';
import LocaleReceiver from '../../locale-provider/LocaleReceiver';
import { getRangePlaceholder } from '../util';
import { RangePickerProps, PickerLocale, getTimeProps, Components } from '.';
export default function generateRangePicker<DateType>(
generateConfig: GenerateConfig<DateType>,
): React.ComponentClass<RangePickerProps<DateType>> {
class RangePicker extends React.Component<RangePickerProps<DateType>> {
static contextType = ConfigContext;
context: ConfigConsumerProps;
pickerRef = React.createRef<RCRangePicker<DateType>>();
focus = () => {
if (this.pickerRef.current) {
this.pickerRef.current.focus();
}
};
blur = () => {
if (this.pickerRef.current) {
this.pickerRef.current.blur();
}
};
getDefaultLocale = () => {
const { locale } = this.props;
const result = {
...enUS,
...locale,
};
result.lang = {
...result.lang,
...((locale || {}) as PickerLocale).lang,
};
return result;
};
renderPicker = (locale: PickerLocale) => {
const { getPrefixCls, direction } = this.context;
const {
prefixCls: customizePrefixCls,
className,
size: customizeSize,
bordered = true,
...restProps
} = this.props;
const { format, showTime, picker } = this.props as any;
const prefixCls = getPrefixCls('picker', customizePrefixCls);
let additionalOverrideProps: any = {};
additionalOverrideProps = {
...additionalOverrideProps,
...(showTime ? getTimeProps({ format, picker, ...showTime }) : {}),
...(picker === 'time' ? getTimeProps({ format, ...this.props, picker }) : {}),
};
return (
<SizeContext.Consumer>
{size => {
const mergedSize = customizeSize || size;
return (
<RCRangePicker<DateType>
separator={<span aria-label="to" className={`${prefixCls}-separator`} />}
ref={this.pickerRef}
placeholder={getRangePlaceholder(picker, locale)}
suffixIcon={picker === 'time' ? <ClockCircleOutlined /> : <CalendarOutlined />}
clearIcon={<CloseCircleFilled />}
allowClear
transitionName="slide-up"
{...restProps}
className={classNames(className, {
[`${prefixCls}-${mergedSize}`]: mergedSize,
[`${prefixCls}-borderless`]: !bordered,
})}
{...additionalOverrideProps}
locale={locale!.lang}
prefixCls={prefixCls}
generateConfig={generateConfig}
prevIcon={<span className={`${prefixCls}-prev-icon`} />}
nextIcon={<span className={`${prefixCls}-next-icon`} />}
superPrevIcon={<span className={`${prefixCls}-super-prev-icon`} />}
superNextIcon={<span className={`${prefixCls}-super-next-icon`} />}
components={Components}
direction={direction}
/>
);
}}
</SizeContext.Consumer>
);
};
render() {
return (
<LocaleReceiver componentName="DatePicker" defaultLocale={this.getDefaultLocale}>
{this.renderPicker}
</LocaleReceiver>
);
}
}
return RangePicker;
}

View File

@ -0,0 +1,155 @@
import * as React from 'react';
import classNames from 'classnames';
import CalendarOutlined from '@ant-design/icons/CalendarOutlined';
import ClockCircleOutlined from '@ant-design/icons/ClockCircleOutlined';
import CloseCircleFilled from '@ant-design/icons/CloseCircleFilled';
import RCPicker from 'rc-picker';
import { PickerMode } from 'rc-picker/lib/interface';
import { GenerateConfig } from 'rc-picker/lib/generate/index';
import enUS from '../locale/en_US';
import { getPlaceholder } from '../util';
import { ConfigContext, ConfigConsumerProps } from '../../config-provider';
import LocaleReceiver from '../../locale-provider/LocaleReceiver';
import SizeContext from '../../config-provider/SizeContext';
import {
PickerProps,
PickerLocale,
PickerDateProps,
PickerTimeProps,
getTimeProps,
Components,
} from '.';
export default function generatePicker<DateType>(generateConfig: GenerateConfig<DateType>) {
type DatePickerProps = PickerProps<DateType>;
function getPicker<InnerPickerProps extends DatePickerProps>(
picker?: PickerMode,
displayName?: string,
) {
class Picker extends React.Component<InnerPickerProps> {
static contextType = ConfigContext;
static displayName: string;
context: ConfigConsumerProps;
pickerRef = React.createRef<RCPicker<DateType>>();
focus = () => {
if (this.pickerRef.current) {
this.pickerRef.current.focus();
}
};
blur = () => {
if (this.pickerRef.current) {
this.pickerRef.current.blur();
}
};
getDefaultLocale = () => {
const { locale } = this.props;
const result = {
...enUS,
...locale,
};
result.lang = {
...result.lang,
...((locale || {}) as PickerLocale).lang,
};
return result;
};
renderPicker = (locale: PickerLocale) => {
const { getPrefixCls, direction } = this.context;
const {
prefixCls: customizePrefixCls,
className,
size: customizeSize,
bordered = true,
...restProps
} = this.props;
const { format, showTime } = this.props as any;
const prefixCls = getPrefixCls('picker', customizePrefixCls);
const additionalProps = {
showToday: true,
};
let additionalOverrideProps: any = {};
if (picker) {
additionalOverrideProps.picker = picker;
}
const mergedPicker = picker || this.props.picker;
additionalOverrideProps = {
...additionalOverrideProps,
...(showTime ? getTimeProps({ format, picker: mergedPicker, ...showTime }) : {}),
...(mergedPicker === 'time'
? getTimeProps({ format, ...this.props, picker: mergedPicker })
: {}),
};
return (
<SizeContext.Consumer>
{size => {
const mergedSize = customizeSize || size;
return (
<RCPicker<DateType>
ref={this.pickerRef}
placeholder={getPlaceholder(mergedPicker, locale)}
suffixIcon={
mergedPicker === 'time' ? <ClockCircleOutlined /> : <CalendarOutlined />
}
clearIcon={<CloseCircleFilled />}
allowClear
transitionName="slide-up"
{...additionalProps}
{...restProps}
{...additionalOverrideProps}
locale={locale!.lang}
className={classNames(className, {
[`${prefixCls}-${mergedSize}`]: mergedSize,
[`${prefixCls}-borderless`]: !bordered,
})}
prefixCls={prefixCls}
generateConfig={generateConfig}
prevIcon={<span className={`${prefixCls}-prev-icon`} />}
nextIcon={<span className={`${prefixCls}-next-icon`} />}
superPrevIcon={<span className={`${prefixCls}-super-prev-icon`} />}
superNextIcon={<span className={`${prefixCls}-super-next-icon`} />}
components={Components}
direction={direction}
/>
);
}}
</SizeContext.Consumer>
);
};
render() {
return (
<LocaleReceiver componentName="DatePicker" defaultLocale={this.getDefaultLocale}>
{this.renderPicker}
</LocaleReceiver>
);
}
}
if (displayName) {
Picker.displayName = displayName;
}
return Picker as React.ComponentClass<InnerPickerProps>;
}
const DatePicker = getPicker<DatePickerProps>();
const WeekPicker = getPicker<Omit<PickerDateProps<DateType>, 'picker'>>('week', 'WeekPicker');
const MonthPicker = getPicker<Omit<PickerDateProps<DateType>, 'picker'>>('month', 'MonthPicker');
const YearPicker = getPicker<Omit<PickerDateProps<DateType>, 'picker'>>('year', 'YearPicker');
const TimePicker = getPicker<Omit<PickerTimeProps<DateType>, 'picker'>>('time', 'TimePicker');
return { DatePicker, WeekPicker, MonthPicker, YearPicker, TimePicker };
}

View File

@ -0,0 +1,152 @@
import * as React from 'react';
import { GenerateConfig } from 'rc-picker/lib/generate/index';
import {
PickerBaseProps as RCPickerBaseProps,
PickerDateProps as RCPickerDateProps,
PickerTimeProps as RCPickerTimeProps,
} from 'rc-picker/lib/Picker';
import { SharedTimeProps } from 'rc-picker/lib/panels/TimePanel';
import {
RangePickerBaseProps as RCRangePickerBaseProps,
RangePickerDateProps as RCRangePickerDateProps,
RangePickerTimeProps as RCRangePickerTimeProps,
} from 'rc-picker/lib/RangePicker';
import { PickerMode, Locale as RcPickerLocale } from 'rc-picker/lib/interface';
import { SizeType } from '../../config-provider/SizeContext';
import PickerButton from '../PickerButton';
import PickerTag from '../PickerTag';
import { TimePickerLocale } from '../../time-picker';
import generateSinglePicker from './generateSinglePicker';
import generateRangePicker from './generateRangePicker';
export const Components = { button: PickerButton, rangeItem: PickerTag };
function toArray<T>(list: T | T[]): T[] {
if (!list) {
return [];
}
return Array.isArray(list) ? list : [list];
}
export function getTimeProps<DateType>(
props: { format?: string; picker?: PickerMode } & SharedTimeProps<DateType>,
) {
const { format, picker, showHour, showMinute, showSecond, use12Hours } = props;
const firstFormat = toArray(format)[0];
const showTimeObj: SharedTimeProps<DateType> = { ...props };
if (firstFormat) {
if (!firstFormat.includes('s') && showSecond === undefined) {
showTimeObj.showSecond = false;
}
if (!firstFormat.includes('m') && showMinute === undefined) {
showTimeObj.showMinute = false;
}
if (!firstFormat.includes('H') && !firstFormat.includes('h') && showHour === undefined) {
showTimeObj.showHour = false;
}
if ((firstFormat.includes('a') || firstFormat.includes('A')) && use12Hours === undefined) {
showTimeObj.use12Hours = true;
}
}
if (picker === 'time') {
return showTimeObj;
}
return {
showTime: showTimeObj,
};
}
type InjectDefaultProps<Props> = Omit<
Props,
| 'locale'
| 'generateConfig'
| 'prevIcon'
| 'nextIcon'
| 'superPrevIcon'
| 'superNextIcon'
| 'hideHeader'
| 'components'
> & {
locale?: PickerLocale;
size?: SizeType;
bordered?: boolean;
};
export type PickerLocale = {
lang: RcPickerLocale & AdditionalPickerLocaleLangProps;
timePickerLocale: TimePickerLocale;
} & AdditionalPickerLocaleProps;
export type AdditionalPickerLocaleProps = {
dateFormat?: string;
dateTimeFormat?: string;
weekFormat?: string;
monthFormat?: string;
};
export type AdditionalPickerLocaleLangProps = {
placeholder: string;
yearPlaceholder?: string;
quarterPlaceholder?: string;
monthPlaceholder?: string;
weekPlaceholder?: string;
rangeYearPlaceholder?: [string, string];
rangeMonthPlaceholder?: [string, string];
rangeWeekPlaceholder?: [string, string];
rangePlaceholder?: [string, string];
};
// Picker Props
export type PickerBaseProps<DateType> = InjectDefaultProps<RCPickerBaseProps<DateType>>;
export type PickerDateProps<DateType> = InjectDefaultProps<RCPickerDateProps<DateType>>;
export type PickerTimeProps<DateType> = InjectDefaultProps<RCPickerTimeProps<DateType>>;
export type PickerProps<DateType> =
| PickerBaseProps<DateType>
| PickerDateProps<DateType>
| PickerTimeProps<DateType>;
// Range Picker Props
export type RangePickerBaseProps<DateType> = InjectDefaultProps<RCRangePickerBaseProps<DateType>>;
export type RangePickerDateProps<DateType> = InjectDefaultProps<RCRangePickerDateProps<DateType>>;
export type RangePickerTimeProps<DateType> = InjectDefaultProps<RCRangePickerTimeProps<DateType>>;
export type RangePickerProps<DateType> =
| RangePickerBaseProps<DateType>
| RangePickerDateProps<DateType>
| RangePickerTimeProps<DateType>;
function generatePicker<DateType>(generateConfig: GenerateConfig<DateType>) {
// =========================== Picker ===========================
const { DatePicker, WeekPicker, MonthPicker, YearPicker, TimePicker } = generateSinglePicker(
generateConfig,
);
// ======================== Range Picker ========================
const RangePicker = generateRangePicker(generateConfig);
// =========================== Export ===========================
type MergedDatePicker = typeof DatePicker & {
WeekPicker: typeof WeekPicker;
MonthPicker: typeof MonthPicker;
YearPicker: typeof YearPicker;
RangePicker: React.ComponentClass<RangePickerProps<DateType>>;
TimePicker: typeof TimePicker;
};
const MergedDatePicker = DatePicker as MergedDatePicker;
MergedDatePicker.WeekPicker = WeekPicker;
MergedDatePicker.MonthPicker = MonthPicker;
MergedDatePicker.YearPicker = YearPicker;
MergedDatePicker.RangePicker = RangePicker;
MergedDatePicker.TimePicker = TimePicker;
return MergedDatePicker;
}
export default generatePicker;

View File

@ -126,15 +126,35 @@
}
&-separator {
position: relative;
display: inline-block;
align-self: center;
width: 2em;
width: 1em;
height: @font-size-lg;
color: @disabled-color;
font-size: @font-size-lg;
line-height: @font-size-lg;
text-align: center;
vertical-align: top;
cursor: default;
&::before,
&::after {
position: absolute;
border-top: 1px solid #979797;
content: '';
}
&::before {
top: 50%;
left: 0.1em;
width: 0.8em;
}
&::after {
top: 50%;
right: 0.11em;
width: 0.8em;
width: 0.3em;
transform: rotate(45deg);
transform-origin: 100% 100%;
}
.@{picker-prefix-cls}-range-separator & {
.@{picker-prefix-cls}-disabled & {
cursor: not-allowed;
@ -174,6 +194,12 @@
opacity: 1;
}
}
&-separator {
align-items: center;
padding: 0 @padding-xs;
line-height: 1;
}
}
// ======================= Dropdown =======================

View File

@ -3552,10 +3552,9 @@ exports[`renders ./components/form/demo/time-related-controls.md correctly 1`] =
class="ant-picker-range-separator"
>
<span
aria-label="to"
class="ant-picker-separator"
>
</span>
/>
</div>
<div
class="ant-picker-input"
@ -3640,10 +3639,9 @@ exports[`renders ./components/form/demo/time-related-controls.md correctly 1`] =
class="ant-picker-range-separator"
>
<span
aria-label="to"
class="ant-picker-separator"
>
</span>
/>
</div>
<div
class="ant-picker-input"

View File

@ -84,7 +84,7 @@ Form field component for data bidirectional binding, validation, layout, and so
| normalize | Normalize value to form component | (value, prevValue, prevValues) => any | - |
| required | Whether provided or not, it will be generated by the validation rule | boolean | false |
| rules | Rules for field validation. Click [here](#components-form-demo-basic) to see an example | [Rule](#Rule)[] | - |
| shouldUpdate | Custom field update logic. See [bellow](#shouldUpdate) | boolean \| (prevValue, curValue) => boolean | false |
| shouldUpdate | Custom field update logic. See [below](#shouldUpdate) | boolean \| (prevValue, curValue) => boolean | false |
| trigger | When to collect the value of children node | string | onChange |
| validateFirst | Whether stop validate on first rule of error for this field | boolean | false |
| validateStatus | The validation status. If not provided, it will be generated by validation rule. options: 'success' 'warning' 'error' 'validating' | string | - |

View File

@ -700,10 +700,9 @@ exports[`renders ./components/input/demo/align.md correctly 1`] = `
class="ant-picker-range-separator"
>
<span
aria-label="to"
class="ant-picker-separator"
>
</span>
/>
</div>
<div
class="ant-picker-input"

View File

@ -4,6 +4,10 @@
@menu-prefix-cls: ~'@{ant-prefix}-menu';
.@{menu-prefix-cls} {
&-rtl {
direction: rtl;
}
&-item-group-title {
.@{menu-prefix-cls}-rtl & {
text-align: right;

View File

@ -11,7 +11,7 @@
// -------- Colors -----------
@primary-color: @blue-6;
@info-color: @blue-6;
@info-color: @primary-color;
@success-color: @green-6;
@processing-color: @blue-6;
@error-color: @red-5;

View File

@ -11,12 +11,7 @@ import ConfigProvider from '../../config-provider';
const nativeEvent = { nativeEvent: { stopImmediatePropagation: () => {} } };
function getDropdownWrapper(wrapper) {
return mount(
wrapper
.find('Trigger')
.instance()
.getComponent(),
);
return mount(wrapper.find('Trigger').instance().getComponent());
}
describe('Table.filter', () => {
@ -62,6 +57,18 @@ describe('Table.filter', () => {
return wrapper.find('BodyRow').map(row => row.props().record.name);
}
it('not show filter icon when undefined', () => {
const noFilterColumn = { ...column, filters: undefined };
delete noFilterColumn.onFilter;
const wrapper = mount(
createTable({
columns: [noFilterColumn],
}),
);
expect(wrapper.find('.ant-table-filter-column')).toHaveLength(0);
});
it('renders filter correctly', () => {
const wrapper = mount(createTable());
@ -213,7 +220,10 @@ describe('Table.filter', () => {
expect(wrapper.find('FilterDropdown').props().filterState.filteredKeys).toBeFalsy();
wrapper.find('FilterDropdown').find('input[type="checkbox"]').first().simulate('click');
wrapper.find('FilterDropdown').find('.ant-table-filter-dropdown-btns .ant-btn-primary').simulate('click');
wrapper
.find('FilterDropdown')
.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' }] });
expect(wrapper.find('FilterDropdown').props().filterState.filteredKeys).toEqual(['boy']);
@ -342,7 +352,10 @@ describe('Table.filter', () => {
const wrapper = mount(createTable({ onChange: handleChange }));
wrapper.find('.ant-dropdown-trigger').first().simulate('click');
wrapper.find('FilterDropdown').find('MenuItem').first().simulate('click');
wrapper.find('FilterDropdown').find('.ant-table-filter-dropdown-btns .ant-btn-primary').simulate('click');
wrapper
.find('FilterDropdown')
.find('.ant-table-filter-dropdown-btns .ant-btn-primary')
.simulate('click');
expect(handleChange).toHaveBeenCalledWith(
{},
{ name: ['boy'] },
@ -358,12 +371,15 @@ describe('Table.filter', () => {
const wrapper = mount(createTable({ pagination: { onChange: onPaginationChange } }));
wrapper.find('.ant-dropdown-trigger').first().simulate('click');
wrapper.find('FilterDropdown').find('MenuItem').first().simulate('click');
wrapper.find('FilterDropdown').find('.ant-table-filter-dropdown-btns .ant-btn-primary').simulate('click');
wrapper
.find('FilterDropdown')
.find('.ant-table-filter-dropdown-btns .ant-btn-primary')
.simulate('click');
expect(onPaginationChange).toHaveBeenCalledWith(1, 10);
});
it('should not fire change event on close filterDropdown without changing anything', () => {
it('should not fire change event when close filterDropdown without changing anything', () => {
const handleChange = jest.fn();
const wrapper = mount(createTable({ onChange: handleChange }));
@ -373,6 +389,26 @@ describe('Table.filter', () => {
expect(handleChange).not.toHaveBeenCalled();
});
it('should not fire change event when close a filtered filterDropdown without changing anything', () => {
const handleChange = jest.fn();
const wrapper = mount(
createTable({
onChange: handleChange,
columns: [
{
...column,
defaultFilteredValue: ['boy', 'designer'],
},
],
}),
);
wrapper.find('.ant-dropdown-trigger').first().simulate('click');
wrapper.find('.ant-table-filter-dropdown-btns .ant-btn-primary').simulate('click');
expect(handleChange).not.toHaveBeenCalled();
});
it('three levels menu', () => {
const filters = [
{ text: 'Upper', value: 'Upper' },
@ -410,29 +446,17 @@ describe('Table.filter', () => {
let dropdownWrapper = getDropdownWrapper(wrapper);
expect(renderedNames(wrapper)).toEqual(['Jack', 'Lucy', 'Tom', 'Jerry']);
// select
dropdownWrapper
.find('.ant-dropdown-menu-submenu-title')
.at(0)
.simulate('mouseEnter');
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');
dropdownWrapper.find('.ant-dropdown-menu-submenu-title').at(1).simulate('mouseEnter');
jest.runAllTimers();
dropdownWrapper = getDropdownWrapper(wrapper);
dropdownWrapper
.find('MenuItem')
.last()
.simulate('click');
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');
dropdownWrapper.find('MenuItem').last().simulate('click');
jest.useRealTimers();
});
@ -1060,12 +1084,9 @@ describe('Table.filter', () => {
expect(wrapper.find('.ant-table-filter-dropdown-btns .ant-btn-primary').text()).toEqual(
'Bamboo',
);
expect(
wrapper
.find('.ant-table-filter-dropdown-btns .ant-btn-link')
.last()
.text(),
).toEqual('Reset');
expect(wrapper.find('.ant-table-filter-dropdown-btns .ant-btn-link').last().text()).toEqual(
'Reset',
);
});
it('filtered should work', () => {

View File

@ -429,6 +429,7 @@ describe('Table.rowSelection', () => {
const wrapper = render(
createTable({
rowSelection: { fixed: true },
scroll: { x: 903 },
}),
);
@ -444,6 +445,7 @@ describe('Table.rowSelection', () => {
},
},
rowSelection: { fixed: true },
scroll: { x: 903 },
}),
);
@ -461,6 +463,7 @@ describe('Table.rowSelection', () => {
fixed: 'left',
},
],
scroll: { x: 903 },
}),
);

View File

@ -155,38 +155,37 @@ describe('Table.sorter', () => {
jest.useFakeTimers();
const wrapper = mount(createTable({}));
// default show sorter tooltip
wrapper.find('.ant-table-column-sorters').simulate('mouseenter');
wrapper.find('.ant-table-column-sorters-with-tooltip').simulate('mouseenter');
jest.runAllTimers();
wrapper.update();
expect(wrapper.find('.ant-tooltip-open').length).toBeTruthy();
wrapper.find('.ant-table-column-sorters').simulate('mouseout');
wrapper.find('.ant-table-column-sorters-with-tooltip').simulate('mouseout');
// set table props showSorterTooltip is false
wrapper.setProps({ showSorterTooltip: false });
wrapper.find('.ant-table-column-sorters').simulate('mouseenter');
expect(wrapper.find('.ant-table-column-sorters-with-tooltip')).toHaveLength(0);
jest.runAllTimers();
wrapper.update();
expect(wrapper.find('.ant-tooltip-open').length).toBeFalsy();
wrapper.find('.ant-table-column-sorters').simulate('mouseout');
expect(wrapper.find('.ant-tooltip-open')).toHaveLength(0);
// 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');
wrapper.find('.ant-table-column-sorters-with-tooltip').simulate('mouseenter');
jest.runAllTimers();
wrapper.update();
expect(wrapper.find('.ant-tooltip-open').length).toBeTruthy();
wrapper.find('.ant-table-column-sorters').simulate('mouseout');
wrapper.find('.ant-table-column-sorters-with-tooltip').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');
expect(wrapper.find('.ant-table-column-sorters-with-tooltip')).toHaveLength(0);
jest.runAllTimers();
wrapper.update();
expect(wrapper.find('.ant-tooltip-open').length).toBeFalsy();
wrapper.find('.ant-table-column-sorters').simulate('mouseout');
expect(wrapper.find('.ant-tooltip-open')).toHaveLength(0);
});
it('works with grouping columns in controlled mode', () => {

View File

@ -11,16 +11,17 @@ exports[`Table.rowSelection fix expand on th left when selection column fixed on
class="ant-spin-container"
>
<div
class="ant-table ant-table-has-fix-left"
class="ant-table ant-table-fixed-column ant-table-scroll-horizontal ant-table-has-fix-left"
>
<div
class="ant-table-container"
>
<div
class="ant-table-content"
style="overflow-x:scroll;overflow-y:hidden"
>
<table
style="table-layout:fixed"
style="width:903px;min-width:100%;table-layout:fixed"
>
<colgroup>
<col
@ -72,6 +73,21 @@ exports[`Table.rowSelection fix expand on th left when selection column fixed on
<tbody
class="ant-table-tbody"
>
<tr
aria-hidden="true"
class="ant-table-measure-row"
style="height:0"
>
<td
style="padding:0;border:0;height:0"
/>
<td
style="padding:0;border:0;height:0"
/>
<td
style="padding:0;border:0;height:0"
/>
</tr>
<tr
class="ant-table-row ant-table-row-level-0"
data-row-key="0"
@ -329,16 +345,17 @@ exports[`Table.rowSelection fix selection column on the left 1`] = `
class="ant-spin-container"
>
<div
class="ant-table ant-table-has-fix-left"
class="ant-table ant-table-fixed-column ant-table-scroll-horizontal ant-table-has-fix-left"
>
<div
class="ant-table-container"
>
<div
class="ant-table-content"
style="overflow-x:scroll;overflow-y:hidden"
>
<table
style="table-layout:fixed"
style="width:903px;min-width:100%;table-layout:fixed"
>
<colgroup>
<col
@ -383,6 +400,18 @@ exports[`Table.rowSelection fix selection column on the left 1`] = `
<tbody
class="ant-table-tbody"
>
<tr
aria-hidden="true"
class="ant-table-measure-row"
style="height:0"
>
<td
style="padding:0;border:0;height:0"
/>
<td
style="padding:0;border:0;height:0"
/>
</tr>
<tr
class="ant-table-row ant-table-row-level-0"
data-row-key="0"
@ -600,16 +629,17 @@ exports[`Table.rowSelection fix selection column on the left when any other colu
class="ant-spin-container"
>
<div
class="ant-table ant-table-has-fix-left"
class="ant-table ant-table-fixed-column ant-table-scroll-horizontal ant-table-has-fix-left"
>
<div
class="ant-table-container"
>
<div
class="ant-table-content"
style="overflow-x:scroll;overflow-y:hidden"
>
<table
style="table-layout:fixed"
style="width:903px;min-width:100%;table-layout:fixed"
>
<colgroup>
<col
@ -655,6 +685,18 @@ exports[`Table.rowSelection fix selection column on the left when any other colu
<tbody
class="ant-table-tbody"
>
<tr
aria-hidden="true"
class="ant-table-measure-row"
style="height:0"
>
<td
style="padding:0;border:0;height:0"
/>
<td
style="padding:0;border:0;height:0"
/>
</tr>
<tr
class="ant-table-row ant-table-row-level-0"
data-row-key="0"

View File

@ -7,6 +7,9 @@ exports[`Table.sorter renders sorter icon correctly 1`] = `
<tr>
<th
class="ant-table-cell ant-table-column-has-sorters"
>
<div
class="ant-table-column-sorters-with-tooltip"
>
<div
class="ant-table-column-sorters"
@ -63,6 +66,7 @@ exports[`Table.sorter renders sorter icon correctly 1`] = `
</span>
</span>
</div>
</div>
</th>
</tr>
</thead>
@ -97,6 +101,9 @@ exports[`Table.sorter should support defaultOrder in Column 1`] = `
<tr>
<th
class="ant-table-cell ant-table-column-sort ant-table-column-has-sorters"
>
<div
class="ant-table-column-sorters-with-tooltip"
>
<div
class="ant-table-column-sorters"
@ -153,6 +160,7 @@ exports[`Table.sorter should support defaultOrder in Column 1`] = `
</span>
</span>
</div>
</div>
</th>
</tr>
</thead>

View File

@ -36,6 +36,9 @@ exports[`renders ./components/table/demo/ajax.md correctly 1`] = `
<tr>
<th
class="ant-table-cell ant-table-column-has-sorters"
>
<div
class="ant-table-column-sorters-with-tooltip"
>
<div
class="ant-table-column-sorters"
@ -92,6 +95,7 @@ exports[`renders ./components/table/demo/ajax.md correctly 1`] = `
</span>
</span>
</div>
</div>
</th>
<th
class="ant-table-cell"
@ -2307,19 +2311,211 @@ exports[`renders ./components/table/demo/dynamic-settings.md correctly 1`] = `
Name
</th>
<th
class="ant-table-cell"
class="ant-table-cell ant-table-column-has-sorters"
>
<div
class="ant-table-column-sorters-with-tooltip"
>
<div
class="ant-table-column-sorters"
>
<span>
Age
</span>
<span
class="ant-table-column-sorter ant-table-column-sorter-full"
>
<span
class="ant-table-column-sorter-inner"
>
<span
aria-label="caret-up"
class="anticon anticon-caret-up ant-table-column-sorter-up"
role="img"
>
<svg
aria-hidden="true"
class=""
data-icon="caret-up"
fill="currentColor"
focusable="false"
height="1em"
viewBox="0 0 1024 1024"
width="1em"
>
<path
d="M858.9 689L530.5 308.2c-9.4-10.9-27.5-10.9-37 0L165.1 689c-12.2 14.2-1.2 35 18.5 35h656.8c19.7 0 30.7-20.8 18.5-35z"
/>
</svg>
</span>
<span
aria-label="caret-down"
class="anticon anticon-caret-down ant-table-column-sorter-down"
role="img"
>
<svg
aria-hidden="true"
class=""
data-icon="caret-down"
fill="currentColor"
focusable="false"
height="1em"
viewBox="0 0 1024 1024"
width="1em"
>
<path
d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"
/>
</svg>
</span>
</span>
</span>
</div>
</div>
</th>
<th
class="ant-table-cell"
>
<div
class="ant-table-filter-column"
>
<span
class="ant-table-filter-column-title"
>
Address
</span>
<span
class="ant-table-filter-trigger-container"
>
<span
class="ant-table-filter-trigger ant-dropdown-trigger"
role="button"
tabindex="-1"
>
<span
aria-label="filter"
class="anticon anticon-filter"
role="img"
>
<svg
aria-hidden="true"
class=""
data-icon="filter"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M349 838c0 17.7 14.2 32 31.8 32h262.4c17.6 0 31.8-14.3 31.8-32V642H349v196zm531.1-684H143.9c-24.5 0-39.8 26.7-27.5 48l221.3 376h348.8l221.3-376c12.1-21.3-3.2-48-27.7-48z"
/>
</svg>
</span>
</span>
</span>
</div>
</th>
<th
class="ant-table-cell"
class="ant-table-cell ant-table-column-has-sorters"
>
<div
class="ant-table-filter-column"
>
<span
class="ant-table-filter-column-title"
>
<div
class="ant-table-column-sorters-with-tooltip"
>
<div
class="ant-table-column-sorters"
>
<span>
Action
</span>
<span
class="ant-table-column-sorter ant-table-column-sorter-full"
>
<span
class="ant-table-column-sorter-inner"
>
<span
aria-label="caret-up"
class="anticon anticon-caret-up ant-table-column-sorter-up"
role="img"
>
<svg
aria-hidden="true"
class=""
data-icon="caret-up"
fill="currentColor"
focusable="false"
height="1em"
viewBox="0 0 1024 1024"
width="1em"
>
<path
d="M858.9 689L530.5 308.2c-9.4-10.9-27.5-10.9-37 0L165.1 689c-12.2 14.2-1.2 35 18.5 35h656.8c19.7 0 30.7-20.8 18.5-35z"
/>
</svg>
</span>
<span
aria-label="caret-down"
class="anticon anticon-caret-down ant-table-column-sorter-down"
role="img"
>
<svg
aria-hidden="true"
class=""
data-icon="caret-down"
fill="currentColor"
focusable="false"
height="1em"
viewBox="0 0 1024 1024"
width="1em"
>
<path
d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"
/>
</svg>
</span>
</span>
</span>
</div>
</div>
</span>
<span
class="ant-table-filter-trigger-container"
>
<span
class="ant-table-filter-trigger ant-dropdown-trigger"
role="button"
tabindex="-1"
>
<span
aria-label="filter"
class="anticon anticon-filter"
role="img"
>
<svg
aria-hidden="true"
class=""
data-icon="filter"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M349 838c0 17.7 14.2 32 31.8 32h262.4c17.6 0 31.8-14.3 31.8-32V642H349v196zm531.1-684H143.9c-24.5 0-39.8 26.7-27.5 48l221.3 376h348.8l221.3-376c12.1-21.3-3.2-48-27.7-48z"
/>
</svg>
</span>
</span>
</span>
</div>
</th>
</tr>
</thead>
@ -2361,9 +2557,7 @@ exports[`renders ./components/table/demo/dynamic-settings.md correctly 1`] = `
<td
class="ant-table-cell"
>
<a>
John Brown
</a>
</td>
<td
class="ant-table-cell"
@ -2447,9 +2641,7 @@ exports[`renders ./components/table/demo/dynamic-settings.md correctly 1`] = `
<td
class="ant-table-cell"
>
<a>
John Brown
</a>
</td>
<td
class="ant-table-cell"
@ -2533,9 +2725,7 @@ exports[`renders ./components/table/demo/dynamic-settings.md correctly 1`] = `
<td
class="ant-table-cell"
>
<a>
John Brown
</a>
</td>
<td
class="ant-table-cell"
@ -2619,9 +2809,7 @@ exports[`renders ./components/table/demo/dynamic-settings.md correctly 1`] = `
<td
class="ant-table-cell"
>
<a>
John Brown
</a>
</td>
<td
class="ant-table-cell"
@ -2705,9 +2893,7 @@ exports[`renders ./components/table/demo/dynamic-settings.md correctly 1`] = `
<td
class="ant-table-cell"
>
<a>
John Brown
</a>
</td>
<td
class="ant-table-cell"
@ -2791,9 +2977,7 @@ exports[`renders ./components/table/demo/dynamic-settings.md correctly 1`] = `
<td
class="ant-table-cell"
>
<a>
John Brown
</a>
</td>
<td
class="ant-table-cell"
@ -2877,9 +3061,7 @@ exports[`renders ./components/table/demo/dynamic-settings.md correctly 1`] = `
<td
class="ant-table-cell"
>
<a>
John Brown
</a>
</td>
<td
class="ant-table-cell"
@ -2963,9 +3145,7 @@ exports[`renders ./components/table/demo/dynamic-settings.md correctly 1`] = `
<td
class="ant-table-cell"
>
<a>
John Brown
</a>
</td>
<td
class="ant-table-cell"
@ -3049,9 +3229,7 @@ exports[`renders ./components/table/demo/dynamic-settings.md correctly 1`] = `
<td
class="ant-table-cell"
>
<a>
John Brown
</a>
</td>
<td
class="ant-table-cell"
@ -3135,9 +3313,7 @@ exports[`renders ./components/table/demo/dynamic-settings.md correctly 1`] = `
<td
class="ant-table-cell"
>
<a>
John Brown
</a>
</td>
<td
class="ant-table-cell"
@ -4903,7 +5079,7 @@ exports[`renders ./components/table/demo/fixed-columns.md correctly 1`] = `
class="ant-spin-container"
>
<div
class="ant-table ant-table-fixed-column ant-table-has-fix-left ant-table-has-fix-right"
class="ant-table ant-table-fixed-column ant-table-scroll-horizontal ant-table-has-fix-left ant-table-has-fix-right"
>
<div
class="ant-table-container"
@ -5267,7 +5443,7 @@ exports[`renders ./components/table/demo/fixed-columns-header.md correctly 1`] =
class="ant-spin-container"
>
<div
class="ant-table ant-table-fixed-header ant-table-fixed-column ant-table-has-fix-left ant-table-has-fix-right"
class="ant-table ant-table-fixed-header ant-table-fixed-column ant-table-scroll-horizontal ant-table-has-fix-left ant-table-has-fix-right"
>
<div
class="ant-table-container"
@ -7556,7 +7732,7 @@ exports[`renders ./components/table/demo/grouping-columns.md correctly 1`] = `
class="ant-spin-container"
>
<div
class="ant-table ant-table-middle ant-table-bordered ant-table-fixed-header ant-table-fixed-column ant-table-has-fix-left ant-table-has-fix-right"
class="ant-table ant-table-middle ant-table-bordered ant-table-fixed-header ant-table-fixed-column ant-table-scroll-horizontal ant-table-has-fix-left ant-table-has-fix-right"
>
<div
class="ant-table-container"
@ -7642,6 +7818,9 @@ exports[`renders ./components/table/demo/grouping-columns.md correctly 1`] = `
<th
class="ant-table-cell ant-table-column-has-sorters"
rowspan="3"
>
<div
class="ant-table-column-sorters-with-tooltip"
>
<div
class="ant-table-column-sorters"
@ -7698,6 +7877,7 @@ exports[`renders ./components/table/demo/grouping-columns.md correctly 1`] = `
</span>
</span>
</div>
</div>
</th>
<th
class="ant-table-cell"
@ -8547,6 +8727,9 @@ exports[`renders ./components/table/demo/head.md correctly 1`] = `
>
<span
class="ant-table-filter-column-title"
>
<div
class="ant-table-column-sorters-with-tooltip"
>
<div
class="ant-table-column-sorters"
@ -8583,6 +8766,7 @@ exports[`renders ./components/table/demo/head.md correctly 1`] = `
</span>
</span>
</div>
</div>
</span>
<span
class="ant-table-filter-trigger-container"
@ -8618,6 +8802,9 @@ exports[`renders ./components/table/demo/head.md correctly 1`] = `
</th>
<th
class="ant-table-cell ant-table-column-sort ant-table-column-has-sorters"
>
<div
class="ant-table-column-sorters-with-tooltip"
>
<div
class="ant-table-column-sorters"
@ -8674,6 +8861,7 @@ exports[`renders ./components/table/demo/head.md correctly 1`] = `
</span>
</span>
</div>
</div>
</th>
<th
class="ant-table-cell ant-table-column-has-sorters"
@ -8683,6 +8871,9 @@ exports[`renders ./components/table/demo/head.md correctly 1`] = `
>
<span
class="ant-table-filter-column-title"
>
<div
class="ant-table-column-sorters-with-tooltip"
>
<div
class="ant-table-column-sorters"
@ -8739,6 +8930,7 @@ exports[`renders ./components/table/demo/head.md correctly 1`] = `
</span>
</span>
</div>
</div>
</span>
<span
class="ant-table-filter-trigger-container"
@ -9297,6 +9489,9 @@ exports[`renders ./components/table/demo/multiple-sorter.md correctly 1`] = `
</th>
<th
class="ant-table-cell ant-table-column-has-sorters"
>
<div
class="ant-table-column-sorters-with-tooltip"
>
<div
class="ant-table-column-sorters"
@ -9353,9 +9548,13 @@ exports[`renders ./components/table/demo/multiple-sorter.md correctly 1`] = `
</span>
</span>
</div>
</div>
</th>
<th
class="ant-table-cell ant-table-column-has-sorters"
>
<div
class="ant-table-column-sorters-with-tooltip"
>
<div
class="ant-table-column-sorters"
@ -9412,9 +9611,13 @@ exports[`renders ./components/table/demo/multiple-sorter.md correctly 1`] = `
</span>
</span>
</div>
</div>
</th>
<th
class="ant-table-cell ant-table-column-has-sorters"
>
<div
class="ant-table-column-sorters-with-tooltip"
>
<div
class="ant-table-column-sorters"
@ -9471,6 +9674,7 @@ exports[`renders ./components/table/demo/multiple-sorter.md correctly 1`] = `
</span>
</span>
</div>
</div>
</th>
</tr>
</thead>
@ -10578,6 +10782,9 @@ exports[`renders ./components/table/demo/reset-filter.md correctly 1`] = `
>
<span
class="ant-table-filter-column-title"
>
<div
class="ant-table-column-sorters-with-tooltip"
>
<div
class="ant-table-column-sorters"
@ -10634,6 +10841,7 @@ exports[`renders ./components/table/demo/reset-filter.md correctly 1`] = `
</span>
</span>
</div>
</div>
</span>
<span
class="ant-table-filter-trigger-container"
@ -10669,6 +10877,9 @@ exports[`renders ./components/table/demo/reset-filter.md correctly 1`] = `
</th>
<th
class="ant-table-cell ant-table-cell-ellipsis ant-table-column-has-sorters"
>
<div
class="ant-table-column-sorters-with-tooltip"
>
<div
class="ant-table-column-sorters"
@ -10725,6 +10936,7 @@ exports[`renders ./components/table/demo/reset-filter.md correctly 1`] = `
</span>
</span>
</div>
</div>
</th>
<th
class="ant-table-cell ant-table-cell-ellipsis ant-table-column-has-sorters"
@ -10734,6 +10946,9 @@ exports[`renders ./components/table/demo/reset-filter.md correctly 1`] = `
>
<span
class="ant-table-filter-column-title"
>
<div
class="ant-table-column-sorters-with-tooltip"
>
<div
class="ant-table-column-sorters"
@ -10790,6 +11005,7 @@ exports[`renders ./components/table/demo/reset-filter.md correctly 1`] = `
</span>
</span>
</div>
</div>
</span>
<span
class="ant-table-filter-trigger-container"
@ -11054,6 +11270,9 @@ exports[`renders ./components/table/demo/resizable-column.md correctly 1`] = `
</th>
<th
class="ant-table-cell ant-table-column-has-sorters react-resizable"
>
<div
class="ant-table-column-sorters-with-tooltip"
>
<div
class="ant-table-column-sorters"
@ -11110,6 +11329,7 @@ exports[`renders ./components/table/demo/resizable-column.md correctly 1`] = `
</span>
</span>
</div>
</div>
<span
class="react-resizable-handle react-resizable-handle-se"
style="touch-action:none"
@ -13886,7 +14106,7 @@ exports[`renders ./components/table/demo/virtual-list.md correctly 1`] = `
class="ant-spin-container"
>
<div
class="ant-table ant-table-fixed-header ant-table-fixed-column"
class="ant-table ant-table-fixed-header ant-table-scroll-horizontal"
>
<div
class="ant-table-container"

View File

@ -240,16 +240,17 @@ exports[`Table renders empty table with fixed columns 1`] = `
class="ant-spin-container"
>
<div
class="ant-table ant-table-has-fix-left ant-table-has-fix-right"
class="ant-table ant-table-fixed-column ant-table-scroll-horizontal ant-table-has-fix-left ant-table-has-fix-right"
>
<div
class="ant-table-container"
>
<div
class="ant-table-content"
style="overflow-x:scroll;overflow-y:hidden"
>
<table
style="table-layout:fixed"
style="width:1px;min-width:100%;table-layout:fixed"
>
<colgroup>
<col
@ -337,12 +338,55 @@ exports[`Table renders empty table with fixed columns 1`] = `
<tbody
class="ant-table-tbody"
>
<tr
aria-hidden="true"
class="ant-table-measure-row"
style="height:0"
>
<td
style="padding:0;border:0;height:0"
/>
<td
style="padding:0;border:0;height:0"
/>
<td
style="padding:0;border:0;height:0"
/>
<td
style="padding:0;border:0;height:0"
/>
<td
style="padding:0;border:0;height:0"
/>
<td
style="padding:0;border:0;height:0"
/>
<td
style="padding:0;border:0;height:0"
/>
<td
style="padding:0;border:0;height:0"
/>
<td
style="padding:0;border:0;height:0"
/>
<td
style="padding:0;border:0;height:0"
/>
<td
style="padding:0;border:0;height:0"
/>
</tr>
<tr
class="ant-table-placeholder"
>
<td
class="ant-table-cell"
colspan="11"
>
<div
class="ant-table-expanded-row-fixed"
style="width:0;position:sticky;left:0;overflow:hidden"
>
<div
class="ant-empty ant-empty-normal"
@ -390,6 +434,7 @@ exports[`Table renders empty table with fixed columns 1`] = `
No Data
</p>
</div>
</div>
</td>
</tr>
</tbody>

View File

@ -51,7 +51,9 @@ describe('Table', () => {
});
it('renders empty table with fixed columns', () => {
const wrapper = render(<Table dataSource={[]} columns={columnsFixed} pagination={false} />);
const wrapper = render(
<Table dataSource={[]} columns={columnsFixed} pagination={false} scroll={{ x: 1 }} />,
);
expect(wrapper).toMatchSnapshot();
});

View File

@ -21,22 +21,33 @@ const columns = [
{
title: 'Name',
dataIndex: 'name',
key: 'name',
render: text => <a>{text}</a>,
},
{
title: 'Age',
dataIndex: 'age',
key: 'age',
sorter: (a, b) => a.age - b.age,
},
{
title: 'Address',
dataIndex: 'address',
key: 'address',
filters: [
{
text: 'London',
value: 'London',
},
{
text: 'New York',
value: 'New York',
},
],
onFilter: (value, record) => record.address.indexOf(value) === 0,
},
{
title: 'Action',
key: 'action',
sorter: true,
filters: [],
onFilter: () => {},
render: () => (
<span>
<a style={{ marginRight: 16 }}>Delete</a>

View File

@ -1,5 +1,6 @@
import * as React from 'react';
import classNames from 'classnames';
import isEqual from 'lodash/isEqual';
import FilterFilled from '@ant-design/icons/FilterFilled';
import Button from '../../../button';
import Menu from '../../../menu';
@ -131,6 +132,10 @@ function FilterDropdown<RecordType>(props: FilterDropdownProps<RecordType>) {
return null;
}
if (isEqual(mergedKeys, filterState?.filteredKeys)) {
return null;
}
triggerFilter({
column,
key: columnKey,

View File

@ -31,7 +31,7 @@ function collectFilterStates<RecordType>(
if ('children' in column) {
filterStates = [...filterStates, ...collectFilterStates(column.children, init, columnPos)];
} else if ('filters' in column || 'filterDropdown' in column || 'onFilter' in column) {
} else if (column.filters || 'filterDropdown' in column || 'onFilter' in column) {
if ('filteredValue' in column) {
// Controlled
filterStates.push({
@ -70,7 +70,7 @@ function injectFilter<RecordType>(
const columnPos = getColumnPos(index, pos);
const { filterMultiple = true } = column as ColumnType<RecordType>;
if ('filters' in column || 'filterDropdown' in column) {
if (column.filters || 'filterDropdown' in column) {
const columnKey = getColumnKey(column, columnPos);
const filterState = filterStates.find(({ key }) => columnKey === key);

View File

@ -167,7 +167,9 @@ function injectSorter<RecordType>(
</div>
);
return showSorterTooltip ? (
<Tooltip title={sortTip}>{renderSortTitle}</Tooltip>
<Tooltip title={sortTip}>
<div className={`${prefixCls}-column-sorters-with-tooltip`}>{renderSortTitle}</div>
</Tooltip>
) : (
renderSortTitle
);

View File

@ -92,14 +92,14 @@ Same as `onRow` `onHeaderRow` `onCell` `onHeaderCell`
<Table
onRow={(record, rowIndex) => {
return {
onClick: (event) => {}, // click row
onDoubleClick: (event) => {}, // double click row
onContextMenu: (event) => {}, // right button click row
onMouseEnter: (event) => {}, // mouse enter row
onMouseLeave: (event) => {}, // mouse leave row
onClick: event => {}, // click row
onDoubleClick: event => {}, // double click row
onContextMenu: event => {}, // right button click row
onMouseEnter: event => {}, // mouse enter row
onMouseLeave: event => {}, // mouse leave row
};
}}
onHeaderRow={(column) => {
onHeaderRow={column => {
return {
onClick: () => {}, // click header row
};
@ -265,7 +265,7 @@ If `dataSource[i].key` is not provided, then you should specify the primary key
// primary key is uid
return <Table rowKey="uid" />;
// or
return <Table rowKey={(record) => record.uid} />;
return <Table rowKey={record => record.uid} />;
```
## Migrate to v4
@ -276,6 +276,12 @@ Besides, the breaking change is changing `dataIndex` from nest string path like
## FAQ
### How to hide pagination when single page or not data
### How to hide pagination when single page or not data?
You can set `hideOnSinglePage` with `pagination` prop.
### Table will return to first page when filter data.
Table total page count usually reduce after filter data, we defaultly return to first page in case of current page is out of filtered results.
You may need to keep current page after filtering when fetch data from remote service, please check [this demo](https://codesandbox.io/s/yuanchengjiazaishuju-ant-design-demo-7y2uf) as workaround.

View File

@ -95,16 +95,16 @@ const columns = [
```jsx
<Table
onRow={(record) => {
onRow={record => {
return {
onClick: (event) => {}, // 点击行
onDoubleClick: (event) => {},
onContextMenu: (event) => {},
onMouseEnter: (event) => {}, // 鼠标移入行
onMouseLeave: (event) => {},
onClick: event => {}, // 点击行
onDoubleClick: event => {},
onContextMenu: event => {},
onMouseEnter: event => {}, // 鼠标移入行
onMouseLeave: event => {},
};
}}
onHeaderRow={(column) => {
onHeaderRow={column => {
return {
onClick: () => {}, // 点击表头行
};
@ -269,7 +269,7 @@ class NameColumn extends Table.Column<User> {}
// 比如你的数据主键是 uid
return <Table rowKey="uid" />;
// 或
return <Table rowKey={(record) => record.uid} />;
return <Table rowKey={record => record.uid} />;
```
## 从 v3 升级到 v4
@ -283,3 +283,9 @@ Table 移除了在 v3 中废弃的 `onRowClick`、`onRowDoubleClick`、`onRowMou
### 如何在没有数据或只有一页数据时隐藏分页栏
你可以设置 `pagination``hideOnSinglePage` 属性为 `true`
### 表格过滤时会回到第一页?
 前端过滤时通常条目总数会减少,从而导致总页数小于筛选前的当前页数,为了防止当前页面没有数据,我们默认会返回第一页。
如果你在使用远程分页,很可能需要保持当前页面,你可以参照这个 [受控例子](https://codesandbox.io/s/yuanchengjiazaishuju-ant-design-demo-7y2uf) 控制当前页面不变。

View File

@ -53,7 +53,7 @@
}
}
&.@{table-prefix-cls}-fixed-column {
&.@{table-prefix-cls}-scroll-horizontal {
tr.@{table-prefix-cls}-expanded-row,
tr.@{table-prefix-cls}-placeholder {
> td {

View File

@ -124,6 +124,7 @@
}
// ========================= Nest Table ===========================
.@{table-prefix-cls}-wrapper:only-child {
.@{table-prefix-cls} {
margin: -@table-padding-vertical -@table-padding-horizontal -@table-padding-vertical (@table-padding-horizontal +
ceil(@font-size-sm * 1.4));
@ -143,6 +144,7 @@
}
}
}
}
// =========================== Summary ============================
tfoot {
@ -199,10 +201,14 @@
background: @table-body-sort-bg;
}
&-column-sorters-with-tooltip {
display: inline-block;
width: 100%;
}
&-column-sorters {
display: inline-flex;
align-items: center;
width: 100%;
padding: @table-padding-vertical @table-padding-horizontal;
}
@ -249,6 +255,17 @@
padding: @table-padding-vertical 2.3em @table-padding-vertical @table-padding-horizontal;
}
// Remove padding when sorter also provided
&-thead tr th.@{table-prefix-cls}-column-has-sorters {
.@{table-prefix-cls}-filter-column {
margin: 0;
}
.@{table-prefix-cls}-filter-column-title {
padding: 0 2.3em 0 0;
}
}
&-filter-trigger-container {
position: absolute;
top: 0;
@ -361,7 +378,7 @@
top: 0;
right: -10px;
cursor: pointer;
transition: all .3s;
transition: all 0.3s;
.@{iconfont-css-prefix} {
.iconfont-size-under-12px(10px);

View File

@ -1,7 +1,7 @@
@import './index';
.table-size(@size, @padding-vertical, @padding-horizontal) {
.@{table-prefix-cls}.@{table-prefix-cls}-@{size} {
.@{table-prefix-cls}-@{size} {
.@{table-prefix-cls}-title,
.@{table-prefix-cls}-footer,
.@{table-prefix-cls}-thead > tr > th,
@ -9,10 +9,24 @@
padding: @padding-vertical @padding-horizontal;
}
.@{table-prefix-cls}-thead {
th.@{table-prefix-cls}-column-has-sorters {
padding: 0;
}
.@{table-prefix-cls}-filter-column {
margin: -@padding-vertical -@padding-horizontal;
}
.@{table-prefix-cls}-filter-column-title {
padding: @padding-vertical 2.3em @padding-vertical @padding-horizontal;
}
.@{table-prefix-cls}-column-sorters {
padding: @padding-vertical @padding-horizontal;
}
}
.@{table-prefix-cls}-expanded-row-fixed {
margin: -@padding-vertical -@padding-horizontal;
}
@ -29,7 +43,7 @@
// ================================================================
.table-size(~'small', @table-padding-vertical-sm, @table-padding-horizontal-sm);
.@{table-prefix-cls}.@{table-prefix-cls}-small {
.@{table-prefix-cls}-small {
.@{table-prefix-cls}-thead > tr > th {
background-color: @table-header-bg-sm;
}

View File

@ -401,10 +401,9 @@ exports[`renders ./components/time-picker/demo/range-picker.md correctly 1`] = `
class="ant-picker-range-separator"
>
<span
aria-label="to"
class="ant-picker-separator"
>
</span>
/>
</div>
<div
class="ant-picker-input"

View File

@ -275,6 +275,15 @@ exports[`renders ./components/typography/demo/ellipsis-debug.md correctly 1`] =
</span>
case. Bnt Design, a design language for background applications, is refined by Ant UED Team. Cnt Design, a design language for background applications, is refined by Ant UED Team. Dnt Design, a design language for background applications, is refined by Ant UED Team. Ent Design, a design language for background applications, is refined by Ant UED Team.
</div>
<p>
2333
<span
class="ant-typography ant-typography-ellipsis"
>
2333
</span>
2333
</p>
</div>
`;

View File

@ -63,6 +63,10 @@ class Demo extends React.Component {
Hello World
</Paragraph>
)}
<p>
2333<Text ellipsis>2333</Text>2333
</p>
</div>
);
}

View File

@ -192,6 +192,11 @@
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
// https://blog.csdn.net/iefreer/article/details/50421025
span& {
vertical-align: bottom;
}
}
&-ellipsis-multiple-line {

View File

@ -5,6 +5,8 @@ title: Use in TypeScript
Let's create a TypeScript project by using `create-react-app`, then import `antd` step by step.
> We build `antd` based on latest stable version of TypeScript (`>=3.8.4`), please make sure your project dependency matches it.
---
## Install and Initialization

View File

@ -5,6 +5,8 @@ title: 在 TypeScript 中使用
使用 `create-react-app` 一步步地创建一个 TypeScript 项目,并引入 antd。
> `antd` 基于最新稳定版本的 TypeScript`>=3.8.4`),请确保项目中使用匹配的版本。
---
## 安装和初始化

View File

@ -203,6 +203,8 @@ We have built-in dark theme and compact theme in antd, you can reference to [Use
> You could also try [craco](https://github.com/sharegate/craco) and [craco-antd](https://github.com/FormAPI/craco-antd) to customize create-react-app webpack config same as customize-cra does.
> Note: It is recommended to use the latest version of `less`, or a minimum version greater than `3.0.1`.
## Replace momentjs to Day.js
You can use [antd-dayjs-webpack-plugin](https://github.com/ant-design/antd-dayjs-webpack-plugin) plugin to replace momentjs to Day.js to reduce bundle size dramatically.

View File

@ -201,6 +201,10 @@ module.exports = override(
antd 内建了深色主题和紧凑主题,你可以参照 [使用暗色主题和紧凑主题](/docs/react/customize-theme#使用暗色主题和紧凑主题) 进行接入。
> 同样,你可以使用 [craco](https://github.com/sharegate/craco) 和 [craco-antd](https://github.com/FormAPI/craco-antd) 来自定义 create-react-app 的 webpack 配置,类似于 customize-cra。
> 注意:建议使用最新版本的 `less`,或不低于 `3.0.1`
## 使用 Day.js 替换 momentjs 优化打包大小
你可以使用 [antd-dayjs-webpack-plugin](https://github.com/ant-design/antd-dayjs-webpack-plugin) 插件用 Day.js 替换 momentjs 来大幅减小打包大小。

View File

@ -70,7 +70,7 @@ title: 可视化
### 色板
<img class="preview-img no-padding" align="right" description="AntV 官方默认色板示例" src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*58AFS77miwoAAAAAAAAAAABkARQnAQ" />
<img class="preview-img no-padding" align="right" description="AntV 官方默认色板示例" src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*Skn6TZsQ7ksAAAAAAAAAAABkARQnAQ" />
AntV 提供了一套默认的图表颜色,包括颜色的用法,

View File

@ -169,7 +169,7 @@ title:
#### 选择正确的色板
<img class="preview-img no-padding" align="right" src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*hip9RpGrtJQAAAAAAAAAAABkARQnAQ">
<img class="preview-img no-padding" align="right" src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*Skn6TZsQ7ksAAAAAAAAAAABkARQnAQ">
## 延伸阅读

View File

@ -51,8 +51,8 @@
"bundlesize": "bundlesize",
"check-commit": "node ./scripts/check-commit.js",
"compile": "antd-tools run compile",
"predeploy": "antd-tools run clean && npm run site && cp netlify.toml CNAME _site && cp -r .circleci/ _site && npm run site:test",
"deploy": "bisheng gh-pages --push-only",
"predeploy": "antd-tools run clean && npm run site && cp netlify.toml CNAME _site && cp -r .circleci/ .github/ _site && npm run site:test",
"deploy": "bisheng gh-pages --push-only --dotfiles",
"deploy:china-mirror": "git checkout gh-pages && git pull origin gh-pages && git push git@gitee.com:ant-design/ant-design.git gh-pages",
"dist": "antd-tools run dist",
"lint": "npm run lint:tsc && npm run lint:script && npm run lint:demo && npm run lint:style && npm run lint:deps",
@ -127,7 +127,7 @@
"rc-slider": "~9.2.3",
"rc-steps": "~3.5.0",
"rc-switch": "~1.9.0",
"rc-table": "~7.3.0",
"rc-table": "~7.4.2",
"rc-tabs": "~10.1.1",
"rc-tooltip": "~4.0.2",
"rc-tree": "~3.1.0",
@ -164,12 +164,12 @@
"antd-theme-generator": "^1.1.6",
"babel-eslint": "^10.0.1",
"babel-plugin-add-react-displayname": "^0.0.5",
"bisheng": "^1.4.6",
"bisheng": "^1.5.1",
"bisheng-plugin-description": "^0.1.4",
"bisheng-plugin-react": "^1.1.0",
"bisheng-plugin-toc": "^0.4.4",
"bundlesize": "^0.18.0",
"chalk": "^3.0.0",
"chalk": "^4.0.0",
"cheerio": "^1.0.0-rc.3",
"concurrently": "^5.0.2",
"cross-env": "^7.0.0",