From 6f8a13985ceb4f18dde0a0a7880620d59bec3cdc Mon Sep 17 00:00:00 2001 From: tangjinzhou <415800467@qq.com> Date: Thu, 26 Aug 2021 14:09:04 +0800 Subject: [PATCH] refactor: datePicker & calendar & trigger (#4522) --- .gitignore | 2 + CHANGELOG.en-US.md | 24 + CHANGELOG.zh-CN.md | 24 + antd-tools/getWebpackConfig.js | 1 - components/_util/EventInterface.ts | 8 + components/_util/Portal.js | 60 +- components/_util/PortalWrapper.js | 5 +- components/_util/hooks/useConfigInject.ts | 6 + components/_util/hooks/useMemo.ts | 4 +- components/_util/hooks/useMergedState.ts | 51 + components/_util/hooks/useState.ts | 17 + components/_util/interopDefault.js | 4 - components/_util/moment-util.js | 75 - components/_util/transition.tsx | 30 +- components/auto-complete/InputElement.tsx | 9 - components/auto-complete/index.tsx | 3 +- components/calendar/Header.tsx | 370 +++-- components/calendar/date-fns.tsx | 8 + components/calendar/dayjs.tsx | 9 + components/calendar/generateCalendar.tsx | 332 +++++ components/calendar/index.tsx | 260 +--- components/calendar/locale/ar_EG.ts | 2 - components/calendar/locale/ar_EG.tsx | 3 + components/calendar/locale/az_AZ.tsx | 3 + components/calendar/locale/bg_BG.ts | 2 - components/calendar/locale/bg_BG.tsx | 3 + components/calendar/locale/by_BY.tsx | 3 + components/calendar/locale/ca_ES.ts | 2 - components/calendar/locale/ca_ES.tsx | 3 + components/calendar/locale/cs_CZ.ts | 2 - components/calendar/locale/cs_CZ.tsx | 3 + components/calendar/locale/da_DK.ts | 2 - components/calendar/locale/da_DK.tsx | 3 + components/calendar/locale/de_DE.ts | 2 - components/calendar/locale/de_DE.tsx | 3 + components/calendar/locale/el_GR.ts | 2 - components/calendar/locale/el_GR.tsx | 3 + components/calendar/locale/en_GB.ts | 2 - components/calendar/locale/en_GB.tsx | 3 + components/calendar/locale/en_US.ts | 2 - components/calendar/locale/en_US.tsx | 3 + components/calendar/locale/es_ES.ts | 2 - components/calendar/locale/es_ES.tsx | 3 + components/calendar/locale/et_EE.ts | 2 - components/calendar/locale/et_EE.tsx | 3 + components/calendar/locale/fa_IR.ts | 2 - components/calendar/locale/fa_IR.tsx | 3 + components/calendar/locale/fi_FI.ts | 2 - components/calendar/locale/fi_FI.tsx | 3 + components/calendar/locale/fr_BE.ts | 2 - components/calendar/locale/fr_BE.tsx | 3 + components/calendar/locale/fr_CA.tsx | 3 + components/calendar/locale/fr_FR.ts | 2 - components/calendar/locale/fr_FR.tsx | 3 + components/calendar/locale/ga_IE.ts | 3 - components/calendar/locale/ga_IE.tsx | 3 + components/calendar/locale/gl_ES.tsx | 3 + components/calendar/locale/he_IL.ts | 2 - components/calendar/locale/he_IL.tsx | 3 + components/calendar/locale/hi_IN.ts | 2 - components/calendar/locale/hi_IN.tsx | 3 + components/calendar/locale/hr_HR.ts | 3 - components/calendar/locale/hr_HR.tsx | 3 + components/calendar/locale/hu_HU.ts | 2 - components/calendar/locale/hu_HU.tsx | 3 + components/calendar/locale/id_ID.ts | 2 - components/calendar/locale/id_ID.tsx | 3 + components/calendar/locale/is_IS.ts | 2 - components/calendar/locale/is_IS.tsx | 3 + components/calendar/locale/it_IT.ts | 2 - components/calendar/locale/it_IT.tsx | 3 + components/calendar/locale/ja_JP.ts | 2 - components/calendar/locale/ja_JP.tsx | 3 + components/calendar/locale/kk_KZ.tsx | 3 + components/calendar/locale/kmr_IQ.tsx | 3 + components/calendar/locale/kn_IN.ts | 2 - components/calendar/locale/kn_IN.tsx | 3 + components/calendar/locale/ko_KR.ts | 2 - components/calendar/locale/ko_KR.tsx | 3 + components/calendar/locale/ku_IQ.ts | 2 - components/calendar/locale/ku_KU.ts | 2 - components/calendar/locale/lt_LT.tsx | 3 + components/calendar/locale/lv_LV.ts | 3 - components/calendar/locale/lv_LV.tsx | 3 + components/calendar/locale/mk_MK.ts | 3 - components/calendar/locale/mk_MK.tsx | 3 + components/calendar/locale/mn_MN.ts | 2 - components/calendar/locale/mn_MN.tsx | 3 + components/calendar/locale/ms_MY.ts | 3 - components/calendar/locale/ms_MY.tsx | 3 + components/calendar/locale/nb_NO.ts | 2 - components/calendar/locale/nb_NO.tsx | 3 + components/calendar/locale/nl_BE.ts | 2 - components/calendar/locale/nl_BE.tsx | 3 + components/calendar/locale/nl_NL.ts | 2 - components/calendar/locale/nl_NL.tsx | 3 + components/calendar/locale/pl_PL.ts | 2 - components/calendar/locale/pl_PL.tsx | 3 + components/calendar/locale/pt_BR.ts | 2 - components/calendar/locale/pt_BR.tsx | 3 + components/calendar/locale/pt_PT.ts | 2 - components/calendar/locale/pt_PT.tsx | 3 + components/calendar/locale/ro_RO.ts | 3 - components/calendar/locale/ro_RO.tsx | 3 + components/calendar/locale/ru_RU.ts | 2 - components/calendar/locale/ru_RU.tsx | 3 + components/calendar/locale/sk_SK.ts | 2 - components/calendar/locale/sk_SK.tsx | 3 + components/calendar/locale/sl_SI.ts | 2 - components/calendar/locale/sl_SI.tsx | 3 + components/calendar/locale/sr_RS.ts | 2 - components/calendar/locale/sr_RS.tsx | 3 + components/calendar/locale/sv_SE.ts | 2 - components/calendar/locale/sv_SE.tsx | 3 + components/calendar/locale/ta_IN.ts | 3 - components/calendar/locale/ta_IN.tsx | 3 + components/calendar/locale/th_TH.ts | 2 - components/calendar/locale/th_TH.tsx | 3 + components/calendar/locale/tr_TR.ts | 2 - components/calendar/locale/tr_TR.tsx | 3 + components/calendar/locale/uk_UA.ts | 2 - components/calendar/locale/uk_UA.tsx | 3 + components/calendar/locale/vi_VN.ts | 2 - components/calendar/locale/vi_VN.tsx | 3 + components/calendar/locale/zh_CN.ts | 2 - components/calendar/locale/zh_CN.tsx | 3 + components/calendar/locale/zh_TW.ts | 2 - components/calendar/locale/zh_TW.tsx | 3 + components/calendar/moment.tsx | 9 + components/calendar/style/index.less | 432 +++--- .../calendar/style/{index.ts => index.tsx} | 2 + components/calendar/style/rtl.less | 46 + .../__snapshots__/index.test.js.snap | 2 +- components/components.ts | 13 +- components/date-picker/InputIcon.tsx | 22 - components/date-picker/PickerButton.tsx | 8 + components/date-picker/PickerTag.tsx | 6 + components/date-picker/RangePicker.tsx | 446 ------ components/date-picker/WeekPicker.tsx | 229 --- components/date-picker/createPicker.tsx | 266 ---- components/date-picker/date-fns.tsx | 44 + components/date-picker/dayjs.tsx | 45 + .../generatePicker/generateRangePicker.tsx | 216 +++ .../generatePicker/generateSinglePicker.tsx | 235 ++++ .../date-picker/generatePicker/index.tsx | 150 ++ .../date-picker/generatePicker/props.ts | 141 ++ components/date-picker/index.ts | 61 - components/date-picker/index.tsx | 4 + components/date-picker/interface.tsx | 110 -- .../locale/{ar_EG.ts => ar_EG.tsx} | 7 +- components/date-picker/locale/az_AZ.tsx | 16 + .../locale/{bg_BG.ts => bg_BG.tsx} | 7 +- components/date-picker/locale/by_BY.tsx | 23 + .../locale/{ca_ES.ts => ca_ES.tsx} | 7 +- .../locale/{cs_CZ.ts => cs_CZ.tsx} | 7 +- .../locale/{da_DK.ts => da_DK.tsx} | 7 +- .../locale/{de_DE.ts => de_DE.tsx} | 5 +- .../locale/{el_GR.ts => el_GR.tsx} | 5 +- components/date-picker/locale/en_GB.ts | 19 - components/date-picker/locale/en_GB.tsx | 27 + components/date-picker/locale/en_US.ts | 19 - components/date-picker/locale/en_US.tsx | 27 + .../locale/{es_ES.ts => es_ES.tsx} | 7 +- .../locale/{et_EE.ts => et_EE.tsx} | 7 +- components/date-picker/locale/example.json | 1 + components/date-picker/locale/fa_IR.ts | 19 - components/date-picker/locale/fa_IR.tsx | 27 + components/date-picker/locale/fi_FI.ts | 19 - components/date-picker/locale/fi_FI.tsx | 20 + .../locale/{fr_BE.ts => fr_BE.tsx} | 5 +- components/date-picker/locale/fr_CA.tsx | 27 + components/date-picker/locale/fr_FR.ts | 19 - components/date-picker/locale/fr_FR.tsx | 27 + components/date-picker/locale/ga_IE.ts | 19 - components/date-picker/locale/ga_IE.tsx | 27 + components/date-picker/locale/gl_ES.tsx | 20 + .../locale/{he_IL.ts => he_IL.tsx} | 7 +- components/date-picker/locale/hi_IN.ts | 19 - components/date-picker/locale/hi_IN.tsx | 27 + components/date-picker/locale/hr_HR.ts | 19 - components/date-picker/locale/hr_HR.tsx | 27 + .../locale/{hu_HU.ts => hu_HU.tsx} | 7 +- .../locale/{id_ID.ts => id_ID.tsx} | 7 +- .../locale/{is_IS.ts => is_IS.tsx} | 7 +- .../locale/{it_IT.ts => it_IT.tsx} | 5 +- .../locale/{ja_JP.ts => ja_JP.tsx} | 8 +- components/date-picker/locale/kk_KZ.tsx | 27 + components/date-picker/locale/kmr_IQ.tsx | 19 + .../locale/{kn_IN.ts => kn_IN.tsx} | 7 +- .../locale/{ko_KR.ts => ko_KR.tsx} | 7 +- components/date-picker/locale/ku_IQ.ts | 18 - components/date-picker/locale/ku_KU.ts | 19 - components/date-picker/locale/lt_LT.tsx | 27 + .../locale/{lv_LV.ts => lv_LV.tsx} | 7 +- .../locale/{mk_MK.ts => mk_MK.tsx} | 7 +- .../locale/{mn_MN.ts => mn_MN.tsx} | 7 +- .../locale/{ms_MY.ts => ms_MY.tsx} | 7 +- components/date-picker/locale/nb_NO.ts | 19 - components/date-picker/locale/nb_NO.tsx | 27 + components/date-picker/locale/nl_BE.ts | 19 - components/date-picker/locale/nl_BE.tsx | 27 + components/date-picker/locale/nl_NL.ts | 19 - components/date-picker/locale/nl_NL.tsx | 27 + .../locale/{pl_PL.ts => pl_PL.tsx} | 7 +- components/date-picker/locale/pt_BR.ts | 19 - components/date-picker/locale/pt_BR.tsx | 20 + .../locale/{pt_PT.ts => pt_PT.tsx} | 7 +- .../locale/{ro_RO.ts => ro_RO.tsx} | 7 +- components/date-picker/locale/ru_RU.ts | 22 - components/date-picker/locale/ru_RU.tsx | 29 + .../locale/{sk_SK.ts => sk_SK.tsx} | 7 +- .../locale/{sl_SI.ts => sl_SI.tsx} | 6 +- components/date-picker/locale/sr_RS.ts | 19 - components/date-picker/locale/sr_RS.tsx | 27 + components/date-picker/locale/sv_SE.ts | 18 - components/date-picker/locale/sv_SE.tsx | 27 + .../locale/{ta_IN.ts => ta_IN.tsx} | 7 +- components/date-picker/locale/th_TH.ts | 19 - components/date-picker/locale/th_TH.tsx | 27 + components/date-picker/locale/tr_TR.ts | 19 - components/date-picker/locale/tr_TR.tsx | 28 + .../locale/{uk_UA.ts => uk_UA.tsx} | 8 +- .../locale/{vi_VN.ts => vi_VN.tsx} | 7 +- components/date-picker/locale/zh_CN.ts | 21 - components/date-picker/locale/zh_CN.tsx | 30 + components/date-picker/locale/zh_TW.ts | 20 - components/date-picker/locale/zh_TW.tsx | 29 + components/date-picker/moment.tsx | 47 + components/date-picker/props.ts | 111 -- components/date-picker/style/Calendar.less | 405 ------ components/date-picker/style/DecadePanel.less | 81 -- components/date-picker/style/MonthPanel.less | 86 -- components/date-picker/style/MonthPicker.less | 11 - components/date-picker/style/Picker.less | 113 -- components/date-picker/style/RangePicker.less | 251 ---- components/date-picker/style/TimePicker.less | 151 -- components/date-picker/style/WeekPicker.less | 21 - components/date-picker/style/YearPanel.less | 85 -- components/date-picker/style/index.less | 364 ++++- components/date-picker/style/index.ts | 8 - components/date-picker/style/index.tsx | 5 + components/date-picker/style/panel.less | 681 +++++++++ components/date-picker/style/rtl.less | 252 ++++ components/date-picker/util.ts | 53 + components/date-picker/utils.ts | 16 - components/date-picker/wrapPicker.tsx | 255 ---- components/descriptions/Row.tsx | 6 +- components/drawer/index.tsx | 2 +- components/input/Input.tsx | 2 +- components/input/TextArea.tsx | 2 +- components/locale-provider/LocaleReceiver.tsx | 7 +- components/locale-provider/index.tsx | 48 +- components/locale-provider/ku_KU.ts | 3 - components/locale/ar_EG.ts | 43 - components/locale/ar_EG.tsx | 120 ++ components/locale/az_AZ.tsx | 48 + components/locale/{bg_BG.ts => bg_BG.tsx} | 7 +- components/locale/by_BY.tsx | 128 ++ components/locale/ca_ES.ts | 41 - components/locale/ca_ES.tsx | 128 ++ components/locale/{cs_CZ.ts => cs_CZ.tsx} | 18 +- components/locale/{da_DK.ts => da_DK.tsx} | 5 +- components/locale/de_DE.ts | 43 - components/locale/de_DE.tsx | 124 ++ components/locale/{default.ts => default.tsx} | 9 +- components/locale/{el_GR.ts => el_GR.tsx} | 5 +- components/locale/en_GB.ts | 43 - components/locale/en_GB.tsx | 107 ++ components/locale/{en_US.ts => en_US.tsx} | 0 components/locale/es_ES.ts | 59 - components/locale/es_ES.tsx | 131 ++ components/locale/{et_EE.ts => et_EE.tsx} | 5 +- components/locale/fa_IR.ts | 43 - components/locale/fa_IR.tsx | 134 ++ components/locale/{fi_FI.ts => fi_FI.tsx} | 11 +- components/locale/{fr_BE.ts => fr_BE.tsx} | 5 +- components/locale/fr_CA.tsx | 62 + components/locale/fr_FR.ts | 47 - components/locale/fr_FR.tsx | 131 ++ components/locale/ga_IE.ts | 43 - components/locale/ga_IE.tsx | 127 ++ components/locale/gl_ES.tsx | 114 ++ components/locale/he_IL.ts | 43 - components/locale/he_IL.tsx | 120 ++ components/locale/hi_IN.ts | 51 - components/locale/hi_IN.tsx | 134 ++ components/locale/hr_HR.ts | 57 - components/locale/hr_HR.tsx | 133 ++ components/locale/{hu_HU.ts => hu_HU.tsx} | 5 +- components/locale/{hy_AM.ts => hy_AM.tsx} | 12 +- components/locale/{id_ID.ts => id_ID.tsx} | 5 +- components/locale/{is_IS.ts => is_IS.tsx} | 5 +- components/locale/{it_IT.ts => it_IT.tsx} | 8 +- components/locale/ja_JP.ts | 43 - components/locale/ja_JP.tsx | 106 ++ components/locale/kk_KZ.tsx | 129 ++ components/locale/{ku_IQ.ts => kmr_IQ.tsx} | 15 +- components/locale/{kn_IN.ts => kn_IN.tsx} | 5 +- components/locale/ko_KR.ts | 43 - components/locale/ko_KR.tsx | 100 ++ components/locale/ku_IQ.tsx | 50 + components/locale/ku_KU.ts | 43 - components/locale/lt_LT.tsx | 126 ++ components/locale/{lv_LV.ts => lv_LV.tsx} | 5 +- components/locale/{mk_MK.ts => mk_MK.tsx} | 5 +- components/locale/{mn_MN.ts => mn_MN.tsx} | 5 +- components/locale/{ms_MY.ts => ms_MY.tsx} | 5 +- components/locale/nb_NO.ts | 43 - components/locale/nb_NO.tsx | 128 ++ components/locale/{ne_NP.ts => ne_NP.tsx} | 5 +- components/locale/nl_BE.ts | 43 - components/locale/nl_BE.tsx | 134 ++ components/locale/nl_NL.ts | 62 - components/locale/nl_NL.tsx | 134 ++ components/locale/{pl_PL.ts => pl_PL.tsx} | 8 +- components/locale/pt_BR.ts | 49 - components/locale/pt_BR.tsx | 134 ++ components/locale/{pt_PT.ts => pt_PT.tsx} | 5 +- components/locale/ro_RO.ts | 62 - components/locale/ro_RO.tsx | 134 ++ components/locale/ru_RU.ts | 53 - components/locale/ru_RU.tsx | 132 ++ components/locale/{sk_SK.ts => sk_SK.tsx} | 5 +- components/locale/{sl_SI.ts => sl_SI.tsx} | 5 +- components/locale/sr_RS.ts | 43 - components/locale/sr_RS.tsx | 134 ++ components/locale/sv_SE.ts | 47 - components/locale/sv_SE.tsx | 134 ++ components/locale/{ta_IN.ts => ta_IN.tsx} | 5 +- components/locale/th_TH.ts | 62 - components/locale/th_TH.tsx | 130 ++ components/locale/tr_TR.ts | 57 - components/locale/tr_TR.tsx | 129 ++ components/locale/{uk_UA.ts => uk_UA.tsx} | 9 +- components/locale/{vi_VN.ts => vi_VN.tsx} | 5 +- components/locale/zh_CN.ts | 64 - components/locale/zh_CN.tsx | 133 ++ components/locale/zh_HK.tsx | 125 ++ components/locale/zh_TW.ts | 51 - components/locale/zh_TW.tsx | 125 ++ components/menu/src/MenuItem.tsx | 11 +- components/menu/src/SubMenu.tsx | 17 +- components/modal/Modal.tsx | 4 +- components/modal/__tests__/Modal.test.js | 13 + .../__snapshots__/Modal.test.js.snap | 23 + components/pagination/Pagination.tsx | 1 + components/rate/index.tsx | 1 - components/select/index.tsx | 11 +- components/style/themes/default.less | 27 +- components/table/filterDropdown.tsx | 2 +- components/time-picker/date-fns.tsx | 30 + components/time-picker/dayjs.tsx | 31 + components/time-picker/index.tsx | 275 +--- components/time-picker/locale/ar_EG.ts | 5 - components/time-picker/locale/ar_EG.tsx | 7 + components/time-picker/locale/az_AZ.tsx | 7 + components/time-picker/locale/bg_BG.ts | 5 - components/time-picker/locale/bg_BG.tsx | 7 + components/time-picker/locale/by_BY.tsx | 8 + components/time-picker/locale/ca_ES.ts | 5 - components/time-picker/locale/ca_ES.tsx | 7 + components/time-picker/locale/cs_CZ.ts | 5 - components/time-picker/locale/cs_CZ.tsx | 7 + components/time-picker/locale/da_DK.ts | 5 - components/time-picker/locale/da_DK.tsx | 8 + components/time-picker/locale/de_DE.ts | 5 - components/time-picker/locale/de_DE.tsx | 7 + components/time-picker/locale/el_GR.ts | 5 - components/time-picker/locale/el_GR.tsx | 7 + components/time-picker/locale/en_GB.ts | 5 - components/time-picker/locale/en_GB.tsx | 7 + components/time-picker/locale/en_US.ts | 5 - components/time-picker/locale/en_US.tsx | 8 + components/time-picker/locale/es_ES.ts | 5 - components/time-picker/locale/es_ES.tsx | 7 + components/time-picker/locale/et_EE.ts | 5 - components/time-picker/locale/et_EE.tsx | 7 + components/time-picker/locale/fa_IR.ts | 5 - components/time-picker/locale/fa_IR.tsx | 8 + components/time-picker/locale/fi_FI.ts | 5 - components/time-picker/locale/fi_FI.tsx | 7 + components/time-picker/locale/fr_BE.ts | 5 - components/time-picker/locale/fr_BE.tsx | 7 + components/time-picker/locale/fr_CA.tsx | 8 + components/time-picker/locale/fr_FR.ts | 5 - components/time-picker/locale/fr_FR.tsx | 8 + components/time-picker/locale/ga_IE.ts | 5 - components/time-picker/locale/ga_IE.tsx | 8 + components/time-picker/locale/gl_ES.tsx | 7 + components/time-picker/locale/he_IL.ts | 5 - components/time-picker/locale/he_IL.tsx | 7 + components/time-picker/locale/hi_IN.ts | 5 - components/time-picker/locale/hi_IN.tsx | 8 + components/time-picker/locale/hr_HR.ts | 5 - components/time-picker/locale/hr_HR.tsx | 8 + components/time-picker/locale/hu_HU.ts | 5 - components/time-picker/locale/hu_HU.tsx | 7 + components/time-picker/locale/id_ID.ts | 5 - components/time-picker/locale/id_ID.tsx | 7 + components/time-picker/locale/is_IS.ts | 5 - components/time-picker/locale/is_IS.tsx | 7 + components/time-picker/locale/it_IT.ts | 5 - components/time-picker/locale/it_IT.tsx | 7 + components/time-picker/locale/ja_JP.ts | 5 - components/time-picker/locale/ja_JP.tsx | 8 + components/time-picker/locale/kk_KZ.tsx | 8 + components/time-picker/locale/kmr_IQ.tsx | 7 + components/time-picker/locale/kn_IN.ts | 5 - components/time-picker/locale/kn_IN.tsx | 7 + components/time-picker/locale/ko_KR.ts | 5 - components/time-picker/locale/ko_KR.tsx | 8 + components/time-picker/locale/ku_IQ.ts | 5 - components/time-picker/locale/ku_KU.ts | 5 - components/time-picker/locale/lt_LT.tsx | 8 + components/time-picker/locale/lv_LV.ts | 5 - components/time-picker/locale/lv_LV.tsx | 7 + components/time-picker/locale/mk_MK.ts | 5 - components/time-picker/locale/mk_MK.tsx | 7 + components/time-picker/locale/mn_MN.ts | 5 - components/time-picker/locale/mn_MN.tsx | 7 + components/time-picker/locale/ms_MY.ts | 5 - components/time-picker/locale/ms_MY.tsx | 7 + components/time-picker/locale/nb_NO.ts | 5 - components/time-picker/locale/nb_NO.tsx | 8 + components/time-picker/locale/nl_BE.ts | 5 - components/time-picker/locale/nl_BE.tsx | 8 + components/time-picker/locale/nl_NL.ts | 5 - components/time-picker/locale/nl_NL.tsx | 8 + components/time-picker/locale/pl_PL.ts | 5 - components/time-picker/locale/pl_PL.tsx | 7 + components/time-picker/locale/pt_BR.ts | 5 - components/time-picker/locale/pt_BR.tsx | 7 + components/time-picker/locale/pt_PT.ts | 5 - components/time-picker/locale/pt_PT.tsx | 7 + components/time-picker/locale/ro_RO.ts | 5 - components/time-picker/locale/ro_RO.tsx | 7 + components/time-picker/locale/ru_RU.ts | 8 - components/time-picker/locale/ru_RU.tsx | 9 + components/time-picker/locale/sk_SK.ts | 5 - components/time-picker/locale/sk_SK.tsx | 7 + components/time-picker/locale/sl_SI.ts | 5 - components/time-picker/locale/sl_SI.tsx | 7 + components/time-picker/locale/sr_RS.ts | 5 - components/time-picker/locale/sr_RS.tsx | 8 + components/time-picker/locale/sv_SE.ts | 5 - components/time-picker/locale/sv_SE.tsx | 7 + .../locale/{ta_IN.ts => ta_IN.tsx} | 4 +- components/time-picker/locale/th_TH.ts | 5 - components/time-picker/locale/th_TH.tsx | 7 + components/time-picker/locale/tr_TR.ts | 5 - components/time-picker/locale/tr_TR.tsx | 8 + components/time-picker/locale/uk_UA.ts | 5 - components/time-picker/locale/uk_UA.tsx | 7 + components/time-picker/locale/vi_VN.ts | 5 - components/time-picker/locale/vi_VN.tsx | 7 + components/time-picker/locale/zh_CN.ts | 5 - components/time-picker/locale/zh_CN.tsx | 8 + components/time-picker/locale/zh_TW.ts | 5 - components/time-picker/locale/zh_TW.tsx | 7 + components/time-picker/moment.tsx | 31 + components/time-picker/style/index.less | 244 ---- components/time-picker/style/index.ts | 2 - components/time-picker/style/index.tsx | 5 + components/time-picker/time-picker.tsx | 203 +++ components/upload/UploadList.tsx | 2 +- components/vc-align/Align.tsx | 49 +- components/vc-align/Align1.tsx | 196 +++ components/vc-align/util.ts | 1 + .../vc-calendar/assets/common/Calendar.less | 106 -- .../assets/common/FullCalendar.less | 91 -- .../vc-calendar/assets/common/Picker.less | 10 - .../assets/common/RangeCalendar.less | 131 -- .../vc-calendar/assets/common/index.less | 16 - components/vc-calendar/assets/index.less | 10 - .../vc-calendar/assets/index/Calendar.less | 301 ---- .../vc-calendar/assets/index/DecadePanel.less | 122 -- .../vc-calendar/assets/index/Input.less | 23 - .../vc-calendar/assets/index/MonthPanel.less | 143 -- .../vc-calendar/assets/index/Picker.less | 110 -- components/vc-calendar/assets/index/Time.less | 6 - .../vc-calendar/assets/index/TimePanel.less | 72 - .../vc-calendar/assets/index/YearPanel.less | 136 -- components/vc-calendar/index.js | 4 - components/vc-calendar/src/Calendar.jsx | 388 ------ components/vc-calendar/src/FullCalendar.jsx | 164 --- components/vc-calendar/src/MonthCalendar.jsx | 126 -- components/vc-calendar/src/Picker.jsx | 245 ---- components/vc-calendar/src/RangeCalendar.jsx | 837 ----------- .../src/calendar/CalendarFooter.jsx | 86 -- .../src/calendar/CalendarHeader.jsx | 243 ---- .../vc-calendar/src/calendar/OkButton.jsx | 16 - .../src/calendar/TimePickerButton.jsx | 27 - .../vc-calendar/src/calendar/TodayButton.jsx | 23 - .../vc-calendar/src/date/DateConstants.js | 4 - components/vc-calendar/src/date/DateInput.jsx | 226 --- components/vc-calendar/src/date/DateTBody.jsx | 258 ---- components/vc-calendar/src/date/DateTHead.jsx | 46 - components/vc-calendar/src/date/DateTable.jsx | 16 - .../vc-calendar/src/decade/DecadePanel.jsx | 133 -- .../src/full-calendar/CalendarHeader.jsx | 135 -- components/vc-calendar/src/index.js | 3 - components/vc-calendar/src/locale/ku_KU.js | 27 - .../vc-calendar/src/mixin/CalendarMixin.js | 129 -- .../vc-calendar/src/mixin/CommonMixin.js | 29 - .../vc-calendar/src/month/MonthPanel.jsx | 114 -- .../vc-calendar/src/month/MonthTable.jsx | 133 -- .../vc-calendar/src/picker/placements.js | 35 - .../src/range-calendar/CalendarPart.jsx | 160 --- components/vc-calendar/src/util/index.js | 113 -- components/vc-calendar/src/util/toTime.js | 15 - components/vc-calendar/src/year/YearPanel.jsx | 153 -- components/vc-dialog/DialogWrap.jsx | 8 +- components/vc-mentions/src/Mentions.tsx | 2 +- components/vc-pagination/locale/bn_BD.js | 15 + components/vc-pagination/locale/by_BY.js | 14 + components/vc-pagination/locale/fr_CA.js | 15 + components/vc-pagination/locale/gl_ES.tsx | 15 + components/vc-pagination/locale/ja_JP.js | 2 +- components/vc-pagination/locale/ka_GE.js | 14 + components/vc-pagination/locale/kk_KZ.js | 15 + components/vc-pagination/locale/km_KH.js | 15 + .../locale/{ku_IQ.js => kmr_IQ.js} | 0 components/vc-pagination/locale/ku_KU.js | 15 - components/vc-pagination/locale/lt_LT.js | 15 + components/vc-pagination/locale/ml_IN.js | 15 + components/vc-pagination/locale/pl_PL.js | 4 +- components/vc-pagination/locale/ur_PK.js | 15 + components/vc-picker/PanelContext.tsx | 38 + components/vc-picker/Picker.tsx | 592 ++++++++ components/vc-picker/PickerPanel.tsx | 613 ++++++++ components/vc-picker/PickerTrigger.tsx | 103 ++ components/vc-picker/RangeContext.tsx | 74 + components/vc-picker/RangePicker.tsx | 1227 +++++++++++++++++ components/vc-picker/generate/dateFns.ts | 138 ++ components/vc-picker/generate/dayjs.ts | 137 ++ components/vc-picker/generate/index.ts | 52 + components/vc-picker/generate/moment.ts | 158 +++ .../vc-picker/hooks/useCellClassName.ts | 97 ++ components/vc-picker/hooks/useHoverValue.ts | 45 + components/vc-picker/hooks/useMergeProps.ts | 8 + components/vc-picker/hooks/usePickerInput.ts | 183 +++ .../vc-picker/hooks/useRangeDisabled.ts | 114 ++ .../vc-picker/hooks/useRangeViewDates.ts | 134 ++ .../vc-picker/hooks/useTextValueMapping.ts | 37 + components/vc-picker/hooks/useValueTexts.ts | 51 + components/vc-picker/index.tsx | 7 + components/vc-picker/interface.ts | 111 ++ .../ar_EG.js => vc-picker/locale/ar_EG.ts} | 7 +- components/vc-picker/locale/az_AZ.ts | 33 + .../bg_BG.js => vc-picker/locale/bg_BG.ts} | 6 +- components/vc-picker/locale/by_BY.ts | 33 + .../ca_ES.js => vc-picker/locale/ca_ES.ts} | 7 +- .../cs_CZ.js => vc-picker/locale/cs_CZ.ts} | 7 +- .../da_DK.js => vc-picker/locale/da_DK.ts} | 17 +- .../de_DE.js => vc-picker/locale/de_DE.ts} | 7 +- .../el_GR.js => vc-picker/locale/el_GR.ts} | 7 +- .../en_GB.js => vc-picker/locale/en_GB.ts} | 7 +- .../en_US.js => vc-picker/locale/en_US.ts} | 7 +- .../es_ES.js => vc-picker/locale/es_ES.ts} | 7 +- .../et_EE.js => vc-picker/locale/et_EE.ts} | 7 +- .../fa_IR.js => vc-picker/locale/fa_IR.ts} | 7 +- .../fi_FI.js => vc-picker/locale/fi_FI.ts} | 7 +- .../fr_BE.js => vc-picker/locale/fr_BE.ts} | 7 +- .../fr_FR.js => vc-picker/locale/fr_CA.ts} | 7 +- components/vc-picker/locale/fr_FR.ts | 32 + .../ga_IE.js => vc-picker/locale/ga_IE.ts} | 7 +- components/vc-picker/locale/gl_ES.ts | 32 + .../he_IL.js => vc-picker/locale/he_IL.ts} | 7 +- .../hi_IN.js => vc-picker/locale/hi_IN.ts} | 7 +- .../hr_HR.js => vc-picker/locale/hr_HR.ts} | 7 +- .../hu_HU.js => vc-picker/locale/hu_HU.ts} | 7 +- .../id_ID.js => vc-picker/locale/id_ID.ts} | 7 +- .../is_IS.js => vc-picker/locale/is_IS.ts} | 7 +- .../it_IT.js => vc-picker/locale/it_IT.ts} | 7 +- .../ja_JP.js => vc-picker/locale/ja_JP.ts} | 8 +- components/vc-picker/locale/kk_KZ.ts | 32 + components/vc-picker/locale/km_KH.ts | 32 + .../ku_IQ.js => vc-picker/locale/kmr_IQ.ts} | 7 +- .../kn_IN.js => vc-picker/locale/kn_IN.ts} | 7 +- .../ko_KR.js => vc-picker/locale/ko_KR.ts} | 7 +- components/vc-picker/locale/lt_LT.ts | 32 + .../lv_LV.js => vc-picker/locale/lv_LV.ts} | 7 +- .../mk_MK.js => vc-picker/locale/mk_MK.ts} | 7 +- components/vc-picker/locale/ml_IN.ts | 33 + .../mm_MM.js => vc-picker/locale/mm_MM.ts} | 7 +- .../mn_MN.js => vc-picker/locale/mn_MN.ts} | 7 +- .../ms_MY.js => vc-picker/locale/ms_MY.ts} | 7 +- .../nb_NO.js => vc-picker/locale/nb_NO.ts} | 16 +- .../nl_BE.js => vc-picker/locale/nl_BE.ts} | 7 +- .../nl_NL.js => vc-picker/locale/nl_NL.ts} | 7 +- .../pl_PL.js => vc-picker/locale/pl_PL.ts} | 7 +- .../pt_BR.js => vc-picker/locale/pt_BR.ts} | 11 +- .../pt_PT.js => vc-picker/locale/pt_PT.ts} | 7 +- .../ro_RO.js => vc-picker/locale/ro_RO.ts} | 7 +- .../ru_RU.js => vc-picker/locale/ru_RU.ts} | 9 +- .../sk_SK.js => vc-picker/locale/sk_SK.ts} | 8 +- .../sl_SI.js => vc-picker/locale/sl_SI.ts} | 7 +- .../sr_RS.js => vc-picker/locale/sr_RS.ts} | 7 +- .../sv_SE.js => vc-picker/locale/sv_SE.ts} | 7 +- .../ta_IN.js => vc-picker/locale/ta_IN.ts} | 7 +- .../th_TH.js => vc-picker/locale/th_TH.ts} | 7 +- .../tr_TR.js => vc-picker/locale/tr_TR.ts} | 7 +- .../ug_CN.js => vc-picker/locale/ug_CN.ts} | 7 +- .../uk_UA.js => vc-picker/locale/uk_UA.ts} | 7 +- .../vi_VN.js => vc-picker/locale/vi_VN.ts} | 7 +- .../zh_CN.js => vc-picker/locale/zh_CN.ts} | 7 +- .../zh_TW.js => vc-picker/locale/zh_TW.ts} | 9 +- .../vc-picker/panels/DatePanel/DateBody.tsx | 119 ++ .../vc-picker/panels/DatePanel/DateHeader.tsx | 106 ++ .../vc-picker/panels/DatePanel/index.tsx | 117 ++ .../vc-picker/panels/DatetimePanel/index.tsx | 165 +++ .../panels/DecadePanel/DecadeBody.tsx | 68 + .../panels/DecadePanel/DecadeHeader.tsx | 45 + .../vc-picker/panels/DecadePanel/index.tsx | 80 ++ components/vc-picker/panels/Header.tsx | 100 ++ .../vc-picker/panels/MonthPanel/MonthBody.tsx | 89 ++ .../panels/MonthPanel/MonthHeader.tsx | 51 + .../vc-picker/panels/MonthPanel/index.tsx | 83 ++ components/vc-picker/panels/PanelBody.tsx | 145 ++ .../panels/QuarterPanel/QuarterBody.tsx | 71 + .../panels/QuarterPanel/QuarterHeader.tsx | 50 + .../vc-picker/panels/QuarterPanel/index.tsx | 76 + .../vc-picker/panels/TimePanel/TimeBody.tsx | 285 ++++ .../vc-picker/panels/TimePanel/TimeHeader.tsx | 42 + .../panels/TimePanel/TimeUnitColumn.tsx | 104 ++ .../vc-picker/panels/TimePanel/index.tsx | 99 ++ .../vc-picker/panels/WeekPanel/index.tsx | 44 + .../vc-picker/panels/YearPanel/YearBody.tsx | 78 ++ .../vc-picker/panels/YearPanel/YearHeader.tsx | 49 + .../vc-picker/panels/YearPanel/index.tsx | 85 ++ components/vc-picker/utils/dateUtil.ts | 321 +++++ components/vc-picker/utils/getExtraFooter.tsx | 13 + components/vc-picker/utils/getRanges.tsx | 78 ++ components/vc-picker/utils/miscUtil.ts | 58 + components/vc-picker/utils/timeUtil.ts | 60 + components/vc-picker/utils/uiUtil.ts | 276 ++++ components/vc-resize-observer/index.tsx | 7 +- components/vc-select/OptionList.tsx | 38 +- components/vc-select/Select.tsx | 1 + components/vc-select/SelectTrigger.tsx | 3 +- components/vc-select/Selector/Input.tsx | 2 +- .../vc-select/Selector/MultipleSelector.tsx | 18 +- .../vc-select/Selector/SingleSelector.tsx | 2 +- components/vc-select/Selector/index.tsx | 121 +- components/vc-select/Selector/interface.ts | 27 + components/vc-select/generate.tsx | 5 +- components/vc-select/utils/legacyUtil.ts | 7 +- components/vc-slick/src/inner-slider.js | 1 + components/vc-table/src/BaseTable.jsx | 7 +- components/vc-table/src/BodyTable.jsx | 59 +- components/vc-table/src/Table.jsx | 31 +- components/vc-table/src/TableHeader.jsx | 9 +- .../vc-tabs/src/ScrollableTabBarNode.jsx | 1 + components/vc-time-picker/Combobox.jsx | 215 --- components/vc-time-picker/Header.jsx | 185 --- components/vc-time-picker/Panel.jsx | 229 --- components/vc-time-picker/Select.jsx | 142 -- components/vc-time-picker/TimePicker.jsx | 394 ------ components/vc-time-picker/assets/index.less | 44 - .../vc-time-picker/assets/index/Header.less | 22 - .../vc-time-picker/assets/index/Panel.less | 29 - .../vc-time-picker/assets/index/Picker.less | 25 - .../vc-time-picker/assets/index/Select.less | 62 - components/vc-time-picker/index.js | 2 - components/vc-time-picker/placements.js | 35 - components/vc-tooltip/src/Tooltip.tsx | 2 +- components/vc-trigger/LazyRenderBox.jsx | 27 - components/vc-trigger/Popup.jsx | 317 ----- components/vc-trigger/Popup/Mask.tsx | 39 + .../vc-trigger/Popup/MobilePopupInner.tsx | 58 + components/vc-trigger/Popup/PopupInner.tsx | 195 +++ components/vc-trigger/Popup/index.tsx | 54 + components/vc-trigger/Popup/interface.ts | 55 + .../vc-trigger/Popup/useStretchStyle.ts | 41 + .../vc-trigger/Popup/useVisibleStatus.ts | 96 ++ components/vc-trigger/PopupInner.jsx | 21 - .../vc-trigger/{Trigger.jsx => Trigger.tsx} | 236 ++-- components/vc-trigger/index.md | 160 --- components/vc-trigger/{index.js => index.ts} | 2 +- components/vc-trigger/interface.ts | 72 + components/vc-trigger/utils.js | 31 - components/vc-trigger/utils/alignUtil.ts | 40 + components/vc-trigger/utils/motionUtil.ts | 23 + components/vc-util/Dom/contains.ts | 2 +- examples/App.vue | 84 +- package.json | 8 +- tests/shared/demoTest.js | 4 +- tests/utils.js | 4 +- tsconfig.json | 16 +- v2-doc | 2 +- webpack.build.conf.js | 93 +- 691 files changed, 18032 insertions(+), 13914 deletions(-) create mode 100644 components/_util/EventInterface.ts create mode 100644 components/_util/hooks/useMergedState.ts create mode 100644 components/_util/hooks/useState.ts delete mode 100644 components/_util/interopDefault.js delete mode 100644 components/_util/moment-util.js delete mode 100644 components/auto-complete/InputElement.tsx create mode 100644 components/calendar/date-fns.tsx create mode 100644 components/calendar/dayjs.tsx create mode 100644 components/calendar/generateCalendar.tsx delete mode 100644 components/calendar/locale/ar_EG.ts create mode 100644 components/calendar/locale/ar_EG.tsx create mode 100644 components/calendar/locale/az_AZ.tsx delete mode 100644 components/calendar/locale/bg_BG.ts create mode 100644 components/calendar/locale/bg_BG.tsx create mode 100644 components/calendar/locale/by_BY.tsx delete mode 100644 components/calendar/locale/ca_ES.ts create mode 100644 components/calendar/locale/ca_ES.tsx delete mode 100644 components/calendar/locale/cs_CZ.ts create mode 100644 components/calendar/locale/cs_CZ.tsx delete mode 100644 components/calendar/locale/da_DK.ts create mode 100644 components/calendar/locale/da_DK.tsx delete mode 100644 components/calendar/locale/de_DE.ts create mode 100644 components/calendar/locale/de_DE.tsx delete mode 100644 components/calendar/locale/el_GR.ts create mode 100644 components/calendar/locale/el_GR.tsx delete mode 100644 components/calendar/locale/en_GB.ts create mode 100644 components/calendar/locale/en_GB.tsx delete mode 100644 components/calendar/locale/en_US.ts create mode 100644 components/calendar/locale/en_US.tsx delete mode 100644 components/calendar/locale/es_ES.ts create mode 100644 components/calendar/locale/es_ES.tsx delete mode 100644 components/calendar/locale/et_EE.ts create mode 100644 components/calendar/locale/et_EE.tsx delete mode 100644 components/calendar/locale/fa_IR.ts create mode 100644 components/calendar/locale/fa_IR.tsx delete mode 100644 components/calendar/locale/fi_FI.ts create mode 100644 components/calendar/locale/fi_FI.tsx delete mode 100644 components/calendar/locale/fr_BE.ts create mode 100644 components/calendar/locale/fr_BE.tsx create mode 100644 components/calendar/locale/fr_CA.tsx delete mode 100644 components/calendar/locale/fr_FR.ts create mode 100644 components/calendar/locale/fr_FR.tsx delete mode 100644 components/calendar/locale/ga_IE.ts create mode 100644 components/calendar/locale/ga_IE.tsx create mode 100644 components/calendar/locale/gl_ES.tsx delete mode 100644 components/calendar/locale/he_IL.ts create mode 100644 components/calendar/locale/he_IL.tsx delete mode 100644 components/calendar/locale/hi_IN.ts create mode 100644 components/calendar/locale/hi_IN.tsx delete mode 100644 components/calendar/locale/hr_HR.ts create mode 100644 components/calendar/locale/hr_HR.tsx delete mode 100644 components/calendar/locale/hu_HU.ts create mode 100644 components/calendar/locale/hu_HU.tsx delete mode 100644 components/calendar/locale/id_ID.ts create mode 100644 components/calendar/locale/id_ID.tsx delete mode 100644 components/calendar/locale/is_IS.ts create mode 100644 components/calendar/locale/is_IS.tsx delete mode 100644 components/calendar/locale/it_IT.ts create mode 100644 components/calendar/locale/it_IT.tsx delete mode 100644 components/calendar/locale/ja_JP.ts create mode 100644 components/calendar/locale/ja_JP.tsx create mode 100644 components/calendar/locale/kk_KZ.tsx create mode 100755 components/calendar/locale/kmr_IQ.tsx delete mode 100644 components/calendar/locale/kn_IN.ts create mode 100644 components/calendar/locale/kn_IN.tsx delete mode 100644 components/calendar/locale/ko_KR.ts create mode 100644 components/calendar/locale/ko_KR.tsx delete mode 100755 components/calendar/locale/ku_IQ.ts delete mode 100644 components/calendar/locale/ku_KU.ts create mode 100644 components/calendar/locale/lt_LT.tsx delete mode 100644 components/calendar/locale/lv_LV.ts create mode 100644 components/calendar/locale/lv_LV.tsx delete mode 100644 components/calendar/locale/mk_MK.ts create mode 100644 components/calendar/locale/mk_MK.tsx delete mode 100644 components/calendar/locale/mn_MN.ts create mode 100644 components/calendar/locale/mn_MN.tsx delete mode 100644 components/calendar/locale/ms_MY.ts create mode 100644 components/calendar/locale/ms_MY.tsx delete mode 100644 components/calendar/locale/nb_NO.ts create mode 100644 components/calendar/locale/nb_NO.tsx delete mode 100644 components/calendar/locale/nl_BE.ts create mode 100644 components/calendar/locale/nl_BE.tsx delete mode 100644 components/calendar/locale/nl_NL.ts create mode 100644 components/calendar/locale/nl_NL.tsx delete mode 100644 components/calendar/locale/pl_PL.ts create mode 100644 components/calendar/locale/pl_PL.tsx delete mode 100644 components/calendar/locale/pt_BR.ts create mode 100644 components/calendar/locale/pt_BR.tsx delete mode 100644 components/calendar/locale/pt_PT.ts create mode 100644 components/calendar/locale/pt_PT.tsx delete mode 100644 components/calendar/locale/ro_RO.ts create mode 100644 components/calendar/locale/ro_RO.tsx delete mode 100644 components/calendar/locale/ru_RU.ts create mode 100644 components/calendar/locale/ru_RU.tsx delete mode 100644 components/calendar/locale/sk_SK.ts create mode 100644 components/calendar/locale/sk_SK.tsx delete mode 100644 components/calendar/locale/sl_SI.ts create mode 100644 components/calendar/locale/sl_SI.tsx delete mode 100644 components/calendar/locale/sr_RS.ts create mode 100644 components/calendar/locale/sr_RS.tsx delete mode 100644 components/calendar/locale/sv_SE.ts create mode 100644 components/calendar/locale/sv_SE.tsx delete mode 100644 components/calendar/locale/ta_IN.ts create mode 100644 components/calendar/locale/ta_IN.tsx delete mode 100644 components/calendar/locale/th_TH.ts create mode 100644 components/calendar/locale/th_TH.tsx delete mode 100644 components/calendar/locale/tr_TR.ts create mode 100644 components/calendar/locale/tr_TR.tsx delete mode 100644 components/calendar/locale/uk_UA.ts create mode 100644 components/calendar/locale/uk_UA.tsx delete mode 100644 components/calendar/locale/vi_VN.ts create mode 100644 components/calendar/locale/vi_VN.tsx delete mode 100644 components/calendar/locale/zh_CN.ts create mode 100644 components/calendar/locale/zh_CN.tsx delete mode 100644 components/calendar/locale/zh_TW.ts create mode 100644 components/calendar/locale/zh_TW.tsx create mode 100644 components/calendar/moment.tsx rename components/calendar/style/{index.ts => index.tsx} (67%) create mode 100644 components/calendar/style/rtl.less delete mode 100644 components/date-picker/InputIcon.tsx create mode 100644 components/date-picker/PickerButton.tsx create mode 100644 components/date-picker/PickerTag.tsx delete mode 100644 components/date-picker/RangePicker.tsx delete mode 100644 components/date-picker/WeekPicker.tsx delete mode 100644 components/date-picker/createPicker.tsx create mode 100755 components/date-picker/date-fns.tsx create mode 100755 components/date-picker/dayjs.tsx create mode 100644 components/date-picker/generatePicker/generateRangePicker.tsx create mode 100644 components/date-picker/generatePicker/generateSinglePicker.tsx create mode 100644 components/date-picker/generatePicker/index.tsx create mode 100644 components/date-picker/generatePicker/props.ts delete mode 100755 components/date-picker/index.ts create mode 100755 components/date-picker/index.tsx delete mode 100644 components/date-picker/interface.tsx rename components/date-picker/locale/{ar_EG.ts => ar_EG.tsx} (65%) create mode 100644 components/date-picker/locale/az_AZ.tsx rename components/date-picker/locale/{bg_BG.ts => bg_BG.tsx} (57%) create mode 100644 components/date-picker/locale/by_BY.tsx rename components/date-picker/locale/{ca_ES.ts => ca_ES.tsx} (56%) rename components/date-picker/locale/{cs_CZ.ts => cs_CZ.tsx} (55%) rename components/date-picker/locale/{da_DK.ts => da_DK.tsx} (56%) rename components/date-picker/locale/{de_DE.ts => de_DE.tsx} (72%) rename components/date-picker/locale/{el_GR.ts => el_GR.tsx} (75%) delete mode 100644 components/date-picker/locale/en_GB.ts create mode 100644 components/date-picker/locale/en_GB.tsx delete mode 100644 components/date-picker/locale/en_US.ts create mode 100644 components/date-picker/locale/en_US.tsx rename components/date-picker/locale/{es_ES.ts => es_ES.tsx} (57%) rename components/date-picker/locale/{et_EE.ts => et_EE.tsx} (57%) delete mode 100644 components/date-picker/locale/fa_IR.ts create mode 100644 components/date-picker/locale/fa_IR.tsx delete mode 100644 components/date-picker/locale/fi_FI.ts create mode 100644 components/date-picker/locale/fi_FI.tsx rename components/date-picker/locale/{fr_BE.ts => fr_BE.tsx} (72%) create mode 100644 components/date-picker/locale/fr_CA.tsx delete mode 100644 components/date-picker/locale/fr_FR.ts create mode 100644 components/date-picker/locale/fr_FR.tsx delete mode 100644 components/date-picker/locale/ga_IE.ts create mode 100644 components/date-picker/locale/ga_IE.tsx create mode 100644 components/date-picker/locale/gl_ES.tsx rename components/date-picker/locale/{he_IL.ts => he_IL.tsx} (58%) delete mode 100644 components/date-picker/locale/hi_IN.ts create mode 100644 components/date-picker/locale/hi_IN.tsx delete mode 100644 components/date-picker/locale/hr_HR.ts create mode 100644 components/date-picker/locale/hr_HR.tsx rename components/date-picker/locale/{hu_HU.ts => hu_HU.tsx} (57%) rename components/date-picker/locale/{id_ID.ts => id_ID.tsx} (57%) rename components/date-picker/locale/{is_IS.ts => is_IS.tsx} (56%) rename components/date-picker/locale/{it_IT.ts => it_IT.tsx} (72%) rename components/date-picker/locale/{ja_JP.ts => ja_JP.tsx} (51%) create mode 100644 components/date-picker/locale/kk_KZ.tsx create mode 100755 components/date-picker/locale/kmr_IQ.tsx rename components/date-picker/locale/{kn_IN.ts => kn_IN.tsx} (62%) rename components/date-picker/locale/{ko_KR.ts => ko_KR.tsx} (56%) delete mode 100755 components/date-picker/locale/ku_IQ.ts delete mode 100644 components/date-picker/locale/ku_KU.ts create mode 100644 components/date-picker/locale/lt_LT.tsx rename components/date-picker/locale/{lv_LV.ts => lv_LV.tsx} (57%) rename components/date-picker/locale/{mk_MK.ts => mk_MK.tsx} (58%) rename components/date-picker/locale/{mn_MN.ts => mn_MN.tsx} (59%) rename components/date-picker/locale/{ms_MY.ts => ms_MY.tsx} (56%) delete mode 100644 components/date-picker/locale/nb_NO.ts create mode 100644 components/date-picker/locale/nb_NO.tsx delete mode 100644 components/date-picker/locale/nl_BE.ts create mode 100644 components/date-picker/locale/nl_BE.tsx delete mode 100644 components/date-picker/locale/nl_NL.ts create mode 100644 components/date-picker/locale/nl_NL.tsx rename components/date-picker/locale/{pl_PL.ts => pl_PL.tsx} (57%) delete mode 100644 components/date-picker/locale/pt_BR.ts create mode 100644 components/date-picker/locale/pt_BR.tsx rename components/date-picker/locale/{pt_PT.ts => pt_PT.tsx} (82%) rename components/date-picker/locale/{ro_RO.ts => ro_RO.tsx} (57%) delete mode 100644 components/date-picker/locale/ru_RU.ts create mode 100644 components/date-picker/locale/ru_RU.tsx rename components/date-picker/locale/{sk_SK.ts => sk_SK.tsx} (55%) rename components/date-picker/locale/{sl_SI.ts => sl_SI.tsx} (85%) delete mode 100644 components/date-picker/locale/sr_RS.ts create mode 100644 components/date-picker/locale/sr_RS.tsx delete mode 100644 components/date-picker/locale/sv_SE.ts create mode 100644 components/date-picker/locale/sv_SE.tsx rename components/date-picker/locale/{ta_IN.ts => ta_IN.tsx} (65%) delete mode 100644 components/date-picker/locale/th_TH.ts create mode 100644 components/date-picker/locale/th_TH.tsx delete mode 100644 components/date-picker/locale/tr_TR.ts create mode 100644 components/date-picker/locale/tr_TR.tsx rename components/date-picker/locale/{uk_UA.ts => uk_UA.tsx} (54%) rename components/date-picker/locale/{vi_VN.ts => vi_VN.tsx} (58%) delete mode 100644 components/date-picker/locale/zh_CN.ts create mode 100644 components/date-picker/locale/zh_CN.tsx delete mode 100644 components/date-picker/locale/zh_TW.ts create mode 100644 components/date-picker/locale/zh_TW.tsx create mode 100755 components/date-picker/moment.tsx delete mode 100644 components/date-picker/props.ts delete mode 100644 components/date-picker/style/Calendar.less delete mode 100644 components/date-picker/style/DecadePanel.less delete mode 100644 components/date-picker/style/MonthPanel.less delete mode 100644 components/date-picker/style/MonthPicker.less delete mode 100644 components/date-picker/style/Picker.less delete mode 100644 components/date-picker/style/RangePicker.less delete mode 100644 components/date-picker/style/TimePicker.less delete mode 100644 components/date-picker/style/WeekPicker.less delete mode 100644 components/date-picker/style/YearPanel.less delete mode 100644 components/date-picker/style/index.ts create mode 100644 components/date-picker/style/index.tsx create mode 100644 components/date-picker/style/panel.less create mode 100644 components/date-picker/style/rtl.less create mode 100644 components/date-picker/util.ts delete mode 100644 components/date-picker/utils.ts delete mode 100644 components/date-picker/wrapPicker.tsx delete mode 100644 components/locale-provider/ku_KU.ts delete mode 100644 components/locale/ar_EG.ts create mode 100644 components/locale/ar_EG.tsx create mode 100644 components/locale/az_AZ.tsx rename components/locale/{bg_BG.ts => bg_BG.tsx} (87%) create mode 100644 components/locale/by_BY.tsx delete mode 100644 components/locale/ca_ES.ts create mode 100644 components/locale/ca_ES.tsx rename components/locale/{cs_CZ.ts => cs_CZ.tsx} (59%) rename components/locale/{da_DK.ts => da_DK.tsx} (89%) delete mode 100644 components/locale/de_DE.ts create mode 100644 components/locale/de_DE.tsx rename components/locale/{default.ts => default.tsx} (95%) rename components/locale/{el_GR.ts => el_GR.tsx} (91%) delete mode 100644 components/locale/en_GB.ts create mode 100644 components/locale/en_GB.tsx rename components/locale/{en_US.ts => en_US.tsx} (100%) delete mode 100644 components/locale/es_ES.ts create mode 100644 components/locale/es_ES.tsx rename components/locale/{et_EE.ts => et_EE.tsx} (89%) delete mode 100644 components/locale/fa_IR.ts create mode 100644 components/locale/fa_IR.tsx rename components/locale/{fi_FI.ts => fi_FI.tsx} (81%) rename components/locale/{fr_BE.ts => fr_BE.tsx} (90%) create mode 100644 components/locale/fr_CA.tsx delete mode 100644 components/locale/fr_FR.ts create mode 100644 components/locale/fr_FR.tsx delete mode 100644 components/locale/ga_IE.ts create mode 100644 components/locale/ga_IE.tsx create mode 100644 components/locale/gl_ES.tsx delete mode 100644 components/locale/he_IL.ts create mode 100644 components/locale/he_IL.tsx delete mode 100644 components/locale/hi_IN.ts create mode 100644 components/locale/hi_IN.tsx delete mode 100644 components/locale/hr_HR.ts create mode 100644 components/locale/hr_HR.tsx rename components/locale/{hu_HU.ts => hu_HU.tsx} (90%) rename components/locale/{hy_AM.ts => hy_AM.tsx} (92%) rename components/locale/{id_ID.ts => id_ID.tsx} (90%) rename components/locale/{is_IS.ts => is_IS.tsx} (89%) rename components/locale/{it_IT.ts => it_IT.tsx} (81%) delete mode 100644 components/locale/ja_JP.ts create mode 100644 components/locale/ja_JP.tsx create mode 100644 components/locale/kk_KZ.tsx rename components/locale/{ku_IQ.ts => kmr_IQ.tsx} (68%) mode change 100755 => 100644 rename components/locale/{kn_IN.ts => kn_IN.tsx} (93%) delete mode 100644 components/locale/ko_KR.ts create mode 100644 components/locale/ko_KR.tsx create mode 100755 components/locale/ku_IQ.tsx delete mode 100644 components/locale/ku_KU.ts create mode 100644 components/locale/lt_LT.tsx rename components/locale/{lv_LV.ts => lv_LV.tsx} (90%) rename components/locale/{mk_MK.ts => mk_MK.tsx} (92%) rename components/locale/{mn_MN.ts => mn_MN.tsx} (90%) rename components/locale/{ms_MY.ts => ms_MY.tsx} (92%) delete mode 100644 components/locale/nb_NO.ts create mode 100644 components/locale/nb_NO.tsx rename components/locale/{ne_NP.ts => ne_NP.tsx} (92%) delete mode 100644 components/locale/nl_BE.ts create mode 100644 components/locale/nl_BE.tsx delete mode 100644 components/locale/nl_NL.ts create mode 100644 components/locale/nl_NL.tsx rename components/locale/{pl_PL.ts => pl_PL.tsx} (81%) delete mode 100644 components/locale/pt_BR.ts create mode 100644 components/locale/pt_BR.tsx rename components/locale/{pt_PT.ts => pt_PT.tsx} (89%) delete mode 100644 components/locale/ro_RO.ts create mode 100644 components/locale/ro_RO.tsx delete mode 100644 components/locale/ru_RU.ts create mode 100644 components/locale/ru_RU.tsx rename components/locale/{sk_SK.ts => sk_SK.tsx} (92%) rename components/locale/{sl_SI.ts => sl_SI.tsx} (90%) delete mode 100644 components/locale/sr_RS.ts create mode 100644 components/locale/sr_RS.tsx delete mode 100644 components/locale/sv_SE.ts create mode 100644 components/locale/sv_SE.tsx rename components/locale/{ta_IN.ts => ta_IN.tsx} (95%) delete mode 100644 components/locale/th_TH.ts create mode 100644 components/locale/th_TH.tsx delete mode 100644 components/locale/tr_TR.ts create mode 100644 components/locale/tr_TR.tsx rename components/locale/{uk_UA.ts => uk_UA.tsx} (87%) rename components/locale/{vi_VN.ts => vi_VN.tsx} (89%) delete mode 100644 components/locale/zh_CN.ts create mode 100644 components/locale/zh_CN.tsx create mode 100644 components/locale/zh_HK.tsx delete mode 100644 components/locale/zh_TW.ts create mode 100644 components/locale/zh_TW.tsx create mode 100644 components/time-picker/date-fns.tsx create mode 100644 components/time-picker/dayjs.tsx delete mode 100644 components/time-picker/locale/ar_EG.ts create mode 100644 components/time-picker/locale/ar_EG.tsx create mode 100644 components/time-picker/locale/az_AZ.tsx delete mode 100644 components/time-picker/locale/bg_BG.ts create mode 100644 components/time-picker/locale/bg_BG.tsx create mode 100644 components/time-picker/locale/by_BY.tsx delete mode 100644 components/time-picker/locale/ca_ES.ts create mode 100644 components/time-picker/locale/ca_ES.tsx delete mode 100644 components/time-picker/locale/cs_CZ.ts create mode 100644 components/time-picker/locale/cs_CZ.tsx delete mode 100644 components/time-picker/locale/da_DK.ts create mode 100644 components/time-picker/locale/da_DK.tsx delete mode 100644 components/time-picker/locale/de_DE.ts create mode 100644 components/time-picker/locale/de_DE.tsx delete mode 100644 components/time-picker/locale/el_GR.ts create mode 100644 components/time-picker/locale/el_GR.tsx delete mode 100644 components/time-picker/locale/en_GB.ts create mode 100644 components/time-picker/locale/en_GB.tsx delete mode 100644 components/time-picker/locale/en_US.ts create mode 100644 components/time-picker/locale/en_US.tsx delete mode 100644 components/time-picker/locale/es_ES.ts create mode 100644 components/time-picker/locale/es_ES.tsx delete mode 100644 components/time-picker/locale/et_EE.ts create mode 100644 components/time-picker/locale/et_EE.tsx delete mode 100644 components/time-picker/locale/fa_IR.ts create mode 100644 components/time-picker/locale/fa_IR.tsx delete mode 100644 components/time-picker/locale/fi_FI.ts create mode 100644 components/time-picker/locale/fi_FI.tsx delete mode 100644 components/time-picker/locale/fr_BE.ts create mode 100644 components/time-picker/locale/fr_BE.tsx create mode 100644 components/time-picker/locale/fr_CA.tsx delete mode 100644 components/time-picker/locale/fr_FR.ts create mode 100644 components/time-picker/locale/fr_FR.tsx delete mode 100644 components/time-picker/locale/ga_IE.ts create mode 100644 components/time-picker/locale/ga_IE.tsx create mode 100644 components/time-picker/locale/gl_ES.tsx delete mode 100644 components/time-picker/locale/he_IL.ts create mode 100644 components/time-picker/locale/he_IL.tsx delete mode 100644 components/time-picker/locale/hi_IN.ts create mode 100644 components/time-picker/locale/hi_IN.tsx delete mode 100644 components/time-picker/locale/hr_HR.ts create mode 100644 components/time-picker/locale/hr_HR.tsx delete mode 100644 components/time-picker/locale/hu_HU.ts create mode 100644 components/time-picker/locale/hu_HU.tsx delete mode 100644 components/time-picker/locale/id_ID.ts create mode 100644 components/time-picker/locale/id_ID.tsx delete mode 100644 components/time-picker/locale/is_IS.ts create mode 100644 components/time-picker/locale/is_IS.tsx delete mode 100644 components/time-picker/locale/it_IT.ts create mode 100644 components/time-picker/locale/it_IT.tsx delete mode 100644 components/time-picker/locale/ja_JP.ts create mode 100644 components/time-picker/locale/ja_JP.tsx create mode 100644 components/time-picker/locale/kk_KZ.tsx create mode 100755 components/time-picker/locale/kmr_IQ.tsx delete mode 100644 components/time-picker/locale/kn_IN.ts create mode 100644 components/time-picker/locale/kn_IN.tsx delete mode 100644 components/time-picker/locale/ko_KR.ts create mode 100644 components/time-picker/locale/ko_KR.tsx delete mode 100755 components/time-picker/locale/ku_IQ.ts delete mode 100644 components/time-picker/locale/ku_KU.ts create mode 100644 components/time-picker/locale/lt_LT.tsx delete mode 100644 components/time-picker/locale/lv_LV.ts create mode 100644 components/time-picker/locale/lv_LV.tsx delete mode 100644 components/time-picker/locale/mk_MK.ts create mode 100644 components/time-picker/locale/mk_MK.tsx delete mode 100644 components/time-picker/locale/mn_MN.ts create mode 100644 components/time-picker/locale/mn_MN.tsx delete mode 100644 components/time-picker/locale/ms_MY.ts create mode 100644 components/time-picker/locale/ms_MY.tsx delete mode 100644 components/time-picker/locale/nb_NO.ts create mode 100644 components/time-picker/locale/nb_NO.tsx delete mode 100644 components/time-picker/locale/nl_BE.ts create mode 100644 components/time-picker/locale/nl_BE.tsx delete mode 100644 components/time-picker/locale/nl_NL.ts create mode 100644 components/time-picker/locale/nl_NL.tsx delete mode 100644 components/time-picker/locale/pl_PL.ts create mode 100644 components/time-picker/locale/pl_PL.tsx delete mode 100644 components/time-picker/locale/pt_BR.ts create mode 100644 components/time-picker/locale/pt_BR.tsx delete mode 100644 components/time-picker/locale/pt_PT.ts create mode 100644 components/time-picker/locale/pt_PT.tsx delete mode 100644 components/time-picker/locale/ro_RO.ts create mode 100644 components/time-picker/locale/ro_RO.tsx delete mode 100644 components/time-picker/locale/ru_RU.ts create mode 100644 components/time-picker/locale/ru_RU.tsx delete mode 100644 components/time-picker/locale/sk_SK.ts create mode 100644 components/time-picker/locale/sk_SK.tsx delete mode 100644 components/time-picker/locale/sl_SI.ts create mode 100644 components/time-picker/locale/sl_SI.tsx delete mode 100644 components/time-picker/locale/sr_RS.ts create mode 100644 components/time-picker/locale/sr_RS.tsx delete mode 100644 components/time-picker/locale/sv_SE.ts create mode 100644 components/time-picker/locale/sv_SE.tsx rename components/time-picker/locale/{ta_IN.ts => ta_IN.tsx} (59%) delete mode 100644 components/time-picker/locale/th_TH.ts create mode 100644 components/time-picker/locale/th_TH.tsx delete mode 100644 components/time-picker/locale/tr_TR.ts create mode 100644 components/time-picker/locale/tr_TR.tsx delete mode 100644 components/time-picker/locale/uk_UA.ts create mode 100644 components/time-picker/locale/uk_UA.tsx delete mode 100644 components/time-picker/locale/vi_VN.ts create mode 100644 components/time-picker/locale/vi_VN.tsx delete mode 100644 components/time-picker/locale/zh_CN.ts create mode 100644 components/time-picker/locale/zh_CN.tsx delete mode 100644 components/time-picker/locale/zh_TW.ts create mode 100644 components/time-picker/locale/zh_TW.tsx create mode 100644 components/time-picker/moment.tsx delete mode 100644 components/time-picker/style/index.ts create mode 100644 components/time-picker/style/index.tsx create mode 100644 components/time-picker/time-picker.tsx create mode 100644 components/vc-align/Align1.tsx delete mode 100644 components/vc-calendar/assets/common/Calendar.less delete mode 100644 components/vc-calendar/assets/common/FullCalendar.less delete mode 100644 components/vc-calendar/assets/common/Picker.less delete mode 100644 components/vc-calendar/assets/common/RangeCalendar.less delete mode 100644 components/vc-calendar/assets/common/index.less delete mode 100644 components/vc-calendar/assets/index.less delete mode 100644 components/vc-calendar/assets/index/Calendar.less delete mode 100644 components/vc-calendar/assets/index/DecadePanel.less delete mode 100644 components/vc-calendar/assets/index/Input.less delete mode 100644 components/vc-calendar/assets/index/MonthPanel.less delete mode 100644 components/vc-calendar/assets/index/Picker.less delete mode 100644 components/vc-calendar/assets/index/Time.less delete mode 100644 components/vc-calendar/assets/index/TimePanel.less delete mode 100644 components/vc-calendar/assets/index/YearPanel.less delete mode 100644 components/vc-calendar/index.js delete mode 100644 components/vc-calendar/src/Calendar.jsx delete mode 100644 components/vc-calendar/src/FullCalendar.jsx delete mode 100644 components/vc-calendar/src/MonthCalendar.jsx delete mode 100644 components/vc-calendar/src/Picker.jsx delete mode 100644 components/vc-calendar/src/RangeCalendar.jsx delete mode 100644 components/vc-calendar/src/calendar/CalendarFooter.jsx delete mode 100644 components/vc-calendar/src/calendar/CalendarHeader.jsx delete mode 100644 components/vc-calendar/src/calendar/OkButton.jsx delete mode 100644 components/vc-calendar/src/calendar/TimePickerButton.jsx delete mode 100644 components/vc-calendar/src/calendar/TodayButton.jsx delete mode 100644 components/vc-calendar/src/date/DateConstants.js delete mode 100644 components/vc-calendar/src/date/DateInput.jsx delete mode 100644 components/vc-calendar/src/date/DateTBody.jsx delete mode 100644 components/vc-calendar/src/date/DateTHead.jsx delete mode 100644 components/vc-calendar/src/date/DateTable.jsx delete mode 100644 components/vc-calendar/src/decade/DecadePanel.jsx delete mode 100644 components/vc-calendar/src/full-calendar/CalendarHeader.jsx delete mode 100644 components/vc-calendar/src/index.js delete mode 100644 components/vc-calendar/src/locale/ku_KU.js delete mode 100644 components/vc-calendar/src/mixin/CalendarMixin.js delete mode 100644 components/vc-calendar/src/mixin/CommonMixin.js delete mode 100644 components/vc-calendar/src/month/MonthPanel.jsx delete mode 100644 components/vc-calendar/src/month/MonthTable.jsx delete mode 100644 components/vc-calendar/src/picker/placements.js delete mode 100644 components/vc-calendar/src/range-calendar/CalendarPart.jsx delete mode 100644 components/vc-calendar/src/util/index.js delete mode 100644 components/vc-calendar/src/util/toTime.js delete mode 100644 components/vc-calendar/src/year/YearPanel.jsx create mode 100644 components/vc-pagination/locale/bn_BD.js create mode 100644 components/vc-pagination/locale/by_BY.js create mode 100644 components/vc-pagination/locale/fr_CA.js create mode 100644 components/vc-pagination/locale/gl_ES.tsx create mode 100644 components/vc-pagination/locale/ka_GE.js create mode 100644 components/vc-pagination/locale/kk_KZ.js create mode 100644 components/vc-pagination/locale/km_KH.js rename components/vc-pagination/locale/{ku_IQ.js => kmr_IQ.js} (100%) delete mode 100644 components/vc-pagination/locale/ku_KU.js create mode 100644 components/vc-pagination/locale/lt_LT.js create mode 100644 components/vc-pagination/locale/ml_IN.js create mode 100644 components/vc-pagination/locale/ur_PK.js create mode 100644 components/vc-picker/PanelContext.tsx create mode 100644 components/vc-picker/Picker.tsx create mode 100644 components/vc-picker/PickerPanel.tsx create mode 100644 components/vc-picker/PickerTrigger.tsx create mode 100644 components/vc-picker/RangeContext.tsx create mode 100644 components/vc-picker/RangePicker.tsx create mode 100644 components/vc-picker/generate/dateFns.ts create mode 100644 components/vc-picker/generate/dayjs.ts create mode 100644 components/vc-picker/generate/index.ts create mode 100644 components/vc-picker/generate/moment.ts create mode 100644 components/vc-picker/hooks/useCellClassName.ts create mode 100644 components/vc-picker/hooks/useHoverValue.ts create mode 100644 components/vc-picker/hooks/useMergeProps.ts create mode 100644 components/vc-picker/hooks/usePickerInput.ts create mode 100644 components/vc-picker/hooks/useRangeDisabled.ts create mode 100644 components/vc-picker/hooks/useRangeViewDates.ts create mode 100644 components/vc-picker/hooks/useTextValueMapping.ts create mode 100644 components/vc-picker/hooks/useValueTexts.ts create mode 100644 components/vc-picker/index.tsx create mode 100644 components/vc-picker/interface.ts rename components/{vc-calendar/src/locale/ar_EG.js => vc-picker/locale/ar_EG.ts} (88%) create mode 100644 components/vc-picker/locale/az_AZ.ts rename components/{vc-calendar/src/locale/bg_BG.js => vc-picker/locale/bg_BG.ts} (89%) create mode 100644 components/vc-picker/locale/by_BY.ts rename components/{vc-calendar/src/locale/ca_ES.js => vc-picker/locale/ca_ES.ts} (87%) rename components/{vc-calendar/src/locale/cs_CZ.js => vc-picker/locale/cs_CZ.ts} (87%) rename components/{vc-calendar/src/locale/da_DK.js => vc-picker/locale/da_DK.ts} (63%) rename components/{vc-calendar/src/locale/de_DE.js => vc-picker/locale/de_DE.ts} (87%) rename components/{vc-calendar/src/locale/el_GR.js => vc-picker/locale/el_GR.ts} (90%) rename components/{vc-calendar/src/locale/en_GB.js => vc-picker/locale/en_GB.ts} (86%) rename components/{vc-calendar/src/locale/en_US.js => vc-picker/locale/en_US.ts} (86%) rename components/{vc-calendar/src/locale/es_ES.js => vc-picker/locale/es_ES.ts} (87%) rename components/{vc-calendar/src/locale/et_EE.js => vc-picker/locale/et_EE.ts} (86%) rename components/{vc-calendar/src/locale/fa_IR.js => vc-picker/locale/fa_IR.ts} (88%) rename components/{vc-calendar/src/locale/fi_FI.js => vc-picker/locale/fi_FI.ts} (87%) rename components/{vc-calendar/src/locale/fr_BE.js => vc-picker/locale/fr_BE.ts} (87%) rename components/{vc-calendar/src/locale/fr_FR.js => vc-picker/locale/fr_CA.ts} (87%) create mode 100644 components/vc-picker/locale/fr_FR.ts rename components/{vc-calendar/src/locale/ga_IE.js => vc-picker/locale/ga_IE.ts} (88%) create mode 100644 components/vc-picker/locale/gl_ES.ts rename components/{vc-calendar/src/locale/he_IL.js => vc-picker/locale/he_IL.ts} (88%) rename components/{vc-calendar/src/locale/hi_IN.js => vc-picker/locale/hi_IN.ts} (90%) rename components/{vc-calendar/src/locale/hr_HR.js => vc-picker/locale/hr_HR.ts} (87%) rename components/{vc-calendar/src/locale/hu_HU.js => vc-picker/locale/hu_HU.ts} (91%) rename components/{vc-calendar/src/locale/id_ID.js => vc-picker/locale/id_ID.ts} (87%) rename components/{vc-calendar/src/locale/is_IS.js => vc-picker/locale/is_IS.ts} (86%) rename components/{vc-calendar/src/locale/it_IT.js => vc-picker/locale/it_IT.ts} (87%) rename components/{vc-calendar/src/locale/ja_JP.js => vc-picker/locale/ja_JP.ts} (84%) create mode 100644 components/vc-picker/locale/kk_KZ.ts create mode 100644 components/vc-picker/locale/km_KH.ts rename components/{vc-calendar/src/locale/ku_IQ.js => vc-picker/locale/kmr_IQ.ts} (86%) rename components/{vc-calendar/src/locale/kn_IN.js => vc-picker/locale/kn_IN.ts} (91%) rename components/{vc-calendar/src/locale/ko_KR.js => vc-picker/locale/ko_KR.ts} (86%) create mode 100644 components/vc-picker/locale/lt_LT.ts rename components/{vc-calendar/src/locale/lv_LV.js => vc-picker/locale/lv_LV.ts} (87%) rename components/{vc-calendar/src/locale/mk_MK.js => vc-picker/locale/mk_MK.ts} (89%) create mode 100644 components/vc-picker/locale/ml_IN.ts rename components/{vc-calendar/src/locale/mm_MM.js => vc-picker/locale/mm_MM.ts} (90%) rename components/{vc-calendar/src/locale/mn_MN.js => vc-picker/locale/mn_MN.ts} (88%) rename components/{vc-calendar/src/locale/ms_MY.js => vc-picker/locale/ms_MY.ts} (86%) rename components/{vc-calendar/src/locale/nb_NO.js => vc-picker/locale/nb_NO.ts} (64%) rename components/{vc-calendar/src/locale/nl_BE.js => vc-picker/locale/nl_BE.ts} (86%) rename components/{vc-calendar/src/locale/nl_NL.js => vc-picker/locale/nl_NL.ts} (86%) rename components/{vc-calendar/src/locale/pl_PL.js => vc-picker/locale/pl_PL.ts} (86%) rename components/{vc-calendar/src/locale/pt_BR.js => vc-picker/locale/pt_BR.ts} (69%) rename components/{vc-calendar/src/locale/pt_PT.js => vc-picker/locale/pt_PT.ts} (86%) rename components/{vc-calendar/src/locale/ro_RO.js => vc-picker/locale/ro_RO.ts} (87%) rename components/{vc-calendar/src/locale/ru_RU.js => vc-picker/locale/ru_RU.ts} (88%) rename components/{vc-calendar/src/locale/sk_SK.js => vc-picker/locale/sk_SK.ts} (87%) rename components/{vc-calendar/src/locale/sl_SI.js => vc-picker/locale/sl_SI.ts} (87%) rename components/{vc-calendar/src/locale/sr_RS.js => vc-picker/locale/sr_RS.ts} (87%) rename components/{vc-calendar/src/locale/sv_SE.js => vc-picker/locale/sv_SE.ts} (86%) rename components/{vc-calendar/src/locale/ta_IN.js => vc-picker/locale/ta_IN.ts} (92%) rename components/{vc-calendar/src/locale/th_TH.js => vc-picker/locale/th_TH.ts} (90%) rename components/{vc-calendar/src/locale/tr_TR.js => vc-picker/locale/tr_TR.ts} (86%) rename components/{vc-calendar/src/locale/ug_CN.js => vc-picker/locale/ug_CN.ts} (90%) rename components/{vc-calendar/src/locale/uk_UA.js => vc-picker/locale/uk_UA.ts} (89%) rename components/{vc-calendar/src/locale/vi_VN.js => vc-picker/locale/vi_VN.ts} (87%) rename components/{vc-calendar/src/locale/zh_CN.js => vc-picker/locale/zh_CN.ts} (87%) rename components/{vc-calendar/src/locale/zh_TW.js => vc-picker/locale/zh_TW.ts} (84%) create mode 100644 components/vc-picker/panels/DatePanel/DateBody.tsx create mode 100644 components/vc-picker/panels/DatePanel/DateHeader.tsx create mode 100644 components/vc-picker/panels/DatePanel/index.tsx create mode 100644 components/vc-picker/panels/DatetimePanel/index.tsx create mode 100644 components/vc-picker/panels/DecadePanel/DecadeBody.tsx create mode 100644 components/vc-picker/panels/DecadePanel/DecadeHeader.tsx create mode 100644 components/vc-picker/panels/DecadePanel/index.tsx create mode 100644 components/vc-picker/panels/Header.tsx create mode 100644 components/vc-picker/panels/MonthPanel/MonthBody.tsx create mode 100644 components/vc-picker/panels/MonthPanel/MonthHeader.tsx create mode 100644 components/vc-picker/panels/MonthPanel/index.tsx create mode 100644 components/vc-picker/panels/PanelBody.tsx create mode 100644 components/vc-picker/panels/QuarterPanel/QuarterBody.tsx create mode 100644 components/vc-picker/panels/QuarterPanel/QuarterHeader.tsx create mode 100644 components/vc-picker/panels/QuarterPanel/index.tsx create mode 100644 components/vc-picker/panels/TimePanel/TimeBody.tsx create mode 100644 components/vc-picker/panels/TimePanel/TimeHeader.tsx create mode 100644 components/vc-picker/panels/TimePanel/TimeUnitColumn.tsx create mode 100644 components/vc-picker/panels/TimePanel/index.tsx create mode 100644 components/vc-picker/panels/WeekPanel/index.tsx create mode 100644 components/vc-picker/panels/YearPanel/YearBody.tsx create mode 100644 components/vc-picker/panels/YearPanel/YearHeader.tsx create mode 100644 components/vc-picker/panels/YearPanel/index.tsx create mode 100644 components/vc-picker/utils/dateUtil.ts create mode 100644 components/vc-picker/utils/getExtraFooter.tsx create mode 100644 components/vc-picker/utils/getRanges.tsx create mode 100644 components/vc-picker/utils/miscUtil.ts create mode 100644 components/vc-picker/utils/timeUtil.ts create mode 100644 components/vc-picker/utils/uiUtil.ts create mode 100644 components/vc-select/Selector/interface.ts delete mode 100644 components/vc-time-picker/Combobox.jsx delete mode 100644 components/vc-time-picker/Header.jsx delete mode 100644 components/vc-time-picker/Panel.jsx delete mode 100644 components/vc-time-picker/Select.jsx delete mode 100644 components/vc-time-picker/TimePicker.jsx delete mode 100644 components/vc-time-picker/assets/index.less delete mode 100644 components/vc-time-picker/assets/index/Header.less delete mode 100644 components/vc-time-picker/assets/index/Panel.less delete mode 100644 components/vc-time-picker/assets/index/Picker.less delete mode 100644 components/vc-time-picker/assets/index/Select.less delete mode 100644 components/vc-time-picker/index.js delete mode 100644 components/vc-time-picker/placements.js delete mode 100644 components/vc-trigger/LazyRenderBox.jsx delete mode 100644 components/vc-trigger/Popup.jsx create mode 100644 components/vc-trigger/Popup/Mask.tsx create mode 100644 components/vc-trigger/Popup/MobilePopupInner.tsx create mode 100644 components/vc-trigger/Popup/PopupInner.tsx create mode 100644 components/vc-trigger/Popup/index.tsx create mode 100644 components/vc-trigger/Popup/interface.ts create mode 100644 components/vc-trigger/Popup/useStretchStyle.ts create mode 100644 components/vc-trigger/Popup/useVisibleStatus.ts delete mode 100644 components/vc-trigger/PopupInner.jsx rename components/vc-trigger/{Trigger.jsx => Trigger.tsx} (76%) delete mode 100644 components/vc-trigger/index.md rename components/vc-trigger/{index.js => index.ts} (65%) create mode 100644 components/vc-trigger/interface.ts delete mode 100644 components/vc-trigger/utils.js create mode 100644 components/vc-trigger/utils/alignUtil.ts create mode 100644 components/vc-trigger/utils/motionUtil.ts diff --git a/.gitignore b/.gitignore index 86ef043fe..b41f07728 100644 --- a/.gitignore +++ b/.gitignore @@ -73,3 +73,5 @@ site/dev.js # IDE 语法提示临时文件 vetur/ + +report.html diff --git a/CHANGELOG.en-US.md b/CHANGELOG.en-US.md index 24e3cdb21..5865a859a 100644 --- a/CHANGELOG.en-US.md +++ b/CHANGELOG.en-US.md @@ -10,6 +10,30 @@ --- +## 2.2.6 + +`2021-08-12` + +- 🐞 Fix `Table` expanded list rendering problem [#4507](https://github.com/vueComponent/ant-design-vue/issues/4507) +- 🐞 Fix `Rate` custom `character` slot not taking effect [#4509](https://github.com/vueComponent/ant-design-vue/issues/4509) +- 🐞 Add resize-observer-polyfill to fix the problem of reporting errors in low versions of Chrome [#4508](https://github.com/vueComponent/ant-design-vue/issues/4508) + +## 2.2.5 + +`2021-08-11` + +- 🌟 `Select` supports customizing nodes through option slots [68c1f4](https://github.com/vueComponent/ant-design-vue/commit/68c1f4550108a3a6bbe4f1b2c5c168523fd6c84a) +- 🐞 Fix the problem that the pop-up window component in the development environment does not display in the lower version of chrome, and avoid the pop-up window flashing [#4409](https://github.com/vueComponent/ant-design-vue/issues/4409) +- 🐞 Fix the problem of not scrolling to the active position when `Select` is opened [ccb240](https://github.com/vueComponent/ant-design-vue/commit/ccb24016c07632f49550646c971060c402586c67) + +## 2.2.4 + +`2021-08-10` + +- 🌟 Support Vue@3.2 [#4490](https://github.com/vueComponent/ant-design-vue/issues/4490) +- 🌟 Automatically hide the horizontal scroll bar of `Table` [#4484](https://github.com/vueComponent/ant-design-vue/issues/4484) +- 🐞 Fix the issue of `Progress` trailColor not taking effect [#4483](https://github.com/vueComponent/ant-design-vue/issues/4483) + ## 2.2.3 `2021-08-07` diff --git a/CHANGELOG.zh-CN.md b/CHANGELOG.zh-CN.md index d93a8bbe8..662b07486 100644 --- a/CHANGELOG.zh-CN.md +++ b/CHANGELOG.zh-CN.md @@ -10,6 +10,30 @@ --- +## 2.2.6 + +`2021-08-12` + +- 🐞 修复 `Table` 展开列表渲染错位问题 [#4507](https://github.com/vueComponent/ant-design-vue/issues/4507) +- 🐞 修复 `Rate` 自定义 `character` 插槽未生效问题 [#4509](https://github.com/vueComponent/ant-design-vue/issues/4509) +- 🐞 添加 resize-observer-polyfill, 修复在低版本 Chrome 下报错问题 [#4508](https://github.com/vueComponent/ant-design-vue/issues/4508) + +## 2.2.5 + +`2021-08-11` + +- 🌟 `Select` 支持通过 option 插槽定制化节点 [68c1f4](https://github.com/vueComponent/ant-design-vue/commit/68c1f4550108a3a6bbe4f1b2c5c168523fd6c84a) +- 🐞 修复开发环境下弹窗类组件在低版本 chrome 下,不显示问题,并避免弹窗闪动 [#4409](https://github.com/vueComponent/ant-design-vue/issues/4409) +- 🐞 修复 `Select` 打开时没有滚动到激活位置问题 [ccb240](https://github.com/vueComponent/ant-design-vue/commit/ccb24016c07632f49550646c971060c402586c67) + +## 2.2.4 + +`2021-08-10` + +- 🌟 支持 Vue@3.2 [#4490](https://github.com/vueComponent/ant-design-vue/issues/4490) +- 🌟 自动隐藏 `Table` 横向滚动条 [#4484](https://github.com/vueComponent/ant-design-vue/issues/4484) +- 🐞 修复 `Progress` trailColor 不生效问题 [#4483](https://github.com/vueComponent/ant-design-vue/issues/4483) + ## 2.2.3 `2021-08-07` diff --git a/antd-tools/getWebpackConfig.js b/antd-tools/getWebpackConfig.js index 8b4deef31..c483603a3 100644 --- a/antd-tools/getWebpackConfig.js +++ b/antd-tools/getWebpackConfig.js @@ -80,7 +80,6 @@ function getWebpackConfig(modules) { }, module: { - noParse: [/moment.js/], rules: [ { test: /\.vue$/, diff --git a/components/_util/EventInterface.ts b/components/_util/EventInterface.ts new file mode 100644 index 000000000..361eea747 --- /dev/null +++ b/components/_util/EventInterface.ts @@ -0,0 +1,8 @@ +export type FocusEventHandler = (e: FocusEvent) => void; +export type MouseEventHandler = (e: MouseEvent) => void; +export type KeyboardEventHandler = (e: KeyboardEvent) => void; +export type ChangeEvent = Event & { + target: { + value?: string | undefined; + }; +}; diff --git a/components/_util/Portal.js b/components/_util/Portal.js index e0ca32114..782b3cf9e 100644 --- a/components/_util/Portal.js +++ b/components/_util/Portal.js @@ -1,48 +1,38 @@ import PropTypes from './vue-types'; -import { defineComponent, nextTick, Teleport } from 'vue'; +import { + defineComponent, + nextTick, + onBeforeUnmount, + onMounted, + onUpdated, + ref, + Teleport, +} from 'vue'; export default defineComponent({ name: 'Portal', + inheritAttrs: false, props: { getContainer: PropTypes.func.isRequired, - children: PropTypes.any.isRequired, didUpdate: PropTypes.func, }, - data() { - this._container = null; - return {}; - }, - mounted() { - this.createContainer(); - }, - updated() { - const { didUpdate } = this.$props; - if (didUpdate) { + setup(props, { slots }) { + const container = ref(); + onMounted(() => { + container.value = props.getContainer(); + }); + onUpdated(() => { nextTick(() => { - didUpdate(this.$props); + props.nextTick?.(props); }); - } - }, - - beforeUnmount() { - this.removeContainer(); - }, - methods: { - createContainer() { - this._container = this.$props.getContainer(); - this.$forceUpdate(); - }, - removeContainer() { - if (this._container && this._container.parentNode) { - this._container.parentNode.removeChild(this._container); + }); + onBeforeUnmount(() => { + if (container.value && container.value.parentNode) { + container.value.parentNode.removeChild(container.value); } - }, - }, - - render() { - if (this._container) { - return {this.$props.children}; - } - return null; + }); + return () => { + return container.value ? {slots.default?.()} : null; + }; }, }); diff --git a/components/_util/PortalWrapper.js b/components/_util/PortalWrapper.js index 38113023f..7cf359071 100644 --- a/components/_util/PortalWrapper.js +++ b/components/_util/PortalWrapper.js @@ -20,7 +20,6 @@ export default defineComponent({ wrapperClassName: PropTypes.string, forceRender: PropTypes.looseBool, getContainer: PropTypes.any, - children: PropTypes.func, visible: PropTypes.looseBool, }, data() { @@ -130,7 +129,7 @@ export default defineComponent({ }, render() { - const { children, forceRender, visible } = this.$props; + const { forceRender, visible } = this.$props; let portal = null; const childProps = { getOpenCount: () => openCount, @@ -141,8 +140,8 @@ export default defineComponent({ portal = ( this.$slots.default?.(childProps) }} > ); } diff --git a/components/_util/hooks/useConfigInject.ts b/components/_util/hooks/useConfigInject.ts index 93f18e1f8..e4a3ffeb1 100644 --- a/components/_util/hooks/useConfigInject.ts +++ b/components/_util/hooks/useConfigInject.ts @@ -10,9 +10,11 @@ export default ( ): { configProvider: UnwrapRef; prefixCls: ComputedRef; + rootPrefixCls: ComputedRef; direction: ComputedRef; size: ComputedRef; getTargetContainer: ComputedRef<() => HTMLElement>; + getPopupContainer: ComputedRef<() => HTMLElement>; space: ComputedRef<{ size: SizeType | number }>; pageHeader: ComputedRef<{ ghost: boolean }>; form?: ComputedRef<{ @@ -26,6 +28,7 @@ export default ( defaultConfigProvider, ); const prefixCls = computed(() => configProvider.getPrefixCls(name, props.prefixCls)); + const rootPrefixCls = computed(() => configProvider.getPrefixCls()); const direction = computed(() => configProvider.direction); const autoInsertSpaceInButton = computed(() => configProvider.autoInsertSpaceInButton); const renderEmpty = computed(() => configProvider.renderEmpty); @@ -34,16 +37,19 @@ export default ( const form = computed(() => configProvider.form); const size = computed(() => props.size || configProvider.componentSize); const getTargetContainer = computed(() => props.getTargetContainer); + const getPopupContainer = computed(() => props.getPopupContainer); return { configProvider, prefixCls, direction, size, getTargetContainer, + getPopupContainer, space, pageHeader, form, autoInsertSpaceInButton, renderEmpty, + rootPrefixCls, }; }; diff --git a/components/_util/hooks/useMemo.ts b/components/_util/hooks/useMemo.ts index f137badca..769136999 100644 --- a/components/_util/hooks/useMemo.ts +++ b/components/_util/hooks/useMemo.ts @@ -1,9 +1,9 @@ -import type { Ref } from 'vue'; +import type { Ref, WatchSource } from 'vue'; import { ref, watch } from 'vue'; export default function useMemo( getValue: () => T, - condition: any[], + condition: (WatchSource | object)[], shouldUpdate?: (prev: any[], next: any[]) => boolean, ) { const cacheRef: Ref = ref(getValue() as any); diff --git a/components/_util/hooks/useMergedState.ts b/components/_util/hooks/useMergedState.ts new file mode 100644 index 000000000..e18a9028d --- /dev/null +++ b/components/_util/hooks/useMergedState.ts @@ -0,0 +1,51 @@ +import type { Ref, UnwrapRef } from 'vue'; +import { toRaw } from 'vue'; +import { watchEffect } from 'vue'; +import { unref } from 'vue'; +import { watch } from 'vue'; +import { ref } from 'vue'; + +export default function useMergedState>( + defaultStateValue: T | (() => T), + option?: { + defaultValue?: T | (() => T); + value?: Ref | Ref>; + onChange?: (val: T, prevValue: T) => void; + postState?: (val: T) => T; + }, +): [R, (val: T) => void] { + const { defaultValue, value = ref() } = option || {}; + let initValue: T = + typeof defaultStateValue === 'function' ? (defaultStateValue as any)() : defaultStateValue; + if (value.value !== undefined) { + initValue = unref(value as any) as T; + } + if (defaultValue !== undefined) { + initValue = typeof defaultValue === 'function' ? (defaultValue as any)() : defaultValue; + } + + const innerValue = ref(initValue) as Ref; + const mergedValue = ref(initValue) as Ref; + watchEffect(() => { + let val = value.value !== undefined ? value.value : innerValue.value; + if (option.postState) { + val = option.postState(val as T); + } + mergedValue.value = val as T; + }); + + function triggerChange(newValue: T) { + const preVal = mergedValue.value; + innerValue.value = newValue; + if (toRaw(mergedValue.value) !== newValue && option.onChange) { + option.onChange(newValue, preVal); + } + } + + // Effect of reset value to `undefined` + watch(value, () => { + innerValue.value = value.value as T; + }); + + return [mergedValue as unknown as R, triggerChange]; +} diff --git a/components/_util/hooks/useState.ts b/components/_util/hooks/useState.ts new file mode 100644 index 000000000..a74476a9e --- /dev/null +++ b/components/_util/hooks/useState.ts @@ -0,0 +1,17 @@ +import type { Ref } from 'vue'; +import { ref } from 'vue'; + +export default function useState>( + defaultStateValue: T | (() => T), +): [R, (val: T) => void] { + const initValue: T = + typeof defaultStateValue === 'function' ? (defaultStateValue as any)() : defaultStateValue; + + const innerValue = ref(initValue) as Ref; + + function triggerChange(newValue: T) { + innerValue.value = newValue; + } + + return [innerValue as unknown as R, triggerChange]; +} diff --git a/components/_util/interopDefault.js b/components/_util/interopDefault.js deleted file mode 100644 index d1adc3c40..000000000 --- a/components/_util/interopDefault.js +++ /dev/null @@ -1,4 +0,0 @@ -// https://github.com/moment/moment/issues/3650 -export default function interopDefault(m) { - return m.default || m; -} diff --git a/components/_util/moment-util.js b/components/_util/moment-util.js deleted file mode 100644 index 002820474..000000000 --- a/components/_util/moment-util.js +++ /dev/null @@ -1,75 +0,0 @@ -import interopDefault from './interopDefault'; -import moment from 'moment'; -import warning from './warning'; -import isNil from 'lodash-es/isNil'; - -export const TimeType = { - validator(value) { - return typeof value === 'string' || isNil(value) || moment.isMoment(value); - }, -}; - -export const TimesType = { - validator(value) { - if (Array.isArray(value)) { - return ( - value.length === 0 || - value.findIndex(val => typeof val !== 'string') === -1 || - value.findIndex(val => !isNil(val) && !moment.isMoment(val)) === -1 - ); - } - return false; - }, -}; - -export const TimeOrTimesType = { - validator(value) { - if (Array.isArray(value)) { - return ( - value.length === 0 || - value.findIndex(val => typeof val !== 'string') === -1 || - value.findIndex(val => !isNil(val) && !moment.isMoment(val)) === -1 - ); - } else { - return typeof value === 'string' || isNil(value) || moment.isMoment(value); - } - }, -}; - -export function checkValidate(componentName, value, propName, valueFormat) { - const values = Array.isArray(value) ? value : [value]; - values.forEach(val => { - if (!val) return; - valueFormat && - warning( - interopDefault(moment)(val, valueFormat).isValid(), - componentName, - `When set \`valueFormat\`, \`${propName}\` should provides invalidate string time. `, - ); - !valueFormat && - warning( - interopDefault(moment).isMoment(val) && val.isValid(), - componentName, - `\`${propName}\` provides invalidate moment time. If you want to set empty value, use \`null\` instead.`, - ); - }); -} -export const stringToMoment = (value, valueFormat) => { - if (Array.isArray(value)) { - return value.map(val => - typeof val === 'string' && val ? interopDefault(moment)(val, valueFormat) : val || null, - ); - } else { - return typeof value === 'string' && value - ? interopDefault(moment)(value, valueFormat) - : value || null; - } -}; - -export const momentToString = (value, valueFormat) => { - if (Array.isArray(value)) { - return value.map(val => (interopDefault(moment).isMoment(val) ? val.format(valueFormat) : val)); - } else { - return interopDefault(moment).isMoment(value) ? value.format(valueFormat) : value; - } -}; diff --git a/components/_util/transition.tsx b/components/_util/transition.tsx index 1894aff8b..29b747455 100644 --- a/components/_util/transition.tsx +++ b/components/_util/transition.tsx @@ -1,19 +1,27 @@ -import type { BaseTransitionProps, CSSProperties, Ref } from 'vue'; -import { getCurrentInstance, onUpdated } from 'vue'; +import type { + BaseTransitionProps, + CSSProperties, + Ref, + TransitionGroupProps, + TransitionProps, +} from 'vue'; +import { onBeforeUpdate } from 'vue'; +import { getCurrentInstance } from 'vue'; import { defineComponent, nextTick, Transition as T, TransitionGroup as TG } from 'vue'; -export const getTransitionProps = (transitionName: string, opt: object = {}) => { +export const getTransitionProps = (transitionName: string, opt: TransitionProps = {}) => { if (process.env.NODE_ENV === 'test') { return opt; } - const transitionProps = transitionName + const transitionProps: TransitionProps = transitionName ? { appear: true, - appearFromClass: `${transitionName}-appear ${transitionName}-appear-prepare`, + // type: 'animation', + // appearFromClass: `${transitionName}-appear ${transitionName}-appear-prepare`, // appearActiveClass: `antdv-base-transtion`, - appearToClass: `${transitionName}-appear ${transitionName}-appear-active`, + // appearToClass: `${transitionName}-appear ${transitionName}-appear-active`, enterFromClass: `${transitionName}-enter ${transitionName}-enter-prepare`, - // enterActiveClass: `antdv-base-transtion`, + // enterActiveClass: `${transitionName}-enter ${transitionName}-enter-active`, enterToClass: `${transitionName}-enter ${transitionName}-enter-active`, leaveFromClass: ` ${transitionName}-leave`, leaveActiveClass: `${transitionName}-leave ${transitionName}-leave-active`, @@ -24,11 +32,11 @@ export const getTransitionProps = (transitionName: string, opt: object = {}) => return transitionProps; }; -export const getTransitionGroupProps = (transitionName: string, opt: object = {}) => { - const transitionProps = transitionName +export const getTransitionGroupProps = (transitionName: string, opt: TransitionProps = {}) => { + const transitionProps: TransitionGroupProps = transitionName ? { appear: true, - appearFromClass: `${transitionName}-appear ${transitionName}-appear-prepare`, + // appearFromClass: `${transitionName}-appear ${transitionName}-appear-prepare`, appearActiveClass: `${transitionName}`, appearToClass: `${transitionName}-appear ${transitionName}-appear-active`, enterFromClass: `${transitionName}-appear ${transitionName}-enter ${transitionName}-appear-prepare ${transitionName}-enter-prepare`, @@ -51,7 +59,7 @@ if (process.env.NODE_ENV === 'test') { inheritAttrs: false, setup(_props, { slots, attrs }) { const instance = getCurrentInstance(); - onUpdated(() => { + onBeforeUpdate(() => { const child = instance.subTree.children[0]; if (child && child.dirs && child.dirs[0]) { const value = child.dirs[0].value; diff --git a/components/auto-complete/InputElement.tsx b/components/auto-complete/InputElement.tsx deleted file mode 100644 index c3623cfec..000000000 --- a/components/auto-complete/InputElement.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import { cloneElement } from '../_util/vnode'; -import { flattenChildren } from '../_util/props-util'; - -const InputElement = (_: any, { attrs, slots }) => { - const children = flattenChildren(slots.default?.())[0]; - return cloneElement(children, { ...attrs }); -}; -InputElement.inheritAttrs = false; -export default InputElement; diff --git a/components/auto-complete/index.tsx b/components/auto-complete/index.tsx index dac4d43db..d9e43f753 100644 --- a/components/auto-complete/index.tsx +++ b/components/auto-complete/index.tsx @@ -2,7 +2,6 @@ import type { App, Plugin, VNode, ExtractPropTypes } from 'vue'; import { defineComponent, inject, provide } from 'vue'; import Select, { SelectProps } from '../select'; import Input from '../input'; -import InputElement from './InputElement'; import PropTypes from '../_util/vue-types'; import { defaultConfigProvider } from '../config-provider'; import { getComponent, getOptionProps, isValidElement, getSlot } from '../_util/props-util'; @@ -72,7 +71,7 @@ const AutoComplete = defineComponent({ getInputElement() { const children = getSlot(this); const element = children.length ? children[0] : ; - return {element}; + return element; }, focus() { diff --git a/components/calendar/Header.tsx b/components/calendar/Header.tsx index 5e7cfe7a0..374e186d9 100644 --- a/components/calendar/Header.tsx +++ b/components/calendar/Header.tsx @@ -1,211 +1,179 @@ -import type { PropType } from 'vue'; -import { defineComponent, inject } from 'vue'; import Select from '../select'; import { Group, Button } from '../radio'; -import PropTypes from '../_util/vue-types'; -import { defaultConfigProvider } from '../config-provider'; -import type { VueNode } from '../_util/type'; -import type moment from 'moment'; -import type { RadioChangeEvent } from '../radio/interface'; +import type { CalendarMode } from './generateCalendar'; +import type { Ref } from 'vue'; +import { defineComponent, ref } from 'vue'; +import type { Locale } from '../vc-picker/interface'; +import type { GenerateConfig } from '../vc-picker/generate'; -function getMonthsLocale(value: moment.Moment): string[] { - const current = value.clone(); - const localeData = value.localeData(); - const months = []; - for (let i = 0; i < 12; i++) { - current.month(i); - months.push(localeData.monthsShort(current)); +const YearSelectOffset = 10; +const YearSelectTotal = 20; + +interface SharedProps { + prefixCls: string; + value: DateType; + validRange?: [DateType, DateType]; + generateConfig: GenerateConfig; + locale: Locale; + fullscreen: boolean; + divRef: Ref; + onChange: (year: DateType) => void; +} + +function YearSelect(props: SharedProps) { + const { fullscreen, validRange, generateConfig, locale, prefixCls, value, onChange, divRef } = + props; + + const year = generateConfig.getYear(value || generateConfig.getNow()); + + let start = year - YearSelectOffset; + let end = start + YearSelectTotal; + + if (validRange) { + start = generateConfig.getYear(validRange[0]); + end = generateConfig.getYear(validRange[1]) + 1; } - return months; -} -export interface RenderHeader { - value: moment.Moment; - onChange?: (value: moment.Moment) => void; - type: string; - onTypeChange: (type: string) => void; -} -export type HeaderRender = (headerRender: RenderHeader) => VueNode; -export const HeaderProps = { - prefixCls: PropTypes.string, - locale: PropTypes.any, - fullscreen: PropTypes.looseBool, - yearSelectOffset: PropTypes.number, - yearSelectTotal: PropTypes.number, - type: PropTypes.string, - value: { - type: Object as PropType, - }, - validRange: { - type: Array as PropType, - }, - headerRender: PropTypes.func, - onValueChange: PropTypes.func, - onTypeChange: PropTypes.func, -}; -export default defineComponent({ + const suffix = locale && locale.year === '年' ? '年' : ''; + const options: { label: string; value: number }[] = []; + for (let index = start; index < end; index++) { + options.push({ label: `${index}${suffix}`, value: index }); + } + return ( + { + onChange(generateConfig.setMonth(value, newMonth)); + }} + getPopupContainer={() => divRef!.value!} + /> + ); +} + +MonthSelect.inheritAttrs = false; + +interface ModeSwitchProps extends Omit, 'onChange'> { + mode: CalendarMode; + onModeChange: (type: CalendarMode) => void; +} + +function ModeSwitch(props: ModeSwitchProps) { + const { prefixCls, locale, mode, fullscreen, onModeChange } = props; + return ( + { + onModeChange(value); + }} + value={mode} + size={fullscreen ? undefined : 'small'} + class={`${prefixCls}-mode-switch`} + > + + + + ); +} +ModeSwitch.inheritAttrs = false; + +export interface CalendarHeaderProps { + prefixCls: string; + value: DateType; + validRange?: [DateType, DateType]; + generateConfig: GenerateConfig; + locale: Locale; + mode: CalendarMode; + fullscreen: boolean; + onChange: (date: DateType) => void; + onModeChange: (mode: CalendarMode) => void; +} + +export default defineComponent>({ name: 'CalendarHeader', inheritAttrs: false, - props: { - ...HeaderProps, - yearSelectOffset: PropTypes.number.def(10), - yearSelectTotal: PropTypes.number.def(20), - }, - setup() { - return { - configProvider: inject('configProvider', defaultConfigProvider), - calendarHeaderNode: undefined, + setup(_props, { attrs }) { + const divRef = ref(null); + return () => { + const { prefixCls, fullscreen, mode, onChange, onModeChange } = attrs; + const sharedProps = { + ...attrs, + onChange, + fullscreen, + divRef, + } as any; + + return ( +
+ + {mode === 'month' && } + +
+ ); }; }, - // private calendarHeaderNode: HTMLDivElement; - methods: { - getYearSelectElement(prefixCls: string, year: number) { - const { yearSelectOffset, yearSelectTotal, locale = {}, fullscreen, validRange } = this; - let start = year - yearSelectOffset; - let end = start + yearSelectTotal; - if (validRange) { - start = validRange[0].get('year'); - end = validRange[1].get('year') + 1; - } - const suffix = locale && locale.year === '年' ? '年' : ''; - const options: { label: string; value: number }[] = []; - for (let index = start; index < end; index++) { - options.push({ label: `${index}${suffix}`, value: index }); - } - return ( - - ); - }, - - getMonthSelectElement(prefixCls: string, month: number, months: string[]) { - const { fullscreen, validRange, value } = this; - let start = 0; - let end = 11; - if (validRange) { - const [rangeStart, rangeEnd] = validRange; - const currentYear = value.get('year'); - if (rangeEnd.get('year') === currentYear) { - end = rangeEnd.get('month') + 1; - } - if (rangeStart.get('year') === currentYear) { - start = rangeStart.get('month'); - } - } - const options: { label: string; value: number }[] = []; - for (let index = start; index <= end; index += 1) { - options.push({ - label: months[index], - value: index, - }); - } - - return ( - - ); - }, - - onYearChange(year: string) { - const { value, validRange } = this; - const newValue = value.clone(); - newValue.year(parseInt(year, 10)); - // switch the month so that it remains within range when year changes - if (validRange) { - const [start, end] = validRange; - const newYear = newValue.get('year'); - const newMonth = newValue.get('month'); - if (newYear === end.get('year') && newMonth > end.get('month')) { - newValue.month(end.get('month')); - } - if (newYear === start.get('year') && newMonth < start.get('month')) { - newValue.month(start.get('month')); - } - } - this.$emit('valueChange', newValue); - }, - - onMonthChange(month: string) { - const newValue = this.value.clone(); - newValue.month(parseInt(month, 10)); - this.$emit('valueChange', newValue); - }, - - onInternalTypeChange(e: RadioChangeEvent) { - this.triggerTypeChange(e.target.value); - }, - - triggerTypeChange(val: string) { - this.$emit('typeChange', val); - }, - getMonthYearSelections(getPrefixCls) { - const { prefixCls: customizePrefixCls, type, value } = this.$props; - - const prefixCls = getPrefixCls('fullcalendar', customizePrefixCls); - const yearReactNode = this.getYearSelectElement(prefixCls, value.year()); - const monthReactNode = - type === 'month' - ? this.getMonthSelectElement(prefixCls, value.month(), getMonthsLocale(value)) - : null; - return { - yearReactNode, - monthReactNode, - }; - }, - - getTypeSwitch() { - const { locale = {}, type, fullscreen } = this.$props; - const size = fullscreen ? 'default' : 'small'; - return ( - - - - - ); - }, - triggerValueChange(...args: any[]) { - this.$emit('valueChange', ...args); - }, - saveCalendarHeaderNode(node: HTMLElement) { - this.calendarHeaderNode = node; - }, - headerRenderCustom(headerRender: HeaderRender) { - const { type, value } = this.$props; - return headerRender({ - value, - type: type || 'month', - onChange: this.triggerValueChange, - onTypeChange: this.triggerTypeChange, - }); - }, - }, - - render() { - const { prefixCls: customizePrefixCls, headerRender } = this; - const getPrefixCls = this.configProvider.getPrefixCls; - const prefixCls = getPrefixCls('fullcalendar', customizePrefixCls); - const typeSwitch = this.getTypeSwitch(); - const { yearReactNode, monthReactNode } = this.getMonthYearSelections(getPrefixCls); - return headerRender ? ( - this.headerRenderCustom(headerRender) - ) : ( -
- {yearReactNode} - {monthReactNode} - {typeSwitch} -
- ); - }, }); diff --git a/components/calendar/date-fns.tsx b/components/calendar/date-fns.tsx new file mode 100644 index 000000000..d5496d151 --- /dev/null +++ b/components/calendar/date-fns.tsx @@ -0,0 +1,8 @@ +import generateConfig from '../vc-picker/generate/dateFns'; +import { withInstall } from '../_util/type'; +import generateCalendar, { CalendarProps } from './generateCalendar'; + +const Calendar = generateCalendar(generateConfig); + +export { CalendarProps }; +export default withInstall(Calendar); diff --git a/components/calendar/dayjs.tsx b/components/calendar/dayjs.tsx new file mode 100644 index 000000000..fc3222303 --- /dev/null +++ b/components/calendar/dayjs.tsx @@ -0,0 +1,9 @@ +import type { Dayjs } from 'dayjs'; +import generateConfig from '../vc-picker/generate/dayjs'; +import { withInstall } from '../_util/type'; +import generateCalendar, { CalendarProps } from './generateCalendar'; + +const Calendar = generateCalendar(generateConfig); + +export { CalendarProps }; +export default withInstall(Calendar); diff --git a/components/calendar/generateCalendar.tsx b/components/calendar/generateCalendar.tsx new file mode 100644 index 000000000..32ad27f0a --- /dev/null +++ b/components/calendar/generateCalendar.tsx @@ -0,0 +1,332 @@ +import useMergedState from '../_util/hooks/useMergedState'; +import padStart from 'lodash-es/padStart'; +import { PickerPanel } from '../vc-picker'; +import type { Locale } from '../vc-picker/interface'; +import type { GenerateConfig } from '../vc-picker/generate'; +import type { + PickerPanelBaseProps as RCPickerPanelBaseProps, + PickerPanelDateProps as RCPickerPanelDateProps, + PickerPanelTimeProps as RCPickerPanelTimeProps, +} from '../vc-picker/PickerPanel'; +import { useLocaleReceiver } from '../locale-provider/LocaleReceiver'; +import enUS from './locale/en_US'; +import CalendarHeader from './Header'; +import type { VueNode } from '../_util/type'; +import type { App } from 'vue'; +import { computed, defineComponent, toRef } from 'vue'; +import useConfigInject from '../_util/hooks/useConfigInject'; +import classNames from '../_util/classNames'; + +type InjectDefaultProps = Omit< + Props, + 'locale' | 'generateConfig' | 'prevIcon' | 'nextIcon' | 'superPrevIcon' | 'superNextIcon' +> & { + locale?: typeof enUS; + size?: 'large' | 'default' | 'small'; +}; + +// Picker Props +export type PickerPanelBaseProps = InjectDefaultProps>; +export type PickerPanelDateProps = InjectDefaultProps>; +export type PickerPanelTimeProps = InjectDefaultProps>; + +export type PickerProps = + | PickerPanelBaseProps + | PickerPanelDateProps + | PickerPanelTimeProps; + +export type CalendarMode = 'year' | 'month'; +export type HeaderRender = (config: { + value: DateType; + type: CalendarMode; + onChange: (date: DateType) => void; + onTypeChange: (type: CalendarMode) => void; +}) => VueNode; + +type CustomRenderType = (config: { current: DateType }) => VueNode; + +export interface CalendarProps { + prefixCls?: string; + locale?: typeof enUS; + validRange?: [DateType, DateType]; + disabledDate?: (date: DateType) => boolean; + dateFullCellRender?: CustomRenderType; + dateCellRender?: CustomRenderType; + monthFullCellRender?: CustomRenderType; + monthCellRender?: CustomRenderType; + headerRender?: HeaderRender; + value?: DateType | string; + defaultValue?: DateType | string; + mode?: CalendarMode; + fullscreen?: boolean; + onChange?: (date: DateType | string) => void; + onPanelChange?: (date: DateType | string, mode: CalendarMode) => void; + onSelect?: (date: DateType | string) => void; + valueFormat?: string; +} + +function generateCalendar(generateConfig: GenerateConfig) { + function isSameYear(date1: DateType, date2: DateType) { + return date1 && date2 && generateConfig.getYear(date1) === generateConfig.getYear(date2); + } + + function isSameMonth(date1: DateType, date2: DateType) { + return ( + isSameYear(date1, date2) && generateConfig.getMonth(date1) === generateConfig.getMonth(date2) + ); + } + + function isSameDate(date1: DateType, date2: DateType) { + return ( + isSameMonth(date1, date2) && generateConfig.getDate(date1) === generateConfig.getDate(date2) + ); + } + + const Calendar = defineComponent>({ + name: 'ACalendar', + inheritAttrs: false, + props: [ + 'prefixCls', + 'locale', + 'validRange', + 'disabledDate', + 'dateFullCellRender', + 'dateCellRender', + 'monthFullCellRender', + 'monthCellRender', + 'headerRender', + 'value', + 'defaultValue', + 'mode', + 'fullscreen', + 'onChange', + 'onPanelChange', + 'onSelect', + 'valueFormat', + ] as any, + emits: ['change', 'panelChange', 'select', 'update:value'], + slots: [ + 'dateFullCellRender', + 'dateCellRender', + 'monthFullCellRender', + 'monthCellRender', + 'headerRender', + ], + setup(props, { emit, slots, attrs }) { + const { prefixCls, direction } = useConfigInject('picker', props); + const calendarPrefixCls = computed(() => `${prefixCls.value}-calendar`); + const maybeToString = (date: DateType) => { + return props.valueFormat ? generateConfig.toString(date, props.valueFormat) : date; + }; + const value = computed(() => { + if (props.value) { + return props.valueFormat + ? (generateConfig.toDate(props.value, props.valueFormat) as DateType) + : (props.value as DateType); + } + return props.value as DateType; + }); + const defaultValue = computed(() => { + if (props.defaultValue) { + return props.valueFormat + ? (generateConfig.toDate(props.defaultValue, props.valueFormat) as DateType) + : (props.defaultValue as DateType); + } + return props.defaultValue as DateType; + }); + + // Value + const [mergedValue, setMergedValue] = useMergedState( + () => value.value || generateConfig.getNow(), + { + defaultValue: defaultValue.value, + value, + }, + ); + + // Mode + const [mergedMode, setMergedMode] = useMergedState('month', { + value: toRef(props, 'mode'), + }); + + const panelMode = computed(() => (mergedMode.value === 'year' ? 'month' : 'date')); + + const mergedDisabledDate = computed(() => { + return (date: DateType) => { + const notInRange = props.validRange + ? generateConfig.isAfter(props.validRange[0], date) || + generateConfig.isAfter(date, props.validRange[1]) + : false; + return notInRange || !!props.disabledDate?.(date); + }; + }); + + // ====================== Events ====================== + const triggerPanelChange = (date: DateType, newMode: CalendarMode) => { + emit('panelChange', maybeToString(date), newMode); + }; + + const triggerChange = (date: DateType) => { + setMergedValue(date); + + if (!isSameDate(date, mergedValue.value)) { + // Trigger when month panel switch month + if ( + (panelMode.value === 'date' && !isSameMonth(date, mergedValue.value)) || + (panelMode.value === 'month' && !isSameYear(date, mergedValue.value)) + ) { + triggerPanelChange(date, mergedMode.value); + } + const val = maybeToString(date); + emit('update:value', val); + emit('change', val); + } + }; + + const triggerModeChange = (newMode: CalendarMode) => { + setMergedMode(newMode); + triggerPanelChange(mergedValue.value, newMode); + }; + + const onInternalSelect = (date: DateType) => { + triggerChange(date); + emit('select', maybeToString(date)); + }; + // ====================== Locale ====================== + const defaultLocale = computed(() => { + const { locale } = props; + const result = { + ...enUS, + ...locale, + }; + result.lang = { + ...result.lang, + ...(locale || {}).lang, + }; + return result; + }); + + const [mergedLocale] = useLocaleReceiver('Calendar', defaultLocale) as [typeof defaultLocale]; + + return () => { + const today = generateConfig.getNow(); + const { + dateFullCellRender = slots?.dateFullCellRender, + dateCellRender = slots?.dateCellRender, + monthFullCellRender = slots?.monthFullCellRender, + monthCellRender = slots?.monthCellRender, + headerRender = slots?.headerRender, + fullscreen = true, + validRange, + } = props; + // ====================== Render ====================== + const dateRender = ({ current: date }) => { + if (dateFullCellRender) { + return dateFullCellRender({ current: date }); + } + return ( +
+
+ {padStart(String(generateConfig.getDate(date)), 2, '0')} +
+
+ {dateCellRender && dateCellRender({ current: date })} +
+
+ ); + }; + + const monthRender = ({ current: date }, locale: Locale) => { + if (monthFullCellRender) { + return monthFullCellRender({ current: date }); + } + + const months = locale.shortMonths || generateConfig.locale.getShortMonths!(locale.locale); + + return ( +
+
+ {months[generateConfig.getMonth(date)]} +
+
+ {monthCellRender && monthCellRender({ current: date })} +
+
+ ); + }; + return ( +
+ {headerRender ? ( + headerRender({ + value: mergedValue.value, + type: mergedMode.value, + onChange: onInternalSelect, + onTypeChange: triggerModeChange, + }) + ) : ( + + )} + + monthRender(obj, mergedLocale.value.lang)} + onSelect={onInternalSelect} + mode={panelMode.value} + picker={panelMode.value} + disabledDate={mergedDisabledDate.value} + hideHeader + /> +
+ ); + }; + }, + }); + Calendar.install = function (app: App) { + app.component(Calendar.name, Calendar); + return app; + }; + return Calendar; +} + +export default generateCalendar; diff --git a/components/calendar/index.tsx b/components/calendar/index.tsx index 6e7370d80..1d35db234 100644 --- a/components/calendar/index.tsx +++ b/components/calendar/index.tsx @@ -1,258 +1,4 @@ -import type { PropType } from 'vue'; -import { defineComponent, inject } from 'vue'; -import PropTypes from '../_util/vue-types'; -import BaseMixin from '../_util/BaseMixin'; -import { getOptionProps, hasProp } from '../_util/props-util'; -import moment from 'moment'; -import FullCalendar from '../vc-calendar/src/FullCalendar'; -import Header from './Header'; -import LocaleReceiver from '../locale-provider/LocaleReceiver'; -import interopDefault from '../_util/interopDefault'; -import { defaultConfigProvider } from '../config-provider'; -import enUS from './locale/en_US'; -import { checkValidate, stringToMoment, momentToString, TimeType } from '../_util/moment-util'; -import { tuple, withInstall } from '../_util/type'; +import Calendar from './dayjs'; +export * from './dayjs'; -function noop() { - return null; -} - -function zerofixed(v: number) { - if (v < 10) { - return `0${v}`; - } - return `${v}`; -} - -const CalendarModeTypes = tuple('month', 'year'); -export type CalendarMode = typeof CalendarModeTypes[number]; - -export const CalendarProps = { - monthCellRender: PropTypes.func, - dateCellRender: PropTypes.func, - monthFullCellRender: PropTypes.func, - dateFullCellRender: PropTypes.func, - prefixCls: PropTypes.string, - value: TimeType, - defaultValue: TimeType, - mode: PropTypes.oneOf(CalendarModeTypes), - fullscreen: PropTypes.looseBool.def(true), - locale: PropTypes.object.def({}), - disabledDate: PropTypes.func, - validRange: { - type: Array as PropType, - }, - headerRender: PropTypes.func, - valueFormat: PropTypes.string, - onPanelChange: PropTypes.func, - onSelect: PropTypes.func, - onChange: PropTypes.func, - 'onUpdate:value': PropTypes.func, -}; - -const Calendar = defineComponent({ - name: 'ACalendar', - mixins: [BaseMixin], - inheritAttrs: false, - props: CalendarProps, - setup() { - return { - configProvider: inject('configProvider', defaultConfigProvider), - sPrefixCls: undefined, - }; - }, - data() { - const { value, defaultValue, valueFormat } = this; - const sValue = value || defaultValue || interopDefault(moment)(); - checkValidate('Calendar', defaultValue, 'defaultValue', valueFormat); - checkValidate('Calendar', value, 'value', valueFormat); - return { - sValue: stringToMoment(sValue, valueFormat), - sMode: this.mode || 'month', - }; - }, - watch: { - value(val) { - checkValidate('Calendar', val, 'value', this.valueFormat); - this.setState({ - sValue: stringToMoment(val, this.valueFormat), - }); - }, - mode(val) { - this.setState({ - sMode: val, - }); - }, - }, - methods: { - onHeaderValueChange(value: moment.Moment) { - this.setValue(value, 'changePanel'); - }, - onHeaderTypeChange(mode: CalendarMode) { - this.sMode = mode; - this.triggerPanelChange(this.sValue, mode); - }, - triggerPanelChange(value: moment.Moment, mode: CalendarMode | undefined) { - const val = this.valueFormat ? momentToString(value, this.valueFormat) : value; - if (value !== this.sValue) { - this.$emit('update:value', val); - this.$emit('change', val); - } - this.$emit('panelChange', val, mode); - }, - - triggerSelect(value: moment.Moment) { - this.setValue(value, 'select'); - }, - setValue(value: moment.Moment, way: 'select' | 'changePanel') { - const prevValue = this.value ? stringToMoment(this.value, this.valueFormat) : this.sValue; - const { sMode: mode, valueFormat } = this; - if (!hasProp(this, 'value')) { - this.setState({ sValue: value }); - } - if (way === 'select') { - const val = valueFormat ? momentToString(value, valueFormat) : value; - if (prevValue && prevValue.month() !== value.month()) { - this.triggerPanelChange(value, mode); - } else { - this.$emit('update:value', val); - } - this.$emit('select', val); - } else if (way === 'changePanel') { - this.triggerPanelChange(value, mode); - } - }, - getDateRange( - validRange: [moment.Moment, moment.Moment], - disabledDate?: (current: moment.Moment) => boolean, - ) { - return (current: moment.Moment) => { - if (!current) { - return false; - } - const [startDate, endDate] = validRange; - const inRange = !current.isBetween(startDate, endDate, 'days', '[]'); - if (disabledDate) { - return disabledDate(current) || inRange; - } - return inRange; - }; - }, - getDefaultLocale() { - const result = { - ...enUS, - ...this.$props.locale, - }; - result.lang = { - ...result.lang, - ...(this.$props.locale || {}).lang, - }; - return result; - }, - monthCellRender2({ current: value }) { - const { sPrefixCls, $slots } = this; - const monthCellRender: Function = this.monthCellRender || $slots.monthCellRender || noop; - return ( -
-
{value.localeData().monthsShort(value)}
-
{monthCellRender({ current: value })}
-
- ); - }, - - dateCellRender2({ current: value }) { - const { sPrefixCls, $slots } = this; - const dateCellRender: Function = this.dateCellRender || $slots.dateCellRender || noop; - return ( -
-
{zerofixed(value.date())}
-
{dateCellRender({ current: value })}
-
- ); - }, - - renderCalendar(locale: any, localeCode: string) { - const props: any = { ...getOptionProps(this), ...this.$attrs }; - const { sValue: value, sMode: mode, $slots } = this; - if (value && localeCode) { - value.locale(localeCode); - } - const { - prefixCls: customizePrefixCls, - fullscreen, - dateFullCellRender, - monthFullCellRender, - class: className, - style, - } = props; - const headerRender = this.headerRender || $slots.headerRender; - const getPrefixCls = this.configProvider.getPrefixCls; - const prefixCls = getPrefixCls('fullcalendar', customizePrefixCls); - - // To support old version react. - // Have to add prefixCls on the instance. - // https://github.com/facebook/react/issues/12397 - this.sPrefixCls = prefixCls; - - let cls = className || ''; - if (fullscreen) { - cls += ` ${prefixCls}-fullscreen`; - } - - const monthCellRender = - monthFullCellRender || $slots.monthFullCellRender || this.monthCellRender2; - const dateCellRender = - dateFullCellRender || $slots.dateFullCellRender || this.dateCellRender2; - - let disabledDate = props.disabledDate; - - if (props.validRange) { - disabledDate = this.getDateRange(props.validRange, disabledDate); - } - const fullCalendarProps = { - ...props, - ...this.$attrs, - Select: {}, - locale: locale.lang, - type: mode === 'year' ? 'month' : 'date', - prefixCls, - showHeader: false, - value, - monthCellRender, - dateCellRender, - disabledDate, - onSelect: this.triggerSelect, - }; - return ( -
-
- -
- ); - }, - }, - - render() { - return ( - - ); - }, -}); - -export { HeaderProps } from './Header'; - -export default withInstall(Calendar); +export default Calendar; diff --git a/components/calendar/locale/ar_EG.ts b/components/calendar/locale/ar_EG.ts deleted file mode 100644 index f51f426ff..000000000 --- a/components/calendar/locale/ar_EG.ts +++ /dev/null @@ -1,2 +0,0 @@ -import ar_EG from '../../date-picker/locale/ar_EG'; -export default ar_EG; diff --git a/components/calendar/locale/ar_EG.tsx b/components/calendar/locale/ar_EG.tsx new file mode 100644 index 000000000..8eeec95e6 --- /dev/null +++ b/components/calendar/locale/ar_EG.tsx @@ -0,0 +1,3 @@ +import arEG from '../../date-picker/locale/ar_EG'; + +export default arEG; diff --git a/components/calendar/locale/az_AZ.tsx b/components/calendar/locale/az_AZ.tsx new file mode 100644 index 000000000..32463c68f --- /dev/null +++ b/components/calendar/locale/az_AZ.tsx @@ -0,0 +1,3 @@ +import azAZ from '../../date-picker/locale/az_AZ'; + +export default azAZ; diff --git a/components/calendar/locale/bg_BG.ts b/components/calendar/locale/bg_BG.ts deleted file mode 100644 index c9dd46118..000000000 --- a/components/calendar/locale/bg_BG.ts +++ /dev/null @@ -1,2 +0,0 @@ -import bg_BG from '../../date-picker/locale/bg_BG'; -export default bg_BG; diff --git a/components/calendar/locale/bg_BG.tsx b/components/calendar/locale/bg_BG.tsx new file mode 100644 index 000000000..25365c42b --- /dev/null +++ b/components/calendar/locale/bg_BG.tsx @@ -0,0 +1,3 @@ +import bgBG from '../../date-picker/locale/bg_BG'; + +export default bgBG; diff --git a/components/calendar/locale/by_BY.tsx b/components/calendar/locale/by_BY.tsx new file mode 100644 index 000000000..819063db0 --- /dev/null +++ b/components/calendar/locale/by_BY.tsx @@ -0,0 +1,3 @@ +import byBY from '../../date-picker/locale/by_BY'; + +export default byBY; diff --git a/components/calendar/locale/ca_ES.ts b/components/calendar/locale/ca_ES.ts deleted file mode 100644 index 25b2888ef..000000000 --- a/components/calendar/locale/ca_ES.ts +++ /dev/null @@ -1,2 +0,0 @@ -import ca_ES from '../../date-picker/locale/ca_ES'; -export default ca_ES; diff --git a/components/calendar/locale/ca_ES.tsx b/components/calendar/locale/ca_ES.tsx new file mode 100644 index 000000000..9110541ac --- /dev/null +++ b/components/calendar/locale/ca_ES.tsx @@ -0,0 +1,3 @@ +import caES from '../../date-picker/locale/ca_ES'; + +export default caES; diff --git a/components/calendar/locale/cs_CZ.ts b/components/calendar/locale/cs_CZ.ts deleted file mode 100644 index bfba281a9..000000000 --- a/components/calendar/locale/cs_CZ.ts +++ /dev/null @@ -1,2 +0,0 @@ -import cs_CZ from '../../date-picker/locale/cs_CZ'; -export default cs_CZ; diff --git a/components/calendar/locale/cs_CZ.tsx b/components/calendar/locale/cs_CZ.tsx new file mode 100644 index 000000000..fc609b958 --- /dev/null +++ b/components/calendar/locale/cs_CZ.tsx @@ -0,0 +1,3 @@ +import csCZ from '../../date-picker/locale/cs_CZ'; + +export default csCZ; diff --git a/components/calendar/locale/da_DK.ts b/components/calendar/locale/da_DK.ts deleted file mode 100644 index 4b20c4603..000000000 --- a/components/calendar/locale/da_DK.ts +++ /dev/null @@ -1,2 +0,0 @@ -import da_DK from '../../date-picker/locale/da_DK'; -export default da_DK; diff --git a/components/calendar/locale/da_DK.tsx b/components/calendar/locale/da_DK.tsx new file mode 100644 index 000000000..56baf76f7 --- /dev/null +++ b/components/calendar/locale/da_DK.tsx @@ -0,0 +1,3 @@ +import daDK from '../../date-picker/locale/da_DK'; + +export default daDK; diff --git a/components/calendar/locale/de_DE.ts b/components/calendar/locale/de_DE.ts deleted file mode 100644 index 652a9be31..000000000 --- a/components/calendar/locale/de_DE.ts +++ /dev/null @@ -1,2 +0,0 @@ -import de_DE from '../../date-picker/locale/de_DE'; -export default de_DE; diff --git a/components/calendar/locale/de_DE.tsx b/components/calendar/locale/de_DE.tsx new file mode 100644 index 000000000..bbd3f3224 --- /dev/null +++ b/components/calendar/locale/de_DE.tsx @@ -0,0 +1,3 @@ +import deDE from '../../date-picker/locale/de_DE'; + +export default deDE; diff --git a/components/calendar/locale/el_GR.ts b/components/calendar/locale/el_GR.ts deleted file mode 100644 index 4d665092a..000000000 --- a/components/calendar/locale/el_GR.ts +++ /dev/null @@ -1,2 +0,0 @@ -import el_GR from '../../date-picker/locale/el_GR'; -export default el_GR; diff --git a/components/calendar/locale/el_GR.tsx b/components/calendar/locale/el_GR.tsx new file mode 100644 index 000000000..631631198 --- /dev/null +++ b/components/calendar/locale/el_GR.tsx @@ -0,0 +1,3 @@ +import elGR from '../../date-picker/locale/el_GR'; + +export default elGR; diff --git a/components/calendar/locale/en_GB.ts b/components/calendar/locale/en_GB.ts deleted file mode 100644 index 0d081144e..000000000 --- a/components/calendar/locale/en_GB.ts +++ /dev/null @@ -1,2 +0,0 @@ -import en_GB from '../../date-picker/locale/en_GB'; -export default en_GB; diff --git a/components/calendar/locale/en_GB.tsx b/components/calendar/locale/en_GB.tsx new file mode 100644 index 000000000..e65d7ad14 --- /dev/null +++ b/components/calendar/locale/en_GB.tsx @@ -0,0 +1,3 @@ +import enGB from '../../date-picker/locale/en_GB'; + +export default enGB; diff --git a/components/calendar/locale/en_US.ts b/components/calendar/locale/en_US.ts deleted file mode 100644 index 6847cc35d..000000000 --- a/components/calendar/locale/en_US.ts +++ /dev/null @@ -1,2 +0,0 @@ -import en_US from '../../date-picker/locale/en_US'; -export default en_US; diff --git a/components/calendar/locale/en_US.tsx b/components/calendar/locale/en_US.tsx new file mode 100644 index 000000000..6772cec70 --- /dev/null +++ b/components/calendar/locale/en_US.tsx @@ -0,0 +1,3 @@ +import enUS from '../../date-picker/locale/en_US'; + +export default enUS; diff --git a/components/calendar/locale/es_ES.ts b/components/calendar/locale/es_ES.ts deleted file mode 100644 index 6270b85ad..000000000 --- a/components/calendar/locale/es_ES.ts +++ /dev/null @@ -1,2 +0,0 @@ -import es_ES from '../../date-picker/locale/es_ES'; -export default es_ES; diff --git a/components/calendar/locale/es_ES.tsx b/components/calendar/locale/es_ES.tsx new file mode 100644 index 000000000..597965960 --- /dev/null +++ b/components/calendar/locale/es_ES.tsx @@ -0,0 +1,3 @@ +import esES from '../../date-picker/locale/es_ES'; + +export default esES; diff --git a/components/calendar/locale/et_EE.ts b/components/calendar/locale/et_EE.ts deleted file mode 100644 index 47ad3e77f..000000000 --- a/components/calendar/locale/et_EE.ts +++ /dev/null @@ -1,2 +0,0 @@ -import et_EE from '../../date-picker/locale/et_EE'; -export default et_EE; diff --git a/components/calendar/locale/et_EE.tsx b/components/calendar/locale/et_EE.tsx new file mode 100644 index 000000000..0be6422b4 --- /dev/null +++ b/components/calendar/locale/et_EE.tsx @@ -0,0 +1,3 @@ +import etEE from '../../date-picker/locale/et_EE'; + +export default etEE; diff --git a/components/calendar/locale/fa_IR.ts b/components/calendar/locale/fa_IR.ts deleted file mode 100644 index 9aa9d1a34..000000000 --- a/components/calendar/locale/fa_IR.ts +++ /dev/null @@ -1,2 +0,0 @@ -import fa_IR from '../../date-picker/locale/fa_IR'; -export default fa_IR; diff --git a/components/calendar/locale/fa_IR.tsx b/components/calendar/locale/fa_IR.tsx new file mode 100644 index 000000000..8492d4d0a --- /dev/null +++ b/components/calendar/locale/fa_IR.tsx @@ -0,0 +1,3 @@ +import faIR from '../../date-picker/locale/fa_IR'; + +export default faIR; diff --git a/components/calendar/locale/fi_FI.ts b/components/calendar/locale/fi_FI.ts deleted file mode 100644 index b81ea8628..000000000 --- a/components/calendar/locale/fi_FI.ts +++ /dev/null @@ -1,2 +0,0 @@ -import fi_FI from '../../date-picker/locale/fi_FI'; -export default fi_FI; diff --git a/components/calendar/locale/fi_FI.tsx b/components/calendar/locale/fi_FI.tsx new file mode 100644 index 000000000..efbf028ef --- /dev/null +++ b/components/calendar/locale/fi_FI.tsx @@ -0,0 +1,3 @@ +import fiFI from '../../date-picker/locale/fi_FI'; + +export default fiFI; diff --git a/components/calendar/locale/fr_BE.ts b/components/calendar/locale/fr_BE.ts deleted file mode 100644 index 89560fc1f..000000000 --- a/components/calendar/locale/fr_BE.ts +++ /dev/null @@ -1,2 +0,0 @@ -import fr_BE from '../../date-picker/locale/fr_BE'; -export default fr_BE; diff --git a/components/calendar/locale/fr_BE.tsx b/components/calendar/locale/fr_BE.tsx new file mode 100644 index 000000000..d0e9f82d2 --- /dev/null +++ b/components/calendar/locale/fr_BE.tsx @@ -0,0 +1,3 @@ +import frBE from '../../date-picker/locale/fr_BE'; + +export default frBE; diff --git a/components/calendar/locale/fr_CA.tsx b/components/calendar/locale/fr_CA.tsx new file mode 100644 index 000000000..cee8645ca --- /dev/null +++ b/components/calendar/locale/fr_CA.tsx @@ -0,0 +1,3 @@ +import frCA from '../../date-picker/locale/fr_CA'; + +export default frCA; diff --git a/components/calendar/locale/fr_FR.ts b/components/calendar/locale/fr_FR.ts deleted file mode 100644 index 98c62aa75..000000000 --- a/components/calendar/locale/fr_FR.ts +++ /dev/null @@ -1,2 +0,0 @@ -import fr_FR from '../../date-picker/locale/fr_FR'; -export default fr_FR; diff --git a/components/calendar/locale/fr_FR.tsx b/components/calendar/locale/fr_FR.tsx new file mode 100644 index 000000000..19a1b853a --- /dev/null +++ b/components/calendar/locale/fr_FR.tsx @@ -0,0 +1,3 @@ +import frFR from '../../date-picker/locale/fr_FR'; + +export default frFR; diff --git a/components/calendar/locale/ga_IE.ts b/components/calendar/locale/ga_IE.ts deleted file mode 100644 index fe10dd1de..000000000 --- a/components/calendar/locale/ga_IE.ts +++ /dev/null @@ -1,3 +0,0 @@ -import ga_IE from '../../date-picker/locale/ga_IE'; - -export default ga_IE; diff --git a/components/calendar/locale/ga_IE.tsx b/components/calendar/locale/ga_IE.tsx new file mode 100644 index 000000000..8d1f76d1d --- /dev/null +++ b/components/calendar/locale/ga_IE.tsx @@ -0,0 +1,3 @@ +import gaIE from '../../date-picker/locale/ga_IE'; + +export default gaIE; diff --git a/components/calendar/locale/gl_ES.tsx b/components/calendar/locale/gl_ES.tsx new file mode 100644 index 000000000..0f777fd0b --- /dev/null +++ b/components/calendar/locale/gl_ES.tsx @@ -0,0 +1,3 @@ +import glES from '../../date-picker/locale/gl_ES'; + +export default glES; diff --git a/components/calendar/locale/he_IL.ts b/components/calendar/locale/he_IL.ts deleted file mode 100644 index 740b2b40b..000000000 --- a/components/calendar/locale/he_IL.ts +++ /dev/null @@ -1,2 +0,0 @@ -import he_IL from '../../date-picker/locale/he_IL'; -export default he_IL; diff --git a/components/calendar/locale/he_IL.tsx b/components/calendar/locale/he_IL.tsx new file mode 100644 index 000000000..2394acf8b --- /dev/null +++ b/components/calendar/locale/he_IL.tsx @@ -0,0 +1,3 @@ +import heIL from '../../date-picker/locale/he_IL'; + +export default heIL; diff --git a/components/calendar/locale/hi_IN.ts b/components/calendar/locale/hi_IN.ts deleted file mode 100644 index fea69a566..000000000 --- a/components/calendar/locale/hi_IN.ts +++ /dev/null @@ -1,2 +0,0 @@ -import hi_IN from '../../date-picker/locale/hi_IN'; -export default hi_IN; diff --git a/components/calendar/locale/hi_IN.tsx b/components/calendar/locale/hi_IN.tsx new file mode 100644 index 000000000..95f1190f6 --- /dev/null +++ b/components/calendar/locale/hi_IN.tsx @@ -0,0 +1,3 @@ +import hiIN from '../../date-picker/locale/hi_IN'; + +export default hiIN; diff --git a/components/calendar/locale/hr_HR.ts b/components/calendar/locale/hr_HR.ts deleted file mode 100644 index 74f31c747..000000000 --- a/components/calendar/locale/hr_HR.ts +++ /dev/null @@ -1,3 +0,0 @@ -import hr_HR from '../../date-picker/locale/hr_HR'; - -export default hr_HR; diff --git a/components/calendar/locale/hr_HR.tsx b/components/calendar/locale/hr_HR.tsx new file mode 100644 index 000000000..62e5c6845 --- /dev/null +++ b/components/calendar/locale/hr_HR.tsx @@ -0,0 +1,3 @@ +import hrHR from '../../date-picker/locale/hr_HR'; + +export default hrHR; diff --git a/components/calendar/locale/hu_HU.ts b/components/calendar/locale/hu_HU.ts deleted file mode 100644 index 0c5853800..000000000 --- a/components/calendar/locale/hu_HU.ts +++ /dev/null @@ -1,2 +0,0 @@ -import hu_HU from '../../date-picker/locale/hu_HU'; -export default hu_HU; diff --git a/components/calendar/locale/hu_HU.tsx b/components/calendar/locale/hu_HU.tsx new file mode 100644 index 000000000..8efd5af18 --- /dev/null +++ b/components/calendar/locale/hu_HU.tsx @@ -0,0 +1,3 @@ +import huHU from '../../date-picker/locale/hu_HU'; + +export default huHU; diff --git a/components/calendar/locale/id_ID.ts b/components/calendar/locale/id_ID.ts deleted file mode 100644 index 494bcf4a5..000000000 --- a/components/calendar/locale/id_ID.ts +++ /dev/null @@ -1,2 +0,0 @@ -import id_ID from '../../date-picker/locale/id_ID'; -export default id_ID; diff --git a/components/calendar/locale/id_ID.tsx b/components/calendar/locale/id_ID.tsx new file mode 100644 index 000000000..fd07285d8 --- /dev/null +++ b/components/calendar/locale/id_ID.tsx @@ -0,0 +1,3 @@ +import idID from '../../date-picker/locale/id_ID'; + +export default idID; diff --git a/components/calendar/locale/is_IS.ts b/components/calendar/locale/is_IS.ts deleted file mode 100644 index a9524638e..000000000 --- a/components/calendar/locale/is_IS.ts +++ /dev/null @@ -1,2 +0,0 @@ -import is_IS from '../../date-picker/locale/is_IS'; -export default is_IS; diff --git a/components/calendar/locale/is_IS.tsx b/components/calendar/locale/is_IS.tsx new file mode 100644 index 000000000..577f17f9e --- /dev/null +++ b/components/calendar/locale/is_IS.tsx @@ -0,0 +1,3 @@ +import isIS from '../../date-picker/locale/is_IS'; + +export default isIS; diff --git a/components/calendar/locale/it_IT.ts b/components/calendar/locale/it_IT.ts deleted file mode 100644 index 907792ffb..000000000 --- a/components/calendar/locale/it_IT.ts +++ /dev/null @@ -1,2 +0,0 @@ -import it_IT from '../../date-picker/locale/it_IT'; -export default it_IT; diff --git a/components/calendar/locale/it_IT.tsx b/components/calendar/locale/it_IT.tsx new file mode 100644 index 000000000..70772595c --- /dev/null +++ b/components/calendar/locale/it_IT.tsx @@ -0,0 +1,3 @@ +import itIT from '../../date-picker/locale/it_IT'; + +export default itIT; diff --git a/components/calendar/locale/ja_JP.ts b/components/calendar/locale/ja_JP.ts deleted file mode 100644 index 05ebc1440..000000000 --- a/components/calendar/locale/ja_JP.ts +++ /dev/null @@ -1,2 +0,0 @@ -import ja_JP from '../../date-picker/locale/ja_JP'; -export default ja_JP; diff --git a/components/calendar/locale/ja_JP.tsx b/components/calendar/locale/ja_JP.tsx new file mode 100644 index 000000000..c07227935 --- /dev/null +++ b/components/calendar/locale/ja_JP.tsx @@ -0,0 +1,3 @@ +import jaJP from '../../date-picker/locale/ja_JP'; + +export default jaJP; diff --git a/components/calendar/locale/kk_KZ.tsx b/components/calendar/locale/kk_KZ.tsx new file mode 100644 index 000000000..c8abdfdc9 --- /dev/null +++ b/components/calendar/locale/kk_KZ.tsx @@ -0,0 +1,3 @@ +import kkKZ from '../../date-picker/locale/kk_KZ'; + +export default kkKZ; diff --git a/components/calendar/locale/kmr_IQ.tsx b/components/calendar/locale/kmr_IQ.tsx new file mode 100755 index 000000000..6d467b300 --- /dev/null +++ b/components/calendar/locale/kmr_IQ.tsx @@ -0,0 +1,3 @@ +import kmrIQ from '../../date-picker/locale/kmr_IQ'; + +export default kmrIQ; diff --git a/components/calendar/locale/kn_IN.ts b/components/calendar/locale/kn_IN.ts deleted file mode 100644 index 958c45a7b..000000000 --- a/components/calendar/locale/kn_IN.ts +++ /dev/null @@ -1,2 +0,0 @@ -import kn_IN from '../../date-picker/locale/kn_IN'; -export default kn_IN; diff --git a/components/calendar/locale/kn_IN.tsx b/components/calendar/locale/kn_IN.tsx new file mode 100644 index 000000000..8a3edf6a9 --- /dev/null +++ b/components/calendar/locale/kn_IN.tsx @@ -0,0 +1,3 @@ +import knIN from '../../date-picker/locale/kn_IN'; + +export default knIN; diff --git a/components/calendar/locale/ko_KR.ts b/components/calendar/locale/ko_KR.ts deleted file mode 100644 index dc0e5ebdb..000000000 --- a/components/calendar/locale/ko_KR.ts +++ /dev/null @@ -1,2 +0,0 @@ -import ko_KR from '../../date-picker/locale/ko_KR'; -export default ko_KR; diff --git a/components/calendar/locale/ko_KR.tsx b/components/calendar/locale/ko_KR.tsx new file mode 100644 index 000000000..547cd09b1 --- /dev/null +++ b/components/calendar/locale/ko_KR.tsx @@ -0,0 +1,3 @@ +import koKR from '../../date-picker/locale/ko_KR'; + +export default koKR; diff --git a/components/calendar/locale/ku_IQ.ts b/components/calendar/locale/ku_IQ.ts deleted file mode 100755 index f491af31e..000000000 --- a/components/calendar/locale/ku_IQ.ts +++ /dev/null @@ -1,2 +0,0 @@ -import ku_IQ from '../../date-picker/locale/ku_IQ'; -export default ku_IQ; diff --git a/components/calendar/locale/ku_KU.ts b/components/calendar/locale/ku_KU.ts deleted file mode 100644 index bca7f1e84..000000000 --- a/components/calendar/locale/ku_KU.ts +++ /dev/null @@ -1,2 +0,0 @@ -import ku_KU from '../../date-picker/locale/ku_KU'; -export default ku_KU; diff --git a/components/calendar/locale/lt_LT.tsx b/components/calendar/locale/lt_LT.tsx new file mode 100644 index 000000000..f8bd2a535 --- /dev/null +++ b/components/calendar/locale/lt_LT.tsx @@ -0,0 +1,3 @@ +import ltLT from '../../date-picker/locale/lt_LT'; + +export default ltLT; diff --git a/components/calendar/locale/lv_LV.ts b/components/calendar/locale/lv_LV.ts deleted file mode 100644 index dcec39362..000000000 --- a/components/calendar/locale/lv_LV.ts +++ /dev/null @@ -1,3 +0,0 @@ -import lv_LV from '../../date-picker/locale/lv_LV'; - -export default lv_LV; diff --git a/components/calendar/locale/lv_LV.tsx b/components/calendar/locale/lv_LV.tsx new file mode 100644 index 000000000..10548b1e9 --- /dev/null +++ b/components/calendar/locale/lv_LV.tsx @@ -0,0 +1,3 @@ +import lvLV from '../../date-picker/locale/lv_LV'; + +export default lvLV; diff --git a/components/calendar/locale/mk_MK.ts b/components/calendar/locale/mk_MK.ts deleted file mode 100644 index d8881c804..000000000 --- a/components/calendar/locale/mk_MK.ts +++ /dev/null @@ -1,3 +0,0 @@ -import mk_MK from '../../date-picker/locale/mk_MK'; - -export default mk_MK; diff --git a/components/calendar/locale/mk_MK.tsx b/components/calendar/locale/mk_MK.tsx new file mode 100644 index 000000000..002db7790 --- /dev/null +++ b/components/calendar/locale/mk_MK.tsx @@ -0,0 +1,3 @@ +import mkMK from '../../date-picker/locale/mk_MK'; + +export default mkMK; diff --git a/components/calendar/locale/mn_MN.ts b/components/calendar/locale/mn_MN.ts deleted file mode 100644 index 1eba89e09..000000000 --- a/components/calendar/locale/mn_MN.ts +++ /dev/null @@ -1,2 +0,0 @@ -import mn_MN from '../../date-picker/locale/mn_MN'; -export default mn_MN; diff --git a/components/calendar/locale/mn_MN.tsx b/components/calendar/locale/mn_MN.tsx new file mode 100644 index 000000000..7003e2100 --- /dev/null +++ b/components/calendar/locale/mn_MN.tsx @@ -0,0 +1,3 @@ +import mnMN from '../../date-picker/locale/mn_MN'; + +export default mnMN; diff --git a/components/calendar/locale/ms_MY.ts b/components/calendar/locale/ms_MY.ts deleted file mode 100644 index f8f248792..000000000 --- a/components/calendar/locale/ms_MY.ts +++ /dev/null @@ -1,3 +0,0 @@ -import ms_MY from '../../date-picker/locale/ms_MY'; - -export default ms_MY; diff --git a/components/calendar/locale/ms_MY.tsx b/components/calendar/locale/ms_MY.tsx new file mode 100644 index 000000000..f5a72389c --- /dev/null +++ b/components/calendar/locale/ms_MY.tsx @@ -0,0 +1,3 @@ +import msMY from '../../date-picker/locale/ms_MY'; + +export default msMY; diff --git a/components/calendar/locale/nb_NO.ts b/components/calendar/locale/nb_NO.ts deleted file mode 100644 index f7417e06d..000000000 --- a/components/calendar/locale/nb_NO.ts +++ /dev/null @@ -1,2 +0,0 @@ -import nb_NO from '../../date-picker/locale/nb_NO'; -export default nb_NO; diff --git a/components/calendar/locale/nb_NO.tsx b/components/calendar/locale/nb_NO.tsx new file mode 100644 index 000000000..633b0a329 --- /dev/null +++ b/components/calendar/locale/nb_NO.tsx @@ -0,0 +1,3 @@ +import nbNO from '../../date-picker/locale/nb_NO'; + +export default nbNO; diff --git a/components/calendar/locale/nl_BE.ts b/components/calendar/locale/nl_BE.ts deleted file mode 100644 index 7f36785fe..000000000 --- a/components/calendar/locale/nl_BE.ts +++ /dev/null @@ -1,2 +0,0 @@ -import nl_BE from '../../date-picker/locale/nl_BE'; -export default nl_BE; diff --git a/components/calendar/locale/nl_BE.tsx b/components/calendar/locale/nl_BE.tsx new file mode 100644 index 000000000..d1090f4d2 --- /dev/null +++ b/components/calendar/locale/nl_BE.tsx @@ -0,0 +1,3 @@ +import nlBE from '../../date-picker/locale/nl_BE'; + +export default nlBE; diff --git a/components/calendar/locale/nl_NL.ts b/components/calendar/locale/nl_NL.ts deleted file mode 100644 index cdf131aa3..000000000 --- a/components/calendar/locale/nl_NL.ts +++ /dev/null @@ -1,2 +0,0 @@ -import nl_NL from '../../date-picker/locale/nl_NL'; -export default nl_NL; diff --git a/components/calendar/locale/nl_NL.tsx b/components/calendar/locale/nl_NL.tsx new file mode 100644 index 000000000..29969dcbe --- /dev/null +++ b/components/calendar/locale/nl_NL.tsx @@ -0,0 +1,3 @@ +import nlNL from '../../date-picker/locale/nl_NL'; + +export default nlNL; diff --git a/components/calendar/locale/pl_PL.ts b/components/calendar/locale/pl_PL.ts deleted file mode 100644 index c309a788b..000000000 --- a/components/calendar/locale/pl_PL.ts +++ /dev/null @@ -1,2 +0,0 @@ -import pl_PL from '../../date-picker/locale/pl_PL'; -export default pl_PL; diff --git a/components/calendar/locale/pl_PL.tsx b/components/calendar/locale/pl_PL.tsx new file mode 100644 index 000000000..421d087c5 --- /dev/null +++ b/components/calendar/locale/pl_PL.tsx @@ -0,0 +1,3 @@ +import plPL from '../../date-picker/locale/pl_PL'; + +export default plPL; diff --git a/components/calendar/locale/pt_BR.ts b/components/calendar/locale/pt_BR.ts deleted file mode 100644 index 2908a36dc..000000000 --- a/components/calendar/locale/pt_BR.ts +++ /dev/null @@ -1,2 +0,0 @@ -import pt_BR from '../../date-picker/locale/pt_BR'; -export default pt_BR; diff --git a/components/calendar/locale/pt_BR.tsx b/components/calendar/locale/pt_BR.tsx new file mode 100644 index 000000000..3d1c1c20d --- /dev/null +++ b/components/calendar/locale/pt_BR.tsx @@ -0,0 +1,3 @@ +import ptBR from '../../date-picker/locale/pt_BR'; + +export default ptBR; diff --git a/components/calendar/locale/pt_PT.ts b/components/calendar/locale/pt_PT.ts deleted file mode 100644 index c3aebf364..000000000 --- a/components/calendar/locale/pt_PT.ts +++ /dev/null @@ -1,2 +0,0 @@ -import pt_PT from '../../date-picker/locale/pt_PT'; -export default pt_PT; diff --git a/components/calendar/locale/pt_PT.tsx b/components/calendar/locale/pt_PT.tsx new file mode 100644 index 000000000..31aacbdc5 --- /dev/null +++ b/components/calendar/locale/pt_PT.tsx @@ -0,0 +1,3 @@ +import ptPT from '../../date-picker/locale/pt_PT'; + +export default ptPT; diff --git a/components/calendar/locale/ro_RO.ts b/components/calendar/locale/ro_RO.ts deleted file mode 100644 index e4e9ec0c3..000000000 --- a/components/calendar/locale/ro_RO.ts +++ /dev/null @@ -1,3 +0,0 @@ -import ro_RO from '../../date-picker/locale/ro_RO'; - -export default ro_RO; diff --git a/components/calendar/locale/ro_RO.tsx b/components/calendar/locale/ro_RO.tsx new file mode 100644 index 000000000..b399e36dd --- /dev/null +++ b/components/calendar/locale/ro_RO.tsx @@ -0,0 +1,3 @@ +import roRO from '../../date-picker/locale/ro_RO'; + +export default roRO; diff --git a/components/calendar/locale/ru_RU.ts b/components/calendar/locale/ru_RU.ts deleted file mode 100644 index c1feaedae..000000000 --- a/components/calendar/locale/ru_RU.ts +++ /dev/null @@ -1,2 +0,0 @@ -import ru_RU from '../../date-picker/locale/ru_RU'; -export default ru_RU; diff --git a/components/calendar/locale/ru_RU.tsx b/components/calendar/locale/ru_RU.tsx new file mode 100644 index 000000000..31023b72e --- /dev/null +++ b/components/calendar/locale/ru_RU.tsx @@ -0,0 +1,3 @@ +import ruRU from '../../date-picker/locale/ru_RU'; + +export default ruRU; diff --git a/components/calendar/locale/sk_SK.ts b/components/calendar/locale/sk_SK.ts deleted file mode 100644 index 3e9a32d8c..000000000 --- a/components/calendar/locale/sk_SK.ts +++ /dev/null @@ -1,2 +0,0 @@ -import sk_SK from '../../date-picker/locale/sk_SK'; -export default sk_SK; diff --git a/components/calendar/locale/sk_SK.tsx b/components/calendar/locale/sk_SK.tsx new file mode 100644 index 000000000..0427815a2 --- /dev/null +++ b/components/calendar/locale/sk_SK.tsx @@ -0,0 +1,3 @@ +import skSK from '../../date-picker/locale/sk_SK'; + +export default skSK; diff --git a/components/calendar/locale/sl_SI.ts b/components/calendar/locale/sl_SI.ts deleted file mode 100644 index a97c3f9a8..000000000 --- a/components/calendar/locale/sl_SI.ts +++ /dev/null @@ -1,2 +0,0 @@ -import sl_SI from '../../date-picker/locale/sl_SI'; -export default sl_SI; diff --git a/components/calendar/locale/sl_SI.tsx b/components/calendar/locale/sl_SI.tsx new file mode 100644 index 000000000..e51693779 --- /dev/null +++ b/components/calendar/locale/sl_SI.tsx @@ -0,0 +1,3 @@ +import slSI from '../../date-picker/locale/sl_SI'; + +export default slSI; diff --git a/components/calendar/locale/sr_RS.ts b/components/calendar/locale/sr_RS.ts deleted file mode 100644 index ae46beb97..000000000 --- a/components/calendar/locale/sr_RS.ts +++ /dev/null @@ -1,2 +0,0 @@ -import sr_RS from '../../date-picker/locale/sr_RS'; -export default sr_RS; diff --git a/components/calendar/locale/sr_RS.tsx b/components/calendar/locale/sr_RS.tsx new file mode 100644 index 000000000..73978d3a9 --- /dev/null +++ b/components/calendar/locale/sr_RS.tsx @@ -0,0 +1,3 @@ +import srRS from '../../date-picker/locale/sr_RS'; + +export default srRS; diff --git a/components/calendar/locale/sv_SE.ts b/components/calendar/locale/sv_SE.ts deleted file mode 100644 index b9e4c3e5d..000000000 --- a/components/calendar/locale/sv_SE.ts +++ /dev/null @@ -1,2 +0,0 @@ -import sv_SE from '../../date-picker/locale/sv_SE'; -export default sv_SE; diff --git a/components/calendar/locale/sv_SE.tsx b/components/calendar/locale/sv_SE.tsx new file mode 100644 index 000000000..20d753709 --- /dev/null +++ b/components/calendar/locale/sv_SE.tsx @@ -0,0 +1,3 @@ +import svSE from '../../date-picker/locale/sv_SE'; + +export default svSE; diff --git a/components/calendar/locale/ta_IN.ts b/components/calendar/locale/ta_IN.ts deleted file mode 100644 index 560961645..000000000 --- a/components/calendar/locale/ta_IN.ts +++ /dev/null @@ -1,3 +0,0 @@ -import ta_IN from '../../date-picker/locale/ta_IN'; - -export default ta_IN; diff --git a/components/calendar/locale/ta_IN.tsx b/components/calendar/locale/ta_IN.tsx new file mode 100644 index 000000000..aea0fabf2 --- /dev/null +++ b/components/calendar/locale/ta_IN.tsx @@ -0,0 +1,3 @@ +import taIN from '../../date-picker/locale/ta_IN'; + +export default taIN; diff --git a/components/calendar/locale/th_TH.ts b/components/calendar/locale/th_TH.ts deleted file mode 100644 index 62bbf4776..000000000 --- a/components/calendar/locale/th_TH.ts +++ /dev/null @@ -1,2 +0,0 @@ -import th_TH from '../../date-picker/locale/th_TH'; -export default th_TH; diff --git a/components/calendar/locale/th_TH.tsx b/components/calendar/locale/th_TH.tsx new file mode 100644 index 000000000..0277ec701 --- /dev/null +++ b/components/calendar/locale/th_TH.tsx @@ -0,0 +1,3 @@ +import thTH from '../../date-picker/locale/th_TH'; + +export default thTH; diff --git a/components/calendar/locale/tr_TR.ts b/components/calendar/locale/tr_TR.ts deleted file mode 100644 index d5ba572d4..000000000 --- a/components/calendar/locale/tr_TR.ts +++ /dev/null @@ -1,2 +0,0 @@ -import tr_TR from '../../date-picker/locale/tr_TR'; -export default tr_TR; diff --git a/components/calendar/locale/tr_TR.tsx b/components/calendar/locale/tr_TR.tsx new file mode 100644 index 000000000..06277224d --- /dev/null +++ b/components/calendar/locale/tr_TR.tsx @@ -0,0 +1,3 @@ +import trTR from '../../date-picker/locale/tr_TR'; + +export default trTR; diff --git a/components/calendar/locale/uk_UA.ts b/components/calendar/locale/uk_UA.ts deleted file mode 100644 index b27523dd7..000000000 --- a/components/calendar/locale/uk_UA.ts +++ /dev/null @@ -1,2 +0,0 @@ -import uk_UA from '../../date-picker/locale/uk_UA'; -export default uk_UA; diff --git a/components/calendar/locale/uk_UA.tsx b/components/calendar/locale/uk_UA.tsx new file mode 100644 index 000000000..3b72ee47c --- /dev/null +++ b/components/calendar/locale/uk_UA.tsx @@ -0,0 +1,3 @@ +import ukUA from '../../date-picker/locale/uk_UA'; + +export default ukUA; diff --git a/components/calendar/locale/vi_VN.ts b/components/calendar/locale/vi_VN.ts deleted file mode 100644 index 0579ee2e6..000000000 --- a/components/calendar/locale/vi_VN.ts +++ /dev/null @@ -1,2 +0,0 @@ -import vi_VN from '../../date-picker/locale/vi_VN'; -export default vi_VN; diff --git a/components/calendar/locale/vi_VN.tsx b/components/calendar/locale/vi_VN.tsx new file mode 100644 index 000000000..4043ea8b9 --- /dev/null +++ b/components/calendar/locale/vi_VN.tsx @@ -0,0 +1,3 @@ +import viVN from '../../date-picker/locale/vi_VN'; + +export default viVN; diff --git a/components/calendar/locale/zh_CN.ts b/components/calendar/locale/zh_CN.ts deleted file mode 100644 index 9c83ec845..000000000 --- a/components/calendar/locale/zh_CN.ts +++ /dev/null @@ -1,2 +0,0 @@ -import zh_CN from '../../date-picker/locale/zh_CN'; -export default zh_CN; diff --git a/components/calendar/locale/zh_CN.tsx b/components/calendar/locale/zh_CN.tsx new file mode 100644 index 000000000..d185efc2f --- /dev/null +++ b/components/calendar/locale/zh_CN.tsx @@ -0,0 +1,3 @@ +import zhCN from '../../date-picker/locale/zh_CN'; + +export default zhCN; diff --git a/components/calendar/locale/zh_TW.ts b/components/calendar/locale/zh_TW.ts deleted file mode 100644 index 2fa73ae62..000000000 --- a/components/calendar/locale/zh_TW.ts +++ /dev/null @@ -1,2 +0,0 @@ -import zh_TW from '../../date-picker/locale/zh_TW'; -export default zh_TW; diff --git a/components/calendar/locale/zh_TW.tsx b/components/calendar/locale/zh_TW.tsx new file mode 100644 index 000000000..1fa8867a9 --- /dev/null +++ b/components/calendar/locale/zh_TW.tsx @@ -0,0 +1,3 @@ +import zhTW from '../../date-picker/locale/zh_TW'; + +export default zhTW; diff --git a/components/calendar/moment.tsx b/components/calendar/moment.tsx new file mode 100644 index 000000000..4acc05a03 --- /dev/null +++ b/components/calendar/moment.tsx @@ -0,0 +1,9 @@ +import type { Moment } from 'moment'; +import generateConfig from '../vc-picker/generate/moment'; +import { withInstall } from '../_util/type'; +import generateCalendar, { CalendarProps } from './generateCalendar'; + +const Calendar = generateCalendar(generateConfig); + +export { CalendarProps }; +export default withInstall(Calendar); diff --git a/components/calendar/style/index.less b/components/calendar/style/index.less index ad73b5e43..af0e8a4a6 100644 --- a/components/calendar/style/index.less +++ b/components/calendar/style/index.less @@ -1,278 +1,192 @@ @import '../../style/themes/index'; @import '../../style/mixins/index'; -@full-calendar-prefix-cls: ~'@{ant-prefix}-fullcalendar'; +@calendar-prefix-cls: ~'@{ant-prefix}-picker-calendar'; +@calendar-picker-prefix-cls: ~'@{ant-prefix}-picker'; -.@{full-calendar-prefix-cls} { +.@{calendar-prefix-cls} { .reset-component(); + background: @calendar-full-bg; - border-top: @border-width-base @border-style-base @border-color-base; - outline: none; - - .@{ant-prefix}-select&-year-select { - min-width: 80px; - - &.@{ant-prefix}-select-sm { - min-width: 70px; - } - } - - .@{ant-prefix}-select&-month-select { - min-width: 80px; - margin-left: 8px; - - &.@{ant-prefix}-select-sm { - min-width: 70px; - } - } - + // ========================= Header ========================= &-header { - padding: 11px 16px 11px 0; - text-align: right; + display: flex; + justify-content: flex-end; + padding: @padding-sm 0; - .@{ant-prefix}-select-dropdown { - text-align: left; + .@{calendar-prefix-cls}-year-select { + min-width: 80px; } - .@{ant-prefix}-radio-group { - margin-left: 8px; - text-align: left; + .@{calendar-prefix-cls}-month-select { + min-width: 70px; + margin-left: @padding-xs; } - label.@{ant-prefix}-radio-button { - height: 22px; - padding: 0 10px; - line-height: 20px; + .@{calendar-prefix-cls}-mode-switch { + margin-left: @padding-xs; } } - &-date-panel { - position: relative; - outline: none; - } - - &-calendar-body { - padding: 8px 12px; - } - - table { - width: 100%; - max-width: 100%; - height: 256px; - background-color: transparent; - border-collapse: collapse; - } - - table, - th, - td { + .@{calendar-picker-prefix-cls}-panel { + background: @calendar-full-panel-bg; border: 0; - } - - td { - position: relative; - } - - &-calendar-table { - margin-bottom: 0; - border-spacing: 0; - } - - &-column-header { - width: 33px; - padding: 0; - line-height: 18px; - text-align: center; - .@{full-calendar-prefix-cls}-column-header-inner { - display: block; - font-weight: normal; - } - } - - &-week-number-header { - .@{full-calendar-prefix-cls}-column-header-inner { - display: none; - } - } - - &-month, - &-date { - text-align: center; - transition: all 0.3s; - } - - &-value { - display: block; - width: 24px; - height: 24px; - margin: 0 auto; - padding: 0; - color: @text-color; - line-height: 24px; - background: transparent; - border-radius: @border-radius-sm; - transition: all 0.3s; - - &:hover { - background: @item-hover-bg; - cursor: pointer; - } - - &:active { - color: @text-color-inverse; - background: @primary-color; - } - } - - &-month-panel-cell &-value { - width: 48px; - } - - &-today &-value, - &-month-panel-current-cell &-value { - box-shadow: 0 0 0 1px @primary-color inset; - } - - &-selected-day &-value, - &-month-panel-selected-cell &-value { - color: @text-color-inverse; - background: @primary-color; - } - - &-disabled-cell-first-of-row &-value { - border-top-left-radius: @border-radius-base; - border-bottom-left-radius: @border-radius-base; - } - - &-disabled-cell-last-of-row &-value { - border-top-right-radius: @border-radius-base; - border-bottom-right-radius: @border-radius-base; - } - - &-last-month-cell &-value, - &-next-month-btn-day &-value { - color: @disabled-color; - } - - &-month-panel-table { - width: 100%; - table-layout: fixed; - border-collapse: separate; - } - - &-content { - position: absolute; - bottom: -9px; - left: 0; - width: 100%; - } - - &-fullscreen { - border-top: 0; - } - - &-fullscreen &-table { - table-layout: fixed; - } - - &-fullscreen &-header { - .@{ant-prefix}-radio-group { - margin-left: 16px; - } - label.@{ant-prefix}-radio-button { - height: @input-height-base; - line-height: @input-height-base - 2px; - } - } - - &-fullscreen &-month, - &-fullscreen &-date { - display: block; - height: 116px; - margin: 0 4px; - padding: 4px 8px; - color: @text-color; - text-align: left; - border-top: 2px solid @border-color-split; - transition: background 0.3s; - - &:hover { - background: @item-hover-bg; - cursor: pointer; - } - - &:active { - background: @primary-2; - } - } - - &-fullscreen &-column-header { - padding-right: 12px; - padding-bottom: 5px; - text-align: right; - } - - &-fullscreen &-value { - width: auto; - text-align: right; - background: transparent; - } - - &-fullscreen &-today &-value { - color: @text-color; - } - - &-fullscreen &-month-panel-current-cell &-month, - &-fullscreen &-today &-date { - background: transparent; - border-top-color: @primary-color; - } - - &-fullscreen &-month-panel-current-cell &-value, - &-fullscreen &-today &-value { - box-shadow: none; - } - - &-fullscreen &-month-panel-selected-cell &-month, - &-fullscreen &-selected-day &-date { - background: @primary-1; - } - - &-fullscreen &-month-panel-selected-cell &-value, - &-fullscreen &-selected-day &-value { - color: @primary-color; - } - - &-fullscreen &-last-month-cell &-date, - &-fullscreen &-next-month-btn-day &-date { - color: @disabled-color; - } - - &-fullscreen &-content { - position: static; - width: auto; - height: 88px; - overflow-y: auto; - } - - &-disabled-cell &-date { - &, - &:hover { - cursor: not-allowed; - } - } - - &-disabled-cell:not(&-today) &-date { - &, - &:hover { - background: transparent; - } - } - - &-disabled-cell &-value { - width: auto; - color: @disabled-color; + border-top: @border-width-base @border-style-base @border-color-split; border-radius: 0; - cursor: not-allowed; + + .@{calendar-picker-prefix-cls}-month-panel, + .@{calendar-picker-prefix-cls}-date-panel { + width: auto; + } + + .@{calendar-picker-prefix-cls}-body { + padding: @padding-xs 0; + } + + .@{calendar-picker-prefix-cls}-content { + width: 100%; + } + } + + // ========================== Mini ========================== + &-mini { + border-radius: @border-radius-base; + + .@{calendar-picker-prefix-cls}-calendar-header { + padding-right: @padding-xs; + padding-left: @padding-xs; + } + + .@{calendar-picker-prefix-cls}-panel { + border-radius: 0 0 @border-radius-base @border-radius-base; + } + + .@{calendar-picker-prefix-cls}-content { + height: 256px; + + th { + height: auto; + padding: 0; + line-height: 18px; + } + } + } + + // ========================== Full ========================== + &-full { + .@{calendar-picker-prefix-cls}-panel { + display: block; + width: 100%; + text-align: right; + background: @calendar-full-bg; + border: 0; + + .@{calendar-picker-prefix-cls}-body { + th, + td { + padding: 0; + } + + th { + height: auto; + padding: 0 12px 5px 0; + line-height: 18px; + } + } + + // Cell + .@{calendar-picker-prefix-cls}-cell { + &::before { + display: none; + } + + &:hover { + .@{calendar-prefix-cls}-date { + background: @item-hover-bg; + } + } + + .@{calendar-prefix-cls}-date-today::before { + display: none; + } + + &-selected, + &-selected:hover { + .@{calendar-prefix-cls}-date, + .@{calendar-prefix-cls}-date-today { + background: @calendar-item-active-bg; + + .@{calendar-prefix-cls}-date-value { + color: @primary-color; + } + } + } + } + + // Cell date + .@{calendar-prefix-cls}-date { + display: block; + width: auto; + height: auto; + margin: 0 (@padding-xs / 2); + padding: (@padding-xs / 2) @padding-xs 0; + border: 0; + border-top: 2px solid @border-color-split; + border-radius: 0; + transition: background 0.3s; + + &-value { + line-height: 24px; + transition: color 0.3s; + } + + &-content { + position: static; + width: auto; + height: 86px; + overflow-y: auto; + color: @text-color; + line-height: @line-height-base; + text-align: left; + } + + &-today { + border-color: @primary-color; + + .@{calendar-prefix-cls}-date-value { + color: @text-color; + } + } + } + } } } + +@media only screen and (max-width: @screen-xs) { + .@{calendar-prefix-cls} { + &-header { + display: block; + + .@{calendar-prefix-cls}-year-select { + width: 50%; + } + + .@{calendar-prefix-cls}-month-select { + width: ~'calc(50% - @{padding-xs})'; + } + + .@{calendar-prefix-cls}-mode-switch { + width: 100%; + margin-top: @padding-xs; + margin-left: 0; + + > label { + width: 50%; + text-align: center; + } + } + } + } +} + +@import './rtl'; diff --git a/components/calendar/style/index.ts b/components/calendar/style/index.tsx similarity index 67% rename from components/calendar/style/index.ts rename to components/calendar/style/index.tsx index 184ccc0ac..045b1fa40 100644 --- a/components/calendar/style/index.ts +++ b/components/calendar/style/index.tsx @@ -2,5 +2,7 @@ import '../../style/index.less'; import './index.less'; // style dependencies +// deps-lint-skip: date-picker import '../../select/style'; import '../../radio/style'; +import '../../date-picker/style'; diff --git a/components/calendar/style/rtl.less b/components/calendar/style/rtl.less new file mode 100644 index 000000000..06464daad --- /dev/null +++ b/components/calendar/style/rtl.less @@ -0,0 +1,46 @@ +.@{calendar-prefix-cls} { + &-rtl { + direction: rtl; + } + + &-header { + .@{calendar-prefix-cls}-month-select { + .@{calendar-prefix-cls}-rtl & { + margin-right: @padding-xs; + margin-left: 0; + } + } + + .@{calendar-prefix-cls}-mode-switch { + .@{calendar-prefix-cls}-rtl & { + margin-right: @padding-xs; + margin-left: 0; + } + } + } + + // ========================== Full ========================== + &-full { + .@{calendar-picker-prefix-cls}-panel { + .@{calendar-prefix-cls}-rtl& { + text-align: left; + } + + .@{calendar-picker-prefix-cls}-body { + th { + .@{calendar-prefix-cls}-rtl& { + padding: 0 0 5px 12px; + } + } + } + + .@{calendar-prefix-cls}-date { + &-content { + .@{calendar-prefix-cls}-rtl& { + text-align: right; + } + } + } + } + } +} diff --git a/components/cascader/__tests__/__snapshots__/index.test.js.snap b/components/cascader/__tests__/__snapshots__/index.test.js.snap index 708351c16..358aacf65 100644 --- a/components/cascader/__tests__/__snapshots__/index.test.js.snap +++ b/components/cascader/__tests__/__snapshots__/index.test.js.snap @@ -113,4 +113,4 @@ exports[`Cascader popup correctly with defaultValue 1`] = ` `; -exports[`Cascader support controlled mode 1`] = `Zhejiang / Hangzhou / West Lake`; +exports[`Cascader support controlled mode 1`] = `Zhejiang / Hangzhou / West Lake`; diff --git a/components/components.ts b/components/components.ts index e901d6a9a..6f2501775 100644 --- a/components/components.ts +++ b/components/components.ts @@ -50,7 +50,14 @@ export { default as Comment } from './comment'; export { default as ConfigProvider } from './config-provider'; -export { default as DatePicker, RangePicker, MonthPicker, WeekPicker } from './date-picker'; +export type { DatePickerProps } from './date-picker'; +export { + default as DatePicker, + MonthPicker, + WeekPicker, + RangePicker, + QuarterPicker, +} from './date-picker'; export type { DescriptionsProps } from './descriptions'; export { default as Descriptions, DescriptionsItem } from './descriptions'; @@ -172,8 +179,8 @@ export { default as Tabs, TabPane, TabContent } from './tabs'; export type { TagProps } from './tag'; export { default as Tag, CheckableTag } from './tag'; -export type { TimePickerProps } from './time-picker'; -export { default as TimePicker } from './time-picker'; +export type { TimePickerProps, TimeRangePickerProps } from './time-picker'; +export { default as TimePicker, TimeRangePicker } from './time-picker'; export type { TimelineProps, TimelineItemProps } from './timeline'; export { default as Timeline, TimelineItem } from './timeline'; diff --git a/components/date-picker/InputIcon.tsx b/components/date-picker/InputIcon.tsx deleted file mode 100644 index 1b260ceba..000000000 --- a/components/date-picker/InputIcon.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import CalendarOutlined from '@ant-design/icons-vue/CalendarOutlined'; -import { isValidElement } from '../_util/props-util'; -import { cloneElement } from '../_util/vnode'; -import classNames from '../_util/classNames'; - -const InputIcon = (_: any, { attrs }) => { - const { suffixIcon, prefixCls } = attrs; - return ( - (suffixIcon && isValidElement(suffixIcon) ? ( - cloneElement(suffixIcon, { - class: classNames({ - [suffixIcon.props?.class]: suffixIcon.props?.class, - [`${prefixCls}-picker-icon`]: true, - }), - }) - ) : ( - {suffixIcon} - )) || - ); -}; -InputIcon.inheritAttrs = false; -export default InputIcon; diff --git a/components/date-picker/PickerButton.tsx b/components/date-picker/PickerButton.tsx new file mode 100644 index 000000000..f7db131c2 --- /dev/null +++ b/components/date-picker/PickerButton.tsx @@ -0,0 +1,8 @@ +import type { FunctionalComponent } from 'vue'; +import type { ButtonProps } from '../button'; +import Button from '../button'; + +const PickerButton: FunctionalComponent = (props: ButtonProps, { attrs, slots }) => { + return ; +}; +export default PickerButton; diff --git a/components/date-picker/PickerTag.tsx b/components/date-picker/PickerTag.tsx new file mode 100644 index 000000000..4b3106bfa --- /dev/null +++ b/components/date-picker/PickerTag.tsx @@ -0,0 +1,6 @@ +import type { TagProps } from '../tag'; +import Tag from '../tag'; + +export default function PickerTag(props: TagProps, { slots, attrs }) { + return ; +} diff --git a/components/date-picker/RangePicker.tsx b/components/date-picker/RangePicker.tsx deleted file mode 100644 index e1856d757..000000000 --- a/components/date-picker/RangePicker.tsx +++ /dev/null @@ -1,446 +0,0 @@ -import type { CSSProperties } from 'vue'; -import { defineComponent, inject, nextTick } from 'vue'; -import moment from 'moment'; -import RangeCalendar from '../vc-calendar/src/RangeCalendar'; -import VcDatePicker from '../vc-calendar/src/Picker'; -import classNames from '../_util/classNames'; -import shallowequal from '../_util/shallowequal'; -import CloseCircleFilled from '@ant-design/icons-vue/CloseCircleFilled'; -import Tag from '../tag'; -import { defaultConfigProvider } from '../config-provider'; -import interopDefault from '../_util/interopDefault'; -import { RangePickerProps } from './props'; -import { hasProp, getOptionProps, getComponent } from '../_util/props-util'; -import BaseMixin from '../_util/BaseMixin'; -import { formatDate } from './utils'; -import InputIcon from './InputIcon'; -import { getDataAndAriaProps } from '../_util/util'; -import initDefaultProps from '../_util/props-util/initDefaultProps'; - -type RangePickerValue = - | undefined[] - | null[] - | [moment.Moment] - | [undefined, moment.Moment] - | [moment.Moment, undefined] - | [null, moment.Moment] - | [moment.Moment, null] - | [moment.Moment, moment.Moment]; - -export type RangePickerPresetRange = RangePickerValue | (() => RangePickerValue); -function getShowDateFromValue(value: RangePickerValue, mode?: string | string[]) { - const [start, end] = value; - // value could be an empty array, then we should not reset showDate - if (!start && !end) { - return; - } - if (mode && mode[0] === 'month') { - return [start, end] as RangePickerValue; - } - const newEnd = end && end.isSame(start, 'month') ? end.clone().add(1, 'month') : end; - return [start, newEnd] as RangePickerValue; -} - -function pickerValueAdapter( - value?: moment.Moment | RangePickerValue, -): RangePickerValue | undefined { - if (!value) { - return; - } - if (Array.isArray(value)) { - return value; - } - return [value, value.clone().add(1, 'month')]; -} - -function isEmptyArray(arr: any) { - if (Array.isArray(arr)) { - return arr.length === 0 || arr.every(i => !i); - } - return false; -} - -function fixLocale(value: RangePickerValue | undefined, localeCode: string | undefined) { - if (!localeCode) { - return; - } - if (!value || value.length === 0) { - return; - } - const [start, end] = value; - if (start) { - start.locale(localeCode); - } - if (end) { - end.locale(localeCode); - } -} - -export interface RangePickerState { - sValue?: RangePickerValue; - sShowDate?: RangePickerValue; - sOpen?: boolean; - sHoverValue?: RangePickerValue; -} - -export default defineComponent({ - name: 'ARangePicker', - mixins: [BaseMixin], - inheritAttrs: false, - props: initDefaultProps(RangePickerProps, { - allowClear: true, - showToday: false, - separator: '~', - }), - setup() { - return { - configProvider: inject('configProvider', defaultConfigProvider), - picker: null, - sTagPrefixCls: undefined, - sPrefixCls: '', - }; - }, - data(): RangePickerState { - const value = this.value || this.defaultValue || []; - const [start, end] = value; - if ( - (start && !interopDefault(moment).isMoment(start)) || - (end && !interopDefault(moment).isMoment(end)) - ) { - throw new Error( - 'The value/defaultValue of RangePicker must be a moment object array after `antd@2.0`, ' + - 'see: https://u.ant.design/date-picker-value', - ); - } - const pickerValue = !value || isEmptyArray(value) ? this.defaultPickerValue : value; - return { - sValue: value as RangePickerValue, - sShowDate: pickerValueAdapter(pickerValue || interopDefault(moment)()), - sOpen: this.open, - sHoverValue: [], - }; - }, - watch: { - value(val) { - const value = val || []; - let state: RangePickerState = { sValue: value }; - if (!shallowequal(val, this.sValue)) { - state = { - ...state, - sShowDate: getShowDateFromValue(value, this.mode) || this.sShowDate, - }; - } - this.setState(state); - }, - open(val) { - const state = { sOpen: val }; - this.setState(state); - }, - sOpen(val, oldVal) { - nextTick(() => { - if (!hasProp(this, 'open') && oldVal && !val) { - this.focus(); - } - }); - }, - }, - methods: { - setValue(value: RangePickerValue, hidePanel?: boolean) { - this.handleChange(value); - if ((hidePanel || !this.showTime) && !hasProp(this, 'open')) { - this.setState({ sOpen: false }); - } - }, - - savePicker(node: any) { - this.picker = node; - }, - clearSelection(e) { - e.preventDefault(); - e.stopPropagation(); - this.setState({ sValue: [] }); - this.handleChange([]); - }, - - clearHoverValue() { - this.setState({ sHoverValue: [] }); - }, - - handleChange(value: RangePickerValue) { - if (!hasProp(this, 'value')) { - this.setState(({ sShowDate }) => ({ - sValue: value, - sShowDate: getShowDateFromValue(value) || sShowDate, - })); - } - if (value[0] && value[1] && value[0].diff(value[1]) > 0) { - value[1] = undefined; - } - const [start, end] = value; - this.$emit('change', value, [formatDate(start, this.format), formatDate(end, this.format)]); - }, - - handleOpenChange(open: boolean) { - if (!hasProp(this, 'open')) { - this.setState({ sOpen: open }); - } - - if (open === false) { - this.clearHoverValue(); - } - this.$emit('openChange', open); - }, - - handleShowDateChange(showDate: boolean) { - this.setState({ sShowDate: showDate }); - }, - - handleHoverChange(hoverValue: any) { - this.setState({ sHoverValue: hoverValue }); - }, - - handleRangeMouseLeave() { - if (this.sOpen) { - this.clearHoverValue(); - } - }, - - handleCalendarInputSelect(value: RangePickerValue) { - const [start] = value; - if (!start) { - return; - } - this.setState(({ sShowDate }) => ({ - sValue: value, - sShowDate: getShowDateFromValue(value) || sShowDate, - })); - }, - - handleRangeClick(value: RangePickerPresetRange) { - if (typeof value === 'function') { - value = value(); - } - - this.setValue(value, true); - this.$emit('ok', value); - this.$emit('openChange', false); - }, - - onMouseEnter(e: MouseEvent) { - this.$emit('mouseenter', e); - }, - onMouseLeave(e: MouseEvent) { - this.$emit('mouseleave', e); - }, - - focus() { - this.picker.focus(); - }, - - blur() { - this.picker.blur(); - }, - - renderFooter() { - const { ranges, $slots } = this; - const { sPrefixCls: prefixCls, sTagPrefixCls: tagPrefixCls } = this; - const renderExtraFooter = this.renderExtraFooter || $slots.renderExtraFooter; - if (!ranges && !renderExtraFooter) { - return null; - } - const customFooter = renderExtraFooter ? ( - - ) : null; - const operations = - ranges && - Object.keys(ranges).map(range => { - const value = ranges[range]; - const hoverValue = typeof value === 'function' ? value.call(this) : value; - return ( - this.handleRangeClick(value)} - onMouseenter={() => this.setState({ sHoverValue: hoverValue })} - onMouseleave={this.handleRangeMouseLeave} - > - {range} - - ); - }); - const rangeNode = - operations && operations.length > 0 ? ( - - ) : null; - return [rangeNode, customFooter]; - }, - }, - - render() { - const props: any = { ...getOptionProps(this), ...this.$attrs }; - let suffixIcon = getComponent(this, 'suffixIcon'); - suffixIcon = Array.isArray(suffixIcon) ? suffixIcon[0] : suffixIcon; - const { - sValue: value, - sShowDate: showDate, - sHoverValue: hoverValue, - sOpen: open, - $slots, - } = this; - const { - prefixCls: customizePrefixCls, - tagPrefixCls: customizeTagPrefixCls, - popupStyle, - disabledDate, - disabledTime, - showTime, - showToday, - ranges, - locale, - localeCode, - format, - separator, - inputReadOnly, - style, - onCalendarChange, - onOk, - onBlur, - onFocus, - onPanelChange, - } = props; - const getPrefixCls = this.configProvider.getPrefixCls; - const prefixCls = getPrefixCls('calendar', customizePrefixCls); - const tagPrefixCls = getPrefixCls('tag', customizeTagPrefixCls); - this.sPrefixCls = prefixCls; - this.sTagPrefixCls = tagPrefixCls; - - const dateRender = props.dateRender || $slots.dateRender; - fixLocale(value, localeCode); - fixLocale(showDate, localeCode); - - const calendarClassName = classNames({ - [`${prefixCls}-time`]: showTime, - [`${prefixCls}-range-with-ranges`]: ranges, - }); - - // 需要选择时间时,点击 ok 时才触发 onChange - const pickerChangeHandler = { - onChange: this.handleChange, - }; - let calendarProps: any = { - onOk: this.handleChange, - }; - if (props.timePicker) { - pickerChangeHandler.onChange = changedValue => this.handleChange(changedValue); - } else { - calendarProps = {}; - } - if ('mode' in props) { - calendarProps.mode = props.mode; - } - - const startPlaceholder = Array.isArray(props.placeholder) - ? props.placeholder[0] - : locale.lang.rangePlaceholder[0]; - const endPlaceholder = Array.isArray(props.placeholder) - ? props.placeholder[1] - : locale.lang.rangePlaceholder[1]; - - const rangeCalendarProps = { - ...calendarProps, - separator, - format, - prefixCls, - renderFooter: this.renderFooter, - timePicker: props.timePicker, - disabledDate, - disabledTime, - dateInputPlaceholder: [startPlaceholder, endPlaceholder], - locale: locale.lang, - dateRender, - value: showDate, - hoverValue, - showToday, - inputReadOnly, - onChange: onCalendarChange, - onOk, - onValueChange: this.handleShowDateChange, - onHoverChange: this.handleHoverChange, - onPanelChange, - onInputSelect: this.handleCalendarInputSelect, - class: calendarClassName, - }; - const calendar = ; - - // default width for showTime - const pickerStyle: CSSProperties = {}; - if (props.showTime) { - pickerStyle.width = '350px'; - } - const [startValue, endValue] = value; - const clearIcon = - !props.disabled && props.allowClear && value && (startValue || endValue) ? ( - - ) : null; - - const inputIcon = ; - - const input = ({ value: inputValue }) => { - const [start, end] = inputValue; - return ( - - - {separator} - - {clearIcon} - {inputIcon} - - ); - }; - const vcDatePickerProps = { - ...props, - ...pickerChangeHandler, - calendar, - value, - open, - prefixCls: `${prefixCls}-picker-container`, - onOpenChange: this.handleOpenChange, - style: popupStyle, - }; - return ( - - - - ); - }, -}); diff --git a/components/date-picker/WeekPicker.tsx b/components/date-picker/WeekPicker.tsx deleted file mode 100644 index fd031dcc7..000000000 --- a/components/date-picker/WeekPicker.tsx +++ /dev/null @@ -1,229 +0,0 @@ -import { defineComponent, inject, nextTick } from 'vue'; -import moment from 'moment'; -import Calendar from '../vc-calendar'; -import VcDatePicker from '../vc-calendar/src/Picker'; -import CloseCircleFilled from '@ant-design/icons-vue/CloseCircleFilled'; -import { defaultConfigProvider } from '../config-provider'; -import { hasProp, getOptionProps, getComponent } from '../_util/props-util'; -import classNames from '../_util/classNames'; -import BaseMixin from '../_util/BaseMixin'; -import { WeekPickerProps } from './props'; -import interopDefault from '../_util/interopDefault'; -import InputIcon from './InputIcon'; -import { getDataAndAriaProps } from '../_util/util'; -import initDefaultProps from '../_util/props-util/initDefaultProps'; - -function formatValue(value: moment.Moment | null, format: string): string { - return (value && value.format(format)) || ''; -} - -interface WeekPickerState { - _open?: boolean; - _value?: moment.Moment | null; -} -function noop() {} - -export default defineComponent({ - name: 'AWeekPicker', - mixins: [BaseMixin], - inheritAttrs: false, - props: initDefaultProps(WeekPickerProps, { - allowClear: true, - }), - setup() { - return { - configProvider: inject('configProvider', defaultConfigProvider), - prevState: {} as WeekPickerState, - input: undefined, - sPrefixCls: undefined, - }; - }, - data(): WeekPickerState { - const value: any = this.value || this.defaultValue; - if (value && !interopDefault(moment).isMoment(value)) { - throw new Error( - 'The value/defaultValue of WeekPicker or MonthPicker must be ' + 'a moment object', - ); - } - return { - _value: value, - _open: this.open, - }; - }, - watch: { - value(val) { - const state = { _value: val }; - this.setState(state); - this.prevState = { ...this.$data, ...state }; - }, - open(val) { - const state = { _open: val }; - this.setState(state); - this.prevState = { ...this.$data, ...state }; - }, - _open(val, oldVal) { - nextTick(() => { - if (!hasProp(this, 'open') && oldVal && !val) { - this.focus(); - } - }); - }, - }, - mounted() { - this.prevState = { ...this.$data }; - }, - updated() { - nextTick(() => { - if (!hasProp(this, 'open') && this.prevState._open && !this._open) { - this.focus(); - } - }); - }, - methods: { - saveInput(node: any) { - this.input = node; - }, - weekDateRender({ current }) { - const selectedValue = this.$data._value; - const { sPrefixCls: prefixCls, $slots } = this; - const dateRender = this.dateRender || $slots.dateRender; - const dateNode = dateRender ? dateRender({ current }) : current.date(); - if ( - selectedValue && - current.year() === selectedValue.year() && - current.week() === selectedValue.week() - ) { - return ( -
-
{dateNode}
-
- ); - } - return
{dateNode}
; - }, - handleChange(value: moment.Moment | null) { - if (!hasProp(this, 'value')) { - this.setState({ _value: value }); - } - this.$emit('change', value, formatValue(value, this.format)); - }, - handleOpenChange(open: boolean) { - if (!hasProp(this, 'open')) { - this.setState({ _open: open }); - } - this.$emit('openChange', open); - }, - clearSelection(e: MouseEvent) { - e.preventDefault(); - e.stopPropagation(); - this.handleChange(null); - }, - focus() { - this.input.focus(); - }, - - blur() { - this.input.blur(); - }, - renderFooter(...args: any[]) { - const { sPrefixCls: prefixCls, $slots } = this; - const renderExtraFooter = this.renderExtraFooter || $slots.renderExtraFooter; - return renderExtraFooter ? ( - - ) : null; - }, - }, - - render() { - const props = { ...getOptionProps(this), ...this.$attrs }; - let suffixIcon = getComponent(this, 'suffixIcon'); - suffixIcon = Array.isArray(suffixIcon) ? suffixIcon[0] : suffixIcon; - const { - prefixCls: customizePrefixCls, - disabled, - pickerClass, - popupStyle, - pickerInputClass, - format, - allowClear, - locale, - localeCode, - disabledDate, - defaultPickerValue, - $data, - $slots, - } = this; - const getPrefixCls = this.configProvider.getPrefixCls; - const prefixCls = getPrefixCls('calendar', customizePrefixCls); - this.sPrefixCls = prefixCls; - - const { _value: pickerValue, _open: open } = $data; - const { class: className, style, id, onFocus = noop, onBlur = noop } = props as any; - - if (pickerValue && localeCode) { - pickerValue.locale(localeCode); - } - - const placeholder = hasProp(this, 'placeholder') ? this.placeholder : locale.lang.placeholder; - const weekDateRender = this.dateRender || $slots.dateRender || this.weekDateRender; - const calendar = ( - - ); - const clearIcon = - !disabled && allowClear && $data._value ? ( - - ) : null; - - const inputIcon = ; - - const input = ({ value }) => { - return ( - - - {clearIcon} - {inputIcon} - - ); - }; - const vcDatePickerProps = { - ...props, - calendar, - prefixCls: `${prefixCls}-picker-container`, - value: pickerValue, - open, - onChange: this.handleChange, - onOpenChange: this.handleOpenChange, - style: popupStyle, - }; - return ( - - - - ); - }, -}); diff --git a/components/date-picker/createPicker.tsx b/components/date-picker/createPicker.tsx deleted file mode 100644 index e14eac559..000000000 --- a/components/date-picker/createPicker.tsx +++ /dev/null @@ -1,266 +0,0 @@ -import type { CSSProperties, DefineComponent } from 'vue'; -import { defineComponent, inject, nextTick } from 'vue'; -import moment from 'moment'; -import omit from 'lodash-es/omit'; -import MonthCalendar from '../vc-calendar/src/MonthCalendar'; -import VcDatePicker from '../vc-calendar/src/Picker'; -import classNames from '../_util/classNames'; -import CloseCircleFilled from '@ant-design/icons-vue/CloseCircleFilled'; -import CalendarOutlined from '@ant-design/icons-vue/CalendarOutlined'; -import { defaultConfigProvider } from '../config-provider'; -import interopDefault from '../_util/interopDefault'; -import BaseMixin from '../_util/BaseMixin'; -import PropTypes from '../_util/vue-types'; -import { hasProp, getOptionProps, getComponent, isValidElement } from '../_util/props-util'; -import { cloneElement } from '../_util/vnode'; -import { formatDate } from './utils'; -import { getDataAndAriaProps } from '../_util/util'; -import { isEmptySlot } from '../_util/props-util'; - -export interface PickerProps { - value?: moment.Moment; - open?: boolean; - prefixCls?: string; -} -export interface PickerState { - sOpen?: boolean; - sValue?: moment.Moment | null; - showDate?: moment.Moment | null; -} -export default function createPicker

( - TheCalendar: DefineComponent

, - props: any, - name: string, -): any { - return defineComponent({ - name, - mixins: [BaseMixin], - inheritAttrs: false, - props: { - ...props, - allowClear: PropTypes.looseBool.def(true), - showToday: PropTypes.looseBool.def(true), - }, - setup() { - return { - configProvider: inject('configProvider', defaultConfigProvider), - input: undefined, - sPrefixCls: undefined, - }; - }, - data(): PickerState { - const value = this.value || this.defaultValue; - return { - sValue: value, - showDate: value, - sOpen: !!this.open, - }; - }, - watch: { - open(val) { - const props: PickerProps = getOptionProps(this); - const state: PickerState = {}; - state.sOpen = val; - if ('value' in props && !val && props.value !== this.showDate) { - state.showDate = props.value; - } - this.setState(state); - }, - value(val) { - const state: PickerState = {}; - state.sValue = val; - if (val !== this.sValue) { - state.showDate = val; - } - this.setState(state); - }, - sOpen(val, oldVal) { - nextTick(() => { - if (!hasProp(this, 'open') && oldVal && !val) { - this.focus(); - } - }); - }, - }, - methods: { - saveInput(node: any) { - this.input = node; - }, - clearSelection(e: MouseEvent) { - e.preventDefault(); - e.stopPropagation(); - this.handleChange(null); - }, - - handleChange(value: moment.Moment | null) { - if (!hasProp(this, 'value')) { - this.setState({ - sValue: value, - showDate: value, - }); - } - this.$emit('change', value, formatDate(value, this.format)); - }, - - handleCalendarChange(value: moment.Moment) { - this.setState({ showDate: value }); - }, - handleOpenChange(open: boolean) { - const props = getOptionProps(this); - if (!('open' in props)) { - this.setState({ sOpen: open }); - } - this.$emit('openChange', open); - }, - focus() { - this.input?.focus(); - }, - - blur() { - this.input?.blur(); - }, - renderFooter(...args: any[]) { - const { $slots, sPrefixCls: prefixCls } = this; - const renderExtraFooter: Function = this.renderExtraFooter || $slots.renderExtraFooter; - return renderExtraFooter ? ( -

- ) : null; - }, - onMouseEnter(e: MouseEvent) { - this.$emit('mouseenter', e); - }, - onMouseLeave(e: MouseEvent) { - this.$emit('mouseleave', e); - }, - }, - - render() { - const { $slots } = this; - const { sValue: value, showDate, sOpen: open } = this.$data; - let suffixIcon = getComponent(this, 'suffixIcon'); - suffixIcon = Array.isArray(suffixIcon) ? suffixIcon[0] : suffixIcon; - const props: any = omit({ ...getOptionProps(this), ...this.$attrs }, ['onChange']); - - const { prefixCls: customizePrefixCls, locale, localeCode, inputReadOnly } = props; - const getPrefixCls = this.configProvider.getPrefixCls; - const prefixCls = getPrefixCls('calendar', customizePrefixCls); - this.sPrefixCls = prefixCls; - - const dateRender = props.dateRender || $slots.dateRender; - const monthCellContentRender = props.monthCellContentRender || $slots.monthCellContentRender; - const placeholder = 'placeholder' in props ? props.placeholder : locale.lang.placeholder; - - const disabledTime = props.showTime ? props.disabledTime : null; - - const calendarClassName = classNames({ - [`${prefixCls}-time`]: props.showTime, - [`${prefixCls}-month`]: (MonthCalendar as any) === TheCalendar, - }); - - if (value && localeCode) { - value.locale(localeCode); - } - - const pickerProps: any = {}; - const calendarProps: any = {}; - const pickerStyle: CSSProperties = {}; - if (props.showTime) { - // fix https://github.com/ant-design/ant-design/issues/1902 - calendarProps.onSelect = this.handleChange; - pickerStyle.minWidth = '195px'; - } else { - pickerProps.onChange = this.handleChange; - } - if ('mode' in props) { - calendarProps.mode = props.mode; - } - const theCalendarProps = { - ...calendarProps, - disabledDate: props.disabledDate, - disabledTime, - locale: locale.lang, - timePicker: props.timePicker, - defaultValue: props.defaultPickerValue || interopDefault(moment)(), - dateInputPlaceholder: placeholder, - prefixCls, - dateRender, - format: props.format, - showToday: props.showToday, - monthCellContentRender, - renderFooter: this.renderFooter, - value: showDate, - inputReadOnly, - onOk: props.onOk, - onPanelChange: props.onPanelChange, - onChange: this.handleCalendarChange, - class: calendarClassName, - }; - const calendar = ; - - const clearIcon = - !props.disabled && props.allowClear && value ? ( - - ) : null; - - const inputIcon = (suffixIcon && - (isValidElement(suffixIcon) ? ( - cloneElement(suffixIcon, { - class: `${prefixCls}-picker-icon`, - }) - ) : ( - {suffixIcon} - ))) || ; - - const input = ({ value: inputValue }) => ( -
- - {clearIcon} - {inputIcon} -
- ); - const vcDatePickerProps = { - ...props, - ...pickerProps, - calendar, - value, - prefixCls: `${prefixCls}-picker-container`, - open, - onOpenChange: this.handleOpenChange, - style: props.popupStyle, - }; - return ( - - - - ); - }, - }); -} diff --git a/components/date-picker/date-fns.tsx b/components/date-picker/date-fns.tsx new file mode 100755 index 000000000..8023a8ab7 --- /dev/null +++ b/components/date-picker/date-fns.tsx @@ -0,0 +1,44 @@ +import type { App } from 'vue'; +import dataFnsGenerateConfig from '../vc-picker/generate/dateFns'; +import type { + PickerProps, + PickerDateProps, + RangePickerProps as BaseRangePickerProps, +} from './generatePicker'; +import generatePicker from './generatePicker'; +import type { ExtraDatePickerProps, ExtraRangePickerProps } from './generatePicker/props'; + +export type DatePickerProps = PickerProps & ExtraDatePickerProps; +export type MonthPickerProps = Omit, 'picker'> & ExtraDatePickerProps; +export type WeekPickerProps = Omit, 'picker'> & ExtraDatePickerProps; +export type RangePickerProps = BaseRangePickerProps & ExtraRangePickerProps; + +const { DatePicker, WeekPicker, MonthPicker, YearPicker, TimePicker, QuarterPicker, RangePicker } = + generatePicker(dataFnsGenerateConfig); + +DatePicker.WeekPicker = WeekPicker; +DatePicker.MonthPicker = MonthPicker; +DatePicker.YearPicker = YearPicker; +DatePicker.RangePicker = RangePicker; +DatePicker.TimePicker = TimePicker; +DatePicker.QuarterPicker = QuarterPicker; + +/* istanbul ignore next */ +DatePicker.install = function (app: App) { + app.component(DatePicker.name, DatePicker); + app.component(RangePicker.name, RangePicker); + app.component(MonthPicker.name, MonthPicker); + app.component(WeekPicker.name, WeekPicker); + app.component(QuarterPicker.name, QuarterPicker); + return app; +}; + +export { RangePicker, WeekPicker, MonthPicker, QuarterPicker }; + +export default DatePicker as typeof DatePicker & + Plugin & { + readonly RangePicker: typeof RangePicker; + readonly MonthPicker: typeof MonthPicker; + readonly WeekPicker: typeof WeekPicker; + readonly QuarterPicker: typeof QuarterPicker; + }; diff --git a/components/date-picker/dayjs.tsx b/components/date-picker/dayjs.tsx new file mode 100755 index 000000000..e977b0f19 --- /dev/null +++ b/components/date-picker/dayjs.tsx @@ -0,0 +1,45 @@ +import type { Dayjs } from 'dayjs'; +import type { App } from 'vue'; +import dayjsGenerateConfig from '../vc-picker/generate/dayjs'; +import type { + PickerProps, + PickerDateProps, + RangePickerProps as BaseRangePickerProps, +} from './generatePicker'; +import generatePicker from './generatePicker'; +import type { ExtraDatePickerProps, ExtraRangePickerProps } from './generatePicker/props'; + +export type DatePickerProps = PickerProps & ExtraDatePickerProps; +export type MonthPickerProps = Omit, 'picker'> & ExtraDatePickerProps; +export type WeekPickerProps = Omit, 'picker'> & ExtraDatePickerProps; +export type RangePickerProps = BaseRangePickerProps & ExtraRangePickerProps; + +const { DatePicker, WeekPicker, MonthPicker, YearPicker, TimePicker, QuarterPicker, RangePicker } = + generatePicker(dayjsGenerateConfig); + +DatePicker.WeekPicker = WeekPicker; +DatePicker.MonthPicker = MonthPicker; +DatePicker.YearPicker = YearPicker; +DatePicker.RangePicker = RangePicker; +DatePicker.TimePicker = TimePicker; +DatePicker.QuarterPicker = QuarterPicker; + +/* istanbul ignore next */ +DatePicker.install = function (app: App) { + app.component(DatePicker.name, DatePicker); + app.component(RangePicker.name, RangePicker); + app.component(MonthPicker.name, MonthPicker); + app.component(WeekPicker.name, WeekPicker); + app.component(QuarterPicker.name, QuarterPicker); + return app; +}; + +export { RangePicker, WeekPicker, MonthPicker, QuarterPicker }; + +export default DatePicker as typeof DatePicker & + Plugin & { + readonly RangePicker: typeof RangePicker; + readonly MonthPicker: typeof MonthPicker; + readonly WeekPicker: typeof WeekPicker; + readonly QuarterPicker: typeof QuarterPicker; + }; diff --git a/components/date-picker/generatePicker/generateRangePicker.tsx b/components/date-picker/generatePicker/generateRangePicker.tsx new file mode 100644 index 000000000..405bcf316 --- /dev/null +++ b/components/date-picker/generatePicker/generateRangePicker.tsx @@ -0,0 +1,216 @@ +import CalendarOutlined from '@ant-design/icons-vue/CalendarOutlined'; +import ClockCircleOutlined from '@ant-design/icons-vue/ClockCircleOutlined'; +import CloseCircleFilled from '@ant-design/icons-vue/CloseCircleFilled'; +import SwapRightOutlined from '@ant-design/icons-vue/SwapRightOutlined'; +import { RangePicker as VCRangePicker } from '../../vc-picker'; +import type { GenerateConfig } from '../../vc-picker/generate/index'; +import enUS from '../locale/en_US'; +import { useLocaleReceiver } from '../../locale-provider/LocaleReceiver'; +import { getRangePlaceholder } from '../util'; +import { getTimeProps, Components } from '.'; +import { computed, defineComponent, ref } from 'vue'; +import useConfigInject from '../../_util/hooks/useConfigInject'; +import classNames from '../../_util/classNames'; +import { commonProps, rangePickerProps } from './props'; +import type { PanelMode, RangeValue } from '../../vc-picker/interface'; +import type { RangePickerSharedProps } from '../../vc-picker/RangePicker'; +import devWarning from '../../vc-util/devWarning'; + +export default function generateRangePicker( + generateConfig: GenerateConfig, + extraProps: ExtraProps, +) { + const RangePicker = defineComponent({ + name: 'ARangePicker', + inheritAttrs: false, + props: { + ...commonProps(), + ...rangePickerProps(), + ...extraProps, + }, + slots: [ + 'suffixIcon', + // 'clearIcon', + // 'prevIcon', + // 'nextIcon', + // 'superPrevIcon', + // 'superNextIcon', + // 'panelRender', + 'dateRender', + 'renderExtraFooter', + // 'separator', + ], + emits: [ + 'change', + 'panelChange', + 'ok', + 'openChange', + 'update:value', + 'update:open', + 'calendarChange', + 'focus', + 'blur', + ], + setup(props, { expose, slots, attrs, emit }) { + devWarning( + !attrs.getCalendarContainer, + 'DatePicker', + '`getCalendarContainer` is deprecated. Please use `getPopupContainer"` instead.', + ); + const { prefixCls, direction, getPopupContainer, size, rootPrefixCls } = useConfigInject( + 'picker', + props, + ); + const pickerRef = ref(); + expose({ + focus: () => { + pickerRef.value?.focus(); + }, + blur: () => { + pickerRef.value?.blur(); + }, + }); + const maybeToStrings = (dates: DateType[]) => { + return props.valueFormat ? generateConfig.toString(dates, props.valueFormat) : dates; + }; + const onChange = (dates: [DateType, DateType], dateStrings: [string, string]) => { + const values = maybeToStrings(dates); + emit('update:value', values); + emit('change', values, dateStrings); + }; + const onOpenChange = (open: boolean) => { + emit('update:open', open); + emit('openChange', open); + }; + const onFocus = () => { + emit('focus'); + }; + const onBlur = () => { + emit('blur'); + }; + const onPanelChange = (dates: RangeValue, modes: [PanelMode, PanelMode]) => { + const values = maybeToStrings(dates); + emit('panelChange', values, modes); + }; + const onOk = (dates: DateType[]) => { + const value = maybeToStrings(dates); + emit('ok', value); + }; + const onCalendarChange: RangePickerSharedProps['onCalendarChange'] = ( + dates: [DateType, DateType], + dateStrings: [string, string], + info, + ) => { + const values = maybeToStrings(dates); + emit('calendarChange', values, dateStrings, info); + }; + const [contextLocale] = useLocaleReceiver('DatePicker', enUS); + + const value = computed(() => { + if (props.value) { + return props.valueFormat + ? generateConfig.toDate(props.value, props.valueFormat) + : props.value; + } + return props.value; + }); + const defaultValue = computed(() => { + if (props.defaultValue) { + return props.valueFormat + ? generateConfig.toDate(props.defaultValue, props.valueFormat) + : props.defaultValue; + } + return props.defaultValue; + }); + const defaultPickerValue = computed(() => { + if (props.defaultPickerValue) { + return props.valueFormat + ? generateConfig.toDate(props.defaultPickerValue, props.valueFormat) + : props.defaultPickerValue; + } + return props.defaultPickerValue; + }); + return () => { + const locale = { ...contextLocale.value, ...props.locale }; + const p = { ...props, ...attrs }; + const { + prefixCls: customizePrefixCls, + bordered = true, + placeholder, + suffixIcon = slots.suffixIcon?.(), + picker = 'date', + transitionName, + allowClear = true, + dateRender = slots.dateRender, + renderExtraFooter = slots.renderExtraFooter, + separator = slots.separator?.(), + clearIcon = slots.clearIcon?.(), + ...restProps + } = p; + const { format, showTime } = p as any; + + let additionalOverrideProps: any = {}; + + additionalOverrideProps = { + ...additionalOverrideProps, + ...(showTime ? getTimeProps({ format, picker, ...showTime }) : {}), + ...(picker === 'time' ? getTimeProps({ format, ...restProps, picker }) : {}), + }; + const pre = prefixCls.value; + return ( + + + + ) + } + ref={pickerRef} + placeholder={getRangePlaceholder(picker, locale, placeholder as [string, string])} + suffixIcon={ + suffixIcon || (picker === 'time' ? : ) + } + clearIcon={clearIcon || } + allowClear={allowClear} + transitionName={transitionName || `${rootPrefixCls.value}-slide-up`} + {...restProps} + {...additionalOverrideProps} + value={value.value} + defaultValue={defaultValue.value} + defaultPickerValue={defaultPickerValue.value} + picker={picker} + class={classNames( + { + [`${pre}-${size.value}`]: size.value, + [`${pre}-borderless`]: !bordered, + }, + attrs.class, + )} + locale={locale!.lang} + prefixCls={pre} + getPopupContainer={attrs.getCalendarContainer || getPopupContainer.value} + generateConfig={generateConfig} + prevIcon={} + nextIcon={} + superPrevIcon={} + superNextIcon={} + components={Components} + direction={direction.value} + onChange={onChange} + onOpenChange={onOpenChange} + onFocus={onFocus} + onBlur={onBlur} + onPanelChange={onPanelChange} + onOk={onOk} + onCalendarChange={onCalendarChange} + /> + ); + }; + }, + }); + + return RangePicker; +} diff --git a/components/date-picker/generatePicker/generateSinglePicker.tsx b/components/date-picker/generatePicker/generateSinglePicker.tsx new file mode 100644 index 000000000..a8cf7baba --- /dev/null +++ b/components/date-picker/generatePicker/generateSinglePicker.tsx @@ -0,0 +1,235 @@ +import CalendarOutlined from '@ant-design/icons-vue/CalendarOutlined'; +import ClockCircleOutlined from '@ant-design/icons-vue/ClockCircleOutlined'; +import CloseCircleFilled from '@ant-design/icons-vue/CloseCircleFilled'; +import RCPicker from '../../vc-picker'; +import type { PanelMode, PickerMode } from '../../vc-picker/interface'; +import type { GenerateConfig } from '../../vc-picker/generate/index'; +import enUS from '../locale/en_US'; +import { getPlaceholder } from '../util'; +import { useLocaleReceiver } from '../../locale-provider/LocaleReceiver'; +import { getTimeProps, Components } from '.'; +import { computed, defineComponent, ref } from 'vue'; +import useConfigInject from '../../_util/hooks/useConfigInject'; +import classNames from '../../_util/classNames'; +import { commonProps, datePickerProps } from './props'; +import devWarning from '../../vc-util/devWarning'; + +export default function generateSinglePicker( + generateConfig: GenerateConfig, + extraProps: ExtraProps, +) { + function getPicker(picker?: PickerMode, displayName?: string) { + return defineComponent({ + name: displayName, + inheritAttrs: false, + props: { + ...commonProps(), + ...datePickerProps(), + ...extraProps, + }, + slots: [ + 'suffixIcon', + // 'clearIcon', + // 'prevIcon', + // 'nextIcon', + // 'superPrevIcon', + // 'superNextIcon', + // 'panelRender', + 'dateRender', + 'renderExtraFooter', + 'monthCellRender', + ], + emits: [ + 'change', + 'openChange', + 'focus', + 'blur', + 'panelChange', + 'ok', + 'update:value', + 'update:open', + ], + setup(props, { slots, expose, attrs, emit }) { + devWarning( + !(props.monthCellContentRender || slots.monthCellContentRender), + 'DatePicker', + '`monthCellContentRender` is deprecated. Please use `monthCellRender"` instead.', + ); + + devWarning( + !attrs.getCalendarContainer, + 'DatePicker', + '`getCalendarContainer` is deprecated. Please use `getPopupContainer"` instead.', + ); + const { prefixCls, direction, getPopupContainer, size, rootPrefixCls } = useConfigInject( + 'picker', + props, + ); + const pickerRef = ref(); + expose({ + focus: () => { + pickerRef.value?.focus(); + }, + blur: () => { + pickerRef.value?.blur(); + }, + }); + const maybeToString = (date: DateType) => { + return props.valueFormat ? generateConfig.toString(date, props.valueFormat) : date; + }; + const onChange = (date: DateType, dateString: string) => { + const value = maybeToString(date); + emit('update:value', value); + emit('change', value, dateString); + }; + const onOpenChange = (open: boolean) => { + emit('update:open', open); + emit('openChange', open); + }; + const onPanelChange = (date: DateType, mode: PanelMode | null) => { + const value = maybeToString(date); + emit('panelChange', value, mode); + }; + const onOk = (date: DateType) => { + const value = maybeToString(date); + emit('ok', value); + }; + + const [contextLocale] = useLocaleReceiver('DatePicker', enUS); + + const value = computed(() => { + if (props.value) { + return props.valueFormat + ? generateConfig.toDate(props.value as string | DateType, props.valueFormat) + : props.value; + } + return props.value; + }); + const defaultValue = computed(() => { + if (props.defaultValue) { + return props.valueFormat + ? generateConfig.toDate(props.defaultValue as string | DateType, props.valueFormat) + : props.defaultValue; + } + return props.defaultValue; + }); + const defaultPickerValue = computed(() => { + if (props.defaultPickerValue) { + return props.valueFormat + ? generateConfig.toDate( + props.defaultPickerValue as string | DateType, + props.valueFormat, + ) + : props.defaultPickerValue; + } + return props.defaultPickerValue; + }); + + return () => { + const locale = { ...contextLocale.value, ...props.locale }; + const p = { ...props, ...attrs }; + const { + bordered = true, + placeholder, + suffixIcon = slots.suffixIcon?.(), + showToday = true, + transitionName, + allowClear = true, + dateRender = slots.dateRender, + renderExtraFooter = slots.renderExtraFooter, + monthCellRender = slots.monthCellRender || + (props as any).monthCellContentRender || + slots.monthCellContentRender, + clearIcon = slots.clearIcon?.(), + ...restProps + } = p; + const showTime = p.showTime === '' ? true : p.showTime; + const { format } = p as any; + + let additionalOverrideProps: any = {}; + if (picker) { + additionalOverrideProps.picker = picker; + } + const mergedPicker = picker || p.picker || 'date'; + + additionalOverrideProps = { + ...additionalOverrideProps, + ...(showTime + ? getTimeProps({ + format, + picker: mergedPicker, + ...(typeof showTime === 'object' ? showTime : {}), + }) + : {}), + ...(mergedPicker === 'time' + ? getTimeProps({ format, ...restProps, picker: mergedPicker }) + : {}), + }; + const pre = prefixCls.value; + return ( + : ) + } + clearIcon={clearIcon || } + allowClear={allowClear} + transitionName={transitionName || `${rootPrefixCls.value}-slide-up`} + {...restProps} + {...additionalOverrideProps} + picker={mergedPicker} + value={value.value} + defaultValue={defaultValue.value} + defaultPickerValue={defaultPickerValue.value} + showToday={showToday} + locale={locale!.lang} + class={classNames( + { + [`${pre}-${size.value}`]: size.value, + [`${pre}-borderless`]: !bordered, + }, + attrs.class, + )} + prefixCls={pre} + getPopupContainer={attrs.getCalendarContainer || getPopupContainer.value} + generateConfig={generateConfig} + prevIcon={} + nextIcon={} + superPrevIcon={} + superNextIcon={} + components={Components} + direction={direction.value} + onChange={onChange} + onOpenChange={onOpenChange} + onFocus={props.onFocus} + onBlur={props.onBlur} + onPanelChange={onPanelChange} + onOk={onOk} + /> + ); + }; + }, + }); + } + + const DatePicker = getPicker(undefined, 'ADatePicker'); + const WeekPicker = getPicker('week', 'AWeekPicker'); + const MonthPicker = getPicker('month', 'AMonthPicker'); + const YearPicker = getPicker('year', 'AYearPicker'); + const TimePicker = getPicker('time', 'TimePicker'); // 给独立组件 TimePicker 使用,此处名称不用更改 + const QuarterPicker = getPicker('quarter', 'AQuarterPicker'); + + return { + DatePicker, + WeekPicker, + MonthPicker, + YearPicker, + TimePicker, + QuarterPicker, + }; +} diff --git a/components/date-picker/generatePicker/index.tsx b/components/date-picker/generatePicker/index.tsx new file mode 100644 index 000000000..43f168631 --- /dev/null +++ b/components/date-picker/generatePicker/index.tsx @@ -0,0 +1,150 @@ +import type { GenerateConfig } from '../../vc-picker/generate/index'; +import type { + PickerBaseProps as RCPickerBaseProps, + PickerDateProps as RCPickerDateProps, + PickerTimeProps as RCPickerTimeProps, +} from '../../vc-picker/Picker'; +import type { SharedTimeProps } from '../../vc-picker/panels/TimePanel'; +import type { + RangePickerBaseProps as RCRangePickerBaseProps, + RangePickerDateProps as RCRangePickerDateProps, + RangePickerTimeProps as RCRangePickerTimeProps, +} from '../../vc-picker/RangePicker'; +import type { PickerMode, Locale as RcPickerLocale } from '../../vc-picker/interface'; +import PickerButton from '../PickerButton'; +import PickerTag from '../PickerTag'; +import type { TimePickerLocale } from '../../time-picker'; +import generateSinglePicker from './generateSinglePicker'; +import generateRangePicker from './generateRangePicker'; +import type { SizeType } from '../../config-provider'; + +export const Components = { button: PickerButton, rangeItem: PickerTag }; + +function toArray(list: T | T[]): T[] { + if (!list) { + return []; + } + return Array.isArray(list) ? list : [list]; +} + +export function getTimeProps( + props: { format?: string; picker?: PickerMode } & SharedTimeProps, +) { + const { format, picker, showHour, showMinute, showSecond, use12Hours } = props; + + const firstFormat = toArray(format)[0]; + const showTimeObj: SharedTimeProps = { ...props }; + + 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') && 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 InjectDefaultProps = Omit< + Props, + | 'locale' + | 'generateConfig' + | 'prevIcon' + | 'nextIcon' + | 'superPrevIcon' + | 'superNextIcon' + | 'hideHeader' + | 'components' +> & { + locale?: PickerLocale; + size?: SizeType; + bordered?: boolean; +}; + +export type PickerLocale = { + lang: RcPickerLocale & AdditionalPickerLocaleLangProps; + timePickerLocale: TimePickerLocale; +} & AdditionalPickerLocaleProps; + +export type AdditionalPickerLocaleProps = { + dateFormat?: string; + dateTimeFormat?: string; + weekFormat?: string; + monthFormat?: string; +}; + +export type AdditionalPickerLocaleLangProps = { + placeholder: string; + yearPlaceholder?: string; + quarterPlaceholder?: string; + monthPlaceholder?: string; + weekPlaceholder?: string; + rangeYearPlaceholder?: [string, string]; + rangeMonthPlaceholder?: [string, string]; + rangeWeekPlaceholder?: [string, string]; + rangePlaceholder?: [string, string]; +}; + +// Picker Props +export type PickerBaseProps = InjectDefaultProps>; +export type PickerDateProps = InjectDefaultProps>; +export type PickerTimeProps = InjectDefaultProps>; + +export type PickerProps = + | PickerBaseProps + | PickerDateProps + | PickerTimeProps; + +// Range Picker Props +export type RangePickerBaseProps = InjectDefaultProps>; +export type RangePickerDateProps = InjectDefaultProps>; +export type RangePickerTimeProps = InjectDefaultProps>; + +export type RangePickerProps = + | RangePickerBaseProps + | RangePickerDateProps + | RangePickerTimeProps; + +function generatePicker = {}>( + generateConfig: GenerateConfig, + extraProps?: ExtraProps, +) { + // =========================== Picker =========================== + const { DatePicker, WeekPicker, MonthPicker, YearPicker, TimePicker, QuarterPicker } = + generateSinglePicker(generateConfig, extraProps); + + // ======================== Range Picker ======================== + const RangePicker = generateRangePicker(generateConfig, extraProps); + + return { + DatePicker, + WeekPicker, + MonthPicker, + YearPicker, + TimePicker, + QuarterPicker, + RangePicker, + }; +} + +export default generatePicker; diff --git a/components/date-picker/generatePicker/props.ts b/components/date-picker/generatePicker/props.ts new file mode 100644 index 000000000..b233ac193 --- /dev/null +++ b/components/date-picker/generatePicker/props.ts @@ -0,0 +1,141 @@ +import type { CSSProperties, PropType } from 'vue'; +import type { PickerLocale } from '.'; +import type { SizeType } from '../../config-provider'; +import type { AlignType } from '../../vc-align/interface'; +import type { + CustomFormat, + DisabledTime, + DisabledTimes, + EventValue, + PanelMode, + PickerMode, + RangeValue, +} from '../../vc-picker/interface'; +import type { DateRender } from '../../vc-picker/panels/DatePanel/DateBody'; +import type { MonthCellRender } from '../../vc-picker/panels/MonthPanel/MonthBody'; +import type { SharedTimeProps } from '../../vc-picker/panels/TimePanel'; +import type { RangeDateRender, RangeType } from '../../vc-picker/RangePicker'; +import type { VueNode } from '../../_util/type'; + +function commonProps() { + return { + dropdownClassName: String, + dropdownAlign: { type: Object as PropType }, + popupStyle: { type: Object as PropType }, + transitionName: String, + placeholder: String, + allowClear: { type: Boolean, default: undefined }, + autofocus: { type: Boolean, default: undefined }, + disabled: { type: Boolean, default: undefined }, + tabindex: Number, + open: { type: Boolean, default: undefined }, + defaultOpen: { type: Boolean, default: undefined }, + /** Make input readOnly to avoid popup keyboard in mobile */ + inputReadOnly: { type: Boolean, default: undefined }, + // Value + // format: string | CustomFormat | (string | CustomFormat)[]; + // Render + // suffixIcon?: VueNode; + // clearIcon?: VueNode; + // prevIcon?: VueNode; + // nextIcon?: VueNode; + // superPrevIcon?: VueNode; + // superNextIcon?: VueNode; + getPopupContainer: { type: Function as PropType<(node: HTMLElement) => HTMLElement> }, + panelRender: { type: Function as PropType<(originPanel: VueNode) => VueNode> }, + // // Events + // onChange?: (value: DateType | null, dateString: string) => void; + // onOpenChange?: (open: boolean) => void; + // onFocus?: FocusEventHandler; + // onBlur?: FocusEventHandler; + // onMousedown?: MouseEventHandler; + // onMouseup?: MouseEventHandler; + // onMouseenter?: MouseEventHandler; + // onMouseleave?: MouseEventHandler; + // onClick?: MouseEventHandler; + // onContextmenu?: MouseEventHandler; + // onKeydown?: (event: KeyboardEvent, preventDefault: () => void) => void; + // WAI-ARIA + role: String, + name: String, + autocomplete: String, + direction: { type: String as PropType<'ltr' | 'rtl'> }, + showToday: { type: Boolean, default: undefined }, + showTime: { + type: [Boolean, Object] as PropType>, + default: undefined, + }, + locale: { type: Object as PropType }, + size: { type: String as PropType }, + bordered: { type: Boolean, default: undefined }, + dateRender: { type: Function as PropType> }, + disabledDate: { type: Function as PropType<(date: DateType) => boolean> }, + mode: { type: String as PropType }, + picker: { type: String as PropType }, + valueFormat: String, + }; +} + +function datePickerProps() { + return { + defaultPickerValue: { type: [String, Object] as PropType }, + defaultValue: { type: [String, Object] as PropType }, + value: { type: [String, Object] as PropType }, + disabledTime: { type: Function as PropType> }, + format: { + type: [String, Function, Array] as PropType< + string | CustomFormat | (string | CustomFormat)[] + >, + }, + renderExtraFooter: { type: Function as PropType<(mode: PanelMode) => VueNode> }, + showNow: { type: Boolean, default: undefined }, + monthCellRender: { type: Function as PropType> }, + // deprecated Please use `monthCellRender"` instead.', + monthCellContentRender: { type: Function as PropType> }, + }; +} + +function rangePickerProps() { + return { + allowEmpty: { type: Array as unknown as PropType<[boolean, boolean]> }, + dateRender: { type: Function as PropType> }, + defaultPickerValue: { + type: Array as unknown as PropType<[DateType, DateType] | [string, string]>, + }, + defaultValue: { type: Array as unknown as PropType<[DateType, DateType] | [string, string]> }, + value: { type: Array as unknown as PropType<[DateType, DateType]> }, + disabledTime: { + type: Function as PropType<(date: EventValue, type: RangeType) => DisabledTimes>, + }, + disabled: { type: [Boolean, Array] as unknown as PropType }, + format: String, + renderExtraFooter: { type: Function as PropType<() => VueNode> }, + separator: { type: String }, + ranges: { + type: Object as PropType< + Record< + string, + Exclude, null> | (() => Exclude, null>) + > + >, + }, + placeholder: Array, + mode: { type: Array as unknown as PropType<[PanelMode, PanelMode]> }, + }; +} + +export type ExtraDatePickerProps = { + valueFormat?: string; + defaultPickerValue?: DateType | string; + defaultValue?: DateType | string; + value?: DateType | string; +}; + +export type ExtraRangePickerProps = { + valueFormat?: string; + defaultPickerValue?: [DateType, DateType] | [string, string]; + defaultValue?: [DateType, DateType] | [string, string]; + value?: [DateType, DateType] | [string, string]; +}; + +export { commonProps, datePickerProps, rangePickerProps }; diff --git a/components/date-picker/index.ts b/components/date-picker/index.ts deleted file mode 100755 index 22530bec5..000000000 --- a/components/date-picker/index.ts +++ /dev/null @@ -1,61 +0,0 @@ -import type { App, DefineComponent, Plugin } from 'vue'; -import VcCalendar from '../vc-calendar'; -import MonthCalendar from '../vc-calendar/src/MonthCalendar'; -import createPicker from './createPicker'; -import wrapPicker from './wrapPicker'; -import RangePicker from './RangePicker'; -import WeekPicker from './WeekPicker'; -import { DatePickerProps, MonthPickerProps, WeekPickerProps, RangePickerProps } from './props'; -import type { - DatePickerPropsTypes, - RangePickerPropsTypes, - MonthPickerPropsTypes, - WeekPickerPropsTypes, -} from './interface'; - -const WrappedRangePicker = wrapPicker( - RangePicker as any, - RangePickerProps, - 'date', -) as unknown as DefineComponent; - -const WrappedWeekPicker = wrapPicker( - WeekPicker as any, - WeekPickerProps, - 'week', -) as unknown as DefineComponent; - -const DatePicker = wrapPicker( - createPicker(VcCalendar as any, DatePickerProps, 'ADatePicker'), - DatePickerProps, - 'date', -) as unknown as DefineComponent & { - readonly RangePicker: typeof WrappedRangePicker; - readonly MonthPicker: typeof MonthPicker; - readonly WeekPicker: typeof WrappedWeekPicker; -}; - -export const MonthPicker = wrapPicker( - createPicker(MonthCalendar as any, MonthPickerProps, 'AMonthPicker'), - MonthPickerProps, - 'month', -) as unknown as DefineComponent; - -Object.assign(DatePicker, { - RangePicker: WrappedRangePicker, - MonthPicker, - WeekPicker: WrappedWeekPicker, -}); - -/* istanbul ignore next */ -DatePicker.install = function (app: App) { - app.component(DatePicker.name, DatePicker); - app.component(DatePicker.RangePicker.name, DatePicker.RangePicker); - app.component(DatePicker.MonthPicker.name, DatePicker.MonthPicker); - app.component(DatePicker.WeekPicker.name, DatePicker.WeekPicker); - return app; -}; - -export { WrappedRangePicker as RangePicker, WrappedWeekPicker as WeekPicker }; - -export default DatePicker as typeof DatePicker & Plugin; diff --git a/components/date-picker/index.tsx b/components/date-picker/index.tsx new file mode 100755 index 000000000..c5f053ba9 --- /dev/null +++ b/components/date-picker/index.tsx @@ -0,0 +1,4 @@ +import DatePicker from './dayjs'; +export * from './dayjs'; + +export default DatePicker; diff --git a/components/date-picker/interface.tsx b/components/date-picker/interface.tsx deleted file mode 100644 index d0bfc1141..000000000 --- a/components/date-picker/interface.tsx +++ /dev/null @@ -1,110 +0,0 @@ -import type moment from 'moment'; -import type { CSSProperties } from 'vue'; -import type { VueNode } from '../_util/type'; -import { tuple } from '../_util/type'; - -export type RangePickerValue = - | undefined[] - | null[] - | [moment.Moment | string] - | [undefined, moment.Moment | string] - | [moment.Moment | string, undefined] - | [null, moment.Moment | string] - | [moment.Moment | string, null] - | [moment.Moment, moment.Moment] - | [string, string]; - -export interface PickerProps { - name?: string; - transitionName?: string; - prefixCls?: string; - inputPrefixCls?: string; - format?: string | string[] | Function; - disabled?: boolean; - allowClear?: boolean; - pickerClass?: string; - pickerInputClass?: string; - suffixIcon?: VueNode; - popupStyle?: CSSProperties; - dropdownClassName?: string; - locale?: any; - localeCode?: string; - size?: 'large' | 'small' | 'default'; - getCalendarContainer?: (triggerNode: Element) => HTMLElement; - open?: boolean; - valueFormat?: string; - onOpenChange?: (status: boolean) => void; - disabledDate?: (current: moment.Moment | null) => boolean; - dateRender?: (current: moment.Moment, today: moment.Moment) => any; - autofocus?: boolean; - onFocus?: EventHandlerNonNull; - onBlur?: EventHandlerNonNull; -} - -export interface SinglePickerProps { - value?: moment.Moment | undefined | null | string; - defaultValue?: moment.Moment | undefined | null | string; - defaultPickerValue?: moment.Moment | undefined | null | string; - placeholder?: string; - renderExtraFooter?: (mode: DatePickerMode) => any; - onChange?: (date: moment.Moment | null, dateString: string) => void; -} - -const DatePickerModes = tuple('time', 'date', 'month', 'year', 'decade'); -export type DatePickerMode = typeof DatePickerModes[number]; - -export interface DatePickerPropsTypes extends PickerProps, SinglePickerProps { - showTime?: Record | boolean; - showToday?: boolean; - open?: boolean; - disabledTime?: (current?: moment.Moment | null) => { - disabledHours?: () => number[]; - disabledMinutes?: () => number[]; - disabledSeconds?: () => number[]; - }; - onOpenChange?: (status: boolean) => void; - onPanelChange?: (value: moment.Moment | null, mode: DatePickerMode) => void; - onOk?: (selectedTime: moment.Moment | null) => void; - mode?: DatePickerMode; -} - -export interface MonthPickerPropsTypes extends PickerProps, SinglePickerProps { - monthCellContentRender?: (date: moment.Moment, locale: any) => any; -} - -export type RangePickerPresetRange = RangePickerValue | (() => RangePickerValue); - -export interface RangePickerPropsTypes extends PickerProps { - tagPrefixCls?: string; - value?: RangePickerValue; - defaultValue?: RangePickerValue; - defaultPickerValue?: RangePickerValue; - timePicker?: VueNode; - onChange?: (dates: RangePickerValue, dateStrings: [string, string]) => void; - onCalendarChange?: (dates: RangePickerValue, dateStrings: [string, string]) => void; - onOk?: (selectedTime: RangePickerPresetRange) => void; - showTime?: Record | boolean; - showToday?: boolean; - ranges?: { - [range: string]: RangePickerPresetRange; - }; - placeholder?: [string, string]; - mode?: string | string[]; - separator?: VueNode; - disabledTime?: ( - current: RangePickerValue, - type: string, - ) => { - disabledHours?: () => number[]; - disabledMinutes?: () => number[]; - disabledSeconds?: () => number[]; - }; - onPanelChange?: (value?: RangePickerValue, mode?: string | string[]) => void; - renderExtraFooter?: () => any; - onMouseenter?: (e: MouseEvent) => void; - onMouseleave?: (e: MouseEvent) => void; -} - -export interface WeekPickerPropsTypes extends PickerProps, SinglePickerProps { - // - currently no own props - -} diff --git a/components/date-picker/locale/ar_EG.ts b/components/date-picker/locale/ar_EG.tsx similarity index 65% rename from components/date-picker/locale/ar_EG.ts rename to components/date-picker/locale/ar_EG.tsx index 8076680a9..9b04a9f82 100644 --- a/components/date-picker/locale/ar_EG.ts +++ b/components/date-picker/locale/ar_EG.tsx @@ -1,8 +1,9 @@ -import CalendarLocale from '../../vc-calendar/src/locale/ar_EG'; +import CalendarLocale from '../../vc-picker/locale/ar_EG'; import TimePickerLocale from '../../time-picker/locale/ar_EG'; +import type { PickerLocale } from '../generatePicker'; // Merge into a locale object -const locale = { +const locale: PickerLocale = { lang: { placeholder: 'اختيار التاريخ', rangePlaceholder: ['البداية', 'النهاية'], @@ -18,6 +19,6 @@ const locale = { }; // All settings at: -// https://github.com/vueComponent/ant-design-vue/blob/master/components/date-picker/locale/example.json +// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json export default locale; diff --git a/components/date-picker/locale/az_AZ.tsx b/components/date-picker/locale/az_AZ.tsx new file mode 100644 index 000000000..d2cddf9b8 --- /dev/null +++ b/components/date-picker/locale/az_AZ.tsx @@ -0,0 +1,16 @@ +import CalendarLocale from '../../vc-picker/locale/az_AZ'; +import TimePickerLocale from '../../time-picker/locale/az_AZ'; +import type { PickerLocale } from '../generatePicker'; + +const locale: PickerLocale = { + lang: { + placeholder: 'Tarix seçin', + rangePlaceholder: ['Başlama tarixi', 'Bitmə tarixi'], + ...CalendarLocale, + }, + timePickerLocale: { + ...TimePickerLocale, + }, +}; + +export default locale; diff --git a/components/date-picker/locale/bg_BG.ts b/components/date-picker/locale/bg_BG.tsx similarity index 57% rename from components/date-picker/locale/bg_BG.ts rename to components/date-picker/locale/bg_BG.tsx index 70265f6d7..b74fc9a14 100644 --- a/components/date-picker/locale/bg_BG.ts +++ b/components/date-picker/locale/bg_BG.tsx @@ -1,8 +1,9 @@ -import CalendarLocale from '../../vc-calendar/src/locale/bg_BG'; +import CalendarLocale from '../../vc-picker/locale/bg_BG'; import TimePickerLocale from '../../time-picker/locale/bg_BG'; +import type { PickerLocale } from '../generatePicker'; // Merge into a locale object -const locale = { +const locale: PickerLocale = { lang: { placeholder: 'Избор на дата', rangePlaceholder: ['Начална', 'Крайна'], @@ -14,6 +15,6 @@ const locale = { }; // All settings at: -// https://github.com/vueComponent/ant-design-vue/blob/master/components/date-picker/locale/example.json +// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json export default locale; diff --git a/components/date-picker/locale/by_BY.tsx b/components/date-picker/locale/by_BY.tsx new file mode 100644 index 000000000..4457c3171 --- /dev/null +++ b/components/date-picker/locale/by_BY.tsx @@ -0,0 +1,23 @@ +import CalendarLocale from '../../vc-picker/locale/by_BY'; +import TimePickerLocale from '../../time-picker/locale/by_BY'; +import type { PickerLocale } from '../generatePicker'; + +const locale: PickerLocale = { + lang: { + placeholder: 'Выберыце дату', + yearPlaceholder: 'Выберыце год', + quarterPlaceholder: 'Выберыце квартал', + monthPlaceholder: 'Выберыце месяц', + weekPlaceholder: 'Выберыце тыдзень', + rangePlaceholder: ['Пачатковая дата', 'Канчатковая дата'], + rangeYearPlaceholder: ['Пачатковы год', 'Год заканчэння'], + rangeMonthPlaceholder: ['Пачатковы месяц', 'Канчатковы месяц'], + rangeWeekPlaceholder: ['Пачатковы тыдзень', 'Канчатковы тыдзень'], + ...CalendarLocale, + }, + timePickerLocale: { + ...TimePickerLocale, + }, +}; + +export default locale; diff --git a/components/date-picker/locale/ca_ES.ts b/components/date-picker/locale/ca_ES.tsx similarity index 56% rename from components/date-picker/locale/ca_ES.ts rename to components/date-picker/locale/ca_ES.tsx index 113922b3a..d3aa89c01 100644 --- a/components/date-picker/locale/ca_ES.ts +++ b/components/date-picker/locale/ca_ES.tsx @@ -1,8 +1,9 @@ -import CalendarLocale from '../../vc-calendar/src/locale/ca_ES'; +import CalendarLocale from '../../vc-picker/locale/ca_ES'; import TimePickerLocale from '../../time-picker/locale/ca_ES'; +import type { PickerLocale } from '../generatePicker'; // Merge into a locale object -const locale = { +const locale: PickerLocale = { lang: { placeholder: 'Seleccionar data', rangePlaceholder: ['Data inicial', 'Data final'], @@ -14,6 +15,6 @@ const locale = { }; // All settings at: -// https://github.com/vueComponent/ant-design-vue/blob/master/components/date-picker/locale/example.json +// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json export default locale; diff --git a/components/date-picker/locale/cs_CZ.ts b/components/date-picker/locale/cs_CZ.tsx similarity index 55% rename from components/date-picker/locale/cs_CZ.ts rename to components/date-picker/locale/cs_CZ.tsx index f046d7fba..deb32c7ac 100644 --- a/components/date-picker/locale/cs_CZ.ts +++ b/components/date-picker/locale/cs_CZ.tsx @@ -1,8 +1,9 @@ -import CalendarLocale from '../../vc-calendar/src/locale/cs_CZ'; +import CalendarLocale from '../../vc-picker/locale/cs_CZ'; import TimePickerLocale from '../../time-picker/locale/cs_CZ'; +import type { PickerLocale } from '../generatePicker'; // Merge into a locale object -const locale = { +const locale: PickerLocale = { lang: { placeholder: 'Vybrat datum', rangePlaceholder: ['Od', 'Do'], @@ -14,6 +15,6 @@ const locale = { }; // All settings at: -// https://github.com/vueComponent/ant-design-vue/blob/master/components/date-picker/locale/example.json +// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json export default locale; diff --git a/components/date-picker/locale/da_DK.ts b/components/date-picker/locale/da_DK.tsx similarity index 56% rename from components/date-picker/locale/da_DK.ts rename to components/date-picker/locale/da_DK.tsx index 796ce2821..2a1a91b6e 100644 --- a/components/date-picker/locale/da_DK.ts +++ b/components/date-picker/locale/da_DK.tsx @@ -1,8 +1,9 @@ -import CalendarLocale from '../../vc-calendar/src/locale/da_DK'; +import CalendarLocale from '../../vc-picker/locale/da_DK'; import TimePickerLocale from '../../time-picker/locale/da_DK'; +import type { PickerLocale } from '../generatePicker'; // Merge into a locale object -const locale = { +const locale: PickerLocale = { lang: { placeholder: 'Vælg dato', rangePlaceholder: ['Startdato', 'Slutdato'], @@ -14,6 +15,6 @@ const locale = { }; // All settings at: -// https://github.com/vueComponent/ant-design-vue/blob/master/components/date-picker/locale/example.json +// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json export default locale; diff --git a/components/date-picker/locale/de_DE.ts b/components/date-picker/locale/de_DE.tsx similarity index 72% rename from components/date-picker/locale/de_DE.ts rename to components/date-picker/locale/de_DE.tsx index 0d4fc8fcf..02b30d5ae 100644 --- a/components/date-picker/locale/de_DE.ts +++ b/components/date-picker/locale/de_DE.tsx @@ -1,8 +1,9 @@ -import CalendarLocale from '../../vc-calendar/src/locale/de_DE'; +import CalendarLocale from '../../vc-picker/locale/de_DE'; import TimePickerLocale from '../../time-picker/locale/de_DE'; +import type { PickerLocale } from '../generatePicker'; // Merge into a locale object -const locale = { +const locale: PickerLocale = { lang: { placeholder: 'Datum auswählen', rangePlaceholder: ['Startdatum', 'Enddatum'], diff --git a/components/date-picker/locale/el_GR.ts b/components/date-picker/locale/el_GR.tsx similarity index 75% rename from components/date-picker/locale/el_GR.ts rename to components/date-picker/locale/el_GR.tsx index 6b49b4a20..9a311e14d 100644 --- a/components/date-picker/locale/el_GR.ts +++ b/components/date-picker/locale/el_GR.tsx @@ -1,8 +1,9 @@ -import CalendarLocale from '../../vc-calendar/src/locale/el_GR'; +import CalendarLocale from '../../vc-picker/locale/el_GR'; import TimePickerLocale from '../../time-picker/locale/el_GR'; +import type { PickerLocale } from '../generatePicker'; // Merge into a locale object -const locale = { +const locale: PickerLocale = { lang: { placeholder: 'Επιλέξτε ημερομηνία', rangePlaceholder: ['Αρχική ημερομηνία', 'Τελική ημερομηνία'], diff --git a/components/date-picker/locale/en_GB.ts b/components/date-picker/locale/en_GB.ts deleted file mode 100644 index 87cb1ab5a..000000000 --- a/components/date-picker/locale/en_GB.ts +++ /dev/null @@ -1,19 +0,0 @@ -import CalendarLocale from '../../vc-calendar/src/locale/en_GB'; -import TimePickerLocale from '../../time-picker/locale/en_GB'; - -// Merge into a locale object -const locale = { - lang: { - placeholder: 'Select date', - rangePlaceholder: ['Start date', 'End date'], - ...CalendarLocale, - }, - timePickerLocale: { - ...TimePickerLocale, - }, -}; - -// All settings at: -// https://github.com/vueComponent/ant-design-vue/blob/master/components/date-picker/locale/example.json - -export default locale; diff --git a/components/date-picker/locale/en_GB.tsx b/components/date-picker/locale/en_GB.tsx new file mode 100644 index 000000000..e359de872 --- /dev/null +++ b/components/date-picker/locale/en_GB.tsx @@ -0,0 +1,27 @@ +import CalendarLocale from '../../vc-picker/locale/en_GB'; +import TimePickerLocale from '../../time-picker/locale/en_GB'; +import type { PickerLocale } from '../generatePicker'; + +// Merge into a locale object +const locale: PickerLocale = { + lang: { + placeholder: 'Select date', + yearPlaceholder: 'Select year', + quarterPlaceholder: 'Select quarter', + monthPlaceholder: 'Select month', + weekPlaceholder: 'Select week', + rangePlaceholder: ['Start date', 'End date'], + rangeYearPlaceholder: ['Start year', 'End year'], + rangeMonthPlaceholder: ['Start month', 'End month'], + rangeWeekPlaceholder: ['Start week', 'End week'], + ...CalendarLocale, + }, + timePickerLocale: { + ...TimePickerLocale, + }, +}; + +// All settings at: +// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json + +export default locale; diff --git a/components/date-picker/locale/en_US.ts b/components/date-picker/locale/en_US.ts deleted file mode 100644 index 4b9c4559d..000000000 --- a/components/date-picker/locale/en_US.ts +++ /dev/null @@ -1,19 +0,0 @@ -import CalendarLocale from '../../vc-calendar/src/locale/en_US'; -import TimePickerLocale from '../../time-picker/locale/en_US'; - -// Merge into a locale object -const locale = { - lang: { - placeholder: 'Select date', - rangePlaceholder: ['Start date', 'End date'], - ...CalendarLocale, - }, - timePickerLocale: { - ...TimePickerLocale, - }, -}; - -// All settings at: -// https://github.com/vueComponent/ant-design-vue/blob/master/components/date-picker/locale/example.json - -export default locale; diff --git a/components/date-picker/locale/en_US.tsx b/components/date-picker/locale/en_US.tsx new file mode 100644 index 000000000..0b09c56ce --- /dev/null +++ b/components/date-picker/locale/en_US.tsx @@ -0,0 +1,27 @@ +import CalendarLocale from '../../vc-picker/locale/en_US'; +import TimePickerLocale from '../../time-picker/locale/en_US'; +import type { PickerLocale } from '../generatePicker'; + +// Merge into a locale object +const locale: PickerLocale = { + lang: { + placeholder: 'Select date', + yearPlaceholder: 'Select year', + quarterPlaceholder: 'Select quarter', + monthPlaceholder: 'Select month', + weekPlaceholder: 'Select week', + rangePlaceholder: ['Start date', 'End date'], + rangeYearPlaceholder: ['Start year', 'End year'], + rangeMonthPlaceholder: ['Start month', 'End month'], + rangeWeekPlaceholder: ['Start week', 'End week'], + ...CalendarLocale, + }, + timePickerLocale: { + ...TimePickerLocale, + }, +}; + +// All settings at: +// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json + +export default locale; diff --git a/components/date-picker/locale/es_ES.ts b/components/date-picker/locale/es_ES.tsx similarity index 57% rename from components/date-picker/locale/es_ES.ts rename to components/date-picker/locale/es_ES.tsx index 188ebceca..42b72eaf9 100644 --- a/components/date-picker/locale/es_ES.ts +++ b/components/date-picker/locale/es_ES.tsx @@ -1,8 +1,9 @@ -import CalendarLocale from '../../vc-calendar/src/locale/es_ES'; +import CalendarLocale from '../../vc-picker/locale/es_ES'; import TimePickerLocale from '../../time-picker/locale/es_ES'; +import type { PickerLocale } from '../generatePicker'; // Merge into a locale object -const locale = { +const locale: PickerLocale = { lang: { placeholder: 'Seleccionar fecha', rangePlaceholder: ['Fecha inicial', 'Fecha final'], @@ -14,6 +15,6 @@ const locale = { }; // All settings at: -// https://github.com/vueComponent/ant-design-vue/blob/master/components/date-picker/locale/example.json +// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json export default locale; diff --git a/components/date-picker/locale/et_EE.ts b/components/date-picker/locale/et_EE.tsx similarity index 57% rename from components/date-picker/locale/et_EE.ts rename to components/date-picker/locale/et_EE.tsx index 9c9263a3e..532e619d0 100644 --- a/components/date-picker/locale/et_EE.ts +++ b/components/date-picker/locale/et_EE.tsx @@ -1,8 +1,9 @@ -import CalendarLocale from '../../vc-calendar/src/locale/et_EE'; +import CalendarLocale from '../../vc-picker/locale/et_EE'; import TimePickerLocale from '../../time-picker/locale/et_EE'; +import type { PickerLocale } from '../generatePicker'; // 统一合并为完整的 Locale -const locale = { +const locale: PickerLocale = { lang: { placeholder: 'Vali kuupäev', rangePlaceholder: ['Algus kuupäev', 'Lõpu kuupäev'], @@ -14,6 +15,6 @@ const locale = { }; // All settings at: -// https://github.com/vueComponent/ant-design-vue/blob/master/components/date-picker/locale/example.json +// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json export default locale; diff --git a/components/date-picker/locale/example.json b/components/date-picker/locale/example.json index 4c260f922..2fb5ee33f 100644 --- a/components/date-picker/locale/example.json +++ b/components/date-picker/locale/example.json @@ -1,5 +1,6 @@ { "lang": { + "locale": "en_US", "placeholder": "Select date", "rangePlaceholder": ["Start date", "End date"], "today": "Today", diff --git a/components/date-picker/locale/fa_IR.ts b/components/date-picker/locale/fa_IR.ts deleted file mode 100644 index b67006a25..000000000 --- a/components/date-picker/locale/fa_IR.ts +++ /dev/null @@ -1,19 +0,0 @@ -import CalendarLocale from '../../vc-calendar/src/locale/fa_IR'; -import TimePickerLocale from '../../time-picker/locale/fa_IR'; - -// Merge into a locale object -const locale = { - lang: { - placeholder: 'انتخاب تاریخ', - rangePlaceholder: ['تاریخ شروع', 'تاریخ پایان'], - ...CalendarLocale, - }, - timePickerLocale: { - ...TimePickerLocale, - }, -}; - -// All settings at: -// https://github.com/vueComponent/ant-design-vue/blob/master/components/date-picker/locale/example.json - -export default locale; diff --git a/components/date-picker/locale/fa_IR.tsx b/components/date-picker/locale/fa_IR.tsx new file mode 100644 index 000000000..bcc3bd930 --- /dev/null +++ b/components/date-picker/locale/fa_IR.tsx @@ -0,0 +1,27 @@ +import CalendarLocale from '../../vc-picker/locale/fa_IR'; +import TimePickerLocale from '../../time-picker/locale/fa_IR'; +import type { PickerLocale } from '../generatePicker'; + +// Merge into a locale object +const locale: PickerLocale = { + lang: { + placeholder: 'انتخاب تاریخ', + yearPlaceholder: 'انتخاب سال', + quarterPlaceholder: 'انتخاب فصل', + monthPlaceholder: 'انتخاب ماه', + weekPlaceholder: 'انتخاب هفته', + rangePlaceholder: ['تاریخ شروع', 'تاریخ پایان'], + rangeYearPlaceholder: ['سال شروع', 'سال پایان'], + rangeMonthPlaceholder: ['ماه شروع', 'ماه پایان'], + rangeWeekPlaceholder: ['هفته شروع', 'هفته پایان'], + ...CalendarLocale, + }, + timePickerLocale: { + ...TimePickerLocale, + }, +}; + +// All settings at: +// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json + +export default locale; diff --git a/components/date-picker/locale/fi_FI.ts b/components/date-picker/locale/fi_FI.ts deleted file mode 100644 index d687f632a..000000000 --- a/components/date-picker/locale/fi_FI.ts +++ /dev/null @@ -1,19 +0,0 @@ -import CalendarLocale from '../../vc-calendar/src/locale/fi_FI'; -import TimePickerLocale from '../../time-picker/locale/fi_FI'; - -// Merge into a locale object -const locale = { - lang: { - placeholder: 'Valitse päivä', - rangePlaceholder: ['Alku päivä', 'Loppu päivä'], - ...CalendarLocale, - }, - timePickerLocale: { - ...TimePickerLocale, - }, -}; - -// All settings at: -// https://github.com/vueComponent/ant-design-vue/blob/master/components/date-picker/locale/example.json - -export default locale; diff --git a/components/date-picker/locale/fi_FI.tsx b/components/date-picker/locale/fi_FI.tsx new file mode 100644 index 000000000..7ca6d08a9 --- /dev/null +++ b/components/date-picker/locale/fi_FI.tsx @@ -0,0 +1,20 @@ +import CalendarLocale from '../../vc-picker/locale/fi_FI'; +import TimePickerLocale from '../../time-picker/locale/fi_FI'; +import type { PickerLocale } from '../generatePicker'; + +// Merge into a locale object +const locale: PickerLocale = { + lang: { + placeholder: 'Valitse päivä', + rangePlaceholder: ['Alkamispäivä', 'Päättymispäivä'], + ...CalendarLocale, + }, + timePickerLocale: { + ...TimePickerLocale, + }, +}; + +// All settings at: +// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json + +export default locale; diff --git a/components/date-picker/locale/fr_BE.ts b/components/date-picker/locale/fr_BE.tsx similarity index 72% rename from components/date-picker/locale/fr_BE.ts rename to components/date-picker/locale/fr_BE.tsx index 0cd937f1a..e1429761c 100644 --- a/components/date-picker/locale/fr_BE.ts +++ b/components/date-picker/locale/fr_BE.tsx @@ -1,8 +1,9 @@ -import CalendarLocale from '../../vc-calendar/src/locale/fr_BE'; +import CalendarLocale from '../../vc-picker/locale/fr_BE'; import TimePickerLocale from '../../time-picker/locale/fr_BE'; +import type { PickerLocale } from '../generatePicker'; // Merge into a locale object -const locale = { +const locale: PickerLocale = { lang: { placeholder: 'Sélectionner une date', rangePlaceholder: ['Date de début', 'Date de fin'], diff --git a/components/date-picker/locale/fr_CA.tsx b/components/date-picker/locale/fr_CA.tsx new file mode 100644 index 000000000..4146284aa --- /dev/null +++ b/components/date-picker/locale/fr_CA.tsx @@ -0,0 +1,27 @@ +import CalendarLocale from '../../vc-picker/locale/fr_CA'; +import TimePickerLocale from '../../time-picker/locale/fr_CA'; +import type { PickerLocale } from '../generatePicker'; + +// Merge into a locale object +const locale: PickerLocale = { + lang: { + placeholder: 'Sélectionner une date', + yearPlaceholder: 'Sélectionner une année', + quarterPlaceholder: 'Sélectionner un trimestre', + monthPlaceholder: 'Sélectionner un mois', + weekPlaceholder: 'Sélectionner une semaine', + rangePlaceholder: ['Date de début', 'Date de fin'], + rangeYearPlaceholder: ['Année de début', 'Année de fin'], + rangeMonthPlaceholder: ['Mois de début', 'Mois de fin'], + rangeWeekPlaceholder: ['Semaine de début', 'Semaine de fin'], + ...CalendarLocale, + }, + timePickerLocale: { + ...TimePickerLocale, + }, +}; + +// All settings at: +// https://github.com/ant-design/ant-design/issues/424 + +export default locale; diff --git a/components/date-picker/locale/fr_FR.ts b/components/date-picker/locale/fr_FR.ts deleted file mode 100644 index 9ee126c31..000000000 --- a/components/date-picker/locale/fr_FR.ts +++ /dev/null @@ -1,19 +0,0 @@ -import CalendarLocale from '../../vc-calendar/src/locale/fr_FR'; -import TimePickerLocale from '../../time-picker/locale/fr_FR'; - -// Merge into a locale object -const locale = { - lang: { - placeholder: 'Sélectionner une date', - rangePlaceholder: ['Date de début', 'Date de fin'], - ...CalendarLocale, - }, - timePickerLocale: { - ...TimePickerLocale, - }, -}; - -// All settings at: -// https://github.com/ant-design/ant-design/issues/424 - -export default locale; diff --git a/components/date-picker/locale/fr_FR.tsx b/components/date-picker/locale/fr_FR.tsx new file mode 100644 index 000000000..b8d94a3f1 --- /dev/null +++ b/components/date-picker/locale/fr_FR.tsx @@ -0,0 +1,27 @@ +import CalendarLocale from '../../vc-picker/locale/fr_FR'; +import TimePickerLocale from '../../time-picker/locale/fr_FR'; +import type { PickerLocale } from '../generatePicker'; + +// Merge into a locale object +const locale: PickerLocale = { + lang: { + placeholder: 'Sélectionner une date', + yearPlaceholder: 'Sélectionner une année', + quarterPlaceholder: 'Sélectionner un trimestre', + monthPlaceholder: 'Sélectionner un mois', + weekPlaceholder: 'Sélectionner une semaine', + rangePlaceholder: ['Date de début', 'Date de fin'], + rangeYearPlaceholder: ['Année de début', 'Année de fin'], + rangeMonthPlaceholder: ['Mois de début', 'Mois de fin'], + rangeWeekPlaceholder: ['Semaine de début', 'Semaine de fin'], + ...CalendarLocale, + }, + timePickerLocale: { + ...TimePickerLocale, + }, +}; + +// All settings at: +// https://github.com/ant-design/ant-design/issues/424 + +export default locale; diff --git a/components/date-picker/locale/ga_IE.ts b/components/date-picker/locale/ga_IE.ts deleted file mode 100644 index dc509192d..000000000 --- a/components/date-picker/locale/ga_IE.ts +++ /dev/null @@ -1,19 +0,0 @@ -import CalendarLocale from '../../vc-calendar/src/locale/ga_IE'; -import TimePickerLocale from '../../time-picker/locale/ga_IE'; - -// Merge into a locale object -const locale = { - lang: { - placeholder: 'Select date', - rangePlaceholder: ['Start date', 'End date'], - ...CalendarLocale, - }, - timePickerLocale: { - ...TimePickerLocale, - }, -}; - -// All settings at: -// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json - -export default locale; diff --git a/components/date-picker/locale/ga_IE.tsx b/components/date-picker/locale/ga_IE.tsx new file mode 100644 index 000000000..f57c463a0 --- /dev/null +++ b/components/date-picker/locale/ga_IE.tsx @@ -0,0 +1,27 @@ +import CalendarLocale from '../../vc-picker/locale/ga_IE'; +import TimePickerLocale from '../../time-picker/locale/ga_IE'; +import type { PickerLocale } from '../generatePicker'; + +// Merge into a locale object +const locale: PickerLocale = { + lang: { + placeholder: 'Roghnaigh dáta', + yearPlaceholder: 'Roghnaigh bliain', + quarterPlaceholder: 'Roghnaigh ráithe', + monthPlaceholder: 'Roghnaigh mí', + weekPlaceholder: 'Roghnaigh seachtain', + rangePlaceholder: ['Dáta tosaigh', 'Dáta deiridh'], + rangeYearPlaceholder: ['Tús na bliana', 'Deireadh na bliana'], + rangeMonthPlaceholder: ['Tosaigh mhí', 'Deireadh mhí'], + rangeWeekPlaceholder: ['Tosaigh an tseachtain', 'Deireadh na seachtaine'], + ...CalendarLocale, + }, + timePickerLocale: { + ...TimePickerLocale, + }, +}; + +// All settings at: +// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json + +export default locale; diff --git a/components/date-picker/locale/gl_ES.tsx b/components/date-picker/locale/gl_ES.tsx new file mode 100644 index 000000000..a3de016e0 --- /dev/null +++ b/components/date-picker/locale/gl_ES.tsx @@ -0,0 +1,20 @@ +import CalendarLocale from '../../vc-picker/locale/gl_ES'; +import TimePickerLocale from '../../time-picker/locale/gl_ES'; +import type { PickerLocale } from '../generatePicker'; + +// Merge into a locale object +const locale: PickerLocale = { + lang: { + placeholder: 'Escolla data', + rangePlaceholder: ['Data inicial', 'Data final'], + ...CalendarLocale, + }, + timePickerLocale: { + ...TimePickerLocale, + }, +}; + +// All settings at: +// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json + +export default locale; diff --git a/components/date-picker/locale/he_IL.ts b/components/date-picker/locale/he_IL.tsx similarity index 58% rename from components/date-picker/locale/he_IL.ts rename to components/date-picker/locale/he_IL.tsx index 6e2027dcb..818848378 100644 --- a/components/date-picker/locale/he_IL.ts +++ b/components/date-picker/locale/he_IL.tsx @@ -1,8 +1,9 @@ -import CalendarLocale from '../../vc-calendar/src/locale/he_IL'; +import CalendarLocale from '../../vc-picker/locale/he_IL'; import TimePickerLocale from '../../time-picker/locale/he_IL'; +import type { PickerLocale } from '../generatePicker'; // Merge into a locale object -const locale = { +const locale: PickerLocale = { lang: { placeholder: 'בחר תאריך', rangePlaceholder: ['תאריך התחלה', 'תאריך סיום'], @@ -14,6 +15,6 @@ const locale = { }; // All settings at: -// https://github.com/vueComponent/ant-design-vue/blob/master/components/date-picker/locale/example.json +// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json export default locale; diff --git a/components/date-picker/locale/hi_IN.ts b/components/date-picker/locale/hi_IN.ts deleted file mode 100644 index 53bf390ca..000000000 --- a/components/date-picker/locale/hi_IN.ts +++ /dev/null @@ -1,19 +0,0 @@ -import CalendarLocale from '../../vc-calendar/src/locale/hi_IN'; -import TimePickerLocale from '../../time-picker/locale/hi_IN'; - -// Merge into a locale object -const locale = { - lang: { - placeholder: 'तारीख़ चुनें', - rangePlaceholder: ['प्रारंभ तिथि', 'समाप्ति तिथि'], - ...CalendarLocale, - }, - timePickerLocale: { - ...TimePickerLocale, - }, -}; - -// All settings at: -// https://github.com/vueComponent/ant-design-vue/blob/master/components/date-picker/locale/example.json - -export default locale; diff --git a/components/date-picker/locale/hi_IN.tsx b/components/date-picker/locale/hi_IN.tsx new file mode 100644 index 000000000..b6afd6b22 --- /dev/null +++ b/components/date-picker/locale/hi_IN.tsx @@ -0,0 +1,27 @@ +import CalendarLocale from '../../vc-picker/locale/hi_IN'; +import TimePickerLocale from '../../time-picker/locale/hi_IN'; +import type { PickerLocale } from '../generatePicker'; + +// Merge into a locale object +const locale: PickerLocale = { + lang: { + placeholder: 'तारीख़ चुनें', + yearPlaceholder: 'वर्ष चुनें', + quarterPlaceholder: 'तिमाही चुनें', + monthPlaceholder: 'महीना चुनिए', + weekPlaceholder: 'सप्ताह चुनें', + rangePlaceholder: ['प्रारंभ तिथि', 'समाप्ति तिथि'], + rangeYearPlaceholder: ['आरंभिक वर्ष', 'अंत वर्ष'], + rangeMonthPlaceholder: ['आरंभिक महीना', 'अंत महीना'], + rangeWeekPlaceholder: ['आरंभिक सप्ताह', 'अंत सप्ताह'], + ...CalendarLocale, + }, + timePickerLocale: { + ...TimePickerLocale, + }, +}; + +// All settings at: +// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json + +export default locale; diff --git a/components/date-picker/locale/hr_HR.ts b/components/date-picker/locale/hr_HR.ts deleted file mode 100644 index 859cd1854..000000000 --- a/components/date-picker/locale/hr_HR.ts +++ /dev/null @@ -1,19 +0,0 @@ -import CalendarLocale from '../../vc-calendar/src/locale/hr_HR'; -import TimePickerLocale from '../../time-picker/locale/hr_HR'; - -// Merge into a locale object -const locale = { - lang: { - placeholder: 'Odaberite datum', - rangePlaceholder: ['Početni datum', 'Završni datum'], - ...CalendarLocale, - }, - timePickerLocale: { - ...TimePickerLocale, - }, -}; - -// All settings at: -// https://github.com/vueComponent/ant-design-vue/blob/master/components/date-picker/locale/example.json - -export default locale; diff --git a/components/date-picker/locale/hr_HR.tsx b/components/date-picker/locale/hr_HR.tsx new file mode 100644 index 000000000..186d6b0c1 --- /dev/null +++ b/components/date-picker/locale/hr_HR.tsx @@ -0,0 +1,27 @@ +import CalendarLocale from '../../vc-picker/locale/hr_HR'; +import TimePickerLocale from '../../time-picker/locale/hr_HR'; +import type { PickerLocale } from '../generatePicker'; + +// Merge into a locale object +const locale: PickerLocale = { + lang: { + placeholder: 'Odaberite datum', + yearPlaceholder: 'Odaberite godinu', + quarterPlaceholder: 'Odaberite četvrtinu', + monthPlaceholder: 'Odaberite mjesec', + weekPlaceholder: 'Odaberite tjedan', + rangePlaceholder: ['Početni datum', 'Završni datum'], + rangeYearPlaceholder: ['Početna godina', 'Završna godina'], + rangeMonthPlaceholder: ['Početni mjesec', 'Završni mjesec'], + rangeWeekPlaceholder: ['Početni tjedan', 'Završni tjedan'], + ...CalendarLocale, + }, + timePickerLocale: { + ...TimePickerLocale, + }, +}; + +// All settings at: +// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json + +export default locale; diff --git a/components/date-picker/locale/hu_HU.ts b/components/date-picker/locale/hu_HU.tsx similarity index 57% rename from components/date-picker/locale/hu_HU.ts rename to components/date-picker/locale/hu_HU.tsx index 11243bc8e..4d9b561c6 100644 --- a/components/date-picker/locale/hu_HU.ts +++ b/components/date-picker/locale/hu_HU.tsx @@ -1,8 +1,9 @@ -import CalendarLocale from '../../vc-calendar/src/locale/hu_HU'; +import CalendarLocale from '../../vc-picker/locale/hu_HU'; import TimePickerLocale from '../../time-picker/locale/hu_HU'; +import type { PickerLocale } from '../generatePicker'; // Merge into a locale object -const locale = { +const locale: PickerLocale = { lang: { placeholder: 'Válasszon dátumot', rangePlaceholder: ['Kezdő dátum', 'Befejezés dátuma'], @@ -14,6 +15,6 @@ const locale = { }; // All settings at: -// https://github.com/vueComponent/ant-design-vue/blob/master/components/date-picker/locale/example.json +// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json export default locale; diff --git a/components/date-picker/locale/id_ID.ts b/components/date-picker/locale/id_ID.tsx similarity index 57% rename from components/date-picker/locale/id_ID.ts rename to components/date-picker/locale/id_ID.tsx index 0c253edea..d453df523 100644 --- a/components/date-picker/locale/id_ID.ts +++ b/components/date-picker/locale/id_ID.tsx @@ -1,8 +1,9 @@ -import CalendarLocale from '../../vc-calendar/src/locale/id_ID'; +import CalendarLocale from '../../vc-picker/locale/id_ID'; import TimePickerLocale from '../../time-picker/locale/id_ID'; +import type { PickerLocale } from '../generatePicker'; // Merge into a locale object -const locale = { +const locale: PickerLocale = { lang: { placeholder: 'Pilih tanggal', rangePlaceholder: ['Mulai tanggal', 'Tanggal akhir'], @@ -14,6 +15,6 @@ const locale = { }; // All settings at: -// https://github.com/vueComponent/ant-design-vue/blob/master/components/date-picker/locale/example.json +// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json export default locale; diff --git a/components/date-picker/locale/is_IS.ts b/components/date-picker/locale/is_IS.tsx similarity index 56% rename from components/date-picker/locale/is_IS.ts rename to components/date-picker/locale/is_IS.tsx index 150adfc38..7b5dc2f99 100644 --- a/components/date-picker/locale/is_IS.ts +++ b/components/date-picker/locale/is_IS.tsx @@ -1,8 +1,9 @@ -import CalendarLocale from '../../vc-calendar/src/locale/is_IS'; +import CalendarLocale from '../../vc-picker/locale/is_IS'; import TimePickerLocale from '../../time-picker/locale/is_IS'; +import type { PickerLocale } from '../generatePicker'; // Merge into a locale object -const locale = { +const locale: PickerLocale = { lang: { placeholder: 'Veldu dag', rangePlaceholder: ['Upphafsdagur', 'Lokadagur'], @@ -14,6 +15,6 @@ const locale = { }; // All settings at: -// https://github.com/vueComponent/ant-design-vue/blob/master/components/date-picker/locale/example.json +// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json export default locale; diff --git a/components/date-picker/locale/it_IT.ts b/components/date-picker/locale/it_IT.tsx similarity index 72% rename from components/date-picker/locale/it_IT.ts rename to components/date-picker/locale/it_IT.tsx index a89b66a01..43de396f4 100644 --- a/components/date-picker/locale/it_IT.ts +++ b/components/date-picker/locale/it_IT.tsx @@ -1,8 +1,9 @@ -import CalendarLocale from '../../vc-calendar/src/locale/it_IT'; +import CalendarLocale from '../../vc-picker/locale/it_IT'; import TimePickerLocale from '../../time-picker/locale/it_IT'; +import type { PickerLocale } from '../generatePicker'; // Merge into a locale object -const locale = { +const locale: PickerLocale = { lang: { placeholder: 'Selezionare la data', rangePlaceholder: ["Data d'inizio", 'Data di fine'], diff --git a/components/date-picker/locale/ja_JP.ts b/components/date-picker/locale/ja_JP.tsx similarity index 51% rename from components/date-picker/locale/ja_JP.ts rename to components/date-picker/locale/ja_JP.tsx index 67b5c4c35..58ea44ef9 100644 --- a/components/date-picker/locale/ja_JP.ts +++ b/components/date-picker/locale/ja_JP.tsx @@ -1,7 +1,9 @@ -import CalendarLocale from '../../vc-calendar/src/locale/ja_JP'; +import CalendarLocale from '../../vc-picker/locale/ja_JP'; import TimePickerLocale from '../../time-picker/locale/ja_JP'; +import type { PickerLocale } from '../generatePicker'; -const locale = { +// Merge into a locale object +const locale: PickerLocale = { lang: { placeholder: '日付を選択', rangePlaceholder: ['開始日付', '終了日付'], @@ -13,6 +15,6 @@ const locale = { }; // All settings at: -// https://github.com/vueComponent/ant-design-vue/blob/master/components/date-picker/locale/example.json +// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json export default locale; diff --git a/components/date-picker/locale/kk_KZ.tsx b/components/date-picker/locale/kk_KZ.tsx new file mode 100644 index 000000000..5a4a7697a --- /dev/null +++ b/components/date-picker/locale/kk_KZ.tsx @@ -0,0 +1,27 @@ +import CalendarLocale from '../../vc-picker/locale/kk_KZ'; +import TimePickerLocale from '../../time-picker/locale/kk_KZ'; +import type { PickerLocale } from '../generatePicker'; + +// Merge into a locale object +const locale: PickerLocale = { + lang: { + placeholder: 'Күнді таңдаңыз', + yearPlaceholder: 'Жылды таңдаңыз', + quarterPlaceholder: 'Тоқсанды таңдаңыз', + monthPlaceholder: 'Айды таңдаңыз', + weekPlaceholder: 'Аптаны таңдаңыз', + rangePlaceholder: ['Бастау күні', 'Аяқталу күні'], + rangeYearPlaceholder: ['Бастау жылы', 'Аяқталу жылы'], + rangeMonthPlaceholder: ['Бастау айы', 'Аяқталу айы'], + rangeWeekPlaceholder: ['Бастау апта', 'Аяқталу апта'], + ...CalendarLocale, + }, + timePickerLocale: { + ...TimePickerLocale, + }, +}; + +// All settings at: +// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json + +export default locale; diff --git a/components/date-picker/locale/kmr_IQ.tsx b/components/date-picker/locale/kmr_IQ.tsx new file mode 100755 index 000000000..dbbea24e1 --- /dev/null +++ b/components/date-picker/locale/kmr_IQ.tsx @@ -0,0 +1,19 @@ +import CalendarLocale from '../../vc-picker/locale/kmr_IQ'; +import TimePickerLocale from '../../time-picker/locale/kmr_IQ'; +import type { PickerLocale } from '../generatePicker'; + +// Merge into a locale object +const locale: PickerLocale = { + lang: { + placeholder: 'Dîrok hilbijêre', + rangePlaceholder: ['Dîroka destpêkê', 'Dîroka dawîn'], + ...CalendarLocale, + }, + timePickerLocale: { + ...TimePickerLocale, + }, +}; + +// All settings at: +// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json +export default locale; diff --git a/components/date-picker/locale/kn_IN.ts b/components/date-picker/locale/kn_IN.tsx similarity index 62% rename from components/date-picker/locale/kn_IN.ts rename to components/date-picker/locale/kn_IN.tsx index 633b92b15..0eaf17e89 100644 --- a/components/date-picker/locale/kn_IN.ts +++ b/components/date-picker/locale/kn_IN.tsx @@ -1,8 +1,9 @@ -import CalendarLocale from '../../vc-calendar/src/locale/kn_IN'; +import CalendarLocale from '../../vc-picker/locale/kn_IN'; import TimePickerLocale from '../../time-picker/locale/kn_IN'; +import type { PickerLocale } from '../generatePicker'; // Merge into a locale object -const locale = { +const locale: PickerLocale = { lang: { placeholder: 'ದಿನಾಂಕ ಆಯ್ಕೆಮಾಡಿ', rangePlaceholder: ['ಪ್ರಾರಂಭ ದಿನಾಂಕ', 'ಅಂತಿಮ ದಿನಾಂಕ'], @@ -14,6 +15,6 @@ const locale = { }; // All settings at: -// https://github.com/vueComponent/ant-design-vue/blob/master/components/date-picker/locale/example.json +// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json export default locale; diff --git a/components/date-picker/locale/ko_KR.ts b/components/date-picker/locale/ko_KR.tsx similarity index 56% rename from components/date-picker/locale/ko_KR.ts rename to components/date-picker/locale/ko_KR.tsx index 2df0e5c7e..c7c3d2750 100644 --- a/components/date-picker/locale/ko_KR.ts +++ b/components/date-picker/locale/ko_KR.tsx @@ -1,8 +1,9 @@ -import CalendarLocale from '../../vc-calendar/src/locale/ko_KR'; +import CalendarLocale from '../../vc-picker/locale/ko_KR'; import TimePickerLocale from '../../time-picker/locale/ko_KR'; +import type { PickerLocale } from '../generatePicker'; // Merge into a locale object -const locale = { +const locale: PickerLocale = { lang: { placeholder: '날짜 선택', rangePlaceholder: ['시작일', '종료일'], @@ -14,6 +15,6 @@ const locale = { }; // All settings at: -// https://github.com/vueComponent/ant-design-vue/blob/master/components/date-picker/locale/example.json +// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json export default locale; diff --git a/components/date-picker/locale/ku_IQ.ts b/components/date-picker/locale/ku_IQ.ts deleted file mode 100755 index bc07a52ec..000000000 --- a/components/date-picker/locale/ku_IQ.ts +++ /dev/null @@ -1,18 +0,0 @@ -import CalendarLocale from '../../vc-calendar/src/locale/ku_IQ'; -import TimePickerLocale from '../../time-picker/locale/ku_IQ'; - -// Merge into a locale object -const locale = { - lang: { - placeholder: 'Dîrok hilbijêre', - rangePlaceholder: ['Dîroka destpêkê', 'Dîroka dawîn'], - ...CalendarLocale, - }, - timePickerLocale: { - ...TimePickerLocale, - }, -}; - -// All settings at: -// https://github.com/vueComponent/ant-design-vue/blob/master/components/date-picker/locale/example.json -export default locale; diff --git a/components/date-picker/locale/ku_KU.ts b/components/date-picker/locale/ku_KU.ts deleted file mode 100644 index 57c6f44a7..000000000 --- a/components/date-picker/locale/ku_KU.ts +++ /dev/null @@ -1,19 +0,0 @@ -import CalendarLocale from '../../vc-calendar/src/locale/ku_KU'; -import TimePickerLocale from '../../time-picker/locale/ku_KU'; - -// Merge into a locale object -const locale = { - lang: { - placeholder: 'هەڵبژاردنی ڕێکەوت', - rangePlaceholder: ['دەستپێکی ڕێکەوت', 'کوتایی ڕێکەوت'], - ...CalendarLocale, - }, - timePickerLocale: { - ...TimePickerLocale, - }, -}; - -// All settings at: -// https://github.com/vueComponent/ant-design-vue/blob/master/components/date-picker/locale/example.json - -export default locale; diff --git a/components/date-picker/locale/lt_LT.tsx b/components/date-picker/locale/lt_LT.tsx new file mode 100644 index 000000000..66d69eb16 --- /dev/null +++ b/components/date-picker/locale/lt_LT.tsx @@ -0,0 +1,27 @@ +import CalendarLocale from '../../vc-picker/locale/lt_LT'; +import TimePickerLocale from '../../time-picker/locale/lt_LT'; +import type { PickerLocale } from '../generatePicker'; + +// Merge into a locale object +const locale: PickerLocale = { + lang: { + placeholder: 'Pasirinkite datą', + yearPlaceholder: 'Pasirinkite metus', + quarterPlaceholder: 'Pasirinkite ketvirtį', + monthPlaceholder: 'Pasirinkite mėnesį', + weekPlaceholder: 'Pasirinkite savaitę', + rangePlaceholder: ['Pradžios data', 'Pabaigos data'], + rangeYearPlaceholder: ['Pradžios metai', 'Pabaigos metai'], + rangeMonthPlaceholder: ['Pradžios mėnesis', 'Pabaigos mėnesis'], + rangeWeekPlaceholder: ['Pradžios savaitė', 'Pabaigos savaitė'], + ...CalendarLocale, + }, + timePickerLocale: { + ...TimePickerLocale, + }, +}; + +// All settings at: +// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json + +export default locale; diff --git a/components/date-picker/locale/lv_LV.ts b/components/date-picker/locale/lv_LV.tsx similarity index 57% rename from components/date-picker/locale/lv_LV.ts rename to components/date-picker/locale/lv_LV.tsx index 137520bf7..a735b5f69 100644 --- a/components/date-picker/locale/lv_LV.ts +++ b/components/date-picker/locale/lv_LV.tsx @@ -1,8 +1,9 @@ -import CalendarLocale from '../../vc-calendar/src/locale/lv_LV'; +import CalendarLocale from '../../vc-picker/locale/lv_LV'; import TimePickerLocale from '../../time-picker/locale/lv_LV'; +import type { PickerLocale } from '../generatePicker'; // Merge into a locale object -const locale = { +const locale: PickerLocale = { lang: { placeholder: 'Izvēlieties datumu', rangePlaceholder: ['Sākuma datums', 'Beigu datums'], @@ -14,6 +15,6 @@ const locale = { }; // All settings at: -// https://github.com/vueComponent/ant-design-vue/blob/master/components/date-picker/locale/example.json +// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json export default locale; diff --git a/components/date-picker/locale/mk_MK.ts b/components/date-picker/locale/mk_MK.tsx similarity index 58% rename from components/date-picker/locale/mk_MK.ts rename to components/date-picker/locale/mk_MK.tsx index 7367b3467..902857ce9 100644 --- a/components/date-picker/locale/mk_MK.ts +++ b/components/date-picker/locale/mk_MK.tsx @@ -1,8 +1,9 @@ -import CalendarLocale from '../../vc-calendar/src/locale/mk_MK'; +import CalendarLocale from '../../vc-picker/locale/mk_MK'; import TimePickerLocale from '../../time-picker/locale/mk_MK'; +import type { PickerLocale } from '../generatePicker'; // Merge into a locale object -const locale = { +const locale: PickerLocale = { lang: { placeholder: 'Избери датум', rangePlaceholder: ['Од датум', 'До датум'], @@ -14,6 +15,6 @@ const locale = { }; // All settings at: -// https://github.com/vueComponent/ant-design-vue/blob/master/components/date-picker/locale/example.json +// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json export default locale; diff --git a/components/date-picker/locale/mn_MN.ts b/components/date-picker/locale/mn_MN.tsx similarity index 59% rename from components/date-picker/locale/mn_MN.ts rename to components/date-picker/locale/mn_MN.tsx index c6a3c86ab..aa06a31dd 100644 --- a/components/date-picker/locale/mn_MN.ts +++ b/components/date-picker/locale/mn_MN.tsx @@ -1,8 +1,9 @@ -import CalendarLocale from '../../vc-calendar/src/locale/mn_MN'; +import CalendarLocale from '../../vc-picker/locale/mn_MN'; import TimePickerLocale from '../../time-picker/locale/mn_MN'; +import type { PickerLocale } from '../generatePicker'; // Merge into a locale object -const locale = { +const locale: PickerLocale = { lang: { placeholder: 'Огноо сонгох', rangePlaceholder: ['Эхлэх огноо', 'Дуусах огноо'], @@ -14,6 +15,6 @@ const locale = { }; // All settings at: -// https://github.com/vueComponent/ant-design-vue/blob/master/components/date-picker/locale/example.json +// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json export default locale; diff --git a/components/date-picker/locale/ms_MY.ts b/components/date-picker/locale/ms_MY.tsx similarity index 56% rename from components/date-picker/locale/ms_MY.ts rename to components/date-picker/locale/ms_MY.tsx index f421c7c19..3cd9979e8 100644 --- a/components/date-picker/locale/ms_MY.ts +++ b/components/date-picker/locale/ms_MY.tsx @@ -1,8 +1,9 @@ -import CalendarLocale from '../../vc-calendar/src/locale/ms_MY'; +import CalendarLocale from '../../vc-picker/locale/ms_MY'; import TimePickerLocale from '../../time-picker/locale/ms_MY'; +import type { PickerLocale } from '../generatePicker'; // Merge into a locale object -const locale = { +const locale: PickerLocale = { lang: { placeholder: 'Pilih tarikh', rangePlaceholder: ['Tarikh mula', 'Tarikh akhir'], @@ -14,6 +15,6 @@ const locale = { }; // All settings at: -// https://github.com/vueComponent/ant-design-vue/blob/master/components/date-picker/locale/example.json +// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json export default locale; diff --git a/components/date-picker/locale/nb_NO.ts b/components/date-picker/locale/nb_NO.ts deleted file mode 100644 index dcbc38126..000000000 --- a/components/date-picker/locale/nb_NO.ts +++ /dev/null @@ -1,19 +0,0 @@ -import CalendarLocale from '../../vc-calendar/src/locale/nb_NO'; -import TimePickerLocale from '../../time-picker/locale/nb_NO'; - -// Merge into a locale object -const locale = { - lang: { - placeholder: 'Velg dato', - rangePlaceholder: ['Startdato', 'Sluttdato'], - ...CalendarLocale, - }, - timePickerLocale: { - ...TimePickerLocale, - }, -}; - -// All settings at: -// https://github.com/vueComponent/ant-design-vue/blob/master/components/date-picker/locale/example.json - -export default locale; diff --git a/components/date-picker/locale/nb_NO.tsx b/components/date-picker/locale/nb_NO.tsx new file mode 100644 index 000000000..6e232173b --- /dev/null +++ b/components/date-picker/locale/nb_NO.tsx @@ -0,0 +1,27 @@ +import CalendarLocale from '../../vc-picker/locale/nb_NO'; +import TimePickerLocale from '../../time-picker/locale/nb_NO'; +import type { PickerLocale } from '../generatePicker'; + +// Merge into a locale object +const locale: PickerLocale = { + lang: { + placeholder: 'Velg dato', + yearPlaceholder: 'Velg år', + quarterPlaceholder: 'Velg kvartal', + monthPlaceholder: 'Velg måned', + weekPlaceholder: 'Velg uke', + rangePlaceholder: ['Startdato', 'Sluttdato'], + rangeYearPlaceholder: ['Startår', 'Sluttår'], + rangeMonthPlaceholder: ['Startmåned', 'Sluttmåned'], + rangeWeekPlaceholder: ['Start uke', 'Sluttuke'], + ...CalendarLocale, + }, + timePickerLocale: { + ...TimePickerLocale, + }, +}; + +// All settings at: +// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json + +export default locale; diff --git a/components/date-picker/locale/nl_BE.ts b/components/date-picker/locale/nl_BE.ts deleted file mode 100644 index 6ee0e410f..000000000 --- a/components/date-picker/locale/nl_BE.ts +++ /dev/null @@ -1,19 +0,0 @@ -import CalendarLocale from '../../vc-calendar/src/locale/nl_BE'; -import TimePickerLocale from '../../time-picker/locale/nl_BE'; - -// Merge into a locale object -const locale = { - lang: { - placeholder: 'Selecteer datum', - rangePlaceholder: ['Begin datum', 'Eind datum'], - ...CalendarLocale, - }, - timePickerLocale: { - ...TimePickerLocale, - }, -}; - -// All settings at: -// https://github.com/ant-design/ant-design/issues/424 - -export default locale; diff --git a/components/date-picker/locale/nl_BE.tsx b/components/date-picker/locale/nl_BE.tsx new file mode 100644 index 000000000..93bf9fa25 --- /dev/null +++ b/components/date-picker/locale/nl_BE.tsx @@ -0,0 +1,27 @@ +import CalendarLocale from '../../vc-picker/locale/nl_BE'; +import TimePickerLocale from '../../time-picker/locale/nl_BE'; +import type { PickerLocale } from '../generatePicker'; + +// Merge into a locale object +const locale: PickerLocale = { + lang: { + monthPlaceholder: 'Selecteer maand', + placeholder: 'Selecteer datum', + quarterPlaceholder: 'Selecteer kwartaal', + rangeMonthPlaceholder: ['Begin maand', 'Eind maand'], + rangePlaceholder: ['Begin datum', 'Eind datum'], + rangeWeekPlaceholder: ['Begin week', 'Eind week'], + rangeYearPlaceholder: ['Begin jaar', 'Eind jaar'], + weekPlaceholder: 'Selecteer week', + yearPlaceholder: 'Selecteer jaar', + ...CalendarLocale, + }, + timePickerLocale: { + ...TimePickerLocale, + }, +}; + +// All settings at: +// https://github.com/ant-design/ant-design/issues/424 + +export default locale; diff --git a/components/date-picker/locale/nl_NL.ts b/components/date-picker/locale/nl_NL.ts deleted file mode 100644 index dfc2ead84..000000000 --- a/components/date-picker/locale/nl_NL.ts +++ /dev/null @@ -1,19 +0,0 @@ -import CalendarLocale from '../../vc-calendar/src/locale/nl_NL'; -import TimePickerLocale from '../../time-picker/locale/nl_NL'; - -// Merge into a locale object -const locale = { - lang: { - placeholder: 'Selecteer datum', - rangePlaceholder: ['Begin datum', 'Eind datum'], - ...CalendarLocale, - }, - timePickerLocale: { - ...TimePickerLocale, - }, -}; - -// All settings at: -// https://github.com/ant-design/ant-design/issues/424 - -export default locale; diff --git a/components/date-picker/locale/nl_NL.tsx b/components/date-picker/locale/nl_NL.tsx new file mode 100644 index 000000000..3d7e82934 --- /dev/null +++ b/components/date-picker/locale/nl_NL.tsx @@ -0,0 +1,27 @@ +import CalendarLocale from '../../vc-picker/locale/nl_NL'; +import TimePickerLocale from '../../time-picker/locale/nl_NL'; +import type { PickerLocale } from '../generatePicker'; + +// Merge into a locale object +const locale: PickerLocale = { + lang: { + monthPlaceholder: 'Selecteer maand', + placeholder: 'Selecteer datum', + quarterPlaceholder: 'Selecteer kwartaal', + rangeMonthPlaceholder: ['Begin maand', 'Eind maand'], + rangePlaceholder: ['Begin datum', 'Eind datum'], + rangeWeekPlaceholder: ['Begin week', 'Eind week'], + rangeYearPlaceholder: ['Begin jaar', 'Eind jaar'], + weekPlaceholder: 'Selecteer week', + yearPlaceholder: 'Selecteer jaar', + ...CalendarLocale, + }, + timePickerLocale: { + ...TimePickerLocale, + }, +}; + +// All settings at: +// https://github.com/ant-design/ant-design/issues/424 + +export default locale; diff --git a/components/date-picker/locale/pl_PL.ts b/components/date-picker/locale/pl_PL.tsx similarity index 57% rename from components/date-picker/locale/pl_PL.ts rename to components/date-picker/locale/pl_PL.tsx index 2f4081ad2..1c66ee39a 100644 --- a/components/date-picker/locale/pl_PL.ts +++ b/components/date-picker/locale/pl_PL.tsx @@ -1,8 +1,9 @@ -import CalendarLocale from '../../vc-calendar/src/locale/pl_PL'; +import CalendarLocale from '../../vc-picker/locale/pl_PL'; import TimePickerLocale from '../../time-picker/locale/pl_PL'; +import type { PickerLocale } from '../generatePicker'; // Merge into a locale object -const locale = { +const locale: PickerLocale = { lang: { placeholder: 'Wybierz datę', rangePlaceholder: ['Data początkowa', 'Data końcowa'], @@ -14,6 +15,6 @@ const locale = { }; // All settings at: -// https://github.com/vueComponent/ant-design-vue/blob/master/components/date-picker/locale/example.json +// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json export default locale; diff --git a/components/date-picker/locale/pt_BR.ts b/components/date-picker/locale/pt_BR.ts deleted file mode 100644 index 4b6b53748..000000000 --- a/components/date-picker/locale/pt_BR.ts +++ /dev/null @@ -1,19 +0,0 @@ -import CalendarLocale from '../../vc-calendar/src/locale/pt_BR'; -import TimePickerLocale from '../../time-picker/locale/pt_BR'; - -// Merge into a locale object -const locale = { - lang: { - placeholder: 'Selecionar data', - rangePlaceholder: ['Data de início', 'Data de fim'], - ...CalendarLocale, - }, - timePickerLocale: { - ...TimePickerLocale, - }, -}; - -// All settings at: -// https://github.com/vueComponent/ant-design-vue/blob/master/components/date-picker/locale/example.json - -export default locale; diff --git a/components/date-picker/locale/pt_BR.tsx b/components/date-picker/locale/pt_BR.tsx new file mode 100644 index 000000000..da1e8b915 --- /dev/null +++ b/components/date-picker/locale/pt_BR.tsx @@ -0,0 +1,20 @@ +import CalendarLocale from '../../vc-picker/locale/pt_BR'; +import TimePickerLocale from '../../time-picker/locale/pt_BR'; +import type { PickerLocale } from '../generatePicker'; + +// Merge into a locale object +const locale: PickerLocale = { + lang: { + placeholder: 'Selecionar data', + rangePlaceholder: ['Data inicial', 'Data final'], + ...CalendarLocale, + }, + timePickerLocale: { + ...TimePickerLocale, + }, +}; + +// All settings at: +// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json + +export default locale; diff --git a/components/date-picker/locale/pt_PT.ts b/components/date-picker/locale/pt_PT.tsx similarity index 82% rename from components/date-picker/locale/pt_PT.ts rename to components/date-picker/locale/pt_PT.tsx index 76d5ab147..37e808931 100644 --- a/components/date-picker/locale/pt_PT.ts +++ b/components/date-picker/locale/pt_PT.tsx @@ -1,8 +1,9 @@ -import CalendarLocale from '../../vc-calendar/src/locale/pt_PT'; +import CalendarLocale from '../../vc-picker/locale/pt_PT'; import TimePickerLocale from '../../time-picker/locale/pt_PT'; +import type { PickerLocale } from '../generatePicker'; // Merge into a locale object -const locale = { +const locale: PickerLocale = { lang: { ...CalendarLocale, placeholder: 'Data', @@ -41,6 +42,6 @@ const locale = { }; // All settings at: -// https://github.com/vueComponent/ant-design-vue/blob/master/components/date-picker/locale/example.json +// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json export default locale; diff --git a/components/date-picker/locale/ro_RO.ts b/components/date-picker/locale/ro_RO.tsx similarity index 57% rename from components/date-picker/locale/ro_RO.ts rename to components/date-picker/locale/ro_RO.tsx index 0069d1b76..7f8d615ed 100644 --- a/components/date-picker/locale/ro_RO.ts +++ b/components/date-picker/locale/ro_RO.tsx @@ -1,8 +1,9 @@ -import CalendarLocale from '../../vc-calendar/src/locale/ro_RO'; +import CalendarLocale from '../../vc-picker/locale/ro_RO'; import TimePickerLocale from '../../time-picker/locale/ro_RO'; +import type { PickerLocale } from '../generatePicker'; // Merge into a locale object -const locale = { +const locale: PickerLocale = { lang: { placeholder: 'Selectează data', rangePlaceholder: ['Data start', 'Data sfârșit'], @@ -14,6 +15,6 @@ const locale = { }; // All settings at: -// https://github.com/vueComponent/ant-design-vue/blob/master/components/date-picker/locale/example.json +// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json export default locale; diff --git a/components/date-picker/locale/ru_RU.ts b/components/date-picker/locale/ru_RU.ts deleted file mode 100644 index 6694d52cf..000000000 --- a/components/date-picker/locale/ru_RU.ts +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Created by Andrey Gayvoronsky on 13/04/16. - */ - -import CalendarLocale from '../../vc-calendar/src/locale/ru_RU'; -import TimePickerLocale from '../../time-picker/locale/ru_RU'; - -const locale = { - lang: { - placeholder: 'Выберите дату', - rangePlaceholder: ['Начальная дата', 'Конечная дата'], - ...CalendarLocale, - }, - timePickerLocale: { - ...TimePickerLocale, - }, -}; - -// All settings at: -// https://github.com/vueComponent/ant-design-vue/blob/master/components/date-picker/locale/example.json - -export default locale; diff --git a/components/date-picker/locale/ru_RU.tsx b/components/date-picker/locale/ru_RU.tsx new file mode 100644 index 000000000..07f07af82 --- /dev/null +++ b/components/date-picker/locale/ru_RU.tsx @@ -0,0 +1,29 @@ +/** Created by Andrey Gayvoronsky on 13/04/16. */ + +import CalendarLocale from '../../vc-picker/locale/ru_RU'; +import TimePickerLocale from '../../time-picker/locale/ru_RU'; +import type { PickerLocale } from '../generatePicker'; + +// Merge into a locale object +const locale: PickerLocale = { + lang: { + placeholder: 'Выберите дату', + yearPlaceholder: 'Выберите год', + quarterPlaceholder: 'Выберите квартал', + monthPlaceholder: 'Выберите месяц', + weekPlaceholder: 'Выберите неделю', + rangePlaceholder: ['Начальная дата', 'Конечная дата'], + rangeYearPlaceholder: ['Начальный год', 'Год окончания'], + rangeMonthPlaceholder: ['Начальный месяц', 'Конечный месяц'], + rangeWeekPlaceholder: ['Начальная неделя', 'Конечная неделя'], + ...CalendarLocale, + }, + timePickerLocale: { + ...TimePickerLocale, + }, +}; + +// All settings at: +// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json + +export default locale; diff --git a/components/date-picker/locale/sk_SK.ts b/components/date-picker/locale/sk_SK.tsx similarity index 55% rename from components/date-picker/locale/sk_SK.ts rename to components/date-picker/locale/sk_SK.tsx index b7afae64c..700f7ffdb 100644 --- a/components/date-picker/locale/sk_SK.ts +++ b/components/date-picker/locale/sk_SK.tsx @@ -1,8 +1,9 @@ -import CalendarLocale from '../../vc-calendar/src/locale/sk_SK'; +import CalendarLocale from '../../vc-picker/locale/sk_SK'; import TimePickerLocale from '../../time-picker/locale/sk_SK'; +import type { PickerLocale } from '../generatePicker'; // 统一合并为完整的 Locale -const locale = { +const locale: PickerLocale = { lang: { placeholder: 'Vybrať dátum', rangePlaceholder: ['Od', 'Do'], @@ -14,6 +15,6 @@ const locale = { }; // All settings at: -// https://github.com/vueComponent/ant-design-vue/blob/master/components/date-picker/locale/example.json +// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json export default locale; diff --git a/components/date-picker/locale/sl_SI.ts b/components/date-picker/locale/sl_SI.tsx similarity index 85% rename from components/date-picker/locale/sl_SI.ts rename to components/date-picker/locale/sl_SI.tsx index 342180426..935fadf95 100644 --- a/components/date-picker/locale/sl_SI.ts +++ b/components/date-picker/locale/sl_SI.tsx @@ -1,8 +1,10 @@ import TimePickerLocale from '../../time-picker/locale/sl_SI'; +import type { PickerLocale } from '../generatePicker'; // Merge into a locale object -const locale = { +const locale: PickerLocale = { lang: { + locale: 'sl', placeholder: 'Izberite datum', rangePlaceholder: ['Začetni datum', 'Končni datum'], today: 'Danes', @@ -38,6 +40,6 @@ const locale = { }; // All settings at: -// https://github.com/vueComponent/ant-design-vue/blob/master/components/date-picker/locale/example.json +// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json export default locale; diff --git a/components/date-picker/locale/sr_RS.ts b/components/date-picker/locale/sr_RS.ts deleted file mode 100644 index 3241ec26f..000000000 --- a/components/date-picker/locale/sr_RS.ts +++ /dev/null @@ -1,19 +0,0 @@ -import CalendarLocale from '../../vc-calendar/src/locale/sr_RS'; -import TimePickerLocale from '../../time-picker/locale/sr_RS'; - -// Merge into a locale object -const locale = { - lang: { - placeholder: 'Izaberite datum', - rangePlaceholder: ['Početni datum', 'Krajnji datum'], - ...CalendarLocale, - }, - timePickerLocale: { - ...TimePickerLocale, - }, -}; - -// All settings at: -// https://github.com/vueComponent/ant-design-vue/blob/master/components/date-picker/locale/example.json - -export default locale; diff --git a/components/date-picker/locale/sr_RS.tsx b/components/date-picker/locale/sr_RS.tsx new file mode 100644 index 000000000..3edd34bd6 --- /dev/null +++ b/components/date-picker/locale/sr_RS.tsx @@ -0,0 +1,27 @@ +import CalendarLocale from '../../vc-picker/locale/sr_RS'; +import TimePickerLocale from '../../time-picker/locale/sr_RS'; +import type { PickerLocale } from '../generatePicker'; + +// Merge into a locale object +const locale: PickerLocale = { + lang: { + placeholder: 'Izaberi datum', + yearPlaceholder: 'Izaberi godinu', + quarterPlaceholder: 'Izaberi tromesečje', + monthPlaceholder: 'Izaberi mesec', + weekPlaceholder: 'Izaberi sedmicu', + rangePlaceholder: ['Datum početka', 'Datum završetka'], + rangeYearPlaceholder: ['Godina početka', 'Godina završetka'], + rangeMonthPlaceholder: ['Mesec početka', 'Mesec završetka'], + rangeWeekPlaceholder: ['Sedmica početka', 'Sedmica završetka'], + ...CalendarLocale, + }, + timePickerLocale: { + ...TimePickerLocale, + }, +}; + +// All settings at: +// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json + +export default locale; diff --git a/components/date-picker/locale/sv_SE.ts b/components/date-picker/locale/sv_SE.ts deleted file mode 100644 index 438cc08e7..000000000 --- a/components/date-picker/locale/sv_SE.ts +++ /dev/null @@ -1,18 +0,0 @@ -import CalendarLocale from '../../vc-calendar/src/locale/sv_SE'; -import TimePickerLocale from '../../time-picker/locale/sv_SE'; - -const locale = { - lang: { - placeholder: 'Välj datum', - rangePlaceholder: ['Startdatum', 'Slutdatum'], - ...CalendarLocale, - }, - timePickerLocale: { - ...TimePickerLocale, - }, -}; - -// All settings at: -// https://github.com/vueComponent/ant-design-vue/blob/master/components/date-picker/locale/example.json - -export default locale; diff --git a/components/date-picker/locale/sv_SE.tsx b/components/date-picker/locale/sv_SE.tsx new file mode 100644 index 000000000..270da3fa1 --- /dev/null +++ b/components/date-picker/locale/sv_SE.tsx @@ -0,0 +1,27 @@ +import CalendarLocale from '../../vc-picker/locale/sv_SE'; +import TimePickerLocale from '../../time-picker/locale/sv_SE'; +import type { PickerLocale } from '../generatePicker'; + +// Merge into a locale object +const locale: PickerLocale = { + lang: { + placeholder: 'Välj datum', + yearPlaceholder: 'Välj år', + quarterPlaceholder: 'Välj kvartal', + monthPlaceholder: 'Välj månad', + weekPlaceholder: 'Välj vecka', + rangePlaceholder: ['Startdatum', 'Slutdatum'], + rangeYearPlaceholder: ['Startår', 'Slutår'], + rangeMonthPlaceholder: ['Startmånad', 'Slutmånad'], + rangeWeekPlaceholder: ['Startvecka', 'Slutvecka'], + ...CalendarLocale, + }, + timePickerLocale: { + ...TimePickerLocale, + }, +}; + +// All settings at: +// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json + +export default locale; diff --git a/components/date-picker/locale/ta_IN.ts b/components/date-picker/locale/ta_IN.tsx similarity index 65% rename from components/date-picker/locale/ta_IN.ts rename to components/date-picker/locale/ta_IN.tsx index 9c754468c..c7371f905 100644 --- a/components/date-picker/locale/ta_IN.ts +++ b/components/date-picker/locale/ta_IN.tsx @@ -1,9 +1,10 @@ // Tamil Locale added to rc-calendar -import CalendarLocale from '../../vc-calendar/src/locale/ta_IN'; +import CalendarLocale from '../../vc-picker/locale/ta_IN'; import TimePickerLocale from '../../time-picker/locale/ta_IN'; +import type { PickerLocale } from '../generatePicker'; // Merge into a locale object -const locale = { +const locale: PickerLocale = { lang: { placeholder: 'தேதியைத் தேர்ந்தெடுக்கவும்', rangePlaceholder: ['தொடக்க தேதி', 'கடைசி தேதி'], @@ -15,6 +16,6 @@ const locale = { }; // All settings at: -// https://github.com/vueComponent/ant-design-vue/blob/master/components/date-picker/locale/example.json +// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json export default locale; diff --git a/components/date-picker/locale/th_TH.ts b/components/date-picker/locale/th_TH.ts deleted file mode 100644 index 42839fc52..000000000 --- a/components/date-picker/locale/th_TH.ts +++ /dev/null @@ -1,19 +0,0 @@ -import CalendarLocale from '../../vc-calendar/src/locale/th_TH'; -import TimePickerLocale from '../../time-picker/locale/th_TH'; - -// Merge into a locale object -const locale = { - lang: { - placeholder: 'เลือกวันที่', - rangePlaceholder: ['วันเริ่มต้น', 'วันสิ้นสุด'], - ...CalendarLocale, - }, - timePickerLocale: { - ...TimePickerLocale, - }, -}; - -// All settings at: -// https://github.com/vueComponent/ant-design-vue/blob/master/components/date-picker/locale/example.json - -export default locale; diff --git a/components/date-picker/locale/th_TH.tsx b/components/date-picker/locale/th_TH.tsx new file mode 100644 index 000000000..d54736a5d --- /dev/null +++ b/components/date-picker/locale/th_TH.tsx @@ -0,0 +1,27 @@ +import CalendarLocale from '../../vc-picker/locale/th_TH'; +import TimePickerLocale from '../../time-picker/locale/th_TH'; +import type { PickerLocale } from '../generatePicker'; + +// Merge into a locale object +const locale: PickerLocale = { + lang: { + placeholder: 'เลือกวันที่', + yearPlaceholder: 'เลือกปี', + quarterPlaceholder: 'เลือกไตรมาส', + monthPlaceholder: 'เลือกเดือน', + weekPlaceholder: 'เลือกสัปดาห์', + rangePlaceholder: ['วันเริ่มต้น', 'วันสิ้นสุด'], + rangeYearPlaceholder: ['ปีเริ่มต้น', 'ปีสิ้นสุด'], + rangeMonthPlaceholder: ['เดือนเริ่มต้น', 'เดือนสิ้นสุด'], + rangeWeekPlaceholder: ['สัปดาห์เริ่มต้น', 'สัปดาห์สิ้นสุด'], + ...CalendarLocale, + }, + timePickerLocale: { + ...TimePickerLocale, + }, +}; + +// All settings at: +// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json + +export default locale; diff --git a/components/date-picker/locale/tr_TR.ts b/components/date-picker/locale/tr_TR.ts deleted file mode 100644 index b23259b9b..000000000 --- a/components/date-picker/locale/tr_TR.ts +++ /dev/null @@ -1,19 +0,0 @@ -import CalendarLocale from '../../vc-calendar/src/locale/tr_TR'; -import TimePickerLocale from '../../time-picker/locale/tr_TR'; - -// Merge into a locale object -const locale = { - lang: { - placeholder: 'Tarih Seç', - rangePlaceholder: ['Başlangıç Tarihi', 'Bitiş Tarihi'], - ...CalendarLocale, - }, - timePickerLocale: { - ...TimePickerLocale, - }, -}; - -// All settings at: -// https://github.com/vueComponent/ant-design-vue/blob/master/components/date-picker/locale/example.json - -export default locale; diff --git a/components/date-picker/locale/tr_TR.tsx b/components/date-picker/locale/tr_TR.tsx new file mode 100644 index 000000000..7bf24acf3 --- /dev/null +++ b/components/date-picker/locale/tr_TR.tsx @@ -0,0 +1,28 @@ +import CalendarLocale from '../../vc-picker/locale/tr_TR'; +import TimePickerLocale from '../../time-picker/locale/tr_TR'; +import type { PickerLocale } from '../generatePicker'; + +// Merge into a locale object +const locale: PickerLocale = { + lang: { + placeholder: 'Tarih seç', + yearPlaceholder: 'Yıl seç', + quarterPlaceholder: 'Çeyrek seç', + monthPlaceholder: 'Ay seç', + weekPlaceholder: 'Hafta seç', + rangePlaceholder: ['Başlangıç tarihi', 'Bitiş tarihi'], + rangeYearPlaceholder: ['Başlangıç yılı', 'Bitiş yılı'], + rangeMonthPlaceholder: ['Başlangıç ayı', 'Bitiş ayı'], + rangeWeekPlaceholder: ['Başlangıç haftası', 'Bitiş haftası'], + + ...CalendarLocale, + }, + timePickerLocale: { + ...TimePickerLocale, + }, +}; + +// All settings at: +// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json + +export default locale; diff --git a/components/date-picker/locale/uk_UA.ts b/components/date-picker/locale/uk_UA.tsx similarity index 54% rename from components/date-picker/locale/uk_UA.ts rename to components/date-picker/locale/uk_UA.tsx index bfb88c064..e506266db 100644 --- a/components/date-picker/locale/uk_UA.ts +++ b/components/date-picker/locale/uk_UA.tsx @@ -1,7 +1,9 @@ -import CalendarLocale from '../../vc-calendar/src/locale/uk_UA'; +import CalendarLocale from '../../vc-picker/locale/uk_UA'; import TimePickerLocale from '../../time-picker/locale/uk_UA'; +import type { PickerLocale } from '../generatePicker'; -const locale = { +// Merge into a locale object +const locale: PickerLocale = { lang: { placeholder: 'Оберіть дату', rangePlaceholder: ['Початкова дата', 'Кінцева дата'], @@ -13,6 +15,6 @@ const locale = { }; // All settings at: -// https://github.com/vueComponent/ant-design-vue/blob/master/components/date-picker/locale/example.json +// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json export default locale; diff --git a/components/date-picker/locale/vi_VN.ts b/components/date-picker/locale/vi_VN.tsx similarity index 58% rename from components/date-picker/locale/vi_VN.ts rename to components/date-picker/locale/vi_VN.tsx index 0bf7184ea..6287cecd7 100644 --- a/components/date-picker/locale/vi_VN.ts +++ b/components/date-picker/locale/vi_VN.tsx @@ -1,8 +1,9 @@ -import CalendarLocale from '../../vc-calendar/src/locale/vi_VN'; +import CalendarLocale from '../../vc-picker/locale/vi_VN'; import TimePickerLocale from '../../time-picker/locale/vi_VN'; +import type { PickerLocale } from '../generatePicker'; // Merge into a locale object -const locale = { +const locale: PickerLocale = { lang: { placeholder: 'Chọn thời điểm', rangePlaceholder: ['Ngày bắt đầu', 'Ngày kết thúc'], @@ -14,6 +15,6 @@ const locale = { }; // All settings at: -// https://github.com/vueComponent/ant-design-vue/blob/master/components/date-picker/locale/example.json +// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json export default locale; diff --git a/components/date-picker/locale/zh_CN.ts b/components/date-picker/locale/zh_CN.ts deleted file mode 100644 index db7f5473b..000000000 --- a/components/date-picker/locale/zh_CN.ts +++ /dev/null @@ -1,21 +0,0 @@ -import CalendarLocale from '../../vc-calendar/src/locale/zh_CN'; -import TimePickerLocale from '../../time-picker/locale/zh_CN'; - -const locale = { - lang: { - placeholder: '请选择日期', - rangePlaceholder: ['开始日期', '结束日期'], - ...CalendarLocale, - }, - timePickerLocale: { - ...TimePickerLocale, - }, -}; - -// should add whitespace between char in Button -locale.lang.ok = '确 定'; - -// All settings at: -// https://github.com/vueComponent/ant-design-vue/blob/master/components/date-picker/locale/example.json - -export default locale; diff --git a/components/date-picker/locale/zh_CN.tsx b/components/date-picker/locale/zh_CN.tsx new file mode 100644 index 000000000..25a021e1f --- /dev/null +++ b/components/date-picker/locale/zh_CN.tsx @@ -0,0 +1,30 @@ +import CalendarLocale from '../../vc-picker/locale/zh_CN'; +import TimePickerLocale from '../../time-picker/locale/zh_CN'; +import type { PickerLocale } from '../generatePicker'; + +// 统一合并为完整的 Locale +const locale: PickerLocale = { + lang: { + placeholder: '请选择日期', + yearPlaceholder: '请选择年份', + quarterPlaceholder: '请选择季度', + monthPlaceholder: '请选择月份', + weekPlaceholder: '请选择周', + rangePlaceholder: ['开始日期', '结束日期'], + rangeYearPlaceholder: ['开始年份', '结束年份'], + rangeMonthPlaceholder: ['开始月份', '结束月份'], + rangeWeekPlaceholder: ['开始周', '结束周'], + ...CalendarLocale, + }, + timePickerLocale: { + ...TimePickerLocale, + }, +}; + +// should add whitespace between char in Button +locale.lang.ok = '确 定'; + +// All settings at: +// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json + +export default locale; diff --git a/components/date-picker/locale/zh_TW.ts b/components/date-picker/locale/zh_TW.ts deleted file mode 100644 index 2a9b9b8a3..000000000 --- a/components/date-picker/locale/zh_TW.ts +++ /dev/null @@ -1,20 +0,0 @@ -import CalendarLocale from '../../vc-calendar/src/locale/zh_TW'; -import TimePickerLocale from '../../time-picker/locale/zh_TW'; - -const locale = { - lang: { - placeholder: '請選擇日期', - rangePlaceholder: ['開始日期', '結束日期'], - ...CalendarLocale, - }, - timePickerLocale: { - ...TimePickerLocale, - }, -}; - -locale.lang.ok = '確 定'; - -// All settings at: -// https://github.com/vueComponent/ant-design-vue/blob/master/components/date-picker/locale/example.json - -export default locale; diff --git a/components/date-picker/locale/zh_TW.tsx b/components/date-picker/locale/zh_TW.tsx new file mode 100644 index 000000000..2a84a772c --- /dev/null +++ b/components/date-picker/locale/zh_TW.tsx @@ -0,0 +1,29 @@ +import CalendarLocale from '../../vc-picker/locale/zh_TW'; +import TimePickerLocale from '../../time-picker/locale/zh_TW'; +import type { PickerLocale } from '../generatePicker'; + +// 统一合并为完整的 Locale +const locale: PickerLocale = { + lang: { + placeholder: '請選擇日期', + yearPlaceholder: '請選擇年份', + quarterPlaceholder: '請選擇季度', + monthPlaceholder: '請選擇月份', + weekPlaceholder: '請選擇周', + rangePlaceholder: ['開始日期', '結束日期'], + rangeYearPlaceholder: ['開始年份', '結束年份'], + rangeMonthPlaceholder: ['開始月份', '結束月份'], + rangeWeekPlaceholder: ['開始周', '結束周'], + ...CalendarLocale, + }, + timePickerLocale: { + ...TimePickerLocale, + }, +}; + +locale.lang.ok = '確 定'; + +// All settings at: +// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json + +export default locale; diff --git a/components/date-picker/moment.tsx b/components/date-picker/moment.tsx new file mode 100755 index 000000000..1c902ad3c --- /dev/null +++ b/components/date-picker/moment.tsx @@ -0,0 +1,47 @@ +import type { Moment } from 'moment'; +import type { App } from 'vue'; +import momentGenerateConfig from '../vc-picker/generate/moment'; +import type { + PickerProps, + PickerDateProps, + RangePickerProps as BaseRangePickerProps, +} from './generatePicker'; +import generatePicker from './generatePicker'; +import type { ExtraDatePickerProps, ExtraRangePickerProps } from './generatePicker/props'; + +export type DatePickerProps = PickerProps & ExtraDatePickerProps; +export type MonthPickerProps = Omit, 'picker'> & + ExtraDatePickerProps; +export type WeekPickerProps = Omit, 'picker'> & + ExtraDatePickerProps; +export type RangePickerProps = BaseRangePickerProps & ExtraRangePickerProps; + +const { DatePicker, WeekPicker, MonthPicker, YearPicker, TimePicker, QuarterPicker, RangePicker } = + generatePicker(momentGenerateConfig); + +DatePicker.WeekPicker = WeekPicker; +DatePicker.MonthPicker = MonthPicker; +DatePicker.YearPicker = YearPicker; +DatePicker.RangePicker = RangePicker; +DatePicker.TimePicker = TimePicker; +DatePicker.QuarterPicker = QuarterPicker; + +/* istanbul ignore next */ +DatePicker.install = function (app: App) { + app.component(DatePicker.name, DatePicker); + app.component(RangePicker.name, RangePicker); + app.component(MonthPicker.name, MonthPicker); + app.component(WeekPicker.name, WeekPicker); + app.component(QuarterPicker.name, QuarterPicker); + return app; +}; + +export { RangePicker, WeekPicker, MonthPicker, QuarterPicker }; + +export default DatePicker as typeof DatePicker & + Plugin & { + readonly RangePicker: typeof RangePicker; + readonly MonthPicker: typeof MonthPicker; + readonly WeekPicker: typeof WeekPicker; + readonly QuarterPicker: typeof QuarterPicker; + }; diff --git a/components/date-picker/props.ts b/components/date-picker/props.ts deleted file mode 100644 index f9d0047b6..000000000 --- a/components/date-picker/props.ts +++ /dev/null @@ -1,111 +0,0 @@ -import type { PropType } from 'vue'; -import type moment from 'moment'; -import PropTypes, { withUndefined } from '../_util/vue-types'; -import { tuple } from '../_util/type'; - -export type PickerValue = moment.Moment | undefined | null | string; - -export type RangePickerValue = - | undefined[] - | null[] - | [moment.Moment | string] - | [undefined, moment.Moment | string] - | [moment.Moment | string, undefined] - | [null, moment.Moment | string] - | [moment.Moment | string, null] - | [moment.Moment, moment.Moment] - | [string, string]; - -export const PickerProps = { - name: PropTypes.string, - transitionName: PropTypes.string, - prefixCls: PropTypes.string, - inputPrefixCls: PropTypes.string, - format: PropTypes.oneOfType([PropTypes.string, PropTypes.array, PropTypes.func]), - disabled: PropTypes.looseBool, - allowClear: PropTypes.looseBool, - suffixIcon: PropTypes.any, - popupStyle: PropTypes.object, - dropdownClassName: PropTypes.string, - locale: PropTypes.any, - localeCode: PropTypes.string, - size: PropTypes.oneOf(tuple('large', 'small', 'default')), - getCalendarContainer: PropTypes.func, - open: PropTypes.looseBool, - disabledDate: PropTypes.func, - showToday: PropTypes.looseBool, - dateRender: PropTypes.any, // ({current: moment.Moment, today: moment.Moment}) => vNode, - pickerClass: PropTypes.string, - pickerInputClass: PropTypes.string, - timePicker: PropTypes.any, - autofocus: PropTypes.looseBool, - tagPrefixCls: PropTypes.string, - tabindex: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), - align: PropTypes.object.def(() => ({})), - inputReadOnly: PropTypes.looseBool, - valueFormat: PropTypes.string, - onOpenChange: PropTypes.func, - onFocus: PropTypes.func, - onBlur: PropTypes.func, - //'onUpdate:value': PropTypes.func, - onMouseenter: PropTypes.func, - onMouseleave: PropTypes.func, -}; - -export const SinglePickerProps = { - value: { type: [String, Object] as PropType }, - defaultValue: { type: [String, Object] as PropType }, - defaultPickerValue: { type: [String, Object] as PropType }, - renderExtraFooter: PropTypes.any, - placeholder: PropTypes.string, - onChange: PropTypes.func, -}; - -export const DatePickerProps = { - ...PickerProps, - ...SinglePickerProps, - showTime: withUndefined(PropTypes.oneOfType([PropTypes.object, PropTypes.looseBool])), - open: PropTypes.looseBool, - disabledTime: PropTypes.func, - mode: PropTypes.oneOf(tuple('time', 'date', 'month', 'year', 'decade')), - onOpenChange: PropTypes.func, - onPanelChange: PropTypes.func, - onOk: PropTypes.func, -}; - -export const MonthPickerProps = { - ...PickerProps, - ...SinglePickerProps, - placeholder: PropTypes.string, - monthCellContentRender: PropTypes.func, -}; -// export const RangePickerPresetRange = PropTypes.oneOfType([TimesType, PropTypes.func]) - -export const RangePickerProps = { - ...PickerProps, - tagPrefixCls: PropTypes.string, - value: { type: Array as PropType }, - defaultValue: { type: Array as PropType }, - defaultPickerValue: { type: Array as PropType }, - timePicker: PropTypes.any, - showTime: withUndefined(PropTypes.oneOfType([PropTypes.object, PropTypes.looseBool])), - ranges: PropTypes.object, - placeholder: PropTypes.arrayOf(String), - mode: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(String)]), - separator: PropTypes.any, - disabledTime: PropTypes.func, - showToday: PropTypes.looseBool, - renderExtraFooter: PropTypes.any, - onChange: PropTypes.func, - onCalendarChange: PropTypes.func, - onOk: PropTypes.func, - onPanelChange: PropTypes.func, - onMouseenter: PropTypes.func, - onMouseleave: PropTypes.func, -}; - -export const WeekPickerProps = { - ...PickerProps, - ...SinglePickerProps, - placeholder: PropTypes.string, -}; diff --git a/components/date-picker/style/Calendar.less b/components/date-picker/style/Calendar.less deleted file mode 100644 index 5dbac6f8c..000000000 --- a/components/date-picker/style/Calendar.less +++ /dev/null @@ -1,405 +0,0 @@ -.calendarLeftArrow() { - height: 100%; - - &::before, - &::after { - position: relative; - top: -1px; - display: inline-block; - width: 8px; - height: 8px; - vertical-align: middle; - border: 0 solid #aaa; - border-width: 1.5px 0 0 1.5px; - border-radius: 1px; - transform: rotate(-45deg) scale(0.8); - transition: all 0.3s; - content: ''; - } - - &:hover::before, - &:hover::after { - border-color: @text-color; - } - - &::after { - display: none; - } -} - -.calendarLeftDoubleArrow() { - .calendarLeftArrow(); - - &::after { - position: relative; - left: -3px; - display: inline-block; - } -} - -.calendarRightArrow() { - .calendarLeftArrow(); - - &::before, - &::after { - transform: rotate(135deg) scale(0.8); - } -} - -.calendarRightDoubleArrow() { - .calendarRightArrow(); - - &::before { - position: relative; - left: 3px; - } - - &::after { - display: inline-block; - } -} - -.calendarPanelHeader(@calendar-prefix-cls) { - height: 40px; - line-height: 40px; - text-align: center; - border-bottom: @border-width-base @border-style-base @border-color-split; - user-select: none; - - a:hover { - color: @link-hover-color; - } - - .@{calendar-prefix-cls}-century-select, - .@{calendar-prefix-cls}-decade-select, - .@{calendar-prefix-cls}-year-select, - .@{calendar-prefix-cls}-month-select { - display: inline-block; - padding: 0 2px; - color: @heading-color; - font-weight: 500; - line-height: 40px; - } - - .@{calendar-prefix-cls}-century-select-arrow, - .@{calendar-prefix-cls}-decade-select-arrow, - .@{calendar-prefix-cls}-year-select-arrow, - .@{calendar-prefix-cls}-month-select-arrow { - display: none; - } - - .@{calendar-prefix-cls}-prev-century-btn, - .@{calendar-prefix-cls}-next-century-btn, - .@{calendar-prefix-cls}-prev-decade-btn, - .@{calendar-prefix-cls}-next-decade-btn, - .@{calendar-prefix-cls}-prev-month-btn, - .@{calendar-prefix-cls}-next-month-btn, - .@{calendar-prefix-cls}-prev-year-btn, - .@{calendar-prefix-cls}-next-year-btn { - position: absolute; - top: 0; - display: inline-block; - padding: 0 5px; - color: @text-color-secondary; - font-size: 16px; - font-family: Arial, 'Hiragino Sans GB', 'Microsoft Yahei', 'Microsoft Sans Serif', sans-serif; - line-height: 40px; - } - - .@{calendar-prefix-cls}-prev-century-btn, - .@{calendar-prefix-cls}-prev-decade-btn, - .@{calendar-prefix-cls}-prev-year-btn { - left: 7px; - .calendarLeftDoubleArrow(); - } - - .@{calendar-prefix-cls}-next-century-btn, - .@{calendar-prefix-cls}-next-decade-btn, - .@{calendar-prefix-cls}-next-year-btn { - right: 7px; - .calendarRightDoubleArrow(); - } - - .@{calendar-prefix-cls}-prev-month-btn { - left: 29px; - .calendarLeftArrow(); - } - - .@{calendar-prefix-cls}-next-month-btn { - right: 29px; - .calendarRightArrow(); - } -} - -.calendar-selected-cell() { - .@{calendar-prefix-cls}-date { - color: @text-color-inverse; - background: @primary-color; - border: @border-width-base @border-style-base transparent; - - &:hover { - background: @primary-color; - } - } -} - -.@{calendar-prefix-cls} { - position: relative; - width: 280px; - font-size: @font-size-base; - line-height: @line-height-base; - text-align: left; - list-style: none; - background-color: @component-background; - background-clip: padding-box; - border: @border-width-base @border-style-base @border-color-inverse; - & when (@theme = dark) { - border-color: @black; - } - border-radius: @border-radius-base; - outline: none; - box-shadow: @box-shadow-base; - - &-input-wrap { - height: 34px; - padding: 6px @control-padding-horizontal - 2px; - border-bottom: @border-width-base @border-style-base @border-color-split; - } - - &-input { - width: 100%; - height: 22px; - color: @input-color; - background: @input-bg; - border: 0; - outline: 0; - cursor: auto; - .placeholder(); - } - - &-week-number { - width: 286px; - - &-cell { - text-align: center; - } - } - - &-header { - .calendarPanelHeader(@calendar-prefix-cls); - } - - &-body { - padding: 8px 12px; - } - - table { - width: 100%; - max-width: 100%; - background-color: transparent; - border-collapse: collapse; - } - - table, - th, - td { - text-align: center; - border: 0; - } - - &-calendar-table { - margin-bottom: 0; - border-spacing: 0; - } - - &-column-header { - width: 33px; - padding: 6px 0; - line-height: 18px; - text-align: center; - .@{calendar-prefix-cls}-column-header-inner { - display: block; - font-weight: normal; - } - } - - &-week-number-header { - .@{calendar-prefix-cls}-column-header-inner { - display: none; - } - } - - &-cell { - height: 30px; - padding: 3px 0; - } - - &-date { - display: block; - width: 24px; - height: 24px; - margin: 0 auto; - padding: 0; - color: @text-color; - line-height: 22px; - text-align: center; - background: transparent; - border: @border-width-base @border-style-base transparent; - border-radius: @border-radius-sm; - transition: background 0.3s ease; - - &-panel { - position: relative; - outline: none; - } - - &:hover { - background: @item-hover-bg; - cursor: pointer; - } - - &:active { - color: @text-color-inverse; - background: @primary-5; - } - } - - &-today &-date { - color: @primary-color; - font-weight: bold; - border-color: @primary-color; - } - - &-selected-day &-date { - background: @primary-2; - } - - &-last-month-cell &-date, - &-next-month-btn-day &-date { - &, - &:hover { - color: @disabled-color; - background: transparent; - border-color: transparent; - } - } - - &-disabled-cell &-date { - position: relative; - width: auto; - color: @disabled-color; - background: @disabled-bg; - border: @border-width-base @border-style-base transparent; - border-radius: 0; - cursor: not-allowed; - - &:hover { - background: @disabled-bg; - } - } - - &-disabled-cell&-selected-day &-date::before { - position: absolute; - top: -1px; - left: 5px; - width: 24px; - height: 24px; - background: rgba(0, 0, 0, 0.1); - border-radius: @border-radius-sm; - content: ''; - } - - &-disabled-cell&-today &-date { - position: relative; - padding-right: 5px; - padding-left: 5px; - &::before { - position: absolute; - top: -1px; - left: 5px; - width: 24px; - height: 24px; - border: @border-width-base @border-style-base @disabled-color; - border-radius: @border-radius-sm; - content: ' '; - } - } - - &-disabled-cell-first-of-row &-date { - border-top-left-radius: 4px; - border-bottom-left-radius: 4px; - } - - &-disabled-cell-last-of-row &-date { - border-top-right-radius: 4px; - border-bottom-right-radius: 4px; - } - - &-footer { - padding: 0 12px; - line-height: 38px; - border-top: @border-width-base @border-style-base @border-color-split; - &:empty { - border-top: 0; - } - &-btn { - display: block; - text-align: center; - } - &-extra { - text-align: left; - } - } - - .@{calendar-prefix-cls}-today-btn, - .@{calendar-prefix-cls}-clear-btn { - display: inline-block; - margin: 0 0 0 8px; - text-align: center; - &-disabled { - color: @disabled-color; - cursor: not-allowed; - } - &:only-child { - margin: 0; - } - } - - .@{calendar-prefix-cls}-clear-btn { - position: absolute; - top: 7px; - right: 5px; - display: none; - width: 20px; - height: 20px; - margin: 0; - overflow: hidden; - line-height: 20px; - text-align: center; - text-indent: -76px; - } - - .@{calendar-prefix-cls}-clear-btn::after { - display: inline-block; - width: 20px; - color: @disabled-color; - font-size: @font-size-base; - line-height: 1; - text-indent: 43px; - transition: color 0.3s ease; - } - - .@{calendar-prefix-cls}-clear-btn:hover::after { - color: @text-color-secondary; - } - - .@{calendar-prefix-cls}-ok-btn { - .btn(); - .btn-primary(); - .button-size(@btn-height-sm; @btn-padding-horizontal-sm; @font-size-base; @border-radius-base); - - line-height: @btn-height-sm - 2px; - - .button-disabled(); - } -} diff --git a/components/date-picker/style/DecadePanel.less b/components/date-picker/style/DecadePanel.less deleted file mode 100644 index b444b8597..000000000 --- a/components/date-picker/style/DecadePanel.less +++ /dev/null @@ -1,81 +0,0 @@ -.@{calendar-prefix-cls}-decade-panel { - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: @zindex-picker-panel; - display: flex; - flex-direction: column; - background: @component-background; - border-radius: @border-radius-base; - outline: none; -} - -.@{calendar-prefix-cls}-decade-panel-hidden { - display: none; -} - -.@{calendar-prefix-cls}-decade-panel-header { - .calendarPanelHeader(~'@{calendar-prefix-cls}-decade-panel'); - position: relative; -} - -.@{calendar-prefix-cls}-decade-panel-body { - flex: 1; -} - -.@{calendar-prefix-cls}-decade-panel-footer { - border-top: @border-width-base @border-style-base @border-color-split; - .@{calendar-prefix-cls}-footer-extra { - padding: 0 12px; - } -} - -.@{calendar-prefix-cls}-decade-panel-table { - width: 100%; - height: 100%; - table-layout: fixed; - border-collapse: separate; -} - -.@{calendar-prefix-cls}-decade-panel-cell { - white-space: nowrap; - text-align: center; -} - -.@{calendar-prefix-cls}-decade-panel-decade { - display: inline-block; - height: 24px; - margin: 0 auto; - padding: 0 6px; - color: @text-color; - line-height: 24px; - text-align: center; - background: transparent; - border-radius: @border-radius-sm; - transition: background 0.3s ease; - - &:hover { - background: @item-hover-bg; - cursor: pointer; - } -} - -.@{calendar-prefix-cls}-decade-panel-selected-cell .@{calendar-prefix-cls}-decade-panel-decade { - color: @text-color-inverse; - background: @primary-color; - - &:hover { - color: @text-color-inverse; - background: @primary-color; - } -} - -.@{calendar-prefix-cls}-decade-panel-last-century-cell, -.@{calendar-prefix-cls}-decade-panel-next-century-cell { - .@{calendar-prefix-cls}-decade-panel-decade { - color: @disabled-color; - user-select: none; - } -} diff --git a/components/date-picker/style/MonthPanel.less b/components/date-picker/style/MonthPanel.less deleted file mode 100644 index aa8b4ee23..000000000 --- a/components/date-picker/style/MonthPanel.less +++ /dev/null @@ -1,86 +0,0 @@ -.@{calendar-prefix-cls}-month-panel { - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: @zindex-picker-panel; - background: @component-background; - border-radius: @border-radius-base; - outline: none; - - > div { - display: flex; - flex-direction: column; - // TODO: this is a useless wrapper, and we need to remove it in rc-calendar - height: 100%; - } -} - -.@{calendar-prefix-cls}-month-panel-hidden { - display: none; -} - -.@{calendar-prefix-cls}-month-panel-header { - .calendarPanelHeader(~'@{calendar-prefix-cls}-month-panel'); - position: relative; -} - -.@{calendar-prefix-cls}-month-panel-body { - flex: 1; -} - -.@{calendar-prefix-cls}-month-panel-footer { - border-top: @border-width-base @border-style-base @border-color-split; - .@{calendar-prefix-cls}-footer-extra { - padding: 0 12px; - } -} - -.@{calendar-prefix-cls}-month-panel-table { - width: 100%; - height: 100%; - table-layout: fixed; - border-collapse: separate; -} - -.@{calendar-prefix-cls}-month-panel-selected-cell .@{calendar-prefix-cls}-month-panel-month { - color: @text-color-inverse; - background: @primary-color; - - &:hover { - color: @text-color-inverse; - background: @primary-color; - } -} - -.@{calendar-prefix-cls}-month-panel-cell { - text-align: center; - - &-disabled .@{calendar-prefix-cls}-month-panel-month { - &, - &:hover { - color: @disabled-color; - background: @disabled-bg; - cursor: not-allowed; - } - } -} - -.@{calendar-prefix-cls}-month-panel-month { - display: inline-block; - height: 24px; - margin: 0 auto; - padding: 0 8px; - color: @text-color; - line-height: 24px; - text-align: center; - background: transparent; - border-radius: @border-radius-sm; - transition: background 0.3s ease; - - &:hover { - background: @item-hover-bg; - cursor: pointer; - } -} diff --git a/components/date-picker/style/MonthPicker.less b/components/date-picker/style/MonthPicker.less deleted file mode 100644 index 27955fe37..000000000 --- a/components/date-picker/style/MonthPicker.less +++ /dev/null @@ -1,11 +0,0 @@ -.@{calendar-prefix-cls}-month { - .@{calendar-prefix-cls}-month-header-wrap { - position: relative; - height: 288px; - } - .@{calendar-prefix-cls}-month-panel, - .@{calendar-prefix-cls}-year-panel { - top: 0; - height: 100%; - } -} diff --git a/components/date-picker/style/Picker.less b/components/date-picker/style/Picker.less deleted file mode 100644 index 1d7e59373..000000000 --- a/components/date-picker/style/Picker.less +++ /dev/null @@ -1,113 +0,0 @@ -@import '../../button/style/mixin'; - -.@{calendar-prefix-cls}-picker-container { - .reset-component(); - - position: absolute; - z-index: @zindex-picker; - font-family: @font-family; - - &.slide-up-enter.slide-up-enter-active&-placement-topLeft, - &.slide-up-enter.slide-up-enter-active&-placement-topRight, - &.slide-up-appear.slide-up-appear-active&-placement-topLeft, - &.slide-up-appear.slide-up-appear-active&-placement-topRight { - animation-name: antSlideDownIn; - } - - &.slide-up-enter.slide-up-enter-active&-placement-bottomLeft, - &.slide-up-enter.slide-up-enter-active&-placement-bottomRight, - &.slide-up-appear.slide-up-appear-active&-placement-bottomLeft, - &.slide-up-appear.slide-up-appear-active&-placement-bottomRight { - animation-name: antSlideUpIn; - } - - &.slide-up-leave.slide-up-leave-active&-placement-topLeft, - &.slide-up-leave.slide-up-leave-active&-placement-topRight { - animation-name: antSlideDownOut; - } - - &.slide-up-leave.slide-up-leave-active&-placement-bottomLeft, - &.slide-up-leave.slide-up-leave-active&-placement-bottomRight { - animation-name: antSlideUpOut; - } -} - -.@{calendar-prefix-cls}-picker { - .reset-component(); - - position: relative; - display: inline-block; - outline: none; - cursor: text; - transition: opacity 0.3s; - - &-input { - outline: none; - - &.@{ant-prefix}-input { - line-height: @line-height-base; - } - } - - &-input.@{ant-prefix}-input-sm { - padding-top: 0; - padding-bottom: 0; - } - - &:hover &-input:not(.@{ant-prefix}-input-disabled) { - border-color: @input-hover-border-color; - } - - &:focus &-input:not(.@{ant-prefix}-input-disabled) { - .active(); - } - - &-clear, - &-icon { - position: absolute; - top: 50%; - right: @control-padding-horizontal; - z-index: 1; - width: 14px; - height: 14px; - margin-top: -7px; - font-size: @font-size-sm; - line-height: 14px; - transition: all 0.3s; - user-select: none; - } - - &-clear { - z-index: 2; - color: @disabled-color; - font-size: @font-size-base; - background: @component-background; - cursor: pointer; - opacity: 0; - pointer-events: none; - &:hover { - color: @text-color-secondary; - } - } - - &:hover &-clear { - opacity: 1; - pointer-events: auto; - } - - &-icon { - display: inline-block; - color: @disabled-color; - font-size: @font-size-base; - line-height: 1; - } - - .@{ant-prefix}-input-disabled + &-icon { - cursor: not-allowed; - } - - &-small &-clear, - &-small &-icon { - right: @control-padding-horizontal-sm; - } -} diff --git a/components/date-picker/style/RangePicker.less b/components/date-picker/style/RangePicker.less deleted file mode 100644 index 4e1d30d9f..000000000 --- a/components/date-picker/style/RangePicker.less +++ /dev/null @@ -1,251 +0,0 @@ -@input-box-height: 34px; - -.@{calendar-prefix-cls}-range-picker-input { - width: 44%; - height: 99%; - text-align: center; - background-color: transparent; - border: 0; - outline: 0; - .placeholder(); - - &[disabled] { - cursor: not-allowed; - } -} - -.@{calendar-prefix-cls}-range-picker-separator { - display: inline-block; - min-width: 10px; - height: 100%; - color: @text-color-secondary; - white-space: nowrap; - text-align: center; - vertical-align: top; - pointer-events: none; - .@{ant-prefix}-input-disabled & { - color: @disabled-color; - } -} - -.@{calendar-prefix-cls}-range { - width: 552px; - overflow: hidden; - - .@{calendar-prefix-cls}-date-panel { - &::after { - display: block; - clear: both; - height: 0; - visibility: hidden; - content: '.'; - } - } - &-part { - position: relative; - width: 50%; - } - - &-left { - float: left; - .@{calendar-prefix-cls} { - &-time-picker-inner { - border-right: 1px solid @border-color-split; - } - } - } - - &-right { - float: right; - .@{calendar-prefix-cls} { - &-time-picker-inner { - border-left: 1px solid @border-color-split; - } - } - } - - &-middle { - position: absolute; - left: 50%; - z-index: 1; - height: @input-box-height; - margin: 1px 0 0 0; - padding: 0 200px 0 0; - color: @text-color-secondary; - line-height: @input-box-height; - text-align: center; - transform: translateX(-50%); - pointer-events: none; - } - - &-right .@{calendar-prefix-cls}-date-input-wrap { - margin-left: -90px; - } - - &.@{calendar-prefix-cls}-time &-middle { - padding: 0 10px 0 0; - transform: translateX(-50%); - } - - .@{calendar-prefix-cls}-today - :not(.@{calendar-prefix-cls}-disabled-cell) - :not(.@{calendar-prefix-cls}-last-month-cell) - :not(.@{calendar-prefix-cls}-next-month-btn-day) { - .@{calendar-prefix-cls}-date { - color: @primary-color; - background: @primary-2; - border-color: @primary-color; - } - } - - .@{calendar-prefix-cls}-selected-start-date, - .@{calendar-prefix-cls}-selected-end-date { - .calendar-selected-cell(); - } - - &.@{calendar-prefix-cls}-time &-right .@{calendar-prefix-cls}-date-input-wrap { - margin-left: 0; - } - - .@{calendar-prefix-cls}-input-wrap { - position: relative; - height: @input-box-height; - } - - .@{calendar-prefix-cls}-input, - .@{calendar-timepicker-prefix-cls}-input { - .input(); - height: @input-height-sm; - padding-right: 0; - padding-left: 0; - line-height: @input-height-sm; - border: 0; - box-shadow: none; - - &:focus { - box-shadow: none; - } - } - - .@{calendar-timepicker-prefix-cls}-icon { - display: none; - } - - &.@{calendar-prefix-cls}-week-number { - width: 574px; - - .@{calendar-prefix-cls}-range-part { - width: 286px; - } - } - - .@{calendar-prefix-cls}-year-panel, - .@{calendar-prefix-cls}-month-panel, - .@{calendar-prefix-cls}-decade-panel { - top: @input-box-height; - } - .@{calendar-prefix-cls}-month-panel .@{calendar-prefix-cls}-year-panel { - top: 0; - } - .@{calendar-prefix-cls}-decade-panel-table, - .@{calendar-prefix-cls}-year-panel-table, - .@{calendar-prefix-cls}-month-panel-table { - height: 208px; - } - - .@{calendar-prefix-cls}-in-range-cell { - position: relative; - border-radius: 0; - > div { - position: relative; - z-index: 1; - } - &::before { - position: absolute; - top: 4px; - right: 0; - bottom: 4px; - left: 0; - display: block; - background: @item-active-bg; - border: 0; - border-radius: 0; - content: ''; - } - } - - .@{calendar-prefix-cls}-footer-extra { - float: left; - } - - // `div` for selector specificity - div&-quick-selector { - text-align: left; - - > a { - margin-right: 8px; - } - } - - .@{calendar-prefix-cls}, - .@{calendar-prefix-cls}-month-panel, - .@{calendar-prefix-cls}-year-panel, - .@{calendar-prefix-cls}-decade-panel { - &-header { - border-bottom: 0; - } - &-body { - border-top: @border-width-base @border-style-base @border-color-split; - } - } - - &.@{calendar-prefix-cls}-time { - .@{calendar-timepicker-prefix-cls} { - top: 68px; - z-index: 2; // cover .ant-calendar-range .ant-calendar-in-range-cell > div (z-index: 1) - width: 100%; - height: 207px; - &-panel { - height: 267px; - margin-top: -34px; - } - - &-inner { - height: 100%; - padding-top: 40px; - background: none; - } - - &-combobox { - display: inline-block; - height: 100%; - background-color: @component-background; - border-top: @border-width-base @border-style-base @border-color-split; - } - &-select { - height: 100%; - ul { - max-height: 100%; - } - } - } - .@{calendar-prefix-cls}-footer .@{calendar-prefix-cls}-time-picker-btn { - margin-right: 8px; - } - .@{calendar-prefix-cls}-today-btn { - height: 22px; - margin: 8px 12px; - line-height: 22px; - } - } - - &-with-ranges.@{calendar-prefix-cls}-time .@{calendar-timepicker-prefix-cls} { - height: 233px; - } -} - -.@{calendar-prefix-cls}-range.@{calendar-prefix-cls}-show-time-picker { - .@{calendar-prefix-cls}-body { - border-top-color: transparent; - } -} diff --git a/components/date-picker/style/TimePicker.less b/components/date-picker/style/TimePicker.less deleted file mode 100644 index 0c6f57e77..000000000 --- a/components/date-picker/style/TimePicker.less +++ /dev/null @@ -1,151 +0,0 @@ -.@{calendar-timepicker-prefix-cls} { - position: absolute; - top: 40px; - width: 100%; - background-color: @component-background; - - &-panel { - position: absolute; - z-index: @zindex-picker; - width: 100%; - } - - &-inner { - position: relative; - display: inline-block; - width: 100%; - overflow: hidden; - font-size: @font-size-base; - line-height: 1.5; - text-align: left; - list-style: none; - background-color: @component-background; - background-clip: padding-box; - outline: none; - } - &-combobox { - width: 100%; - } - - &-column-1, - &-column-1 &-select { - width: 100%; - } - &-column-2 &-select { - width: 50%; - } - &-column-3 &-select { - width: 33.33%; - } - &-column-4 &-select { - width: 25%; - } - - &-input-wrap { - display: none; - } - - &-select { - position: relative; // Fix chrome weird render bug - float: left; - height: 226px; - overflow: hidden; - font-size: @font-size-base; - border-right: @border-width-base @border-style-base @border-color-split; - - &:hover { - overflow-y: auto; - } - - &:first-child { - margin-left: 0; - border-left: 0; - } - - &:last-child { - border-right: 0; - } - - ul { - width: 100%; - max-height: 206px; - margin: 0; - padding: 0; - list-style: none; - } - - li { - width: 100%; - height: 24px; - margin: 0; - line-height: 24px; - text-align: center; - list-style: none; - cursor: pointer; - transition: all 0.3s; - user-select: none; - - &:last-child::after { - display: block; - height: 202px; - content: ''; - } - - &:hover { - background: @item-hover-bg; - } - - &:focus { - color: @primary-color; - font-weight: 600; - outline: none; - } - } - - li&-option-selected { - font-weight: 600; - background: @time-picker-selected-bg; - } - - li&-option-disabled { - color: @btn-disable-color; - &:hover { - background: transparent; - cursor: not-allowed; - } - } - } -} - -.@{calendar-prefix-cls}-time { - .@{calendar-prefix-cls}-day-select { - display: inline-block; - padding: 0 2px; - color: @heading-color; - font-weight: 500; - line-height: 34px; - } - - .@{calendar-prefix-cls}-footer { - position: relative; - height: auto; - - &-btn { - text-align: right; - } - - .@{calendar-prefix-cls}-today-btn { - float: left; - margin: 0; - } - - .@{calendar-prefix-cls}-time-picker-btn { - display: inline-block; - margin-right: 8px; - - &-disabled { - color: @disabled-color; - } - } - } -} diff --git a/components/date-picker/style/WeekPicker.less b/components/date-picker/style/WeekPicker.less deleted file mode 100644 index 8b592d7b0..000000000 --- a/components/date-picker/style/WeekPicker.less +++ /dev/null @@ -1,21 +0,0 @@ -.@{calendar-prefix-cls}-week-number { - &-cell { - opacity: 0.5; - } - .@{calendar-prefix-cls}-body tr { - cursor: pointer; - transition: all 0.3s; - &:hover { - background: @primary-1; - } - &.@{calendar-prefix-cls}-active-week { - font-weight: bold; - background: @primary-2; - } - .@{calendar-prefix-cls}-selected-day .@{calendar-prefix-cls}-date, - .@{calendar-prefix-cls}-selected-day:hover .@{calendar-prefix-cls}-date { - color: @text-color; - background: transparent; - } - } -} diff --git a/components/date-picker/style/YearPanel.less b/components/date-picker/style/YearPanel.less deleted file mode 100644 index b9efca73c..000000000 --- a/components/date-picker/style/YearPanel.less +++ /dev/null @@ -1,85 +0,0 @@ -.@{calendar-prefix-cls}-year-panel { - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: @zindex-picker-panel; - background: @component-background; - border-radius: @border-radius-base; - outline: none; - - > div { - display: flex; - flex-direction: column; - // TODO: this is a useless wrapper, and we need to remove it in rc-calendar - height: 100%; - } -} - -.@{calendar-prefix-cls}-year-panel-hidden { - display: none; -} - -.@{calendar-prefix-cls}-year-panel-header { - .calendarPanelHeader(~'@{calendar-prefix-cls}-year-panel'); - position: relative; -} - -.@{calendar-prefix-cls}-year-panel-body { - flex: 1; -} - -.@{calendar-prefix-cls}-year-panel-footer { - border-top: @border-width-base @border-style-base @border-color-split; - .@{calendar-prefix-cls}-footer-extra { - padding: 0 12px; - } -} - -.@{calendar-prefix-cls}-year-panel-table { - width: 100%; - height: 100%; - table-layout: fixed; - border-collapse: separate; -} - -.@{calendar-prefix-cls}-year-panel-cell { - text-align: center; -} - -.@{calendar-prefix-cls}-year-panel-year { - display: inline-block; - height: 24px; - margin: 0 auto; - padding: 0 8px; - color: @text-color; - line-height: 24px; - text-align: center; - background: transparent; - border-radius: @border-radius-sm; - transition: background 0.3s ease; - - &:hover { - background: @item-hover-bg; - cursor: pointer; - } -} - -.@{calendar-prefix-cls}-year-panel-selected-cell .@{calendar-prefix-cls}-year-panel-year { - color: @text-color-inverse; - background: @primary-color; - - &:hover { - color: @text-color-inverse; - background: @primary-color; - } -} - -.@{calendar-prefix-cls}-year-panel-last-decade-cell, -.@{calendar-prefix-cls}-year-panel-next-decade-cell { - .@{calendar-prefix-cls}-year-panel-year { - color: @disabled-color; - user-select: none; - } -} diff --git a/components/date-picker/style/index.less b/components/date-picker/style/index.less index 14eedcced..b707b9bd0 100644 --- a/components/date-picker/style/index.less +++ b/components/date-picker/style/index.less @@ -1,17 +1,357 @@ @import '../../style/themes/index'; @import '../../style/mixins/index'; @import '../../input/style/mixin'; -@import '../../button/style/mixin'; -@calendar-prefix-cls: ~'@{ant-prefix}-calendar'; -@calendar-timepicker-prefix-cls: ~'@{ant-prefix}-calendar-time-picker'; +@picker-prefix-cls: ~'@{ant-prefix}-picker'; -@import 'Picker'; -@import 'Calendar'; -@import 'RangePicker'; -@import 'TimePicker'; -@import 'MonthPanel'; -@import 'YearPanel'; -@import 'DecadePanel'; -@import 'MonthPicker'; -@import 'WeekPicker'; +.picker-padding(@input-height, @font-size, @padding-horizontal) { + // font height probably 22.0001, So use floor better + @font-height: floor(@font-size * @line-height-base) + 2; + @padding-top: max(((@input-height - @font-height) / 2), 0); + @padding-bottom: max(@input-height - @font-height - @padding-top, 0); + padding: @padding-top @padding-horizontal @padding-bottom; +} + +.@{picker-prefix-cls} { + @arrow-size: 10px; + + .reset-component(); + .picker-padding(@input-height-base, @font-size-base, @input-padding-horizontal-base); + position: relative; + display: inline-flex; + align-items: center; + background: @picker-bg; + border: @border-width-base @border-style-base @select-border-color; + border-radius: @border-radius-base; + transition: border @animation-duration-slow, box-shadow @animation-duration-slow; + + &:hover, + &-focused { + .hover(); + } + + &-focused { + .active(); + } + + &&-disabled { + background: @input-disabled-bg; + border-color: @select-border-color; + cursor: not-allowed; + } + + &&-disabled &-suffix { + color: @disabled-color; + } + + &&-borderless { + background-color: transparent !important; + border-color: transparent !important; + box-shadow: none !important; + } + + // ======================== Input ========================= + &-input { + position: relative; + display: inline-flex; + align-items: center; + width: 100%; + + > input { + .input(); + flex: auto; + + // Fix Firefox flex not correct: + // https://github.com/ant-design/ant-design/pull/20023#issuecomment-564389553 + min-width: 1px; + height: auto; + padding: 0; + background: transparent; + + border: 0; + + &:focus { + box-shadow: none; + } + + &[disabled] { + background: transparent; + } + } + + &:hover { + .@{picker-prefix-cls}-clear { + opacity: 1; + } + } + + &-placeholder { + > input { + color: @input-placeholder-color; + } + } + } + + // Size + &-large { + .picker-padding(@input-height-lg, @font-size-lg, @input-padding-horizontal-lg); + + .@{picker-prefix-cls}-input > input { + font-size: @font-size-lg; + } + } + + &-small { + .picker-padding(@input-height-sm, @font-size-base, @input-padding-horizontal-sm); + } + + &-suffix { + align-self: center; + margin-left: (@padding-xs / 2); + color: @disabled-color; + line-height: 1; + pointer-events: none; + + > * { + vertical-align: top; + } + } + + &-clear { + position: absolute; + top: 50%; + right: 0; + color: @disabled-color; + line-height: 1; + background: @component-background; + transform: translateY(-50%); + cursor: pointer; + opacity: 0; + transition: opacity @animation-duration-slow, color @animation-duration-slow; + + > * { + vertical-align: top; + } + + &:hover { + color: @text-color-secondary; + } + } + + &-separator { + position: relative; + display: inline-block; + width: 1em; + height: @font-size-lg; + color: @disabled-color; + font-size: @font-size-lg; + vertical-align: top; + cursor: default; + + .@{picker-prefix-cls}-focused & { + color: @text-color-secondary; + } + + .@{picker-prefix-cls}-range-separator & { + .@{picker-prefix-cls}-disabled & { + cursor: not-allowed; + } + } + } + + // ======================== Range ========================= + &-range { + position: relative; + display: inline-flex; + + // Clear + .@{picker-prefix-cls}-clear { + right: @input-padding-horizontal-base; + } + + &:hover { + .@{picker-prefix-cls}-clear { + opacity: 1; + } + } + + // Active bar + .@{picker-prefix-cls}-active-bar { + bottom: -@border-width-base; + height: 2px; + margin-left: @input-padding-horizontal-base; + background: @primary-color; + opacity: 0; + transition: all @animation-duration-slow ease-out; + pointer-events: none; + } + + &.@{picker-prefix-cls}-focused { + .@{picker-prefix-cls}-active-bar { + opacity: 1; + } + } + + &-separator { + align-items: center; + padding: 0 @padding-xs; + line-height: 1; + } + + &.@{picker-prefix-cls}-small { + .@{picker-prefix-cls}-clear { + right: @input-padding-horizontal-sm; + } + + .@{picker-prefix-cls}-active-bar { + margin-left: @input-padding-horizontal-sm; + } + } + } + + // ======================= Dropdown ======================= + &-dropdown { + .reset-component(); + position: absolute; + z-index: @zindex-picker; + + &-hidden { + display: none; + } + + &-placement-bottomLeft { + .@{picker-prefix-cls}-range-arrow { + top: (@arrow-size / 2) - (@arrow-size / 3); + display: block; + transform: rotate(-45deg); + } + } + + &-placement-topLeft { + .@{picker-prefix-cls}-range-arrow { + bottom: (@arrow-size / 2) - (@arrow-size / 3); + display: block; + transform: rotate(135deg); + } + } + + &.@{ant-prefix}-slide-up-enter.@{ant-prefix}-slide-up-enter-active&-placement-topLeft, + &.@{ant-prefix}-slide-up-enter.@{ant-prefix}-slide-up-enter-active&-placement-topRight, + &.@{ant-prefix}-slide-up-appear.@{ant-prefix}-slide-up-appear-active&-placement-topLeft, + &.@{ant-prefix}-slide-up-appear.@{ant-prefix}-slide-up-appear-active&-placement-topRight { + animation-name: antSlideDownIn; + } + + &.@{ant-prefix}-slide-up-enter.@{ant-prefix}-slide-up-enter-active&-placement-bottomLeft, + &.@{ant-prefix}-slide-up-enter.@{ant-prefix}-slide-up-enter-active&-placement-bottomRight, + &.@{ant-prefix}-slide-up-appear.@{ant-prefix}-slide-up-appear-active&-placement-bottomLeft, + &.@{ant-prefix}-slide-up-appear.@{ant-prefix}-slide-up-appear-active&-placement-bottomRight { + animation-name: antSlideUpIn; + } + + &.@{ant-prefix}-slide-up-leave.@{ant-prefix}-slide-up-leave-active&-placement-topLeft, + &.@{ant-prefix}-slide-up-leave.@{ant-prefix}-slide-up-leave-active&-placement-topRight { + animation-name: antSlideDownOut; + } + + &.@{ant-prefix}-slide-up-leave.@{ant-prefix}-slide-up-leave-active&-placement-bottomLeft, + &.@{ant-prefix}-slide-up-leave.@{ant-prefix}-slide-up-leave-active&-placement-bottomRight { + animation-name: antSlideUpOut; + } + } + + &-dropdown-range { + padding: (@arrow-size * 2 / 3) 0; + + &-hidden { + display: none; + } + } + + // Time picker with additional style + &-dropdown &-panel > &-time-panel { + padding-top: (@padding-xs / 2); + } + + // ======================== Ranges ======================== + &-ranges { + margin-bottom: 0; + padding: (@padding-xs / 2) @padding-sm; + overflow: hidden; + line-height: @picker-text-height - 2 * @border-width-base - (@padding-xs / 2); + text-align: left; + list-style: none; + + > li { + display: inline-block; + } + + // https://github.com/ant-design/ant-design/issues/23687 + .@{picker-prefix-cls}-preset > .@{ant-prefix}-tag-blue { + color: @primary-color; + background: @primary-1; + border-color: @primary-3; + cursor: pointer; + } + + .@{picker-prefix-cls}-ok { + float: right; + margin-left: @padding-xs; + } + } + + &-range-wrapper { + display: flex; + } + + &-range-arrow { + position: absolute; + z-index: 1; + display: none; + width: @arrow-size; + height: @arrow-size; + margin-left: @input-padding-horizontal-base * 1.5; + box-shadow: 2px -2px 6px fade(@black, 6%); + transition: left @animation-duration-slow ease-out; + + &::after { + position: absolute; + top: @border-width-base; + right: @border-width-base; + width: @arrow-size; + height: @arrow-size; + border: (@arrow-size / 2) solid @border-color-split; + border-color: @calendar-bg @calendar-bg transparent transparent; + content: ''; + } + } + + &-panel-container { + overflow: hidden; + vertical-align: top; + background: @calendar-bg; + border-radius: @border-radius-base; + box-shadow: @box-shadow-base; + transition: margin @animation-duration-slow; + + .@{picker-prefix-cls}-panels { + display: inline-flex; + flex-wrap: nowrap; + direction: ltr; + } + + .@{picker-prefix-cls}-panel { + vertical-align: top; + background: transparent; + border-width: 0 0 @border-width-base 0; + border-radius: 0; + + &-focused { + border-color: @border-color-split; + } + } + } +} + +@import './panel'; +@import './rtl'; diff --git a/components/date-picker/style/index.ts b/components/date-picker/style/index.ts deleted file mode 100644 index f27ae9b25..000000000 --- a/components/date-picker/style/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -import '../../style/index.less'; -import './index.less'; - -// style dependencies -// deps-lint-skip: input -import '../../input/style'; -import '../../time-picker/style'; -import '../../tag/style'; diff --git a/components/date-picker/style/index.tsx b/components/date-picker/style/index.tsx new file mode 100644 index 000000000..cc4424295 --- /dev/null +++ b/components/date-picker/style/index.tsx @@ -0,0 +1,5 @@ +import './index.less'; + +// style dependencies +import '../../tag/style'; +import '../../button/style'; diff --git a/components/date-picker/style/panel.less b/components/date-picker/style/panel.less new file mode 100644 index 000000000..b8bd76fc3 --- /dev/null +++ b/components/date-picker/style/panel.less @@ -0,0 +1,681 @@ +@picker-cell-inner-cls: ~'@{picker-prefix-cls}-cell-inner'; + +.@{picker-prefix-cls} { + @picker-arrow-size: 7px; + @picker-year-month-cell-width: 60px; + @picker-panel-width: @picker-panel-cell-width * 7 + @padding-sm * 2 + 4; + + &-panel { + display: inline-flex; + flex-direction: column; + text-align: center; + background: @calendar-bg; + border: @border-width-base @border-style-base @picker-border-color; + border-radius: @border-radius-base; + outline: none; + + &-focused { + border-color: @primary-color; + } + } + + // ======================================================== + // = Shared Panel = + // ======================================================== + &-decade-panel, + &-year-panel, + &-quarter-panel, + &-month-panel, + &-week-panel, + &-date-panel, + &-time-panel { + display: flex; + flex-direction: column; + width: @picker-panel-width; + } + + // ======================= Header ======================= + &-header { + display: flex; + padding: 0 @padding-xs; + color: @heading-color; + border-bottom: @border-width-base @border-style-base @picker-border-color; + + > * { + flex: none; + } + + button { + padding: 0; + color: @disabled-color; + line-height: @picker-text-height; + background: transparent; + border: 0; + cursor: pointer; + transition: color @animation-duration-slow; + } + + > button { + min-width: 1.6em; + font-size: @font-size-base; + + &:hover { + color: @text-color; + } + } + + &-view { + flex: auto; + font-weight: 500; + line-height: @picker-text-height; + + button { + color: inherit; + font-weight: inherit; + + &:not(:first-child) { + margin-left: @padding-xs; + } + + &:hover { + color: @primary-color; + } + } + } + } + + // Arrow button + &-prev-icon, + &-next-icon, + &-super-prev-icon, + &-super-next-icon { + position: relative; + display: inline-block; + width: @picker-arrow-size; + height: @picker-arrow-size; + + &::before { + position: absolute; + top: 0; + left: 0; + display: inline-block; + width: @picker-arrow-size; + height: @picker-arrow-size; + border: 0 solid currentColor; + border-width: 1.5px 0 0 1.5px; + content: ''; + } + } + + &-super-prev-icon, + &-super-next-icon { + &::after { + position: absolute; + top: ceil((@picker-arrow-size / 2)); + left: ceil((@picker-arrow-size / 2)); + display: inline-block; + width: @picker-arrow-size; + height: @picker-arrow-size; + border: 0 solid currentColor; + border-width: 1.5px 0 0 1.5px; + content: ''; + } + } + + &-prev-icon, + &-super-prev-icon { + transform: rotate(-45deg); + } + + &-next-icon, + &-super-next-icon { + transform: rotate(135deg); + } + + // ======================== Body ======================== + &-content { + width: 100%; + table-layout: fixed; + border-collapse: collapse; + + th, + td { + position: relative; + min-width: 24px; + font-weight: 400; + } + + th { + height: 30px; + color: @text-color; + line-height: 30px; + } + } + + .picker-cell-inner(@cellClassName) { + &::before { + position: absolute; + top: 50%; + right: 0; + left: 0; + z-index: 1; + height: @picker-panel-cell-height; + transform: translateY(-50%); + content: ''; + } + + // >>> Default + .@{cellClassName} { + position: relative; + z-index: 2; + display: inline-block; + min-width: @picker-panel-cell-height; + height: @picker-panel-cell-height; + line-height: @picker-panel-cell-height; + border-radius: @border-radius-base; + transition: background @animation-duration-slow, border @animation-duration-slow; + } + + // >>> Hover + &:hover:not(&-in-view), + &:hover:not(&-selected):not(&-range-start):not(&-range-end):not(&-range-hover-start):not(&-range-hover-end) { + .@{cellClassName} { + background: @picker-basic-cell-hover-color; + } + } + + // >>> Today + &-in-view&-today .@{cellClassName} { + &::before { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1; + border: @border-width-base @border-style-base @primary-color; + border-radius: @border-radius-base; + content: ''; + } + } + + // >>> In Range + &-in-view&-in-range { + position: relative; + + &::before { + background: @picker-basic-cell-active-with-range-color; + } + } + + // >>> Selected + &-in-view&-selected .@{cellClassName}, + &-in-view&-range-start .@{cellClassName}, + &-in-view&-range-end .@{cellClassName} { + color: @text-color-inverse; + background: @primary-color; + } + + &-in-view&-range-start:not(&-range-start-single), + &-in-view&-range-end:not(&-range-end-single) { + &::before { + background: @picker-basic-cell-active-with-range-color; + } + } + + &-in-view&-range-start::before { + left: 50%; + } + + &-in-view&-range-end::before { + right: 50%; + } + + // >>> Range Hover + &-in-view&-range-hover-start:not(&-in-range):not(&-range-start):not(&-range-end), + &-in-view&-range-hover-end:not(&-in-range):not(&-range-start):not(&-range-end), + &-in-view&-range-hover-start&-range-start-single, + &-in-view&-range-hover-start&-range-start&-range-end&-range-end-near-hover, + &-in-view&-range-hover-end&-range-start&-range-end&-range-start-near-hover, + &-in-view&-range-hover-end&-range-end-single, + &-in-view&-range-hover:not(&-in-range) { + &::after { + position: absolute; + top: 50%; + z-index: 0; + height: 24px; + border-top: @border-width-base dashed @picker-date-hover-range-border-color; + border-bottom: @border-width-base dashed @picker-date-hover-range-border-color; + transform: translateY(-50%); + content: ''; + } + } + + // Add space for stash + &-range-hover-start::after, + &-range-hover-end::after, + &-range-hover::after { + right: 0; + left: 2px; + } + + // Hover with in range + &-in-view&-in-range&-range-hover::before, + &-in-view&-range-start&-range-hover::before, + &-in-view&-range-end&-range-hover::before, + &-in-view&-range-start:not(&-range-start-single)&-range-hover-start::before, + &-in-view&-range-end:not(&-range-end-single)&-range-hover-end::before, + .@{picker-prefix-cls}-panel + > :not(.@{picker-prefix-cls}-date-panel) + &-in-view&-in-range&-range-hover-start::before, + .@{picker-prefix-cls}-panel + > :not(.@{picker-prefix-cls}-date-panel) + &-in-view&-in-range&-range-hover-end::before { + background: @picker-date-hover-range-color; + } + + // range start border-radius + &-in-view&-range-start:not(&-range-start-single):not(&-range-end) .@{cellClassName} { + border-radius: @border-radius-base 0 0 @border-radius-base; + } + // range end border-radius + &-in-view&-range-end:not(&-range-end-single):not(&-range-start) .@{cellClassName} { + border-radius: 0 @border-radius-base @border-radius-base 0; + } + + // DatePanel only + .@{picker-prefix-cls}-date-panel &-in-view&-in-range&-range-hover-start .@{cellClassName}, + .@{picker-prefix-cls}-date-panel &-in-view&-in-range&-range-hover-end .@{cellClassName} { + &::after { + position: absolute; + top: 0; + bottom: 0; + z-index: -1; + background: @picker-date-hover-range-color; + content: ''; + } + } + .@{picker-prefix-cls}-date-panel + &-in-view&-in-range&-range-hover-start + .@{cellClassName}::after { + right: -5px - @border-width-base; + left: 0; + } + .@{picker-prefix-cls}-date-panel &-in-view&-in-range&-range-hover-end .@{cellClassName}::after { + right: 0; + left: -5px - @border-width-base; + } + + // Hover with range start & end + &-range-hover&-range-start::after { + right: 50%; + } + &-range-hover&-range-end::after { + left: 50%; + } + + // Edge start + tr > &-in-view&-range-hover:first-child::after, + tr > &-in-view&-range-hover-end:first-child::after, + &-in-view&-start&-range-hover-edge-start&-range-hover-edge-start-near-range::after, + &-in-view&-range-hover-edge-start:not(&-range-hover-edge-start-near-range)::after, + &-in-view&-range-hover-start::after { + left: 6px; + border-left: @border-width-base dashed @picker-date-hover-range-border-color; + border-top-left-radius: @border-radius-base; + border-bottom-left-radius: @border-radius-base; + } + + // Edge end + tr > &-in-view&-range-hover:last-child::after, + tr > &-in-view&-range-hover-start:last-child::after, + &-in-view&-end&-range-hover-edge-end&-range-hover-edge-end-near-range::after, + &-in-view&-range-hover-edge-end:not(&-range-hover-edge-end-near-range)::after, + &-in-view&-range-hover-end::after { + right: 6px; + border-right: @border-width-base dashed @picker-date-hover-range-border-color; + border-top-right-radius: @border-radius-base; + border-bottom-right-radius: @border-radius-base; + } + + // >>> Disabled + &-disabled { + pointer-events: none; + + .@{cellClassName} { + color: @disabled-color; + background: transparent; + } + + &::before { + background: @picker-basic-cell-disabled-bg; + } + } + &-disabled&-today .@{cellClassName}::before { + border-color: @disabled-color; + } + } + + &-cell { + padding: 3px 0; + color: @disabled-color; + cursor: pointer; + + // In view + &-in-view { + color: @text-color; + } + + // Disabled + &-disabled { + cursor: not-allowed; + } + + .picker-cell-inner(~'@{picker-cell-inner-cls}'); + } + + &-decade-panel, + &-year-panel, + &-quarter-panel, + &-month-panel { + .@{picker-prefix-cls}-content { + height: @picker-panel-without-time-cell-height * 4; + } + + .@{picker-cell-inner-cls} { + padding: 0 @padding-xs; + } + + .@{picker-prefix-cls}-cell { + &-disabled .@{picker-cell-inner-cls} { + background: @picker-basic-cell-disabled-bg; + } + } + } + + &-quarter-panel { + .@{picker-prefix-cls}-content { + height: 56px; + } + } + + // ======================== Footer ======================== + &-footer { + width: min-content; + min-width: 100%; + line-height: @picker-text-height - 2 * @border-width-base; + text-align: center; + border-bottom: @border-width-base @border-style-base transparent; + + .@{picker-prefix-cls}-panel & { + border-top: @border-width-base @border-style-base @picker-border-color; + } + + &-extra { + padding: 0 @padding-sm; + line-height: @picker-text-height - 2 * @border-width-base; + text-align: left; + + &:not(:last-child) { + border-bottom: @border-width-base @border-style-base @picker-border-color; + } + } + } + + &-now { + text-align: left; + } + + &-today-btn { + color: @link-color; + + &:hover { + color: @link-hover-color; + } + + &:active { + color: @link-active-color; + } + + &&-disabled { + color: @disabled-color; + cursor: not-allowed; + } + } + + // ======================================================== + // = Special = + // ======================================================== + + // ===================== Decade Panel ===================== + &-decade-panel { + .@{picker-cell-inner-cls} { + padding: 0 (@padding-xs / 2); + } + + .@{picker-prefix-cls}-cell::before { + display: none; + } + } + + // ============= Year & Quarter & Month Panel ============= + &-year-panel, + &-quarter-panel, + &-month-panel { + @hover-cell-fixed-distance: ( + (((@picker-panel-width - @padding-xs * 2) / 3) - @picker-year-month-cell-width) / 2 + ); + + .@{picker-prefix-cls}-body { + padding: 0 @padding-xs; + } + + .@{picker-cell-inner-cls} { + width: @picker-year-month-cell-width; + } + + .@{picker-prefix-cls}-cell-range-hover-start::after { + left: @hover-cell-fixed-distance; + border-left: @border-width-base dashed @picker-date-hover-range-border-color; + border-radius: @border-radius-base 0 0 @border-radius-base; + + .@{picker-prefix-cls}-panel-rtl & { + right: @hover-cell-fixed-distance; + border-right: @border-width-base dashed @picker-date-hover-range-border-color; + border-radius: 0 @border-radius-base @border-radius-base 0; + } + } + .@{picker-prefix-cls}-cell-range-hover-end::after { + right: @hover-cell-fixed-distance; + border-right: @border-width-base dashed @picker-date-hover-range-border-color; + border-radius: 0 @border-radius-base @border-radius-base 0; + + .@{picker-prefix-cls}-panel-rtl & { + left: @hover-cell-fixed-distance; + border-left: @border-width-base dashed @picker-date-hover-range-border-color; + border-radius: @border-radius-base 0 0 @border-radius-base; + } + } + } + + // ====================== Week Panel ====================== + &-week-panel { + .@{picker-prefix-cls}-body { + padding: @padding-xs @padding-sm; + } + + // Clear cell style + .@{picker-prefix-cls}-cell { + &:hover .@{picker-cell-inner-cls}, + &-selected .@{picker-cell-inner-cls}, + .@{picker-cell-inner-cls} { + background: transparent !important; + } + } + + &-row { + td { + transition: background @animation-duration-slow; + } + + &:hover td { + background: @picker-basic-cell-hover-color; + } + + &-selected td, + &-selected:hover td { + background: @primary-color; + + &.@{picker-prefix-cls}-cell-week { + color: fade(@text-color-inverse, 50%); + } + + &.@{picker-prefix-cls}-cell-today .@{picker-cell-inner-cls}::before { + border-color: @text-color-inverse; + } + + .@{picker-cell-inner-cls} { + color: @text-color-inverse; + } + } + } + } + + // ====================== Date Panel ====================== + &-date-panel { + .@{picker-prefix-cls}-body { + padding: @padding-xs @padding-sm; + } + + .@{picker-prefix-cls}-content { + width: @picker-panel-cell-width * 7; + + th { + width: @picker-panel-cell-width; + } + } + } + + // ==================== Datetime Panel ==================== + &-datetime-panel { + display: flex; + + .@{picker-prefix-cls}-time-panel { + border-left: @border-width-base @border-style-base @picker-border-color; + } + + .@{picker-prefix-cls}-date-panel, + .@{picker-prefix-cls}-time-panel { + transition: opacity @animation-duration-slow; + } + + // Keyboard + &-active { + .@{picker-prefix-cls}-date-panel, + .@{picker-prefix-cls}-time-panel { + opacity: 0.3; + + &-active { + opacity: 1; + } + } + } + } + + // ====================== Time Panel ====================== + &-time-panel { + width: auto; + min-width: auto; + + .@{picker-prefix-cls}-content { + display: flex; + flex: auto; + height: @picker-time-panel-column-height; + } + + &-column { + flex: 1 0 auto; + width: @picker-time-panel-column-width; + margin: 0; + padding: 0; + overflow-y: hidden; + text-align: left; + list-style: none; + transition: background @animation-duration-slow; + + &::after { + display: block; + height: @picker-time-panel-column-height - @picker-time-panel-cell-height; + content: ''; + .@{picker-prefix-cls}-datetime-panel & { + height: @picker-time-panel-column-height - @picker-time-panel-cell-height + 2 * + @border-width-base; + } + } + + &:not(:first-child) { + border-left: @border-width-base @border-style-base @picker-border-color; + } + + &-active { + background: fade(@calendar-item-active-bg, 20%); + } + + &:hover { + overflow-y: auto; + } + + > li { + margin: 0; + padding: 0; + + &.@{picker-prefix-cls}-time-panel-cell { + .@{picker-prefix-cls}-time-panel-cell-inner { + display: block; + width: 100%; + height: @picker-time-panel-cell-height; + margin: 0; + padding: 0 0 0 ((@picker-time-panel-column-width - 28px) / 2); + color: @text-color; + line-height: @picker-time-panel-cell-height; + border-radius: 0; + cursor: pointer; + transition: background @animation-duration-slow; + + &:hover { + background: @item-hover-bg; + } + } + + &-selected { + .@{picker-prefix-cls}-time-panel-cell-inner { + background: @calendar-item-active-bg; + } + } + + &-disabled { + .@{picker-prefix-cls}-time-panel-cell-inner { + color: @disabled-color; + background: transparent; + cursor: not-allowed; + } + } + } + } + } + } +} + +// Fix IE11 render bug by css hacks +// https://github.com/ant-design/ant-design/issues/21559 +// https://codepen.io/afc163-1472555193/pen/mdJRaNj?editors=0110 +/* stylelint-disable-next-line */ +_:-ms-fullscreen, +:root { + .@{picker-prefix-cls}-range-wrapper { + .@{picker-prefix-cls}-month-panel .@{picker-prefix-cls}-cell, + .@{picker-prefix-cls}-year-panel .@{picker-prefix-cls}-cell { + padding: 21px 0; + } + } +} diff --git a/components/date-picker/style/rtl.less b/components/date-picker/style/rtl.less new file mode 100644 index 000000000..8112c71d5 --- /dev/null +++ b/components/date-picker/style/rtl.less @@ -0,0 +1,252 @@ +.@{picker-prefix-cls} { + &-rtl { + direction: rtl; + } + + &-suffix { + .@{picker-prefix-cls}-rtl & { + margin-right: (@padding-xs / 2); + margin-left: 0; + } + } + + &-clear { + .@{picker-prefix-cls}-rtl & { + right: auto; + left: 0; + } + } + + &-separator { + .@{picker-prefix-cls}-rtl & { + transform: rotate(180deg); + } + } + + &-header { + &-view { + button { + &:not(:first-child) { + .@{picker-prefix-cls}-panel-rtl & { + margin-right: @padding-xs; + margin-left: 0; + } + } + } + } + } + + // ======================== Range ========================= + &-range { + // Clear + .@{picker-prefix-cls}-clear { + .@{picker-prefix-cls}-rtl& { + right: auto; + left: @input-padding-horizontal-base; + } + } + + // Active bar + .@{picker-prefix-cls}-active-bar { + .@{picker-prefix-cls}-rtl& { + margin-right: @input-padding-horizontal-base; + margin-left: 0; + } + } + + &.@{picker-prefix-cls}-small { + .@{picker-prefix-cls}-active-bar { + .@{picker-prefix-cls}-rtl& { + margin-right: @input-padding-horizontal-sm; + } + } + } + } + + // ======================== Ranges ======================== + &-ranges { + .@{picker-prefix-cls}-dropdown-rtl & { + text-align: right; + } + + .@{picker-prefix-cls}-ok { + .@{picker-prefix-cls}-dropdown-rtl & { + float: left; + margin-right: @padding-xs; + margin-left: 0; + } + } + } + + // ======================== Panel ======================== + &-panel { + &-rtl { + direction: rtl; + } + } + + &-prev-icon, + &-super-prev-icon { + .@{picker-prefix-cls}-panel-rtl & { + transform: rotate(135deg); + } + } + + &-next-icon, + &-super-next-icon { + .@{picker-prefix-cls}-panel-rtl & { + transform: rotate(-45deg); + } + } + + &-cell { + .picker-cell-inner(~'@{picker-cell-inner-cls}'); + } + + // ======================== Body ========================== + .picker-cell-inner(@cellClassName) { + .@{cellClassName} { + position: relative; + z-index: 2; + display: inline-block; + min-width: @picker-panel-cell-height; + height: @picker-panel-cell-height; + line-height: @picker-panel-cell-height; + border-radius: @border-radius-base; + transition: background @animation-duration-slow, border @animation-duration-slow; + } + + &-in-view&-range-start::before { + .@{picker-prefix-cls}-panel-rtl & { + right: 50%; + left: 0; + } + } + + &-in-view&-range-end::before { + .@{picker-prefix-cls}-panel-rtl & { + right: 0; + left: 50%; + } + } + + &-in-view&-range-start&-range-end::before { + .@{picker-prefix-cls}-panel-rtl & { + right: 50%; + left: 50%; + } + } + + .@{picker-prefix-cls}-date-panel + &-in-view&-in-range&-range-hover-start + .@{cellClassName}::after { + .@{picker-prefix-cls}-panel-rtl & { + right: 0; + left: -5px - @border-width-base; + } + } + + .@{picker-prefix-cls}-date-panel &-in-view&-in-range&-range-hover-end .@{cellClassName}::after { + .@{picker-prefix-cls}-panel-rtl & { + right: -5px - @border-width-base; + left: 0; + } + } + + // Hover with range start & end + &-range-hover&-range-start::after { + .@{picker-prefix-cls}-panel-rtl & { + right: 0; + left: 50%; + } + } + + &-range-hover&-range-end::after { + .@{picker-prefix-cls}-panel-rtl & { + right: 50%; + left: 0; + } + } + + // range start border-radius + &-in-view&-range-start:not(&-range-start-single):not(&-range-end) .@{cellClassName} { + .@{picker-prefix-cls}-panel-rtl & { + border-radius: 0 @border-radius-base @border-radius-base 0; + } + } + + // range end border-radius + &-in-view&-range-end:not(&-range-end-single):not(&-range-start) .@{cellClassName} { + .@{picker-prefix-cls}-panel-rtl & { + border-radius: @border-radius-base 0 0 @border-radius-base; + } + } + + // Edge start + tr > &-in-view&-range-hover:not(&-selected):first-child::after, + &-in-view&-start&-range-hover-edge-start&-range-hover-edge-start-near-range::after, + &-in-view&-range-hover-edge-start:not(&-range-hover-edge-start-near-range)::after, + &-in-view&-range-hover-start::after { + .@{picker-prefix-cls}-panel-rtl & { + right: 6px; + left: 0; + border-right: @border-width-base dashed @picker-date-hover-range-border-color; + border-left: none; + border-top-left-radius: 0; + border-top-right-radius: @border-radius-base; + border-bottom-right-radius: @border-radius-base; + border-bottom-left-radius: 0; + } + } + + // Edge end + tr > &-in-view&-range-hover:not(&-selected):last-child::after, + &-in-view&-end&-range-hover-edge-end&-range-hover-edge-end-near-range::after, + &-in-view&-range-hover-edge-end:not(&-range-hover-edge-end-near-range)::after, + &-in-view&-range-hover-end::after { + .@{picker-prefix-cls}-panel-rtl & { + right: 0; + left: 6px; + border-right: none; + border-left: @border-width-base dashed @picker-date-hover-range-border-color; + border-top-left-radius: @border-radius-base; + border-top-right-radius: 0; + border-bottom-right-radius: 0; + border-bottom-left-radius: @border-radius-base; + } + } + + tr > &-in-view&-range-hover-start:last-child::after, + tr > &-in-view&-range-hover-end:first-child::after, + &-in-view&-start&-range-hover-edge-start:not(&-range-hover)::after, + &-in-view&-start&-range-hover-end&-range-hover-edge-start:not(&-range-hover)::after, + &-in-view&-end&-range-hover-start&-range-hover-edge-end:not(&-range-hover)::after, + tr > &-in-view&-start&-range-hover&-range-hover-edge-start:last-child::after, + tr > &-in-view&-end&-range-hover&-range-hover-edge-end:first-child::after { + .@{picker-prefix-cls}-panel-rtl & { + right: 6px; + left: 6px; + border-right: @border-width-base dashed @picker-date-hover-range-border-color; + border-left: @border-width-base dashed @picker-date-hover-range-border-color; + border-radius: @border-radius-base; + } + } + } + + // ======================== Footer ======================== + &-footer { + &-extra { + .@{picker-prefix-cls}-dropdown-rtl & { + direction: rtl; + text-align: right; + } + } + } + + // ====================== Time Panel ====================== + &-time-panel { + .@{picker-prefix-cls}-panel-rtl & { + direction: ltr; + } + } +} diff --git a/components/date-picker/util.ts b/components/date-picker/util.ts new file mode 100644 index 000000000..fbd314ed9 --- /dev/null +++ b/components/date-picker/util.ts @@ -0,0 +1,53 @@ +import type { PickerMode } from '../vc-picker/interface'; +import type { PickerLocale } from './generatePicker'; + +export function getPlaceholder( + picker: PickerMode | undefined, + locale: PickerLocale, + customizePlaceholder?: string, +): string { + if (customizePlaceholder !== undefined) { + return customizePlaceholder; + } + + if (picker === 'year' && locale.lang.yearPlaceholder) { + return locale.lang.yearPlaceholder; + } + if (picker === 'quarter' && locale.lang.quarterPlaceholder) { + return locale.lang.quarterPlaceholder; + } + if (picker === 'month' && locale.lang.monthPlaceholder) { + return locale.lang.monthPlaceholder; + } + if (picker === 'week' && locale.lang.weekPlaceholder) { + return locale.lang.weekPlaceholder; + } + if (picker === 'time' && locale.timePickerLocale.placeholder) { + return locale!.timePickerLocale.placeholder; + } + return locale.lang.placeholder; +} + +export function getRangePlaceholder( + picker: PickerMode | undefined, + locale: PickerLocale, + customizePlaceholder?: [string, string], +) { + if (customizePlaceholder !== undefined) { + return customizePlaceholder; + } + + if (picker === 'year' && locale.lang.yearPlaceholder) { + return locale.lang.rangeYearPlaceholder; + } + if (picker === 'month' && locale.lang.monthPlaceholder) { + return locale.lang.rangeMonthPlaceholder; + } + if (picker === 'week' && locale.lang.weekPlaceholder) { + return locale.lang.rangeWeekPlaceholder; + } + if (picker === 'time' && locale.timePickerLocale.placeholder) { + return locale!.timePickerLocale.rangePlaceholder; + } + return locale.lang.rangePlaceholder; +} diff --git a/components/date-picker/utils.ts b/components/date-picker/utils.ts deleted file mode 100644 index 790b37534..000000000 --- a/components/date-picker/utils.ts +++ /dev/null @@ -1,16 +0,0 @@ -import type moment from 'moment'; - -type Value = moment.Moment | undefined | null; -type Format = string | string[] | undefined | ((val?: Value) => string | string[] | undefined); -export function formatDate(value: Value, format: Format) { - if (!value) { - return ''; - } - if (Array.isArray(format)) { - format = format[0]; - } - if (typeof format === 'function') { - return format(value); - } - return value.format(format); -} diff --git a/components/date-picker/wrapPicker.tsx b/components/date-picker/wrapPicker.tsx deleted file mode 100644 index a09ec82a4..000000000 --- a/components/date-picker/wrapPicker.tsx +++ /dev/null @@ -1,255 +0,0 @@ -import type { DefineComponent } from 'vue'; -import { provide, inject, defineComponent, nextTick } from 'vue'; -import TimePickerPanel from '../vc-time-picker/Panel'; -import classNames from '../_util/classNames'; -import LocaleReceiver from '../locale-provider/LocaleReceiver'; -import { generateShowHourMinuteSecond } from '../time-picker'; -import enUS from './locale/en_US'; -import PropTypes from '../_util/vue-types'; -import { getOptionProps } from '../_util/props-util'; -import { defaultConfigProvider } from '../config-provider'; -import { checkValidate, stringToMoment, momentToString } from '../_util/moment-util'; - -type PickerType = 'date' | 'week' | 'month'; - -interface PickerMap { - [name: string]: string; -} -const DEFAULT_FORMAT: PickerMap = { - date: 'YYYY-MM-DD', - dateTime: 'YYYY-MM-DD HH:mm:ss', - week: 'gggg-wo', - month: 'YYYY-MM', -}; - -const LOCALE_FORMAT_MAPPING: PickerMap = { - date: 'dateFormat', - dateTime: 'dateTimeFormat', - week: 'weekFormat', - month: 'monthFormat', -}; - -function getColumns({ showHour, showMinute, showSecond, use12Hours }: any) { - let column = 0; - if (showHour) { - column += 1; - } - if (showMinute) { - column += 1; - } - if (showSecond) { - column += 1; - } - if (use12Hours) { - column += 1; - } - return column; -} - -export default function wrapPicker

( - Picker: DefineComponent

, - props: any, - pickerType: PickerType, -) { - return defineComponent({ - name: Picker.name, - inheritAttrs: false, - props: { - ...props, - transitionName: PropTypes.string.def('slide-up'), - popupStyle: PropTypes.style, - locale: PropTypes.any.def({}), - }, - emits: [ - 'update:value', - 'openChange', - 'focus', - 'blur', - 'mouseenter', - 'mouseleave', - 'change', - 'ok', - 'calendarChange', - ], - setup() { - return { - configProvider: inject('configProvider', defaultConfigProvider), - picker: undefined, - popupRef: undefined, - }; - }, - watch: { - value(val) { - checkValidate('DatePicker', val, 'value', this.valueFormat); - }, - }, - created() { - provide('savePopupRef', this.savePopupRef); - }, - mounted() { - const { autofocus, disabled, value, defaultValue, valueFormat } = this.$props; - checkValidate('DatePicker', defaultValue, 'defaultValue', valueFormat); - checkValidate('DatePicker', value, 'value', valueFormat); - if (autofocus && !disabled) { - nextTick(() => { - this.focus(); - }); - } - }, - methods: { - savePicker(node: any) { - this.picker = node; - }, - getDefaultLocale() { - const result = { - ...enUS, - ...this.locale, - }; - result.lang = { - ...result.lang, - ...(this.locale || {}).lang, - }; - return result; - }, - - savePopupRef(ref: any) { - this.popupRef = ref; - }, - handleOpenChange(open: boolean) { - this.$emit('openChange', open); - }, - - handleFocus(e: FocusEvent) { - this.$emit('focus', e); - }, - - handleBlur(e: FocusEvent) { - this.$emit('blur', e); - }, - - handleMouseEnter(e: MouseEvent) { - this.$emit('mouseenter', e); - }, - - handleMouseLeave(e: MouseEvent) { - this.$emit('mouseleave', e); - }, - handleChange(date: any, dateString: string) { - const value = this.valueFormat ? momentToString(date, this.valueFormat) : date; - this.$emit('update:value', value); - this.$emit('change', value, dateString); - }, - handleOk(val: any) { - this.$emit('ok', this.valueFormat ? momentToString(val, this.valueFormat) : val); - }, - handleCalendarChange(date: any, dateString: string) { - this.$emit( - 'calendarChange', - this.valueFormat ? momentToString(date, this.valueFormat) : date, - dateString, - ); - }, - focus() { - this.picker.focus(); - }, - - blur() { - this.picker.blur(); - }, - - transformValue(props) { - if ('value' in props) { - props.value = stringToMoment(props.value, this.valueFormat); - } - if ('defaultValue' in props) { - props.defaultValue = stringToMoment(props.defaultValue, this.valueFormat); - } - if ('defaultPickerValue' in props) { - props.defaultPickerValue = stringToMoment(props.defaultPickerValue, this.valueFormat); - } - }, - - renderPicker(locale: any, localeCode: string) { - const props: any = { ...getOptionProps(this), ...this.$attrs }; - this.transformValue(props); - const { - prefixCls: customizePrefixCls, - inputPrefixCls: customizeInputPrefixCls, - getCalendarContainer, - size, - showTime, - disabled, - format, - } = props; - const mergedPickerType = showTime ? `${pickerType}Time` : pickerType; - const mergedFormat = - format || - locale[LOCALE_FORMAT_MAPPING[mergedPickerType]] || - DEFAULT_FORMAT[mergedPickerType]; - - const { getPrefixCls, getPopupContainer: getContextPopupContainer } = this.configProvider; - const getPopupContainer = getCalendarContainer || getContextPopupContainer; - const prefixCls = getPrefixCls('calendar', customizePrefixCls); - const inputPrefixCls = getPrefixCls('input', customizeInputPrefixCls); - - const pickerClass = classNames(`${prefixCls}-picker`, { - [`${prefixCls}-picker-${size}`]: !!size, - }); - const pickerInputClass = classNames(`${prefixCls}-picker-input`, inputPrefixCls, { - [`${inputPrefixCls}-lg`]: size === 'large', - [`${inputPrefixCls}-sm`]: size === 'small', - [`${inputPrefixCls}-disabled`]: disabled, - }); - - const timeFormat = (showTime && showTime.format) || 'HH:mm:ss'; - const vcTimePickerProps = { - ...generateShowHourMinuteSecond(timeFormat), - format: timeFormat, - use12Hours: showTime && showTime.use12Hours, - }; - const columns = getColumns(vcTimePickerProps); - const timePickerCls = `${prefixCls}-time-picker-column-${columns}`; - const timePickerPanelProps = { - ...vcTimePickerProps, - ...showTime, - prefixCls: `${prefixCls}-time-picker`, - placeholder: locale.timePickerLocale.placeholder, - transitionName: 'slide-up', - class: timePickerCls, - onEsc: () => {}, - }; - const timePicker = showTime ? : null; - const pickerProps = { - ...props, - getCalendarContainer: getPopupContainer, - format: mergedFormat, - pickerClass, - pickerInputClass, - locale, - localeCode, - timePicker, - onOpenChange: this.handleOpenChange, - onFocus: this.handleFocus, - onBlur: this.handleBlur, - onMouseenter: this.handleMouseEnter, - onMouseleave: this.handleMouseLeave, - onChange: this.handleChange, - onOk: this.handleOk, - onCalendarChange: this.handleCalendarChange, - ref: this.savePicker, - }; - return ; - }, - }, - - render() { - return ( - - ); - }, - }); -} diff --git a/components/descriptions/Row.tsx b/components/descriptions/Row.tsx index 556d1d19d..0f0e7055c 100644 --- a/components/descriptions/Row.tsx +++ b/components/descriptions/Row.tsx @@ -50,7 +50,7 @@ const Row: FunctionalComponent = props => { if (typeof component === 'string') { return ( = props => { return [ = props => { label={label} />, { callback && callback(); diff --git a/components/input/TextArea.tsx b/components/input/TextArea.tsx index 1fb195432..f654bc56d 100644 --- a/components/input/TextArea.tsx +++ b/components/input/TextArea.tsx @@ -55,7 +55,7 @@ export default defineComponent({ if (!hasProp(this, 'value')) { this.stateValue = value; } else { - this.$forceUpdate(); + (this as any).$forceUpdate(); } nextTick(() => { callback && callback(); diff --git a/components/locale-provider/LocaleReceiver.tsx b/components/locale-provider/LocaleReceiver.tsx index 9b1fa6e1d..5918e96ed 100644 --- a/components/locale-provider/LocaleReceiver.tsx +++ b/components/locale-provider/LocaleReceiver.tsx @@ -1,4 +1,5 @@ import type { VNodeTypes, PropType, ComputedRef } from 'vue'; +import { unref } from 'vue'; import { inject, defineComponent, computed } from 'vue'; import PropTypes from '../_util/vue-types'; import defaultLocaleData from './default'; @@ -66,13 +67,13 @@ type LocaleComponent = keyof Locale; export function useLocaleReceiver( componentName: T, - defaultLocale?: Locale[T] | Function, + defaultLocale?: Locale[T] | Function | ComputedRef, ): [ComputedRef] { const localeData = inject('localeData', {} as LocaleReceiverContext); - const componentLocale = computed(() => { + const componentLocale = computed(() => { const { antLocale } = localeData; const locale = - defaultLocale || (defaultLocaleData as LocaleInterface)[componentName || 'global']; + unref(defaultLocale) || (defaultLocaleData as LocaleInterface)[componentName || 'global']; const localeFromContext = componentName && antLocale ? antLocale[componentName] : {}; return { diff --git a/components/locale-provider/index.tsx b/components/locale-provider/index.tsx index 86b046d9c..8d1573a48 100644 --- a/components/locale-provider/index.tsx +++ b/components/locale-provider/index.tsx @@ -1,26 +1,24 @@ import type { App, VNode, PropType } from 'vue'; import { provide, defineComponent, reactive, watch, onUnmounted } from 'vue'; import PropTypes from '../_util/vue-types'; -import moment from 'moment'; -import interopDefault from '../_util/interopDefault'; import type { ModalLocale } from '../modal/locale'; import { changeConfirmLocale } from '../modal/locale'; import warning from '../_util/warning'; import { withInstall } from '../_util/type'; import type { ValidateMessages } from '../form/interface'; +import type { TransferLocale } from '../transfer'; +import type { PickerLocale as DatePickerLocale } from '../date-picker/generatePicker'; +import type { PaginationLocale } from '../pagination/Pagination'; + +interface TransferLocaleForEmpty { + description: string; +} export interface Locale { locale: string; - Pagination?: Object; - DatePicker?: Object; - TimePicker?: Object; - Calendar?: Object; - Table?: Object; - Modal?: ModalLocale; - Popconfirm?: Object; - Transfer?: Object; - Select?: Object; - Upload?: Object; - + Pagination?: PaginationLocale; + Table?: Record; + Popconfirm?: Record; + Upload?: Record; Form?: { optional?: string; defaultValidateMessages: ValidateMessages; @@ -28,6 +26,17 @@ export interface Locale { Image?: { preview: string; }; + DatePicker?: DatePickerLocale; + TimePicker?: Record; + Calendar?: Record; + Modal?: ModalLocale; + Transfer?: Partial; + Select?: Record; + Empty?: TransferLocaleForEmpty; + global?: Record; + PageHeader?: { back: string }; + Icon?: Record; + Text?: Record; } export interface LocaleProviderProps { @@ -38,14 +47,6 @@ export interface LocaleProviderProps { export const ANT_MARK = 'internalMark'; -function setMomentLocale(locale?: Locale) { - if (locale && locale.locale) { - interopDefault(moment).locale(locale.locale); - } else { - interopDefault(moment).locale('en'); - } -} - const LocaleProvider = defineComponent({ name: 'ALocaleProvider', props: { @@ -72,10 +73,9 @@ const LocaleProvider = defineComponent({ () => props.locale, val => { state.antLocale = { - ...val, + ...props.locale, exist: true, - }; - setMomentLocale(val); + } as any; changeConfirmLocale(val && val.Modal); }, { immediate: true }, diff --git a/components/locale-provider/ku_KU.ts b/components/locale-provider/ku_KU.ts deleted file mode 100644 index 16ca16ce3..000000000 --- a/components/locale-provider/ku_KU.ts +++ /dev/null @@ -1,3 +0,0 @@ -import locale from '../locale/ku_KU'; - -export default locale; diff --git a/components/locale/ar_EG.ts b/components/locale/ar_EG.ts deleted file mode 100644 index 25be688a2..000000000 --- a/components/locale/ar_EG.ts +++ /dev/null @@ -1,43 +0,0 @@ -import Pagination from '../vc-pagination/locale/ar_EG'; -import DatePicker from '../date-picker/locale/ar_EG'; -import TimePicker from '../time-picker/locale/ar_EG'; -import Calendar from '../calendar/locale/ar_EG'; - -export default { - locale: 'ar', - Pagination, - DatePicker, - TimePicker, - Calendar, - Table: { - filterTitle: 'الفلاتر', - filterConfirm: 'تأكيد', - filterReset: 'إعادة ضبط', - selectAll: 'اختيار الكل', - selectInvert: 'إلغاء الاختيار', - }, - Modal: { - okText: 'تأكيد', - cancelText: 'إلغاء', - justOkText: 'تأكيد', - }, - Popconfirm: { - okText: 'تأكيد', - cancelText: 'إلغاء', - }, - Transfer: { - searchPlaceholder: 'ابحث هنا', - itemUnit: 'عنصر', - itemsUnit: 'عناصر', - }, - Upload: { - uploading: 'جاري الرفع...', - removeFile: 'احذف الملف', - uploadError: 'مشكلة فى الرفع', - previewFile: 'استعرض الملف', - downloadFile: 'تحميل الملف', - }, - Empty: { - description: 'لا توجد بيانات', - }, -}; diff --git a/components/locale/ar_EG.tsx b/components/locale/ar_EG.tsx new file mode 100644 index 000000000..356e5446b --- /dev/null +++ b/components/locale/ar_EG.tsx @@ -0,0 +1,120 @@ +/* eslint-disable no-template-curly-in-string */ +import Pagination from '../vc-pagination/locale/ar_EG'; +import DatePicker from '../date-picker/locale/ar_EG'; +import TimePicker from '../time-picker/locale/ar_EG'; +import Calendar from '../calendar/locale/ar_EG'; +import type { Locale } from '../locale-provider'; + +const typeTemplate = 'ليس ${label} من نوع ${type} صالحًا'; + +const localeValues: Locale = { + locale: 'ar', + Pagination, + DatePicker, + TimePicker, + Calendar, + global: { + placeholder: 'يرجى التحديد', + }, + Table: { + filterTitle: 'الفلاتر', + filterConfirm: 'تأكيد', + filterReset: 'إعادة ضبط', + selectAll: 'اختيار الكل', + selectInvert: 'إلغاء الاختيار', + selectionAll: 'حدد جميع البيانات', + sortTitle: 'رتب', + expand: 'توسيع الصف', + collapse: 'طي الصف', + triggerDesc: 'ترتيب تنازلي', + triggerAsc: 'ترتيب تصاعدي', + cancelSort: 'إلغاء الترتيب', + }, + Modal: { + okText: 'تأكيد', + cancelText: 'إلغاء', + justOkText: 'تأكيد', + }, + Popconfirm: { + okText: 'تأكيد', + cancelText: 'إلغاء', + }, + Transfer: { + searchPlaceholder: 'ابحث هنا', + itemUnit: 'عنصر', + itemsUnit: 'عناصر', + }, + Upload: { + uploading: 'جاري الرفع...', + removeFile: 'احذف الملف', + uploadError: 'مشكلة فى الرفع', + previewFile: 'استعرض الملف', + downloadFile: 'تحميل الملف', + }, + Empty: { + description: 'لا توجد بيانات', + }, + Icon: { + icon: 'أيقونة', + }, + Text: { + edit: 'تعديل', + copy: 'نسخ', + copied: 'نقل', + expand: 'وسع', + }, + PageHeader: { + back: 'عودة', + }, + Form: { + defaultValidateMessages: { + default: 'خطأ في حقل الإدخال ${label}', + required: 'يرجى إدخال ${label}', + enum: '${label} يجب أن يكون واحدا من [${enum}]', + whitespace: '${label} لا يمكن أن يكون حرفًا فارغًا', + date: { + format: '${label} تنسيق التاريخ غير صحيح', + parse: '${label} لا يمكن تحويلها إلى تاريخ', + invalid: 'تاريخ ${label} غير صحيح', + }, + types: { + string: typeTemplate, + method: typeTemplate, + array: typeTemplate, + object: typeTemplate, + number: typeTemplate, + date: typeTemplate, + boolean: typeTemplate, + integer: typeTemplate, + float: typeTemplate, + regexp: typeTemplate, + email: typeTemplate, + url: typeTemplate, + hex: typeTemplate, + }, + string: { + len: 'يجب ${label} ان يكون ${len} أحرف', + min: '${label} على الأقل ${min} أحرف', + max: '${label} يصل إلى ${max} أحرف', + range: 'يجب ${label} ان يكون مابين ${min}-${max} أحرف', + }, + number: { + len: '${len} ان يساوي ${label} يجب', + min: '${min} الأدنى هو ${label} حد', + max: '${max} الأقصى هو ${label} حد', + range: '${max}-${min} ان يكون مابين ${label} يجب', + }, + array: { + len: 'يجب أن يكون ${label} طوله ${len}', + min: 'يجب أن يكون ${label} طوله الأدنى ${min}', + max: 'يجب أن يكون ${label} طوله الأقصى ${max}', + range: 'يجب أن يكون ${label} طوله مابين ${min}-${max}', + }, + pattern: { + mismatch: 'لا يتطابق ${label} مع ${pattern}', + }, + }, + }, +}; + +export default localeValues; diff --git a/components/locale/az_AZ.tsx b/components/locale/az_AZ.tsx new file mode 100644 index 000000000..aa2d2ce38 --- /dev/null +++ b/components/locale/az_AZ.tsx @@ -0,0 +1,48 @@ +import Pagination from '../vc-pagination/locale/az_AZ'; +import DatePicker from '../date-picker/locale/az_AZ'; +import TimePicker from '../time-picker/locale/az_AZ'; +import Calendar from '../calendar/locale/az_AZ'; +import type { Locale } from '../locale-provider'; + +const localeValues: Locale = { + locale: 'az', + Pagination, + DatePicker, + TimePicker, + Calendar, + Table: { + filterTitle: 'Filter menyu', + filterConfirm: 'Axtar', + filterReset: 'Sıfırla', + emptyText: 'Məlumat yoxdur', + selectAll: 'Cari səhifəni seç', + selectInvert: 'Invert current page', + }, + Modal: { + okText: 'Bəli', + cancelText: 'Ləğv et', + justOkText: 'Bəli', + }, + Popconfirm: { + okText: 'Bəli', + cancelText: 'Ləğv et', + }, + Transfer: { + titles: ['', ''], + notFoundContent: 'Tapılmadı', + searchPlaceholder: 'Burada axtar', + itemUnit: 'item', + itemsUnit: 'items', + }, + Select: { + notFoundContent: 'Tapılmadı', + }, + Upload: { + uploading: 'Yüklənir...', + removeFile: 'Faylı sil', + uploadError: 'Yükləmə xətası', + previewFile: 'Fayla önbaxış', + }, +}; + +export default localeValues; diff --git a/components/locale/bg_BG.ts b/components/locale/bg_BG.tsx similarity index 87% rename from components/locale/bg_BG.ts rename to components/locale/bg_BG.tsx index 551dfb0fb..e5887e937 100644 --- a/components/locale/bg_BG.ts +++ b/components/locale/bg_BG.tsx @@ -2,8 +2,9 @@ import Pagination from '../vc-pagination/locale/bg_BG'; import DatePicker from '../date-picker/locale/bg_BG'; import TimePicker from '../time-picker/locale/bg_BG'; import Calendar from '../calendar/locale/bg_BG'; +import type { Locale } from '../locale-provider'; -export default { +const localeValues: Locale = { locale: 'bg', Pagination, DatePicker, @@ -12,7 +13,7 @@ export default { Table: { filterTitle: 'Филтриране', filterConfirm: 'Добре', - filterReset: 'Нулиране', + filterReset: 'Нулриане', selectAll: 'Избор на текуща страница', selectInvert: 'Обръщане', }, @@ -41,3 +42,5 @@ export default { description: 'Няма данни', }, }; + +export default localeValues; diff --git a/components/locale/by_BY.tsx b/components/locale/by_BY.tsx new file mode 100644 index 000000000..87317669d --- /dev/null +++ b/components/locale/by_BY.tsx @@ -0,0 +1,128 @@ +/* eslint-disable no-template-curly-in-string */ +import Pagination from '../vc-pagination/locale/by_BY'; +import DatePicker from '../date-picker/locale/by_BY'; +import TimePicker from '../time-picker/locale/by_BY'; +import Calendar from '../calendar/locale/by_BY'; +import type { Locale } from '../locale-provider'; + +const typeTemplate = "${label} не з'яўляецца тыпам ${type}"; + +const localeValues: Locale = { + locale: 'by', + Pagination, + DatePicker, + TimePicker, + Calendar, + global: { + placeholder: 'Калі ласка выберыце', + }, + Table: { + filterTitle: 'Фільтр', + filterConfirm: 'OK', + filterReset: 'Скінуць', + filterEmptyText: 'Без фільтраў', + emptyText: 'Няма дадзеных', + selectAll: 'Выбраць усе', + selectInvert: 'Інвертаваць выбар', + selectionAll: 'Выбраць усе дадзеныя', + sortTitle: 'Сартаванне', + expand: 'Разгарнуць радок', + collapse: 'Згарнуць радок', + triggerDesc: 'Націсніце для сартавання па змяншэнні', + triggerAsc: 'Націсніце для сартавання па ўзросту', + cancelSort: 'Націсніце, каб адмяніць сартаванне', + }, + Modal: { + okText: 'OK', + cancelText: 'Адмена', + justOkText: 'OK', + }, + Popconfirm: { + okText: 'OK', + cancelText: 'Адмена', + }, + Transfer: { + titles: ['', ''], + searchPlaceholder: 'Пошук', + itemUnit: 'элем.', + itemsUnit: 'элем.', + remove: 'Выдаліць', + selectAll: 'Выбраць усе дадзеныя', + selectCurrent: 'Вылучыць дадзеную старонку', + selectInvert: 'Паказаць у зваротным парадку', + removeAll: 'Выдаліць усе дадзеныя', + removeCurrent: 'Выдаліць дадзеную старонку', + }, + Upload: { + uploading: 'Загрузка...', + removeFile: 'Выдаліць файл', + uploadError: 'Адбылася памылка пры загрузцы', + previewFile: 'Прадпрагляд файла', + downloadFile: 'Загрузіць файл', + }, + Empty: { + description: 'Няма дадзеных', + }, + Icon: { + icon: 'Іконка', + }, + Text: { + edit: 'Рэдагаваць', + copy: 'Капіяваць', + copied: 'Капіяванне завершана', + expand: 'Разгарнуць', + }, + PageHeader: { + back: 'Назад', + }, + Form: { + defaultValidateMessages: { + default: 'Памылка праверкі поля ${label}', + required: 'Калі ласка, увядзіце ${label}', + enum: '${label} павінен быць адным з [${enum}]', + whitespace: '${label} не можа быць пустым', + date: { + format: '${label} няправільны фармат даты', + parse: '${label} не можа быць пераўтворана ў дату', + invalid: "${label} не з'яўляецца карэктнай датай", + }, + types: { + string: typeTemplate, + method: typeTemplate, + array: typeTemplate, + object: typeTemplate, + number: typeTemplate, + date: typeTemplate, + boolean: typeTemplate, + integer: typeTemplate, + float: typeTemplate, + regexp: typeTemplate, + email: typeTemplate, + url: typeTemplate, + hex: typeTemplate, + }, + string: { + len: '${label} павінна быць ${len} сімвалаў', + min: '${label} павінна быць больш або роўная ${min} сімвалаў', + max: '${label} павінна быць менш або роўная ${max} сімвалаў', + range: 'Даўжыня ${label} павінна быць паміж ${min}-${max} сімвалаў', + }, + number: { + len: '${label} павінна быць роўная ${len}', + min: '${label} павінна быць больш або роўная ${min}', + max: '${label} павінна быць больш або роўная ${max}', + }, + array: { + len: 'Колькасць элементаў ${label} павінна быць роўная ${len}', + min: 'Колькасць элементаў ${label} павінна быць больш або роўная ${min}', + max: 'Колькасць элементаў ${label} павінна быць менш або роўная ${max}', + range: 'Колькасць элементаў ${label} павінна быць паміж ${min} і ${max}', + }, + pattern: { + mismatch: '${label} не адпавядае шаблону ${pattern}', + }, + }, + }, +}; + +export default localeValues; diff --git a/components/locale/ca_ES.ts b/components/locale/ca_ES.ts deleted file mode 100644 index 1c960ae20..000000000 --- a/components/locale/ca_ES.ts +++ /dev/null @@ -1,41 +0,0 @@ -import Pagination from '../vc-pagination/locale/ca_ES'; -import DatePicker from '../date-picker/locale/ca_ES'; -import TimePicker from '../time-picker/locale/ca_ES'; -import Calendar from '../calendar/locale/ca_ES'; - -export default { - locale: 'ca', - Pagination, - DatePicker, - TimePicker, - Calendar, - Table: { - filterTitle: 'Filtrar Menu', - filterConfirm: 'OK', - filterReset: 'Restablir', - }, - Modal: { - okText: 'OK', - cancelText: 'Cancel·lar', - justOkText: 'OK', - }, - Popconfirm: { - okText: 'OK', - cancelText: 'Cancel·lar', - }, - Transfer: { - searchPlaceholder: 'Cercar aquí', - itemUnit: 'item', - itemsUnit: 'items', - }, - Upload: { - uploading: 'Carregant...', - removeFile: 'Elimina el fitxer', - uploadError: 'Error de càrrega', - previewFile: 'Vista prèvia del fitxer', - downloadFile: "Descarrega l'arxiu", - }, - Empty: { - description: 'Sense dades', - }, -}; diff --git a/components/locale/ca_ES.tsx b/components/locale/ca_ES.tsx new file mode 100644 index 000000000..7142e52fe --- /dev/null +++ b/components/locale/ca_ES.tsx @@ -0,0 +1,128 @@ +/* eslint-disable no-template-curly-in-string */ +import Pagination from '../vc-pagination/locale/ca_ES'; +import DatePicker from '../date-picker/locale/ca_ES'; +import TimePicker from '../time-picker/locale/ca_ES'; +import Calendar from '../calendar/locale/ca_ES'; +import type { Locale } from '../locale-provider'; + +const typeTemplate = '${label} no és un ${type} vàlid'; + +const localeValues: Locale = { + locale: 'ca', + Pagination, + DatePicker, + TimePicker, + Calendar, + global: { + placeholder: 'Seleccionar', + }, + Table: { + filterTitle: 'Filtrar el menú', + filterConfirm: 'D’acord', + filterReset: 'Reiniciar', + filterEmptyText: 'Sense filtres', + selectAll: 'Seleccionar la pàgina actual', + selectInvert: 'Invertir la selecció', + selectionAll: 'Seleccionar-ho tot', + sortTitle: 'Ordenar', + expand: 'Ampliar la fila', + collapse: 'Plegar la fila', + triggerDesc: 'Ordre descendent', + triggerAsc: 'Ordre ascendent', + cancelSort: 'Desactivar l’ordre', + }, + Modal: { + okText: 'D’acord', + cancelText: 'Cancel·lar', + justOkText: 'D’acord', + }, + Popconfirm: { + okText: 'D’acord', + cancelText: 'Cancel·lar', + }, + Transfer: { + titles: ['', ''], + searchPlaceholder: 'Cercar', + itemUnit: 'ítem', + itemsUnit: 'ítems', + remove: 'Eliminar', + selectCurrent: 'Seleccionar la pàgina actual', + removeCurrent: 'Eliminar la selecció', + selectAll: 'Seleccionar-ho tot', + removeAll: 'Eliminar-ho tot', + selectInvert: 'Invertir la selecció', + }, + Upload: { + uploading: 'Carregant…', + removeFile: 'Eliminar el fitxer', + uploadError: 'Error de càrrega', + previewFile: 'Vista prèvia del fitxer', + downloadFile: 'Baixar el fitxer', + }, + Empty: { + description: 'Sense dades', + }, + Icon: { + icon: 'icona', + }, + Text: { + edit: 'Editar', + copy: 'Copiar', + copied: 'Copiat', + expand: 'Ampliar', + }, + PageHeader: { + back: 'Enrere', + }, + Form: { + defaultValidateMessages: { + default: 'Error de validació del camp ${label}', + required: 'Introdueix ${label}', + enum: '${label} ha de ser un de [${enum}]', + whitespace: '${label} no pot ser un caràcter en blanc', + date: { + format: 'El format de la data de ${label} és invàlid', + parse: '${label} no es pot convertir a cap data', + invalid: '${label} és una data invàlida', + }, + types: { + string: typeTemplate, + method: typeTemplate, + array: typeTemplate, + object: typeTemplate, + number: typeTemplate, + date: typeTemplate, + boolean: typeTemplate, + integer: typeTemplate, + float: typeTemplate, + regexp: typeTemplate, + email: typeTemplate, + url: typeTemplate, + hex: typeTemplate, + }, + string: { + len: '${label} ha de ser de ${len} caràcters', + min: '${label} ha de tenir com a mínim ${min} caràcters', + max: '${label} ha de tenir com a màxim ${max} caràcters', + range: '${label} ha d’estar entre ${min} i ${max} caràcters', + }, + number: { + len: '${label} ha de ser igual a ${len}', + min: '${label} ha de tenir un valor mínim de ${min}', + max: '${label} ha de tenir un valor màxim de ${max}', + range: '${label} ha de tenir un valor entre ${min} i ${max}', + }, + array: { + len: 'La llargada de ${label} ha de ser de ${len}', + min: 'La llargada de ${label} ha de ser com a mínim de ${min}', + max: 'La llargada de ${label} ha de ser com a màxim de ${max}', + range: 'La llargada de ${label} ha d’estar entre ${min} i ${max}', + }, + pattern: { + mismatch: '${label} no coincideix amb el patró ${pattern}', + }, + }, + }, +}; + +export default localeValues; diff --git a/components/locale/cs_CZ.ts b/components/locale/cs_CZ.tsx similarity index 59% rename from components/locale/cs_CZ.ts rename to components/locale/cs_CZ.tsx index 11440a259..b9746b44d 100644 --- a/components/locale/cs_CZ.ts +++ b/components/locale/cs_CZ.tsx @@ -2,17 +2,31 @@ import Pagination from '../vc-pagination/locale/cs_CZ'; import DatePicker from '../date-picker/locale/cs_CZ'; import TimePicker from '../time-picker/locale/cs_CZ'; import Calendar from '../calendar/locale/cs_CZ'; +import type { Locale } from '../locale-provider'; -export default { +const localeValues: Locale = { locale: 'cs', Pagination, DatePicker, TimePicker, Calendar, + global: { + placeholder: 'Prosím vyber', + }, Table: { filterTitle: 'Filtr', filterConfirm: 'Potvrdit', filterReset: 'Obnovit', + filterEmptyText: 'Žádné filtry', + selectAll: 'Vybrat všechny řádky na současné stránce', + selectInvert: 'Invertovat výběr na současné stránce', + selectionAll: 'Vybrat všechny řádky', + sortTitle: 'Řadit', + expand: 'Rozbalit řádek', + collapse: 'Zabalit řádek', + triggerDesc: 'Klikni pro sestupné řazení', + triggerAsc: 'Klikni pro vzestupné řazení', + cancelSort: 'Klikni pro zrušení řazení', }, Modal: { okText: 'Ok', @@ -39,3 +53,5 @@ export default { description: 'Žádná data', }, }; + +export default localeValues; diff --git a/components/locale/da_DK.ts b/components/locale/da_DK.tsx similarity index 89% rename from components/locale/da_DK.ts rename to components/locale/da_DK.tsx index 2a764267a..951a4e012 100644 --- a/components/locale/da_DK.ts +++ b/components/locale/da_DK.tsx @@ -2,8 +2,9 @@ import Pagination from '../vc-pagination/locale/da_DK'; import DatePicker from '../date-picker/locale/da_DK'; import TimePicker from '../time-picker/locale/da_DK'; import Calendar from '../calendar/locale/da_DK'; +import type { Locale } from '../locale-provider'; -export default { +const localeValues: Locale = { locale: 'da', DatePicker, TimePicker, @@ -41,3 +42,5 @@ export default { description: 'Ingen data', }, }; + +export default localeValues; diff --git a/components/locale/de_DE.ts b/components/locale/de_DE.ts deleted file mode 100644 index 5f0611342..000000000 --- a/components/locale/de_DE.ts +++ /dev/null @@ -1,43 +0,0 @@ -import Pagination from '../vc-pagination/locale/de_DE'; -import DatePicker from '../date-picker/locale/de_DE'; -import TimePicker from '../time-picker/locale/de_DE'; -import Calendar from '../calendar/locale/de_DE'; - -export default { - locale: 'de', - Pagination, - DatePicker, - TimePicker, - Calendar, - Table: { - filterTitle: 'Filter-Menü', - filterConfirm: 'OK', - filterReset: 'Zurücksetzen', - selectAll: 'Selektiere Alle', - selectInvert: 'Selektion Invertieren', - }, - Modal: { - okText: 'OK', - cancelText: 'Abbrechen', - justOkText: 'OK', - }, - Popconfirm: { - okText: 'OK', - cancelText: 'Abbrechen', - }, - Transfer: { - searchPlaceholder: 'Suchen', - itemUnit: 'Eintrag', - itemsUnit: 'Einträge', - }, - Upload: { - uploading: 'Hochladen...', - removeFile: 'Datei entfernen', - uploadError: 'Fehler beim Hochladen', - previewFile: 'Dateivorschau', - downloadFile: 'Download-Datei', - }, - Empty: { - description: 'Keine Daten', - }, -}; diff --git a/components/locale/de_DE.tsx b/components/locale/de_DE.tsx new file mode 100644 index 000000000..5eef76622 --- /dev/null +++ b/components/locale/de_DE.tsx @@ -0,0 +1,124 @@ +/* eslint-disable no-template-curly-in-string */ +import Pagination from '../vc-pagination/locale/de_DE'; +import DatePicker from '../date-picker/locale/de_DE'; +import TimePicker from '../time-picker/locale/de_DE'; +import Calendar from '../calendar/locale/de_DE'; +import type { Locale } from '../locale-provider'; + +const typeTemplate = '${label} ist nicht gültig. ${type} erwartet'; + +const localeValues: Locale = { + locale: 'de', + Pagination, + DatePicker, + TimePicker, + Calendar, + global: { + placeholder: 'Bitte auswählen', + }, + Table: { + filterTitle: 'Filter-Menü', + filterConfirm: 'OK', + filterReset: 'Zurücksetzen', + selectAll: 'Selektiere Alle', + selectInvert: 'Selektion Invertieren', + selectionAll: 'Wählen Sie alle Daten aus', + sortTitle: 'Sortieren', + expand: 'Zeile erweitern', + collapse: 'Zeile reduzieren', + triggerDesc: 'Klicken zur absteigenden Sortierung', + triggerAsc: 'Klicken zur aufsteigenden Sortierung', + cancelSort: 'Klicken zum Abbrechen der Sortierung', + }, + Modal: { + okText: 'OK', + cancelText: 'Abbrechen', + justOkText: 'OK', + }, + Popconfirm: { + okText: 'OK', + cancelText: 'Abbrechen', + }, + Transfer: { + titles: ['', ''], + searchPlaceholder: 'Suchen', + itemUnit: 'Eintrag', + itemsUnit: 'Einträge', + remove: 'Entfernen', + selectCurrent: 'Alle auf aktueller Seite auswählen', + removeCurrent: 'Auswahl auf aktueller Seite aufheben', + selectAll: 'Alle auswählen', + removeAll: 'Auswahl aufheben', + selectInvert: 'Auswahl umkehren', + }, + Upload: { + uploading: 'Hochladen...', + removeFile: 'Datei entfernen', + uploadError: 'Fehler beim Hochladen', + previewFile: 'Dateivorschau', + downloadFile: 'Download-Datei', + }, + Empty: { + description: 'Keine Daten', + }, + Text: { + edit: 'Bearbeiten', + copy: 'Kopieren', + copied: 'Kopiert', + expand: 'Erweitern', + }, + PageHeader: { + back: 'Zurück', + }, + Form: { + defaultValidateMessages: { + default: 'Feld-Validierungsfehler: ${label}', + required: 'Bitte geben Sie ${label} an', + enum: '${label} muss eines der folgenden sein [${enum}]', + whitespace: '${label} darf kein Leerzeichen sein', + date: { + format: '${label} ist ein ungültiges Datumsformat', + parse: '${label} kann nicht in ein Datum umgewandelt werden', + invalid: '${label} ist ein ungültiges Datum', + }, + types: { + string: typeTemplate, + method: typeTemplate, + array: typeTemplate, + object: typeTemplate, + number: typeTemplate, + date: typeTemplate, + boolean: typeTemplate, + integer: typeTemplate, + float: typeTemplate, + regexp: typeTemplate, + email: typeTemplate, + url: typeTemplate, + hex: typeTemplate, + }, + string: { + len: '${label} muss genau ${len} Zeichen lang sein', + min: '${label} muss mindestens ${min} Zeichen lang sein', + max: '${label} darf höchstens ${max} Zeichen lang sein', + range: '${label} muss zwischen ${min} und ${max} Zeichen lang sein', + }, + number: { + len: '${label} muss gleich ${len} sein', + min: '${label} muss mindestens ${min} sein', + max: '${label} darf maximal ${max} sein', + range: '${label} muss zwischen ${min} und ${max} liegen', + }, + array: { + len: 'Es müssen ${len} ${label} sein', + min: 'Es müssen mindestens ${min} ${label} sein', + max: 'Es dürfen maximal ${max} ${label} sein', + range: 'Die Anzahl an ${label} muss zwischen ${min} und ${max} liegen', + }, + pattern: { + mismatch: '${label} enspricht nicht dem ${pattern} Muster', + }, + }, + }, +}; + +export default localeValues; diff --git a/components/locale/default.ts b/components/locale/default.tsx similarity index 95% rename from components/locale/default.ts rename to components/locale/default.tsx index 518a461e2..cb9f096af 100644 --- a/components/locale/default.ts +++ b/components/locale/default.tsx @@ -1,10 +1,13 @@ +/* eslint-disable no-template-curly-in-string */ import Pagination from '../vc-pagination/locale/en_US'; import DatePicker from '../date-picker/locale/en_US'; import TimePicker from '../time-picker/locale/en_US'; import Calendar from '../calendar/locale/en_US'; -// import ColorPicker from '../color-picker/locale/en_US'; +import type { Locale } from '../locale-provider'; + const typeTemplate = '${label} is not a valid ${type}'; -export default { + +const localeValues: Locale = { locale: 'en', Pagination, DatePicker, @@ -127,3 +130,5 @@ export default { preview: 'Preview', }, }; + +export default localeValues; diff --git a/components/locale/el_GR.ts b/components/locale/el_GR.tsx similarity index 91% rename from components/locale/el_GR.ts rename to components/locale/el_GR.tsx index 2b9d7b659..9262d97d5 100644 --- a/components/locale/el_GR.ts +++ b/components/locale/el_GR.tsx @@ -2,8 +2,9 @@ import Pagination from '../vc-pagination/locale/el_GR'; import DatePicker from '../date-picker/locale/el_GR'; import TimePicker from '../time-picker/locale/el_GR'; import Calendar from '../calendar/locale/el_GR'; +import type { Locale } from '../locale-provider'; -export default { +const localeValues: Locale = { locale: 'el', Pagination, DatePicker, @@ -41,3 +42,5 @@ export default { description: 'Δεν υπάρχουν δεδομένα', }, }; + +export default localeValues; diff --git a/components/locale/en_GB.ts b/components/locale/en_GB.ts deleted file mode 100644 index 828c819c6..000000000 --- a/components/locale/en_GB.ts +++ /dev/null @@ -1,43 +0,0 @@ -import Pagination from '../vc-pagination/locale/en_GB'; -import DatePicker from '../date-picker/locale/en_GB'; -import TimePicker from '../time-picker/locale/en_GB'; -import Calendar from '../calendar/locale/en_GB'; - -export default { - locale: 'en-gb', - Pagination, - DatePicker, - TimePicker, - Calendar, - Table: { - filterTitle: 'Filter menu', - filterConfirm: 'OK', - filterReset: 'Reset', - selectAll: 'Select current page', - selectInvert: 'Invert current page', - }, - Modal: { - okText: 'OK', - cancelText: 'Cancel', - justOkText: 'OK', - }, - Popconfirm: { - okText: 'OK', - cancelText: 'Cancel', - }, - Transfer: { - searchPlaceholder: 'Search here', - itemUnit: 'item', - itemsUnit: 'items', - }, - Upload: { - uploading: 'Uploading...', - removeFile: 'Remove file', - uploadError: 'Upload error', - previewFile: 'Preview file', - downloadFile: 'Download file', - }, - Empty: { - description: 'No data', - }, -}; diff --git a/components/locale/en_GB.tsx b/components/locale/en_GB.tsx new file mode 100644 index 000000000..dd3cd9c6d --- /dev/null +++ b/components/locale/en_GB.tsx @@ -0,0 +1,107 @@ +/* eslint-disable no-template-curly-in-string */ +import Pagination from '../vc-pagination/locale/en_GB'; +import DatePicker from '../date-picker/locale/en_GB'; +import TimePicker from '../time-picker/locale/en_GB'; +import Calendar from '../calendar/locale/en_GB'; +import type { Locale } from '../locale-provider'; + +const typeTemplate = '${label} is not a valid ${type}'; + +const localeValues: Locale = { + locale: 'en-gb', + Pagination, + DatePicker, + TimePicker, + Calendar, + Table: { + filterTitle: 'Filter menu', + filterConfirm: 'OK', + filterReset: 'Reset', + filterEmptyText: 'No filters', + emptyText: 'No data', + selectAll: 'Select current page', + selectInvert: 'Invert current page', + selectionAll: 'Select all data', + sortTitle: 'Sort', + expand: 'Expand row', + collapse: 'Collapse row', + triggerDesc: 'Click to sort descending', + triggerAsc: 'Click to sort ascending', + cancelSort: 'Click to cancel sorting', + }, + Modal: { + okText: 'OK', + cancelText: 'Cancel', + justOkText: 'OK', + }, + Popconfirm: { + okText: 'OK', + cancelText: 'Cancel', + }, + Transfer: { + searchPlaceholder: 'Search here', + itemUnit: 'item', + itemsUnit: 'items', + }, + Upload: { + uploading: 'Uploading...', + removeFile: 'Remove file', + uploadError: 'Upload error', + previewFile: 'Preview file', + downloadFile: 'Download file', + }, + Empty: { + description: 'No data', + }, + Form: { + defaultValidateMessages: { + default: 'Field validation error for ${label}', + required: 'Please enter ${label}', + enum: '${label} must be one of [${enum}]', + whitespace: '${label} cannot be a blank character', + date: { + format: '${label} date format is invalid', + parse: '${label} cannot be converted to a date', + invalid: '${label} is an invalid date', + }, + types: { + string: typeTemplate, + method: typeTemplate, + array: typeTemplate, + object: typeTemplate, + number: typeTemplate, + date: typeTemplate, + boolean: typeTemplate, + integer: typeTemplate, + float: typeTemplate, + regexp: typeTemplate, + email: typeTemplate, + url: typeTemplate, + hex: typeTemplate, + }, + string: { + len: '${label} must be ${len} characters', + min: '${label} must be at least ${min} characters', + max: '${label} must be up to ${max} characters', + range: '${label} must be between ${min}-${max} characters', + }, + number: { + len: '${label} must be equal to ${len}', + min: '${label} must be minimum ${min}', + max: '${label} must be maximum ${max}', + range: '${label} must be between ${min}-${max}', + }, + array: { + len: 'Must be ${len} ${label}', + min: 'At least ${min} ${label}', + max: 'At most ${max} ${label}', + range: 'The amount of ${label} must be between ${min}-${max}', + }, + pattern: { + mismatch: '${label} does not match the pattern ${pattern}', + }, + }, + }, +}; + +export default localeValues; diff --git a/components/locale/en_US.ts b/components/locale/en_US.tsx similarity index 100% rename from components/locale/en_US.ts rename to components/locale/en_US.tsx diff --git a/components/locale/es_ES.ts b/components/locale/es_ES.ts deleted file mode 100644 index 1852ca810..000000000 --- a/components/locale/es_ES.ts +++ /dev/null @@ -1,59 +0,0 @@ -import Pagination from '../vc-pagination/locale/es_ES'; -import DatePicker from '../date-picker/locale/es_ES'; -import TimePicker from '../time-picker/locale/es_ES'; -import Calendar from '../calendar/locale/es_ES'; - -export default { - locale: 'es', - Pagination, - DatePicker, - TimePicker, - Calendar, - global: { - placeholder: 'Seleccione', - }, - Table: { - filterTitle: 'Filtrar menú', - filterConfirm: 'Aceptar', - filterReset: 'Reiniciar', - selectAll: 'Seleccionar todo', - selectInvert: 'Invertir selección', - sortTitle: 'Ordenar', - }, - Modal: { - okText: 'Aceptar', - cancelText: 'Cancelar', - justOkText: 'Aceptar', - }, - Popconfirm: { - okText: 'Aceptar', - cancelText: 'Cancelar', - }, - Transfer: { - searchPlaceholder: 'Buscar aquí', - itemUnit: 'elemento', - itemsUnit: 'elementos', - }, - Upload: { - uploading: 'Subiendo...', - removeFile: 'Eliminar archivo', - uploadError: 'Error al subir el archivo', - previewFile: 'Vista previa', - downloadFile: 'Descargar archivo', - }, - Empty: { - description: 'No hay datos', - }, - Icon: { - icon: 'ícono', - }, - Text: { - edit: 'editar', - copy: 'copiar', - copied: 'copiado', - expand: 'expandir', - }, - PageHeader: { - back: 'volver', - }, -}; diff --git a/components/locale/es_ES.tsx b/components/locale/es_ES.tsx new file mode 100644 index 000000000..d08e824da --- /dev/null +++ b/components/locale/es_ES.tsx @@ -0,0 +1,131 @@ +/* eslint-disable no-template-curly-in-string */ +import Pagination from '../vc-pagination/locale/es_ES'; +import DatePicker from '../date-picker/locale/es_ES'; +import TimePicker from '../time-picker/locale/es_ES'; +import Calendar from '../calendar/locale/es_ES'; +import type { Locale } from '../locale-provider'; + +const typeTemplate = '${label} no es un ${type} válido'; + +const localeValues: Locale = { + locale: 'es', + Pagination, + DatePicker, + TimePicker, + Calendar, + global: { + placeholder: 'Seleccione', + }, + Table: { + filterTitle: 'Filtrar menú', + filterConfirm: 'Aceptar', + filterReset: 'Reiniciar', + filterEmptyText: 'Sin filtros', + emptyText: 'Sin datos', + selectAll: 'Seleccionar todo', + selectInvert: 'Invertir selección', + selectNone: 'Vacíe todo', + selectionAll: 'Seleccionar todos los datos', + sortTitle: 'Ordenar', + expand: 'Expandir fila', + collapse: 'Colapsar fila', + triggerDesc: 'Click para ordenar en orden descendente', + triggerAsc: 'Click para ordenar en orden ascendente', + cancelSort: 'Click para cancelar ordenamiento', + }, + Modal: { + okText: 'Aceptar', + cancelText: 'Cancelar', + justOkText: 'Aceptar', + }, + Popconfirm: { + okText: 'Aceptar', + cancelText: 'Cancelar', + }, + Transfer: { + titles: ['', ''], + searchPlaceholder: 'Buscar aquí', + itemUnit: 'elemento', + itemsUnit: 'elementos', + remove: 'Eliminar', + selectCurrent: 'Seleccionar página actual', + removeCurrent: 'Remover página actual', + selectAll: 'Seleccionar todos los datos', + removeAll: 'Eliminar todos los datos', + selectInvert: 'Invertir página actual', + }, + Upload: { + uploading: 'Subiendo...', + removeFile: 'Eliminar archivo', + uploadError: 'Error al subir el archivo', + previewFile: 'Vista previa', + downloadFile: 'Descargar archivo', + }, + Empty: { + description: 'No hay datos', + }, + Icon: { + icon: 'ícono', + }, + Text: { + edit: 'Editar', + copy: 'Copiar', + copied: 'Copiado', + expand: 'Expandir', + }, + PageHeader: { + back: 'Volver', + }, + Form: { + optional: '(opcional)', + defaultValidateMessages: { + default: 'Error de validación del campo ${label}', + required: 'Por favor ingresar ${label}', + enum: '${label} debe ser uno de [${enum}]', + whitespace: '${label} no puede ser un carácter en blanco', + date: { + format: 'El formato de fecha de ${label} es inválido', + parse: '${label} no se puede convertir a una fecha', + invalid: '${label} es una fecha inválida', + }, + types: { + string: typeTemplate, + method: typeTemplate, + array: typeTemplate, + object: typeTemplate, + number: typeTemplate, + date: typeTemplate, + boolean: typeTemplate, + integer: typeTemplate, + float: typeTemplate, + regexp: typeTemplate, + email: typeTemplate, + url: typeTemplate, + hex: typeTemplate, + }, + string: { + len: '${label} debe tener ${len} caracteres', + min: '${label} debe tener al menos ${min} caracteres', + max: '${label} debe tener hasta ${max} caracteres', + range: '${label} debe tener entre ${min}-${max} caracteres', + }, + number: { + len: '${label} debe ser igual a ${len}', + min: '${label} valor mínimo es ${min}', + max: '${label} valor máximo es ${max}', + range: '${label} debe estar entre ${min}-${max}', + }, + array: { + len: 'Debe ser ${len} ${label}', + min: 'Al menos ${min} ${label}', + max: 'A lo mucho ${max} ${label}', + range: 'El monto de ${label} debe estar entre ${min}-${max}', + }, + pattern: { + mismatch: '${label} no coincide con el patrón ${pattern}', + }, + }, + }, +}; + +export default localeValues; diff --git a/components/locale/et_EE.ts b/components/locale/et_EE.tsx similarity index 89% rename from components/locale/et_EE.ts rename to components/locale/et_EE.tsx index 1c1f91e58..c840327be 100644 --- a/components/locale/et_EE.ts +++ b/components/locale/et_EE.tsx @@ -2,8 +2,9 @@ import Pagination from '../vc-pagination/locale/et_EE'; import DatePicker from '../date-picker/locale/et_EE'; import TimePicker from '../time-picker/locale/et_EE'; import Calendar from '../calendar/locale/et_EE'; +import type { Locale } from '../locale-provider'; -export default { +const localeValues: Locale = { locale: 'et', Pagination, DatePicker, @@ -41,3 +42,5 @@ export default { description: 'Andmed puuduvad', }, }; + +export default localeValues; diff --git a/components/locale/fa_IR.ts b/components/locale/fa_IR.ts deleted file mode 100644 index 6390fb37a..000000000 --- a/components/locale/fa_IR.ts +++ /dev/null @@ -1,43 +0,0 @@ -import Pagination from '../vc-pagination/locale/fa_IR'; -import DatePicker from '../date-picker/locale/fa_IR'; -import TimePicker from '../time-picker/locale/fa_IR'; -import Calendar from '../calendar/locale/fa_IR'; - -export default { - locale: 'fa', - Pagination, - DatePicker, - TimePicker, - Calendar, - Table: { - filterTitle: 'منوی فیلتر', - filterConfirm: 'تایید', - filterReset: 'پاک کردن', - selectAll: 'انتخاب صفحه‌ی کنونی', - selectInvert: 'معکوس کردن انتخاب‌ها در صفحه ی کنونی', - }, - Modal: { - okText: 'تایید', - cancelText: 'لغو', - justOkText: 'تایید', - }, - Popconfirm: { - okText: 'تایید', - cancelText: 'لغو', - }, - Transfer: { - searchPlaceholder: 'جستجو', - itemUnit: '', - itemsUnit: '', - }, - Upload: { - uploading: 'در حال آپلود...', - removeFile: 'حذف فایل', - uploadError: 'خطا در آپلود', - previewFile: 'مشاهده‌ی فایل', - downloadFile: 'دریافت فایل', - }, - Empty: { - description: 'داده‌ای موجود نیست', - }, -}; diff --git a/components/locale/fa_IR.tsx b/components/locale/fa_IR.tsx new file mode 100644 index 000000000..cbf2f677f --- /dev/null +++ b/components/locale/fa_IR.tsx @@ -0,0 +1,134 @@ +/* eslint-disable no-template-curly-in-string */ +import Pagination from '../vc-pagination/locale/fa_IR'; +import DatePicker from '../date-picker/locale/fa_IR'; +import TimePicker from '../time-picker/locale/fa_IR'; +import Calendar from '../calendar/locale/fa_IR'; +import type { Locale } from '../locale-provider'; + +const typeTemplate = '${label} از نوع ${type} معتبر نیست'; + +const localeValues: Locale = { + locale: 'fa', + Pagination, + DatePicker, + TimePicker, + Calendar, + global: { + placeholder: 'لطفاً انتخاب کنید', + }, + Table: { + filterTitle: 'منوی فیلتر', + filterConfirm: 'تایید', + filterReset: 'پاک کردن', + filterEmptyText: 'بدون فیلتر', + emptyText: 'بدون داده', + selectAll: 'انتخاب صفحه‌ی کنونی', + selectInvert: 'معکوس کردن انتخاب‌ها در صفحه ی کنونی', + selectNone: 'انتخاب هیچکدام', + selectionAll: 'انتخاب همه داده‌ها', + sortTitle: 'مرتب سازی', + expand: 'باز شدن ردیف', + collapse: 'بستن ردیف', + triggerDesc: 'ترتیب نزولی', + triggerAsc: 'ترتیب صعودی', + cancelSort: 'لغوِ ترتیبِ داده شده', + }, + Modal: { + okText: 'تایید', + cancelText: 'لغو', + justOkText: 'تایید', + }, + Popconfirm: { + okText: 'تایید', + cancelText: 'لغو', + }, + Transfer: { + titles: ['', ''], + searchPlaceholder: 'جستجو', + itemUnit: 'عدد', + itemsUnit: 'عدد', + remove: 'حذف', + selectCurrent: 'انتخاب صفحه فعلی', + removeCurrent: 'پاک کردن انتخاب‌های صفحه فعلی', + selectAll: 'انتخاب همه', + removeAll: 'پاک کردن همه انتخاب‌ها', + selectInvert: 'معکوس کردن انتخاب‌ها در صفحه ی کنونی', + }, + Upload: { + uploading: 'در حال آپلود...', + removeFile: 'حذف فایل', + uploadError: 'خطا در آپلود', + previewFile: 'مشاهده‌ی فایل', + downloadFile: 'دریافت فایل', + }, + Empty: { + description: 'داده‌ای موجود نیست', + }, + Icon: { + icon: 'آیکن', + }, + Text: { + edit: 'ویرایش', + copy: 'کپی', + copied: 'کپی شد', + expand: 'توسعه', + }, + PageHeader: { + back: 'برگشت', + }, + Form: { + optional: '(اختیاری)', + defaultValidateMessages: { + default: 'خطا در ${label}', + required: 'فیلد ${label} اجباریست', + enum: '${label} باید یکی از [${enum}] باشد', + whitespace: '${label} نمیتواند خالی باشد', + date: { + format: 'ساختار تاریخ در ${label} نامعتبر است', + parse: '${label} قابل تبدیل به تاریخ نیست', + invalid: '${label} تاریخی نا معتبر است', + }, + types: { + string: typeTemplate, + method: typeTemplate, + array: typeTemplate, + object: typeTemplate, + number: typeTemplate, + date: typeTemplate, + boolean: typeTemplate, + integer: typeTemplate, + float: typeTemplate, + regexp: typeTemplate, + email: typeTemplate, + url: typeTemplate, + hex: typeTemplate, + }, + string: { + len: '${label} باید ${len} کاراکتر باشد', + min: '${label} باید حداقل ${min} کاراکتر باشد', + max: '${label} باید حداکثر ${max} کاراکتر باشد', + range: '${label} باید بین ${min}-${max} کاراکتر باشد', + }, + number: { + len: '${label} باید برابر ${len}', + min: '${label} حداقل میتواند ${min} باشد', + max: '${label} حداکثر میتواند ${max} باشد', + range: '${label} باید بین ${min}-${max} باشد', + }, + array: { + len: 'تعداد ${label} باید ${len} باشد.', + min: 'تعداد ${label} حداقل باید ${min} باشد', + max: 'تعداد ${label} حداکثر باید ${max} باشد', + range: 'مقدار ${label} باید بین ${min}-${max} باشد', + }, + pattern: { + mismatch: 'الگوی ${label} با ${pattern} برابری نمی‌کند', + }, + }, + }, + Image: { + preview: 'نمایش', + }, +}; + +export default localeValues; diff --git a/components/locale/fi_FI.ts b/components/locale/fi_FI.tsx similarity index 81% rename from components/locale/fi_FI.ts rename to components/locale/fi_FI.tsx index 8612f184e..a8858b6b8 100644 --- a/components/locale/fi_FI.ts +++ b/components/locale/fi_FI.tsx @@ -2,8 +2,9 @@ import Pagination from '../vc-pagination/locale/fi_FI'; import DatePicker from '../date-picker/locale/fi_FI'; import TimePicker from '../time-picker/locale/fi_FI'; import Calendar from '../calendar/locale/fi_FI'; +import type { Locale } from '../locale-provider'; -export default { +const localeValues: Locale = { locale: 'fi', Pagination, DatePicker, @@ -41,4 +42,12 @@ export default { Empty: { description: 'Ei kohteita', }, + Text: { + edit: 'Muokkaa', + copy: 'Kopioi', + copied: 'Kopioitu', + expand: 'Näytä lisää', + }, }; + +export default localeValues; diff --git a/components/locale/fr_BE.ts b/components/locale/fr_BE.tsx similarity index 90% rename from components/locale/fr_BE.ts rename to components/locale/fr_BE.tsx index 0317e25d0..ce0f28b71 100644 --- a/components/locale/fr_BE.ts +++ b/components/locale/fr_BE.tsx @@ -2,8 +2,9 @@ import Pagination from '../vc-pagination/locale/fr_BE'; import DatePicker from '../date-picker/locale/fr_BE'; import TimePicker from '../time-picker/locale/fr_BE'; import Calendar from '../calendar/locale/fr_BE'; +import type { Locale } from '../locale-provider'; -export default { +const localeValues: Locale = { locale: 'fr', Pagination, DatePicker, @@ -45,3 +46,5 @@ export default { expand: 'développer', }, }; + +export default localeValues; diff --git a/components/locale/fr_CA.tsx b/components/locale/fr_CA.tsx new file mode 100644 index 000000000..d7cd566c2 --- /dev/null +++ b/components/locale/fr_CA.tsx @@ -0,0 +1,62 @@ +import Pagination from '../vc-pagination/locale/fr_CA'; +import DatePicker from '../date-picker/locale/fr_CA'; +import TimePicker from '../time-picker/locale/fr_CA'; +import Calendar from '../calendar/locale/fr_CA'; +import type { Locale } from '../locale-provider'; + +const localeValues: Locale = { + locale: 'fr', + Pagination, + DatePicker, + TimePicker, + Calendar, + Table: { + filterTitle: 'Filtrer', + filterConfirm: 'OK', + filterReset: 'Réinitialiser', + selectAll: 'Sélectionner la page actuelle', + selectInvert: 'Inverser la sélection de la page actuelle', + selectionAll: 'Sélectionner toutes les données', + sortTitle: 'Trier', + expand: 'Développer la ligne', + collapse: 'Réduire la ligne', + triggerDesc: 'Trier par ordre décroissant', + triggerAsc: 'Trier par ordre croissant', + cancelSort: 'Annuler le tri', + }, + Modal: { + okText: 'OK', + cancelText: 'Annuler', + justOkText: 'OK', + }, + Popconfirm: { + okText: 'OK', + cancelText: 'Annuler', + }, + Transfer: { + searchPlaceholder: 'Rechercher', + itemUnit: 'élément', + itemsUnit: 'éléments', + }, + Empty: { + description: 'Aucune donnée', + }, + Upload: { + uploading: 'Téléchargement...', + removeFile: 'Effacer le fichier', + uploadError: 'Erreur de téléchargement', + previewFile: 'Fichier de prévisualisation', + downloadFile: 'Télécharger un fichier', + }, + Text: { + edit: 'Éditer', + copy: 'Copier', + copied: 'Copie effectuée', + expand: 'Développer', + }, + PageHeader: { + back: 'Retour', + }, +}; + +export default localeValues; diff --git a/components/locale/fr_FR.ts b/components/locale/fr_FR.ts deleted file mode 100644 index 169264562..000000000 --- a/components/locale/fr_FR.ts +++ /dev/null @@ -1,47 +0,0 @@ -import Pagination from '../vc-pagination/locale/fr_FR'; -import DatePicker from '../date-picker/locale/fr_FR'; -import TimePicker from '../time-picker/locale/fr_FR'; -import Calendar from '../calendar/locale/fr_FR'; - -export default { - locale: 'fr', - Pagination, - DatePicker, - TimePicker, - Calendar, - Table: { - filterTitle: 'Filtrer', - filterConfirm: 'OK', - filterReset: 'Réinitialiser', - }, - Modal: { - okText: 'OK', - cancelText: 'Annuler', - justOkText: 'OK', - }, - Popconfirm: { - okText: 'OK', - cancelText: 'Annuler', - }, - Transfer: { - searchPlaceholder: 'Recherche', - itemUnit: 'élément', - itemsUnit: 'éléments', - }, - Empty: { - description: 'Aucune donnée', - }, - Upload: { - uploading: 'Téléchargement...', - removeFile: 'Effacer le fichier', - uploadError: 'Erreur de téléchargement', - previewFile: 'Fichier de prévisualisation', - downloadFile: 'Télécharger un fichier', - }, - Text: { - edit: 'éditer', - copy: 'copier', - copied: 'copie effectuée', - expand: 'développer', - }, -}; diff --git a/components/locale/fr_FR.tsx b/components/locale/fr_FR.tsx new file mode 100644 index 000000000..340175351 --- /dev/null +++ b/components/locale/fr_FR.tsx @@ -0,0 +1,131 @@ +/* eslint-disable no-template-curly-in-string */ +import Pagination from '../vc-pagination/locale/fr_FR'; +import DatePicker from '../date-picker/locale/fr_FR'; +import TimePicker from '../time-picker/locale/fr_FR'; +import Calendar from '../calendar/locale/fr_FR'; +import type { Locale } from '../locale-provider'; + +const typeTemplate = "La valeur du champ ${label} n'est pas valide pour le type ${type}"; + +const localeValues: Locale = { + locale: 'fr', + Pagination, + DatePicker, + TimePicker, + Calendar, + Table: { + filterTitle: 'Filtrer', + filterConfirm: 'OK', + filterReset: 'Réinitialiser', + filterEmptyText: 'Aucun filtre', + emptyText: 'Aucune donnée', + selectAll: 'Sélectionner la page actuelle', + selectInvert: 'Inverser la sélection de la page actuelle', + selectNone: 'Désélectionner toutes les données', + selectionAll: 'Sélectionner toutes les données', + sortTitle: 'Trier', + expand: 'Développer la ligne', + collapse: 'Réduire la ligne', + triggerDesc: 'Trier par ordre décroissant', + triggerAsc: 'Trier par ordre croissant', + cancelSort: 'Annuler le tri', + }, + Modal: { + okText: 'OK', + cancelText: 'Annuler', + justOkText: 'OK', + }, + Popconfirm: { + okText: 'OK', + cancelText: 'Annuler', + }, + Transfer: { + titles: ['', ''], + searchPlaceholder: 'Rechercher', + itemUnit: 'élément', + itemsUnit: 'éléments', + remove: 'Désélectionner', + selectCurrent: 'Sélectionner la page actuelle', + removeCurrent: 'Désélectionner la page actuelle', + selectAll: 'Sélectionner toutes les données', + removeAll: 'Désélectionner toutes les données', + selectInvert: 'Inverser la sélection de la page actuelle', + }, + Upload: { + uploading: 'Téléchargement...', + removeFile: 'Effacer le fichier', + uploadError: 'Erreur de téléchargement', + previewFile: 'Fichier de prévisualisation', + downloadFile: 'Télécharger un fichier', + }, + Empty: { + description: 'Aucune donnée', + }, + Icon: { + icon: 'icône', + }, + Text: { + edit: 'Éditer', + copy: 'Copier', + copied: 'Copie effectuée', + expand: 'Développer', + }, + PageHeader: { + back: 'Retour', + }, + Form: { + optional: '(optionnel)', + defaultValidateMessages: { + default: 'Erreur de validation pour le champ ${label}', + required: 'Le champ ${label} est obligatoire', + enum: 'La valeur du champ ${label} doit être parmi [${enum}]', + whitespace: 'La valeur du champ ${label} ne peut pas être vide', + date: { + format: "La valeur du champ ${label} n'est pas au format date", + parse: 'La valeur du champ ${label} ne peut pas être convertie vers une date', + invalid: "La valeur du champ ${label} n'est pas une date valide", + }, + types: { + string: typeTemplate, + method: typeTemplate, + array: typeTemplate, + object: typeTemplate, + number: typeTemplate, + date: typeTemplate, + boolean: typeTemplate, + integer: typeTemplate, + float: typeTemplate, + regexp: typeTemplate, + email: typeTemplate, + url: typeTemplate, + hex: typeTemplate, + }, + string: { + len: 'La taille du champ ${label} doit être de ${len} caractères', + min: 'La taille du champ ${label} doit être au minimum de ${min} caractères', + max: 'La taille du champ ${label} doit être au maximum de ${max} caractères', + range: 'La taille du champ ${label} doit être entre ${min} et ${max} caractères', + }, + number: { + len: 'La valeur du champ ${label} doit être égale à ${len}', + min: 'La valeur du champ ${label} doit être plus grande que ${min}', + max: 'La valeur du champ ${label} doit être plus petit que ${max}', + range: 'La valeur du champ ${label} doit être entre ${min} et ${max}', + }, + array: { + len: 'La taille du tableau ${label} doit être de ${len}', + min: 'La taille du tableau ${label} doit être au minimum de ${min}', + max: 'La taille du tableau ${label} doit être au maximum de ${max}', + range: 'La taille du tableau ${label} doit être entre ${min}-${max}', + }, + pattern: { + mismatch: 'La valeur du champ ${label} ne correspond pas au modèle ${pattern}', + }, + }, + }, + Image: { + preview: 'Aperçu', + }, +}; + +export default localeValues; diff --git a/components/locale/ga_IE.ts b/components/locale/ga_IE.ts deleted file mode 100644 index 0911902d4..000000000 --- a/components/locale/ga_IE.ts +++ /dev/null @@ -1,43 +0,0 @@ -import Pagination from '../vc-pagination/locale/ga_IE'; -import DatePicker from '../date-picker/locale/ga_IE'; -import TimePicker from '../time-picker/locale/ga_IE'; -import Calendar from '../calendar/locale/ga_IE'; - -export default { - locale: 'ga_IE', - Pagination, - DatePicker, - TimePicker, - Calendar, - Table: { - filterTitle: 'Scagaire roghchlár', - filterConfirm: 'Ceart go leor', - filterReset: 'Athshocraigh', - selectAll: 'Roghnaigh an leathanach reatha', - selectInvert: 'Inbhéartaigh an leathanach reatha', - }, - Modal: { - okText: 'Ceart go leor', - cancelText: 'Cealaigh', - justOkText: 'Ceart go leor', - }, - Popconfirm: { - okText: 'Ceart go leor', - cancelText: 'Cealaigh', - }, - Transfer: { - searchPlaceholder: 'Cuardaigh anseo', - itemUnit: 'mír', - itemsUnit: 'míreanna', - }, - Upload: { - uploading: 'Uaslódáil ...', - removeFile: 'Bain comhad', - uploadError: 'Earráid uaslódáil', - previewFile: 'Comhad réamhamhairc', - downloadFile: 'Íoslódáil an comhad', - }, - Empty: { - description: 'Gan aon sonraí', - }, -}; diff --git a/components/locale/ga_IE.tsx b/components/locale/ga_IE.tsx new file mode 100644 index 000000000..b1c35159c --- /dev/null +++ b/components/locale/ga_IE.tsx @@ -0,0 +1,127 @@ +/* eslint-disable no-template-curly-in-string */ +import Pagination from '../vc-pagination/locale/ga_IE'; +import DatePicker from '../date-picker/locale/ga_IE'; +import TimePicker from '../time-picker/locale/ga_IE'; +import Calendar from '../calendar/locale/ga_IE'; +import type { Locale } from '../locale-provider'; + +const typeTemplate = '${label} is not a valid ${type}'; + +const localeValues: Locale = { + locale: 'ga', + Pagination, + DatePicker, + TimePicker, + Calendar, + global: { + placeholder: 'Please select', + }, + Table: { + filterTitle: 'Filter menu', + filterConfirm: 'OK', + filterReset: 'Reset', + selectAll: 'Select current page', + selectInvert: 'Invert current page', + selectionAll: 'Select all data', + sortTitle: 'Sort', + expand: 'Expand row', + collapse: 'Collapse row', + triggerDesc: 'Click to sort descending', + triggerAsc: 'Click to sort ascending', + cancelSort: 'Click to cancel sorting', + }, + Modal: { + okText: 'OK', + cancelText: 'Cancel', + justOkText: 'OK', + }, + Popconfirm: { + okText: 'OK', + cancelText: 'Cancel', + }, + Transfer: { + titles: ['', ''], + searchPlaceholder: 'Search here', + itemUnit: 'item', + itemsUnit: 'items', + remove: 'Remove', + selectCurrent: 'Select current page', + removeCurrent: 'Remove current page', + selectAll: 'Select all data', + removeAll: 'Remove all data', + selectInvert: 'Invert current page', + }, + Upload: { + uploading: 'Uploading...', + removeFile: 'Remove file', + uploadError: 'Upload error', + previewFile: 'Preview file', + downloadFile: 'Download file', + }, + Empty: { + description: 'No Data', + }, + Icon: { + icon: 'icon', + }, + Text: { + edit: 'Edit', + copy: 'Copy', + copied: 'Copied', + expand: 'Expand', + }, + PageHeader: { + back: 'Back', + }, + Form: { + defaultValidateMessages: { + default: 'Field validation error for ${label}', + required: 'Please enter ${label}', + enum: '${label} must be one of [${enum}]', + whitespace: '${label} cannot be a blank character', + date: { + format: '${label} date format is invalid', + parse: '${label} cannot be converted to a date', + invalid: '${label} is an invalid date', + }, + types: { + string: typeTemplate, + method: typeTemplate, + array: typeTemplate, + object: typeTemplate, + number: typeTemplate, + date: typeTemplate, + boolean: typeTemplate, + integer: typeTemplate, + float: typeTemplate, + regexp: typeTemplate, + email: typeTemplate, + url: typeTemplate, + hex: typeTemplate, + }, + string: { + len: '${label} must be ${len} characters', + min: '${label} must be at least ${min} characters', + max: '${label} must be up to ${max} characters', + range: '${label} must be between ${min}-${max} characters', + }, + number: { + len: '${label} must be equal to ${len}', + min: '${label} must be minimum ${min}', + max: '${label} must be maximum ${max}', + range: '${label} must be between ${min}-${max}', + }, + array: { + len: 'Must be ${len} ${label}', + min: 'At least ${min} ${label}', + max: 'At most ${max} ${label}', + range: 'The amount of ${label} must be between ${min}-${max}', + }, + pattern: { + mismatch: '${label} does not match the pattern ${pattern}', + }, + }, + }, +}; + +export default localeValues; diff --git a/components/locale/gl_ES.tsx b/components/locale/gl_ES.tsx new file mode 100644 index 000000000..4c54b0787 --- /dev/null +++ b/components/locale/gl_ES.tsx @@ -0,0 +1,114 @@ +/* eslint-disable no-template-curly-in-string */ +import Pagination from '../vc-pagination/locale/gl_ES'; +import DatePicker from '../date-picker/locale/gl_ES'; +import TimePicker from '../time-picker/locale/gl_ES'; +import Calendar from '../calendar/locale/gl_ES'; +import type { Locale } from '../locale-provider'; + +const typeTemplate = '${label} non é un ${type} válido'; + +const localeValues: Locale = { + locale: 'gl', + Pagination, + DatePicker, + TimePicker, + Calendar, + global: { + placeholder: 'Escolla', + }, + Table: { + filterTitle: 'Filtrar menú', + filterConfirm: 'Aceptar', + filterReset: 'Reiniciar', + selectAll: 'Seleccionar todo', + selectInvert: 'Invertir selección', + sortTitle: 'Ordenar', + }, + Modal: { + okText: 'Aceptar', + cancelText: 'Cancelar', + justOkText: 'Aceptar', + }, + Popconfirm: { + okText: 'Aceptar', + cancelText: 'Cancelar', + }, + Transfer: { + searchPlaceholder: 'Buscar aquí', + itemUnit: 'elemento', + itemsUnit: 'elementos', + }, + Upload: { + uploading: 'Subindo...', + removeFile: 'Eliminar arquivo', + uploadError: 'Error ao subir o arquivo', + previewFile: 'Vista previa', + downloadFile: 'Descargar arquivo', + }, + Empty: { + description: 'Non hai datos', + }, + Icon: { + icon: 'icona', + }, + Text: { + edit: 'editar', + copy: 'copiar', + copied: 'copiado', + expand: 'expandir', + }, + PageHeader: { + back: 'voltar', + }, + Form: { + defaultValidateMessages: { + default: 'Error de validación do campo ${label}', + required: 'Por favor complete ${label}', + enum: '${label} ten que ser un de [${enum}]', + whitespace: '${label} non pode ter ningún caracter en branco', + date: { + format: 'O formato de data ${label} non é válido', + parse: '${label} non se pode convertir a unha data', + invalid: '${label} é unha data inválida', + }, + types: { + string: typeTemplate, + method: typeTemplate, + array: typeTemplate, + object: typeTemplate, + number: typeTemplate, + date: typeTemplate, + boolean: typeTemplate, + integer: typeTemplate, + float: typeTemplate, + regexp: typeTemplate, + email: typeTemplate, + url: typeTemplate, + hex: typeTemplate, + }, + string: { + len: '${label} debe ter ${len} caracteres', + min: '${label} debe ter como mínimo ${min} caracteres', + max: '${label} debe ter ata ${max} caracteres', + range: '${label} debe ter entre ${min}-${max} caracteres', + }, + number: { + len: '${label} debe ser igual a ${len}', + min: '${label} valor mínimo é ${min}', + max: '${label} valor máximo é ${max}', + range: '${label} debe estar entre ${min}-${max}', + }, + array: { + len: 'Debe ser ${len} ${label}', + min: 'Como mínimo ${min} ${label}', + max: 'Como máximo ${max} ${label}', + range: 'O valor de ${label} debe estar entre ${min}-${max}', + }, + pattern: { + mismatch: '${label} non coincide co patrón ${pattern}', + }, + }, + }, +}; + +export default localeValues; diff --git a/components/locale/he_IL.ts b/components/locale/he_IL.ts deleted file mode 100644 index 6df4736a8..000000000 --- a/components/locale/he_IL.ts +++ /dev/null @@ -1,43 +0,0 @@ -import Pagination from '../vc-pagination/locale/he_IL'; -import DatePicker from '../date-picker/locale/he_IL'; -import TimePicker from '../time-picker/locale/he_IL'; -import Calendar from '../calendar/locale/he_IL'; - -export default { - locale: 'he', - Pagination, - DatePicker, - TimePicker, - Calendar, - Table: { - filterTitle: 'תפריט סינון', - filterConfirm: 'אישור', - filterReset: 'איפוס', - selectAll: 'בחר הכל', - selectInvert: 'הפוך בחירה', - }, - Modal: { - okText: 'אישור', - cancelText: 'ביטול', - justOkText: 'אישור', - }, - Popconfirm: { - okText: 'אישור', - cancelText: 'ביטול', - }, - Transfer: { - searchPlaceholder: 'חפש כאן', - itemUnit: 'פריט', - itemsUnit: 'פריטים', - }, - Upload: { - uploading: 'מעלה...', - removeFile: 'הסר קובץ', - uploadError: 'שגיאת העלאה', - previewFile: 'הצג קובץ', - downloadFile: 'הורד קובץ', - }, - Empty: { - description: 'אין מידע', - }, -}; diff --git a/components/locale/he_IL.tsx b/components/locale/he_IL.tsx new file mode 100644 index 000000000..0a305aabb --- /dev/null +++ b/components/locale/he_IL.tsx @@ -0,0 +1,120 @@ +/* eslint-disable no-template-curly-in-string */ +import Pagination from '../vc-pagination/locale/he_IL'; +import DatePicker from '../date-picker/locale/he_IL'; +import TimePicker from '../time-picker/locale/he_IL'; +import Calendar from '../calendar/locale/he_IL'; +import type { Locale } from '../locale-provider'; + +const typeTemplate = '${label} הוא לא ${type} תקין'; + +const localeValues: Locale = { + locale: 'he', + Pagination, + DatePicker, + TimePicker, + Calendar, + global: { + placeholder: 'אנא בחר', + }, + Table: { + filterTitle: 'תפריט סינון', + filterConfirm: 'אישור', + filterReset: 'איפוס', + selectAll: 'בחר הכל', + selectInvert: 'הפוך בחירה', + selectionAll: 'בחר את כל הנתונים', + sortTitle: 'מיון', + expand: 'הרחב שורה', + collapse: 'צמצם שורהw', + triggerDesc: 'לחץ על מיון לפי סדר יורד', + triggerAsc: 'לחץ על מיון לפי סדר עולה', + cancelSort: 'לחץ כדי לבטל את המיון', + }, + Modal: { + okText: 'אישור', + cancelText: 'ביטול', + justOkText: 'אישור', + }, + Popconfirm: { + okText: 'אישור', + cancelText: 'ביטול', + }, + Transfer: { + searchPlaceholder: 'חפש כאן', + itemUnit: 'פריט', + itemsUnit: 'פריטים', + }, + Upload: { + uploading: 'מעלה...', + removeFile: 'הסר קובץ', + uploadError: 'שגיאת העלאה', + previewFile: 'הצג קובץ', + downloadFile: 'הורד קובץ', + }, + Empty: { + description: 'אין מידע', + }, + Icon: { + icon: 'סמל', + }, + Text: { + edit: 'ערוך', + copy: 'העתק', + copied: 'הועתק', + expand: 'הרחב', + }, + PageHeader: { + back: 'חזרה', + }, + Form: { + defaultValidateMessages: { + default: 'ערך השדה שגוי ${label}', + required: 'בבקשה הזן ${label}', + enum: '${label} חייב להיות אחד מערכים אלו [${enum}]', + whitespace: '${label} לא יכול להיות ריק', + date: { + format: '${label} תאריך לא תקין', + parse: '${label} לא ניתן להמיר לתאריך', + invalid: '${label} הוא לא תאריך תקין', + }, + types: { + string: typeTemplate, + method: typeTemplate, + array: typeTemplate, + object: typeTemplate, + number: typeTemplate, + date: typeTemplate, + boolean: typeTemplate, + integer: typeTemplate, + float: typeTemplate, + regexp: typeTemplate, + email: typeTemplate, + url: typeTemplate, + hex: typeTemplate, + }, + string: { + len: '${label} חייב להיות ${len} תווים', + min: '${label} חייב להיות ${min} תווים', + max: '${label} מקסימום ${max} תווים', + range: '${label} חייב להיות בין ${min}-${max} תווים', + }, + number: { + len: '${label} חייב להיות שווה ל ${len}', + min: '${label} ערך מינימלי הוא ${min}', + max: '${label} ערך מקסימלי הוא ${max}', + range: '${label} חייב להיות בין ${min}-${max}', + }, + array: { + len: 'חייב להיות ${len} ${label}', + min: 'מינימום ${min} ${label}', + max: 'מקסימום ${max} ${label}', + range: 'הסכום של ${label} חייב להיות בין ${min}-${max}', + }, + pattern: { + mismatch: '${label} לא תואם לתבנית ${pattern}', + }, + }, + }, +}; + +export default localeValues; diff --git a/components/locale/hi_IN.ts b/components/locale/hi_IN.ts deleted file mode 100644 index e8b7510bf..000000000 --- a/components/locale/hi_IN.ts +++ /dev/null @@ -1,51 +0,0 @@ -import Pagination from '../vc-pagination/locale/hi_IN'; -import DatePicker from '../date-picker/locale/hi_IN'; -import TimePicker from '../time-picker/locale/hi_IN'; -import Calendar from '../calendar/locale/hi_IN'; - -export default { - locale: 'hi', - Pagination, - DatePicker, - TimePicker, - Calendar, - // locales for all comoponents - global: { - placeholder: 'कृपया चुनें', - }, - Table: { - filterTitle: 'सूची बंद करें', - filterConfirm: 'अच्छी तरह से', - filterReset: 'रीसेट', - emptyText: 'कोई जानकारी नहीं', - selectAll: 'वर्तमान पृष्ठ का चयन करें', - selectInvert: 'वर्तमान पृष्ठ घुमाएं', - sortTitle: 'द्वारा क्रमबद्ध करें', - }, - Modal: { - okText: 'अच्छी तरह से', - cancelText: 'रद्द करना', - justOkText: 'अच्छी तरह से', - }, - Popconfirm: { - okText: 'अच्छी तरह से', - cancelText: 'रद्द करना', - }, - Transfer: { - titles: ['', ''], - notFoundContent: 'नहीं मिला', - searchPlaceholder: 'यहां खोजें', - itemUnit: 'तत्त्व', - itemsUnit: 'विषय-वस्तु', - }, - Select: { - notFoundContent: 'नहीं मिला', - }, - Upload: { - uploading: 'अपलोडिंग...', - removeFile: 'फ़ाइल निकालें', - uploadError: 'अपलोड में त्रुटि', - previewFile: 'फ़ाइल पूर्वावलोकन', - downloadFile: 'फ़ाइल डाउनलोड करें', - }, -}; diff --git a/components/locale/hi_IN.tsx b/components/locale/hi_IN.tsx new file mode 100644 index 000000000..208abf836 --- /dev/null +++ b/components/locale/hi_IN.tsx @@ -0,0 +1,134 @@ +/* eslint-disable no-template-curly-in-string */ +import Pagination from '../vc-pagination/locale/hi_IN'; +import DatePicker from '../date-picker/locale/hi_IN'; +import TimePicker from '../time-picker/locale/hi_IN'; +import Calendar from '../calendar/locale/hi_IN'; +import type { Locale } from '../locale-provider'; + +const typeTemplate = '${label} मान्य ${type} नहीं है'; + +const localeValues: Locale = { + locale: 'hi', + Pagination, + DatePicker, + TimePicker, + Calendar, + global: { + placeholder: 'कृपया चुनें', + }, + Table: { + filterTitle: 'सूची बंद करें', + filterConfirm: 'अच्छी तरह से', + filterReset: 'रीसेट', + filterEmptyText: 'कोई फ़िल्टर नहीं', + emptyText: 'कोई जानकारी नहीं', + selectAll: 'वर्तमान पृष्ठ का चयन करें', + selectInvert: 'वर्तमान पृष्ठ घुमाएं', + selectNone: 'सभी डेटा साफ़ करें', + selectionAll: 'सभी डेटा का चयन करें', + sortTitle: 'द्वारा क्रमबद्ध करें', + expand: 'पंक्ति का विस्तार करें', + collapse: 'पंक्ति संक्षिप्त करें', + triggerDesc: 'अवरोही क्रमित करने के लिए क्लिक करें', + triggerAsc: 'आरोही क्रमित करने के लिए क्लिक करें', + cancelSort: 'छँटाई रद्द करने के लिए क्लिक करें', + }, + Modal: { + okText: 'अच्छी तरह से', + cancelText: 'रद्द करना', + justOkText: 'अच्छी तरह से', + }, + Popconfirm: { + okText: 'अच्छी तरह से', + cancelText: 'रद्द करना', + }, + Transfer: { + titles: ['', ''], + searchPlaceholder: 'यहां खोजें', + itemUnit: 'तत्त्व', + itemsUnit: 'विषय-वस्तु', + remove: 'हटाए', + selectCurrent: 'वर्तमान पृष्ठ का चयन करें', + removeCurrent: 'वर्तमान पृष्ठ हटाएं', + selectAll: 'सभी डेटा का चयन करें', + removeAll: 'सभी डेटा हटाएं', + selectInvert: 'वर्तमान पृष्ठ को उल्टा करें', + }, + Upload: { + uploading: 'अपलोड हो रहा...', + removeFile: 'फ़ाइल निकालें', + uploadError: 'अपलोड में त्रुटि', + previewFile: 'फ़ाइल पूर्वावलोकन', + downloadFile: 'फ़ाइल डाउनलोड करें', + }, + Empty: { + description: 'कोई आकड़ा उपलब्ध नहीं है', + }, + Icon: { + icon: 'आइकन', + }, + Text: { + edit: 'संपादित करें', + copy: 'प्रतिलिपि', + copied: 'कॉपी किया गया', + expand: 'विस्तार', + }, + PageHeader: { + back: 'वापस', + }, + Form: { + optional: '(ऐच्छिक)', + defaultValidateMessages: { + default: '${label} के लिए फील्ड सत्यापन त्रुटि', + required: 'कृपया ${label} दर्ज करें', + enum: '${label} [${enum}] में से एक होना चाहिए', + whitespace: '${label} एक खाली अक्षर नहीं हो सकता', + date: { + format: '${label} तिथि प्रारूप अमान्य है', + parse: '${label} को तारीख में नहीं बदला जा सकता', + invalid: '${label} एक अमान्य तिथि है', + }, + types: { + string: typeTemplate, + method: typeTemplate, + array: typeTemplate, + object: typeTemplate, + number: typeTemplate, + date: typeTemplate, + boolean: typeTemplate, + integer: typeTemplate, + float: typeTemplate, + regexp: typeTemplate, + email: typeTemplate, + url: typeTemplate, + hex: typeTemplate, + }, + string: { + len: '${label} ${len} अक्षर का होना चाहिए', + min: '${label} कम से कम ${min} वर्णों का होना चाहिए', + max: '${label} अधिकतम ${max} वर्णों का होना चाहिए', + range: '${label} ${min}-${max} वर्णों के बीच होना चाहिए', + }, + number: { + len: '${label} ${len} के बराबर होना चाहिए', + min: '${label} कम से कम ${min} होना चाहिए', + max: '${label} अधिकतम ${max} होना चाहिए', + range: '${label} ${min}-${max} के बीच होना चाहिए', + }, + array: { + len: '${len} ${label} होना चाहिए', + min: 'कम से कम ${min} ${label}', + max: 'ज्यादा से ज्यादा ${max} ${label}', + range: '${label} की राशि ${min}-${max} के बीच होनी चाहिए', + }, + pattern: { + mismatch: '${label} ${pattern} पैटर्न से मेल नहीं खाता', + }, + }, + }, + Image: { + preview: 'पूर्वावलोकन', + }, +}; + +export default localeValues; diff --git a/components/locale/hr_HR.ts b/components/locale/hr_HR.ts deleted file mode 100644 index 8403cd456..000000000 --- a/components/locale/hr_HR.ts +++ /dev/null @@ -1,57 +0,0 @@ -import Pagination from '../vc-pagination/locale/hr_HR'; -import DatePicker from '../date-picker/locale/hr_HR'; -import TimePicker from '../time-picker/locale/hr_HR'; -import Calendar from '../calendar/locale/hr_HR'; - -export default { - locale: 'hr', - Pagination, - DatePicker, - TimePicker, - Calendar, - global: { - placeholder: 'Molimo označite', - }, - Table: { - filterTitle: 'Filter meni', - filterConfirm: 'OK', - filterReset: 'Reset', - selectAll: 'Označi trenutnu stranicu', - selectInvert: 'Invertiraj trenutnu stranicu', - sortTitle: 'Sortiraj', - }, - Modal: { - okText: 'OK', - cancelText: 'Odustani', - justOkText: 'OK', - }, - Popconfirm: { - okText: 'OK', - cancelText: 'Odustani', - }, - Transfer: { - titles: ['', ''], - searchPlaceholder: 'Pretraži ovdje', - itemUnit: 'stavka', - itemsUnit: 'stavke', - }, - Upload: { - uploading: 'Upload u tijeku...', - removeFile: 'Makni datoteku', - uploadError: 'Greška kod uploada', - previewFile: 'Pogledaj datoteku', - downloadFile: 'Preuzmi datoteku', - }, - Empty: { - description: 'Nema podataka', - }, - Icon: { - icon: 'ikona', - }, - Text: { - edit: 'uredi', - copy: 'kopiraj', - copied: 'kopiranje uspješno', - expand: 'proširi', - }, -}; diff --git a/components/locale/hr_HR.tsx b/components/locale/hr_HR.tsx new file mode 100644 index 000000000..d91aea4c8 --- /dev/null +++ b/components/locale/hr_HR.tsx @@ -0,0 +1,133 @@ +/* eslint-disable no-template-curly-in-string */ +import Pagination from '../vc-pagination/locale/hr_HR'; +import DatePicker from '../date-picker/locale/hr_HR'; +import TimePicker from '../time-picker/locale/hr_HR'; +import Calendar from '../calendar/locale/hr_HR'; +import type { Locale } from '../locale-provider'; + +const typeTemplate = '${label} nije valjan ${type}'; + +const localeValues: Locale = { + locale: 'hr', + Pagination, + DatePicker, + TimePicker, + Calendar, + global: { + placeholder: 'Molimo označite', + }, + Table: { + filterTitle: 'Filter meni', + filterConfirm: 'OK', + filterReset: 'Reset', + filterEmptyText: 'Nema filtera', + emptyText: 'Nema podataka', + selectAll: 'Označi trenutnu stranicu', + selectInvert: 'Invertiraj trenutnu stranicu', + selectionAll: 'Odaberite sve podatke', + sortTitle: 'Sortiraj', + expand: 'Proširi redak', + collapse: 'Sažmi redak', + triggerDesc: 'Kliknite za sortiranje silazno', + triggerAsc: 'Kliknite za sortiranje uzlazno', + cancelSort: 'Kliknite da biste otkazali sortiranje', + }, + Modal: { + okText: 'OK', + cancelText: 'Odustani', + justOkText: 'OK', + }, + Popconfirm: { + okText: 'OK', + cancelText: 'Odustani', + }, + Transfer: { + titles: ['', ''], + searchPlaceholder: 'Pretraži ovdje', + itemUnit: 'stavka', + itemsUnit: 'stavke', + remove: 'Ukloniti', + selectCurrent: 'Odaberite trenutnu stranicu', + removeCurrent: 'Ukloni trenutnu stranicu', + selectAll: 'Odaberite sve podatke', + removeAll: 'Uklonite sve podatke', + selectInvert: 'Obrni trenutnu stranicu', + }, + Upload: { + uploading: 'Upload u tijeku...', + removeFile: 'Makni datoteku', + uploadError: 'Greška kod uploada', + previewFile: 'Pogledaj datoteku', + downloadFile: 'Preuzmi datoteku', + }, + Empty: { + description: 'Nema podataka', + }, + Icon: { + icon: 'ikona', + }, + Text: { + edit: 'Uredi', + copy: 'Kopiraj', + copied: 'Kopiranje uspješno', + expand: 'Proširi', + }, + PageHeader: { + back: 'Natrag', + }, + Form: { + optional: '(neobavezno)', + defaultValidateMessages: { + default: 'Pogreška provjere valjanosti polja za ${label}', + required: 'Molimo unesite ${label}', + enum: '${label} mora biti jedan od [${enum}]', + whitespace: '${label} ne može biti prazan znak', + date: { + format: '${label} format datuma je nevažeći', + parse: '${label} ne može se pretvoriti u datum', + invalid: '${label} je nevažeći datum', + }, + types: { + string: typeTemplate, + method: typeTemplate, + array: typeTemplate, + object: typeTemplate, + number: typeTemplate, + date: typeTemplate, + boolean: typeTemplate, + integer: typeTemplate, + float: typeTemplate, + regexp: typeTemplate, + email: typeTemplate, + url: typeTemplate, + hex: typeTemplate, + }, + string: { + len: '${label} mora biti ${len} slova', + min: '${label} mora biti najmanje ${min} slova', + max: '${label} mora biti do ${max} slova', + range: '${label} mora biti između ${min}-${max} slova', + }, + number: { + len: '${label} mora biti jednak ${len}', + min: '${label} mora biti minimalano ${min}', + max: '${label} mora biti maksimalano ${max}', + range: '${label} mora biti između ${min}-${max}', + }, + array: { + len: 'Mora biti ${len} ${label}', + min: 'Najmanje ${min} ${label}', + max: 'Najviše ${max} ${label}', + range: 'Količina ${label} mora biti između ${min}-${max}', + }, + pattern: { + mismatch: '${label} ne odgovara obrascu ${pattern}', + }, + }, + }, + Image: { + preview: 'Pregled', + }, +}; + +export default localeValues; diff --git a/components/locale/hu_HU.ts b/components/locale/hu_HU.tsx similarity index 90% rename from components/locale/hu_HU.ts rename to components/locale/hu_HU.tsx index 8e90608a4..290c5254f 100644 --- a/components/locale/hu_HU.ts +++ b/components/locale/hu_HU.tsx @@ -2,8 +2,9 @@ import Pagination from '../vc-pagination/locale/hu_HU'; import DatePicker from '../date-picker/locale/hu_HU'; import TimePicker from '../time-picker/locale/hu_HU'; import Calendar from '../calendar/locale/hu_HU'; +import type { Locale } from '../locale-provider'; -export default { +const localeValues: Locale = { locale: 'hu', Pagination, DatePicker, @@ -42,3 +43,5 @@ export default { description: 'Nincs adat', }, }; + +export default localeValues; diff --git a/components/locale/hy_AM.ts b/components/locale/hy_AM.tsx similarity index 92% rename from components/locale/hy_AM.ts rename to components/locale/hy_AM.tsx index ee698cdda..a324b3c98 100644 --- a/components/locale/hy_AM.ts +++ b/components/locale/hy_AM.tsx @@ -1,5 +1,9 @@ -const datePickerLocale = { +import type { Locale } from '../locale-provider'; +import type { PickerLocale } from '../date-picker/generatePicker'; + +const datePickerLocale: PickerLocale = { lang: { + locale: 'hy-am', placeholder: 'Ընտրեք ամսաթիվը', rangePlaceholder: ['Մեկնարկի ամսաթիվ', 'Ավարտի ամսաթիվը'], today: 'Այսօր', @@ -34,8 +38,8 @@ const datePickerLocale = { }, }; -export default { - locale: 'hy', +const localeValues: Locale = { + locale: 'hy-am', Pagination: { // Options.jsx items_per_page: '/ էջ', @@ -107,3 +111,5 @@ export default { back: 'Հետ', }, }; + +export default localeValues; diff --git a/components/locale/id_ID.ts b/components/locale/id_ID.tsx similarity index 90% rename from components/locale/id_ID.ts rename to components/locale/id_ID.tsx index cc89bd93e..a389523b9 100644 --- a/components/locale/id_ID.ts +++ b/components/locale/id_ID.tsx @@ -2,8 +2,9 @@ import Pagination from '../vc-pagination/locale/id_ID'; import DatePicker from '../date-picker/locale/id_ID'; import TimePicker from '../time-picker/locale/id_ID'; import Calendar from '../calendar/locale/id_ID'; +import type { Locale } from '../locale-provider'; -export default { +const localeValues: Locale = { locale: 'id', Pagination, DatePicker, @@ -43,3 +44,5 @@ export default { description: 'Tidak ada data', }, }; + +export default localeValues; diff --git a/components/locale/is_IS.ts b/components/locale/is_IS.tsx similarity index 89% rename from components/locale/is_IS.ts rename to components/locale/is_IS.tsx index 745e1ee91..356ace19f 100644 --- a/components/locale/is_IS.ts +++ b/components/locale/is_IS.tsx @@ -2,8 +2,9 @@ import Pagination from '../vc-pagination/locale/is_IS'; import DatePicker from '../date-picker/locale/is_IS'; import TimePicker from '../time-picker/locale/is_IS'; import Calendar from '../calendar/locale/is_IS'; +import type { Locale } from '../locale-provider'; -export default { +const localeValues: Locale = { locale: 'is', Pagination, DatePicker, @@ -41,3 +42,5 @@ export default { description: 'Engin gögn', }, }; + +export default localeValues; diff --git a/components/locale/it_IT.ts b/components/locale/it_IT.tsx similarity index 81% rename from components/locale/it_IT.ts rename to components/locale/it_IT.tsx index 0843b9ff3..dc9531fd7 100644 --- a/components/locale/it_IT.ts +++ b/components/locale/it_IT.tsx @@ -2,8 +2,9 @@ import Pagination from '../vc-pagination/locale/it_IT'; import DatePicker from '../date-picker/locale/it_IT'; import TimePicker from '../time-picker/locale/it_IT'; import Calendar from '../calendar/locale/it_IT'; +import type { Locale } from '../locale-provider'; -export default { +const localeValues: Locale = { locale: 'it', Pagination, DatePicker, @@ -19,6 +20,9 @@ export default { selectAll: 'Seleziona pagina corrente', selectInvert: 'Inverti selezione nella pagina corrente', sortTitle: 'Ordina', + triggerDesc: 'Clicca per ordinare in modo discendente', + triggerAsc: 'Clicca per ordinare in modo ascendente', + cancelSort: 'Clicca per eliminare i filtri', }, Modal: { okText: 'OK', @@ -54,3 +58,5 @@ export default { expand: 'espandi', }, }; + +export default localeValues; diff --git a/components/locale/ja_JP.ts b/components/locale/ja_JP.ts deleted file mode 100644 index 49f64d647..000000000 --- a/components/locale/ja_JP.ts +++ /dev/null @@ -1,43 +0,0 @@ -import Pagination from '../vc-pagination/locale/ja_JP'; -import DatePicker from '../date-picker/locale/ja_JP'; -import TimePicker from '../time-picker/locale/ja_JP'; -import Calendar from '../calendar/locale/ja_JP'; - -export default { - locale: 'ja', - Pagination, - DatePicker, - TimePicker, - Calendar, - Table: { - filterTitle: 'メニューをフィルター', - filterConfirm: 'OK', - filterReset: 'リセット', - selectAll: 'すべてを選択', - selectInvert: '選択を反転', - }, - Modal: { - okText: 'OK', - cancelText: 'キャンセル', - justOkText: 'OK', - }, - Popconfirm: { - okText: 'OK', - cancelText: 'キャンセル', - }, - Transfer: { - searchPlaceholder: 'ここを検索', - itemUnit: 'アイテム', - itemsUnit: 'アイテム', - }, - Upload: { - uploading: 'アップロード中...', - removeFile: 'ファイルを削除', - uploadError: 'アップロードエラー', - previewFile: 'ファイルをプレビュー', - downloadFile: 'ダウンロードファイル', - }, - Empty: { - description: 'データがありません', - }, -}; diff --git a/components/locale/ja_JP.tsx b/components/locale/ja_JP.tsx new file mode 100644 index 000000000..3627466ea --- /dev/null +++ b/components/locale/ja_JP.tsx @@ -0,0 +1,106 @@ +/* eslint-disable no-template-curly-in-string */ +import Pagination from '../vc-pagination/locale/ja_JP'; +import DatePicker from '../date-picker/locale/ja_JP'; +import TimePicker from '../time-picker/locale/ja_JP'; +import Calendar from '../calendar/locale/ja_JP'; +import type { Locale } from '../locale-provider'; + +const typeTemplate = '${label}は有効な${type}ではありません'; + +const localeValues: Locale = { + locale: 'ja', + Pagination, + DatePicker, + TimePicker, + Calendar, + Table: { + filterTitle: 'フィルター', + filterConfirm: 'OK', + filterReset: 'リセット', + filterEmptyText: 'フィルターなし', + selectAll: 'ページ単位で選択', + selectInvert: 'ページ単位で反転', + selectionAll: 'すべてを選択', + sortTitle: 'ソート', + expand: '展開する', + collapse: '折り畳む', + triggerDesc: 'クリックで降順にソート', + triggerAsc: 'クリックで昇順にソート', + cancelSort: 'ソートをキャンセル', + }, + Modal: { + okText: 'OK', + cancelText: 'キャンセル', + justOkText: 'OK', + }, + Popconfirm: { + okText: 'OK', + cancelText: 'キャンセル', + }, + Transfer: { + searchPlaceholder: 'ここを検索', + itemUnit: 'アイテム', + itemsUnit: 'アイテム', + }, + Upload: { + uploading: 'アップロード中...', + removeFile: 'ファイルを削除', + uploadError: 'アップロードエラー', + previewFile: 'ファイルをプレビュー', + downloadFile: 'ダウンロードファイル', + }, + Empty: { + description: 'データがありません', + }, + Form: { + defaultValidateMessages: { + default: '${label}のフィールド検証エラー', + required: '${label}を入力してください', + enum: '${label}は[${enum}]のいずれかである必要があります', + whitespace: '${label}は空白文字にすることはできません', + date: { + format: '${label}の日付形式は不正です', + parse: '${label}は日付に変換できません', + invalid: '${label}は不正な日付です', + }, + types: { + string: typeTemplate, + method: typeTemplate, + array: typeTemplate, + object: typeTemplate, + number: typeTemplate, + date: typeTemplate, + boolean: typeTemplate, + integer: typeTemplate, + float: typeTemplate, + regexp: typeTemplate, + email: typeTemplate, + url: typeTemplate, + hex: typeTemplate, + }, + string: { + len: '${label}は${len}文字である必要があります', + min: '${label}は${min}文字以上である必要があります', + max: '${label}は${max}文字以下である必要があります', + range: '${label}は${min}-${max}文字の範囲である必要があります', + }, + number: { + len: '${label}は${len}と等しい必要があります', + min: '${label}の最小値は${min}です', + max: '${label}の最大値は${max}です', + range: '${label}は${min}-${max}の範囲である必要があります', + }, + array: { + len: '${label}は${len}である必要があります', + min: '${label}の最小は${min}です', + max: '${label}の最大は${max}です', + range: '${label}の合計は${min}-${max}の範囲である必要があります', + }, + pattern: { + mismatch: '${label}はパターン${pattern}と一致しません', + }, + }, + }, +}; + +export default localeValues; diff --git a/components/locale/kk_KZ.tsx b/components/locale/kk_KZ.tsx new file mode 100644 index 000000000..457a73237 --- /dev/null +++ b/components/locale/kk_KZ.tsx @@ -0,0 +1,129 @@ +/* eslint-disable no-template-curly-in-string */ + +import Pagination from '../vc-pagination/locale/kk_KZ'; +import DatePicker from '../date-picker/locale/kk_KZ'; +import TimePicker from '../time-picker/locale/kk_KZ'; +import Calendar from '../calendar/locale/kk_KZ'; +import type { Locale } from '../locale-provider'; + +const typeTemplate = '${label} ${type} типі емес'; + +const localeValues: Locale = { + locale: 'kk', + Pagination, + DatePicker, + TimePicker, + Calendar, + global: { + placeholder: 'Таңдаңыз', + }, + Table: { + filterTitle: 'Фильтр', + filterConfirm: 'Ok', + filterReset: 'Тазарту', + filterEmptyText: 'Фильтр жоқ', + emptyText: 'Деректер жоқ', + selectAll: 'Барлығын таңдау', + selectInvert: 'Таңдауды төңкеру', + selectionAll: 'Барлық деректерді таңдаңыз', + sortTitle: 'Сұрыптау', + expand: 'Жолды жазу', + collapse: 'Жолды бүктеу', + triggerDesc: 'Төмендеуді сұрыптау үшін басыңыз', + triggerAsc: 'Өсу ретімен сұрыптау үшін басыңыз', + cancelSort: 'Сұрыптаудан бас тарту үшін басыңыз', + }, + Modal: { + okText: 'Жарайды', + cancelText: 'Болдырмау', + justOkText: 'Жарайды', + }, + Popconfirm: { + okText: 'Жарайды', + cancelText: 'Болдырмау', + }, + Transfer: { + titles: ['', ''], + searchPlaceholder: 'Іздеу', + itemUnit: 'элемент.', + itemsUnit: 'элемент.', + remove: 'Жою', + selectAll: 'Барлық деректерді таңдау', + selectCurrent: 'Ағымдағы бетті таңдау', + selectInvert: 'Кері тәртіпте көрсету', + removeAll: 'Барлық деректерді жою', + removeCurrent: 'Ағымдағы парақты өшіру', + }, + Upload: { + uploading: 'Жүктеу...', + removeFile: 'Файлды жою', + uploadError: 'Жүктеу кезінде қате пайда болды', + previewFile: 'Файлды алдын ала қарау', + downloadFile: 'Файлды жүктеу', + }, + Empty: { + description: 'Деректер жоқ', + }, + Icon: { + icon: 'белгішесі', + }, + Text: { + edit: 'Өңдеу', + copy: 'Көшіру', + copied: 'Көшірілді', + expand: 'Жазу', + }, + PageHeader: { + back: 'Артқа', + }, + Form: { + defaultValidateMessages: { + default: '${label} өрісін тексеру қателігі', + required: '${label} енгізіңіз', + enum: '${label} [${enum}] қатарынан болуы керек', + whitespace: '${label} бос болмауы керек', + date: { + format: '${label} жарамды күн форматы емес', + parse: '${label} күнге түрлендірілмейді', + invalid: '${label} жарамды күн емес', + }, + types: { + string: typeTemplate, + method: typeTemplate, + array: typeTemplate, + object: typeTemplate, + number: typeTemplate, + date: typeTemplate, + boolean: typeTemplate, + integer: typeTemplate, + float: typeTemplate, + regexp: typeTemplate, + email: typeTemplate, + url: typeTemplate, + hex: typeTemplate, + }, + string: { + len: '${label} ${len} таңбадан тұруы керек', + min: '${label} ${min} таңбадан үлкен немесе оған тең болуы керек', + max: '${label} ${max} таңбадан кем немесе оған тең болуы керек', + range: '${label} ұзындығы ${min}-${max} таңба аралығында болуы керек', + }, + number: { + len: '${label} ${len} тең болуы керек', + min: '${label} ${min} мәнінен үлкен немесе оған тең болуы керек', + max: '${label} ${max} мәнінен аз немесе оған тең болуы керек', + }, + array: { + len: '${label} элементтерінің саны ${len} тең болуы керек', + min: '${label} элементтерінің саны ${min} көп немесе оған тең болуы керек', + max: '${label} элементтерінің саны ${max} аз немесе оған тең болуы керек', + range: '${label} элементтерінің саны ${min} - ${max} аралығында болуы керек', + }, + pattern: { + mismatch: '${label} ${pattern} мен сәйкес келмейді', + }, + }, + }, +}; + +export default localeValues; diff --git a/components/locale/ku_IQ.ts b/components/locale/kmr_IQ.tsx old mode 100755 new mode 100644 similarity index 68% rename from components/locale/ku_IQ.ts rename to components/locale/kmr_IQ.tsx index 72fbef498..18d878888 --- a/components/locale/ku_IQ.ts +++ b/components/locale/kmr_IQ.tsx @@ -1,10 +1,11 @@ -import Pagination from '../vc-pagination/locale/ku_IQ'; -import DatePicker from '../date-picker/locale/ku_IQ'; -import TimePicker from '../time-picker/locale/ku_IQ'; -import Calendar from '../calendar/locale/ku_IQ'; +import Pagination from '../vc-pagination/locale/kmr_IQ'; +import DatePicker from '../date-picker/locale/kmr_IQ'; +import TimePicker from '../time-picker/locale/kmr_IQ'; +import Calendar from '../calendar/locale/kmr_IQ'; +import type { Locale } from '../locale-provider'; -export default { - locale: 'ku-iq', +const localeValues: Locale = { + locale: 'ku', Pagination, DatePicker, TimePicker, @@ -41,3 +42,5 @@ export default { description: 'Agahî tune', }, }; + +export default localeValues; diff --git a/components/locale/kn_IN.ts b/components/locale/kn_IN.tsx similarity index 93% rename from components/locale/kn_IN.ts rename to components/locale/kn_IN.tsx index 26308eb41..157432094 100644 --- a/components/locale/kn_IN.ts +++ b/components/locale/kn_IN.tsx @@ -2,8 +2,9 @@ import Pagination from '../vc-pagination/locale/kn_IN'; import DatePicker from '../date-picker/locale/kn_IN'; import TimePicker from '../time-picker/locale/kn_IN'; import Calendar from '../calendar/locale/kn_IN'; +import type { Locale } from '../locale-provider'; -export default { +const localeValues: Locale = { locale: 'kn', Pagination, DatePicker, @@ -49,3 +50,5 @@ export default { downloadFile: 'ಫೈಲ್ ಡೌನ್‌ಲೋಡ್ ಮಾಡಿ', }, }; + +export default localeValues; diff --git a/components/locale/ko_KR.ts b/components/locale/ko_KR.ts deleted file mode 100644 index f0de0736c..000000000 --- a/components/locale/ko_KR.ts +++ /dev/null @@ -1,43 +0,0 @@ -import Pagination from '../vc-pagination/locale/ko_KR'; -import DatePicker from '../date-picker/locale/ko_KR'; -import TimePicker from '../time-picker/locale/ko_KR'; -import Calendar from '../calendar/locale/ko_KR'; - -export default { - locale: 'ko', - Pagination, - DatePicker, - TimePicker, - Calendar, - Table: { - filterTitle: '필터 메뉴', - filterConfirm: '확인', - filterReset: '초기화', - selectAll: '모두 선택', - selectInvert: '선택 반전', - }, - Modal: { - okText: '확인', - cancelText: '취소', - justOkText: '확인', - }, - Popconfirm: { - okText: '확인', - cancelText: '취소', - }, - Transfer: { - searchPlaceholder: '여기에 검색하세요', - itemUnit: '개', - itemsUnit: '개', - }, - Upload: { - uploading: '업로드 중...', - removeFile: '파일 삭제', - uploadError: '업로드 실패', - previewFile: '파일 미리보기', - downloadFile: '파일 다운로드', - }, - Empty: { - description: '데이터 없음', - }, -}; diff --git a/components/locale/ko_KR.tsx b/components/locale/ko_KR.tsx new file mode 100644 index 000000000..a1b1eb3ac --- /dev/null +++ b/components/locale/ko_KR.tsx @@ -0,0 +1,100 @@ +/* eslint-disable no-template-curly-in-string */ +import Pagination from '../vc-pagination/locale/ko_KR'; +import DatePicker from '../date-picker/locale/ko_KR'; +import TimePicker from '../time-picker/locale/ko_KR'; +import Calendar from '../calendar/locale/ko_KR'; +import type { Locale } from '../locale-provider'; + +const typeTemplate = '${label} 유효하지 않은 ${type}'; + +const localeValues: Locale = { + locale: 'ko', + Pagination, + DatePicker, + TimePicker, + Calendar, + Table: { + filterTitle: '필터 메뉴', + filterConfirm: '확인', + filterReset: '초기화', + filterEmptyText: '필터 없음', + emptyText: '데이터 없음', + selectAll: '모두 선택', + selectInvert: '선택 반전', + }, + Modal: { + okText: '확인', + cancelText: '취소', + justOkText: '확인', + }, + Popconfirm: { + okText: '확인', + cancelText: '취소', + }, + Transfer: { + searchPlaceholder: '여기에 검색하세요', + itemUnit: '개', + itemsUnit: '개', + }, + Upload: { + uploading: '업로드 중...', + removeFile: '파일 삭제', + uploadError: '업로드 실패', + previewFile: '파일 미리보기', + downloadFile: '파일 다운로드', + }, + Empty: { + description: '데이터 없음', + }, + Form: { + defaultValidateMessages: { + default: '필드 유효성 검사 요류 ${label}', + required: '${label} 입력해 주세요', + enum: '${label} [${enum}] 중에 하나여야 합니다', + whitespace: '${label} 비워둘 수 없습니다', + date: { + format: '${label} 유효하지 않은 날짜 형식입니다', + parse: '${label} 날짜 형식으로 변환될 수 없습니다', + invalid: '${label} 유효하지 않은 날짜입니다', + }, + types: { + string: typeTemplate, + method: typeTemplate, + array: typeTemplate, + object: typeTemplate, + number: typeTemplate, + date: typeTemplate, + boolean: typeTemplate, + integer: typeTemplate, + float: typeTemplate, + regexp: typeTemplate, + email: typeTemplate, + url: typeTemplate, + hex: typeTemplate, + }, + string: { + len: '${label} ${len}글자여야 합니다', + min: '${label} 적어도 ${min}글자 이상이어야 합니다', + max: '${label} ${max}글자 이하여야 합니다', + range: '${label} ${min}-${max}글자 사이어야 합니다', + }, + number: { + len: '${label} 값은 ${len}이어야 합니다', + min: '${label} 최솟값은 ${min}입니다', + max: '${label} 최댓값은 ${max}입니다', + range: '${label} 값은 ${min}-${max} 사이어야 합니다', + }, + array: { + len: '${len}이어야 합니다 ${label} ', + min: '최소 ${min}이어야 합니다 ${label}', + max: '최대 ${max}이어야 합니다 ${label}', + range: '${label} ${min}-${max} 사이어야 합니다', + }, + pattern: { + mismatch: '${label} ${pattern} 패턴과 일치하지 않습니다', + }, + }, + }, +}; + +export default localeValues; diff --git a/components/locale/ku_IQ.tsx b/components/locale/ku_IQ.tsx new file mode 100755 index 000000000..3dc4d7e7d --- /dev/null +++ b/components/locale/ku_IQ.tsx @@ -0,0 +1,50 @@ +import Pagination from '../vc-pagination/locale/kmr_IQ'; +import DatePicker from '../date-picker/locale/kmr_IQ'; +import TimePicker from '../time-picker/locale/kmr_IQ'; +import Calendar from '../calendar/locale/kmr_IQ'; +import type { Locale } from '../locale-provider'; + +// please use antd/lib/locale/kmr_IQ instead +// keep this file for compatibility +// https://github.com/ant-design/ant-design/issues/25778 + +const localeValues: Locale = { + locale: 'ku-iq', + Pagination, + DatePicker, + TimePicker, + Calendar, + Table: { + filterTitle: 'Menuê peldanka', + filterConfirm: 'Temam', + filterReset: 'Jê bibe', + selectAll: 'Hemî hilbijêre', + selectInvert: 'Hilbijartinan veguhere', + }, + Modal: { + okText: 'Temam', + cancelText: 'Betal ke', + justOkText: 'Temam', + }, + Popconfirm: { + okText: 'Temam', + cancelText: 'Betal ke', + }, + Transfer: { + searchPlaceholder: 'Lêgerîn', + itemUnit: 'tişt', + itemsUnit: 'tişt', + }, + Upload: { + uploading: 'Bardike...', + removeFile: 'Pelê rabike', + uploadError: 'Xeta barkirine', + previewFile: 'Pelê pêşbibîne', + downloadFile: 'Pelê dakêşin', + }, + Empty: { + description: 'Agahî tune', + }, +}; + +export default localeValues; diff --git a/components/locale/ku_KU.ts b/components/locale/ku_KU.ts deleted file mode 100644 index 22d2ad61e..000000000 --- a/components/locale/ku_KU.ts +++ /dev/null @@ -1,43 +0,0 @@ -import Pagination from '../vc-pagination/locale/ku_KU'; -import DatePicker from '../date-picker/locale/ku_KU'; -import TimePicker from '../time-picker/locale/ku_KU'; -import Calendar from '../calendar/locale/ku_KU'; - -export default { - locale: 'ku-ku', - Pagination, - DatePicker, - TimePicker, - Calendar, - Table: { - filterTitle: 'مێنوی پاڵاوتن', - filterConfirm: 'پشتڕاستکردنەوە', - filterReset: 'پاک کردن', - selectAll: 'هەڵبژاردنی هەموو', - selectInvert: 'هەڵبژزاردنی پێچەوانە', - }, - Modal: { - okText: 'باشە', - cancelText: 'پاشگەزبونەوە', - justOkText: 'باشە', - }, - Popconfirm: { - okText: 'باشە', - cancelText: 'پاشگەزبونەوە', - }, - Transfer: { - searchPlaceholder: 'گەڕان', - itemUnit: 'یەکە', - itemsUnit: 'یەکە', - }, - Upload: { - uploading: 'بارکردن...', - removeFile: 'پاککردنی فایل', - uploadError: 'هەڵەی بارکردن', - previewFile: 'پیشاندانی فایل', - downloadFile: 'وەرگرتنی فایل', - }, - Empty: { - description: 'هیچ زانیاریەک نیە', - }, -}; diff --git a/components/locale/lt_LT.tsx b/components/locale/lt_LT.tsx new file mode 100644 index 000000000..2dd991ab6 --- /dev/null +++ b/components/locale/lt_LT.tsx @@ -0,0 +1,126 @@ +/* eslint-disable no-template-curly-in-string */ + +import Pagination from '../vc-pagination/locale/lt_LT'; +import DatePicker from '../date-picker/locale/lt_LT'; +import TimePicker from '../time-picker/locale/lt_LT'; +import Calendar from '../calendar/locale/lt_LT'; +import type { Locale } from '../locale-provider'; + +const typeTemplate = '${label} не является типом ${type}'; + +const localeValues: Locale = { + locale: 'lt', + Pagination, + DatePicker, + TimePicker, + Calendar, + Table: { + filterTitle: 'Filtras', + filterConfirm: 'Gerai', + filterReset: 'Atstatyti', + filterEmptyText: 'Be filtrų', + emptyText: 'Nėra duomenų', + selectAll: 'Pasirinkti viską', + selectInvert: 'Apversti pasirinkimą', + selectionAll: 'Rinktis visus', + sortTitle: 'Rikiavimas', + expand: 'Išskleisti', + collapse: 'Suskleisti', + triggerDesc: 'Spustelėkite norėdami rūšiuoti mažėjančia tvarka', + triggerAsc: 'Spustelėkite norėdami rūšiuoti didėjančia tvarka', + cancelSort: 'Spustelėkite, kad atšauktumėte rūšiavimą', + }, + Modal: { + okText: 'Taip', + cancelText: 'Atšaukti', + justOkText: 'Gerai', + }, + Popconfirm: { + okText: 'Taip', + cancelText: 'Atšaukti', + }, + Transfer: { + titles: ['', ''], + searchPlaceholder: 'Paieška', + itemUnit: 'vnt.', + itemsUnit: 'vnt.', + remove: 'Pašalinti', + selectAll: 'Pasirinkti visus', + selectCurrent: 'Pasirinkite dabartinį puslapį', + selectInvert: 'Atkeist pasirinkimą', + removeAll: 'Ištrinti visus duomenis', + removeCurrent: 'Ištrinti dabartinį puslapį', + }, + Upload: { + uploading: 'Gaunami duomenys...', + removeFile: 'Ištrinti failą', + uploadError: 'Įkeliant įvyko klaida', + previewFile: 'Failo peržiūra', + downloadFile: 'Įkelti failą', + }, + Empty: { + description: 'Nėra duomenų', + }, + Icon: { + icon: 'piktograma', + }, + Text: { + edit: 'Redaguoti', + copy: 'Kopijuoti', + copied: 'Nukopijuota', + expand: 'Plačiau', + }, + PageHeader: { + back: 'Atgal', + }, + Form: { + defaultValidateMessages: { + default: 'Laukelio klaida ${label}', + required: 'Prašome įvesti ${label}', + enum: '${label} turėtu būti vienas iš [${enum}]', + whitespace: '${label} negali likti tuščiu', + date: { + format: '${label} neteisingas datos formatas', + parse: '${label} negali būti konvertuotas į datą', + invalid: '${label} neatitinka datos formato', + }, + types: { + string: typeTemplate, + method: typeTemplate, + array: typeTemplate, + object: typeTemplate, + number: typeTemplate, + date: typeTemplate, + boolean: typeTemplate, + integer: typeTemplate, + float: typeTemplate, + regexp: typeTemplate, + email: typeTemplate, + url: typeTemplate, + hex: typeTemplate, + }, + string: { + len: '${label} turi būti ${len} simbolių', + min: '${label} turi būti ilgesnis nei ${min} simbolių', + max: '${label} turi būti ne trumpesnis ${max} simbolių', + range: 'Lauko ${label} reikšmės ribos ${min}-${max} simbolių', + }, + number: { + len: '${label} turi būti lygi ${len}', + min: '${label} turi būti lygus arba didesnis ${min}', + max: '${label} turi būti lygus arba mažesnis ${max}', + }, + array: { + len: 'Pasirinktas kiekis ${label} turi būti lygus ${len}', + min: 'Pasirinktas kiekis ${label} turi būti lygus arba didesnis ${min}', + max: 'Pasirinktas kiekis ${label} turi būti lygus arba mažesnis ${max}', + range: 'Pasirinktas kiekis ${label} turi būti tarp ${min} и ${max}', + }, + pattern: { + mismatch: '${label} neatitinka modelio ${pattern}', + }, + }, + }, +}; + +export default localeValues; diff --git a/components/locale/lv_LV.ts b/components/locale/lv_LV.tsx similarity index 90% rename from components/locale/lv_LV.ts rename to components/locale/lv_LV.tsx index 20e1fa5cd..f175bd611 100644 --- a/components/locale/lv_LV.ts +++ b/components/locale/lv_LV.tsx @@ -2,8 +2,9 @@ import Pagination from '../vc-pagination/locale/lv_LV'; import DatePicker from '../date-picker/locale/lv_LV'; import TimePicker from '../time-picker/locale/lv_LV'; import Calendar from '../calendar/locale/lv_LV'; +import type { Locale } from '../locale-provider'; -export default { +const localeValues: Locale = { locale: 'lv', Pagination, DatePicker, @@ -41,3 +42,5 @@ export default { description: 'Nav datu', }, }; + +export default localeValues; diff --git a/components/locale/mk_MK.ts b/components/locale/mk_MK.tsx similarity index 92% rename from components/locale/mk_MK.ts rename to components/locale/mk_MK.tsx index b42cfd79a..6110ddda6 100644 --- a/components/locale/mk_MK.ts +++ b/components/locale/mk_MK.tsx @@ -2,8 +2,9 @@ import Pagination from '../vc-pagination/locale/mk_MK'; import DatePicker from '../date-picker/locale/mk_MK'; import TimePicker from '../time-picker/locale/mk_MK'; import Calendar from '../calendar/locale/mk_MK'; +import type { Locale } from '../locale-provider'; -export default { +const localeValues: Locale = { locale: 'mk', Pagination, DatePicker, @@ -56,3 +57,5 @@ export default { back: 'Назад', }, }; + +export default localeValues; diff --git a/components/locale/mn_MN.ts b/components/locale/mn_MN.tsx similarity index 90% rename from components/locale/mn_MN.ts rename to components/locale/mn_MN.tsx index 2f3a31b26..748ec1a30 100644 --- a/components/locale/mn_MN.ts +++ b/components/locale/mn_MN.tsx @@ -2,8 +2,9 @@ import Pagination from '../vc-pagination/locale/mn_MN'; import DatePicker from '../date-picker/locale/mn_MN'; import TimePicker from '../time-picker/locale/mn_MN'; import Calendar from '../calendar/locale/mn_MN'; +import type { Locale } from '../locale-provider'; -export default { +const localeValues: Locale = { locale: 'mn-mn', Pagination, DatePicker, @@ -41,3 +42,5 @@ export default { description: 'Мэдээлэл байхгүй байна', }, }; + +export default localeValues; diff --git a/components/locale/ms_MY.ts b/components/locale/ms_MY.tsx similarity index 92% rename from components/locale/ms_MY.ts rename to components/locale/ms_MY.tsx index 9a42b1e83..c301c923d 100644 --- a/components/locale/ms_MY.ts +++ b/components/locale/ms_MY.tsx @@ -2,8 +2,9 @@ import Pagination from '../vc-pagination/locale/ms_MY'; import DatePicker from '../date-picker/locale/ms_MY'; import TimePicker from '../time-picker/locale/ms_MY'; import Calendar from '../calendar/locale/ms_MY'; +import type { Locale } from '../locale-provider'; -export default { +const localeValues: Locale = { locale: 'ms-my', Pagination, DatePicker, @@ -61,3 +62,5 @@ export default { downloadFile: 'Muat turun fail', }, }; + +export default localeValues; diff --git a/components/locale/nb_NO.ts b/components/locale/nb_NO.ts deleted file mode 100644 index 83d246625..000000000 --- a/components/locale/nb_NO.ts +++ /dev/null @@ -1,43 +0,0 @@ -import Pagination from '../vc-pagination/locale/nb_NO'; -import DatePicker from '../date-picker/locale/nb_NO'; -import TimePicker from '../time-picker/locale/nb_NO'; -import Calendar from '../calendar/locale/nb_NO'; - -export default { - locale: 'nb', - DatePicker, - TimePicker, - Calendar, - Pagination, - Table: { - filterTitle: 'Filtermeny', - filterConfirm: 'OK', - filterReset: 'Nullstill', - selectAll: 'Velg alle', - selectInvert: 'Inverter valg', - }, - Modal: { - okText: 'OK', - cancelText: 'Avbryt', - justOkText: 'OK', - }, - Popconfirm: { - okText: 'OK', - cancelText: 'Avbryt', - }, - Transfer: { - searchPlaceholder: 'Søk her', - itemUnit: 'element', - itemsUnit: 'elementer', - }, - Upload: { - uploading: 'Laster opp...', - removeFile: 'Fjern fil', - uploadError: 'Feil ved opplastning', - previewFile: 'Forhåndsvisning', - downloadFile: 'Last ned fil', - }, - Empty: { - description: 'Ingen data', - }, -}; diff --git a/components/locale/nb_NO.tsx b/components/locale/nb_NO.tsx new file mode 100644 index 000000000..fb90879ac --- /dev/null +++ b/components/locale/nb_NO.tsx @@ -0,0 +1,128 @@ +/* eslint-disable no-template-curly-in-string */ +import Pagination from '../vc-pagination/locale/nb_NO'; +import DatePicker from '../date-picker/locale/nb_NO'; +import TimePicker from '../time-picker/locale/nb_NO'; +import Calendar from '../calendar/locale/nb_NO'; +import type { Locale } from '../locale-provider'; + +const typeTemplate = '${label} er ikke et gyldig ${type}'; + +const localeValues: Locale = { + locale: 'nb', + Pagination, + DatePicker, + TimePicker, + Calendar, + global: { + placeholder: 'Vennligst velg', + }, + Table: { + filterTitle: 'Filtermeny', + filterConfirm: 'OK', + filterReset: 'Nullstill', + filterEmptyText: 'Ingen filtre', + selectAll: 'Velg alle', + selectInvert: 'Inverter gjeldende side', + selectionAll: 'Velg all data', + sortTitle: 'Sorter', + expand: 'Utvid rad', + collapse: 'Skjul rad', + triggerDesc: 'Sorter data i synkende rekkefølge', + triggerAsc: 'Sorterer data i stigende rekkefølge', + cancelSort: 'Klikk for å avbryte sorteringen', + }, + Modal: { + okText: 'OK', + cancelText: 'Avbryt', + justOkText: 'OK', + }, + Popconfirm: { + okText: 'OK', + cancelText: 'Avbryt', + }, + Transfer: { + titles: ['', ''], + searchPlaceholder: 'Søk her', + itemUnit: 'element', + itemsUnit: 'elementer', + remove: 'Fjern', + selectCurrent: 'Velg gjeldende side', + removeCurrent: 'Fjern gjeldende side', + selectAll: 'Velg all data', + removeAll: 'Fjern all data', + selectInvert: 'Inverter gjeldende side', + }, + Upload: { + uploading: 'Laster opp...', + removeFile: 'Fjern fil', + uploadError: 'Feil ved opplastning', + previewFile: 'Forhåndsvisning', + downloadFile: 'Last ned fil', + }, + Empty: { + description: 'Ingen data', + }, + Icon: { + icon: 'ikon', + }, + Text: { + edit: 'Rediger', + copy: 'Kopier', + copied: 'Kopiert', + expand: 'Utvid', + }, + PageHeader: { + back: 'Tilbake', + }, + Form: { + defaultValidateMessages: { + default: 'Feltvalideringsfeil ${label}', + required: 'Vennligst skriv inn ${label}', + enum: '${label} må være en av [${enum}]', + whitespace: '${label} kan ikke være et blankt tegn', + date: { + format: '${label} datoformatet er ugyldig', + parse: '${label} kan ikke konverteres til en dato', + invalid: '${label} er en ugyldig dato', + }, + types: { + string: typeTemplate, + method: typeTemplate, + array: typeTemplate, + object: typeTemplate, + number: typeTemplate, + date: typeTemplate, + boolean: typeTemplate, + integer: typeTemplate, + float: typeTemplate, + regexp: typeTemplate, + email: typeTemplate, + url: typeTemplate, + hex: typeTemplate, + }, + string: { + len: '${label} må være ${len} tegn', + min: '${label} må minst ha ${min} tegn', + max: '${label} opp til ${max} tegn', + range: '${label} må være mellom ${min}-${max} tegn', + }, + number: { + len: '${label} må være lik ${len}', + min: '${label} minimumsverdien er ${min}', + max: '${label} maksimumsverdien er ${max}', + range: '${label} må være mellom ${min}-${max}', + }, + array: { + len: 'Må være ${len} ${label}', + min: 'Må være minst ${min} ${label}', + max: 'På det meste ${max} ${label}', + range: 'Totalt av ${label} må være mellom ${min}-${max}', + }, + pattern: { + mismatch: '${label} stemmer ikke overens med mønsteret ${pattern}', + }, + }, + }, +}; + +export default localeValues; diff --git a/components/locale/ne_NP.ts b/components/locale/ne_NP.tsx similarity index 92% rename from components/locale/ne_NP.ts rename to components/locale/ne_NP.tsx index bedd096e6..a7553e074 100644 --- a/components/locale/ne_NP.ts +++ b/components/locale/ne_NP.tsx @@ -2,8 +2,9 @@ import Pagination from '../vc-pagination/locale/en_US'; import DatePicker from '../date-picker/locale/en_US'; import TimePicker from '../time-picker/locale/en_US'; import Calendar from '../calendar/locale/en_US'; +import type { Locale } from '../locale-provider'; -export default { +const localeValues: Locale = { locale: 'ne-np', Pagination, DatePicker, @@ -42,3 +43,5 @@ export default { description: 'डाटा छैन', }, }; + +export default localeValues; diff --git a/components/locale/nl_BE.ts b/components/locale/nl_BE.ts deleted file mode 100644 index cc2d5c825..000000000 --- a/components/locale/nl_BE.ts +++ /dev/null @@ -1,43 +0,0 @@ -import Pagination from '../vc-pagination/locale/nl_BE'; -import DatePicker from '../date-picker/locale/nl_BE'; -import TimePicker from '../time-picker/locale/nl_BE'; -import Calendar from '../calendar/locale/nl_BE'; - -export default { - locale: 'nl-be', - Pagination, - DatePicker, - TimePicker, - Calendar, - Table: { - filterTitle: 'FilterMenu', - filterConfirm: 'OK', - filterReset: 'Reset', - selectAll: 'Selecteer huidige pagina', - selectInvert: 'Selecteer huidige pagina', - }, - Modal: { - okText: 'OK', - cancelText: 'Annuleer', - justOkText: 'OK', - }, - Popconfirm: { - okText: 'OK', - cancelText: 'Annuleer', - }, - Transfer: { - searchPlaceholder: 'Zoek hier', - itemUnit: 'item', - itemsUnit: 'items', - }, - Upload: { - uploading: 'Uploaden...', - removeFile: 'Bestand verwijderen', - uploadError: 'Upload fout', - previewFile: 'Preview bestand', - downloadFile: 'Download bestand', - }, - Empty: { - description: 'Geen gegevens', - }, -}; diff --git a/components/locale/nl_BE.tsx b/components/locale/nl_BE.tsx new file mode 100644 index 000000000..0172a9aa5 --- /dev/null +++ b/components/locale/nl_BE.tsx @@ -0,0 +1,134 @@ +/* eslint-disable no-template-curly-in-string */ +import Pagination from '../vc-pagination/locale/nl_BE'; +import DatePicker from '../date-picker/locale/nl_BE'; +import TimePicker from '../time-picker/locale/nl_BE'; +import Calendar from '../calendar/locale/nl_BE'; +import type { Locale } from '../locale-provider'; + +const typeTemplate = '${label} is geen geldige ${type}'; + +const localeValues: Locale = { + locale: 'nl-be', + Pagination, + DatePicker, + TimePicker, + Calendar, + global: { + placeholder: 'Maak een selectie', + }, + Table: { + cancelSort: 'Klik om sortering te annuleren', + collapse: 'Rij inklappen', + emptyText: 'Geen data', + expand: 'Rij uitklappen', + filterConfirm: 'OK', + filterEmptyText: 'Geen filters', + filterReset: 'Reset', + filterTitle: 'Filteren', + selectAll: 'Selecteer huidige pagina', + selectInvert: 'Keer volgorde om', + selectNone: 'Maak selectie leeg', + selectionAll: 'Selecteer alle data', + sortTitle: 'Sorteren', + triggerAsc: 'Klik om oplopend te sorteren', + triggerDesc: 'Klik om aflopend te sorteren', + }, + Modal: { + okText: 'OK', + cancelText: 'Annuleer', + justOkText: 'OK', + }, + Popconfirm: { + okText: 'OK', + cancelText: 'Annuleer', + }, + Transfer: { + itemUnit: 'item', + itemsUnit: 'items', + remove: 'Verwijder', + removeAll: 'Verwijder alles', + removeCurrent: 'Verwijder huidige pagina', + searchPlaceholder: 'Zoek hier', + selectAll: 'Selecteer alles', + selectCurrent: 'Selecteer huidige pagina', + selectInvert: 'Huidige pagina omkeren', + titles: ['', ''], + }, + Upload: { + downloadFile: 'Bestand downloaden', + previewFile: 'Preview file', + removeFile: 'Verwijder bestand', + uploadError: 'Fout tijdens uploaden', + uploading: 'Uploaden...', + }, + Empty: { + description: 'Geen gegevens', + }, + Icon: { + icon: 'icoon', + }, + Text: { + edit: 'Bewerken', + copy: 'kopiëren', + copied: 'Gekopieerd', + expand: 'Uitklappen', + }, + PageHeader: { + back: 'Terug', + }, + Form: { + optional: '(optioneel)', + defaultValidateMessages: { + default: 'Validatiefout voor ${label}', + required: 'Gelieve ${label} in te vullen', + enum: '${label} moet één van [${enum}] zijn', + whitespace: '${label} mag geen blanco teken zijn', + date: { + format: '${label} heeft een ongeldig formaat', + parse: '${label} kan niet naar een datum omgezet worden', + invalid: '${label} is een ongeldige datum', + }, + types: { + string: typeTemplate, + method: typeTemplate, + array: typeTemplate, + object: typeTemplate, + number: typeTemplate, + date: typeTemplate, + boolean: typeTemplate, + integer: typeTemplate, + float: typeTemplate, + regexp: typeTemplate, + email: typeTemplate, + url: typeTemplate, + hex: typeTemplate, + }, + string: { + len: '${label} moet ${len} karakters lang zijn', + min: '${label} moet minimaal ${min} karakters lang zijn', + max: '${label} mag maximaal ${max} karakters lang zijn', + range: '${label} moet tussen ${min}-${max} karakters lang zijn', + }, + number: { + len: '${label} moet gelijk zijn aan ${len}', + min: '${label} moet minimaal ${min} zijn', + max: '${label} mag maximaal ${max} zijn', + range: '${label} moet tussen ${min}-${max} liggen', + }, + array: { + len: 'Moeten ${len} ${label} zijn', + min: 'Minimaal ${min} ${label}', + max: 'maximaal ${max} ${label}', + range: 'Het aantal ${label} moet tussen ${min}-${max} liggen', + }, + pattern: { + mismatch: '${label} komt niet overeen met het patroon ${pattern}', + }, + }, + }, + Image: { + preview: 'Voorbeeld', + }, +}; + +export default localeValues; diff --git a/components/locale/nl_NL.ts b/components/locale/nl_NL.ts deleted file mode 100644 index 773d5068a..000000000 --- a/components/locale/nl_NL.ts +++ /dev/null @@ -1,62 +0,0 @@ -import Pagination from '../vc-pagination/locale/nl_NL'; -import DatePicker from '../date-picker/locale/nl_NL'; -import TimePicker from '../time-picker/locale/nl_NL'; -import Calendar from '../calendar/locale/nl_NL'; - -export default { - locale: 'nl', - Pagination, - DatePicker, - TimePicker, - Calendar, - global: { - placeholder: 'Maak een selectie', - }, - Table: { - filterTitle: 'Filteren', - filterConfirm: 'OK', - filterReset: 'Reset', - selectAll: 'Selecteer huidige pagina', - selectInvert: 'Deselecteer huidige pagina', - sortTitle: 'Sorteren', - expand: 'Rij uitklappen', - collapse: 'Rij inklappen', - }, - Modal: { - okText: 'OK', - cancelText: 'Annuleren', - justOkText: 'OK', - }, - Popconfirm: { - okText: 'OK', - cancelText: 'Annuleren', - }, - Transfer: { - titles: ['', ''], - searchPlaceholder: 'Zoeken', - itemUnit: 'item', - itemsUnit: 'items', - }, - Upload: { - uploading: 'Uploaden...', - removeFile: 'Verwijder bestand', - uploadError: 'Fout tijdens uploaden', - previewFile: 'Bekijk bestand', - downloadFile: 'Downloaden bestand', - }, - Empty: { - description: 'Geen gegevens', - }, - Icon: { - icon: 'icoon', - }, - Text: { - edit: 'Bewerken', - copy: 'Kopieren', - copied: 'Gekopieerd', - expand: 'Uitklappen', - }, - PageHeader: { - back: 'Terug', - }, -}; diff --git a/components/locale/nl_NL.tsx b/components/locale/nl_NL.tsx new file mode 100644 index 000000000..64d261b61 --- /dev/null +++ b/components/locale/nl_NL.tsx @@ -0,0 +1,134 @@ +/* eslint-disable no-template-curly-in-string */ +import Pagination from '../vc-pagination/locale/nl_NL'; +import DatePicker from '../date-picker/locale/nl_NL'; +import TimePicker from '../time-picker/locale/nl_NL'; +import Calendar from '../calendar/locale/nl_NL'; +import type { Locale } from '../locale-provider'; + +const typeTemplate = '${label} is geen geldige ${type}'; + +const localeValues: Locale = { + locale: 'nl', + Pagination, + DatePicker, + TimePicker, + Calendar, + global: { + placeholder: 'Maak een selectie', + }, + Table: { + cancelSort: 'Klik om sortering te annuleren', + collapse: 'Rij inklappen', + emptyText: 'Geen data', + expand: 'Rij uitklappen', + filterConfirm: 'OK', + filterEmptyText: 'Geen filters', + filterReset: 'Reset', + filterTitle: 'Filteren', + selectAll: 'Selecteer huidige pagina', + selectInvert: 'Keer volgorde om', + selectNone: 'Maak selectie leeg', + selectionAll: 'Selecteer alle data', + sortTitle: 'Sorteren', + triggerAsc: 'Klik om oplopend te sorteren', + triggerDesc: 'Klik om aflopend te sorteren', + }, + Modal: { + okText: 'OK', + cancelText: 'Annuleer', + justOkText: 'OK', + }, + Popconfirm: { + okText: 'OK', + cancelText: 'Annuleer', + }, + Transfer: { + itemUnit: 'item', + itemsUnit: 'items', + remove: 'Verwijder', + removeAll: 'Verwijder alles', + removeCurrent: 'Verwijder huidige pagina', + searchPlaceholder: 'Zoek hier', + selectAll: 'Selecteer alles', + selectCurrent: 'Selecteer huidige pagina', + selectInvert: 'Huidige pagina omkeren', + titles: ['', ''], + }, + Upload: { + downloadFile: 'Bestand downloaden', + previewFile: 'Preview file', + removeFile: 'Verwijder bestand', + uploadError: 'Fout tijdens uploaden', + uploading: 'Uploaden...', + }, + Empty: { + description: 'Geen gegevens', + }, + Icon: { + icon: 'icoon', + }, + Text: { + edit: 'Bewerken', + copy: 'kopiëren', + copied: 'Gekopieerd', + expand: 'Uitklappen', + }, + PageHeader: { + back: 'Terug', + }, + Form: { + optional: '(optioneel)', + defaultValidateMessages: { + default: 'Validatiefout voor ${label}', + required: 'Gelieve ${label} in te vullen', + enum: '${label} moet één van [${enum}] zijn', + whitespace: '${label} mag geen blanco teken zijn', + date: { + format: '${label} heeft een ongeldig formaat', + parse: '${label} kan niet naar een datum omgezet worden', + invalid: '${label} is een ongeldige datum', + }, + types: { + string: typeTemplate, + method: typeTemplate, + array: typeTemplate, + object: typeTemplate, + number: typeTemplate, + date: typeTemplate, + boolean: typeTemplate, + integer: typeTemplate, + float: typeTemplate, + regexp: typeTemplate, + email: typeTemplate, + url: typeTemplate, + hex: typeTemplate, + }, + string: { + len: '${label} moet ${len} karakters lang zijn', + min: '${label} moet minimaal ${min} karakters lang zijn', + max: '${label} mag maximaal ${max} karakters lang zijn', + range: '${label} moet tussen ${min}-${max} karakters lang zijn', + }, + number: { + len: '${label} moet gelijk zijn aan ${len}', + min: '${label} moet minimaal ${min} zijn', + max: '${label} mag maximaal ${max} zijn', + range: '${label} moet tussen ${min}-${max} liggen', + }, + array: { + len: 'Moeten ${len} ${label} zijn', + min: 'Minimaal ${min} ${label}', + max: 'maximaal ${max} ${label}', + range: 'Het aantal ${label} moet tussen ${min}-${max} liggen', + }, + pattern: { + mismatch: '${label} komt niet overeen met het patroon ${pattern}', + }, + }, + }, + Image: { + preview: 'Voorbeeld', + }, +}; + +export default localeValues; diff --git a/components/locale/pl_PL.ts b/components/locale/pl_PL.tsx similarity index 81% rename from components/locale/pl_PL.ts rename to components/locale/pl_PL.tsx index c5da9e9ba..278326df8 100644 --- a/components/locale/pl_PL.ts +++ b/components/locale/pl_PL.tsx @@ -2,8 +2,9 @@ import Pagination from '../vc-pagination/locale/pl_PL'; import DatePicker from '../date-picker/locale/pl_PL'; import TimePicker from '../time-picker/locale/pl_PL'; import Calendar from '../calendar/locale/pl_PL'; +import type { Locale } from '../locale-provider'; -export default { +const localeValues: Locale = { locale: 'pl', Pagination, DatePicker, @@ -15,6 +16,9 @@ export default { filterReset: 'Wyczyść', selectAll: 'Zaznacz bieżącą stronę', selectInvert: 'Odwróć zaznaczenie', + triggerDesc: 'Sortuj malejąco', + triggerAsc: 'Sortuj rosnąco', + cancelSort: 'Usuń sortowanie', }, Modal: { okText: 'OK', @@ -41,3 +45,5 @@ export default { description: 'Brak danych', }, }; + +export default localeValues; diff --git a/components/locale/pt_BR.ts b/components/locale/pt_BR.ts deleted file mode 100644 index c50b9283a..000000000 --- a/components/locale/pt_BR.ts +++ /dev/null @@ -1,49 +0,0 @@ -import Pagination from '../vc-pagination/locale/pt_BR'; -import DatePicker from '../date-picker/locale/pt_BR'; -import TimePicker from '../time-picker/locale/pt_BR'; -import Calendar from '../calendar/locale/pt_BR'; - -export default { - locale: 'pt-br', - Pagination, - DatePicker, - TimePicker, - Calendar, - Table: { - filterTitle: 'Filtro', - filterConfirm: 'OK', - filterReset: 'Resetar', - selectAll: 'Selecionar página atual', - selectInvert: 'Inverter seleção', - }, - Modal: { - okText: 'OK', - cancelText: 'Cancelar', - justOkText: 'OK', - }, - Popconfirm: { - okText: 'OK', - cancelText: 'Cancelar', - }, - Transfer: { - searchPlaceholder: 'Procurar', - itemUnit: 'item', - itemsUnit: 'items', - }, - Upload: { - uploading: 'Enviando...', - removeFile: 'Remover arquivo', - uploadError: 'Erro no envio', - previewFile: 'Visualizar arquivo', - downloadFile: 'Baixar arquivo', - }, - Empty: { - description: 'Não há dados', - }, - Text: { - edit: 'editar', - copy: 'copiar', - copied: 'copiado', - expand: 'expandir', - }, -}; diff --git a/components/locale/pt_BR.tsx b/components/locale/pt_BR.tsx new file mode 100644 index 000000000..ec779f0cb --- /dev/null +++ b/components/locale/pt_BR.tsx @@ -0,0 +1,134 @@ +/* eslint-disable no-template-curly-in-string */ +import Pagination from '../vc-pagination/locale/pt_BR'; +import DatePicker from '../date-picker/locale/pt_BR'; +import TimePicker from '../time-picker/locale/pt_BR'; +import Calendar from '../calendar/locale/pt_BR'; +import type { Locale } from '../locale-provider'; + +const typeTemplate = '${label} não é um ${type} válido'; + +const localeValues: Locale = { + locale: 'pt-br', + Pagination, + DatePicker, + TimePicker, + Calendar, + global: { + placeholder: 'Por favor escolha', + }, + Table: { + filterTitle: 'Menu de Filtro', + filterConfirm: 'OK', + filterReset: 'Resetar', + filterEmptyText: 'Sem filtros', + emptyText: 'Sem conteúdo', + selectAll: 'Selecionar página atual', + selectInvert: 'Inverter seleção', + selectNone: 'Apagar todo o conteúdo', + selectionAll: 'Selecionar todo o conteúdo', + sortTitle: 'Ordenar título', + expand: 'Expandir linha', + collapse: 'Colapsar linha', + triggerDesc: 'Clique organiza por descendente', + triggerAsc: 'Clique organiza por ascendente', + cancelSort: 'Clique para cancelar organização', + }, + Modal: { + okText: 'OK', + cancelText: 'Cancelar', + justOkText: 'OK', + }, + Popconfirm: { + okText: 'OK', + cancelText: 'Cancelar', + }, + Transfer: { + titles: ['', ''], + searchPlaceholder: 'Procurar', + itemUnit: 'item', + itemsUnit: 'items', + remove: 'Remover', + selectCurrent: 'Selecionar página atual', + removeCurrent: 'Remover página atual', + selectAll: 'Selecionar todos', + removeAll: 'Remover todos', + selectInvert: 'Inverter seleção atual', + }, + Upload: { + uploading: 'Enviando...', + removeFile: 'Remover arquivo', + uploadError: 'Erro no envio', + previewFile: 'Visualizar arquivo', + downloadFile: 'Baixar arquivo', + }, + Empty: { + description: 'Não há dados', + }, + Icon: { + icon: 'ícone', + }, + Text: { + edit: 'editar', + copy: 'copiar', + copied: 'copiado', + expand: 'expandir', + }, + PageHeader: { + back: 'Retornar', + }, + Form: { + optional: '(opcional)', + defaultValidateMessages: { + default: 'Erro ${label} na validação de campo', + required: 'Por favor, insira ${label}', + enum: '${label} deve ser um dos seguinte: [${enum}]', + whitespace: '${label} não pode ser um carácter vazio', + date: { + format: ' O formato de data ${label} é inválido', + parse: '${label} não pode ser convertido para uma data', + invalid: '${label} é uma data inválida', + }, + types: { + string: typeTemplate, + method: typeTemplate, + array: typeTemplate, + object: typeTemplate, + number: typeTemplate, + date: typeTemplate, + boolean: typeTemplate, + integer: typeTemplate, + float: typeTemplate, + regexp: typeTemplate, + email: typeTemplate, + url: typeTemplate, + hex: typeTemplate, + }, + string: { + len: '${label} deve possuir ${len} caracteres', + min: '${label} deve possuir ao menos ${min} caracteres', + max: '${label} deve possuir no máximo ${max} caracteres', + range: '${label} deve possuir entre ${min} e ${max} caracteres', + }, + number: { + len: '${label} deve ser igual à ${len}', + min: 'O valor mínimo de ${label} é ${min}', + max: 'O valor máximo de ${label} é ${max}', + range: '${label} deve estar entre ${min} e ${max}', + }, + array: { + len: 'Deve ser ${len} ${label}', + min: 'No mínimo ${min} ${label}', + max: 'No máximo ${max} ${label}', + range: 'A quantidade de ${label} deve estar entre ${min} e ${max}', + }, + pattern: { + mismatch: '${label} não se encaixa no padrão ${pattern}', + }, + }, + }, + Image: { + preview: 'Pré-visualização', + }, +}; + +export default localeValues; diff --git a/components/locale/pt_PT.ts b/components/locale/pt_PT.tsx similarity index 89% rename from components/locale/pt_PT.ts rename to components/locale/pt_PT.tsx index 89deec39b..a91bf0a8a 100644 --- a/components/locale/pt_PT.ts +++ b/components/locale/pt_PT.tsx @@ -2,8 +2,9 @@ import Pagination from '../vc-pagination/locale/pt_PT'; import DatePicker from '../date-picker/locale/pt_PT'; import TimePicker from '../time-picker/locale/pt_PT'; import Calendar from '../calendar/locale/pt_PT'; +import type { Locale } from '../locale-provider'; -export default { +const localeValues: Locale = { locale: 'pt', Pagination, DatePicker, @@ -42,3 +43,5 @@ export default { description: 'Sem resultados', }, }; + +export default localeValues; diff --git a/components/locale/ro_RO.ts b/components/locale/ro_RO.ts deleted file mode 100644 index eec391c0e..000000000 --- a/components/locale/ro_RO.ts +++ /dev/null @@ -1,62 +0,0 @@ -import Pagination from '../vc-pagination/locale/ro_RO'; -import DatePicker from '../date-picker/locale/ro_RO'; -import TimePicker from '../time-picker/locale/ro_RO'; -import Calendar from '../calendar/locale/ro_RO'; - -export default { - locale: 'ro', - Pagination, - DatePicker, - TimePicker, - Calendar, - global: { - placeholder: 'Selectează', - }, - Table: { - filterTitle: 'Filtrează', - filterConfirm: 'OK', - filterReset: 'Resetează', - selectAll: 'Selectează pagina curentă', - selectInvert: 'Inversează pagina curentă', - sortTitle: 'Ordonează', - expand: 'Extinde rândul', - collapse: 'Micșorează rândul', - }, - Modal: { - okText: 'OK', - cancelText: 'Anulare', - justOkText: 'OK', - }, - Popconfirm: { - okText: 'OK', - cancelText: 'Anulare', - }, - Transfer: { - titles: ['', ''], - searchPlaceholder: 'Căutare', - itemUnit: 'element', - itemsUnit: 'elemente', - }, - Upload: { - uploading: 'Se transferă...', - removeFile: 'Înlătură fișierul', - uploadError: 'Eroare la upload', - previewFile: 'Previzualizare fișier', - downloadFile: 'Descărcare fișier', - }, - Empty: { - description: 'Fără date', - }, - Icon: { - icon: 'icon', - }, - Text: { - edit: 'editează', - copy: 'copiază', - copied: 'copiat', - expand: 'extinde', - }, - PageHeader: { - back: 'înapoi', - }, -}; diff --git a/components/locale/ro_RO.tsx b/components/locale/ro_RO.tsx new file mode 100644 index 000000000..281207a81 --- /dev/null +++ b/components/locale/ro_RO.tsx @@ -0,0 +1,134 @@ +/* eslint-disable no-template-curly-in-string */ +import Pagination from '../vc-pagination/locale/ro_RO'; +import DatePicker from '../date-picker/locale/ro_RO'; +import TimePicker from '../time-picker/locale/ro_RO'; +import Calendar from '../calendar/locale/ro_RO'; +import type { Locale } from '../locale-provider'; + +const typeTemplate = '${label} nu conține tipul corect (${type})'; + +const localeValues: Locale = { + locale: 'ro', + Pagination, + DatePicker, + TimePicker, + Calendar, + global: { + placeholder: 'Selectează', + }, + Table: { + filterTitle: 'Filtrează', + filterConfirm: 'OK', + filterReset: 'Resetează', + filterEmptyText: 'Fără filtre', + emptyText: 'Nu există date', + selectAll: 'Selectează pagina curentă', + selectInvert: 'Inversează pagina curentă', + selectNone: 'Șterge selecția', + selectionAll: 'Selectează toate datele', + sortTitle: 'Ordonează', + expand: 'Extinde rândul', + collapse: 'Micșorează rândul', + triggerDesc: 'Apasă pentru ordonare descrescătoare', + triggerAsc: 'Apasă pentru ordonare crescătoare', + cancelSort: 'Apasă pentru a anula ordonarea', + }, + Modal: { + okText: 'OK', + cancelText: 'Anulare', + justOkText: 'OK', + }, + Popconfirm: { + okText: 'OK', + cancelText: 'Anulare', + }, + Transfer: { + titles: ['', ''], + searchPlaceholder: 'Căutare', + itemUnit: 'element', + itemsUnit: 'elemente', + remove: 'Șterge', + selectCurrent: 'Selectează pagina curentă', + removeCurrent: 'Șterge pagina curentă', + selectAll: 'Selectează toate datele', + removeAll: 'Șterge toate datele', + selectInvert: 'Inversează pagina curentă', + }, + Upload: { + uploading: 'Se transferă...', + removeFile: 'Înlătură fișierul', + uploadError: 'Eroare la upload', + previewFile: 'Previzualizare fișier', + downloadFile: 'Descărcare fișier', + }, + Empty: { + description: 'Fără date', + }, + Icon: { + icon: 'icon', + }, + Text: { + edit: 'editează', + copy: 'copiază', + copied: 'copiat', + expand: 'extinde', + }, + PageHeader: { + back: 'înapoi', + }, + Form: { + optional: '(opțional)', + defaultValidateMessages: { + default: 'Eroare la validarea câmpului ${label}', + required: 'Vă rugăm introduceți ${label}', + enum: '${label} trebuie să fie una din valorile [${enum}]', + whitespace: '${label} nu poate fi gol', + date: { + format: '${label} - data nu este în formatul corect', + parse: '${label} nu poate fi convertit la o dată', + invalid: '${label} este o dată invalidă', + }, + types: { + string: typeTemplate, + method: typeTemplate, + array: typeTemplate, + object: typeTemplate, + number: typeTemplate, + date: typeTemplate, + boolean: typeTemplate, + integer: typeTemplate, + float: typeTemplate, + regexp: typeTemplate, + email: typeTemplate, + url: typeTemplate, + hex: typeTemplate, + }, + string: { + len: '${label} trebuie să conțină ${len} caractere', + min: '${label} trebuie să conțină cel puțin ${min} caractere', + max: '${label} trebuie să conțină cel mult ${max} caractere', + range: '${label} trebuie să conțină între ${min}-${max} caractere', + }, + number: { + len: '${label} trebuie să conțină ${len} cifre', + min: '${label} trebuie să fie minim ${min}', + max: '${label} trebuie să fie maxim ${max}', + range: '${label} trebuie să fie între ${min}-${max}', + }, + array: { + len: '${label} trebuie să conțină ${len} elemente', + min: '${label} trebuie să conțină cel puțin ${min} elemente', + max: '${label} trebuie să conțină cel mult ${max} elemente', + range: '${label} trebuie să conțină între ${min}-${max} elemente', + }, + pattern: { + mismatch: '${label} nu respectă șablonul ${pattern}', + }, + }, + }, + Image: { + preview: 'Preview', + }, +}; + +export default localeValues; diff --git a/components/locale/ru_RU.ts b/components/locale/ru_RU.ts deleted file mode 100644 index 451235a23..000000000 --- a/components/locale/ru_RU.ts +++ /dev/null @@ -1,53 +0,0 @@ -import Pagination from '../vc-pagination/locale/ru_RU'; -import DatePicker from '../date-picker/locale/ru_RU'; -import TimePicker from '../time-picker/locale/ru_RU'; -import Calendar from '../calendar/locale/ru_RU'; - -export default { - locale: 'ru', - Pagination, - DatePicker, - TimePicker, - Calendar, - Table: { - filterTitle: 'Фильтр', - filterConfirm: 'OK', - filterReset: 'Сбросить', - selectAll: 'Выбрать всё', - selectInvert: 'Инвертировать выбор', - sortTitle: 'Сортировка', - }, - Modal: { - okText: 'OK', - cancelText: 'Отмена', - justOkText: 'OK', - }, - Popconfirm: { - okText: 'OK', - cancelText: 'Отмена', - }, - Transfer: { - searchPlaceholder: 'Поиск', - itemUnit: 'элем.', - itemsUnit: 'элем.', - }, - Upload: { - uploading: 'Загрузка...', - removeFile: 'Удалить файл', - uploadError: 'При загрузке произошла ошибка', - previewFile: 'Предпросмотр файла', - downloadFile: 'Загрузить файл', - }, - Empty: { - description: 'Нет данных', - }, - Text: { - edit: 'редактировать', - copy: 'копировать', - copied: 'скопировано', - expand: 'раскрыть', - }, - PageHeader: { - back: 'назад', - }, -}; diff --git a/components/locale/ru_RU.tsx b/components/locale/ru_RU.tsx new file mode 100644 index 000000000..d57964fe5 --- /dev/null +++ b/components/locale/ru_RU.tsx @@ -0,0 +1,132 @@ +/* eslint-disable no-template-curly-in-string */ + +import Pagination from '../vc-pagination/locale/ru_RU'; +import DatePicker from '../date-picker/locale/ru_RU'; +import TimePicker from '../time-picker/locale/ru_RU'; +import Calendar from '../calendar/locale/ru_RU'; +import type { Locale } from '../locale-provider'; + +const typeTemplate = '${label} не является типом ${type}'; + +const localeValues: Locale = { + locale: 'ru', + Pagination, + DatePicker, + TimePicker, + Calendar, + global: { + placeholder: 'Пожалуйста выберите', + }, + Table: { + filterTitle: 'Фильтр', + filterConfirm: 'OK', + filterReset: 'Сбросить', + filterEmptyText: 'Без фильтров', + emptyText: 'Нет данных', + selectAll: 'Выбрать всё', + selectInvert: 'Инвертировать выбор', + selectionAll: 'Выбрать все данные', + sortTitle: 'Сортировка', + expand: 'Развернуть строку', + collapse: 'Свернуть строку', + triggerDesc: 'Нажмите для сортировки по убыванию', + triggerAsc: 'Нажмите для сортировки по возрастанию', + cancelSort: 'Нажмите, чтобы отменить сортировку', + }, + Modal: { + okText: 'OK', + cancelText: 'Отмена', + justOkText: 'OK', + }, + Popconfirm: { + okText: 'OK', + cancelText: 'Отмена', + }, + Transfer: { + titles: ['', ''], + searchPlaceholder: 'Поиск', + itemUnit: 'элем.', + itemsUnit: 'элем.', + remove: 'Удалить', + selectAll: 'Выбрать все данные', + selectCurrent: 'Выбрать текущую страницу', + selectInvert: 'Показать в обратном порядке', + removeAll: 'Удалить все данные', + removeCurrent: 'Удалить текущую страницу', + }, + Upload: { + uploading: 'Загрузка...', + removeFile: 'Удалить файл', + uploadError: 'При загрузке произошла ошибка', + previewFile: 'Предпросмотр файла', + downloadFile: 'Загрузить файл', + }, + Empty: { + description: 'Нет данных', + }, + Icon: { + icon: 'иконка', + }, + Text: { + edit: 'Редактировать', + copy: 'Копировать', + copied: 'Скопировано', + expand: 'Раскрыть', + }, + PageHeader: { + back: 'Назад', + }, + Form: { + defaultValidateMessages: { + default: 'Ошибка проверки поля ${label}', + required: 'Пожалуйста, введите ${label}', + enum: '${label} должен быть одним из [${enum}]', + whitespace: '${label} не может быть пустым', + date: { + format: '${label} не правильный формат даты', + parse: '${label} не может быть преобразовано в дату', + invalid: '${label} не является корректной датой', + }, + types: { + string: typeTemplate, + method: typeTemplate, + array: typeTemplate, + object: typeTemplate, + number: typeTemplate, + date: typeTemplate, + boolean: typeTemplate, + integer: typeTemplate, + float: typeTemplate, + regexp: typeTemplate, + email: typeTemplate, + url: typeTemplate, + hex: typeTemplate, + }, + string: { + len: '${label} должна быть ${len} символов', + min: '${label} должна быть больше или равна ${min} символов', + max: '${label} должна быть меньше или равна ${max} символов', + range: 'Длина ${label} должна быть между ${min}-${max} символами', + }, + number: { + len: '${label} должна быть равна ${len}', + min: '${label} должна быть больше или равна ${min}', + max: '${label} должна быть меньше или равна ${max}', + }, + array: { + len: 'Количество элементов ${label} должно быть равно ${len}', + min: 'Количество элементов ${label} должно быть больше или равно ${min}', + max: 'Количество элементов ${label} должно быть меньше или равно ${max}', + range: 'Количество элементов ${label} должно быть между ${min} и ${max}', + }, + pattern: { + mismatch: '${label} не соответствует шаблону ${pattern}', + }, + }, + }, + Image: { + preview: 'Превью', + }, +}; + +export default localeValues; diff --git a/components/locale/sk_SK.ts b/components/locale/sk_SK.tsx similarity index 92% rename from components/locale/sk_SK.ts rename to components/locale/sk_SK.tsx index fd3e67226..3d7aee58b 100644 --- a/components/locale/sk_SK.ts +++ b/components/locale/sk_SK.tsx @@ -2,8 +2,9 @@ import Pagination from '../vc-pagination/locale/sk_SK'; import DatePicker from '../date-picker/locale/sk_SK'; import TimePicker from '../time-picker/locale/sk_SK'; import Calendar from '../calendar/locale/sk_SK'; +import type { Locale } from '../locale-provider'; -export default { +const localeValues: Locale = { locale: 'sk', Pagination, DatePicker, @@ -60,3 +61,5 @@ export default { back: 'Späť', }, }; + +export default localeValues; diff --git a/components/locale/sl_SI.ts b/components/locale/sl_SI.tsx similarity index 90% rename from components/locale/sl_SI.ts rename to components/locale/sl_SI.tsx index afbbde48c..b651af612 100644 --- a/components/locale/sl_SI.ts +++ b/components/locale/sl_SI.tsx @@ -2,8 +2,9 @@ import Pagination from '../vc-pagination/locale/sl_SI'; import DatePicker from '../date-picker/locale/sl_SI'; import TimePicker from '../time-picker/locale/sl_SI'; import Calendar from '../calendar/locale/sl_SI'; +import type { Locale } from '../locale-provider'; -export default { +const localeValues: Locale = { locale: 'sl', Pagination, DatePicker, @@ -41,3 +42,5 @@ export default { description: 'Ni podatkov', }, }; + +export default localeValues; diff --git a/components/locale/sr_RS.ts b/components/locale/sr_RS.ts deleted file mode 100644 index 0cdda61b0..000000000 --- a/components/locale/sr_RS.ts +++ /dev/null @@ -1,43 +0,0 @@ -import Pagination from '../vc-pagination/locale/sr_RS'; -import DatePicker from '../date-picker/locale/sr_RS'; -import TimePicker from '../time-picker/locale/sr_RS'; -import Calendar from '../calendar/locale/sr_RS'; - -export default { - locale: 'sr', - Pagination, - DatePicker, - TimePicker, - Calendar, - Table: { - filterTitle: 'Filter', - filterConfirm: 'Primeni filter', - filterReset: 'Resetuj filter', - selectAll: 'Obeleži sve na trenutnoj strani', - selectInvert: 'Obrni selekciju na trenutnoj stranici', - }, - Modal: { - okText: 'U redu', - cancelText: 'Otkaži', - justOkText: 'U redu', - }, - Popconfirm: { - okText: 'U redu', - cancelText: 'Otkaži', - }, - Transfer: { - searchPlaceholder: 'Pretražite ovde', - itemUnit: 'stavka', - itemsUnit: 'stavki', - }, - Upload: { - uploading: 'Slanje...', - removeFile: 'Ukloni fajl', - uploadError: 'Greška prilikom slanja', - previewFile: 'Pogledaj fajl', - downloadFile: 'Preuzmi datoteku', - }, - Empty: { - description: 'Nema podataka', - }, -}; diff --git a/components/locale/sr_RS.tsx b/components/locale/sr_RS.tsx new file mode 100644 index 000000000..715f2dfa5 --- /dev/null +++ b/components/locale/sr_RS.tsx @@ -0,0 +1,134 @@ +/* eslint-disable no-template-curly-in-string */ +import Pagination from '../vc-pagination/locale/sr_RS'; +import DatePicker from '../date-picker/locale/sr_RS'; +import TimePicker from '../time-picker/locale/sr_RS'; +import Calendar from '../calendar/locale/sr_RS'; +import type { Locale } from '../locale-provider'; + +const typeTemplate = '${label} nije važeći ${type}'; + +const localeValues: Locale = { + locale: 'sr', + Pagination, + DatePicker, + TimePicker, + Calendar, + global: { + placeholder: 'Izaberi', + }, + Table: { + filterTitle: 'Meni filtera', + filterConfirm: 'U redu', + filterReset: 'Poništi', + filterEmptyText: 'Nema filtera', + emptyText: 'Nema podataka', + selectAll: 'Izaberi trenutnu stranicu', + selectInvert: 'Obrni izbor trenutne stranice', + selectNone: 'Obriši sve podatke', + selectionAll: 'Izaberi sve podatke', + sortTitle: 'Sortiraj', + expand: 'Proširi red', + collapse: 'Skupi red', + triggerDesc: 'Klikni da sortiraš po padajućem redosledu', + triggerAsc: 'Klikni da sortiraš po rastućem redosledu', + cancelSort: 'Klikni da otkažeš sortiranje', + }, + Modal: { + okText: 'U redu', + cancelText: 'Otkaži', + justOkText: 'U redu', + }, + Popconfirm: { + okText: 'U redu', + cancelText: 'Otkaži', + }, + Transfer: { + titles: ['', ''], + searchPlaceholder: 'Pretraži ovde', + itemUnit: 'stavka', + itemsUnit: 'stavki', + remove: 'Ukloni', + selectCurrent: 'Izaberi trenutnu stranicu', + removeCurrent: 'Ukloni trenutnu stranicu', + selectAll: 'Izaberi sve podatke', + removeAll: 'Ukloni sve podatke', + selectInvert: 'Obrni izbor trenutne stranice', + }, + Upload: { + uploading: 'Otpremanje...', + removeFile: 'Ukloni datoteku', + uploadError: 'Greška pri otpremanju', + previewFile: 'Pregledaj datoteku', + downloadFile: 'Preuzmi datoteku', + }, + Empty: { + description: 'Nema podataka', + }, + Icon: { + icon: 'ikona', + }, + Text: { + edit: 'Uredi', + copy: 'Kopiraj', + copied: 'Kopirano', + expand: 'Proširi', + }, + PageHeader: { + back: 'Nazad', + }, + Form: { + optional: '(opcionalno)', + defaultValidateMessages: { + default: 'Greška pri proveri valjanosti za ${label}', + required: 'Unesi ${label}', + enum: '${label} mora da bude nešto od [${enum}]', + whitespace: '${label} ne može biti prazan znak', + date: { + format: '${label} format datuma je nevažeći', + parse: '${label} se ne može konvertovati u datum', + invalid: '${label} je nevažeći datum', + }, + types: { + string: typeTemplate, + method: typeTemplate, + array: typeTemplate, + object: typeTemplate, + number: typeTemplate, + date: typeTemplate, + boolean: typeTemplate, + integer: typeTemplate, + float: typeTemplate, + regexp: typeTemplate, + email: typeTemplate, + url: typeTemplate, + hex: typeTemplate, + }, + string: { + len: '${label} mora da sadrži ${len} znakova', + min: '${label} mora da sadrži bar ${min} znakova', + max: '${label} mora da sadrži do ${max} znakova', + range: '${label} mora da sadrži između ${min} i ${max} znakova', + }, + number: { + len: '${label} mora biti jednak ${len}', + min: '${label} mora biti najmanje ${min}', + max: '${label} mora biti najviše ${max}', + range: '${label} mora biti između ${min} i ${max}', + }, + array: { + len: 'Mora biti ${len} ${label}', + min: 'Najmanje ${min} ${label}', + max: 'najviše ${max} ${label}', + range: 'Iznos ${label} mora biti između ${min} i ${max}', + }, + pattern: { + mismatch: '${label} ne odgovara obrascu ${pattern}', + }, + }, + }, + Image: { + preview: 'Pregled', + }, +}; + +export default localeValues; diff --git a/components/locale/sv_SE.ts b/components/locale/sv_SE.ts deleted file mode 100644 index 48340c593..000000000 --- a/components/locale/sv_SE.ts +++ /dev/null @@ -1,47 +0,0 @@ -import Pagination from '../vc-pagination/locale/sv_SE'; -import DatePicker from '../date-picker/locale/sv_SE'; -import TimePicker from '../time-picker/locale/sv_SE'; -import Calendar from '../calendar/locale/sv_SE'; - -export default { - locale: 'sv', - Pagination, - DatePicker, - TimePicker, - Calendar, - Table: { - filterTitle: 'Filtermeny', - filterConfirm: 'OK', - filterReset: 'Rensa', - }, - Modal: { - okText: 'OK', - cancelText: 'Avbryt', - justOkText: 'OK', - }, - Popconfirm: { - okText: 'OK', - cancelText: 'Avbryt', - }, - Transfer: { - searchPlaceholder: 'Sök', - itemUnit: 'element', - itemsUnit: 'element', - }, - Empty: { - description: 'Ingen information', - }, - Text: { - edit: 'editera', - copy: 'kopiera', - copied: 'kopierad', - expand: 'expandera', - }, - Upload: { - uploading: 'Uppladdning...', - removeFile: 'Ta bort fil', - uploadError: 'Uppladdningsfel', - previewFile: 'Förhandsgranska filen', - downloadFile: 'Nedladdning fil', - }, -}; diff --git a/components/locale/sv_SE.tsx b/components/locale/sv_SE.tsx new file mode 100644 index 000000000..001c23e50 --- /dev/null +++ b/components/locale/sv_SE.tsx @@ -0,0 +1,134 @@ +/* eslint-disable no-template-curly-in-string */ +import Pagination from '../vc-pagination/locale/sv_SE'; +import DatePicker from '../date-picker/locale/sv_SE'; +import TimePicker from '../time-picker/locale/sv_SE'; +import Calendar from '../calendar/locale/sv_SE'; +import type { Locale } from '../locale-provider'; + +const typeTemplate = '${label} är inte en giltig ${type}'; + +const localeValues: Locale = { + locale: 'sv', + Pagination, + DatePicker, + TimePicker, + Calendar, + global: { + placeholder: 'Vänligen välj', + }, + Table: { + filterTitle: 'Filtermeny', + filterConfirm: 'OK', + filterReset: 'Återställ', + filterEmptyText: 'Inga filter', + emptyText: 'Ingen data', + selectAll: 'Markera nuvarande sida', + selectInvert: 'Invertera nuvarande sida', + selectNone: 'Avmarkera all data', + selectionAll: 'Markera all data', + sortTitle: 'Sortera', + expand: 'Expandera rad', + collapse: 'Komprimera rad', + triggerDesc: 'Klicka för att sortera i fallande ordning', + triggerAsc: 'Klicka för att sortera i stigande ordning', + cancelSort: 'Klicka för att avbryta sortering', + }, + Modal: { + okText: 'OK', + cancelText: 'Avbryt', + justOkText: 'OK', + }, + Popconfirm: { + okText: 'OK', + cancelText: 'Avbryt', + }, + Transfer: { + titles: ['', ''], + searchPlaceholder: 'Sök här', + itemUnit: 'objekt', + itemsUnit: 'objekt', + remove: 'Ta bort', + selectCurrent: 'Markera nuvarande sida', + removeCurrent: 'Ta bort nuvarande sida', + selectAll: 'Markera all data', + removeAll: 'Ta bort all data', + selectInvert: 'Invertera nuvarande sida', + }, + Upload: { + uploading: 'Laddar upp...', + removeFile: 'Ta bort fil', + uploadError: 'Uppladdningsfel', + previewFile: 'Förhandsgranska fil', + downloadFile: 'Ladda ned fil', + }, + Empty: { + description: 'Ingen data', + }, + Icon: { + icon: 'ikon', + }, + Text: { + edit: 'Redigera', + copy: 'Kopiera', + copied: 'Kopierad', + expand: 'Expandera', + }, + PageHeader: { + back: 'Tillbaka', + }, + Form: { + optional: '(valfritt)', + defaultValidateMessages: { + default: 'Fältvalideringsfel för ${label}', + required: 'Vänligen fyll i ${label}', + enum: '${label} måste vara en av [${enum}]', + whitespace: '${label} kan inte vara ett tomt tecken', + date: { + format: '${label} datumformatet är ogiltigt', + parse: '${label} kan inte konverteras till ett datum', + invalid: '${label} är ett ogiltigt datum', + }, + types: { + string: typeTemplate, + method: typeTemplate, + array: typeTemplate, + object: typeTemplate, + number: typeTemplate, + date: typeTemplate, + boolean: typeTemplate, + integer: typeTemplate, + float: typeTemplate, + regexp: typeTemplate, + email: typeTemplate, + url: typeTemplate, + hex: typeTemplate, + }, + string: { + len: '${label} måste vara ${len} tecken', + min: '${label} måste vara minst ${min} tecken', + max: '${label} måste vara högst ${max} tecken', + range: '${label} måste vara mellan ${min}-${max} tecken', + }, + number: { + len: '${label} måste vara lika med ${len}', + min: '${label} måste vara minst ${min}', + max: '${label} måste vara högst ${max}', + range: '${label} måste vara mellan ${min}-${max}', + }, + array: { + len: 'Måste vara ${len} ${label}', + min: 'Minst ${min} ${label}', + max: 'Högst ${max} ${label}', + range: 'Antal ${label} måste vara mellan ${min}-${max}', + }, + pattern: { + mismatch: '${label} stämmer inte överens med mönstret ${pattern}', + }, + }, + }, + Image: { + preview: 'Förhandsgranska', + }, +}; + +export default localeValues; diff --git a/components/locale/ta_IN.ts b/components/locale/ta_IN.tsx similarity index 95% rename from components/locale/ta_IN.ts rename to components/locale/ta_IN.tsx index 2b0e9079c..2d4d26a8c 100644 --- a/components/locale/ta_IN.ts +++ b/components/locale/ta_IN.tsx @@ -2,8 +2,9 @@ import Pagination from '../vc-pagination/locale/ta_IN'; import DatePicker from '../date-picker/locale/ta_IN'; import TimePicker from '../time-picker/locale/ta_IN'; import Calendar from '../calendar/locale/ta_IN'; +import type { Locale } from '../locale-provider'; -export default { +const localeValues: Locale = { locale: 'ta', Pagination, DatePicker, @@ -61,3 +62,5 @@ export default { back: 'பின் செல்லவும்', }, }; + +export default localeValues; diff --git a/components/locale/th_TH.ts b/components/locale/th_TH.ts deleted file mode 100644 index 8257cd3f5..000000000 --- a/components/locale/th_TH.ts +++ /dev/null @@ -1,62 +0,0 @@ -import Pagination from '../vc-pagination/locale/th_TH'; -import DatePicker from '../date-picker/locale/th_TH'; -import TimePicker from '../time-picker/locale/th_TH'; -import Calendar from '../calendar/locale/th_TH'; - -export default { - locale: 'th', - Pagination, - DatePicker, - TimePicker, - Calendar, - global: { - placeholder: 'กรุณาเลือก', - }, - Table: { - filterTitle: 'ตัวกรอง', - filterConfirm: 'ยืนยัน', - filterReset: 'รีเซ็ต', - selectAll: 'เลือกทั้งหมดในหน้านี้', - selectInvert: 'เลือกสถานะตรงกันข้าม', - sortTitle: 'เรียง', - expand: 'แสดงแถวข้อมูล', - collapse: 'ย่อแถวข้อมูล', - }, - Modal: { - okText: 'ตกลง', - cancelText: 'ยกเลิก', - justOkText: 'ตกลง', - }, - Popconfirm: { - okText: 'ตกลง', - cancelText: 'ยกเลิก', - }, - Transfer: { - titles: ['', ''], - searchPlaceholder: 'ค้นหา', - itemUnit: 'ชิ้น', - itemsUnit: 'ชิ้น', - }, - Upload: { - uploading: 'กำลังอัปโหลด...', - removeFile: 'ลบไฟล์', - uploadError: 'เกิดข้อผิดพลาดในการอัปโหลด', - previewFile: 'ดูตัวอย่างไฟล์', - downloadFile: 'ดาวน์โหลดไฟล์', - }, - Empty: { - description: 'ไม่มีข้อมูล', - }, - Icon: { - icon: 'ไอคอน', - }, - Text: { - edit: 'แก้ไข', - copy: 'คัดลอก', - copied: 'คัดลอกแล้ว', - expand: 'ขยาย', - }, - PageHeader: { - back: 'ย้อนกลับ', - }, -}; diff --git a/components/locale/th_TH.tsx b/components/locale/th_TH.tsx new file mode 100644 index 000000000..32e8bbcc1 --- /dev/null +++ b/components/locale/th_TH.tsx @@ -0,0 +1,130 @@ +/* eslint-disable no-template-curly-in-string */ +import Pagination from '../vc-pagination/locale/th_TH'; +import DatePicker from '../date-picker/locale/th_TH'; +import TimePicker from '../time-picker/locale/th_TH'; +import Calendar from '../calendar/locale/th_TH'; +import type { Locale } from '../locale-provider'; + +const typeTemplate = '${label} ไม่ใช่ ${type} ที่ถูกต้อง'; + +const localeValues: Locale = { + locale: 'th', + Pagination, + DatePicker, + TimePicker, + Calendar, + global: { + placeholder: 'กรุณาเลือก', + }, + Table: { + filterTitle: 'ตัวกรอง', + filterConfirm: 'ยืนยัน', + filterReset: 'รีเซ็ต', + filterEmptyText: 'ไม่มีตัวกรอง', + emptyText: 'ไม่มีข้อมูล', + selectAll: 'เลือกทั้งหมดในหน้านี้', + selectInvert: 'กลับสถานะการเลือกในหน้านี้', + selectionAll: 'เลือกข้อมูลทั้งหมด', + sortTitle: 'เรียง', + expand: 'แสดงแถวข้อมูล', + collapse: 'ย่อแถวข้อมูล', + triggerDesc: 'คลิกเรียงจากมากไปน้อย', + triggerAsc: 'คลิกเรียงจากน้อยไปมาก', + cancelSort: 'คลิกเพื่อยกเลิกการเรียง', + }, + Modal: { + okText: 'ตกลง', + cancelText: 'ยกเลิก', + justOkText: 'ตกลง', + }, + Popconfirm: { + okText: 'ตกลง', + cancelText: 'ยกเลิก', + }, + Transfer: { + titles: ['', ''], + searchPlaceholder: 'ค้นหา', + itemUnit: 'ชิ้น', + itemsUnit: 'ชิ้น', + remove: 'นำออก', + selectCurrent: 'เลือกทั้งหมดในหน้านี้', + removeCurrent: 'นำออกทั้งหมดในหน้านี้', + selectAll: 'เลือกข้อมูลทั้งหมด', + removeAll: 'นำข้อมูลออกทั้งหมด', + selectInvert: 'กลับสถานะการเลือกในหน้านี้', + }, + Upload: { + uploading: 'กำลังอัปโหลด...', + removeFile: 'ลบไฟล์', + uploadError: 'เกิดข้อผิดพลาดในการอัปโหลด', + previewFile: 'ดูตัวอย่างไฟล์', + downloadFile: 'ดาวน์โหลดไฟล์', + }, + Empty: { + description: 'ไม่มีข้อมูล', + }, + Icon: { + icon: 'ไอคอน', + }, + Text: { + edit: 'แก้ไข', + copy: 'คัดลอก', + copied: 'คัดลอกแล้ว', + expand: 'ขยาย', + }, + PageHeader: { + back: 'ย้อนกลับ', + }, + Form: { + optional: '(ไม่จำเป็น)', + defaultValidateMessages: { + default: 'ฟิลด์ ${label} ไม่ผ่านเงื่อนไขการตรวจสอบ', + required: 'กรุณากรอก ${label}', + enum: '${label} ต้องเป็นค่าใดค่าหนึ่งใน [${enum}]', + whitespace: '${label} ไม่สามารถเป็นช่องว่างได้', + date: { + format: 'รูปแบบวันที่ ${label} ไม่ถูกต้อง', + parse: '${label} ไม่สามารถแปลงเป็นวันที่ได้', + invalid: '${label} เป็นวันที่ที่ไม่ถูกต้อง', + }, + types: { + string: typeTemplate, + method: typeTemplate, + array: typeTemplate, + object: typeTemplate, + number: typeTemplate, + date: typeTemplate, + boolean: typeTemplate, + integer: typeTemplate, + float: typeTemplate, + regexp: typeTemplate, + email: typeTemplate, + url: typeTemplate, + hex: typeTemplate, + }, + string: { + len: '${label} ต้องมี ${len} ตัวอักษร', + min: '${label} ต้องมีอย่างน้อย ${min} ตัวอักษร', + max: '${label} มีได้สูงสุด ${max} ตัวอักษร', + range: '${label} ต้องมี ${min}-${max} ตัวอักษร', + }, + number: { + len: '${label} ต้องมี ${len} ตัว', + min: 'ค่าต่ำสุด ${label} คือ ${min}', + max: 'ค่าสูงสุด ${label} คือ ${max}', + range: '${label} ต้องมีค่า ${min}-${max}', + }, + array: { + len: 'ต้องมี ${len} ${label}', + min: 'ต้องมีอย่างน้อย ${min} ${label}', + max: 'มีได้สูงสุด ${max} ${label}', + range: 'จำนวน ${label} ต้องอยู่ในช่วง ${min}-${max}', + }, + pattern: { + mismatch: '${label} ไม่ตรงกับรูปแบบ ${pattern}', + }, + }, + }, +}; + +export default localeValues; diff --git a/components/locale/tr_TR.ts b/components/locale/tr_TR.ts deleted file mode 100644 index a82bd9812..000000000 --- a/components/locale/tr_TR.ts +++ /dev/null @@ -1,57 +0,0 @@ -import Pagination from '../vc-pagination/locale/tr_TR'; -import DatePicker from '../date-picker/locale/tr_TR'; -import TimePicker from '../time-picker/locale/tr_TR'; -import Calendar from '../calendar/locale/tr_TR'; - -export default { - locale: 'tr', - Pagination, - DatePicker, - TimePicker, - Calendar, - global: { - placeholder: 'Lütfen seçiniz', - }, - Table: { - filterTitle: 'Menü Filtrele', - filterConfirm: 'Tamam', - filterReset: 'Sıfırla', - selectAll: 'Hepsini Seç', - selectInvert: 'Tersini Seç', - sortTitle: 'Sırala', - }, - Modal: { - okText: 'Tamam', - cancelText: 'İptal', - justOkText: 'Tamam', - }, - Popconfirm: { - okText: 'Tamam', - cancelText: 'İptal', - }, - Transfer: { - titles: ['', ''], - searchPlaceholder: 'Arama', - itemUnit: 'Öğe', - itemsUnit: 'Öğeler', - }, - Upload: { - uploading: 'Yükleniyor...', - removeFile: `Dosyayı kaldır`, - uploadError: 'Yükleme Hatası', - previewFile: `Dosyayı Önizle`, - downloadFile: 'Dosyayı indir', - }, - Empty: { - description: 'Veri Yok', - }, - Icon: { - icon: 'icon', - }, - Text: { - edit: 'düzenle', - copy: 'kopyala', - copied: 'kopyalandı', - expand: 'genişlet', - }, -}; diff --git a/components/locale/tr_TR.tsx b/components/locale/tr_TR.tsx new file mode 100644 index 000000000..4ab979f85 --- /dev/null +++ b/components/locale/tr_TR.tsx @@ -0,0 +1,129 @@ +/* eslint-disable no-template-curly-in-string */ +import Pagination from '../vc-pagination/locale/tr_TR'; +import DatePicker from '../date-picker/locale/tr_TR'; +import TimePicker from '../time-picker/locale/tr_TR'; +import Calendar from '../calendar/locale/tr_TR'; +import type { Locale } from '../locale-provider'; + +const typeTemplate = '${label} geçerli bir ${type} değil'; + +const localeValues: Locale = { + locale: 'tr', + Pagination, + DatePicker, + TimePicker, + Calendar, + global: { + placeholder: 'Lütfen seçiniz', + }, + Table: { + filterTitle: 'Filtre menüsü', + filterConfirm: 'Tamam', + filterReset: 'Sıfırla', + filterEmptyText: 'Filtre yok', + selectAll: 'Tüm sayfayı seç', + selectInvert: 'Tersini seç', + selectionAll: 'Tümünü seç', + sortTitle: 'Sırala', + expand: 'Satırı genişlet', + collapse: 'Satırı daralt', + triggerDesc: 'Azalan düzende sırala', + triggerAsc: 'Artan düzende sırala', + cancelSort: 'Sıralamayı kaldır', + }, + Modal: { + okText: 'Tamam', + cancelText: 'İptal', + justOkText: 'Tamam', + }, + Popconfirm: { + okText: 'Tamam', + cancelText: 'İptal', + }, + Transfer: { + titles: ['', ''], + searchPlaceholder: 'Arama', + itemUnit: 'Öğe', + itemsUnit: 'Öğeler', + remove: 'Kaldır', + selectCurrent: 'Tüm sayfayı seç', + removeCurrent: 'Sayfayı kaldır', + selectAll: 'Tümünü seç', + removeAll: 'Tümünü kaldır', + selectInvert: 'Tersini seç', + }, + Upload: { + uploading: 'Yükleniyor...', + removeFile: 'Dosyayı kaldır', + uploadError: 'Yükleme hatası', + previewFile: 'Dosyayı önizle', + downloadFile: 'Dosyayı indir', + }, + Empty: { + description: 'Veri Yok', + }, + Icon: { + icon: 'ikon', + }, + Text: { + edit: 'Düzenle', + copy: 'Kopyala', + copied: 'Kopyalandı', + expand: 'Genişlet', + }, + PageHeader: { + back: 'Geri', + }, + Form: { + optional: '(opsiyonel)', + defaultValidateMessages: { + default: 'Alan doğrulama hatası ${label}', + required: '${label} gerekli bir alan', + enum: '${label} şunlardan biri olmalı: [${enum}]', + whitespace: '${label} sadece boşluk olamaz', + date: { + format: '${label} tarih biçimi geçersiz', + parse: '${label} bir tarihe dönüştürülemedi', + invalid: '${label} geçersiz bir tarih', + }, + types: { + string: typeTemplate, + method: typeTemplate, + array: typeTemplate, + object: typeTemplate, + number: typeTemplate, + date: typeTemplate, + boolean: typeTemplate, + integer: typeTemplate, + float: typeTemplate, + regexp: typeTemplate, + email: typeTemplate, + url: typeTemplate, + hex: typeTemplate, + }, + string: { + len: '${label} ${len} karakter olmalı', + min: '${label} en az ${min} karakter olmalı', + max: '${label} en çok ${max} karakter olmalı', + range: '${label} ${min}-${max} karakter arası olmalı', + }, + number: { + len: '${label} ${len} olmalı', + min: '${label} en az ${min} olmalı', + max: '${label} en çok ${max} olmalı', + range: '${label} ${min}-${max} arası olmalı', + }, + array: { + len: '${label} sayısı ${len} olmalı', + min: '${label} sayısı en az ${min} olmalı', + max: '${label} sayısı en çok ${max} olmalı', + range: '${label} sayısı ${min}-${max} arası olmalı', + }, + pattern: { + mismatch: '${label} şu kalıpla eşleşmeli: ${pattern}', + }, + }, + }, +}; + +export default localeValues; diff --git a/components/locale/uk_UA.ts b/components/locale/uk_UA.tsx similarity index 87% rename from components/locale/uk_UA.ts rename to components/locale/uk_UA.tsx index 1712bc6b2..3ef547d56 100644 --- a/components/locale/uk_UA.ts +++ b/components/locale/uk_UA.tsx @@ -2,8 +2,9 @@ import Pagination from '../vc-pagination/locale/uk_UA'; import DatePicker from '../date-picker/locale/uk_UA'; import TimePicker from '../time-picker/locale/uk_UA'; import Calendar from '../calendar/locale/uk_UA'; +import type { Locale } from '../locale-provider'; -export default { +const localeValues: Locale = { locale: 'uk', Pagination, DatePicker, @@ -27,8 +28,8 @@ export default { }, Transfer: { searchPlaceholder: 'Введіть текст для пошуку', - itemUnit: 'item', - itemsUnit: 'items', + itemUnit: 'елем.', + itemsUnit: 'елем.', }, Upload: { uploading: 'Завантаження ...', @@ -41,3 +42,5 @@ export default { description: 'Даних немає', }, }; + +export default localeValues; diff --git a/components/locale/vi_VN.ts b/components/locale/vi_VN.tsx similarity index 89% rename from components/locale/vi_VN.ts rename to components/locale/vi_VN.tsx index f09c4f104..3bc626aec 100644 --- a/components/locale/vi_VN.ts +++ b/components/locale/vi_VN.tsx @@ -2,8 +2,9 @@ import Pagination from '../vc-pagination/locale/vi_VN'; import DatePicker from '../date-picker/locale/vi_VN'; import TimePicker from '../time-picker/locale/vi_VN'; import Calendar from '../calendar/locale/vi_VN'; +import type { Locale } from '../locale-provider'; -export default { +const localeValues: Locale = { locale: 'vi', Pagination, DatePicker, @@ -41,3 +42,5 @@ export default { description: 'Trống', }, }; + +export default localeValues; diff --git a/components/locale/zh_CN.ts b/components/locale/zh_CN.ts deleted file mode 100644 index d77241d3b..000000000 --- a/components/locale/zh_CN.ts +++ /dev/null @@ -1,64 +0,0 @@ -import Pagination from '../vc-pagination/locale/zh_CN'; -import DatePicker from '../date-picker/locale/zh_CN'; -import TimePicker from '../time-picker/locale/zh_CN'; -import Calendar from '../calendar/locale/zh_CN'; -import ColorPicker from '../color-picker/locale/zh_CN'; - -export default { - locale: 'zh-cn', - Pagination, - DatePicker, - TimePicker, - Calendar, - ColorPicker, - // locales for all comoponents - global: { - placeholder: '请选择', - }, - Table: { - filterTitle: '筛选', - filterConfirm: '确定', - filterReset: '重置', - selectAll: '全选当页', - selectInvert: '反选当页', - sortTitle: '排序', - expand: '展开行', - collapse: '关闭行', - }, - Modal: { - okText: '确定', - cancelText: '取消', - justOkText: '知道了', - }, - Popconfirm: { - cancelText: '取消', - okText: '确定', - }, - Transfer: { - searchPlaceholder: '请输入搜索内容', - itemUnit: '项', - itemsUnit: '项', - }, - Upload: { - uploading: '文件上传中', - removeFile: '删除文件', - uploadError: '上传错误', - previewFile: '预览文件', - downloadFile: '下载文件', - }, - Empty: { - description: '暂无数据', - }, - Icon: { - icon: '图标', - }, - Text: { - edit: '编辑', - copy: '复制', - copied: '复制成功', - expand: '展开', - }, - PageHeader: { - back: '返回', - }, -}; diff --git a/components/locale/zh_CN.tsx b/components/locale/zh_CN.tsx new file mode 100644 index 000000000..72ae7238e --- /dev/null +++ b/components/locale/zh_CN.tsx @@ -0,0 +1,133 @@ +/* eslint-disable no-template-curly-in-string */ +import Pagination from '../vc-pagination/locale/zh_CN'; +import DatePicker from '../date-picker/locale/zh_CN'; +import TimePicker from '../time-picker/locale/zh_CN'; +import Calendar from '../calendar/locale/zh_CN'; +import type { Locale } from '../locale-provider'; + +const typeTemplate = '${label}不是一个有效的${type}'; + +const localeValues: Locale = { + locale: 'zh-cn', + Pagination, + DatePicker, + TimePicker, + Calendar, + // locales for all components + global: { + placeholder: '请选择', + }, + Table: { + filterTitle: '筛选', + filterConfirm: '确定', + filterReset: '重置', + filterEmptyText: '无筛选项', + selectAll: '全选当页', + selectInvert: '反选当页', + selectNone: '清空所有', + selectionAll: '全选所有', + sortTitle: '排序', + expand: '展开行', + collapse: '关闭行', + triggerDesc: '点击降序', + triggerAsc: '点击升序', + cancelSort: '取消排序', + }, + Modal: { + okText: '确定', + cancelText: '取消', + justOkText: '知道了', + }, + Popconfirm: { + cancelText: '取消', + okText: '确定', + }, + Transfer: { + searchPlaceholder: '请输入搜索内容', + itemUnit: '项', + itemsUnit: '项', + remove: '删除', + selectCurrent: '全选当页', + removeCurrent: '删除当页', + selectAll: '全选所有', + removeAll: '删除全部', + selectInvert: '反选当页', + }, + Upload: { + uploading: '文件上传中', + removeFile: '删除文件', + uploadError: '上传错误', + previewFile: '预览文件', + downloadFile: '下载文件', + }, + Empty: { + description: '暂无数据', + }, + Icon: { + icon: '图标', + }, + Text: { + edit: '编辑', + copy: '复制', + copied: '复制成功', + expand: '展开', + }, + PageHeader: { + back: '返回', + }, + Form: { + optional: '(可选)', + defaultValidateMessages: { + default: '字段验证错误${label}', + required: '请输入${label}', + enum: '${label}必须是其中一个[${enum}]', + whitespace: '${label}不能为空字符', + date: { + format: '${label}日期格式无效', + parse: '${label}不能转换为日期', + invalid: '${label}是一个无效日期', + }, + types: { + string: typeTemplate, + method: typeTemplate, + array: typeTemplate, + object: typeTemplate, + number: typeTemplate, + date: typeTemplate, + boolean: typeTemplate, + integer: typeTemplate, + float: typeTemplate, + regexp: typeTemplate, + email: typeTemplate, + url: typeTemplate, + hex: typeTemplate, + }, + string: { + len: '${label}须为${len}个字符', + min: '${label}最少${min}个字符', + max: '${label}最多${max}个字符', + range: '${label}须在${min}-${max}字符之间', + }, + number: { + len: '${label}必须等于${len}', + min: '${label}最小值为${min}', + max: '${label}最大值为${max}', + range: '${label}须在${min}-${max}之间', + }, + array: { + len: '须为${len}个${label}', + min: '最少${min}个${label}', + max: '最多${max}个${label}', + range: '${label}数量须在${min}-${max}之间', + }, + pattern: { + mismatch: '${label}与模式不匹配${pattern}', + }, + }, + }, + Image: { + preview: '预览', + }, +}; + +export default localeValues; diff --git a/components/locale/zh_HK.tsx b/components/locale/zh_HK.tsx new file mode 100644 index 000000000..3cdc22e11 --- /dev/null +++ b/components/locale/zh_HK.tsx @@ -0,0 +1,125 @@ +/* eslint-disable no-template-curly-in-string */ +import Pagination from '../vc-pagination/locale/zh_TW'; +import DatePicker from '../date-picker/locale/zh_TW'; +import TimePicker from '../time-picker/locale/zh_TW'; +import Calendar from '../calendar/locale/zh_TW'; +import type { Locale } from '../locale-provider'; + +const typeTemplate = '${label}不是一個有效的${type}'; + +const localeValues: Locale = { + locale: 'zh-hk', + Pagination, + DatePicker, + TimePicker, + Calendar, + global: { + placeholder: '請選擇', + }, + Table: { + filterTitle: '篩選器', + filterConfirm: '確定', + filterReset: '重置', + filterEmptyText: '無篩選項', + selectAll: '全部選取', + selectInvert: '反向選取', + selectNone: '清空所有', + selectionAll: '全選所有', + sortTitle: '排序', + expand: '展開行', + collapse: '關閉行', + triggerDesc: '點擊降序', + triggerAsc: '點擊升序', + cancelSort: '取消排序', + }, + Modal: { + okText: '確定', + cancelText: '取消', + justOkText: '知道了', + }, + Popconfirm: { + okText: '確定', + cancelText: '取消', + }, + Transfer: { + searchPlaceholder: '搜尋資料', + itemUnit: '項目', + itemsUnit: '項目', + }, + Upload: { + uploading: '正在上傳...', + removeFile: '刪除檔案', + uploadError: '上傳失敗', + previewFile: '檔案預覽', + downloadFile: '下载文件', + }, + Empty: { + description: '無此資料', + }, + Icon: { + icon: '圖標', + }, + Text: { + edit: '編輯', + copy: '複製', + copied: '複製成功', + expand: '展開', + }, + PageHeader: { + back: '返回', + }, + Form: { + defaultValidateMessages: { + default: '字段驗證錯誤${label}', + required: '請輸入${label}', + enum: '${label}必須是其中一個[${enum}]', + whitespace: '${label}不能為空字符', + date: { + format: '${label}日期格式無效', + parse: '${label}不能轉換為日期', + invalid: '${label}是一個無效日期', + }, + types: { + string: typeTemplate, + method: typeTemplate, + array: typeTemplate, + object: typeTemplate, + number: typeTemplate, + date: typeTemplate, + boolean: typeTemplate, + integer: typeTemplate, + float: typeTemplate, + regexp: typeTemplate, + email: typeTemplate, + url: typeTemplate, + hex: typeTemplate, + }, + string: { + len: '${label}須為${len}個字符', + min: '${label}最少${min}個字符', + max: '${label}最多${max}個字符', + range: '${label}須在${min}-${max}字符之間', + }, + number: { + len: '${label}必須等於${len}', + min: '${label}最小值為${min}', + max: '${label}最大值為${max}', + range: '${label}須在${min}-${max}之間', + }, + array: { + len: '須為${len}個${label}', + min: '最少${min}個${label}', + max: '最多${max}個${label}', + range: '${label}數量須在${min}-${max}之間', + }, + pattern: { + mismatch: '${label}與模式不匹配${pattern}', + }, + }, + }, + Image: { + preview: '預覽', + }, +}; + +export default localeValues; diff --git a/components/locale/zh_TW.ts b/components/locale/zh_TW.ts deleted file mode 100644 index d0f421fa8..000000000 --- a/components/locale/zh_TW.ts +++ /dev/null @@ -1,51 +0,0 @@ -import Pagination from '../vc-pagination/locale/zh_TW'; -import DatePicker from '../date-picker/locale/zh_TW'; -import TimePicker from '../time-picker/locale/zh_TW'; -import Calendar from '../calendar/locale/zh_TW'; -import ColorPicker from '../color-picker/locale/zh_TW'; - -export default { - locale: 'zh-tw', - Pagination, - DatePicker, - TimePicker, - Calendar, - ColorPicker, - Table: { - filterTitle: '篩選器', - filterConfirm: '確定', - filterReset: '重置', - selectAll: '全部選取', - selectInvert: '反向選取', - sortTitle: '排序', - expand: '展開行', - collapse: '關閉行', - }, - Modal: { - okText: '確定', - cancelText: '取消', - justOkText: '知道了', - }, - Popconfirm: { - okText: '確定', - cancelText: '取消', - }, - Transfer: { - searchPlaceholder: '搜尋資料', - itemUnit: '項目', - itemsUnit: '項目', - }, - Upload: { - uploading: '正在上傳...', - removeFile: '刪除檔案', - uploadError: '上傳失敗', - previewFile: '檔案預覽', - downloadFile: '下载文件', - }, - Empty: { - description: '無此資料', - }, - PageHeader: { - back: '返回', - }, -}; diff --git a/components/locale/zh_TW.tsx b/components/locale/zh_TW.tsx new file mode 100644 index 000000000..dfa21765b --- /dev/null +++ b/components/locale/zh_TW.tsx @@ -0,0 +1,125 @@ +/* eslint-disable no-template-curly-in-string */ +import Pagination from '../vc-pagination/locale/zh_TW'; +import DatePicker from '../date-picker/locale/zh_TW'; +import TimePicker from '../time-picker/locale/zh_TW'; +import Calendar from '../calendar/locale/zh_TW'; +import type { Locale } from '../locale-provider'; + +const typeTemplate = '${label}不是一個有效的${type}'; + +const localeValues: Locale = { + locale: 'zh-tw', + Pagination, + DatePicker, + TimePicker, + Calendar, + global: { + placeholder: '請選擇', + }, + Table: { + filterTitle: '篩選器', + filterConfirm: '確定', + filterReset: '重置', + filterEmptyText: '無篩選項', + selectAll: '全部選取', + selectInvert: '反向選取', + selectNone: '清空所有', + selectionAll: '全選所有', + sortTitle: '排序', + expand: '展開行', + collapse: '關閉行', + triggerDesc: '點擊降序', + triggerAsc: '點擊升序', + cancelSort: '取消排序', + }, + Modal: { + okText: '確定', + cancelText: '取消', + justOkText: '知道了', + }, + Popconfirm: { + okText: '確定', + cancelText: '取消', + }, + Transfer: { + searchPlaceholder: '搜尋資料', + itemUnit: '項目', + itemsUnit: '項目', + }, + Upload: { + uploading: '正在上傳...', + removeFile: '刪除檔案', + uploadError: '上傳失敗', + previewFile: '檔案預覽', + downloadFile: '下载文件', + }, + Empty: { + description: '無此資料', + }, + Icon: { + icon: '圖標', + }, + Text: { + edit: '編輯', + copy: '複製', + copied: '複製成功', + expand: '展開', + }, + PageHeader: { + back: '返回', + }, + Form: { + defaultValidateMessages: { + default: '字段驗證錯誤${label}', + required: '請輸入${label}', + enum: '${label}必須是其中一個[${enum}]', + whitespace: '${label}不能為空字符', + date: { + format: '${label}日期格式無效', + parse: '${label}不能轉換為日期', + invalid: '${label}是一個無效日期', + }, + types: { + string: typeTemplate, + method: typeTemplate, + array: typeTemplate, + object: typeTemplate, + number: typeTemplate, + date: typeTemplate, + boolean: typeTemplate, + integer: typeTemplate, + float: typeTemplate, + regexp: typeTemplate, + email: typeTemplate, + url: typeTemplate, + hex: typeTemplate, + }, + string: { + len: '${label}須為${len}個字符', + min: '${label}最少${min}個字符', + max: '${label}最多${max}個字符', + range: '${label}須在${min}-${max}字符之間', + }, + number: { + len: '${label}必須等於${len}', + min: '${label}最小值為${min}', + max: '${label}最大值為${max}', + range: '${label}須在${min}-${max}之間', + }, + array: { + len: '須為${len}個${label}', + min: '最少${min}個${label}', + max: '最多${max}個${label}', + range: '${label}數量須在${min}-${max}之間', + }, + pattern: { + mismatch: '${label}與模式不匹配${pattern}', + }, + }, + }, + Image: { + preview: '預覽', + }, +}; + +export default localeValues; diff --git a/components/menu/src/MenuItem.tsx b/components/menu/src/MenuItem.tsx index 49f7f7405..df483b93d 100644 --- a/components/menu/src/MenuItem.tsx +++ b/components/menu/src/MenuItem.tsx @@ -10,6 +10,7 @@ import type { MenuInfo } from './interface'; import KeyCode from '../../_util/KeyCode'; import useDirectionStyle from './hooks/useDirectionStyle'; import Overflow from '../../vc-overflow'; +import devWarning from '../../vc-util/devWarning'; let indexGuid = 0; const menuItemProps = { @@ -30,7 +31,15 @@ export default defineComponent({ slots: ['icon', 'title'], setup(props, { slots, emit, attrs }) { const instance = getCurrentInstance(); - const key = instance.vnode.key; + + const key = + typeof instance.vnode.key === 'symbol' ? String(instance.vnode.key) : instance.vnode.key; + devWarning( + typeof instance.vnode.key !== 'symbol', + 'MenuItem', + `MenuItem \`:key="${String(key)}"\` not support Symbol type`, + ); + const eventKey = `menu_item_${++indexGuid}_$$_${key}`; const { parentEventKeys, parentKeys } = useInjectKeyPath(); const { diff --git a/components/menu/src/SubMenu.tsx b/components/menu/src/SubMenu.tsx index 24fde493f..57fea3003 100644 --- a/components/menu/src/SubMenu.tsx +++ b/components/menu/src/SubMenu.tsx @@ -12,6 +12,8 @@ import InlineSubMenuList from './InlineSubMenuList'; import Transition, { getTransitionProps } from '../../_util/transition'; import { cloneElement } from '../../_util/vnode'; import Overflow from '../../vc-overflow'; +import devWarning from '../../vc-util/devWarning'; +import isValid from '../../_util/isValid'; let indexGuid = 0; @@ -39,14 +41,17 @@ export default defineComponent({ useProvideFirstLevel(false); const instance = getCurrentInstance(); - const key = - instance.vnode.key !== null ? instance.vnode.key : `sub_menu_${++indexGuid}_$$_not_set_key`; - + const vnodeKey = + typeof instance.vnode.key === 'symbol' ? String(instance.vnode.key) : instance.vnode.key; + devWarning( + typeof instance.vnode.key !== 'symbol', + 'SubMenu', + `SubMenu \`:key="${String(vnodeKey)}"\` not support Symbol type`, + ); + const key = isValid(vnodeKey) ? vnodeKey : `sub_menu_${++indexGuid}_$$_not_set_key`; const eventKey = props.eventKey ?? - (instance.vnode.key !== null - ? `sub_menu_${++indexGuid}_$$_${instance.vnode.key}` - : (key as string)); + (isValid(vnodeKey) ? `sub_menu_${++indexGuid}_$$_${vnodeKey}` : (key as string)); const { parentEventKeys, parentInfo, parentKeys } = useInjectKeyPath(); const keysPath = computed(() => [...parentKeys.value, key]); const eventKeysPath = computed(() => [...parentEventKeys.value, eventKey]); diff --git a/components/modal/Modal.tsx b/components/modal/Modal.tsx index bc28b952c..1b3fbc02e 100644 --- a/components/modal/Modal.tsx +++ b/components/modal/Modal.tsx @@ -79,7 +79,7 @@ const modalProps = { wrapClassName: PropTypes.string, maskTransitionName: PropTypes.string, transitionName: PropTypes.string, - getContainer: PropTypes.func, + getContainer: PropTypes.any, zIndex: PropTypes.number, bodyStyle: PropTypes.style, maskStyle: PropTypes.style, @@ -119,7 +119,7 @@ export interface ModalFuncProps { maskStyle?: CSSProperties; type?: string; keyboard?: boolean; - getContainer?: getContainerFunc; + getContainer?: getContainerFunc | boolean | string; autoFocusButton?: null | 'ok' | 'cancel'; transitionName?: string; maskTransitionName?: string; diff --git a/components/modal/__tests__/Modal.test.js b/components/modal/__tests__/Modal.test.js index fb8a6bc7e..f9f7adca3 100644 --- a/components/modal/__tests__/Modal.test.js +++ b/components/modal/__tests__/Modal.test.js @@ -65,4 +65,17 @@ describe('Modal', () => { expect(wrapper.html()).toMatchSnapshot(); }); }); + + it('should work with getContainer=false', async () => { + const wrapper1 = mount(Modal, { + sync: false, + props: { + getContainer: false, + visible: true, + }, + }); + await asyncExpect(() => { + expect(wrapper1.html()).toMatchSnapshot(); + }); + }); }); diff --git a/components/modal/__tests__/__snapshots__/Modal.test.js.snap b/components/modal/__tests__/__snapshots__/Modal.test.js.snap index 1d3bc0ccc..ede42e3f3 100644 --- a/components/modal/__tests__/__snapshots__/Modal.test.js.snap +++ b/components/modal/__tests__/__snapshots__/Modal.test.js.snap @@ -86,3 +86,26 @@ exports[`Modal render without footer 1`] = ` `; + +exports[`Modal should work with getContainer=false 1`] = ` +

+
+ +
+`; diff --git a/components/pagination/Pagination.tsx b/components/pagination/Pagination.tsx index 5c5ce32ac..fe2e63ce5 100644 --- a/components/pagination/Pagination.tsx +++ b/components/pagination/Pagination.tsx @@ -51,6 +51,7 @@ export const paginationConfig = () => ({ export type PaginationProps = Partial>>; export type PaginationConfig = Partial>>; +export type PaginationLocale = any; export default defineComponent({ name: 'APagination', inheritAttrs: false, diff --git a/components/rate/index.tsx b/components/rate/index.tsx index 312a3dac0..fb690bab8 100644 --- a/components/rate/index.tsx +++ b/components/rate/index.tsx @@ -40,7 +40,6 @@ const Rate = defineComponent({ allowClear: true, prefixCls: 'ant-rate', tabindex: 0, - character: '★', direction: 'ltr', }), emits: ['hoverChange', 'update:value', 'change', 'focus', 'blur', 'keydown'], diff --git a/components/select/index.tsx b/components/select/index.tsx index 5cce05d0d..17b278961 100644 --- a/components/select/index.tsx +++ b/components/select/index.tsx @@ -76,7 +76,15 @@ const Select = defineComponent({ props: SelectProps(), SECRET_COMBOBOX_MODE_DO_NOT_USE: 'SECRET_COMBOBOX_MODE_DO_NOT_USE', emits: ['change', 'update:value'], - slots: ['notFoundContent', 'suffixIcon', 'itemIcon', 'removeIcon', 'clearIcon', 'dropdownRender'], + slots: [ + 'notFoundContent', + 'suffixIcon', + 'itemIcon', + 'removeIcon', + 'clearIcon', + 'dropdownRender', + 'option', + ], setup(props, { attrs, emit, slots, expose }) { const selectRef = ref(null); @@ -194,6 +202,7 @@ const Select = defineComponent({ dropdownClassName={rcSelectRtlDropDownClassName} onChange={triggerChange} dropdownRender={selectProps.dropdownRender || slots.dropdownRender} + v-slots={{ option: slots.option }} > {slots.default?.()} diff --git a/components/style/themes/default.less b/components/style/themes/default.less index 76e1653b6..93a16e985 100644 --- a/components/style/themes/default.less +++ b/components/style/themes/default.less @@ -581,9 +581,30 @@ // TimePicker // --- -@time-picker-panel-column-width: 56px; -@time-picker-panel-width: @time-picker-panel-column-width * 3; -@time-picker-selected-bg: @background-color-base; +@picker-bg: @component-background; +@picker-basic-cell-hover-color: @item-hover-bg; +@picker-basic-cell-active-with-range-color: @primary-1; +@picker-basic-cell-hover-with-range-color: lighten(@primary-color, 35%); +@picker-basic-cell-disabled-bg: @disabled-bg; +@picker-border-color: @border-color-split; +@picker-date-hover-range-border-color: lighten(@primary-color, 20%); +@picker-date-hover-range-color: @picker-basic-cell-hover-with-range-color; +@picker-time-panel-column-width: 56px; +@picker-time-panel-column-height: 224px; +@picker-time-panel-cell-height: 28px; +@picker-panel-cell-height: 24px; +@picker-panel-cell-width: 36px; +@picker-text-height: 40px; +@picker-panel-without-time-cell-height: 66px; + +// Calendar +// --- +@calendar-bg: @component-background; +@calendar-input-bg: @input-bg; +@calendar-border-color: @border-color-inverse; +@calendar-item-active-bg: @item-active-bg; +@calendar-full-bg: @calendar-bg; +@calendar-full-panel-bg: @calendar-full-bg; // Carousel // --- diff --git a/components/table/filterDropdown.tsx b/components/table/filterDropdown.tsx index 8f3b8ba27..12380eb11 100755 --- a/components/table/filterDropdown.tsx +++ b/components/table/filterDropdown.tsx @@ -98,7 +98,7 @@ export default defineComponent({ this.setVisible(false); // Call `setSelectedKeys` & `confirm` in the same time will make filter data not up to date // https://github.com/ant-design/ant-design/issues/12284 - this.$forceUpdate(); + (this as any).$forceUpdate(); nextTick(this.confirmFilter2); }, diff --git a/components/time-picker/date-fns.tsx b/components/time-picker/date-fns.tsx new file mode 100644 index 000000000..c2f363cd3 --- /dev/null +++ b/components/time-picker/date-fns.tsx @@ -0,0 +1,30 @@ +import createTimePicker from './time-picker'; +import dateFnsGenerateConfig from '../vc-picker/generate/dateFns'; +import type { App } from 'vue'; +import type { PickerTimeProps, RangePickerTimeProps } from '../date-picker/generatePicker'; + +const { TimePicker, TimeRangePicker } = createTimePicker(dateFnsGenerateConfig); + +export interface TimeRangePickerProps extends Omit, 'picker'> { + popupClassName?: string; + valueFormat?: string; +} +export interface TimePickerProps extends Omit, 'picker'> { + popupClassName?: string; + valueFormat?: string; +} + +/* istanbul ignore next */ +TimePicker.install = function (app: App) { + app.component(TimePicker.name, TimePicker); + app.component(TimeRangePicker.name, TimeRangePicker); + return app; +}; +TimePicker.TimeRangePicker = TimeRangePicker; + +export { TimePicker, TimeRangePicker }; + +export default TimePicker as typeof TimePicker & + Plugin & { + readonly TimeRangePicker: typeof TimeRangePicker; + }; diff --git a/components/time-picker/dayjs.tsx b/components/time-picker/dayjs.tsx new file mode 100644 index 000000000..fe3f702ce --- /dev/null +++ b/components/time-picker/dayjs.tsx @@ -0,0 +1,31 @@ +import type { Dayjs } from 'dayjs'; +import createTimePicker from './time-picker'; +import dayjsGenerateConfig from '../vc-picker/generate/dayjs'; +import type { App } from 'vue'; +import type { PickerTimeProps, RangePickerTimeProps } from '../date-picker/generatePicker'; + +const { TimePicker, TimeRangePicker } = createTimePicker(dayjsGenerateConfig); + +export interface TimeRangePickerProps extends Omit, 'picker'> { + popupClassName?: string; + valueFormat?: string; +} +export interface TimePickerProps extends Omit, 'picker'> { + popupClassName?: string; + valueFormat?: string; +} + +/* istanbul ignore next */ +TimePicker.install = function (app: App) { + app.component(TimePicker.name, TimePicker); + app.component(TimeRangePicker.name, TimeRangePicker); + return app; +}; +TimePicker.TimeRangePicker = TimeRangePicker; + +export { TimePicker, TimeRangePicker }; + +export default TimePicker as typeof TimePicker & + Plugin & { + readonly TimeRangePicker: typeof TimeRangePicker; + }; diff --git a/components/time-picker/index.tsx b/components/time-picker/index.tsx index 8103baf17..a6f2f3609 100644 --- a/components/time-picker/index.tsx +++ b/components/time-picker/index.tsx @@ -1,271 +1,8 @@ -import omit from 'omit.js'; -import type { ExtractPropTypes } from 'vue'; -import { defineComponent, inject, provide } from 'vue'; -import VcTimePicker from '../vc-time-picker'; -import LocaleReceiver from '../locale-provider/LocaleReceiver'; -import BaseMixin from '../_util/BaseMixin'; -import PropTypes from '../_util/vue-types'; -import warning from '../_util/warning'; -import ClockCircleOutlined from '@ant-design/icons-vue/ClockCircleOutlined'; -import CloseCircleFilled from '@ant-design/icons-vue/CloseCircleFilled'; -import enUS from './locale/en_US'; -import { hasProp, getOptionProps, getComponent, isValidElement } from '../_util/props-util'; -import initDefaultProps from '../_util/props-util/initDefaultProps'; -import { cloneElement } from '../_util/vnode'; -import { defaultConfigProvider } from '../config-provider'; -import { - checkValidate, - stringToMoment, - momentToString, - TimeOrTimesType, -} from '../_util/moment-util'; -import { tuple, withInstall } from '../_util/type'; -import classNames from '../_util/classNames'; - -export function generateShowHourMinuteSecond(format: string) { - // Ref: http://momentjs.com/docs/#/parsing/string-format/ - return { - showHour: format.indexOf('H') > -1 || format.indexOf('h') > -1 || format.indexOf('k') > -1, - showMinute: format.indexOf('m') > -1, - showSecond: format.indexOf('s') > -1, - }; +import TimePicker from './dayjs'; +export * from './dayjs'; +export interface TimePickerLocale { + placeholder?: string; + rangePlaceholder?: [string, string]; } -export const timePickerProps = () => ({ - size: PropTypes.oneOf(tuple('large', 'default', 'small')), - value: TimeOrTimesType, - defaultValue: TimeOrTimesType, - open: PropTypes.looseBool, - format: PropTypes.string, - disabled: PropTypes.looseBool, - placeholder: PropTypes.string, - prefixCls: PropTypes.string, - hideDisabledOptions: PropTypes.looseBool, - disabledHours: PropTypes.func, - disabledMinutes: PropTypes.func, - disabledSeconds: PropTypes.func, - getPopupContainer: PropTypes.func, - use12Hours: PropTypes.looseBool, - focusOnOpen: PropTypes.looseBool, - hourStep: PropTypes.number, - minuteStep: PropTypes.number, - secondStep: PropTypes.number, - allowEmpty: PropTypes.looseBool, - allowClear: PropTypes.looseBool, - inputReadOnly: PropTypes.looseBool, - clearText: PropTypes.string, - defaultOpenValue: PropTypes.object, - popupClassName: PropTypes.string, - popupStyle: PropTypes.style, - suffixIcon: PropTypes.any, - align: PropTypes.object, - placement: PropTypes.any, - transitionName: PropTypes.string, - autofocus: PropTypes.looseBool, - addon: PropTypes.any, - clearIcon: PropTypes.any, - locale: PropTypes.object, - valueFormat: PropTypes.string, - onChange: PropTypes.func, - onAmPmChange: PropTypes.func, - onOpen: PropTypes.func, - onClose: PropTypes.func, - onFocus: PropTypes.func, - onBlur: PropTypes.func, - onKeydown: PropTypes.func, - onOpenChange: PropTypes.func, -}); - -export type TimePickerProps = Partial>>; - -const TimePicker = defineComponent({ - name: 'ATimePicker', - mixins: [BaseMixin], - inheritAttrs: false, - props: initDefaultProps(timePickerProps(), { - align: { - offset: [0, -2], - }, - disabled: false, - disabledHours: undefined, - disabledMinutes: undefined, - disabledSeconds: undefined, - hideDisabledOptions: false, - placement: 'bottomLeft', - transitionName: 'slide-up', - focusOnOpen: true, - allowClear: true, - }), - emits: ['update:value', 'update:open', 'change', 'openChange', 'focus', 'blur', 'keydown'], - setup() { - return { - popupRef: null, - timePickerRef: null, - configProvider: inject('configProvider', defaultConfigProvider), - }; - }, - - data() { - const { value, defaultValue, valueFormat } = this; - - checkValidate('TimePicker', defaultValue, 'defaultValue', valueFormat); - checkValidate('TimePicker', value, 'value', valueFormat); - warning( - !hasProp(this, 'allowEmpty'), - 'TimePicker', - '`allowEmpty` is deprecated. Please use `allowClear` instead.', - ); - return { - sValue: stringToMoment(value || defaultValue, valueFormat), - }; - }, - watch: { - value(val) { - checkValidate('TimePicker', val, 'value', this.valueFormat); - this.setState({ sValue: stringToMoment(val, this.valueFormat) }); - }, - }, - created() { - provide('savePopupRef', this.savePopupRef); - }, - methods: { - getDefaultFormat() { - const { format, use12Hours } = this; - if (format) { - return format; - } else if (use12Hours) { - return 'h:mm:ss a'; - } - return 'HH:mm:ss'; - }, - - getAllowClear() { - const { allowClear, allowEmpty } = this.$props; - if (hasProp(this, 'allowClear')) { - return allowClear; - } - return allowEmpty; - }, - getDefaultLocale() { - const defaultLocale = { - ...enUS, - ...this.$props.locale, - }; - return defaultLocale; - }, - savePopupRef(ref) { - this.popupRef = ref; - }, - saveTimePicker(timePickerRef) { - this.timePickerRef = timePickerRef; - }, - handleChange(value) { - if (!hasProp(this, 'value')) { - this.setState({ sValue: value }); - } - const { format = 'HH:mm:ss' } = this; - const val = this.valueFormat ? momentToString(value, this.valueFormat) : value; - this.$emit('update:value', val); - this.$emit('change', val, (value && value.format(format)) || ''); - }, - - handleOpenClose({ open }) { - this.$emit('update:open', open); - this.$emit('openChange', open); - }, - - focus() { - (this.timePickerRef as any).focus(); - }, - - blur() { - (this.timePickerRef as any).blur(); - }, - - renderInputIcon(prefixCls: string) { - let suffixIcon = getComponent(this, 'suffixIcon'); - suffixIcon = Array.isArray(suffixIcon) ? suffixIcon[0] : suffixIcon; - const clockIcon = (suffixIcon && - isValidElement(suffixIcon) && - cloneElement(suffixIcon, { - class: `${prefixCls}-clock-icon`, - })) || ; - - return {clockIcon}; - }, - - renderClearIcon(prefixCls: string) { - const clearIcon = getComponent(this, 'clearIcon'); - const clearIconPrefixCls = `${prefixCls}-clear`; - - if (clearIcon && isValidElement(clearIcon)) { - return cloneElement(clearIcon, { - class: clearIconPrefixCls, - }); - } - - return ; - }, - - renderTimePicker(locale) { - let props = getOptionProps(this); - props = omit(props, ['defaultValue', 'suffixIcon', 'allowEmpty', 'allowClear']); - const { class: className } = this.$attrs; - const { prefixCls: customizePrefixCls, getPopupContainer, placeholder, size } = props; - const getPrefixCls = this.configProvider.getPrefixCls; - const prefixCls = getPrefixCls('time-picker', customizePrefixCls); - const inputPrefixCls = getPrefixCls('input'); - const pickerInputClass = classNames(`${prefixCls}-input`, inputPrefixCls); - - const format = this.getDefaultFormat(); - const pickerClassName = { - [className as string]: className, - [`${prefixCls}-${size}`]: !!size, - }; - const tempAddon = getComponent(this, 'addon', {}, false); - const pickerAddon = panel => { - return tempAddon ? ( -
- {typeof tempAddon === 'function' ? tempAddon(panel) : tempAddon} -
- ) : null; - }; - const inputIcon = this.renderInputIcon(prefixCls); - const clearIcon = this.renderClearIcon(prefixCls); - const { getPopupContainer: getContextPopupContainer } = this.configProvider; - const timeProps = { - ...generateShowHourMinuteSecond(format), - ...props, - ...this.$attrs, - allowEmpty: this.getAllowClear(), - prefixCls, - pickerInputClass, - getPopupContainer: getPopupContainer || getContextPopupContainer, - format, - value: this.sValue, - placeholder: placeholder === undefined ? locale.placeholder : placeholder, - addon: pickerAddon, - inputIcon, - clearIcon, - class: pickerClassName, - ref: this.saveTimePicker, - onChange: this.handleChange, - onOpen: this.handleOpenClose, - onClose: this.handleOpenClose, - }; - return ; - }, - }, - - render() { - return ( - - ); - }, -}); - -export default withInstall(TimePicker); +export default TimePicker; diff --git a/components/time-picker/locale/ar_EG.ts b/components/time-picker/locale/ar_EG.ts deleted file mode 100644 index 48ba68e07..000000000 --- a/components/time-picker/locale/ar_EG.ts +++ /dev/null @@ -1,5 +0,0 @@ -const locale = { - placeholder: 'اختيار الوقت', -}; - -export default locale; diff --git a/components/time-picker/locale/ar_EG.tsx b/components/time-picker/locale/ar_EG.tsx new file mode 100644 index 000000000..87e95b28d --- /dev/null +++ b/components/time-picker/locale/ar_EG.tsx @@ -0,0 +1,7 @@ +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { + placeholder: 'اختيار الوقت', +}; + +export default locale; diff --git a/components/time-picker/locale/az_AZ.tsx b/components/time-picker/locale/az_AZ.tsx new file mode 100644 index 000000000..d016e5b57 --- /dev/null +++ b/components/time-picker/locale/az_AZ.tsx @@ -0,0 +1,7 @@ +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { + placeholder: 'Vaxtı seç', +}; + +export default locale; diff --git a/components/time-picker/locale/bg_BG.ts b/components/time-picker/locale/bg_BG.ts deleted file mode 100644 index e6896fe4a..000000000 --- a/components/time-picker/locale/bg_BG.ts +++ /dev/null @@ -1,5 +0,0 @@ -const locale = { - placeholder: 'Избор на час', -}; - -export default locale; diff --git a/components/time-picker/locale/bg_BG.tsx b/components/time-picker/locale/bg_BG.tsx new file mode 100644 index 000000000..d18122b26 --- /dev/null +++ b/components/time-picker/locale/bg_BG.tsx @@ -0,0 +1,7 @@ +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { + placeholder: 'Избор на час', +}; + +export default locale; diff --git a/components/time-picker/locale/by_BY.tsx b/components/time-picker/locale/by_BY.tsx new file mode 100644 index 000000000..750979381 --- /dev/null +++ b/components/time-picker/locale/by_BY.tsx @@ -0,0 +1,8 @@ +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { + placeholder: 'Выберыце час', + rangePlaceholder: ['Час пачатку', 'Час заканчэння'], +}; + +export default locale; diff --git a/components/time-picker/locale/ca_ES.ts b/components/time-picker/locale/ca_ES.ts deleted file mode 100644 index cfd60a8b9..000000000 --- a/components/time-picker/locale/ca_ES.ts +++ /dev/null @@ -1,5 +0,0 @@ -const locale = { - placeholder: 'Seleccionar hora', -}; - -export default locale; diff --git a/components/time-picker/locale/ca_ES.tsx b/components/time-picker/locale/ca_ES.tsx new file mode 100644 index 000000000..390c6f1eb --- /dev/null +++ b/components/time-picker/locale/ca_ES.tsx @@ -0,0 +1,7 @@ +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { + placeholder: 'Seleccionar hora', +}; + +export default locale; diff --git a/components/time-picker/locale/cs_CZ.ts b/components/time-picker/locale/cs_CZ.ts deleted file mode 100644 index 5c89f7aff..000000000 --- a/components/time-picker/locale/cs_CZ.ts +++ /dev/null @@ -1,5 +0,0 @@ -const locale = { - placeholder: 'Vybrat čas', -}; - -export default locale; diff --git a/components/time-picker/locale/cs_CZ.tsx b/components/time-picker/locale/cs_CZ.tsx new file mode 100644 index 000000000..2fc167197 --- /dev/null +++ b/components/time-picker/locale/cs_CZ.tsx @@ -0,0 +1,7 @@ +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { + placeholder: 'Vybrat čas', +}; + +export default locale; diff --git a/components/time-picker/locale/da_DK.ts b/components/time-picker/locale/da_DK.ts deleted file mode 100644 index b3e966e6b..000000000 --- a/components/time-picker/locale/da_DK.ts +++ /dev/null @@ -1,5 +0,0 @@ -const locale = { - placeholder: 'Vælg tid', -}; - -export default locale; diff --git a/components/time-picker/locale/da_DK.tsx b/components/time-picker/locale/da_DK.tsx new file mode 100644 index 000000000..81d0d5ee8 --- /dev/null +++ b/components/time-picker/locale/da_DK.tsx @@ -0,0 +1,8 @@ +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { + placeholder: 'Vælg tid', + rangePlaceholder: ['Starttidspunkt', 'Sluttidspunkt'], +}; + +export default locale; diff --git a/components/time-picker/locale/de_DE.ts b/components/time-picker/locale/de_DE.ts deleted file mode 100644 index c912e9e8f..000000000 --- a/components/time-picker/locale/de_DE.ts +++ /dev/null @@ -1,5 +0,0 @@ -const locale = { - placeholder: 'Zeit auswählen', -}; - -export default locale; diff --git a/components/time-picker/locale/de_DE.tsx b/components/time-picker/locale/de_DE.tsx new file mode 100644 index 000000000..f4b00c50d --- /dev/null +++ b/components/time-picker/locale/de_DE.tsx @@ -0,0 +1,7 @@ +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { + placeholder: 'Zeit auswählen', +}; + +export default locale; diff --git a/components/time-picker/locale/el_GR.ts b/components/time-picker/locale/el_GR.ts deleted file mode 100644 index 2c0dea51f..000000000 --- a/components/time-picker/locale/el_GR.ts +++ /dev/null @@ -1,5 +0,0 @@ -const locale = { - placeholder: 'Επιλέξτε ώρα', -}; - -export default locale; diff --git a/components/time-picker/locale/el_GR.tsx b/components/time-picker/locale/el_GR.tsx new file mode 100644 index 000000000..199e1a5e6 --- /dev/null +++ b/components/time-picker/locale/el_GR.tsx @@ -0,0 +1,7 @@ +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { + placeholder: 'Επιλέξτε ώρα', +}; + +export default locale; diff --git a/components/time-picker/locale/en_GB.ts b/components/time-picker/locale/en_GB.ts deleted file mode 100644 index b95b5a362..000000000 --- a/components/time-picker/locale/en_GB.ts +++ /dev/null @@ -1,5 +0,0 @@ -const locale = { - placeholder: 'Select time', -}; - -export default locale; diff --git a/components/time-picker/locale/en_GB.tsx b/components/time-picker/locale/en_GB.tsx new file mode 100644 index 000000000..d04444685 --- /dev/null +++ b/components/time-picker/locale/en_GB.tsx @@ -0,0 +1,7 @@ +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { + placeholder: 'Select time', +}; + +export default locale; diff --git a/components/time-picker/locale/en_US.ts b/components/time-picker/locale/en_US.ts deleted file mode 100644 index b95b5a362..000000000 --- a/components/time-picker/locale/en_US.ts +++ /dev/null @@ -1,5 +0,0 @@ -const locale = { - placeholder: 'Select time', -}; - -export default locale; diff --git a/components/time-picker/locale/en_US.tsx b/components/time-picker/locale/en_US.tsx new file mode 100644 index 000000000..56d89dd08 --- /dev/null +++ b/components/time-picker/locale/en_US.tsx @@ -0,0 +1,8 @@ +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { + placeholder: 'Select time', + rangePlaceholder: ['Start time', 'End time'], +}; + +export default locale; diff --git a/components/time-picker/locale/es_ES.ts b/components/time-picker/locale/es_ES.ts deleted file mode 100644 index cfd60a8b9..000000000 --- a/components/time-picker/locale/es_ES.ts +++ /dev/null @@ -1,5 +0,0 @@ -const locale = { - placeholder: 'Seleccionar hora', -}; - -export default locale; diff --git a/components/time-picker/locale/es_ES.tsx b/components/time-picker/locale/es_ES.tsx new file mode 100644 index 000000000..390c6f1eb --- /dev/null +++ b/components/time-picker/locale/es_ES.tsx @@ -0,0 +1,7 @@ +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { + placeholder: 'Seleccionar hora', +}; + +export default locale; diff --git a/components/time-picker/locale/et_EE.ts b/components/time-picker/locale/et_EE.ts deleted file mode 100644 index 7ebc008d0..000000000 --- a/components/time-picker/locale/et_EE.ts +++ /dev/null @@ -1,5 +0,0 @@ -const locale = { - placeholder: 'Vali aeg', -}; - -export default locale; diff --git a/components/time-picker/locale/et_EE.tsx b/components/time-picker/locale/et_EE.tsx new file mode 100644 index 000000000..72dd5cb8e --- /dev/null +++ b/components/time-picker/locale/et_EE.tsx @@ -0,0 +1,7 @@ +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { + placeholder: 'Vali aeg', +}; + +export default locale; diff --git a/components/time-picker/locale/fa_IR.ts b/components/time-picker/locale/fa_IR.ts deleted file mode 100644 index 0dcc5d924..000000000 --- a/components/time-picker/locale/fa_IR.ts +++ /dev/null @@ -1,5 +0,0 @@ -const locale = { - placeholder: 'انتخاب زمان', -}; - -export default locale; diff --git a/components/time-picker/locale/fa_IR.tsx b/components/time-picker/locale/fa_IR.tsx new file mode 100644 index 000000000..ef5bb6e42 --- /dev/null +++ b/components/time-picker/locale/fa_IR.tsx @@ -0,0 +1,8 @@ +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { + placeholder: 'انتخاب زمان', + rangePlaceholder: ['زمان شروع', 'زمان پایان'], +}; + +export default locale; diff --git a/components/time-picker/locale/fi_FI.ts b/components/time-picker/locale/fi_FI.ts deleted file mode 100644 index 6c4d9a122..000000000 --- a/components/time-picker/locale/fi_FI.ts +++ /dev/null @@ -1,5 +0,0 @@ -const locale = { - placeholder: 'Valitse aika', -}; - -export default locale; diff --git a/components/time-picker/locale/fi_FI.tsx b/components/time-picker/locale/fi_FI.tsx new file mode 100644 index 000000000..bc0c0b4fa --- /dev/null +++ b/components/time-picker/locale/fi_FI.tsx @@ -0,0 +1,7 @@ +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { + placeholder: 'Valitse aika', +}; + +export default locale; diff --git a/components/time-picker/locale/fr_BE.ts b/components/time-picker/locale/fr_BE.ts deleted file mode 100644 index decc19373..000000000 --- a/components/time-picker/locale/fr_BE.ts +++ /dev/null @@ -1,5 +0,0 @@ -const locale = { - placeholder: "Sélectionner l'heure", -}; - -export default locale; diff --git a/components/time-picker/locale/fr_BE.tsx b/components/time-picker/locale/fr_BE.tsx new file mode 100644 index 000000000..f066f6c27 --- /dev/null +++ b/components/time-picker/locale/fr_BE.tsx @@ -0,0 +1,7 @@ +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { + placeholder: "Sélectionner l'heure", +}; + +export default locale; diff --git a/components/time-picker/locale/fr_CA.tsx b/components/time-picker/locale/fr_CA.tsx new file mode 100644 index 000000000..8bf25122d --- /dev/null +++ b/components/time-picker/locale/fr_CA.tsx @@ -0,0 +1,8 @@ +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { + placeholder: "Sélectionner l'heure", + rangePlaceholder: ['Heure de début', 'Heure de fin'], +}; + +export default locale; diff --git a/components/time-picker/locale/fr_FR.ts b/components/time-picker/locale/fr_FR.ts deleted file mode 100644 index decc19373..000000000 --- a/components/time-picker/locale/fr_FR.ts +++ /dev/null @@ -1,5 +0,0 @@ -const locale = { - placeholder: "Sélectionner l'heure", -}; - -export default locale; diff --git a/components/time-picker/locale/fr_FR.tsx b/components/time-picker/locale/fr_FR.tsx new file mode 100644 index 000000000..8bf25122d --- /dev/null +++ b/components/time-picker/locale/fr_FR.tsx @@ -0,0 +1,8 @@ +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { + placeholder: "Sélectionner l'heure", + rangePlaceholder: ['Heure de début', 'Heure de fin'], +}; + +export default locale; diff --git a/components/time-picker/locale/ga_IE.ts b/components/time-picker/locale/ga_IE.ts deleted file mode 100644 index 5b6ae711b..000000000 --- a/components/time-picker/locale/ga_IE.ts +++ /dev/null @@ -1,5 +0,0 @@ -const locale = { - placeholder: 'Roghnaigh am', -}; - -export default locale; diff --git a/components/time-picker/locale/ga_IE.tsx b/components/time-picker/locale/ga_IE.tsx new file mode 100644 index 000000000..3a2206903 --- /dev/null +++ b/components/time-picker/locale/ga_IE.tsx @@ -0,0 +1,8 @@ +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { + placeholder: 'Roghnaigh am', + rangePlaceholder: ['Am tosaigh', 'Am deiridh'], +}; + +export default locale; diff --git a/components/time-picker/locale/gl_ES.tsx b/components/time-picker/locale/gl_ES.tsx new file mode 100644 index 000000000..2a51d722a --- /dev/null +++ b/components/time-picker/locale/gl_ES.tsx @@ -0,0 +1,7 @@ +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { + placeholder: 'Escolla hora', +}; + +export default locale; diff --git a/components/time-picker/locale/he_IL.ts b/components/time-picker/locale/he_IL.ts deleted file mode 100644 index 6f0cf1a31..000000000 --- a/components/time-picker/locale/he_IL.ts +++ /dev/null @@ -1,5 +0,0 @@ -const locale = { - placeholder: 'בחר שעה', -}; - -export default locale; diff --git a/components/time-picker/locale/he_IL.tsx b/components/time-picker/locale/he_IL.tsx new file mode 100644 index 000000000..63b764f82 --- /dev/null +++ b/components/time-picker/locale/he_IL.tsx @@ -0,0 +1,7 @@ +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { + placeholder: 'בחר שעה', +}; + +export default locale; diff --git a/components/time-picker/locale/hi_IN.ts b/components/time-picker/locale/hi_IN.ts deleted file mode 100644 index 9daaecf3a..000000000 --- a/components/time-picker/locale/hi_IN.ts +++ /dev/null @@ -1,5 +0,0 @@ -const locale = { - placeholder: 'समय का चयन करें', -}; - -export default locale; diff --git a/components/time-picker/locale/hi_IN.tsx b/components/time-picker/locale/hi_IN.tsx new file mode 100644 index 000000000..96f4608a3 --- /dev/null +++ b/components/time-picker/locale/hi_IN.tsx @@ -0,0 +1,8 @@ +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { + placeholder: 'समय का चयन करें', + rangePlaceholder: ['आरंभिक समय', 'अंत समय'], +}; + +export default locale; diff --git a/components/time-picker/locale/hr_HR.ts b/components/time-picker/locale/hr_HR.ts deleted file mode 100644 index 06096123d..000000000 --- a/components/time-picker/locale/hr_HR.ts +++ /dev/null @@ -1,5 +0,0 @@ -const locale = { - placeholder: 'Odaberite vrijeme', -}; - -export default locale; diff --git a/components/time-picker/locale/hr_HR.tsx b/components/time-picker/locale/hr_HR.tsx new file mode 100644 index 000000000..484eec8e1 --- /dev/null +++ b/components/time-picker/locale/hr_HR.tsx @@ -0,0 +1,8 @@ +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { + placeholder: 'Odaberite vrijeme', + rangePlaceholder: ['Vrijeme početka', 'Vrijeme završetka'], +}; + +export default locale; diff --git a/components/time-picker/locale/hu_HU.ts b/components/time-picker/locale/hu_HU.ts deleted file mode 100644 index 404d13ebd..000000000 --- a/components/time-picker/locale/hu_HU.ts +++ /dev/null @@ -1,5 +0,0 @@ -const locale = { - placeholder: 'Válasszon időt', -}; - -export default locale; diff --git a/components/time-picker/locale/hu_HU.tsx b/components/time-picker/locale/hu_HU.tsx new file mode 100644 index 000000000..e3ce591c0 --- /dev/null +++ b/components/time-picker/locale/hu_HU.tsx @@ -0,0 +1,7 @@ +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { + placeholder: 'Válasszon időt', +}; + +export default locale; diff --git a/components/time-picker/locale/id_ID.ts b/components/time-picker/locale/id_ID.ts deleted file mode 100644 index 92c81ffe1..000000000 --- a/components/time-picker/locale/id_ID.ts +++ /dev/null @@ -1,5 +0,0 @@ -const locale = { - placeholder: 'Pilih waktu', -}; - -export default locale; diff --git a/components/time-picker/locale/id_ID.tsx b/components/time-picker/locale/id_ID.tsx new file mode 100644 index 000000000..033637a5e --- /dev/null +++ b/components/time-picker/locale/id_ID.tsx @@ -0,0 +1,7 @@ +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { + placeholder: 'Pilih waktu', +}; + +export default locale; diff --git a/components/time-picker/locale/is_IS.ts b/components/time-picker/locale/is_IS.ts deleted file mode 100644 index 6a5994a28..000000000 --- a/components/time-picker/locale/is_IS.ts +++ /dev/null @@ -1,5 +0,0 @@ -const locale = { - placeholder: 'Velja tíma', -}; - -export default locale; diff --git a/components/time-picker/locale/is_IS.tsx b/components/time-picker/locale/is_IS.tsx new file mode 100644 index 000000000..efdf1cab6 --- /dev/null +++ b/components/time-picker/locale/is_IS.tsx @@ -0,0 +1,7 @@ +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { + placeholder: 'Velja tíma', +}; + +export default locale; diff --git a/components/time-picker/locale/it_IT.ts b/components/time-picker/locale/it_IT.ts deleted file mode 100644 index b9dd24e3b..000000000 --- a/components/time-picker/locale/it_IT.ts +++ /dev/null @@ -1,5 +0,0 @@ -const locale = { - placeholder: "Selezionare l'orario", -}; - -export default locale; diff --git a/components/time-picker/locale/it_IT.tsx b/components/time-picker/locale/it_IT.tsx new file mode 100644 index 000000000..6aa9d8034 --- /dev/null +++ b/components/time-picker/locale/it_IT.tsx @@ -0,0 +1,7 @@ +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { + placeholder: "Selezionare l'orario", +}; + +export default locale; diff --git a/components/time-picker/locale/ja_JP.ts b/components/time-picker/locale/ja_JP.ts deleted file mode 100644 index 366344d41..000000000 --- a/components/time-picker/locale/ja_JP.ts +++ /dev/null @@ -1,5 +0,0 @@ -const locale = { - placeholder: '時刻を選択', -}; - -export default locale; diff --git a/components/time-picker/locale/ja_JP.tsx b/components/time-picker/locale/ja_JP.tsx new file mode 100644 index 000000000..4411853b0 --- /dev/null +++ b/components/time-picker/locale/ja_JP.tsx @@ -0,0 +1,8 @@ +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { + placeholder: '時間を選択', + rangePlaceholder: ['開始時間', '終了時間'], +}; + +export default locale; diff --git a/components/time-picker/locale/kk_KZ.tsx b/components/time-picker/locale/kk_KZ.tsx new file mode 100644 index 000000000..0d5eff5df --- /dev/null +++ b/components/time-picker/locale/kk_KZ.tsx @@ -0,0 +1,8 @@ +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { + placeholder: 'Уақытты таңдаңыз', + rangePlaceholder: ['Бастау уақыты', 'Аяқталу уақыты'], +}; + +export default locale; diff --git a/components/time-picker/locale/kmr_IQ.tsx b/components/time-picker/locale/kmr_IQ.tsx new file mode 100755 index 000000000..07cb074c2 --- /dev/null +++ b/components/time-picker/locale/kmr_IQ.tsx @@ -0,0 +1,7 @@ +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { + placeholder: 'Demê hilbijêre', +}; + +export default locale; diff --git a/components/time-picker/locale/kn_IN.ts b/components/time-picker/locale/kn_IN.ts deleted file mode 100644 index 7d54cd70c..000000000 --- a/components/time-picker/locale/kn_IN.ts +++ /dev/null @@ -1,5 +0,0 @@ -const locale = { - placeholder: 'ಸಮಯ ಆಯ್ಕೆಮಾಡಿ', -}; - -export default locale; diff --git a/components/time-picker/locale/kn_IN.tsx b/components/time-picker/locale/kn_IN.tsx new file mode 100644 index 000000000..9fc680548 --- /dev/null +++ b/components/time-picker/locale/kn_IN.tsx @@ -0,0 +1,7 @@ +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { + placeholder: 'ಸಮಯ ಆಯ್ಕೆಮಾಡಿ', +}; + +export default locale; diff --git a/components/time-picker/locale/ko_KR.ts b/components/time-picker/locale/ko_KR.ts deleted file mode 100644 index fad0ffd8c..000000000 --- a/components/time-picker/locale/ko_KR.ts +++ /dev/null @@ -1,5 +0,0 @@ -const locale = { - placeholder: '날짜 선택', -}; - -export default locale; diff --git a/components/time-picker/locale/ko_KR.tsx b/components/time-picker/locale/ko_KR.tsx new file mode 100644 index 000000000..8a7f3c388 --- /dev/null +++ b/components/time-picker/locale/ko_KR.tsx @@ -0,0 +1,8 @@ +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { + placeholder: '시간 선택', + rangePlaceholder: ['시작 시간', '종료 시간'], +}; + +export default locale; diff --git a/components/time-picker/locale/ku_IQ.ts b/components/time-picker/locale/ku_IQ.ts deleted file mode 100755 index 838b1958d..000000000 --- a/components/time-picker/locale/ku_IQ.ts +++ /dev/null @@ -1,5 +0,0 @@ -const locale = { - placeholder: 'Demê hilbijêre', -}; - -export default locale; diff --git a/components/time-picker/locale/ku_KU.ts b/components/time-picker/locale/ku_KU.ts deleted file mode 100644 index c09f7fca1..000000000 --- a/components/time-picker/locale/ku_KU.ts +++ /dev/null @@ -1,5 +0,0 @@ -const locale = { - placeholder: 'هەڵبژاردنی کات', -}; - -export default locale; diff --git a/components/time-picker/locale/lt_LT.tsx b/components/time-picker/locale/lt_LT.tsx new file mode 100644 index 000000000..27fd504d6 --- /dev/null +++ b/components/time-picker/locale/lt_LT.tsx @@ -0,0 +1,8 @@ +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { + placeholder: 'Pasirinkite laiką', + rangePlaceholder: ['Pradžios laikas', 'Pabaigos laikas'], +}; + +export default locale; diff --git a/components/time-picker/locale/lv_LV.ts b/components/time-picker/locale/lv_LV.ts deleted file mode 100644 index 5e3890e7b..000000000 --- a/components/time-picker/locale/lv_LV.ts +++ /dev/null @@ -1,5 +0,0 @@ -const locale = { - placeholder: 'Izvēlieties laiku', -}; - -export default locale; diff --git a/components/time-picker/locale/lv_LV.tsx b/components/time-picker/locale/lv_LV.tsx new file mode 100644 index 000000000..bee77ff34 --- /dev/null +++ b/components/time-picker/locale/lv_LV.tsx @@ -0,0 +1,7 @@ +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { + placeholder: 'Izvēlieties laiku', +}; + +export default locale; diff --git a/components/time-picker/locale/mk_MK.ts b/components/time-picker/locale/mk_MK.ts deleted file mode 100644 index b5b355ccf..000000000 --- a/components/time-picker/locale/mk_MK.ts +++ /dev/null @@ -1,5 +0,0 @@ -const locale = { - placeholder: 'Избери време', -}; - -export default locale; diff --git a/components/time-picker/locale/mk_MK.tsx b/components/time-picker/locale/mk_MK.tsx new file mode 100644 index 000000000..dcef7d65d --- /dev/null +++ b/components/time-picker/locale/mk_MK.tsx @@ -0,0 +1,7 @@ +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { + placeholder: 'Избери време', +}; + +export default locale; diff --git a/components/time-picker/locale/mn_MN.ts b/components/time-picker/locale/mn_MN.ts deleted file mode 100644 index 70f548611..000000000 --- a/components/time-picker/locale/mn_MN.ts +++ /dev/null @@ -1,5 +0,0 @@ -const locale = { - placeholder: 'Цаг сонгох', -}; - -export default locale; diff --git a/components/time-picker/locale/mn_MN.tsx b/components/time-picker/locale/mn_MN.tsx new file mode 100644 index 000000000..0359f999d --- /dev/null +++ b/components/time-picker/locale/mn_MN.tsx @@ -0,0 +1,7 @@ +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { + placeholder: 'Цаг сонгох', +}; + +export default locale; diff --git a/components/time-picker/locale/ms_MY.ts b/components/time-picker/locale/ms_MY.ts deleted file mode 100644 index 2e66160ff..000000000 --- a/components/time-picker/locale/ms_MY.ts +++ /dev/null @@ -1,5 +0,0 @@ -const locale = { - placeholder: 'Sila pilih masa', -}; - -export default locale; diff --git a/components/time-picker/locale/ms_MY.tsx b/components/time-picker/locale/ms_MY.tsx new file mode 100644 index 000000000..3cfbbe354 --- /dev/null +++ b/components/time-picker/locale/ms_MY.tsx @@ -0,0 +1,7 @@ +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { + placeholder: 'Sila pilih masa', +}; + +export default locale; diff --git a/components/time-picker/locale/nb_NO.ts b/components/time-picker/locale/nb_NO.ts deleted file mode 100644 index dfc0d96e9..000000000 --- a/components/time-picker/locale/nb_NO.ts +++ /dev/null @@ -1,5 +0,0 @@ -const locale = { - placeholder: 'Velg tid', -}; - -export default locale; diff --git a/components/time-picker/locale/nb_NO.tsx b/components/time-picker/locale/nb_NO.tsx new file mode 100644 index 000000000..7a034022d --- /dev/null +++ b/components/time-picker/locale/nb_NO.tsx @@ -0,0 +1,8 @@ +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { + placeholder: 'Velg tid', + rangePlaceholder: ['Starttid', 'Sluttid'], +}; + +export default locale; diff --git a/components/time-picker/locale/nl_BE.ts b/components/time-picker/locale/nl_BE.ts deleted file mode 100644 index 7318ca9f6..000000000 --- a/components/time-picker/locale/nl_BE.ts +++ /dev/null @@ -1,5 +0,0 @@ -const locale = { - placeholder: 'Selecteer tijd', -}; - -export default locale; diff --git a/components/time-picker/locale/nl_BE.tsx b/components/time-picker/locale/nl_BE.tsx new file mode 100644 index 000000000..cc5ede683 --- /dev/null +++ b/components/time-picker/locale/nl_BE.tsx @@ -0,0 +1,8 @@ +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { + placeholder: 'Selecteer tijd', + rangePlaceholder: ['Start tijd', 'Eind tijd'], +}; + +export default locale; diff --git a/components/time-picker/locale/nl_NL.ts b/components/time-picker/locale/nl_NL.ts deleted file mode 100644 index 7318ca9f6..000000000 --- a/components/time-picker/locale/nl_NL.ts +++ /dev/null @@ -1,5 +0,0 @@ -const locale = { - placeholder: 'Selecteer tijd', -}; - -export default locale; diff --git a/components/time-picker/locale/nl_NL.tsx b/components/time-picker/locale/nl_NL.tsx new file mode 100644 index 000000000..cc5ede683 --- /dev/null +++ b/components/time-picker/locale/nl_NL.tsx @@ -0,0 +1,8 @@ +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { + placeholder: 'Selecteer tijd', + rangePlaceholder: ['Start tijd', 'Eind tijd'], +}; + +export default locale; diff --git a/components/time-picker/locale/pl_PL.ts b/components/time-picker/locale/pl_PL.ts deleted file mode 100644 index bd48f4f68..000000000 --- a/components/time-picker/locale/pl_PL.ts +++ /dev/null @@ -1,5 +0,0 @@ -const locale = { - placeholder: 'Wybierz godzinę', -}; - -export default locale; diff --git a/components/time-picker/locale/pl_PL.tsx b/components/time-picker/locale/pl_PL.tsx new file mode 100644 index 000000000..12e9c4da7 --- /dev/null +++ b/components/time-picker/locale/pl_PL.tsx @@ -0,0 +1,7 @@ +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { + placeholder: 'Wybierz godzinę', +}; + +export default locale; diff --git a/components/time-picker/locale/pt_BR.ts b/components/time-picker/locale/pt_BR.ts deleted file mode 100644 index ed0247e10..000000000 --- a/components/time-picker/locale/pt_BR.ts +++ /dev/null @@ -1,5 +0,0 @@ -const locale = { - placeholder: 'Hora', -}; - -export default locale; diff --git a/components/time-picker/locale/pt_BR.tsx b/components/time-picker/locale/pt_BR.tsx new file mode 100644 index 000000000..8b6c5f843 --- /dev/null +++ b/components/time-picker/locale/pt_BR.tsx @@ -0,0 +1,7 @@ +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { + placeholder: 'Hora', +}; + +export default locale; diff --git a/components/time-picker/locale/pt_PT.ts b/components/time-picker/locale/pt_PT.ts deleted file mode 100644 index ed0247e10..000000000 --- a/components/time-picker/locale/pt_PT.ts +++ /dev/null @@ -1,5 +0,0 @@ -const locale = { - placeholder: 'Hora', -}; - -export default locale; diff --git a/components/time-picker/locale/pt_PT.tsx b/components/time-picker/locale/pt_PT.tsx new file mode 100644 index 000000000..8b6c5f843 --- /dev/null +++ b/components/time-picker/locale/pt_PT.tsx @@ -0,0 +1,7 @@ +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { + placeholder: 'Hora', +}; + +export default locale; diff --git a/components/time-picker/locale/ro_RO.ts b/components/time-picker/locale/ro_RO.ts deleted file mode 100644 index d6ad6c161..000000000 --- a/components/time-picker/locale/ro_RO.ts +++ /dev/null @@ -1,5 +0,0 @@ -const locale = { - placeholder: 'Selectează ora', -}; - -export default locale; diff --git a/components/time-picker/locale/ro_RO.tsx b/components/time-picker/locale/ro_RO.tsx new file mode 100644 index 000000000..caba56127 --- /dev/null +++ b/components/time-picker/locale/ro_RO.tsx @@ -0,0 +1,7 @@ +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { + placeholder: 'Selectează ora', +}; + +export default locale; diff --git a/components/time-picker/locale/ru_RU.ts b/components/time-picker/locale/ru_RU.ts deleted file mode 100644 index 0490573e7..000000000 --- a/components/time-picker/locale/ru_RU.ts +++ /dev/null @@ -1,8 +0,0 @@ -/** - * Created by Andrey Gayvoronsky on 13/04/16. - */ -const locale = { - placeholder: 'Выберите время', -}; - -export default locale; diff --git a/components/time-picker/locale/ru_RU.tsx b/components/time-picker/locale/ru_RU.tsx new file mode 100644 index 000000000..9f3519165 --- /dev/null +++ b/components/time-picker/locale/ru_RU.tsx @@ -0,0 +1,9 @@ +/** Created by Andrey Gayvoronsky on 13/04/16. */ +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { + placeholder: 'Выберите время', + rangePlaceholder: ['Время начала', 'Время окончания'], +}; + +export default locale; diff --git a/components/time-picker/locale/sk_SK.ts b/components/time-picker/locale/sk_SK.ts deleted file mode 100644 index 4c62d104b..000000000 --- a/components/time-picker/locale/sk_SK.ts +++ /dev/null @@ -1,5 +0,0 @@ -const locale = { - placeholder: 'Vybrať čas', -}; - -export default locale; diff --git a/components/time-picker/locale/sk_SK.tsx b/components/time-picker/locale/sk_SK.tsx new file mode 100644 index 000000000..ce643fd7e --- /dev/null +++ b/components/time-picker/locale/sk_SK.tsx @@ -0,0 +1,7 @@ +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { + placeholder: 'Vybrať čas', +}; + +export default locale; diff --git a/components/time-picker/locale/sl_SI.ts b/components/time-picker/locale/sl_SI.ts deleted file mode 100644 index 1d77c9a5b..000000000 --- a/components/time-picker/locale/sl_SI.ts +++ /dev/null @@ -1,5 +0,0 @@ -const locale = { - placeholder: 'Izberite čas', -}; - -export default locale; diff --git a/components/time-picker/locale/sl_SI.tsx b/components/time-picker/locale/sl_SI.tsx new file mode 100644 index 000000000..942dec7c6 --- /dev/null +++ b/components/time-picker/locale/sl_SI.tsx @@ -0,0 +1,7 @@ +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { + placeholder: 'Izberite čas', +}; + +export default locale; diff --git a/components/time-picker/locale/sr_RS.ts b/components/time-picker/locale/sr_RS.ts deleted file mode 100644 index ef621a0d7..000000000 --- a/components/time-picker/locale/sr_RS.ts +++ /dev/null @@ -1,5 +0,0 @@ -const locale = { - placeholder: 'Izaberite vreme', -}; - -export default locale; diff --git a/components/time-picker/locale/sr_RS.tsx b/components/time-picker/locale/sr_RS.tsx new file mode 100644 index 000000000..3b21cfee6 --- /dev/null +++ b/components/time-picker/locale/sr_RS.tsx @@ -0,0 +1,8 @@ +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { + placeholder: 'Izaberi vreme', + rangePlaceholder: ['Vreme početka', 'Vreme završetka'], +}; + +export default locale; diff --git a/components/time-picker/locale/sv_SE.ts b/components/time-picker/locale/sv_SE.ts deleted file mode 100644 index 063c46b78..000000000 --- a/components/time-picker/locale/sv_SE.ts +++ /dev/null @@ -1,5 +0,0 @@ -const locale = { - placeholder: 'Välj tid', -}; - -export default locale; diff --git a/components/time-picker/locale/sv_SE.tsx b/components/time-picker/locale/sv_SE.tsx new file mode 100644 index 000000000..af732fd21 --- /dev/null +++ b/components/time-picker/locale/sv_SE.tsx @@ -0,0 +1,7 @@ +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { + placeholder: 'Välj tid', +}; + +export default locale; diff --git a/components/time-picker/locale/ta_IN.ts b/components/time-picker/locale/ta_IN.tsx similarity index 59% rename from components/time-picker/locale/ta_IN.ts rename to components/time-picker/locale/ta_IN.tsx index e549c9ad1..dc2bb9489 100644 --- a/components/time-picker/locale/ta_IN.ts +++ b/components/time-picker/locale/ta_IN.tsx @@ -1,4 +1,6 @@ -const locale = { +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { placeholder: 'நேரத்தைத் தேர்ந்தெடுக்கவும்', }; diff --git a/components/time-picker/locale/th_TH.ts b/components/time-picker/locale/th_TH.ts deleted file mode 100644 index 335e55e01..000000000 --- a/components/time-picker/locale/th_TH.ts +++ /dev/null @@ -1,5 +0,0 @@ -const locale = { - placeholder: 'เลือกเวลา', -}; - -export default locale; diff --git a/components/time-picker/locale/th_TH.tsx b/components/time-picker/locale/th_TH.tsx new file mode 100644 index 000000000..d6b79f80c --- /dev/null +++ b/components/time-picker/locale/th_TH.tsx @@ -0,0 +1,7 @@ +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { + placeholder: 'เลือกเวลา', +}; + +export default locale; diff --git a/components/time-picker/locale/tr_TR.ts b/components/time-picker/locale/tr_TR.ts deleted file mode 100644 index 66f860dca..000000000 --- a/components/time-picker/locale/tr_TR.ts +++ /dev/null @@ -1,5 +0,0 @@ -const locale = { - placeholder: 'Zaman Seç', -}; - -export default locale; diff --git a/components/time-picker/locale/tr_TR.tsx b/components/time-picker/locale/tr_TR.tsx new file mode 100644 index 000000000..4578a5ee1 --- /dev/null +++ b/components/time-picker/locale/tr_TR.tsx @@ -0,0 +1,8 @@ +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { + placeholder: 'Zaman seç', + rangePlaceholder: ['Başlangıç zamanı', 'Bitiş zamanı'], +}; + +export default locale; diff --git a/components/time-picker/locale/uk_UA.ts b/components/time-picker/locale/uk_UA.ts deleted file mode 100644 index 20a81cc53..000000000 --- a/components/time-picker/locale/uk_UA.ts +++ /dev/null @@ -1,5 +0,0 @@ -const locale = { - placeholder: 'Оберіть час', -}; - -export default locale; diff --git a/components/time-picker/locale/uk_UA.tsx b/components/time-picker/locale/uk_UA.tsx new file mode 100644 index 000000000..9398e4e67 --- /dev/null +++ b/components/time-picker/locale/uk_UA.tsx @@ -0,0 +1,7 @@ +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { + placeholder: 'Оберіть час', +}; + +export default locale; diff --git a/components/time-picker/locale/vi_VN.ts b/components/time-picker/locale/vi_VN.ts deleted file mode 100644 index 05dff1df5..000000000 --- a/components/time-picker/locale/vi_VN.ts +++ /dev/null @@ -1,5 +0,0 @@ -const locale = { - placeholder: 'Chọn thời gian', -}; - -export default locale; diff --git a/components/time-picker/locale/vi_VN.tsx b/components/time-picker/locale/vi_VN.tsx new file mode 100644 index 000000000..37ae3215e --- /dev/null +++ b/components/time-picker/locale/vi_VN.tsx @@ -0,0 +1,7 @@ +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { + placeholder: 'Chọn thời gian', +}; + +export default locale; diff --git a/components/time-picker/locale/zh_CN.ts b/components/time-picker/locale/zh_CN.ts deleted file mode 100644 index 6898e575d..000000000 --- a/components/time-picker/locale/zh_CN.ts +++ /dev/null @@ -1,5 +0,0 @@ -const locale = { - placeholder: '请选择时间', -}; - -export default locale; diff --git a/components/time-picker/locale/zh_CN.tsx b/components/time-picker/locale/zh_CN.tsx new file mode 100644 index 000000000..110be8a2e --- /dev/null +++ b/components/time-picker/locale/zh_CN.tsx @@ -0,0 +1,8 @@ +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { + placeholder: '请选择时间', + rangePlaceholder: ['开始时间', '结束时间'], +}; + +export default locale; diff --git a/components/time-picker/locale/zh_TW.ts b/components/time-picker/locale/zh_TW.ts deleted file mode 100644 index cde48a919..000000000 --- a/components/time-picker/locale/zh_TW.ts +++ /dev/null @@ -1,5 +0,0 @@ -const locale = { - placeholder: '請選擇時間', -}; - -export default locale; diff --git a/components/time-picker/locale/zh_TW.tsx b/components/time-picker/locale/zh_TW.tsx new file mode 100644 index 000000000..b295be19c --- /dev/null +++ b/components/time-picker/locale/zh_TW.tsx @@ -0,0 +1,7 @@ +import type { TimePickerLocale } from '../index'; + +const locale: TimePickerLocale = { + placeholder: '請選擇時間', +}; + +export default locale; diff --git a/components/time-picker/moment.tsx b/components/time-picker/moment.tsx new file mode 100644 index 000000000..f268cc06f --- /dev/null +++ b/components/time-picker/moment.tsx @@ -0,0 +1,31 @@ +import type { Moment } from 'moment'; +import createTimePicker from './time-picker'; +import momentGenerateConfig from '../vc-picker/generate/moment'; +import type { App } from 'vue'; +import type { PickerTimeProps, RangePickerTimeProps } from '../date-picker/generatePicker'; + +const { TimePicker, TimeRangePicker } = createTimePicker(momentGenerateConfig); + +export interface TimeRangePickerProps extends Omit, 'picker'> { + popupClassName?: string; + valueFormat?: string; +} +export interface TimePickerProps extends Omit, 'picker'> { + popupClassName?: string; + valueFormat?: string; +} + +/* istanbul ignore next */ +TimePicker.install = function (app: App) { + app.component(TimePicker.name, TimePicker); + app.component(TimeRangePicker.name, TimeRangePicker); + return app; +}; +TimePicker.TimeRangePicker = TimeRangePicker; + +export { TimePicker, TimeRangePicker }; + +export default TimePicker as typeof TimePicker & + Plugin & { + readonly TimeRangePicker: typeof TimeRangePicker; + }; diff --git a/components/time-picker/style/index.less b/components/time-picker/style/index.less index 6d7c5814b..af7ae24a9 100644 --- a/components/time-picker/style/index.less +++ b/components/time-picker/style/index.less @@ -1,247 +1,3 @@ @import '../../style/themes/index'; @import '../../style/mixins/index'; @import '../../input/style/mixin'; - -@timepicker-prefix-cls: ~'@{ant-prefix}-time-picker'; -@timepicker-item-height: 32px; - -.@{timepicker-prefix-cls}-panel { - .reset-component(); - - position: absolute; - z-index: @zindex-picker; - font-family: @font-family; - - &-inner { - position: relative; - left: -2px; - font-size: @font-size-base; - text-align: left; - list-style: none; - background-color: @component-background; - background-clip: padding-box; - border-radius: @border-radius-base; - outline: none; - box-shadow: @box-shadow-base; - } - - &-input { - background: @input-bg; - width: 100%; - max-width: @time-picker-panel-column-width * 3 - @control-padding-horizontal - 2px; - margin: 0; - padding: 0; - line-height: normal; - border: 0; - outline: 0; - cursor: auto; - - .placeholder(); - - &-wrap { - position: relative; - padding: 7px 2px 7px @control-padding-horizontal; - border-bottom: @border-width-base @border-style-base @border-color-split; - } - - &-invalid { - border-color: @error-color; - } - } - - &-narrow &-input-wrap { - max-width: @time-picker-panel-column-width * 2; - } - - &-select { - position: relative; // Fix chrome weird render bug - float: left; - width: @time-picker-panel-column-width; - max-height: @timepicker-item-height * 6; - overflow: hidden; - font-size: @font-size-base; - border-left: @border-width-base @border-style-base @border-color-split; - - &:hover { - overflow-y: auto; - } - - &:first-child { - margin-left: 0; - border-left: 0; - } - - &:last-child { - border-right: 0; - } - - &:only-child { - width: 100%; - } - - ul { - // use fixed width instead of 100% - // to fix strange render bug in safari: https://github.com/ant-design/ant-design/issues/17842 - width: @time-picker-panel-column-width; - margin: 0; - padding: 0 0 @timepicker-item-height * 5; - list-style: none; - } - - li { - width: 100%; - height: @timepicker-item-height; - margin: 0; - padding: 0 0 0 @control-padding-horizontal; - line-height: @timepicker-item-height; - text-align: left; - list-style: none; - cursor: pointer; - transition: all 0.3s; - user-select: none; - - &:focus { - color: @primary-color; - font-weight: 600; - outline: none; - } - } - - li:hover { - background: @item-hover-bg; - } - - li&-option-selected { - font-weight: 600; - background: @time-picker-selected-bg; - &:hover { - background: @time-picker-selected-bg; - } - } - - li&-option-disabled { - color: @btn-disable-color; - &:hover { - background: transparent; - cursor: not-allowed; - } - &:focus { - color: @btn-disable-color; - font-weight: inherit; - } - } - } - - &-combobox { - .clearfix(); - } - - &-addon { - padding: 8px; - border-top: @border-width-base @border-style-base @border-color-split; - } - - &.slide-up-enter.slide-up-enter-active&-placement-topLeft, - &.slide-up-enter.slide-up-enter-active&-placement-topRight, - &.slide-up-appear.slide-up-appear-active&-placement-topLeft, - &.slide-up-appear.slide-up-appear-active&-placement-topRight { - animation-name: antSlideDownIn; - } - - &.slide-up-enter.slide-up-enter-active&-placement-bottomLeft, - &.slide-up-enter.slide-up-enter-active&-placement-bottomRight, - &.slide-up-appear.slide-up-appear-active&-placement-bottomLeft, - &.slide-up-appear.slide-up-appear-active&-placement-bottomRight { - animation-name: antSlideUpIn; - } - - &.slide-up-leave.slide-up-leave-active&-placement-topLeft, - &.slide-up-leave.slide-up-leave-active&-placement-topRight { - animation-name: antSlideDownOut; - } - - &.slide-up-leave.slide-up-leave-active&-placement-bottomLeft, - &.slide-up-leave.slide-up-leave-active&-placement-bottomRight { - animation-name: antSlideUpOut; - } -} - -.@{timepicker-prefix-cls} { - .reset-component(); - - position: relative; - display: inline-block; - width: 128px; - outline: none; - cursor: text; - transition: opacity 0.3s; - - &-input { - .input(); - &[disabled] { - .disabled(); - } - } - - &-open { - opacity: 0; - } - - &-icon, - &-clear { - position: absolute; - top: 50%; - right: @control-padding-horizontal - 1px; - z-index: 1; - width: 14px; - height: 14px; - margin-top: -7px; - color: @disabled-color; - line-height: 14px; - transition: all 0.3s @ease-in-out; - user-select: none; - .@{timepicker-prefix-cls}-clock-icon { - display: block; - color: @disabled-color; - line-height: 1; - } - } - - &-clear { - z-index: 2; - background: @input-bg; - opacity: 0; - pointer-events: none; - &:hover { - color: @text-color-secondary; - } - } - &:hover &-clear { - opacity: 1; - pointer-events: auto; - } - - &-large &-input { - .input-lg(); - } - - &-small &-input { - .input-sm(); - } - - &-small &-icon, - &-small &-clear { - right: @control-padding-horizontal-sm - 1px; - } -} - -// Fix cursor height in safari -// https://stackoverflow.com/q/3843408/3040605 -// https://browserstrangeness.github.io/css_hacks.html#safari -@media not all and (min-resolution: 0.001dpcm) { - @supports (-webkit-appearance: none) and (stroke-color: transparent) { - .@{ant-prefix}-input { - line-height: @line-height-base; - } - } -} diff --git a/components/time-picker/style/index.ts b/components/time-picker/style/index.ts deleted file mode 100644 index 3a3ab0de5..000000000 --- a/components/time-picker/style/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -import '../../style/index.less'; -import './index.less'; diff --git a/components/time-picker/style/index.tsx b/components/time-picker/style/index.tsx new file mode 100644 index 000000000..b2534aab0 --- /dev/null +++ b/components/time-picker/style/index.tsx @@ -0,0 +1,5 @@ +import '../../style/index.less'; +import './index.less'; + +// style dependencies +import '../../date-picker/style'; diff --git a/components/time-picker/time-picker.tsx b/components/time-picker/time-picker.tsx new file mode 100644 index 000000000..63c6e1ac1 --- /dev/null +++ b/components/time-picker/time-picker.tsx @@ -0,0 +1,203 @@ +import { defineComponent, ref } from 'vue'; +import type { PickerTimeProps, RangePickerTimeProps } from '../date-picker/generatePicker'; +import generatePicker from '../date-picker/generatePicker'; +import { + commonProps, + datePickerProps, + rangePickerProps, +} from '../date-picker/generatePicker/props'; +import type { GenerateConfig } from '../vc-picker/generate'; +import type { PanelMode, RangeValue } from '../vc-picker/interface'; +import type { RangePickerSharedProps } from '../vc-picker/RangePicker'; +import devWarning from '../vc-util/devWarning'; + +export interface TimePickerLocale { + placeholder?: string; + rangePlaceholder?: [string, string]; +} + +const timpePickerProps = { + format: String, + showNow: { type: Boolean, default: undefined }, + showHour: { type: Boolean, default: undefined }, + showMinute: { type: Boolean, default: undefined }, + showSecond: { type: Boolean, default: undefined }, + use12Hours: { type: Boolean, default: undefined }, + hourStep: Number, + minuteStep: Number, + secondStep: Number, + hideDisabledOptions: { type: Boolean, default: undefined }, + popupClassName: String, +}; + +function createTimePicker(generateConfig: GenerateConfig) { + const DatePicker = generatePicker(generateConfig, { + ...timpePickerProps, + order: { type: Boolean, default: true }, + }); + const { TimePicker: InternalTimePicker, RangePicker: InternalRangePicker } = DatePicker as any; + type TimeRangePickerProps = Omit, 'picker'> & { + popupClassName?: string; + valueFormat?: string; + }; + type TimePickerProps = Omit, 'picker'> & { + popupClassName?: string; + valueFormat?: string; + }; + const TimePicker = defineComponent({ + name: 'ATimePicker', + inheritAttrs: false, + props: { + ...commonProps(), + ...datePickerProps(), + ...timpePickerProps, + } as any, + slot: ['addon', 'renderExtraFooter', 'suffixIcon', 'clearIcon'], + emits: ['change', 'openChange', 'focus', 'blur', 'ok', 'update:value', 'update:open'], + setup(props, { slots, expose, emit, attrs }) { + devWarning( + !slots.addon, + 'TimePicker', + '`addon` is deprecated. Please use `renderExtraFooter` instead.', + ); + const pickerRef = ref(); + expose({ + focus: () => { + pickerRef.value?.focus(); + }, + blur: () => { + pickerRef.value?.blur(); + }, + }); + const onChange = (value: DateType | string, dateString: string) => { + emit('update:value', value); + emit('change', value, dateString); + }; + const onOpenChange = (open: boolean) => { + emit('update:open', open); + emit('openChange', open); + }; + const onFoucs = () => { + emit('focus'); + }; + const onBlur = () => { + emit('blur'); + }; + const onOk = (value: DateType) => { + emit('ok', value); + }; + return () => { + return ( + + ); + }; + }, + }); + + const TimeRangePicker = defineComponent({ + name: 'ATimeRangePicker', + inheritAttrs: false, + props: { + ...commonProps(), + ...rangePickerProps(), + ...timpePickerProps, + order: { type: Boolean, default: true }, + } as any, + slot: ['renderExtraFooter', 'suffixIcon', 'clearIcon'], + emits: [ + 'change', + 'panelChange', + 'ok', + 'openChange', + 'update:value', + 'update:open', + 'calendarChange', + 'focus', + 'blur', + ], + setup(props, { slots, expose, emit, attrs }) { + const pickerRef = ref(); + expose({ + focus: () => { + pickerRef.value?.focus(); + }, + blur: () => { + pickerRef.value?.blur(); + }, + }); + const onChange = ( + values: RangeValue | RangeValue, + dateStrings: [string, string], + ) => { + emit('update:value', values); + emit('change', values, dateStrings); + }; + const onOpenChange = (open: boolean) => { + emit('update:open', open); + emit('openChange', open); + }; + const onFoucs = () => { + emit('focus'); + }; + const onBlur = () => { + emit('blur'); + }; + const onPanelChange = ( + values: RangeValue | RangeValue, + modes: [PanelMode, PanelMode], + ) => { + emit('panelChange', values, modes); + }; + const onOk = (values: RangeValue | RangeValue) => { + emit('ok', values); + }; + const onCalendarChange: RangePickerSharedProps['onCalendarChange'] = ( + values: RangeValue | RangeValue, + dateStrings: [string, string], + info, + ) => { + emit('calendarChange', values, dateStrings, info); + }; + return () => { + return ( + + ); + }; + }, + }); + + return { + TimePicker, + TimeRangePicker, + }; +} + +export default createTimePicker; diff --git a/components/upload/UploadList.tsx b/components/upload/UploadList.tsx index 4137f876a..05f5fdc9b 100644 --- a/components/upload/UploadList.tsx +++ b/components/upload/UploadList.tsx @@ -64,7 +64,7 @@ export default defineComponent({ previewFile(file.originFileObj).then(previewDataUrl => { // Need append '' to avoid dead loop file.thumbUrl = previewDataUrl || ''; - this.$forceUpdate(); + (this as any).$forceUpdate(); }); } }); diff --git a/components/vc-align/Align.tsx b/components/vc-align/Align.tsx index 6dd82e847..de1f793ba 100644 --- a/components/vc-align/Align.tsx +++ b/components/vc-align/Align.tsx @@ -1,4 +1,5 @@ import type { PropType } from 'vue'; +import { nextTick } from 'vue'; import { defineComponent, ref, computed, onMounted, onUpdated, watch, onUnmounted } from 'vue'; import { alignElement, alignPoint } from 'dom-align'; import addEventListener from '../vc-util/Dom/addEventListener'; @@ -8,6 +9,7 @@ import isVisible from '../vc-util/Dom/isVisible'; import { isSamePoint, restoreFocus, monitorResize } from './util'; import type { AlignType, AlignResult, TargetType, TargetPoint } from './interface'; import useBuffer from './hooks/useBuffer'; +import isEqual from 'lodash-es/isEqual'; type OnAlign = (source: HTMLElement, result: AlignResult) => void; @@ -53,23 +55,18 @@ export default defineComponent({ props: alignProps, emits: ['align'], setup(props, { expose, slots }) { - const cacheRef = ref<{ element?: HTMLElement; point?: TargetPoint }>({}); + const cacheRef = ref<{ element?: HTMLElement; point?: TargetPoint; align?: AlignType }>({}); const nodeRef = ref(); - const forceAlignPropsRef = computed(() => ({ - disabled: props.disabled, - target: props.target, - onAlign: props.onAlign, - })); - const [forceAlign, cancelForceAlign] = useBuffer( () => { const { disabled: latestDisabled, target: latestTarget, + align: latestAlign, onAlign: latestOnAlign, - } = forceAlignPropsRef.value; - if (!latestDisabled && latestTarget && nodeRef.value && nodeRef.value.$el) { - const source = nodeRef.value.$el; + } = props; + if (!latestDisabled && latestTarget && nodeRef.value) { + const source = nodeRef.value; let result: AlignResult; const element = getElement(latestTarget); @@ -77,18 +74,16 @@ export default defineComponent({ cacheRef.value.element = element; cacheRef.value.point = point; - + cacheRef.value.align = latestAlign; // IE lose focus after element realign // We should record activeElement and restore later const { activeElement } = document; - // We only align when element is visible if (element && isVisible(element)) { - result = alignElement(source, element, props.align); + result = alignElement(source, element, latestAlign); } else if (point) { - result = alignPoint(source, point, props.align); + result = alignPoint(source, point, latestAlign); } - restoreFocus(activeElement, source); if (latestOnAlign && result) { @@ -118,13 +113,17 @@ export default defineComponent({ const element = getElement(target); const point = getPoint(target); - if (nodeRef.value && nodeRef.value.$el !== sourceResizeMonitor.value.element) { + if (nodeRef.value !== sourceResizeMonitor.value.element) { sourceResizeMonitor.value.cancel(); - sourceResizeMonitor.value.element = nodeRef.value.$el; - sourceResizeMonitor.value.cancel = monitorResize(nodeRef.value.$el, forceAlign); + sourceResizeMonitor.value.element = nodeRef.value; + sourceResizeMonitor.value.cancel = monitorResize(nodeRef.value, forceAlign); } - if (cacheRef.value.element !== element || !isSamePoint(cacheRef.value.point, point)) { + if ( + cacheRef.value.element !== element || + !isSamePoint(cacheRef.value.point, point) || + !isEqual(cacheRef.value.align, props.align) + ) { forceAlign(); // Add resize observer @@ -137,11 +136,15 @@ export default defineComponent({ }; onMounted(() => { - goAlign(); + nextTick(() => { + goAlign(); + }); }); onUpdated(() => { - goAlign(); + nextTick(() => { + goAlign(); + }); }); // Listen for disabled change @@ -154,7 +157,7 @@ export default defineComponent({ cancelForceAlign(); } }, - { flush: 'post' }, + { immediate: true, flush: 'post' }, ); // Listen for window resize @@ -190,7 +193,7 @@ export default defineComponent({ if (child) { return cloneElement(child[0], { ref: nodeRef }, true, true); } - return child && child[0]; + return null; }; }, }); diff --git a/components/vc-align/Align1.tsx b/components/vc-align/Align1.tsx new file mode 100644 index 000000000..6dd82e847 --- /dev/null +++ b/components/vc-align/Align1.tsx @@ -0,0 +1,196 @@ +import type { PropType } from 'vue'; +import { defineComponent, ref, computed, onMounted, onUpdated, watch, onUnmounted } from 'vue'; +import { alignElement, alignPoint } from 'dom-align'; +import addEventListener from '../vc-util/Dom/addEventListener'; +import { cloneElement } from '../_util/vnode'; +import isVisible from '../vc-util/Dom/isVisible'; + +import { isSamePoint, restoreFocus, monitorResize } from './util'; +import type { AlignType, AlignResult, TargetType, TargetPoint } from './interface'; +import useBuffer from './hooks/useBuffer'; + +type OnAlign = (source: HTMLElement, result: AlignResult) => void; + +export interface AlignProps { + align: AlignType; + target: TargetType; + onAlign?: OnAlign; + monitorBufferTime?: number; + monitorWindowResize?: boolean; + disabled?: boolean; +} + +const alignProps = { + align: Object as PropType, + target: [Object, Function] as PropType, + onAlign: Function as PropType, + monitorBufferTime: Number, + monitorWindowResize: Boolean, + disabled: Boolean, +}; + +interface MonitorRef { + element?: HTMLElement; + cancel: () => void; +} + +export interface RefAlign { + forceAlign: () => void; +} + +function getElement(func: TargetType) { + if (typeof func !== 'function') return null; + return func(); +} + +function getPoint(point: TargetType) { + if (typeof point !== 'object' || !point) return null; + return point; +} + +export default defineComponent({ + name: 'Align', + props: alignProps, + emits: ['align'], + setup(props, { expose, slots }) { + const cacheRef = ref<{ element?: HTMLElement; point?: TargetPoint }>({}); + const nodeRef = ref(); + const forceAlignPropsRef = computed(() => ({ + disabled: props.disabled, + target: props.target, + onAlign: props.onAlign, + })); + + const [forceAlign, cancelForceAlign] = useBuffer( + () => { + const { + disabled: latestDisabled, + target: latestTarget, + onAlign: latestOnAlign, + } = forceAlignPropsRef.value; + if (!latestDisabled && latestTarget && nodeRef.value && nodeRef.value.$el) { + const source = nodeRef.value.$el; + + let result: AlignResult; + const element = getElement(latestTarget); + const point = getPoint(latestTarget); + + cacheRef.value.element = element; + cacheRef.value.point = point; + + // IE lose focus after element realign + // We should record activeElement and restore later + const { activeElement } = document; + + // We only align when element is visible + if (element && isVisible(element)) { + result = alignElement(source, element, props.align); + } else if (point) { + result = alignPoint(source, point, props.align); + } + + restoreFocus(activeElement, source); + + if (latestOnAlign && result) { + latestOnAlign(source, result); + } + + return true; + } + + return false; + }, + computed(() => props.monitorBufferTime), + ); + + // ===================== Effect ===================== + // Listen for target updated + const resizeMonitor = ref({ + cancel: () => {}, + }); + // Listen for source updated + const sourceResizeMonitor = ref({ + cancel: () => {}, + }); + + const goAlign = () => { + const target = props.target; + const element = getElement(target); + const point = getPoint(target); + + if (nodeRef.value && nodeRef.value.$el !== sourceResizeMonitor.value.element) { + sourceResizeMonitor.value.cancel(); + sourceResizeMonitor.value.element = nodeRef.value.$el; + sourceResizeMonitor.value.cancel = monitorResize(nodeRef.value.$el, forceAlign); + } + + if (cacheRef.value.element !== element || !isSamePoint(cacheRef.value.point, point)) { + forceAlign(); + + // Add resize observer + if (resizeMonitor.value.element !== element) { + resizeMonitor.value.cancel(); + resizeMonitor.value.element = element; + resizeMonitor.value.cancel = monitorResize(element, forceAlign); + } + } + }; + + onMounted(() => { + goAlign(); + }); + + onUpdated(() => { + goAlign(); + }); + + // Listen for disabled change + watch( + () => props.disabled, + disabled => { + if (!disabled) { + forceAlign(); + } else { + cancelForceAlign(); + } + }, + { flush: 'post' }, + ); + + // Listen for window resize + const winResizeRef = ref<{ remove: Function }>(null); + + watch( + () => props.monitorWindowResize, + monitorWindowResize => { + if (monitorWindowResize) { + if (!winResizeRef.value) { + winResizeRef.value = addEventListener(window, 'resize', forceAlign); + } + } else if (winResizeRef.value) { + winResizeRef.value.remove(); + winResizeRef.value = null; + } + }, + { flush: 'post' }, + ); + onUnmounted(() => { + resizeMonitor.value.cancel(); + sourceResizeMonitor.value.cancel(); + if (winResizeRef.value) winResizeRef.value.remove(); + cancelForceAlign(); + }); + + expose({ + forceAlign: () => forceAlign(true), + }); + + return () => { + const child = slots?.default(); + if (child) { + return cloneElement(child[0], { ref: nodeRef }, true, true); + } + return child && child[0]; + }; + }, +}); diff --git a/components/vc-align/util.ts b/components/vc-align/util.ts index ecff1cdfc..585828c1b 100644 --- a/components/vc-align/util.ts +++ b/components/vc-align/util.ts @@ -1,5 +1,6 @@ import contains from '../vc-util/Dom/contains'; import type { TargetPoint } from './interface'; +import ResizeObserver from 'resize-observer-polyfill'; export function isSamePoint(prev: TargetPoint, next: TargetPoint) { if (prev === next) return true; diff --git a/components/vc-calendar/assets/common/Calendar.less b/components/vc-calendar/assets/common/Calendar.less deleted file mode 100644 index 1e5fe9d5a..000000000 --- a/components/vc-calendar/assets/common/Calendar.less +++ /dev/null @@ -1,106 +0,0 @@ -.@{prefixClass} { - &-input-wrap { - position: relative; - padding: 6px; - border-bottom: 1px solid #e9e9e9; - &:after { - content: ''; - clear: both; - } - } - - &-date-input-wrap { - overflow: hidden; - } - &-time-picker { - position: absolute; - width: 100%; - top: 34px; - background-color: white; - height: 217px; - &-panel { - width: 100%; - position: relative; - .@{timePickerClass}-panel { - &-input-wrap { - display: none; - } - &-inner { - border: none; - box-shadow: none; - } - &-select { - width: 84px; - ul { - max-height: 217px; - } - li { - text-align: center; - padding: 0; - } - } - } - } - } - &-time-picker-wrap { - float: left; - width: 100%; - - .@{timePickerClass} { - width: 100%; - - &-input { - padding: 0; - border: 1px solid transparent; - outline: 0; - height: 22px; - } - - &-icon { - display: none; - } - } - } - - &-input { - border: 1px solid transparent; - width: 100%; - color: #666; - cursor: text; - line-height: 1.5; - outline: 0; - height: 22px; - - &-invalid { - border-color: red; - } - } - - &-clear-btn { - z-index: 9999; - position: absolute; - right: 6px; - cursor: pointer; - overflow: hidden; - width: 20px; - height: 20px; - text-align: center; - line-height: 20px; - top: 6px; - margin: 0; - } - - &-clear-btn:after { - content: 'x'; - font-size: 12px; - color: #aaa; - display: inline-block; - line-height: 1; - width: 20px; - transition: color 0.3s ease; - } - - &-clear-btn:hover:after { - color: #666; - } -} diff --git a/components/vc-calendar/assets/common/FullCalendar.less b/components/vc-calendar/assets/common/FullCalendar.less deleted file mode 100644 index b9ee2e0df..000000000 --- a/components/vc-calendar/assets/common/FullCalendar.less +++ /dev/null @@ -1,91 +0,0 @@ -.@{prefixClass}-full { - width: 275px; - &-header { - padding: 5px 10px; - text-align: center; - user-select: none; - -webkit-user-select: none; - border-bottom: 1px solid #ccc; - overflow: hidden; - - &-month-select, - &-year-select { - width: 70px; - float: right; - margin-right: 5px; - } - - &-switcher { - float: right; - display: inline-block; - &-normal:hover { - border-color: #23c0fa; - box-shadow: 0 0 2px rgba(45, 183, 245, 0.8); - cursor: pointer; - } - &-focus { - border-color: #3fc7fa; - background-color: #3fc7fa; - color: #fff; - } - > span { - float: left; - height: 28px; - line-height: 24px; - border: 1px solid #d9d9d9; - padding: 0 10px; - color: #666; - &:first-child { - border-top-left-radius: 4px; - border-bottom-left-radius: 4px; - border-right: none; - } - &:last-child { - border-top-right-radius: 4px; - border-bottom-right-radius: 4px; - border-left: none; - } - } - } - } -} - -.@{prefixClass}-fullscreen { - width: auto; - - .@{prefixClass}-full-header { - border-bottom: none; - } - - .@{prefixClass} { - &-column-header { - text-align: right; - padding-right: 12px; - } - &-cell { - padding: 0; - } - &-cell .@{prefixClass}-date, - &-month-panel-cell .@{prefixClass}-month-panel-month { - display: block; - height: 116px; - width: auto; - border-radius: 0; - margin: 0 4px; - border: none; - border-top: 2px solid #eee; - text-align: right; - padding-right: 8px; - } - &-selected-day .@{prefixClass}-date, - &-month-panel-selected-cell .@{prefixClass}-month-panel-month { - background-color: #ebfaff; - color: #666; - } - &-today .@{prefixClass}-date, - &-month-panel-selected-cell .@{prefixClass}-month-panel-month { - border-top-color: #3fc7fa; - color: #3fc7fa; - } - } -} diff --git a/components/vc-calendar/assets/common/Picker.less b/components/vc-calendar/assets/common/Picker.less deleted file mode 100644 index 0a5971784..000000000 --- a/components/vc-calendar/assets/common/Picker.less +++ /dev/null @@ -1,10 +0,0 @@ -.@{prefixClass}-picker { - position: absolute; - left: -9999px; - top: -9999px; - z-index: 1000; - - &-hidden { - display: none; - } -} diff --git a/components/vc-calendar/assets/common/RangeCalendar.less b/components/vc-calendar/assets/common/RangeCalendar.less deleted file mode 100644 index 3b90110dc..000000000 --- a/components/vc-calendar/assets/common/RangeCalendar.less +++ /dev/null @@ -1,131 +0,0 @@ -@input-box-height: 35px; - -.@{prefixClass}-range { - width: 502px; - overflow: hidden; - - &-part { - width: 250px; - position: relative; - - .@{prefixClass}-time-picker { - top: 69px; - &-panel { - &-select { - width: 77px; - } - } - } - } - - &-left { - float: left; - .@{prefixClass}-time-picker-panel { - &-select:last-child { - border-right: 1px solid #e9e9e9; - } - } - } - - &-right { - float: right; - .@{prefixClass}-time-picker-panel { - left: 21px; - - &-select:first-child { - border-left: 1px solid #e9e9e9; - } - } - } - - &-middle { - position: absolute; - margin-left: -10px; - text-align: center; - height: @input-box-height; - line-height: @input-box-height; - } - .@{prefixClass}-date-panel::after { - content: '.'; - display: block; - height: 0; - clear: both; - visibility: hidden; - } - - .@{prefixClass}-input-wrap { - height: @input-box-height; - } - .@{prefixClass}-input, - .@{timePickerClass}-input { - padding: 1px 7px; - height: 22px; - } - - .@{prefixClass}-body, - .@{prefixClass}-decade-panel-body, - .@{prefixClass}-year-panel-body, - .@{prefixClass}-month-panel-body { - border-bottom: 1px solid #e9e9e9; - } - - &.@{prefixClass}-week-number { - width: 574px; - - .@{prefixClass}-range { - &-part { - width: 286px; - .@{prefixClass}-time-picker { - top: 69px; - &-panel { - &-select { - width: 89px; - } - } - } - } - &-right { - .@{prefixClass}-time-picker-panel { - left: 36px; - } - } - } - } - - .@{prefixClass}-year-panel, - .@{prefixClass}-month-panel, - .@{prefixClass}-decade-panel { - top: @input-box-height; - } - .@{prefixClass}-month-panel .@{prefixClass}-year-panel { - top: 0; - } - .@{prefixClass}-decade-panel-table, - .@{prefixClass}-year-panel-table, - .@{prefixClass}-month-panel-table { - height: 198px; - } - - .@{prefixClass}-in-range-cell { - background: #ebf4f8; - border-radius: 0; - } - - &-bottom { - text-align: right; - } - - .@{prefixClass}-footer { - border-top: none; - padding: 0; - &-btn { - padding: 10px 12px 10px 0; - } - } - .@{prefixClass}-ok-btn { - position: static; - } - .@{prefixClass}-today-btn { - float: left; - } -} diff --git a/components/vc-calendar/assets/common/index.less b/components/vc-calendar/assets/common/index.less deleted file mode 100644 index 07caf25b9..000000000 --- a/components/vc-calendar/assets/common/index.less +++ /dev/null @@ -1,16 +0,0 @@ -@prefixClass: rc-calendar; -@timePickerClass: rc-time-picker; - -.@{prefixClass} { - box-sizing: border-box; - * { - box-sizing: border-box; - } -} - -.@{prefixClass}-hidden { - display: none; -} - -@import 'Calendar.less'; -@import 'Picker.less'; diff --git a/components/vc-calendar/assets/index.less b/components/vc-calendar/assets/index.less deleted file mode 100644 index ec7406d8c..000000000 --- a/components/vc-calendar/assets/index.less +++ /dev/null @@ -1,10 +0,0 @@ -@import './common/index.less'; -@import 'index/Picker'; -@import 'index/Calendar'; -@import 'index/Time'; -@import 'index/TimePanel'; -@import 'index/MonthPanel'; -@import 'index/YearPanel'; -@import 'index/DecadePanel'; -@import 'common/RangeCalendar'; -@import 'common/FullCalendar'; diff --git a/components/vc-calendar/assets/index/Calendar.less b/components/vc-calendar/assets/index/Calendar.less deleted file mode 100644 index 1c387b775..000000000 --- a/components/vc-calendar/assets/index/Calendar.less +++ /dev/null @@ -1,301 +0,0 @@ -.@{prefixClass} { - position: relative; - outline: none; - font-family: Arial, 'Hiragino Sans GB', 'Microsoft Yahei', 'Microsoft Sans Serif', - 'WenQuanYi Micro Hei', sans-serif; - width: 253px; - border: 1px solid #ccc; - list-style: none; - font-size: 12px; - text-align: left; - background-color: #fff; - border-radius: 3px; - box-shadow: 0 1px 5px #ccc; - background-clip: padding-box; - border: 1px solid #ccc; - line-height: 1.5; - - &-date-panel, - &-panel { - position: relative; - outline: none; - } - - &-week-number { - width: 286px; - - &-cell { - text-align: center; - } - } - - &-header { - padding: 0 10px; - height: 34px; - line-height: 30px; - text-align: center; - user-select: none; - -webkit-user-select: none; - border-bottom: 1px solid #ccc; - - > a { - font-weight: bold; - display: inline-block; - padding: 0px 5px; - line-height: 34px; - text-align: center; - width: 30px; - - &:hover { - cursor: pointer; - color: #23c0fa; - } - } - - .@{prefixClass}-prev-month-btn { - position: absolute; - left: 25px; - - &:after { - content: '‹'; - } - } - - .@{prefixClass}-next-month-btn { - position: absolute; - right: 25px; - - &:after { - content: '›'; - } - } - } - - &-year-select, - &-month-select, - &-day-select { - display: inline-block; - font-size: 12px; - font-weight: bold; - color: #666; - padding: 0 8px; - line-height: 34px; - - &:hover { - cursor: pointer; - color: #23c0fa; - } - } - - &-prev-month-btn, - &-next-month-btn, - &-prev-year-btn, - &-next-year-btn { - position: absolute; - top: 0; - cursor: pointer; - color: #999; - font-family: Arial, 'Hiragino Sans GB', 'Microsoft Yahei', 'Microsoft Sans Serif', sans-serif; - padding: 0 5px; - font-size: 16px; - display: inline-block; - line-height: 34px; - - &:hover { - color: #23c0fa; - } - } - - &-next-year-btn { - right: 0; - - &:after { - content: '»'; - } - } - - &-prev-year-btn { - left: 0; - - &:after { - content: '«'; - } - } - - &-body { - padding: 9px 10px 10px; - height: 217px; - } - - table { - border-collapse: collapse; - max-width: 100%; - background-color: transparent; - width: 100%; - } - - table, - td, - th, - td { - border: none; - } - - &-table { - border-spacing: 0; - margin-bottom: 0; - } - - &-column-header { - line-height: 18px; - padding: 6px 0; - width: 33px; - text-align: center; - .@{prefixClass}-column-header-inner { - display: block; - font-weight: normal; - } - } - - &-week-number-header { - .@{prefixClass}-column-header-inner { - display: none; - } - } - - &-cell { - padding: 1px 0; - } - - &-date { - display: block; - margin: 0 auto; - color: #666; - border-radius: 4px 4px; - width: 26px; - height: 26px; - padding: 0; - background: transparent; - line-height: 26px; - text-align: center; - - &:hover { - background: #ebfaff; - cursor: pointer; - } - } - - &-selected-day &-date { - background: tint(#3fc7fa, 80%); - } - - &-selected-date &-date { - background: #3fc7fa; - color: #fff; - &:hover { - background: #3fc7fa; - } - } - - &-today &-date { - border: 1px solid #3fc7fa; - } - - &-disabled-cell &-date { - cursor: not-allowed; - color: #bcbcbc; - background: #f3f3f3; - border-radius: 0; - width: auto; - - &:hover { - background: #f3f3f3; - } - } - - &-disabled-cell-first-of-row &-date { - border-top-left-radius: 4px; - border-bottom-left-radius: 4px; - } - - &-disabled-cell-last-of-row &-date { - border-top-right-radius: 4px; - border-bottom-right-radius: 4px; - } - - &-last-month-cell &-date, - &-next-month-btn-day &-date { - color: #bbb; - } - - &-footer { - border-top: 1px solid #ccc; - padding: 10px 0; - text-align: center; - position: relative; - - .@{timePickerClass} { - width: 90px; - &-input { - height: 24px; - } - } - &-show-ok { - text-align: right; - .@{prefixClass} { - &-footer-btn { - padding-right: 12px; - } - - &-time-picker-btn { - margin-left: 0; - padding: 0 12px; - } - &-today-btn { - float: left; - padding-left: 12px; - } - } - } - } - - &-footer-btn { - margin-top: 2px; - - &:after { - content: 'x'; - height: 0; - font-size: 0; - overflow: hidden; - clear: both; - } - } - - &-time-picker-btn { - margin-left: 10px; - } - - &-today-btn, - &-ok-btn, - &-time-picker-btn { - display: inline-block; - text-align: center; - color: #f46830; - - &:hover { - cursor: pointer; - color: #23c0fa; - } - - &-disabled { - color: #bbb; - &:hover { - color: #bbb; - } - } - } - - &-today-btn { - padding-left: 10px; - } -} diff --git a/components/vc-calendar/assets/index/DecadePanel.less b/components/vc-calendar/assets/index/DecadePanel.less deleted file mode 100644 index b758eb57c..000000000 --- a/components/vc-calendar/assets/index/DecadePanel.less +++ /dev/null @@ -1,122 +0,0 @@ -.@{prefixClass}-decade-panel { - left: 0; - top: 0; - bottom: 0; - right: 0; - background: #ffffff; - z-index: 10; - position: absolute; - outline: none; - display: flex; - flex-direction: column; -} - -.@{prefixClass}-decade-panel-hidden { - display: none; -} - -.@{prefixClass}-decade-panel-header { - padding: 0 10px; - height: 34px; - line-height: 34px; - position: relative; - text-align: center; - user-select: none; - -webkit-user-select: none; - border-bottom: 1px solid #ccc; - - > a { - font-weight: bold; - display: inline-block; - padding: 1px 5px; - text-align: center; - width: 30px; - - &:hover { - cursor: pointer; - color: #23c0fa; - } - } -} - -.@{prefixClass}-decade-panel-prev-century-btn, -.@{prefixClass}-decade-panel-next-century-btn { - position: absolute; - top: 0; -} - -.@{prefixClass}-decade-panel-next-century-btn { - &:after { - content: '»'; - } -} - -.@{prefixClass}-decade-panel-prev-century-btn { - user-select: none; - left: 0; - &:after { - content: '«'; - } -} - -.@{prefixClass}-decade-panel-next-century-btn { - user-select: none; - right: 0; -} - -.@{prefixClass}-decade-panel-body { - flex: 1; - padding: 9px 10px 10px; -} - -.@{prefixClass}-decade-panel-footer { - border-top: 1px solid #ccc; - line-height: 38px; -} - -.@{prefixClass}-decade-panel-table { - table-layout: fixed; - width: 100%; - height: 100%; - border-collapse: separate; -} - -.@{prefixClass}-decade-panel-cell { - text-align: center; -} - -.@{prefixClass}-decade-panel-decade { - display: block; - margin: 0 auto; - color: #666; - border-radius: 4px 4px; - height: 36px; - padding: 0; - background: transparent; - line-height: 36px; - text-align: center; - - &:hover { - background: #ebfaff; - cursor: pointer; - } -} - -.@{prefixClass}-decade-panel-selected-cell .@{prefixClass}-decade-panel-decade { - background: #3fc7fa; - color: #fff; - - &:hover { - background: #3fc7fa; - color: #fff; - } -} - -.@{prefixClass}-decade-panel-last-century-cell, -.@{prefixClass}-decade-panel-next-century-cell { - .@{prefixClass}-decade-panel-decade { - user-select: none; - -webkit-user-select: none; - color: rgba(0, 0, 0, 0.25); - } -} diff --git a/components/vc-calendar/assets/index/Input.less b/components/vc-calendar/assets/index/Input.less deleted file mode 100644 index 65d550d0e..000000000 --- a/components/vc-calendar/assets/index/Input.less +++ /dev/null @@ -1,23 +0,0 @@ -.input() { - height: 25px; - position: relative; - display: inline-block; - margin: 0 0; - padding: 4px 10px; - border-radius: 6px 6px; - border: 1px solid #d9d9d9; - background-color: #ffffff; - color: #666; - line-height: 1.5; - transform: border 0.3s cubic-bezier(0.35, 0, 0.25, 1), - background 0.3s cubic-bezier(0.35, 0, 0.25, 1), box-shadow 0.3s cubic-bezier(0.35, 0, 0.25, 1); - - &:hover { - border-color: #23c0fa; - } - - &:focus { - border-color: #23c0fa; - box-shadow: 0 0 3px #23c0fa; - } -} diff --git a/components/vc-calendar/assets/index/MonthPanel.less b/components/vc-calendar/assets/index/MonthPanel.less deleted file mode 100644 index 5bb3fc7a0..000000000 --- a/components/vc-calendar/assets/index/MonthPanel.less +++ /dev/null @@ -1,143 +0,0 @@ -.@{prefixClass}-month-panel { - left: 0; - top: 0; - bottom: 0; - right: 0; - background: #ffffff; - z-index: 10; - position: absolute; - outline: none; - - > div { - height: 100%; - display: flex; - flex-direction: column; - } -} - -.@{prefixClass}-month-panel-hidden { - display: none; -} - -.@{prefixClass}-month-panel-header { - padding: 0 10px; - height: 34px; - line-height: 30px; - position: relative; - text-align: center; - user-select: none; - -webkit-user-select: none; - border-bottom: 1px solid #ccc; - - > a { - font-weight: bold; - display: inline-block; - padding: 4px 5px; - text-align: center; - width: 30px; - - &:hover { - cursor: pointer; - color: #23c0fa; - } - } -} - -.@{prefixClass}-month-panel-prev-year-btn, -.@{prefixClass}-month-panel-next-year-btn { - position: absolute; - top: 0; -} - -.@{prefixClass}-month-panel-next-year-btn { - &:after { - content: '»'; - } -} - -.@{prefixClass}-month-panel-prev-year-btn { - user-select: none; - left: 0; - - &:after { - content: '«'; - } -} - -.@{prefixClass}-month-panel .@{prefixClass}-month-panel-year-select { - width: 180px; -} - -.@{prefixClass}-month-panel-year-select-arrow { - display: none; -} - -.@{prefixClass}-month-panel-next-year-btn { - user-select: none; - right: 0; -} - -.@{prefixClass}-month-panel-body { - flex: 1; - padding: 9px 10px 10px; -} - -.@{prefixClass}-month-panel-footer { - border-top: 1px solid #ccc; - line-height: 38px; -} - -.@{prefixClass}-month-panel-table { - table-layout: fixed; - width: 100%; - height: 100%; - border-collapse: separate; -} - -.@{prefixClass}-month-panel-cell { - text-align: center; - - .@{prefixClass}-month-panel-month { - display: block; - width: 46px; - margin: 0 auto; - color: #666; - border-radius: 4px 4px; - height: 36px; - padding: 0; - background: transparent; - line-height: 36px; - text-align: center; - - &:hover { - background: #ebfaff; - cursor: pointer; - } - } - - &-disabled { - .@{prefixClass}-month-panel-month { - color: #bfbfbf; - - &:hover { - background: white; - cursor: not-allowed; - } - } - } -} - -.@{prefixClass}-month-panel-selected-cell .@{prefixClass}-month-panel-month { - background: #3fc7fa; - color: #fff; - - &:hover { - background: #3fc7fa; - color: #fff; - } -} - -.@{prefixClass}-month-header-wrap { - position: relative; - height: 308px; -} diff --git a/components/vc-calendar/assets/index/Picker.less b/components/vc-calendar/assets/index/Picker.less deleted file mode 100644 index 3c111d3ae..000000000 --- a/components/vc-calendar/assets/index/Picker.less +++ /dev/null @@ -1,110 +0,0 @@ -.@{prefixClass} { - &-picker { - .effect() { - animation-duration: 0.3s; - animation-fill-mode: both; - transform-origin: 0 0; - display: block !important; - } - - &-slide-up-enter { - .effect(); - opacity: 0; - animation-timing-function: cubic-bezier(0.08, 0.82, 0.17, 1); - animation-play-state: paused; - } - - &-slide-up-appear { - .effect(); - opacity: 0; - animation-timing-function: cubic-bezier(0.08, 0.82, 0.17, 1); - animation-play-state: paused; - } - - &-slide-up-leave { - .effect(); - opacity: 1; - animation-timing-function: cubic-bezier(0.6, 0.04, 0.98, 0.34); - animation-play-state: paused; - } - - &-slide-up-enter&-slide-up-enter-active&-placement-bottomLeft, - &-slide-up-enter&-slide-up-enter-active&-placement-bottomRight, - &-slide-up-appear&-slide-up-appear-active&-placement-bottomLeft, - &-slide-up-appear&-slide-up-appear-active&-placement-bottomRight { - animation-name: rcDropdownSlideUpIn; - animation-play-state: running; - } - - &-slide-up-enter&-slide-up-enter-active&-placement-topLeft, - &-slide-up-enter&-slide-up-enter-active&-placement-topRight, - &-slide-up-appear&-slide-up-appear-active&-placement-topLeft, - &-slide-up-appear&-slide-up-appear-active&-placement-topRight { - animation-name: rcDropdownSlideDownIn; - animation-play-state: running; - } - - &-slide-up-leave&-slide-up-leave-active&-placement-bottomLeft, - &-slide-up-leave&-slide-up-leave-active&-placement-bottomRight { - animation-name: rcDropdownSlideUpOut; - animation-play-state: running; - } - - &-slide-up-leave&-slide-up-leave-active&-placement-topLeft, - &-slide-up-leave&-slide-up-leave-active&-placement-topRight { - animation-name: rcDropdownSlideDownOut; - animation-play-state: running; - } - - @keyframes rcDropdownSlideUpIn { - 0% { - opacity: 0; - transform-origin: 0% 0%; - transform: scaleY(0); - } - 100% { - opacity: 1; - transform-origin: 0% 0%; - transform: scaleY(1); - } - } - - @keyframes rcDropdownSlideUpOut { - 0% { - opacity: 1; - transform-origin: 0% 0%; - transform: scaleY(1); - } - 100% { - opacity: 0; - transform-origin: 0% 0%; - transform: scaleY(0); - } - } - - @keyframes rcDropdownSlideDownIn { - 0% { - opacity: 0; - transform-origin: 100% 100%; - transform: scaleY(0); - } - 100% { - opacity: 1; - transform-origin: 100% 100%; - transform: scaleY(1); - } - } - @keyframes rcDropdownSlideDownOut { - 0% { - opacity: 1; - transform-origin: 100% 100%; - transform: scaleY(1); - } - 100% { - opacity: 0; - transform-origin: 100% 100%; - transform: scaleY(0); - } - } - } -} diff --git a/components/vc-calendar/assets/index/Time.less b/components/vc-calendar/assets/index/Time.less deleted file mode 100644 index e860d73cb..000000000 --- a/components/vc-calendar/assets/index/Time.less +++ /dev/null @@ -1,6 +0,0 @@ -@import './Input.less'; - -.@{prefixClass}-time-input { - .input(); - width: 40px; -} diff --git a/components/vc-calendar/assets/index/TimePanel.less b/components/vc-calendar/assets/index/TimePanel.less deleted file mode 100644 index 66e5e916a..000000000 --- a/components/vc-calendar/assets/index/TimePanel.less +++ /dev/null @@ -1,72 +0,0 @@ -.@{prefixClass}-time-panel { - left: 0; - top: 0; - bottom: 0; - right: 0; - background: #ffffff; - z-index: 10; - position: absolute; - outline: none; -} - -.@{prefixClass}-time-panel-header { - padding: 0 10px; - height: 34px; - line-height: 34px; - position: relative; - text-align: center; - user-select: none; - -webkit-user-select: none; - border-bottom: 1px solid #ccc; -} - -.@{prefixClass}-time-panel-body { - padding: 9px 10px 10px; -} - -.@{prefixClass}-time-panel-title { - width: 180px; - font-weight: bold; - display: inline-block; - padding: 4px 5px; - text-align: center; - height: 30px; - line-height: 22px; - border-radius: 4px; -} - -.@{prefixClass}-time-panel-table { - table-layout: fixed; - width: 100%; - height: 255px; - border-collapse: separate; -} - -.@{prefixClass}-time-panel-cell { - text-align: center; - height: 42px; - vertical-align: middle; -} - -.@{prefixClass}-time-panel-time { - line-height: 26px; - display: block; - border-radius: 4px; - width: 26px; - margin: 0 auto; - - &:hover { - background: #ebfaff; - cursor: pointer; - } -} - -.@{prefixClass}-time-panel-selected-cell .@{prefixClass}-time-panel-time { - background: #3fc7fa; - color: #fff; - - &:hover { - background: #3fc7fa; - color: #fff; - } -} diff --git a/components/vc-calendar/assets/index/YearPanel.less b/components/vc-calendar/assets/index/YearPanel.less deleted file mode 100644 index 77ba5c778..000000000 --- a/components/vc-calendar/assets/index/YearPanel.less +++ /dev/null @@ -1,136 +0,0 @@ -.@{prefixClass}-year-panel { - left: 0; - top: 0; - bottom: 0; - right: 0; - background: #ffffff; - z-index: 10; - position: absolute; - outline: none; - - > div { - height: 100%; - display: flex; - flex-direction: column; - } -} - -.@{prefixClass}-year-panel-hidden { - display: none; -} - -.@{prefixClass}-year-panel-header { - padding: 0 10px; - height: 34px; - line-height: 30px; - position: relative; - text-align: center; - user-select: none; - -webkit-user-select: none; - border-bottom: 1px solid #ccc; - - > a { - font-weight: bold; - display: inline-block; - padding: 4px 5px; - text-align: center; - width: 30px; - - &:hover { - cursor: pointer; - color: #23c0fa; - } - } -} - -.@{prefixClass}-year-panel-prev-decade-btn, -.@{prefixClass}-year-panel-next-decade-btn { - position: absolute; - top: 0; -} - -.@{prefixClass}-year-panel-next-decade-btn { - &:after { - content: '»'; - } -} - -.@{prefixClass}-year-panel-prev-decade-btn { - user-select: none; - left: 0; - - &:after { - content: '«'; - } -} - -.@{prefixClass}-year-panel .@{prefixClass}-year-panel-decade-select { - width: 180px; -} - -.@{prefixClass}-year-panel-decade-select-arrow { - display: none; -} - -.@{prefixClass}-year-panel-next-decade-btn { - user-select: none; - right: 0; -} - -.@{prefixClass}-year-panel-body { - flex: 1; - padding: 9px 10px 10px; -} - -.@{prefixClass}-year-panel-footer { - border-top: 1px solid #ccc; - line-height: 38px; -} - -.@{prefixClass}-year-panel-table { - table-layout: fixed; - width: 100%; - height: 100%; - border-collapse: separate; -} - -.@{prefixClass}-year-panel-cell { - text-align: center; -} - -.@{prefixClass}-year-panel-year { - display: block; - width: 46px; - margin: 0 auto; - color: #666; - border-radius: 4px 4px; - height: 36px; - padding: 0; - background: transparent; - line-height: 36px; - text-align: center; - - &:hover { - background: #ebfaff; - cursor: pointer; - } -} - -.@{prefixClass}-year-panel-selected-cell .@{prefixClass}-year-panel-year { - background: #3fc7fa; - color: #fff; - - &:hover { - background: #3fc7fa; - color: #fff; - } -} - -.@{prefixClass}-year-panel-last-decade-cell, -.@{prefixClass}-year-panel-next-decade-cell { - .@{prefixClass}-year-panel-year { - user-select: none; - -webkit-user-select: none; - color: rgba(0, 0, 0, 0.25); - } -} diff --git a/components/vc-calendar/index.js b/components/vc-calendar/index.js deleted file mode 100644 index 56945f6d2..000000000 --- a/components/vc-calendar/index.js +++ /dev/null @@ -1,4 +0,0 @@ -// based on rc-calendar 9.15.10 -import Calendar from './src/'; - -export default Calendar; diff --git a/components/vc-calendar/src/Calendar.jsx b/components/vc-calendar/src/Calendar.jsx deleted file mode 100644 index 67a32bbde..000000000 --- a/components/vc-calendar/src/Calendar.jsx +++ /dev/null @@ -1,388 +0,0 @@ -import PropTypes from '../../_util/vue-types'; -import BaseMixin from '../../_util/BaseMixin'; -import { getOptionProps, hasProp, getComponent, findDOMNode } from '../../_util/props-util'; -import { cloneElement } from '../../_util/vnode'; -import KeyCode from '../../_util/KeyCode'; -import moment from 'moment'; -import DateTable from './date/DateTable'; -import CalendarHeader from './calendar/CalendarHeader'; -import CalendarFooter from './calendar/CalendarFooter'; -import CalendarMixin, { getNowByCurrentStateValue } from './mixin/CalendarMixin'; -import CommonMixin from './mixin/CommonMixin'; -import DateInput from './date/DateInput'; -import enUs from './locale/en_US'; -import { getTimeConfig, getTodayTime, syncTime } from './util'; -import { goStartMonth, goEndMonth, goTime } from './util/toTime'; -import { defineComponent } from 'vue'; - -const getMomentObjectIfValid = date => { - if (moment.isMoment(date) && date.isValid()) { - return date; - } - return false; -}; - -const Calendar = defineComponent({ - name: 'Calendar', - mixins: [BaseMixin, CommonMixin, CalendarMixin], - inheritAttrs: false, - props: { - locale: PropTypes.object.def(enUs), - format: PropTypes.oneOfType([ - PropTypes.string, - PropTypes.arrayOf(PropTypes.string), - PropTypes.func, - ]), - visible: PropTypes.looseBool.def(true), - prefixCls: PropTypes.string.def('rc-calendar'), - // prefixCls: PropTypes.string, - defaultValue: PropTypes.object, - value: PropTypes.object, - selectedValue: PropTypes.object, - defaultSelectedValue: PropTypes.object, - mode: PropTypes.oneOf(['time', 'date', 'month', 'year', 'decade']), - // locale: PropTypes.object, - showDateInput: PropTypes.looseBool.def(true), - showWeekNumber: PropTypes.looseBool, - showToday: PropTypes.looseBool.def(true), - showOk: PropTypes.looseBool, - // onSelect: PropTypes.func, - // onOk: PropTypes.func, - // onKeyDown: PropTypes.func, - timePicker: PropTypes.any, - dateInputPlaceholder: PropTypes.any, - // onClear: PropTypes.func, - // onChange: PropTypes.func, - // onPanelChange: PropTypes.func, - disabledDate: PropTypes.func, - disabledTime: PropTypes.any, - dateRender: PropTypes.func, - renderFooter: PropTypes.func.def(() => null), - renderSidebar: PropTypes.func.def(() => null), - clearIcon: PropTypes.any, - focusablePanel: PropTypes.looseBool.def(true), - inputMode: PropTypes.string, - inputReadOnly: PropTypes.looseBool, - monthCellRender: PropTypes.func, - monthCellContentRender: PropTypes.func, - }, - - data() { - const props = this.$props; - return { - sMode: this.mode || 'date', - sValue: - getMomentObjectIfValid(props.value) || - getMomentObjectIfValid(props.defaultValue) || - moment(), - sSelectedValue: props.selectedValue || props.defaultSelectedValue, - }; - }, - watch: { - mode(val) { - this.setState({ sMode: val }); - }, - value(val) { - this.setState({ - sValue: - getMomentObjectIfValid(val) || - getMomentObjectIfValid(this.defaultValue) || - getNowByCurrentStateValue(this.sValue), - }); - }, - selectedValue(val) { - this.setState({ - sSelectedValue: val, - }); - }, - }, - mounted() { - this.$nextTick(() => { - this.saveFocusElement(DateInput.getInstance()); - }); - }, - methods: { - onPanelChange(value, mode) { - const { sValue } = this; - if (!hasProp(this, 'mode')) { - this.setState({ sMode: mode }); - } - this.__emit('panelChange', value || sValue, mode); - }, - onKeyDown(event) { - if (event.target.nodeName.toLowerCase() === 'input') { - return undefined; - } - const keyCode = event.keyCode; - // mac - const ctrlKey = event.ctrlKey || event.metaKey; - const { disabledDate, sValue: value } = this; - switch (keyCode) { - case KeyCode.DOWN: - this.goTime(1, 'weeks'); - event.preventDefault(); - return 1; - case KeyCode.UP: - this.goTime(-1, 'weeks'); - event.preventDefault(); - return 1; - case KeyCode.LEFT: - if (ctrlKey) { - this.goTime(-1, 'years'); - } else { - this.goTime(-1, 'days'); - } - event.preventDefault(); - return 1; - case KeyCode.RIGHT: - if (ctrlKey) { - this.goTime(1, 'years'); - } else { - this.goTime(1, 'days'); - } - event.preventDefault(); - return 1; - case KeyCode.HOME: - this.setValue(goStartMonth(value)); - event.preventDefault(); - return 1; - case KeyCode.END: - this.setValue(goEndMonth(value)); - event.preventDefault(); - return 1; - case KeyCode.PAGE_DOWN: - this.goTime(1, 'month'); - event.preventDefault(); - return 1; - case KeyCode.PAGE_UP: - this.goTime(-1, 'month'); - event.preventDefault(); - return 1; - case KeyCode.ENTER: - if (!disabledDate || !disabledDate(value)) { - this.onSelect(value, { - source: 'keyboard', - }); - } - event.preventDefault(); - return 1; - default: - this.__emit('keydown', event); - return 1; - } - }, - - onClear() { - this.onSelect(null); - this.__emit('clear'); - }, - - onOk() { - const { sSelectedValue } = this; - if (this.isAllowedDate(sSelectedValue)) { - this.__emit('ok', sSelectedValue); - } - }, - - onDateInputChange(value) { - this.onSelect(value, { - source: 'dateInput', - }); - }, - onDateInputSelect(value) { - this.onSelect(value, { - source: 'dateInputSelect', - }); - }, - onDateTableSelect(value) { - const { timePicker, sSelectedValue } = this; - if (!sSelectedValue && timePicker) { - const timePickerProps = getOptionProps(timePicker); - const timePickerDefaultValue = timePickerProps.defaultValue; - if (timePickerDefaultValue) { - syncTime(timePickerDefaultValue, value); - } - } - this.onSelect(value); - }, - onToday() { - const { sValue } = this; - const now = getTodayTime(sValue); - this.onSelect(now, { - source: 'todayButton', - }); - }, - - onBlur(event) { - setTimeout(() => { - const dateInput = DateInput.getInstance(); - const rootInstance = this.rootInstance; - - if ( - !rootInstance || - rootInstance.contains(document.activeElement) || - (dateInput && dateInput.contains(document.activeElement)) - ) { - // focused element is still part of Calendar - return; - } - - this.__emit('blur', event); - }, 0); - }, - - getRootDOMNode() { - return findDOMNode(this); - }, - openTimePicker() { - this.onPanelChange(null, 'time'); - }, - closeTimePicker() { - this.onPanelChange(null, 'date'); - }, - goTime(direction, unit) { - this.setValue(goTime(this.sValue, direction, unit)); - }, - }, - - render() { - const { - locale, - prefixCls, - disabledDate, - dateInputPlaceholder, - timePicker, - disabledTime, - showDateInput, - sValue, - sSelectedValue, - sMode, - renderFooter, - inputMode, - inputReadOnly, - monthCellRender, - monthCellContentRender, - $props: props, - } = this; - const clearIcon = getComponent(this, 'clearIcon'); - const showTimePicker = sMode === 'time'; - const disabledTimeConfig = - showTimePicker && disabledTime && timePicker - ? getTimeConfig(sSelectedValue, disabledTime) - : null; - - let timePickerEle = null; - - if (timePicker && showTimePicker) { - const timePickerOriginProps = getOptionProps(timePicker); - const timePickerProps = { - showHour: true, - showSecond: true, - showMinute: true, - ...timePickerOriginProps, - ...disabledTimeConfig, - value: sSelectedValue, - disabledTime, - onChange: this.onDateInputChange, - }; - - if (timePickerOriginProps.defaultValue !== undefined) { - timePickerProps.defaultOpenValue = timePickerOriginProps.defaultValue; - } - timePickerEle = cloneElement(timePicker, timePickerProps); - } - - const dateInputElement = showDateInput ? ( - - ) : null; - const children = []; - if (props.renderSidebar) { - children.push(props.renderSidebar()); - } - children.push( -
- {dateInputElement} -
- - {timePicker && showTimePicker ? ( -
-
{timePickerEle}
-
- ) : null} -
- -
- - -
-
, - ); - - return this.renderRoot({ - children, - class: props.showWeekNumber ? `${prefixCls}-week-number` : '', - }); - }, -}); - -export default Calendar; diff --git a/components/vc-calendar/src/FullCalendar.jsx b/components/vc-calendar/src/FullCalendar.jsx deleted file mode 100644 index ad75e191e..000000000 --- a/components/vc-calendar/src/FullCalendar.jsx +++ /dev/null @@ -1,164 +0,0 @@ -import moment from 'moment'; -import PropTypes from '../../_util/vue-types'; -import BaseMixin from '../../_util/BaseMixin'; -import { getOptionProps, hasProp } from '../../_util/props-util'; -import DateTable from './date/DateTable'; -import MonthTable from './month/MonthTable'; -import CalendarMixin, { getNowByCurrentStateValue } from './mixin/CalendarMixin'; -import CommonMixin from './mixin/CommonMixin'; -import CalendarHeader from './full-calendar/CalendarHeader'; -import enUs from './locale/en_US'; -import { defineComponent } from 'vue'; -const FullCalendar = defineComponent({ - name: 'FullCalendar', - mixins: [BaseMixin, CommonMixin, CalendarMixin], - inheritAttrs: false, - props: { - locale: PropTypes.object.def(enUs), - format: PropTypes.oneOfType([PropTypes.string, PropTypes.array, PropTypes.func]), - visible: PropTypes.looseBool.def(true), - prefixCls: PropTypes.string.def('rc-calendar'), - defaultType: PropTypes.string.def('date'), - type: PropTypes.string, - fullscreen: PropTypes.looseBool.def(false), - monthCellRender: PropTypes.func, - dateCellRender: PropTypes.func, - showTypeSwitch: PropTypes.looseBool.def(true), - Select: PropTypes.object.isRequired, - headerComponents: PropTypes.array, - headerComponent: PropTypes.object, // The whole header component - headerRender: PropTypes.func, - showHeader: PropTypes.looseBool.def(true), - disabledDate: PropTypes.func, - value: PropTypes.object, - defaultValue: PropTypes.object, - selectedValue: PropTypes.object, - defaultSelectedValue: PropTypes.object, - renderFooter: PropTypes.func.def(() => null), - renderSidebar: PropTypes.func.def(() => null), - }, - data() { - let type; - if (hasProp(this, 'type')) { - type = this.type; - } else { - type = this.defaultType; - } - const props = this.$props; - return { - sType: type, - sValue: props.value || props.defaultValue || moment(), - sSelectedValue: props.selectedValue || props.defaultSelectedValue, - }; - }, - watch: { - type(val) { - this.setState({ - sType: val, - }); - }, - value(val) { - const sValue = val || this.defaultValue || getNowByCurrentStateValue(this.sValue); - this.setState({ - sValue, - }); - }, - selectedValue(val) { - this.setState({ - sSelectedValue: val, - }); - }, - }, - methods: { - onMonthSelect(value) { - this.onSelect(value, { - target: 'month', - }); - }, - setType(type) { - if (!hasProp(this, 'type')) { - this.setState({ - sType: type, - }); - } - this.__emit('typeChange', type); - }, - }, - - render() { - const props = getOptionProps(this); - const { - locale, - prefixCls, - fullscreen, - showHeader, - headerComponent, - headerRender, - disabledDate, - } = props; - const { sValue: value, sType: type } = this; - - let header = null; - if (showHeader) { - if (headerRender) { - header = headerRender(value, type, locale); - } else { - const TheHeader = headerComponent || CalendarHeader; - const headerProps = { - ...props, - ...this.$attrs, - prefixCls: `${prefixCls}-full`, - type, - value, - onTypeChange: this.setType, - onValueChange: this.setValue, - key: 'calendar-header', - }; - header = ; - } - } - - const table = - type === 'date' ? ( - - ) : ( - - ); - - const children = [ - header, -
- {table} -
, - ]; - - const className = [`${prefixCls}-full`]; - - if (fullscreen) { - className.push(`${prefixCls}-fullscreen`); - } - - return this.renderRoot({ - children, - class: className.join(' '), - }); - }, -}); - -export default FullCalendar; diff --git a/components/vc-calendar/src/MonthCalendar.jsx b/components/vc-calendar/src/MonthCalendar.jsx deleted file mode 100644 index b0287b239..000000000 --- a/components/vc-calendar/src/MonthCalendar.jsx +++ /dev/null @@ -1,126 +0,0 @@ -import moment from 'moment'; -import PropTypes from '../../_util/vue-types'; -import BaseMixin from '../../_util/BaseMixin'; -import KeyCode from '../../_util/KeyCode'; -import CalendarHeader from './calendar/CalendarHeader'; -import CalendarFooter from './calendar/CalendarFooter'; -import CalendarMixin from './mixin/CalendarMixin'; -import CommonMixin from './mixin/CommonMixin'; -import enUs from './locale/en_US'; -import { defineComponent } from 'vue'; -const MonthCalendar = defineComponent({ - name: 'MonthCalendar', - mixins: [BaseMixin, CommonMixin, CalendarMixin], - inheritAttrs: false, - props: { - locale: PropTypes.object.def(enUs), - format: PropTypes.string, - visible: PropTypes.looseBool.def(true), - prefixCls: PropTypes.string.def('rc-calendar'), - monthCellRender: PropTypes.func, - value: PropTypes.object, - defaultValue: PropTypes.object, - selectedValue: PropTypes.object, - defaultSelectedValue: PropTypes.object, - disabledDate: PropTypes.func, - monthCellContentRender: PropTypes.func, - renderFooter: PropTypes.func.def(() => null), - renderSidebar: PropTypes.func.def(() => null), - }, - - data() { - const props = this.$props; - return { - mode: 'month', - sValue: props.value || props.defaultValue || moment(), - sSelectedValue: props.selectedValue || props.defaultSelectedValue, - }; - }, - methods: { - onKeyDown(event) { - const keyCode = event.keyCode; - const ctrlKey = event.ctrlKey || event.metaKey; - const stateValue = this.sValue; - const { disabledDate } = this; - let value = stateValue; - switch (keyCode) { - case KeyCode.DOWN: - value = stateValue.clone(); - value.add(3, 'months'); - break; - case KeyCode.UP: - value = stateValue.clone(); - value.add(-3, 'months'); - break; - case KeyCode.LEFT: - value = stateValue.clone(); - if (ctrlKey) { - value.add(-1, 'years'); - } else { - value.add(-1, 'months'); - } - break; - case KeyCode.RIGHT: - value = stateValue.clone(); - if (ctrlKey) { - value.add(1, 'years'); - } else { - value.add(1, 'months'); - } - break; - case KeyCode.ENTER: - if (!disabledDate || !disabledDate(stateValue)) { - this.onSelect(stateValue); - } - event.preventDefault(); - return 1; - default: - return undefined; - } - if (value !== stateValue) { - this.setValue(value); - event.preventDefault(); - return 1; - } - }, - - handlePanelChange(_, mode) { - if (mode !== 'date') { - this.setState({ mode }); - } - }, - }, - - render() { - const { mode, sValue: value, $props: props, $slots } = this; - const { prefixCls, locale, disabledDate } = props; - const monthCellRender = this.monthCellRender || $slots.monthCellRender; - const monthCellContentRender = this.monthCellContentRender || $slots.monthCellContentRender; - const renderFooter = this.renderFooter || $slots.renderFooter; - const children = ( -
-
- -
- -
- ); - return this.renderRoot({ - class: `${props.prefixCls}-month-calendar`, - children, - }); - }, -}); - -export default MonthCalendar; diff --git a/components/vc-calendar/src/Picker.jsx b/components/vc-calendar/src/Picker.jsx deleted file mode 100644 index ac463f250..000000000 --- a/components/vc-calendar/src/Picker.jsx +++ /dev/null @@ -1,245 +0,0 @@ -import PropTypes from '../../_util/vue-types'; -import BaseMixin from '../../_util/BaseMixin'; -import { getOptionProps, hasProp, getEvents, findDOMNode } from '../../_util/props-util'; -import { cloneElement } from '../../_util/vnode'; -import createChainedFunction from '../../_util/createChainedFunction'; -import KeyCode from '../../_util/KeyCode'; -import placements from './picker/placements'; -import Trigger from '../../vc-trigger'; -import moment from 'moment'; -import isNil from 'lodash-es/isNil'; -import { defineComponent } from 'vue'; -const TimeType = { - validator(value) { - if (Array.isArray(value)) { - return ( - value.length === 0 || value.findIndex(val => !isNil(val) && !moment.isMoment(val)) === -1 - ); - } else { - return isNil(value) || moment.isMoment(value); - } - }, -}; - -function refFn(field, component) { - this[field] = component; -} - -const Picker = defineComponent({ - name: 'Picker', - mixins: [BaseMixin], - inheritAttrs: false, - props: { - animation: PropTypes.oneOfType([PropTypes.func, PropTypes.string]), - disabled: PropTypes.looseBool, - transitionName: PropTypes.string, - format: PropTypes.oneOfType([PropTypes.string, PropTypes.array, PropTypes.func]), - // onChange: PropTypes.func, - // onOpenChange: PropTypes.func, - getCalendarContainer: PropTypes.func, - calendar: PropTypes.any, - open: PropTypes.looseBool, - defaultOpen: PropTypes.looseBool.def(false), - prefixCls: PropTypes.string.def('rc-calendar-picker'), - placement: PropTypes.any.def('bottomLeft'), - value: TimeType, - defaultValue: TimeType, - align: PropTypes.object.def(() => ({})), - dropdownClassName: PropTypes.string, - dateRender: PropTypes.func, - children: PropTypes.func, - }, - - data() { - const props = this.$props; - this.calendarElement = null; - this.saveCalendarRef = refFn.bind(this, 'calendarInstance'); - let open; - if (hasProp(this, 'open')) { - open = props.open; - } else { - open = props.defaultOpen; - } - const value = props.value || props.defaultValue; - return { - sOpen: open, - sValue: value, - }; - }, - watch: { - value(val) { - this.setState({ - sValue: val, - }); - }, - open(val) { - this.setState({ - sOpen: val, - }); - }, - }, - mounted() { - this.preSOpen = this.sOpen; - }, - updated() { - if (!this.preSOpen && this.sOpen) { - // setTimeout is for making sure saveCalendarRef happen before focusCalendar - this.focusTimeout = setTimeout(this.focusCalendar, 100); - } - this.preSOpen = this.sOpen; - }, - - beforeUnmount() { - clearTimeout(this.focusTimeout); - }, - methods: { - onCalendarKeyDown(event) { - if (event.keyCode === KeyCode.ESC) { - event.stopPropagation(); - this.closeCalendar(this.focus); - } - }, - - onCalendarSelect(value, cause = {}) { - const props = this.$props; - if (!hasProp(this, 'value')) { - this.setState({ - sValue: value, - }); - } - const calendarProps = getOptionProps(props.calendar); - if ( - cause.source === 'keyboard' || - cause.source === 'dateInputSelect' || - (!calendarProps.timePicker && cause.source !== 'dateInput') || - cause.source === 'todayButton' - ) { - this.closeCalendar(this.focus); - } - this.__emit('change', value); - }, - - onKeyDown(event) { - if (!this.sOpen && (event.keyCode === KeyCode.DOWN || event.keyCode === KeyCode.ENTER)) { - this.openCalendar(); - event.preventDefault(); - } - }, - - onCalendarOk() { - this.closeCalendar(this.focus); - }, - - onCalendarClear() { - this.closeCalendar(this.focus); - }, - - onCalendarBlur() { - this.setOpen(false); - }, - - onVisibleChange(open) { - this.setOpen(open); - }, - - getCalendarElement() { - const props = this.$props; - const calendarProps = getOptionProps(props.calendar); - const calendarEvents = getEvents(props.calendar); - const { sValue: value } = this; - const defaultValue = value; - const extraProps = { - ref: this.saveCalendarRef, - defaultValue: defaultValue || calendarProps.defaultValue, - selectedValue: value, - onKeydown: this.onCalendarKeyDown, - onOk: createChainedFunction(calendarEvents.onOk, this.onCalendarOk), - onSelect: createChainedFunction(calendarEvents.onSelect, this.onCalendarSelect), - onClear: createChainedFunction(calendarEvents.onClear, this.onCalendarClear), - onBlur: createChainedFunction(calendarEvents.onBlur, this.onCalendarBlur), - }; - - return cloneElement(props.calendar, extraProps); - }, - - setOpen(open, callback) { - if (this.sOpen !== open) { - if (!hasProp(this, 'open')) { - this.setState( - { - sOpen: open, - }, - callback, - ); - } - this.__emit('openChange', open); - } - }, - - openCalendar(callback) { - this.setOpen(true, callback); - }, - - closeCalendar(callback) { - this.setOpen(false, callback); - }, - - focus() { - if (!this.sOpen) { - findDOMNode(this).focus(); - } - }, - - focusCalendar() { - if (this.sOpen && !!this.calendarInstance) { - this.calendarInstance.focus(); - } - }, - }, - - render() { - const props = getOptionProps(this); - const { - prefixCls, - placement, - getCalendarContainer, - align, - animation, - disabled, - dropdownClassName, - transitionName, - } = props; - const { sValue, sOpen } = this; - const childrenState = { - value: sValue, - open: sOpen, - }; - const children = this.$slots.default(childrenState); - if (this.sOpen || !this.calendarElement) { - this.calendarElement = this.getCalendarElement(); - } - - return ( - - {cloneElement(children, { onKeydown: this.onKeyDown })} - - ); - }, -}); - -export default Picker; diff --git a/components/vc-calendar/src/RangeCalendar.jsx b/components/vc-calendar/src/RangeCalendar.jsx deleted file mode 100644 index 9787cc4cf..000000000 --- a/components/vc-calendar/src/RangeCalendar.jsx +++ /dev/null @@ -1,837 +0,0 @@ -import PropTypes from '../../_util/vue-types'; -import BaseMixin from '../../_util/BaseMixin'; -import { getOptionProps, hasProp, getComponent } from '../../_util/props-util'; -import moment from 'moment'; -import KeyCode from '../../_util/KeyCode'; -import CalendarPart from './range-calendar/CalendarPart'; -import TodayButton from './calendar/TodayButton'; -import OkButton from './calendar/OkButton'; -import TimePickerButton from './calendar/TimePickerButton'; -import CommonMixin from './mixin/CommonMixin'; -import enUs from './locale/en_US'; -import { syncTime, getTodayTime, isAllowedDate } from './util/'; -import { goTime, goStartMonth, goEndMonth, includesTime } from './util/toTime'; -import { defineComponent } from 'vue'; - -function noop() {} - -function isEmptyArray(arr) { - return Array.isArray(arr) && (arr.length === 0 || arr.every(i => !i)); -} - -function isArraysEqual(a, b) { - if (a === b) return true; - if (a === null || typeof a === 'undefined' || b === null || typeof b === 'undefined') { - return false; - } - if (a.length !== b.length) return false; - - for (let i = 0; i < a.length; ++i) { - if (a[i] !== b[i]) return false; - } - return true; -} - -function getValueFromSelectedValue(selectedValue) { - let [start, end] = selectedValue; - if (end && (start === undefined || start === null)) { - start = end.clone().subtract(1, 'month'); - } - - if (start && (end === undefined || end === null)) { - end = start.clone().add(1, 'month'); - } - return [start, end]; -} - -function normalizeAnchor(props, init) { - const selectedValue = props.selectedValue || (init && props.defaultSelectedValue); - const value = props.value || (init && props.defaultValue); - const normalizedValue = value - ? getValueFromSelectedValue(value) - : getValueFromSelectedValue(selectedValue); - return !isEmptyArray(normalizedValue) - ? normalizedValue - : init && [moment(), moment().add(1, 'months')]; -} - -function generateOptions(length, extraOptionGen) { - const arr = extraOptionGen ? extraOptionGen().concat() : []; - for (let value = 0; value < length; value++) { - if (arr.indexOf(value) === -1) { - arr.push(value); - } - } - return arr; -} - -function onInputSelect(direction, value, cause) { - if (!value) { - return; - } - const originalValue = this.sSelectedValue; - const selectedValue = originalValue.concat(); - const index = direction === 'left' ? 0 : 1; - selectedValue[index] = value; - if (selectedValue[0] && this.compare(selectedValue[0], selectedValue[1]) > 0) { - selectedValue[1 - index] = this.sShowTimePicker ? selectedValue[index] : undefined; - } - this.__emit('inputSelect', selectedValue); - this.fireSelectValueChange(selectedValue, null, cause || { source: 'dateInput' }); -} - -const RangeCalendar = defineComponent({ - name: 'RangeCalendar', - mixins: [BaseMixin, CommonMixin], - inheritAttrs: false, - props: { - locale: PropTypes.object.def(enUs), - visible: PropTypes.looseBool.def(true), - prefixCls: PropTypes.string.def('rc-calendar'), - dateInputPlaceholder: PropTypes.any, - seperator: PropTypes.string.def('~'), - defaultValue: PropTypes.any, - value: PropTypes.any, - hoverValue: PropTypes.any, - mode: PropTypes.arrayOf(PropTypes.oneOf(['time', 'date', 'month', 'year', 'decade'])), - showDateInput: PropTypes.looseBool.def(true), - timePicker: PropTypes.any, - showOk: PropTypes.looseBool, - showToday: PropTypes.looseBool.def(true), - defaultSelectedValue: PropTypes.array.def([]), - selectedValue: PropTypes.array, - showClear: PropTypes.looseBool, - showWeekNumber: PropTypes.looseBool, - // locale: PropTypes.object, - // onChange: PropTypes.func, - // onSelect: PropTypes.func, - // onValueChange: PropTypes.func, - // onHoverChange: PropTypes.func, - // onPanelChange: PropTypes.func, - format: PropTypes.oneOfType([ - PropTypes.string, - PropTypes.arrayOf(PropTypes.string), - PropTypes.func, - ]), - // onClear: PropTypes.func, - type: PropTypes.any.def('both'), - disabledDate: PropTypes.func, - disabledTime: PropTypes.func.def(noop), - renderFooter: PropTypes.func.def(() => null), - renderSidebar: PropTypes.func.def(() => null), - dateRender: PropTypes.func, - clearIcon: PropTypes.any, - inputReadOnly: PropTypes.looseBool, - }, - - data() { - const props = this.$props; - const selectedValue = props.selectedValue || props.defaultSelectedValue; - const value = normalizeAnchor(props, 1); - return { - sSelectedValue: selectedValue, - prevSelectedValue: selectedValue, - firstSelectedValue: null, - sHoverValue: props.hoverValue || [], - sValue: value, - sShowTimePicker: false, - sMode: props.mode || ['date', 'date'], - sPanelTriggerSource: '', // Trigger by which picker panel: 'start' & 'end' - }; - }, - watch: { - value() { - const newState = {}; - newState.sValue = normalizeAnchor(this.$props, 0); - this.setState(newState); - }, - hoverValue(val) { - if (!isArraysEqual(this.sHoverValue, val)) { - this.setState({ sHoverValue: val }); - } - }, - selectedValue(val) { - const newState = {}; - newState.sSelectedValue = val; - newState.prevSelectedValue = val; - this.setState(newState); - }, - mode(val) { - if (!isArraysEqual(this.sMode, val)) { - this.setState({ sMode: val }); - } - }, - }, - - methods: { - onDatePanelEnter() { - if (this.hasSelectedValue()) { - this.fireHoverValueChange(this.sSelectedValue.concat()); - } - }, - - onDatePanelLeave() { - if (this.hasSelectedValue()) { - this.fireHoverValueChange([]); - } - }, - - onSelect(value) { - const { type, sSelectedValue, prevSelectedValue, firstSelectedValue } = this; - let nextSelectedValue; - if (type === 'both') { - if (!firstSelectedValue) { - syncTime(prevSelectedValue[0], value); - nextSelectedValue = [value]; - } else if (this.compare(firstSelectedValue, value) < 0) { - syncTime(prevSelectedValue[1], value); - nextSelectedValue = [firstSelectedValue, value]; - } else { - syncTime(prevSelectedValue[0], value); - syncTime(prevSelectedValue[1], firstSelectedValue); - nextSelectedValue = [value, firstSelectedValue]; - } - } else if (type === 'start') { - syncTime(prevSelectedValue[0], value); - const endValue = sSelectedValue[1]; - nextSelectedValue = - endValue && this.compare(endValue, value) > 0 ? [value, endValue] : [value]; - } else { - // type === 'end' - const startValue = sSelectedValue[0]; - if (startValue && this.compare(startValue, value) <= 0) { - syncTime(prevSelectedValue[1], value); - nextSelectedValue = [startValue, value]; - } else { - syncTime(prevSelectedValue[0], value); - nextSelectedValue = [value]; - } - } - - this.fireSelectValueChange(nextSelectedValue); - }, - - onKeyDown(event) { - if (event.target.nodeName.toLowerCase() === 'input') { - return; - } - - const { keyCode } = event; - const ctrlKey = event.ctrlKey || event.metaKey; - - const { - sSelectedValue: selectedValue, - sHoverValue: hoverValue, - firstSelectedValue, - sValue: value, // Value is used for `CalendarPart` current page - } = this.$data; - const { disabledDate } = this.$props; - - // Update last time of the picker - const updateHoverPoint = func => { - // Change hover to make focus in UI - let currentHoverTime; - let nextHoverTime; - let nextHoverValue; - - if (!firstSelectedValue) { - currentHoverTime = hoverValue[0] || selectedValue[0] || value[0] || moment(); - nextHoverTime = func(currentHoverTime); - nextHoverValue = [nextHoverTime]; - this.fireHoverValueChange(nextHoverValue); - } else { - if (hoverValue.length === 1) { - currentHoverTime = hoverValue[0].clone(); - nextHoverTime = func(currentHoverTime); - nextHoverValue = this.onDayHover(nextHoverTime); - } else { - currentHoverTime = hoverValue[0].isSame(firstSelectedValue, 'day') - ? hoverValue[1] - : hoverValue[0]; - nextHoverTime = func(currentHoverTime); - nextHoverValue = this.onDayHover(nextHoverTime); - } - } - - // Find origin hover time on value index - if (nextHoverValue.length >= 2) { - const miss = nextHoverValue.some(ht => !includesTime(value, ht, 'month')); - if (miss) { - const newValue = nextHoverValue.slice().sort((t1, t2) => t1.valueOf() - t2.valueOf()); - if (newValue[0].isSame(newValue[1], 'month')) { - newValue[1] = newValue[0].clone().add(1, 'month'); - } - this.fireValueChange(newValue); - } - } else if (nextHoverValue.length === 1) { - // If only one value, let's keep the origin panel - let oriValueIndex = value.findIndex(time => time.isSame(currentHoverTime, 'month')); - if (oriValueIndex === -1) oriValueIndex = 0; - - if (value.every(time => !time.isSame(nextHoverTime, 'month'))) { - const newValue = value.slice(); - newValue[oriValueIndex] = nextHoverTime.clone(); - this.fireValueChange(newValue); - } - } - - event.preventDefault(); - - return nextHoverTime; - }; - - switch (keyCode) { - case KeyCode.DOWN: - updateHoverPoint(time => goTime(time, 1, 'weeks')); - return; - case KeyCode.UP: - updateHoverPoint(time => goTime(time, -1, 'weeks')); - return; - case KeyCode.LEFT: - if (ctrlKey) { - updateHoverPoint(time => goTime(time, -1, 'years')); - } else { - updateHoverPoint(time => goTime(time, -1, 'days')); - } - return; - case KeyCode.RIGHT: - if (ctrlKey) { - updateHoverPoint(time => goTime(time, 1, 'years')); - } else { - updateHoverPoint(time => goTime(time, 1, 'days')); - } - return; - case KeyCode.HOME: - updateHoverPoint(time => goStartMonth(time)); - return; - case KeyCode.END: - updateHoverPoint(time => goEndMonth(time)); - return; - case KeyCode.PAGE_DOWN: - updateHoverPoint(time => goTime(time, 1, 'month')); - return; - case KeyCode.PAGE_UP: - updateHoverPoint(time => goTime(time, -1, 'month')); - return; - case KeyCode.ENTER: { - let lastValue; - if (hoverValue.length === 0) { - lastValue = updateHoverPoint(time => time); - } else if (hoverValue.length === 1) { - lastValue = hoverValue[0]; - } else { - lastValue = hoverValue[0].isSame(firstSelectedValue, 'day') - ? hoverValue[1] - : hoverValue[0]; - } - if (lastValue && (!disabledDate || !disabledDate(lastValue))) { - this.onSelect(lastValue); - } - event.preventDefault(); - return; - } - default: - this.__emit('keydown', event); - } - }, - - onDayHover(value) { - let hoverValue = []; - const { sSelectedValue, firstSelectedValue, type } = this; - if (type === 'start' && sSelectedValue[1]) { - hoverValue = - this.compare(value, sSelectedValue[1]) < 0 ? [value, sSelectedValue[1]] : [value]; - } else if (type === 'end' && sSelectedValue[0]) { - hoverValue = this.compare(value, sSelectedValue[0]) > 0 ? [sSelectedValue[0], value] : []; - } else { - if (!firstSelectedValue) { - if (this.sHoverValue.length) { - this.setState({ sHoverValue: [] }); - } - return hoverValue; - } - hoverValue = - this.compare(value, firstSelectedValue) < 0 - ? [value, firstSelectedValue] - : [firstSelectedValue, value]; - } - this.fireHoverValueChange(hoverValue); - return hoverValue; - }, - - onToday() { - const startValue = getTodayTime(this.sValue[0]); - const endValue = startValue.clone().add(1, 'months'); - this.setState({ sValue: [startValue, endValue] }); - }, - - onOpenTimePicker() { - this.setState({ - sShowTimePicker: true, - }); - }, - onCloseTimePicker() { - this.setState({ - sShowTimePicker: false, - }); - }, - - onOk() { - const { sSelectedValue } = this; - if (this.isAllowedDateAndTime(sSelectedValue)) { - this.__emit('ok', sSelectedValue); - } - }, - - onStartInputChange(...oargs) { - const args = ['left'].concat(oargs); - return onInputSelect.apply(this, args); - }, - - onEndInputChange(...oargs) { - const args = ['right'].concat(oargs); - return onInputSelect.apply(this, args); - }, - - onStartInputSelect(value) { - const args = ['left', value, { source: 'dateInputSelect' }]; - return onInputSelect.apply(this, args); - }, - - onEndInputSelect(value) { - const args = ['right', value, { source: 'dateInputSelect' }]; - return onInputSelect.apply(this, args); - }, - - onStartValueChange(leftValue) { - const value = [...this.sValue]; - value[0] = leftValue; - return this.fireValueChange(value); - }, - - onEndValueChange(rightValue) { - const value = [...this.sValue]; - value[1] = rightValue; - return this.fireValueChange(value); - }, - - onStartPanelChange(value, mode) { - const { sMode, sValue } = this; - const newMode = [mode, sMode[1]]; - const newValue = [value || sValue[0], sValue[1]]; - this.__emit('panelChange', newValue, newMode); - const newState = { - sPanelTriggerSource: 'start', - }; - if (!hasProp(this, 'mode')) { - newState.sMode = newMode; - } - this.setState(newState); - }, - - onEndPanelChange(value, mode) { - const { sMode, sValue } = this; - const newMode = [sMode[0], mode]; - const newValue = [sValue[0], value || sValue[1]]; - this.__emit('panelChange', newValue, newMode); - const newState = { - sPanelTriggerSource: 'end', - }; - if (!hasProp(this, 'mode')) { - newState.sMode = newMode; - } - this.setState(newState); - }, - - getStartValue() { - const { - sSelectedValue: selectedValue, - sShowTimePicker: showTimePicker, - sValue: value, - sMode: mode, - sPanelTriggerSource: panelTriggerSource, - } = this.$data; - let startValue = value[0]; - // keep selectedTime when select date - if (selectedValue[0] && this.$props.timePicker) { - startValue = startValue.clone(); - syncTime(selectedValue[0], startValue); - } - if (showTimePicker && selectedValue[0]) { - startValue = selectedValue[0]; - } - - // Adjust month if date not align - if ( - panelTriggerSource === 'end' && - mode[0] === 'date' && - mode[1] === 'date' && - startValue.isSame(value[1], 'month') - ) { - startValue = startValue.clone().subtract(1, 'month'); - } - - return startValue; - }, - - getEndValue() { - const { - sSelectedValue: selectedValue, - sShowTimePicker: showTimePicker, - sValue: value, - sMode: mode, - sPanelTriggerSource: panelTriggerSource, - } = this.$data; - let endValue = value[1] ? value[1].clone() : value[0].clone().add(1, 'month'); - // keep selectedTime when select date - if (selectedValue[1] && this.$props.timePicker) { - syncTime(selectedValue[1], endValue); - } - if (showTimePicker) { - endValue = selectedValue[1] ? selectedValue[1] : this.getStartValue(); - } - - // Adjust month if date not align - if ( - !showTimePicker && - panelTriggerSource !== 'end' && - mode[0] === 'date' && - mode[1] === 'date' && - endValue.isSame(value[0], 'month') - ) { - endValue = endValue.clone().add(1, 'month'); - } - - return endValue; - }, - // get disabled hours for second picker - getEndDisableTime() { - const { sSelectedValue, sValue, disabledTime } = this; - const userSettingDisabledTime = disabledTime(sSelectedValue, 'end') || {}; - const startValue = (sSelectedValue && sSelectedValue[0]) || sValue[0].clone(); - // if startTime and endTime is same day.. - // the second time picker will not able to pick time before first time picker - if (!sSelectedValue[1] || startValue.isSame(sSelectedValue[1], 'day')) { - const hours = startValue.hour(); - const minutes = startValue.minute(); - const second = startValue.second(); - let { disabledHours, disabledMinutes, disabledSeconds } = userSettingDisabledTime; - const oldDisabledMinutes = disabledMinutes ? disabledMinutes() : []; - const olddisabledSeconds = disabledSeconds ? disabledSeconds() : []; - disabledHours = generateOptions(hours, disabledHours); - disabledMinutes = generateOptions(minutes, disabledMinutes); - disabledSeconds = generateOptions(second, disabledSeconds); - return { - disabledHours() { - return disabledHours; - }, - disabledMinutes(hour) { - if (hour === hours) { - return disabledMinutes; - } - return oldDisabledMinutes; - }, - disabledSeconds(hour, minute) { - if (hour === hours && minute === minutes) { - return disabledSeconds; - } - return olddisabledSeconds; - }, - }; - } - return userSettingDisabledTime; - }, - - isAllowedDateAndTime(selectedValue) { - return ( - isAllowedDate(selectedValue[0], this.disabledDate, this.disabledStartTime) && - isAllowedDate(selectedValue[1], this.disabledDate, this.disabledEndTime) - ); - }, - - isMonthYearPanelShow(mode) { - return ['month', 'year', 'decade'].indexOf(mode) > -1; - }, - - hasSelectedValue() { - const { sSelectedValue } = this; - return !!sSelectedValue[1] && !!sSelectedValue[0]; - }, - - compare(v1, v2) { - if (this.timePicker) { - return v1.diff(v2); - } - return v1.diff(v2, 'days'); - }, - - fireSelectValueChange(selectedValue, direct, cause) { - const { timePicker, prevSelectedValue } = this; - if (timePicker) { - const timePickerProps = getOptionProps(timePicker); - if (timePickerProps.defaultValue) { - const timePickerDefaultValue = timePickerProps.defaultValue; - if (!prevSelectedValue[0] && selectedValue[0]) { - syncTime(timePickerDefaultValue[0], selectedValue[0]); - } - if (!prevSelectedValue[1] && selectedValue[1]) { - syncTime(timePickerDefaultValue[1], selectedValue[1]); - } - } - } - // 尚未选择过时间,直接输入的话 - if (!this.sSelectedValue[0] || !this.sSelectedValue[1]) { - const startValue = selectedValue[0] || moment(); - const endValue = selectedValue[1] || startValue.clone().add(1, 'months'); - this.setState({ - sSelectedValue: selectedValue, - sValue: - selectedValue && selectedValue.length === 2 - ? getValueFromSelectedValue([startValue, endValue]) - : this.sValue, - }); - } - - if (selectedValue[0] && !selectedValue[1]) { - this.setState({ firstSelectedValue: selectedValue[0] }); - this.fireHoverValueChange(selectedValue.concat()); - } - this.__emit('change', selectedValue); - if (direct || (selectedValue[0] && selectedValue[1])) { - this.setState({ - prevSelectedValue: selectedValue, - firstSelectedValue: null, - }); - this.fireHoverValueChange([]); - this.__emit('select', selectedValue, cause); - } - if (!hasProp(this, 'selectedValue')) { - this.setState({ - sSelectedValue: selectedValue, - }); - } - }, - - fireValueChange(value) { - if (!hasProp(this, 'value')) { - this.setState({ - sValue: value, - }); - } - this.__emit('valueChange', value); - }, - - fireHoverValueChange(hoverValue) { - if (!hasProp(this, 'hoverValue')) { - this.setState({ sHoverValue: hoverValue }); - } - this.__emit('hoverChange', hoverValue); - }, - - clear() { - this.fireSelectValueChange([], true); - this.__emit('clear'); - }, - - disabledStartTime(time) { - return this.disabledTime(time, 'start'); - }, - - disabledEndTime(time) { - return this.disabledTime(time, 'end'); - }, - - disabledStartMonth(month) { - const { sValue } = this; - return month.isAfter(sValue[1], 'month'); - }, - - disabledEndMonth(month) { - const { sValue } = this; - return month.isBefore(sValue[0], 'month'); - }, - }, - - render() { - const props = getOptionProps(this); - const { - prefixCls, - dateInputPlaceholder, - timePicker, - showOk, - locale, - showClear, - showToday, - type, - seperator, - } = props; - const clearIcon = getComponent(this, 'clearIcon'); - const { sHoverValue, sSelectedValue, sMode: mode, sShowTimePicker, sValue } = this; - const className = { - [this.$attrs.class]: !!this.$attrs.class, - [prefixCls]: 1, - [`${prefixCls}-hidden`]: !props.visible, - [`${prefixCls}-range`]: 1, - [`${prefixCls}-show-time-picker`]: sShowTimePicker, - [`${prefixCls}-week-number`]: props.showWeekNumber, - }; - const baseProps = { - ...props, - ...this.$attrs, - }; - const newProps = { - selectedValue: sSelectedValue, - onSelect: this.onSelect, - onDayHover: - (type === 'start' && sSelectedValue[1]) || - (type === 'end' && sSelectedValue[0]) || - !!sHoverValue.length - ? this.onDayHover - : noop, - }; - - let placeholder1; - let placeholder2; - - if (dateInputPlaceholder) { - if (Array.isArray(dateInputPlaceholder)) { - [placeholder1, placeholder2] = dateInputPlaceholder; - } else { - placeholder1 = placeholder2 = dateInputPlaceholder; - } - } - const showOkButton = showOk === true || (showOk !== false && !!timePicker); - const cls = { - [`${prefixCls}-footer`]: true, - [`${prefixCls}-range-bottom`]: true, - [`${prefixCls}-footer-show-ok`]: showOkButton, - }; - - const startValue = this.getStartValue(); - const endValue = this.getEndValue(); - const todayTime = getTodayTime(startValue); - const thisMonth = todayTime.month(); - const thisYear = todayTime.year(); - const isTodayInView = - (startValue.year() === thisYear && startValue.month() === thisMonth) || - (endValue.year() === thisYear && endValue.month() === thisMonth); - const nextMonthOfStart = startValue.clone().add(1, 'months'); - const isClosestMonths = - nextMonthOfStart.year() === endValue.year() && nextMonthOfStart.month() === endValue.month(); - const leftPartProps = { - ...baseProps, - ...newProps, - hoverValue: sHoverValue, - direction: 'left', - disabledTime: this.disabledStartTime, - disabledMonth: this.disabledStartMonth, - format: this.getFormat(), - value: startValue, - mode: mode[0], - placeholder: placeholder1, - showDateInput: this.showDateInput, - timePicker, - showTimePicker: sShowTimePicker || mode[0] === 'time', - enablePrev: true, - enableNext: !isClosestMonths || this.isMonthYearPanelShow(mode[1]), - clearIcon, - onInputChange: this.onStartInputChange, - onInputSelect: this.onStartInputSelect, - onValueChange: this.onStartValueChange, - onPanelChange: this.onStartPanelChange, - }; - const rightPartProps = { - ...baseProps, - ...newProps, - hoverValue: sHoverValue, - direction: 'right', - format: this.getFormat(), - timePickerDisabledTime: this.getEndDisableTime(), - placeholder: placeholder2, - value: endValue, - mode: mode[1], - showDateInput: this.showDateInput, - timePicker, - showTimePicker: sShowTimePicker || mode[1] === 'time', - disabledTime: this.disabledEndTime, - disabledMonth: this.disabledEndMonth, - enablePrev: !isClosestMonths || this.isMonthYearPanelShow(mode[0]), - enableNext: true, - clearIcon, - onInputChange: this.onEndInputChange, - onInputSelect: this.onEndInputSelect, - onValueChange: this.onEndValueChange, - onPanelChange: this.onEndPanelChange, - }; - let TodayButtonNode = null; - if (showToday) { - const todayButtonProps = { - ...baseProps, - disabled: isTodayInView, - value: sValue[0], - text: locale.backToToday, - onToday: this.onToday, - }; - TodayButtonNode = ; - } - - let TimePickerButtonNode = null; - if (props.timePicker) { - const timePickerButtonProps = { - ...baseProps, - showTimePicker: sShowTimePicker || (mode[0] === 'time' && mode[1] === 'time'), - timePickerDisabled: !this.hasSelectedValue() || sHoverValue.length, - onOpenTimePicker: this.onOpenTimePicker, - onCloseTimePicker: this.onCloseTimePicker, - }; - TimePickerButtonNode = ; - } - - let OkButtonNode = null; - if (showOkButton) { - const okButtonProps = { - ...baseProps, - okDisabled: - !this.isAllowedDateAndTime(sSelectedValue) || - !this.hasSelectedValue() || - sHoverValue.length, - onOk: this.onOk, - }; - OkButtonNode = ; - } - const extraFooter = this.renderFooter(mode); - return ( -
- {props.renderSidebar()} -
- {showClear && sSelectedValue[0] && sSelectedValue[1] ? ( - - {clearIcon || } - - ) : null} -
- - {seperator} - -
-
- {showToday || props.timePicker || showOkButton || extraFooter ? ( - - ) : null} -
-
-
- ); - }, -}); - -export default RangeCalendar; diff --git a/components/vc-calendar/src/calendar/CalendarFooter.jsx b/components/vc-calendar/src/calendar/CalendarFooter.jsx deleted file mode 100644 index ff365a4a0..000000000 --- a/components/vc-calendar/src/calendar/CalendarFooter.jsx +++ /dev/null @@ -1,86 +0,0 @@ -import PropTypes from '../../../_util/vue-types'; -import BaseMixin from '../../../_util/BaseMixin'; -import { getOptionProps, findDOMNode } from '../../../_util/props-util'; -import TodayButton from './TodayButton'; -import OkButton from './OkButton'; -import TimePickerButton from './TimePickerButton'; - -const CalendarFooter = { - name: 'CalendarFooter', - inheritAttrs: false, - mixins: [BaseMixin], - props: { - prefixCls: PropTypes.string, - showDateInput: PropTypes.looseBool, - disabledTime: PropTypes.any, - timePicker: PropTypes.any, - selectedValue: PropTypes.any, - showOk: PropTypes.looseBool, - // onSelect: PropTypes.func, - value: PropTypes.object, - renderFooter: PropTypes.func, - defaultValue: PropTypes.object, - locale: PropTypes.object, - showToday: PropTypes.looseBool, - disabledDate: PropTypes.func, - showTimePicker: PropTypes.looseBool, - okDisabled: PropTypes.looseBool, - mode: PropTypes.string, - }, - methods: { - onSelect(value) { - this.__emit('select', value); - }, - - getRootDOMNode() { - return findDOMNode(this); - }, - }, - - render() { - const props = getOptionProps(this); - const { value, prefixCls, showOk, timePicker, renderFooter, showToday, mode } = props; - let footerEl = null; - const extraFooter = renderFooter && renderFooter(mode); - if (showToday || timePicker || extraFooter) { - const btnProps = { - ...props, - ...this.$attrs, - value, - }; - let nowEl = null; - if (showToday) { - nowEl = ; - } - delete btnProps.value; - let okBtn = null; - if (showOk === true || (showOk !== false && !!timePicker)) { - okBtn = ; - } - let timePickerBtn = null; - if (timePicker) { - timePickerBtn = ; - } - - let footerBtn; - if (nowEl || timePickerBtn || okBtn || extraFooter) { - footerBtn = ( - - {extraFooter} - {nowEl} - {timePickerBtn} - {okBtn} - - ); - } - const cls = { - [`${prefixCls}-footer`]: true, - [`${prefixCls}-footer-show-ok`]: !!okBtn, - }; - footerEl =
{footerBtn}
; - } - return footerEl; - }, -}; - -export default CalendarFooter; diff --git a/components/vc-calendar/src/calendar/CalendarHeader.jsx b/components/vc-calendar/src/calendar/CalendarHeader.jsx deleted file mode 100644 index ffa238b3f..000000000 --- a/components/vc-calendar/src/calendar/CalendarHeader.jsx +++ /dev/null @@ -1,243 +0,0 @@ -import PropTypes from '../../../_util/vue-types'; -import BaseMixin from '../../../_util/BaseMixin'; -import { getOptionProps } from '../../../_util/props-util'; -import MonthPanel from '../month/MonthPanel'; -import YearPanel from '../year/YearPanel'; -import DecadePanel from '../decade/DecadePanel'; -function noop() {} -function goMonth(direction) { - const next = this.value.clone(); - next.add(direction, 'months'); - this.__emit('valueChange', next); -} - -function goYear(direction) { - const next = this.value.clone(); - next.add(direction, 'years'); - this.__emit('valueChange', next); -} - -function showIf(condition, el) { - return condition ? el : null; -} - -const CalendarHeader = { - name: 'CalendarHeader', - inheritAttrs: false, - mixins: [BaseMixin], - props: { - prefixCls: PropTypes.string, - value: PropTypes.object, - // onValueChange: PropTypes.func, - showTimePicker: PropTypes.looseBool, - // onPanelChange: PropTypes.func, - locale: PropTypes.object, - enablePrev: PropTypes.any.def(1), - enableNext: PropTypes.any.def(1), - disabledMonth: PropTypes.func, - mode: PropTypes.any, - monthCellRender: PropTypes.func, - monthCellContentRender: PropTypes.func, - renderFooter: PropTypes.func, - }, - data() { - this.nextMonth = goMonth.bind(this, 1); - this.previousMonth = goMonth.bind(this, -1); - this.nextYear = goYear.bind(this, 1); - this.previousYear = goYear.bind(this, -1); - return { - yearPanelReferer: null, - }; - }, - methods: { - onMonthSelect(value) { - this.__emit('panelChange', value, 'date'); - if (this.$attrs.onMonthSelect) { - this.__emit('monthSelect', value); - } else { - this.__emit('valueChange', value); - } - }, - - onYearSelect(value) { - const referer = this.yearPanelReferer; - this.setState({ yearPanelReferer: null }); - this.__emit('panelChange', value, referer); - this.__emit('valueChange', value); - }, - - onDecadeSelect(value) { - this.__emit('panelChange', value, 'year'); - this.__emit('valueChange', value); - }, - - changeYear(direction) { - if (direction > 0) { - this.nextYear(); - } else { - this.previousYear(); - } - }, - - monthYearElement(showTimePicker) { - const props = this.$props; - const prefixCls = props.prefixCls; - const locale = props.locale; - const value = props.value; - const localeData = value.localeData(); - const monthBeforeYear = locale.monthBeforeYear; - const selectClassName = `${prefixCls}-${monthBeforeYear ? 'my-select' : 'ym-select'}`; - const timeClassName = showTimePicker ? ` ${prefixCls}-time-status` : ''; - const year = ( - this.showYearPanel('date')} - title={showTimePicker ? null : locale.yearSelect} - > - {value.format(locale.yearFormat)} - - ); - const month = ( - - {locale.monthFormat ? value.format(locale.monthFormat) : localeData.monthsShort(value)} - - ); - let day; - if (showTimePicker) { - day = ( - - {value.format(locale.dayFormat)} - - ); - } - let my = []; - if (monthBeforeYear) { - my = [month, day, year]; - } else { - my = [year, month, day]; - } - return {my}; - }, - - showMonthPanel() { - // null means that users' interaction doesn't change value - this.__emit('panelChange', null, 'month'); - }, - - showYearPanel(referer) { - this.setState({ yearPanelReferer: referer }); - this.__emit('panelChange', null, 'year'); - }, - - showDecadePanel() { - this.__emit('panelChange', null, 'decade'); - }, - }, - - render() { - const props = getOptionProps(this); - const { - prefixCls, - locale, - mode, - value, - showTimePicker, - enableNext, - enablePrev, - disabledMonth, - renderFooter, - } = props; - - let panel = null; - if (mode === 'month') { - panel = ( - this.showYearPanel('month')} - disabledDate={disabledMonth} - cellRender={props.monthCellRender} - contentRender={props.monthCellContentRender} - renderFooter={renderFooter} - changeYear={this.changeYear} - /> - ); - } - if (mode === 'year') { - panel = ( - - ); - } - if (mode === 'decade') { - panel = ( - - ); - } - - return ( - - ); - }, -}; - -export default CalendarHeader; diff --git a/components/vc-calendar/src/calendar/OkButton.jsx b/components/vc-calendar/src/calendar/OkButton.jsx deleted file mode 100644 index 404beb0b9..000000000 --- a/components/vc-calendar/src/calendar/OkButton.jsx +++ /dev/null @@ -1,16 +0,0 @@ -function noop() {} -const OkButton = (_, { attrs }) => { - const { prefixCls, locale, okDisabled, onOk } = attrs; - let className = `${prefixCls}-ok-btn`; - if (okDisabled) { - className += ` ${prefixCls}-ok-btn-disabled`; - } - return ( - - {locale.ok} - - ); -}; - -OkButton.inheritAttrs = false; -export default OkButton; diff --git a/components/vc-calendar/src/calendar/TimePickerButton.jsx b/components/vc-calendar/src/calendar/TimePickerButton.jsx deleted file mode 100644 index 80efc9c7e..000000000 --- a/components/vc-calendar/src/calendar/TimePickerButton.jsx +++ /dev/null @@ -1,27 +0,0 @@ -function noop() {} -const TimePickerButton = (_, { attrs }) => { - const { - prefixCls, - locale, - showTimePicker, - timePickerDisabled, - onCloseTimePicker = noop, - onOpenTimePicker = noop, - } = attrs; - const className = { - [`${prefixCls}-time-picker-btn`]: true, - [`${prefixCls}-time-picker-btn-disabled`]: timePickerDisabled, - }; - let onClick = noop; - if (!timePickerDisabled) { - onClick = showTimePicker ? onCloseTimePicker : onOpenTimePicker; - } - return ( - - {showTimePicker ? locale.dateSelect : locale.timeSelect} - - ); -}; - -TimePickerButton.inheritAttrs = false; -export default TimePickerButton; diff --git a/components/vc-calendar/src/calendar/TodayButton.jsx b/components/vc-calendar/src/calendar/TodayButton.jsx deleted file mode 100644 index 7f94ab65c..000000000 --- a/components/vc-calendar/src/calendar/TodayButton.jsx +++ /dev/null @@ -1,23 +0,0 @@ -import { getTodayTimeStr, getTodayTime, isAllowedDate } from '../util/'; -function noop() {} -const TodayButton = (_, { attrs }) => { - const { prefixCls, locale, value, timePicker, disabled, disabledDate, onToday, text } = attrs; - const localeNow = (!text && timePicker ? locale.now : text) || locale.today; - const disabledToday = disabledDate && !isAllowedDate(getTodayTime(value), disabledDate); - const isDisabled = disabledToday || disabled; - const disabledTodayClass = isDisabled ? `${prefixCls}-today-btn-disabled` : ''; - return ( - - {localeNow} - - ); -}; - -TodayButton.inheritAttrs = false; - -export default TodayButton; diff --git a/components/vc-calendar/src/date/DateConstants.js b/components/vc-calendar/src/date/DateConstants.js deleted file mode 100644 index 55f910b00..000000000 --- a/components/vc-calendar/src/date/DateConstants.js +++ /dev/null @@ -1,4 +0,0 @@ -export default { - DATE_ROW_COUNT: 6, - DATE_COL_COUNT: 7, -}; diff --git a/components/vc-calendar/src/date/DateInput.jsx b/components/vc-calendar/src/date/DateInput.jsx deleted file mode 100644 index 1524694b1..000000000 --- a/components/vc-calendar/src/date/DateInput.jsx +++ /dev/null @@ -1,226 +0,0 @@ -import PropTypes from '../../../_util/vue-types'; -import BaseMixin from '../../../_util/BaseMixin'; -import { getComponent, findDOMNode } from '../../../_util/props-util'; -import moment from 'moment'; -import { formatDate } from '../util'; -import KeyCode from '../../../_util/KeyCode'; -import { withDirectives } from 'vue'; -import antInput from '../../../_util/antInputDirective'; - -let cachedSelectionStart; -let cachedSelectionEnd; -let dateInputInstance; - -const DateInput = { - name: 'DateInput', - inheritAttrs: false, - mixins: [BaseMixin], - props: { - prefixCls: PropTypes.string, - timePicker: PropTypes.object, - value: PropTypes.object, - disabledTime: PropTypes.any, - format: PropTypes.oneOfType([ - PropTypes.string, - PropTypes.arrayOf(PropTypes.string), - PropTypes.func, - ]), - locale: PropTypes.object, - disabledDate: PropTypes.func, - // onChange: PropTypes.func, - // onClear: PropTypes.func, - placeholder: PropTypes.string, - // onSelect: PropTypes.func, - selectedValue: PropTypes.object, - clearIcon: PropTypes.any, - inputMode: PropTypes.string, - inputReadOnly: PropTypes.looseBool, - disabled: PropTypes.looseBool, - showClear: PropTypes.looseBool, - }, - - data() { - const selectedValue = this.selectedValue; - return { - str: formatDate(selectedValue, this.format), - invalid: false, - hasFocus: false, - }; - }, - watch: { - selectedValue() { - this.setState(); - }, - format() { - this.setState(); - }, - }, - - updated() { - this.$nextTick(() => { - if ( - dateInputInstance && - this.$data.hasFocus && - !this.invalid && - !(cachedSelectionStart === 0 && cachedSelectionEnd === 0) - ) { - dateInputInstance.setSelectionRange(cachedSelectionStart, cachedSelectionEnd); - } - }); - }, - getInstance() { - return dateInputInstance; - }, - methods: { - getDerivedStateFromProps(nextProps, state) { - let newState = {}; - if (dateInputInstance) { - cachedSelectionStart = dateInputInstance.selectionStart; - cachedSelectionEnd = dateInputInstance.selectionEnd; - } - // when popup show, click body will call this, bug! - const selectedValue = nextProps.selectedValue; - if (!state.hasFocus) { - newState = { - str: formatDate(selectedValue, this.format), - invalid: false, - }; - } - return newState; - }, - onClear() { - this.setState({ - str: '', - }); - this.__emit('clear', null); - }, - onInputChange(e) { - const { value: str, composing } = e.target; - const { str: oldStr = '' } = this; - if (e.isComposing || composing || oldStr === str) return; - - const { disabledDate, format, selectedValue } = this.$props; - - // 没有内容,合法并直接退出 - if (!str) { - this.__emit('change', null); - this.setState({ - invalid: false, - str, - }); - return; - } - - // 不合法直接退出 - const parsed = moment(str, format, true); - if (!parsed.isValid()) { - this.setState({ - invalid: true, - str, - }); - return; - } - const value = this.value.clone(); - value - .year(parsed.year()) - .month(parsed.month()) - .date(parsed.date()) - .hour(parsed.hour()) - .minute(parsed.minute()) - .second(parsed.second()); - - if (!value || (disabledDate && disabledDate(value))) { - this.setState({ - invalid: true, - str, - }); - return; - } - - if (selectedValue !== value || (selectedValue && value && !selectedValue.isSame(value))) { - this.setState({ - invalid: false, - str, - }); - this.__emit('change', value); - } - }, - onFocus() { - this.setState({ hasFocus: true }); - }, - onBlur() { - this.setState((prevState, prevProps) => ({ - hasFocus: false, - str: formatDate(prevProps.value, prevProps.format), - })); - }, - onKeyDown(event) { - const { keyCode } = event; - const { value, disabledDate } = this.$props; - if (keyCode === KeyCode.ENTER) { - const validateDate = !disabledDate || !disabledDate(value); - if (validateDate) { - this.__emit('select', value.clone()); - } - event.preventDefault(); - } - }, - getRootDOMNode() { - return findDOMNode(this); - }, - focus() { - if (dateInputInstance) { - dateInputInstance.focus(); - } - }, - saveDateInput(dateInput) { - dateInputInstance = dateInput; - }, - }, - - render() { - const { - invalid, - str, - locale, - prefixCls, - placeholder, - disabled, - showClear, - inputMode, - inputReadOnly, - } = this; - const clearIcon = getComponent(this, 'clearIcon'); - const invalidClass = invalid ? `${prefixCls}-input-invalid` : ''; - return ( -
-
- {withDirectives( - , - [[antInput]], - )} -
- {showClear ? ( - - {clearIcon || } - - ) : null} -
- ); - }, -}; - -export default DateInput; diff --git a/components/vc-calendar/src/date/DateTBody.jsx b/components/vc-calendar/src/date/DateTBody.jsx deleted file mode 100644 index 08871b0d6..000000000 --- a/components/vc-calendar/src/date/DateTBody.jsx +++ /dev/null @@ -1,258 +0,0 @@ -import PropTypes from '../../../_util/vue-types'; -import { getOptionProps } from '../../../_util/props-util'; -import cx from '../../../_util/classNames'; -import DateConstants from './DateConstants'; -import { getTitleString, getTodayTime } from '../util/'; -function noop() {} -function isSameDay(one, two) { - return one && two && one.isSame(two, 'day'); -} - -function beforeCurrentMonthYear(current, today) { - if (current.year() < today.year()) { - return 1; - } - return current.year() === today.year() && current.month() < today.month(); -} - -function afterCurrentMonthYear(current, today) { - if (current.year() > today.year()) { - return 1; - } - return current.year() === today.year() && current.month() > today.month(); -} - -function getIdFromDate(date) { - return `rc-calendar-${date.year()}-${date.month()}-${date.date()}`; -} - -const DateTBody = { - name: 'DateTBody', - inheritAttrs: false, - props: { - contentRender: PropTypes.func, - dateRender: PropTypes.func, - disabledDate: PropTypes.func, - prefixCls: PropTypes.string, - selectedValue: PropTypes.any, - value: PropTypes.object, - hoverValue: PropTypes.any.def([]), - showWeekNumber: PropTypes.looseBool, - }, - - render() { - const props = getOptionProps(this); - const { - contentRender, - prefixCls, - selectedValue, - value, - showWeekNumber, - dateRender, - disabledDate, - hoverValue, - } = props; - const { onSelect = noop, onDayHover = noop } = this.$attrs; - let iIndex; - let jIndex; - let current; - const dateTable = []; - const today = getTodayTime(value); - const cellClass = `${prefixCls}-cell`; - const weekNumberCellClass = `${prefixCls}-week-number-cell`; - const dateClass = `${prefixCls}-date`; - const todayClass = `${prefixCls}-today`; - const selectedClass = `${prefixCls}-selected-day`; - const selectedDateClass = `${prefixCls}-selected-date`; // do not move with mouse operation - const selectedStartDateClass = `${prefixCls}-selected-start-date`; - const selectedEndDateClass = `${prefixCls}-selected-end-date`; - const inRangeClass = `${prefixCls}-in-range-cell`; - const lastMonthDayClass = `${prefixCls}-last-month-cell`; - const nextMonthDayClass = `${prefixCls}-next-month-btn-day`; - const disabledClass = `${prefixCls}-disabled-cell`; - const firstDisableClass = `${prefixCls}-disabled-cell-first-of-row`; - const lastDisableClass = `${prefixCls}-disabled-cell-last-of-row`; - const lastDayOfMonthClass = `${prefixCls}-last-day-of-month`; - const month1 = value.clone(); - month1.date(1); - const day = month1.day(); - const lastMonthDiffDay = (day + 7 - value.localeData().firstDayOfWeek()) % 7; - // calculate last month - const lastMonth1 = month1.clone(); - lastMonth1.add(0 - lastMonthDiffDay, 'days'); - let passed = 0; - for (iIndex = 0; iIndex < DateConstants.DATE_ROW_COUNT; iIndex++) { - for (jIndex = 0; jIndex < DateConstants.DATE_COL_COUNT; jIndex++) { - current = lastMonth1; - if (passed) { - current = current.clone(); - current.add(passed, 'days'); - } - dateTable.push(current); - passed++; - } - } - const tableHtml = []; - passed = 0; - - for (iIndex = 0; iIndex < DateConstants.DATE_ROW_COUNT; iIndex++) { - let isCurrentWeek; - let weekNumberCell; - let isActiveWeek = false; - const dateCells = []; - if (showWeekNumber) { - weekNumberCell = ( - - {dateTable[passed].week()} - - ); - } - for (jIndex = 0; jIndex < DateConstants.DATE_COL_COUNT; jIndex++) { - let next = null; - let last = null; - current = dateTable[passed]; - if (jIndex < DateConstants.DATE_COL_COUNT - 1) { - next = dateTable[passed + 1]; - } - if (jIndex > 0) { - last = dateTable[passed - 1]; - } - let cls = cellClass; - let disabled = false; - let selected = false; - - if (isSameDay(current, today)) { - cls += ` ${todayClass}`; - isCurrentWeek = true; - } - - const isBeforeCurrentMonthYear = beforeCurrentMonthYear(current, value); - const isAfterCurrentMonthYear = afterCurrentMonthYear(current, value); - - if (selectedValue && Array.isArray(selectedValue)) { - const rangeValue = hoverValue.length ? hoverValue : selectedValue; - if (!isBeforeCurrentMonthYear && !isAfterCurrentMonthYear) { - const startValue = rangeValue[0]; - const endValue = rangeValue[1]; - if (startValue) { - if (isSameDay(current, startValue)) { - selected = true; - isActiveWeek = true; - cls += ` ${selectedStartDateClass}`; - } - } - if (startValue || endValue) { - if (isSameDay(current, endValue)) { - selected = true; - isActiveWeek = true; - cls += ` ${selectedEndDateClass}`; - } else if ( - (startValue === null || startValue === undefined) && - current.isBefore(endValue, 'day') - ) { - cls += ` ${inRangeClass}`; - } else if ( - (endValue === null || endValue === undefined) && - current.isAfter(startValue, 'day') - ) { - cls += ` ${inRangeClass}`; - } else if (current.isAfter(startValue, 'day') && current.isBefore(endValue, 'day')) { - cls += ` ${inRangeClass}`; - } - } - } - } else if (isSameDay(current, value)) { - // keyboard change value, highlight works - selected = true; - isActiveWeek = true; - } - - if (isSameDay(current, selectedValue)) { - cls += ` ${selectedDateClass}`; - } - - if (isBeforeCurrentMonthYear) { - cls += ` ${lastMonthDayClass}`; - } - if (isAfterCurrentMonthYear) { - cls += ` ${nextMonthDayClass}`; - } - - if (current.clone().endOf('month').date() === current.date()) { - cls += ` ${lastDayOfMonthClass}`; - } - - if (disabledDate) { - if (disabledDate(current, value)) { - disabled = true; - - if (!last || !disabledDate(last, value)) { - cls += ` ${firstDisableClass}`; - } - - if (!next || !disabledDate(next, value)) { - cls += ` ${lastDisableClass}`; - } - } - } - - if (selected) { - cls += ` ${selectedClass}`; - } - - if (disabled) { - cls += ` ${disabledClass}`; - } - - let dateHtml; - if (dateRender) { - dateHtml = dateRender({ current, today: value }); - } else { - const content = contentRender ? contentRender({ current, today: value }) : current.date(); - dateHtml = ( -
- {content} -
- ); - } - - dateCells.push( - - {dateHtml} - , - ); - - passed++; - } - - tableHtml.push( - - {weekNumberCell} - {dateCells} - , - ); - } - return {tableHtml}; - }, -}; - -export default DateTBody; diff --git a/components/vc-calendar/src/date/DateTHead.jsx b/components/vc-calendar/src/date/DateTHead.jsx deleted file mode 100644 index a9fcc5119..000000000 --- a/components/vc-calendar/src/date/DateTHead.jsx +++ /dev/null @@ -1,46 +0,0 @@ -import DateConstants from './DateConstants'; -import moment from 'moment'; - -const DateTHead = (_, { attrs }) => { - const value = attrs.value; - const localeData = value.localeData(); - const prefixCls = attrs.prefixCls; - const veryShortWeekdays = []; - const weekDays = []; - const firstDayOfWeek = localeData.firstDayOfWeek(); - let showWeekNumberEl; - const now = moment(); - for (let dateColIndex = 0; dateColIndex < DateConstants.DATE_COL_COUNT; dateColIndex++) { - const index = (firstDayOfWeek + dateColIndex) % DateConstants.DATE_COL_COUNT; - now.day(index); - veryShortWeekdays[dateColIndex] = localeData.weekdaysMin(now); - weekDays[dateColIndex] = localeData.weekdaysShort(now); - } - - if (attrs.showWeekNumber) { - showWeekNumberEl = ( - - x - - ); - } - const weekDaysEls = weekDays.map((day, xindex) => { - return ( - - {veryShortWeekdays[xindex]} - - ); - }); - return ( - - - {showWeekNumberEl} - {weekDaysEls} - - - ); -}; - -DateTHead.inheritAttrs = false; - -export default DateTHead; diff --git a/components/vc-calendar/src/date/DateTable.jsx b/components/vc-calendar/src/date/DateTable.jsx deleted file mode 100644 index 7c7408b34..000000000 --- a/components/vc-calendar/src/date/DateTable.jsx +++ /dev/null @@ -1,16 +0,0 @@ -import DateTHead from './DateTHead'; -import DateTBody from './DateTBody'; - -const DateTable = (_, { attrs }) => { - const prefixCls = attrs.prefixCls; - return ( - - - -
- ); -}; - -DateTable.inheritAttrs = false; - -export default DateTable; diff --git a/components/vc-calendar/src/decade/DecadePanel.jsx b/components/vc-calendar/src/decade/DecadePanel.jsx deleted file mode 100644 index 2bf35c104..000000000 --- a/components/vc-calendar/src/decade/DecadePanel.jsx +++ /dev/null @@ -1,133 +0,0 @@ -import PropTypes from '../../../_util/vue-types'; -import BaseMixin from '../../../_util/BaseMixin'; -const ROW = 4; -const COL = 3; -function noop() {} -function goYear(direction) { - const next = this.sValue.clone(); - next.add(direction, 'years'); - this.setState({ - sValue: next, - }); -} - -function chooseDecade(year, event) { - const next = this.sValue.clone(); - next.year(year); - next.month(this.sValue.month()); - this.__emit('select', next); - event.preventDefault(); -} - -export default { - name: 'DecadePanel', - mixins: [BaseMixin], - inheritAttrs: false, - props: { - locale: PropTypes.object, - value: PropTypes.object, - defaultValue: PropTypes.object, - rootPrefixCls: PropTypes.string, - renderFooter: PropTypes.func, - }, - data() { - this.nextCentury = goYear.bind(this, 100); - this.previousCentury = goYear.bind(this, -100); - return { - sValue: this.value || this.defaultValue, - }; - }, - watch: { - value(val) { - this.sValue = val; - }, - }, - render() { - const value = this.sValue; - const { locale, renderFooter } = this.$props; - const currentYear = value.year(); - const startYear = parseInt(currentYear / 100, 10) * 100; - const preYear = startYear - 10; - const endYear = startYear + 99; - const decades = []; - let index = 0; - const prefixCls = `${this.rootPrefixCls}-decade-panel`; - - for (let rowIndex = 0; rowIndex < ROW; rowIndex++) { - decades[rowIndex] = []; - for (let colIndex = 0; colIndex < COL; colIndex++) { - const startDecade = preYear + index * 10; - const endDecade = preYear + index * 10 + 9; - decades[rowIndex][colIndex] = { - startDecade, - endDecade, - }; - index++; - } - } - - const footer = renderFooter && renderFooter('decade'); - const decadesEls = decades.map((row, decadeIndex) => { - const tds = row.map(decadeData => { - const dStartDecade = decadeData.startDecade; - const dEndDecade = decadeData.endDecade; - const isLast = dStartDecade < startYear; - const isNext = dEndDecade > endYear; - const classNameMap = { - [`${prefixCls}-cell`]: 1, - [`${prefixCls}-selected-cell`]: dStartDecade <= currentYear && currentYear <= dEndDecade, - [`${prefixCls}-last-century-cell`]: isLast, - [`${prefixCls}-next-century-cell`]: isNext, - }; - const content = `${dStartDecade}-${dEndDecade}`; - let clickHandler = noop; - if (isLast) { - clickHandler = this.previousCentury; - } else if (isNext) { - clickHandler = this.nextCentury; - } else { - clickHandler = chooseDecade.bind(this, dStartDecade); - } - return ( - - {content} - - ); - }); - return ( - - {tds} - - ); - }); - - return ( - - ); - }, -}; diff --git a/components/vc-calendar/src/full-calendar/CalendarHeader.jsx b/components/vc-calendar/src/full-calendar/CalendarHeader.jsx deleted file mode 100644 index 3800fcfa4..000000000 --- a/components/vc-calendar/src/full-calendar/CalendarHeader.jsx +++ /dev/null @@ -1,135 +0,0 @@ -import PropTypes from '../../../_util/vue-types'; -import BaseMixin from '../../../_util/BaseMixin'; -import { getMonthName } from '../util'; - -const CalendarHeader = { - name: 'CalendarHeader', - inheritAttrs: false, - mixins: [BaseMixin], - props: { - value: PropTypes.object, - locale: PropTypes.object, - yearSelectOffset: PropTypes.number.def(10), - yearSelectTotal: PropTypes.number.def(20), - // onValueChange: PropTypes.func, - // onTypeChange: PropTypes.func, - Select: PropTypes.object, - prefixCls: PropTypes.string, - type: PropTypes.string, - showTypeSwitch: PropTypes.looseBool, - headerComponents: PropTypes.array, - }, - methods: { - onYearChange(year) { - const newValue = this.value.clone(); - newValue.year(parseInt(year, 10)); - this.__emit('valueChange', newValue); - }, - - onMonthChange(month) { - const newValue = this.value.clone(); - newValue.month(parseInt(month, 10)); - this.__emit('valueChange', newValue); - }, - - yearSelectElement(year) { - const { yearSelectOffset, yearSelectTotal, prefixCls, Select } = this; - const start = year - yearSelectOffset; - const end = start + yearSelectTotal; - - const options = []; - for (let index = start; index < end; index++) { - options.push({(() => index)()}); - } - return ( - - ); - }, - - monthSelectElement(month) { - const { value, Select, prefixCls } = this; - const t = value.clone(); - const options = []; - - for (let index = 0; index < 12; index++) { - t.month(index); - options.push({(() => getMonthName(t))()}); - } - - return ( - - ); - }, - - changeTypeToDate() { - this.__emit('typeChange', 'date'); - }, - - changeTypeToMonth() { - this.__emit('typeChange', 'month'); - }, - }, - - render() { - const { value, locale, prefixCls, type, showTypeSwitch, headerComponents } = this; - const year = value.year(); - const month = value.month(); - const yearSelect = this.yearSelectElement(year); - const monthSelect = type === 'month' ? null : this.monthSelectElement(month); - const switchCls = `${prefixCls}-header-switcher`; - const typeSwitcher = showTypeSwitch ? ( - - {type === 'date' ? ( - {locale.month} - ) : ( - - {locale.month} - - )} - {type === 'month' ? ( - {locale.year} - ) : ( - - {locale.year} - - )} - - ) : null; - - return ( -
- {typeSwitcher} - {monthSelect} - {yearSelect} - {headerComponents} -
- ); - }, -}; - -export default CalendarHeader; diff --git a/components/vc-calendar/src/index.js b/components/vc-calendar/src/index.js deleted file mode 100644 index abd4428bf..000000000 --- a/components/vc-calendar/src/index.js +++ /dev/null @@ -1,3 +0,0 @@ -import Calendar from './Calendar'; - -export default Calendar; diff --git a/components/vc-calendar/src/locale/ku_KU.js b/components/vc-calendar/src/locale/ku_KU.js deleted file mode 100644 index c947facb4..000000000 --- a/components/vc-calendar/src/locale/ku_KU.js +++ /dev/null @@ -1,27 +0,0 @@ -export default { - today: 'ئەمڕۆ', - now: 'ئێستا', - backToToday: 'گەڕانەوە بۆ ڕۆژی', - ok: 'باشە', - clear: 'پاک کردن', - month: 'مانگ', - year: 'ساڵ', - timeSelect: 'هەڵبژاردنی کات', - dateSelect: 'هەڵبژاردنی ڕێکەوت', - monthSelect: 'مانگێک هەلبژێرە', - yearSelect: 'ساڵێک هەڵبژێرە', - decadeSelect: 'سەدەیەک هەڵبژێرە', - yearFormat: 'YYYY', - dateFormat: 'M/D/YYYY', - dayFormat: 'D', - dateTimeFormat: 'M/D/YYYY HH:mm:ss', - monthBeforeYear: true, - previousMonth: 'مانگی پێشو (PageUp)', - nextMonth: 'مانگی داهاتو (PageDown)', - previousYear: 'پارساڵ (Control + left)', - nextYear: 'ساڵی داهاتو (Control + right)', - previousDecade: 'دەیە پێشو', - nextDecade: 'دەیە داهاتو', - previousCentury: 'سەدەی پێشو', - nextCentury: 'سەدەی داهاتو', -}; diff --git a/components/vc-calendar/src/mixin/CalendarMixin.js b/components/vc-calendar/src/mixin/CalendarMixin.js deleted file mode 100644 index 01bf59f92..000000000 --- a/components/vc-calendar/src/mixin/CalendarMixin.js +++ /dev/null @@ -1,129 +0,0 @@ -import PropTypes from '../../../_util/vue-types'; -import BaseMixin from '../../../_util/BaseMixin'; -import { hasProp } from '../../../_util/props-util'; -import moment from 'moment'; -import { isAllowedDate, getTodayTime } from '../util/index'; -function noop() {} - -export function getNowByCurrentStateValue(value) { - let ret; - if (value) { - ret = getTodayTime(value); - } else { - ret = moment(); - } - return ret; -} -function isMoment(value) { - if (Array.isArray(value)) { - return ( - value.length === 0 || value.findIndex(val => val === undefined || moment.isMoment(val)) !== -1 - ); - } else { - return value === undefined || moment.isMoment(value); - } -} -const MomentType = PropTypes.custom(isMoment); -const CalendarMixin = { - mixins: [BaseMixin], - inheritAttrs: false, - name: 'CalendarMixinWrapper', - props: { - value: MomentType, - defaultValue: MomentType, - }, - - data() { - if (this.onKeyDown === undefined) { - this.onKeyDown = noop; - } - if (this.onBlur === undefined) { - this.onBlur = noop; - } - const props = this.$props; - const sValue = props.value || props.defaultValue || getNowByCurrentStateValue(); - return { - sValue, - sSelectedValue: props.selectedValue || props.defaultSelectedValue, - }; - }, - watch: { - value(val) { - const sValue = val || this.defaultValue || getNowByCurrentStateValue(this.sValue); - this.setState({ - sValue, - }); - }, - selectedValue(val) { - this.setState({ - sSelectedValue: val, - }); - }, - }, - methods: { - onSelect(value, cause) { - if (value) { - this.setValue(value); - } - this.setSelectedValue(value, cause); - }, - - renderRoot(newProps) { - const props = { ...this.$props, ...this.$attrs }; - const prefixCls = props.prefixCls; - - const className = { - [prefixCls]: 1, - [`${prefixCls}-hidden`]: !props.visible, - [props.class]: !!props.class, - [newProps.class]: !!newProps.class, - }; - return ( -
- {newProps.children} -
- ); - }, - - setSelectedValue(selectedValue, cause) { - // if (this.isAllowedDate(selectedValue)) { - if (!hasProp(this, 'selectedValue')) { - this.setState({ - sSelectedValue: selectedValue, - }); - } - this.__emit('select', selectedValue, cause); - // } - }, - - setValue(value) { - const originalValue = this.sValue; - if (!hasProp(this, 'value')) { - this.setState({ - sValue: value, - }); - } - if ( - (originalValue && value && !originalValue.isSame(value)) || - (!originalValue && value) || - (originalValue && !value) - ) { - this.__emit('change', value); - } - }, - - isAllowedDate(value) { - const disabledDate = this.disabledDate; - const disabledTime = this.disabledTime; - return isAllowedDate(value, disabledDate, disabledTime); - }, - }, -}; - -export default CalendarMixin; diff --git a/components/vc-calendar/src/mixin/CommonMixin.js b/components/vc-calendar/src/mixin/CommonMixin.js deleted file mode 100644 index ebaf4d890..000000000 --- a/components/vc-calendar/src/mixin/CommonMixin.js +++ /dev/null @@ -1,29 +0,0 @@ -export default { - methods: { - getFormat() { - let { format } = this; - const { locale, timePicker } = this; - if (!format) { - if (timePicker) { - format = locale.dateTimeFormat; - } else { - format = locale.dateFormat; - } - } - return format; - }, - focus() { - if (this.focusElement) { - this.focusElement.focus(); - } else if (this.rootInstance) { - this.rootInstance.focus(); - } - }, - saveFocusElement(focusElement) { - this.focusElement = focusElement; - }, - saveRoot(root) { - this.rootInstance = root; - }, - }, -}; diff --git a/components/vc-calendar/src/month/MonthPanel.jsx b/components/vc-calendar/src/month/MonthPanel.jsx deleted file mode 100644 index 8aa19434b..000000000 --- a/components/vc-calendar/src/month/MonthPanel.jsx +++ /dev/null @@ -1,114 +0,0 @@ -import PropTypes from '../../../_util/vue-types'; -import BaseMixin from '../../../_util/BaseMixin'; -import { hasProp } from '../../../_util/props-util'; -import MonthTable from './MonthTable'; - -function goYear(direction) { - this.changeYear(direction); -} - -function noop() {} - -const MonthPanel = { - name: 'MonthPanel', - inheritAttrs: false, - mixins: [BaseMixin], - props: { - value: PropTypes.any, - defaultValue: PropTypes.any, - cellRender: PropTypes.any, - contentRender: PropTypes.any, - locale: PropTypes.any, - rootPrefixCls: PropTypes.string, - // onChange: PropTypes.func, - disabledDate: PropTypes.func, - // onSelect: PropTypes.func, - renderFooter: PropTypes.func, - changeYear: PropTypes.func.def(noop), - }, - - data() { - const { value, defaultValue } = this; - // bind methods - this.nextYear = goYear.bind(this, 1); - this.previousYear = goYear.bind(this, -1); - return { - sValue: value || defaultValue, - }; - }, - watch: { - value(val) { - this.setState({ - sValue: val, - }); - }, - }, - methods: { - setAndSelectValue(value) { - this.setValue(value); - this.__emit('select', value); - }, - - setValue(value) { - if (hasProp(this, 'value')) { - this.setState({ - sValue: value, - }); - } - }, - }, - - render() { - const { sValue, cellRender, contentRender, locale, rootPrefixCls, disabledDate, renderFooter } = - this; - const year = sValue.year(); - const prefixCls = `${rootPrefixCls}-month-panel`; - - const footer = renderFooter && renderFooter('month'); - return ( -
- ); - }, -}; - -export default MonthPanel; diff --git a/components/vc-calendar/src/month/MonthTable.jsx b/components/vc-calendar/src/month/MonthTable.jsx deleted file mode 100644 index 212ef440f..000000000 --- a/components/vc-calendar/src/month/MonthTable.jsx +++ /dev/null @@ -1,133 +0,0 @@ -import PropTypes from '../../../_util/vue-types'; -import BaseMixin from '../../../_util/BaseMixin'; -import { getTodayTime, getMonthName } from '../util/index'; - -const ROW = 4; -const COL = 3; - -function noop() {} - -const MonthTable = { - name: 'MonthTable', - inheritAttrs: false, - mixins: [BaseMixin], - props: { - cellRender: PropTypes.func, - prefixCls: PropTypes.string, - value: PropTypes.object, - locale: PropTypes.any, - contentRender: PropTypes.any, - disabledDate: PropTypes.func, - }, - data() { - return { - sValue: this.value, - }; - }, - watch: { - value(val) { - this.setState({ - sValue: val, - }); - }, - }, - methods: { - setAndSelectValue(value) { - this.setState({ - sValue: value, - }); - this.__emit('select', value); - }, - chooseMonth(month) { - const next = this.sValue.clone(); - next.month(month); - this.setAndSelectValue(next); - }, - months() { - const value = this.sValue; - const current = value.clone(); - const months = []; - let index = 0; - for (let rowIndex = 0; rowIndex < ROW; rowIndex++) { - months[rowIndex] = []; - for (let colIndex = 0; colIndex < COL; colIndex++) { - current.month(index); - const content = getMonthName(current); - months[rowIndex][colIndex] = { - value: index, - content, - title: content, - }; - index++; - } - } - return months; - }, - }, - - render() { - const props = this.$props; - const value = this.sValue; - const today = getTodayTime(value); - const months = this.months(); - const currentMonth = value.month(); - const { prefixCls, locale, contentRender, cellRender, disabledDate } = props; - const monthsEls = months.map((month, index) => { - const tds = month.map(monthData => { - let disabled = false; - if (disabledDate) { - const testValue = value.clone(); - testValue.month(monthData.value); - disabled = disabledDate(testValue); - } - const classNameMap = { - [`${prefixCls}-cell`]: 1, - [`${prefixCls}-cell-disabled`]: disabled, - [`${prefixCls}-selected-cell`]: monthData.value === currentMonth, - [`${prefixCls}-current-cell`]: - today.year() === value.year() && monthData.value === today.month(), - }; - let cellEl; - if (cellRender) { - const currentValue = value.clone(); - currentValue.month(monthData.value); - cellEl = cellRender({ current: currentValue, locale }); - } else { - let content; - if (contentRender) { - const currentValue = value.clone(); - currentValue.month(monthData.value); - content = contentRender({ current: currentValue, locale }); - } else { - content = monthData.content; - } - cellEl = {content}; - } - return ( - this.chooseMonth(monthData.value)} - title={monthData.title} - class={classNameMap} - > - {cellEl} - - ); - }); - return ( - - {tds} - - ); - }); - - return ( - - {monthsEls} -
- ); - }, -}; - -export default MonthTable; diff --git a/components/vc-calendar/src/picker/placements.js b/components/vc-calendar/src/picker/placements.js deleted file mode 100644 index 676028676..000000000 --- a/components/vc-calendar/src/picker/placements.js +++ /dev/null @@ -1,35 +0,0 @@ -const autoAdjustOverflow = { - adjustX: 1, - adjustY: 1, -}; - -const targetOffset = [0, 0]; - -const placements = { - bottomLeft: { - points: ['tl', 'tl'], - overflow: autoAdjustOverflow, - offset: [0, -3], - targetOffset, - }, - bottomRight: { - points: ['tr', 'tr'], - overflow: autoAdjustOverflow, - offset: [0, -3], - targetOffset, - }, - topRight: { - points: ['br', 'br'], - overflow: autoAdjustOverflow, - offset: [0, 3], - targetOffset, - }, - topLeft: { - points: ['bl', 'bl'], - overflow: autoAdjustOverflow, - offset: [0, 3], - targetOffset, - }, -}; - -export default placements; diff --git a/components/vc-calendar/src/range-calendar/CalendarPart.jsx b/components/vc-calendar/src/range-calendar/CalendarPart.jsx deleted file mode 100644 index 5f6724817..000000000 --- a/components/vc-calendar/src/range-calendar/CalendarPart.jsx +++ /dev/null @@ -1,160 +0,0 @@ -import PropTypes from '../../../_util/vue-types'; -import BaseMixin from '../../../_util/BaseMixin'; -import { getOptionProps, getComponent } from '../../../_util/props-util'; -import { cloneElement } from '../../../_util/vnode'; -import CalendarHeader from '../calendar/CalendarHeader'; -import DateTable from '../date/DateTable'; -import DateInput from '../date/DateInput'; -import { getTimeConfig } from '../util/index'; -function noop() {} -const CalendarPart = { - name: 'CalendarPart', - inheritAttrs: false, - mixins: [BaseMixin], - props: { - prefixCls: PropTypes.string, - value: PropTypes.any, - hoverValue: PropTypes.any, - selectedValue: PropTypes.any, - direction: PropTypes.any, - locale: PropTypes.any, - showDateInput: PropTypes.looseBool, - showTimePicker: PropTypes.looseBool, - showWeekNumber: PropTypes.looseBool, - format: PropTypes.any, - placeholder: PropTypes.any, - disabledDate: PropTypes.any, - timePicker: PropTypes.any, - disabledTime: PropTypes.any, - disabledMonth: PropTypes.any, - mode: PropTypes.any, - // onInputSelect: PropTypes.func, - timePickerDisabledTime: PropTypes.object, - enableNext: PropTypes.any, - enablePrev: PropTypes.any, - clearIcon: PropTypes.any, - dateRender: PropTypes.func, - inputMode: PropTypes.string, - inputReadOnly: PropTypes.looseBool, - }, - render() { - const { $props: props } = this; - const { - prefixCls, - value, - hoverValue, - selectedValue, - mode, - direction, - locale, - format, - placeholder, - disabledDate, - timePicker, - disabledTime, - timePickerDisabledTime, - showTimePicker, - enablePrev, - enableNext, - disabledMonth, - showDateInput, - dateRender, - showWeekNumber, - showClear, - inputMode, - inputReadOnly, - } = props; - const clearIcon = getComponent(this, 'clearIcon'); - const { - onInputChange = noop, - onInputSelect = noop, - onValueChange = noop, - onPanelChange = noop, - onSelect = noop, - onDayHover = noop, - } = this.$attrs; - const shouldShowTimePicker = showTimePicker && timePicker; - const disabledTimeConfig = - shouldShowTimePicker && disabledTime ? getTimeConfig(selectedValue, disabledTime) : null; - const rangeClassName = `${prefixCls}-range`; - const newProps = { - locale, - value, - prefixCls, - showTimePicker, - }; - const index = direction === 'left' ? 0 : 1; - let timePickerEle = null; - if (shouldShowTimePicker) { - const timePickerProps = getOptionProps(timePicker); - timePickerEle = cloneElement(timePicker, { - showHour: true, - showMinute: true, - showSecond: true, - ...timePickerProps, - ...disabledTimeConfig, - ...timePickerDisabledTime, - defaultOpenValue: value, - value: selectedValue[index], - onChange: onInputChange, - }); - } - - const dateInputElement = showDateInput && ( - - ); - const headerProps = { - ...newProps, - mode, - enableNext, - enablePrev, - disabledMonth, - onValueChange, - onPanelChange, - }; - const tableProps = { - ...newProps, - hoverValue, - selectedValue, - dateRender, - disabledDate, - showWeekNumber, - onSelect, - onDayHover, - }; - return ( -
- {dateInputElement} -
- - {showTimePicker ? ( -
-
{timePickerEle}
-
- ) : null} -
- -
-
-
- ); - }, -}; - -export default CalendarPart; diff --git a/components/vc-calendar/src/util/index.js b/components/vc-calendar/src/util/index.js deleted file mode 100644 index 296e046cb..000000000 --- a/components/vc-calendar/src/util/index.js +++ /dev/null @@ -1,113 +0,0 @@ -import moment from 'moment'; - -const defaultDisabledTime = { - disabledHours() { - return []; - }, - disabledMinutes() { - return []; - }, - disabledSeconds() { - return []; - }, -}; - -export function getTodayTime(value) { - const today = moment(); - today.locale(value.locale()).utcOffset(value.utcOffset()); - return today; -} - -export function getTitleString(value) { - return value.format('LL'); -} - -export function getTodayTimeStr(value) { - const today = getTodayTime(value); - return getTitleString(today); -} - -export function getMonthName(month) { - const locale = month.locale(); - const localeData = month.localeData(); - return localeData[locale === 'zh-cn' ? 'months' : 'monthsShort'](month); -} - -export function syncTime(from, to) { - if (!moment.isMoment(from) || !moment.isMoment(to)) return; - to.hour(from.hour()); - to.minute(from.minute()); - to.second(from.second()); - to.millisecond(from.millisecond()); -} - -export function getTimeConfig(value, disabledTime) { - let disabledTimeConfig = disabledTime ? disabledTime(value) : {}; - disabledTimeConfig = { - ...defaultDisabledTime, - ...disabledTimeConfig, - }; - return disabledTimeConfig; -} - -export function isTimeValidByConfig(value, disabledTimeConfig) { - let invalidTime = false; - if (value) { - const hour = value.hour(); - const minutes = value.minute(); - const seconds = value.second(); - const disabledHours = disabledTimeConfig.disabledHours(); - if (disabledHours.indexOf(hour) === -1) { - const disabledMinutes = disabledTimeConfig.disabledMinutes(hour); - if (disabledMinutes.indexOf(minutes) === -1) { - const disabledSeconds = disabledTimeConfig.disabledSeconds(hour, minutes); - invalidTime = disabledSeconds.indexOf(seconds) !== -1; - } else { - invalidTime = true; - } - } else { - invalidTime = true; - } - } - return !invalidTime; -} - -export function isTimeValid(value, disabledTime) { - const disabledTimeConfig = getTimeConfig(value, disabledTime); - return isTimeValidByConfig(value, disabledTimeConfig); -} - -export function isAllowedDate(value, disabledDate, disabledTime) { - if (disabledDate) { - if (disabledDate(value)) { - return false; - } - } - if (disabledTime) { - if (!isTimeValid(value, disabledTime)) { - return false; - } - } - return true; -} - -export function formatDate(value, format) { - if (!value) { - return ''; - } - - if (Array.isArray(format)) { - format = format[0]; - } - - if (typeof format === 'function') { - const result = format(value); - if (typeof result === 'string') { - return result; - } else { - throw new Error('The function of format does not return a string'); - } - } - - return value.format(format); -} diff --git a/components/vc-calendar/src/util/toTime.js b/components/vc-calendar/src/util/toTime.js deleted file mode 100644 index 22023b5ad..000000000 --- a/components/vc-calendar/src/util/toTime.js +++ /dev/null @@ -1,15 +0,0 @@ -export function goStartMonth(time) { - return time.clone().startOf('month'); -} - -export function goEndMonth(time) { - return time.clone().endOf('month'); -} - -export function goTime(time, direction, unit) { - return time.clone().add(direction, unit); -} - -export function includesTime(timeList = [], time, unit) { - return timeList.some(t => t.isSame(time, unit)); -} diff --git a/components/vc-calendar/src/year/YearPanel.jsx b/components/vc-calendar/src/year/YearPanel.jsx deleted file mode 100644 index e4d2ecb21..000000000 --- a/components/vc-calendar/src/year/YearPanel.jsx +++ /dev/null @@ -1,153 +0,0 @@ -import PropTypes from '../../../_util/vue-types'; -import BaseMixin from '../../../_util/BaseMixin'; -const ROW = 4; -const COL = 3; -function noop() {} -function goYear(direction) { - const value = this.sValue.clone(); - value.add(direction, 'year'); - this.setState({ - sValue: value, - }); -} - -function chooseYear(year) { - const value = this.sValue.clone(); - value.year(year); - value.month(this.sValue.month()); - this.sValue = value; - this.__emit('select', value); -} - -export default { - name: 'YearPanel', - mixins: [BaseMixin], - inheritAttrs: false, - props: { - rootPrefixCls: PropTypes.string, - value: PropTypes.object, - defaultValue: PropTypes.object, - locale: PropTypes.object, - renderFooter: PropTypes.func, - }, - data() { - this.nextDecade = goYear.bind(this, 10); - this.previousDecade = goYear.bind(this, -10); - return { - sValue: this.value || this.defaultValue, - }; - }, - watch: { - value(val) { - this.sValue = val; - }, - }, - methods: { - years() { - const value = this.sValue; - const currentYear = value.year(); - const startYear = parseInt(currentYear / 10, 10) * 10; - const previousYear = startYear - 1; - const years = []; - let index = 0; - for (let rowIndex = 0; rowIndex < ROW; rowIndex++) { - years[rowIndex] = []; - for (let colIndex = 0; colIndex < COL; colIndex++) { - const year = previousYear + index; - const content = String(year); - years[rowIndex][colIndex] = { - content, - year, - title: content, - }; - index++; - } - } - return years; - }, - }, - - render() { - const { sValue: value, locale, renderFooter } = this; - const onDecadePanelShow = this.$attrs.onDecadePanelShow || noop; - const years = this.years(); - const currentYear = value.year(); - const startYear = parseInt(currentYear / 10, 10) * 10; - const endYear = startYear + 9; - const prefixCls = `${this.rootPrefixCls}-year-panel`; - - const yeasEls = years.map((row, index) => { - const tds = row.map(yearData => { - const classNameMap = { - [`${prefixCls}-cell`]: 1, - [`${prefixCls}-selected-cell`]: yearData.year === currentYear, - [`${prefixCls}-last-decade-cell`]: yearData.year < startYear, - [`${prefixCls}-next-decade-cell`]: yearData.year > endYear, - }; - let clickHandler = noop; - if (yearData.year < startYear) { - clickHandler = this.previousDecade; - } else if (yearData.year > endYear) { - clickHandler = this.nextDecade; - } else { - clickHandler = chooseYear.bind(this, yearData.year); - } - return ( - - {yearData.content} - - ); - }); - return ( - - {tds} - - ); - }); - const footer = renderFooter && renderFooter('year'); - return ( - - ); - }, -}; diff --git a/components/vc-dialog/DialogWrap.jsx b/components/vc-dialog/DialogWrap.jsx index ef9a2b313..6dfe9d2fc 100644 --- a/components/vc-dialog/DialogWrap.jsx +++ b/components/vc-dialog/DialogWrap.jsx @@ -35,9 +35,11 @@ const DialogWrap = defineComponent({ visible={visible} forceRender={forceRender} getContainer={getContainer} - children={childProps => { - dialogProps = { ...dialogProps, ...childProps }; - return {getSlot(this)}; + v-slots={{ + default: childProps => { + dialogProps = { ...dialogProps, ...childProps }; + return {getSlot(this)}; + }, }} /> ); diff --git a/components/vc-mentions/src/Mentions.tsx b/components/vc-mentions/src/Mentions.tsx index 10e78387b..ec291fe67 100644 --- a/components/vc-mentions/src/Mentions.tsx +++ b/components/vc-mentions/src/Mentions.tsx @@ -212,7 +212,7 @@ export default defineComponent({ if (!!filterOption === false) { return true; } - return filterOption(targetMeasureText, option); + return (filterOption as Function)(targetMeasureText, option); }); return list; }; diff --git a/components/vc-pagination/locale/bn_BD.js b/components/vc-pagination/locale/bn_BD.js new file mode 100644 index 000000000..d5c8c4609 --- /dev/null +++ b/components/vc-pagination/locale/bn_BD.js @@ -0,0 +1,15 @@ +export default { + // Options.jsx + items_per_page: '/ পৃষ্ঠা', + jump_to: 'যাও', + jump_to_confirm: 'নিশ্চিত', + page: '', + + // Pagination.jsx + prev_page: 'আগের পৃষ্ঠা', + next_page: 'পরের পৃষ্ঠা', + prev_5: 'পূর্ববর্তী ৫ পৃষ্ঠা', + next_5: 'পরবর্তী ৫ পৃষ্ঠা', + prev_3: 'পূর্ববর্তী ৩ পৃষ্ঠা', + next_3: 'পরবর্তী ৩ পৃষ্ঠা', +}; diff --git a/components/vc-pagination/locale/by_BY.js b/components/vc-pagination/locale/by_BY.js new file mode 100644 index 000000000..36b1886cc --- /dev/null +++ b/components/vc-pagination/locale/by_BY.js @@ -0,0 +1,14 @@ +export default { + // Options.jsx + items_per_page: '/старонка', + jump_to: 'Перайсці', + jump_to_confirm: 'Пацвердзіць', + page: '', + // Pagination.jsx + prev_page: 'Назад', + next_page: 'Наперад', + prev_5: 'Папярэднія 5', + next_5: 'Наступныя 5', + prev_3: 'Папярэднія 3', + next_3: 'Наступныя 3', + }; \ No newline at end of file diff --git a/components/vc-pagination/locale/fr_CA.js b/components/vc-pagination/locale/fr_CA.js new file mode 100644 index 000000000..e71070622 --- /dev/null +++ b/components/vc-pagination/locale/fr_CA.js @@ -0,0 +1,15 @@ +export default { + // Options.jsx + items_per_page: '/ page', + jump_to: 'Aller à', + jump_to_confirm: 'confirmer', + page: '', + + // Pagination.jsx + prev_page: 'Page précédente', + next_page: 'Page suivante', + prev_5: '5 Pages précédentes', + next_5: '5 Pages suivantes', + prev_3: '3 Pages précédentes', + next_3: '3 Pages suivantes', +}; diff --git a/components/vc-pagination/locale/gl_ES.tsx b/components/vc-pagination/locale/gl_ES.tsx new file mode 100644 index 000000000..61fb164be --- /dev/null +++ b/components/vc-pagination/locale/gl_ES.tsx @@ -0,0 +1,15 @@ +export default { + // Options.jsx + items_per_page: '/ páxina', + jump_to: 'Ir a', + jump_to_confirm: 'confirmar', + page: '', + + // Pagination.jsx + prev_page: 'Páxina anterior', + next_page: 'Páxina seguinte', + prev_5: '5 páxinas previas', + next_5: '5 páxinas seguintes', + prev_3: '3 páxinas previas', + next_3: '3 páxinas seguintes', +}; diff --git a/components/vc-pagination/locale/ja_JP.js b/components/vc-pagination/locale/ja_JP.js index f0ebaa9f7..9aa0f6e2f 100644 --- a/components/vc-pagination/locale/ja_JP.js +++ b/components/vc-pagination/locale/ja_JP.js @@ -1,6 +1,6 @@ export default { // Options.jsx - items_per_page: '/ ページ', + items_per_page: '件 / ページ', jump_to: '移動', jump_to_confirm: '確認する', page: 'ページ', diff --git a/components/vc-pagination/locale/ka_GE.js b/components/vc-pagination/locale/ka_GE.js new file mode 100644 index 000000000..82cf45bda --- /dev/null +++ b/components/vc-pagination/locale/ka_GE.js @@ -0,0 +1,14 @@ +export default { + // Options.jsx + items_per_page: '/ გვერდი.', + jump_to: 'გადასვლა', + jump_to_confirm: 'დადასტურება', + page: '', + // Pagination.jsx + prev_page: 'წინა გვერდი', + next_page: 'შემდეგი გვერდი', + prev_5: 'წინა 5 გვერდი', + next_5: 'შემდეგი 5 გვერდი', + prev_3: 'წინა 3 გვერდი', + next_3: 'შემდეგი 3 გვერდი', +}; diff --git a/components/vc-pagination/locale/kk_KZ.js b/components/vc-pagination/locale/kk_KZ.js new file mode 100644 index 000000000..fd5f1a3ff --- /dev/null +++ b/components/vc-pagination/locale/kk_KZ.js @@ -0,0 +1,15 @@ +export default { + // Options.jsx + items_per_page: '/ бет', + jump_to: 'Секіру', + jump_to_confirm: 'Растау', + page: '', + + // Pagination.jsx + prev_page: 'Артқа', + next_page: 'Алға', + prev_5: 'Алдыңғы 5', + next_5: 'Келесі 5', + prev_3: 'Алдыңғы 3', + next_3: 'Келесі 3', +}; diff --git a/components/vc-pagination/locale/km_KH.js b/components/vc-pagination/locale/km_KH.js new file mode 100644 index 000000000..86ec1b3fd --- /dev/null +++ b/components/vc-pagination/locale/km_KH.js @@ -0,0 +1,15 @@ +export default { + // Options.jsx + items_per_page: '/ ទំព័រ', + jump_to: 'លោត​ទៅ', + jump_to_confirm: 'បញ្ជាក់', + page: 'ទំព័រ', + + // Pagination.jsx + prev_page: 'ទំព័រ​មុន', + next_page: 'ទំព័រ​​បន្ទាប់', + prev_5: '៥ ទំព័រថយក្រោយ', + next_5: '៥ ទំព័រទៅមុខ', + prev_3: '៣ ទំព័រថយក្រោយ', + next_3: '៣ ទំព័រទៅមុខ', +}; diff --git a/components/vc-pagination/locale/ku_IQ.js b/components/vc-pagination/locale/kmr_IQ.js similarity index 100% rename from components/vc-pagination/locale/ku_IQ.js rename to components/vc-pagination/locale/kmr_IQ.js diff --git a/components/vc-pagination/locale/ku_KU.js b/components/vc-pagination/locale/ku_KU.js deleted file mode 100644 index c70ec9670..000000000 --- a/components/vc-pagination/locale/ku_KU.js +++ /dev/null @@ -1,15 +0,0 @@ -export default { - // Options.jsx - items_per_page: '/ ڵاپەرە', - jump_to: 'بڕو بۆ', - jump_to_confirm: 'پشت راستکردنەوە', - page: 'ڵاپەرە', - - // Pagination.jsx - prev_page: 'ڵاپەرەی پێشو', - next_page: 'ڵاپەرەی داهاتو', - prev_5: '۵ ڵاپەرەی پێشو', - next_5: '۵ ڵاپەرەی داهاتو', - prev_3: '۳ ڵاپەرەی پێشو', - next_3: '۳ ڵاپەرەی داهاتو', -}; diff --git a/components/vc-pagination/locale/lt_LT.js b/components/vc-pagination/locale/lt_LT.js new file mode 100644 index 000000000..1504133c2 --- /dev/null +++ b/components/vc-pagination/locale/lt_LT.js @@ -0,0 +1,15 @@ +export default { + // Options.jsx + items_per_page: '/ psl.', + jump_to: 'Pereiti', + jump_to_confirm: 'patvirtinti', + page: '', + + // Pagination.jsx + prev_page: 'Atgal', + next_page: 'Pirmyn', + prev_5: 'Grįžti 5 pls.', + next_5: 'Peršokti 5 pls.', + prev_3: 'Grįžti 3 pls.', + next_3: 'Peršokti 3 pls.', +}; diff --git a/components/vc-pagination/locale/ml_IN.js b/components/vc-pagination/locale/ml_IN.js new file mode 100644 index 000000000..83ec8f7bd --- /dev/null +++ b/components/vc-pagination/locale/ml_IN.js @@ -0,0 +1,15 @@ +export default { + // Options.jsx + items_per_page: '/ പേജ്', + jump_to: 'അടുത്തത്', + jump_to_confirm: 'ഉറപ്പാക്കുക', + page: '', + + // Pagination.jsx + prev_page: 'മുൻപുള്ള പേജ്', + next_page: 'അടുത്ത പേജ്', + prev_5: 'മുൻപുള്ള 5 പേജുകൾ', + next_5: 'അടുത്ത 5 പേജുകൾ', + prev_3: 'മുൻപുള്ള 3 പേജുകൾ', + next_3: 'അടുത്ത 3 പേജുകൾ', +}; diff --git a/components/vc-pagination/locale/pl_PL.js b/components/vc-pagination/locale/pl_PL.js index 7c16a7305..a0dc044d4 100644 --- a/components/vc-pagination/locale/pl_PL.js +++ b/components/vc-pagination/locale/pl_PL.js @@ -1,8 +1,8 @@ export default { // Options.jsx - items_per_page: '/ stronę', + items_per_page: 'na stronę', jump_to: 'Idź do', - jump_to_confirm: 'potwierdzać', + jump_to_confirm: 'potwierdź', page: '', // Pagination.jsx diff --git a/components/vc-pagination/locale/ur_PK.js b/components/vc-pagination/locale/ur_PK.js new file mode 100644 index 000000000..3b4721d11 --- /dev/null +++ b/components/vc-pagination/locale/ur_PK.js @@ -0,0 +1,15 @@ +export default { + // Options.jsx + items_per_page: '/ صفحہ', + jump_to: 'پاس جاؤ', + jump_to_confirm: 'تصدیق کریں', + page: '', + + // Pagination.jsx + prev_page: 'پچھلا صفحہ', + next_page: 'اگلا صفحہ', + prev_5: 'پچھلے 5 صفحات', + next_5: 'اگلے 5 صفحات', + prev_3: 'پچھلے 3 صفحات', + next_3: 'اگلے 3 صفحات', +}; diff --git a/components/vc-picker/PanelContext.tsx b/components/vc-picker/PanelContext.tsx new file mode 100644 index 000000000..5ea2f23b6 --- /dev/null +++ b/components/vc-picker/PanelContext.tsx @@ -0,0 +1,38 @@ +import type { InjectionKey, Ref } from 'vue'; +import { inject, provide } from 'vue'; +import type { OnSelect, PanelMode } from './interface'; + +export type ContextOperationRefProps = { + onKeydown?: (e: KeyboardEvent) => boolean; + onClose?: () => void; +}; + +export type PanelContextProps = { + operationRef?: Ref; + /** Only work with time panel */ + hideHeader?: Ref; + panelRef?: Ref; + hidePrevBtn?: Ref; + hideNextBtn?: Ref; + onDateMouseenter?: (date: any) => void; + onDateMouseleave?: (date: any) => void; + onSelect?: OnSelect; + hideRanges?: Ref; + open?: Ref; + mode?: Ref; + + /** Only used for TimePicker and this is a deprecated prop */ + defaultOpenValue?: Ref; +}; + +const PanelContextKey: InjectionKey = Symbol('PanelContextProps'); + +export const useProvidePanel = (props: PanelContextProps) => { + provide(PanelContextKey, props); +}; + +export const useInjectPanel = () => { + return inject(PanelContextKey, {}); +}; + +export default PanelContextKey; diff --git a/components/vc-picker/Picker.tsx b/components/vc-picker/Picker.tsx new file mode 100644 index 000000000..e57d59033 --- /dev/null +++ b/components/vc-picker/Picker.tsx @@ -0,0 +1,592 @@ +/** + * Removed: + * - getCalendarContainer: use `getPopupContainer` instead + * - onOk + * + * New Feature: + * - picker + * - allowEmpty + * - selectable + * + * Tips: Should add faq about `datetime` mode with `defaultValue` + */ + +import type { + PickerPanelBaseProps, + PickerPanelDateProps, + PickerPanelTimeProps, +} from './PickerPanel'; +import PickerPanel from './PickerPanel'; +import PickerTrigger from './PickerTrigger'; +import { formatValue, isEqual, parseValue } from './utils/dateUtil'; +import getDataOrAriaProps, { toArray } from './utils/miscUtil'; +import type { ContextOperationRefProps } from './PanelContext'; +import { useProvidePanel } from './PanelContext'; +import type { CustomFormat, PickerMode } from './interface'; +import { getDefaultFormat, getInputSize, elementsContains } from './utils/uiUtil'; +import usePickerInput from './hooks/usePickerInput'; +import useTextValueMapping from './hooks/useTextValueMapping'; +import useValueTexts from './hooks/useValueTexts'; +import useHoverValue from './hooks/useHoverValue'; +import type { CSSProperties, Ref } from 'vue'; +import { computed, defineComponent, ref, toRef, watch } from 'vue'; +import type { ChangeEvent, FocusEventHandler, MouseEventHandler } from '../_util/EventInterface'; +import type { VueNode } from '../_util/type'; +import type { AlignType } from '../vc-align/interface'; +import useMergedState from '../_util/hooks/useMergedState'; +import { warning } from '../vc-util/warning'; +import classNames from '../_util/classNames'; +import type { SharedTimeProps } from './panels/TimePanel'; + +export type PickerRefConfig = { + focus: () => void; + blur: () => void; +}; + +export type PickerSharedProps = { + dropdownClassName?: string; + dropdownAlign?: AlignType; + popupStyle?: CSSProperties; + transitionName?: string; + placeholder?: string; + allowClear?: boolean; + autofocus?: boolean; + disabled?: boolean; + tabindex?: number; + open?: boolean; + defaultOpen?: boolean; + /** Make input readOnly to avoid popup keyboard in mobile */ + inputReadOnly?: boolean; + id?: string; + + // Value + format?: string | CustomFormat | (string | CustomFormat)[]; + + // Render + suffixIcon?: VueNode; + clearIcon?: VueNode; + prevIcon?: VueNode; + nextIcon?: VueNode; + superPrevIcon?: VueNode; + superNextIcon?: VueNode; + getPopupContainer?: (node: HTMLElement) => HTMLElement; + panelRender?: (originPanel: VueNode) => VueNode; + + // Events + onChange?: (value: DateType | null, dateString: string) => void; + onOpenChange?: (open: boolean) => void; + onFocus?: FocusEventHandler; + onBlur?: FocusEventHandler; + onMousedown?: MouseEventHandler; + onMouseup?: MouseEventHandler; + onMouseenter?: MouseEventHandler; + onMouseleave?: MouseEventHandler; + onClick?: MouseEventHandler; + onContextmenu?: MouseEventHandler; + onKeydown?: (event: KeyboardEvent, preventDefault: () => void) => void; + + // WAI-ARIA + role?: string; + name?: string; + + autocomplete?: string; + direction?: 'ltr' | 'rtl'; + showToday?: boolean; + showTime?: boolean | SharedTimeProps; +}; + +type OmitPanelProps = Omit< + Props, + 'onChange' | 'hideHeader' | 'pickerValue' | 'onPickerValueChange' +>; + +export type PickerBaseProps = {} & PickerSharedProps & + OmitPanelProps>; + +export type PickerDateProps = {} & PickerSharedProps & + OmitPanelProps>; + +export type PickerTimeProps = { + picker: 'time'; + /** + * @deprecated Please use `defaultValue` directly instead + * since `defaultOpenValue` will confuse user of current value status + */ + defaultOpenValue?: DateType; +} & PickerSharedProps & + Omit>, 'format'>; + +export type PickerProps = + | PickerBaseProps + | PickerDateProps + | PickerTimeProps; + +// TMP type to fit for ts 3.9.2 +type OmitType = Omit, 'picker'> & + Omit, 'picker'> & + Omit, 'picker'>; +type MergedPickerProps = { + picker?: PickerMode; +} & OmitType; + +function Picker() { + return defineComponent>({ + name: 'Picker', + inheritAttrs: false, + props: [ + 'prefixCls', + 'id', + 'tabindex', + 'dropdownClassName', + 'dropdownAlign', + 'popupStyle', + 'transitionName', + 'generateConfig', + 'locale', + 'inputReadOnly', + 'allowClear', + 'autofocus', + 'showTime', + 'picker', + 'format', + 'use12Hours', + 'value', + 'defaultValue', + 'open', + 'defaultOpen', + 'defaultOpenValue', + 'suffixIcon', + 'clearIcon', + 'disabled', + 'disabledDate', + 'placeholder', + 'getPopupContainer', + 'panelRender', + 'onChange', + 'onOpenChange', + 'onFocus', + 'onBlur', + 'onMousedown', + 'onMouseup', + 'onMouseenter', + 'onMouseleave', + 'onContextmenu', + 'onClick', + 'onKeydown', + 'onSelect', + 'direction', + 'autocomplete', + 'showToday', + 'renderExtraFooter', + 'dateRender', + ] as any, + // slots: [ + // 'suffixIcon', + // 'clearIcon', + // 'prevIcon', + // 'nextIcon', + // 'superPrevIcon', + // 'superNextIcon', + // 'panelRender', + // ], + setup(props, { attrs, expose }) { + const inputRef = ref(null); + const picker = computed(() => props.picker ?? 'date'); + const needConfirmButton = computed( + () => (picker.value === 'date' && !!props.showTime) || picker.value === 'time', + ); + + // ============================= State ============================= + const formatList = computed(() => + toArray(getDefaultFormat(props.format, picker.value, props.showTime, props.use12Hours)), + ); + + // Panel ref + const panelDivRef = ref(null); + const inputDivRef = ref(null); + + // Real value + const [mergedValue, setInnerValue] = useMergedState(null, { + value: toRef(props, 'value'), + defaultValue: props.defaultValue, + }); + const selectedValue = ref(mergedValue.value) as Ref; + const setSelectedValue = (val: DateType) => { + selectedValue.value = val; + }; + + // Operation ref + const operationRef = ref(null); + + // Open + const [mergedOpen, triggerInnerOpen] = useMergedState(false, { + value: toRef(props, 'open'), + defaultValue: props.defaultOpen, + postState: postOpen => (props.disabled ? false : postOpen), + onChange: newOpen => { + if (props.onOpenChange) { + props.onOpenChange(newOpen); + } + + if (!newOpen && operationRef.value && operationRef.value.onClose) { + operationRef.value.onClose(); + } + }, + }); + + // ============================= Text ============================== + const [valueTexts, firstValueText] = useValueTexts(selectedValue, { + formatList, + generateConfig: toRef(props, 'generateConfig'), + locale: toRef(props, 'locale'), + }); + const [text, triggerTextChange, resetText] = useTextValueMapping({ + valueTexts, + onTextChange: newText => { + const inputDate = parseValue(newText, { + locale: props.locale, + formatList: formatList.value, + generateConfig: props.generateConfig, + }); + if (inputDate && (!props.disabledDate || !props.disabledDate(inputDate))) { + setSelectedValue(inputDate); + } + }, + }); + + // ============================ Trigger ============================ + const triggerChange = (newValue: DateType | null) => { + const { onChange, generateConfig, locale } = props; + setSelectedValue(newValue); + setInnerValue(newValue); + + if (onChange && !isEqual(generateConfig, mergedValue.value, newValue)) { + onChange( + newValue, + newValue + ? formatValue(newValue, { generateConfig, locale, format: formatList.value[0] }) + : '', + ); + } + }; + + const triggerOpen = (newOpen: boolean) => { + if (props.disabled && newOpen) { + return; + } + triggerInnerOpen(newOpen); + }; + + const forwardKeydown = (e: KeyboardEvent) => { + if (mergedOpen.value && operationRef.value && operationRef.value.onKeydown) { + // Let popup panel handle keyboard + return operationRef.value.onKeydown(e); + } + + /* istanbul ignore next */ + /* eslint-disable no-lone-blocks */ + { + warning( + false, + 'Picker not correct forward Keydown operation. Please help to fire issue about this.', + ); + return false; + } + }; + + const onInternalMouseup: MouseEventHandler = (...args) => { + if (props.onMouseup) { + props.onMouseup(...args); + } + + if (inputRef.value) { + inputRef.value.focus(); + triggerOpen(true); + } + }; + + // ============================= Input ============================= + const [inputProps, { focused, typing }] = usePickerInput({ + blurToCancel: needConfirmButton, + open: mergedOpen, + value: text, + triggerOpen, + forwardKeydown, + isClickOutside: target => + !elementsContains([panelDivRef.value, inputDivRef.value], target as HTMLElement), + onSubmit: () => { + if (props.disabledDate && props.disabledDate(selectedValue.value)) { + return false; + } + + triggerChange(selectedValue.value); + triggerOpen(false); + resetText(); + return true; + }, + onCancel: () => { + triggerOpen(false); + setSelectedValue(mergedValue.value); + resetText(); + }, + onKeydown: (e, preventDefault) => { + props.onKeydown?.(e, preventDefault); + }, + onFocus: (e: FocusEvent) => { + props.onFocus?.(e); + }, + onBlur: (e: FocusEvent) => { + props.onBlur?.(e); + }, + }); + + // ============================= Sync ============================== + // Close should sync back with text value + watch([mergedOpen, valueTexts], () => { + if (!mergedOpen.value) { + setSelectedValue(mergedValue.value); + + if (!valueTexts.value.length || valueTexts.value[0] === '') { + triggerTextChange(''); + } else if (firstValueText.value !== text.value) { + resetText(); + } + } + }); + + // Change picker should sync back with text value + watch(picker, () => { + if (!mergedOpen.value) { + resetText(); + } + }); + + // Sync innerValue with control mode + watch(mergedValue, () => { + // Sync select value + setSelectedValue(mergedValue.value); + }); + + const [hoverValue, onEnter, onLeave] = useHoverValue(text, { + formatList, + generateConfig: toRef(props, 'generateConfig'), + locale: toRef(props, 'locale'), + }); + + const onContextSelect = (date: DateType, type: 'key' | 'mouse' | 'submit') => { + if (type === 'submit' || (type !== 'key' && !needConfirmButton.value)) { + // triggerChange will also update selected values + triggerChange(date); + triggerOpen(false); + } + }; + + useProvidePanel({ + operationRef, + hideHeader: computed(() => picker.value === 'time'), + panelRef: panelDivRef, + onSelect: onContextSelect, + open: mergedOpen, + defaultOpenValue: toRef(props, 'defaultOpenValue'), + onDateMouseenter: onEnter, + onDateMouseleave: onLeave, + }); + + expose({ + focus: () => { + if (inputRef.value) { + inputRef.value.focus(); + } + }, + blur: () => { + if (inputRef.value) { + inputRef.value.blur(); + } + }, + }); + + return () => { + const { + prefixCls = 'rc-picker', + id, + tabindex, + dropdownClassName, + dropdownAlign, + popupStyle, + transitionName, + generateConfig, + locale, + inputReadOnly, + allowClear, + autofocus, + picker = 'date', + defaultOpenValue, + suffixIcon, + clearIcon, + disabled, + placeholder, + getPopupContainer, + panelRender, + onMousedown, + onMouseenter, + onMouseleave, + onContextmenu, + onClick, + onSelect, + direction, + autocomplete = 'off', + } = props; + + // ============================= Panel ============================= + const panelProps = { + // Remove `picker` & `format` here since TimePicker is little different with other panel + ...(props as Omit, 'picker' | 'format'>), + ...attrs, + class: classNames({ + [`${prefixCls}-panel-focused`]: !typing.value, + }), + style: undefined, + pickerValue: undefined, + onPickerValueChange: undefined, + onChange: null, + }; + + let panelNode: VueNode = ( + { + onSelect?.(date); + setSelectedValue(date); + }} + direction={direction} + onPanelChange={(viewDate, mode) => { + const { onPanelChange } = props; + onLeave(true); + onPanelChange?.(viewDate, mode); + }} + /> + ); + + if (panelRender) { + panelNode = panelRender(panelNode); + } + + const panel = ( +
{ + e.preventDefault(); + }} + > + {panelNode} +
+ ); + + let suffixNode: VueNode; + if (suffixIcon) { + suffixNode = {suffixIcon}; + } + + let clearNode: VueNode; + if (allowClear && mergedValue.value && !disabled) { + clearNode = ( + { + e.preventDefault(); + e.stopPropagation(); + }} + onMouseup={e => { + e.preventDefault(); + e.stopPropagation(); + triggerChange(null); + triggerOpen(false); + }} + class={`${prefixCls}-clear`} + role="button" + > + {clearIcon || } + + ); + } + + // ============================ Warning ============================ + if (process.env.NODE_ENV !== 'production') { + warning( + !defaultOpenValue, + '`defaultOpenValue` may confuse user for the current value status. Please use `defaultValue` instead.', + ); + } + + // ============================ Return ============================= + + const popupPlacement = direction === 'rtl' ? 'bottomRight' : 'bottomLeft'; + return ( + panel, + }} + > +
+
+ { + triggerTextChange(e.target.value); + }} + autofocus={autofocus} + placeholder={placeholder} + ref={inputRef} + title={text.value} + {...inputProps.value} + size={getInputSize(picker, formatList.value[0], generateConfig)} + {...getDataOrAriaProps(props)} + autocomplete={autocomplete} + /> + {suffixNode} + {clearNode} +
+
+
+ ); + }; + }, + }); +} +export default Picker(); diff --git a/components/vc-picker/PickerPanel.tsx b/components/vc-picker/PickerPanel.tsx new file mode 100644 index 000000000..b60a7ffe5 --- /dev/null +++ b/components/vc-picker/PickerPanel.tsx @@ -0,0 +1,613 @@ +/** + * Logic: + * When `mode` === `picker`, + * click will trigger `onSelect` (if value changed trigger `onChange` also). + * Panel change will not trigger `onSelect` but trigger `onPanelChange` + */ +import type { SharedTimeProps } from './panels/TimePanel'; +import TimePanel from './panels/TimePanel'; +import DatetimePanel from './panels/DatetimePanel'; +import DatePanel from './panels/DatePanel'; +import WeekPanel from './panels/WeekPanel'; +import MonthPanel from './panels/MonthPanel'; +import QuarterPanel from './panels/QuarterPanel'; +import YearPanel from './panels/YearPanel'; +import DecadePanel from './panels/DecadePanel'; +import type { GenerateConfig } from './generate'; +import type { + Locale, + PanelMode, + PanelRefProps, + PickerMode, + DisabledTime, + OnPanelChange, + Components, +} from './interface'; +import { isEqual } from './utils/dateUtil'; +import { useInjectPanel, useProvidePanel } from './PanelContext'; +import type { DateRender } from './panels/DatePanel/DateBody'; +import { PickerModeMap } from './utils/uiUtil'; +import type { MonthCellRender } from './panels/MonthPanel/MonthBody'; +import { useInjectRange } from './RangeContext'; +import getExtraFooter from './utils/getExtraFooter'; +import getRanges from './utils/getRanges'; +import { getLowerBoundTime, setDateTime, setTime } from './utils/timeUtil'; +import type { VueNode } from '../_util/type'; +import { computed, createVNode, defineComponent, ref, toRef, watch, watchEffect } from 'vue'; +import useMergedState from '../_util/hooks/useMergedState'; +import { warning } from '../vc-util/warning'; +import KeyCode from '../_util/KeyCode'; +import classNames from '../_util/classNames'; + +export type PickerPanelSharedProps = { + prefixCls?: string; + // className?: string; + // style?: React.CSSProperties; + /** @deprecated Will be removed in next big version. Please use `mode` instead */ + mode?: PanelMode; + tabindex?: number; + + // Locale + locale: Locale; + generateConfig: GenerateConfig; + + // Value + value?: DateType | null; + defaultValue?: DateType; + /** [Legacy] Set default display picker view date */ + pickerValue?: DateType; + /** [Legacy] Set default display picker view date */ + defaultPickerValue?: DateType; + + // Date + disabledDate?: (date: DateType) => boolean; + + // Render + dateRender?: DateRender; + monthCellRender?: MonthCellRender; + renderExtraFooter?: (mode: PanelMode) => VueNode; + + // Event + onSelect?: (value: DateType) => void; + onChange?: (value: DateType) => void; + onPanelChange?: OnPanelChange; + onMousedown?: (e: MouseEvent) => void; + onOk?: (date: DateType) => void; + + direction?: 'ltr' | 'rtl'; + + /** @private This is internal usage. Do not use in your production env */ + hideHeader?: boolean; + /** @private This is internal usage. Do not use in your production env */ + onPickerValueChange?: (date: DateType) => void; + + /** @private Internal usage. Do not use in your production env */ + components?: Components; +}; + +export type PickerPanelBaseProps = { + picker: Exclude; +} & PickerPanelSharedProps; + +export type PickerPanelDateProps = { + picker?: 'date'; + showToday?: boolean; + showNow?: boolean; + + // Time + showTime?: boolean | SharedTimeProps; + disabledTime?: DisabledTime; +} & PickerPanelSharedProps; + +export type PickerPanelTimeProps = { + picker: 'time'; +} & PickerPanelSharedProps & + SharedTimeProps; + +export type PickerPanelProps = + | PickerPanelBaseProps + | PickerPanelDateProps + | PickerPanelTimeProps; + +// TMP type to fit for ts 3.9.2 +type OmitType = Omit, 'picker'> & + Omit, 'picker'> & + Omit, 'picker'>; +type MergedPickerPanelProps = { + picker?: PickerMode; +} & OmitType; + +function PickerPanel() { + return defineComponent>({ + name: 'PickerPanel', + inheritAttrs: false, + props: { + prefixCls: String, + locale: Object, + generateConfig: Object, + value: Object, + defaultValue: Object, + pickerValue: Object, + defaultPickerValue: Object, + disabledDate: Function, + mode: String, + picker: { type: String, default: 'date' }, + tabindex: { type: [Number, String], default: 0 }, + showNow: { type: Boolean, default: undefined }, + showTime: [Boolean, Object], + showToday: Boolean, + renderExtraFooter: Function, + dateRender: Function, + hideHeader: { type: Boolean, default: undefined }, + onSelect: Function, + onChange: Function, + onPanelChange: Function, + onMousedown: Function, + onPickerValueChange: Function, + onOk: Function, + components: Object, + direction: String, + hourStep: { type: Number, default: 1 }, + minuteStep: { type: Number, default: 1 }, + secondStep: { type: Number, default: 1 }, + } as any, + setup(props, { attrs }) { + const needConfirmButton = computed( + () => (props.picker === 'date' && !!props.showTime) || props.picker === 'time', + ); + + const isHourStepValid = computed(() => 24 % props.hourStep === 0); + const isMinuteStepValid = computed(() => 60 % props.minuteStep === 0); + const isSecondStepValid = computed(() => 60 % props.secondStep === 0); + if (process.env.NODE_ENV !== 'production') { + watchEffect(() => { + const { generateConfig, value, hourStep = 1, minuteStep = 1, secondStep = 1 } = props; + warning(!value || generateConfig.isValidate(value), 'Invalidate date pass to `value`.'); + warning( + !value || generateConfig.isValidate(value), + 'Invalidate date pass to `defaultValue`.', + ); + warning( + isHourStepValid.value, + `\`hourStep\` ${hourStep} is invalid. It should be a factor of 24.`, + ); + warning( + isMinuteStepValid.value, + `\`minuteStep\` ${minuteStep} is invalid. It should be a factor of 60.`, + ); + warning( + isSecondStepValid.value, + `\`secondStep\` ${secondStep} is invalid. It should be a factor of 60.`, + ); + }); + } + + const panelContext = useInjectPanel(); + const { + operationRef, + panelRef: panelDivRef, + onSelect: onContextSelect, + hideRanges, + defaultOpenValue, + } = panelContext; + const { inRange, panelPosition, rangedValue, hoverRangedValue } = useInjectRange(); + const panelRef = ref({}); + // Value + const [mergedValue, setInnerValue] = useMergedState(null, { + value: toRef(props, 'value'), + defaultValue: props.defaultValue, + postState: val => { + if (!val && defaultOpenValue?.value && props.picker === 'time') { + return defaultOpenValue.value; + } + return val; + }, + }); + + // View date control + const [viewDate, setInnerViewDate] = useMergedState(null, { + value: toRef(props, 'pickerValue'), + defaultValue: props.defaultPickerValue || mergedValue.value, + postState: date => { + const { generateConfig, showTime, defaultValue } = props; + const now = generateConfig.getNow(); + if (!date) return now; + // When value is null and set showTime + if (!mergedValue.value && props.showTime) { + if (typeof showTime === 'object') { + return setDateTime(generateConfig, date, showTime.defaultValue || now); + } + if (defaultValue) { + return setDateTime(generateConfig, date, defaultValue); + } + return setDateTime(generateConfig, date, now); + } + return date; + }, + }); + + const setViewDate = (date: DateType) => { + setInnerViewDate(date); + if (props.onPickerValueChange) { + props.onPickerValueChange(date); + } + }; + + // Panel control + const getInternalNextMode = (nextMode: PanelMode): PanelMode => { + const getNextMode = PickerModeMap[props.picker!]; + if (getNextMode) { + return getNextMode(nextMode); + } + + return nextMode; + }; + + // Save panel is changed from which panel + const [mergedMode, setInnerMode] = useMergedState( + () => { + if (props.picker === 'time') { + return 'time'; + } + return getInternalNextMode('date'); + }, + { + value: toRef(props, 'mode'), + }, + ); + watch( + () => props.picker, + () => { + setInnerMode(props.picker); + }, + ); + + const sourceMode = ref(mergedMode.value); + const setSourceMode = (val: PanelMode) => { + sourceMode.value = val; + }; + + const onInternalPanelChange = (newMode: PanelMode | null, viewValue: DateType) => { + const { onPanelChange, generateConfig } = props; + const nextMode = getInternalNextMode(newMode || mergedMode.value); + setSourceMode(mergedMode.value); + setInnerMode(nextMode); + + if ( + onPanelChange && + (mergedMode.value !== nextMode || isEqual(generateConfig, viewDate.value, viewDate.value)) + ) { + onPanelChange(viewValue, nextMode); + } + }; + + const triggerSelect = ( + date: DateType, + type: 'key' | 'mouse' | 'submit', + forceTriggerSelect = false, + ) => { + const { picker, generateConfig, onSelect, onChange, disabledDate } = props; + if (mergedMode.value === picker || forceTriggerSelect) { + setInnerValue(date); + + if (onSelect) { + onSelect(date); + } + + if (onContextSelect) { + onContextSelect(date, type); + } + + if ( + onChange && + !isEqual(generateConfig, date, mergedValue.value) && + !disabledDate?.(date) + ) { + onChange(date); + } + } + }; + + // ========================= Interactive ========================== + const onInternalKeydown = (e: KeyboardEvent) => { + if (panelRef.value && panelRef.value.onKeydown) { + if ( + [ + KeyCode.LEFT, + KeyCode.RIGHT, + KeyCode.UP, + KeyCode.DOWN, + KeyCode.PAGE_UP, + KeyCode.PAGE_DOWN, + KeyCode.ENTER, + ].includes(e.which) + ) { + e.preventDefault(); + } + return panelRef.value.onKeydown(e); + } + + /* istanbul ignore next */ + /* eslint-disable no-lone-blocks */ + { + warning( + false, + 'Panel not correct handle keyDown event. Please help to fire issue about this.', + ); + return false; + } + /* eslint-enable no-lone-blocks */ + }; + + const onInternalBlur = (e: FocusEvent) => { + if (panelRef.value && panelRef.value.onBlur) { + panelRef.value.onBlur(e); + } + }; + const onNow = () => { + const { generateConfig, hourStep, minuteStep, secondStep } = props; + const now = generateConfig.getNow(); + const lowerBoundTime = getLowerBoundTime( + generateConfig.getHour(now), + generateConfig.getMinute(now), + generateConfig.getSecond(now), + isHourStepValid.value ? hourStep : 1, + isMinuteStepValid.value ? minuteStep : 1, + isSecondStepValid.value ? secondStep : 1, + ); + const adjustedNow = setTime( + generateConfig, + now, + lowerBoundTime[0], // hour + lowerBoundTime[1], // minute + lowerBoundTime[2], // second + ); + triggerSelect(adjustedNow, 'submit'); + }; + + const classString = computed(() => { + const { prefixCls, direction } = props; + return classNames(`${prefixCls}-panel`, { + [`${prefixCls}-panel-has-range`]: + rangedValue && rangedValue.value && rangedValue.value[0] && rangedValue.value[1], + [`${prefixCls}-panel-has-range-hover`]: + hoverRangedValue && + hoverRangedValue.value && + hoverRangedValue.value[0] && + hoverRangedValue.value[1], + [`${prefixCls}-panel-rtl`]: direction === 'rtl', + }); + }); + useProvidePanel({ + ...panelContext, + mode: mergedMode, + hideHeader: computed(() => + props.hideHeader !== undefined ? props.hideHeader : panelContext.hideHeader?.value, + ), + hidePrevBtn: computed(() => inRange.value && panelPosition.value === 'right'), + hideNextBtn: computed(() => inRange.value && panelPosition.value === 'left'), + }); + + watch( + () => props.value, + () => { + if (props.value) { + setInnerViewDate(props.value); + } + }, + ); + + return () => { + const { + prefixCls = 'ant-picker', + locale, + generateConfig, + disabledDate, + picker = 'date', + tabindex = 0, + showNow, + showTime, + showToday, + renderExtraFooter, + onMousedown, + onOk, + components, + } = props; + if (operationRef && panelPosition.value !== 'right') { + operationRef.value = { + onKeydown: onInternalKeydown, + onClose: () => { + if (panelRef.value && panelRef.value.onClose) { + panelRef.value.onClose(); + } + }, + }; + } + + // ============================ Panels ============================ + let panelNode: VueNode; + const pickerProps = { + ...attrs, + ...(props as MergedPickerPanelProps), + operationRef: panelRef, + prefixCls, + viewDate: viewDate.value, + value: mergedValue.value, + onViewDateChange: setViewDate, + sourceMode: sourceMode.value, + onPanelChange: onInternalPanelChange, + disabledDate, + }; + delete pickerProps.onChange; + delete pickerProps.onSelect; + switch (mergedMode.value) { + case 'decade': + panelNode = ( + + {...pickerProps} + onSelect={(date, type) => { + setViewDate(date); + triggerSelect(date, type); + }} + /> + ); + break; + + case 'year': + panelNode = ( + + {...pickerProps} + onSelect={(date, type) => { + setViewDate(date); + triggerSelect(date, type); + }} + /> + ); + break; + + case 'month': + panelNode = ( + + {...pickerProps} + onSelect={(date, type) => { + setViewDate(date); + triggerSelect(date, type); + }} + /> + ); + break; + + case 'quarter': + panelNode = ( + + {...pickerProps} + onSelect={(date, type) => { + setViewDate(date); + triggerSelect(date, type); + }} + /> + ); + break; + + case 'week': + panelNode = ( + { + setViewDate(date); + triggerSelect(date, type); + }} + /> + ); + break; + + case 'time': + delete pickerProps.showTime; + panelNode = ( + + {...pickerProps} + {...(typeof showTime === 'object' ? showTime : null)} + onSelect={(date, type) => { + setViewDate(date); + triggerSelect(date, type); + }} + /> + ); + break; + + default: + if (showTime) { + panelNode = ( + { + setViewDate(date); + triggerSelect(date, type); + }} + /> + ); + } else { + panelNode = ( + + {...pickerProps} + onSelect={(date, type) => { + setViewDate(date); + triggerSelect(date, type); + }} + /> + ); + } + } + + // ============================ Footer ============================ + let extraFooter: VueNode; + let rangesNode: VueNode; + + if (!hideRanges?.value) { + extraFooter = getExtraFooter(prefixCls, mergedMode.value, renderExtraFooter); + rangesNode = getRanges({ + prefixCls, + components, + needConfirmButton: needConfirmButton.value, + okDisabled: !mergedValue.value || (disabledDate && disabledDate(mergedValue.value)), + locale, + showNow, + onNow: needConfirmButton.value && onNow, + onOk: () => { + if (mergedValue.value) { + triggerSelect(mergedValue.value, 'submit', true); + if (onOk) { + onOk(mergedValue.value); + } + } + }, + }); + } + + let todayNode: VueNode; + + if (showToday && mergedMode.value === 'date' && picker === 'date' && !showTime) { + const now = generateConfig.getNow(); + const todayCls = `${prefixCls}-today-btn`; + const disabled = disabledDate && disabledDate(now); + todayNode = ( +
{ + if (!disabled) { + triggerSelect(now, 'mouse', true); + } + }} + > + {locale.today} + + ); + } + return ( +
+ {panelNode} + {extraFooter || rangesNode || todayNode ? ( +
+ {extraFooter} + {rangesNode} + {todayNode} +
+ ) : null} +
+ ); + }; + }, + }); +} +const InterPickerPanel = PickerPanel(); +export default (props: MergedPickerPanelProps): JSX.Element => + createVNode(InterPickerPanel, props); diff --git a/components/vc-picker/PickerTrigger.tsx b/components/vc-picker/PickerTrigger.tsx new file mode 100644 index 000000000..4b133ff4d --- /dev/null +++ b/components/vc-picker/PickerTrigger.tsx @@ -0,0 +1,103 @@ +import type { CSSProperties } from '@vue/runtime-dom'; +import type { AlignType } from '../vc-align/interface'; +import Trigger from '../vc-trigger'; +import classNames from '../_util/classNames'; +import useMergeProps from './hooks/useMergeProps'; + +const BUILT_IN_PLACEMENTS = { + bottomLeft: { + points: ['tl', 'bl'], + offset: [0, 4], + overflow: { + adjustX: 1, + adjustY: 1, + }, + }, + bottomRight: { + points: ['tr', 'br'], + offset: [0, 4], + overflow: { + adjustX: 1, + adjustY: 1, + }, + }, + topLeft: { + points: ['bl', 'tl'], + offset: [0, -4], + overflow: { + adjustX: 0, + adjustY: 1, + }, + }, + topRight: { + points: ['br', 'tr'], + offset: [0, -4], + overflow: { + adjustX: 0, + adjustY: 1, + }, + }, +}; + +type Placement = 'bottomLeft' | 'bottomRight' | 'topLeft' | 'topRight'; + +export type PickerTriggerProps = { + prefixCls: string; + visible: boolean; + popupStyle?: CSSProperties; + dropdownClassName?: string; + transitionName?: string; + getPopupContainer?: (node: HTMLElement) => HTMLElement; + dropdownAlign?: AlignType; + range?: boolean; + popupPlacement?: Placement; + direction?: 'ltr' | 'rtl'; +}; + +function PickerTrigger(props: PickerTriggerProps, { slots }) { + const { + prefixCls, + popupStyle, + visible, + dropdownClassName, + dropdownAlign, + transitionName, + getPopupContainer, + range, + popupPlacement, + direction, + } = useMergeProps(props); + const dropdownPrefixCls = `${prefixCls}-dropdown`; + + const getPopupPlacement = () => { + if (popupPlacement !== undefined) { + return popupPlacement; + } + return direction === 'rtl' ? 'bottomRight' : 'bottomLeft'; + }; + + return ( + + ); +} + +export default PickerTrigger; diff --git a/components/vc-picker/RangeContext.tsx b/components/vc-picker/RangeContext.tsx new file mode 100644 index 000000000..17146b3ac --- /dev/null +++ b/components/vc-picker/RangeContext.tsx @@ -0,0 +1,74 @@ +import type { InjectionKey, PropType, Ref } from 'vue'; +import { defineComponent, inject, provide, ref, toRef, watch } from 'vue'; +import type { NullableDateType, RangeValue } from './interface'; + +export type RangeContextProps = { + /** + * Set displayed range value style. + * Panel only has one value, this is only style effect. + */ + rangedValue?: Ref<[NullableDateType, NullableDateType] | null>; + hoverRangedValue?: Ref>; + inRange?: Ref; + panelPosition?: Ref<'left' | 'right' | false>; +}; + +type RangeContextProviderValue = { + /** + * Set displayed range value style. + * Panel only has one value, this is only style effect. + */ + rangedValue?: [NullableDateType, NullableDateType] | null; + hoverRangedValue?: RangeValue; + inRange?: boolean; + panelPosition?: 'left' | 'right' | false; +}; + +const RangeContextKey: InjectionKey = Symbol('RangeContextProps'); + +export const useProvideRange = (props: RangeContextProps) => { + provide(RangeContextKey, props); +}; + +export const useInjectRange = () => { + return inject(RangeContextKey, { + rangedValue: ref(), + hoverRangedValue: ref(), + inRange: ref(), + panelPosition: ref(), + }); +}; + +export const RangeContextProvider = defineComponent({ + name: 'PanelContextProvider', + inheritAttrs: false, + props: { + value: { + type: Object as PropType, + default: () => ({} as RangeContextProviderValue), + }, + }, + setup(props, { slots }) { + const value: RangeContextProps = { + rangedValue: ref(props.value.rangedValue), + hoverRangedValue: ref(props.value.hoverRangedValue), + inRange: ref(props.value.inRange), + panelPosition: ref(props.value.panelPosition), + }; + useProvideRange(value); + toRef; + watch( + () => props.value, + () => { + Object.keys(props.value).forEach(key => { + if (value[key]) { + value[key].value = props.value[key]; + } + }); + }, + ); + return () => slots.default?.(); + }, +}); + +export default RangeContextKey; diff --git a/components/vc-picker/RangePicker.tsx b/components/vc-picker/RangePicker.tsx new file mode 100644 index 000000000..7a71bb085 --- /dev/null +++ b/components/vc-picker/RangePicker.tsx @@ -0,0 +1,1227 @@ +import type { DisabledTimes, PanelMode, PickerMode, RangeValue, EventValue } from './interface'; +import type { PickerBaseProps, PickerDateProps, PickerTimeProps } from './Picker'; +import type { SharedTimeProps } from './panels/TimePanel'; +import PickerTrigger from './PickerTrigger'; +import PickerPanel from './PickerPanel'; +import usePickerInput from './hooks/usePickerInput'; +import getDataOrAriaProps, { toArray, getValue, updateValues } from './utils/miscUtil'; +import { getDefaultFormat, getInputSize, elementsContains } from './utils/uiUtil'; +import type { ContextOperationRefProps } from './PanelContext'; +import { useProvidePanel } from './PanelContext'; +import { + isEqual, + getClosingViewDate, + isSameDate, + isSameWeek, + isSameQuarter, + formatValue, + parseValue, +} from './utils/dateUtil'; +import useValueTexts from './hooks/useValueTexts'; +import useTextValueMapping from './hooks/useTextValueMapping'; +import type { GenerateConfig } from './generate'; +import type { PickerPanelProps } from '.'; +import { RangeContextProvider } from './RangeContext'; +import useRangeDisabled from './hooks/useRangeDisabled'; +import getExtraFooter from './utils/getExtraFooter'; +import getRanges from './utils/getRanges'; +import useRangeViewDates from './hooks/useRangeViewDates'; +import type { DateRender } from './panels/DatePanel/DateBody'; +import useHoverValue from './hooks/useHoverValue'; +import type { VueNode } from '../_util/type'; +import type { ChangeEvent, FocusEventHandler, MouseEventHandler } from '../_util/EventInterface'; +import { computed, defineComponent, ref, toRef, watch, watchEffect } from 'vue'; +import useMergedState from '../_util/hooks/useMergedState'; +import { warning } from '../vc-util/warning'; +import useState from '../_util/hooks/useState'; +import classNames from '../_util/classNames'; + +function reorderValues( + values: RangeValue, + generateConfig: GenerateConfig, +): RangeValue { + if (values && values[0] && values[1] && generateConfig.isAfter(values[0], values[1])) { + return [values[1], values[0]]; + } + + return values; +} + +function canValueTrigger( + value: EventValue, + index: number, + disabled: [boolean, boolean], + allowEmpty?: [boolean, boolean] | null, +): boolean { + if (value) { + return true; + } + + if (allowEmpty && allowEmpty[index]) { + return true; + } + + if (disabled[(index + 1) % 2]) { + return true; + } + + return false; +} + +export type RangeType = 'start' | 'end'; + +export type RangeInfo = { + range: RangeType; +}; + +export type RangeDateRender = (props: { + current: DateType; + today: DateType; + info: RangeInfo; +}) => VueNode; + +export type RangePickerSharedProps = { + id?: string; + value?: RangeValue; + defaultValue?: RangeValue; + defaultPickerValue?: [DateType, DateType]; + placeholder?: [string, string]; + disabled?: boolean | [boolean, boolean]; + disabledTime?: (date: EventValue, type: RangeType) => DisabledTimes; + ranges?: Record< + string, + Exclude, null> | (() => Exclude, null>) + >; + separator?: VueNode; + allowEmpty?: [boolean, boolean]; + mode?: [PanelMode, PanelMode]; + onChange?: (values: RangeValue, formatString: [string, string]) => void; + onCalendarChange?: ( + values: RangeValue, + formatString: [string, string], + info: RangeInfo, + ) => void; + onPanelChange?: (values: RangeValue, modes: [PanelMode, PanelMode]) => void; + onFocus?: FocusEventHandler; + onBlur?: FocusEventHandler; + onMouseenter?: MouseEventHandler; + onMouseleave?: MouseEventHandler; + onOk?: (dates: RangeValue) => void; + direction?: 'ltr' | 'rtl'; + autocomplete?: string; + /** @private Internal control of active picker. Do not use since it's private usage */ + activePickerIndex?: 0 | 1; + dateRender?: RangeDateRender; + panelRender?: (originPanel: VueNode) => VueNode; +}; + +type OmitPickerProps = Omit< + Props, + | 'value' + | 'defaultValue' + | 'defaultPickerValue' + | 'placeholder' + | 'disabled' + | 'disabledTime' + | 'showToday' + | 'showTime' + | 'mode' + | 'onChange' + | 'onSelect' + | 'onPanelChange' + | 'pickerValue' + | 'onPickerValueChange' + | 'onOk' + | 'dateRender' +>; + +type RangeShowTimeObject = Omit, 'defaultValue'> & { + defaultValue?: DateType[]; +}; + +export type RangePickerBaseProps = {} & RangePickerSharedProps & + OmitPickerProps>; + +export type RangePickerDateProps = { + showTime?: boolean | RangeShowTimeObject; +} & RangePickerSharedProps & + OmitPickerProps>; + +export type RangePickerTimeProps = { + order?: boolean; +} & RangePickerSharedProps & + OmitPickerProps>; + +export type RangePickerProps = + | RangePickerBaseProps + | RangePickerDateProps + | RangePickerTimeProps; + +// TMP type to fit for ts 3.9.2 +type OmitType = Omit, 'picker'> & + Omit, 'picker'> & + Omit, 'picker'>; + +type MergedRangePickerProps = { + picker?: PickerMode; +} & OmitType; +function RangerPicker() { + return defineComponent>({ + name: 'RangerPicker', + inheritAttrs: false, + props: [ + 'prefixCls', + 'id', + 'popupStyle', + 'dropdownClassName', + 'transitionName', + 'dropdownAlign', + 'getPopupContainer', + 'generateConfig', + 'locale', + 'placeholder', + 'autofocus', + 'disabled', + 'format', + 'picker', + 'showTime', + 'use12Hours', + 'separator', + 'value', + 'defaultValue', + 'defaultPickerValue', + 'open', + 'defaultOpen', + 'disabledDate', + 'disabledTime', + 'dateRender', + 'panelRender', + 'ranges', + 'allowEmpty', + 'allowClear', + 'suffixIcon', + 'clearIcon', + 'pickerRef', + 'inputReadOnly', + 'mode', + 'renderExtraFooter', + 'onChange', + 'onOpenChange', + 'onPanelChange', + 'onCalendarChange', + 'onFocus', + 'onBlur', + 'onMouseenter', + 'onMouseleave', + 'onOk', + 'onKeydown', + 'components', + 'order', + 'direction', + 'activePickerIndex', + 'autocomplete', + ] as any, + setup(props, { attrs, expose }) { + const needConfirmButton = computed( + () => (props.picker === 'date' && !!props.showTime) || props.picker === 'time', + ); + + // We record opened status here in case repeat open with picker + const openRecordsRef = ref>({}); + + const containerRef = ref(null); + const panelDivRef = ref(null); + const startInputDivRef = ref(null); + const endInputDivRef = ref(null); + const separatorRef = ref(null); + const startInputRef = ref(null); + const endInputRef = ref(null); + + // ============================= Misc ============================== + const formatList = computed(() => + toArray( + getDefaultFormat(props.format, props.picker, props.showTime, props.use12Hours), + ), + ); + + // Active picker + const [mergedActivePickerIndex, setMergedActivePickerIndex] = useMergedState<0 | 1>(0, { + value: toRef(props, 'activePickerIndex'), + }); + + // Operation ref + const operationRef = ref(null); + + const mergedDisabled = computed<[boolean, boolean]>(() => { + const { disabled } = props; + if (Array.isArray(disabled)) { + return disabled; + } + + return [disabled || false, disabled || false]; + }); + + // ============================= Value ============================= + const [mergedValue, setInnerValue] = useMergedState>(null, { + value: toRef(props, 'value'), + defaultValue: props.defaultValue, + postState: values => + props.picker === 'time' && !props.order + ? values + : reorderValues(values, props.generateConfig), + }); + + // =========================== View Date =========================== + // Config view panel + const [startViewDate, endViewDate, setViewDate] = useRangeViewDates({ + values: mergedValue, + picker: toRef(props, 'picker'), + defaultDates: props.defaultPickerValue, + generateConfig: toRef(props, 'generateConfig'), + }); + + // ========================= Select Values ========================= + const [selectedValue, setSelectedValue] = useMergedState(mergedValue.value, { + postState: values => { + let postValues = values; + + if (mergedDisabled.value[0] && mergedDisabled.value[1]) { + return postValues; + } + + // Fill disabled unit + for (let i = 0; i < 2; i += 1) { + if (mergedDisabled[i] && !getValue(postValues, i) && !getValue(props.allowEmpty, i)) { + postValues = updateValues(postValues, props.generateConfig.getNow(), i); + } + } + return postValues; + }, + }); + + // ============================= Modes ============================= + const [mergedModes, setInnerModes] = useMergedState<[PanelMode, PanelMode]>( + [props.picker, props.picker], + { + value: toRef(props, 'mode'), + }, + ); + + watch( + () => props.picker, + () => { + setInnerModes([props.picker, props.picker]); + }, + ); + + const triggerModesChange = (modes: [PanelMode, PanelMode], values: RangeValue) => { + setInnerModes(modes); + props.onPanelChange?.(values, modes); + }; + + // ========================= Disable Date ========================== + const [disabledStartDate, disabledEndDate] = useRangeDisabled( + { + picker: toRef(props, 'picker'), + selectedValue, + locale: toRef(props, 'locale'), + disabled: mergedDisabled, + disabledDate: toRef(props, 'disabledDate'), + generateConfig: toRef(props, 'generateConfig'), + }, + openRecordsRef, + ); + + // ============================= Open ============================== + const [mergedOpen, triggerInnerOpen] = useMergedState(false, { + value: toRef(props, 'open'), + defaultValue: props.defaultOpen, + postState: postOpen => + mergedDisabled.value[mergedActivePickerIndex.value] ? false : postOpen, + onChange: newOpen => { + props.onOpenChange?.(newOpen); + + if (!newOpen && operationRef.value && operationRef.value.onClose) { + operationRef.value.onClose(); + } + }, + }); + + const startOpen = computed(() => mergedOpen.value && mergedActivePickerIndex.value === 0); + const endOpen = computed(() => mergedOpen.value && mergedActivePickerIndex.value === 1); + + // ============================= Popup ============================= + // Popup min width + const popupMinWidth = ref(0); + watch(mergedOpen, () => { + if (!mergedOpen.value && containerRef.value) { + popupMinWidth.value = containerRef.value.offsetWidth; + } + }); + + // ============================ Trigger ============================ + const triggerRef = ref(); + + function triggerOpen(newOpen: boolean, index: 0 | 1) { + if (newOpen) { + clearTimeout(triggerRef.value); + openRecordsRef.value[index] = true; + + setMergedActivePickerIndex(index); + triggerInnerOpen(newOpen); + + // Open to reset view date + if (!mergedOpen.value) { + setViewDate(null, index); + } + } else if (mergedActivePickerIndex.value === index) { + triggerInnerOpen(newOpen); + + // Clean up async + // This makes ref not quick refresh in case user open another input with blur trigger + const openRecords = openRecordsRef.value; + triggerRef.value = setTimeout(() => { + if (openRecords === openRecordsRef.value) { + openRecordsRef.value = {}; + } + }); + } + } + + function triggerOpenAndFocus(index: 0 | 1) { + triggerOpen(true, index); + // Use setTimeout to make sure panel DOM exists + window.setTimeout(() => { + const inputRef = [startInputRef, endInputRef][index]; + if (inputRef.value) { + inputRef.value.focus(); + } + }, 0); + } + + function triggerChange(newValue: RangeValue, sourceIndex: 0 | 1) { + let values = newValue; + let startValue = getValue(values, 0); + let endValue = getValue(values, 1); + const { generateConfig, locale, picker, order, onCalendarChange, allowEmpty, onChange } = + props; + + // >>>>> Format start & end values + if (startValue && endValue && generateConfig.isAfter(startValue, endValue)) { + if ( + // WeekPicker only compare week + (picker === 'week' && + !isSameWeek(generateConfig, locale.locale, startValue, endValue)) || + // QuotaPicker only compare week + (picker === 'quarter' && !isSameQuarter(generateConfig, startValue, endValue)) || + // Other non-TimePicker compare date + (picker !== 'week' && + picker !== 'quarter' && + picker !== 'time' && + !isSameDate(generateConfig, startValue, endValue)) + ) { + // Clean up end date when start date is after end date + if (sourceIndex === 0) { + values = [startValue, null]; + endValue = null; + } else { + startValue = null; + values = [null, endValue]; + } + + // Clean up cache since invalidate + openRecordsRef.value = { + [sourceIndex]: true, + }; + } else if (picker !== 'time' || order !== false) { + // Reorder when in same date + values = reorderValues(values, generateConfig); + } + } + + setSelectedValue(values); + + const startStr = + values && values[0] + ? formatValue(values[0], { generateConfig, locale, format: formatList.value[0] }) + : ''; + const endStr = + values && values[1] + ? formatValue(values[1], { generateConfig, locale, format: formatList.value[0] }) + : ''; + if (onCalendarChange) { + const info: RangeInfo = { range: sourceIndex === 0 ? 'start' : 'end' }; + + onCalendarChange(values, [startStr, endStr], info); + } + + // >>>>> Trigger `onChange` event + const canStartValueTrigger = canValueTrigger( + startValue, + 0, + mergedDisabled.value, + allowEmpty, + ); + const canEndValueTrigger = canValueTrigger(endValue, 1, mergedDisabled.value, allowEmpty); + + const canTrigger = values === null || (canStartValueTrigger && canEndValueTrigger); + + if (canTrigger) { + // Trigger onChange only when value is validate + setInnerValue(values); + + if ( + onChange && + (!isEqual(generateConfig, getValue(mergedValue.value, 0), startValue) || + !isEqual(generateConfig, getValue(mergedValue.value, 1), endValue)) + ) { + onChange(values, [startStr, endStr]); + } + } + + // >>>>> Open picker when + + // Always open another picker if possible + let nextOpenIndex: 0 | 1 = null; + if (sourceIndex === 0 && !mergedDisabled.value[1]) { + nextOpenIndex = 1; + } else if (sourceIndex === 1 && !mergedDisabled.value[0]) { + nextOpenIndex = 0; + } + + if ( + nextOpenIndex !== null && + nextOpenIndex !== mergedActivePickerIndex.value && + (!openRecordsRef.value[nextOpenIndex] || !getValue(values, nextOpenIndex)) && + getValue(values, sourceIndex) + ) { + // Delay to focus to avoid input blur trigger expired selectedValues + triggerOpenAndFocus(nextOpenIndex); + } else { + triggerOpen(false, sourceIndex); + } + } + + const forwardKeydown = (e: KeyboardEvent) => { + if (mergedOpen && operationRef.value && operationRef.value.onKeydown) { + // Let popup panel handle keyboard + return operationRef.value.onKeydown(e); + } + + /* istanbul ignore next */ + /* eslint-disable no-lone-blocks */ + { + warning( + false, + 'Picker not correct forward Keydown operation. Please help to fire issue about this.', + ); + return false; + } + }; + + // ============================= Text ============================== + const sharedTextHooksProps = { + formatList, + generateConfig: toRef(props, 'generateConfig'), + locale: toRef(props, 'locale'), + }; + + const [startValueTexts, firstStartValueText] = useValueTexts( + computed(() => getValue(selectedValue.value, 0)), + sharedTextHooksProps, + ); + + const [endValueTexts, firstEndValueText] = useValueTexts( + computed(() => getValue(selectedValue.value, 1)), + sharedTextHooksProps, + ); + + const onTextChange = (newText: string, index: 0 | 1) => { + const inputDate = parseValue(newText, { + locale: props.locale, + formatList: formatList.value, + generateConfig: props.generateConfig, + }); + + const disabledFunc = index === 0 ? disabledStartDate : disabledEndDate; + + if (inputDate && !disabledFunc(inputDate)) { + setSelectedValue(updateValues(selectedValue.value, inputDate, index)); + setViewDate(inputDate, index); + } + }; + + const [startText, triggerStartTextChange, resetStartText] = useTextValueMapping({ + valueTexts: startValueTexts, + onTextChange: newText => onTextChange(newText, 0), + }); + + const [endText, triggerEndTextChange, resetEndText] = useTextValueMapping({ + valueTexts: endValueTexts, + onTextChange: newText => onTextChange(newText, 1), + }); + + const [rangeHoverValue, setRangeHoverValue] = useState>(null); + + // ========================== Hover Range ========================== + const [hoverRangedValue, setHoverRangedValue] = useState>(null); + + const [startHoverValue, onStartEnter, onStartLeave] = useHoverValue( + startText, + sharedTextHooksProps, + ); + + const [endHoverValue, onEndEnter, onEndLeave] = useHoverValue(endText, sharedTextHooksProps); + + const onDateMouseenter = (date: DateType) => { + setHoverRangedValue(updateValues(selectedValue.value, date, mergedActivePickerIndex.value)); + if (mergedActivePickerIndex.value === 0) { + onStartEnter(date); + } else { + onEndEnter(date); + } + }; + + const onDateMouseleave = () => { + setHoverRangedValue(updateValues(selectedValue.value, null, mergedActivePickerIndex.value)); + if (mergedActivePickerIndex.value === 0) { + onStartLeave(); + } else { + onEndLeave(); + } + }; + + // ============================= Input ============================= + const getSharedInputHookProps = (index: 0 | 1, resetText: () => void) => ({ + forwardKeydown, + onBlur: (e: FocusEvent) => { + props.onBlur?.(e); + }, + isClickOutside: (target: EventTarget | null) => + !elementsContains( + [panelDivRef.value, startInputDivRef.value, endInputDivRef.value], + target as HTMLElement, + ), + onFocus: (e: FocusEvent) => { + setMergedActivePickerIndex(index); + props.onFocus?.(e); + }, + triggerOpen: (newOpen: boolean) => { + triggerOpen(newOpen, index); + }, + onSubmit: () => { + triggerChange(selectedValue.value, index); + resetText(); + }, + onCancel: () => { + triggerOpen(false, index); + setSelectedValue(mergedValue.value); + resetText(); + }, + }); + + const [startInputProps, { focused: startFocused, typing: startTyping }] = usePickerInput({ + ...getSharedInputHookProps(0, resetStartText), + blurToCancel: needConfirmButton, + open: startOpen, + value: startText, + onKeydown: (e, preventDefault) => { + props.onKeydown?.(e, preventDefault); + }, + }); + + const [endInputProps, { focused: endFocused, typing: endTyping }] = usePickerInput({ + ...getSharedInputHookProps(1, resetEndText), + blurToCancel: needConfirmButton, + open: endOpen, + value: endText, + onKeydown: (e, preventDefault) => { + props.onKeydown?.(e, preventDefault); + }, + }); + + // ========================== Click Picker ========================== + const onPickerClick = (e: MouseEvent) => { + // When click inside the picker & outside the picker's input elements + // the panel should still be opened + if ( + !mergedOpen.value && + !startInputRef.value.contains(e.target as Node) && + !endInputRef.value.contains(e.target as Node) + ) { + if (!mergedDisabled.value[0]) { + triggerOpenAndFocus(0); + } else if (!mergedDisabled.value[1]) { + triggerOpenAndFocus(1); + } + } + }; + + const onPickerMousedown = (e: MouseEvent) => { + // shouldn't affect input elements if picker is active + if ( + mergedOpen.value && + (startFocused.value || endFocused.value) && + !startInputRef.value.contains(e.target as Node) && + !endInputRef.value.contains(e.target as Node) + ) { + e.preventDefault(); + } + }; + + // ============================= Sync ============================== + // Close should sync back with text value + const startStr = computed(() => + mergedValue.value?.[0] + ? formatValue(mergedValue.value[0], { + locale: props.locale, + format: 'YYYYMMDDHHmmss', + generateConfig: props.generateConfig, + }) + : '', + ); + const endStr = computed(() => + mergedValue.value?.[1] + ? formatValue(mergedValue.value[1], { + locale: props.locale, + format: 'YYYYMMDDHHmmss', + generateConfig: props.generateConfig, + }) + : '', + ); + + watch([mergedOpen, startValueTexts, endValueTexts], () => { + if (!mergedOpen.value) { + setSelectedValue(mergedValue.value); + + if (!startValueTexts.value.length || startValueTexts.value[0] === '') { + triggerStartTextChange(''); + } else if (firstStartValueText.value !== startText.value) { + resetStartText(); + } + if (!endValueTexts.value.length || endValueTexts.value[0] === '') { + triggerEndTextChange(''); + } else if (firstEndValueText.value !== endText.value) { + resetEndText(); + } + } + }); + + // Sync innerValue with control mode + watch([startStr, endStr], () => { + setSelectedValue(mergedValue.value); + }); + + // ============================ Warning ============================ + if (process.env.NODE_ENV !== 'production') { + watchEffect(() => { + const { value, disabled } = props; + if ( + value && + Array.isArray(disabled) && + ((getValue(disabled, 0) && !getValue(value, 0)) || + (getValue(disabled, 1) && !getValue(value, 1))) + ) { + warning( + false, + '`disabled` should not set with empty `value`. You should set `allowEmpty` or `value` instead.', + ); + } + }); + } + + expose({ + focus: () => { + if (startInputRef.value) { + startInputRef.value.focus(); + } + }, + blur: () => { + if (startInputRef.value) { + startInputRef.value.blur(); + } + if (endInputRef.value) { + endInputRef.value.blur(); + } + }, + }); + + // ============================ Ranges ============================= + + const rangeList = computed(() => + Object.keys(props.ranges || {}).map(label => { + const range = props.ranges![label]; + const newValues = typeof range === 'function' ? range() : range; + + return { + label, + onClick: () => { + triggerChange(newValues, null); + triggerOpen(false, mergedActivePickerIndex.value); + }, + onMouseenter: () => { + setRangeHoverValue(newValues); + }, + onMouseleave: () => { + setRangeHoverValue(null); + }, + }; + }), + ); + // ============================= Panel ============================= + const panelHoverRangedValue = computed(() => { + if ( + mergedOpen.value && + hoverRangedValue.value && + hoverRangedValue.value[0] && + hoverRangedValue.value[1] && + props.generateConfig.isAfter(hoverRangedValue.value[1], hoverRangedValue.value[0]) + ) { + return hoverRangedValue.value; + } else { + return null; + } + }); + function renderPanel( + panelPosition: 'left' | 'right' | false = false, + panelProps: Partial> = {}, + ) { + const { generateConfig, showTime, dateRender, direction, disabledTime, prefixCls, locale } = + props; + + let panelShowTime: boolean | SharedTimeProps | undefined = + showTime as SharedTimeProps; + if (showTime && typeof showTime === 'object' && showTime.defaultValue) { + const timeDefaultValues: DateType[] = showTime.defaultValue!; + panelShowTime = { + ...showTime, + defaultValue: getValue(timeDefaultValues, mergedActivePickerIndex.value) || undefined, + }; + } + + let panelDateRender: DateRender | null = null; + if (dateRender) { + panelDateRender = ({ current: date, today }) => + dateRender({ + current: date, + today, + info: { + range: mergedActivePickerIndex.value ? 'end' : 'start', + }, + }); + } + + return ( + + + {...(props as any)} + {...panelProps} + dateRender={panelDateRender} + showTime={panelShowTime} + mode={mergedModes.value[mergedActivePickerIndex.value]} + generateConfig={generateConfig} + style={undefined} + direction={direction} + disabledDate={ + mergedActivePickerIndex.value === 0 ? disabledStartDate : disabledEndDate + } + disabledTime={date => { + if (disabledTime) { + return disabledTime(date, mergedActivePickerIndex.value === 0 ? 'start' : 'end'); + } + return false; + }} + class={classNames({ + [`${prefixCls}-panel-focused`]: + mergedActivePickerIndex.value === 0 ? !startTyping.value : !endTyping.value, + })} + value={getValue(selectedValue.value, mergedActivePickerIndex.value)} + locale={locale} + tabIndex={-1} + onPanelChange={(date, newMode) => { + // clear hover value when panel change + if (mergedActivePickerIndex.value === 0) { + onStartLeave(true); + } + if (mergedActivePickerIndex.value === 1) { + onEndLeave(true); + } + triggerModesChange( + updateValues(mergedModes.value, newMode, mergedActivePickerIndex.value), + updateValues(selectedValue.value, date, mergedActivePickerIndex.value), + ); + + let viewDate = date; + if ( + panelPosition === 'right' && + mergedModes.value[mergedActivePickerIndex.value] === newMode + ) { + viewDate = getClosingViewDate(viewDate, newMode as any, generateConfig, -1); + } + setViewDate(viewDate, mergedActivePickerIndex.value); + }} + onOk={null} + onSelect={undefined} + onChange={undefined} + defaultValue={ + mergedActivePickerIndex.value === 0 + ? getValue(selectedValue.value, 1) + : getValue(selectedValue.value, 0) + } + defaultPickerValue={undefined} + /> + + ); + } + + const onContextSelect = (date: DateType, type: 'key' | 'mouse' | 'submit') => { + const values = updateValues(selectedValue.value, date, mergedActivePickerIndex.value); + + if (type === 'submit' || (type !== 'key' && !needConfirmButton.value)) { + // triggerChange will also update selected values + triggerChange(values, mergedActivePickerIndex.value); + // clear hover value style + if (mergedActivePickerIndex.value === 0) { + onStartLeave(); + } else { + onEndLeave(); + } + } else { + setSelectedValue(values); + } + }; + + useProvidePanel({ + operationRef, + hideHeader: computed(() => props.picker === 'time'), + onDateMouseenter, + onDateMouseleave, + hideRanges: computed(() => true), + onSelect: onContextSelect, + open: mergedOpen, + }); + + return () => { + const { + prefixCls = 'rc-picker', + id, + popupStyle, + dropdownClassName, + transitionName, + dropdownAlign, + getPopupContainer, + generateConfig, + locale, + placeholder, + autofocus, + picker = 'date', + showTime, + separator = '~', + disabledDate, + panelRender, + allowClear, + suffixIcon, + clearIcon, + inputReadOnly, + renderExtraFooter, + onMouseenter, + onMouseleave, + onOk, + components, + direction, + autocomplete = 'off', + } = props; + let arrowLeft = 0; + let panelLeft = 0; + if ( + mergedActivePickerIndex.value && + startInputDivRef.value && + separatorRef.value && + panelDivRef.value + ) { + // Arrow offset + arrowLeft = startInputDivRef.value.offsetWidth + separatorRef.value.offsetWidth; + + if (panelDivRef.value.offsetWidth && arrowLeft > panelDivRef.value.offsetWidth) { + panelLeft = arrowLeft; + } + } + + const arrowPositionStyle = direction === 'rtl' ? { right: arrowLeft } : { left: arrowLeft }; + + function renderPanels() { + let panels: VueNode; + const extraNode = getExtraFooter( + prefixCls, + mergedModes.value[mergedActivePickerIndex.value], + renderExtraFooter, + ); + + const rangesNode = getRanges({ + prefixCls, + components, + needConfirmButton: needConfirmButton.value, + okDisabled: + !getValue(selectedValue.value, mergedActivePickerIndex.value) || + (disabledDate && disabledDate(selectedValue.value[mergedActivePickerIndex.value])), + locale, + rangeList: rangeList.value, + onOk: () => { + if (getValue(selectedValue.value, mergedActivePickerIndex.value)) { + // triggerChangeOld(selectedValue.value); + triggerChange(selectedValue.value, mergedActivePickerIndex.value); + if (onOk) { + onOk(selectedValue.value); + } + } + }, + }); + + if (picker !== 'time' && !showTime) { + const viewDate = + mergedActivePickerIndex.value === 0 ? startViewDate.value : endViewDate.value; + const nextViewDate = getClosingViewDate(viewDate, picker, generateConfig); + const currentMode = mergedModes.value[mergedActivePickerIndex.value]; + + const showDoublePanel = currentMode === picker; + const leftPanel = renderPanel(showDoublePanel ? 'left' : false, { + pickerValue: viewDate, + onPickerValueChange: newViewDate => { + setViewDate(newViewDate, mergedActivePickerIndex.value); + }, + }); + const rightPanel = renderPanel('right', { + pickerValue: nextViewDate, + onPickerValueChange: newViewDate => { + setViewDate( + getClosingViewDate(newViewDate, picker, generateConfig, -1), + mergedActivePickerIndex.value, + ); + }, + }); + + if (direction === 'rtl') { + panels = ( + <> + {rightPanel} + {showDoublePanel && leftPanel} + + ); + } else { + panels = ( + <> + {leftPanel} + {showDoublePanel && rightPanel} + + ); + } + } else { + panels = renderPanel(); + } + + let mergedNodes: VueNode = ( + <> +
{panels}
+ {(extraNode || rangesNode) && ( +
+ {extraNode} + {rangesNode} +
+ )} + + ); + + if (panelRender) { + mergedNodes = panelRender(mergedNodes); + } + + return ( +
{ + e.preventDefault(); + }} + > + {mergedNodes} +
+ ); + } + + const rangePanel = ( +
+
+ {renderPanels()} +
+ ); + + // ============================= Icons ============================= + let suffixNode: VueNode; + if (suffixIcon) { + suffixNode = {suffixIcon}; + } + + let clearNode: VueNode; + if ( + allowClear && + ((getValue(mergedValue.value, 0) && !mergedDisabled.value[0]) || + (getValue(mergedValue.value, 1) && !mergedDisabled.value[1])) + ) { + clearNode = ( + { + e.preventDefault(); + e.stopPropagation(); + }} + onMouseup={e => { + e.preventDefault(); + e.stopPropagation(); + let values = mergedValue.value; + + if (!mergedDisabled.value[0]) { + values = updateValues(values, null, 0); + } + if (!mergedDisabled.value[1]) { + values = updateValues(values, null, 1); + } + + triggerChange(values, null); + triggerOpen(false, mergedActivePickerIndex.value); + }} + class={`${prefixCls}-clear`} + > + {clearIcon || } + + ); + } + + const inputSharedProps = { + size: getInputSize(picker, formatList.value[0], generateConfig), + }; + + let activeBarLeft = 0; + let activeBarWidth = 0; + if (startInputDivRef.value && endInputDivRef.value && separatorRef.value) { + if (mergedActivePickerIndex.value === 0) { + activeBarWidth = startInputDivRef.value.offsetWidth; + } else { + activeBarLeft = arrowLeft; + activeBarWidth = endInputDivRef.value.offsetWidth; + } + } + const activeBarPositionStyle = + direction === 'rtl' ? { right: `${activeBarLeft}px` } : { left: `${activeBarLeft}px` }; + // ============================ Return ============================= + + return ( + rangePanel, + }} + > +
+
+ { + triggerStartTextChange(e.target.value); + }} + autofocus={autofocus} + placeholder={getValue(placeholder, 0) || ''} + ref={startInputRef} + {...startInputProps.value} + {...inputSharedProps} + autocomplete={autocomplete} + /> +
+
+ {separator} +
+
+ { + triggerEndTextChange(e.target.value); + }} + placeholder={getValue(placeholder, 1) || ''} + ref={endInputRef} + {...endInputProps.value} + {...inputSharedProps} + autocomplete={autocomplete} + /> +
+
+ {suffixNode} + {clearNode} +
+ + ); + }; + }, + }); +} + +const InterRangerPicker = RangerPicker(); +export default InterRangerPicker; diff --git a/components/vc-picker/generate/dateFns.ts b/components/vc-picker/generate/dateFns.ts new file mode 100644 index 000000000..29d9be5ea --- /dev/null +++ b/components/vc-picker/generate/dateFns.ts @@ -0,0 +1,138 @@ +import { + getDay, + getYear, + getMonth, + getDate, + endOfMonth, + getHours, + getMinutes, + getSeconds, + addYears, + addMonths, + addDays, + setYear, + setMonth, + setDate, + setHours, + setMinutes, + setSeconds, + isAfter, + isValid, + getWeek, + startOfWeek, + format as formatDate, + parse as parseDate, + isDate, +} from 'date-fns'; +import * as Locale from 'date-fns/locale'; +import type { GenerateConfig } from '.'; + +const dealLocal = (str: string) => { + return str.replace(/_/g, ''); +}; + +const localeParse = (format: string) => { + return format + .replace(/Y/g, 'y') + .replace(/D/g, 'd') + .replace(/gggg/, 'yyyy') + .replace(/g/g, 'G') + .replace(/([Ww])o/g, 'wo'); +}; + +const generateConfig: GenerateConfig = { + // get + getNow: () => new Date(), + getFixedDate: string => new Date(string), + getEndDate: date => endOfMonth(date), + getWeekDay: date => getDay(date), + getYear: date => getYear(date), + getMonth: date => getMonth(date), + getDate: date => getDate(date), + getHour: date => getHours(date), + getMinute: date => getMinutes(date), + getSecond: date => getSeconds(date), + + // set + addYear: (date, diff) => addYears(date, diff), + addMonth: (date, diff) => addMonths(date, diff), + addDate: (date, diff) => addDays(date, diff), + setYear: (date, year) => setYear(date, year), + setMonth: (date, month) => setMonth(date, month), + setDate: (date, num) => setDate(date, num), + setHour: (date, hour) => setHours(date, hour), + setMinute: (date, minute) => setMinutes(date, minute), + setSecond: (date, second) => setSeconds(date, second), + + // Compare + isAfter: (date1, date2) => isAfter(date1, date2), + isValidate: date => isValid(date), + + locale: { + getWeekFirstDay: locale => { + const clone = Locale[dealLocal(locale)]; + return clone.options.weekStartsOn; + }, + getWeekFirstDate: (locale, date) => { + return startOfWeek(date, { locale: Locale[dealLocal(locale)] }); + }, + getWeek: (locale, date) => { + return getWeek(date, { locale: Locale[dealLocal(locale)] }); + }, + getShortWeekDays: locale => { + const clone = Locale[dealLocal(locale)]; + return Array.from({ length: 7 }).map((_, i) => clone.localize.day(i, { width: 'short' })); + }, + getShortMonths: locale => { + const clone = Locale[dealLocal(locale)]; + return Array.from({ length: 12 }).map((_, i) => + clone.localize.month(i, { width: 'abbreviated' }), + ); + }, + format: (locale, date, format) => { + if (!isValid(date)) { + return null; + } + return formatDate(date, localeParse(format), { + locale: Locale[dealLocal(locale)], + }); + }, + parse: (locale, text, formats) => { + for (let i = 0; i < formats.length; i += 1) { + const format = localeParse(formats[i]); + const formatText = text; + const date = parseDate(formatText, format, new Date(), { + locale: Locale[dealLocal(locale)], + }); + if (isValid(date)) { + return date; + } + } + return null; + }, + }, + toDate: (value, valueFormat) => { + if (Array.isArray(value)) { + return value.map((val: any) => + typeof val === 'string' && val ? parseDate(val, valueFormat, new Date()) : val || null, + ) as Date[]; + } else { + return ( + typeof value === 'string' && value + ? parseDate(value, valueFormat, new Date()) + : value || null + ) as Date; + } + }, + toString: (value, valueFormat) => { + if (Array.isArray(value)) { + return value.map((val: any) => + isDate(val) ? formatDate(val as Date, valueFormat) : val, + ) as string[]; + } else { + return (isDate(value) ? formatDate(value as Date, valueFormat) : value) as string; + } + }, +}; + +export default generateConfig; diff --git a/components/vc-picker/generate/dayjs.ts b/components/vc-picker/generate/dayjs.ts new file mode 100644 index 000000000..39ab3a1d5 --- /dev/null +++ b/components/vc-picker/generate/dayjs.ts @@ -0,0 +1,137 @@ +import type { Dayjs } from 'dayjs'; +import dayjs from 'dayjs'; +import weekday from 'dayjs/plugin/weekday'; +import localeData from 'dayjs/plugin/localeData'; +import weekOfYear from 'dayjs/plugin/weekOfYear'; +import weekYear from 'dayjs/plugin/weekYear'; +import advancedFormat from 'dayjs/plugin/advancedFormat'; +import customParseFormat from 'dayjs/plugin/customParseFormat'; +import type { GenerateConfig } from '.'; +import { noteOnce } from '../../vc-util/warning'; + +dayjs.extend(customParseFormat); +dayjs.extend(advancedFormat); +dayjs.extend(weekday); +dayjs.extend(localeData); +dayjs.extend(weekOfYear); +dayjs.extend(weekYear); + +dayjs.extend((_o, c) => { + // todo support Wo (ISO week) + const proto = c.prototype; + const oldFormat = proto.format; + proto.format = function f(formatStr: string) { + const str = (formatStr || '').replace('Wo', 'wo'); + return oldFormat.bind(this)(str); + }; +}); + +type IlocaleMapObject = Record; +const localeMap: IlocaleMapObject = { + en_GB: 'en-gb', + en_US: 'en', + zh_CN: 'zh-cn', + zh_TW: 'zh-tw', +}; + +const parseLocale = (locale: string) => { + const mapLocale = localeMap[locale]; + return mapLocale || locale.split('_')[0]; +}; + +const parseNoMatchNotice = () => { + /* istanbul ignore next */ + noteOnce(false, 'Not match any format. Please help to fire a issue about this.'); +}; + +const generateConfig: GenerateConfig = { + // get + getNow: () => dayjs(), + getFixedDate: string => dayjs(string, 'YYYY-MM-DD'), + getEndDate: date => date.endOf('month'), + getWeekDay: date => { + const clone = date.locale('en'); + return clone.weekday() + clone.localeData().firstDayOfWeek(); + }, + getYear: date => date.year(), + getMonth: date => date.month(), + getDate: date => date.date(), + getHour: date => date.hour(), + getMinute: date => date.minute(), + getSecond: date => date.second(), + + // set + addYear: (date, diff) => date.add(diff, 'year'), + addMonth: (date, diff) => date.add(diff, 'month'), + addDate: (date, diff) => date.add(diff, 'day'), + setYear: (date, year) => date.year(year), + setMonth: (date, month) => date.month(month), + setDate: (date, num) => date.date(num), + setHour: (date, hour) => date.hour(hour), + setMinute: (date, minute) => date.minute(minute), + setSecond: (date, second) => date.second(second), + + // Compare + isAfter: (date1, date2) => date1.isAfter(date2), + isValidate: date => date.isValid(), + + locale: { + getWeekFirstDay: locale => dayjs().locale(parseLocale(locale)).localeData().firstDayOfWeek(), + getWeekFirstDate: (locale, date) => date.locale(parseLocale(locale)).weekday(0), + getWeek: (locale, date) => date.locale(parseLocale(locale)).week(), + getShortWeekDays: locale => dayjs().locale(parseLocale(locale)).localeData().weekdaysMin(), + getShortMonths: locale => dayjs().locale(parseLocale(locale)).localeData().monthsShort(), + format: (locale, date, format) => date.locale(parseLocale(locale)).format(format), + parse: (locale, text, formats) => { + const localeStr = parseLocale(locale); + for (let i = 0; i < formats.length; i += 1) { + const format = formats[i]; + const formatText = text; + if (format.includes('wo') || format.includes('Wo')) { + // parse Wo + const year = formatText.split('-')[0]; + const weekStr = formatText.split('-')[1]; + const firstWeek = dayjs(year, 'YYYY').startOf('year').locale(localeStr); + for (let j = 0; j <= 52; j += 1) { + const nextWeek = firstWeek.add(j, 'week'); + if (nextWeek.format('Wo') === weekStr) { + return nextWeek; + } + } + parseNoMatchNotice(); + return null; + } + const date = dayjs(formatText, format).locale(localeStr); + if (date.isValid()) { + return date; + } + } + + if (text) { + parseNoMatchNotice(); + } + return null; + }, + }, + + toDate: (value, valueFormat) => { + if (Array.isArray(value)) { + return value.map((val: any) => + typeof val === 'string' && val ? dayjs(val, valueFormat) : val || null, + ) as Dayjs[]; + } else { + return ( + typeof value === 'string' && value ? dayjs(value, valueFormat) : value || null + ) as Dayjs; + } + }, + toString: (value, valueFormat) => { + if (Array.isArray(value)) { + return value.map((val: any) => (dayjs.isDayjs(val) ? val.format(valueFormat) : val)); + } else { + return dayjs.isDayjs(value) ? value.format(valueFormat) : value; + } + }, +}; + +export default generateConfig; diff --git a/components/vc-picker/generate/index.ts b/components/vc-picker/generate/index.ts new file mode 100644 index 000000000..4e3e7ca38 --- /dev/null +++ b/components/vc-picker/generate/index.ts @@ -0,0 +1,52 @@ +export type GenerateConfig = { + // Get + getWeekDay: (value: DateType) => number; + getSecond: (value: DateType) => number; + getMinute: (value: DateType) => number; + getHour: (value: DateType) => number; + getDate: (value: DateType) => number; + getMonth: (value: DateType) => number; + getYear: (value: DateType) => number; + getNow: () => DateType; + getFixedDate: (fixed: string) => DateType; + getEndDate: (value: DateType) => DateType; + + // Set + addYear: (value: DateType, diff: number) => DateType; + addMonth: (value: DateType, diff: number) => DateType; + addDate: (value: DateType, diff: number) => DateType; + setYear: (value: DateType, year: number) => DateType; + setMonth: (value: DateType, month: number) => DateType; + setDate: (value: DateType, date: number) => DateType; + setHour: (value: DateType, hour: number) => DateType; + setMinute: (value: DateType, minute: number) => DateType; + setSecond: (value: DateType, second: number) => DateType; + + // Compare + isAfter: (date1: DateType, date2: DateType) => boolean; + isValidate: (date: DateType) => boolean; + + toDate: ( + value: string | string[] | DateType | DateType[], + valueFormat: string, + ) => DateType | DateType[]; + toString: ( + value: string | string[] | DateType | DateType[], + valueFormat: string, + ) => string | string[]; + locale: { + getWeekFirstDay: (locale: string) => number; + getWeekFirstDate: (locale: string, value: DateType) => DateType; + getWeek: (locale: string, value: DateType) => number; + + format: (locale: string, date: DateType, format: string) => string; + + /** Should only return validate date instance */ + parse: (locale: string, text: string, formats: string[]) => DateType | null; + + /** A proxy for getting locale with moment or other locale library */ + getShortWeekDays?: (locale: string) => string[]; + /** A proxy for getting locale with moment or other locale library */ + getShortMonths?: (locale: string) => string[]; + }; +}; diff --git a/components/vc-picker/generate/moment.ts b/components/vc-picker/generate/moment.ts new file mode 100644 index 000000000..cbe549a62 --- /dev/null +++ b/components/vc-picker/generate/moment.ts @@ -0,0 +1,158 @@ +import { noteOnce } from '../../vc-util/warning'; +import type { Moment } from 'moment'; +import moment from 'moment'; +import type { GenerateConfig } from '.'; + +const generateConfig: GenerateConfig = { + // get + getNow: () => moment(), + getFixedDate: string => moment(string, 'YYYY-MM-DD'), + getEndDate: date => { + const clone = date.clone(); + return clone.endOf('month'); + }, + getWeekDay: date => { + const clone = date.clone().locale('en_US'); + return clone.weekday() + clone.localeData().firstDayOfWeek(); + }, + getYear: date => date.year(), + getMonth: date => date.month(), + getDate: date => date.date(), + getHour: date => date.hour(), + getMinute: date => date.minute(), + getSecond: date => date.second(), + + // set + addYear: (date, diff) => { + const clone = date.clone(); + return clone.add(diff, 'year'); + }, + addMonth: (date, diff) => { + const clone = date.clone(); + return clone.add(diff, 'month'); + }, + addDate: (date, diff) => { + const clone = date.clone(); + return clone.add(diff, 'day'); + }, + setYear: (date, year) => { + const clone = date.clone(); + return clone.year(year); + }, + setMonth: (date, month) => { + const clone = date.clone(); + return clone.month(month); + }, + setDate: (date, num) => { + const clone = date.clone(); + return clone.date(num); + }, + setHour: (date, hour) => { + const clone = date.clone(); + return clone.hour(hour); + }, + setMinute: (date, minute) => { + const clone = date.clone(); + return clone.minute(minute); + }, + setSecond: (date, second) => { + const clone = date.clone(); + return clone.second(second); + }, + + // Compare + isAfter: (date1, date2) => date1.isAfter(date2), + isValidate: date => date.isValid(), + + locale: { + getWeekFirstDay: locale => { + const date = moment().locale(locale); + return date.localeData().firstDayOfWeek(); + }, + getWeekFirstDate: (locale, date) => { + const clone = date.clone(); + const result = clone.locale(locale); + return result.weekday(0); + }, + getWeek: (locale, date) => { + const clone = date.clone(); + const result = clone.locale(locale); + return result.week(); + }, + getShortWeekDays: locale => { + const date = moment().locale(locale); + return date.localeData().weekdaysMin(); + }, + getShortMonths: locale => { + const date = moment().locale(locale); + return date.localeData().monthsShort(); + }, + format: (locale, date, format) => { + const clone = date.clone(); + const result = clone.locale(locale); + return result.format(format); + }, + parse: (locale, text, formats) => { + const fallbackFormatList: string[] = []; + + for (let i = 0; i < formats.length; i += 1) { + let format = formats[i]; + let formatText = text; + + if (format.includes('wo') || format.includes('Wo')) { + format = format.replace(/wo/g, 'w').replace(/Wo/g, 'W'); + const matchFormat = format.match(/[-YyMmDdHhSsWwGg]+/g); + const matchText = formatText.match(/[-\d]+/g); + + if (matchFormat && matchText) { + format = matchFormat.join(''); + formatText = matchText.join(''); + } else { + fallbackFormatList.push(format.replace(/o/g, '')); + } + } + + const date = moment(formatText, format, locale, true); + if (date.isValid()) { + return date; + } + } + + // Fallback to fuzzy matching, this should always not reach match or need fire a issue + for (let i = 0; i < fallbackFormatList.length; i += 1) { + const date = moment(text, fallbackFormatList[i], locale, false); + + /* istanbul ignore next */ + if (date.isValid()) { + noteOnce( + false, + 'Not match any format strictly and fallback to fuzzy match. Please help to fire a issue about this.', + ); + return date; + } + } + + return null; + }, + }, + toDate: (value, valueFormat) => { + if (Array.isArray(value)) { + return value.map((val: any) => + typeof val === 'string' && val ? moment(val, valueFormat) : val || null, + ) as Moment[]; + } else { + return ( + typeof value === 'string' && value ? moment(value, valueFormat) : value || null + ) as Moment; + } + }, + toString: (value, valueFormat) => { + if (Array.isArray(value)) { + return value.map((val: any) => (moment.isMoment(val) ? val.format(valueFormat) : val)); + } else { + return moment.isMoment(value) ? value.format(valueFormat) : value; + } + }, +}; + +export default generateConfig; diff --git a/components/vc-picker/hooks/useCellClassName.ts b/components/vc-picker/hooks/useCellClassName.ts new file mode 100644 index 000000000..5c9bc4b38 --- /dev/null +++ b/components/vc-picker/hooks/useCellClassName.ts @@ -0,0 +1,97 @@ +import { isInRange } from '../utils/dateUtil'; +import type { GenerateConfig } from '../generate'; +import type { RangeValue, NullableDateType } from '../interface'; +import { getValue } from '../utils/miscUtil'; + +export default function useCellClassName({ + cellPrefixCls, + generateConfig, + rangedValue, + hoverRangedValue, + isInView, + isSameCell, + offsetCell, + today, + value, +}: { + cellPrefixCls: string; + generateConfig: GenerateConfig; + isSameCell: (current: NullableDateType, target: NullableDateType) => boolean; + offsetCell: (date: DateType, offset: number) => DateType; + isInView: (date: DateType) => boolean; + rangedValue?: RangeValue; + hoverRangedValue?: RangeValue; + today?: NullableDateType; + value?: NullableDateType; +}) { + function getClassName(currentDate: DateType) { + const prevDate = offsetCell(currentDate, -1); + const nextDate = offsetCell(currentDate, 1); + + const rangeStart = getValue(rangedValue, 0); + const rangeEnd = getValue(rangedValue, 1); + + const hoverStart = getValue(hoverRangedValue, 0); + const hoverEnd = getValue(hoverRangedValue, 1); + + const isRangeHovered = isInRange(generateConfig, hoverStart, hoverEnd, currentDate); + + function isRangeStart(date: DateType) { + return isSameCell(rangeStart, date); + } + function isRangeEnd(date: DateType) { + return isSameCell(rangeEnd, date); + } + const isHoverStart = isSameCell(hoverStart, currentDate); + const isHoverEnd = isSameCell(hoverEnd, currentDate); + + const isHoverEdgeStart = + (isRangeHovered || isHoverEnd) && (!isInView(prevDate) || isRangeEnd(prevDate)); + const isHoverEdgeEnd = + (isRangeHovered || isHoverStart) && (!isInView(nextDate) || isRangeStart(nextDate)); + + return { + // In view + [`${cellPrefixCls}-in-view`]: isInView(currentDate), + + // Range + [`${cellPrefixCls}-in-range`]: isInRange( + generateConfig, + rangeStart, + rangeEnd, + currentDate, + ), + [`${cellPrefixCls}-range-start`]: isRangeStart(currentDate), + [`${cellPrefixCls}-range-end`]: isRangeEnd(currentDate), + [`${cellPrefixCls}-range-start-single`]: isRangeStart(currentDate) && !rangeEnd, + [`${cellPrefixCls}-range-end-single`]: isRangeEnd(currentDate) && !rangeStart, + [`${cellPrefixCls}-range-start-near-hover`]: + isRangeStart(currentDate) && + (isSameCell(prevDate, hoverStart) || + isInRange(generateConfig, hoverStart, hoverEnd, prevDate)), + [`${cellPrefixCls}-range-end-near-hover`]: + isRangeEnd(currentDate) && + (isSameCell(nextDate, hoverEnd) || + isInRange(generateConfig, hoverStart, hoverEnd, nextDate)), + + // Range Hover + [`${cellPrefixCls}-range-hover`]: isRangeHovered, + [`${cellPrefixCls}-range-hover-start`]: isHoverStart, + [`${cellPrefixCls}-range-hover-end`]: isHoverEnd, + + // Range Edge + [`${cellPrefixCls}-range-hover-edge-start`]: isHoverEdgeStart, + [`${cellPrefixCls}-range-hover-edge-end`]: isHoverEdgeEnd, + [`${cellPrefixCls}-range-hover-edge-start-near-range`]: + isHoverEdgeStart && isSameCell(prevDate, rangeEnd), + [`${cellPrefixCls}-range-hover-edge-end-near-range`]: + isHoverEdgeEnd && isSameCell(nextDate, rangeStart), + + // Others + [`${cellPrefixCls}-today`]: isSameCell(today, currentDate), + [`${cellPrefixCls}-selected`]: isSameCell(value, currentDate), + }; + } + + return getClassName; +} diff --git a/components/vc-picker/hooks/useHoverValue.ts b/components/vc-picker/hooks/useHoverValue.ts new file mode 100644 index 000000000..2081c95da --- /dev/null +++ b/components/vc-picker/hooks/useHoverValue.ts @@ -0,0 +1,45 @@ +import type { ComputedRef, Ref, UnwrapRef } from 'vue'; +import { ref, onBeforeUnmount, watch } from 'vue'; +import type { ValueTextConfig } from './useValueTexts'; +import useValueTexts from './useValueTexts'; + +export default function useHoverValue( + valueText: Ref, + { formatList, generateConfig, locale }: ValueTextConfig, +): [ComputedRef, (date: DateType) => void, (immediately?: boolean) => void] { + const innerValue = ref(null); + const raf = ref(null); + + function setValue(val: DateType, immediately = false) { + cancelAnimationFrame(raf.value); + if (immediately) { + innerValue.value = val as UnwrapRef; + return; + } + raf.value = requestAnimationFrame(() => { + innerValue.value = val as UnwrapRef; + }); + } + + const [, firstText] = useValueTexts(innerValue as Ref, { + formatList, + generateConfig, + locale, + }); + function onEnter(date: DateType) { + setValue(date); + } + + function onLeave(immediately = false) { + setValue(null, immediately); + } + + watch(valueText, () => { + onLeave(true); + }); + onBeforeUnmount(() => { + cancelAnimationFrame(raf.value); + }); + + return [firstText, onEnter, onLeave]; +} diff --git a/components/vc-picker/hooks/useMergeProps.ts b/components/vc-picker/hooks/useMergeProps.ts new file mode 100644 index 000000000..54450bd6d --- /dev/null +++ b/components/vc-picker/hooks/useMergeProps.ts @@ -0,0 +1,8 @@ +import type { HTMLAttributes } from 'vue'; +import { useAttrs } from 'vue'; + +// 仅用在函数式组件中,不用考虑响应式问题 +export default function useMergeProps(props: T) { + const attrs: HTMLAttributes = useAttrs(); + return { ...props, ...attrs }; +} diff --git a/components/vc-picker/hooks/usePickerInput.ts b/components/vc-picker/hooks/usePickerInput.ts new file mode 100644 index 000000000..5518e11f8 --- /dev/null +++ b/components/vc-picker/hooks/usePickerInput.ts @@ -0,0 +1,183 @@ +import type { ComputedRef, HTMLAttributes, Ref } from 'vue'; +import { onBeforeUnmount } from 'vue'; +import { watchEffect } from 'vue'; +import { watch } from 'vue'; +import { ref } from 'vue'; +import { computed } from 'vue'; +import type { FocusEventHandler } from '../../_util/EventInterface'; +import KeyCode from '../../_util/KeyCode'; +import { addGlobalMousedownEvent, getTargetFromEvent } from '../utils/uiUtil'; + +export default function usePickerInput({ + open, + value, + isClickOutside, + triggerOpen, + forwardKeydown, + onKeydown, + blurToCancel, + onSubmit, + onCancel, + onFocus, + onBlur, +}: { + open: Ref; + value: Ref; + isClickOutside: (clickElement: EventTarget | null) => boolean; + triggerOpen: (open: boolean) => void; + forwardKeydown: (e: KeyboardEvent) => boolean; + onKeydown: (e: KeyboardEvent, preventDefault: () => void) => void; + blurToCancel?: ComputedRef; + onSubmit: () => void | boolean; + onCancel: () => void; + onFocus?: FocusEventHandler; + onBlur?: FocusEventHandler; +}): [ComputedRef, { focused: Ref; typing: Ref }] { + const typing = ref(false); + const focused = ref(false); + + /** + * We will prevent blur to handle open event when user click outside, + * since this will repeat trigger `onOpenChange` event. + */ + const preventBlurRef = ref(false); + + const valueChangedRef = ref(false); + + const preventDefaultRef = ref(false); + + const inputProps = computed(() => ({ + onMousedown: () => { + typing.value = true; + triggerOpen(true); + }, + onKeydown: e => { + const preventDefault = (): void => { + preventDefaultRef.value = true; + }; + + onKeydown(e, preventDefault); + + if (preventDefaultRef.value) return; + + switch (e.which) { + case KeyCode.ENTER: { + if (!open.value) { + triggerOpen(true); + } else if (onSubmit() !== false) { + typing.value = true; + } + + e.preventDefault(); + return; + } + + case KeyCode.TAB: { + if (typing.value && open.value && !e.shiftKey) { + typing.value = false; + e.preventDefault(); + } else if (!typing.value && open.value) { + if (!forwardKeydown(e) && e.shiftKey) { + typing.value = true; + e.preventDefault(); + } + } + return; + } + + case KeyCode.ESC: { + typing.value = true; + onCancel(); + return; + } + } + + if (!open.value && ![KeyCode.SHIFT].includes(e.which)) { + triggerOpen(true); + } else if (!typing.value) { + // Let popup panel handle keyboard + forwardKeydown(e); + } + }, + + onFocus: e => { + typing.value = true; + focused.value = true; + + if (onFocus) { + onFocus(e); + } + }, + + onBlur: e => { + if (preventBlurRef.value || !isClickOutside(document.activeElement)) { + preventBlurRef.value = false; + return; + } + + if (blurToCancel.value) { + setTimeout(() => { + let { activeElement } = document; + while (activeElement && activeElement.shadowRoot) { + activeElement = activeElement.shadowRoot.activeElement; + } + + if (isClickOutside(activeElement)) { + onCancel(); + } + }, 0); + } else if (open.value) { + triggerOpen(false); + + if (valueChangedRef.value) { + onSubmit(); + } + } + focused.value = false; + + if (onBlur) { + onBlur(e); + } + }, + })); + + // check if value changed + watch(open, () => { + valueChangedRef.value = false; + }); + + watch(value, () => { + valueChangedRef.value = true; + }); + const globalMousedownEvent = ref(); + // Global click handler + watchEffect( + () => + globalMousedownEvent.value && + globalMousedownEvent.value()( + (globalMousedownEvent.value = addGlobalMousedownEvent((e: MouseEvent) => { + const target = getTargetFromEvent(e); + + if (open) { + const clickedOutside = isClickOutside(target); + + if (!clickedOutside) { + preventBlurRef.value = true; + + // Always set back in case `onBlur` prevented by user + requestAnimationFrame(() => { + preventBlurRef.value = false; + }); + } else if (!focused.value || clickedOutside) { + triggerOpen(false); + } + } + })), + ), + ); + onBeforeUnmount(() => { + globalMousedownEvent.value && globalMousedownEvent.value(); + }); + + return [inputProps, { focused, typing }]; +} diff --git a/components/vc-picker/hooks/useRangeDisabled.ts b/components/vc-picker/hooks/useRangeDisabled.ts new file mode 100644 index 000000000..b11c1ecd3 --- /dev/null +++ b/components/vc-picker/hooks/useRangeDisabled.ts @@ -0,0 +1,114 @@ +import type { RangeValue, PickerMode, Locale } from '../interface'; +import { getValue } from '../utils/miscUtil'; +import type { GenerateConfig } from '../generate'; +import { isSameDate, getQuarter } from '../utils/dateUtil'; +import type { ComputedRef, Ref } from 'vue'; +import { computed } from 'vue'; + +export default function useRangeDisabled( + { + picker, + locale, + selectedValue, + disabledDate, + disabled, + generateConfig, + }: { + picker: Ref; + selectedValue: Ref>; + disabledDate?: Ref<(date: DateType) => boolean>; + disabled: ComputedRef<[boolean, boolean]>; + locale: Ref; + generateConfig: Ref>; + }, + openRecordsRef: Ref<{ + [x: number]: boolean; + }>, +) { + const startDate = computed(() => getValue(selectedValue.value, 0)); + const endDate = computed(() => getValue(selectedValue.value, 1)); + + function weekFirstDate(date: DateType) { + return generateConfig.value.locale.getWeekFirstDate(locale.value.locale, date); + } + + function monthNumber(date: DateType) { + const year = generateConfig.value.getYear(date); + const month = generateConfig.value.getMonth(date); + return year * 100 + month; + } + + function quarterNumber(date: DateType) { + const year = generateConfig.value.getYear(date); + const quarter = getQuarter(generateConfig.value, date); + return year * 10 + quarter; + } + + const disabledStartDate = (date: DateType) => { + if (disabledDate && disabledDate?.value?.(date)) { + return true; + } + + // Disabled range + if (disabled[1] && endDate) { + return ( + !isSameDate(generateConfig.value, date, endDate.value) && + generateConfig.value.isAfter(date, endDate.value) + ); + } + + // Disabled part + if (openRecordsRef.value[1] && endDate.value) { + switch (picker.value) { + case 'quarter': + return quarterNumber(date) > quarterNumber(endDate.value); + case 'month': + return monthNumber(date) > monthNumber(endDate.value); + case 'week': + return weekFirstDate(date) > weekFirstDate(endDate.value); + default: + return ( + !isSameDate(generateConfig.value, date, endDate.value) && + generateConfig.value.isAfter(date, endDate.value) + ); + } + } + + return false; + }; + + const disabledEndDate = (date: DateType) => { + if (disabledDate.value?.(date)) { + return true; + } + + // Disabled range + if (disabled[0] && startDate) { + return ( + !isSameDate(generateConfig.value, date, endDate.value) && + generateConfig.value.isAfter(startDate.value, date) + ); + } + + // Disabled part + if (openRecordsRef.value[0] && startDate.value) { + switch (picker.value) { + case 'quarter': + return quarterNumber(date) < quarterNumber(startDate.value); + case 'month': + return monthNumber(date) < monthNumber(startDate.value); + case 'week': + return weekFirstDate(date) < weekFirstDate(startDate.value); + default: + return ( + !isSameDate(generateConfig.value, date, startDate.value) && + generateConfig.value.isAfter(startDate.value, date) + ); + } + } + + return false; + }; + + return [disabledStartDate, disabledEndDate]; +} diff --git a/components/vc-picker/hooks/useRangeViewDates.ts b/components/vc-picker/hooks/useRangeViewDates.ts new file mode 100644 index 000000000..274c295c9 --- /dev/null +++ b/components/vc-picker/hooks/useRangeViewDates.ts @@ -0,0 +1,134 @@ +import type { RangeValue, PickerMode } from '../interface'; +import type { GenerateConfig } from '../generate'; +import { getValue, updateValues } from '../utils/miscUtil'; +import { getClosingViewDate, isSameYear, isSameMonth, isSameDecade } from '../utils/dateUtil'; +import type { Ref } from 'vue'; +import { watch } from 'vue'; +import { computed } from 'vue'; +import { ref } from 'vue'; + +function getStartEndDistance( + startDate: DateType, + endDate: DateType, + picker: PickerMode, + generateConfig: GenerateConfig, +): 'same' | 'closing' | 'far' { + const startNext = getClosingViewDate(startDate, picker, generateConfig, 1); + + function getDistance(compareFunc: (start: DateType | null, end: DateType | null) => boolean) { + if (compareFunc(startDate, endDate)) { + return 'same'; + } + if (compareFunc(startNext, endDate)) { + return 'closing'; + } + return 'far'; + } + + switch (picker) { + case 'year': + return getDistance((start, end) => isSameDecade(generateConfig, start, end)); + case 'quarter': + case 'month': + return getDistance((start, end) => isSameYear(generateConfig, start, end)); + default: + return getDistance((start, end) => isSameMonth(generateConfig, start, end)); + } +} + +function getRangeViewDate( + values: RangeValue, + index: 0 | 1, + picker: PickerMode, + generateConfig: GenerateConfig, +): DateType | null { + const startDate = getValue(values, 0); + const endDate = getValue(values, 1); + + if (index === 0) { + return startDate; + } + + if (startDate && endDate) { + const distance = getStartEndDistance(startDate, endDate, picker, generateConfig); + switch (distance) { + case 'same': + return startDate; + case 'closing': + return startDate; + default: + return getClosingViewDate(endDate, picker, generateConfig, -1); + } + } + + return startDate; +} + +export default function useRangeViewDates({ + values, + picker, + defaultDates, + generateConfig, +}: { + values: Ref>; + picker: Ref; + defaultDates: RangeValue | undefined; + generateConfig: Ref>; +}): [Ref, Ref, (viewDate: DateType | null, index: 0 | 1) => void] { + const defaultViewDates = ref<[DateType | null, DateType | null]>([ + getValue(defaultDates, 0), + getValue(defaultDates, 1), + ]); + const viewDates = ref>(null); + const startDate = computed(() => getValue(values.value, 0)); + const endDate = computed(() => getValue(values.value, 1)); + + const getViewDate = (index: 0 | 1): DateType => { + // If set default view date, use it + if (defaultViewDates.value[index]) { + return defaultViewDates.value[index]! as DateType; + } + + return ( + (getValue(viewDates.value, index) as any) || + getRangeViewDate(values.value, index, picker.value, generateConfig.value) || + startDate.value || + endDate.value || + generateConfig.value.getNow() + ); + }; + + const startViewDate = ref(null); + + const endViewDate = ref(null); + watch( + viewDates, + () => { + startViewDate.value = getViewDate(0); + endViewDate.value = getViewDate(1); + }, + { immediate: true }, + ); + + function setViewDate(viewDate: DateType | null, index: 0 | 1) { + if (viewDate) { + let newViewDates = updateValues(viewDates.value, viewDate as any, index); + // Set view date will clean up default one + // Should always be an array + defaultViewDates.value = updateValues(defaultViewDates.value, null, index) || [null, null]; + + // Reset another one when not have value + const anotherIndex = (index + 1) % 2; + if (!getValue(values.value, anotherIndex)) { + newViewDates = updateValues(newViewDates, viewDate, anotherIndex); + } + + viewDates.value = newViewDates; + } else if (startDate.value || endDate.value) { + // Reset all when has values when `viewDate` is `null` which means from open trigger + viewDates.value = null; + } + } + + return [startViewDate, endViewDate, setViewDate]; +} diff --git a/components/vc-picker/hooks/useTextValueMapping.ts b/components/vc-picker/hooks/useTextValueMapping.ts new file mode 100644 index 000000000..eec0366da --- /dev/null +++ b/components/vc-picker/hooks/useTextValueMapping.ts @@ -0,0 +1,37 @@ +import type { ComputedRef, Ref } from 'vue'; +import { ref, watch } from 'vue'; + +export default function useTextValueMapping({ + valueTexts, + onTextChange, +}: { + /** Must useMemo, to assume that `valueTexts` only match on the first change */ + valueTexts: ComputedRef; + onTextChange: (text: string) => void; +}): [Ref, (text: string) => void, () => void] { + const text = ref(''); + + function triggerTextChange(value: string) { + text.value = value; + onTextChange(value); + } + + function resetText() { + text.value = valueTexts.value[0]; + } + + watch( + () => [...valueTexts.value], + (cur, pre = []) => { + if ( + cur.join('||') !== pre.join('||') && + valueTexts.value.every(valText => valText !== text.value) + ) { + resetText(); + } + }, + { immediate: true }, + ); + + return [text, triggerTextChange, resetText]; +} diff --git a/components/vc-picker/hooks/useValueTexts.ts b/components/vc-picker/hooks/useValueTexts.ts new file mode 100644 index 000000000..ac5de2f65 --- /dev/null +++ b/components/vc-picker/hooks/useValueTexts.ts @@ -0,0 +1,51 @@ +import type { ComputedRef, Ref } from 'vue'; +import { computed } from 'vue'; +import useMemo from '../../_util/hooks/useMemo'; +import shallowequal from '../../_util/shallowequal'; +import type { GenerateConfig } from '../generate'; +import type { CustomFormat, Locale } from '../interface'; +import { formatValue } from '../utils/dateUtil'; + +export type ValueTextConfig = { + formatList: ComputedRef<(string | CustomFormat)[]>; + generateConfig: Ref>; + locale: Ref; +}; + +export default function useValueTexts( + value: Ref, + { formatList, generateConfig, locale }: ValueTextConfig, +): [ComputedRef, ComputedRef] { + const texts = useMemo<[string[], string]>( + () => { + if (!value.value) { + return [[''], '']; + } + + // We will convert data format back to first format + let firstValueText = ''; + const fullValueTexts: string[] = []; + + for (let i = 0; i < formatList.value.length; i += 1) { + const format = formatList.value[i]; + const formatStr = formatValue(value.value, { + generateConfig: generateConfig.value, + locale: locale.value, + format, + }); + fullValueTexts.push(formatStr); + + if (i === 0) { + firstValueText = formatStr; + } + } + + return [fullValueTexts, firstValueText]; + }, + [value, formatList], + (next, prev) => prev[0] !== next[0] || !shallowequal(prev[1], next[1]), + ); + const fullValueTexts = computed(() => texts.value[0]); + const firstValueText = computed(() => texts.value[1]); + return [fullValueTexts, firstValueText]; +} diff --git a/components/vc-picker/index.tsx b/components/vc-picker/index.tsx new file mode 100644 index 000000000..10a59da73 --- /dev/null +++ b/components/vc-picker/index.tsx @@ -0,0 +1,7 @@ +import Picker, { PickerProps } from './Picker'; +import PickerPanel, { PickerPanelProps } from './PickerPanel'; +import RangePicker, { RangePickerProps } from './RangePicker'; + +export { PickerPanel, RangePicker, PickerProps, PickerPanelProps, RangePickerProps }; + +export default Picker; diff --git a/components/vc-picker/interface.ts b/components/vc-picker/interface.ts new file mode 100644 index 000000000..fc710d812 --- /dev/null +++ b/components/vc-picker/interface.ts @@ -0,0 +1,111 @@ +import type { Ref } from 'vue'; +import type { VueNode } from '../_util/type'; +import type { GenerateConfig } from './generate'; + +export type Locale = { + locale: string; + + // ===================== Date Panel ===================== + /** Display month before year in date panel header */ + monthBeforeYear?: boolean; + yearFormat: string; + monthFormat?: string; + quarterFormat?: string; + + today: string; + now: string; + backToToday: string; + ok: string; + timeSelect: string; + dateSelect: string; + weekSelect?: string; + clear: string; + month: string; + year: string; + previousMonth: string; + nextMonth: string; + monthSelect: string; + yearSelect: string; + decadeSelect: string; + + dayFormat: string; + dateFormat: string; + dateTimeFormat: string; + previousYear: string; + nextYear: string; + previousDecade: string; + nextDecade: string; + previousCentury: string; + nextCentury: string; + + shortWeekDays?: string[]; + shortMonths?: string[]; +}; + +export type PanelMode = 'time' | 'date' | 'week' | 'month' | 'quarter' | 'year' | 'decade'; + +export type PickerMode = Exclude; + +export type PanelRefProps = { + onKeydown?: (e: KeyboardEvent) => boolean; + onBlur?: (e: FocusEvent) => void; + onClose?: () => void; +}; + +export type NullableDateType = DateType | null | undefined; + +export type OnSelect = (value: DateType, type: 'key' | 'mouse' | 'submit') => void; + +export type PanelSharedProps = { + prefixCls: string; + generateConfig: GenerateConfig; + value?: NullableDateType; + viewDate: DateType; + /** [Legacy] Set default display picker view date */ + defaultPickerValue?: DateType; + locale: Locale; + disabledDate?: (date: DateType) => boolean; + + prevIcon?: VueNode; + nextIcon?: VueNode; + superPrevIcon?: VueNode; + superNextIcon?: VueNode; + + // /** + // * Typescript can not handle generic type so we can not use `forwardRef` here. + // * Thus, move ref into operationRef. + // * This is little hack which should refactor after typescript support. + // */ + operationRef: Ref; + + onSelect: OnSelect; + onViewDateChange: (value: DateType) => void; + onPanelChange: (mode: PanelMode | null, viewValue: DateType) => void; +}; + +export type DisabledTimes = { + disabledHours?: () => number[]; + disabledMinutes?: (hour: number) => number[]; + disabledSeconds?: (hour: number, minute: number) => number[]; +}; + +export type DisabledTime = (date: DateType | null) => DisabledTimes; + +export type OnPanelChange = (value: DateType, mode: PanelMode) => void; + +export type EventValue = DateType | null; +export type RangeValue = [EventValue, EventValue] | null; + +export type Components = { + button?: any; + rangeItem?: any; +}; + +export type RangeList = { + label: string; + onClick: () => void; + onMouseenter: () => void; + onMouseleave: () => void; +}[]; + +export type CustomFormat = (value: DateType) => string; diff --git a/components/vc-calendar/src/locale/ar_EG.js b/components/vc-picker/locale/ar_EG.ts similarity index 88% rename from components/vc-calendar/src/locale/ar_EG.js rename to components/vc-picker/locale/ar_EG.ts index 75b44ac4b..14e9b6b27 100644 --- a/components/vc-calendar/src/locale/ar_EG.js +++ b/components/vc-picker/locale/ar_EG.ts @@ -1,4 +1,7 @@ -export default { +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'ar_EG', today: 'اليوم', now: 'الأن', backToToday: 'العودة إلى اليوم', @@ -25,3 +28,5 @@ export default { previousCentury: 'القرن السابق', nextCentury: 'القرن التالى', }; + +export default locale; diff --git a/components/vc-picker/locale/az_AZ.ts b/components/vc-picker/locale/az_AZ.ts new file mode 100644 index 000000000..a499805bc --- /dev/null +++ b/components/vc-picker/locale/az_AZ.ts @@ -0,0 +1,33 @@ +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'az_AZ', + today: 'Bugün', + now: 'İndi', + backToToday: 'Bugünə qayıt', + ok: 'Təsdiq', + clear: 'Təmizlə', + month: 'Ay', + year: 'İl', + timeSelect: 'vaxtı seç', + dateSelect: 'tarixi seç', + weekSelect: 'Həftə seç', + monthSelect: 'Ay seç', + yearSelect: 'il seç', + decadeSelect: 'Onillik seçin', + yearFormat: 'YYYY', + dateFormat: 'D.M.YYYY', + dayFormat: 'D', + dateTimeFormat: 'D.M.YYYY HH:mm:ss', + monthBeforeYear: true, + previousMonth: 'Əvvəlki ay (PageUp)', + nextMonth: 'Növbəti ay (PageDown)', + previousYear: 'Sonuncu il (Control + left)', + nextYear: 'Növbəti il (Control + right)', + previousDecade: 'Sonuncu onillik', + nextDecade: 'Növbəti onillik', + previousCentury: 'Sonuncu əsr', + nextCentury: 'Növbəti əsr', +}; + +export default locale; diff --git a/components/vc-calendar/src/locale/bg_BG.js b/components/vc-picker/locale/bg_BG.ts similarity index 89% rename from components/vc-calendar/src/locale/bg_BG.js rename to components/vc-picker/locale/bg_BG.ts index 0dd82941a..07334a91d 100644 --- a/components/vc-calendar/src/locale/bg_BG.js +++ b/components/vc-picker/locale/bg_BG.ts @@ -1,4 +1,7 @@ -export default { +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'bg_BG', today: 'Днес', now: 'Сега', backToToday: 'Към днес', @@ -25,3 +28,4 @@ export default { previousCentury: 'Последен век', nextCentury: 'Следващ век', }; +export default locale; diff --git a/components/vc-picker/locale/by_BY.ts b/components/vc-picker/locale/by_BY.ts new file mode 100644 index 000000000..fe5984afa --- /dev/null +++ b/components/vc-picker/locale/by_BY.ts @@ -0,0 +1,33 @@ +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'by_BY', + today: 'Сёння', + now: 'Зараз', + backToToday: 'Дадзеная дата', + ok: 'Ok', + clear: 'Ачысціць', + month: 'Месяц', + year: 'Год', + timeSelect: 'Выбраць час', + dateSelect: 'Выбраць дату', + weekSelect: 'Выбраць тыдзень', + monthSelect: 'Выбраць месяц', + yearSelect: 'Выбраць год', + decadeSelect: 'Выбраць дзесяцігоддзе', + yearFormat: 'YYYY', + dateFormat: 'D-M-YYYY', + dayFormat: 'D', + dateTimeFormat: 'D-M-YYYY HH:mm:ss', + monthBeforeYear: true, + previousMonth: 'Папярэдні месяц (PageUp)', + nextMonth: 'Наступны месяц (PageDown)', + previousYear: 'Папярэдні год (Control + left)', + nextYear: 'Наступны год (Control + right)', + previousDecade: 'Папярэдняе дзесяцігоддзе', + nextDecade: 'Наступнае дзесяцігоддзе', + previousCentury: 'Папярэдні век', + nextCentury: 'Наступны век', +}; + +export default locale; diff --git a/components/vc-calendar/src/locale/ca_ES.js b/components/vc-picker/locale/ca_ES.ts similarity index 87% rename from components/vc-calendar/src/locale/ca_ES.js rename to components/vc-picker/locale/ca_ES.ts index d67f1a6fc..f93f09397 100644 --- a/components/vc-calendar/src/locale/ca_ES.js +++ b/components/vc-picker/locale/ca_ES.ts @@ -1,4 +1,7 @@ -export default { +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'ca_ES', today: 'Avui', now: 'Ara', backToToday: 'Tornar a avui', @@ -25,3 +28,5 @@ export default { previousCentury: 'Segle anterior', nextCentury: 'Segle següent', }; + +export default locale; diff --git a/components/vc-calendar/src/locale/cs_CZ.js b/components/vc-picker/locale/cs_CZ.ts similarity index 87% rename from components/vc-calendar/src/locale/cs_CZ.js rename to components/vc-picker/locale/cs_CZ.ts index 33fa3d60f..3c1b2eb3c 100644 --- a/components/vc-calendar/src/locale/cs_CZ.js +++ b/components/vc-picker/locale/cs_CZ.ts @@ -1,4 +1,7 @@ -export default { +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'cs_CZ', today: 'Dnes', now: 'Nyní', backToToday: 'Zpět na dnešek', @@ -25,3 +28,5 @@ export default { previousCentury: 'Předchozí století', nextCentury: 'Následující století', }; + +export default locale; diff --git a/components/vc-calendar/src/locale/da_DK.js b/components/vc-picker/locale/da_DK.ts similarity index 63% rename from components/vc-calendar/src/locale/da_DK.js rename to components/vc-picker/locale/da_DK.ts index 9f1311881..f3fe17c6e 100644 --- a/components/vc-calendar/src/locale/da_DK.js +++ b/components/vc-picker/locale/da_DK.ts @@ -1,9 +1,12 @@ -export default { +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'da_DK', today: 'I dag', now: 'Nu', backToToday: 'Gå til i dag', ok: 'Ok', - clear: 'Annuller', + clear: 'Ryd', month: 'Måned', year: 'År', timeSelect: 'Vælg tidspunkt', @@ -16,12 +19,14 @@ export default { dayFormat: 'D', dateTimeFormat: 'D/M/YYYY HH:mm:ss', monthBeforeYear: true, - previousMonth: 'Forrige måned(PageUp)', - nextMonth: 'Næste måned (PageDown)', - previousYear: 'Forrige år (Control + left)', - nextYear: 'Næste r (Control + right)', + previousMonth: 'Forrige måned (Page Up)', + nextMonth: 'Næste måned (Page Down)', + previousYear: 'Forrige år (Ctrl-venstre pil)', + nextYear: 'Næste år (Ctrl-højre pil)', previousDecade: 'Forrige årti', nextDecade: 'Næste årti', previousCentury: 'Forrige århundrede', nextCentury: 'Næste århundrede', }; + +export default locale; diff --git a/components/vc-calendar/src/locale/de_DE.js b/components/vc-picker/locale/de_DE.ts similarity index 87% rename from components/vc-calendar/src/locale/de_DE.js rename to components/vc-picker/locale/de_DE.ts index 85161ea34..e053a6302 100644 --- a/components/vc-calendar/src/locale/de_DE.js +++ b/components/vc-picker/locale/de_DE.ts @@ -1,4 +1,7 @@ -export default { +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'de_DE', today: 'Heute', now: 'Jetzt', backToToday: 'Zurück zu Heute', @@ -25,3 +28,5 @@ export default { previousCentury: 'Vorheriges Jahrhundert', nextCentury: 'Nächstes Jahrhundert', }; + +export default locale; diff --git a/components/vc-calendar/src/locale/el_GR.js b/components/vc-picker/locale/el_GR.ts similarity index 90% rename from components/vc-calendar/src/locale/el_GR.js rename to components/vc-picker/locale/el_GR.ts index 980218d48..e8979a57a 100644 --- a/components/vc-calendar/src/locale/el_GR.js +++ b/components/vc-picker/locale/el_GR.ts @@ -1,4 +1,7 @@ -export default { +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'el_GR', today: 'Σήμερα', now: 'Τώρα', backToToday: 'Πίσω στη σημερινή μέρα', @@ -25,3 +28,5 @@ export default { previousCentury: 'Προηγούμενος αιώνας', nextCentury: 'Επόμενος αιώνας', }; + +export default locale; diff --git a/components/vc-calendar/src/locale/en_GB.js b/components/vc-picker/locale/en_GB.ts similarity index 86% rename from components/vc-calendar/src/locale/en_GB.js rename to components/vc-picker/locale/en_GB.ts index c8fb80a6e..a875ae257 100644 --- a/components/vc-calendar/src/locale/en_GB.js +++ b/components/vc-picker/locale/en_GB.ts @@ -1,4 +1,7 @@ -export default { +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'en_GB', today: 'Today', now: 'Now', backToToday: 'Back to today', @@ -25,3 +28,5 @@ export default { previousCentury: 'Last century', nextCentury: 'Next century', }; + +export default locale; diff --git a/components/vc-calendar/src/locale/en_US.js b/components/vc-picker/locale/en_US.ts similarity index 86% rename from components/vc-calendar/src/locale/en_US.js rename to components/vc-picker/locale/en_US.ts index df56595ac..28d5fad58 100644 --- a/components/vc-calendar/src/locale/en_US.js +++ b/components/vc-picker/locale/en_US.ts @@ -1,4 +1,7 @@ -export default { +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'en_US', today: 'Today', now: 'Now', backToToday: 'Back to today', @@ -26,3 +29,5 @@ export default { previousCentury: 'Last century', nextCentury: 'Next century', }; + +export default locale; diff --git a/components/vc-calendar/src/locale/es_ES.js b/components/vc-picker/locale/es_ES.ts similarity index 87% rename from components/vc-calendar/src/locale/es_ES.js rename to components/vc-picker/locale/es_ES.ts index cdedd4c15..373db7dbf 100644 --- a/components/vc-calendar/src/locale/es_ES.js +++ b/components/vc-picker/locale/es_ES.ts @@ -1,4 +1,7 @@ -export default { +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'es_ES', today: 'Hoy', now: 'Ahora', backToToday: 'Volver a hoy', @@ -25,3 +28,5 @@ export default { previousCentury: 'Siglo anterior', nextCentury: 'Siglo siguiente', }; + +export default locale; diff --git a/components/vc-calendar/src/locale/et_EE.js b/components/vc-picker/locale/et_EE.ts similarity index 86% rename from components/vc-calendar/src/locale/et_EE.js rename to components/vc-picker/locale/et_EE.ts index 3b8f2d75c..19a4af593 100644 --- a/components/vc-calendar/src/locale/et_EE.js +++ b/components/vc-picker/locale/et_EE.ts @@ -1,4 +1,7 @@ -export default { +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'et_EE', today: 'Täna', now: 'Praegu', backToToday: 'Tagasi tänase juurde', @@ -25,3 +28,5 @@ export default { previousCentury: 'Eelmine sajand', nextCentury: 'Järgmine sajand', }; + +export default locale; diff --git a/components/vc-calendar/src/locale/fa_IR.js b/components/vc-picker/locale/fa_IR.ts similarity index 88% rename from components/vc-calendar/src/locale/fa_IR.js rename to components/vc-picker/locale/fa_IR.ts index 43c6bc15a..f7e1af3b5 100644 --- a/components/vc-calendar/src/locale/fa_IR.js +++ b/components/vc-picker/locale/fa_IR.ts @@ -1,4 +1,7 @@ -export default { +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'fa_IR', today: 'امروز', now: 'اکنون', backToToday: 'بازگشت به روز', @@ -25,3 +28,5 @@ export default { previousCentury: 'قرن قبل', nextCentury: 'قرن بعد', }; + +export default locale; diff --git a/components/vc-calendar/src/locale/fi_FI.js b/components/vc-picker/locale/fi_FI.ts similarity index 87% rename from components/vc-calendar/src/locale/fi_FI.js rename to components/vc-picker/locale/fi_FI.ts index 5959d305f..9a02113bf 100644 --- a/components/vc-calendar/src/locale/fi_FI.js +++ b/components/vc-picker/locale/fi_FI.ts @@ -1,4 +1,7 @@ -export default { +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'fi_FI', today: 'Tänään', now: 'Nyt', backToToday: 'Tämä päivä', @@ -25,3 +28,5 @@ export default { previousCentury: 'Edellinen vuosisata', nextCentury: 'Seuraava vuosisata', }; + +export default locale; diff --git a/components/vc-calendar/src/locale/fr_BE.js b/components/vc-picker/locale/fr_BE.ts similarity index 87% rename from components/vc-calendar/src/locale/fr_BE.js rename to components/vc-picker/locale/fr_BE.ts index 8495e995d..b39864474 100644 --- a/components/vc-calendar/src/locale/fr_BE.js +++ b/components/vc-picker/locale/fr_BE.ts @@ -1,4 +1,7 @@ -export default { +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'fr_BE', today: "Aujourd'hui", now: 'Maintenant', backToToday: "Aujourd'hui", @@ -25,3 +28,5 @@ export default { previousCentury: 'Siècle précédent', nextCentury: 'Siècle suivant', }; + +export default locale; diff --git a/components/vc-calendar/src/locale/fr_FR.js b/components/vc-picker/locale/fr_CA.ts similarity index 87% rename from components/vc-calendar/src/locale/fr_FR.js rename to components/vc-picker/locale/fr_CA.ts index 1f03dcc03..8bbaf2ff6 100644 --- a/components/vc-calendar/src/locale/fr_FR.js +++ b/components/vc-picker/locale/fr_CA.ts @@ -1,4 +1,7 @@ -export default { +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'fr_CA', today: "Aujourd'hui", now: 'Maintenant', backToToday: "Aujourd'hui", @@ -25,3 +28,5 @@ export default { previousCentury: 'Siècle précédent', nextCentury: 'Siècle suivant', }; + +export default locale; diff --git a/components/vc-picker/locale/fr_FR.ts b/components/vc-picker/locale/fr_FR.ts new file mode 100644 index 000000000..53239b592 --- /dev/null +++ b/components/vc-picker/locale/fr_FR.ts @@ -0,0 +1,32 @@ +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'fr_FR', + today: "Aujourd'hui", + now: 'Maintenant', + backToToday: "Aujourd'hui", + ok: 'Ok', + clear: 'Rétablir', + month: 'Mois', + year: 'Année', + timeSelect: "Sélectionner l'heure", + dateSelect: 'Sélectionner la date', + monthSelect: 'Choisissez un mois', + yearSelect: 'Choisissez une année', + decadeSelect: 'Choisissez une décennie', + yearFormat: 'YYYY', + dateFormat: 'DD/MM/YYYY', + dayFormat: 'DD', + dateTimeFormat: 'DD/MM/YYYY HH:mm:ss', + monthBeforeYear: true, + previousMonth: 'Mois précédent (PageUp)', + nextMonth: 'Mois suivant (PageDown)', + previousYear: 'Année précédente (Ctrl + gauche)', + nextYear: 'Année prochaine (Ctrl + droite)', + previousDecade: 'Décennie précédente', + nextDecade: 'Décennie suivante', + previousCentury: 'Siècle précédent', + nextCentury: 'Siècle suivant', +}; + +export default locale; diff --git a/components/vc-calendar/src/locale/ga_IE.js b/components/vc-picker/locale/ga_IE.ts similarity index 88% rename from components/vc-calendar/src/locale/ga_IE.js rename to components/vc-picker/locale/ga_IE.ts index 66eac5905..326a209bd 100644 --- a/components/vc-calendar/src/locale/ga_IE.js +++ b/components/vc-picker/locale/ga_IE.ts @@ -1,4 +1,7 @@ -export default { +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'ga_IE', today: 'inniu', now: 'anois', backToToday: 'Ar ais inniu', @@ -26,3 +29,5 @@ export default { previousCentury: 'An chéid seo caite', nextCentury: 'An chéad aois eile', }; + +export default locale; diff --git a/components/vc-picker/locale/gl_ES.ts b/components/vc-picker/locale/gl_ES.ts new file mode 100644 index 000000000..13258764e --- /dev/null +++ b/components/vc-picker/locale/gl_ES.ts @@ -0,0 +1,32 @@ +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'gl_ES', + today: 'Hoxe', + now: 'Agora', + backToToday: 'Voltar a hoxe', + ok: 'Aceptar', + clear: 'Limpar', + month: 'Mes', + year: 'Ano', + timeSelect: 'Seleccionar hora', + dateSelect: 'Seleccionar data', + monthSelect: 'Elexir un mes', + yearSelect: 'Elexir un año', + decadeSelect: 'Elexir unha década', + yearFormat: 'YYYY', + dateFormat: 'D/M/YYYY', + dayFormat: 'D', + dateTimeFormat: 'D/M/YYYY HH:mm:ss', + monthBeforeYear: true, + previousMonth: 'Mes anterior (PageUp)', + nextMonth: 'Mes seguinte (PageDown)', + previousYear: 'Ano anterior (Control + left)', + nextYear: 'Ano seguinte (Control + right)', + previousDecade: 'Década anterior', + nextDecade: 'Década seguinte', + previousCentury: 'Século anterior', + nextCentury: 'Século seguinte', +}; + +export default locale; diff --git a/components/vc-calendar/src/locale/he_IL.js b/components/vc-picker/locale/he_IL.ts similarity index 88% rename from components/vc-calendar/src/locale/he_IL.js rename to components/vc-picker/locale/he_IL.ts index d463ce4fb..ea3fc8b73 100644 --- a/components/vc-calendar/src/locale/he_IL.js +++ b/components/vc-picker/locale/he_IL.ts @@ -1,4 +1,7 @@ -export default { +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'he_IL', today: 'היום', now: 'עכשיו', backToToday: 'חזור להיום', @@ -26,3 +29,5 @@ export default { previousCentury: 'המאה הקודמת', nextCentury: 'המאה הבאה', }; + +export default locale; diff --git a/components/vc-calendar/src/locale/hi_IN.js b/components/vc-picker/locale/hi_IN.ts similarity index 90% rename from components/vc-calendar/src/locale/hi_IN.js rename to components/vc-picker/locale/hi_IN.ts index a0b6b4e63..51ae22917 100644 --- a/components/vc-calendar/src/locale/hi_IN.js +++ b/components/vc-picker/locale/hi_IN.ts @@ -1,4 +1,7 @@ -export default { +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'hi_IN', today: 'आज', now: 'अभी', backToToday: 'आज तक', @@ -26,3 +29,5 @@ export default { previousCentury: 'पीछ्ली शताब्दी', nextCentury: 'अगली सदी', }; + +export default locale; diff --git a/components/vc-calendar/src/locale/hr_HR.js b/components/vc-picker/locale/hr_HR.ts similarity index 87% rename from components/vc-calendar/src/locale/hr_HR.js rename to components/vc-picker/locale/hr_HR.ts index 670c6cb02..a341396b5 100644 --- a/components/vc-calendar/src/locale/hr_HR.js +++ b/components/vc-picker/locale/hr_HR.ts @@ -1,4 +1,7 @@ -export default { +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'hr_HR', today: 'Danas', now: 'Sad', backToToday: 'Natrag na danas', @@ -26,3 +29,5 @@ export default { previousCentury: 'Prošlo stoljeće', nextCentury: 'Sljedeće stoljeće', }; + +export default locale; diff --git a/components/vc-calendar/src/locale/hu_HU.js b/components/vc-picker/locale/hu_HU.ts similarity index 91% rename from components/vc-calendar/src/locale/hu_HU.js rename to components/vc-picker/locale/hu_HU.ts index 3f046877b..b98603dc8 100644 --- a/components/vc-calendar/src/locale/hu_HU.js +++ b/components/vc-picker/locale/hu_HU.ts @@ -1,4 +1,7 @@ -export default { +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'hu_HU', today: 'Ma', // 'Today', now: 'Most', // 'Now', backToToday: 'Vissza a mai napra', // 'Back to today', @@ -25,3 +28,5 @@ export default { previousCentury: 'Múlt évszázad', // 'Last century', nextCentury: 'Jövő évszázad', // 'Next century', }; + +export default locale; diff --git a/components/vc-calendar/src/locale/id_ID.js b/components/vc-picker/locale/id_ID.ts similarity index 87% rename from components/vc-calendar/src/locale/id_ID.js rename to components/vc-picker/locale/id_ID.ts index 1c9df774f..01c9d760b 100644 --- a/components/vc-calendar/src/locale/id_ID.js +++ b/components/vc-picker/locale/id_ID.ts @@ -1,4 +1,7 @@ -export default { +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'id_ID', today: 'Hari ini', now: 'Sekarang', backToToday: 'Kembali ke hari ini', @@ -26,3 +29,5 @@ export default { previousCentury: 'Abad terakhir', nextCentury: 'Abad berikutnya', }; + +export default locale; diff --git a/components/vc-calendar/src/locale/is_IS.js b/components/vc-picker/locale/is_IS.ts similarity index 86% rename from components/vc-calendar/src/locale/is_IS.js rename to components/vc-picker/locale/is_IS.ts index 13de5e1ee..efea36701 100644 --- a/components/vc-calendar/src/locale/is_IS.js +++ b/components/vc-picker/locale/is_IS.ts @@ -1,4 +1,7 @@ -export default { +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'is_IS', today: 'Í dag', now: 'Núna', backToToday: 'Til baka til dagsins í dag', @@ -25,3 +28,5 @@ export default { previousCentury: 'Fyrri öld', nextCentury: 'Næsta öld', }; + +export default locale; diff --git a/components/vc-calendar/src/locale/it_IT.js b/components/vc-picker/locale/it_IT.ts similarity index 87% rename from components/vc-calendar/src/locale/it_IT.js rename to components/vc-picker/locale/it_IT.ts index e76ae7cb6..3b69a9f2f 100644 --- a/components/vc-calendar/src/locale/it_IT.js +++ b/components/vc-picker/locale/it_IT.ts @@ -1,4 +1,7 @@ -export default { +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'it_IT', today: 'Oggi', now: 'Adesso', backToToday: 'Torna ad oggi', @@ -25,3 +28,5 @@ export default { previousCentury: 'Secolo precedente', nextCentury: 'Prossimo secolo', }; + +export default locale; diff --git a/components/vc-calendar/src/locale/ja_JP.js b/components/vc-picker/locale/ja_JP.ts similarity index 84% rename from components/vc-calendar/src/locale/ja_JP.js rename to components/vc-picker/locale/ja_JP.ts index d49e748b3..f4d3985f9 100644 --- a/components/vc-calendar/src/locale/ja_JP.js +++ b/components/vc-picker/locale/ja_JP.ts @@ -1,10 +1,14 @@ -export default { +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'ja_JP', today: '今日', now: '現在時刻', backToToday: '今日に戻る', ok: '決定', timeSelect: '時間を選択', dateSelect: '日時を選択', + weekSelect: '週を選択', clear: 'クリア', month: '月', year: '年', @@ -24,3 +28,5 @@ export default { previousCentury: '前の世紀', nextCentury: '次の世紀', }; + +export default locale; diff --git a/components/vc-picker/locale/kk_KZ.ts b/components/vc-picker/locale/kk_KZ.ts new file mode 100644 index 000000000..f3b6787ff --- /dev/null +++ b/components/vc-picker/locale/kk_KZ.ts @@ -0,0 +1,32 @@ +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'kk_KZ', + today: 'Бүгін', + now: 'Қазір', + backToToday: 'Ағымдағы күн', + ok: 'Таңдау', + clear: 'Таза', + month: 'Ай', + year: 'Жыл', + timeSelect: 'Уақытты таңдау', + dateSelect: 'Күнді таңдау', + monthSelect: 'Айды таңдаңыз', + yearSelect: 'Жылды таңдаңыз', + decadeSelect: 'Онжылды таңдаңыз', + yearFormat: 'YYYY', + dateFormat: 'D-M-YYYY', + dayFormat: 'D', + dateTimeFormat: 'D-M-YYYY HH:mm:ss', + monthBeforeYear: true, + previousMonth: 'Алдыңғы ай (PageUp)', + nextMonth: 'Келесі ай (PageDown)', + previousYear: 'Алдыңғы жыл (Control + left)', + nextYear: 'Келесі жыл (Control + right)', + previousDecade: 'Алдыңғы онжылдық', + nextDecade: 'Келесі онжылдық', + previousCentury: 'Алдыңғы ғасыр', + nextCentury: 'Келесі ғасыр', +}; + +export default locale; diff --git a/components/vc-picker/locale/km_KH.ts b/components/vc-picker/locale/km_KH.ts new file mode 100644 index 000000000..2edb5da3d --- /dev/null +++ b/components/vc-picker/locale/km_KH.ts @@ -0,0 +1,32 @@ +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'km', + today: 'ថ្ងៃនេះ', + now: 'ឥឡូវ​នេះ', + backToToday: 'ត្រលប់ទៅថ្ងៃនេះ', + ok: 'កំណត់', + timeSelect: 'រយៈពេលជ្រើសរើស', + dateSelect: 'ជ្រើសរើសកាលបរិច្ឆេទ', + weekSelect: 'ជ្រើសរើសសប្តាហ៍', + clear: 'ច្បាស់', + month: 'ខែ', + year: 'ឆ្នាំ', + previousMonth: 'ខែមុន (ឡើងទំព័រ)', + nextMonth: 'ខែបន្ទាប់ (ប៊ូតុងចុះទំព័រ)', + monthSelect: 'ជ្រើសរើសខែ', + yearSelect: 'ជ្រើសរើសឆ្នាំ', + decadeSelect: 'ជ្រើសរើសអាយុ', + yearFormat: 'YYYY', + dayFormat: 'D', + dateFormat: 'YYYY-M-D', + dateTimeFormat: 'YYYY-M-D HH:mm:ss', + previousYear: 'ឆ្នាំមុន (Controlគ្រាប់ចុចបូកព្រួញខាងឆ្វេង)', + nextYear: 'ឆ្នាំក្រោយ (Control គ្រាប់ចុចបូកព្រួញស្ដាំ)', + previousDecade: 'ជំនាន់ចុងក្រោយ', + nextDecade: 'ជំនាន់​ក្រោយ', + previousCentury: 'សតវត្សចុងក្រោយ', + nextCentury: 'សតវត្សរ៍បន្ទាប់', +}; + +export default locale; diff --git a/components/vc-calendar/src/locale/ku_IQ.js b/components/vc-picker/locale/kmr_IQ.ts similarity index 86% rename from components/vc-calendar/src/locale/ku_IQ.js rename to components/vc-picker/locale/kmr_IQ.ts index 01197b038..867ec68b0 100644 --- a/components/vc-calendar/src/locale/ku_IQ.js +++ b/components/vc-picker/locale/kmr_IQ.ts @@ -1,4 +1,7 @@ -export default { +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'ku', today: 'Îro', now: 'Niha', backToToday: 'Vegere îro', @@ -25,3 +28,5 @@ export default { previousCentury: 'Sedsalen peş', nextCentury: 'Sedsalen paş', }; + +export default locale; diff --git a/components/vc-calendar/src/locale/kn_IN.js b/components/vc-picker/locale/kn_IN.ts similarity index 91% rename from components/vc-calendar/src/locale/kn_IN.js rename to components/vc-picker/locale/kn_IN.ts index 5acf5d698..1731ebdaf 100644 --- a/components/vc-calendar/src/locale/kn_IN.js +++ b/components/vc-picker/locale/kn_IN.ts @@ -1,4 +1,7 @@ -export default { +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'kn_IN', today: 'ಇಂದು', now: 'ಈಗ', backToToday: 'ಇಂದು ಹಿಂದಿರುಗಿ', @@ -26,3 +29,5 @@ export default { previousCentury: 'ಕಳೆದ ಶತಮಾನ', nextCentury: 'ಮುಂದಿನ ಶತಮಾನ', }; + +export default locale; diff --git a/components/vc-calendar/src/locale/ko_KR.js b/components/vc-picker/locale/ko_KR.ts similarity index 86% rename from components/vc-calendar/src/locale/ko_KR.js rename to components/vc-picker/locale/ko_KR.ts index 5efbddfc1..6f8416c7e 100644 --- a/components/vc-calendar/src/locale/ko_KR.js +++ b/components/vc-picker/locale/ko_KR.ts @@ -1,4 +1,7 @@ -export default { +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'ko_KR', today: '오늘', now: '현재 시각', backToToday: '오늘로 돌아가기', @@ -25,3 +28,5 @@ export default { previousCentury: '이전 세기', nextCentury: '다음 세기', }; + +export default locale; diff --git a/components/vc-picker/locale/lt_LT.ts b/components/vc-picker/locale/lt_LT.ts new file mode 100644 index 000000000..2ddb658c7 --- /dev/null +++ b/components/vc-picker/locale/lt_LT.ts @@ -0,0 +1,32 @@ +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'lt_LT', + today: 'Šiandien', + now: 'Dabar', + backToToday: 'Rodyti šiandien', + ok: 'Gerai', + clear: 'Išvalyti', + month: 'Mėnesis', + year: 'Metai', + timeSelect: 'Pasirinkti laiką', + dateSelect: 'Pasirinkti datą', + monthSelect: 'Pasirinkti mėnesį', + yearSelect: 'Pasirinkti metus', + decadeSelect: 'Pasirinkti dešimtmetį', + yearFormat: 'YYYY', + dateFormat: 'YYYY-MM-DD', + dayFormat: 'DD', + dateTimeFormat: 'YYYY-MM-DD HH:MM:SS', + monthBeforeYear: true, + previousMonth: 'Buvęs mėnesis (PageUp)', + nextMonth: 'Sekantis mėnesis (PageDown)', + previousYear: 'Buvę metai (Control + left)', + nextYear: 'Sekantis metai (Control + right)', + previousDecade: 'Buvęs dešimtmetis', + nextDecade: 'Sekantis dešimtmetis', + previousCentury: 'Buvęs amžius', + nextCentury: 'Sekantis amžius', +}; + +export default locale; diff --git a/components/vc-calendar/src/locale/lv_LV.js b/components/vc-picker/locale/lv_LV.ts similarity index 87% rename from components/vc-calendar/src/locale/lv_LV.js rename to components/vc-picker/locale/lv_LV.ts index f06ffcd4f..0529ff639 100644 --- a/components/vc-calendar/src/locale/lv_LV.js +++ b/components/vc-picker/locale/lv_LV.ts @@ -1,4 +1,7 @@ -export default { +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'lv_LV', today: 'Šodien', now: 'Tagad', backToToday: 'Atpakaļ pie šodienas', @@ -25,3 +28,5 @@ export default { previousCentury: 'Pagājušajā gadsimtā', nextCentury: 'Nākamajā gadsimtā', }; + +export default locale; diff --git a/components/vc-calendar/src/locale/mk_MK.js b/components/vc-picker/locale/mk_MK.ts similarity index 89% rename from components/vc-calendar/src/locale/mk_MK.js rename to components/vc-picker/locale/mk_MK.ts index 91d9188a8..d1dd459ab 100644 --- a/components/vc-calendar/src/locale/mk_MK.js +++ b/components/vc-picker/locale/mk_MK.ts @@ -1,4 +1,7 @@ -export default { +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'mk_MK', today: 'Денес', now: 'Сега', backToToday: 'Назад до денес', @@ -25,3 +28,5 @@ export default { previousCentury: 'Претходен век', nextCentury: 'Нареден век', }; + +export default locale; diff --git a/components/vc-picker/locale/ml_IN.ts b/components/vc-picker/locale/ml_IN.ts new file mode 100644 index 000000000..5c7b513e0 --- /dev/null +++ b/components/vc-picker/locale/ml_IN.ts @@ -0,0 +1,33 @@ +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'ml_IN', + today: 'ഇന്ന്', + now: 'ഇപ്പോൾ', + backToToday: 'ഇന്നത്തെ ദിവസത്തിലേക്ക് തിരിച്ചു പോകുക', + ok: 'ശരിയാണ്', + clear: 'നീക്കം ചെയ്യുക', + month: 'മാസം', + year: 'വർഷം', + timeSelect: 'സമയം തിരഞ്ഞെടുക്കുക', + dateSelect: 'ദിവസം തിരഞ്ഞെടുക്കുക', + weekSelect: 'വാരം തിരഞ്ഞെടുക്കുക', + monthSelect: 'മാസം തിരഞ്ഞെടുക്കുക', + yearSelect: 'വർഷം തിരഞ്ഞെടുക്കുക', + decadeSelect: 'ദശാബ്ദം തിരഞ്ഞെടുക്കുക', + yearFormat: 'YYYY', + dateFormat: 'M/D/YYYY', + dayFormat: 'D', + dateTimeFormat: 'M/D/YYYY HH:mm:ss', + monthBeforeYear: true, + previousMonth: 'കഴിഞ്ഞ മാസം (PageUp)', + nextMonth: 'അടുത്ത മാസം (PageDown)', + previousYear: 'കഴിഞ്ഞ വർഷം (Control + left)', + nextYear: 'അടുത്ത വർഷം (Control + right)', + previousDecade: 'കഴിഞ്ഞ ദശാബ്ദം', + nextDecade: 'അടുത്ത ദശാബ്ദം', + previousCentury: 'കഴിഞ്ഞ നൂറ്റാണ്ട്', + nextCentury: 'അടുത്ത നൂറ്റാണ്ട്', +}; + +export default locale; diff --git a/components/vc-calendar/src/locale/mm_MM.js b/components/vc-picker/locale/mm_MM.ts similarity index 90% rename from components/vc-calendar/src/locale/mm_MM.js rename to components/vc-picker/locale/mm_MM.ts index 15fd9912d..b6a824156 100644 --- a/components/vc-calendar/src/locale/mm_MM.js +++ b/components/vc-picker/locale/mm_MM.ts @@ -1,4 +1,7 @@ -export default { +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'mm_MM', today: 'ယနေ့', now: 'ယခု', backToToday: 'ယနေ့ မတိုင်ခင် သို့', @@ -26,3 +29,5 @@ export default { previousCentury: 'ယခင် ရာစုနှစ်', nextCentury: 'နောက် ရာစုနှစ်', }; + +export default locale; diff --git a/components/vc-calendar/src/locale/mn_MN.js b/components/vc-picker/locale/mn_MN.ts similarity index 88% rename from components/vc-calendar/src/locale/mn_MN.js rename to components/vc-picker/locale/mn_MN.ts index 61fe5cf86..3b9e2ef7d 100644 --- a/components/vc-calendar/src/locale/mn_MN.js +++ b/components/vc-picker/locale/mn_MN.ts @@ -1,4 +1,7 @@ -export default { +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'mn_MN', today: 'Өнөөдөр', now: 'Одоо', backToToday: 'Өнөөдөрлүү буцах', @@ -26,3 +29,5 @@ export default { previousCentury: 'Өмнөх зуун', nextCentury: 'Дараа зуун', }; + +export default locale; diff --git a/components/vc-calendar/src/locale/ms_MY.js b/components/vc-picker/locale/ms_MY.ts similarity index 86% rename from components/vc-calendar/src/locale/ms_MY.js rename to components/vc-picker/locale/ms_MY.ts index a721e3e4c..1e3784c9e 100644 --- a/components/vc-calendar/src/locale/ms_MY.js +++ b/components/vc-picker/locale/ms_MY.ts @@ -1,4 +1,7 @@ -export default { +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'ms_MY', today: 'Hari ini', now: 'Sekarang', backToToday: 'Kembali ke hari ini', @@ -25,3 +28,5 @@ export default { previousCentury: 'Abad lepas', nextCentury: 'Abad depan', }; + +export default locale; diff --git a/components/vc-calendar/src/locale/nb_NO.js b/components/vc-picker/locale/nb_NO.ts similarity index 64% rename from components/vc-calendar/src/locale/nb_NO.js rename to components/vc-picker/locale/nb_NO.ts index 04e5babba..a2ce4ea64 100644 --- a/components/vc-calendar/src/locale/nb_NO.js +++ b/components/vc-picker/locale/nb_NO.ts @@ -1,4 +1,7 @@ -export default { +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'nb_NO', today: 'I dag', now: 'Nå', backToToday: 'Gå til i dag', @@ -8,20 +11,23 @@ export default { year: 'År', timeSelect: 'Velg tidspunkt', dateSelect: 'Velg dato', + weekSelect: 'Velg uke', monthSelect: 'Velg måned', yearSelect: 'Velg år', - decadeSelect: 'Velg årti', + decadeSelect: 'Velg tiår', yearFormat: 'YYYY', dateFormat: 'DD.MM.YYYY', dayFormat: 'DD', dateTimeFormat: 'DD.MM.YYYY HH:mm:ss', monthBeforeYear: true, - previousMonth: 'Forrige måned(PageUp)', + previousMonth: 'Forrige måned (PageUp)', nextMonth: 'Neste måned (PageDown)', - previousYear: 'Forrige år (Control + left)', - nextYear: 'Neste år (Control + right)', + previousYear: 'Forrige år (Control + venstre)', + nextYear: 'Neste år (Control + høyre)', previousDecade: 'Forrige tiår', nextDecade: 'Neste tiår', previousCentury: 'Forrige århundre', nextCentury: 'Neste århundre', }; + +export default locale; diff --git a/components/vc-calendar/src/locale/nl_BE.js b/components/vc-picker/locale/nl_BE.ts similarity index 86% rename from components/vc-calendar/src/locale/nl_BE.js rename to components/vc-picker/locale/nl_BE.ts index 6dd28fc98..e78fef000 100644 --- a/components/vc-calendar/src/locale/nl_BE.js +++ b/components/vc-picker/locale/nl_BE.ts @@ -1,4 +1,7 @@ -export default { +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'nl_BE', today: 'Vandaag', now: 'Nu', backToToday: 'Terug naar vandaag', @@ -25,3 +28,5 @@ export default { previousCentury: 'Vorige eeuw', nextCentury: 'Volgende eeuw', }; + +export default locale; diff --git a/components/vc-calendar/src/locale/nl_NL.js b/components/vc-picker/locale/nl_NL.ts similarity index 86% rename from components/vc-calendar/src/locale/nl_NL.js rename to components/vc-picker/locale/nl_NL.ts index 6dd28fc98..cb33549e5 100644 --- a/components/vc-calendar/src/locale/nl_NL.js +++ b/components/vc-picker/locale/nl_NL.ts @@ -1,4 +1,7 @@ -export default { +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'nl_NL', today: 'Vandaag', now: 'Nu', backToToday: 'Terug naar vandaag', @@ -25,3 +28,5 @@ export default { previousCentury: 'Vorige eeuw', nextCentury: 'Volgende eeuw', }; + +export default locale; diff --git a/components/vc-calendar/src/locale/pl_PL.js b/components/vc-picker/locale/pl_PL.ts similarity index 86% rename from components/vc-calendar/src/locale/pl_PL.js rename to components/vc-picker/locale/pl_PL.ts index 3202a7f3b..d37f20f8f 100644 --- a/components/vc-calendar/src/locale/pl_PL.js +++ b/components/vc-picker/locale/pl_PL.ts @@ -1,4 +1,7 @@ -export default { +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'pl_PL', today: 'Dzisiaj', now: 'Teraz', backToToday: 'Ustaw dzisiaj', @@ -25,3 +28,5 @@ export default { previousCentury: 'Ostatni wiek', nextCentury: 'Następny wiek', }; + +export default locale; diff --git a/components/vc-calendar/src/locale/pt_BR.js b/components/vc-picker/locale/pt_BR.ts similarity index 69% rename from components/vc-calendar/src/locale/pt_BR.js rename to components/vc-picker/locale/pt_BR.ts index a94c36bf9..a6ca2af3b 100644 --- a/components/vc-calendar/src/locale/pt_BR.js +++ b/components/vc-picker/locale/pt_BR.ts @@ -1,4 +1,7 @@ -export default { +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'pt_BR', today: 'Hoje', now: 'Agora', backToToday: 'Voltar para hoje', @@ -6,7 +9,7 @@ export default { clear: 'Limpar', month: 'Mês', year: 'Ano', - timeSelect: 'Selecionar tempo', + timeSelect: 'Selecionar hora', dateSelect: 'Selecionar data', monthSelect: 'Escolher mês', yearSelect: 'Escolher ano', @@ -24,4 +27,8 @@ export default { nextDecade: 'Próxima década', previousCentury: 'Século anterior', nextCentury: 'Próximo século', + shortWeekDays: ['Dom', 'Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sáb'], + shortMonths: ['Jan', 'Fev', 'Mar', 'Abr', 'Mai', 'Jun', 'Jul', 'Ago', 'Set', 'Out', 'Nov', 'Dez'], }; + +export default locale; diff --git a/components/vc-calendar/src/locale/pt_PT.js b/components/vc-picker/locale/pt_PT.ts similarity index 86% rename from components/vc-calendar/src/locale/pt_PT.js rename to components/vc-picker/locale/pt_PT.ts index 121faba26..86a9a64cc 100644 --- a/components/vc-calendar/src/locale/pt_PT.js +++ b/components/vc-picker/locale/pt_PT.ts @@ -1,4 +1,7 @@ -export default { +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'pt_PT', today: 'Hoje', now: 'Agora', backToToday: 'Hoje', @@ -25,3 +28,5 @@ export default { previousCentury: 'Século anterior', nextCentury: 'Século seguinte', }; + +export default locale; diff --git a/components/vc-calendar/src/locale/ro_RO.js b/components/vc-picker/locale/ro_RO.ts similarity index 87% rename from components/vc-calendar/src/locale/ro_RO.js rename to components/vc-picker/locale/ro_RO.ts index d69416804..7994b7bee 100644 --- a/components/vc-calendar/src/locale/ro_RO.js +++ b/components/vc-picker/locale/ro_RO.ts @@ -1,4 +1,7 @@ -export default { +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'ro_RO', today: 'Azi', now: 'Acum', backToToday: 'Înapoi la azi', @@ -26,3 +29,5 @@ export default { previousCentury: 'Secolul anterior', nextCentury: 'Secolul următor', }; + +export default locale; diff --git a/components/vc-calendar/src/locale/ru_RU.js b/components/vc-picker/locale/ru_RU.ts similarity index 88% rename from components/vc-calendar/src/locale/ru_RU.js rename to components/vc-picker/locale/ru_RU.ts index 5a1a8ab56..a93224c92 100644 --- a/components/vc-calendar/src/locale/ru_RU.js +++ b/components/vc-picker/locale/ru_RU.ts @@ -1,8 +1,11 @@ -export default { +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'ru_RU', today: 'Сегодня', now: 'Сейчас', backToToday: 'Текущая дата', - ok: 'Ok', + ok: 'ОК', clear: 'Очистить', month: 'Месяц', year: 'Год', @@ -25,3 +28,5 @@ export default { previousCentury: 'Предыдущий век', nextCentury: 'Следующий век', }; + +export default locale; diff --git a/components/vc-calendar/src/locale/sk_SK.js b/components/vc-picker/locale/sk_SK.ts similarity index 87% rename from components/vc-calendar/src/locale/sk_SK.js rename to components/vc-picker/locale/sk_SK.ts index a543172ce..997f55e4f 100644 --- a/components/vc-calendar/src/locale/sk_SK.js +++ b/components/vc-picker/locale/sk_SK.ts @@ -1,4 +1,7 @@ -export default { +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'sk_SK', today: 'Dnes', now: 'Teraz', backToToday: 'Späť na dnes', @@ -8,7 +11,6 @@ export default { year: 'Rok', timeSelect: 'Vybrať čas', dateSelect: 'Vybrať dátum', - weekSelect: 'Vybrať týždeň', monthSelect: 'Vybrať mesiac', yearSelect: 'Vybrať rok', decadeSelect: 'Vybrať dekádu', @@ -26,3 +28,5 @@ export default { previousCentury: 'Predchádzajúce storočie', nextCentury: 'Nasledujúce storočie', }; + +export default locale; diff --git a/components/vc-calendar/src/locale/sl_SI.js b/components/vc-picker/locale/sl_SI.ts similarity index 87% rename from components/vc-calendar/src/locale/sl_SI.js rename to components/vc-picker/locale/sl_SI.ts index 17123b72f..4af01844f 100644 --- a/components/vc-calendar/src/locale/sl_SI.js +++ b/components/vc-picker/locale/sl_SI.ts @@ -1,4 +1,7 @@ -export default { +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'sl_SI', today: 'Danes', now: 'Trenutno', backToToday: 'Nazaj na danes', @@ -25,3 +28,5 @@ export default { previousCentury: 'Prejšnje stoletje', nextCentury: 'Naslednje stoletje', }; + +export default locale; diff --git a/components/vc-calendar/src/locale/sr_RS.js b/components/vc-picker/locale/sr_RS.ts similarity index 87% rename from components/vc-calendar/src/locale/sr_RS.js rename to components/vc-picker/locale/sr_RS.ts index a797bf58a..d77eb97a4 100644 --- a/components/vc-calendar/src/locale/sr_RS.js +++ b/components/vc-picker/locale/sr_RS.ts @@ -1,4 +1,7 @@ -export default { +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'sr_RS', today: 'Danas', now: 'Sada', backToToday: 'Vrati se na danas', @@ -25,3 +28,5 @@ export default { previousCentury: 'Prethodni vek', nextCentury: 'Sledeći vek', }; + +export default locale; diff --git a/components/vc-calendar/src/locale/sv_SE.js b/components/vc-picker/locale/sv_SE.ts similarity index 86% rename from components/vc-calendar/src/locale/sv_SE.js rename to components/vc-picker/locale/sv_SE.ts index faf6394b5..c42c29cc0 100644 --- a/components/vc-calendar/src/locale/sv_SE.js +++ b/components/vc-picker/locale/sv_SE.ts @@ -1,4 +1,7 @@ -export default { +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'sv_SE', today: 'I dag', now: 'Nu', backToToday: 'Till idag', @@ -25,3 +28,5 @@ export default { previousCentury: 'Föreg århundrade', nextCentury: 'Nästa århundrade', }; + +export default locale; diff --git a/components/vc-calendar/src/locale/ta_IN.js b/components/vc-picker/locale/ta_IN.ts similarity index 92% rename from components/vc-calendar/src/locale/ta_IN.js rename to components/vc-picker/locale/ta_IN.ts index 20ac8316b..7f0e30568 100644 --- a/components/vc-calendar/src/locale/ta_IN.js +++ b/components/vc-picker/locale/ta_IN.ts @@ -1,4 +1,7 @@ -export default { +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'ta_IN', today: 'இன்று', now: 'இப்போது', backToToday: 'இன்றுக்கு திரும்பு', @@ -26,3 +29,5 @@ export default { previousCentury: 'முந்தைய நூற்றாண்டு', nextCentury: 'அடுத்த நூற்றாண்டு', }; + +export default locale; diff --git a/components/vc-calendar/src/locale/th_TH.js b/components/vc-picker/locale/th_TH.ts similarity index 90% rename from components/vc-calendar/src/locale/th_TH.js rename to components/vc-picker/locale/th_TH.ts index 7021d4592..bcc1c42ab 100644 --- a/components/vc-calendar/src/locale/th_TH.js +++ b/components/vc-picker/locale/th_TH.ts @@ -1,4 +1,7 @@ -export default { +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'th_TH', today: 'วันนี้', now: 'ตอนนี้', backToToday: 'กลับไปยังวันนี้', @@ -25,3 +28,5 @@ export default { previousCentury: 'ศตวรรษก่อนหน้า', nextCentury: 'ศตวรรษถัดไป', }; + +export default locale; diff --git a/components/vc-calendar/src/locale/tr_TR.js b/components/vc-picker/locale/tr_TR.ts similarity index 86% rename from components/vc-calendar/src/locale/tr_TR.js rename to components/vc-picker/locale/tr_TR.ts index 317161667..f2f10540b 100644 --- a/components/vc-calendar/src/locale/tr_TR.js +++ b/components/vc-picker/locale/tr_TR.ts @@ -1,4 +1,7 @@ -export default { +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'tr_TR', today: 'Bugün', now: 'Şimdi', backToToday: 'Bugüne Geri Dön', @@ -25,3 +28,5 @@ export default { previousCentury: 'Önceki Yüzyıl', nextCentury: 'Sonraki Yüzyıl', }; + +export default locale; diff --git a/components/vc-calendar/src/locale/ug_CN.js b/components/vc-picker/locale/ug_CN.ts similarity index 90% rename from components/vc-calendar/src/locale/ug_CN.js rename to components/vc-picker/locale/ug_CN.ts index 7d0321e57..4e0241671 100644 --- a/components/vc-calendar/src/locale/ug_CN.js +++ b/components/vc-picker/locale/ug_CN.ts @@ -1,4 +1,7 @@ -export default { +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'ug_CN', today: 'بۈگۈن', now: 'ھازىر', backToToday: 'بۈگۈنگە قايتىش', @@ -24,3 +27,5 @@ export default { previousCentury: 'ئالدىنقى ئەسىر', nextCentury: 'كېيىنكى ئەسىر', }; + +export default locale; diff --git a/components/vc-calendar/src/locale/uk_UA.js b/components/vc-picker/locale/uk_UA.ts similarity index 89% rename from components/vc-calendar/src/locale/uk_UA.js rename to components/vc-picker/locale/uk_UA.ts index 2d9c17b15..eb56087fe 100644 --- a/components/vc-calendar/src/locale/uk_UA.js +++ b/components/vc-picker/locale/uk_UA.ts @@ -1,4 +1,7 @@ -export default { +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'uk_UA', today: 'Сьогодні', now: 'Зараз', backToToday: 'Поточна дата', @@ -25,3 +28,5 @@ export default { previousCentury: 'Попереднє століття', nextCentury: 'Наступне століття', }; + +export default locale; diff --git a/components/vc-calendar/src/locale/vi_VN.js b/components/vc-picker/locale/vi_VN.ts similarity index 87% rename from components/vc-calendar/src/locale/vi_VN.js rename to components/vc-picker/locale/vi_VN.ts index 69cadd452..75302e70e 100644 --- a/components/vc-calendar/src/locale/vi_VN.js +++ b/components/vc-picker/locale/vi_VN.ts @@ -1,4 +1,7 @@ -export default { +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'vi_VN', today: 'Hôm nay', now: 'Bây giờ', backToToday: 'Trở về hôm nay', @@ -26,3 +29,5 @@ export default { previousCentury: 'Thế kỷ trước', nextCentury: 'Thế kỷ sau', }; + +export default locale; diff --git a/components/vc-calendar/src/locale/zh_CN.js b/components/vc-picker/locale/zh_CN.ts similarity index 87% rename from components/vc-calendar/src/locale/zh_CN.js rename to components/vc-picker/locale/zh_CN.ts index 66fb90051..0b0495bae 100644 --- a/components/vc-calendar/src/locale/zh_CN.js +++ b/components/vc-picker/locale/zh_CN.ts @@ -1,4 +1,7 @@ -export default { +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'zh_CN', today: '今天', now: '此刻', backToToday: '返回今天', @@ -25,3 +28,5 @@ export default { previousCentury: '上一世纪', nextCentury: '下一世纪', }; + +export default locale; diff --git a/components/vc-calendar/src/locale/zh_TW.js b/components/vc-picker/locale/zh_TW.ts similarity index 84% rename from components/vc-calendar/src/locale/zh_TW.js rename to components/vc-picker/locale/zh_TW.ts index 208bdda0e..47bd3b03a 100644 --- a/components/vc-calendar/src/locale/zh_TW.js +++ b/components/vc-picker/locale/zh_TW.ts @@ -1,10 +1,15 @@ -export default { +import type { Locale } from '../interface'; + +const locale: Locale = { + locale: 'zh_TW', + today: '今天', now: '此刻', backToToday: '返回今天', ok: '確定', timeSelect: '選擇時間', dateSelect: '選擇日期', + weekSelect: '選擇周', clear: '清除', month: '月', year: '年', @@ -24,3 +29,5 @@ export default { previousCentury: '上一世紀', nextCentury: '下一世紀', }; + +export default locale; diff --git a/components/vc-picker/panels/DatePanel/DateBody.tsx b/components/vc-picker/panels/DatePanel/DateBody.tsx new file mode 100644 index 000000000..cd15b2dc8 --- /dev/null +++ b/components/vc-picker/panels/DatePanel/DateBody.tsx @@ -0,0 +1,119 @@ +import type { GenerateConfig } from '../../generate'; +import { + WEEK_DAY_COUNT, + getWeekStartDate, + isSameDate, + isSameMonth, + formatValue, +} from '../../utils/dateUtil'; +import type { Locale } from '../../interface'; +import useCellClassName from '../../hooks/useCellClassName'; +import PanelBody from '../PanelBody'; +import type { VueNode } from '../../../_util/type'; +import { useInjectRange } from '../../RangeContext'; +import useMergeProps from '../../hooks/useMergeProps'; + +export type DateRender = (props: { current: DateType; today: DateType }) => VueNode; + +export type DateBodyPassProps = { + dateRender?: DateRender; + disabledDate?: (date: DateType) => boolean; + + // Used for week panel + prefixColumn?: (date: DateType) => VueNode; + rowClassName?: (date: DateType) => string; +}; + +export type DateBodyProps = { + prefixCls: string; + generateConfig: GenerateConfig; + value?: DateType | null; + viewDate: DateType; + locale: Locale; + rowCount: number; + onSelect: (value: DateType) => void; +} & DateBodyPassProps; + +function DateBody(_props: DateBodyProps) { + const props = useMergeProps(_props); + const { prefixCls, generateConfig, prefixColumn, locale, rowCount, viewDate, value, dateRender } = + props; + + const { rangedValue, hoverRangedValue } = useInjectRange(); + + const baseDate = getWeekStartDate(locale.locale, generateConfig, viewDate); + const cellPrefixCls = `${prefixCls}-cell`; + const weekFirstDay = generateConfig.locale.getWeekFirstDay(locale.locale); + const today = generateConfig.getNow(); + + // ============================== Header ============================== + const headerCells: VueNode[] = []; + const weekDaysLocale: string[] = + locale.shortWeekDays || + (generateConfig.locale.getShortWeekDays + ? generateConfig.locale.getShortWeekDays(locale.locale) + : []); + + if (prefixColumn) { + headerCells.push(); + } + for (let i = 0; i < WEEK_DAY_COUNT; i += 1) { + headerCells.push({weekDaysLocale[(i + weekFirstDay) % WEEK_DAY_COUNT]}); + } + + // =============================== Body =============================== + const getCellClassName = useCellClassName({ + cellPrefixCls, + today, + value, + generateConfig, + rangedValue: prefixColumn ? null : rangedValue.value, + hoverRangedValue: prefixColumn ? null : hoverRangedValue.value, + isSameCell: (current, target) => isSameDate(generateConfig, current, target), + isInView: date => isSameMonth(generateConfig, date, viewDate), + offsetCell: (date, offset) => generateConfig.addDate(date, offset), + }); + + const getCellNode = dateRender + ? (date: DateType) => dateRender({ current: date, today }) + : undefined; + + return ( + + formatValue(date, { + locale, + format: 'YYYY-MM-DD', + generateConfig, + }) + } + headerCells={headerCells} + /> + ); +} + +DateBody.displayName = 'DateBody'; +DateBody.inheritAttrs = false; +DateBody.props = [ + 'prefixCls', + 'generateConfig', + 'value?', + 'viewDate', + 'locale', + 'rowCount', + 'onSelect', + 'dateRender?', + 'disabledDate?', + // Used for week panel + 'prefixColumn?', + 'rowClassName?', +]; +export default DateBody; diff --git a/components/vc-picker/panels/DatePanel/DateHeader.tsx b/components/vc-picker/panels/DatePanel/DateHeader.tsx new file mode 100644 index 000000000..941f31d45 --- /dev/null +++ b/components/vc-picker/panels/DatePanel/DateHeader.tsx @@ -0,0 +1,106 @@ +import Header from '../Header'; +import type { Locale } from '../../interface'; +import type { GenerateConfig } from '../../generate'; +import { useInjectPanel } from '../../PanelContext'; +import { formatValue } from '../../utils/dateUtil'; +import type { VueNode } from '../../../_util/type'; +import useMergeProps from '../../hooks/useMergeProps'; + +export type DateHeaderProps = { + prefixCls: string; + viewDate: DateType; + value?: DateType | null; + locale: Locale; + generateConfig: GenerateConfig; + + onPrevYear: () => void; + onNextYear: () => void; + onPrevMonth: () => void; + onNextMonth: () => void; + onYearClick: () => void; + onMonthClick: () => void; +}; + +function DateHeader(_props: DateHeaderProps) { + const props = useMergeProps(_props); + const { + prefixCls, + generateConfig, + locale, + viewDate, + onNextMonth, + onPrevMonth, + onNextYear, + onPrevYear, + onYearClick, + onMonthClick, + } = props; + + const { hideHeader } = useInjectPanel(); + if (hideHeader.value) { + return null; + } + + const headerPrefixCls = `${prefixCls}-header`; + + const monthsLocale: string[] = + locale.shortMonths || + (generateConfig.locale.getShortMonths + ? generateConfig.locale.getShortMonths(locale.locale) + : []); + + const month = generateConfig.getMonth(viewDate); + + // =================== Month & Year =================== + const yearNode: VueNode = ( + + ); + const monthNode: VueNode = ( + + ); + + const monthYearNodes = locale.monthBeforeYear ? [monthNode, yearNode] : [yearNode, monthNode]; + + return ( +
+ {monthYearNodes} +
+ ); +} + +DateHeader.displayName = 'DateHeader'; +DateHeader.inheritAttrs = false; +export default DateHeader; diff --git a/components/vc-picker/panels/DatePanel/index.tsx b/components/vc-picker/panels/DatePanel/index.tsx new file mode 100644 index 000000000..052b00e8d --- /dev/null +++ b/components/vc-picker/panels/DatePanel/index.tsx @@ -0,0 +1,117 @@ +import type { DateBodyPassProps, DateRender } from './DateBody'; +import DateBody from './DateBody'; +import DateHeader from './DateHeader'; +import type { PanelSharedProps } from '../../interface'; +import { WEEK_DAY_COUNT } from '../../utils/dateUtil'; +import type { KeyboardConfig } from '../../utils/uiUtil'; +import { createKeydownHandler } from '../../utils/uiUtil'; +import classNames from '../../../_util/classNames'; +import useMergeProps from '../../hooks/useMergeProps'; + +const DATE_ROW_COUNT = 6; + +export type DatePanelProps = { + active?: boolean; + dateRender?: DateRender; + + // Used for week panel + panelName?: string; + keyboardConfig?: KeyboardConfig; +} & PanelSharedProps & + DateBodyPassProps; + +function DatePanel(_props: DatePanelProps) { + const props = useMergeProps(_props); + const { + prefixCls, + panelName = 'date', + keyboardConfig, + active, + operationRef, + generateConfig, + value, + viewDate, + onViewDateChange, + onPanelChange, + onSelect, + } = props; + const panelPrefixCls = `${prefixCls}-${panelName}-panel`; + // ======================= Keyboard ======================= + operationRef.value = { + onKeydown: (event: KeyboardEvent) => + createKeydownHandler(event, { + onLeftRight: diff => { + onSelect(generateConfig.addDate(value || viewDate, diff), 'key'); + }, + onCtrlLeftRight: diff => { + onSelect(generateConfig.addYear(value || viewDate, diff), 'key'); + }, + onUpDown: diff => { + onSelect(generateConfig.addDate(value || viewDate, diff * WEEK_DAY_COUNT), 'key'); + }, + onPageUpDown: diff => { + onSelect(generateConfig.addMonth(value || viewDate, diff), 'key'); + }, + ...keyboardConfig, + }), + }; + + // ==================== View Operation ==================== + const onYearChange = (diff: number) => { + const newDate = generateConfig.addYear(viewDate, diff); + onViewDateChange(newDate); + onPanelChange(null, newDate); + }; + const onMonthChange = (diff: number) => { + const newDate = generateConfig.addMonth(viewDate, diff); + onViewDateChange(newDate); + onPanelChange(null, newDate); + }; + + return ( +
+ { + onYearChange(-1); + }} + onNextYear={() => { + onYearChange(1); + }} + onPrevMonth={() => { + onMonthChange(-1); + }} + onNextMonth={() => { + onMonthChange(1); + }} + onMonthClick={() => { + onPanelChange('month', viewDate); + }} + onYearClick={() => { + onPanelChange('year', viewDate); + }} + /> + onSelect(date, 'mouse')} + prefixCls={prefixCls} + value={value} + viewDate={viewDate} + rowCount={DATE_ROW_COUNT} + /> +
+ ); +} + +DatePanel.displayName = 'DatePanel'; +DatePanel.inheritAttrs = false; + +export default DatePanel; diff --git a/components/vc-picker/panels/DatetimePanel/index.tsx b/components/vc-picker/panels/DatetimePanel/index.tsx new file mode 100644 index 000000000..79fd79538 --- /dev/null +++ b/components/vc-picker/panels/DatetimePanel/index.tsx @@ -0,0 +1,165 @@ +import type { DatePanelProps } from '../DatePanel'; +import DatePanel from '../DatePanel'; +import type { SharedTimeProps } from '../TimePanel'; +import TimePanel from '../TimePanel'; +import { tuple } from '../../utils/miscUtil'; +import { setDateTime as setTime } from '../../utils/timeUtil'; +import type { PanelRefProps, DisabledTime } from '../../interface'; +import KeyCode from '../../../_util/KeyCode'; +import classNames from '../../../_util/classNames'; +import { ref } from '@vue/reactivity'; +import useMergeProps from '../../hooks/useMergeProps'; + +export type DatetimePanelProps = { + disabledTime?: DisabledTime; + showTime?: boolean | SharedTimeProps; + defaultValue?: DateType; +} & Omit, 'disabledHours' | 'disabledMinutes' | 'disabledSeconds'>; + +const ACTIVE_PANEL = tuple('date', 'time'); +type ActivePanelType = typeof ACTIVE_PANEL[number]; + +function DatetimePanel(_props: DatetimePanelProps) { + const props = useMergeProps(_props); + const { + prefixCls, + operationRef, + generateConfig, + value, + defaultValue, + disabledTime, + showTime, + onSelect, + } = props; + const panelPrefixCls = `${prefixCls}-datetime-panel`; + const activePanel = ref(null); + + const dateOperationRef = ref({}); + const timeOperationRef = ref({}); + + const timeProps = typeof showTime === 'object' ? { ...showTime } : {}; + + // ======================= Keyboard ======================= + function getNextActive(offset: number) { + const activeIndex = ACTIVE_PANEL.indexOf(activePanel.value!) + offset; + const nextActivePanel = ACTIVE_PANEL[activeIndex] || null; + return nextActivePanel; + } + + const onBlur = (e?: FocusEvent) => { + if (timeOperationRef.value.onBlur) { + timeOperationRef.value.onBlur(e!); + } + activePanel.value = null; + }; + + operationRef.value = { + onKeydown: (event: KeyboardEvent) => { + // Switch active panel + if (event.which === KeyCode.TAB) { + const nextActivePanel = getNextActive(event.shiftKey ? -1 : 1); + activePanel.value = nextActivePanel; + + if (nextActivePanel) { + event.preventDefault(); + } + + return true; + } + + // Operate on current active panel + if (activePanel.value) { + const ref = activePanel.value === 'date' ? dateOperationRef : timeOperationRef; + + if (ref.value && ref.value.onKeydown) { + ref.value.onKeydown(event); + } + + return true; + } + + // Switch first active panel if operate without panel + if ([KeyCode.LEFT, KeyCode.RIGHT, KeyCode.UP, KeyCode.DOWN].includes(event.which)) { + activePanel.value = 'date'; + return true; + } + + return false; + }, + onBlur, + onClose: onBlur, + }; + + // ======================== Events ======================== + const onInternalSelect = (date: DateType, source: 'date' | 'time') => { + let selectedDate = date; + + if (source === 'date' && !value && timeProps.defaultValue) { + // Date with time defaultValue + selectedDate = generateConfig.setHour( + selectedDate, + generateConfig.getHour(timeProps.defaultValue), + ); + selectedDate = generateConfig.setMinute( + selectedDate, + generateConfig.getMinute(timeProps.defaultValue), + ); + selectedDate = generateConfig.setSecond( + selectedDate, + generateConfig.getSecond(timeProps.defaultValue), + ); + } else if (source === 'time' && !value && defaultValue) { + selectedDate = generateConfig.setYear(selectedDate, generateConfig.getYear(defaultValue)); + selectedDate = generateConfig.setMonth(selectedDate, generateConfig.getMonth(defaultValue)); + selectedDate = generateConfig.setDate(selectedDate, generateConfig.getDate(defaultValue)); + } + + if (onSelect) { + onSelect(selectedDate, 'mouse'); + } + }; + + // ======================== Render ======================== + const disabledTimes = disabledTime ? disabledTime(value || null) : {}; + + return ( +
+ { + onInternalSelect( + setTime( + generateConfig, + date, + showTime && typeof showTime === 'object' ? showTime.defaultValue : null, + ), + 'date', + ); + }} + /> + { + onInternalSelect(date, 'time'); + }} + /> +
+ ); +} + +DatetimePanel.displayName = 'DatetimePanel'; +DatetimePanel.inheritAttrs = false; + +export default DatetimePanel; diff --git a/components/vc-picker/panels/DecadePanel/DecadeBody.tsx b/components/vc-picker/panels/DecadePanel/DecadeBody.tsx new file mode 100644 index 000000000..3da59f5cf --- /dev/null +++ b/components/vc-picker/panels/DecadePanel/DecadeBody.tsx @@ -0,0 +1,68 @@ +import type { GenerateConfig } from '../../generate'; +import { DECADE_DISTANCE_COUNT, DECADE_UNIT_DIFF } from '.'; +import PanelBody from '../PanelBody'; +import useMergeProps from '../../hooks/useMergeProps'; + +export const DECADE_COL_COUNT = 3; +const DECADE_ROW_COUNT = 4; + +export type YearBodyProps = { + prefixCls: string; + generateConfig: GenerateConfig; + viewDate: DateType; + disabledDate?: (date: DateType) => boolean; + onSelect: (value: DateType) => void; +}; + +function DecadeBody(_props: YearBodyProps) { + const props = useMergeProps(_props); + const DECADE_UNIT_DIFF_DES = DECADE_UNIT_DIFF - 1; + const { prefixCls, viewDate, generateConfig } = props; + + const cellPrefixCls = `${prefixCls}-cell`; + + const yearNumber = generateConfig.getYear(viewDate); + const decadeYearNumber = Math.floor(yearNumber / DECADE_UNIT_DIFF) * DECADE_UNIT_DIFF; + + const startDecadeYear = Math.floor(yearNumber / DECADE_DISTANCE_COUNT) * DECADE_DISTANCE_COUNT; + const endDecadeYear = startDecadeYear + DECADE_DISTANCE_COUNT - 1; + + const baseDecadeYear = generateConfig.setYear( + viewDate, + startDecadeYear - + Math.ceil( + (DECADE_COL_COUNT * DECADE_ROW_COUNT * DECADE_UNIT_DIFF - DECADE_DISTANCE_COUNT) / 2, + ), + ); + + const getCellClassName = (date: DateType) => { + const startDecadeNumber = generateConfig.getYear(date); + const endDecadeNumber = startDecadeNumber + DECADE_UNIT_DIFF_DES; + + return { + [`${cellPrefixCls}-in-view`]: + startDecadeYear <= startDecadeNumber && endDecadeNumber <= endDecadeYear, + [`${cellPrefixCls}-selected`]: startDecadeNumber === decadeYearNumber, + }; + }; + + return ( + { + const startDecadeNumber = generateConfig.getYear(date); + return `${startDecadeNumber}-${startDecadeNumber + DECADE_UNIT_DIFF_DES}`; + }} + getCellClassName={getCellClassName} + getCellDate={(date, offset) => generateConfig.addYear(date, offset * DECADE_UNIT_DIFF)} + /> + ); +} + +DecadeBody.displayName = 'DecadeBody'; +DecadeBody.inheritAttrs = false; + +export default DecadeBody; diff --git a/components/vc-picker/panels/DecadePanel/DecadeHeader.tsx b/components/vc-picker/panels/DecadePanel/DecadeHeader.tsx new file mode 100644 index 000000000..1b56f722e --- /dev/null +++ b/components/vc-picker/panels/DecadePanel/DecadeHeader.tsx @@ -0,0 +1,45 @@ +import Header from '../Header'; +import type { GenerateConfig } from '../../generate'; +import { DECADE_DISTANCE_COUNT } from '.'; +import { useInjectPanel } from '../../PanelContext'; +import useMergeProps from '../../hooks/useMergeProps'; + +export type YearHeaderProps = { + prefixCls: string; + viewDate: DateType; + generateConfig: GenerateConfig; + + onPrevDecades: () => void; + onNextDecades: () => void; +}; + +function DecadeHeader(_props: YearHeaderProps) { + const props = useMergeProps(_props); + const { prefixCls, generateConfig, viewDate, onPrevDecades, onNextDecades } = props; + const { hideHeader } = useInjectPanel(); + if (hideHeader) { + return null; + } + + const headerPrefixCls = `${prefixCls}-header`; + + const yearNumber = generateConfig.getYear(viewDate); + const startYear = Math.floor(yearNumber / DECADE_DISTANCE_COUNT) * DECADE_DISTANCE_COUNT; + const endYear = startYear + DECADE_DISTANCE_COUNT - 1; + + return ( +
+ {startYear}-{endYear} +
+ ); +} + +DecadeHeader.displayName = 'DecadeHeader'; +DecadeHeader.inheritAttrs = false; + +export default DecadeHeader; diff --git a/components/vc-picker/panels/DecadePanel/index.tsx b/components/vc-picker/panels/DecadePanel/index.tsx new file mode 100644 index 000000000..e600b3351 --- /dev/null +++ b/components/vc-picker/panels/DecadePanel/index.tsx @@ -0,0 +1,80 @@ +import DecadeHeader from './DecadeHeader'; +import DecadeBody, { DECADE_COL_COUNT } from './DecadeBody'; +import type { PanelSharedProps } from '../../interface'; +import { createKeydownHandler } from '../../utils/uiUtil'; +import useMergeProps from '../../hooks/useMergeProps'; + +export type DecadePanelProps = PanelSharedProps; + +export const DECADE_UNIT_DIFF = 10; +export const DECADE_DISTANCE_COUNT = DECADE_UNIT_DIFF * 10; + +function DecadePanel(_props: DecadePanelProps) { + const props = useMergeProps(_props); + const { + prefixCls, + onViewDateChange, + generateConfig, + viewDate, + operationRef, + onSelect, + onPanelChange, + } = props; + + const panelPrefixCls = `${prefixCls}-decade-panel`; + + // ======================= Keyboard ======================= + operationRef.value = { + onKeydown: (event: KeyboardEvent) => + createKeydownHandler(event, { + onLeftRight: diff => { + onSelect(generateConfig.addYear(viewDate, diff * DECADE_UNIT_DIFF), 'key'); + }, + onCtrlLeftRight: diff => { + onSelect(generateConfig.addYear(viewDate, diff * DECADE_DISTANCE_COUNT), 'key'); + }, + onUpDown: diff => { + onSelect( + generateConfig.addYear(viewDate, diff * DECADE_UNIT_DIFF * DECADE_COL_COUNT), + 'key', + ); + }, + onEnter: () => { + onPanelChange('year', viewDate); + }, + }), + }; + + // ==================== View Operation ==================== + const onDecadesChange = (diff: number) => { + const newDate = generateConfig.addYear(viewDate, diff * DECADE_DISTANCE_COUNT); + onViewDateChange(newDate); + onPanelChange(null, newDate); + }; + + const onInternalSelect = (date: DateType) => { + onSelect(date, 'mouse'); + onPanelChange('year', date); + }; + + return ( +
+ { + onDecadesChange(-1); + }} + onNextDecades={() => { + onDecadesChange(1); + }} + /> + +
+ ); +} + +DecadePanel.displayName = 'DecadePanel'; +DecadePanel.inheritAttrs = false; + +export default DecadePanel; diff --git a/components/vc-picker/panels/Header.tsx b/components/vc-picker/panels/Header.tsx new file mode 100644 index 000000000..335994332 --- /dev/null +++ b/components/vc-picker/panels/Header.tsx @@ -0,0 +1,100 @@ +import type { CSSProperties } from 'vue'; +import type { VueNode } from '../../_util/type'; +import useMergeProps from '../hooks/useMergeProps'; +import { useInjectPanel } from '../PanelContext'; + +const HIDDEN_STYLE: CSSProperties = { + visibility: 'hidden', +}; + +export type HeaderProps = { + prefixCls: string; + + // Icons + prevIcon?: VueNode; + nextIcon?: VueNode; + superPrevIcon?: VueNode; + superNextIcon?: VueNode; + + /** Last one step */ + onPrev?: () => void; + /** Next one step */ + onNext?: () => void; + /** Last multiple steps */ + onSuperPrev?: () => void; + /** Next multiple steps */ + onSuperNext?: () => void; + + children?: VueNode; +}; + +function Header(_props: HeaderProps, { slots }) { + const props = useMergeProps(_props); + const { + prefixCls, + prevIcon = '\u2039', + nextIcon = '\u203A', + superPrevIcon = '\u00AB', + superNextIcon = '\u00BB', + onSuperPrev, + onSuperNext, + onPrev, + onNext, + } = props; + const { hideNextBtn, hidePrevBtn } = useInjectPanel(); + + return ( +
+ {onSuperPrev && ( + + )} + {onPrev && ( + + )} +
{slots.default?.()}
+ {onNext && ( + + )} + {onSuperNext && ( + + )} +
+ ); +} + +Header.displayName = 'Header'; +Header.inheritAttrs = false; + +export default Header; diff --git a/components/vc-picker/panels/MonthPanel/MonthBody.tsx b/components/vc-picker/panels/MonthPanel/MonthBody.tsx new file mode 100644 index 000000000..66b25fb6e --- /dev/null +++ b/components/vc-picker/panels/MonthPanel/MonthBody.tsx @@ -0,0 +1,89 @@ +import type { GenerateConfig } from '../../generate'; +import type { Locale } from '../../interface'; +import { formatValue, isSameMonth } from '../../utils/dateUtil'; +import { useInjectRange } from '../../RangeContext'; +import useCellClassName from '../../hooks/useCellClassName'; +import PanelBody from '../PanelBody'; +import type { VueNode } from '../../../_util/type'; +import useMergeProps from '../../hooks/useMergeProps'; + +export const MONTH_COL_COUNT = 3; +const MONTH_ROW_COUNT = 4; + +export type MonthCellRender = (obj: { current: DateType; locale: Locale }) => VueNode; + +export type MonthBodyProps = { + prefixCls: string; + locale: Locale; + generateConfig: GenerateConfig; + value?: DateType | null; + viewDate: DateType; + disabledDate?: (date: DateType) => boolean; + monthCellRender?: MonthCellRender; + onSelect: (value: DateType) => void; +}; + +function MonthBody(_props: MonthBodyProps) { + const props = useMergeProps(_props); + const { prefixCls, locale, value, viewDate, generateConfig, monthCellRender } = props; + + const { rangedValue, hoverRangedValue } = useInjectRange(); + + const cellPrefixCls = `${prefixCls}-cell`; + + const getCellClassName = useCellClassName({ + cellPrefixCls, + value, + generateConfig, + rangedValue: rangedValue.value, + hoverRangedValue: hoverRangedValue.value, + isSameCell: (current, target) => isSameMonth(generateConfig, current, target), + isInView: () => true, + offsetCell: (date, offset) => generateConfig.addMonth(date, offset), + }); + + const monthsLocale: string[] = + locale.shortMonths || + (generateConfig.locale.getShortMonths + ? generateConfig.locale.getShortMonths(locale.locale) + : []); + + const baseMonth = generateConfig.setMonth(viewDate, 0); + + const getCellNode = monthCellRender + ? (date: DateType) => monthCellRender({ current: date, locale }) + : undefined; + + return ( + + locale.monthFormat + ? formatValue(date, { + locale, + format: locale.monthFormat, + generateConfig, + }) + : monthsLocale[generateConfig.getMonth(date)] + } + getCellClassName={getCellClassName} + getCellDate={generateConfig.addMonth} + titleCell={date => + formatValue(date, { + locale, + format: 'YYYY-MM', + generateConfig, + }) + } + /> + ); +} + +MonthBody.displayName = 'MonthBody'; +MonthBody.inheritAttrs = false; + +export default MonthBody; diff --git a/components/vc-picker/panels/MonthPanel/MonthHeader.tsx b/components/vc-picker/panels/MonthPanel/MonthHeader.tsx new file mode 100644 index 000000000..cc010ffe5 --- /dev/null +++ b/components/vc-picker/panels/MonthPanel/MonthHeader.tsx @@ -0,0 +1,51 @@ +import Header from '../Header'; +import type { Locale } from '../../interface'; +import type { GenerateConfig } from '../../generate'; +import { useInjectPanel } from '../../PanelContext'; +import { formatValue } from '../../utils/dateUtil'; +import useMergeProps from '../../hooks/useMergeProps'; + +export type MonthHeaderProps = { + prefixCls: string; + viewDate: DateType; + locale: Locale; + generateConfig: GenerateConfig; + + onPrevYear: () => void; + onNextYear: () => void; + onYearClick: () => void; +}; + +function MonthHeader(_props: MonthHeaderProps) { + const props = useMergeProps(_props); + const { prefixCls, generateConfig, locale, viewDate, onNextYear, onPrevYear, onYearClick } = + props; + const { hideHeader } = useInjectPanel(); + if (hideHeader.value) { + return null; + } + + const headerPrefixCls = `${prefixCls}-header`; + + return ( +
+ +
+ ); +} + +MonthHeader.displayName = 'MonthHeader'; +MonthHeader.inheritAttrs = false; + +export default MonthHeader; diff --git a/components/vc-picker/panels/MonthPanel/index.tsx b/components/vc-picker/panels/MonthPanel/index.tsx new file mode 100644 index 000000000..04fdfd776 --- /dev/null +++ b/components/vc-picker/panels/MonthPanel/index.tsx @@ -0,0 +1,83 @@ +import MonthHeader from './MonthHeader'; +import type { MonthCellRender } from './MonthBody'; +import MonthBody, { MONTH_COL_COUNT } from './MonthBody'; +import type { PanelSharedProps } from '../../interface'; +import { createKeydownHandler } from '../../utils/uiUtil'; +import useMergeProps from '../../hooks/useMergeProps'; + +export type MonthPanelProps = { + monthCellContentRender?: MonthCellRender; +} & PanelSharedProps; + +function MonthPanel(_props: MonthPanelProps) { + const props = useMergeProps(_props); + const { + prefixCls, + operationRef, + onViewDateChange, + generateConfig, + value, + viewDate, + onPanelChange, + onSelect, + } = props; + + const panelPrefixCls = `${prefixCls}-month-panel`; + + // ======================= Keyboard ======================= + operationRef.value = { + onKeydown: (event: KeyboardEvent) => + createKeydownHandler(event, { + onLeftRight: diff => { + onSelect(generateConfig.addMonth(value || viewDate, diff), 'key'); + }, + onCtrlLeftRight: diff => { + onSelect(generateConfig.addYear(value || viewDate, diff), 'key'); + }, + onUpDown: diff => { + onSelect(generateConfig.addMonth(value || viewDate, diff * MONTH_COL_COUNT), 'key'); + }, + onEnter: () => { + onPanelChange('date', value || viewDate); + }, + }), + }; + + // ==================== View Operation ==================== + const onYearChange = (diff: number) => { + const newDate = generateConfig.addYear(viewDate, diff); + onViewDateChange(newDate); + onPanelChange(null, newDate); + }; + + return ( +
+ { + onYearChange(-1); + }} + onNextYear={() => { + onYearChange(1); + }} + onYearClick={() => { + onPanelChange('year', viewDate); + }} + /> + + {...props} + prefixCls={prefixCls} + onSelect={date => { + onSelect(date, 'mouse'); + onPanelChange('date', date); + }} + /> +
+ ); +} + +MonthPanel.displayName = 'MonthPanel'; +MonthPanel.inheritAttrs = false; + +export default MonthPanel; diff --git a/components/vc-picker/panels/PanelBody.tsx b/components/vc-picker/panels/PanelBody.tsx new file mode 100644 index 000000000..4af0ee3f2 --- /dev/null +++ b/components/vc-picker/panels/PanelBody.tsx @@ -0,0 +1,145 @@ +import { useInjectPanel } from '../PanelContext'; +import type { GenerateConfig } from '../generate'; +import { getLastDay } from '../utils/timeUtil'; +import type { PanelMode } from '../interface'; +import { getCellDateDisabled } from '../utils/dateUtil'; +import type { VueNode } from '../../_util/type'; +import classNames from '../../_util/classNames'; +import useMergeProps from '../hooks/useMergeProps'; + +export type PanelBodyProps = { + prefixCls: string; + disabledDate?: (date: DateType) => boolean; + onSelect: (value: DateType) => void; + picker?: PanelMode; + + // By panel + headerCells?: VueNode; + rowNum: number; + colNum: number; + baseDate: DateType; + getCellClassName: (date: DateType) => Record; + getCellDate: (date: DateType, offset: number) => DateType; + getCellText: (date: DateType) => VueNode; + getCellNode?: (date: DateType) => VueNode; + titleCell?: (date: DateType) => string; + generateConfig: GenerateConfig; + + // Used for week panel + prefixColumn?: (date: DateType) => VueNode; + rowClassName?: (date: DateType) => string; +}; + +function PanelBody(_props: PanelBodyProps) { + const { + prefixCls, + disabledDate, + onSelect, + picker, + rowNum, + colNum, + prefixColumn, + rowClassName, + baseDate, + getCellClassName, + getCellText, + getCellNode, + getCellDate, + generateConfig, + titleCell, + headerCells, + } = useMergeProps(_props); + const { onDateMouseenter, onDateMouseleave, mode } = useInjectPanel(); + + const cellPrefixCls = `${prefixCls}-cell`; + + // =============================== Body =============================== + const rows: VueNode[] = []; + + for (let i = 0; i < rowNum; i += 1) { + const row: VueNode[] = []; + let rowStartDate: DateType; + + for (let j = 0; j < colNum; j += 1) { + const offset = i * colNum + j; + const currentDate = getCellDate(baseDate, offset); + const disabled = getCellDateDisabled({ + cellDate: currentDate, + mode: mode.value, + disabledDate, + generateConfig, + }); + + if (j === 0) { + rowStartDate = currentDate; + + if (prefixColumn) { + row.push(prefixColumn(rowStartDate)); + } + } + + const title = titleCell && titleCell(currentDate); + + row.push( + { + if (!disabled) { + onSelect(currentDate); + } + }} + onMouseenter={() => { + if (!disabled && onDateMouseenter) { + onDateMouseenter(currentDate); + } + }} + onMouseleave={() => { + if (!disabled && onDateMouseleave) { + onDateMouseleave(currentDate); + } + }} + > + {getCellNode ? ( + getCellNode(currentDate) + ) : ( +
{getCellText(currentDate)}
+ )} + , + ); + } + + rows.push( + + {row} + , + ); + } + + return ( +
+ + {headerCells && ( + + {headerCells} + + )} + {rows} +
+
+ ); +} + +PanelBody.displayName = 'PanelBody'; +PanelBody.inheritAttrs = false; + +export default PanelBody; diff --git a/components/vc-picker/panels/QuarterPanel/QuarterBody.tsx b/components/vc-picker/panels/QuarterPanel/QuarterBody.tsx new file mode 100644 index 000000000..edbb8add6 --- /dev/null +++ b/components/vc-picker/panels/QuarterPanel/QuarterBody.tsx @@ -0,0 +1,71 @@ +import type { GenerateConfig } from '../../generate'; +import type { Locale } from '../../interface'; +import { formatValue, isSameQuarter } from '../../utils/dateUtil'; +import { useInjectRange } from '../../RangeContext'; +import useCellClassName from '../../hooks/useCellClassName'; +import PanelBody from '../PanelBody'; +import useMergeProps from '../../hooks/useMergeProps'; + +export const QUARTER_COL_COUNT = 4; +const QUARTER_ROW_COUNT = 1; + +export type QuarterBodyProps = { + prefixCls: string; + locale: Locale; + generateConfig: GenerateConfig; + value?: DateType | null; + viewDate: DateType; + disabledDate?: (date: DateType) => boolean; + onSelect: (value: DateType) => void; +}; + +function QuarterBody(_props: QuarterBodyProps) { + const props = useMergeProps(_props); + const { prefixCls, locale, value, viewDate, generateConfig } = props; + + const { rangedValue, hoverRangedValue } = useInjectRange(); + + const cellPrefixCls = `${prefixCls}-cell`; + + const getCellClassName = useCellClassName({ + cellPrefixCls, + value, + generateConfig, + rangedValue: rangedValue.value, + hoverRangedValue: hoverRangedValue.value, + isSameCell: (current, target) => isSameQuarter(generateConfig, current, target), + isInView: () => true, + offsetCell: (date, offset) => generateConfig.addMonth(date, offset * 3), + }); + + const baseQuarter = generateConfig.setDate(generateConfig.setMonth(viewDate, 0), 1); + + return ( + + formatValue(date, { + locale, + format: locale.quarterFormat || '[Q]Q', + generateConfig, + }) + } + getCellClassName={getCellClassName} + getCellDate={(date, offset) => generateConfig.addMonth(date, offset * 3)} + titleCell={date => + formatValue(date, { + locale, + format: 'YYYY-[Q]Q', + generateConfig, + }) + } + /> + ); +} + +QuarterBody.displayName = 'QuarterBody'; +QuarterBody.inheritAttrs = false; +export default QuarterBody; diff --git a/components/vc-picker/panels/QuarterPanel/QuarterHeader.tsx b/components/vc-picker/panels/QuarterPanel/QuarterHeader.tsx new file mode 100644 index 000000000..223f5d1b0 --- /dev/null +++ b/components/vc-picker/panels/QuarterPanel/QuarterHeader.tsx @@ -0,0 +1,50 @@ +import Header from '../Header'; +import type { Locale } from '../../interface'; +import type { GenerateConfig } from '../../generate'; +import { useInjectPanel } from '../../PanelContext'; +import { formatValue } from '../../utils/dateUtil'; +import useMergeProps from '../../hooks/useMergeProps'; + +export type QuarterHeaderProps = { + prefixCls: string; + viewDate: DateType; + locale: Locale; + generateConfig: GenerateConfig; + + onPrevYear: () => void; + onNextYear: () => void; + onYearClick: () => void; +}; + +function QuarterHeader(_props: QuarterHeaderProps) { + const props = useMergeProps(_props); + const { prefixCls, generateConfig, locale, viewDate, onNextYear, onPrevYear, onYearClick } = + props; + const { hideHeader } = useInjectPanel(); + if (hideHeader.value) { + return null; + } + + const headerPrefixCls = `${prefixCls}-header`; + return ( +
+ +
+ ); +} + +QuarterHeader.displayName = 'QuarterHeader'; +QuarterHeader.inheritAttrs = false; + +export default QuarterHeader; diff --git a/components/vc-picker/panels/QuarterPanel/index.tsx b/components/vc-picker/panels/QuarterPanel/index.tsx new file mode 100644 index 000000000..a1f5057b3 --- /dev/null +++ b/components/vc-picker/panels/QuarterPanel/index.tsx @@ -0,0 +1,76 @@ +import QuarterHeader from './QuarterHeader'; +import QuarterBody from './QuarterBody'; +import type { PanelSharedProps } from '../../interface'; +import { createKeydownHandler } from '../../utils/uiUtil'; +import useMergeProps from '../../hooks/useMergeProps'; + +export type QuarterPanelProps = {} & PanelSharedProps; + +function QuarterPanel(_props: QuarterPanelProps) { + const props = useMergeProps(_props); + const { + prefixCls, + operationRef, + onViewDateChange, + generateConfig, + value, + viewDate, + onPanelChange, + onSelect, + } = props; + + const panelPrefixCls = `${prefixCls}-quarter-panel`; + + // ======================= Keyboard ======================= + operationRef.value = { + onKeydown: (event: KeyboardEvent) => + createKeydownHandler(event, { + onLeftRight: diff => { + onSelect(generateConfig.addMonth(value || viewDate, diff * 3), 'key'); + }, + onCtrlLeftRight: diff => { + onSelect(generateConfig.addYear(value || viewDate, diff), 'key'); + }, + onUpDown: diff => { + onSelect(generateConfig.addYear(value || viewDate, diff), 'key'); + }, + }), + }; + + // ==================== View Operation ==================== + const onYearChange = (diff: number) => { + const newDate = generateConfig.addYear(viewDate, diff); + onViewDateChange(newDate); + onPanelChange(null, newDate); + }; + + return ( +
+ { + onYearChange(-1); + }} + onNextYear={() => { + onYearChange(1); + }} + onYearClick={() => { + onPanelChange('year', viewDate); + }} + /> + + {...props} + prefixCls={prefixCls} + onSelect={date => { + onSelect(date, 'mouse'); + }} + /> +
+ ); +} + +QuarterPanel.displayName = 'QuarterPanel'; +QuarterPanel.inheritAttrs = false; + +export default QuarterPanel; diff --git a/components/vc-picker/panels/TimePanel/TimeBody.tsx b/components/vc-picker/panels/TimePanel/TimeBody.tsx new file mode 100644 index 000000000..2c99941e0 --- /dev/null +++ b/components/vc-picker/panels/TimePanel/TimeBody.tsx @@ -0,0 +1,285 @@ +import type { GenerateConfig } from '../../generate'; +import type { Locale, OnSelect } from '../../interface'; +import type { Unit } from './TimeUnitColumn'; +import TimeUnitColumn from './TimeUnitColumn'; +import { leftPad } from '../../utils/miscUtil'; +import type { SharedTimeProps } from '.'; +import { setTime as utilSetTime } from '../../utils/timeUtil'; +import { cloneElement } from '../../../_util/vnode'; +import type { VueNode } from '../../../_util/type'; +import type { Ref } from 'vue'; +import { computed, defineComponent } from 'vue'; + +function generateUnits( + start: number, + end: number, + step: number, + disabledUnits: number[] | undefined, +) { + const units: Unit[] = []; + for (let i = start; i <= end; i += step) { + units.push({ + label: leftPad(i, 2), + value: i, + disabled: (disabledUnits || []).includes(i), + }); + } + return units; +} + +export type BodyOperationRef = { + onUpDown: (diff: number) => void; +}; + +export type TimeBodyProps = { + prefixCls: string; + locale: Locale; + generateConfig: GenerateConfig; + value?: DateType | null; + onSelect: OnSelect; + activeColumnIndex: number; + operationRef: Ref; +} & SharedTimeProps; + +const TimeBody = defineComponent({ + name: 'TimeBody', + inheritAttrs: false, + props: [ + 'generateConfig', + 'prefixCls', + 'operationRef', + 'activeColumnIndex', + 'value', + 'showHour', + 'showMinute', + 'showSecond', + 'use12Hours', + 'hourStep', + 'minuteStep', + 'secondStep', + 'disabledHours', + 'disabledMinutes', + 'disabledSeconds', + 'hideDisabledOptions', + 'onSelect', + ], + setup(props) { + const originHour = computed(() => + props.value ? props.generateConfig.getHour(props.value) : -1, + ); + const isPM = computed(() => { + if (props.use12Hours) { + return originHour.value >= 12; // -1 means should display AM + } else { + return false; + } + }); + const hour = computed(() => { + // Should additional logic to handle 12 hours + if (props.use12Hours) { + return originHour.value % 12; + } else { + return originHour.value; + } + }); + const minute = computed(() => (props.value ? props.generateConfig.getMinute(props.value) : -1)); + const second = computed(() => (props.value ? props.generateConfig.getSecond(props.value) : -1)); + + const setTime = ( + isNewPM: boolean | undefined, + newHour: number, + newMinute: number, + newSecond: number, + ) => { + let newDate = props.value || props.generateConfig.getNow(); + + const mergedHour = Math.max(0, newHour); + const mergedMinute = Math.max(0, newMinute); + const mergedSecond = Math.max(0, newSecond); + + newDate = utilSetTime( + props.generateConfig, + newDate, + !props.use12Hours || !isNewPM ? mergedHour : mergedHour + 12, + mergedMinute, + mergedSecond, + ); + + return newDate; + }; + + // ========================= Unit ========================= + const rawHours = computed(() => + generateUnits(0, 23, props.hourStep ?? 1, props.disabledHours && props.disabledHours()), + ); + + // const memorizedRawHours = useMemo(() => rawHours, rawHours, shouldUnitsUpdate); + + const AMPMDisabled = computed(() => { + if (!props.use12Hours) { + return [false, false]; + } + const AMPMDisabled = [true, true]; + rawHours.value.forEach(({ disabled, value: hourValue }) => { + if (disabled) return; + if (hourValue >= 12) { + AMPMDisabled[1] = false; + } else { + AMPMDisabled[0] = false; + } + }); + return AMPMDisabled; + }); + + const hours = computed(() => { + if (!props.use12Hours) return rawHours.value; + return rawHours.value + .filter(isPM.value ? hourMeta => hourMeta.value >= 12 : hourMeta => hourMeta.value < 12) + .map(hourMeta => { + const hourValue = hourMeta.value % 12; + const hourLabel = hourValue === 0 ? '12' : leftPad(hourValue, 2); + return { + ...hourMeta, + label: hourLabel, + value: hourValue, + }; + }); + }); + + const minutes = computed(() => + generateUnits( + 0, + 59, + props.minuteStep ?? 1, + props.disabledMinutes && props.disabledMinutes(originHour.value), + ), + ); + + const seconds = computed(() => + generateUnits( + 0, + 59, + props.secondStep ?? 1, + props.disabledSeconds && props.disabledSeconds(originHour.value, minute), + ), + ); + + return () => { + const { + prefixCls, + operationRef, + activeColumnIndex, + showHour, + showMinute, + showSecond, + use12Hours, + hideDisabledOptions, + onSelect, + } = props; + + const columns: { + node: VueNode; + value: number; + units: Unit[]; + onSelect: (diff: number) => void; + }[] = []; + const contentPrefixCls = `${prefixCls}-content`; + const columnPrefixCls = `${prefixCls}-time-panel`; + + // ====================== Operations ====================== + operationRef.value = { + onUpDown: (diff: number) => { + const column = columns[activeColumnIndex]; + if (column) { + const valueIndex = column.units.findIndex(unit => unit.value === column.value); + + const unitLen = column.units.length; + for (let i = 1; i < unitLen; i += 1) { + const nextUnit = column.units[(valueIndex + diff * i + unitLen) % unitLen]; + + if (nextUnit.disabled !== true) { + column.onSelect(nextUnit.value); + break; + } + } + } + }, + }; + + // ======================== Render ======================== + function addColumnNode( + condition: boolean | undefined, + node: VueNode, + columnValue: number, + units: Unit[], + onColumnSelect: (diff: number) => void, + ) { + if (condition !== false) { + columns.push({ + node: cloneElement(node, { + prefixCls: columnPrefixCls, + value: columnValue, + active: activeColumnIndex === columns.length, + onSelect: onColumnSelect, + units, + hideDisabledOptions, + }), + onSelect: onColumnSelect, + value: columnValue, + units, + }); + } + } + + // Hour + addColumnNode(showHour, , hour.value, hours.value, num => { + onSelect(setTime(isPM.value, num, minute.value, second.value), 'mouse'); + }); + + // Minute + addColumnNode( + showMinute, + , + minute.value, + minutes.value, + num => { + onSelect(setTime(isPM.value, hour.value, num, second.value), 'mouse'); + }, + ); + + // Second + addColumnNode( + showSecond, + , + second.value, + seconds.value, + num => { + onSelect(setTime(isPM.value, hour.value, minute.value, num), 'mouse'); + }, + ); + + // 12 Hours + let PMIndex = -1; + if (typeof isPM.value === 'boolean') { + PMIndex = isPM.value ? 1 : 0; + } + + addColumnNode( + use12Hours === true, + , + PMIndex, + [ + { label: 'AM', value: 0, disabled: AMPMDisabled.value[0] }, + { label: 'PM', value: 1, disabled: AMPMDisabled.value[1] }, + ], + num => { + onSelect(setTime(!!num, hour.value, minute.value, second.value), 'mouse'); + }, + ); + + return
{columns.map(({ node }) => node)}
; + }; + }, +}); + +export default TimeBody; diff --git a/components/vc-picker/panels/TimePanel/TimeHeader.tsx b/components/vc-picker/panels/TimePanel/TimeHeader.tsx new file mode 100644 index 000000000..977ef408a --- /dev/null +++ b/components/vc-picker/panels/TimePanel/TimeHeader.tsx @@ -0,0 +1,42 @@ +import Header from '../Header'; +import type { Locale } from '../../interface'; +import type { GenerateConfig } from '../../generate'; +import { useInjectPanel } from '../../PanelContext'; +import { formatValue } from '../../utils/dateUtil'; +import useMergeProps from '../../hooks/useMergeProps'; + +export type TimeHeaderProps = { + prefixCls: string; + value?: DateType | null; + locale: Locale; + generateConfig: GenerateConfig; + format: string; +}; + +function TimeHeader(_props: TimeHeaderProps) { + const props = useMergeProps(_props); + const { hideHeader } = useInjectPanel(); + if (hideHeader.value) { + return null; + } + + const { prefixCls, generateConfig, locale, value, format } = props; + const headerPrefixCls = `${prefixCls}-header`; + + return ( +
+ {value + ? formatValue(value, { + locale, + format, + generateConfig, + }) + : '\u00A0'} +
+ ); +} + +TimeHeader.displayName = 'TimeHeader'; +TimeHeader.inheritAttrs = false; + +export default TimeHeader; diff --git a/components/vc-picker/panels/TimePanel/TimeUnitColumn.tsx b/components/vc-picker/panels/TimePanel/TimeUnitColumn.tsx new file mode 100644 index 000000000..ccd197967 --- /dev/null +++ b/components/vc-picker/panels/TimePanel/TimeUnitColumn.tsx @@ -0,0 +1,104 @@ +import { scrollTo, waitElementReady } from '../../utils/uiUtil'; +import { useInjectPanel } from '../../PanelContext'; +import classNames from '../../../_util/classNames'; +import { ref } from '@vue/reactivity'; +import { onBeforeUnmount, watch } from '@vue/runtime-core'; +import { defineComponent, nextTick } from 'vue'; + +export type Unit = { + label: any; + value: number; + disabled: boolean; +}; + +export type TimeUnitColumnProps = { + prefixCls?: string; + units?: Unit[]; + value?: number; + active?: boolean; + hideDisabledOptions?: boolean; + onSelect?: (value: number) => void; +}; + +export default defineComponent({ + name: 'TimeUnitColumn', + props: ['prefixCls', 'units', 'onSelect', 'value', 'active', 'hideDisabledOptions'] as any, + setup(props) { + const { open } = useInjectPanel(); + + const ulRef = ref(null); + const liRefs = ref>(new Map()); + const scrollRef = ref(); + + watch( + () => props.value, + () => { + const li = liRefs.value.get(props.value!); + if (li && open.value !== false) { + scrollTo(ulRef.value!, li.offsetTop, 120); + } + }, + ); + onBeforeUnmount(() => { + scrollRef.value?.(); + }); + + watch( + open, + () => { + scrollRef.value?.(); + nextTick(() => { + if (open.value) { + const li = liRefs.value.get(props.value!); + if (li) { + scrollRef.value = waitElementReady(li, () => { + scrollTo(ulRef.value!, li.offsetTop, 0); + }); + } + } + }); + }, + { immediate: true, flush: 'post' }, + ); + return () => { + const { prefixCls, units, onSelect, value, active, hideDisabledOptions } = props; + const cellPrefixCls = `${prefixCls}-cell`; + return ( +
    + {units!.map(unit => { + if (hideDisabledOptions && unit.disabled) { + return null; + } + + return ( +
  • { + liRefs.value.set(unit.value, element as HTMLElement); + }} + class={classNames(cellPrefixCls, { + [`${cellPrefixCls}-disabled`]: unit.disabled, + [`${cellPrefixCls}-selected`]: value === unit.value, + })} + onClick={() => { + if (unit.disabled) { + return; + } + onSelect!(unit.value); + }} + > +
    {unit.label}
    +
  • + ); + })} +
+ ); + }; + }, +}); diff --git a/components/vc-picker/panels/TimePanel/index.tsx b/components/vc-picker/panels/TimePanel/index.tsx new file mode 100644 index 000000000..31530d66b --- /dev/null +++ b/components/vc-picker/panels/TimePanel/index.tsx @@ -0,0 +1,99 @@ +import TimeHeader from './TimeHeader'; +import type { BodyOperationRef } from './TimeBody'; +import TimeBody from './TimeBody'; +import type { PanelSharedProps, DisabledTimes } from '../../interface'; +import { createKeydownHandler } from '../../utils/uiUtil'; +import classNames from '../../../_util/classNames'; +import { ref } from '@vue/reactivity'; +import useMergeProps from '../../hooks/useMergeProps'; + +export type SharedTimeProps = { + format?: string; + showNow?: boolean; + showHour?: boolean; + showMinute?: boolean; + showSecond?: boolean; + use12Hours?: boolean; + hourStep?: number; + minuteStep?: number; + secondStep?: number; + hideDisabledOptions?: boolean; + defaultValue?: DateType; +} & DisabledTimes; + +export type TimePanelProps = { + format?: string; + active?: boolean; +} & PanelSharedProps & + SharedTimeProps; + +const countBoolean = (boolList: (boolean | undefined)[]) => + boolList.filter(bool => bool !== false).length; + +function TimePanel(_props: TimePanelProps) { + const props = useMergeProps(_props); + const { + generateConfig, + format = 'HH:mm:ss', + prefixCls, + active, + operationRef, + showHour, + showMinute, + showSecond, + use12Hours = false, + onSelect, + value, + } = props; + const panelPrefixCls = `${prefixCls}-time-panel`; + const bodyOperationRef = ref(); + + // ======================= Keyboard ======================= + const activeColumnIndex = ref(-1); + const columnsCount = countBoolean([showHour, showMinute, showSecond, use12Hours]); + + operationRef.value = { + onKeydown: (event: KeyboardEvent) => + createKeydownHandler(event, { + onLeftRight: diff => { + activeColumnIndex.value = (activeColumnIndex.value + diff + columnsCount) % columnsCount; + }, + onUpDown: diff => { + if (activeColumnIndex.value === -1) { + activeColumnIndex.value = 0; + } else if (bodyOperationRef.value) { + bodyOperationRef.value.onUpDown(diff); + } + }, + onEnter: () => { + onSelect(value || generateConfig.getNow(), 'key'); + activeColumnIndex.value = -1; + }, + }), + + onBlur: () => { + activeColumnIndex.value = -1; + }, + }; + + return ( +
+ + +
+ ); +} + +TimePanel.displayName = 'TimePanel'; +TimePanel.inheritAttrs = false; + +export default TimePanel; diff --git a/components/vc-picker/panels/WeekPanel/index.tsx b/components/vc-picker/panels/WeekPanel/index.tsx new file mode 100644 index 000000000..b0c203f22 --- /dev/null +++ b/components/vc-picker/panels/WeekPanel/index.tsx @@ -0,0 +1,44 @@ +import DatePanel from '../DatePanel'; +import type { PanelSharedProps } from '../../interface'; +import { isSameWeek } from '../../utils/dateUtil'; +import classNames from '../../../_util/classNames'; +import useMergeProps from '../../hooks/useMergeProps'; + +export type WeekPanelProps = PanelSharedProps; + +function WeekPanel(_props: WeekPanelProps) { + const props = useMergeProps(_props); + const { prefixCls, generateConfig, locale, value } = props; + + // Render additional column + const cellPrefixCls = `${prefixCls}-cell`; + const prefixColumn = (date: DateType) => ( + + {generateConfig.locale.getWeek(locale.locale, date)} + + ); + + // Add row className + const rowPrefixCls = `${prefixCls}-week-panel-row`; + const rowClassName = (date: DateType) => + classNames(rowPrefixCls, { + [`${rowPrefixCls}-selected`]: isSameWeek(generateConfig, locale.locale, value, date), + }); + + return ( + + ); +} + +WeekPanel.displayName = 'WeekPanel'; +WeekPanel.inheritAttrs = false; + +export default WeekPanel; diff --git a/components/vc-picker/panels/YearPanel/YearBody.tsx b/components/vc-picker/panels/YearPanel/YearBody.tsx new file mode 100644 index 000000000..18bc46e8e --- /dev/null +++ b/components/vc-picker/panels/YearPanel/YearBody.tsx @@ -0,0 +1,78 @@ +import type { GenerateConfig } from '../../generate'; +import { YEAR_DECADE_COUNT } from '.'; +import type { Locale, NullableDateType } from '../../interface'; +import useCellClassName from '../../hooks/useCellClassName'; +import { formatValue, isSameYear } from '../../utils/dateUtil'; +import { useInjectRange } from '../../RangeContext'; +import PanelBody from '../PanelBody'; +import useMergeProps from '../../hooks/useMergeProps'; + +export const YEAR_COL_COUNT = 3; +const YEAR_ROW_COUNT = 4; + +export type YearBodyProps = { + prefixCls: string; + locale: Locale; + generateConfig: GenerateConfig; + value?: NullableDateType; + viewDate: DateType; + disabledDate?: (date: DateType) => boolean; + onSelect: (value: DateType) => void; +}; + +function YearBody(_props: YearBodyProps) { + const props = useMergeProps(_props); + const { prefixCls, value, viewDate, locale, generateConfig } = props; + const { rangedValue, hoverRangedValue } = useInjectRange(); + + const yearPrefixCls = `${prefixCls}-cell`; + + // =============================== Year =============================== + const yearNumber = generateConfig.getYear(viewDate); + const startYear = Math.floor(yearNumber / YEAR_DECADE_COUNT) * YEAR_DECADE_COUNT; + const endYear = startYear + YEAR_DECADE_COUNT - 1; + const baseYear = generateConfig.setYear( + viewDate, + startYear - Math.ceil((YEAR_COL_COUNT * YEAR_ROW_COUNT - YEAR_DECADE_COUNT) / 2), + ); + + const isInView = (date: DateType) => { + const currentYearNumber = generateConfig.getYear(date); + return startYear <= currentYearNumber && currentYearNumber <= endYear; + }; + + const getCellClassName = useCellClassName({ + cellPrefixCls: yearPrefixCls, + value, + generateConfig, + rangedValue: rangedValue.value, + hoverRangedValue: hoverRangedValue.value, + isSameCell: (current, target) => isSameYear(generateConfig, current, target), + isInView, + offsetCell: (date, offset) => generateConfig.addYear(date, offset), + }); + + return ( + + formatValue(date, { + locale, + format: 'YYYY', + generateConfig, + }) + } + /> + ); +} + +YearBody.displayName = 'YearBody'; +YearBody.inheritAttrs = false; + +export default YearBody; diff --git a/components/vc-picker/panels/YearPanel/YearHeader.tsx b/components/vc-picker/panels/YearPanel/YearHeader.tsx new file mode 100644 index 000000000..79d95fb7d --- /dev/null +++ b/components/vc-picker/panels/YearPanel/YearHeader.tsx @@ -0,0 +1,49 @@ +import Header from '../Header'; +import type { GenerateConfig } from '../../generate'; +import { YEAR_DECADE_COUNT } from '.'; +import { useInjectPanel } from '../../PanelContext'; +import useMergeProps from '../../hooks/useMergeProps'; + +export type YearHeaderProps = { + prefixCls: string; + viewDate: DateType; + value?: DateType | null; + generateConfig: GenerateConfig; + + onPrevDecade: () => void; + onNextDecade: () => void; + onDecadeClick: () => void; +}; + +function YearHeader(_props: YearHeaderProps) { + const props = useMergeProps(_props); + const { prefixCls, generateConfig, viewDate, onPrevDecade, onNextDecade, onDecadeClick } = props; + const { hideHeader } = useInjectPanel(); + if (hideHeader.value) { + return null; + } + + const headerPrefixCls = `${prefixCls}-header`; + + const yearNumber = generateConfig.getYear(viewDate); + const startYear = Math.floor(yearNumber / YEAR_DECADE_COUNT) * YEAR_DECADE_COUNT; + const endYear = startYear + YEAR_DECADE_COUNT - 1; + + return ( +
+ +
+ ); +} + +YearHeader.displayName = 'YearHeader'; +YearHeader.inheritAttrs = false; + +export default YearHeader; diff --git a/components/vc-picker/panels/YearPanel/index.tsx b/components/vc-picker/panels/YearPanel/index.tsx new file mode 100644 index 000000000..7a43bc86a --- /dev/null +++ b/components/vc-picker/panels/YearPanel/index.tsx @@ -0,0 +1,85 @@ +import YearHeader from './YearHeader'; +import YearBody, { YEAR_COL_COUNT } from './YearBody'; +import type { PanelSharedProps, PanelMode } from '../../interface'; +import { createKeydownHandler } from '../../utils/uiUtil'; +import useMergeProps from '../../hooks/useMergeProps'; + +export type YearPanelProps = { + sourceMode: PanelMode; +} & PanelSharedProps; + +export const YEAR_DECADE_COUNT = 10; + +function YearPanel(_props: YearPanelProps) { + const props = useMergeProps(_props); + const { + prefixCls, + operationRef, + onViewDateChange, + generateConfig, + value, + viewDate, + sourceMode, + onSelect, + onPanelChange, + } = props; + + const panelPrefixCls = `${prefixCls}-year-panel`; + + // ======================= Keyboard ======================= + operationRef.value = { + onKeydown: (event: KeyboardEvent) => + createKeydownHandler(event, { + onLeftRight: diff => { + onSelect(generateConfig.addYear(value || viewDate, diff), 'key'); + }, + onCtrlLeftRight: diff => { + onSelect(generateConfig.addYear(value || viewDate, diff * YEAR_DECADE_COUNT), 'key'); + }, + onUpDown: diff => { + onSelect(generateConfig.addYear(value || viewDate, diff * YEAR_COL_COUNT), 'key'); + }, + onEnter: () => { + onPanelChange(sourceMode === 'date' ? 'date' : 'month', value || viewDate); + }, + }), + }; + + // ==================== View Operation ==================== + const onDecadeChange = (diff: number) => { + const newDate = generateConfig.addYear(viewDate, diff * 10); + onViewDateChange(newDate); + onPanelChange(null, newDate); + }; + + return ( +
+ { + onDecadeChange(-1); + }} + onNextDecade={() => { + onDecadeChange(1); + }} + onDecadeClick={() => { + onPanelChange('decade', viewDate); + }} + /> + { + onPanelChange(sourceMode === 'date' ? 'date' : 'month', date); + onSelect(date, 'mouse'); + }} + /> +
+ ); +} + +YearPanel.displayName = 'YearPanel'; +YearPanel.inheritAttrs = false; + +export default YearPanel; diff --git a/components/vc-picker/utils/dateUtil.ts b/components/vc-picker/utils/dateUtil.ts new file mode 100644 index 000000000..8b6a542b4 --- /dev/null +++ b/components/vc-picker/utils/dateUtil.ts @@ -0,0 +1,321 @@ +import { DECADE_UNIT_DIFF } from '../panels/DecadePanel/index'; +import type { PanelMode, NullableDateType, PickerMode, Locale, CustomFormat } from '../interface'; +import type { GenerateConfig } from '../generate'; + +export const WEEK_DAY_COUNT = 7; + +export function isNullEqual(value1: T, value2: T): boolean | undefined { + if (!value1 && !value2) { + return true; + } + if (!value1 || !value2) { + return false; + } + return undefined; +} + +export function isSameDecade( + generateConfig: GenerateConfig, + decade1: NullableDateType, + decade2: NullableDateType, +) { + const equal = isNullEqual(decade1, decade2); + if (typeof equal === 'boolean') { + return equal; + } + + const num1 = Math.floor(generateConfig.getYear(decade1!) / 10); + const num2 = Math.floor(generateConfig.getYear(decade2!) / 10); + return num1 === num2; +} + +export function isSameYear( + generateConfig: GenerateConfig, + year1: NullableDateType, + year2: NullableDateType, +) { + const equal = isNullEqual(year1, year2); + if (typeof equal === 'boolean') { + return equal; + } + + return generateConfig.getYear(year1!) === generateConfig.getYear(year2!); +} + +export function getQuarter(generateConfig: GenerateConfig, date: DateType) { + const quota = Math.floor(generateConfig.getMonth(date) / 3); + return quota + 1; +} + +export function isSameQuarter( + generateConfig: GenerateConfig, + quarter1: NullableDateType, + quarter2: NullableDateType, +) { + const equal = isNullEqual(quarter1, quarter2); + if (typeof equal === 'boolean') { + return equal; + } + + return ( + isSameYear(generateConfig, quarter1, quarter2) && + getQuarter(generateConfig, quarter1!) === getQuarter(generateConfig, quarter2!) + ); +} + +export function isSameMonth( + generateConfig: GenerateConfig, + month1: NullableDateType, + month2: NullableDateType, +) { + const equal = isNullEqual(month1, month2); + if (typeof equal === 'boolean') { + return equal; + } + + return ( + isSameYear(generateConfig, month1, month2) && + generateConfig.getMonth(month1!) === generateConfig.getMonth(month2!) + ); +} + +export function isSameDate( + generateConfig: GenerateConfig, + date1: NullableDateType, + date2: NullableDateType, +) { + const equal = isNullEqual(date1, date2); + if (typeof equal === 'boolean') { + return equal; + } + + return ( + generateConfig.getYear(date1!) === generateConfig.getYear(date2!) && + generateConfig.getMonth(date1!) === generateConfig.getMonth(date2!) && + generateConfig.getDate(date1!) === generateConfig.getDate(date2!) + ); +} + +export function isSameTime( + generateConfig: GenerateConfig, + time1: NullableDateType, + time2: NullableDateType, +) { + const equal = isNullEqual(time1, time2); + if (typeof equal === 'boolean') { + return equal; + } + + return ( + generateConfig.getHour(time1!) === generateConfig.getHour(time2!) && + generateConfig.getMinute(time1!) === generateConfig.getMinute(time2!) && + generateConfig.getSecond(time1!) === generateConfig.getSecond(time2!) + ); +} + +export function isSameWeek( + generateConfig: GenerateConfig, + locale: string, + date1: NullableDateType, + date2: NullableDateType, +) { + const equal = isNullEqual(date1, date2); + if (typeof equal === 'boolean') { + return equal; + } + + return ( + generateConfig.locale.getWeek(locale, date1!) === generateConfig.locale.getWeek(locale, date2!) + ); +} + +export function isEqual( + generateConfig: GenerateConfig, + value1: NullableDateType, + value2: NullableDateType, +) { + return isSameDate(generateConfig, value1, value2) && isSameTime(generateConfig, value1, value2); +} + +/** Between in date but not equal of date */ +export function isInRange( + generateConfig: GenerateConfig, + startDate: NullableDateType, + endDate: NullableDateType, + current: NullableDateType, +) { + if (!startDate || !endDate || !current) { + return false; + } + + return ( + !isSameDate(generateConfig, startDate, current) && + !isSameDate(generateConfig, endDate, current) && + generateConfig.isAfter(current, startDate) && + generateConfig.isAfter(endDate, current) + ); +} + +export function getWeekStartDate( + locale: string, + generateConfig: GenerateConfig, + value: DateType, +) { + const weekFirstDay = generateConfig.locale.getWeekFirstDay(locale); + const monthStartDate = generateConfig.setDate(value, 1); + const startDateWeekDay = generateConfig.getWeekDay(monthStartDate); + + let alignStartDate = generateConfig.addDate(monthStartDate, weekFirstDay - startDateWeekDay); + + if ( + generateConfig.getMonth(alignStartDate) === generateConfig.getMonth(value) && + generateConfig.getDate(alignStartDate) > 1 + ) { + alignStartDate = generateConfig.addDate(alignStartDate, -7); + } + + return alignStartDate; +} + +export function getClosingViewDate( + viewDate: DateType, + picker: PickerMode, + generateConfig: GenerateConfig, + offset = 1, +): DateType { + switch (picker) { + case 'year': + return generateConfig.addYear(viewDate, offset * 10); + case 'quarter': + case 'month': + return generateConfig.addYear(viewDate, offset); + default: + return generateConfig.addMonth(viewDate, offset); + } +} + +export function formatValue( + value: DateType, + { + generateConfig, + locale, + format, + }: { + generateConfig: GenerateConfig; + locale: Locale; + format: string | CustomFormat; + }, +) { + return typeof format === 'function' + ? format(value) + : generateConfig.locale.format(locale.locale, value, format); +} + +export function parseValue( + value: string, + { + generateConfig, + locale, + formatList, + }: { + generateConfig: GenerateConfig; + locale: Locale; + formatList: (string | CustomFormat)[]; + }, +) { + if (!value || typeof formatList[0] === 'function') { + return null; + } + + return generateConfig.locale.parse(locale.locale, value, formatList as string[]); +} + +// eslint-disable-next-line consistent-return +export function getCellDateDisabled({ + cellDate, + mode, + disabledDate, + generateConfig, +}: { + cellDate: DateType; + mode: Omit; + generateConfig: GenerateConfig; + disabledDate?: (date: DateType) => boolean; +}): boolean { + if (!disabledDate) return false; + // Whether cellDate is disabled in range + const getDisabledFromRange = ( + currentMode: 'date' | 'month' | 'year', + start: number, + end: number, + ) => { + let current = start; + while (current <= end) { + let date: DateType; + switch (currentMode) { + case 'date': { + date = generateConfig.setDate(cellDate, current); + if (!disabledDate(date)) { + return false; + } + break; + } + case 'month': { + date = generateConfig.setMonth(cellDate, current); + if ( + !getCellDateDisabled({ + cellDate: date, + mode: 'month', + generateConfig, + disabledDate, + }) + ) { + return false; + } + break; + } + case 'year': { + date = generateConfig.setYear(cellDate, current); + if ( + !getCellDateDisabled({ + cellDate: date, + mode: 'year', + generateConfig, + disabledDate, + }) + ) { + return false; + } + break; + } + } + current += 1; + } + return true; + }; + switch (mode) { + case 'date': + case 'week': { + return disabledDate(cellDate); + } + case 'month': { + const startDate = 1; + const endDate = generateConfig.getDate(generateConfig.getEndDate(cellDate)); + return getDisabledFromRange('date', startDate, endDate); + } + case 'quarter': { + const startMonth = Math.floor(generateConfig.getMonth(cellDate) / 3) * 3; + const endMonth = startMonth + 2; + return getDisabledFromRange('month', startMonth, endMonth); + } + case 'year': { + return getDisabledFromRange('month', 0, 11); + } + case 'decade': { + const year = generateConfig.getYear(cellDate); + const startYear = Math.floor(year / DECADE_UNIT_DIFF) * DECADE_UNIT_DIFF; + const endYear = startYear + DECADE_UNIT_DIFF - 1; + return getDisabledFromRange('year', startYear, endYear); + } + } +} diff --git a/components/vc-picker/utils/getExtraFooter.tsx b/components/vc-picker/utils/getExtraFooter.tsx new file mode 100644 index 000000000..b536adea8 --- /dev/null +++ b/components/vc-picker/utils/getExtraFooter.tsx @@ -0,0 +1,13 @@ +import type { PanelMode } from '../interface'; + +export default function getExtraFooter( + prefixCls: string, + mode: PanelMode, + renderExtraFooter?: (mode: PanelMode) => any, +) { + if (!renderExtraFooter) { + return null; + } + + return ; +} diff --git a/components/vc-picker/utils/getRanges.tsx b/components/vc-picker/utils/getRanges.tsx new file mode 100644 index 000000000..5f1e68ce4 --- /dev/null +++ b/components/vc-picker/utils/getRanges.tsx @@ -0,0 +1,78 @@ +import type { VueNode } from '../../_util/type'; +import type { Components, RangeList, Locale } from '../interface'; + +export type RangesProps = { + prefixCls: string; + rangeList?: RangeList; + components?: Components; + needConfirmButton: boolean; + onNow?: null | (() => void) | false; + onOk?: null | (() => void) | false; + okDisabled?: boolean; + showNow?: boolean; + locale: Locale; +}; + +export default function getRanges({ + prefixCls, + rangeList = [], + components = {}, + needConfirmButton, + onNow, + onOk, + okDisabled, + showNow, + locale, +}: RangesProps) { + let presetNode: VueNode; + let okNode: VueNode; + + if (rangeList.length) { + const Item = (components.rangeItem || 'span') as any; + + presetNode = ( + <> + {rangeList.map(({ label, onClick, onMouseenter, onMouseleave }) => ( +
  • + + {label} + +
  • + ))} + + ); + } + + if (needConfirmButton) { + const Button = (components.button || 'button') as any; + + if (onNow && !presetNode && showNow !== false) { + presetNode = ( +
  • + + {locale.now} + +
  • + ); + } + + okNode = needConfirmButton && ( +
  • + +
  • + ); + } + + if (!presetNode && !okNode) { + return null; + } + + return ( +
      + {presetNode} + {okNode} +
    + ); +} diff --git a/components/vc-picker/utils/miscUtil.ts b/components/vc-picker/utils/miscUtil.ts new file mode 100644 index 000000000..4ba6c67f2 --- /dev/null +++ b/components/vc-picker/utils/miscUtil.ts @@ -0,0 +1,58 @@ +export function leftPad(str: string | number, length: number, fill = '0') { + let current = String(str); + while (current.length < length) { + current = `${fill}${str}`; + } + return current; +} + +export const tuple = (...args: T) => args; + +export function toArray(val: T | T[]): T[] { + if (val === null || val === undefined) { + return []; + } + + return Array.isArray(val) ? val : [val]; +} + +export default function getDataOrAriaProps(props: any) { + const retProps: any = {}; + + Object.keys(props).forEach(key => { + if ( + (key.substr(0, 5) === 'data-' || + key.substr(0, 5) === 'aria-' || + key === 'role' || + key === 'name') && + key.substr(0, 7) !== 'data-__' + ) { + retProps[key] = props[key]; + } + }); + + return retProps; +} + +export function getValue(values: null | undefined | (T | null)[], index: number): T | null { + return values ? values[index] : null; +} + +type UpdateValue = (prev: T) => T; + +export function updateValues( + values: [T | null, T | null] | null, + value: T | UpdateValue, + index: number, +): R { + const newValues: [T | null, T | null] = [getValue(values, 0), getValue(values, 1)]; + + newValues[index] = + typeof value === 'function' ? (value as UpdateValue)(newValues[index]) : value; + + if (!newValues[0] && !newValues[1]) { + return null as unknown as R; + } + + return newValues as unknown as R; +} diff --git a/components/vc-picker/utils/timeUtil.ts b/components/vc-picker/utils/timeUtil.ts new file mode 100644 index 000000000..f666723ba --- /dev/null +++ b/components/vc-picker/utils/timeUtil.ts @@ -0,0 +1,60 @@ +import type { NullableDateType } from '../interface'; +import type { GenerateConfig } from '../generate'; + +export function setTime( + generateConfig: GenerateConfig, + date: DateType, + hour: number, + minute: number, + second: number, +): DateType { + let nextTime = generateConfig.setHour(date, hour); + nextTime = generateConfig.setMinute(nextTime, minute); + nextTime = generateConfig.setSecond(nextTime, second); + return nextTime; +} + +export function setDateTime( + generateConfig: GenerateConfig, + date: DateType, + defaultDate: NullableDateType, +) { + if (!defaultDate) { + return date; + } + + let newDate = date; + newDate = generateConfig.setHour(newDate, generateConfig.getHour(defaultDate)); + newDate = generateConfig.setMinute(newDate, generateConfig.getMinute(defaultDate)); + newDate = generateConfig.setSecond(newDate, generateConfig.getSecond(defaultDate)); + return newDate; +} + +export function getLowerBoundTime( + hour: number, + minute: number, + second: number, + hourStep: number, + minuteStep: number, + secondStep: number, +): [number, number, number] { + const lowerBoundHour = Math.floor(hour / hourStep) * hourStep; + if (lowerBoundHour < hour) { + return [lowerBoundHour, 60 - minuteStep, 60 - secondStep]; + } + const lowerBoundMinute = Math.floor(minute / minuteStep) * minuteStep; + if (lowerBoundMinute < minute) { + return [lowerBoundHour, lowerBoundMinute, 60 - secondStep]; + } + const lowerBoundSecond = Math.floor(second / secondStep) * secondStep; + return [lowerBoundHour, lowerBoundMinute, lowerBoundSecond]; +} + +export function getLastDay(generateConfig: GenerateConfig, date: DateType) { + const year = generateConfig.getYear(date); + const month = generateConfig.getMonth(date) + 1; + const endDate = generateConfig.getEndDate(generateConfig.getFixedDate(`${year}-${month}-01`)); + const lastDay = generateConfig.getDate(endDate); + const monthShow = month < 10 ? `0${month}` : `${month}`; + return `${year}-${monthShow}-${lastDay}`; +} diff --git a/components/vc-picker/utils/uiUtil.ts b/components/vc-picker/utils/uiUtil.ts new file mode 100644 index 000000000..c874fa517 --- /dev/null +++ b/components/vc-picker/utils/uiUtil.ts @@ -0,0 +1,276 @@ +import isVisible from '../../vc-util/Dom/isVisible'; +import KeyCode from '../../_util/KeyCode'; +import raf from '../../_util/raf'; +import type { GenerateConfig } from '../generate'; +import type { CustomFormat, PanelMode, PickerMode } from '../interface'; + +const scrollIds = new Map(); + +/** Trigger when element is visible in view */ +export function waitElementReady(element: HTMLElement, callback: () => void): () => void { + let id: number; + + function tryOrNextFrame() { + if (isVisible(element)) { + callback(); + } else { + id = raf(() => { + tryOrNextFrame(); + }); + } + } + + tryOrNextFrame(); + + return () => { + raf.cancel(id); + }; +} + +/* eslint-disable no-param-reassign */ +export function scrollTo(element: HTMLElement, to: number, duration: number) { + if (scrollIds.get(element)) { + cancelAnimationFrame(scrollIds.get(element)!); + } + + // jump to target if duration zero + if (duration <= 0) { + scrollIds.set( + element, + requestAnimationFrame(() => { + element.scrollTop = to; + }), + ); + + return; + } + const difference = to - element.scrollTop; + const perTick = (difference / duration) * 10; + + scrollIds.set( + element, + requestAnimationFrame(() => { + element.scrollTop += perTick; + if (element.scrollTop !== to) { + scrollTo(element, to, duration - 10); + } + }), + ); +} +/* eslint-enable */ + +export type KeyboardConfig = { + onLeftRight?: ((diff: number) => void) | null; + onCtrlLeftRight?: ((diff: number) => void) | null; + onUpDown?: ((diff: number) => void) | null; + onPageUpDown?: ((diff: number) => void) | null; + onEnter?: (() => void) | null; +}; +export function createKeydownHandler( + event: KeyboardEvent, + { onLeftRight, onCtrlLeftRight, onUpDown, onPageUpDown, onEnter }: KeyboardConfig, +): boolean { + const { which, ctrlKey, metaKey } = event; + + switch (which) { + case KeyCode.LEFT: + if (ctrlKey || metaKey) { + if (onCtrlLeftRight) { + onCtrlLeftRight(-1); + return true; + } + } else if (onLeftRight) { + onLeftRight(-1); + return true; + } + /* istanbul ignore next */ + break; + + case KeyCode.RIGHT: + if (ctrlKey || metaKey) { + if (onCtrlLeftRight) { + onCtrlLeftRight(1); + return true; + } + } else if (onLeftRight) { + onLeftRight(1); + return true; + } + /* istanbul ignore next */ + break; + + case KeyCode.UP: + if (onUpDown) { + onUpDown(-1); + return true; + } + /* istanbul ignore next */ + break; + + case KeyCode.DOWN: + if (onUpDown) { + onUpDown(1); + return true; + } + /* istanbul ignore next */ + break; + + case KeyCode.PAGE_UP: + if (onPageUpDown) { + onPageUpDown(-1); + return true; + } + /* istanbul ignore next */ + break; + + case KeyCode.PAGE_DOWN: + if (onPageUpDown) { + onPageUpDown(1); + return true; + } + /* istanbul ignore next */ + break; + + case KeyCode.ENTER: + if (onEnter) { + onEnter(); + return true; + } + /* istanbul ignore next */ + break; + } + + return false; +} + +// ===================== Format ===================== +export function getDefaultFormat( + format: string | CustomFormat | (string | CustomFormat)[] | undefined, + picker: PickerMode | undefined, + showTime: boolean | object | undefined, + use12Hours: boolean | undefined, +) { + let mergedFormat = format; + if (!mergedFormat) { + switch (picker) { + case 'time': + mergedFormat = use12Hours ? 'hh:mm:ss a' : 'HH:mm:ss'; + break; + + case 'week': + mergedFormat = 'gggg-wo'; + break; + + case 'month': + mergedFormat = 'YYYY-MM'; + break; + + case 'quarter': + mergedFormat = 'YYYY-[Q]Q'; + break; + + case 'year': + mergedFormat = 'YYYY'; + break; + + default: + mergedFormat = showTime ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD'; + } + } + + return mergedFormat; +} + +export function getInputSize( + picker: PickerMode | undefined, + format: string | CustomFormat, + generateConfig: GenerateConfig, +) { + const defaultSize = picker === 'time' ? 8 : 10; + const length = + typeof format === 'function' ? format(generateConfig.getNow()).length : format.length; + return Math.max(defaultSize, length) + 2; +} + +// ===================== Window ===================== +type ClickEventHandler = (event: MouseEvent) => void; +let globalClickFunc: ClickEventHandler | null = null; +const clickCallbacks = new Set(); + +export function addGlobalMousedownEvent(callback: ClickEventHandler) { + if (!globalClickFunc && typeof window !== 'undefined' && window.addEventListener) { + globalClickFunc = (e: MouseEvent) => { + // Clone a new list to avoid repeat trigger events + [...clickCallbacks].forEach(queueFunc => { + queueFunc(e); + }); + }; + window.addEventListener('mousedown', globalClickFunc); + } + + clickCallbacks.add(callback); + + return () => { + clickCallbacks.delete(callback); + if (clickCallbacks.size === 0) { + window.removeEventListener('mousedown', globalClickFunc!); + globalClickFunc = null; + } + }; +} + +export function getTargetFromEvent(e: Event) { + const target = e.target as HTMLElement; + + // get target if in shadow dom + if (e.composed && target.shadowRoot) { + return (e.composedPath?.()[0] || target) as HTMLElement; + } + + return target; +} + +// ====================== Mode ====================== +const getYearNextMode = (next: PanelMode): PanelMode => { + if (next === 'month' || next === 'date') { + return 'year'; + } + return next; +}; + +const getMonthNextMode = (next: PanelMode): PanelMode => { + if (next === 'date') { + return 'month'; + } + return next; +}; + +const getQuarterNextMode = (next: PanelMode): PanelMode => { + if (next === 'month' || next === 'date') { + return 'quarter'; + } + return next; +}; + +const getWeekNextMode = (next: PanelMode): PanelMode => { + if (next === 'date') { + return 'week'; + } + return next; +}; + +export const PickerModeMap: Record PanelMode) | null> = { + year: getYearNextMode, + month: getMonthNextMode, + quarter: getQuarterNextMode, + week: getWeekNextMode, + time: null, + date: null, +}; + +export function elementsContains( + elements: (HTMLElement | undefined | null)[], + target: HTMLElement, +) { + return elements.some(ele => ele && ele.contains(target)); +} diff --git a/components/vc-resize-observer/index.tsx b/components/vc-resize-observer/index.tsx index 850f27e6b..86613fc4a 100644 --- a/components/vc-resize-observer/index.tsx +++ b/components/vc-resize-observer/index.tsx @@ -1,5 +1,6 @@ // based on rc-resize-observer 1.0.0 import type { PropType } from 'vue'; +import ResizeObserver from 'resize-observer-polyfill'; import { defineComponent, getCurrentInstance, @@ -18,7 +19,7 @@ interface ResizeObserverState { offsetWidth: number; } -const ResizeObserver = defineComponent({ +export default defineComponent({ name: 'ResizeObserver', props: { disabled: Boolean, @@ -110,7 +111,7 @@ const ResizeObserver = defineComponent({ } if (!resizeObserver && element) { - resizeObserver = new window.ResizeObserver(onResize); + resizeObserver = new ResizeObserver(onResize); resizeObserver.observe(element); } }; @@ -135,5 +136,3 @@ const ResizeObserver = defineComponent({ }; }, }); - -export default ResizeObserver; diff --git a/components/vc-select/OptionList.tsx b/components/vc-select/OptionList.tsx index fbeb9744b..be343cc2b 100644 --- a/components/vc-select/OptionList.tsx +++ b/components/vc-select/OptionList.tsx @@ -5,7 +5,7 @@ import classNames from '../_util/classNames'; import pickAttrs from '../_util/pickAttrs'; import { isValidElement } from '../_util/props-util'; import createRef from '../_util/createRef'; -import type { VNodeChild } from 'vue'; +import type { PropType, VNodeChild } from 'vue'; import { computed, defineComponent, nextTick, reactive, watch } from 'vue'; import List from '../vc-virtual-list/List'; import type { @@ -61,7 +61,7 @@ const OptionListProps = { virtual: PropTypes.looseBool, onSelect: PropTypes.func, - onToggleOpen: PropTypes.func, + onToggleOpen: { type: Function as PropType<(open?: boolean) => void> }, /** Tell Select that some value is now active to make accessibility work */ onActiveValue: PropTypes.func, onScroll: PropTypes.func, @@ -77,6 +77,7 @@ const OptionListProps = { const OptionList = defineComponent({ name: 'OptionList', inheritAttrs: false, + slots: ['option'], setup(props) { const itemPrefixCls = computed(() => `${props.prefixCls}-item`); @@ -146,20 +147,20 @@ const OptionList = defineComponent({ watch( () => props.open, () => { - if (!props.multiple && props.open && props.values.size === 1) { - const value = Array.from(props.values)[0]; - const index = memoFlattenOptions.value.findIndex(({ data }) => data.value === value); - setActive(index); - scrollIntoView(index); - } - // Force trigger scrollbar visible when open - if (props.open) { - nextTick(() => { + nextTick(() => { + if (!props.multiple && props.open && props.values.size === 1) { + const value = Array.from(props.values)[0]; + const index = memoFlattenOptions.value.findIndex(({ data }) => data.value === value); + setActive(index); + scrollIntoView(index); + } + // Force trigger scrollbar visible when open + if (props.open) { listRef.current?.scrollTo(undefined); - }); - } + } + }); }, - { immediate: true, flush: 'post' }, + { immediate: true }, ); // ========================== Values ========================== @@ -268,6 +269,7 @@ const OptionList = defineComponent({ setActive, onSelectValue, memoFlattenOptions, + $slots, } = this as any; const { id, @@ -281,6 +283,7 @@ const OptionList = defineComponent({ onScroll, onMouseenter, } = this.$props as OptionListProps; + const renderOption = $slots.option; const { activeIndex } = this.state; // ========================== Render ========================== if (memoFlattenOptions.length === 0) { @@ -315,12 +318,11 @@ const OptionList = defineComponent({ onMouseenter={onMouseenter} children={({ group, groupOption, data }, itemIndex) => { const { label, key } = data; - // Group if (group) { return (
    - {label !== undefined ? label : key} + {renderOption ? renderOption(data) : label !== undefined ? label : key}
    ); } @@ -387,7 +389,9 @@ const OptionList = defineComponent({ }} style={style} > -
    {content}
    +
    + {renderOption ? renderOption(data) : content} +
    {isValidElement(menuItemSelectedIcon) || selected} {iconVisible && ( >({ ref={selectRef} {...(props as any)} {...attrs} + v-slots={slots} children={slots.default?.() || []} /> ); diff --git a/components/vc-select/SelectTrigger.tsx b/components/vc-select/SelectTrigger.tsx index e9f4e9cca..8e88ab439 100644 --- a/components/vc-select/SelectTrigger.tsx +++ b/components/vc-select/SelectTrigger.tsx @@ -95,6 +95,7 @@ const SelectTrigger = defineComponent({ transitionName, direction, getPopupContainer, + getTriggerDOMNode, } = props as SelectTriggerProps; const dropdownPrefixCls = `${prefixCls}-dropdown`; @@ -131,7 +132,7 @@ const SelectTrigger = defineComponent({ [`${dropdownPrefixCls}-empty`]: empty, })} popupStyle={popupStyle} - // getTriggerDOMNode={getTriggerDOMNode} + getTriggerDOMNode={getTriggerDOMNode} > {getSlot(this)[0]} diff --git a/components/vc-select/Selector/Input.tsx b/components/vc-select/Selector/Input.tsx index c8f72a71d..b29c6edf0 100644 --- a/components/vc-select/Selector/Input.tsx +++ b/components/vc-select/Selector/Input.tsx @@ -74,7 +74,7 @@ const Input = defineComponent) as VNode, [[antInput]]); + let inputNode: any = inputElement || withDirectives(() as VNode, [[antInput]]); const inputProps = inputNode.props || {}; const { diff --git a/components/vc-select/Selector/MultipleSelector.tsx b/components/vc-select/Selector/MultipleSelector.tsx index dc9805a97..950378854 100644 --- a/components/vc-select/Selector/MultipleSelector.tsx +++ b/components/vc-select/Selector/MultipleSelector.tsx @@ -7,9 +7,9 @@ import type { DisplayLabelValueType, } from '../interface/generator'; import type { RenderNode } from '../interface'; -import type { InnerSelectorProps } from '.'; +import type { InnerSelectorProps } from './interface'; import Input from './Input'; -import type { VNodeChild, Ref } from 'vue'; +import type { VNodeChild, Ref, PropType } from 'vue'; import { computed, defineComponent, onMounted, ref, watch } from 'vue'; import classNames from '../../_util/classNames'; import pickAttrs from '../../_util/pickAttrs'; @@ -17,24 +17,24 @@ import PropTypes from '../../_util/vue-types'; import type { VueNode } from '../../_util/type'; import Overflow from '../../vc-overflow'; -interface SelectorProps extends InnerSelectorProps { +type SelectorProps = InnerSelectorProps & { // Icon removeIcon?: RenderNode; // Tags maxTagCount?: number | 'responsive'; maxTagTextLength?: number; - maxTagPlaceholder?: VNodeChild; + maxTagPlaceholder?: VNodeChild | ((omittedValues: LabelValueType[]) => VNodeChild); tokenSeparators?: string[]; tagRender?: (props: CustomTagProps) => VNodeChild; - onToggleOpen: (open?: boolean) => void; + onToggleOpen: any; // Motion choiceTransitionName?: string; // Event onSelect: (value: RawValueType, option: { selected: boolean }) => void; -} +}; const props = { id: PropTypes.string, @@ -62,6 +62,7 @@ const props = { ), tagRender: PropTypes.func, + onToggleOpen: { type: Function as PropType<(open?: boolean) => void> }, onSelect: PropTypes.func, onInputChange: PropTypes.func, onInputPaste: PropTypes.func, @@ -78,6 +79,8 @@ const onPreventMouseDown = (event: MouseEvent) => { const SelectSelector = defineComponent({ name: 'MultipleSelectSelector', + inheritAttrs: false, + props: props as any, setup(props) { const measureRef = ref(); const inputWidth = ref(0); @@ -278,6 +281,5 @@ const SelectSelector = defineComponent({ }; }, }); -SelectSelector.inheritAttrs = false; -SelectSelector.props = props; + export default SelectSelector; diff --git a/components/vc-select/Selector/SingleSelector.tsx b/components/vc-select/Selector/SingleSelector.tsx index be58e784f..fdbff431a 100644 --- a/components/vc-select/Selector/SingleSelector.tsx +++ b/components/vc-select/Selector/SingleSelector.tsx @@ -1,6 +1,6 @@ import pickAttrs from '../../_util/pickAttrs'; import Input from './Input'; -import type { InnerSelectorProps } from '.'; +import type { InnerSelectorProps } from './interface'; import type { VNodeChild } from 'vue'; import { computed, defineComponent, Fragment, ref, watch } from 'vue'; import PropTypes from '../../_util/vue-types'; diff --git a/components/vc-select/Selector/index.tsx b/components/vc-select/Selector/index.tsx index d4430c35a..e6dd0f9a1 100644 --- a/components/vc-select/Selector/index.tsx +++ b/components/vc-select/Selector/index.tsx @@ -14,36 +14,12 @@ import SingleSelector from './SingleSelector'; import type { LabelValueType, RawValueType, CustomTagProps } from '../interface/generator'; import type { RenderNode, Mode } from '../interface'; import useLock from '../hooks/useLock'; -import type { VNodeChild } from 'vue'; +import type { VNodeChild, PropType } from 'vue'; import { defineComponent } from 'vue'; -import type { RefObject } from '../../_util/createRef'; import createRef from '../../_util/createRef'; import PropTypes from '../../_util/vue-types'; import type { VueNode } from '../../_util/type'; -export interface InnerSelectorProps { - prefixCls: string; - id: string; - mode: Mode; - inputRef: RefObject; - placeholder?: VNodeChild; - disabled?: boolean; - autofocus?: boolean; - autocomplete?: string; - values: LabelValueType[]; - showSearch?: boolean; - searchValue: string; - accessibilityIndex: number; - open: boolean; - tabindex?: number | string; - onInputKeyDown: EventHandlerNonNull; - onInputMouseDown: EventHandlerNonNull; - onInputChange: EventHandlerNonNull; - onInputPaste: EventHandlerNonNull; - onInputCompositionStart: EventHandlerNonNull; - onInputCompositionEnd: EventHandlerNonNull; -} - export interface SelectorProps { id: string; prefixCls: string; @@ -67,7 +43,7 @@ export interface SelectorProps { // Tags maxTagCount?: number | 'responsive'; maxTagTextLength?: number; - maxTagPlaceholder?: VNodeChild; + maxTagPlaceholder?: VNodeChild | ((omittedValues: LabelValueType[]) => VNodeChild); tagRender?: (props: CustomTagProps) => VNodeChild; /** Check if `tokenSeparators` contains `\n` or `\r\n` */ @@ -92,6 +68,52 @@ export interface SelectorProps { const Selector = defineComponent({ name: 'Selector', + inheritAttrs: false, + props: { + id: PropTypes.string, + prefixCls: PropTypes.string, + showSearch: PropTypes.looseBool, + open: PropTypes.looseBool, + /** Display in the Selector value, it's not same as `value` prop */ + values: PropTypes.array, + multiple: PropTypes.looseBool, + mode: PropTypes.string, + searchValue: PropTypes.string, + activeValue: PropTypes.string, + inputElement: PropTypes.any, + + autofocus: PropTypes.looseBool, + accessibilityIndex: PropTypes.number, + tabindex: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), + disabled: PropTypes.looseBool, + placeholder: PropTypes.any, + removeIcon: PropTypes.any, + + // Tags + maxTagCount: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), + maxTagTextLength: PropTypes.number, + maxTagPlaceholder: PropTypes.any, + tagRender: PropTypes.func, + + /** Check if `tokenSeparators` contains `\n` or `\r\n` */ + tokenWithEnter: PropTypes.looseBool, + + // Motion + choiceTransitionName: PropTypes.string, + + onToggleOpen: { type: Function as PropType<(open?: boolean) => void> }, + /** `onSearch` returns go next step boolean to check if need do toggle open */ + onSearch: PropTypes.func, + onSearchSubmit: PropTypes.func, + onSelect: PropTypes.func, + onInputKeyDown: PropTypes.func, + + /** + * @private get real dom for trigger align. + * This may be removed after React provides replacement of `findDOMNode` + */ + domRef: PropTypes.func, + } as any, setup(props) { const inputRef = createRef(); let compositionStatus = false; @@ -258,51 +280,4 @@ const Selector = defineComponent({ }, }); -Selector.inheritAttrs = false; -Selector.props = { - id: PropTypes.string, - prefixCls: PropTypes.string, - showSearch: PropTypes.looseBool, - open: PropTypes.looseBool, - /** Display in the Selector value, it's not same as `value` prop */ - values: PropTypes.array, - multiple: PropTypes.looseBool, - mode: PropTypes.string, - searchValue: PropTypes.string, - activeValue: PropTypes.string, - inputElement: PropTypes.any, - - autofocus: PropTypes.looseBool, - accessibilityIndex: PropTypes.number, - tabindex: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), - disabled: PropTypes.looseBool, - placeholder: PropTypes.any, - removeIcon: PropTypes.any, - - // Tags - maxTagCount: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), - maxTagTextLength: PropTypes.number, - maxTagPlaceholder: PropTypes.any, - tagRender: PropTypes.func, - - /** Check if `tokenSeparators` contains `\n` or `\r\n` */ - tokenWithEnter: PropTypes.looseBool, - - // Motion - choiceTransitionName: PropTypes.string, - - onToggleOpen: PropTypes.func, - /** `onSearch` returns go next step boolean to check if need do toggle open */ - onSearch: PropTypes.func, - onSearchSubmit: PropTypes.func, - onSelect: PropTypes.func, - onInputKeyDown: PropTypes.func, - - /** - * @private get real dom for trigger align. - * This may be removed after React provides replacement of `findDOMNode` - */ - domRef: PropTypes.func, -}; - export default Selector; diff --git a/components/vc-select/Selector/interface.ts b/components/vc-select/Selector/interface.ts new file mode 100644 index 000000000..2aa8b1e2c --- /dev/null +++ b/components/vc-select/Selector/interface.ts @@ -0,0 +1,27 @@ +import type { RefObject } from '../../_util/createRef'; +import type { VNodeChild } from 'vue'; +import type { Mode } from '../interface'; +import type { LabelValueType } from '../interface/generator'; + +export interface InnerSelectorProps { + prefixCls: string; + id: string; + mode: Mode; + inputRef: RefObject; + placeholder?: VNodeChild; + disabled?: boolean; + autofocus?: boolean; + autocomplete?: string; + values: LabelValueType[]; + showSearch?: boolean; + searchValue: string; + accessibilityIndex: number; + open: boolean; + tabindex?: number | string; + onInputKeyDown: EventHandlerNonNull; + onInputMouseDown: EventHandlerNonNull; + onInputChange: EventHandlerNonNull; + onInputPaste: EventHandlerNonNull; + onInputCompositionStart: EventHandlerNonNull; + onInputCompositionEnd: EventHandlerNonNull; +} diff --git a/components/vc-select/generate.tsx b/components/vc-select/generate.tsx index 09b2591ce..f0049771e 100644 --- a/components/vc-select/generate.tsx +++ b/components/vc-select/generate.tsx @@ -340,6 +340,7 @@ export default function generateSelector< } = config as any; const Select = defineComponent>({ name: 'Select', + slots: ['option'], setup(props: SelectProps) { const useInternalProps = computed( () => props.internalProps && props.internalProps.mark === INTERNAL_PROPS_MARK, @@ -1057,7 +1058,7 @@ export default function generateSelector< methods: { // We need force update here since popup dom is render async onPopupMouseEnter() { - this.$forceUpdate(); + (this as any).$forceUpdate(); }, }, render() { @@ -1093,6 +1094,7 @@ export default function generateSelector< displayValues, activeValue, onSearchSubmit, + $slots: slots, } = this as any; const { prefixCls = defaultPrefixCls, @@ -1204,6 +1206,7 @@ export default function generateSelector< menuItemSelectedIcon={menuItemSelectedIcon} virtual={virtual !== false && dropdownMatchSelectWidth !== false} onMouseenter={onPopupMouseEnter} + v-slots={{ option: slots.option }} /> ); diff --git a/components/vc-select/utils/legacyUtil.ts b/components/vc-select/utils/legacyUtil.ts index 7d0780638..24778f024 100644 --- a/components/vc-select/utils/legacyUtil.ts +++ b/components/vc-select/utils/legacyUtil.ts @@ -7,8 +7,9 @@ function convertNodeToOption(node: VNode): OptionData { key, children, props: { value, disabled, ...restProps }, - } = node as VNode & { + } = node as Omit & { children: { default?: () => any }; + key: string | number; }; const child = children && children.default ? children.default() : undefined; return { @@ -16,7 +17,7 @@ function convertNodeToOption(node: VNode): OptionData { value: value !== undefined ? value : key, children: child, disabled: disabled || disabled === '', // support - ...restProps, + ...(restProps as Omit), }; } @@ -46,7 +47,7 @@ export function convertChildrenToData( const child = children && children.default ? children.default() : undefined; const label = props?.label || children.label?.() || key; return { - key: `__RC_SELECT_GRP__${key === null ? index : key}__`, + key: `__RC_SELECT_GRP__${key === null ? index : String(key)}__`, ...props, label, options: convertChildrenToData(child || []), diff --git a/components/vc-slick/src/inner-slider.js b/components/vc-slick/src/inner-slider.js index 421ef43d9..828e79bad 100644 --- a/components/vc-slick/src/inner-slider.js +++ b/components/vc-slick/src/inner-slider.js @@ -1,4 +1,5 @@ import debounce from 'lodash-es/debounce'; +import ResizeObserver from 'resize-observer-polyfill'; import classnames from '../../_util/classNames'; import BaseMixin from '../../_util/BaseMixin'; import defaultProps from './default-props'; diff --git a/components/vc-table/src/BaseTable.jsx b/components/vc-table/src/BaseTable.jsx index 36bf0da97..2e5a5dc8a 100644 --- a/components/vc-table/src/BaseTable.jsx +++ b/components/vc-table/src/BaseTable.jsx @@ -132,16 +132,13 @@ const BaseTable = { render() { const { sComponents: components, prefixCls, scroll, data } = this.table; - const { expander, tableClassName, hasHead, hasBody, fixed, isAnyColumnsFixed } = this.$props; + const { expander, tableClassName, hasHead, hasBody, fixed } = this.$props; const columns = this.getColumns(); const tableStyle = {}; if (!fixed && scroll.x) { - // 当有固定列时,width auto 会导致 body table 的宽度撑不开,从而固定列无法对齐 - // 详情见:https://github.com/ant-design/ant-design/issues/22160 - const tableWidthScrollX = isAnyColumnsFixed ? 'max-content' : 'auto'; // not set width, then use content fixed width - tableStyle.width = scroll.x === true ? tableWidthScrollX : scroll.x; + tableStyle.width = scroll.x === true ? 'auto' : scroll.x; tableStyle.width = typeof tableStyle.width === 'number' ? `${tableStyle.width}px` : tableStyle.width; } diff --git a/components/vc-table/src/BodyTable.jsx b/components/vc-table/src/BodyTable.jsx index ea5ba86de..b0352dab0 100644 --- a/components/vc-table/src/BodyTable.jsx +++ b/components/vc-table/src/BodyTable.jsx @@ -1,13 +1,11 @@ import { inject } from 'vue'; -import PropTypes, { withUndefined } from '../../_util/vue-types'; -import { measureScrollbar } from './utils'; +import PropTypes from '../../_util/vue-types'; import BaseTable from './BaseTable'; export default { name: 'BodyTable', inheritAttrs: false, props: { - fixed: withUndefined(PropTypes.oneOfType([PropTypes.string, PropTypes.looseBool])), columns: PropTypes.array.isRequired, tableClassName: PropTypes.string.isRequired, handleBodyScroll: PropTypes.func.isRequired, @@ -25,7 +23,6 @@ export default { const { prefixCls, scroll } = this.table; const { columns, - fixed, tableClassName, getRowKey, handleBodyScroll, @@ -35,34 +32,26 @@ export default { } = this; let { useFixedHeader, saveRef } = this.table; const bodyStyle = { ...this.table.bodyStyle }; - const innerBodyStyle = {}; - - if (scroll.x || fixed) { - bodyStyle.overflowX = bodyStyle.overflowX || 'scroll'; - // Fix weired webkit render bug - // https://github.com/ant-design/ant-design/issues/7783 - bodyStyle.WebkitTransform = 'translate3d (0, 0, 0)'; - } if (scroll.y) { // maxHeight will make fixed-Table scrolling not working // so we only set maxHeight to body-Table here let maxHeight = bodyStyle.maxHeight || scroll.y; maxHeight = typeof maxHeight === 'number' ? `${maxHeight}px` : maxHeight; - if (fixed) { - innerBodyStyle.maxHeight = maxHeight; - innerBodyStyle.overflowY = bodyStyle.overflowY || 'scroll'; - } else { - bodyStyle.maxHeight = maxHeight; - } + + bodyStyle.maxHeight = maxHeight; bodyStyle.overflowY = bodyStyle.overflowY || 'scroll'; useFixedHeader = true; + } - // Add negative margin bottom for scroll bar overflow bug - const scrollbarWidth = measureScrollbar({ direction: 'vertical' }); - if (scrollbarWidth > 0 && fixed) { - bodyStyle.marginBottom = `-${scrollbarWidth}px`; - bodyStyle.paddingBottom = '0px'; + if (scroll.x) { + bodyStyle.overflowX = bodyStyle.overflowX || 'auto'; + // Fix weired webkit render bug + // https://github.com/ant-design/ant-design/issues/7783 + bodyStyle.WebkitTransform = 'translate3d (0, 0, 0)'; + + if (!scroll.y) { + bodyStyle.overflowY = 'hidden'; } } @@ -71,7 +60,6 @@ export default { tableClassName={tableClassName} hasHead={!useFixedHeader} hasBody - fixed={fixed} columns={columns} expander={expander} getRowKey={getRowKey} @@ -79,29 +67,6 @@ export default { /> ); - if (fixed && columns.length) { - let refName; - if (columns[0].fixed === 'left' || columns[0].fixed === true) { - refName = 'fixedColumnsBodyLeft'; - } else if (columns[0].fixed === 'right') { - refName = 'fixedColumnsBodyRight'; - } - delete bodyStyle.overflowX; - delete bodyStyle.overflowY; - return ( -
    -
    - {baseTable} -
    -
    - ); - } // Should provides `tabindex` if use scroll to enable keyboard scroll const useTabIndex = scroll && (scroll.x || scroll.y); diff --git a/components/vc-table/src/Table.jsx b/components/vc-table/src/Table.jsx index c05c4a379..19d0d6acc 100644 --- a/components/vc-table/src/Table.jsx +++ b/components/vc-table/src/Table.jsx @@ -501,41 +501,15 @@ export default defineComponent({ ); }, - renderLeftFixedTable() { - const { prefixCls } = this; - - return ( -
    - {this.renderTable({ - columns: this.columnManager.leftColumns.value, - fixed: 'left', - })} -
    - ); - }, - renderRightFixedTable() { - const { prefixCls } = this; - - return ( -
    - {this.renderTable({ - columns: this.columnManager.rightColumns.value, - fixed: 'right', - })} -
    - ); - }, - renderTable(options) { - const { columns, fixed, isAnyColumnsFixed } = options; + const { columns, isAnyColumnsFixed } = options; const { prefixCls, scroll = {} } = this; - const tableClassName = scroll.x || fixed ? `${prefixCls}-fixed` : ''; + const tableClassName = scroll.x ? `${prefixCls}-fixed` : ''; const headTable = ( parseHeaderRows(props.columns)), }; }, render() { const { sComponents: components, prefixCls, showHeader, customHeaderRow } = this.table; - const { expander, columns, fixed, rows } = this; + const { expander, columns, fixed } = this; if (!showHeader) { return null; } - + const rows = parseHeaderRows(this.columns); expander.renderExpandIndentCell(rows, fixed); const HeaderWrapper = components.header.wrapper; diff --git a/components/vc-tabs/src/ScrollableTabBarNode.jsx b/components/vc-tabs/src/ScrollableTabBarNode.jsx index 806bc9a32..2e1650e47 100644 --- a/components/vc-tabs/src/ScrollableTabBarNode.jsx +++ b/components/vc-tabs/src/ScrollableTabBarNode.jsx @@ -1,4 +1,5 @@ import debounce from 'lodash-es/debounce'; +import ResizeObserver from 'resize-observer-polyfill'; import PropTypes from '../../_util/vue-types'; import BaseMixin from '../../_util/BaseMixin'; import { getComponent, getSlot } from '../../_util/props-util'; diff --git a/components/vc-time-picker/Combobox.jsx b/components/vc-time-picker/Combobox.jsx deleted file mode 100644 index e6b567457..000000000 --- a/components/vc-time-picker/Combobox.jsx +++ /dev/null @@ -1,215 +0,0 @@ -import PropTypes from '../_util/vue-types'; -import Select from './Select'; -import BaseMixin from '../_util/BaseMixin'; - -const formatOption = (option, disabledOptions) => { - let value = `${option}`; - if (option < 10) { - value = `0${option}`; - } - - let disabled = false; - if (disabledOptions && disabledOptions.indexOf(option) >= 0) { - disabled = true; - } - - return { - value, - disabled, - }; -}; - -const Combobox = { - inheritAttrs: false, - mixins: [BaseMixin], - name: 'Combobox', - props: { - format: PropTypes.string, - defaultOpenValue: PropTypes.object, - prefixCls: PropTypes.string, - value: PropTypes.object, - // onChange: PropTypes.func, - // onAmPmChange: PropTypes.func, - showHour: PropTypes.looseBool, - showMinute: PropTypes.looseBool, - showSecond: PropTypes.looseBool, - hourOptions: PropTypes.array, - minuteOptions: PropTypes.array, - secondOptions: PropTypes.array, - disabledHours: PropTypes.func, - disabledMinutes: PropTypes.func, - disabledSeconds: PropTypes.func, - // onCurrentSelectPanelChange: PropTypes.func, - use12Hours: PropTypes.looseBool, - isAM: PropTypes.looseBool, - }, - methods: { - onItemChange(type, itemValue) { - const { defaultOpenValue, use12Hours, value: propValue, isAM } = this; - const value = (propValue || defaultOpenValue).clone(); - - if (type === 'hour') { - if (use12Hours) { - if (isAM) { - value.hour(+itemValue % 12); - } else { - value.hour((+itemValue % 12) + 12); - } - } else { - value.hour(+itemValue); - } - } else if (type === 'minute') { - value.minute(+itemValue); - } else if (type === 'ampm') { - const ampm = itemValue.toUpperCase(); - if (use12Hours) { - if (ampm === 'PM' && value.hour() < 12) { - value.hour((value.hour() % 12) + 12); - } - - if (ampm === 'AM') { - if (value.hour() >= 12) { - value.hour(value.hour() - 12); - } - } - } - this.__emit('amPmChange', ampm); - } else { - value.second(+itemValue); - } - this.__emit('change', value); - }, - - onEnterSelectPanel(range) { - this.__emit('currentSelectPanelChange', range); - }, - onEsc(e) { - this.__emit('esc', e); - }, - - getHourSelect(hour) { - const { prefixCls, hourOptions, disabledHours, showHour, use12Hours } = this; - if (!showHour) { - return null; - } - const disabledOptions = disabledHours(); - let hourOptionsAdj; - let hourAdj; - if (use12Hours) { - hourOptionsAdj = [12].concat(hourOptions.filter(h => h < 12 && h > 0)); - hourAdj = hour % 12 || 12; - } else { - hourOptionsAdj = hourOptions; - hourAdj = hour; - } - - return ( - formatOption(option, disabledOptions))} - selectedIndex={minuteOptions.indexOf(minute)} - type="minute" - onSelect={this.onItemChange} - onMouseenter={() => this.onEnterSelectPanel('minute')} - onEsc={this.onEsc} - /> - ); - }, - - getSecondSelect(second) { - const { - prefixCls, - secondOptions, - disabledSeconds, - showSecond, - defaultOpenValue, - value: propValue, - } = this; - if (!showSecond) { - return null; - } - const value = propValue || defaultOpenValue; - const disabledOptions = disabledSeconds(value.hour(), value.minute()); - - return ( - this.onEnterSelectPanel('ampm')} - onEsc={this.onEsc} - /> - ); - }, - }, - - render() { - const { prefixCls, defaultOpenValue, value: propValue } = this; - const value = propValue || defaultOpenValue; - return ( -
    - {this.getHourSelect(value.hour())} - {this.getMinuteSelect(value.minute())} - {this.getSecondSelect(value.second())} - {this.getAMPMSelect(value.hour())} -
    - ); - }, -}; - -export default Combobox; diff --git a/components/vc-time-picker/Header.jsx b/components/vc-time-picker/Header.jsx deleted file mode 100644 index 1f2fa1801..000000000 --- a/components/vc-time-picker/Header.jsx +++ /dev/null @@ -1,185 +0,0 @@ -import PropTypes from '../_util/vue-types'; -import BaseMixin from '../_util/BaseMixin'; -import moment from 'moment'; -import { withDirectives } from 'vue'; -import antInput from '../_util/antInputDirective'; - -const Header = { - inheritAttrs: false, - name: 'Header', - mixins: [BaseMixin], - props: { - format: PropTypes.string, - prefixCls: PropTypes.string, - disabledDate: PropTypes.func, - placeholder: PropTypes.string, - clearText: PropTypes.string, - value: PropTypes.object, - inputReadOnly: PropTypes.looseBool.def(false), - hourOptions: PropTypes.array, - minuteOptions: PropTypes.array, - secondOptions: PropTypes.array, - disabledHours: PropTypes.func, - disabledMinutes: PropTypes.func, - disabledSeconds: PropTypes.func, - // onChange: PropTypes.func, - // onClear: PropTypes.func, - // onEsc: PropTypes.func, - allowEmpty: PropTypes.looseBool, - defaultOpenValue: PropTypes.object, - currentSelectPanel: PropTypes.string, - focusOnOpen: PropTypes.looseBool, - // onKeyDown: PropTypes.func, - clearIcon: PropTypes.any, - }, - data() { - const { value, format } = this; - return { - str: (value && value.format(format)) || '', - invalid: false, - }; - }, - - mounted() { - if (this.focusOnOpen) { - // Wait one frame for the panel to be positioned before focusing - const requestAnimationFrame = window.requestAnimationFrame || window.setTimeout; - requestAnimationFrame(() => { - this.refInput.focus(); - this.refInput.select(); - }); - } - }, - watch: { - value(val) { - this.$nextTick(() => { - this.setState({ - str: (val && val.format(this.format)) || '', - invalid: false, - }); - }); - }, - }, - - methods: { - onInputChange(e) { - const { value: str, composing } = e.target; - const { str: oldStr = '' } = this; - if (e.isComposing || composing || oldStr === str) return; - - this.setState({ - str, - }); - const { - format, - hourOptions, - minuteOptions, - secondOptions, - disabledHours, - disabledMinutes, - disabledSeconds, - value: originalValue, - } = this; - - if (str) { - const value = this.getProtoValue().clone(); - const parsed = moment(str, format, true); - if (!parsed.isValid()) { - this.setState({ - invalid: true, - }); - return; - } - value.hour(parsed.hour()).minute(parsed.minute()).second(parsed.second()); - - // if time value not allowed, response warning. - if ( - hourOptions.indexOf(value.hour()) < 0 || - minuteOptions.indexOf(value.minute()) < 0 || - secondOptions.indexOf(value.second()) < 0 - ) { - this.setState({ - invalid: true, - }); - return; - } - - // if time value is disabled, response warning. - const disabledHourOptions = disabledHours(); - const disabledMinuteOptions = disabledMinutes(value.hour()); - const disabledSecondOptions = disabledSeconds(value.hour(), value.minute()); - if ( - (disabledHourOptions && disabledHourOptions.indexOf(value.hour()) >= 0) || - (disabledMinuteOptions && disabledMinuteOptions.indexOf(value.minute()) >= 0) || - (disabledSecondOptions && disabledSecondOptions.indexOf(value.second()) >= 0) - ) { - this.setState({ - invalid: true, - }); - return; - } - - if (originalValue) { - if ( - originalValue.hour() !== value.hour() || - originalValue.minute() !== value.minute() || - originalValue.second() !== value.second() - ) { - // keep other fields for rc-calendar - const changedValue = originalValue.clone(); - changedValue.hour(value.hour()); - changedValue.minute(value.minute()); - changedValue.second(value.second()); - this.__emit('change', changedValue); - } - } else if (originalValue !== value) { - this.__emit('change', value); - } - } else { - this.__emit('change', null); - } - - this.setState({ - invalid: false, - }); - }, - - onKeyDown(e) { - if (e.keyCode === 27) { - this.__emit('esc'); - } - this.__emit('keydown', e); - }, - - getProtoValue() { - return this.value || this.defaultOpenValue; - }, - - getInput() { - const { prefixCls, placeholder, inputReadOnly, invalid, str } = this; - const invalidClass = invalid ? `${prefixCls}-input-invalid` : ''; - return withDirectives( - { - this.refInput = ref; - }} - onKeydown={this.onKeyDown} - value={str} - placeholder={placeholder} - onInput={this.onInputChange} - onChange={this.onInputChange} - readonly={!!inputReadOnly} - />, - [[antInput]], - ); - }, - }, - - render() { - const { prefixCls } = this; - return
    {this.getInput()}
    ; - }, -}; - -export default Header; diff --git a/components/vc-time-picker/Panel.jsx b/components/vc-time-picker/Panel.jsx deleted file mode 100644 index d3a0d57aa..000000000 --- a/components/vc-time-picker/Panel.jsx +++ /dev/null @@ -1,229 +0,0 @@ -import moment from 'moment'; -import classNames from '../_util/classNames'; -import PropTypes from '../_util/vue-types'; -import BaseMixin from '../_util/BaseMixin'; -import Header from './Header'; -import Combobox from './Combobox'; -import { getComponent } from '../_util/props-util'; -import { defineComponent } from 'vue'; - -function noop() {} - -function generateOptions(length, disabledOptions, hideDisabledOptions, step = 1) { - const arr = []; - for (let value = 0; value < length; value += step) { - if (!disabledOptions || disabledOptions.indexOf(value) < 0 || !hideDisabledOptions) { - arr.push(value); - } - } - return arr; -} - -function toNearestValidTime(time, hourOptions, minuteOptions, secondOptions) { - const hour = hourOptions - .slice() - .sort((a, b) => Math.abs(time.hour() - a) - Math.abs(time.hour() - b))[0]; - const minute = minuteOptions - .slice() - .sort((a, b) => Math.abs(time.minute() - a) - Math.abs(time.minute() - b))[0]; - const second = secondOptions - .slice() - .sort((a, b) => Math.abs(time.second() - a) - Math.abs(time.second() - b))[0]; - return moment(`${hour}:${minute}:${second}`, 'HH:mm:ss'); -} - -const Panel = defineComponent({ - name: 'Panel', - mixins: [BaseMixin], - inheritAttrs: false, - props: { - clearText: PropTypes.string, - prefixCls: PropTypes.string.def('rc-time-picker-panel'), - defaultOpenValue: { - type: Object, - default: () => { - return moment(); - }, - }, - value: PropTypes.any, - defaultValue: PropTypes.any, - placeholder: PropTypes.string, - format: PropTypes.string, - inputReadOnly: PropTypes.looseBool.def(false), - disabledHours: PropTypes.func.def(noop), - disabledMinutes: PropTypes.func.def(noop), - disabledSeconds: PropTypes.func.def(noop), - hideDisabledOptions: PropTypes.looseBool, - // onChange: PropTypes.func, - // onEsc: PropTypes.func, - allowEmpty: PropTypes.looseBool, - showHour: PropTypes.looseBool, - showMinute: PropTypes.looseBool, - showSecond: PropTypes.looseBool, - // onClear: PropTypes.func, - use12Hours: PropTypes.looseBool.def(false), - hourStep: PropTypes.number, - minuteStep: PropTypes.number, - secondStep: PropTypes.number, - addon: PropTypes.func.def(noop), - focusOnOpen: PropTypes.looseBool, - // onKeydown: PropTypes.func, - clearIcon: PropTypes.any, - }, - data() { - return { - sValue: this.value, - selectionRange: [], - currentSelectPanel: '', - }; - }, - watch: { - value(val) { - this.setState({ - sValue: val, - }); - }, - }, - - methods: { - onChange(newValue) { - this.setState({ sValue: newValue }); - this.__emit('change', newValue); - }, - - onAmPmChange(ampm) { - this.__emit('amPmChange', ampm); - }, - - onCurrentSelectPanelChange(currentSelectPanel) { - this.setState({ currentSelectPanel }); - }, - - // https://github.com/ant-design/ant-design/issues/5829 - close() { - this.__emit('esc'); - }, - onEsc(e) { - this.__emit('esc', e); - }, - disabledHours2() { - const { use12Hours, disabledHours } = this; - let disabledOptions = disabledHours(); - if (use12Hours && Array.isArray(disabledOptions)) { - if (this.isAM()) { - disabledOptions = disabledOptions.filter(h => h < 12).map(h => (h === 0 ? 12 : h)); - } else { - disabledOptions = disabledOptions.map(h => (h === 12 ? 12 : h - 12)); - } - } - return disabledOptions; - }, - - isAM() { - const value = this.sValue || this.defaultOpenValue; - return value.hour() >= 0 && value.hour() < 12; - }, - }, - - render() { - const { - prefixCls, - placeholder, - disabledMinutes, - addon, - disabledSeconds, - hideDisabledOptions, - showHour, - showMinute, - showSecond, - format, - defaultOpenValue, - clearText, - use12Hours, - focusOnOpen, - hourStep, - minuteStep, - secondStep, - inputReadOnly, - sValue, - currentSelectPanel, - } = this; - const { class: className, onEsc = noop, onKeydown = noop } = this.$attrs; - const clearIcon = getComponent(this, 'clearIcon'); - - const disabledHourOptions = this.disabledHours2(); - const disabledMinuteOptions = disabledMinutes(sValue ? sValue.hour() : null); - const disabledSecondOptions = disabledSeconds( - sValue ? sValue.hour() : null, - sValue ? sValue.minute() : null, - ); - const hourOptions = generateOptions(24, disabledHourOptions, hideDisabledOptions, hourStep); - const minuteOptions = generateOptions( - 60, - disabledMinuteOptions, - hideDisabledOptions, - minuteStep, - ); - const secondOptions = generateOptions( - 60, - disabledSecondOptions, - hideDisabledOptions, - secondStep, - ); - const validDefaultOpenValue = toNearestValidTime( - defaultOpenValue, - hourOptions, - minuteOptions, - secondOptions, - ); - return ( -
    -
    - - {addon(this)} -
    - ); - }, -}); - -export default Panel; diff --git a/components/vc-time-picker/Select.jsx b/components/vc-time-picker/Select.jsx deleted file mode 100644 index fc9f24769..000000000 --- a/components/vc-time-picker/Select.jsx +++ /dev/null @@ -1,142 +0,0 @@ -import PropTypes from '../_util/vue-types'; -import BaseMixin from '../_util/BaseMixin'; -import classnames from '../_util/classNames'; -import { findDOMNode } from '../_util/props-util'; - -function noop() {} -const scrollTo = (element, to, duration) => { - // jump to target if duration zero - if (duration <= 0) { - requestAnimationFrame(() => { - element.scrollTop = to; - }); - return; - } - const difference = to - element.scrollTop; - const perTick = (difference / duration) * 10; - - requestAnimationFrame(() => { - element.scrollTop += perTick; - if (element.scrollTop === to) return; - scrollTo(element, to, duration - 10); - }); -}; - -const Select = { - name: 'Select', - mixins: [BaseMixin], - inheritAttrs: false, - props: { - prefixCls: PropTypes.string, - options: PropTypes.array, - selectedIndex: PropTypes.number, - type: PropTypes.string, - // onSelect: PropTypes.func, - // onMouseEnter: PropTypes.func, - }, - data() { - return { - active: false, - }; - }, - - mounted() { - this.$nextTick(() => { - // jump to selected option - this.scrollToSelected(0); - }); - }, - watch: { - selectedIndex() { - this.$nextTick(() => { - // smooth scroll to selected option - this.scrollToSelected(120); - }); - }, - }, - methods: { - onSelect(value) { - const { type } = this; - this.__emit('select', type, value); - }, - onEsc(e) { - this.__emit('esc', e); - }, - getOptions() { - const { options, selectedIndex, prefixCls } = this; - return options.map((item, index) => { - const cls = classnames({ - [`${prefixCls}-select-option-selected`]: selectedIndex === index, - [`${prefixCls}-select-option-disabled`]: item.disabled, - }); - const onClick = item.disabled - ? noop - : () => { - this.onSelect(item.value); - }; - const onKeyDown = e => { - if (e.keyCode === 13) onClick(); - else if (e.keyCode === 27) this.onEsc(); - }; - return ( -
  • - {item.value} -
  • - ); - }); - }, - - handleMouseEnter(e) { - this.setState({ active: true }); - this.__emit('mouseenter', e); - }, - - handleMouseLeave() { - this.setState({ active: false }); - }, - - scrollToSelected(duration) { - // move to selected item - const select = findDOMNode(this); - const list = this.$refs.list; - if (!list) { - return; - } - let index = this.selectedIndex; - if (index < 0) { - index = 0; - } - const topOption = list.children[index]; - const to = topOption.offsetTop; - scrollTo(select, to, duration); - }, - }, - - render() { - const { prefixCls, options, active } = this; - if (options.length === 0) { - return null; - } - - const cls = { - [`${prefixCls}-select`]: 1, - [`${prefixCls}-select-active`]: active, - }; - - return ( -
    -
      {this.getOptions()}
    -
    - ); - }, -}; - -export default Select; diff --git a/components/vc-time-picker/TimePicker.jsx b/components/vc-time-picker/TimePicker.jsx deleted file mode 100644 index acf433302..000000000 --- a/components/vc-time-picker/TimePicker.jsx +++ /dev/null @@ -1,394 +0,0 @@ -import moment from 'moment'; -import classNames from '../_util/classNames'; -import PropTypes from '../_util/vue-types'; -import BaseMixin from '../_util/BaseMixin'; -import { - initDefaultProps, - hasProp, - getComponent, - isValidElement, - getEvents, -} from '../_util/props-util'; -import { cloneElement } from '../_util/vnode'; -import Trigger from '../vc-trigger'; -import Panel from './Panel'; -import placements from './placements'; -import { defineComponent } from 'vue'; - -function noop() {} -function refFn(field, component) { - this[field] = component; -} - -export default defineComponent({ - name: 'VcTimePicker', - mixins: [BaseMixin], - inheritAttrs: false, - props: initDefaultProps( - { - prefixCls: PropTypes.string, - clearText: PropTypes.string, - value: PropTypes.any, - defaultOpenValue: { - type: Object, - default: () => { - return moment(); - }, - }, - pickerInputClass: String, - inputReadOnly: PropTypes.looseBool, - disabled: PropTypes.looseBool, - allowEmpty: PropTypes.looseBool, - defaultValue: PropTypes.any, - open: PropTypes.looseBool, - defaultOpen: PropTypes.looseBool, - align: PropTypes.object, - placement: PropTypes.any, - transitionName: PropTypes.string, - getPopupContainer: PropTypes.func, - placeholder: PropTypes.string, - format: PropTypes.string, - showHour: PropTypes.looseBool, - showMinute: PropTypes.looseBool, - showSecond: PropTypes.looseBool, - popupClassName: PropTypes.string, - popupStyle: PropTypes.object, - disabledHours: PropTypes.func, - disabledMinutes: PropTypes.func, - disabledSeconds: PropTypes.func, - hideDisabledOptions: PropTypes.looseBool, - // onChange: PropTypes.func, - // onAmPmChange: PropTypes.func, - // onOpen: PropTypes.func, - // onClose: PropTypes.func, - // onFocus: PropTypes.func, - // onBlur: PropTypes.func, - name: PropTypes.string, - autocomplete: PropTypes.string, - use12Hours: PropTypes.looseBool, - hourStep: PropTypes.number, - minuteStep: PropTypes.number, - secondStep: PropTypes.number, - focusOnOpen: PropTypes.looseBool, - // onKeyDown: PropTypes.func, - autofocus: PropTypes.looseBool, - id: PropTypes.string, - inputIcon: PropTypes.any, - clearIcon: PropTypes.any, - addon: PropTypes.func, - }, - { - clearText: 'clear', - prefixCls: 'rc-time-picker', - defaultOpen: false, - inputReadOnly: false, - popupClassName: '', - popupStyle: {}, - align: {}, - allowEmpty: true, - showHour: true, - showMinute: true, - showSecond: true, - disabledHours: noop, - disabledMinutes: noop, - disabledSeconds: noop, - hideDisabledOptions: false, - placement: 'bottomLeft', - use12Hours: false, - focusOnOpen: false, - }, - ), - data() { - this.saveInputRef = refFn.bind(this, 'picker'); - this.savePanelRef = refFn.bind(this, 'panelInstance'); - const { defaultOpen, defaultValue, open = defaultOpen, value = defaultValue } = this; - return { - sOpen: open, - sValue: value, - }; - }, - - watch: { - value(val) { - this.setState({ - sValue: val, - }); - }, - open(val) { - if (val !== undefined) { - this.setState({ - sOpen: val, - }); - } - }, - }, - mounted() { - this.$nextTick(() => { - if (this.autofocus) { - this.focus(); - } - }); - }, - methods: { - onPanelChange(value) { - this.setValue(value); - }, - - onAmPmChange(ampm) { - this.__emit('amPmChange', ampm); - }, - - onClear(event) { - event.stopPropagation(); - this.setValue(null); - this.setOpen(false); - }, - - onVisibleChange(open) { - this.setOpen(open); - }, - - onEsc() { - this.setOpen(false); - this.focus(); - }, - - onKeyDown(e) { - if (e.keyCode === 40) { - this.setOpen(true); - } - }, - onKeyDown2(e) { - this.__emit('keydown', e); - }, - - setValue(value) { - if (!hasProp(this, 'value')) { - this.setState({ - sValue: value, - }); - } - this.__emit('change', value); - }, - - getFormat() { - const { format, showHour, showMinute, showSecond, use12Hours } = this; - if (format) { - return format; - } - - if (use12Hours) { - const fmtString = [showHour ? 'h' : '', showMinute ? 'mm' : '', showSecond ? 'ss' : ''] - .filter(item => !!item) - .join(':'); - - return fmtString.concat(' a'); - } - - return [showHour ? 'HH' : '', showMinute ? 'mm' : '', showSecond ? 'ss' : ''] - .filter(item => !!item) - .join(':'); - }, - - getPanelElement() { - const { - prefixCls, - placeholder, - disabledHours, - addon, - disabledMinutes, - disabledSeconds, - hideDisabledOptions, - inputReadOnly, - showHour, - showMinute, - showSecond, - defaultOpenValue, - clearText, - use12Hours, - focusOnOpen, - onKeyDown2, - hourStep, - minuteStep, - secondStep, - sValue, - } = this; - const clearIcon = getComponent(this, 'clearIcon'); - return ( - - ); - }, - - getPopupClassName() { - const { showHour, showMinute, showSecond, use12Hours, prefixCls, popupClassName } = this; - - let selectColumnCount = 0; - if (showHour) { - selectColumnCount += 1; - } - if (showMinute) { - selectColumnCount += 1; - } - if (showSecond) { - selectColumnCount += 1; - } - if (use12Hours) { - selectColumnCount += 1; - } - // Keep it for old compatibility - return classNames( - popupClassName, - { - [`${prefixCls}-panel-narrow`]: (!showHour || !showMinute || !showSecond) && !use12Hours, - }, - `${prefixCls}-panel-column-${selectColumnCount}`, - ); - }, - - setOpen(open) { - if (this.sOpen !== open) { - if (!hasProp(this, 'open')) { - this.setState({ sOpen: open }); - } - if (open) { - this.__emit('open', { open }); - } else { - this.__emit('close', { open }); - } - } - }, - - focus() { - this.picker.focus(); - }, - - blur() { - this.picker.blur(); - }, - onFocus(e) { - this.__emit('focus', e); - }, - onBlur(e) { - this.__emit('blur', e); - }, - renderClearButton() { - const { sValue } = this; - const { prefixCls, allowEmpty, clearText, disabled } = this.$props; - if (!allowEmpty || !sValue || disabled) { - return null; - } - const clearIcon = getComponent(this, 'clearIcon'); - if (isValidElement(clearIcon)) { - const { onClick } = getEvents(clearIcon) || {}; - return cloneElement(clearIcon, { - onClick: (...args) => { - if (onClick) onClick(...args); - this.onClear(...args); - }, - }); - } - - return ( - - {clearIcon || } - - ); - }, - }, - - render() { - const { - prefixCls, - placeholder, - placement, - align, - id, - disabled, - transitionName, - getPopupContainer, - name, - autocomplete, - autofocus, - sOpen, - sValue, - onFocus, - onBlur, - popupStyle, - pickerInputClass, - } = this; - const { class: className, style } = this.$attrs; - const popupClassName = this.getPopupClassName(); - const inputIcon = getComponent(this, 'inputIcon'); - return ( - - - - {inputIcon || } - {this.renderClearButton()} - - - ); - }, -}); diff --git a/components/vc-time-picker/assets/index.less b/components/vc-time-picker/assets/index.less deleted file mode 100644 index 3f819b097..000000000 --- a/components/vc-time-picker/assets/index.less +++ /dev/null @@ -1,44 +0,0 @@ -@prefixClass: rc-time-picker; - -.@{prefixClass} { - display: inline-block; - position: relative; - box-sizing: border-box; - * { - box-sizing: border-box; - } - - &-clear { - position: absolute; - right: 6px; - cursor: pointer; - overflow: hidden; - width: 20px; - height: 20px; - text-align: center; - line-height: 20px; - top: 3px; - margin: 0; - - &-icon:after { - content: 'x'; - font-size: 12px; - font-style: normal; - color: #aaa; - display: inline-block; - line-height: 1; - height: 20px; - width: 20px; - transition: color 0.3s ease; - } - - &-icon:hover:after { - color: #666; - } - } -} - -@import './index/Picker'; -@import './index/Panel'; -@import './index/Header'; -@import './index/Select'; diff --git a/components/vc-time-picker/assets/index/Header.less b/components/vc-time-picker/assets/index/Header.less deleted file mode 100644 index b107436ac..000000000 --- a/components/vc-time-picker/assets/index/Header.less +++ /dev/null @@ -1,22 +0,0 @@ -.@{prefixClass}-panel { - &-input { - margin: 0; - padding: 0; - width: 100%; - cursor: auto; - line-height: 1.5; - outline: 0; - border: 1px solid transparent; - - &-wrap { - box-sizing: border-box; - position: relative; - padding: 6px; - border-bottom: 1px solid #e9e9e9; - } - - &-invalid { - border-color: red; - } - } -} diff --git a/components/vc-time-picker/assets/index/Panel.less b/components/vc-time-picker/assets/index/Panel.less deleted file mode 100644 index 68e6c8e79..000000000 --- a/components/vc-time-picker/assets/index/Panel.less +++ /dev/null @@ -1,29 +0,0 @@ -.@{prefixClass}-panel { - z-index: 1070; - width: 170px; - position: absolute; - box-sizing: border-box; - - * { - box-sizing: border-box; - } - - &-inner { - display: inline-block; - position: relative; - outline: none; - list-style: none; - font-size: 12px; - text-align: left; - background-color: #fff; - border-radius: 4px; - box-shadow: 0 1px 5px #ccc; - background-clip: padding-box; - border: 1px solid #ccc; - line-height: 1.5; - } - - &-narrow { - max-width: 113px; - } -} diff --git a/components/vc-time-picker/assets/index/Picker.less b/components/vc-time-picker/assets/index/Picker.less deleted file mode 100644 index c2d8d382b..000000000 --- a/components/vc-time-picker/assets/index/Picker.less +++ /dev/null @@ -1,25 +0,0 @@ -.@{prefixClass} { - &-input { - width: 100%; - position: relative; - display: inline-block; - padding: 4px 7px; - height: 28px; - cursor: text; - font-size: 12px; - line-height: 1.5; - color: #666; - background-color: #fff; - background-image: none; - border: 1px solid #d9d9d9; - border-radius: 4px; - transition: border 0.2s cubic-bezier(0.645, 0.045, 0.355, 1), - background 0.2s cubic-bezier(0.645, 0.045, 0.355, 1), - box-shadow 0.2s cubic-bezier(0.645, 0.045, 0.355, 1); - &[disabled] { - color: #ccc; - background: #f7f7f7; - cursor: not-allowed; - } - } -} diff --git a/components/vc-time-picker/assets/index/Select.less b/components/vc-time-picker/assets/index/Select.less deleted file mode 100644 index f11d1e9bd..000000000 --- a/components/vc-time-picker/assets/index/Select.less +++ /dev/null @@ -1,62 +0,0 @@ -.@{prefixClass}-panel-select { - float: left; - font-size: 12px; - border: 1px solid #e9e9e9; - border-width: 0 1px; - margin-left: -1px; - box-sizing: border-box; - width: 56px; - max-height: 144px; - overflow-y: auto; - position: relative; // Fix chrome weird render bug - - &-active { - overflow-y: auto; - } - - &:first-child { - border-left: 0; - margin-left: 0; - } - - &:last-child { - border-right: 0; - } - - ul { - list-style: none; - box-sizing: border-box; - margin: 0; - padding: 0; - width: 100%; - } - - li { - list-style: none; - margin: 0; - padding: 0 0 0 16px; - width: 100%; - height: 24px; - line-height: 24px; - text-align: left; - cursor: pointer; - user-select: none; - - &:hover { - background: #edfaff; - } - } - - li&-option-selected { - background: #f7f7f7; - font-weight: bold; - } - - li&-option-disabled { - color: #ccc; - &:hover { - background: transparent; - cursor: not-allowed; - } - } -} diff --git a/components/vc-time-picker/index.js b/components/vc-time-picker/index.js deleted file mode 100644 index bd9700cb4..000000000 --- a/components/vc-time-picker/index.js +++ /dev/null @@ -1,2 +0,0 @@ -// based on rc-time-picker 3.7.3 -export { default } from './TimePicker'; diff --git a/components/vc-time-picker/placements.js b/components/vc-time-picker/placements.js deleted file mode 100644 index 676028676..000000000 --- a/components/vc-time-picker/placements.js +++ /dev/null @@ -1,35 +0,0 @@ -const autoAdjustOverflow = { - adjustX: 1, - adjustY: 1, -}; - -const targetOffset = [0, 0]; - -const placements = { - bottomLeft: { - points: ['tl', 'tl'], - overflow: autoAdjustOverflow, - offset: [0, -3], - targetOffset, - }, - bottomRight: { - points: ['tr', 'tr'], - overflow: autoAdjustOverflow, - offset: [0, -3], - targetOffset, - }, - topRight: { - points: ['br', 'br'], - overflow: autoAdjustOverflow, - offset: [0, 3], - targetOffset, - }, - topLeft: { - points: ['bl', 'bl'], - overflow: autoAdjustOverflow, - offset: [0, 3], - targetOffset, - }, -}; - -export default placements; diff --git a/components/vc-tooltip/src/Tooltip.tsx b/components/vc-tooltip/src/Tooltip.tsx index e49cc36c9..982cb2aae 100644 --- a/components/vc-tooltip/src/Tooltip.tsx +++ b/components/vc-tooltip/src/Tooltip.tsx @@ -13,7 +13,7 @@ export default defineComponent({ defaultVisible: PropTypes.looseBool, visible: PropTypes.looseBool, placement: PropTypes.string.def('right'), - transitionName: PropTypes.oneOfType([PropTypes.string, PropTypes.object]), + transitionName: PropTypes.string, animation: PropTypes.any, afterVisibleChange: PropTypes.func.def(() => {}), overlay: PropTypes.any, diff --git a/components/vc-trigger/LazyRenderBox.jsx b/components/vc-trigger/LazyRenderBox.jsx deleted file mode 100644 index 5cefd4447..000000000 --- a/components/vc-trigger/LazyRenderBox.jsx +++ /dev/null @@ -1,27 +0,0 @@ -import { Text } from 'vue'; -import PropTypes from '../_util/vue-types'; -import { getSlot } from '../_util/props-util'; - -export default { - name: 'LazyRenderBox', - props: { - visible: PropTypes.looseBool, - hiddenClassName: PropTypes.string, - }, - render() { - const { hiddenClassName } = this.$props; - const child = getSlot(this); - if ( - hiddenClassName || - (child && child.length > 1) || - (child && child[0] && child[0].type === Text) - ) { - // const cls = ''; - // if (!visible && hiddenClassName) { - // // cls += ` ${hiddenClassName}` - // } - return
    {child}
    ; - } - return child && child[0]; - }, -}; diff --git a/components/vc-trigger/Popup.jsx b/components/vc-trigger/Popup.jsx deleted file mode 100644 index 7c49fa836..000000000 --- a/components/vc-trigger/Popup.jsx +++ /dev/null @@ -1,317 +0,0 @@ -import PropTypes from '../_util/vue-types'; -import Align from '../vc-align'; -import PopupInner from './PopupInner'; -import LazyRenderBox from './LazyRenderBox'; -import BaseMixin from '../_util/BaseMixin'; -import { saveRef } from './utils'; -import { splitAttrs, findDOMNode } from '../_util/props-util'; -import { getTransitionProps, Transition } from '../_util/transition'; - -export default { - name: 'VCTriggerPopup', - mixins: [BaseMixin], - inheritAttrs: false, - props: { - visible: PropTypes.looseBool, - getClassNameFromAlign: PropTypes.func, - getRootDomNode: PropTypes.func, - align: PropTypes.any, - destroyPopupOnHide: PropTypes.looseBool, - prefixCls: PropTypes.string, - getContainer: PropTypes.func, - transitionName: PropTypes.string, - animation: PropTypes.any, - maskAnimation: PropTypes.string, - maskTransitionName: PropTypes.string, - mask: PropTypes.looseBool, - zIndex: PropTypes.number, - popupClassName: PropTypes.any, - popupStyle: PropTypes.object.def(() => ({})), - stretch: PropTypes.string, - point: PropTypes.shape({ - pageX: PropTypes.number, - pageY: PropTypes.number, - }).loose, - }, - data() { - this.domEl = null; - this.currentAlignClassName = undefined; - this.transitionProps = {}; - this.savePopupRef = saveRef.bind(this, 'popupInstance'); - this.saveAlignRef = saveRef.bind(this, 'alignInstance'); - return { - // Used for stretch - stretchChecked: false, - targetWidth: undefined, - targetHeight: undefined, - }; - }, - mounted() { - this.$nextTick(() => { - this.rootNode = this.getPopupDomNode(); - this.setStretchSize(); - }); - }, - // 如添加会导致动画失效,如放开会导致快速输入时闪动 https://github.com/vueComponent/ant-design-vue/issues/1327, - // 目前方案是保留动画,闪动问题(动画多次执行)进一步定位 - // beforeUpdate() { - // if (this.domEl && this.domEl.rcEndListener) { - // this.domEl.rcEndListener(); - // this.domEl = null; - // } - // }, - updated() { - this.$nextTick(() => { - this.setStretchSize(); - }); - }, - methods: { - onAlign(popupDomNode, align) { - const props = this.$props; - const currentAlignClassName = props.getClassNameFromAlign(align); - // FIX: https://github.com/react-component/trigger/issues/56 - // FIX: https://github.com/react-component/tooltip/issues/79 - if (this.currentAlignClassName !== currentAlignClassName) { - this.currentAlignClassName = currentAlignClassName; - popupDomNode.className = this.getClassName(currentAlignClassName, popupDomNode.className); - } - const { onaAlign } = this.$attrs; - onaAlign && onaAlign(popupDomNode, align); - }, - - // Record size if stretch needed - setStretchSize() { - const { stretch, getRootDomNode, visible } = this.$props; - const { stretchChecked, targetHeight, targetWidth } = this.$data; - - if (!stretch || !visible) { - if (stretchChecked) { - this.setState({ stretchChecked: false }); - } - return; - } - - const $ele = getRootDomNode(); - if (!$ele) return; - - const height = $ele.offsetHeight; - const width = $ele.offsetWidth; - - if (targetHeight !== height || targetWidth !== width || !stretchChecked) { - this.setState({ - stretchChecked: true, - targetHeight: height, - targetWidth: width, - }); - } - }, - - getPopupDomNode() { - return findDOMNode(this.popupInstance); - }, - - getTargetElement() { - return this.$props.getRootDomNode(); - }, - - // `target` on `rc-align` can accept as a function to get the bind element or a point. - // ref: https://www.npmjs.com/package/rc-align - getAlignTarget() { - const { point } = this.$props; - if (point) { - return point; - } - return this.getTargetElement; - }, - - getMaskTransitionName() { - const props = this.$props; - let transitionName = props.maskTransitionName; - const animation = props.maskAnimation; - if (!transitionName && animation) { - transitionName = `${props.prefixCls}-${animation}`; - } - return transitionName; - }, - - getTransitionName() { - const props = this.$props; - let transitionName = props.transitionName; - const animation = props.animation; - if (!transitionName) { - if (typeof animation === 'string') { - transitionName = `${animation}`; - } else if (animation && animation.props && animation.props.name) { - transitionName = animation.props.name; - } - } - return transitionName; - }, - - getClassName(currentAlignClassName, originClassName = '') { - // 保留动画 class - const enterActiveClass = []; - if (this.transitionProps) { - Object.keys(this.transitionProps).forEach(k => { - if (typeof this.transitionProps[k] === 'string') { - enterActiveClass.push(...this.transitionProps[k].split(' ')); - } - }); - } - const classNames = originClassName - .split(' ') - .filter(c => enterActiveClass.indexOf(c) !== -1) - .join(' '); - return `${this.$props.prefixCls} ${this.$attrs.class || ''} ${ - this.$props.popupClassName - } ${currentAlignClassName} ${classNames}`; - }, - getPopupElement() { - const { savePopupRef } = this; - const { $props: props, $attrs, $slots, getTransitionName } = this; - const { stretchChecked, targetHeight, targetWidth } = this.$data; - const { style = {} } = $attrs; - const onEvents = splitAttrs($attrs).onEvents; - const { - align, - visible, - prefixCls, - animation, - popupStyle, - getClassNameFromAlign, - destroyPopupOnHide, - stretch, - } = props; - const className = this.getClassName( - this.currentAlignClassName || getClassNameFromAlign(align), - ); - // const hiddenClassName = `${prefixCls}-hidden` - if (!visible) { - this.currentAlignClassName = null; - } - const sizeStyle = {}; - if (stretch) { - // Stretch with target - if (stretch.indexOf('height') !== -1) { - sizeStyle.height = typeof targetHeight === 'number' ? `${targetHeight}px` : targetHeight; - } else if (stretch.indexOf('minHeight') !== -1) { - sizeStyle.minHeight = - typeof targetHeight === 'number' ? `${targetHeight}px` : targetHeight; - } - if (stretch.indexOf('width') !== -1) { - sizeStyle.width = typeof targetWidth === 'number' ? `${targetWidth}px` : targetWidth; - } else if (stretch.indexOf('minWidth') !== -1) { - sizeStyle.minWidth = typeof targetWidth === 'number' ? `${targetWidth}px` : targetWidth; - } - // Delay force align to makes ui smooth - if (!stretchChecked) { - // sizeStyle.visibility = 'hidden' - setTimeout(() => { - if (this.alignInstance) { - this.alignInstance.forceAlign(); - } - }, 0); - } - } - const popupInnerProps = { - prefixCls, - visible, - // hiddenClassName, - class: className, - ...onEvents, - ref: savePopupRef, - style: { ...sizeStyle, ...popupStyle, ...style, ...this.getZIndexStyle() }, - }; - - const transitionName = getTransitionName(); - let useTransition = !!transitionName; - let transitionProps = getTransitionProps(transitionName); - if (typeof animation === 'object') { - useTransition = true; - transitionProps = { ...transitionProps, ...animation }; - } - if (!useTransition) { - transitionProps = {}; - } - this.transitionProps = transitionProps; - if (destroyPopupOnHide) { - return ( - - {visible ? ( - - {$slots.default?.()} - - ) : null} - - ); - } - return ( - - - {$slots.default?.()} - - - ); - }, - - getZIndexStyle() { - const style = {}; - const props = this.$props; - if (props.zIndex !== undefined) { - style.zIndex = props.zIndex; - } - return style; - }, - - getMaskElement() { - const props = this.$props; - let maskElement = null; - if (props.mask) { - const maskTransition = this.getMaskTransitionName(); - maskElement = ( - - ); - if (maskTransition) { - maskElement = ( - - {maskElement} - - ); - } - } - return maskElement; - }, - }, - - render() { - const { getMaskElement, getPopupElement } = this; - return ( -
    - {getMaskElement()} - {getPopupElement()} -
    - ); - }, -}; diff --git a/components/vc-trigger/Popup/Mask.tsx b/components/vc-trigger/Popup/Mask.tsx new file mode 100644 index 000000000..2f48a5485 --- /dev/null +++ b/components/vc-trigger/Popup/Mask.tsx @@ -0,0 +1,39 @@ +import { Transition } from 'vue'; +import type { TransitionNameType, AnimationType } from '../interface'; +import { getMotion } from '../utils/motionUtil'; + +export interface MaskProps { + prefixCls: string; + visible?: boolean; + zIndex?: number; + mask?: boolean; + maskAnimation?: AnimationType; + maskTransitionName?: TransitionNameType; +} + +export default function Mask(props: MaskProps) { + const { prefixCls, visible, zIndex, mask, maskAnimation, maskTransitionName } = props; + + if (!mask) { + return null; + } + + let motion = {}; + + if (maskTransitionName || maskAnimation) { + motion = { + ...getMotion({ + prefixCls, + transitionName: maskTransitionName, + animation: maskAnimation, + }), + }; + } + + return ( + +
    + + ); +} +Mask.displayName = 'Mask'; diff --git a/components/vc-trigger/Popup/MobilePopupInner.tsx b/components/vc-trigger/Popup/MobilePopupInner.tsx new file mode 100644 index 000000000..c5b3117f8 --- /dev/null +++ b/components/vc-trigger/Popup/MobilePopupInner.tsx @@ -0,0 +1,58 @@ +import type { CSSProperties } from 'vue'; +import { defineComponent, ref, Transition } from 'vue'; +import { flattenChildren } from '../../_util/props-util'; +import classNames from '../../_util/classNames'; +import type { MobilePopupProps } from './interface'; +import { mobileProps } from './interface'; + +export default defineComponent({ + name: 'MobilePopupInner', + inheritAttrs: false, + props: mobileProps, + emits: ['mouseenter', 'mouseleave', 'mousedown', 'touchstart', 'align'], + setup(props, { expose, slots }) { + const elementRef = ref(); + + expose({ + forceAlign: () => {}, + getElement: () => elementRef.value, + }); + + return () => { + const { + zIndex, + visible, + prefixCls, + mobile: { popupClassName, popupStyle, popupMotion = {}, popupRender } = {}, + } = props as MobilePopupProps; + // ======================== Render ======================== + const mergedStyle: CSSProperties = { + zIndex, + ...popupStyle, + }; + + let childNode: any = flattenChildren(slots.default?.()); + + // Wrapper when multiple children + if (childNode.length > 1) { + childNode =
    {childNode}
    ; + } + + // Mobile support additional render + if (popupRender) { + childNode = popupRender(childNode); + } + + const mergedClassName = classNames(prefixCls, popupClassName); + return ( + + {visible ? ( +
    + {childNode} +
    + ) : null} +
    + ); + }; + }, +}); diff --git a/components/vc-trigger/Popup/PopupInner.tsx b/components/vc-trigger/Popup/PopupInner.tsx new file mode 100644 index 000000000..8c25c793b --- /dev/null +++ b/components/vc-trigger/Popup/PopupInner.tsx @@ -0,0 +1,195 @@ +import type { AlignType } from '../interface'; +import useVisibleStatus from './useVisibleStatus'; +import useStretchStyle from './useStretchStyle'; +import type { CSSProperties } from 'vue'; +import { + computed, + defineComponent, + nextTick, + ref, + toRef, + Transition, + watch, + withModifiers, +} from 'vue'; +import type { RefAlign } from '../../vc-align/Align'; +import Align from '../../vc-align/Align'; +import { getMotion } from '../utils/motionUtil'; +import { flattenChildren } from '../../_util/props-util'; +import classNames from '../../_util/classNames'; +import type { PopupInnerProps } from './interface'; +import { innerProps } from './interface'; +import { getTransitionProps } from '../../_util/transition'; +import supportsPassive from '../../_util/supportsPassive'; + +export default defineComponent({ + name: 'PopupInner', + inheritAttrs: false, + props: innerProps, + emits: ['mouseenter', 'mouseleave', 'mousedown', 'touchstart', 'align'], + setup(props, { expose, attrs, slots }) { + const alignRef = ref(); + const elementRef = ref(); + const alignedClassName = ref(); + // ======================= Measure ======================== + const [stretchStyle, measureStretchStyle] = useStretchStyle(toRef(props, 'stretch')); + + const doMeasure = () => { + if (props.stretch) { + measureStretchStyle(props.getRootDomNode()); + } + }; + + // ======================== Status ======================== + const [status, goNextStatus] = useVisibleStatus(toRef(props, 'visible'), doMeasure); + + // ======================== Aligns ======================== + const prepareResolveRef = ref<(value?: unknown) => void>(); + + // `target` on `rc-align` can accept as a function to get the bind element or a point. + // ref: https://www.npmjs.com/package/rc-align + const getAlignTarget = () => { + if (props.point) { + return props.point; + } + return props.getRootDomNode; + }; + + const forceAlign = () => { + alignRef.value?.forceAlign(); + }; + + const onInternalAlign = (popupDomNode: HTMLElement, matchAlign: AlignType) => { + const nextAlignedClassName = props.getClassNameFromAlign(matchAlign); + const preAlignedClassName = alignedClassName.value; + if (alignedClassName.value !== nextAlignedClassName) { + alignedClassName.value = nextAlignedClassName; + } + if (status.value === 'align') { + // Repeat until not more align needed + if (preAlignedClassName !== nextAlignedClassName) { + nextTick(() => { + forceAlign(); + }); + } else { + goNextStatus(() => { + prepareResolveRef.value?.(); + }); + } + + props.onAlign?.(popupDomNode, matchAlign); + } + }; + + // ======================== Motion ======================== + const motion = computed(() => { + const m = { ...getMotion(props) }; + ['onAfterEnter', 'onAfterLeave'].forEach(eventName => { + m[eventName] = () => { + goNextStatus(); + }; + }); + return m; + }); + + const onShowPrepare = () => { + return new Promise(resolve => { + prepareResolveRef.value = resolve; + }); + }; + + watch( + [toRef(motion.value, 'name'), status], + () => { + if (!motion.value.name && status.value === 'motion') { + goNextStatus(); + } + }, + { immediate: true }, + ); + + expose({ + forceAlign, + getElement: () => elementRef.value, + }); + return () => { + const { + zIndex, + visible, + align, + prefixCls, + destroyPopupOnHide, + onMouseenter, + onMouseleave, + onTouchstart, + onMousedown, + } = props as PopupInnerProps; + const statusValue = status.value; + // ======================== Render ======================== + const mergedStyle: CSSProperties = { + ...stretchStyle.value, + zIndex, + opacity: statusValue === 'motion' || statusValue === 'stable' || !visible ? undefined : 0, + pointerEvents: statusValue === 'stable' ? undefined : 'none', + ...(attrs.style as object), + }; + + // Align statusValue + let alignDisabled = true; + if (align?.points && (statusValue === 'align' || statusValue === 'stable')) { + alignDisabled = false; + } + + let childNode: any = flattenChildren(slots.default?.()); + + // Wrapper when multiple children + if (childNode.length > 1) { + childNode =
    {childNode}
    ; + } + const mergedClassName = classNames(prefixCls, attrs.class, alignedClassName.value); + const transitionProps = getTransitionProps(motion.value.name, motion.value); + return ( + { + return !destroyPopupOnHide || visible ? ( + ( +
    + {childNode} +
    + ), + }} + >
    + ) : null; + }, + }} + >
    + ); + }; + }, +}); diff --git a/components/vc-trigger/Popup/index.tsx b/components/vc-trigger/Popup/index.tsx new file mode 100644 index 000000000..4e482cf81 --- /dev/null +++ b/components/vc-trigger/Popup/index.tsx @@ -0,0 +1,54 @@ +import { defineComponent, ref, watch } from 'vue'; +import { popupProps } from './interface'; +import Mask from './Mask'; +import MobilePopupInner from './MobilePopupInner'; +import PopupInner from './PopupInner'; + +export default defineComponent({ + name: 'Popup', + inheritAttrs: false, + props: popupProps, + setup(props, { attrs, slots, expose }) { + const innerVisible = ref(false); + const inMobile = ref(false); + const popupRef = ref(); + watch( + [() => props.visible, () => props.mobile], + () => { + innerVisible.value = props.visible; + if (props.visible && props.mobile) { + inMobile.value = true; + } + }, + { immediate: true, flush: 'post' }, + ); + expose({ + forceAlign: () => { + popupRef.value?.forceAlign(); + }, + getElement: () => { + popupRef.value?.getElement(); + }, + }); + return () => { + const cloneProps = { ...props, ...attrs, visible: innerVisible.value }; + const popupNode = inMobile.value ? ( + + ) : ( + + ); + + return ( +
    + + {popupNode} +
    + ); + }; + }, +}); diff --git a/components/vc-trigger/Popup/interface.ts b/components/vc-trigger/Popup/interface.ts new file mode 100644 index 000000000..1de9cf024 --- /dev/null +++ b/components/vc-trigger/Popup/interface.ts @@ -0,0 +1,55 @@ +import type { Point, AlignType, StretchType, MobileConfig } from '../interface'; +import type { ExtractPropTypes, PropType } from 'vue'; + +export const innerProps = { + visible: Boolean, + + prefixCls: String, + zIndex: Number, + + destroyPopupOnHide: Boolean, + forceRender: Boolean, + + // Legacy Motion + animation: String, + transitionName: String, + + // Measure + stretch: { type: String as PropType }, + + // Align + align: { type: Object as PropType }, + point: { type: Object as PropType }, + getRootDomNode: { type: Function as PropType<() => HTMLElement> }, + getClassNameFromAlign: { type: Function as PropType<(align: AlignType) => string> }, + onMouseenter: { type: Function as PropType<(align: MouseEvent) => void> }, + onMouseleave: { type: Function as PropType<(align: MouseEvent) => void> }, + onMousedown: { type: Function as PropType<(align: MouseEvent) => void> }, + onTouchstart: { type: Function as PropType<(align: MouseEvent) => void> }, +}; +export type PopupInnerProps = Partial> & { + align?: AlignType; +}; + +export const mobileProps = { + ...innerProps, + mobile: { type: Object as PropType }, +}; + +export type MobilePopupProps = Partial> & { + align?: AlignType; + mobile: MobileConfig; +}; + +export const popupProps = { + ...innerProps, + mask: Boolean, + mobile: { type: Object as PropType }, + maskAnimation: String, + maskTransitionName: String, +}; + +export type PopupProps = Partial> & { + align?: AlignType; + mobile: MobileConfig; +}; diff --git a/components/vc-trigger/Popup/useStretchStyle.ts b/components/vc-trigger/Popup/useStretchStyle.ts new file mode 100644 index 000000000..c808ced27 --- /dev/null +++ b/components/vc-trigger/Popup/useStretchStyle.ts @@ -0,0 +1,41 @@ +import type { ComputedRef, CSSProperties, Ref } from 'vue'; +import { computed, ref } from 'vue'; +import type { StretchType } from '../interface'; + +export default ( + stretch?: Ref, +): [ComputedRef, (element: HTMLElement) => void] => { + const targetSize = ref({ width: 0, height: 0 }); + + function measureStretch(element: HTMLElement) { + targetSize.value = { + width: element.offsetWidth, + height: element.offsetHeight, + }; + } + + // Merge stretch style + const style = computed(() => { + const sizeStyle: CSSProperties = {}; + + if (stretch.value) { + const { width, height } = targetSize.value; + + // Stretch with target + if (stretch.value.indexOf('height') !== -1 && height) { + sizeStyle.height = `${height}px`; + } else if (stretch.value.indexOf('minHeight') !== -1 && height) { + sizeStyle.minHeight = `${height}px`; + } + if (stretch.value.indexOf('width') !== -1 && width) { + sizeStyle.width = `${width}px`; + } else if (stretch.value.indexOf('minWidth') !== -1 && width) { + sizeStyle.minWidth = `${width}px`; + } + } + + return sizeStyle; + }); + + return [style, measureStretch]; +}; diff --git a/components/vc-trigger/Popup/useVisibleStatus.ts b/components/vc-trigger/Popup/useVisibleStatus.ts new file mode 100644 index 000000000..abcbc0356 --- /dev/null +++ b/components/vc-trigger/Popup/useVisibleStatus.ts @@ -0,0 +1,96 @@ +import type { Ref } from 'vue'; +import { nextTick } from 'vue'; +import { onBeforeUnmount } from 'vue'; +import { ref, watch } from 'vue'; +import raf from '../../_util/raf'; + +/** + * Popup should follow the steps for each component work correctly: + * measure - check for the value stretch size + * align - let component align the position + * aligned - re-align again in case additional className changed the size + * afterAlign - choice next step is trigger motion or finished + * beforeMotion - should reset motion to invisible so that CSSMotion can do normal motion + * motion - play the motion + * stable - everything is done + */ +type PopupStatus = null | 'measure' | 'align' | 'aligned' | 'motion' | 'stable'; + +type Func = () => void; + +const StatusQueue: PopupStatus[] = ['measure', 'align', null, 'motion']; + +export default ( + visible: Ref, + doMeasure: Func, +): [Ref, (callback?: () => void) => void] => { + const status = ref(null); + const rafRef = ref(); + const destroyRef = ref(false); + function setStatus(nextStatus: PopupStatus) { + if (!destroyRef.value) { + status.value = nextStatus; + } + } + + function cancelRaf() { + raf.cancel(rafRef.value); + } + + function goNextStatus(callback?: () => void) { + cancelRaf(); + rafRef.value = raf(() => { + // Only align should be manually trigger + let newStatus = status.value; + switch (status.value) { + case 'align': + newStatus = 'motion'; + break; + case 'motion': + newStatus = 'stable'; + break; + default: + } + setStatus(newStatus); + + callback?.(); + }); + } + + watch( + visible, + () => { + setStatus('measure'); + }, + { immediate: true, flush: 'post' }, + ); + // Go next status + watch( + status, + () => { + switch (status.value) { + case 'measure': + doMeasure(); + break; + default: + } + + if (status.value) { + nextTick(() => { + const index = StatusQueue.indexOf(status.value); + const nextStatus = StatusQueue[index + 1]; + if (nextStatus && index !== -1) { + setStatus(nextStatus); + } + }); + } + }, + { immediate: true, flush: 'post' }, + ); + onBeforeUnmount(() => { + destroyRef.value = true; + cancelRaf(); + }); + + return [status, goNextStatus]; +}; diff --git a/components/vc-trigger/PopupInner.jsx b/components/vc-trigger/PopupInner.jsx deleted file mode 100644 index c44d1a189..000000000 --- a/components/vc-trigger/PopupInner.jsx +++ /dev/null @@ -1,21 +0,0 @@ -import PropTypes from '../_util/vue-types'; -import LazyRenderBox from './LazyRenderBox'; - -export default { - props: { - hiddenClassName: PropTypes.string.def(''), - prefixCls: PropTypes.string, - visible: PropTypes.looseBool, - }, - render() { - const { prefixCls, visible, hiddenClassName } = this.$props; - - return ( -
    - - {this.$slots.default?.()} - -
    - ); - }, -}; diff --git a/components/vc-trigger/Trigger.jsx b/components/vc-trigger/Trigger.tsx similarity index 76% rename from components/vc-trigger/Trigger.jsx rename to components/vc-trigger/Trigger.tsx index cbc2f14e4..57e36354e 100644 --- a/components/vc-trigger/Trigger.jsx +++ b/components/vc-trigger/Trigger.tsx @@ -1,6 +1,8 @@ -import { defineComponent, inject, provide } from 'vue'; +import type { HTMLAttributes } from 'vue'; +import { computed, defineComponent, inject, provide, ref } from 'vue'; import PropTypes from '../_util/vue-types'; import contains from '../vc-util/Dom/contains'; +import raf from '../_util/raf'; import { hasProp, getComponent, @@ -11,20 +13,23 @@ import { } from '../_util/props-util'; import { requestAnimationTimeout, cancelAnimationTimeout } from '../_util/requestAnimationTimeout'; import addEventListener from '../vc-util/Dom/addEventListener'; -import warning from '../_util/warning'; import Popup from './Popup'; -import { getAlignFromPlacement, getAlignPopupClassName, noop } from './utils'; +import { getAlignFromPlacement, getAlignPopupClassName } from './utils/alignUtil'; import BaseMixin from '../_util/BaseMixin'; import Portal from '../_util/Portal'; import classNames from '../_util/classNames'; import { cloneElement } from '../_util/vnode'; import supportsPassive from '../_util/supportsPassive'; +function noop() {} function returnEmptyString() { return ''; } -function returnDocument() { +function returnDocument(element) { + if (element) { + return element.ownerDocument; + } return window.document; } const ALL_HANDLERS = [ @@ -55,7 +60,7 @@ export default defineComponent({ popupClassName: PropTypes.string.def(''), popupPlacement: PropTypes.string, builtinPlacements: PropTypes.object, - popupTransitionName: PropTypes.oneOfType([PropTypes.string, PropTypes.object]), + popupTransitionName: PropTypes.string, popupAnimation: PropTypes.any, mouseEnterDelay: PropTypes.number.def(0), mouseLeaveDelay: PropTypes.number.def(0.1), @@ -72,37 +77,58 @@ export default defineComponent({ popupAlign: PropTypes.object.def(() => ({})), popupVisible: PropTypes.looseBool, defaultPopupVisible: PropTypes.looseBool.def(false), - maskTransitionName: PropTypes.oneOfType([PropTypes.string, PropTypes.object]), + maskTransitionName: PropTypes.string, maskAnimation: PropTypes.string, stretch: PropTypes.string, alignPoint: PropTypes.looseBool, // Maybe we can support user pass position in the future + autoDestroy: PropTypes.looseBool.def(false), + mobile: Object, + getTriggerDOMNode: Function, }, - setup() { + setup(props) { + const align = computed(() => { + const { popupPlacement, popupAlign, builtinPlacements } = props; + if (popupPlacement && builtinPlacements) { + return getAlignFromPlacement(builtinPlacements, popupPlacement, popupAlign); + } + return popupAlign; + }); return { - vcTriggerContext: inject('vcTriggerContext', {}), - savePopupRef: inject('savePopupRef', noop), - dialogContext: inject('dialogContext', null), + vcTriggerContext: inject( + 'vcTriggerContext', + {} as { onPopupMouseDown?: (...args: any[]) => void }, + ), + popupRef: ref(null), + triggerRef: ref(null), + align, + focusTime: null, + clickOutsideHandler: null, + contextmenuOutsideHandler1: null, + contextmenuOutsideHandler2: null, + touchOutsideHandler: null, + attachId: null, + delayTimer: null, + hasPopupMouseDown: false, + preClickTime: null, + preTouchTime: null, + mouseDownTimeout: null, + childOriginEvents: {}, }; }, data() { const props = this.$props; let popupVisible; - if (hasProp(this, 'popupVisible')) { + if (this.popupVisible !== undefined) { popupVisible = !!props.popupVisible; } else { popupVisible = !!props.defaultPopupVisible; } ALL_HANDLERS.forEach(h => { - this[`fire${h}`] = e => { - this.fireEvents(h, e); + (this as any)[`fire${h}`] = e => { + (this as any).fireEvents(h, e); }; }); - this._component = null; - this.focusTime = null; - this.clickOutsideHandler = null; - this.contextmenuOutsideHandler1 = null; - this.contextmenuOutsideHandler2 = null; - this.touchOutsideHandler = null; + return { prevPopupVisible: popupVisible, sPopupVisible: popupVisible, @@ -118,7 +144,9 @@ export default defineComponent({ }, }, created() { - provide('vcTriggerContext', this); + provide('vcTriggerContext', { + onPopupMouseDown: this.onPopupMouseDown, + }); }, deactivated() { this.setPopupVisible(false); @@ -139,6 +167,7 @@ export default defineComponent({ this.clearDelayTimer(); this.clearOutsideHandler(); clearTimeout(this.mouseDownTimeout); + raf.cancel(this.attachId); }, methods: { updatedCal() { @@ -152,7 +181,7 @@ export default defineComponent({ if (state.sPopupVisible) { let currentDocument; if (!this.clickOutsideHandler && (this.isClickToHide() || this.isContextmenuToShow())) { - currentDocument = props.getDocument(); + currentDocument = props.getDocument(this.getRootDomNode()); this.clickOutsideHandler = addEventListener( currentDocument, 'mousedown', @@ -161,7 +190,7 @@ export default defineComponent({ } // always hide on mobile if (!this.touchOutsideHandler) { - currentDocument = currentDocument || props.getDocument(); + currentDocument = currentDocument || props.getDocument(this.getRootDomNode()); this.touchOutsideHandler = addEventListener( currentDocument, 'touchstart', @@ -171,7 +200,7 @@ export default defineComponent({ } // close popup when trigger type contains 'onContextmenu' and document is scrolling. if (!this.contextmenuOutsideHandler1 && this.isContextmenuToShow()) { - currentDocument = currentDocument || props.getDocument(); + currentDocument = currentDocument || props.getDocument(this.getRootDomNode()); this.contextmenuOutsideHandler1 = addEventListener( currentDocument, 'scroll', @@ -215,9 +244,7 @@ export default defineComponent({ e && e.relatedTarget && !e.relatedTarget.setTimeout && - this._component && - this._component.getPopupDomNode && - contains(this._component.getPopupDomNode(), e.relatedTarget) + contains(this.popupRef?.getElement(), e.relatedTarget) ) { return; } @@ -304,7 +331,7 @@ export default defineComponent({ this.setPopupVisible(!this.$data.sPopupVisible, event); } }, - onPopupMouseDown(...args) { + onPopupMouseDown(...args: any[]) { const { vcTriggerContext = {} } = this; this.hasPopupMouseDown = true; @@ -323,19 +350,37 @@ export default defineComponent({ return; } const target = event.target; - const root = findDOMNode(this); - if (!contains(root, target) && !this.hasPopupMouseDown) { + const root = this.getRootDomNode(); + const popupNode = this.getPopupDomNode(); + if ( + // mousedown on the target should also close popup when action is contextMenu. + // https://github.com/ant-design/ant-design/issues/29853 + (!contains(root, target) || this.isContextMenuOnly()) && + !contains(popupNode, target) && + !this.hasPopupMouseDown + ) { this.close(); } }, getPopupDomNode() { - if (this._component && this._component.getPopupDomNode) { - return this._component.getPopupDomNode(); - } - return null; + // for test + return this.popupRef?.getElement() || null; }, getRootDomNode() { + const { getTriggerDOMNode } = this.$props; + if (getTriggerDOMNode) { + return getTriggerDOMNode(this.triggerRef); + } + + try { + const domNode = findDOMNode(this.triggerRef); + if (domNode) { + return domNode; + } + } catch (err) { + // Do nothing + } return findDOMNode(this); }, @@ -366,27 +411,21 @@ export default defineComponent({ } return popupAlign; }, - savePopup(node) { - this._component = node; - this.savePopupRef(node); - }, getComponent() { - const self = this; - const mouseProps = {}; + const mouseProps: HTMLAttributes = {}; if (this.isMouseEnterToShow()) { - mouseProps.onMouseenter = self.onPopupMouseenter; + mouseProps.onMouseenter = this.onPopupMouseenter; } if (this.isMouseLeaveToHide()) { - mouseProps.onMouseleave = self.onPopupMouseleave; + mouseProps.onMouseleave = this.onPopupMouseleave; } mouseProps.onMousedown = this.onPopupMouseDown; mouseProps[supportsPassive ? 'onTouchstartPassive' : 'onTouchstart'] = this.onPopupMouseDown; - const { handleGetPopupClassFromAlign, getRootDomNode, getContainer, $attrs } = self; + const { handleGetPopupClassFromAlign, getRootDomNode, getContainer, $attrs } = this; const { prefixCls, destroyPopupOnHide, popupClassName, - action, popupAnimation, popupTransitionName, popupStyle, @@ -396,16 +435,16 @@ export default defineComponent({ zIndex, stretch, alignPoint, - } = self.$props; + mobile, + forceRender, + } = this.$props; const { sPopupVisible, point } = this.$data; - const align = this.getPopupAlign(); const popupProps = { prefixCls, destroyPopupOnHide, visible: sPopupVisible, point: alignPoint ? point : null, - action, - align, + align: this.align, animation: popupAnimation, getClassNameFromAlign: handleGetPopupClassFromAlign, stretch, @@ -416,33 +455,63 @@ export default defineComponent({ maskAnimation, maskTransitionName, getContainer, - popupClassName, - popupStyle, + class: popupClassName, + style: popupStyle, onAlign: $attrs.onPopupAlign || noop, ...mouseProps, - ref: this.savePopup, - }; - return {getComponent(self, 'popup')}; + ref: 'popupRef', + mobile, + forceRender, + } as any; + return ( + getComponent(this, 'popup')) }} + > + ); + }, + + attachParent(popupContainer) { + raf.cancel(this.attachId); + + const { getPopupContainer, getDocument } = this.$props; + const domNode = this.getRootDomNode(); + + let mountNode; + if (!getPopupContainer) { + mountNode = getDocument(this.getRootDomNode()).body; + } else if (domNode || getPopupContainer.length === 0) { + // Compatible for legacy getPopupContainer with domNode argument. + // If no need `domNode` argument, will call directly. + // https://codesandbox.io/s/eloquent-mclean-ss93m?file=/src/App.js + mountNode = getPopupContainer(domNode); + } + + if (mountNode) { + mountNode.appendChild(popupContainer); + } else { + // Retry after frame render in case parent not ready + this.attachId = raf(() => { + this.attachParent(popupContainer); + }); + } }, getContainer() { - const { $props: props, dialogContext } = this; - const popupContainer = document.createElement('div'); + const { $props: props } = this; + const { getDocument } = props; + const popupContainer = getDocument(this.getRootDomNode()).createElement('div'); // Make sure default popup container will never cause scrollbar appearing // https://github.com/react-component/trigger/issues/41 popupContainer.style.position = 'absolute'; popupContainer.style.top = '0'; popupContainer.style.left = '0'; popupContainer.style.width = '100%'; - const mountNode = props.getPopupContainer - ? props.getPopupContainer(findDOMNode(this), dialogContext) - : props.getDocument().body; - mountNode.appendChild(popupContainer); - this.popupContainer = popupContainer; + this.attachParent(popupContainer); return popupContainer; }, - setPopupVisible(sPopupVisible, event) { + setPopupVisible(sPopupVisible: boolean, event?: any) { const { alignPoint, sPopupVisible: prevPopupVisible, onPopupVisibleChange } = this; this.clearDelayTimer(); if (prevPopupVisible !== sPopupVisible) { @@ -455,7 +524,7 @@ export default defineComponent({ onPopupVisibleChange && onPopupVisibleChange(sPopupVisible); } // Always record the point position since mouseEnterDelay will delay the show - if (alignPoint && event) { + if (alignPoint && event && sPopupVisible) { this.setPoint(event); } }, @@ -476,7 +545,7 @@ export default defineComponent({ this.afterPopupVisibleChange(this.sPopupVisible); } }, - delaySetPopupVisible(visible, delayS, event) { + delaySetPopupVisible(visible: boolean, delayS: number, event?: any) { const delay = delayS * 1000; this.clearDelayTimer(); if (delay) { @@ -519,14 +588,14 @@ export default defineComponent({ } }, - createTwoChains(event) { + createTwoChains(event: string) { let fn = () => {}; const events = getEvents(this); if (this.childOriginEvents[event] && events[event]) { return this[`fire${event}`]; } fn = this.childOriginEvents[event] || events[event] || fn; - return fn; + return fn as any; }, isClickToShow() { @@ -534,6 +603,11 @@ export default defineComponent({ return action.indexOf('click') !== -1 || showAction.indexOf('click') !== -1; }, + isContextMenuOnly() { + const { action } = this.$props; + return action === 'contextmenu' || (action.length === 1 && action[0] === 'contextmenu'); + }, + isContextmenuToShow() { const { action, showAction } = this.$props; return action.indexOf('contextmenu') !== -1 || showAction.indexOf('contextmenu') !== -1; @@ -564,11 +638,11 @@ export default defineComponent({ return action.indexOf('focus') !== -1 || hideAction.indexOf('blur') !== -1; }, forcePopupAlign() { - if (this.$data.sPopupVisible && this._component && this._component.alignInstance) { - this._component.alignInstance.forceAlign(); + if (this.$data.sPopupVisible) { + this.popupRef?.forceAlign(); } }, - fireEvents(type, e) { + fireEvents(type: string, e: Event) { if (this.childOriginEvents[type]) { this.childOriginEvents[type](e); } @@ -585,14 +659,11 @@ export default defineComponent({ render() { const { sPopupVisible, $attrs } = this; const children = filterEmpty(getSlot(this)); - const { forceRender, alignPoint } = this.$props; + const { forceRender, alignPoint, autoDestroy } = this.$props; - if (children.length > 1) { - warning(false, 'Trigger children just support only one default', true); - } const child = children[0]; this.childOriginEvents = getEvents(child); - const newChildProps = { + const newChildProps: any = { key: 'trigger', }; @@ -632,7 +703,10 @@ export default defineComponent({ } else { newChildProps.onFocus = this.createTwoChains('onFocus'); newChildProps.onBlur = e => { - if (e && (!e.relatedTarget || !contains(e.target, e.relatedTarget))) { + if ( + e && + (!e.relatedTarget || !contains(e.target as HTMLElement, e.relatedTarget as HTMLElement)) + ) { this.createTwoChains('onBlur')(e); } }; @@ -641,19 +715,27 @@ export default defineComponent({ if (childrenClassName) { newChildProps.class = childrenClassName; } - const trigger = cloneElement(child, newChildProps); + const trigger = cloneElement(child, { ...newChildProps, ref: 'triggerRef' }, true, true); let portal; // prevent unmounting after it's rendered - if (sPopupVisible || this._component || forceRender) { + if (sPopupVisible || this.popupRef || forceRender) { portal = ( ); } - return [portal, trigger]; + if (!sPopupVisible && autoDestroy) { + portal = null; + } + return ( + <> + {portal} + {trigger} + + ); }, }); diff --git a/components/vc-trigger/index.md b/components/vc-trigger/index.md deleted file mode 100644 index bae1a0f2a..000000000 --- a/components/vc-trigger/index.md +++ /dev/null @@ -1,160 +0,0 @@ -## API - -### props - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    nametypedefaultdescription
    popupClassNamestringadditional className added to popup
    forceRenderbooleanfalsewhether render popup before first show
    destroyPopupOnHidebooleanfalsewhether destroy popup when hide
    getPopupClassNameFromAligngetPopupClassNameFromAlign(align: Object):Stringadditional className added to popup according to align
    actionstring[]['hover']which actions cause popup shown. enum of 'hover','click','focus','contextmenu'
    mouseEnterDelaynumber0delay time to show when mouse enter. unit: s.
    mouseLeaveDelaynumber0.1delay time to hide when mouse leave. unit: s.
    popupStyleObjectadditional style of popup
    prefixClsStringrc-trigger-popupprefix class name
    popupTransitionNameString|Objecthttps://github.com/react-component/animate
    maskTransitionNameString|Objecthttps://github.com/react-component/animate
    maskbooleanfalsewhether to support mask
    maskClosablebooleantruewhether to support click mask to hide
    popupVisiblebooleanwhether popup is visible
    zIndexnumberpopup's zIndex
    defaultPopupVisiblebooleanwhether popup is visible initially
    popupAlignObject: alignConfig of [dom-align](https://github.com/yiminghe/dom-align)popup 's align config
    getPopupContainergetPopupContainer(): HTMLElementfunction returning html node which will act as popup container
    getDocumentgetDocument(): HTMLElementfunction returning document node which will be attached click event to close trigger
    popupPlacementstringuse preset popup align config from builtinPlacements, can be merged by popupAlign prop
    builtinPlacementsobjectbuiltin placement align map. used by placement prop
    popupVisibleChange$emitcall when popup visible is changed
    popupAlign$emitcallback when popup node is aligned
    popupslot='popup'popup content
    diff --git a/components/vc-trigger/index.js b/components/vc-trigger/index.ts similarity index 65% rename from components/vc-trigger/index.js rename to components/vc-trigger/index.ts index 8ccbba4d7..dcf37bdc3 100644 --- a/components/vc-trigger/index.js +++ b/components/vc-trigger/index.ts @@ -1,3 +1,3 @@ -// based on rc-trigger 2.6.5 +// based on rc-trigger 5.2.10 import Trigger from './Trigger'; export default Trigger; diff --git a/components/vc-trigger/interface.ts b/components/vc-trigger/interface.ts new file mode 100644 index 000000000..7ef79c111 --- /dev/null +++ b/components/vc-trigger/interface.ts @@ -0,0 +1,72 @@ +import type { CSSProperties, TransitionProps } from 'vue'; +import type { VueNode } from '../_util/type'; + +/** Two char of 't' 'b' 'c' 'l' 'r'. Example: 'lt' */ +export type AlignPoint = string; + +export interface AlignType { + /** + * move point of source node to align with point of target node. + * Such as ['tr','cc'], align top right point of source node with center point of target node. + * Point can be 't'(top), 'b'(bottom), 'c'(center), 'l'(left), 'r'(right) */ + points?: AlignPoint[]; + /** + * offset source node by offset[0] in x and offset[1] in y. + * If offset contains percentage string value, it is relative to sourceNode region. + */ + offset?: number[]; + /** + * offset target node by offset[0] in x and offset[1] in y. + * If targetOffset contains percentage string value, it is relative to targetNode region. + */ + targetOffset?: number[]; + /** + * If adjustX field is true, will adjust source node in x direction if source node is invisible. + * If adjustY field is true, will adjust source node in y direction if source node is invisible. + */ + overflow?: { + adjustX?: boolean | number; + adjustY?: boolean | number; + }; + /** + * Whether use css right instead of left to position + */ + useCssRight?: boolean; + /** + * Whether use css bottom instead of top to position + */ + useCssBottom?: boolean; + /** + * Whether use css transform instead of left/top/right/bottom to position if browser supports. + * Defaults to false. + */ + useCssTransform?: boolean; + ignoreShake?: boolean; +} + +export type BuildInPlacements = Record; + +export type StretchType = string; + +export type ActionType = string; + +export type AnimationType = string; + +export type TransitionNameType = string; + +export interface Point { + pageX: number; + pageY: number; +} + +export interface CommonEventHandler { + remove: () => void; +} + +export interface MobileConfig { + /** Set popup motion. You can ref `rc-motion` for more info. */ + popupMotion?: TransitionProps; + popupClassName?: string; + popupStyle?: CSSProperties; + popupRender?: (originNode: VueNode) => VueNode; +} diff --git a/components/vc-trigger/utils.js b/components/vc-trigger/utils.js deleted file mode 100644 index f024f0f0e..000000000 --- a/components/vc-trigger/utils.js +++ /dev/null @@ -1,31 +0,0 @@ -function isPointsEq(a1, a2, isAlignPoint) { - if (isAlignPoint) { - return a1[0] === a2[0]; - } - return a1[0] === a2[0] && a1[1] === a2[1]; -} - -export function getAlignFromPlacement(builtinPlacements, placementStr, align) { - const baseAlign = builtinPlacements[placementStr] || {}; - return { - ...baseAlign, - ...align, - }; -} - -export function getAlignPopupClassName(builtinPlacements, prefixCls, align, isAlignPoint) { - const points = align.points; - for (const placement in builtinPlacements) { - if (builtinPlacements.hasOwnProperty(placement)) { - if (isPointsEq(builtinPlacements[placement].points, points, isAlignPoint)) { - return `${prefixCls}-placement-${placement}`; - } - } - } - return ''; -} -export function noop() {} - -export function saveRef(name, component) { - this[name] = component; -} diff --git a/components/vc-trigger/utils/alignUtil.ts b/components/vc-trigger/utils/alignUtil.ts new file mode 100644 index 000000000..0041e84c6 --- /dev/null +++ b/components/vc-trigger/utils/alignUtil.ts @@ -0,0 +1,40 @@ +import type { AlignType, BuildInPlacements, AlignPoint } from '../interface'; + +function isPointsEq(a1: AlignPoint[], a2: AlignPoint[], isAlignPoint: boolean): boolean { + if (isAlignPoint) { + return a1[0] === a2[0]; + } + return a1[0] === a2[0] && a1[1] === a2[1]; +} + +export function getAlignFromPlacement( + builtinPlacements: BuildInPlacements, + placementStr: string, + align: AlignType, +): AlignType { + const baseAlign = builtinPlacements[placementStr] || {}; + return { + ...baseAlign, + ...align, + }; +} + +export function getAlignPopupClassName( + builtinPlacements: BuildInPlacements, + prefixCls: string, + align: AlignType, + isAlignPoint: boolean, +): string { + const { points } = align; + + const placements = Object.keys(builtinPlacements); + + for (let i = 0; i < placements.length; i += 1) { + const placement = placements[i]; + if (isPointsEq(builtinPlacements[placement].points, points, isAlignPoint)) { + return `${prefixCls}-placement-${placement}`; + } + } + + return ''; +} diff --git a/components/vc-trigger/utils/motionUtil.ts b/components/vc-trigger/utils/motionUtil.ts new file mode 100644 index 000000000..2146c5d3b --- /dev/null +++ b/components/vc-trigger/utils/motionUtil.ts @@ -0,0 +1,23 @@ +import type { AnimationType, TransitionNameType } from '../interface'; + +interface GetMotionProps { + animation: AnimationType; + transitionName: TransitionNameType; + prefixCls: string; +} + +export function getMotion({ prefixCls, animation, transitionName }: GetMotionProps) { + if (animation) { + return { + name: `${prefixCls}-${animation}`, + }; + } + + if (transitionName) { + return { + name: transitionName, + }; + } + + return null; +} diff --git a/components/vc-util/Dom/contains.ts b/components/vc-util/Dom/contains.ts index 5eb1ebcea..a708d9242 100644 --- a/components/vc-util/Dom/contains.ts +++ b/components/vc-util/Dom/contains.ts @@ -1,4 +1,4 @@ -export default function contains(root: Node | null | undefined, n?: Node) { +export default function contains(root: HTMLElement | null | undefined, n?: HTMLElement) { if (!root) { return false; } diff --git a/examples/App.vue b/examples/App.vue index 65b1ba433..5bb610266 100644 --- a/examples/App.vue +++ b/examples/App.vue @@ -1,39 +1,63 @@ + diff --git a/package.json b/package.json index 9e598b5d4..7d89a2ce5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ant-design-vue", - "version": "2.2.3", + "version": "2.2.6", "title": "Ant Design Vue", "description": "An enterprise-class UI design language and Vue-based implementation", "keywords": [ @@ -160,7 +160,6 @@ "querystring": "^0.2.0", "raw-loader": "^4.0.2", "reqwest": "^2.0.5", - "resize-observer-polyfill": "^1.5.1", "rimraf": "^3.0.0", "rucksack-css": "^1.0.2", "selenium-server": "^3.0.1", @@ -195,7 +194,7 @@ "vue-style-loader": "^4.1.2", "vuex": "^4.0.0-beta.2", "webpack": "^5.0.0", - "webpack-bundle-analyzer": "^4.0.0", + "webpack-bundle-analyzer": "^4.4.2", "webpack-cli": "^4.6.0", "webpack-dev-server": "^3.1.14", "webpack-merge": "^5.0.0", @@ -209,12 +208,15 @@ "@simonwep/pickr": "~1.8.0", "array-tree-filter": "^2.1.0", "async-validator": "^3.3.0", + "date-fns": "^2.22.1", + "dayjs": "^1.10.5", "dom-align": "^1.12.1", "dom-scroll-into-view": "^2.0.0", "lodash": "^4.17.21", "lodash-es": "^4.17.15", "moment": "^2.27.0", "omit.js": "^2.0.0", + "resize-observer-polyfill": "^1.5.1", "scroll-into-view-if-needed": "^2.2.25", "shallow-equal": "^1.0.0", "vue-types": "^3.0.0", diff --git a/tests/shared/demoTest.js b/tests/shared/demoTest.js index 3870187f6..d106b629c 100644 --- a/tests/shared/demoTest.js +++ b/tests/shared/demoTest.js @@ -1,7 +1,7 @@ import glob from 'glob'; import { mount } from '@vue/test-utils'; import MockDate from 'mockdate'; -import moment from 'moment'; +import dayjs from 'dayjs'; import antd from 'ant-design-vue'; import { sleep } from '../utils'; @@ -15,7 +15,7 @@ export default function demoTest(component, options = {}) { testMethod = test.skip; } testMethod(`renders ${file} correctly`, async () => { - MockDate.set(moment('2016-11-22')); + MockDate.set(dayjs('2016-11-22')); const demo = require(`../.${file}`).default || require(`../.${file}`); document.body.innerHTML = ''; const wrapper = mount(demo, { global: { plugins: [antd] }, attachTo: document.body }); diff --git a/tests/utils.js b/tests/utils.js index ce873c5b5..64a875e31 100644 --- a/tests/utils.js +++ b/tests/utils.js @@ -1,9 +1,9 @@ -import moment from 'moment'; +import dayjs from 'dayjs'; import MockDate from 'mockdate'; import { nextTick } from 'vue'; export function setMockDate(dateString = '2017-09-18T03:30:07.795') { - MockDate.set(moment(dateString)); + MockDate.set(dayjs(dateString)); } export function resetMockDate() { diff --git a/tsconfig.json b/tsconfig.json index 14c4d2a04..dfde3b05b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,10 +1,5 @@ { "compilerOptions": { - "baseUrl": "./", - "paths": { - "ant-design-vue": ["components/index.tsx"], - "ant-design-vue/es/*": ["components/*"] - }, "strictNullChecks": false, "strict": true, "moduleResolution": "node", @@ -19,5 +14,14 @@ "skipLibCheck": true, "allowJs": true }, - "exclude": ["node_modules", "lib", "es", "antd-tools", "dist", "v2-doc"] + "exclude": [ + "node_modules", + "lib", + "es", + "antd-tools", + "dist", + "v2-doc", + "scripts", + "**/__tests__/**/*" + ] } diff --git a/v2-doc b/v2-doc index d571ad4bf..2aa53d9c7 160000 --- a/v2-doc +++ b/v2-doc @@ -1 +1 @@ -Subproject commit d571ad4bf772cfc372511dc1dedf07981dc56ae8 +Subproject commit 2aa53d9c7aae3b172d8837a0ba9118c3fd8c2038 diff --git a/webpack.build.conf.js b/webpack.build.conf.js index 1da4ffd91..c065f6b04 100644 --- a/webpack.build.conf.js +++ b/webpack.build.conf.js @@ -1,15 +1,8 @@ // This config is for building dist files +const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer'); const getWebpackConfig = require('./antd-tools/getWebpackConfig'); const IgnoreEmitPlugin = require('ignore-emit-webpack-plugin'); const darkVars = require('./scripts/dark-vars'); -const { webpack } = getWebpackConfig; -// noParse still leave `require('./locale' + name)` in dist files -// ignore is better -// http://stackoverflow.com/q/25384360 -function ignoreMomentLocale(webpackConfig) { - delete webpackConfig.module.noParse; - webpackConfig.plugins.push(new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)); -} function addLocales(webpackConfig) { let packageName = 'antd-with-locales'; @@ -20,52 +13,64 @@ function addLocales(webpackConfig) { webpackConfig.output.filename = '[name].js'; } -function externalMoment(config) { - config.externals.moment = { - root: 'moment', - commonjs2: 'moment', - commonjs: 'moment', - amd: 'moment', +function externalDayjs(config) { + config.externals.dayjs = { + root: 'dayjs', + commonjs2: 'dayjs', + commonjs: 'dayjs', + amd: 'dayjs', }; } -const webpackConfig = getWebpackConfig(false); -if (process.env.RUN_ENV === 'PRODUCTION') { - webpackConfig.forEach(config => { - ignoreMomentLocale(config); - externalMoment(config); - addLocales(config); +function processWebpackThemeConfig(themeConfig, theme, vars) { + themeConfig.forEach(config => { + externalDayjs(config); + + // rename default entry to ${theme} entry + Object.keys(config.entry).forEach(entryName => { + config.entry[entryName.replace('antd', `antd.${theme}`)] = config.entry[entryName]; + delete config.entry[entryName]; + }); + + // apply ${theme} less variables + config.module.rules.forEach(rule => { + // filter less rule + if (rule.test instanceof RegExp && rule.test.test('.less')) { + const lessRule = rule.use[rule.use.length - 1]; + if (lessRule.options.lessOptions) { + lessRule.options.lessOptions.modifyVars = vars; + } else { + lessRule.options.modifyVars = vars; + } + } + }); + + const themeReg = new RegExp(`${theme}(.min)?\\.js(\\.map)?$`); + // ignore emit ${theme} entry js & js.map file + config.plugins.push(new IgnoreEmitPlugin(themeReg)); }); } +const webpackConfig = getWebpackConfig(false); const webpackDarkConfig = getWebpackConfig(false); -webpackDarkConfig.forEach(config => { - ignoreMomentLocale(config); - externalMoment(config); +if (process.env.RUN_ENV === 'PRODUCTION') { + webpackConfig.forEach(config => { + externalDayjs(config); + addLocales(config); + // Reduce non-minified dist files size + config.optimization.usedExports = true; - // rename default entry to ${theme} entry - Object.keys(config.entry).forEach(entryName => { - config.entry[entryName.replace('antd', `antd.dark`)] = config.entry[entryName]; - delete config.entry[entryName]; + config.plugins.push( + new BundleAnalyzerPlugin({ + analyzerMode: 'static', + openAnalyzer: false, + reportFilename: '../report.html', + }), + ); }); - // apply ${theme} less variables - config.module.rules.forEach(rule => { - // filter less rule - if (rule.test instanceof RegExp && rule.test.test('.less')) { - const lessRule = rule.use[rule.use.length - 1]; - if (lessRule.options.lessOptions) { - lessRule.options.lessOptions.modifyVars = darkVars; - } else { - lessRule.options.modifyVars = darkVars; - } - } - }); - - const themeReg = new RegExp(`dark(.min)?\\.js(\\.map)?`); - // ignore emit ${theme} entry js & js.map file - config.plugins.push(new IgnoreEmitPlugin(themeReg)); -}); + processWebpackThemeConfig(webpackDarkConfig, 'dark', darkVars); +} module.exports = webpackConfig.concat(webpackDarkConfig);