feat: New Picker (#46982)

* chore: init

* chore: link picker

* chore: move files

* chore: update style

* chore: update types

* test: update snapshot

* test: update snapshot

* test: update snapshot

* test: update snapshot

* test: update snapshot

* test: fix test case

* test: update snapshot

* test: update snapshot

* test: update snapshot

* test: update snapshot

* chore: clesn up useless types

* chore: update types

* chore: fix types

* chore: fix types

* chore: fix types

* chore: fix types

* chore: fix types

* chore: fix types

* chore: fix types

* chore: fix types

* chore: fix types

* chore: update style

* chore: clean up

* chore: update types

* test: update snapshot

* test: update snapshot

* test: update snapshot

* test: update snapshot

* fix: format

* chore: update deps

* chore: feature merge master (#46794)

* fix: Fix typo s/Notificaiton/Notification/ (#46775)

* docs: supplement form preserve field description (#46788)

close https://github.com/ant-design/ant-design/issues/46773

* docs: tweak changelog drawer width in small screen (#46791)

* docs: Update compatible-style.zh-CN.md (#46790)

Signed-off-by: afc163 <afc163@gmail.com>

---------

Signed-off-by: afc163 <afc163@gmail.com>
Co-authored-by: hugo-syn <61210734+hugo-syn@users.noreply.github.com>
Co-authored-by: Shunze Chen <qianlonwork@outlook.com>
Co-authored-by: afc163 <afc163@gmail.com>

* chore: update locale size

* chore: lock dumi

* test: update snapshot

* test: update snapshot

* test: update snapshot

* test: update snapshot

* test: update snapshot

* test: update snapshot

* chore: bump version

* test: update snapshot

* test: update snapshot

* chore: bump version

* chore: update limit

* test: update snapshot

* docs: update 7 days sample

* chore: rm useless style

* chore: clean up style

* docs: add buddihist era demo

* refactor: interface

* chore: add multiple types

* docs: add demo

* chore: init style

* chore: init style

* chore: fill style

* chore: fill style

* chore: style

* chore: size of it

* chore: size style

* docs: add align demo

* docs: needConfirm

* chore: fix showWeek style

* test: update snapshot

* chore: fix ts

* chore: fix ts

* chore: fix ts

* chore: fix ts

* fix: week style

* docs: update dayjs note

* fix: style missing

* chore: fix footer extra style missing

* test: update snapshot

* test: update snapshot

* test: update snapshot

* test: update snapshot

* chore: demo update

* docs: update demo

* docs: min & max date

* test: update snapshot

* docs: add order

* chore: update deps

* test: update snapshot

* test: update snapshot

* chore: adjust style

* chore: clean up style

* test: update snapshot

* chore: fix comment

* chore: update align

* chore: bump rc-picker

* test: update snapshot

* test: update snapshot

* test: update snapshot

---------

Signed-off-by: afc163 <afc163@gmail.com>
Signed-off-by: lijianan <574980606@qq.com>
Co-authored-by: hugo-syn <61210734+hugo-syn@users.noreply.github.com>
Co-authored-by: Shunze Chen <qianlonwork@outlook.com>
Co-authored-by: afc163 <afc163@gmail.com>
Co-authored-by: lijianan <574980606@qq.com>
This commit is contained in:
二货爱吃白萝卜 2024-01-29 15:34:48 +08:00 committed by GitHub
parent 095b846cad
commit 18e85a7b81
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
74 changed files with 269906 additions and 238699 deletions

View File

@ -865,7 +865,7 @@ exports[`renders components/calendar/demo/basic.tsx extend context correctly 1`]
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-end"
class="ant-picker-cell"
title="2016-10-31"
>
<div
@ -882,7 +882,7 @@ exports[`renders components/calendar/demo/basic.tsx extend context correctly 1`]
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-start ant-picker-cell-in-view"
class="ant-picker-cell ant-picker-cell-in-view"
title="2016-11-01"
>
<div
@ -1245,7 +1245,7 @@ exports[`renders components/calendar/demo/basic.tsx extend context correctly 1`]
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-in-view ant-picker-cell-today ant-picker-cell-selected"
class="ant-picker-cell ant-picker-cell-selected ant-picker-cell-in-view ant-picker-cell-today"
title="2016-11-22"
>
<div
@ -1383,7 +1383,7 @@ exports[`renders components/calendar/demo/basic.tsx extend context correctly 1`]
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-end ant-picker-cell-in-view"
class="ant-picker-cell ant-picker-cell-in-view"
title="2016-11-30"
>
<div
@ -1400,7 +1400,7 @@ exports[`renders components/calendar/demo/basic.tsx extend context correctly 1`]
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-start"
class="ant-picker-cell"
title="2016-12-01"
>
<div
@ -2450,7 +2450,7 @@ exports[`renders components/calendar/demo/card.tsx extend context correctly 1`]
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-end"
class="ant-picker-cell"
title="2016-10-31"
>
<div
@ -2467,7 +2467,7 @@ exports[`renders components/calendar/demo/card.tsx extend context correctly 1`]
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-start ant-picker-cell-in-view"
class="ant-picker-cell ant-picker-cell-in-view"
title="2016-11-01"
>
<div
@ -2830,7 +2830,7 @@ exports[`renders components/calendar/demo/card.tsx extend context correctly 1`]
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-in-view ant-picker-cell-today ant-picker-cell-selected"
class="ant-picker-cell ant-picker-cell-selected ant-picker-cell-in-view ant-picker-cell-today"
title="2016-11-22"
>
<div
@ -2968,7 +2968,7 @@ exports[`renders components/calendar/demo/card.tsx extend context correctly 1`]
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-end ant-picker-cell-in-view"
class="ant-picker-cell ant-picker-cell-in-view"
title="2016-11-30"
>
<div
@ -2985,7 +2985,7 @@ exports[`renders components/calendar/demo/card.tsx extend context correctly 1`]
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-start"
class="ant-picker-cell"
title="2016-12-01"
>
<div
@ -4034,7 +4034,7 @@ Array [
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-end"
class="ant-picker-cell"
title="2016-10-31"
>
<div
@ -4051,7 +4051,7 @@ Array [
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-start ant-picker-cell-in-view"
class="ant-picker-cell ant-picker-cell-in-view"
title="2016-11-01"
>
<div
@ -4414,7 +4414,7 @@ Array [
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-in-view ant-picker-cell-today ant-picker-cell-selected"
class="ant-picker-cell ant-picker-cell-selected ant-picker-cell-in-view ant-picker-cell-today"
title="2016-11-22"
>
<div
@ -4552,7 +4552,7 @@ Array [
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-end ant-picker-cell-in-view"
class="ant-picker-cell ant-picker-cell-in-view"
title="2016-11-30"
>
<div
@ -4569,7 +4569,7 @@ Array [
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-start"
class="ant-picker-cell"
title="2016-12-01"
>
<div
@ -5612,7 +5612,7 @@ Array [
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-end"
class="ant-picker-cell"
title="2016-10-31"
>
<div
@ -5629,7 +5629,7 @@ Array [
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-start ant-picker-cell-in-view"
class="ant-picker-cell ant-picker-cell-in-view"
title="2016-11-01"
>
<div
@ -5992,7 +5992,7 @@ Array [
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-in-view ant-picker-cell-today ant-picker-cell-selected"
class="ant-picker-cell ant-picker-cell-selected ant-picker-cell-in-view ant-picker-cell-today"
title="2016-11-22"
>
<div
@ -6130,7 +6130,7 @@ Array [
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-end ant-picker-cell-in-view"
class="ant-picker-cell ant-picker-cell-in-view"
title="2016-11-30"
>
<div
@ -6147,7 +6147,7 @@ Array [
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-start"
class="ant-picker-cell"
title="2016-12-01"
>
<div
@ -7247,7 +7247,7 @@ exports[`renders components/calendar/demo/customize-header.tsx extend context co
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-end"
class="ant-picker-cell"
title="2016-10-31"
>
<div
@ -7264,7 +7264,7 @@ exports[`renders components/calendar/demo/customize-header.tsx extend context co
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-start ant-picker-cell-in-view"
class="ant-picker-cell ant-picker-cell-in-view"
title="2016-11-01"
>
<div
@ -7627,7 +7627,7 @@ exports[`renders components/calendar/demo/customize-header.tsx extend context co
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-in-view ant-picker-cell-today ant-picker-cell-selected"
class="ant-picker-cell ant-picker-cell-selected ant-picker-cell-in-view ant-picker-cell-today"
title="2016-11-22"
>
<div
@ -7765,7 +7765,7 @@ exports[`renders components/calendar/demo/customize-header.tsx extend context co
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-end ant-picker-cell-in-view"
class="ant-picker-cell ant-picker-cell-in-view"
title="2016-11-30"
>
<div
@ -7782,7 +7782,7 @@ exports[`renders components/calendar/demo/customize-header.tsx extend context co
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-start"
class="ant-picker-cell"
title="2016-12-01"
>
<div
@ -8838,7 +8838,7 @@ exports[`renders components/calendar/demo/notice-calendar.tsx extend context cor
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-end"
class="ant-picker-cell"
title="2016-10-31"
>
<div
@ -8859,7 +8859,7 @@ exports[`renders components/calendar/demo/notice-calendar.tsx extend context cor
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-start ant-picker-cell-in-view"
class="ant-picker-cell ant-picker-cell-in-view"
title="2016-11-01"
>
<div
@ -9463,7 +9463,7 @@ exports[`renders components/calendar/demo/notice-calendar.tsx extend context cor
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-in-view ant-picker-cell-today ant-picker-cell-selected"
class="ant-picker-cell ant-picker-cell-selected ant-picker-cell-in-view ant-picker-cell-today"
title="2016-11-22"
>
<div
@ -9633,7 +9633,7 @@ exports[`renders components/calendar/demo/notice-calendar.tsx extend context cor
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-end ant-picker-cell-in-view"
class="ant-picker-cell ant-picker-cell-in-view"
title="2016-11-30"
>
<div
@ -9654,7 +9654,7 @@ exports[`renders components/calendar/demo/notice-calendar.tsx extend context cor
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-start"
class="ant-picker-cell"
title="2016-12-01"
>
<div
@ -10812,7 +10812,7 @@ Array [
<tbody>
<tr>
<td
class="ant-picker-cell ant-picker-cell-start ant-picker-cell-in-view"
class="ant-picker-cell ant-picker-cell-in-view"
title="2017-01-01"
>
<div
@ -11226,7 +11226,7 @@ Array [
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-in-view ant-picker-cell-selected"
class="ant-picker-cell ant-picker-cell-selected ant-picker-cell-in-view"
title="2017-01-25"
>
<div
@ -11330,7 +11330,7 @@ Array [
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-end ant-picker-cell-in-view"
class="ant-picker-cell ant-picker-cell-in-view"
title="2017-01-31"
>
<div
@ -11347,7 +11347,7 @@ Array [
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-start"
class="ant-picker-cell"
title="2017-02-01"
>
<div

View File

@ -227,7 +227,7 @@ exports[`renders components/calendar/demo/basic.tsx correctly 1`] = `
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-end"
class="ant-picker-cell"
title="2016-10-31"
>
<div
@ -244,7 +244,7 @@ exports[`renders components/calendar/demo/basic.tsx correctly 1`] = `
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-start ant-picker-cell-in-view"
class="ant-picker-cell ant-picker-cell-in-view"
title="2016-11-01"
>
<div
@ -607,7 +607,7 @@ exports[`renders components/calendar/demo/basic.tsx correctly 1`] = `
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-in-view ant-picker-cell-today ant-picker-cell-selected"
class="ant-picker-cell ant-picker-cell-selected ant-picker-cell-in-view ant-picker-cell-today"
title="2016-11-22"
>
<div
@ -745,7 +745,7 @@ exports[`renders components/calendar/demo/basic.tsx correctly 1`] = `
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-end ant-picker-cell-in-view"
class="ant-picker-cell ant-picker-cell-in-view"
title="2016-11-30"
>
<div
@ -762,7 +762,7 @@ exports[`renders components/calendar/demo/basic.tsx correctly 1`] = `
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-start"
class="ant-picker-cell"
title="2016-12-01"
>
<div
@ -1172,7 +1172,7 @@ exports[`renders components/calendar/demo/card.tsx correctly 1`] = `
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-end"
class="ant-picker-cell"
title="2016-10-31"
>
<div
@ -1189,7 +1189,7 @@ exports[`renders components/calendar/demo/card.tsx correctly 1`] = `
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-start ant-picker-cell-in-view"
class="ant-picker-cell ant-picker-cell-in-view"
title="2016-11-01"
>
<div
@ -1552,7 +1552,7 @@ exports[`renders components/calendar/demo/card.tsx correctly 1`] = `
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-in-view ant-picker-cell-today ant-picker-cell-selected"
class="ant-picker-cell ant-picker-cell-selected ant-picker-cell-in-view ant-picker-cell-today"
title="2016-11-22"
>
<div
@ -1690,7 +1690,7 @@ exports[`renders components/calendar/demo/card.tsx correctly 1`] = `
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-end ant-picker-cell-in-view"
class="ant-picker-cell ant-picker-cell-in-view"
title="2016-11-30"
>
<div
@ -1707,7 +1707,7 @@ exports[`renders components/calendar/demo/card.tsx correctly 1`] = `
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-start"
class="ant-picker-cell"
title="2016-12-01"
>
<div
@ -2116,7 +2116,7 @@ Array [
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-end"
class="ant-picker-cell"
title="2016-10-31"
>
<div
@ -2133,7 +2133,7 @@ Array [
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-start ant-picker-cell-in-view"
class="ant-picker-cell ant-picker-cell-in-view"
title="2016-11-01"
>
<div
@ -2496,7 +2496,7 @@ Array [
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-in-view ant-picker-cell-today ant-picker-cell-selected"
class="ant-picker-cell ant-picker-cell-selected ant-picker-cell-in-view ant-picker-cell-today"
title="2016-11-22"
>
<div
@ -2634,7 +2634,7 @@ Array [
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-end ant-picker-cell-in-view"
class="ant-picker-cell ant-picker-cell-in-view"
title="2016-11-30"
>
<div
@ -2651,7 +2651,7 @@ Array [
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-start"
class="ant-picker-cell"
title="2016-12-01"
>
<div
@ -3056,7 +3056,7 @@ Array [
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-end"
class="ant-picker-cell"
title="2016-10-31"
>
<div
@ -3073,7 +3073,7 @@ Array [
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-start ant-picker-cell-in-view"
class="ant-picker-cell ant-picker-cell-in-view"
title="2016-11-01"
>
<div
@ -3436,7 +3436,7 @@ Array [
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-in-view ant-picker-cell-today ant-picker-cell-selected"
class="ant-picker-cell ant-picker-cell-selected ant-picker-cell-in-view ant-picker-cell-today"
title="2016-11-22"
>
<div
@ -3574,7 +3574,7 @@ Array [
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-end ant-picker-cell-in-view"
class="ant-picker-cell ant-picker-cell-in-view"
title="2016-11-30"
>
<div
@ -3591,7 +3591,7 @@ Array [
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-start"
class="ant-picker-cell"
title="2016-12-01"
>
<div
@ -4027,7 +4027,7 @@ exports[`renders components/calendar/demo/customize-header.tsx correctly 1`] = `
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-end"
class="ant-picker-cell"
title="2016-10-31"
>
<div
@ -4044,7 +4044,7 @@ exports[`renders components/calendar/demo/customize-header.tsx correctly 1`] = `
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-start ant-picker-cell-in-view"
class="ant-picker-cell ant-picker-cell-in-view"
title="2016-11-01"
>
<div
@ -4407,7 +4407,7 @@ exports[`renders components/calendar/demo/customize-header.tsx correctly 1`] = `
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-in-view ant-picker-cell-today ant-picker-cell-selected"
class="ant-picker-cell ant-picker-cell-selected ant-picker-cell-in-view ant-picker-cell-today"
title="2016-11-22"
>
<div
@ -4545,7 +4545,7 @@ exports[`renders components/calendar/demo/customize-header.tsx correctly 1`] = `
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-end ant-picker-cell-in-view"
class="ant-picker-cell ant-picker-cell-in-view"
title="2016-11-30"
>
<div
@ -4562,7 +4562,7 @@ exports[`renders components/calendar/demo/customize-header.tsx correctly 1`] = `
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-start"
class="ant-picker-cell"
title="2016-12-01"
>
<div
@ -4974,7 +4974,7 @@ exports[`renders components/calendar/demo/notice-calendar.tsx correctly 1`] = `
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-end"
class="ant-picker-cell"
title="2016-10-31"
>
<div
@ -4995,7 +4995,7 @@ exports[`renders components/calendar/demo/notice-calendar.tsx correctly 1`] = `
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-start ant-picker-cell-in-view"
class="ant-picker-cell ant-picker-cell-in-view"
title="2016-11-01"
>
<div
@ -5599,7 +5599,7 @@ exports[`renders components/calendar/demo/notice-calendar.tsx correctly 1`] = `
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-in-view ant-picker-cell-today ant-picker-cell-selected"
class="ant-picker-cell ant-picker-cell-selected ant-picker-cell-in-view ant-picker-cell-today"
title="2016-11-22"
>
<div
@ -5769,7 +5769,7 @@ exports[`renders components/calendar/demo/notice-calendar.tsx correctly 1`] = `
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-end ant-picker-cell-in-view"
class="ant-picker-cell ant-picker-cell-in-view"
title="2016-11-30"
>
<div
@ -5790,7 +5790,7 @@ exports[`renders components/calendar/demo/notice-calendar.tsx correctly 1`] = `
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-start"
class="ant-picker-cell"
title="2016-12-01"
>
<div
@ -6308,7 +6308,7 @@ Array [
<tbody>
<tr>
<td
class="ant-picker-cell ant-picker-cell-start ant-picker-cell-in-view"
class="ant-picker-cell ant-picker-cell-in-view"
title="2017-01-01"
>
<div
@ -6722,7 +6722,7 @@ Array [
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-in-view ant-picker-cell-selected"
class="ant-picker-cell ant-picker-cell-selected ant-picker-cell-in-view"
title="2017-01-25"
>
<div
@ -6826,7 +6826,7 @@ Array [
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-end ant-picker-cell-in-view"
class="ant-picker-cell ant-picker-cell-in-view"
title="2017-01-31"
>
<div
@ -6843,7 +6843,7 @@ Array [
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-start"
class="ant-picker-cell"
title="2017-02-01"
>
<div

View File

@ -229,7 +229,7 @@ exports[`Calendar Calendar MonthSelect should display correct label 1`] = `
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-end"
class="ant-picker-cell"
title="2018-12-31"
>
<div
@ -246,7 +246,7 @@ exports[`Calendar Calendar MonthSelect should display correct label 1`] = `
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-start ant-picker-cell-in-view ant-picker-cell-selected"
class="ant-picker-cell ant-picker-cell-selected ant-picker-cell-in-view"
title="2019-01-01"
>
<div
@ -764,7 +764,7 @@ exports[`Calendar Calendar MonthSelect should display correct label 1`] = `
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-end ant-picker-cell-in-view"
class="ant-picker-cell ant-picker-cell-in-view"
title="2019-01-31"
>
<div
@ -781,7 +781,7 @@ exports[`Calendar Calendar MonthSelect should display correct label 1`] = `
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-start"
class="ant-picker-cell"
title="2019-02-01"
>
<div
@ -1156,7 +1156,7 @@ exports[`Calendar Calendar should support locale 1`] = `
<tbody>
<tr>
<td
class="ant-picker-cell ant-picker-cell-start ant-picker-cell-in-view"
class="ant-picker-cell ant-picker-cell-in-view"
title="2018-10-01"
>
<div
@ -1466,7 +1466,7 @@ exports[`Calendar Calendar should support locale 1`] = `
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-in-view ant-picker-cell-today ant-picker-cell-selected"
class="ant-picker-cell ant-picker-cell-selected ant-picker-cell-in-view ant-picker-cell-today"
title="2018-10-19"
>
<div
@ -1674,7 +1674,7 @@ exports[`Calendar Calendar should support locale 1`] = `
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-end ant-picker-cell-in-view"
class="ant-picker-cell ant-picker-cell-in-view"
title="2018-10-31"
>
<div
@ -1691,7 +1691,7 @@ exports[`Calendar Calendar should support locale 1`] = `
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-start"
class="ant-picker-cell"
title="2018-11-01"
>
<div
@ -2168,7 +2168,7 @@ exports[`Calendar rtl render component should be rendered correctly in RTL direc
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-end"
class="ant-picker-cell"
title="2000-08-31"
>
<div
@ -2185,7 +2185,7 @@ exports[`Calendar rtl render component should be rendered correctly in RTL direc
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-start ant-picker-cell-in-view"
class="ant-picker-cell ant-picker-cell-in-view"
title="2000-09-01"
>
<div
@ -2652,7 +2652,7 @@ exports[`Calendar rtl render component should be rendered correctly in RTL direc
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-in-view ant-picker-cell-today ant-picker-cell-selected"
class="ant-picker-cell ant-picker-cell-selected ant-picker-cell-in-view ant-picker-cell-today"
title="2000-09-28"
>
<div
@ -2686,7 +2686,7 @@ exports[`Calendar rtl render component should be rendered correctly in RTL direc
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-end ant-picker-cell-in-view"
class="ant-picker-cell ant-picker-cell-in-view"
title="2000-09-30"
>
<div
@ -2705,7 +2705,7 @@ exports[`Calendar rtl render component should be rendered correctly in RTL direc
</tr>
<tr>
<td
class="ant-picker-cell ant-picker-cell-start"
class="ant-picker-cell"
title="2000-10-01"
>
<div
@ -3129,7 +3129,7 @@ exports[`Calendar support Calendar.generateCalendar 1`] = `
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-end"
class="ant-picker-cell"
title="1999-12-31"
>
<div
@ -3146,7 +3146,7 @@ exports[`Calendar support Calendar.generateCalendar 1`] = `
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-start ant-picker-cell-in-view ant-picker-cell-today ant-picker-cell-selected"
class="ant-picker-cell ant-picker-cell-selected ant-picker-cell-in-view ant-picker-cell-today"
title="2000-01-01"
>
<div
@ -3666,7 +3666,7 @@ exports[`Calendar support Calendar.generateCalendar 1`] = `
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-end ant-picker-cell-in-view"
class="ant-picker-cell ant-picker-cell-in-view"
title="2000-01-31"
>
<div
@ -3683,7 +3683,7 @@ exports[`Calendar support Calendar.generateCalendar 1`] = `
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-start"
class="ant-picker-cell"
title="2000-02-01"
>
<div

View File

@ -1,11 +1,14 @@
import Dayjs from 'dayjs';
import 'dayjs/locale/zh-cn';
import React from 'react';
import MockDate from 'mockdate';
import { type PickerPanelProps } from 'rc-picker';
import dayjsGenerateConfig from 'rc-picker/lib/generate/dayjs';
import type { Locale } from 'rc-picker/lib/interface';
import { resetWarned } from 'rc-util/lib/warning';
import React from 'react';
import Calendar from '..';
import mountTest from '../../../tests/shared/mountTest';
import rtlTest from '../../../tests/shared/rtlTest';
@ -16,7 +19,7 @@ import Select from '../../select';
import Header, { type CalendarHeaderProps } from '../Header';
const ref: {
calendarProps?: PickerPanelProps<unknown>;
calendarProps?: PickerPanelProps;
calendarHeaderProps?: CalendarHeaderProps<unknown>;
} = {};
@ -34,7 +37,7 @@ jest.mock('rc-picker', () => {
const PickerPanelComponent = RcPicker.PickerPanel;
return {
...RcPicker,
PickerPanel: (props: PickerPanelProps<unknown>) => {
PickerPanel: (props: PickerPanelProps) => {
ref.calendarProps = props;
return <PickerPanelComponent {...props} />;
},
@ -149,8 +152,8 @@ describe('Calendar', () => {
it('getDateRange should returns a disabledDate function', () => {
const validRange: [Dayjs.Dayjs, Dayjs.Dayjs] = [Dayjs('2018-02-02'), Dayjs('2018-05-18')];
render(<Calendar validRange={validRange} defaultValue={Dayjs('2018-02-02')} />);
expect(ref.calendarProps?.disabledDate?.(Dayjs('2018-06-02'))).toBe(true);
expect(ref.calendarProps?.disabledDate?.(Dayjs('2018-04-02'))).toBe(false);
expect(ref.calendarProps?.disabledDate?.(Dayjs('2018-06-02'), {} as any)).toBe(true);
expect(ref.calendarProps?.disabledDate?.(Dayjs('2018-04-02'), {} as any)).toBe(false);
});
it('validRange should work with disabledDate function', () => {
@ -162,11 +165,11 @@ describe('Calendar', () => {
/>,
);
expect(ref.calendarProps?.disabledDate?.(Dayjs('2018-02-01'))).toBe(true);
expect(ref.calendarProps?.disabledDate?.(Dayjs('2018-02-02'))).toBe(false);
expect(ref.calendarProps?.disabledDate?.(Dayjs('2018-02-03'))).toBe(true);
expect(ref.calendarProps?.disabledDate?.(Dayjs('2018-02-04'))).toBe(false);
expect(ref.calendarProps?.disabledDate?.(Dayjs('2018-06-01'))).toBe(true);
expect(ref.calendarProps?.disabledDate?.(Dayjs('2018-02-01'), {} as any)).toBe(true);
expect(ref.calendarProps?.disabledDate?.(Dayjs('2018-02-02'), {} as any)).toBe(false);
expect(ref.calendarProps?.disabledDate?.(Dayjs('2018-02-03'), {} as any)).toBe(true);
expect(ref.calendarProps?.disabledDate?.(Dayjs('2018-02-04'), {} as any)).toBe(false);
expect(ref.calendarProps?.disabledDate?.(Dayjs('2018-06-01'), {} as any)).toBe(true);
});
it('Calendar MonthSelect should display correct label', () => {

View File

@ -3,13 +3,9 @@ import classNames from 'classnames';
import { PickerPanel as RCPickerPanel } from 'rc-picker';
import type { GenerateConfig } from 'rc-picker/lib/generate';
import type { CellRenderInfo } from 'rc-picker/lib/interface';
import type {
PickerPanelBaseProps as RCPickerPanelBaseProps,
PickerPanelDateProps as RCPickerPanelDateProps,
PickerPanelTimeProps as RCPickerPanelTimeProps,
} from 'rc-picker/lib/PickerPanel';
import useMergedState from 'rc-util/lib/hooks/useMergedState';
import type { AnyObject } from '../_util/type';
import { devUseWarning } from '../_util/warning';
import { ConfigContext } from '../config-provider';
import { useLocale } from '../locale';
@ -17,24 +13,6 @@ import CalendarHeader from './Header';
import enUS from './locale/en_US';
import useStyle from './style';
type InjectDefaultProps<Props> = Omit<
Props,
'locale' | 'generateConfig' | 'prevIcon' | 'nextIcon' | 'superPrevIcon' | 'superNextIcon'
> & {
locale?: typeof enUS;
size?: 'large' | 'default' | 'small';
};
// Picker Props
export type PickerPanelBaseProps<DateType> = InjectDefaultProps<RCPickerPanelBaseProps<DateType>>;
export type PickerPanelDateProps<DateType> = InjectDefaultProps<RCPickerPanelDateProps<DateType>>;
export type PickerPanelTimeProps<DateType> = InjectDefaultProps<RCPickerPanelTimeProps<DateType>>;
export type PickerProps<DateType> =
| PickerPanelBaseProps<DateType>
| PickerPanelDateProps<DateType>
| PickerPanelTimeProps<DateType>;
export type CalendarMode = 'year' | 'month';
export type HeaderRender<DateType> = (config: {
value: DateType;
@ -75,7 +53,7 @@ export interface CalendarProps<DateType> {
onSelect?: (date: DateType, selectInfo: SelectInfo) => void;
}
function generateCalendar<DateType>(generateConfig: GenerateConfig<DateType>) {
function generateCalendar<DateType extends AnyObject>(generateConfig: GenerateConfig<DateType>) {
function isSameYear(date1: DateType, date2: DateType) {
return date1 && date2 && generateConfig.getYear(date1) === generateConfig.getYear(date2);
}

View File

@ -35,6 +35,12 @@ jest.mock('@rc-component/trigger', () => {
};
});
function getCell(text: string) {
const cells = Array.from(document.querySelectorAll('.ant-picker-cell'));
return cells.find((cell) => cell.textContent === text);
}
describe('DatePicker', () => {
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
@ -96,8 +102,10 @@ describe('DatePicker', () => {
it('disabled date', () => {
const disabledDate = (current: any) => current && current < dayjs().endOf('day');
const wrapper = render(<DatePicker disabledDate={disabledDate} open />);
expect(Array.from(wrapper.container.children)).toMatchSnapshot();
render(<DatePicker disabledDate={disabledDate} open />);
expect(getCell('21')).toHaveClass('ant-picker-cell-disabled');
expect(getCell('23')).not.toHaveClass('ant-picker-cell-disabled');
});
it('placeholder', () => {
@ -234,12 +242,7 @@ describe('DatePicker', () => {
it('showTime={{ showHour: true }}', () => {
const { container } = render(
<DatePicker
defaultValue={dayjs()}
showTime={{ showHour: true }}
format="YYYY-MM-DD"
open
/>,
<DatePicker defaultValue={dayjs()} showTime={{ showHour: true }} format="YYYY-MM-DD" open />,
);
expect(container.querySelectorAll('.ant-picker-time-panel-column').length).toBe(1);
expect(
@ -249,16 +252,11 @@ describe('DatePicker', () => {
).toBe(24);
});
it('showTime={{ }} (no true args)', () => {
it('showTime={{ }} (no true args)', () => {
const { container } = render(
<DatePicker
defaultValue={dayjs()}
showTime={{ }}
format="YYYY-MM-DD"
open
/>,
<DatePicker defaultValue={dayjs()} showTime={{}} format="YYYY-MM-DD" open />,
);
expect(container.querySelectorAll('.ant-picker-time-panel-column').length).toBe(0);
expect(container.querySelectorAll('.ant-picker-time-panel-column')).toHaveLength(3);
});
it('showTime should work correctly when format is custom function', () => {
@ -270,13 +268,13 @@ describe('DatePicker', () => {
open
/>,
);
const fuousEvent = () => {
const focusEvent = () => {
fireEvent.focus(container.querySelector('input')!);
};
const mouseDownEvent = () => {
fireEvent.mouseDown(container.querySelector('input')!);
};
expect(fuousEvent).not.toThrow();
expect(focusEvent).not.toThrow();
expect(mouseDownEvent).not.toThrow();
});
@ -411,7 +409,7 @@ describe('DatePicker', () => {
const { container } = render(
<DatePicker defaultValue={dayjs()} format="kk:mm" showTime open />,
);
expect(container.querySelectorAll('.ant-picker-time-panel-column').length).toBe(2);
expect(container.querySelectorAll('.ant-picker-time-panel-column')).toHaveLength(2);
expect(
container
.querySelectorAll('.ant-picker-time-panel-column')?.[0]

View File

@ -1,18 +1,22 @@
import React, { useState } from 'react';
import { CloseCircleFilled } from '@ant-design/icons';
import userEvent from '@testing-library/user-event';
import dayjs from 'dayjs';
import customParseFormat from 'dayjs/plugin/customParseFormat';
import type { RangeValue } from 'rc-picker/lib/interface';
import React, { useState } from 'react';
import userEvent from '@testing-library/user-event';
import { CloseCircleFilled } from '@ant-design/icons';
import DatePicker from '..';
import focusTest from '../../../tests/shared/focusTest';
import { render, resetMockDate, setMockDate, screen, waitFor } from '../../../tests/utils';
import { resetWarned } from '../../_util/warning';
import focusTest from '../../../tests/shared/focusTest';
import { render, resetMockDate, screen, setMockDate, waitFor } from '../../../tests/utils';
import enUS from '../locale/en_US';
import { closeCircleByRole, expectCloseCircle, closePicker, openPicker, selectCell } from './utils';
import { closeCircleByRole, closePicker, expectCloseCircle, openPicker, selectCell } from './utils';
dayjs.extend(customParseFormat);
type RangeValue<DateType extends object> =
| [DateType | undefined | null, DateType | undefined | null]
| null;
const { RangePicker } = DatePicker;
describe('RangePicker', () => {
@ -85,42 +89,12 @@ describe('RangePicker', () => {
expect(start.isBefore(end, 'date')).toBeTruthy();
});
it('the left selection is after the right selection, no selection made', () => {
let rangePickerValue: dayjs.Dayjs[] = [];
const Test: React.FC = () => {
const [value, setValue] = useState<RangeValue<dayjs.Dayjs>>(null);
return (
<RangePicker
value={value}
mode={['month', 'month']}
onPanelChange={(v) => {
setValue(v);
rangePickerValue = v as dayjs.Dayjs[];
}}
/>
);
};
const wrapper = render(<Test />);
openPicker(wrapper);
selectCell(wrapper, 'May');
openPicker(wrapper, 1);
selectCell(wrapper, 'Feb');
closePicker(wrapper, 1);
const [start, end] = rangePickerValue;
expect(start).not.toBeNull();
expect(end).toBeNull();
});
// https://github.com/ant-design/ant-design/issues/13302
describe('in "month" mode, when the left and right panels select the same month', () => {
it('the cell status is correct', () => {
let rangePickerValue: dayjs.Dayjs[] = [];
const Test: React.FC = () => {
const [value, setValue] = useState<RangeValue<dayjs.Dayjs>>(null);
const [value, setValue] = useState<RangeValue<dayjs.Dayjs>>(null!);
return (
<RangePicker
value={value}

View File

@ -9,11 +9,10 @@ exports[`QuarterPicker should support style prop 1`] = `
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
placeholder="Select quarter"
readonly=""
size="12"
title=""
value=""
/>
<span

View File

@ -5,12 +5,13 @@ exports[`RangePicker customize separator 1`] = `
class="ant-picker ant-picker-range ant-picker-outlined"
>
<div
class="ant-picker-input ant-picker-input-active"
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
date-range="start"
placeholder="Start date"
readonly=""
size="12"
value=""
/>
@ -24,16 +25,17 @@ exports[`RangePicker customize separator 1`] = `
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
date-range="end"
placeholder="End date"
readonly=""
size="12"
value=""
/>
</div>
<div
class="ant-picker-active-bar"
style="left: 0px; width: 0px; position: absolute;"
style="position: absolute; width: 0px; left: 0px;"
/>
<span
class="ant-picker-suffix"
@ -70,9 +72,10 @@ Array [
class="ant-picker-input ant-picker-input-active"
>
<input
aria-invalid="false"
autocomplete="off"
date-range="start"
placeholder="Start date"
readonly=""
size="12"
value=""
/>
@ -109,16 +112,17 @@ Array [
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
date-range="end"
placeholder="End date"
readonly=""
size="12"
value=""
/>
</div>
<div
class="ant-picker-active-bar"
style="left: 0px; width: 0px; position: absolute;"
style="position: absolute; width: 0px; left: 0px;"
/>
<span
class="ant-picker-suffix"
@ -150,15 +154,15 @@ Array [
>
<div
class="ant-picker-range-wrapper ant-picker-date-range-wrapper"
style="min-width: 0;"
>
<div
class="ant-picker-range-arrow"
style="left: 0px;"
/>
<div
class="ant-picker-panel-container"
style="margin-left: 0px;"
class="ant-picker-panel-container ant-picker-date-panel-container"
style="margin-left: 0px; margin-right: auto;"
tabindex="-1"
>
<div
class="ant-picker-panel-layout"
@ -180,8 +184,8 @@ Array [
class="ant-picker-panels"
>
<div
class="ant-picker-panel ant-picker-panel-focused"
tabindex="-1"
class="ant-picker-panel"
tabindex="0"
>
<div
class="ant-picker-date-panel"
@ -320,7 +324,7 @@ Array [
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-end"
class="ant-picker-cell"
title="2017-08-31"
>
<div
@ -330,7 +334,7 @@ Array [
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-start ant-picker-cell-in-view"
class="ant-picker-cell ant-picker-cell-in-view"
title="2017-09-01"
>
<div
@ -628,7 +632,7 @@ Array [
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-end ant-picker-cell-in-view"
class="ant-picker-cell ant-picker-cell-in-view"
title="2017-09-30"
>
<div
@ -640,7 +644,7 @@ Array [
</tr>
<tr>
<td
class="ant-picker-cell ant-picker-cell-start"
class="ant-picker-cell"
title="2017-10-01"
>
<div
@ -716,8 +720,8 @@ Array [
</div>
</div>
<div
class="ant-picker-panel ant-picker-panel-focused"
tabindex="-1"
class="ant-picker-panel"
tabindex="0"
>
<div
class="ant-picker-date-panel"
@ -816,7 +820,7 @@ Array [
<tbody>
<tr>
<td
class="ant-picker-cell ant-picker-cell-start ant-picker-cell-in-view"
class="ant-picker-cell ant-picker-cell-in-view"
title="2017-10-01"
>
<div
@ -1124,7 +1128,7 @@ Array [
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-end ant-picker-cell-in-view"
class="ant-picker-cell ant-picker-cell-in-view"
title="2017-10-31"
>
<div
@ -1134,7 +1138,7 @@ Array [
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-start"
class="ant-picker-cell"
title="2017-11-01"
>
<div

View File

@ -9,11 +9,10 @@ exports[`WeekPicker should support style prop 1`] = `
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
placeholder="Select week"
readonly=""
size="12"
title=""
value=""
/>
<span

View File

@ -2,17 +2,16 @@
exports[`mount rtl render component should be rendered correctly in RTL direction 1`] = `
<div
class="ant-picker ant-picker-outlined ant-picker-rtl"
class="ant-picker ant-picker-rtl ant-picker-outlined"
>
<div
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
placeholder="Select date"
readonly=""
size="12"
title=""
value=""
/>
<span
@ -44,17 +43,16 @@ exports[`mount rtl render component should be rendered correctly in RTL directio
exports[`mount rtl render component should be rendered correctly in RTL direction 2`] = `
<div
class="ant-picker ant-picker-outlined ant-picker-rtl"
class="ant-picker ant-picker-rtl ant-picker-outlined"
>
<div
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
placeholder="Select month"
readonly=""
size="12"
title=""
value=""
/>
<span
@ -86,17 +84,16 @@ exports[`mount rtl render component should be rendered correctly in RTL directio
exports[`mount rtl render component should be rendered correctly in RTL direction 3`] = `
<div
class="ant-picker ant-picker-outlined ant-picker-rtl"
class="ant-picker ant-picker-rtl ant-picker-outlined"
>
<div
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
placeholder="Select week"
readonly=""
size="12"
title=""
value=""
/>
<span
@ -128,15 +125,16 @@ exports[`mount rtl render component should be rendered correctly in RTL directio
exports[`mount rtl render component should be rendered correctly in RTL direction 4`] = `
<div
class="ant-picker ant-picker-range ant-picker-outlined ant-picker-rtl"
class="ant-picker ant-picker-range ant-picker-rtl ant-picker-outlined"
>
<div
class="ant-picker-input ant-picker-input-active"
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
date-range="start"
placeholder="Start date"
readonly=""
size="12"
value=""
/>
@ -173,16 +171,17 @@ exports[`mount rtl render component should be rendered correctly in RTL directio
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
date-range="end"
placeholder="End date"
readonly=""
size="12"
value=""
/>
</div>
<div
class="ant-picker-active-bar"
style="right: 0px; width: 0px; position: absolute;"
style="position: absolute; width: 0px; right: 0px;"
/>
<span
class="ant-picker-suffix"

View File

@ -1,8 +1,6 @@
import type { Dayjs } from 'dayjs';
import * as React from 'react';
import type { DatePickerProps, RangePickerProps } from '..';
import DatePicker from '..';
import type { DatePickRef, RangePickerRef } from '../generatePicker/interface';
describe('DatePicker.typescript', () => {
it('DatePicker ref methods', () => {
@ -19,11 +17,8 @@ describe('DatePicker.typescript', () => {
// https://github.com/ant-design/ant-design/issues/33417
it('DatePicker ref methods with forwardRef', () => {
const MyDatePicker = React.forwardRef((props: DatePickerProps, ref: DatePickRef<Dayjs>) => (
<DatePicker {...props} ref={ref} />
));
const datePicker = (
<MyDatePicker
<DatePicker
ref={(picker) => {
picker?.focus();
picker?.blur();
@ -46,13 +41,8 @@ describe('DatePicker.typescript', () => {
});
it('RangePicker ref methods with forwardRef', () => {
const MyRangePicker = React.forwardRef(
(props: RangePickerProps, ref: RangePickerRef<Dayjs>) => (
<DatePicker.RangePicker {...props} ref={ref} />
),
);
const datePicker = (
<MyRangePicker
<DatePicker.RangePicker
ref={(picker) => {
picker?.focus();
picker?.blur();

View File

@ -2,8 +2,10 @@ import type { render } from '../../../tests/utils';
import { fireEvent, screen } from '../../../tests/utils';
export function openPicker(wrapper: ReturnType<typeof render>, index = 0) {
fireEvent.mouseDown(wrapper.container?.querySelectorAll('input')?.[index]!);
fireEvent.focus(wrapper.container?.querySelectorAll('input')?.[index]!);
const inputEle = wrapper.container?.querySelectorAll<HTMLInputElement>('input')?.[index]!;
fireEvent.mouseDown(inputEle);
fireEvent.focus(inputEle);
fireEvent.click(inputEle);
}
export function closePicker(wrapper: ReturnType<typeof render>, index = 0) {

View File

@ -0,0 +1,7 @@
## zh-CN
在范围选择时,可以允许留空。这对于需要保留“至今”日期项颇为有用。
## en-US
Allow empty for the RangePicker. It's useful when you need to keep the "to date".

View File

@ -0,0 +1,14 @@
import React from 'react';
import { DatePicker } from 'antd';
const App: React.FC = () => (
<DatePicker.RangePicker
placeholder={['', 'Till Now']}
allowEmpty={[false, true]}
onChange={(date, dateString) => {
console.log(date, dateString);
}}
/>
);
export default App;

View File

@ -9,10 +9,10 @@ const onChange: DatePickerProps['onChange'] = (date, dateString) => {
const App: React.FC = () => (
<Space direction="vertical">
<DatePicker onChange={onChange} />
<DatePicker onChange={onChange} picker="week" />
{/* <DatePicker onChange={onChange} picker="week" />
<DatePicker onChange={onChange} picker="month" />
<DatePicker onChange={onChange} picker="quarter" />
<DatePicker onChange={onChange} picker="year" />
<DatePicker onChange={onChange} picker="year" /> */}
</Space>
);

View File

@ -0,0 +1,7 @@
## zh-CN
通过 `locale` 配置支持特殊的年历格式。
## en-US
Use `locale` to support special calendar format.

View File

@ -0,0 +1,63 @@
import React from 'react';
import { ConfigProvider, DatePicker, Space, Typography } from 'antd';
import type { DatePickerProps } from 'antd';
import en from 'antd/es/date-picker/locale/en_US';
import enUS from 'antd/es/locale/en_US';
import dayjs from 'dayjs';
import buddhistEra from 'dayjs/plugin/buddhistEra';
dayjs.extend(buddhistEra);
const { Title } = Typography;
// Component level locale
const buddhistLocale: typeof en = {
...en,
lang: {
...en.lang,
fieldDateFormat: 'BBBB-MM-DD',
fieldDateTimeFormat: 'BBBB-MM-DD HH:mm:ss',
yearFormat: 'BBBB',
cellYearFormat: 'BBBB',
},
};
// ConfigProvider level locale
const globalBuddhistLocale: typeof enUS = {
...enUS,
DatePicker: {
...enUS.DatePicker!,
lang: buddhistLocale.lang,
},
};
const defaultValue = dayjs('2024-01-01');
const App: React.FC = () => {
const onChange: DatePickerProps['onChange'] = (_, dateStr) => {
console.log('onChange:', dateStr);
};
return (
<Space direction="vertical">
<Title level={4}>By locale props</Title>
<DatePicker defaultValue={defaultValue} locale={buddhistLocale} onChange={onChange} />
<DatePicker
defaultValue={defaultValue}
showTime
locale={buddhistLocale}
onChange={onChange}
/>
<Title level={4}>By ConfigProvider</Title>
<ConfigProvider locale={globalBuddhistLocale}>
<Space direction="vertical">
<DatePicker defaultValue={defaultValue} onChange={onChange} />
<DatePicker defaultValue={defaultValue} showTime onChange={onChange} />
</Space>
</ConfigProvider>
</Space>
);
};
export default App;

View File

@ -0,0 +1,7 @@
## zh-CN
通过 `components` 替换对应面板。
## en-US
Replace panel with `components`.

View File

@ -0,0 +1,76 @@
import React from 'react';
import type { DatePickerProps } from 'antd';
import { Button, DatePicker, Flex, Slider, Space, Typography } from 'antd';
import dayjs from 'dayjs';
import type { Dayjs } from 'dayjs';
const onChange: DatePickerProps['onChange'] = (date, dateString) => {
console.log(date, dateString);
};
type DateComponent = Required<NonNullable<DatePickerProps<Dayjs>['components']>>['date'];
type GetProps<T> = T extends React.ComponentType<infer P> ? P : never;
const MyDatePanel = (props: GetProps<DateComponent>) => {
const { value, onSelect, onHover } = props;
// Value
const startDate = React.useMemo(() => dayjs().date(1).month(0), []);
const [innerValue, setInnerValue] = React.useState(value || startDate);
React.useEffect(() => {
if (value) {
setInnerValue(value);
}
}, [value]);
// Range
const dateCount = React.useMemo(() => {
const endDate = startDate.add(1, 'year').add(-1, 'day');
return endDate.diff(startDate, 'day');
}, [startDate]);
const sliderValue = Math.min(Math.max(0, innerValue.diff(startDate, 'day')), dateCount);
// Render
return (
<Flex vertical gap="small" style={{ padding: 16 }}>
<Typography.Title level={4} style={{ margin: 0 }} title="no, it's not">
The BEST Picker Panel
</Typography.Title>
<Slider
min={0}
max={dateCount}
value={sliderValue}
onChange={(nextValue) => {
const nextDate = startDate.add(nextValue, 'day');
setInnerValue(nextDate);
onHover?.(nextDate);
}}
tooltip={{
formatter: (nextValue) => startDate.add(nextValue || 0, 'day').format('YYYY-MM-DD'),
}}
/>
<Button
type="primary"
onClick={() => {
onSelect(innerValue);
}}
>{`That's It!`}</Button>
</Flex>
);
};
const App: React.FC = () => (
<Space direction="vertical">
<DatePicker
showNow={false}
onChange={onChange}
components={{
date: MyDatePanel,
}}
/>
</Space>
);
export default App;

View File

@ -0,0 +1,7 @@
## zh-CN
通过 `minDate``maxDate` 限定日期范围。
## en-US
Limit the range of dates by `minDate` and `maxDate`.

View File

@ -0,0 +1,18 @@
import React from 'react';
import { DatePicker } from 'antd';
import dayjs from 'dayjs';
import customParseFormat from 'dayjs/plugin/customParseFormat';
dayjs.extend(customParseFormat);
const dateFormat = 'YYYY-MM-DD';
const App: React.FC = () => (
<DatePicker
defaultValue={dayjs('2019-09-03', dateFormat)}
minDate={dayjs('2019-08-01', dateFormat)}
maxDate={dayjs('2020-10-31', dateFormat)}
/>
);
export default App;

View File

@ -1,7 +1,7 @@
import React from 'react';
import { DatePicker, Space } from 'antd';
import dayjs from 'dayjs';
import customParseFormat from 'dayjs/plugin/customParseFormat';
import { DatePicker, Space } from 'antd';
dayjs.extend(customParseFormat);
@ -21,6 +21,11 @@ const App: React.FC = () => (
defaultValue={[dayjs('2019-09-03', dateFormat), dayjs('2019-11-22', dateFormat)]}
disabled={[false, true]}
/>
<DatePicker
defaultValue={dayjs('2019-09-03', dateFormat)}
minDate={dayjs('2019-06-01', dateFormat)}
maxDate={dayjs('2020-06-30', dateFormat)}
/>
</Space>
);

View File

@ -0,0 +1,7 @@
## zh-CN
输入格式对齐,通过键盘左右切换焦点。失去焦点时会尝试对齐到最后合法的日期。
## en-US
Align the date format. Switch the selection by arrow keys. Will try to align the date to the last valid date when blur.

View File

@ -0,0 +1,28 @@
import React from 'react';
import type { DatePickerProps } from 'antd';
import { DatePicker, Space } from 'antd';
const onChange: DatePickerProps['onChange'] = (date, dateString) => {
console.log(date, dateString);
};
const App: React.FC = () => (
<Space direction="vertical">
<DatePicker
format={{
format: 'YYYY-MM-DD',
type: 'mask',
}}
onChange={onChange}
/>
<DatePicker
format={{
format: 'YYYY-MM-DD HH:mm:ss',
type: 'mask',
}}
onChange={onChange}
/>
</Space>
);
export default App;

View File

@ -1,13 +1,13 @@
import React, { useState } from 'react';
import type { DatePickerProps, GetProps } from 'antd';
import { DatePicker, Space } from 'antd';
import type { DatePickerProps, GetProps } from 'antd';
import type { Dayjs } from 'dayjs';
type RangePickerProps = GetProps<typeof DatePicker.RangePicker>;
const { RangePicker } = DatePicker;
type RangeValue = [Dayjs | null, Dayjs | null] | null;
type RangeValue = [Dayjs | null | undefined, Dayjs | null | undefined] | null;
const ControlledDatePicker = () => {
const [mode, setMode] = useState<DatePickerProps['mode']>('time');

View File

@ -0,0 +1,7 @@
## zh-CN
多选,不支持 `showTime` 以及 `picker="time"`
## en-US
Multiple selection. Not support `showTime` and `picker="time"`.

View File

@ -0,0 +1,33 @@
import React from 'react';
import type { DatePickerProps } from 'antd';
import { DatePicker, Flex } from 'antd';
import dayjs from 'dayjs';
import type { Dayjs } from 'dayjs';
const onChange: DatePickerProps<Dayjs[]>['onChange'] = (date, dateString) => {
console.log(date, dateString);
};
const defaultValue = [dayjs(), dayjs().add(1, 'day'), dayjs().add(2, 'day')];
const App: React.FC = () => (
<Flex vertical gap="small">
<DatePicker
multiple
onChange={onChange}
maxTagCount="responsive"
defaultValue={defaultValue}
size="small"
/>
<DatePicker multiple onChange={onChange} maxTagCount="responsive" defaultValue={defaultValue} />
<DatePicker
multiple
onChange={onChange}
maxTagCount="responsive"
defaultValue={defaultValue}
size="large"
/>
</Flex>
);
export default App;

View File

@ -10,7 +10,19 @@ const App: React.FC = () => (
<RangePicker picker="week" />
<RangePicker picker="month" />
<RangePicker picker="quarter" />
<RangePicker picker="year" />
<RangePicker
picker="year"
id={{
start: 'startInput',
end: 'endInput',
}}
onFocus={(_, info) => {
console.log('Focus:', info.range);
}}
onBlur={(_, info) => {
console.log('Blur:', info.range);
}}
/>
</Space>
);

View File

@ -1,46 +1,24 @@
import type { Dayjs } from 'dayjs';
import React, { useState } from 'react';
import { DatePicker } from 'antd';
import type { DatePickerProps } from 'antd';
import type { Dayjs } from 'dayjs';
const { RangePicker } = DatePicker;
type RangeValue = [Dayjs | null, Dayjs | null] | null;
const App: React.FC = () => {
const [dates, setDates] = useState<RangeValue>(null);
const [value, setValue] = useState<RangeValue>(null);
const disabledDate = (current: Dayjs) => {
if (!dates) {
return false;
const disabledDate: DatePickerProps['disabledDate'] = (current, { from }) => {
if (from) {
return Math.abs(current.diff(from, 'days')) > 7;
}
const tooLate = dates[0] && current.diff(dates[0], 'days') >= 7;
const tooEarly = dates[1] && dates[1].diff(current, 'days') >= 7;
return !!tooEarly || !!tooLate;
return false;
};
const onOpenChange = (open: boolean) => {
if (open) {
setDates([null, null]);
} else {
setDates(null);
}
};
return (
<RangePicker
value={dates || value}
disabledDate={disabledDate}
onCalendarChange={(val) => {
setDates(val);
}}
onChange={(val) => {
setValue(val);
}}
onOpenChange={onOpenChange}
changeOnBlur
/>
);
return <RangePicker value={value} disabledDate={disabledDate} onChange={setValue} />;
};
export default App;

View File

@ -1,18 +1,12 @@
import React from 'react';
import { SmileOutlined } from '@ant-design/icons';
import type { Dayjs } from 'dayjs';
import { DatePicker, Space } from 'antd';
import type { Dayjs } from 'dayjs';
const smileIcon = <SmileOutlined />;
const { RangePicker } = DatePicker;
type DatePickerValue = Dayjs | null;
type RangePickerValue = [Dayjs | null, Dayjs | null] | null;
const onChange = (
date: DatePickerValue | RangePickerValue,
dateString: [string, string] | string,
) => {
const onChange = (date: Dayjs | (Dayjs | null)[] | null, dateString: string | string[]) => {
console.log(date, dateString);
};

View File

@ -1,5 +0,0 @@
import PickerButton from '../PickerButton';
const Components = { button: PickerButton };
export default Components;

View File

@ -5,51 +5,37 @@ import ClockCircleOutlined from '@ant-design/icons/ClockCircleOutlined';
import CloseCircleFilled from '@ant-design/icons/CloseCircleFilled';
import SwapRightOutlined from '@ant-design/icons/SwapRightOutlined';
import classNames from 'classnames';
import { RangePicker as RCRangePicker } from 'rc-picker';
import { RangePicker as RCRangePicker, type PickerRef } from 'rc-picker';
import type { GenerateConfig } from 'rc-picker/lib/generate/index';
import type { RangePickerProps } from '.';
import { useZIndex } from '../../_util/hooks/useZIndex';
import { getMergedStatus, getStatusClassNames } from '../../_util/statusUtils';
import type { AnyObject } from '../../_util/type';
import { devUseWarning } from '../../_util/warning';
import { ConfigContext } from '../../config-provider';
import DisabledContext from '../../config-provider/DisabledContext';
import useCSSVarCls from '../../config-provider/hooks/useCSSVarCls';
import useSize from '../../config-provider/hooks/useSize';
import { FormItemInputContext } from '../../form/context';
import useVariant from '../../form/hooks/useVariants';
import { useLocale } from '../../locale';
import { NoCompactStyle, useCompactItemContext } from '../../space/Compact';
import enUS from '../locale/en_US';
import useStyle from '../style';
import {
getRangePlaceholder,
getTimeProps,
mergeAllowClear,
transPlacement2DropdownAlign,
} from '../util';
import Components from './Components';
import type { CommonPickerMethods, PickerComponentClass } from './interface';
import { useZIndex } from '../../_util/hooks/useZIndex';
import useCSSVarCls from '../../config-provider/hooks/useCSSVarCls';
import useVariant from '../../form/hooks/useVariants';
import { getRangePlaceholder, mergeAllowClear, transPlacement2DropdownAlign } from '../util';
import type { RangePickerProps } from './interface';
import useComponents from './useComponents';
export default function generateRangePicker<DateType>(generateConfig: GenerateConfig<DateType>) {
type InternalRangePickerProps = RangePickerProps<DateType> & {};
type DateRangePickerProps = RangePickerProps<DateType> & {
/**
* @deprecated `dropdownClassName` is deprecated which will be removed in next major
* version.Please use `popupClassName` instead.
*/
dropdownClassName?: string;
popupClassName?: string;
rootClassName?: string;
};
export default function generateRangePicker<DateType extends AnyObject>(
generateConfig: GenerateConfig<DateType>,
) {
type DateRangePickerProps = RangePickerProps<DateType>;
const RangePicker = forwardRef<
InternalRangePickerProps | CommonPickerMethods,
DateRangePickerProps
>((props, ref) => {
const RangePicker = forwardRef<PickerRef, DateRangePickerProps>((props, ref) => {
const {
prefixCls: customizePrefixCls,
getPopupContainer: customGetPopupContainer,
components,
className,
style,
placement,
@ -67,11 +53,11 @@ export default function generateRangePicker<DateType>(generateConfig: GenerateCo
...restProps
} = props;
const innerRef = React.useRef<RCRangePicker<DateType>>(null);
const innerRef = React.useRef<PickerRef>(null);
const { getPrefixCls, direction, getPopupContainer, rangePicker } = useContext(ConfigContext);
const prefixCls = getPrefixCls('picker', customizePrefixCls);
const { compactSize, compactItemClassnames } = useCompactItemContext(prefixCls, direction);
const { format, showTime, picker } = props as any;
const { picker } = props;
const rootPrefixCls = getPrefixCls();
const [variant, enableVariantCls] = useVariant(customVariant, bordered);
@ -79,11 +65,6 @@ export default function generateRangePicker<DateType>(generateConfig: GenerateCo
const rootCls = useCSSVarCls(prefixCls);
const [wrapCSSVar, hashId, cssVarCls] = useStyle(prefixCls, rootCls);
const additionalOverrideProps: any = {
...(showTime ? getTimeProps({ format, picker, ...showTime }) : {}),
...(picker === 'time' ? getTimeProps({ format, ...props, picker }) : {}),
};
// =================== Warning =====================
if (process.env.NODE_ENV !== 'production') {
const warning = devUseWarning('DatePicker.RangePicker');
@ -93,6 +74,9 @@ export default function generateRangePicker<DateType>(generateConfig: GenerateCo
warning.deprecated(!('bordered' in props), 'bordered', 'variant');
}
// ================== components ==================
const mergedComponents = useComponents(components);
// ===================== Size =====================
const mergedSize = useSize((ctx) => customizeSize ?? compactSize ?? ctx);
@ -111,10 +95,7 @@ export default function generateRangePicker<DateType>(generateConfig: GenerateCo
</>
);
useImperativeHandle(ref, () => ({
focus: () => innerRef.current?.focus(),
blur: () => innerRef.current?.blur(),
}));
useImperativeHandle(ref, () => innerRef.current!);
const [contextLocale] = useLocale('Calendar', enUS);
@ -133,7 +114,7 @@ export default function generateRangePicker<DateType>(generateConfig: GenerateCo
}
disabled={mergedDisabled}
ref={innerRef}
dropdownAlign={transPlacement2DropdownAlign(direction, placement)}
popupAlign={transPlacement2DropdownAlign(direction, placement)}
placeholder={getRangePlaceholder(locale, picker, placeholder)}
suffixIcon={suffixNode}
prevIcon={<span className={`${prefixCls}-prev-icon`} />}
@ -142,7 +123,6 @@ export default function generateRangePicker<DateType>(generateConfig: GenerateCo
superNextIcon={<span className={`${prefixCls}-super-next-icon`} />}
transitionName={`${rootPrefixCls}-slide-up`}
{...restProps}
{...additionalOverrideProps}
className={classNames(
{
[`${prefixCls}-${mergedSize}`]: mergedSize,
@ -166,18 +146,22 @@ export default function generateRangePicker<DateType>(generateConfig: GenerateCo
prefixCls={prefixCls}
getPopupContainer={customGetPopupContainer || getPopupContainer}
generateConfig={generateConfig}
components={Components}
components={mergedComponents}
direction={direction}
dropdownClassName={classNames(
hashId,
popupClassName || dropdownClassName,
cssVarCls,
rootCls,
rootClassName,
)}
popupStyle={{
...props.popupStyle,
zIndex,
classNames={{
popup: classNames(
hashId,
popupClassName || dropdownClassName,
cssVarCls,
rootCls,
rootClassName,
),
}}
styles={{
popup: {
...props.popupStyle,
zIndex,
},
}}
allowClear={mergeAllowClear(allowClear, clearIcon, <CloseCircleFilled />)}
/>
@ -189,5 +173,5 @@ export default function generateRangePicker<DateType>(generateConfig: GenerateCo
RangePicker.displayName = 'RangePicker';
}
return RangePicker as unknown as PickerComponentClass<DateRangePickerProps>;
return RangePicker;
}

View File

@ -4,216 +4,199 @@ import CalendarOutlined from '@ant-design/icons/CalendarOutlined';
import ClockCircleOutlined from '@ant-design/icons/ClockCircleOutlined';
import CloseCircleFilled from '@ant-design/icons/CloseCircleFilled';
import classNames from 'classnames';
import RCPicker from 'rc-picker';
import RCPicker, { type PickerRef } from 'rc-picker';
import type { GenerateConfig } from 'rc-picker/lib/generate/index';
import type { PickerMode } from 'rc-picker/lib/interface';
import type { PickerProps, PickerTimeProps } from '.';
import type { InputStatus } from '../../_util/statusUtils';
import { useZIndex } from '../../_util/hooks/useZIndex';
import { getMergedStatus, getStatusClassNames } from '../../_util/statusUtils';
import type { AnyObject } from '../../_util/type';
import { devUseWarning } from '../../_util/warning';
import { ConfigContext } from '../../config-provider';
import DisabledContext from '../../config-provider/DisabledContext';
import useCSSVarCls from '../../config-provider/hooks/useCSSVarCls';
import useSize from '../../config-provider/hooks/useSize';
import { FormItemInputContext } from '../../form/context';
import useVariant from '../../form/hooks/useVariants';
import { useLocale } from '../../locale';
import { NoCompactStyle, useCompactItemContext } from '../../space/Compact';
import enUS from '../locale/en_US';
import useStyle from '../style';
import {
getPlaceholder,
getTimeProps,
mergeAllowClear,
transPlacement2DropdownAlign,
} from '../util';
import Components from './Components';
import type { CommonPickerMethods, DatePickRef, PickerComponentClass } from './interface';
import { useZIndex } from '../../_util/hooks/useZIndex';
import useCSSVarCls from '../../config-provider/hooks/useCSSVarCls';
import useVariant from '../../form/hooks/useVariants';
import { getPlaceholder, mergeAllowClear, transPlacement2DropdownAlign } from '../util';
import type { PickerProps, PickerPropsWithMultiple } from './interface';
import useComponents from './useComponents';
export default function generatePicker<DateType>(generateConfig: GenerateConfig<DateType>) {
type CustomPickerProps = {
status?: InputStatus;
hashId?: string;
popupClassName?: string;
rootClassName?: string;
};
type DatePickerProps = PickerProps<DateType> & CustomPickerProps;
type TimePickerProps = PickerTimeProps<DateType> & CustomPickerProps;
export default function generatePicker<DateType extends AnyObject>(
generateConfig: GenerateConfig<DateType>,
) {
type DatePickerProps = PickerProps<DateType>;
type TimePickerProps = Omit<PickerProps<DateType>, 'picker' | 'showTime'>;
function getPicker<InnerPickerProps extends DatePickerProps>(
picker?: PickerMode,
displayName?: string,
) {
const consumerName = displayName === 'TimePicker' ? 'timePicker' : 'datePicker';
const Picker = forwardRef<DatePickRef<DateType> | CommonPickerMethods, InnerPickerProps>(
(props, ref) => {
const {
prefixCls: customizePrefixCls,
getPopupContainer: customizeGetPopupContainer,
style,
className,
rootClassName,
size: customizeSize,
bordered,
placement,
placeholder,
popupClassName,
dropdownClassName,
disabled: customDisabled,
status: customStatus,
clearIcon,
allowClear,
variant: customVariant,
...restProps
} = props;
const Picker = forwardRef<PickerRef, InnerPickerProps>((props, ref) => {
const {
prefixCls: customizePrefixCls,
getPopupContainer: customizeGetPopupContainer,
components,
style,
className,
rootClassName,
size: customizeSize,
bordered,
placement,
placeholder,
popupClassName,
dropdownClassName,
disabled: customDisabled,
status: customStatus,
clearIcon,
allowClear,
variant: customVariant,
...restProps
} = props;
const {
getPrefixCls,
direction,
getPopupContainer,
// Consume different styles according to different names
[consumerName]: consumerStyle,
} = useContext(ConfigContext);
const {
getPrefixCls,
direction,
getPopupContainer,
// Consume different styles according to different names
[consumerName]: consumerStyle,
} = useContext(ConfigContext);
const prefixCls = getPrefixCls('picker', customizePrefixCls);
const { compactSize, compactItemClassnames } = useCompactItemContext(prefixCls, direction);
const innerRef = React.useRef<RCPicker<DateType>>(null);
const { format, showTime } = props as any;
const prefixCls = getPrefixCls('picker', customizePrefixCls);
const { compactSize, compactItemClassnames } = useCompactItemContext(prefixCls, direction);
const innerRef = React.useRef<PickerRef>(null);
const [variant, enableVariantCls] = useVariant(customVariant, bordered);
const [variant, enableVariantCls] = useVariant(customVariant, bordered);
const rootCls = useCSSVarCls(prefixCls);
const [wrapCSSVar, hashId, cssVarCls] = useStyle(prefixCls, rootCls);
const rootCls = useCSSVarCls(prefixCls);
const [wrapCSSVar, hashId, cssVarCls] = useStyle(prefixCls, rootCls);
useImperativeHandle(ref, () => ({
focus: () => innerRef.current?.focus(),
blur: () => innerRef.current?.blur(),
}));
useImperativeHandle(ref, () => innerRef.current!);
const additionalProps = {
showToday: true,
};
const additionalProps = {
showToday: true,
};
let additionalOverrideProps: any = {};
if (picker) {
additionalOverrideProps.picker = picker;
}
const mergedPicker = picker || props.picker;
const mergedPicker = picker || props.picker;
additionalOverrideProps = {
...additionalOverrideProps,
...(showTime ? getTimeProps({ format, picker: mergedPicker, ...showTime }) : {}),
...(mergedPicker === 'time'
? getTimeProps({ format, ...props, picker: mergedPicker })
: {}),
};
const rootPrefixCls = getPrefixCls();
const rootPrefixCls = getPrefixCls();
// =================== Warning =====================
if (process.env.NODE_ENV !== 'production') {
const warning = devUseWarning(displayName! || 'DatePicker');
// =================== Warning =====================
if (process.env.NODE_ENV !== 'production') {
const warning = devUseWarning(displayName! || 'DatePicker');
warning(
picker !== 'quarter',
'deprecated',
`DatePicker.${displayName} is legacy usage. Please use DatePicker[picker='${picker}'] directly.`,
);
warning.deprecated(!dropdownClassName, 'dropdownClassName', 'popupClassName');
warning.deprecated(!('bordered' in props), 'bordered', 'variant');
}
// ===================== Size =====================
const mergedSize = useSize((ctx) => customizeSize ?? compactSize ?? ctx);
// ===================== Disabled =====================
const disabled = React.useContext(DisabledContext);
const mergedDisabled = customDisabled ?? disabled;
// ===================== FormItemInput =====================
const formItemContext = useContext(FormItemInputContext);
const { hasFeedback, status: contextStatus, feedbackIcon } = formItemContext;
const suffixNode = (
<>
{mergedPicker === 'time' ? <ClockCircleOutlined /> : <CalendarOutlined />}
{hasFeedback && feedbackIcon}
</>
warning(
picker !== 'quarter',
'deprecated',
`DatePicker.${displayName} is legacy usage. Please use DatePicker[picker='${picker}'] directly.`,
);
const [contextLocale] = useLocale('DatePicker', enUS);
warning.deprecated(!dropdownClassName, 'dropdownClassName', 'popupClassName');
const locale = { ...contextLocale, ...props.locale! };
// ============================ zIndex ============================
const [zIndex] = useZIndex('DatePicker', props.popupStyle?.zIndex as number);
warning.deprecated(!('bordered' in props), 'bordered', 'variant');
}
return wrapCSSVar(
<NoCompactStyle>
<RCPicker<DateType>
ref={innerRef}
placeholder={getPlaceholder(locale, mergedPicker, placeholder)}
suffixIcon={suffixNode}
dropdownAlign={transPlacement2DropdownAlign(direction, placement)}
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`} />}
transitionName={`${rootPrefixCls}-slide-up`}
{...additionalProps}
{...restProps}
{...additionalOverrideProps}
locale={locale!.lang}
className={classNames(
{
[`${prefixCls}-${mergedSize}`]: mergedSize,
[`${prefixCls}-${variant}`]: enableVariantCls,
},
getStatusClassNames(
prefixCls,
getMergedStatus(contextStatus, customStatus),
hasFeedback,
),
hashId,
compactItemClassnames,
consumerStyle?.className,
className,
cssVarCls,
rootCls,
rootClassName,
)}
style={{ ...consumerStyle?.style, ...style }}
prefixCls={prefixCls}
getPopupContainer={customizeGetPopupContainer || getPopupContainer}
generateConfig={generateConfig}
components={Components}
direction={direction}
disabled={mergedDisabled}
dropdownClassName={classNames(
// ================== components ==================
const mergedComponents = useComponents(components);
// ===================== Size =====================
const mergedSize = useSize((ctx) => customizeSize ?? compactSize ?? ctx);
// ===================== Disabled =====================
const disabled = React.useContext(DisabledContext);
const mergedDisabled = customDisabled ?? disabled;
// ===================== FormItemInput =====================
const formItemContext = useContext(FormItemInputContext);
const { hasFeedback, status: contextStatus, feedbackIcon } = formItemContext;
const suffixNode = (
<>
{mergedPicker === 'time' ? <ClockCircleOutlined /> : <CalendarOutlined />}
{hasFeedback && feedbackIcon}
</>
);
const [contextLocale] = useLocale('DatePicker', enUS);
const locale = { ...contextLocale, ...props.locale! };
// ============================ zIndex ============================
const [zIndex] = useZIndex('DatePicker', props.popupStyle?.zIndex as number);
return wrapCSSVar(
<NoCompactStyle>
<RCPicker<DateType>
ref={innerRef}
placeholder={getPlaceholder(locale, mergedPicker, placeholder)}
suffixIcon={suffixNode}
dropdownAlign={transPlacement2DropdownAlign(direction, placement)}
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`} />}
transitionName={`${rootPrefixCls}-slide-up`}
picker={picker}
{...additionalProps}
{...restProps}
locale={locale!.lang}
className={classNames(
{
[`${prefixCls}-${mergedSize}`]: mergedSize,
[`${prefixCls}-${variant}`]: enableVariantCls,
},
getStatusClassNames(
prefixCls,
getMergedStatus(contextStatus, customStatus),
hasFeedback,
),
hashId,
compactItemClassnames,
consumerStyle?.className,
className,
cssVarCls,
rootCls,
rootClassName,
)}
style={{ ...consumerStyle?.style, ...style }}
prefixCls={prefixCls}
getPopupContainer={customizeGetPopupContainer || getPopupContainer}
generateConfig={generateConfig}
components={mergedComponents}
direction={direction}
disabled={mergedDisabled}
classNames={{
popup: classNames(
hashId,
cssVarCls,
rootCls,
rootClassName,
popupClassName || dropdownClassName,
)}
popupStyle={{
),
}}
styles={{
popup: {
...props.popupStyle,
zIndex,
}}
allowClear={mergeAllowClear(allowClear, clearIcon, <CloseCircleFilled />)}
/>
</NoCompactStyle>,
);
},
);
},
}}
allowClear={mergeAllowClear(allowClear, clearIcon, <CloseCircleFilled />)}
/>
</NoCompactStyle>,
);
});
if (displayName) {
if (process.env.NODE_ENV !== 'production' && displayName) {
Picker.displayName = displayName;
}
return Picker as unknown as PickerComponentClass<InnerPickerProps>;
return Picker as unknown as (<ValueType = DateType>(
props: PickerPropsWithMultiple<DateType, InnerPickerProps, ValueType>,
) => React.ReactElement) & { displayName?: string };
}
const DatePicker = getPicker<DatePickerProps>();

View File

@ -1,88 +1,12 @@
import type {
PickerBaseProps as RCPickerBaseProps,
PickerDateProps as RCPickerDateProps,
PickerTimeProps as RCPickerTimeProps,
} from 'rc-picker/lib/Picker';
import type {
RangePickerBaseProps as RCRangePickerBaseProps,
RangePickerDateProps as RCRangePickerDateProps,
RangePickerTimeProps as RCRangePickerTimeProps,
} from 'rc-picker/lib/RangePicker';
import type { GenerateConfig } from 'rc-picker/lib/generate/index';
import type { Locale as RcPickerLocale } from 'rc-picker/lib/interface';
import type { InputStatus } from '../../_util/statusUtils';
import type { SizeType } from '../../config-provider/SizeContext';
import type { TimePickerLocale } from '../../time-picker';
import type { AnyObject } from '../../_util/type';
import generateRangePicker from './generateRangePicker';
import generateSinglePicker from './generateSinglePicker';
import type { Variant } from '../../form/hooks/useVariants';
const DataPickerPlacements = ['bottomLeft', 'bottomRight', 'topLeft', 'topRight'] as const;
type DataPickerPlacement = (typeof DataPickerPlacements)[number];
export type { PickerLocale, PickerProps } from './interface';
type InjectDefaultProps<Props> = Omit<
Props,
'locale' | 'generateConfig' | 'hideHeader' | 'components'
> & {
locale?: PickerLocale;
size?: SizeType;
placement?: DataPickerPlacement;
/** @deprecated Use `variant` instead */
bordered?: boolean;
status?: InputStatus;
/**
* @since 5.13.0
* @default "outlined"
*/
variant?: Variant;
};
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];
rangeQuarterPlaceholder?: [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>) {
function generatePicker<DateType extends AnyObject>(generateConfig: GenerateConfig<DateType>) {
// =========================== Picker ===========================
const { DatePicker, WeekPicker, MonthPicker, YearPicker, TimePicker, QuarterPicker } =
generateSinglePicker(generateConfig);

View File

@ -0,0 +1,91 @@
import type {
PickerRef,
PickerProps as RcPickerProps,
RangePickerProps as RcRangePickerProps,
} from 'rc-picker';
import type { Locale as RcPickerLocale } from 'rc-picker/lib/interface';
import type { InputStatus } from '../../_util/statusUtils';
import type { AnyObject } from '../../_util/type';
import type { SizeType } from '../../config-provider/SizeContext';
import type { Variant } from '../../form/hooks/useVariants';
import type { TimePickerLocale } from '../../time-picker';
const DataPickerPlacements = ['bottomLeft', 'bottomRight', 'topLeft', 'topRight'] as const;
type DataPickerPlacement = (typeof DataPickerPlacements)[number];
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];
rangeQuarterPlaceholder?: [string, string];
rangeMonthPlaceholder?: [string, string];
rangeWeekPlaceholder?: [string, string];
rangePlaceholder?: [string, string];
};
type InjectDefaultProps<Props> = Omit<Props, 'locale' | 'generateConfig' | 'hideHeader'> & {
locale?: PickerLocale;
size?: SizeType;
placement?: DataPickerPlacement;
/** @deprecated Use `variant` instead */
bordered?: boolean;
status?: InputStatus;
/**
* @since 5.13.0
* @default "outlined"
*/
variant?: Variant;
/**
* @deprecated `dropdownClassName` is deprecated which will be removed in next major
* version.Please use `popupClassName` instead.
*/
dropdownClassName?: string;
popupClassName?: string;
rootClassName?: string;
popupStyle?: React.CSSProperties;
};
/** Base Single Picker props */
export type PickerProps<DateType extends AnyObject = any> = InjectDefaultProps<
RcPickerProps<DateType>
>;
/** Base Range Picker props */
export type RangePickerProps<DateType extends AnyObject = any> = InjectDefaultProps<
RcRangePickerProps<DateType>
>;
/**
* Single Picker has the `multiple` prop,
* which will make the `value` be `DateType[]` type.
* Here to be a generic which accept the `ValueType` for developer usage.
*/
export type PickerPropsWithMultiple<
DateType extends AnyObject = any,
InnerPickerProps extends PickerProps<DateType> = PickerProps<DateType>,
ValueType = DateType,
> = Omit<InnerPickerProps, 'defaultValue' | 'value' | 'onChange' | 'onOk'> &
React.RefAttributes<PickerRef> & {
defaultValue?: ValueType | null;
value?: ValueType | null;
onChange?: (date: ValueType, dates: string | string[]) => void;
onOk?: (date: ValueType) => void;
};

View File

@ -1,18 +0,0 @@
import type { Component, ComponentClass, ForwardedRef } from 'react';
import type { PickerProps, RangePickerProps } from '.';
export interface CommonPickerMethods {
focus: () => void;
blur: () => void;
}
export interface PickerComponentClass<P = {}, S = unknown> extends ComponentClass<P, S> {
new (...args: ConstructorParameters<ComponentClass<P, S>>): InstanceType<ComponentClass<P, S>> &
CommonPickerMethods;
}
export type PickerRef<P> = ForwardedRef<Component<P> & CommonPickerMethods>;
export type DatePickRef<DateType> = PickerRef<PickerProps<DateType>>;
export type RangePickerRef<DateType> = PickerRef<RangePickerProps<DateType>>;

View File

@ -0,0 +1,14 @@
import { useMemo } from 'react';
import type { Components } from 'rc-picker/lib/interface';
import PickerButton from '../PickerButton';
export default function useComponents(components?: Components) {
return useMemo(
() => ({
button: PickerButton,
...components,
}),
[components],
);
}

View File

@ -18,18 +18,24 @@ By clicking the input box, you can select a date from a popup calendar.
<!-- prettier-ignore -->
<code src="./demo/basic.tsx">Basic</code>
<code src="./demo/range-picker.tsx">Range Picker</code>
<code src="./demo/multiple.tsx" version="5.14.0">Multiple</code>
<code src="./demo/switchable.tsx">Switchable picker</code>
<code src="./demo/format.tsx">Date Format</code>
<code src="./demo/time.tsx">Choose Time</code>
<code src="./demo/mask.tsx" version="5.14.0">Mask Format</code>
<code src="./demo/date-range.tsx" version="5.14.0">Limit Date Range</code>
<code src="./demo/disabled.tsx">Disabled</code>
<code src="./demo/disabled-date.tsx">Disabled Date & Time</code>
<code src="./demo/allow-empty.tsx">Allow Empty</code>
<code src="./demo/select-in-range.tsx">Select range dates in 7 days</code>
<code src="./demo/preset-ranges.tsx">Preset Ranges</code>
<code src="./demo/extra-footer.tsx">Extra Footer</code>
<code src="./demo/size.tsx">Three Sizes</code>
<code src="./demo/cell-render.tsx">Customized Cell Rendering</code>
<code src="./demo/components.tsx" version="5.14.0">Customize Panel</code>
<code src="./demo/buddhist-era.tsx" version="5.14.0">Buddhist Era</code>
<code src="./demo/status.tsx">Status</code>
<code src="./demo/variant.tsx" version="5.13.0">Variants</code>
<code src="./demo/variant.tsx" version="5.14.0">Variants</code>
<code src="./demo/filled-debug.tsx" debug>Filled Debug</code>
<code src="./demo/placement.tsx">Placement</code>
<code src="./demo/mode.tsx" debug>Controlled Panels</code>
@ -92,16 +98,21 @@ The following APIs are shared by DatePicker, RangePicker.
| autoFocus | If get focus when component mounted | boolean | false | |
| className | The picker className | string | - | |
| dateRender | Custom rendering function for date cells, >= 5.4.0 use `cellRender` instead. | function(currentDate: dayjs, today: dayjs) => React.ReactNode | - | < 5.4.0 |
| changeOnBlur | Trigger `change` when blur. e.g. datetime picker no need click confirm button | boolean | false | 5.5.0 |
| cellRender | Custom rendering function for picker cells | (current: dayjs, info: { originNode: React.ReactElement,today: DateType, range?: 'start' \| 'end', type: PanelMode, locale?: Locale, subType?: 'hour' \| 'minute' \| 'second' \| 'meridiem' }) => React.ReactNode | - | 5.4.0 |
| components | Custom panels | Record<Panel \| 'input', React.ComponentType> | - | 5.14.0 |
| disabled | Determine whether the DatePicker is disabled | boolean | false | |
| disabledDate | Specify the date that cannot be selected | (currentDate: dayjs) => boolean | - | |
| disabledDate | Specify the date that cannot be selected | (currentDate: dayjs, info: { from?: dayjs }) => boolean | - | `info`: 5.14.0 |
| format | To set the date format, support multi-format matching when it is an array, display the first one shall prevail. refer to [dayjs#format](https://day.js.org/docs/en/display/format). for example: [Custom Format](#components-date-picker-demo-format) | [formatType](#formattype) | [rc-picker](https://github.com/react-component/picker/blob/f512f18ed59d6791280d1c3d7d37abbb9867eb0b/src/utils/uiUtil.ts#L155-L177) | |
| order | Auto order date when multiple or range selection | boolean | true | 5.14.0 |
| popupClassName | To customize the className of the popup calendar | string | - | 4.23.0 |
| preserveInvalidOnBlur | Not clean input on blur even when the typing is invalidate | boolean | false | 5.14.0 |
| getPopupContainer | To set the container of the floating layer, while the default is to create a `div` element in `body` | function(trigger) | - | |
| inputReadOnly | Set the `readonly` attribute of the input tag (avoids virtual keyboard on touch devices) | boolean | false | |
| locale | Localization configuration | object | [default](https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json) | |
| minDate | The minimum date, which also limits the range of panel switching | dayjs | - | 5.14.0 |
| maxDate | The maximum date, which also limits the range of panel switching | dayjs | - | 5.14.0 |
| mode | The picker panel mode [Cannot select year or month anymore?](/docs/react/faq#when-set-mode-to-datepickerrangepicker-cannot-select-year-or-month-anymore) ) | `time` \| `date` \| `month` \| `year` \| `decade` | - | |
| needConfirm | Need click confirm button to trigger value change | boolean | - | 5.14.0 |
| nextIcon | The custom next icon | ReactNode | - | 4.17.0 |
| open | The open state of picker | boolean | - | |
| panelRender | Customize panel render | (panelNode) => ReactNode | - | 4.5.0 |
@ -117,7 +128,7 @@ The following APIs are shared by DatePicker, RangePicker.
| suffixIcon | The custom suffix icon | ReactNode | - | |
| superNextIcon | The custom super next icon | ReactNode | - | 4.17.0 |
| superPrevIcon | The custom super prev icon | ReactNode | - | 4.17.0 |
| variant | Variants of picker | `outlined` \| `borderless` \| `filled` | `outlined` | 5.13.0 |
| variant | Variants of picker | `outlined` \| `borderless` \| `filled` | `outlined` | 5.14.0 |
| onOpenChange | Callback function, can be executed whether the popup calendar is popped up or closed | function(open) | - | |
| onPanelChange | Callback when picker panel mode is changed | function(value, mode) | - | |
@ -132,14 +143,16 @@ The following APIs are shared by DatePicker, RangePicker.
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| defaultPickerValue | Default panel date, will be reset when panel open | [dayjs](https://day.js.org/) | - | 5.14.0 |
| defaultValue | To set default date, if start time or end time is null or undefined, the date range will be an open interval | [dayjs](https://day.js.org/) | - | |
| disabledTime | To specify the time that cannot be selected | function(date) | - | |
| format | To set the date format. refer to [dayjs#format](https://day.js.org/docs/en/display/format) | [formatType](#formattype) | `YYYY-MM-DD` | |
| pickerValue | Panel date. Used for controlled switching of panel date. Work with `onPanelChange` | [dayjs](https://day.js.org/) | - | 5.14.0 |
| renderExtraFooter | Render extra footer in panel | (mode) => React.ReactNode | - | |
| showNow | Whether to show 'Now' button on panel when `showTime` is set | boolean | - | 4.4.0 |
| showNow | Show the fast access of current datetime | boolean | - | 4.4.0 |
| showTime | To provide an additional time selection | object \| boolean | [TimePicker Options](/components/time-picker/#api) | |
| showTime.defaultValue | To set default time of selected date, [demo](#components-date-picker-demo-disabled-date) | [dayjs](https://day.js.org/) | dayjs() | |
| showToday | Whether to show `Today` button | boolean | true | |
| showWeek | Show week info when in DatePicker | boolean | false | 5.14.0 |
| value | To set date | [dayjs](https://day.js.org/) | - | |
| onChange | Callback function, can be executed when the selected time is changing | function(date: dayjs, dateString: string) | - | |
| onOk | Callback when click ok button | function() | - | |
@ -192,12 +205,15 @@ Added in `4.1.0`.
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| allowEmpty | Allow start or end input leave empty | \[boolean, boolean] | \[false, false] | |
| dateRender | Custom rendering function for date cells, >= 5.4.0 use `cellRender` instead. | function(currentDate: dayjs, today: dayjs) => React.ReactNode | - | < 5.4.0 |
| cellRender | Custom rendering function for picker cells | (current: dayjs, info: { originNode: React.ReactElement,today: DateType, range?: 'start' \| 'end', type: PanelMode, locale?: Locale, subType?: 'hour' \| 'minute' \| 'second' \| 'meridiem' }) => React.ReactNode | - | 5.4.0 |
| dateRender | Custom rendering function for date cells, >= 5.4.0 use `cellRender` instead. | function(currentDate: dayjs, today: dayjs) => React.ReactNode | - | < 5.4.0 |
| defaultPickerValue | Default panel date, will be reset when panel open | [dayjs](https://day.js.org/) | - | 5.14.0 |
| defaultValue | To set default date | \[[dayjs](https://day.js.org/), [dayjs](https://day.js.org/)] | - | |
| disabled | If disable start or end | \[boolean, boolean] | - | |
| disabledTime | To specify the time that cannot be selected | function(date: dayjs, partial: `start` \| `end`) | - | |
| format | To set the date format. refer to [dayjs#format](https://day.js.org/docs/en/display/format) | [formatType](#formattype) | `YYYY-MM-DD HH:mm:ss` | |
| id | Config input ids | { start?: string, end?: string } | - | 5.14.0 |
| pickerValue | Panel date. Used for controlled switching of panel date. Work with `onPanelChange` | [dayjs](https://day.js.org/) | - | 5.14.0 |
| presets | The preset ranges for quick selection, Since `5.8.0`, preset value supports callback function. | { label: React.ReactNode, value: (Dayjs \| (() => Dayjs))\[] }\[] | - | |
| renderExtraFooter | Render extra footer in panel | () => React.ReactNode | - | |
| separator | Set separator between inputs | React.ReactNode | `<SwapRightOutlined />` | |
@ -206,6 +222,8 @@ Added in `4.1.0`.
| value | To set date | \[[dayjs](https://day.js.org/), [dayjs](https://day.js.org/)] | - | |
| onCalendarChange | Callback function, can be executed when the start time or the end time of the range is changing. `info` argument is added in 4.4.0 | function(dates: \[dayjs, dayjs], dateStrings: \[string, string], info: { range:`start`\|`end` }) | - | |
| onChange | Callback function, can be executed when the selected time is changing | function(dates: \[dayjs, dayjs], dateStrings: \[string, string]) | - | |
| onFocus | Trigger when get focus | function(event, { range: 'start' \| 'end' }) | - | `range`: 5.14.0 |
| onBlur | Trigger when lose focus | function(event, { range: 'start' \| 'end' }) | - | `range`: 5.14.0 |
#### formatType
@ -215,9 +233,18 @@ import type { Dayjs } from 'dayjs';
type Generic = string;
type GenericFn = (value: Dayjs) => string;
export type FormatType = Generic | GenericFn | Array<Generic | GenericFn>;
export type FormatType =
| Generic
| GenericFn
| Array<Generic | GenericFn>
| {
format: string;
type?: 'mask';
};
```
Note: `type` is added in `5.14.0`.
## Design Token
<ComponentTokenTable component="DatePicker"></ComponentTokenTable>

View File

@ -2,17 +2,24 @@ import type { Dayjs } from 'dayjs';
import dayjsGenerateConfig from 'rc-picker/lib/generate/dayjs';
import genPurePanel from '../_util/PurePanel';
import generatePicker from './generatePicker';
import type {
RangePickerProps as BaseRangePickerProps,
PickerDateProps,
PickerProps,
} from './generatePicker';
import generatePicker from './generatePicker';
PickerPropsWithMultiple,
} from './generatePicker/interface';
import { transPlacement2DropdownAlign } from './util';
export type DatePickerProps = PickerProps<Dayjs>;
export type MonthPickerProps = Omit<PickerDateProps<Dayjs>, 'picker'>;
export type WeekPickerProps = Omit<PickerDateProps<Dayjs>, 'picker'>;
export type DatePickerProps<ValueType = Dayjs | Dayjs> = PickerPropsWithMultiple<
Dayjs,
PickerProps<Dayjs>,
ValueType
>;
export type MonthPickerProps<ValueType = Dayjs | Dayjs> = Omit<
DatePickerProps<ValueType>,
'picker'
>;
export type WeekPickerProps<ValueType = Dayjs | Dayjs> = Omit<DatePickerProps<ValueType>, 'picker'>;
export type RangePickerProps = BaseRangePickerProps<Dayjs>;
const DatePicker = generatePicker<Dayjs>(dayjsGenerateConfig);
@ -43,4 +50,4 @@ const PureRangePanel = genPurePanel(DatePicker.RangePicker, 'picker', null, post
(DatePicker as DatePickerType)._InternalRangePanelDoNotUseOrYouWillBeFired = PureRangePanel;
(DatePicker as DatePickerType).generatePicker = generatePicker;
export default DatePicker as DatePickerType;
export default (DatePicker as DatePickerType);

View File

@ -19,18 +19,24 @@ demo:
<!-- prettier-ignore -->
<code src="./demo/basic.tsx">基本</code>
<code src="./demo/range-picker.tsx">范围选择器</code>
<code src="./demo/multiple.tsx" version="5.14.0">多选</code>
<code src="./demo/switchable.tsx">切换不同的选择器</code>
<code src="./demo/format.tsx">日期格式</code>
<code src="./demo/time.tsx">日期时间选择</code>
<code src="./demo/mask.tsx" version="5.14.0">格式对齐</code>
<code src="./demo/date-range.tsx" version="5.14.0">日期限定范围</code>
<code src="./demo/disabled.tsx">禁用</code>
<code src="./demo/disabled-date.tsx">不可选择日期和时间</code>
<code src="./demo/allow-empty.tsx">允许留空</code>
<code src="./demo/select-in-range.tsx">选择不超过七天的范围</code>
<code src="./demo/preset-ranges.tsx">预设范围</code>
<code src="./demo/extra-footer.tsx">额外的页脚</code>
<code src="./demo/size.tsx">三种大小</code>
<code src="./demo/cell-render.tsx">定制单元格</code>
<code src="./demo/components.tsx" version="5.14.0">定制面板</code>
<code src="./demo/buddhist-era.tsx" version="5.14.0">佛历格式</code>
<code src="./demo/status.tsx">自定义状态</code>
<code src="./demo/variant.tsx" version="5.13.0">多种形态</code>
<code src="./demo/variant.tsx" version="5.14.0">多种形态</code>
<code src="./demo/filled-debug.tsx" debug>Filled Debug</code>
<code src="./demo/placement.tsx">弹出位置</code>
<code src="./demo/mode.tsx" debug>受控面板</code>
@ -93,16 +99,21 @@ import 'dayjs/locale/zh-cn';
| autoFocus | 自动获取焦点 | boolean | false | |
| className | 选择器 className | string | - | |
| dateRender | 自定义日期单元格的内容5.4.0 起用 `cellRender` 代替 | function(currentDate: dayjs, today: dayjs) => React.ReactNode | - | < 5.4.0 |
| changeOnBlur | 失去焦点时触发 `change` 事件,例如 datetime 下不再需要点击确认按钮 | boolean | false | 5.5.0 |
| cellRender | 自定义单元格的内容 | (current: dayjs, info: { originNode: React.ReactElement,today: DateType, range?: 'start' \| 'end', type: PanelMode, locale?: Locale, subType?: 'hour' \| 'minute' \| 'second' \| 'meridiem' }) => React.ReactNode | - | 5.4.0 |
| components | 自定义面板 | Record<Panel \| 'input', React.ComponentType> | - | 5.14.0 |
| disabled | 禁用 | boolean | false | |
| disabledDate | 不可选择的日期 | (currentDate: dayjs) => boolean | - | |
| disabledDate | 不可选择的日期 | (currentDate: dayjs, info: { from?: dayjs }) => boolean | - | `info`: 5.14.0 |
| format | 设置日期格式,为数组时支持多格式匹配,展示以第一个为准。配置参考 [dayjs#format](https://day.js.org/docs/zh-CN/display/format#%E6%94%AF%E6%8C%81%E7%9A%84%E6%A0%BC%E5%BC%8F%E5%8C%96%E5%8D%A0%E4%BD%8D%E7%AC%A6%E5%88%97%E8%A1%A8)。示例:[自定义格式](#components-date-picker-demo-format) | [formatType](#formattype) | [rc-picker](https://github.com/react-component/picker/blob/f512f18ed59d6791280d1c3d7d37abbb9867eb0b/src/utils/uiUtil.ts#L155-L177) | |
| order | 多选、范围时是否自动排序 | boolean | true | 5.14.0 |
| preserveInvalidOnBlur | 失去焦点是否要清空输入框内无效内容 | boolean | false | 5.14.0 |
| popupClassName | 额外的弹出日历 className | string | - | 4.23.0 |
| getPopupContainer | 定义浮层的容器,默认为 body 上新建 div | function(trigger) | - | |
| inputReadOnly | 设置输入框为只读(避免在移动设备上打开虚拟键盘) | boolean | false | |
| locale | 国际化配置 | object | [默认配置](https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json) | |
| minDate | 最小日期,同样会限制面板的切换范围 | dayjs | - | 5.14.0 |
| maxDate | 最大日期,同样会限制面板的切换范围 | dayjs | - | 5.14.0 |
| mode | 日期面板的状态([设置后无法选择年份/月份?](/docs/react/faq#当我指定了-datepickerrangepicker-的-mode-属性后点击后无法选择年份月份) | `time` \| `date` \| `month` \| `year` \| `decade` | - | |
| needConfirm | 是否需要确认按钮,为 `false` 时失去焦点即代表选择 | boolean | - | 5.14.0 |
| nextIcon | 自定义下一个图标 | ReactNode | - | 4.17.0 |
| open | 控制弹层是否展开 | boolean | - | |
| panelRender | 自定义渲染面板 | (panelNode) => ReactNode | - | 4.5.0 |
@ -118,7 +129,7 @@ import 'dayjs/locale/zh-cn';
| suffixIcon | 自定义的选择框后缀图标 | ReactNode | - | |
| superNextIcon | 自定义 `>>` 切换图标 | ReactNode | - | 4.17.0 |
| superPrevIcon | 自定义 `<<` 切换图标 | ReactNode | - | 4.17.0 |
| variant | 形态变体 | `outlined` \| `borderless` \| `filled` | `outlined` | 5.13.0 |
| variant | 形态变体 | `outlined` \| `borderless` \| `filled` | `outlined` | 5.14.0 |
| onOpenChange | 弹出日历和关闭日历的回调 | function(open) | - | |
| onPanelChange | 日历面板切换的回调 | function(value, mode) | - | |
@ -133,14 +144,16 @@ import 'dayjs/locale/zh-cn';
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| defaultPickerValue | 默认面板日期,每次面板打开时会被重置到该日期 | [dayjs](https://day.js.org/) | - | 5.14.0 |
| defaultValue | 默认日期,如果开始时间或结束时间为 `null` 或者 `undefined`,日期范围将是一个开区间 | [dayjs](https://day.js.org/) | - | |
| disabledTime | 不可选择的时间 | function(date) | - | |
| format | 展示的日期格式,配置参考 [dayjs#format](https://day.js.org/docs/zh-CN/display/format#%E6%94%AF%E6%8C%81%E7%9A%84%E6%A0%BC%E5%BC%8F%E5%8C%96%E5%8D%A0%E4%BD%8D%E7%AC%A6%E5%88%97%E8%A1%A8)。 | [formatType](#formattype) | `YYYY-MM-DD` | |
| pickerValue | 面板日期,可以用于受控切换面板所在日期。配合 `onPanelChange` 使用。 | [dayjs](https://day.js.org/) | - | 5.14.0 |
| renderExtraFooter | 在面板中添加额外的页脚 | (mode) => React.ReactNode | - | |
| showNow | 当设定了 `showTime` 的时候,面板是否显示“此刻”按钮 | boolean | - | 4.4.0 |
| showNow | 显示当前日期时间的快捷选择 | boolean | - | |
| showTime | 增加时间选择功能 | Object \| boolean | [TimePicker Options](/components/time-picker-cn#api) | |
| showTime.defaultValue | 设置用户选择日期时默认的时分秒,[例子](#components-date-picker-demo-disabled-date) | [dayjs](https://day.js.org/) | dayjs() | |
| showToday | 是否展示“今天”按钮 | boolean | true | |
| showWeek | DatePicker 下展示当前周 | boolean | false | 5.14.0 |
| value | 日期 | [dayjs](https://day.js.org/) | - | |
| onChange | 时间发生变化的回调 | function(date: dayjs, dateString: string) | - | |
| onOk | 点击确定按钮的回调 | function() | - | |
@ -193,12 +206,15 @@ import 'dayjs/locale/zh-cn';
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| allowEmpty | 允许起始项部分为空 | \[boolean, boolean] | \[false, false] | |
| dateRender | 自定义日期单元格的内容5.4.0 起用 `cellRender` 代替 | function(currentDate: dayjs, today: dayjs) => React.ReactNode | - | < 5.4.0 |
| cellRender | 自定义单元格的内容。 | (current: dayjs, info: { originNode: React.ReactElement,today: DateType, range?: 'start' \| 'end', type: PanelMode, locale?: Locale, subType?: 'hour' \| 'minute' \| 'second' \| 'meridiem' }) => React.ReactNode | - | 5.4.0 |
| dateRender | 自定义日期单元格的内容5.4.0 起用 `cellRender` 代替 | function(currentDate: dayjs, today: dayjs) => React.ReactNode | - | < 5.4.0 |
| defaultPickerValue | 默认面板日期,每次面板打开时会被重置到该日期 | [dayjs](https://day.js.org/)[] | - | 5.14.0 |
| defaultValue | 默认日期 | [dayjs](https://day.js.org/)\[] | - | |
| disabled | 禁用起始项 | \[boolean, boolean] | - | |
| disabledTime | 不可选择的时间 | function(date: dayjs, partial: `start` \| `end`) | - | |
| format | 展示的日期格式,配置参考 [dayjs#format](https://day.js.org/docs/zh-CN/display/format#%E6%94%AF%E6%8C%81%E7%9A%84%E6%A0%BC%E5%BC%8F%E5%8C%96%E5%8D%A0%E4%BD%8D%E7%AC%A6%E5%88%97%E8%A1%A8)。 | [formatType](#formattype) | `YYYY-MM-DD HH:mm:ss` | |
| id | 设置输入框 `id` 属性。 | { start?: string, end?: string } | - | 5.14.0 |
| pickerValue | 面板日期,可以用于受控切换面板所在日期。配合 `onPanelChange` 使用。 | [dayjs](https://day.js.org/)[] | - | 5.14.0 |
| presets | 预设时间范围快捷选择,自 `5.8.0` 起 value 支持函数返回值 | { label: React.ReactNode, value: (Dayjs \| (() => Dayjs))\[] }\[] | - | |
| renderExtraFooter | 在面板中添加额外的页脚 | () => React.ReactNode | - | |
| separator | 设置分隔符 | React.ReactNode | `<SwapRightOutlined />` | |
@ -207,6 +223,8 @@ import 'dayjs/locale/zh-cn';
| value | 日期 | [dayjs](https://day.js.org/)\[] | - | |
| onCalendarChange | 待选日期发生变化的回调。`info` 参数自 4.4.0 添加 | function(dates: \[dayjs, dayjs], dateStrings: \[string, string], info: { range:`start`\|`end` }) | - | |
| onChange | 日期范围发生变化的回调 | function(dates: \[dayjs, dayjs], dateStrings: \[string, string]) | - | |
| onFocus | 聚焦时回调 | function(event, { range: 'start' \| 'end' }) | - | `range`: 5.14.0 |
| onBlur | 失焦时回调 | function(event, { range: 'start' \| 'end' }) | - | `range`: 5.14.0 |
#### formatType
@ -216,9 +234,18 @@ import type { Dayjs } from 'dayjs';
type Generic = string;
type GenericFn = (value: Dayjs) => string;
export type FormatType = Generic | GenericFn | Array<Generic | GenericFn>;
export type FormatType =
| Generic
| GenericFn
| Array<Generic | GenericFn>
| {
format: string;
type?: 'mask';
};
```
注意:`type` 定义为 `5.14.0` 新增。
## 主题变量Design Token
<ComponentTokenTable component="DatePicker"></ComponentTokenTable>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,94 @@
import type { CSSInterpolation } from '@ant-design/cssinjs';
import { genSelectionStyle } from '../../select/style/multiple';
import { mergeToken, type GenerateStyle } from '../../theme/internal';
import type { PickerToken } from './token';
const genSize = (token: PickerToken, suffix?: string): CSSInterpolation => {
const { componentCls, selectHeight, fontHeight, lineWidth, calc } = token;
const suffixCls = suffix ? `${componentCls}-${suffix}` : '';
const height = token.calc(fontHeight).add(2).equal();
const restHeight = () => calc(selectHeight).sub(height).sub(calc(lineWidth).mul(2));
const paddingTop = token.max(restHeight().div(2).equal(), 0);
const paddingBottom = token.max(restHeight().sub(paddingTop).equal(), 0);
return [
genSelectionStyle(token, suffix),
{
[`${componentCls}-multiple${suffixCls}`]: {
paddingTop,
paddingBottom,
paddingInlineStart: paddingTop,
},
},
];
};
const genPickerMultipleStyle: GenerateStyle<PickerToken> = (token) => {
const { componentCls, calc, lineWidth } = token;
const smallToken = mergeToken<PickerToken>(token, {
fontHeight: token.fontSize,
selectHeight: token.controlHeightSM,
multipleSelectItemHeight: token.controlHeightXS,
borderRadius: token.borderRadiusSM,
borderRadiusSM: token.borderRadiusXS,
});
const largeToken = mergeToken<PickerToken>(token, {
fontHeight: calc(token.multipleItemHeightLG)
.sub(calc(lineWidth).mul(2).equal())
.equal() as number,
fontSize: token.fontSizeLG,
selectHeight: token.controlHeightLG,
multipleSelectItemHeight: token.multipleItemHeightLG,
borderRadius: token.borderRadiusLG,
borderRadiusSM: token.borderRadius,
});
return [
// ======================== Size ========================
genSize(smallToken, 'small'),
genSize(token),
genSize(largeToken, 'large'),
// ====================== Selection ======================
genSelectionStyle(token),
{
[`${componentCls}${componentCls}-multiple`]: {
width: '100%',
// ==================== Selector =====================
[`${componentCls}-selector`]: {
flex: 'auto',
padding: 0,
'&:after': {
margin: 0,
},
},
// ==================== Selection ====================
[`${componentCls}-selection-item`]: {
marginBlock: 0,
},
// ====================== Input ======================
// Input is `readonly`, which is used for a11y only
[`${componentCls}-multiple-input`]: {
width: 0,
height: 0,
border: 0,
visibility: 'hidden',
position: 'absolute',
zIndex: -1,
},
},
},
];
};
export default genPickerMultipleStyle;

View File

@ -0,0 +1,712 @@
import { unit, type CSSObject } from '@ant-design/cssinjs';
import { TinyColor } from '@ctrl/tinycolor';
import type { GenerateStyle } from '../../theme/internal';
import type { PickerToken, SharedPickerToken } from './token';
const genPickerCellInnerStyle = (token: SharedPickerToken): CSSObject => {
const {
pickerCellCls,
pickerCellInnerCls,
cellHeight,
borderRadiusSM,
motionDurationMid,
cellHoverBg,
lineWidth,
lineType,
colorPrimary,
cellActiveWithRangeBg,
colorTextLightSolid,
colorTextDisabled,
cellBgDisabled,
colorFillSecondary,
} = token;
return {
'&::before': {
position: 'absolute',
top: '50%',
insetInlineStart: 0,
insetInlineEnd: 0,
zIndex: 1,
height: cellHeight,
transform: 'translateY(-50%)',
content: '""',
},
// >>> Default
[pickerCellInnerCls]: {
position: 'relative',
zIndex: 2,
display: 'inline-block',
minWidth: cellHeight,
height: cellHeight,
lineHeight: unit(cellHeight),
borderRadius: borderRadiusSM,
transition: `background ${motionDurationMid}`,
},
// >>> Hover
[`&:hover:not(${pickerCellCls}-in-view),
&:hover:not(${pickerCellCls}-selected):not(${pickerCellCls}-range-start):not(${pickerCellCls}-range-end)`]:
{
[pickerCellInnerCls]: {
background: cellHoverBg,
},
},
// >>> Today
[`&-in-view${pickerCellCls}-today ${pickerCellInnerCls}`]: {
'&::before': {
position: 'absolute',
top: 0,
insetInlineEnd: 0,
bottom: 0,
insetInlineStart: 0,
zIndex: 1,
border: `${unit(lineWidth)} ${lineType} ${colorPrimary}`,
borderRadius: borderRadiusSM,
content: '""',
},
},
// >>> In Range
[`&-in-view${pickerCellCls}-in-range,
&-in-view${pickerCellCls}-range-start,
&-in-view${pickerCellCls}-range-end`]: {
position: 'relative',
[`&:not(${pickerCellCls}-disabled):before`]: {
background: cellActiveWithRangeBg,
},
},
// >>> Selected
[`&-in-view${pickerCellCls}-selected,
&-in-view${pickerCellCls}-range-start,
&-in-view${pickerCellCls}-range-end`]: {
[`&:not(${pickerCellCls}-disabled) ${pickerCellInnerCls}`]: {
color: colorTextLightSolid,
background: colorPrimary,
},
[`&${pickerCellCls}-disabled ${pickerCellInnerCls}`]: {
background: colorFillSecondary,
},
},
[`&-in-view${pickerCellCls}-range-start:not(${pickerCellCls}-disabled):before`]: {
insetInlineStart: '50%',
},
[`&-in-view${pickerCellCls}-range-end:not(${pickerCellCls}-disabled):before`]: {
insetInlineEnd: '50%',
},
// range start border-radius
[`&-in-view${pickerCellCls}-range-start:not(${pickerCellCls}-range-end) ${pickerCellInnerCls}`]:
{
borderStartStartRadius: borderRadiusSM,
borderEndStartRadius: borderRadiusSM,
borderStartEndRadius: 0,
borderEndEndRadius: 0,
},
// range end border-radius
[`&-in-view${pickerCellCls}-range-end:not(${pickerCellCls}-range-start) ${pickerCellInnerCls}`]:
{
borderStartStartRadius: 0,
borderEndStartRadius: 0,
borderStartEndRadius: borderRadiusSM,
borderEndEndRadius: borderRadiusSM,
},
// >>> Disabled
'&-disabled': {
color: colorTextDisabled,
pointerEvents: 'none',
[pickerCellInnerCls]: {
background: 'transparent',
},
'&::before': {
background: cellBgDisabled,
},
},
[`&-disabled${pickerCellCls}-today ${pickerCellInnerCls}::before`]: {
borderColor: colorTextDisabled,
},
};
};
export const genPanelStyle = (token: SharedPickerToken): CSSObject => {
const {
componentCls,
pickerCellCls,
pickerCellInnerCls,
pickerYearMonthCellWidth,
pickerControlIconSize,
cellWidth,
paddingSM,
paddingXS,
paddingXXS,
colorBgContainer,
lineWidth,
lineType,
borderRadiusLG,
colorPrimary,
colorTextHeading,
colorSplit,
pickerControlIconBorderWidth,
colorIcon,
textHeight,
motionDurationMid,
colorIconHover,
fontWeightStrong,
cellHeight,
pickerCellPaddingVertical,
colorTextDisabled,
colorText,
fontSize,
motionDurationSlow,
withoutTimeCellHeight,
pickerQuarterPanelContentHeight,
borderRadiusSM,
colorTextLightSolid,
cellHoverBg,
timeColumnHeight,
timeColumnWidth,
timeCellHeight,
controlItemBgActive,
marginXXS,
pickerDatePanelPaddingHorizontal,
pickerControlIconMargin,
} = token;
const pickerPanelWidth = token
.calc(cellWidth)
.mul(7)
.add(token.calc(pickerDatePanelPaddingHorizontal).mul(2))
.equal();
return {
[componentCls]: {
'&-panel': {
display: 'inline-flex',
flexDirection: 'column',
textAlign: 'center',
background: colorBgContainer,
borderRadius: borderRadiusLG,
outline: 'none',
'&-focused': {
borderColor: colorPrimary,
},
'&-rtl': {
direction: 'rtl',
[`${componentCls}-prev-icon,
${componentCls}-super-prev-icon`]: {
transform: 'rotate(45deg)',
},
[`${componentCls}-next-icon,
${componentCls}-super-next-icon`]: {
transform: 'rotate(-135deg)',
},
},
},
// ========================================================
// = Shared Panel =
// ========================================================
[`&-decade-panel,
&-year-panel,
&-quarter-panel,
&-month-panel,
&-week-panel,
&-date-panel,
&-time-panel`]: {
display: 'flex',
flexDirection: 'column',
width: pickerPanelWidth,
},
// ======================= Header =======================
'&-header': {
display: 'flex',
padding: `0 ${unit(paddingXS)}`,
color: colorTextHeading,
borderBottom: `${unit(lineWidth)} ${lineType} ${colorSplit}`,
'> *': {
flex: 'none',
},
button: {
padding: 0,
color: colorIcon,
lineHeight: unit(textHeight),
background: 'transparent',
border: 0,
cursor: 'pointer',
transition: `color ${motionDurationMid}`,
fontSize: 'inherit',
},
'> button': {
minWidth: '1.6em',
fontSize,
'&:hover': {
color: colorIconHover,
},
},
'&-view': {
flex: 'auto',
fontWeight: fontWeightStrong,
lineHeight: unit(textHeight),
button: {
color: 'inherit',
fontWeight: 'inherit',
verticalAlign: 'top',
'&:not(:first-child)': {
marginInlineStart: paddingXS,
},
'&:hover': {
color: colorPrimary,
},
},
},
},
// Arrow button
[`&-prev-icon,
&-next-icon,
&-super-prev-icon,
&-super-next-icon`]: {
position: 'relative',
display: 'inline-block',
width: pickerControlIconSize,
height: pickerControlIconSize,
'&::before': {
position: 'absolute',
top: 0,
insetInlineStart: 0,
display: 'inline-block',
width: pickerControlIconSize,
height: pickerControlIconSize,
border: `0 solid currentcolor`,
borderBlockStartWidth: pickerControlIconBorderWidth,
borderBlockEndWidth: 0,
borderInlineStartWidth: pickerControlIconBorderWidth,
borderInlineEndWidth: 0,
content: '""',
},
},
[`&-super-prev-icon,
&-super-next-icon`]: {
'&::after': {
position: 'absolute',
top: pickerControlIconMargin,
insetInlineStart: pickerControlIconMargin,
display: 'inline-block',
width: pickerControlIconSize,
height: pickerControlIconSize,
border: '0 solid currentcolor',
borderBlockStartWidth: pickerControlIconBorderWidth,
borderBlockEndWidth: 0,
borderInlineStartWidth: pickerControlIconBorderWidth,
borderInlineEndWidth: 0,
content: '""',
},
},
[`&-prev-icon,
&-super-prev-icon`]: {
transform: 'rotate(-45deg)',
},
[`&-next-icon,
&-super-next-icon`]: {
transform: 'rotate(135deg)',
},
// ======================== Body ========================
'&-content': {
width: '100%',
tableLayout: 'fixed',
borderCollapse: 'collapse',
'th, td': {
position: 'relative',
minWidth: cellHeight,
fontWeight: 'normal',
},
th: {
height: token.calc(cellHeight).add(token.calc(pickerCellPaddingVertical).mul(2)).equal(),
color: colorText,
verticalAlign: 'middle',
},
},
'&-cell': {
padding: `${unit(pickerCellPaddingVertical)} 0`,
color: colorTextDisabled,
cursor: 'pointer',
// In view
'&-in-view': {
color: colorText,
},
...genPickerCellInnerStyle(token),
},
[`&-decade-panel,
&-year-panel,
&-quarter-panel,
&-month-panel`]: {
[`${componentCls}-content`]: {
height: token.calc(withoutTimeCellHeight).mul(4).equal(),
},
[pickerCellInnerCls]: {
padding: `0 ${unit(paddingXS)}`,
},
},
'&-quarter-panel': {
[`${componentCls}-content`]: {
height: pickerQuarterPanelContentHeight,
},
},
// ========================================================
// = Special =
// ========================================================
// ===================== Decade Panel =====================
'&-decade-panel': {
[pickerCellInnerCls]: {
padding: `0 ${unit(token.calc(paddingXS).div(2).equal())}`,
},
[`${componentCls}-cell::before`]: {
display: 'none',
},
},
// ============= Year & Quarter & Month Panel =============
[`&-year-panel,
&-quarter-panel,
&-month-panel`]: {
[`${componentCls}-body`]: {
padding: `0 ${unit(paddingXS)}`,
},
[pickerCellInnerCls]: {
width: pickerYearMonthCellWidth,
},
},
// ====================== Date Panel ======================
'&-date-panel': {
[`${componentCls}-body`]: {
padding: `${unit(paddingXS)} ${unit(pickerDatePanelPaddingHorizontal)}`,
},
[`${componentCls}-content th`]: {
boxSizing: 'border-box',
padding: 0,
},
},
// ====================== Week Panel ======================
'&-week-panel': {
// Clear cell style
[`${componentCls}-cell`]: {
[`&:hover ${pickerCellInnerCls},
&-selected ${pickerCellInnerCls},
${pickerCellInnerCls}`]: {
background: 'transparent !important',
},
},
'&-row': {
td: {
'&:before': {
transition: `background ${motionDurationMid}`,
},
'&:first-child:before': {
borderStartStartRadius: borderRadiusSM,
borderEndStartRadius: borderRadiusSM,
},
'&:last-child:before': {
borderStartEndRadius: borderRadiusSM,
borderEndEndRadius: borderRadiusSM,
},
},
[`&:hover td`]: {
'&:before': {
background: cellHoverBg,
},
},
[`&-range-start td,
&-range-end td,
&-selected td`]: {
// Rise priority to override hover style
[`&${pickerCellCls}`]: {
'&:before': {
background: colorPrimary,
},
[`&${componentCls}-cell-week`]: {
color: new TinyColor(colorTextLightSolid).setAlpha(0.5).toHexString(),
},
[pickerCellInnerCls]: {
color: colorTextLightSolid,
},
},
},
[`&-range-hover td:before`]: {
background: controlItemBgActive,
},
},
},
// >>> ShowWeek
[`&-week-panel, &-date-panel-show-week`]: {
[`${componentCls}-body`]: {
padding: `${unit(paddingXS)} ${unit(paddingSM)}`,
},
[`${componentCls}-content th`]: {
width: 'auto',
},
},
// ==================== Datetime Panel ====================
'&-datetime-panel': {
display: 'flex',
[`${componentCls}-time-panel`]: {
borderInlineStart: `${unit(lineWidth)} ${lineType} ${colorSplit}`,
},
[`${componentCls}-date-panel,
${componentCls}-time-panel`]: {
transition: `opacity ${motionDurationSlow}`,
},
// Keyboard
'&-active': {
[`${componentCls}-date-panel,
${componentCls}-time-panel`]: {
opacity: 0.3,
'&-active': {
opacity: 1,
},
},
},
},
// ====================== Time Panel ======================
'&-time-panel': {
width: 'auto',
minWidth: 'auto',
direction: 'ltr',
[`${componentCls}-content`]: {
display: 'flex',
flex: 'auto',
height: timeColumnHeight,
},
'&-column': {
flex: '1 0 auto',
width: timeColumnWidth,
margin: `${unit(paddingXXS)} 0`,
padding: 0,
overflowY: 'hidden',
textAlign: 'start',
listStyle: 'none',
transition: `background ${motionDurationMid}`,
overflowX: 'hidden',
'&::-webkit-scrollbar': {
width: 8,
backgroundColor: 'transparent',
},
'&::-webkit-scrollbar-thumb': {
backgroundColor: token.colorTextTertiary,
borderRadius: 4,
},
// For Firefox
'&': {
scrollbarWidth: 'thin',
scrollbarColor: `${token.colorTextTertiary} transparent`,
},
'&::after': {
display: 'block',
height: token.calc(timeColumnHeight).sub(timeCellHeight).equal(),
content: '""',
},
'&:not(:first-child)': {
borderInlineStart: `${unit(lineWidth)} ${lineType} ${colorSplit}`,
},
'&-active': {
background: new TinyColor(controlItemBgActive).setAlpha(0.2).toHexString(),
},
'&:hover': {
overflowY: 'auto',
},
'> li': {
margin: 0,
padding: 0,
[`&${componentCls}-time-panel-cell`]: {
marginInline: marginXXS,
[`${componentCls}-time-panel-cell-inner`]: {
display: 'block',
width: token.calc(timeColumnWidth).sub(token.calc(marginXXS).mul(2)).equal(),
height: timeCellHeight,
margin: 0,
paddingBlock: 0,
paddingInlineEnd: 0,
paddingInlineStart: token.calc(timeColumnWidth).sub(timeCellHeight).div(2).equal(),
color: colorText,
lineHeight: unit(timeCellHeight),
borderRadius: borderRadiusSM,
cursor: 'pointer',
transition: `background ${motionDurationMid}`,
'&:hover': {
background: cellHoverBg,
},
},
'&-selected': {
[`${componentCls}-time-panel-cell-inner`]: {
background: controlItemBgActive,
},
},
'&-disabled': {
[`${componentCls}-time-panel-cell-inner`]: {
color: colorTextDisabled,
background: 'transparent',
cursor: 'not-allowed',
},
},
},
},
},
},
// https://github.com/ant-design/ant-design/issues/39227
[`&-datetime-panel ${componentCls}-time-panel-column:after`]: {
height: token
.calc(timeColumnHeight)
.sub(timeCellHeight)
.add(token.calc(paddingXXS).mul(2))
.equal(),
},
},
};
};
const genPickerPanelStyle: GenerateStyle<PickerToken> = (token) => {
const {
componentCls,
textHeight,
lineWidth,
paddingSM,
antCls,
colorPrimary,
cellActiveWithRangeBg,
colorPrimaryBorder,
lineType,
colorSplit,
} = token;
return {
[`${componentCls}-dropdown`]: {
// ======================== Footer ========================
[`${componentCls}-footer`]: {
borderTop: `${unit(lineWidth)} ${lineType} ${colorSplit}`,
'&-extra': {
padding: `0 ${unit(paddingSM)}`,
lineHeight: unit(token.calc(textHeight).sub(token.calc(lineWidth).mul(2)).equal()),
textAlign: 'start',
'&:not(:last-child)': {
borderBottom: `${unit(lineWidth)} ${lineType} ${colorSplit}`,
},
},
},
// ==================== Footer > Ranges ===================
[`${componentCls}-panels + ${componentCls}-footer ${componentCls}-ranges`]: {
justifyContent: 'space-between',
},
[`${componentCls}-ranges`]: {
marginBlock: 0,
paddingInline: unit(paddingSM),
overflow: 'hidden',
textAlign: 'start',
listStyle: 'none',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
'> li': {
lineHeight: unit(token.calc(textHeight).sub(token.calc(lineWidth).mul(2)).equal()),
display: 'inline-block',
},
[`${componentCls}-now-btn-disabled`]: {
pointerEvents: 'none',
color: token.colorTextDisabled,
},
// https://github.com/ant-design/ant-design/issues/23687
[`${componentCls}-preset > ${antCls}-tag-blue`]: {
color: colorPrimary,
background: cellActiveWithRangeBg,
borderColor: colorPrimaryBorder,
cursor: 'pointer',
},
[`${componentCls}-ok`]: {
paddingBlock: token.calc(lineWidth).mul(2).equal(),
marginInlineStart: 'auto',
},
},
},
};
};
export default genPickerPanelStyle;

View File

@ -1,16 +1,18 @@
import { TinyColor } from '@ctrl/tinycolor';
import type { SharedComponentToken, SharedInputToken } from '../../input/style/token';
import { initComponentToken } from '../../input/style/token';
import type { MultipleSelectorToken, SelectorToken } from '../../select/style/token';
import type { ArrowToken } from '../../style/roundedArrow';
import { getArrowToken } from '../../style/roundedArrow';
import type { GlobalToken } from '../../theme/interface';
import type {
FullToken,
TokenWithCommonCls,
GetDefaultToken,
TokenWithCommonCls,
} from '../../theme/util/genComponentStyleHook';
import type { GlobalToken } from '../../theme/interface';
import { TinyColor } from '@ctrl/tinycolor';
import { initComponentToken } from '../../input/style/token';
import { getArrowToken } from '../../style/roundedArrow';
export interface PanelComponentToken {
export interface PanelComponentToken extends MultipleSelectorToken {
/**
* @desc
* @descEN Background color of cell hover state
@ -107,7 +109,10 @@ export type PickerPanelToken = {
pickerControlIconBorderWidth: number;
};
export type PickerToken = FullToken<'DatePicker'> & PickerPanelToken & SharedInputToken;
export type PickerToken = FullToken<'DatePicker'> &
PickerPanelToken &
SharedInputToken &
SelectorToken;
export type SharedPickerToken = TokenWithCommonCls<GlobalToken> &
PickerPanelToken &
@ -133,20 +138,30 @@ export const initPickerPanelToken = (token: TokenWithCommonCls<GlobalToken>): Pi
};
};
export const initPanelComponentToken = (token: GlobalToken): PanelComponentToken => ({
cellHoverBg: token.controlItemBgHover,
cellActiveWithRangeBg: token.controlItemBgActive,
cellHoverWithRangeBg: new TinyColor(token.colorPrimary).lighten(35).toHexString(),
cellRangeBorderColor: new TinyColor(token.colorPrimary).lighten(20).toHexString(),
cellBgDisabled: token.colorBgContainerDisabled,
timeColumnWidth: token.controlHeightLG * 1.4,
timeColumnHeight: 28 * 8,
timeCellHeight: 28,
cellWidth: token.controlHeightSM * 1.5,
cellHeight: token.controlHeightSM,
textHeight: token.controlHeightLG,
withoutTimeCellHeight: token.controlHeightLG * 1.65,
});
export const initPanelComponentToken = (token: GlobalToken): PanelComponentToken => {
const { colorBgContainerDisabled, controlHeightSM, controlHeightLG } = token;
return {
cellHoverBg: token.controlItemBgHover,
cellActiveWithRangeBg: token.controlItemBgActive,
cellHoverWithRangeBg: new TinyColor(token.colorPrimary).lighten(35).toHexString(),
cellRangeBorderColor: new TinyColor(token.colorPrimary).lighten(20).toHexString(),
cellBgDisabled: colorBgContainerDisabled,
timeColumnWidth: controlHeightLG * 1.4,
timeColumnHeight: 28 * 8,
timeCellHeight: 28,
cellWidth: controlHeightSM * 1.5,
cellHeight: controlHeightSM,
textHeight: controlHeightLG,
withoutTimeCellHeight: controlHeightLG * 1.65,
multipleItemBg: token.colorFillSecondary,
multipleItemBorderColor: 'transparent',
multipleItemHeight: controlHeightSM,
multipleItemHeightLG: token.controlHeight,
multipleSelectorBgDisabled: colorBgContainerDisabled,
multipleItemColorDisabled: token.colorTextDisabled,
multipleItemBorderColorDisabled: 'transparent',
};
};
export const prepareComponentToken: GetDefaultToken<'DatePicker'> = (token) => ({
...initComponentToken(token),

View File

@ -1,13 +1,41 @@
import type { PickerToken } from './token';
import type { CSSObject } from '@ant-design/cssinjs';
import { genBorderlessStyle, genFilledStyle, genOutlinedStyle } from '../../input/style/variants';
import { unit, type CSSObject } from '@ant-design/cssinjs';
const genVariantsStyle = (token: PickerToken): CSSObject => ({
[token.componentCls]: {
...genOutlinedStyle(token),
...genFilledStyle(token),
...genBorderlessStyle(token),
},
});
import { genBorderlessStyle, genFilledStyle, genOutlinedStyle } from '../../input/style/variants';
import type { PickerToken } from './token';
const genVariantsStyle = (token: PickerToken): CSSObject => {
const { componentCls } = token;
return {
[componentCls]: [
{
...genOutlinedStyle(token),
...genFilledStyle(token),
...genBorderlessStyle(token),
},
// ========================= Multiple =========================
{
'&-outlined': {
[`&${componentCls}-multiple ${componentCls}-selection-item`]: {
background: token.multipleItemBg,
border: `${unit(token.lineWidth)} ${token.lineType} ${token.multipleItemBorderColor}`,
},
},
'&-filled': {
[`&${componentCls}-multiple ${componentCls}-selection-item`]: {
background: token.colorBgContainer,
border: `${unit(token.lineWidth)} ${token.lineType} ${token.colorSplit}`,
},
},
'&-borderless': {
[`&${componentCls}-multiple ${componentCls}-selection-item`]: {
background: token.multipleItemBg,
border: `${unit(token.lineWidth)} ${token.lineType} ${token.multipleItemBorderColor}`,
},
},
},
],
};
};
export default genVariantsStyle;

View File

@ -1,6 +1,6 @@
import type { AlignType } from '@rc-component/trigger';
import type { PickerMode } from 'rc-picker/lib/interface';
import type { SharedTimeProps } from 'rc-picker/lib/panels/TimePanel';
import type { SelectCommonPlacement } from '../_util/motion';
import type { DirectionType } from '../config-provider';
import type { PickerLocale, PickerProps } from './generatePicker';
@ -106,68 +106,8 @@ export function transPlacement2DropdownAlign(
}
}
function toArray<T>(list: T | T[]): T[] {
if (!list) {
return [];
}
return Array.isArray(list) ? list : [list];
}
export function getTimeProps<DateType, DisabledTime>(
props: { format?: string; picker?: PickerMode } & Omit<
SharedTimeProps<DateType>,
'disabledTime'
> & {
disabledTime?: DisabledTime;
},
) {
const { format, picker, showHour, showMinute, showSecond, use12Hours } = props;
const firstFormat = toArray(format)[0];
const showTimeObj = { ...props };
// https://github.com/ant-design/ant-design/issues/44275
if (format && Array.isArray(format)) {
showTimeObj.format = firstFormat;
}
if (firstFormat && typeof firstFormat === 'string') {
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') &&
!firstFormat.includes('K') &&
!firstFormat.includes('k') &&
showHour === undefined
) {
showTimeObj.showHour = false;
}
if ((firstFormat.includes('a') || firstFormat.includes('A')) && use12Hours === undefined) {
showTimeObj.use12Hours = true;
}
}
if (picker === 'time') {
return showTimeObj;
}
if (typeof firstFormat === 'function') {
// format of showTime should use default when format is custom format function
delete showTimeObj.format;
}
return {
showTime: showTimeObj,
};
}
type AllowClear = PickerProps<unknown>['allowClear'];
type ClearIcon = PickerProps<unknown>['clearIcon'];
type AllowClear = PickerProps['allowClear'];
type ClearIcon = PickerProps['clearIcon'];
export function mergeAllowClear(
allowClear: AllowClear,

View File

@ -1523,18 +1523,19 @@ Array [
class="ant-form-item-control-input-content"
>
<div
aria-required="true"
class="ant-picker ant-picker-range ant-picker-outlined"
style="width: 100%;"
>
<div
class="ant-picker-input ant-picker-input-active"
class="ant-picker-input"
>
<input
aria-invalid="false"
aria-required="true"
autocomplete="off"
date-range="start"
id="dateTime"
placeholder="Start date"
readonly=""
size="12"
value=""
/>
@ -1571,16 +1572,18 @@ Array [
class="ant-picker-input"
>
<input
aria-invalid="false"
aria-required="true"
autocomplete="off"
date-range="end"
placeholder="End date"
readonly=""
size="12"
value=""
/>
</div>
<div
class="ant-picker-active-bar"
style="left: 0px; width: 0px; position: absolute;"
style="position: absolute; width: 0px; left: 0px;"
/>
<span
class="ant-picker-suffix"
@ -1612,15 +1615,15 @@ Array [
>
<div
class="ant-picker-range-wrapper ant-picker-date-range-wrapper"
style="min-width: 0;"
>
<div
class="ant-picker-range-arrow"
style="left: 0px;"
/>
<div
class="ant-picker-panel-container"
style="margin-left: 0px;"
class="ant-picker-panel-container ant-picker-date-panel-container"
style="margin-left: 0px; margin-right: auto;"
tabindex="-1"
>
<div
class="ant-picker-panel-layout"
@ -1630,8 +1633,8 @@ Array [
class="ant-picker-panels"
>
<div
class="ant-picker-panel ant-picker-panel-focused"
tabindex="-1"
class="ant-picker-panel"
tabindex="0"
>
<div
class="ant-picker-date-panel"
@ -1740,7 +1743,7 @@ Array [
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-end"
class="ant-picker-cell"
title="2016-10-31"
>
<div
@ -1750,7 +1753,7 @@ Array [
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-start ant-picker-cell-in-view"
class="ant-picker-cell ant-picker-cell-in-view"
title="2016-11-01"
>
<div
@ -2048,7 +2051,7 @@ Array [
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-end ant-picker-cell-in-view"
class="ant-picker-cell ant-picker-cell-in-view"
title="2016-11-30"
>
<div
@ -2058,7 +2061,7 @@ Array [
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-start"
class="ant-picker-cell"
title="2016-12-01"
>
<div
@ -2166,8 +2169,8 @@ Array [
</div>
</div>
<div
class="ant-picker-panel ant-picker-panel-focused"
tabindex="-1"
class="ant-picker-panel"
tabindex="0"
>
<div
class="ant-picker-date-panel"
@ -2296,7 +2299,7 @@ Array [
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-end"
class="ant-picker-cell"
title="2016-11-30"
>
<div
@ -2306,7 +2309,7 @@ Array [
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-start ant-picker-cell-in-view"
class="ant-picker-cell ant-picker-cell-in-view"
title="2016-12-01"
>
<div
@ -2614,7 +2617,7 @@ Array [
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-end ant-picker-cell-in-view"
class="ant-picker-cell ant-picker-cell-in-view"
title="2016-12-31"
>
<div
@ -2626,7 +2629,7 @@ Array [
</tr>
<tr>
<td
class="ant-picker-cell ant-picker-cell-start"
class="ant-picker-cell"
title="2017-01-01"
>
<div

File diff suppressed because it is too large Load Diff

View File

@ -2335,18 +2335,17 @@ Array [
class="ant-form-item-control-input-content"
>
<div
class="ant-picker ant-picker-outlined ant-picker-disabled"
class="ant-picker ant-picker-disabled ant-picker-outlined"
>
<div
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
disabled=""
placeholder="Select date"
readonly=""
size="12"
title=""
value=""
/>
<span
@ -2405,16 +2404,17 @@ Array [
class="ant-form-item-control-input-content"
>
<div
class="ant-picker ant-picker-range ant-picker-outlined ant-picker-disabled"
class="ant-picker ant-picker-range ant-picker-disabled ant-picker-outlined"
>
<div
class="ant-picker-input ant-picker-input-active"
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
date-range="start"
disabled=""
placeholder="Start date"
readonly=""
size="12"
value=""
/>
@ -2451,17 +2451,18 @@ Array [
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
date-range="end"
disabled=""
placeholder="End date"
readonly=""
size="12"
value=""
/>
</div>
<div
class="ant-picker-active-bar"
style="left:0;width:0;position:absolute"
style="position:absolute;width:0;left:0"
/>
<span
class="ant-picker-suffix"
@ -7327,11 +7328,10 @@ exports[`renders components/form/demo/size.tsx correctly 1`] = `
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
placeholder="Select date"
readonly=""
size="12"
title=""
value=""
/>
<span
@ -7597,13 +7597,12 @@ exports[`renders components/form/demo/time-related-controls.tsx correctly 1`] =
class="ant-picker-input"
>
<input
aria-invalid="false"
aria-required="true"
autocomplete="off"
id="time_related_controls_date-picker"
placeholder="Select date"
readonly=""
size="12"
title=""
value=""
/>
<span
@ -7669,13 +7668,12 @@ exports[`renders components/form/demo/time-related-controls.tsx correctly 1`] =
class="ant-picker-input"
>
<input
aria-invalid="false"
aria-required="true"
autocomplete="off"
id="time_related_controls_date-time-picker"
placeholder="Select date"
readonly=""
size="21"
title=""
value=""
/>
<span
@ -7741,13 +7739,12 @@ exports[`renders components/form/demo/time-related-controls.tsx correctly 1`] =
class="ant-picker-input"
>
<input
aria-invalid="false"
aria-required="true"
autocomplete="off"
id="time_related_controls_month-picker"
placeholder="Select month"
readonly=""
size="12"
title=""
value=""
/>
<span
@ -7807,17 +7804,18 @@ exports[`renders components/form/demo/time-related-controls.tsx correctly 1`] =
class="ant-form-item-control-input-content"
>
<div
aria-required="true"
class="ant-picker ant-picker-range ant-picker-outlined"
>
<div
class="ant-picker-input ant-picker-input-active"
class="ant-picker-input"
>
<input
aria-invalid="false"
aria-required="true"
autocomplete="off"
date-range="start"
id="time_related_controls_range-picker"
placeholder="Start date"
readonly=""
size="12"
value=""
/>
@ -7854,16 +7852,18 @@ exports[`renders components/form/demo/time-related-controls.tsx correctly 1`] =
class="ant-picker-input"
>
<input
aria-invalid="false"
aria-required="true"
autocomplete="off"
date-range="end"
placeholder="End date"
readonly=""
size="12"
value=""
/>
</div>
<div
class="ant-picker-active-bar"
style="left:0;width:0;position:absolute"
style="position:absolute;width:0;left:0"
/>
<span
class="ant-picker-suffix"
@ -7921,17 +7921,18 @@ exports[`renders components/form/demo/time-related-controls.tsx correctly 1`] =
class="ant-form-item-control-input-content"
>
<div
aria-required="true"
class="ant-picker ant-picker-range ant-picker-outlined"
>
<div
class="ant-picker-input ant-picker-input-active"
class="ant-picker-input"
>
<input
aria-invalid="false"
aria-required="true"
autocomplete="off"
date-range="start"
id="time_related_controls_range-time-picker"
placeholder="Start date"
readonly=""
size="21"
value=""
/>
@ -7968,16 +7969,18 @@ exports[`renders components/form/demo/time-related-controls.tsx correctly 1`] =
class="ant-picker-input"
>
<input
aria-invalid="false"
aria-required="true"
autocomplete="off"
date-range="end"
placeholder="End date"
readonly=""
size="21"
value=""
/>
</div>
<div
class="ant-picker-active-bar"
style="left:0;width:0;position:absolute"
style="position:absolute;width:0;left:0"
/>
<span
class="ant-picker-suffix"
@ -8041,13 +8044,12 @@ exports[`renders components/form/demo/time-related-controls.tsx correctly 1`] =
class="ant-picker-input"
>
<input
aria-invalid="false"
aria-required="true"
autocomplete="off"
id="time_related_controls_time-picker"
placeholder="Select time"
readonly=""
size="10"
title=""
value=""
/>
<span
@ -10321,11 +10323,10 @@ exports[`renders components/form/demo/validate-static.tsx correctly 1`] = `
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
placeholder="Select date"
readonly=""
size="12"
title=""
value=""
/>
<span
@ -10414,11 +10415,10 @@ exports[`renders components/form/demo/validate-static.tsx correctly 1`] = `
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
placeholder="Select time"
readonly=""
size="10"
title=""
value=""
/>
<span
@ -10507,12 +10507,13 @@ exports[`renders components/form/demo/validate-static.tsx correctly 1`] = `
style="width:100%"
>
<div
class="ant-picker-input ant-picker-input-active"
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
date-range="start"
placeholder="Start date"
readonly=""
size="12"
value=""
/>
@ -10549,16 +10550,17 @@ exports[`renders components/form/demo/validate-static.tsx correctly 1`] = `
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
date-range="end"
placeholder="End date"
readonly=""
size="12"
value=""
/>
</div>
<div
class="ant-picker-active-bar"
style="left:0;width:0;position:absolute"
style="position:absolute;width:0;left:0"
/>
<span
class="ant-picker-suffix"
@ -10997,11 +10999,10 @@ exports[`renders components/form/demo/validate-static.tsx correctly 1`] = `
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
placeholder="Select date"
readonly=""
size="12"
title=""
value=""
/>
<span
@ -11062,11 +11063,10 @@ exports[`renders components/form/demo/validate-static.tsx correctly 1`] = `
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
placeholder="Select date"
readonly=""
size="12"
title=""
value=""
/>
<span
@ -12403,13 +12403,12 @@ exports[`renders components/form/demo/variant.tsx correctly 1`] = `
class="ant-picker-input"
>
<input
aria-invalid="false"
aria-required="true"
autocomplete="off"
id="DatePicker"
placeholder="Select date"
readonly=""
size="12"
title=""
value=""
/>
<span
@ -12469,17 +12468,18 @@ exports[`renders components/form/demo/variant.tsx correctly 1`] = `
class="ant-form-item-control-input-content"
>
<div
aria-required="true"
class="ant-picker ant-picker-range ant-picker-filled"
>
<div
class="ant-picker-input ant-picker-input-active"
class="ant-picker-input"
>
<input
aria-invalid="false"
aria-required="true"
autocomplete="off"
date-range="start"
id="RangePicker"
placeholder="Start date"
readonly=""
size="12"
value=""
/>
@ -12516,16 +12516,18 @@ exports[`renders components/form/demo/variant.tsx correctly 1`] = `
class="ant-picker-input"
>
<input
aria-invalid="false"
aria-required="true"
autocomplete="off"
date-range="end"
placeholder="End date"
readonly=""
size="12"
value=""
/>
</div>
<div
class="ant-picker-active-bar"
style="left:0;width:0;position:absolute"
style="position:absolute;width:0;left:0"
/>
<span
class="ant-picker-suffix"

View File

@ -552,18 +552,17 @@ exports[`Form form should support disabled 1`] = `
class="ant-form-item-control-input-content"
>
<div
class="ant-picker ant-picker-outlined ant-picker-disabled"
class="ant-picker ant-picker-disabled ant-picker-outlined"
>
<div
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
disabled=""
placeholder="Select date"
readonly=""
size="12"
title=""
value=""
/>
<span
@ -622,16 +621,17 @@ exports[`Form form should support disabled 1`] = `
class="ant-form-item-control-input-content"
>
<div
class="ant-picker ant-picker-range ant-picker-outlined ant-picker-disabled"
class="ant-picker ant-picker-range ant-picker-disabled ant-picker-outlined"
>
<div
class="ant-picker-input ant-picker-input-active"
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
date-range="start"
disabled=""
placeholder="Start date"
readonly=""
size="12"
value=""
/>
@ -668,17 +668,18 @@ exports[`Form form should support disabled 1`] = `
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
date-range="end"
disabled=""
placeholder="End date"
readonly=""
size="12"
value=""
/>
</div>
<div
class="ant-picker-active-bar"
style="left: 0px; width: 0px; position: absolute;"
style="position: absolute; width: 0px; left: 0px;"
/>
<span
class="ant-picker-suffix"

View File

@ -599,11 +599,10 @@ Array [
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
placeholder="Select date"
readonly=""
size="12"
title=""
value=""
/>
<span
@ -639,11 +638,10 @@ Array [
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
placeholder="Select time"
readonly=""
size="10"
title=""
value=""
/>
<span
@ -996,12 +994,13 @@ Array [
class="ant-picker ant-picker-range ant-picker-outlined"
>
<div
class="ant-picker-input ant-picker-input-active"
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
date-range="start"
placeholder="Start date"
readonly=""
size="12"
value=""
/>
@ -1038,16 +1037,17 @@ Array [
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
date-range="end"
placeholder="End date"
readonly=""
size="12"
value=""
/>
</div>
<div
class="ant-picker-active-bar"
style="left:0;width:0;position:absolute"
style="position:absolute;width:0;left:0"
/>
<span
class="ant-picker-suffix"
@ -1080,11 +1080,10 @@ Array [
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
placeholder="Select month"
readonly=""
size="12"
title=""
value=""
/>
<span
@ -2954,11 +2953,10 @@ exports[`renders components/input/demo/group.tsx correctly 1`] = `
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
placeholder="Select date"
readonly=""
size="12"
title=""
value=""
/>
<span
@ -3002,12 +3000,13 @@ exports[`renders components/input/demo/group.tsx correctly 1`] = `
style="width:70%"
>
<div
class="ant-picker-input ant-picker-input-active"
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
date-range="start"
placeholder="Start date"
readonly=""
size="12"
value=""
/>
@ -3044,16 +3043,17 @@ exports[`renders components/input/demo/group.tsx correctly 1`] = `
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
date-range="end"
placeholder="End date"
readonly=""
size="12"
value=""
/>
</div>
<div
class="ant-picker-active-bar"
style="left:0;width:0;position:absolute"
style="position:absolute;width:0;left:0"
/>
<span
class="ant-picker-suffix"

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +1,26 @@
import type { CSSInterpolation, CSSObject } from '@ant-design/cssinjs';
import type { SelectToken } from './token';
import { resetIcon } from '../../style';
import { mergeToken } from '../../theme/internal';
import { unit } from '@ant-design/cssinjs';
import { resetIcon } from '../../style';
import { mergeToken, type AliasToken } from '../../theme/internal';
import type { TokenWithCommonCls } from '../../theme/util/genComponentStyleHook';
import type { SelectToken } from './token';
const FIXED_ITEM_MARGIN = 2;
const getSelectItemStyle = (token: SelectToken): number | string => {
type SelectItemToken = Pick<
SelectToken,
| 'multipleSelectItemHeight'
| 'multipleSelectorBgDisabled'
| 'multipleItemColorDisabled'
| 'multipleItemBorderColorDisabled'
| 'selectHeight'
| 'lineWidth'
| 'calc'
| 'inputPaddingHorizontalBase'
>;
const getSelectItemStyle = (token: SelectItemToken): number | string => {
const { multipleSelectItemHeight, selectHeight, lineWidth } = token;
const selectItemDist = token
.calc(selectHeight)
@ -17,7 +31,10 @@ const getSelectItemStyle = (token: SelectToken): number | string => {
return selectItemDist;
};
function genSizeStyle(token: SelectToken, suffix?: string): CSSObject {
export const genSelectionStyle = (
token: TokenWithCommonCls<AliasToken> & SelectItemToken,
suffix?: string,
): CSSObject => {
const { componentCls, iconCls } = token;
const selectOverflowPrefixCls = `${componentCls}-selection-overflow`;
@ -29,8 +46,6 @@ function genSizeStyle(token: SelectToken, suffix?: string): CSSObject {
return {
[`${componentCls}-multiple${suffixCls}`]: {
fontSize: token.fontSize,
/**
* Do not merge `height` & `line-height` under style with `selection` & `search`, since chrome
* may update to redesign with its align logic.
@ -62,10 +77,6 @@ function genSizeStyle(token: SelectToken, suffix?: string): CSSObject {
paddingBlock: token.calc(selectItemDist).sub(FIXED_ITEM_MARGIN).equal(),
borderRadius: token.borderRadius,
[`${componentCls}-show-search&`]: {
cursor: 'text',
},
[`${componentCls}-disabled&`]: {
background: token.multipleSelectorBgDisabled,
cursor: 'not-allowed',
@ -81,16 +92,6 @@ function genSizeStyle(token: SelectToken, suffix?: string): CSSObject {
},
},
[`
&${componentCls}-show-arrow ${componentCls}-selector,
&${componentCls}-allow-clear ${componentCls}-selector
`]: {
paddingInlineEnd: token
.calc(token.fontSizeIcon)
.add(token.controlPaddingHorizontal)
.equal(),
},
// ======================== Selections ========================
[`${componentCls}-selection-item`]: {
display: 'flex',
@ -202,6 +203,37 @@ function genSizeStyle(token: SelectToken, suffix?: string): CSSObject {
},
},
};
};
function genSizeStyle(token: SelectToken, suffix?: string): CSSInterpolation {
const { componentCls } = token;
const suffixCls = suffix ? `${componentCls}-${suffix}` : '';
const rawStyle: CSSObject = {
[`${componentCls}-multiple${suffixCls}`]: {
fontSize: token.fontSize,
// ========================= Selector =========================
[`${componentCls}-selector`]: {
[`${componentCls}-show-search&`]: {
cursor: 'text',
},
},
[`
&${componentCls}-show-arrow ${componentCls}-selector,
&${componentCls}-allow-clear ${componentCls}-selector
`]: {
paddingInlineEnd: token
.calc(token.fontSizeIcon)
.add(token.controlPaddingHorizontal)
.equal(),
},
},
};
return [genSelectionStyle(token, suffix), rawStyle];
}
const genMultipleStyle = (token: SelectToken): CSSInterpolation => {

View File

@ -1,7 +1,48 @@
import type { CSSProperties } from 'react';
import type { FullToken, GetDefaultToken } from 'antd/es/theme/util/genComponentStyleHook';
export interface ComponentToken {
export interface MultipleSelectorToken {
/**
* @desc
* @descEN Background color of multiple tag
*/
multipleItemBg: string;
/**
* @desc
* @descEN Border color of multiple tag
*/
multipleItemBorderColor: string;
/**
* @desc
* @descEN Height of multiple tag
*/
multipleItemHeight: number;
/**
* @desc
* @descEN Height of multiple tag with large size
*/
multipleItemHeightLG: number;
/**
* @desc
* @descEN Background color of multiple selector when disabled
*/
multipleSelectorBgDisabled: string;
/**
* @desc
* @descEN Text color of multiple tag when disabled
*/
multipleItemColorDisabled: string;
/**
* @desc
* @descEN Border color of multiple tag when disabled
*/
multipleItemBorderColorDisabled: string;
/**
* @internal
*/
}
export interface ComponentToken extends MultipleSelectorToken {
/**
* @desc z-index
* @descEN z-index of dropdown
@ -62,54 +103,20 @@ export interface ComponentToken {
* @descEN Height of single selected item with large size
*/
singleItemHeightLG: number;
/**
* @desc
* @descEN Background color of multiple tag
*/
multipleItemBg: string;
/**
* @desc
* @descEN Border color of multiple tag
*/
multipleItemBorderColor: string;
/**
* @desc
* @descEN Height of multiple tag
*/
multipleItemHeight: number;
/**
* @desc
* @descEN Height of multiple tag with large size
*/
multipleItemHeightLG: number;
/**
* @desc
* @descEN Background color of multiple selector when disabled
*/
multipleSelectorBgDisabled: string;
/**
* @desc
* @descEN Text color of multiple tag when disabled
*/
multipleItemColorDisabled: string;
/**
* @desc
* @descEN Border color of multiple tag when disabled
*/
multipleItemBorderColorDisabled: string;
/**
* @internal
*/
showArrowPaddingInlineEnd: number;
}
export interface SelectToken extends FullToken<'Select'> {
rootPrefixCls: string;
export interface SelectorToken {
inputPaddingHorizontalBase: number | string;
multipleSelectItemHeight: number;
selectHeight: number;
}
export interface SelectToken extends FullToken<'Select'>, SelectorToken {
rootPrefixCls: string;
}
export const prepareComponentToken: GetDefaultToken<'Select'> = (token) => {
const {
fontSize,

View File

@ -943,11 +943,10 @@ exports[`renders components/space/demo/compact.tsx correctly 1`] = `
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
placeholder="Select date"
readonly=""
size="12"
title=""
value=""
/>
<span
@ -988,12 +987,13 @@ exports[`renders components/space/demo/compact.tsx correctly 1`] = `
style="width:70%"
>
<div
class="ant-picker-input ant-picker-input-active"
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
date-range="start"
placeholder="Start date"
readonly=""
size="12"
value=""
/>
@ -1030,16 +1030,17 @@ exports[`renders components/space/demo/compact.tsx correctly 1`] = `
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
date-range="end"
placeholder="End date"
readonly=""
size="12"
value=""
/>
</div>
<div
class="ant-picker-active-bar"
style="left:0;width:0;position:absolute"
style="position:absolute;width:0;left:0"
/>
<span
class="ant-picker-suffix"
@ -1098,12 +1099,13 @@ exports[`renders components/space/demo/compact.tsx correctly 1`] = `
style="width:70%"
>
<div
class="ant-picker-input ant-picker-input-active"
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
date-range="start"
placeholder="Start date"
readonly=""
size="12"
value=""
/>
@ -1140,16 +1142,17 @@ exports[`renders components/space/demo/compact.tsx correctly 1`] = `
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
date-range="end"
placeholder="End date"
readonly=""
size="12"
value=""
/>
</div>
<div
class="ant-picker-active-bar"
style="left:0;width:0;position:absolute"
style="position:absolute;width:0;left:0"
/>
<span
class="ant-picker-suffix"
@ -1504,11 +1507,10 @@ exports[`renders components/space/demo/compact.tsx correctly 1`] = `
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
placeholder="Select time"
readonly=""
size="10"
title=""
value=""
/>
<span
@ -1610,12 +1612,13 @@ exports[`renders components/space/demo/compact.tsx correctly 1`] = `
class="ant-picker ant-picker-range ant-picker-outlined ant-picker-compact-item ant-picker-compact-first-item"
>
<div
class="ant-picker-input ant-picker-input-active"
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
date-range="start"
placeholder="Start time"
readonly=""
size="10"
value=""
/>
@ -1652,16 +1655,17 @@ exports[`renders components/space/demo/compact.tsx correctly 1`] = `
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
date-range="end"
placeholder="End time"
readonly=""
size="10"
value=""
/>
</div>
<div
class="ant-picker-active-bar"
style="left:0;width:0;position:absolute"
style="position:absolute;width:0;left:0"
/>
<span
class="ant-picker-suffix"
@ -3597,12 +3601,13 @@ exports[`renders components/space/demo/compact-debug.tsx correctly 1`] = `
style="width:70%"
>
<div
class="ant-picker-input ant-picker-input-active"
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
date-range="start"
placeholder="Start date"
readonly=""
size="12"
value=""
/>
@ -3639,16 +3644,17 @@ exports[`renders components/space/demo/compact-debug.tsx correctly 1`] = `
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
date-range="end"
placeholder="End date"
readonly=""
size="12"
value=""
/>
</div>
<div
class="ant-picker-active-bar"
style="left:0;width:0;position:absolute"
style="position:absolute;width:0;left:0"
/>
<span
class="ant-picker-suffix"
@ -4152,11 +4158,10 @@ Array [
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
placeholder="Select time"
readonly=""
size="10"
title=""
value=""
/>
<span

View File

@ -15,11 +15,10 @@ exports[`renders components/time-picker/demo/12hours.tsx correctly 1`] = `
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
placeholder="Select time"
readonly=""
size="12"
title=""
value=""
/>
<span
@ -61,11 +60,10 @@ exports[`renders components/time-picker/demo/12hours.tsx correctly 1`] = `
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
placeholder="Select time"
readonly=""
size="11"
title=""
value=""
/>
<span
@ -107,11 +105,10 @@ exports[`renders components/time-picker/demo/12hours.tsx correctly 1`] = `
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
placeholder="Select time"
readonly=""
size="10"
title=""
value=""
/>
<span
@ -154,11 +151,10 @@ exports[`renders components/time-picker/demo/addon.tsx correctly 1`] = `
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
placeholder="Select time"
readonly=""
size="10"
title=""
value=""
/>
<span
@ -199,11 +195,54 @@ exports[`renders components/time-picker/demo/basic.tsx correctly 1`] = `
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
placeholder="Select time"
size="10"
value=""
/>
<span
class="ant-picker-suffix"
>
<span
aria-label="clock-circle"
class="anticon anticon-clock-circle"
role="img"
>
<svg
aria-hidden="true"
data-icon="clock-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 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z"
/>
<path
d="M686.7 638.6L544.1 535.5V288c0-4.4-3.6-8-8-8H488c-4.4 0-8 3.6-8 8v275.4c0 2.6 1.2 5 3.3 6.5l165.4 120.6c3.6 2.6 8.6 1.8 11.2-1.7l28.6-39c2.6-3.7 1.8-8.7-1.8-11.2z"
/>
</svg>
</span>
</span>
</div>
</div>
`;
exports[`renders components/time-picker/demo/change-on-scroll.tsx correctly 1`] = `
<div
class="ant-picker ant-picker-outlined"
>
<div
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
placeholder="Select time"
readonly=""
size="10"
title=""
value=""
/>
<span
@ -244,11 +283,10 @@ exports[`renders components/time-picker/demo/colored-popup.tsx correctly 1`] = `
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
placeholder="Select time"
readonly=""
size="10"
title=""
value=""
/>
<span
@ -283,19 +321,18 @@ exports[`renders components/time-picker/demo/colored-popup.tsx correctly 1`] = `
exports[`renders components/time-picker/demo/disabled.tsx correctly 1`] = `
<div
class="ant-picker ant-picker-outlined ant-picker-disabled"
class="ant-picker ant-picker-disabled ant-picker-outlined"
>
<div
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
disabled=""
placeholder="Select time"
readonly=""
size="10"
title=""
value=""
value="12:08:23"
/>
<span
class="ant-picker-suffix"
@ -335,12 +372,11 @@ exports[`renders components/time-picker/demo/hide-column.tsx correctly 1`] = `
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
placeholder="Select time"
readonly=""
size="10"
title=""
value=""
value="12:08"
/>
<span
class="ant-picker-suffix"
@ -405,11 +441,10 @@ exports[`renders components/time-picker/demo/interval-options.tsx correctly 1`]
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
placeholder="Select time"
readonly=""
size="10"
title=""
value=""
/>
<span
@ -447,12 +482,13 @@ exports[`renders components/time-picker/demo/range-picker.tsx correctly 1`] = `
class="ant-picker ant-picker-range ant-picker-outlined"
>
<div
class="ant-picker-input ant-picker-input-active"
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
date-range="start"
placeholder="Start time"
readonly=""
size="10"
value=""
/>
@ -489,16 +525,17 @@ exports[`renders components/time-picker/demo/range-picker.tsx correctly 1`] = `
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
date-range="end"
placeholder="End time"
readonly=""
size="10"
value=""
/>
</div>
<div
class="ant-picker-active-bar"
style="left:0;width:0;position:absolute"
style="position:absolute;width:0;left:0"
/>
<span
class="ant-picker-suffix"
@ -541,11 +578,10 @@ exports[`renders components/time-picker/demo/render-panel.tsx correctly 1`] = `
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
placeholder="Select time"
readonly=""
size="10"
title=""
value=""
/>
<span
@ -594,12 +630,11 @@ exports[`renders components/time-picker/demo/size.tsx correctly 1`] = `
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
placeholder="Select time"
readonly=""
size="10"
title=""
value=""
value="12:08:23"
/>
<span
class="ant-picker-suffix"
@ -665,12 +700,11 @@ exports[`renders components/time-picker/demo/size.tsx correctly 1`] = `
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
placeholder="Select time"
readonly=""
size="10"
title=""
value=""
value="12:08:23"
/>
<span
class="ant-picker-suffix"
@ -736,12 +770,11 @@ exports[`renders components/time-picker/demo/size.tsx correctly 1`] = `
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
placeholder="Select time"
readonly=""
size="10"
title=""
value=""
value="12:08:23"
/>
<span
class="ant-picker-suffix"
@ -814,11 +847,10 @@ exports[`renders components/time-picker/demo/status.tsx correctly 1`] = `
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
placeholder="Select time"
readonly=""
size="10"
title=""
value=""
/>
<span
@ -860,11 +892,10 @@ exports[`renders components/time-picker/demo/status.tsx correctly 1`] = `
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
placeholder="Select time"
readonly=""
size="10"
title=""
value=""
/>
<span
@ -903,12 +934,13 @@ exports[`renders components/time-picker/demo/status.tsx correctly 1`] = `
class="ant-picker ant-picker-range ant-picker-outlined ant-picker-status-error"
>
<div
class="ant-picker-input ant-picker-input-active"
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
date-range="start"
placeholder="Start time"
readonly=""
size="10"
value=""
/>
@ -945,16 +977,17 @@ exports[`renders components/time-picker/demo/status.tsx correctly 1`] = `
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
date-range="end"
placeholder="End time"
readonly=""
size="10"
value=""
/>
</div>
<div
class="ant-picker-active-bar"
style="left:0;width:0;position:absolute"
style="position:absolute;width:0;left:0"
/>
<span
class="ant-picker-suffix"
@ -991,12 +1024,13 @@ exports[`renders components/time-picker/demo/status.tsx correctly 1`] = `
class="ant-picker ant-picker-range ant-picker-outlined ant-picker-status-warning"
>
<div
class="ant-picker-input ant-picker-input-active"
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
date-range="start"
placeholder="Start time"
readonly=""
size="10"
value=""
/>
@ -1033,16 +1067,17 @@ exports[`renders components/time-picker/demo/status.tsx correctly 1`] = `
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
date-range="end"
placeholder="End time"
readonly=""
size="10"
value=""
/>
</div>
<div
class="ant-picker-active-bar"
style="left:0;width:0;position:absolute"
style="position:absolute;width:0;left:0"
/>
<span
class="ant-picker-suffix"
@ -1083,11 +1118,10 @@ exports[`renders components/time-picker/demo/suffix.tsx correctly 1`] = `
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
placeholder="Select time"
readonly=""
size="10"
title=""
value=""
/>
<span
@ -1125,11 +1159,10 @@ exports[`renders components/time-picker/demo/value.tsx correctly 1`] = `
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
placeholder="Select time"
readonly=""
size="10"
title=""
value=""
/>
<span
@ -1178,11 +1211,10 @@ exports[`renders components/time-picker/demo/variant.tsx correctly 1`] = `
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
placeholder="Filled"
readonly=""
size="10"
title=""
value=""
/>
<span
@ -1217,12 +1249,13 @@ exports[`renders components/time-picker/demo/variant.tsx correctly 1`] = `
class="ant-picker ant-picker-range ant-picker-outlined"
>
<div
class="ant-picker-input ant-picker-input-active"
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
date-range="start"
placeholder="Filled"
readonly=""
size="10"
value=""
/>
@ -1259,16 +1292,17 @@ exports[`renders components/time-picker/demo/variant.tsx correctly 1`] = `
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
date-range="end"
placeholder=""
readonly=""
size="10"
value=""
/>
</div>
<div
class="ant-picker-active-bar"
style="left:0;width:0;position:absolute"
style="position:absolute;width:0;left:0"
/>
<span
class="ant-picker-suffix"
@ -1309,11 +1343,10 @@ exports[`renders components/time-picker/demo/variant.tsx correctly 1`] = `
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
placeholder="Filled"
readonly=""
size="10"
title=""
value=""
/>
<span
@ -1348,12 +1381,13 @@ exports[`renders components/time-picker/demo/variant.tsx correctly 1`] = `
class="ant-picker ant-picker-range ant-picker-filled"
>
<div
class="ant-picker-input ant-picker-input-active"
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
date-range="start"
placeholder="Filled"
readonly=""
size="10"
value=""
/>
@ -1390,16 +1424,17 @@ exports[`renders components/time-picker/demo/variant.tsx correctly 1`] = `
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
date-range="end"
placeholder=""
readonly=""
size="10"
value=""
/>
</div>
<div
class="ant-picker-active-bar"
style="left:0;width:0;position:absolute"
style="position:absolute;width:0;left:0"
/>
<span
class="ant-picker-suffix"
@ -1440,11 +1475,10 @@ exports[`renders components/time-picker/demo/variant.tsx correctly 1`] = `
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
placeholder="Borderless"
readonly=""
size="10"
title=""
value=""
/>
<span
@ -1479,12 +1513,13 @@ exports[`renders components/time-picker/demo/variant.tsx correctly 1`] = `
class="ant-picker ant-picker-range ant-picker-borderless"
>
<div
class="ant-picker-input ant-picker-input-active"
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
date-range="start"
placeholder="Borderless"
readonly=""
size="10"
value=""
/>
@ -1521,16 +1556,17 @@ exports[`renders components/time-picker/demo/variant.tsx correctly 1`] = `
class="ant-picker-input"
>
<input
aria-invalid="false"
autocomplete="off"
date-range="end"
placeholder=""
readonly=""
size="10"
value=""
/>
</div>
<div
class="ant-picker-active-bar"
style="left:0;width:0;position:absolute"
style="position:absolute;width:0;left:0"
/>
<span
class="ant-picker-suffix"

View File

@ -0,0 +1,7 @@
## zh-CN
通过 `changeOnScroll``needConfirm` 使其滚动时改变数值。
## en-US
Use `changeOnScroll` and `needConfirm` to change the value when scrolling.

View File

@ -0,0 +1,15 @@
import React from 'react';
import { TimePicker } from 'antd';
import type { Dayjs } from 'dayjs';
import dayjs from 'dayjs';
import customParseFormat from 'dayjs/plugin/customParseFormat';
dayjs.extend(customParseFormat);
const onChange = (time: Dayjs, timeString: string) => {
console.log(time, timeString);
};
const App: React.FC = () => <TimePicker onChange={onChange} changeOnScroll needConfirm={false} />;
export default App;

View File

@ -25,9 +25,10 @@ By clicking the input box, you can select a time from a popup panel.
<code src="./demo/interval-options.tsx">interval option</code>
<code src="./demo/addon.tsx">Addon</code>
<code src="./demo/12hours.tsx">12 hours</code>
<code src="./demo/change-on-scroll.tsx" version="5.14.0">Change on scroll</code>
<code src="./demo/colored-popup.tsx" debug>Colored Popup</code>
<code src="./demo/range-picker.tsx">Time Range Picker</code>
<code src="./demo/variant.tsx" version="5.13.0">Variants</code>
<code src="./demo/variant.tsx" version="5.14.0">Variants</code>
<code src="./demo/status.tsx">Status</code>
<code src="./demo/suffix.tsx" debug>Suffix</code>
<code src="./demo/render-panel.tsx" debug>_InternalPanelDoNotUseOrYouWillBeFired</code>
@ -52,7 +53,7 @@ dayjs.extend(customParseFormat)
| allowClear | Customize clear icon | boolean \| { clearIcon?: ReactNode } | true | 5.8.0: Support object type |
| autoFocus | If get focus when component mounted | boolean | false | |
| cellRender | Custom rendering function for picker cells | (current: number, info: { originNode: React.ReactElement, today: dayjs, range?: 'start' \| 'end', subType: 'hour' \| 'minute' \| 'second' \| 'meridiem' }) => React.ReactNode | - | 5.4.0 |
| changeOnBlur | Trigger `change` when blur. e.g. datetime picker no need click confirm button | boolean | false | 5.5.0 |
| changeOnScroll | Trigger selection when scroll the column | boolean | false | 5.14.0 |
| className | The className of picker | string | - | |
| defaultValue | To set default time | [dayjs](http://day.js.org/) | - | |
| disabled | Determine whether the TimePicker is disabled | boolean | false | |
@ -63,6 +64,7 @@ dayjs.extend(customParseFormat)
| hourStep | Interval between hours in picker | number | 1 | |
| inputReadOnly | Set the `readonly` attribute of the input tag (avoids virtual keyboard on touch devices) | boolean | false | |
| minuteStep | Interval between minutes in picker | number | 1 | |
| needConfirm | Need click confirm button to trigger value change | boolean | - | 5.14.0 |
| open | Whether to popup panel | boolean | false | |
| placeholder | Display when there's no value | string \| \[string, string] | `Select a time` | |
| placement | The position where the selection box pops up | `bottomLeft` `bottomRight` `topLeft` `topRight` | bottomLeft | |
@ -76,7 +78,7 @@ dayjs.extend(customParseFormat)
| suffixIcon | The custom suffix icon | ReactNode | - | |
| use12Hours | Display as 12 hours format, with default format `h:mm:ss a` | boolean | false | |
| value | To set time | [dayjs](http://day.js.org/) | - | |
| variant | Variants of picker | `outlined` \| `borderless` \| `filled` | `outlined` | 5.13.0 |
| variant | Variants of picker | `outlined` \| `borderless` \| `filled` | `outlined` | 5.14.0 |
| onChange | A callback function, can be executed when the selected time is changing | function(time: dayjs, timeString: string): void | - | |
| onOpenChange | A callback function which will be called while panel opening/closing | (open: boolean) => void | - | |
| onSelect | A callback function, executes when a value is selected | function(time: dayjs): void | - | |
@ -88,9 +90,16 @@ type DisabledTime = (now: Dayjs) => {
disabledHours?: () => number[];
disabledMinutes?: (selectedHour: number) => number[];
disabledSeconds?: (selectedHour: number, selectedMinute: number) => number[];
disabledMilliseconds?: (
selectedHour: number,
selectedMinute: number,
selectedSecond: number,
) => number[];
};
```
Note: `disabledMilliseconds` is added in `5.14.0`.
## Methods
| Name | Description | Version |

View File

@ -3,9 +3,24 @@ import type { Dayjs } from 'dayjs';
import genPurePanel from '../_util/PurePanel';
import type { InputStatus } from '../_util/statusUtils';
import type { AnyObject } from '../_util/type';
import { devUseWarning } from '../_util/warning';
import DatePicker from '../date-picker';
import type { PickerTimeProps, RangePickerTimeProps } from '../date-picker/generatePicker';
import type {
PickerProps,
PickerPropsWithMultiple,
RangePickerProps,
} from '../date-picker/generatePicker/interface';
export type PickerTimeProps<DateType extends AnyObject> = PickerPropsWithMultiple<
DateType,
Omit<PickerProps<DateType>, 'picker' | 'showTime'>
>;
export type RangePickerTimeProps<DateType extends AnyObject> = Omit<
RangePickerProps<DateType>,
'showTime' | 'picker'
>;
const { TimePicker: InternalTimePicker, RangePicker: InternalRangePicker } = DatePicker;

View File

@ -26,9 +26,10 @@ demo:
<code src="./demo/interval-options.tsx">步长选项</code>
<code src="./demo/addon.tsx">附加内容</code>
<code src="./demo/12hours.tsx">12 小时制</code>
<code src="./demo/change-on-scroll.tsx" version="5.14.0">滚动即改变</code>
<code src="./demo/colored-popup.tsx" debug>色付きポップアップ</code>
<code src="./demo/range-picker.tsx">范围选择器</code>
<code src="./demo/variant.tsx" version="5.13.0">多种形态</code>
<code src="./demo/variant.tsx" version="5.14.0">多种形态</code>
<code src="./demo/status.tsx">自定义状态</code>
<code src="./demo/suffix.tsx" debug>后缀图标</code>
<code src="./demo/render-panel.tsx" debug>_InternalPanelDoNotUseOrYouWillBeFired</code>
@ -52,7 +53,7 @@ dayjs.extend(customParseFormat)
| allowClear | 自定义清除按钮 | boolean \| { clearIcon?: ReactNode } | true | 5.8.0: 支持对象类型 |
| autoFocus | 自动获取焦点 | boolean | false | |
| cellRender | 自定义单元格的内容 | (current: number, info: { originNode: React.ReactNode, today: dayjs, range?: 'start' \| 'end', subType: 'hour' \| 'minute' \| 'second' \| 'meridiem' }) => React.ReactNode | - | 5.4.0 |
| changeOnBlur | 失去焦点时触发 `change` 事件,例如 datetime 下不再需要点击确认按钮 | boolean | false | 5.5.0 |
| changeOnScroll | 在滚动时改变选择值 | boolean | false | 5.14.0 |
| className | 选择器类名 | string | - | |
| defaultValue | 默认时间 | [dayjs](http://day.js.org/) | - | |
| disabled | 禁用全部操作 | boolean | false | |
@ -63,6 +64,7 @@ dayjs.extend(customParseFormat)
| hourStep | 小时选项间隔 | number | 1 | |
| inputReadOnly | 设置输入框为只读(避免在移动设备上打开虚拟键盘) | boolean | false | |
| minuteStep | 分钟选项间隔 | number | 1 | |
| needConfirm | 是否需要确认按钮,为 `false` 时失去焦点即代表选择 | boolean | - | 5.14.0 |
| open | 面板是否打开 | boolean | false | |
| placeholder | 没有值的时候显示的内容 | string \| \[string, string] | `请选择时间` | |
| placement | 选择框弹出的位置 | `bottomLeft` `bottomRight` `topLeft` `topRight` | bottomLeft | |
@ -76,7 +78,7 @@ dayjs.extend(customParseFormat)
| suffixIcon | 自定义的选择框后缀图标 | ReactNode | - | |
| use12Hours | 使用 12 小时制,为 true 时 `format` 默认为 `h:mm:ss a` | boolean | false | |
| value | 当前时间 | [dayjs](http://day.js.org/) | - | |
| variant | 形态变体 | `outlined` \| `borderless` \| `filled` | `outlined` | 5.13.0 |
| variant | 形态变体 | `outlined` \| `borderless` \| `filled` | `outlined` | 5.14.0 |
| onChange | 时间发生变化的回调 | function(time: dayjs, timeString: string): void | - | |
| onOpenChange | 面板打开/关闭时的回调 | (open: boolean) => void | - | |
@ -87,9 +89,16 @@ type DisabledTime = (now: Dayjs) => {
disabledHours?: () => number[];
disabledMinutes?: (selectedHour: number) => number[];
disabledSeconds?: (selectedHour: number, selectedMinute: number) => number[];
disabledMilliseconds?: (
selectedHour: number,
selectedMinute: number,
selectedSecond: number,
) => number[];
};
```
注意:`disabledMilliseconds` 为 `5.14.0` 新增。
## 方法
| 名称 | 描述 | 版本 |

View File

@ -266,6 +266,8 @@ Replace moment.js locale with day.js locale:
+ dayjs.locale('zh-cn');
```
🚨 You need to pay attention to the day.js plugin system. If you find that the function originally in moment.js cannot be used in day.js, please refer to the [day.js plugin document](https://day.js.org/docs/en/plugin/plugin).
If you do not want to replace with day.js, you can use `@ant-design/moment-webpack-plugin` to keep moment.js:
```bash

View File

@ -259,6 +259,8 @@ export default {
+ dayjs.locale('zh-cn');
```
🚨 需要注意 day.js 通过插件系统拓展功能。如果你发现原本 moment.js 的功能在 day.js 中无法使用,请查阅 [day.js 官方文档](https://day.js.org/docs/en/plugin/plugin)。
如果你暂时不想替换 day.js也可以使用 `@ant-design/moment-webpack-plugin` 插件将 day.js 替换回 moment.js
```bash

View File

@ -144,7 +144,7 @@
"rc-motion": "^2.9.0",
"rc-notification": "~5.3.0",
"rc-pagination": "~4.0.4",
"rc-picker": "~3.14.6",
"rc-picker": "~4.0.0-alpha.40",
"rc-progress": "~3.5.1",
"rc-rate": "~2.12.0",
"rc-resize-observer": "^1.4.0",
@ -353,7 +353,7 @@
},
{
"path": "./dist/antd-with-locales.min.js",
"limit": "378 KiB"
"limit": "379 KiB"
}
],
"title": "Ant Design",