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

View File

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

View File

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

View File

@ -1,11 +1,14 @@
import Dayjs from 'dayjs'; import Dayjs from 'dayjs';
import 'dayjs/locale/zh-cn'; import 'dayjs/locale/zh-cn';
import React from 'react';
import MockDate from 'mockdate'; import MockDate from 'mockdate';
import { type PickerPanelProps } from 'rc-picker'; import { type PickerPanelProps } from 'rc-picker';
import dayjsGenerateConfig from 'rc-picker/lib/generate/dayjs'; import dayjsGenerateConfig from 'rc-picker/lib/generate/dayjs';
import type { Locale } from 'rc-picker/lib/interface'; import type { Locale } from 'rc-picker/lib/interface';
import { resetWarned } from 'rc-util/lib/warning'; import { resetWarned } from 'rc-util/lib/warning';
import React from 'react';
import Calendar from '..'; import Calendar from '..';
import mountTest from '../../../tests/shared/mountTest'; import mountTest from '../../../tests/shared/mountTest';
import rtlTest from '../../../tests/shared/rtlTest'; import rtlTest from '../../../tests/shared/rtlTest';
@ -16,7 +19,7 @@ import Select from '../../select';
import Header, { type CalendarHeaderProps } from '../Header'; import Header, { type CalendarHeaderProps } from '../Header';
const ref: { const ref: {
calendarProps?: PickerPanelProps<unknown>; calendarProps?: PickerPanelProps;
calendarHeaderProps?: CalendarHeaderProps<unknown>; calendarHeaderProps?: CalendarHeaderProps<unknown>;
} = {}; } = {};
@ -34,7 +37,7 @@ jest.mock('rc-picker', () => {
const PickerPanelComponent = RcPicker.PickerPanel; const PickerPanelComponent = RcPicker.PickerPanel;
return { return {
...RcPicker, ...RcPicker,
PickerPanel: (props: PickerPanelProps<unknown>) => { PickerPanel: (props: PickerPanelProps) => {
ref.calendarProps = props; ref.calendarProps = props;
return <PickerPanelComponent {...props} />; return <PickerPanelComponent {...props} />;
}, },
@ -149,8 +152,8 @@ describe('Calendar', () => {
it('getDateRange should returns a disabledDate function', () => { it('getDateRange should returns a disabledDate function', () => {
const validRange: [Dayjs.Dayjs, Dayjs.Dayjs] = [Dayjs('2018-02-02'), Dayjs('2018-05-18')]; const validRange: [Dayjs.Dayjs, Dayjs.Dayjs] = [Dayjs('2018-02-02'), Dayjs('2018-05-18')];
render(<Calendar validRange={validRange} defaultValue={Dayjs('2018-02-02')} />); 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-06-02'), {} as any)).toBe(true);
expect(ref.calendarProps?.disabledDate?.(Dayjs('2018-04-02'))).toBe(false); expect(ref.calendarProps?.disabledDate?.(Dayjs('2018-04-02'), {} as any)).toBe(false);
}); });
it('validRange should work with disabledDate function', () => { 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-01'), {} as any)).toBe(true);
expect(ref.calendarProps?.disabledDate?.(Dayjs('2018-02-02'))).toBe(false); expect(ref.calendarProps?.disabledDate?.(Dayjs('2018-02-02'), {} as any)).toBe(false);
expect(ref.calendarProps?.disabledDate?.(Dayjs('2018-02-03'))).toBe(true); expect(ref.calendarProps?.disabledDate?.(Dayjs('2018-02-03'), {} as any)).toBe(true);
expect(ref.calendarProps?.disabledDate?.(Dayjs('2018-02-04'))).toBe(false); expect(ref.calendarProps?.disabledDate?.(Dayjs('2018-02-04'), {} as any)).toBe(false);
expect(ref.calendarProps?.disabledDate?.(Dayjs('2018-06-01'))).toBe(true); expect(ref.calendarProps?.disabledDate?.(Dayjs('2018-06-01'), {} as any)).toBe(true);
}); });
it('Calendar MonthSelect should display correct label', () => { 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 { PickerPanel as RCPickerPanel } from 'rc-picker';
import type { GenerateConfig } from 'rc-picker/lib/generate'; import type { GenerateConfig } from 'rc-picker/lib/generate';
import type { CellRenderInfo } from 'rc-picker/lib/interface'; 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 useMergedState from 'rc-util/lib/hooks/useMergedState';
import type { AnyObject } from '../_util/type';
import { devUseWarning } from '../_util/warning'; import { devUseWarning } from '../_util/warning';
import { ConfigContext } from '../config-provider'; import { ConfigContext } from '../config-provider';
import { useLocale } from '../locale'; import { useLocale } from '../locale';
@ -17,24 +13,6 @@ import CalendarHeader from './Header';
import enUS from './locale/en_US'; import enUS from './locale/en_US';
import useStyle from './style'; 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 CalendarMode = 'year' | 'month';
export type HeaderRender<DateType> = (config: { export type HeaderRender<DateType> = (config: {
value: DateType; value: DateType;
@ -75,7 +53,7 @@ export interface CalendarProps<DateType> {
onSelect?: (date: DateType, selectInfo: SelectInfo) => void; 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) { function isSameYear(date1: DateType, date2: DateType) {
return date1 && date2 && generateConfig.getYear(date1) === generateConfig.getYear(date2); 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', () => { describe('DatePicker', () => {
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {}); const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
@ -96,8 +102,10 @@ describe('DatePicker', () => {
it('disabled date', () => { it('disabled date', () => {
const disabledDate = (current: any) => current && current < dayjs().endOf('day'); const disabledDate = (current: any) => current && current < dayjs().endOf('day');
const wrapper = render(<DatePicker disabledDate={disabledDate} open />); render(<DatePicker disabledDate={disabledDate} open />);
expect(Array.from(wrapper.container.children)).toMatchSnapshot();
expect(getCell('21')).toHaveClass('ant-picker-cell-disabled');
expect(getCell('23')).not.toHaveClass('ant-picker-cell-disabled');
}); });
it('placeholder', () => { it('placeholder', () => {
@ -234,12 +242,7 @@ describe('DatePicker', () => {
it('showTime={{ showHour: true }}', () => { it('showTime={{ showHour: true }}', () => {
const { container } = render( const { container } = render(
<DatePicker <DatePicker defaultValue={dayjs()} showTime={{ showHour: true }} format="YYYY-MM-DD" open />,
defaultValue={dayjs()}
showTime={{ showHour: true }}
format="YYYY-MM-DD"
open
/>,
); );
expect(container.querySelectorAll('.ant-picker-time-panel-column').length).toBe(1); expect(container.querySelectorAll('.ant-picker-time-panel-column').length).toBe(1);
expect( expect(
@ -249,16 +252,11 @@ describe('DatePicker', () => {
).toBe(24); ).toBe(24);
}); });
it('showTime={{ }} (no true args)', () => { it('showTime={{ }} (no true args)', () => {
const { container } = render( const { container } = render(
<DatePicker <DatePicker defaultValue={dayjs()} showTime={{}} format="YYYY-MM-DD" open />,
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', () => { it('showTime should work correctly when format is custom function', () => {
@ -270,13 +268,13 @@ describe('DatePicker', () => {
open open
/>, />,
); );
const fuousEvent = () => { const focusEvent = () => {
fireEvent.focus(container.querySelector('input')!); fireEvent.focus(container.querySelector('input')!);
}; };
const mouseDownEvent = () => { const mouseDownEvent = () => {
fireEvent.mouseDown(container.querySelector('input')!); fireEvent.mouseDown(container.querySelector('input')!);
}; };
expect(fuousEvent).not.toThrow(); expect(focusEvent).not.toThrow();
expect(mouseDownEvent).not.toThrow(); expect(mouseDownEvent).not.toThrow();
}); });
@ -411,7 +409,7 @@ describe('DatePicker', () => {
const { container } = render( const { container } = render(
<DatePicker defaultValue={dayjs()} format="kk:mm" showTime open />, <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( expect(
container container
.querySelectorAll('.ant-picker-time-panel-column')?.[0] .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 dayjs from 'dayjs';
import customParseFormat from 'dayjs/plugin/customParseFormat'; 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 DatePicker from '..';
import focusTest from '../../../tests/shared/focusTest';
import { render, resetMockDate, setMockDate, screen, waitFor } from '../../../tests/utils';
import { resetWarned } from '../../_util/warning'; 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 enUS from '../locale/en_US';
import { closeCircleByRole, expectCloseCircle, closePicker, openPicker, selectCell } from './utils'; import { closeCircleByRole, closePicker, expectCloseCircle, openPicker, selectCell } from './utils';
dayjs.extend(customParseFormat); dayjs.extend(customParseFormat);
type RangeValue<DateType extends object> =
| [DateType | undefined | null, DateType | undefined | null]
| null;
const { RangePicker } = DatePicker; const { RangePicker } = DatePicker;
describe('RangePicker', () => { describe('RangePicker', () => {
@ -85,42 +89,12 @@ describe('RangePicker', () => {
expect(start.isBefore(end, 'date')).toBeTruthy(); 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 // https://github.com/ant-design/ant-design/issues/13302
describe('in "month" mode, when the left and right panels select the same month', () => { describe('in "month" mode, when the left and right panels select the same month', () => {
it('the cell status is correct', () => { it('the cell status is correct', () => {
let rangePickerValue: dayjs.Dayjs[] = []; let rangePickerValue: dayjs.Dayjs[] = [];
const Test: React.FC = () => { const Test: React.FC = () => {
const [value, setValue] = useState<RangeValue<dayjs.Dayjs>>(null); const [value, setValue] = useState<RangeValue<dayjs.Dayjs>>(null!);
return ( return (
<RangePicker <RangePicker
value={value} value={value}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -2,8 +2,10 @@ import type { render } from '../../../tests/utils';
import { fireEvent, screen } from '../../../tests/utils'; import { fireEvent, screen } from '../../../tests/utils';
export function openPicker(wrapper: ReturnType<typeof render>, index = 0) { export function openPicker(wrapper: ReturnType<typeof render>, index = 0) {
fireEvent.mouseDown(wrapper.container?.querySelectorAll('input')?.[index]!); const inputEle = wrapper.container?.querySelectorAll<HTMLInputElement>('input')?.[index]!;
fireEvent.focus(wrapper.container?.querySelectorAll('input')?.[index]!); fireEvent.mouseDown(inputEle);
fireEvent.focus(inputEle);
fireEvent.click(inputEle);
} }
export function closePicker(wrapper: ReturnType<typeof render>, index = 0) { 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 = () => ( const App: React.FC = () => (
<Space direction="vertical"> <Space direction="vertical">
<DatePicker onChange={onChange} /> <DatePicker onChange={onChange} />
<DatePicker onChange={onChange} picker="week" /> {/* <DatePicker onChange={onChange} picker="week" />
<DatePicker onChange={onChange} picker="month" /> <DatePicker onChange={onChange} picker="month" />
<DatePicker onChange={onChange} picker="quarter" /> <DatePicker onChange={onChange} picker="quarter" />
<DatePicker onChange={onChange} picker="year" /> <DatePicker onChange={onChange} picker="year" /> */}
</Space> </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 React from 'react';
import { DatePicker, Space } from 'antd';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import customParseFormat from 'dayjs/plugin/customParseFormat'; import customParseFormat from 'dayjs/plugin/customParseFormat';
import { DatePicker, Space } from 'antd';
dayjs.extend(customParseFormat); dayjs.extend(customParseFormat);
@ -21,6 +21,11 @@ const App: React.FC = () => (
defaultValue={[dayjs('2019-09-03', dateFormat), dayjs('2019-11-22', dateFormat)]} defaultValue={[dayjs('2019-09-03', dateFormat), dayjs('2019-11-22', dateFormat)]}
disabled={[false, true]} disabled={[false, true]}
/> />
<DatePicker
defaultValue={dayjs('2019-09-03', dateFormat)}
minDate={dayjs('2019-06-01', dateFormat)}
maxDate={dayjs('2020-06-30', dateFormat)}
/>
</Space> </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 React, { useState } from 'react';
import type { DatePickerProps, GetProps } from 'antd';
import { DatePicker, Space } from 'antd'; import { DatePicker, Space } from 'antd';
import type { DatePickerProps, GetProps } from 'antd';
import type { Dayjs } from 'dayjs'; import type { Dayjs } from 'dayjs';
type RangePickerProps = GetProps<typeof DatePicker.RangePicker>; type RangePickerProps = GetProps<typeof DatePicker.RangePicker>;
const { RangePicker } = DatePicker; const { RangePicker } = DatePicker;
type RangeValue = [Dayjs | null, Dayjs | null] | null; type RangeValue = [Dayjs | null | undefined, Dayjs | null | undefined] | null;
const ControlledDatePicker = () => { const ControlledDatePicker = () => {
const [mode, setMode] = useState<DatePickerProps['mode']>('time'); 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="week" />
<RangePicker picker="month" /> <RangePicker picker="month" />
<RangePicker picker="quarter" /> <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> </Space>
); );

View File

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

View File

@ -1,18 +1,12 @@
import React from 'react'; import React from 'react';
import { SmileOutlined } from '@ant-design/icons'; import { SmileOutlined } from '@ant-design/icons';
import type { Dayjs } from 'dayjs';
import { DatePicker, Space } from 'antd'; import { DatePicker, Space } from 'antd';
import type { Dayjs } from 'dayjs';
const smileIcon = <SmileOutlined />; const smileIcon = <SmileOutlined />;
const { RangePicker } = DatePicker; const { RangePicker } = DatePicker;
type DatePickerValue = Dayjs | null; const onChange = (date: Dayjs | (Dayjs | null)[] | null, dateString: string | string[]) => {
type RangePickerValue = [Dayjs | null, Dayjs | null] | null;
const onChange = (
date: DatePickerValue | RangePickerValue,
dateString: [string, string] | string,
) => {
console.log(date, dateString); 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 CloseCircleFilled from '@ant-design/icons/CloseCircleFilled';
import SwapRightOutlined from '@ant-design/icons/SwapRightOutlined'; import SwapRightOutlined from '@ant-design/icons/SwapRightOutlined';
import classNames from 'classnames'; 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 { GenerateConfig } from 'rc-picker/lib/generate/index';
import type { RangePickerProps } from '.'; import { useZIndex } from '../../_util/hooks/useZIndex';
import { getMergedStatus, getStatusClassNames } from '../../_util/statusUtils'; import { getMergedStatus, getStatusClassNames } from '../../_util/statusUtils';
import type { AnyObject } from '../../_util/type';
import { devUseWarning } from '../../_util/warning'; import { devUseWarning } from '../../_util/warning';
import { ConfigContext } from '../../config-provider'; import { ConfigContext } from '../../config-provider';
import DisabledContext from '../../config-provider/DisabledContext'; import DisabledContext from '../../config-provider/DisabledContext';
import useCSSVarCls from '../../config-provider/hooks/useCSSVarCls';
import useSize from '../../config-provider/hooks/useSize'; import useSize from '../../config-provider/hooks/useSize';
import { FormItemInputContext } from '../../form/context'; import { FormItemInputContext } from '../../form/context';
import useVariant from '../../form/hooks/useVariants';
import { useLocale } from '../../locale'; import { useLocale } from '../../locale';
import { NoCompactStyle, useCompactItemContext } from '../../space/Compact'; import { NoCompactStyle, useCompactItemContext } from '../../space/Compact';
import enUS from '../locale/en_US'; import enUS from '../locale/en_US';
import useStyle from '../style'; import useStyle from '../style';
import { import { getRangePlaceholder, mergeAllowClear, transPlacement2DropdownAlign } from '../util';
getRangePlaceholder, import type { RangePickerProps } from './interface';
getTimeProps, import useComponents from './useComponents';
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';
export default function generateRangePicker<DateType>(generateConfig: GenerateConfig<DateType>) { export default function generateRangePicker<DateType extends AnyObject>(
type InternalRangePickerProps = RangePickerProps<DateType> & {}; generateConfig: GenerateConfig<DateType>,
type DateRangePickerProps = 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;
};
const RangePicker = forwardRef< const RangePicker = forwardRef<PickerRef, DateRangePickerProps>((props, ref) => {
InternalRangePickerProps | CommonPickerMethods,
DateRangePickerProps
>((props, ref) => {
const { const {
prefixCls: customizePrefixCls, prefixCls: customizePrefixCls,
getPopupContainer: customGetPopupContainer, getPopupContainer: customGetPopupContainer,
components,
className, className,
style, style,
placement, placement,
@ -67,11 +53,11 @@ export default function generateRangePicker<DateType>(generateConfig: GenerateCo
...restProps ...restProps
} = props; } = props;
const innerRef = React.useRef<RCRangePicker<DateType>>(null); const innerRef = React.useRef<PickerRef>(null);
const { getPrefixCls, direction, getPopupContainer, rangePicker } = useContext(ConfigContext); const { getPrefixCls, direction, getPopupContainer, rangePicker } = useContext(ConfigContext);
const prefixCls = getPrefixCls('picker', customizePrefixCls); const prefixCls = getPrefixCls('picker', customizePrefixCls);
const { compactSize, compactItemClassnames } = useCompactItemContext(prefixCls, direction); const { compactSize, compactItemClassnames } = useCompactItemContext(prefixCls, direction);
const { format, showTime, picker } = props as any; const { picker } = props;
const rootPrefixCls = getPrefixCls(); const rootPrefixCls = getPrefixCls();
const [variant, enableVariantCls] = useVariant(customVariant, bordered); const [variant, enableVariantCls] = useVariant(customVariant, bordered);
@ -79,11 +65,6 @@ export default function generateRangePicker<DateType>(generateConfig: GenerateCo
const rootCls = useCSSVarCls(prefixCls); const rootCls = useCSSVarCls(prefixCls);
const [wrapCSSVar, hashId, cssVarCls] = useStyle(prefixCls, rootCls); const [wrapCSSVar, hashId, cssVarCls] = useStyle(prefixCls, rootCls);
const additionalOverrideProps: any = {
...(showTime ? getTimeProps({ format, picker, ...showTime }) : {}),
...(picker === 'time' ? getTimeProps({ format, ...props, picker }) : {}),
};
// =================== Warning ===================== // =================== Warning =====================
if (process.env.NODE_ENV !== 'production') { if (process.env.NODE_ENV !== 'production') {
const warning = devUseWarning('DatePicker.RangePicker'); const warning = devUseWarning('DatePicker.RangePicker');
@ -93,6 +74,9 @@ export default function generateRangePicker<DateType>(generateConfig: GenerateCo
warning.deprecated(!('bordered' in props), 'bordered', 'variant'); warning.deprecated(!('bordered' in props), 'bordered', 'variant');
} }
// ================== components ==================
const mergedComponents = useComponents(components);
// ===================== Size ===================== // ===================== Size =====================
const mergedSize = useSize((ctx) => customizeSize ?? compactSize ?? ctx); const mergedSize = useSize((ctx) => customizeSize ?? compactSize ?? ctx);
@ -111,10 +95,7 @@ export default function generateRangePicker<DateType>(generateConfig: GenerateCo
</> </>
); );
useImperativeHandle(ref, () => ({ useImperativeHandle(ref, () => innerRef.current!);
focus: () => innerRef.current?.focus(),
blur: () => innerRef.current?.blur(),
}));
const [contextLocale] = useLocale('Calendar', enUS); const [contextLocale] = useLocale('Calendar', enUS);
@ -133,7 +114,7 @@ export default function generateRangePicker<DateType>(generateConfig: GenerateCo
} }
disabled={mergedDisabled} disabled={mergedDisabled}
ref={innerRef} ref={innerRef}
dropdownAlign={transPlacement2DropdownAlign(direction, placement)} popupAlign={transPlacement2DropdownAlign(direction, placement)}
placeholder={getRangePlaceholder(locale, picker, placeholder)} placeholder={getRangePlaceholder(locale, picker, placeholder)}
suffixIcon={suffixNode} suffixIcon={suffixNode}
prevIcon={<span className={`${prefixCls}-prev-icon`} />} prevIcon={<span className={`${prefixCls}-prev-icon`} />}
@ -142,7 +123,6 @@ export default function generateRangePicker<DateType>(generateConfig: GenerateCo
superNextIcon={<span className={`${prefixCls}-super-next-icon`} />} superNextIcon={<span className={`${prefixCls}-super-next-icon`} />}
transitionName={`${rootPrefixCls}-slide-up`} transitionName={`${rootPrefixCls}-slide-up`}
{...restProps} {...restProps}
{...additionalOverrideProps}
className={classNames( className={classNames(
{ {
[`${prefixCls}-${mergedSize}`]: mergedSize, [`${prefixCls}-${mergedSize}`]: mergedSize,
@ -166,18 +146,22 @@ export default function generateRangePicker<DateType>(generateConfig: GenerateCo
prefixCls={prefixCls} prefixCls={prefixCls}
getPopupContainer={customGetPopupContainer || getPopupContainer} getPopupContainer={customGetPopupContainer || getPopupContainer}
generateConfig={generateConfig} generateConfig={generateConfig}
components={Components} components={mergedComponents}
direction={direction} direction={direction}
dropdownClassName={classNames( classNames={{
hashId, popup: classNames(
popupClassName || dropdownClassName, hashId,
cssVarCls, popupClassName || dropdownClassName,
rootCls, cssVarCls,
rootClassName, rootCls,
)} rootClassName,
popupStyle={{ ),
...props.popupStyle, }}
zIndex, styles={{
popup: {
...props.popupStyle,
zIndex,
},
}} }}
allowClear={mergeAllowClear(allowClear, clearIcon, <CloseCircleFilled />)} allowClear={mergeAllowClear(allowClear, clearIcon, <CloseCircleFilled />)}
/> />
@ -189,5 +173,5 @@ export default function generateRangePicker<DateType>(generateConfig: GenerateCo
RangePicker.displayName = 'RangePicker'; 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 ClockCircleOutlined from '@ant-design/icons/ClockCircleOutlined';
import CloseCircleFilled from '@ant-design/icons/CloseCircleFilled'; import CloseCircleFilled from '@ant-design/icons/CloseCircleFilled';
import classNames from 'classnames'; 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 { GenerateConfig } from 'rc-picker/lib/generate/index';
import type { PickerMode } from 'rc-picker/lib/interface'; import type { PickerMode } from 'rc-picker/lib/interface';
import type { PickerProps, PickerTimeProps } from '.'; import { useZIndex } from '../../_util/hooks/useZIndex';
import type { InputStatus } from '../../_util/statusUtils';
import { getMergedStatus, getStatusClassNames } from '../../_util/statusUtils'; import { getMergedStatus, getStatusClassNames } from '../../_util/statusUtils';
import type { AnyObject } from '../../_util/type';
import { devUseWarning } from '../../_util/warning'; import { devUseWarning } from '../../_util/warning';
import { ConfigContext } from '../../config-provider'; import { ConfigContext } from '../../config-provider';
import DisabledContext from '../../config-provider/DisabledContext'; import DisabledContext from '../../config-provider/DisabledContext';
import useCSSVarCls from '../../config-provider/hooks/useCSSVarCls';
import useSize from '../../config-provider/hooks/useSize'; import useSize from '../../config-provider/hooks/useSize';
import { FormItemInputContext } from '../../form/context'; import { FormItemInputContext } from '../../form/context';
import useVariant from '../../form/hooks/useVariants';
import { useLocale } from '../../locale'; import { useLocale } from '../../locale';
import { NoCompactStyle, useCompactItemContext } from '../../space/Compact'; import { NoCompactStyle, useCompactItemContext } from '../../space/Compact';
import enUS from '../locale/en_US'; import enUS from '../locale/en_US';
import useStyle from '../style'; import useStyle from '../style';
import { import { getPlaceholder, mergeAllowClear, transPlacement2DropdownAlign } from '../util';
getPlaceholder, import type { PickerProps, PickerPropsWithMultiple } from './interface';
getTimeProps, import useComponents from './useComponents';
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';
export default function generatePicker<DateType>(generateConfig: GenerateConfig<DateType>) { export default function generatePicker<DateType extends AnyObject>(
type CustomPickerProps = { generateConfig: GenerateConfig<DateType>,
status?: InputStatus; ) {
hashId?: string; type DatePickerProps = PickerProps<DateType>;
popupClassName?: string; type TimePickerProps = Omit<PickerProps<DateType>, 'picker' | 'showTime'>;
rootClassName?: string;
};
type DatePickerProps = PickerProps<DateType> & CustomPickerProps;
type TimePickerProps = PickerTimeProps<DateType> & CustomPickerProps;
function getPicker<InnerPickerProps extends DatePickerProps>( function getPicker<InnerPickerProps extends DatePickerProps>(
picker?: PickerMode, picker?: PickerMode,
displayName?: string, displayName?: string,
) { ) {
const consumerName = displayName === 'TimePicker' ? 'timePicker' : 'datePicker'; const consumerName = displayName === 'TimePicker' ? 'timePicker' : 'datePicker';
const Picker = forwardRef<DatePickRef<DateType> | CommonPickerMethods, InnerPickerProps>( const Picker = forwardRef<PickerRef, InnerPickerProps>((props, ref) => {
(props, ref) => { const {
const { prefixCls: customizePrefixCls,
prefixCls: customizePrefixCls, getPopupContainer: customizeGetPopupContainer,
getPopupContainer: customizeGetPopupContainer, components,
style, style,
className, className,
rootClassName, rootClassName,
size: customizeSize, size: customizeSize,
bordered, bordered,
placement, placement,
placeholder, placeholder,
popupClassName, popupClassName,
dropdownClassName, dropdownClassName,
disabled: customDisabled, disabled: customDisabled,
status: customStatus, status: customStatus,
clearIcon, clearIcon,
allowClear, allowClear,
variant: customVariant, variant: customVariant,
...restProps ...restProps
} = props; } = props;
const { const {
getPrefixCls, getPrefixCls,
direction, direction,
getPopupContainer, getPopupContainer,
// Consume different styles according to different names // Consume different styles according to different names
[consumerName]: consumerStyle, [consumerName]: consumerStyle,
} = useContext(ConfigContext); } = useContext(ConfigContext);
const prefixCls = getPrefixCls('picker', customizePrefixCls); const prefixCls = getPrefixCls('picker', customizePrefixCls);
const { compactSize, compactItemClassnames } = useCompactItemContext(prefixCls, direction); const { compactSize, compactItemClassnames } = useCompactItemContext(prefixCls, direction);
const innerRef = React.useRef<RCPicker<DateType>>(null); const innerRef = React.useRef<PickerRef>(null);
const { format, showTime } = props as any;
const [variant, enableVariantCls] = useVariant(customVariant, bordered); const [variant, enableVariantCls] = useVariant(customVariant, bordered);
const rootCls = useCSSVarCls(prefixCls); const rootCls = useCSSVarCls(prefixCls);
const [wrapCSSVar, hashId, cssVarCls] = useStyle(prefixCls, rootCls); const [wrapCSSVar, hashId, cssVarCls] = useStyle(prefixCls, rootCls);
useImperativeHandle(ref, () => ({ useImperativeHandle(ref, () => innerRef.current!);
focus: () => innerRef.current?.focus(),
blur: () => innerRef.current?.blur(),
}));
const additionalProps = { const additionalProps = {
showToday: true, showToday: true,
}; };
let additionalOverrideProps: any = {}; const mergedPicker = picker || props.picker;
if (picker) {
additionalOverrideProps.picker = picker;
}
const mergedPicker = picker || props.picker;
additionalOverrideProps = { const rootPrefixCls = getPrefixCls();
...additionalOverrideProps,
...(showTime ? getTimeProps({ format, picker: mergedPicker, ...showTime }) : {}),
...(mergedPicker === 'time'
? getTimeProps({ format, ...props, picker: mergedPicker })
: {}),
};
const rootPrefixCls = getPrefixCls();
// =================== Warning ===================== // =================== Warning =====================
if (process.env.NODE_ENV !== 'production') { if (process.env.NODE_ENV !== 'production') {
const warning = devUseWarning(displayName! || 'DatePicker'); const warning = devUseWarning(displayName! || 'DatePicker');
warning( warning(
picker !== 'quarter', picker !== 'quarter',
'deprecated', 'deprecated',
`DatePicker.${displayName} is legacy usage. Please use DatePicker[picker='${picker}'] directly.`, `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}
</>
); );
const [contextLocale] = useLocale('DatePicker', enUS); warning.deprecated(!dropdownClassName, 'dropdownClassName', 'popupClassName');
const locale = { ...contextLocale, ...props.locale! }; warning.deprecated(!('bordered' in props), 'bordered', 'variant');
// ============================ zIndex ============================ }
const [zIndex] = useZIndex('DatePicker', props.popupStyle?.zIndex as number);
return wrapCSSVar( // ================== components ==================
<NoCompactStyle> const mergedComponents = useComponents(components);
<RCPicker<DateType>
ref={innerRef} // ===================== Size =====================
placeholder={getPlaceholder(locale, mergedPicker, placeholder)} const mergedSize = useSize((ctx) => customizeSize ?? compactSize ?? ctx);
suffixIcon={suffixNode}
dropdownAlign={transPlacement2DropdownAlign(direction, placement)} // ===================== Disabled =====================
prevIcon={<span className={`${prefixCls}-prev-icon`} />} const disabled = React.useContext(DisabledContext);
nextIcon={<span className={`${prefixCls}-next-icon`} />} const mergedDisabled = customDisabled ?? disabled;
superPrevIcon={<span className={`${prefixCls}-super-prev-icon`} />}
superNextIcon={<span className={`${prefixCls}-super-next-icon`} />} // ===================== FormItemInput =====================
transitionName={`${rootPrefixCls}-slide-up`} const formItemContext = useContext(FormItemInputContext);
{...additionalProps} const { hasFeedback, status: contextStatus, feedbackIcon } = formItemContext;
{...restProps}
{...additionalOverrideProps} const suffixNode = (
locale={locale!.lang} <>
className={classNames( {mergedPicker === 'time' ? <ClockCircleOutlined /> : <CalendarOutlined />}
{ {hasFeedback && feedbackIcon}
[`${prefixCls}-${mergedSize}`]: mergedSize, </>
[`${prefixCls}-${variant}`]: enableVariantCls, );
},
getStatusClassNames( const [contextLocale] = useLocale('DatePicker', enUS);
prefixCls,
getMergedStatus(contextStatus, customStatus), const locale = { ...contextLocale, ...props.locale! };
hasFeedback, // ============================ zIndex ============================
), const [zIndex] = useZIndex('DatePicker', props.popupStyle?.zIndex as number);
hashId,
compactItemClassnames, return wrapCSSVar(
consumerStyle?.className, <NoCompactStyle>
className, <RCPicker<DateType>
cssVarCls, ref={innerRef}
rootCls, placeholder={getPlaceholder(locale, mergedPicker, placeholder)}
rootClassName, suffixIcon={suffixNode}
)} dropdownAlign={transPlacement2DropdownAlign(direction, placement)}
style={{ ...consumerStyle?.style, ...style }} prevIcon={<span className={`${prefixCls}-prev-icon`} />}
prefixCls={prefixCls} nextIcon={<span className={`${prefixCls}-next-icon`} />}
getPopupContainer={customizeGetPopupContainer || getPopupContainer} superPrevIcon={<span className={`${prefixCls}-super-prev-icon`} />}
generateConfig={generateConfig} superNextIcon={<span className={`${prefixCls}-super-next-icon`} />}
components={Components} transitionName={`${rootPrefixCls}-slide-up`}
direction={direction} picker={picker}
disabled={mergedDisabled} {...additionalProps}
dropdownClassName={classNames( {...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, hashId,
cssVarCls, cssVarCls,
rootCls, rootCls,
rootClassName, rootClassName,
popupClassName || dropdownClassName, popupClassName || dropdownClassName,
)} ),
popupStyle={{ }}
styles={{
popup: {
...props.popupStyle, ...props.popupStyle,
zIndex, zIndex,
}} },
allowClear={mergeAllowClear(allowClear, clearIcon, <CloseCircleFilled />)} }}
/> allowClear={mergeAllowClear(allowClear, clearIcon, <CloseCircleFilled />)}
</NoCompactStyle>, />
); </NoCompactStyle>,
}, );
); });
if (displayName) { if (process.env.NODE_ENV !== 'production' && displayName) {
Picker.displayName = 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>(); 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 { 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 { AnyObject } from '../../_util/type';
import type { SizeType } from '../../config-provider/SizeContext';
import type { TimePickerLocale } from '../../time-picker';
import generateRangePicker from './generateRangePicker'; import generateRangePicker from './generateRangePicker';
import generateSinglePicker from './generateSinglePicker'; import generateSinglePicker from './generateSinglePicker';
import type { Variant } from '../../form/hooks/useVariants';
const DataPickerPlacements = ['bottomLeft', 'bottomRight', 'topLeft', 'topRight'] as const; export type { PickerLocale, PickerProps } from './interface';
type DataPickerPlacement = (typeof DataPickerPlacements)[number];
type InjectDefaultProps<Props> = Omit< function generatePicker<DateType extends AnyObject>(generateConfig: GenerateConfig<DateType>) {
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>) {
// =========================== Picker =========================== // =========================== Picker ===========================
const { DatePicker, WeekPicker, MonthPicker, YearPicker, TimePicker, QuarterPicker } = const { DatePicker, WeekPicker, MonthPicker, YearPicker, TimePicker, QuarterPicker } =
generateSinglePicker(generateConfig); 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 --> <!-- prettier-ignore -->
<code src="./demo/basic.tsx">Basic</code> <code src="./demo/basic.tsx">Basic</code>
<code src="./demo/range-picker.tsx">Range Picker</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/switchable.tsx">Switchable picker</code>
<code src="./demo/format.tsx">Date Format</code> <code src="./demo/format.tsx">Date Format</code>
<code src="./demo/time.tsx">Choose Time</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.tsx">Disabled</code>
<code src="./demo/disabled-date.tsx">Disabled Date & Time</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/select-in-range.tsx">Select range dates in 7 days</code>
<code src="./demo/preset-ranges.tsx">Preset Ranges</code> <code src="./demo/preset-ranges.tsx">Preset Ranges</code>
<code src="./demo/extra-footer.tsx">Extra Footer</code> <code src="./demo/extra-footer.tsx">Extra Footer</code>
<code src="./demo/size.tsx">Three Sizes</code> <code src="./demo/size.tsx">Three Sizes</code>
<code src="./demo/cell-render.tsx">Customized Cell Rendering</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/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/filled-debug.tsx" debug>Filled Debug</code>
<code src="./demo/placement.tsx">Placement</code> <code src="./demo/placement.tsx">Placement</code>
<code src="./demo/mode.tsx" debug>Controlled Panels</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 | | | autoFocus | If get focus when component mounted | boolean | false | |
| className | The picker className | string | - | | | 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 | | 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 | | 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 | | | 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) | | | 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 | | 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) | - | | | 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 | | | 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) | | | 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` | - | | | 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 | | nextIcon | The custom next icon | ReactNode | - | 4.17.0 |
| open | The open state of picker | boolean | - | | | open | The open state of picker | boolean | - | |
| panelRender | Customize panel render | (panelNode) => ReactNode | - | 4.5.0 | | 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 | - | | | suffixIcon | The custom suffix icon | ReactNode | - | |
| superNextIcon | The custom super next icon | ReactNode | - | 4.17.0 | | superNextIcon | The custom super next icon | ReactNode | - | 4.17.0 |
| superPrevIcon | The custom super prev 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) | - | | | 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) | - | | | 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 | | 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/) | - | | | 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) | - | | | 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` | | | 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 | - | | | 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 | 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() | | | 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/) | - | | | 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) | - | | | onChange | Callback function, can be executed when the selected time is changing | function(date: dayjs, dateString: string) | - | |
| onOk | Callback when click ok button | function() | - | | | onOk | Callback when click ok button | function() | - | |
@ -192,12 +205,15 @@ Added in `4.1.0`.
| Property | Description | Type | Default | Version | | Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- | | --- | --- | --- | --- | --- |
| allowEmpty | Allow start or end input leave empty | \[boolean, boolean] | \[false, false] | | | 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 | | 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/)] | - | | | defaultValue | To set default date | \[[dayjs](https://day.js.org/), [dayjs](https://day.js.org/)] | - | |
| disabled | If disable start or end | \[boolean, boolean] | - | | | disabled | If disable start or end | \[boolean, boolean] | - | |
| disabledTime | To specify the time that cannot be selected | function(date: dayjs, partial: `start` \| `end`) | - | | | 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` | | | 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))\[] }\[] | - | | | 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 | - | | | renderExtraFooter | Render extra footer in panel | () => React.ReactNode | - | |
| separator | Set separator between inputs | React.ReactNode | `<SwapRightOutlined />` | | | 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/)] | - | | | 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` }) | - | | | 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]) | - | | | 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 #### formatType
@ -215,9 +233,18 @@ import type { Dayjs } from 'dayjs';
type Generic = string; type Generic = string;
type GenericFn = (value: Dayjs) => 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 ## Design Token
<ComponentTokenTable component="DatePicker"></ComponentTokenTable> <ComponentTokenTable component="DatePicker"></ComponentTokenTable>

View File

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

View File

@ -19,18 +19,24 @@ demo:
<!-- prettier-ignore --> <!-- prettier-ignore -->
<code src="./demo/basic.tsx">基本</code> <code src="./demo/basic.tsx">基本</code>
<code src="./demo/range-picker.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/switchable.tsx">切换不同的选择器</code>
<code src="./demo/format.tsx">日期格式</code> <code src="./demo/format.tsx">日期格式</code>
<code src="./demo/time.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.tsx">禁用</code>
<code src="./demo/disabled-date.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/select-in-range.tsx">选择不超过七天的范围</code>
<code src="./demo/preset-ranges.tsx">预设范围</code> <code src="./demo/preset-ranges.tsx">预设范围</code>
<code src="./demo/extra-footer.tsx">额外的页脚</code> <code src="./demo/extra-footer.tsx">额外的页脚</code>
<code src="./demo/size.tsx">三种大小</code> <code src="./demo/size.tsx">三种大小</code>
<code src="./demo/cell-render.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/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/filled-debug.tsx" debug>Filled Debug</code>
<code src="./demo/placement.tsx">弹出位置</code> <code src="./demo/placement.tsx">弹出位置</code>
<code src="./demo/mode.tsx" debug>受控面板</code> <code src="./demo/mode.tsx" debug>受控面板</code>
@ -93,16 +99,21 @@ import 'dayjs/locale/zh-cn';
| autoFocus | 自动获取焦点 | boolean | false | | | autoFocus | 自动获取焦点 | boolean | false | |
| className | 选择器 className | string | - | | | className | 选择器 className | string | - | |
| dateRender | 自定义日期单元格的内容5.4.0 起用 `cellRender` 代替 | function(currentDate: dayjs, today: dayjs) => React.ReactNode | - | < 5.4.0 | | 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 | | 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 | | | 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) | | | 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 | | popupClassName | 额外的弹出日历 className | string | - | 4.23.0 |
| getPopupContainer | 定义浮层的容器,默认为 body 上新建 div | function(trigger) | - | | | getPopupContainer | 定义浮层的容器,默认为 body 上新建 div | function(trigger) | - | |
| inputReadOnly | 设置输入框为只读(避免在移动设备上打开虚拟键盘) | boolean | false | | | inputReadOnly | 设置输入框为只读(避免在移动设备上打开虚拟键盘) | boolean | false | |
| locale | 国际化配置 | object | [默认配置](https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json) | | | 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` | - | | | mode | 日期面板的状态([设置后无法选择年份/月份?](/docs/react/faq#当我指定了-datepickerrangepicker-的-mode-属性后点击后无法选择年份月份) | `time` \| `date` \| `month` \| `year` \| `decade` | - | |
| needConfirm | 是否需要确认按钮,为 `false` 时失去焦点即代表选择 | boolean | - | 5.14.0 |
| nextIcon | 自定义下一个图标 | ReactNode | - | 4.17.0 | | nextIcon | 自定义下一个图标 | ReactNode | - | 4.17.0 |
| open | 控制弹层是否展开 | boolean | - | | | open | 控制弹层是否展开 | boolean | - | |
| panelRender | 自定义渲染面板 | (panelNode) => ReactNode | - | 4.5.0 | | panelRender | 自定义渲染面板 | (panelNode) => ReactNode | - | 4.5.0 |
@ -118,7 +129,7 @@ import 'dayjs/locale/zh-cn';
| suffixIcon | 自定义的选择框后缀图标 | ReactNode | - | | | suffixIcon | 自定义的选择框后缀图标 | ReactNode | - | |
| superNextIcon | 自定义 `>>` 切换图标 | ReactNode | - | 4.17.0 | | superNextIcon | 自定义 `>>` 切换图标 | ReactNode | - | 4.17.0 |
| superPrevIcon | 自定义 `<<` 切换图标 | 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) | - | | | onOpenChange | 弹出日历和关闭日历的回调 | function(open) | - | |
| onPanelChange | 日历面板切换的回调 | function(value, mode) | - | | | 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/) | - | | | defaultValue | 默认日期,如果开始时间或结束时间为 `null` 或者 `undefined`,日期范围将是一个开区间 | [dayjs](https://day.js.org/) | - | |
| disabledTime | 不可选择的时间 | function(date) | - | | | 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` | | | 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 | - | | | renderExtraFooter | 在面板中添加额外的页脚 | (mode) => React.ReactNode | - | |
| showNow | 当设定了 `showTime` 的时候,面板是否显示“此刻”按钮 | boolean | - | 4.4.0 | | showNow | 显示当前日期时间的快捷选择 | boolean | - | |
| showTime | 增加时间选择功能 | Object \| boolean | [TimePicker Options](/components/time-picker-cn#api) | | | showTime | 增加时间选择功能 | Object \| boolean | [TimePicker Options](/components/time-picker-cn#api) | |
| showTime.defaultValue | 设置用户选择日期时默认的时分秒,[例子](#components-date-picker-demo-disabled-date) | [dayjs](https://day.js.org/) | dayjs() | | | 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/) | - | | | value | 日期 | [dayjs](https://day.js.org/) | - | |
| onChange | 时间发生变化的回调 | function(date: dayjs, dateString: string) | - | | | onChange | 时间发生变化的回调 | function(date: dayjs, dateString: string) | - | |
| onOk | 点击确定按钮的回调 | function() | - | | | onOk | 点击确定按钮的回调 | function() | - | |
@ -193,12 +206,15 @@ import 'dayjs/locale/zh-cn';
| 参数 | 说明 | 类型 | 默认值 | 版本 | | 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- | | --- | --- | --- | --- | --- |
| allowEmpty | 允许起始项部分为空 | \[boolean, boolean] | \[false, false] | | | 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 | | 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/)\[] | - | | | defaultValue | 默认日期 | [dayjs](https://day.js.org/)\[] | - | |
| disabled | 禁用起始项 | \[boolean, boolean] | - | | | disabled | 禁用起始项 | \[boolean, boolean] | - | |
| disabledTime | 不可选择的时间 | function(date: dayjs, partial: `start` \| `end`) | - | | | 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` | | | 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))\[] }\[] | - | | | presets | 预设时间范围快捷选择,自 `5.8.0` 起 value 支持函数返回值 | { label: React.ReactNode, value: (Dayjs \| (() => Dayjs))\[] }\[] | - | |
| renderExtraFooter | 在面板中添加额外的页脚 | () => React.ReactNode | - | | | renderExtraFooter | 在面板中添加额外的页脚 | () => React.ReactNode | - | |
| separator | 设置分隔符 | React.ReactNode | `<SwapRightOutlined />` | | | separator | 设置分隔符 | React.ReactNode | `<SwapRightOutlined />` | |
@ -207,6 +223,8 @@ import 'dayjs/locale/zh-cn';
| value | 日期 | [dayjs](https://day.js.org/)\[] | - | | | value | 日期 | [dayjs](https://day.js.org/)\[] | - | |
| onCalendarChange | 待选日期发生变化的回调。`info` 参数自 4.4.0 添加 | function(dates: \[dayjs, dayjs], dateStrings: \[string, string], info: { range:`start`\|`end` }) | - | | | onCalendarChange | 待选日期发生变化的回调。`info` 参数自 4.4.0 添加 | function(dates: \[dayjs, dayjs], dateStrings: \[string, string], info: { range:`start`\|`end` }) | - | |
| onChange | 日期范围发生变化的回调 | function(dates: \[dayjs, dayjs], dateStrings: \[string, string]) | - | | | 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 #### formatType
@ -216,9 +234,18 @@ import type { Dayjs } from 'dayjs';
type Generic = string; type Generic = string;
type GenericFn = (value: Dayjs) => 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 ## 主题变量Design Token
<ComponentTokenTable component="DatePicker"></ComponentTokenTable> <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 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 type { ArrowToken } from '../../style/roundedArrow';
import { getArrowToken } from '../../style/roundedArrow';
import type { GlobalToken } from '../../theme/interface';
import type { import type {
FullToken, FullToken,
TokenWithCommonCls,
GetDefaultToken, GetDefaultToken,
TokenWithCommonCls,
} from '../../theme/util/genComponentStyleHook'; } 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 * @desc
* @descEN Background color of cell hover state * @descEN Background color of cell hover state
@ -107,7 +109,10 @@ export type PickerPanelToken = {
pickerControlIconBorderWidth: number; pickerControlIconBorderWidth: number;
}; };
export type PickerToken = FullToken<'DatePicker'> & PickerPanelToken & SharedInputToken; export type PickerToken = FullToken<'DatePicker'> &
PickerPanelToken &
SharedInputToken &
SelectorToken;
export type SharedPickerToken = TokenWithCommonCls<GlobalToken> & export type SharedPickerToken = TokenWithCommonCls<GlobalToken> &
PickerPanelToken & PickerPanelToken &
@ -133,20 +138,30 @@ export const initPickerPanelToken = (token: TokenWithCommonCls<GlobalToken>): Pi
}; };
}; };
export const initPanelComponentToken = (token: GlobalToken): PanelComponentToken => ({ export const initPanelComponentToken = (token: GlobalToken): PanelComponentToken => {
cellHoverBg: token.controlItemBgHover, const { colorBgContainerDisabled, controlHeightSM, controlHeightLG } = token;
cellActiveWithRangeBg: token.controlItemBgActive, return {
cellHoverWithRangeBg: new TinyColor(token.colorPrimary).lighten(35).toHexString(), cellHoverBg: token.controlItemBgHover,
cellRangeBorderColor: new TinyColor(token.colorPrimary).lighten(20).toHexString(), cellActiveWithRangeBg: token.controlItemBgActive,
cellBgDisabled: token.colorBgContainerDisabled, cellHoverWithRangeBg: new TinyColor(token.colorPrimary).lighten(35).toHexString(),
timeColumnWidth: token.controlHeightLG * 1.4, cellRangeBorderColor: new TinyColor(token.colorPrimary).lighten(20).toHexString(),
timeColumnHeight: 28 * 8, cellBgDisabled: colorBgContainerDisabled,
timeCellHeight: 28, timeColumnWidth: controlHeightLG * 1.4,
cellWidth: token.controlHeightSM * 1.5, timeColumnHeight: 28 * 8,
cellHeight: token.controlHeightSM, timeCellHeight: 28,
textHeight: token.controlHeightLG, cellWidth: controlHeightSM * 1.5,
withoutTimeCellHeight: token.controlHeightLG * 1.65, 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) => ({ export const prepareComponentToken: GetDefaultToken<'DatePicker'> = (token) => ({
...initComponentToken(token), ...initComponentToken(token),

View File

@ -1,13 +1,41 @@
import type { PickerToken } from './token'; import { unit, type CSSObject } from '@ant-design/cssinjs';
import type { CSSObject } from '@ant-design/cssinjs';
import { genBorderlessStyle, genFilledStyle, genOutlinedStyle } from '../../input/style/variants';
const genVariantsStyle = (token: PickerToken): CSSObject => ({ import { genBorderlessStyle, genFilledStyle, genOutlinedStyle } from '../../input/style/variants';
[token.componentCls]: { import type { PickerToken } from './token';
...genOutlinedStyle(token),
...genFilledStyle(token), const genVariantsStyle = (token: PickerToken): CSSObject => {
...genBorderlessStyle(token), 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; export default genVariantsStyle;

View File

@ -1,6 +1,6 @@
import type { AlignType } from '@rc-component/trigger'; import type { AlignType } from '@rc-component/trigger';
import type { PickerMode } from 'rc-picker/lib/interface'; 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 { SelectCommonPlacement } from '../_util/motion';
import type { DirectionType } from '../config-provider'; import type { DirectionType } from '../config-provider';
import type { PickerLocale, PickerProps } from './generatePicker'; import type { PickerLocale, PickerProps } from './generatePicker';
@ -106,68 +106,8 @@ export function transPlacement2DropdownAlign(
} }
} }
function toArray<T>(list: T | T[]): T[] { type AllowClear = PickerProps['allowClear'];
if (!list) { type ClearIcon = PickerProps['clearIcon'];
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'];
export function mergeAllowClear( export function mergeAllowClear(
allowClear: AllowClear, allowClear: AllowClear,

View File

@ -1523,18 +1523,19 @@ Array [
class="ant-form-item-control-input-content" class="ant-form-item-control-input-content"
> >
<div <div
aria-required="true"
class="ant-picker ant-picker-range ant-picker-outlined" class="ant-picker ant-picker-range ant-picker-outlined"
style="width: 100%;" style="width: 100%;"
> >
<div <div
class="ant-picker-input ant-picker-input-active" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
aria-required="true"
autocomplete="off" autocomplete="off"
date-range="start"
id="dateTime" id="dateTime"
placeholder="Start date" placeholder="Start date"
readonly=""
size="12" size="12"
value="" value=""
/> />
@ -1571,16 +1572,18 @@ Array [
class="ant-picker-input" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
aria-required="true"
autocomplete="off" autocomplete="off"
date-range="end"
placeholder="End date" placeholder="End date"
readonly=""
size="12" size="12"
value="" value=""
/> />
</div> </div>
<div <div
class="ant-picker-active-bar" class="ant-picker-active-bar"
style="left: 0px; width: 0px; position: absolute;" style="position: absolute; width: 0px; left: 0px;"
/> />
<span <span
class="ant-picker-suffix" class="ant-picker-suffix"
@ -1612,15 +1615,15 @@ Array [
> >
<div <div
class="ant-picker-range-wrapper ant-picker-date-range-wrapper" class="ant-picker-range-wrapper ant-picker-date-range-wrapper"
style="min-width: 0;"
> >
<div <div
class="ant-picker-range-arrow" class="ant-picker-range-arrow"
style="left: 0px;" style="left: 0px;"
/> />
<div <div
class="ant-picker-panel-container" class="ant-picker-panel-container ant-picker-date-panel-container"
style="margin-left: 0px;" style="margin-left: 0px; margin-right: auto;"
tabindex="-1"
> >
<div <div
class="ant-picker-panel-layout" class="ant-picker-panel-layout"
@ -1630,8 +1633,8 @@ Array [
class="ant-picker-panels" class="ant-picker-panels"
> >
<div <div
class="ant-picker-panel ant-picker-panel-focused" class="ant-picker-panel"
tabindex="-1" tabindex="0"
> >
<div <div
class="ant-picker-date-panel" class="ant-picker-date-panel"
@ -1740,7 +1743,7 @@ Array [
</div> </div>
</td> </td>
<td <td
class="ant-picker-cell ant-picker-cell-end" class="ant-picker-cell"
title="2016-10-31" title="2016-10-31"
> >
<div <div
@ -1750,7 +1753,7 @@ Array [
</div> </div>
</td> </td>
<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" title="2016-11-01"
> >
<div <div
@ -2048,7 +2051,7 @@ Array [
</div> </div>
</td> </td>
<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" title="2016-11-30"
> >
<div <div
@ -2058,7 +2061,7 @@ Array [
</div> </div>
</td> </td>
<td <td
class="ant-picker-cell ant-picker-cell-start" class="ant-picker-cell"
title="2016-12-01" title="2016-12-01"
> >
<div <div
@ -2166,8 +2169,8 @@ Array [
</div> </div>
</div> </div>
<div <div
class="ant-picker-panel ant-picker-panel-focused" class="ant-picker-panel"
tabindex="-1" tabindex="0"
> >
<div <div
class="ant-picker-date-panel" class="ant-picker-date-panel"
@ -2296,7 +2299,7 @@ Array [
</div> </div>
</td> </td>
<td <td
class="ant-picker-cell ant-picker-cell-end" class="ant-picker-cell"
title="2016-11-30" title="2016-11-30"
> >
<div <div
@ -2306,7 +2309,7 @@ Array [
</div> </div>
</td> </td>
<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" title="2016-12-01"
> >
<div <div
@ -2614,7 +2617,7 @@ Array [
</div> </div>
</td> </td>
<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" title="2016-12-31"
> >
<div <div
@ -2626,7 +2629,7 @@ Array [
</tr> </tr>
<tr> <tr>
<td <td
class="ant-picker-cell ant-picker-cell-start" class="ant-picker-cell"
title="2017-01-01" title="2017-01-01"
> >
<div <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" class="ant-form-item-control-input-content"
> >
<div <div
class="ant-picker ant-picker-outlined ant-picker-disabled" class="ant-picker ant-picker-disabled ant-picker-outlined"
> >
<div <div
class="ant-picker-input" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
autocomplete="off" autocomplete="off"
disabled="" disabled=""
placeholder="Select date" placeholder="Select date"
readonly=""
size="12" size="12"
title=""
value="" value=""
/> />
<span <span
@ -2405,16 +2404,17 @@ Array [
class="ant-form-item-control-input-content" class="ant-form-item-control-input-content"
> >
<div <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 <div
class="ant-picker-input ant-picker-input-active" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
autocomplete="off" autocomplete="off"
date-range="start"
disabled="" disabled=""
placeholder="Start date" placeholder="Start date"
readonly=""
size="12" size="12"
value="" value=""
/> />
@ -2451,17 +2451,18 @@ Array [
class="ant-picker-input" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
autocomplete="off" autocomplete="off"
date-range="end"
disabled="" disabled=""
placeholder="End date" placeholder="End date"
readonly=""
size="12" size="12"
value="" value=""
/> />
</div> </div>
<div <div
class="ant-picker-active-bar" class="ant-picker-active-bar"
style="left:0;width:0;position:absolute" style="position:absolute;width:0;left:0"
/> />
<span <span
class="ant-picker-suffix" class="ant-picker-suffix"
@ -7327,11 +7328,10 @@ exports[`renders components/form/demo/size.tsx correctly 1`] = `
class="ant-picker-input" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
autocomplete="off" autocomplete="off"
placeholder="Select date" placeholder="Select date"
readonly=""
size="12" size="12"
title=""
value="" value=""
/> />
<span <span
@ -7597,13 +7597,12 @@ exports[`renders components/form/demo/time-related-controls.tsx correctly 1`] =
class="ant-picker-input" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
aria-required="true" aria-required="true"
autocomplete="off" autocomplete="off"
id="time_related_controls_date-picker" id="time_related_controls_date-picker"
placeholder="Select date" placeholder="Select date"
readonly=""
size="12" size="12"
title=""
value="" value=""
/> />
<span <span
@ -7669,13 +7668,12 @@ exports[`renders components/form/demo/time-related-controls.tsx correctly 1`] =
class="ant-picker-input" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
aria-required="true" aria-required="true"
autocomplete="off" autocomplete="off"
id="time_related_controls_date-time-picker" id="time_related_controls_date-time-picker"
placeholder="Select date" placeholder="Select date"
readonly=""
size="21" size="21"
title=""
value="" value=""
/> />
<span <span
@ -7741,13 +7739,12 @@ exports[`renders components/form/demo/time-related-controls.tsx correctly 1`] =
class="ant-picker-input" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
aria-required="true" aria-required="true"
autocomplete="off" autocomplete="off"
id="time_related_controls_month-picker" id="time_related_controls_month-picker"
placeholder="Select month" placeholder="Select month"
readonly=""
size="12" size="12"
title=""
value="" value=""
/> />
<span <span
@ -7807,17 +7804,18 @@ exports[`renders components/form/demo/time-related-controls.tsx correctly 1`] =
class="ant-form-item-control-input-content" class="ant-form-item-control-input-content"
> >
<div <div
aria-required="true"
class="ant-picker ant-picker-range ant-picker-outlined" class="ant-picker ant-picker-range ant-picker-outlined"
> >
<div <div
class="ant-picker-input ant-picker-input-active" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
aria-required="true"
autocomplete="off" autocomplete="off"
date-range="start"
id="time_related_controls_range-picker" id="time_related_controls_range-picker"
placeholder="Start date" placeholder="Start date"
readonly=""
size="12" size="12"
value="" value=""
/> />
@ -7854,16 +7852,18 @@ exports[`renders components/form/demo/time-related-controls.tsx correctly 1`] =
class="ant-picker-input" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
aria-required="true"
autocomplete="off" autocomplete="off"
date-range="end"
placeholder="End date" placeholder="End date"
readonly=""
size="12" size="12"
value="" value=""
/> />
</div> </div>
<div <div
class="ant-picker-active-bar" class="ant-picker-active-bar"
style="left:0;width:0;position:absolute" style="position:absolute;width:0;left:0"
/> />
<span <span
class="ant-picker-suffix" 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" class="ant-form-item-control-input-content"
> >
<div <div
aria-required="true"
class="ant-picker ant-picker-range ant-picker-outlined" class="ant-picker ant-picker-range ant-picker-outlined"
> >
<div <div
class="ant-picker-input ant-picker-input-active" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
aria-required="true"
autocomplete="off" autocomplete="off"
date-range="start"
id="time_related_controls_range-time-picker" id="time_related_controls_range-time-picker"
placeholder="Start date" placeholder="Start date"
readonly=""
size="21" size="21"
value="" value=""
/> />
@ -7968,16 +7969,18 @@ exports[`renders components/form/demo/time-related-controls.tsx correctly 1`] =
class="ant-picker-input" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
aria-required="true"
autocomplete="off" autocomplete="off"
date-range="end"
placeholder="End date" placeholder="End date"
readonly=""
size="21" size="21"
value="" value=""
/> />
</div> </div>
<div <div
class="ant-picker-active-bar" class="ant-picker-active-bar"
style="left:0;width:0;position:absolute" style="position:absolute;width:0;left:0"
/> />
<span <span
class="ant-picker-suffix" class="ant-picker-suffix"
@ -8041,13 +8044,12 @@ exports[`renders components/form/demo/time-related-controls.tsx correctly 1`] =
class="ant-picker-input" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
aria-required="true" aria-required="true"
autocomplete="off" autocomplete="off"
id="time_related_controls_time-picker" id="time_related_controls_time-picker"
placeholder="Select time" placeholder="Select time"
readonly=""
size="10" size="10"
title=""
value="" value=""
/> />
<span <span
@ -10321,11 +10323,10 @@ exports[`renders components/form/demo/validate-static.tsx correctly 1`] = `
class="ant-picker-input" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
autocomplete="off" autocomplete="off"
placeholder="Select date" placeholder="Select date"
readonly=""
size="12" size="12"
title=""
value="" value=""
/> />
<span <span
@ -10414,11 +10415,10 @@ exports[`renders components/form/demo/validate-static.tsx correctly 1`] = `
class="ant-picker-input" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
autocomplete="off" autocomplete="off"
placeholder="Select time" placeholder="Select time"
readonly=""
size="10" size="10"
title=""
value="" value=""
/> />
<span <span
@ -10507,12 +10507,13 @@ exports[`renders components/form/demo/validate-static.tsx correctly 1`] = `
style="width:100%" style="width:100%"
> >
<div <div
class="ant-picker-input ant-picker-input-active" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
autocomplete="off" autocomplete="off"
date-range="start"
placeholder="Start date" placeholder="Start date"
readonly=""
size="12" size="12"
value="" value=""
/> />
@ -10549,16 +10550,17 @@ exports[`renders components/form/demo/validate-static.tsx correctly 1`] = `
class="ant-picker-input" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
autocomplete="off" autocomplete="off"
date-range="end"
placeholder="End date" placeholder="End date"
readonly=""
size="12" size="12"
value="" value=""
/> />
</div> </div>
<div <div
class="ant-picker-active-bar" class="ant-picker-active-bar"
style="left:0;width:0;position:absolute" style="position:absolute;width:0;left:0"
/> />
<span <span
class="ant-picker-suffix" class="ant-picker-suffix"
@ -10997,11 +10999,10 @@ exports[`renders components/form/demo/validate-static.tsx correctly 1`] = `
class="ant-picker-input" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
autocomplete="off" autocomplete="off"
placeholder="Select date" placeholder="Select date"
readonly=""
size="12" size="12"
title=""
value="" value=""
/> />
<span <span
@ -11062,11 +11063,10 @@ exports[`renders components/form/demo/validate-static.tsx correctly 1`] = `
class="ant-picker-input" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
autocomplete="off" autocomplete="off"
placeholder="Select date" placeholder="Select date"
readonly=""
size="12" size="12"
title=""
value="" value=""
/> />
<span <span
@ -12403,13 +12403,12 @@ exports[`renders components/form/demo/variant.tsx correctly 1`] = `
class="ant-picker-input" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
aria-required="true" aria-required="true"
autocomplete="off" autocomplete="off"
id="DatePicker" id="DatePicker"
placeholder="Select date" placeholder="Select date"
readonly=""
size="12" size="12"
title=""
value="" value=""
/> />
<span <span
@ -12469,17 +12468,18 @@ exports[`renders components/form/demo/variant.tsx correctly 1`] = `
class="ant-form-item-control-input-content" class="ant-form-item-control-input-content"
> >
<div <div
aria-required="true"
class="ant-picker ant-picker-range ant-picker-filled" class="ant-picker ant-picker-range ant-picker-filled"
> >
<div <div
class="ant-picker-input ant-picker-input-active" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
aria-required="true"
autocomplete="off" autocomplete="off"
date-range="start"
id="RangePicker" id="RangePicker"
placeholder="Start date" placeholder="Start date"
readonly=""
size="12" size="12"
value="" value=""
/> />
@ -12516,16 +12516,18 @@ exports[`renders components/form/demo/variant.tsx correctly 1`] = `
class="ant-picker-input" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
aria-required="true"
autocomplete="off" autocomplete="off"
date-range="end"
placeholder="End date" placeholder="End date"
readonly=""
size="12" size="12"
value="" value=""
/> />
</div> </div>
<div <div
class="ant-picker-active-bar" class="ant-picker-active-bar"
style="left:0;width:0;position:absolute" style="position:absolute;width:0;left:0"
/> />
<span <span
class="ant-picker-suffix" class="ant-picker-suffix"

View File

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

View File

@ -599,11 +599,10 @@ Array [
class="ant-picker-input" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
autocomplete="off" autocomplete="off"
placeholder="Select date" placeholder="Select date"
readonly=""
size="12" size="12"
title=""
value="" value=""
/> />
<span <span
@ -639,11 +638,10 @@ Array [
class="ant-picker-input" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
autocomplete="off" autocomplete="off"
placeholder="Select time" placeholder="Select time"
readonly=""
size="10" size="10"
title=""
value="" value=""
/> />
<span <span
@ -996,12 +994,13 @@ Array [
class="ant-picker ant-picker-range ant-picker-outlined" class="ant-picker ant-picker-range ant-picker-outlined"
> >
<div <div
class="ant-picker-input ant-picker-input-active" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
autocomplete="off" autocomplete="off"
date-range="start"
placeholder="Start date" placeholder="Start date"
readonly=""
size="12" size="12"
value="" value=""
/> />
@ -1038,16 +1037,17 @@ Array [
class="ant-picker-input" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
autocomplete="off" autocomplete="off"
date-range="end"
placeholder="End date" placeholder="End date"
readonly=""
size="12" size="12"
value="" value=""
/> />
</div> </div>
<div <div
class="ant-picker-active-bar" class="ant-picker-active-bar"
style="left:0;width:0;position:absolute" style="position:absolute;width:0;left:0"
/> />
<span <span
class="ant-picker-suffix" class="ant-picker-suffix"
@ -1080,11 +1080,10 @@ Array [
class="ant-picker-input" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
autocomplete="off" autocomplete="off"
placeholder="Select month" placeholder="Select month"
readonly=""
size="12" size="12"
title=""
value="" value=""
/> />
<span <span
@ -2954,11 +2953,10 @@ exports[`renders components/input/demo/group.tsx correctly 1`] = `
class="ant-picker-input" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
autocomplete="off" autocomplete="off"
placeholder="Select date" placeholder="Select date"
readonly=""
size="12" size="12"
title=""
value="" value=""
/> />
<span <span
@ -3002,12 +3000,13 @@ exports[`renders components/input/demo/group.tsx correctly 1`] = `
style="width:70%" style="width:70%"
> >
<div <div
class="ant-picker-input ant-picker-input-active" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
autocomplete="off" autocomplete="off"
date-range="start"
placeholder="Start date" placeholder="Start date"
readonly=""
size="12" size="12"
value="" value=""
/> />
@ -3044,16 +3043,17 @@ exports[`renders components/input/demo/group.tsx correctly 1`] = `
class="ant-picker-input" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
autocomplete="off" autocomplete="off"
date-range="end"
placeholder="End date" placeholder="End date"
readonly=""
size="12" size="12"
value="" value=""
/> />
</div> </div>
<div <div
class="ant-picker-active-bar" class="ant-picker-active-bar"
style="left:0;width:0;position:absolute" style="position:absolute;width:0;left:0"
/> />
<span <span
class="ant-picker-suffix" 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 { 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 { 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 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 { multipleSelectItemHeight, selectHeight, lineWidth } = token;
const selectItemDist = token const selectItemDist = token
.calc(selectHeight) .calc(selectHeight)
@ -17,7 +31,10 @@ const getSelectItemStyle = (token: SelectToken): number | string => {
return selectItemDist; return selectItemDist;
}; };
function genSizeStyle(token: SelectToken, suffix?: string): CSSObject { export const genSelectionStyle = (
token: TokenWithCommonCls<AliasToken> & SelectItemToken,
suffix?: string,
): CSSObject => {
const { componentCls, iconCls } = token; const { componentCls, iconCls } = token;
const selectOverflowPrefixCls = `${componentCls}-selection-overflow`; const selectOverflowPrefixCls = `${componentCls}-selection-overflow`;
@ -29,8 +46,6 @@ function genSizeStyle(token: SelectToken, suffix?: string): CSSObject {
return { return {
[`${componentCls}-multiple${suffixCls}`]: { [`${componentCls}-multiple${suffixCls}`]: {
fontSize: token.fontSize,
/** /**
* Do not merge `height` & `line-height` under style with `selection` & `search`, since chrome * Do not merge `height` & `line-height` under style with `selection` & `search`, since chrome
* may update to redesign with its align logic. * 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(), paddingBlock: token.calc(selectItemDist).sub(FIXED_ITEM_MARGIN).equal(),
borderRadius: token.borderRadius, borderRadius: token.borderRadius,
[`${componentCls}-show-search&`]: {
cursor: 'text',
},
[`${componentCls}-disabled&`]: { [`${componentCls}-disabled&`]: {
background: token.multipleSelectorBgDisabled, background: token.multipleSelectorBgDisabled,
cursor: 'not-allowed', 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 ======================== // ======================== Selections ========================
[`${componentCls}-selection-item`]: { [`${componentCls}-selection-item`]: {
display: 'flex', 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 => { const genMultipleStyle = (token: SelectToken): CSSInterpolation => {

View File

@ -1,7 +1,48 @@
import type { CSSProperties } from 'react'; import type { CSSProperties } from 'react';
import type { FullToken, GetDefaultToken } from 'antd/es/theme/util/genComponentStyleHook'; 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 * @desc z-index
* @descEN z-index of dropdown * @descEN z-index of dropdown
@ -62,54 +103,20 @@ export interface ComponentToken {
* @descEN Height of single selected item with large size * @descEN Height of single selected item with large size
*/ */
singleItemHeightLG: number; 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; showArrowPaddingInlineEnd: number;
} }
export interface SelectToken extends FullToken<'Select'> { export interface SelectorToken {
rootPrefixCls: string;
inputPaddingHorizontalBase: number | string; inputPaddingHorizontalBase: number | string;
multipleSelectItemHeight: number; multipleSelectItemHeight: number;
selectHeight: number; selectHeight: number;
} }
export interface SelectToken extends FullToken<'Select'>, SelectorToken {
rootPrefixCls: string;
}
export const prepareComponentToken: GetDefaultToken<'Select'> = (token) => { export const prepareComponentToken: GetDefaultToken<'Select'> = (token) => {
const { const {
fontSize, fontSize,

View File

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

View File

@ -15,11 +15,10 @@ exports[`renders components/time-picker/demo/12hours.tsx correctly 1`] = `
class="ant-picker-input" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
autocomplete="off" autocomplete="off"
placeholder="Select time" placeholder="Select time"
readonly=""
size="12" size="12"
title=""
value="" value=""
/> />
<span <span
@ -61,11 +60,10 @@ exports[`renders components/time-picker/demo/12hours.tsx correctly 1`] = `
class="ant-picker-input" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
autocomplete="off" autocomplete="off"
placeholder="Select time" placeholder="Select time"
readonly=""
size="11" size="11"
title=""
value="" value=""
/> />
<span <span
@ -107,11 +105,10 @@ exports[`renders components/time-picker/demo/12hours.tsx correctly 1`] = `
class="ant-picker-input" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
autocomplete="off" autocomplete="off"
placeholder="Select time" placeholder="Select time"
readonly=""
size="10" size="10"
title=""
value="" value=""
/> />
<span <span
@ -154,11 +151,10 @@ exports[`renders components/time-picker/demo/addon.tsx correctly 1`] = `
class="ant-picker-input" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
autocomplete="off" autocomplete="off"
placeholder="Select time" placeholder="Select time"
readonly=""
size="10" size="10"
title=""
value="" value=""
/> />
<span <span
@ -199,11 +195,54 @@ exports[`renders components/time-picker/demo/basic.tsx correctly 1`] = `
class="ant-picker-input" class="ant-picker-input"
> >
<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" autocomplete="off"
placeholder="Select time" placeholder="Select time"
readonly=""
size="10" size="10"
title=""
value="" value=""
/> />
<span <span
@ -244,11 +283,10 @@ exports[`renders components/time-picker/demo/colored-popup.tsx correctly 1`] = `
class="ant-picker-input" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
autocomplete="off" autocomplete="off"
placeholder="Select time" placeholder="Select time"
readonly=""
size="10" size="10"
title=""
value="" value=""
/> />
<span <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`] = ` exports[`renders components/time-picker/demo/disabled.tsx correctly 1`] = `
<div <div
class="ant-picker ant-picker-outlined ant-picker-disabled" class="ant-picker ant-picker-disabled ant-picker-outlined"
> >
<div <div
class="ant-picker-input" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
autocomplete="off" autocomplete="off"
disabled="" disabled=""
placeholder="Select time" placeholder="Select time"
readonly=""
size="10" size="10"
title="" value="12:08:23"
value=""
/> />
<span <span
class="ant-picker-suffix" class="ant-picker-suffix"
@ -335,12 +372,11 @@ exports[`renders components/time-picker/demo/hide-column.tsx correctly 1`] = `
class="ant-picker-input" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
autocomplete="off" autocomplete="off"
placeholder="Select time" placeholder="Select time"
readonly=""
size="10" size="10"
title="" value="12:08"
value=""
/> />
<span <span
class="ant-picker-suffix" class="ant-picker-suffix"
@ -405,11 +441,10 @@ exports[`renders components/time-picker/demo/interval-options.tsx correctly 1`]
class="ant-picker-input" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
autocomplete="off" autocomplete="off"
placeholder="Select time" placeholder="Select time"
readonly=""
size="10" size="10"
title=""
value="" value=""
/> />
<span <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" class="ant-picker ant-picker-range ant-picker-outlined"
> >
<div <div
class="ant-picker-input ant-picker-input-active" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
autocomplete="off" autocomplete="off"
date-range="start"
placeholder="Start time" placeholder="Start time"
readonly=""
size="10" size="10"
value="" value=""
/> />
@ -489,16 +525,17 @@ exports[`renders components/time-picker/demo/range-picker.tsx correctly 1`] = `
class="ant-picker-input" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
autocomplete="off" autocomplete="off"
date-range="end"
placeholder="End time" placeholder="End time"
readonly=""
size="10" size="10"
value="" value=""
/> />
</div> </div>
<div <div
class="ant-picker-active-bar" class="ant-picker-active-bar"
style="left:0;width:0;position:absolute" style="position:absolute;width:0;left:0"
/> />
<span <span
class="ant-picker-suffix" class="ant-picker-suffix"
@ -541,11 +578,10 @@ exports[`renders components/time-picker/demo/render-panel.tsx correctly 1`] = `
class="ant-picker-input" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
autocomplete="off" autocomplete="off"
placeholder="Select time" placeholder="Select time"
readonly=""
size="10" size="10"
title=""
value="" value=""
/> />
<span <span
@ -594,12 +630,11 @@ exports[`renders components/time-picker/demo/size.tsx correctly 1`] = `
class="ant-picker-input" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
autocomplete="off" autocomplete="off"
placeholder="Select time" placeholder="Select time"
readonly=""
size="10" size="10"
title="" value="12:08:23"
value=""
/> />
<span <span
class="ant-picker-suffix" class="ant-picker-suffix"
@ -665,12 +700,11 @@ exports[`renders components/time-picker/demo/size.tsx correctly 1`] = `
class="ant-picker-input" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
autocomplete="off" autocomplete="off"
placeholder="Select time" placeholder="Select time"
readonly=""
size="10" size="10"
title="" value="12:08:23"
value=""
/> />
<span <span
class="ant-picker-suffix" class="ant-picker-suffix"
@ -736,12 +770,11 @@ exports[`renders components/time-picker/demo/size.tsx correctly 1`] = `
class="ant-picker-input" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
autocomplete="off" autocomplete="off"
placeholder="Select time" placeholder="Select time"
readonly=""
size="10" size="10"
title="" value="12:08:23"
value=""
/> />
<span <span
class="ant-picker-suffix" class="ant-picker-suffix"
@ -814,11 +847,10 @@ exports[`renders components/time-picker/demo/status.tsx correctly 1`] = `
class="ant-picker-input" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
autocomplete="off" autocomplete="off"
placeholder="Select time" placeholder="Select time"
readonly=""
size="10" size="10"
title=""
value="" value=""
/> />
<span <span
@ -860,11 +892,10 @@ exports[`renders components/time-picker/demo/status.tsx correctly 1`] = `
class="ant-picker-input" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
autocomplete="off" autocomplete="off"
placeholder="Select time" placeholder="Select time"
readonly=""
size="10" size="10"
title=""
value="" value=""
/> />
<span <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" class="ant-picker ant-picker-range ant-picker-outlined ant-picker-status-error"
> >
<div <div
class="ant-picker-input ant-picker-input-active" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
autocomplete="off" autocomplete="off"
date-range="start"
placeholder="Start time" placeholder="Start time"
readonly=""
size="10" size="10"
value="" value=""
/> />
@ -945,16 +977,17 @@ exports[`renders components/time-picker/demo/status.tsx correctly 1`] = `
class="ant-picker-input" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
autocomplete="off" autocomplete="off"
date-range="end"
placeholder="End time" placeholder="End time"
readonly=""
size="10" size="10"
value="" value=""
/> />
</div> </div>
<div <div
class="ant-picker-active-bar" class="ant-picker-active-bar"
style="left:0;width:0;position:absolute" style="position:absolute;width:0;left:0"
/> />
<span <span
class="ant-picker-suffix" 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" class="ant-picker ant-picker-range ant-picker-outlined ant-picker-status-warning"
> >
<div <div
class="ant-picker-input ant-picker-input-active" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
autocomplete="off" autocomplete="off"
date-range="start"
placeholder="Start time" placeholder="Start time"
readonly=""
size="10" size="10"
value="" value=""
/> />
@ -1033,16 +1067,17 @@ exports[`renders components/time-picker/demo/status.tsx correctly 1`] = `
class="ant-picker-input" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
autocomplete="off" autocomplete="off"
date-range="end"
placeholder="End time" placeholder="End time"
readonly=""
size="10" size="10"
value="" value=""
/> />
</div> </div>
<div <div
class="ant-picker-active-bar" class="ant-picker-active-bar"
style="left:0;width:0;position:absolute" style="position:absolute;width:0;left:0"
/> />
<span <span
class="ant-picker-suffix" class="ant-picker-suffix"
@ -1083,11 +1118,10 @@ exports[`renders components/time-picker/demo/suffix.tsx correctly 1`] = `
class="ant-picker-input" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
autocomplete="off" autocomplete="off"
placeholder="Select time" placeholder="Select time"
readonly=""
size="10" size="10"
title=""
value="" value=""
/> />
<span <span
@ -1125,11 +1159,10 @@ exports[`renders components/time-picker/demo/value.tsx correctly 1`] = `
class="ant-picker-input" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
autocomplete="off" autocomplete="off"
placeholder="Select time" placeholder="Select time"
readonly=""
size="10" size="10"
title=""
value="" value=""
/> />
<span <span
@ -1178,11 +1211,10 @@ exports[`renders components/time-picker/demo/variant.tsx correctly 1`] = `
class="ant-picker-input" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
autocomplete="off" autocomplete="off"
placeholder="Filled" placeholder="Filled"
readonly=""
size="10" size="10"
title=""
value="" value=""
/> />
<span <span
@ -1217,12 +1249,13 @@ exports[`renders components/time-picker/demo/variant.tsx correctly 1`] = `
class="ant-picker ant-picker-range ant-picker-outlined" class="ant-picker ant-picker-range ant-picker-outlined"
> >
<div <div
class="ant-picker-input ant-picker-input-active" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
autocomplete="off" autocomplete="off"
date-range="start"
placeholder="Filled" placeholder="Filled"
readonly=""
size="10" size="10"
value="" value=""
/> />
@ -1259,16 +1292,17 @@ exports[`renders components/time-picker/demo/variant.tsx correctly 1`] = `
class="ant-picker-input" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
autocomplete="off" autocomplete="off"
date-range="end"
placeholder="" placeholder=""
readonly=""
size="10" size="10"
value="" value=""
/> />
</div> </div>
<div <div
class="ant-picker-active-bar" class="ant-picker-active-bar"
style="left:0;width:0;position:absolute" style="position:absolute;width:0;left:0"
/> />
<span <span
class="ant-picker-suffix" class="ant-picker-suffix"
@ -1309,11 +1343,10 @@ exports[`renders components/time-picker/demo/variant.tsx correctly 1`] = `
class="ant-picker-input" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
autocomplete="off" autocomplete="off"
placeholder="Filled" placeholder="Filled"
readonly=""
size="10" size="10"
title=""
value="" value=""
/> />
<span <span
@ -1348,12 +1381,13 @@ exports[`renders components/time-picker/demo/variant.tsx correctly 1`] = `
class="ant-picker ant-picker-range ant-picker-filled" class="ant-picker ant-picker-range ant-picker-filled"
> >
<div <div
class="ant-picker-input ant-picker-input-active" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
autocomplete="off" autocomplete="off"
date-range="start"
placeholder="Filled" placeholder="Filled"
readonly=""
size="10" size="10"
value="" value=""
/> />
@ -1390,16 +1424,17 @@ exports[`renders components/time-picker/demo/variant.tsx correctly 1`] = `
class="ant-picker-input" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
autocomplete="off" autocomplete="off"
date-range="end"
placeholder="" placeholder=""
readonly=""
size="10" size="10"
value="" value=""
/> />
</div> </div>
<div <div
class="ant-picker-active-bar" class="ant-picker-active-bar"
style="left:0;width:0;position:absolute" style="position:absolute;width:0;left:0"
/> />
<span <span
class="ant-picker-suffix" class="ant-picker-suffix"
@ -1440,11 +1475,10 @@ exports[`renders components/time-picker/demo/variant.tsx correctly 1`] = `
class="ant-picker-input" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
autocomplete="off" autocomplete="off"
placeholder="Borderless" placeholder="Borderless"
readonly=""
size="10" size="10"
title=""
value="" value=""
/> />
<span <span
@ -1479,12 +1513,13 @@ exports[`renders components/time-picker/demo/variant.tsx correctly 1`] = `
class="ant-picker ant-picker-range ant-picker-borderless" class="ant-picker ant-picker-range ant-picker-borderless"
> >
<div <div
class="ant-picker-input ant-picker-input-active" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
autocomplete="off" autocomplete="off"
date-range="start"
placeholder="Borderless" placeholder="Borderless"
readonly=""
size="10" size="10"
value="" value=""
/> />
@ -1521,16 +1556,17 @@ exports[`renders components/time-picker/demo/variant.tsx correctly 1`] = `
class="ant-picker-input" class="ant-picker-input"
> >
<input <input
aria-invalid="false"
autocomplete="off" autocomplete="off"
date-range="end"
placeholder="" placeholder=""
readonly=""
size="10" size="10"
value="" value=""
/> />
</div> </div>
<div <div
class="ant-picker-active-bar" class="ant-picker-active-bar"
style="left:0;width:0;position:absolute" style="position:absolute;width:0;left:0"
/> />
<span <span
class="ant-picker-suffix" 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/interval-options.tsx">interval option</code>
<code src="./demo/addon.tsx">Addon</code> <code src="./demo/addon.tsx">Addon</code>
<code src="./demo/12hours.tsx">12 hours</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/colored-popup.tsx" debug>Colored Popup</code>
<code src="./demo/range-picker.tsx">Time Range Picker</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/status.tsx">Status</code>
<code src="./demo/suffix.tsx" debug>Suffix</code> <code src="./demo/suffix.tsx" debug>Suffix</code>
<code src="./demo/render-panel.tsx" debug>_InternalPanelDoNotUseOrYouWillBeFired</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 | | allowClear | Customize clear icon | boolean \| { clearIcon?: ReactNode } | true | 5.8.0: Support object type |
| autoFocus | If get focus when component mounted | boolean | false | | | 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 | | 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 | - | | | className | The className of picker | string | - | |
| defaultValue | To set default time | [dayjs](http://day.js.org/) | - | | | defaultValue | To set default time | [dayjs](http://day.js.org/) | - | |
| disabled | Determine whether the TimePicker is disabled | boolean | false | | | disabled | Determine whether the TimePicker is disabled | boolean | false | |
@ -63,6 +64,7 @@ dayjs.extend(customParseFormat)
| hourStep | Interval between hours in picker | number | 1 | | | 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 | | | 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 | | | 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 | | | open | Whether to popup panel | boolean | false | |
| placeholder | Display when there's no value | string \| \[string, string] | `Select a time` | | | 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 | | | 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 | - | | | suffixIcon | The custom suffix icon | ReactNode | - | |
| use12Hours | Display as 12 hours format, with default format `h:mm:ss a` | boolean | false | | | use12Hours | Display as 12 hours format, with default format `h:mm:ss a` | boolean | false | |
| value | To set time | [dayjs](http://day.js.org/) | - | | | 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 | - | | | 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 | - | | | 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 | - | | | onSelect | A callback function, executes when a value is selected | function(time: dayjs): void | - | |
@ -88,9 +90,16 @@ type DisabledTime = (now: Dayjs) => {
disabledHours?: () => number[]; disabledHours?: () => number[];
disabledMinutes?: (selectedHour: number) => number[]; disabledMinutes?: (selectedHour: number) => number[];
disabledSeconds?: (selectedHour: number, selectedMinute: 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 ## Methods
| Name | Description | Version | | Name | Description | Version |

View File

@ -3,9 +3,24 @@ import type { Dayjs } from 'dayjs';
import genPurePanel from '../_util/PurePanel'; import genPurePanel from '../_util/PurePanel';
import type { InputStatus } from '../_util/statusUtils'; import type { InputStatus } from '../_util/statusUtils';
import type { AnyObject } from '../_util/type';
import { devUseWarning } from '../_util/warning'; import { devUseWarning } from '../_util/warning';
import DatePicker from '../date-picker'; 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; const { TimePicker: InternalTimePicker, RangePicker: InternalRangePicker } = DatePicker;

View File

@ -26,9 +26,10 @@ demo:
<code src="./demo/interval-options.tsx">步长选项</code> <code src="./demo/interval-options.tsx">步长选项</code>
<code src="./demo/addon.tsx">附加内容</code> <code src="./demo/addon.tsx">附加内容</code>
<code src="./demo/12hours.tsx">12 小时制</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/colored-popup.tsx" debug>色付きポップアップ</code>
<code src="./demo/range-picker.tsx">范围选择器</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/status.tsx">自定义状态</code>
<code src="./demo/suffix.tsx" debug>后缀图标</code> <code src="./demo/suffix.tsx" debug>后缀图标</code>
<code src="./demo/render-panel.tsx" debug>_InternalPanelDoNotUseOrYouWillBeFired</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: 支持对象类型 | | allowClear | 自定义清除按钮 | boolean \| { clearIcon?: ReactNode } | true | 5.8.0: 支持对象类型 |
| autoFocus | 自动获取焦点 | boolean | false | | | 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 | | 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 | - | | | className | 选择器类名 | string | - | |
| defaultValue | 默认时间 | [dayjs](http://day.js.org/) | - | | | defaultValue | 默认时间 | [dayjs](http://day.js.org/) | - | |
| disabled | 禁用全部操作 | boolean | false | | | disabled | 禁用全部操作 | boolean | false | |
@ -63,6 +64,7 @@ dayjs.extend(customParseFormat)
| hourStep | 小时选项间隔 | number | 1 | | | hourStep | 小时选项间隔 | number | 1 | |
| inputReadOnly | 设置输入框为只读(避免在移动设备上打开虚拟键盘) | boolean | false | | | inputReadOnly | 设置输入框为只读(避免在移动设备上打开虚拟键盘) | boolean | false | |
| minuteStep | 分钟选项间隔 | number | 1 | | | minuteStep | 分钟选项间隔 | number | 1 | |
| needConfirm | 是否需要确认按钮,为 `false` 时失去焦点即代表选择 | boolean | - | 5.14.0 |
| open | 面板是否打开 | boolean | false | | | open | 面板是否打开 | boolean | false | |
| placeholder | 没有值的时候显示的内容 | string \| \[string, string] | `请选择时间` | | | placeholder | 没有值的时候显示的内容 | string \| \[string, string] | `请选择时间` | |
| placement | 选择框弹出的位置 | `bottomLeft` `bottomRight` `topLeft` `topRight` | bottomLeft | | | placement | 选择框弹出的位置 | `bottomLeft` `bottomRight` `topLeft` `topRight` | bottomLeft | |
@ -76,7 +78,7 @@ dayjs.extend(customParseFormat)
| suffixIcon | 自定义的选择框后缀图标 | ReactNode | - | | | suffixIcon | 自定义的选择框后缀图标 | ReactNode | - | |
| use12Hours | 使用 12 小时制,为 true 时 `format` 默认为 `h:mm:ss a` | boolean | false | | | use12Hours | 使用 12 小时制,为 true 时 `format` 默认为 `h:mm:ss a` | boolean | false | |
| value | 当前时间 | [dayjs](http://day.js.org/) | - | | | 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 | - | | | onChange | 时间发生变化的回调 | function(time: dayjs, timeString: string): void | - | |
| onOpenChange | 面板打开/关闭时的回调 | (open: boolean) => void | - | | | onOpenChange | 面板打开/关闭时的回调 | (open: boolean) => void | - | |
@ -87,9 +89,16 @@ type DisabledTime = (now: Dayjs) => {
disabledHours?: () => number[]; disabledHours?: () => number[];
disabledMinutes?: (selectedHour: number) => number[]; disabledMinutes?: (selectedHour: number) => number[];
disabledSeconds?: (selectedHour: number, selectedMinute: 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'); + 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: If you do not want to replace with day.js, you can use `@ant-design/moment-webpack-plugin` to keep moment.js:
```bash ```bash

View File

@ -259,6 +259,8 @@ export default {
+ dayjs.locale('zh-cn'); + 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 如果你暂时不想替换 day.js也可以使用 `@ant-design/moment-webpack-plugin` 插件将 day.js 替换回 moment.js
```bash ```bash

View File

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