├── .dumirc.ts
├── .editorconfig
├── .eslintrc.js
├── .fatherrc.js
├── .github
├── FUNDING.yml
├── dependabot.yml
└── workflows
│ ├── codeql.yml
│ └── main.yml
├── .gitignore
├── .husky
└── pre-commit
├── .lintstagedrc.json
├── .npmignore
├── .prettierignore
├── .prettierrc
├── CHANGELOG.md
├── LICENSE.md
├── README.md
├── assets
└── index.less
├── bunfig.toml
├── docs
├── changelog.md
├── demo
│ ├── basic.md
│ ├── calendar.md
│ ├── cellRender.md
│ ├── customize.md
│ ├── debug.md
│ ├── disabledDate.md
│ ├── focus.md
│ ├── limitation.md
│ ├── locale.md
│ ├── modes.md
│ ├── multiple.md
│ ├── panel.md
│ ├── panelRender.md
│ ├── range.md
│ ├── rtl.md
│ ├── switchType.md
│ ├── time.md
│ └── uncontrolled.md
├── examples
│ ├── basic.tsx
│ ├── calendar.less
│ ├── calendar.tsx
│ ├── cellRender.tsx
│ ├── common.less
│ ├── customize.tsx
│ ├── debug.tsx
│ ├── disabledDate.tsx
│ ├── focus.tsx
│ ├── limitation.tsx
│ ├── locale.tsx
│ ├── modes.tsx
│ ├── multiple.tsx
│ ├── panel.tsx
│ ├── panelRender.tsx
│ ├── range.tsx
│ ├── rtl.tsx
│ ├── slide.less
│ ├── switchType.tsx
│ ├── time.tsx
│ └── uncontrolled.tsx
└── index.md
├── index.js
├── jest.config.js
├── now.json
├── package.json
├── src
├── PickerInput
│ ├── Popup
│ │ ├── Footer.tsx
│ │ ├── PopupPanel.tsx
│ │ ├── PresetPanel.tsx
│ │ └── index.tsx
│ ├── RangePicker.tsx
│ ├── Selector
│ │ ├── Icon.tsx
│ │ ├── Input.tsx
│ │ ├── MaskFormat.ts
│ │ ├── RangeSelector.tsx
│ │ ├── SingleSelector
│ │ │ ├── MultipleDates.tsx
│ │ │ └── index.tsx
│ │ ├── hooks
│ │ │ ├── useClearIcon.tsx
│ │ │ ├── useInputProps.ts
│ │ │ └── useRootProps.ts
│ │ └── util.ts
│ ├── SinglePicker.tsx
│ ├── context.tsx
│ └── hooks
│ │ ├── useCellRender.ts
│ │ ├── useDelayState.ts
│ │ ├── useDisabledBoundary.ts
│ │ ├── useFieldFormat.ts
│ │ ├── useFieldsInvalidate.ts
│ │ ├── useFilledProps.ts
│ │ ├── useInputReadOnly.ts
│ │ ├── useInvalidate.ts
│ │ ├── useLockEffect.ts
│ │ ├── useOpen.ts
│ │ ├── usePickerRef.ts
│ │ ├── usePresets.ts
│ │ ├── useRangeActive.ts
│ │ ├── useRangeDisabledDate.ts
│ │ ├── useRangePickerValue.ts
│ │ ├── useRangeValue.ts
│ │ └── useShowNow.ts
├── PickerPanel
│ ├── DatePanel
│ │ └── index.tsx
│ ├── DateTimePanel
│ │ └── index.tsx
│ ├── DecadePanel
│ │ └── index.tsx
│ ├── MonthPanel
│ │ └── index.tsx
│ ├── PanelBody.tsx
│ ├── PanelHeader.tsx
│ ├── QuarterPanel
│ │ └── index.tsx
│ ├── TimePanel
│ │ ├── TimePanelBody
│ │ │ ├── TimeColumn.tsx
│ │ │ ├── index.tsx
│ │ │ ├── useScrollTo.ts
│ │ │ └── util.ts
│ │ └── index.tsx
│ ├── WeekPanel
│ │ └── index.tsx
│ ├── YearPanel
│ │ └── index.tsx
│ ├── context.ts
│ └── index.tsx
├── PickerTrigger
│ ├── index.tsx
│ └── util.ts
├── generate
│ ├── dateFns.ts
│ ├── dayjs.ts
│ ├── index.ts
│ ├── luxon.ts
│ └── moment.ts
├── hooks
│ ├── useLocale.ts
│ ├── useSemantic.ts
│ ├── useSyncState.ts
│ ├── useTimeConfig.ts
│ ├── useTimeInfo.ts
│ └── useToggleDates.ts
├── index.tsx
├── interface.tsx
├── locale
│ ├── am_ET.ts
│ ├── ar_EG.ts
│ ├── az_AZ.ts
│ ├── bg_BG.ts
│ ├── bn_BD.ts
│ ├── by_BY.ts
│ ├── ca_ES.ts
│ ├── common.ts
│ ├── cs_CZ.ts
│ ├── da_DK.ts
│ ├── de_DE.ts
│ ├── el_GR.ts
│ ├── en_GB.ts
│ ├── en_US.ts
│ ├── es_ES.ts
│ ├── es_MX.ts
│ ├── et_EE.ts
│ ├── eu_ES.ts
│ ├── fa_IR.ts
│ ├── fi_FI.ts
│ ├── fr_BE.ts
│ ├── fr_CA.ts
│ ├── fr_FR.ts
│ ├── ga_IE.ts
│ ├── gl_ES.ts
│ ├── he_IL.ts
│ ├── hi_IN.ts
│ ├── hr_HR.ts
│ ├── hu_HU.ts
│ ├── id_ID.ts
│ ├── is_IS.ts
│ ├── it_IT.ts
│ ├── ja_JP.ts
│ ├── ka_GE.ts
│ ├── kk_KZ.ts
│ ├── km_KH.ts
│ ├── kmr_IQ.ts
│ ├── kn_IN.ts
│ ├── ko_KR.ts
│ ├── lt_LT.ts
│ ├── lv_LV.ts
│ ├── mk_MK.ts
│ ├── ml_IN.ts
│ ├── mn_MN.ts
│ ├── ms_MY.ts
│ ├── my_MM.ts
│ ├── nb_NO.ts
│ ├── ne_NP.ts
│ ├── nl_BE.ts
│ ├── nl_NL.ts
│ ├── pl_PL.ts
│ ├── pt_BR.ts
│ ├── pt_PT.ts
│ ├── ro_RO.ts
│ ├── ru_RU.ts
│ ├── si_LK.ts
│ ├── sk_SK.ts
│ ├── sl_SI.ts
│ ├── sr_Cyrl_RS.ts
│ ├── sr_RS.ts
│ ├── sv_SE.ts
│ ├── ta_IN.ts
│ ├── th_TH.ts
│ ├── tk_TK.ts
│ ├── tr_TR.ts
│ ├── ug_CN.ts
│ ├── uk_UA.ts
│ ├── ur_PK.ts
│ ├── uz_UZ.ts
│ ├── vi_VN.ts
│ ├── zh_CN.ts
│ └── zh_TW.ts
└── utils
│ ├── dateUtil.ts
│ ├── getClearIcon.tsx
│ ├── miscUtil.ts
│ ├── uiUtil.ts
│ └── warnUtil.ts
├── tests
├── __snapshots__
│ ├── panel.spec.tsx.snap
│ ├── picker.spec.tsx.snap
│ └── range.spec.tsx.snap
├── blur.spec.tsx
├── components.spec.tsx
├── disabledTime.spec.tsx
├── generate.spec.tsx
├── generateWithTZ.spec.tsx
├── internal.spec.tsx
├── keyboard.spec.tsx
├── loop.spec.tsx
├── multiple.spec.tsx
├── new-range.spec.tsx
├── panel.spec.tsx
├── picker.spec.tsx
├── range.spec.tsx
├── time.spec.tsx
├── util.spec.tsx
└── util
│ └── commonUtil.tsx
├── tsconfig.json
└── typings.d.ts
/.dumirc.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'dumi';
2 |
3 | export default defineConfig({
4 | favicons: ['https://avatars0.githubusercontent.com/u/9441414?s=200&v=4'],
5 | themeConfig: {
6 | name: 'Picker',
7 | logo: 'https://avatars0.githubusercontent.com/u/9441414?s=200&v=4',
8 | },
9 | });
10 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # top-most EditorConfig file
2 | root = true
3 |
4 | # Unix-style newlines with a newline ending every file
5 | [*.{js,css,md}]
6 | end_of_line = lf
7 | insert_final_newline = true
8 | indent_style = space
9 | indent_size = 2
10 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: [require.resolve('@umijs/fabric/dist/eslint')],
3 | rules: {
4 | 'arrow-parens': 0,
5 | 'no-template-curly-in-string': 0,
6 | 'prefer-promise-reject-errors': 0,
7 | 'react/no-array-index-key': 0,
8 | 'react/sort-comp': 0,
9 | '@typescript-eslint/no-explicit-any': 0,
10 | 'default-case': 0,
11 | 'no-confusing-arrow': 0,
12 | 'jsx-a11y/no-autofocus': 0,
13 | 'jsx-a11y/heading-has-content': 0,
14 | },
15 | };
16 |
--------------------------------------------------------------------------------
/.fatherrc.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'father';
2 |
3 | export default defineConfig({
4 | plugins: ['@rc-component/father-plugin'],
5 | });
6 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: ant-design # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
4 | patreon: # Replace with a single Patreon username
5 | open_collective: ant-design # Replace with a single Open Collective username
6 | ko_fi: # Replace with a single Ko-fi username
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
12 | polar: # Replace with a single Polar username
13 | buy_me_a_coffee: # Replace with a single Buy Me a Coffee username
14 | thanks_dev: # Replace with a single thanks.dev username
15 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
16 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: npm
4 | directory: "/"
5 | schedule:
6 | interval: daily
7 | time: "21:00"
8 | open-pull-requests-limit: 10
9 | ignore:
10 | - dependency-name: eslint
11 | versions:
12 | - 7.18.0
13 | - 7.19.0
14 | - 7.20.0
15 | - 7.21.0
16 | - 7.22.0
17 | - 7.23.0
18 | - 7.24.0
19 | - dependency-name: "@types/react-dom"
20 | versions:
21 | - 17.0.0
22 | - 17.0.1
23 | - 17.0.2
24 | - dependency-name: "@types/react"
25 | versions:
26 | - 17.0.0
27 | - 17.0.1
28 | - 17.0.2
29 | - 17.0.3
30 | - dependency-name: less
31 | versions:
32 | - 4.1.0
33 |
--------------------------------------------------------------------------------
/.github/workflows/codeql.yml:
--------------------------------------------------------------------------------
1 | name: "CodeQL"
2 |
3 | on:
4 | push:
5 | branches: [ "master" ]
6 | pull_request:
7 | branches: [ "master" ]
8 | schedule:
9 | - cron: "19 12 * * 0"
10 |
11 | jobs:
12 | analyze:
13 | name: Analyze
14 | runs-on: ubuntu-latest
15 | permissions:
16 | actions: read
17 | contents: read
18 | security-events: write
19 |
20 | strategy:
21 | fail-fast: false
22 | matrix:
23 | language: [ javascript ]
24 |
25 | steps:
26 | - name: Checkout
27 | uses: actions/checkout@v3
28 |
29 | - name: Initialize CodeQL
30 | uses: github/codeql-action/init@v2
31 | with:
32 | languages: ${{ matrix.language }}
33 | queries: +security-and-quality
34 |
35 | - name: Autobuild
36 | uses: github/codeql-action/autobuild@v2
37 |
38 | - name: Perform CodeQL Analysis
39 | uses: github/codeql-action/analyze@v2
40 | with:
41 | category: "/language:${{ matrix.language }}"
42 |
--------------------------------------------------------------------------------
/.github/workflows/main.yml:
--------------------------------------------------------------------------------
1 | name: ✅ test
2 | on: [push, pull_request]
3 | jobs:
4 | test:
5 | uses: react-component/rc-test/.github/workflows/test.yml@main
6 | secrets: inherit
7 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .storybook
2 | .vscode
3 | *.iml
4 | *.log
5 | .idea/
6 | .ipr
7 | .iws
8 | *~
9 | ~*
10 | *.diff
11 | *.patch
12 | *.bak
13 | .DS_Store
14 | Thumbs.db
15 | .project
16 | .*proj
17 | .svn/
18 | *.swp
19 | *.swo
20 | *.pyc
21 | *.pyo
22 | .build
23 | node_modules
24 | .cache
25 | assets/**/*.css
26 | build
27 | lib
28 | es
29 | yarn.lock
30 | package-lock.json
31 | pnpm-lock.yaml
32 | coverage/
33 | .doc
34 | .history
35 | # umi
36 | .umi
37 | .umi-production
38 | .umi-test
39 | .env.local
40 |
41 | # dumi
42 | .dumi/tmp
43 | .dumi/tmp-production
44 |
45 | bun.lockb
--------------------------------------------------------------------------------
/.husky/pre-commit:
--------------------------------------------------------------------------------
1 | npx lint-staged
2 |
--------------------------------------------------------------------------------
/.lintstagedrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "*": ["prettier --ignore-unknown --write"]
3 | }
4 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | build/
2 | *.cfg
3 | nohup.out
4 | *.iml
5 | .idea/
6 | .ipr
7 | .iws
8 | *~
9 | ~*
10 | *.diff
11 | *.log
12 | *.patch
13 | *.bak
14 | .DS_Store
15 | Thumbs.db
16 | .project
17 | .*proj
18 | .svn/
19 | *.swp
20 | out/
21 | .build
22 | node_modules
23 | .cache
24 | examples
25 | tests
26 | src
27 | /index.js
28 | .*
29 | assets/**/*.less
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | .storybook
2 | node_modules
3 | lib
4 | es
5 | .cache
6 | package.json
7 | package-lock.json
8 | public
9 | .site
10 | _site
11 | .umi
12 | .doc
13 | .umi-production
14 | .umi-test
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "endOfLine": "lf",
3 | "semi": true,
4 | "singleQuote": true,
5 | "tabWidth": 2,
6 | "trailingComma": "all",
7 | "proseWrap": "never",
8 | "printWidth": 100
9 | }
10 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | See https://github.com/react-component/picker/releases
2 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2019-present afc163
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6 |
7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
10 |
--------------------------------------------------------------------------------
/bunfig.toml:
--------------------------------------------------------------------------------
1 | [install]
2 | peer = false
--------------------------------------------------------------------------------
/docs/changelog.md:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/docs/demo/basic.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: basic
3 | nav:
4 | title: Demo
5 | path: /demo
6 | ---
7 |
8 |
9 |
--------------------------------------------------------------------------------
/docs/demo/calendar.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: calendar
3 | nav:
4 | title: Demo
5 | path: /demo
6 | ---
7 |
8 |
9 |
--------------------------------------------------------------------------------
/docs/demo/cellRender.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: cellRender
3 | nav:
4 | title: Demo
5 | path: /demo
6 | ---
7 |
8 |
9 |
--------------------------------------------------------------------------------
/docs/demo/customize.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: customize
3 | nav:
4 | title: Demo
5 | path: /demo
6 | ---
7 |
8 |
9 |
--------------------------------------------------------------------------------
/docs/demo/debug.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: debug
3 | nav:
4 | title: Demo
5 | path: /demo
6 | ---
7 |
8 |
9 |
--------------------------------------------------------------------------------
/docs/demo/disabledDate.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: disabledDate
3 | nav:
4 | title: Demo
5 | path: /demo
6 | ---
7 |
8 |
9 |
--------------------------------------------------------------------------------
/docs/demo/focus.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: focus
3 | nav:
4 | title: Demo
5 | path: /demo
6 | ---
7 |
8 |
9 |
--------------------------------------------------------------------------------
/docs/demo/limitation.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: limitation
3 | nav:
4 | title: Demo
5 | path: /demo
6 | ---
7 |
8 |
9 |
--------------------------------------------------------------------------------
/docs/demo/locale.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: locale
3 | nav:
4 | title: Demo
5 | path: /demo
6 | ---
7 |
8 |
9 |
--------------------------------------------------------------------------------
/docs/demo/modes.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: modes
3 | nav:
4 | title: Demo
5 | path: /demo
6 | ---
7 |
8 |
9 |
--------------------------------------------------------------------------------
/docs/demo/multiple.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: multiple
3 | nav:
4 | title: Demo
5 | path: /demo
6 | ---
7 |
8 |
9 |
--------------------------------------------------------------------------------
/docs/demo/panel.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: panel
3 | nav:
4 | title: Demo
5 | path: /demo
6 | ---
7 |
8 |
9 |
--------------------------------------------------------------------------------
/docs/demo/panelRender.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: panelRender
3 | nav:
4 | title: Demo
5 | path: /demo
6 | ---
7 |
8 |
9 |
--------------------------------------------------------------------------------
/docs/demo/range.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: range
3 | nav:
4 | title: Demo
5 | path: /demo
6 | ---
7 |
8 |
9 |
--------------------------------------------------------------------------------
/docs/demo/rtl.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: rtl
3 | nav:
4 | title: Demo
5 | path: /demo
6 | ---
7 |
8 |
9 |
--------------------------------------------------------------------------------
/docs/demo/switchType.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: switchType
3 | nav:
4 | title: Demo
5 | path: /demo
6 | ---
7 |
8 |
9 |
--------------------------------------------------------------------------------
/docs/demo/time.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: time
3 | nav:
4 | title: Demo
5 | path: /demo
6 | ---
7 |
8 |
9 |
--------------------------------------------------------------------------------
/docs/demo/uncontrolled.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: animation
3 | nav:
4 | title: Demo
5 | path: /demo
6 | ---
7 |
8 |
9 |
--------------------------------------------------------------------------------
/docs/examples/calendar.less:
--------------------------------------------------------------------------------
1 | .rc-picker-cell-selected {
2 | background: red;
3 | }
--------------------------------------------------------------------------------
/docs/examples/calendar.tsx:
--------------------------------------------------------------------------------
1 | import type { Moment } from 'moment';
2 | import React from 'react';
3 | import '../../assets/index.less';
4 | import { Picker, PickerPanel } from '../../src';
5 | import momentGenerateConfig from '../../src/generate/moment';
6 | import zhCN from '../../src/locale/zh_CN';
7 | import './calendar.less';
8 |
9 | function dateRender(date: Moment, today: Moment) {
10 | return (
11 |
19 | {date.date()}
20 |
21 | );
22 | }
23 |
24 | const disabledProps = {
25 | disabledDate: (date) => date.date() === 10,
26 | onSelect: (d) => console.log('Select:', d.format('YYYY-MM-DD')),
27 | onChange: (d) => console.log('Change:', d.format('YYYY-MM-DD')),
28 | };
29 |
30 | export default () => (
31 |
32 |
33 |
34 | locale={zhCN}
35 | // picker="month"
36 | generateConfig={momentGenerateConfig}
37 | dateRender={dateRender}
38 | {...disabledProps}
39 | />
40 |
41 |
42 |
43 | locale={zhCN}
44 | generateConfig={momentGenerateConfig}
45 | dateRender={dateRender}
46 | {...disabledProps}
47 | />
48 |
49 |
50 | );
51 |
--------------------------------------------------------------------------------
/docs/examples/common.less:
--------------------------------------------------------------------------------
1 | h1,
2 | h2,
3 | h3,
4 | h4 {
5 | margin: 0;
6 | line-height: 200%;
7 | }
8 |
--------------------------------------------------------------------------------
/docs/examples/debug.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import '../../assets/index.less';
3 | import type { Locale } from '../../src/interface';
4 | import RangePicker from '../../src/PickerInput/RangePicker';
5 | import SinglePicker from '../../src/PickerInput/SinglePicker';
6 | import PickerPanel from '../../src/PickerPanel';
7 |
8 | import dayjs, { type Dayjs } from 'dayjs';
9 | import 'dayjs/locale/ar';
10 | import 'dayjs/locale/zh-cn';
11 | import buddhistEra from 'dayjs/plugin/buddhistEra';
12 | import LocalizedFormat from 'dayjs/plugin/localizedFormat';
13 | import dayjsGenerateConfig from '../../src/generate/dayjs';
14 | import dateFnsGenerateConfig from '../../src/generate/dateFns';
15 | import zhCN from '../../src/locale/zh_CN';
16 |
17 | dayjs.locale('zh-cn');
18 | // dayjs.locale('ar');
19 | dayjs.extend(buddhistEra);
20 | dayjs.extend(LocalizedFormat);
21 |
22 | console.clear();
23 |
24 | (window as any).dayjs = dayjs;
25 |
26 | const myLocale: Locale = {
27 | ...zhCN,
28 | // cellQuarterFormat: '第Q季度',
29 | // fieldYearFormat: 'BBBB',
30 | // cellYearFormat: 'BBBB',
31 | // yearFormat: 'BBBB',
32 | // cellDateFormat: '!d!',
33 | };
34 |
35 | const sharedLocale = {
36 | locale: myLocale,
37 | generateConfig: dayjsGenerateConfig,
38 | };
39 |
40 | const dateFnsSharedLocale = {
41 | locale: myLocale,
42 | generateConfig: dateFnsGenerateConfig,
43 | };
44 |
45 | export default () => {
46 | return (
47 |
48 |
49 | {/* console.error('>>>>>>>', val)}
53 | /> */}
54 | {
60 | // console.log('Date:', info);
61 | // return false;
62 | // }}
63 | // disabledTime={(date, range, info) => {
64 | // // console.log(`Time-${range}`, range, info);
65 | // const { from } = info;
66 |
67 | // if (from) {
68 | // console.log(
69 | // `Time-${range}`,
70 | // from.format('YYYY-MM-DD HH:mm:ss'),
71 | // date.format('YYYY-MM-DD HH:mm:ss'),
72 | // );
73 | // }
74 |
75 | // if (from && from.isSame(date, 'day')) {
76 | // return {
77 | // disabledHours: () => [from.hour()],
78 | // disabledMinutes: () => [0, 1, 2, 3],
79 | // disabledSeconds: () => [0, 1, 2, 3],
80 | // };
81 | // }
82 | // return {};
83 | // }}
84 | />
85 |
86 |
93 | {/* {
98 | console.log('Time Single:', ...args);
99 | return {};
100 | }}
101 | /> */}
102 | {/* console.error('>>>>>>>', val)}
107 | /> */}
108 |
109 | );
110 | };
111 |
--------------------------------------------------------------------------------
/docs/examples/disabledDate.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import type { Moment } from 'moment';
3 | import moment from 'moment';
4 | import Picker from '../../src';
5 | import momentGenerateConfig from '../../src/generate/moment';
6 | import enUS from '../../src/locale/en_US';
7 | import '../../assets/index.less';
8 |
9 | export default () => {
10 | const [value, setValue] = React.useState(undefined);
11 |
12 | const onSelect = (newValue: Moment) => {
13 | console.log('Select:', newValue);
14 | };
15 |
16 | const onChange = (newValue: Moment | null, formatString?: string) => {
17 | console.log('Change:', newValue, formatString);
18 | setValue(newValue);
19 | };
20 |
21 | function disabledDateBeforeToday(current: Moment) {
22 | return current <= moment().endOf('day');
23 | }
24 |
25 | function disabledDateAfterToday(current: Moment) {
26 | return current >= moment().endOf('day');
27 | }
28 |
29 | function disabledDateAfterTodayAndBeforeLastYear(current) {
30 | return current >= moment().startOf('day') || current < moment().subtract(1, 'years');
31 | }
32 |
33 | const sharedProps = {
34 | generateConfig: momentGenerateConfig,
35 | value,
36 | onSelect,
37 | onChange,
38 | };
39 |
40 | return (
41 |
42 |
Value: {value ? value.format('YYYY-MM-DD HH:mm:ss') : 'null'}
43 |
Date Mode
44 |
45 |
46 |
Before Today
47 |
{...sharedProps} disabledDate={disabledDateBeforeToday} locale={enUS} />
48 |
49 |
50 |
After Today
51 |
{...sharedProps} disabledDate={disabledDateAfterToday} locale={enUS} />
52 |
53 |
54 |
After Today or Before last year
55 |
56 | {...sharedProps}
57 | disabledDate={disabledDateAfterTodayAndBeforeLastYear}
58 | locale={enUS}
59 | />
60 |
61 |
62 |
63 | );
64 | };
65 |
--------------------------------------------------------------------------------
/docs/examples/focus.tsx:
--------------------------------------------------------------------------------
1 | import React, { useLayoutEffect, useRef, useState } from 'react';
2 | import '../../assets/index.less';
3 | import { Picker, RangePicker, type PickerRef } from '../../src';
4 | import momentGenerateConfig from '../../src/generate/moment';
5 | import zhCN from '../../src/locale/zh_CN';
6 | import type { RangePickerRef } from '../../src/interface';
7 |
8 | const MyPicker = () => {
9 | const ref = useRef(null);
10 | useLayoutEffect(() => {
11 | if (ref.current) {
12 | ref.current.focus({ preventScroll: true });
13 | }
14 | }, []);
15 |
16 | return (
17 |
20 | );
21 | };
22 |
23 | const MyRangePicker = () => {
24 | const ref = useRef(null);
25 | useLayoutEffect(() => {
26 | if (ref.current) {
27 | ref.current.focus({ preventScroll: true, index: 1 });
28 | }
29 | }, []);
30 |
31 | return (
32 |
33 |
34 |
35 | );
36 | };
37 |
38 | const Demo = () => {
39 | const [open, setOpen] = useState(false);
40 | const [open2, setOpen2] = useState(false);
41 | return (
42 |
52 | );
53 | };
54 |
55 | export default Demo;
56 |
--------------------------------------------------------------------------------
/docs/examples/limitation.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import '../../assets/index.less';
3 | import SinglePicker from '../../src/PickerInput/SinglePicker';
4 |
5 | import dayjs from 'dayjs';
6 | import 'dayjs/locale/ar';
7 | import 'dayjs/locale/zh-cn';
8 | import LocalizedFormat from 'dayjs/plugin/localizedFormat';
9 | import dayjsGenerateConfig from '../../src/generate/dayjs';
10 | import zhCN from '../../src/locale/zh_CN';
11 |
12 | dayjs.locale('zh-cn');
13 | dayjs.extend(LocalizedFormat);
14 |
15 | console.clear();
16 |
17 | (window as any).dayjs = dayjs;
18 |
19 | const sharedLocale = {
20 | locale: zhCN,
21 | generateConfig: dayjsGenerateConfig,
22 | style: { width: 300 },
23 | };
24 |
25 | export default () => {
26 | return (
27 |
28 |
36 |
43 |
50 |
51 | );
52 | };
53 |
--------------------------------------------------------------------------------
/docs/examples/locale.tsx:
--------------------------------------------------------------------------------
1 | import type { Moment } from 'moment';
2 | import moment from 'moment';
3 | import 'moment/locale/zh-cn';
4 | import React from 'react';
5 | import '../../assets/index.less';
6 | import Picker from '../../src';
7 | import momentGenerateConfig from '../../src/generate/moment';
8 | import enUS from '../../src/locale/en_US';
9 | import zhCN from '../../src/locale/zh_CN';
10 |
11 | // const defaultValue = moment('2019-09-03 05:02:03');
12 | const defaultValue = moment('2019-11-28 01:02:03');
13 |
14 | export default () => {
15 | const [locale, setLocale] = React.useState(enUS);
16 | const [value, setValue] = React.useState(defaultValue);
17 |
18 | const onChange = (newValue: Moment | null, formatString?: string) => {
19 | console.log('Change:', newValue, formatString);
20 | setValue(newValue);
21 | };
22 |
23 | const sharedProps = {
24 | generateConfig: momentGenerateConfig,
25 | value,
26 | onChange,
27 | presets: [
28 | {
29 | label: 'Hello World!',
30 | value: moment(),
31 | },
32 | {
33 | label: 'Now',
34 | value: () => moment(),
35 | },
36 | ],
37 | };
38 |
39 | return (
40 |
41 |
{...sharedProps} locale={locale} format="dddd" />
42 |
54 |
55 | );
56 | };
57 |
--------------------------------------------------------------------------------
/docs/examples/modes.tsx:
--------------------------------------------------------------------------------
1 | import moment, { type Moment } from 'moment';
2 | import React from 'react';
3 | import '../../assets/index.less';
4 | import { RangePicker } from '../../src';
5 | import momentGenerateConfig from '../../src/generate/moment';
6 | import zhCN from '../../src/locale/zh_CN';
7 | import './common.less';
8 |
9 | const defaultStartValue = moment('2019-09-03 05:02:03');
10 | const defaultEndValue = moment('2019-11-28 01:02:03');
11 |
12 | function formatDate(date: Moment | null) {
13 | return date ? date.format('YYYY-MM-DD HH:mm:ss') : null;
14 | }
15 |
16 | export default () => {
17 | const [value, setValue] = React.useState<[Moment | null, Moment | null] | null>([
18 | defaultStartValue,
19 | defaultEndValue,
20 | ]);
21 |
22 | const onChange = (newValue: [Moment | null, Moment | null] | null, formatStrings?: string[]) => {
23 | console.log('Change:', newValue, formatStrings);
24 | setValue(newValue);
25 | };
26 |
27 | const onPanelChange = (values: [Moment | null, Moment | null] | null) => {
28 | setValue(values);
29 | };
30 |
31 | const sharedProps = {
32 | generateConfig: momentGenerateConfig,
33 | value,
34 | onChange,
35 | onPanelChange,
36 | };
37 |
38 | return (
39 |
40 |
Value: {value ? `${formatDate(value[0])} ~ ${formatDate(value[1])}` : 'null'}
41 |
42 |
43 |
44 |
Basic
45 |
46 | {...sharedProps}
47 | locale={zhCN}
48 | mode={['month', 'month']}
49 | defaultValue={[moment('1990-09-03'), moment('1989-11-28')]}
50 | />
51 |
52 |
53 |
54 | );
55 | };
--------------------------------------------------------------------------------
/docs/examples/multiple.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import '../../assets/index.less';
3 | import type { PickerRef } from '../../src/interface';
4 | import SinglePicker from '../../src/PickerInput/SinglePicker';
5 |
6 | import dayjs from 'dayjs';
7 | import 'dayjs/locale/ar';
8 | import 'dayjs/locale/zh-cn';
9 | import LocalizedFormat from 'dayjs/plugin/localizedFormat';
10 | import dayjsGenerateConfig from '../../src/generate/dayjs';
11 | import zhCN from '../../src/locale/zh_CN';
12 |
13 | dayjs.locale('zh-cn');
14 | dayjs.extend(LocalizedFormat);
15 |
16 | console.clear();
17 |
18 | (window as any).dayjs = dayjs;
19 |
20 | const sharedLocale = {
21 | locale: zhCN,
22 | generateConfig: dayjsGenerateConfig,
23 | style: { width: 300 },
24 | };
25 |
26 | export default () => {
27 | const singleRef = React.useRef(null);
28 |
29 | return (
30 |
31 |
32 |
33 |
37 |
38 | );
39 | };
40 |
--------------------------------------------------------------------------------
/docs/examples/panel.tsx:
--------------------------------------------------------------------------------
1 | import moment, { type Moment } from 'moment';
2 | import React from 'react';
3 | import '../../assets/index.less';
4 | import { PickerPanel } from '../../src';
5 | import momentGenerateConfig from '../../src/generate/moment';
6 | import enUS from '../../src/locale/en_US';
7 | import jaJP from '../../src/locale/ja_JP';
8 | import zhCN from '../../src/locale/zh_CN';
9 |
10 | // const defaultValue = moment('2019-09-03 05:02:03');
11 | const defaultValue = moment('2019-11-28 01:02:03');
12 |
13 | export default () => {
14 | const [value, setValue] = React.useState(defaultValue);
15 |
16 | const onSelect = (newValue: Moment) => {
17 | console.log('Select:', newValue);
18 | };
19 |
20 | const onChange = (newValue: Moment | null, formatString?: string) => {
21 | console.log('Change:', newValue, formatString);
22 | setValue(newValue);
23 | };
24 |
25 | const sharedProps = {
26 | generateConfig: momentGenerateConfig,
27 | value,
28 | onSelect,
29 | onChange,
30 | };
31 |
32 | return (
33 |
34 |
Value: {value ? value.format('YYYY-MM-DD HH:mm:ss') : 'null'}
35 |
36 |
37 |
38 |
Basic
39 |
{...sharedProps} locale={zhCN} />
40 |
41 |
42 |
43 |
Uncontrolled
44 |
45 | generateConfig={momentGenerateConfig}
46 | locale={zhCN}
47 | onChange={onChange}
48 | defaultValue={moment('2000-01-01', 'YYYY-MM-DD')}
49 | />
50 |
51 |
52 |
53 |
1 Month earlier
54 |
55 | {...sharedProps}
56 | defaultPickerValue={defaultValue.clone().subtract(1, 'month')}
57 | locale={enUS}
58 | />
59 |
60 |
61 |
62 |
Week Picker CN
63 |
{...sharedProps} locale={zhCN} picker="week" />
64 |
65 |
66 |
67 |
Month Picker
68 |
{...sharedProps} locale={zhCN} picker="month" />
69 |
70 |
71 |
72 |
Quarter Picker
73 |
{...sharedProps} locale={zhCN} picker="quarter" />
74 |
75 |
76 |
77 |
Week Picker US
78 |
{...sharedProps} locale={enUS} picker="week" />
79 |
80 |
81 |
82 |
Time
83 |
{...sharedProps} locale={jaJP} picker="time" />
84 |
85 |
86 |
Uncontrolled
87 |
{...sharedProps} locale={jaJP} value={undefined} picker="time" />
88 |
89 |
90 |
Time AM/PM
91 |
92 | {...sharedProps}
93 | locale={jaJP}
94 | picker="time"
95 | showTime={{
96 | use12Hours: true,
97 | showSecond: false,
98 | format: 'hh:mm A',
99 | }}
100 | />
101 |
102 |
103 |
Datetime
104 |
{...sharedProps} locale={zhCN} showTime />
105 |
106 |
107 |
108 | );
109 | };
110 |
--------------------------------------------------------------------------------
/docs/examples/panelRender.tsx:
--------------------------------------------------------------------------------
1 | import type { Moment } from 'moment';
2 | import moment from 'moment';
3 | import React from 'react';
4 | import '../../assets/index.less';
5 | import Picker, { RangePicker } from '../../src';
6 | import momentGenerateConfig from '../../src/generate/moment';
7 | import zhCN from '../../src/locale/zh_CN';
8 | import './common.less';
9 |
10 | const defaultStartValue = moment('2019-09-03 05:02:03');
11 | const defaultEndValue = moment('2019-11-28 01:02:03');
12 | const defaultValue: [Moment, Moment] = [defaultStartValue, defaultEndValue];
13 |
14 | export default () => {
15 | const [customizeNode, setCustomizeNode] = React.useState(false);
16 |
17 | return (
18 | <>
19 | {String(customizeNode)}
20 |
21 |
22 |
Picker
23 |
24 | generateConfig={momentGenerateConfig}
25 | locale={zhCN}
26 | allowClear
27 | defaultValue={defaultStartValue}
28 | panelRender={(node) => (
29 | <>
30 |
39 |
40 | {customizeNode ? My Panel : node}
41 | >
42 | )}
43 | />
44 |
45 |
46 |
RangePicker
47 |
48 | generateConfig={momentGenerateConfig}
49 | locale={zhCN}
50 | allowClear
51 | defaultValue={defaultValue}
52 | panelRender={(node) => (
53 | <>
54 |
63 | {customizeNode ? My Panel : node}
64 | >
65 | )}
66 | />
67 |
68 |
69 | >
70 | );
71 | };
72 |
--------------------------------------------------------------------------------
/docs/examples/slide.less:
--------------------------------------------------------------------------------
1 | @animation-duration-base: 0.2s;
2 | @ease-out-quint: cubic-bezier(0.23, 1, 0.32, 1);
3 | @ease-in-quint: cubic-bezier(0.755, 0.05, 0.855, 0.06);
4 |
5 | .motion-common(@duration: @animation-duration-base) {
6 | animation-duration: @duration;
7 | animation-fill-mode: both;
8 | }
9 |
10 | .motion-common-leave(@duration: @animation-duration-base) {
11 | animation-duration: @duration;
12 | animation-fill-mode: both;
13 | }
14 |
15 | .make-motion(@className, @keyframeName, @duration: @animation-duration-base) {
16 | .@{className}-enter,
17 | .@{className}-appear {
18 | .motion-common(@duration);
19 |
20 | animation-play-state: paused;
21 | }
22 | .@{className}-leave {
23 | .motion-common-leave(@duration);
24 |
25 | animation-play-state: paused;
26 | }
27 | .@{className}-enter.@{className}-enter-active,
28 | .@{className}-appear.@{className}-appear-active {
29 | animation-name: ~'@{keyframeName}In';
30 | animation-play-state: running;
31 | }
32 | .@{className}-leave.@{className}-leave-active {
33 | animation-name: ~'@{keyframeName}Out';
34 | animation-play-state: running;
35 | pointer-events: none;
36 | }
37 | }
38 |
39 | .slide-motion(@className, @keyframeName) {
40 | .make-motion(@className, @keyframeName);
41 | .@{className}-enter,
42 | .@{className}-appear {
43 | opacity: 0;
44 | animation-timing-function: @ease-out-quint;
45 | }
46 | .@{className}-leave {
47 | animation-timing-function: @ease-in-quint;
48 | }
49 | }
50 |
51 | .slide-motion(slide-up, antSlideUp);
52 | .slide-motion(slide-down, antSlideDown);
53 | .slide-motion(slide-left, antSlideLeft);
54 | .slide-motion(slide-right, antSlideRight);
55 |
56 | @keyframes antSlideUpIn {
57 | 0% {
58 | transform: scaleY(0.8);
59 | transform-origin: 0% 0%;
60 | opacity: 0;
61 | }
62 | 100% {
63 | transform: scaleY(1);
64 | transform-origin: 0% 0%;
65 | opacity: 1;
66 | }
67 | }
68 |
69 | @keyframes antSlideUpOut {
70 | 0% {
71 | transform: scaleY(1);
72 | transform-origin: 0% 0%;
73 | opacity: 1;
74 | }
75 | 100% {
76 | transform: scaleY(0.8);
77 | transform-origin: 0% 0%;
78 | opacity: 0;
79 | }
80 | }
81 |
82 | @keyframes antSlideDownIn {
83 | 0% {
84 | transform: scaleY(0.8);
85 | transform-origin: 100% 100%;
86 | opacity: 0;
87 | }
88 | 100% {
89 | transform: scaleY(1);
90 | transform-origin: 100% 100%;
91 | opacity: 1;
92 | }
93 | }
94 |
95 | @keyframes antSlideDownOut {
96 | 0% {
97 | transform: scaleY(1);
98 | transform-origin: 100% 100%;
99 | opacity: 1;
100 | }
101 | 100% {
102 | transform: scaleY(0.8);
103 | transform-origin: 100% 100%;
104 | opacity: 0;
105 | }
106 | }
107 |
108 | @keyframes antSlideLeftIn {
109 | 0% {
110 | transform: scaleX(0.8);
111 | transform-origin: 0% 0%;
112 | opacity: 0;
113 | }
114 | 100% {
115 | transform: scaleX(1);
116 | transform-origin: 0% 0%;
117 | opacity: 1;
118 | }
119 | }
120 |
121 | @keyframes antSlideLeftOut {
122 | 0% {
123 | transform: scaleX(1);
124 | transform-origin: 0% 0%;
125 | opacity: 1;
126 | }
127 | 100% {
128 | transform: scaleX(0.8);
129 | transform-origin: 0% 0%;
130 | opacity: 0;
131 | }
132 | }
133 |
134 | @keyframes antSlideRightIn {
135 | 0% {
136 | transform: scaleX(0.8);
137 | transform-origin: 100% 0%;
138 | opacity: 0;
139 | }
140 | 100% {
141 | transform: scaleX(1);
142 | transform-origin: 100% 0%;
143 | opacity: 1;
144 | }
145 | }
146 |
147 | @keyframes antSlideRightOut {
148 | 0% {
149 | transform: scaleX(1);
150 | transform-origin: 100% 0%;
151 | opacity: 1;
152 | }
153 | 100% {
154 | transform: scaleX(0.8);
155 | transform-origin: 100% 0%;
156 | opacity: 0;
157 | }
158 | }
159 |
--------------------------------------------------------------------------------
/docs/examples/switchType.tsx:
--------------------------------------------------------------------------------
1 | import type { Moment } from 'moment';
2 | import React, { useState } from 'react';
3 | import '../../assets/index.less';
4 | import Picker from '../../src';
5 | import momentGenerateConfig from '../../src/generate/moment';
6 | import zhCN from '../../src/locale/zh_CN';
7 |
8 | const sharedProps = {
9 | generateConfig: momentGenerateConfig,
10 | };
11 |
12 | function PickerWithType({ type, onChange }) {
13 | if (type === 'date') return {...sharedProps} onChange={onChange} locale={zhCN} />;
14 | return {...sharedProps} picker={type} onChange={onChange} locale={zhCN} />;
15 | }
16 |
17 | export default function SwitchablePicker() {
18 | const [type, setType] = useState('date');
19 | return (
20 | <>
21 |
33 | console.log(value)} />
34 | >
35 | );
36 | }
37 |
--------------------------------------------------------------------------------
/docs/examples/time.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import moment from 'moment';
3 | import Picker, { RangePicker } from '../../src';
4 | import momentGenerateConfig from '../../src/generate/moment';
5 | import zhCN from '../../src/locale/zh_CN';
6 | import '../../assets/index.less';
7 |
8 | const defaultValue = moment('2019-11-28 01:02:03');
9 | const testClassNames = {
10 | input: 'test-input',
11 | prefix: 'test-prefix',
12 | suffix: 'test-suffix',
13 | popupContent: 'test-popup-content',
14 | popupItem: 'test-popup-item',
15 | }
16 |
17 | export default () => {
18 | return (
19 |
20 |
DatePicker
21 |
({
26 | disabledHours: () => [0, 1, 2, 3, 4, 5, 6, 20, 21],
27 | })}
28 | locale={zhCN}
29 | generateConfig={momentGenerateConfig}
30 | />
31 |
32 | TimePicker
33 | ({
41 | disabledHours: () => [now.hours()],
42 | })}
43 | generateConfig={momentGenerateConfig}
44 | />
45 |
46 | RangePicker
47 | ({
53 | disabledHours: () => (type === 'start' ? [now.hours()] : [now.hours() - 5]),
54 | })}
55 | />
56 |
57 | );
58 | };
59 |
--------------------------------------------------------------------------------
/docs/examples/uncontrolled.tsx:
--------------------------------------------------------------------------------
1 | import { type Moment } from 'moment';
2 | import React from 'react';
3 | import '../../assets/index.less';
4 | import Picker, { RangePicker } from '../../src';
5 | import momentGenerateConfig from '../../src/generate/moment';
6 | import zhCN from '../../src/locale/zh_CN';
7 |
8 | export default () => (
9 |
10 |
11 |
Uncontrolled
12 |
13 | generateConfig={momentGenerateConfig}
14 | locale={zhCN}
15 | picker="week"
16 | allowClear
17 | onOpenChange={(open) => {
18 | console.log('1 =>', open);
19 | }}
20 | />
21 |
22 | generateConfig={momentGenerateConfig}
23 | locale={zhCN}
24 | picker="week"
25 | allowClear
26 | open
27 | onOpenChange={(open) => {
28 | console.log('2 =>', open);
29 | }}
30 | />
31 |
32 | generateConfig={momentGenerateConfig}
33 | locale={zhCN}
34 | picker="week"
35 | allowClear
36 | // open
37 | onOpenChange={(open) => {
38 | console.log('3 =>', open);
39 | }}
40 | />
41 |
42 |
43 |
44 | );
45 |
--------------------------------------------------------------------------------
/docs/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | hero:
3 | title: rc-picker
4 | description: React picker component
5 | ---
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | module.exports = require('./src/');
2 |
--------------------------------------------------------------------------------
/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | coveragePathIgnorePatterns: ['src/locale/', 'tests/'],
3 | };
4 |
--------------------------------------------------------------------------------
/now.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 2,
3 | "name": "rc-picker",
4 | "builds": [
5 | {
6 | "src": "package.json",
7 | "use": "@now/static-build",
8 | "config": { "distDir": "dist" }
9 | }
10 | ],
11 | "routes": [{ "src": "/(.*)", "dest": "/dist/$1" }]
12 | }
13 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@rc-component/picker",
3 | "version": "1.3.0",
4 | "description": "React date & time picker",
5 | "keywords": [
6 | "react",
7 | "react-component",
8 | "react-picker"
9 | ],
10 | "main": "./lib/index",
11 | "module": "./es/index",
12 | "files": [
13 | "assets/*.css",
14 | "assets/*.less",
15 | "es",
16 | "lib"
17 | ],
18 | "homepage": "https://react-component.github.io/picker",
19 | "repository": {
20 | "type": "git",
21 | "url": "git@github.com:react-component/picker.git"
22 | },
23 | "bugs": {
24 | "url": "http://github.com/react-component/picker/issues"
25 | },
26 | "license": "MIT",
27 | "scripts": {
28 | "start": "dumi dev",
29 | "build": "dumi build",
30 | "compile": "father build && lessc assets/index.less assets/index.css",
31 | "gh-pages": "npm run build && father doc deploy",
32 | "prepublishOnly": "npm run compile && rc-np",
33 | "lint": "eslint src/ --ext .ts,.tsx,.jsx,.js,.md",
34 | "lint:tsc": "tsc -p tsconfig.json --noEmit",
35 | "prettier": "prettier --write \"**/*.{ts,tsx,js,jsx,json,md}\"",
36 | "test": "rc-test",
37 | "coverage": "father test --coverage",
38 | "now-build": "npm run build",
39 | "prepare": "npx husky"
40 | },
41 | "dependencies": {
42 | "@rc-component/resize-observer": "^1.0.0",
43 | "@rc-component/trigger": "^3.0.0",
44 | "@rc-component/util": "^1.2.1",
45 | "classnames": "^2.2.1",
46 | "rc-overflow": "^1.3.2"
47 | },
48 | "engines": {
49 | "node": ">=8.x"
50 | },
51 | "devDependencies": {
52 | "@rc-component/father-plugin": "^1.0.0",
53 | "@rc-component/np":"^1.0.3",
54 | "@testing-library/react": "^16.0.0",
55 | "@types/classnames": "^2.2.9",
56 | "@types/jest": "^29.4.0",
57 | "@types/luxon": "^3.2.0",
58 | "@types/react": "^18.0.28",
59 | "@types/react-dom": "^18.0.8",
60 | "coveralls": "^3.0.6",
61 | "cross-env": "^7.0.2",
62 | "date-fns": "2.x",
63 | "dayjs": "1.x",
64 | "dumi": "^2.1.15",
65 | "eslint": "^8.56.0",
66 | "eslint-plugin-eslint-comments": "^3.2.0",
67 | "eslint-plugin-jest": "^28.8.1",
68 | "eslint-plugin-react-hooks": "^4.6.0",
69 | "eslint-plugin-unicorn": "^55.0.0",
70 | "father": "^4.0.0",
71 | "glob": "^10.4.1",
72 | "husky": "^9.0.11",
73 | "less": "^4.2.0",
74 | "lint-staged": "^15.2.7",
75 | "luxon": "3.x",
76 | "mockdate": "^3.0.2",
77 | "moment": "^2.24.0",
78 | "moment-timezone": "^0.5.45",
79 | "prettier": "^3.1.0",
80 | "rc-test": "^7.0.9",
81 | "react": "^18.2.0",
82 | "react-dom": "^18.2.0",
83 | "typescript": "^5.3.0"
84 | },
85 | "peerDependencies": {
86 | "date-fns": ">= 2.x",
87 | "dayjs": ">= 1.x",
88 | "luxon": ">= 3.x",
89 | "moment": ">= 2.x",
90 | "react": ">=16.9.0",
91 | "react-dom": ">=16.9.0"
92 | },
93 | "peerDependenciesMeta": {
94 | "date-fns": {
95 | "optional": true
96 | },
97 | "dayjs": {
98 | "optional": true
99 | },
100 | "luxon": {
101 | "optional": true
102 | },
103 | "moment": {
104 | "optional": true
105 | }
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/src/PickerInput/Popup/Footer.tsx:
--------------------------------------------------------------------------------
1 | import cls from 'classnames';
2 | import * as React from 'react';
3 | import type { GenerateConfig } from '../../generate';
4 | import useTimeInfo from '../../hooks/useTimeInfo';
5 | import type { DisabledDate, InternalMode, PanelMode, SharedPickerProps } from '../../interface';
6 | import PickerContext from '../context';
7 | import type { PopupShowTimeConfig } from '.';
8 |
9 | export interface FooterProps {
10 | mode: PanelMode;
11 | internalMode: InternalMode;
12 | renderExtraFooter?: SharedPickerProps['renderExtraFooter'];
13 | showNow: boolean;
14 | generateConfig: GenerateConfig;
15 | disabledDate: DisabledDate;
16 | showTime?: PopupShowTimeConfig;
17 |
18 | // Invalid
19 | /** From Footer component used only. Check if can OK button click */
20 | invalid?: boolean;
21 |
22 | // Submit
23 | onSubmit: (date?: DateType) => void;
24 | needConfirm: boolean;
25 |
26 | // Now
27 | onNow: (now: DateType) => void;
28 | }
29 |
30 | export default function Footer(props: FooterProps) {
31 | const {
32 | mode,
33 | internalMode,
34 | renderExtraFooter,
35 | showNow,
36 | showTime,
37 | onSubmit,
38 | onNow,
39 | invalid,
40 | needConfirm,
41 | generateConfig,
42 | disabledDate,
43 | } = props;
44 |
45 | const {
46 | prefixCls,
47 | locale,
48 | button: Button = 'button',
49 | classNames,
50 | styles,
51 | } = React.useContext(PickerContext);
52 |
53 | // >>> Now
54 | const now = generateConfig.getNow();
55 |
56 | const [getValidTime] = useTimeInfo(generateConfig, showTime, now);
57 |
58 | // ======================== Extra =========================
59 | const extraNode = renderExtraFooter?.(mode);
60 |
61 | // ======================== Ranges ========================
62 | const nowDisabled = disabledDate(now, {
63 | type: mode,
64 | });
65 |
66 | const onInternalNow = () => {
67 | if (!nowDisabled) {
68 | const validateNow = getValidTime(now);
69 | onNow(validateNow);
70 | }
71 | };
72 |
73 | const nowPrefixCls = `${prefixCls}-now`;
74 | const nowBtnPrefixCls = `${nowPrefixCls}-btn`;
75 |
76 | const presetNode = showNow && (
77 |
78 |
83 | {internalMode === 'date' ? locale.today : locale.now}
84 |
85 |
86 | );
87 |
88 | // >>> OK
89 | const okNode = needConfirm && (
90 |
91 |
94 |
95 | );
96 |
97 | const rangeNode = (presetNode || okNode) && (
98 |
99 | {presetNode}
100 | {okNode}
101 |
102 | );
103 |
104 | // ======================== Render ========================
105 | if (!extraNode && !rangeNode) {
106 | return null;
107 | }
108 |
109 | return (
110 |
114 | {extraNode &&
{extraNode}
}
115 | {rangeNode}
116 |
117 | );
118 | }
119 |
--------------------------------------------------------------------------------
/src/PickerInput/Popup/PopupPanel.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import PickerPanel, { type PickerPanelProps } from '../../PickerPanel';
3 | import { PickerHackContext, type PickerHackContextProps } from '../../PickerPanel/context';
4 | import PickerContext from '../context';
5 | import { offsetPanelDate } from '../hooks/useRangePickerValue';
6 | import { type FooterProps } from './Footer';
7 |
8 | export type MustProp = Required<
9 | Pick, 'mode' | 'onPanelChange'>
10 | >;
11 |
12 | export type PopupPanelProps = MustProp &
13 | Omit, 'onPickerValueChange' | 'showTime'> &
14 | FooterProps & {
15 | multiplePanel?: boolean;
16 | range?: boolean;
17 |
18 | onPickerValueChange: (date: DateType) => void;
19 | };
20 |
21 | export default function PopupPanel(
22 | props: PopupPanelProps,
23 | ) {
24 | const {
25 | picker,
26 | multiplePanel,
27 | pickerValue,
28 | onPickerValueChange,
29 | needConfirm,
30 | onSubmit,
31 | range,
32 | hoverValue,
33 | } = props;
34 | const { prefixCls, generateConfig } = React.useContext(PickerContext);
35 |
36 | // ======================== Offset ========================
37 | const internalOffsetDate = React.useCallback(
38 | (date: DateType, offset: number) => {
39 | return offsetPanelDate(generateConfig, picker, date, offset);
40 | },
41 | [generateConfig, picker],
42 | );
43 |
44 | const nextPickerValue = React.useMemo(
45 | () => internalOffsetDate(pickerValue, 1),
46 | [pickerValue, internalOffsetDate],
47 | );
48 |
49 | // Outside
50 | const onSecondPickerValueChange = (nextDate: DateType) => {
51 | onPickerValueChange(internalOffsetDate(nextDate, -1));
52 | };
53 |
54 | // ======================= Context ========================
55 | const sharedContext: PickerHackContextProps = {
56 | onCellDblClick: () => {
57 | if (needConfirm) {
58 | onSubmit();
59 | }
60 | },
61 | };
62 |
63 | const hideHeader = picker === 'time';
64 |
65 | // ======================== Props =========================
66 | const pickerProps = {
67 | ...props,
68 | hoverValue: null,
69 | hoverRangeValue: null,
70 | hideHeader,
71 | };
72 |
73 | if (range) {
74 | pickerProps.hoverRangeValue = hoverValue;
75 | } else {
76 | pickerProps.hoverValue = hoverValue;
77 | }
78 |
79 | // ======================== Render ========================
80 | // Multiple
81 | if (multiplePanel) {
82 | return (
83 |
84 |
90 | {...pickerProps} />
91 |
92 |
98 |
99 | {...pickerProps}
100 | pickerValue={nextPickerValue}
101 | onPickerValueChange={onSecondPickerValueChange}
102 | />
103 |
104 |
105 | );
106 | }
107 |
108 | // Single
109 | return (
110 |
115 |
116 |
117 | );
118 | }
119 |
--------------------------------------------------------------------------------
/src/PickerInput/Popup/PresetPanel.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import type { ValueDate } from '../../interface';
3 |
4 | export interface PresetPanelProps {
5 | prefixCls: string;
6 | presets: ValueDate[];
7 | onClick: (value: ValueType) => void;
8 | onHover: (value: ValueType) => void;
9 | }
10 |
11 | function executeValue(value: ValueDate['value']): ValueType {
12 | return typeof value === 'function' ? value() : value;
13 | }
14 |
15 | export default function PresetPanel(
16 | props: PresetPanelProps,
17 | ) {
18 | const { prefixCls, presets, onClick, onHover } = props;
19 |
20 | if (!presets.length) {
21 | return null;
22 | }
23 |
24 | return (
25 |
26 |
27 | {presets.map(({ label, value }, index) => (
28 | - {
31 | onClick(executeValue(value));
32 | }}
33 | onMouseEnter={() => {
34 | onHover(executeValue(value));
35 | }}
36 | onMouseLeave={() => {
37 | onHover(null);
38 | }}
39 | >
40 | {label}
41 |
42 | ))}
43 |
44 |
45 | );
46 | }
47 |
--------------------------------------------------------------------------------
/src/PickerInput/Selector/Icon.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import PickerContext from '../context';
3 | import cls from 'classnames';
4 |
5 | export interface IconProps extends React.HtmlHTMLAttributes {
6 | icon?: React.ReactNode;
7 | type: 'suffix' | 'clear';
8 | }
9 |
10 | export default function Icon(props: IconProps) {
11 | const { icon, type, ...restProps } = props;
12 | const { prefixCls, classNames, styles } = React.useContext(PickerContext);
13 |
14 | return icon ? (
15 |
20 | {icon}
21 |
22 | ) : null;
23 | }
24 |
25 | export interface ClearIconProps extends Omit {
26 | onClear: VoidFunction;
27 | }
28 |
29 | export function ClearIcon({ onClear, ...restProps }: ClearIconProps) {
30 | return (
31 | {
36 | e.preventDefault();
37 | }}
38 | onClick={(e) => {
39 | e.stopPropagation();
40 | onClear();
41 | }}
42 | />
43 | );
44 | }
45 |
--------------------------------------------------------------------------------
/src/PickerInput/Selector/MaskFormat.ts:
--------------------------------------------------------------------------------
1 | const FORMAT_KEYS = ['YYYY', 'MM', 'DD', 'HH', 'mm', 'ss', 'SSS'];
2 |
3 | export type FormatKey = (typeof FORMAT_KEYS)[number];
4 |
5 | // Use Chinese character to avoid conflict with the mask format
6 | const REPLACE_KEY = '顧';
7 |
8 | export interface Cell {
9 | text: string;
10 | mask: boolean;
11 | start: number;
12 | end: number;
13 | }
14 |
15 | export default class MaskFormat {
16 | format: string;
17 | maskFormat: string;
18 | cells: Cell[];
19 | maskCells: Cell[];
20 |
21 | constructor(format: string) {
22 | this.format = format;
23 |
24 | // Generate mask format
25 | const replaceKeys = FORMAT_KEYS.map((key) => `(${key})`).join('|');
26 | const replaceReg = new RegExp(replaceKeys, 'g');
27 |
28 | this.maskFormat = format.replace(
29 | replaceReg,
30 | // Use Chinese character to avoid user use it in format
31 | (key: string) => REPLACE_KEY.repeat(key.length),
32 | );
33 |
34 | // Generate cells
35 | const cellReg = new RegExp(`(${FORMAT_KEYS.join('|')})`);
36 | const strCells = (format.split(cellReg) || []).filter((str) => str);
37 |
38 | let offset = 0;
39 | this.cells = strCells.map((text) => {
40 | const mask = FORMAT_KEYS.includes(text);
41 |
42 | const start = offset;
43 | const end = offset + text.length;
44 | offset = end;
45 |
46 | return {
47 | text,
48 | mask,
49 | start,
50 | end,
51 | };
52 | });
53 |
54 | // Mask cells
55 | this.maskCells = this.cells.filter((cell) => cell.mask);
56 | }
57 |
58 | getSelection(maskCellIndex: number): [start: number, end: number] {
59 | const { start, end } = this.maskCells[maskCellIndex] || {};
60 | return [start || 0, end || 0];
61 | }
62 |
63 | /** Check given text match format */
64 | match(text: string) {
65 | for (let i = 0; i < this.maskFormat.length; i += 1) {
66 | const maskChar = this.maskFormat[i];
67 | const textChar = text[i];
68 |
69 | if (!textChar || (maskChar !== REPLACE_KEY && maskChar !== textChar)) {
70 | return false;
71 | }
72 | }
73 |
74 | return true;
75 | }
76 |
77 | /** Get mask cell count */
78 | size() {
79 | return this.maskCells.length;
80 | }
81 |
82 | getMaskCellIndex(anchorIndex: number) {
83 | let closetDist = Number.MAX_SAFE_INTEGER;
84 | let closetIndex = 0;
85 |
86 | for (let i = 0; i < this.maskCells.length; i += 1) {
87 | const { start, end } = this.maskCells[i];
88 | if (anchorIndex >= start && anchorIndex <= end) {
89 | return i;
90 | }
91 |
92 | const dist = Math.min(Math.abs(anchorIndex - start), Math.abs(anchorIndex - end));
93 | if (dist < closetDist) {
94 | closetDist = dist;
95 | closetIndex = i;
96 | }
97 | }
98 |
99 | return closetIndex;
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/src/PickerInput/Selector/SingleSelector/MultipleDates.tsx:
--------------------------------------------------------------------------------
1 | import classNames from 'classnames';
2 | import Overflow from 'rc-overflow';
3 | import * as React from 'react';
4 | import type { PickerProps } from '../../SinglePicker';
5 |
6 | export interface MultipleDatesProps
7 | extends Pick {
8 | prefixCls: string;
9 | value: DateType[];
10 | onRemove: (value: DateType) => void;
11 | removeIcon?: React.ReactNode;
12 | formatDate: (date: DateType) => string;
13 | disabled?: boolean;
14 | placeholder?: React.ReactNode;
15 | }
16 |
17 | export default function MultipleDates(
18 | props: MultipleDatesProps,
19 | ) {
20 | const {
21 | prefixCls,
22 | value,
23 | onRemove,
24 | removeIcon = '×',
25 | formatDate,
26 | disabled,
27 | maxTagCount,
28 | placeholder,
29 | } = props;
30 |
31 | const selectorCls = `${prefixCls}-selector`;
32 | const selectionCls = `${prefixCls}-selection`;
33 | const overflowCls = `${selectionCls}-overflow`;
34 |
35 | // ========================= Item =========================
36 | function renderSelector(content: React.ReactNode, onClose?: React.MouseEventHandler) {
37 | return (
38 |
42 | {content}
43 | {!disabled && onClose && (
44 | {
46 | e.preventDefault();
47 | }}
48 | onClick={onClose}
49 | className={`${selectionCls}-item-remove`}
50 | >
51 | {removeIcon}
52 |
53 | )}
54 |
55 | );
56 | }
57 |
58 | function renderItem(date: DateType) {
59 | const displayLabel: React.ReactNode = formatDate(date);
60 |
61 | const onClose = (event?: React.MouseEvent) => {
62 | if (event) event.stopPropagation();
63 | onRemove(date);
64 | };
65 |
66 | return renderSelector(displayLabel, onClose);
67 | }
68 |
69 | // ========================= Rest =========================
70 | function renderRest(omittedValues: DateType[]) {
71 | const content = `+ ${omittedValues.length} ...`;
72 |
73 | return renderSelector(content);
74 | }
75 |
76 | // ======================== Render ========================
77 |
78 | return (
79 |
80 | formatDate(date)}
87 | maxCount={maxTagCount}
88 | />
89 | {!value.length && {placeholder}}
90 |
91 | );
92 | }
93 |
--------------------------------------------------------------------------------
/src/PickerInput/Selector/hooks/useClearIcon.tsx:
--------------------------------------------------------------------------------
1 | import warning from '@rc-component/util/lib/warning';
2 | import type { ReactNode } from 'react';
3 | import * as React from 'react';
4 |
5 | /**
6 | * Used for `useFilledProps` since it already in the React.useMemo
7 | */
8 | export function fillClearIcon(
9 | prefixCls: string,
10 | allowClear?: boolean | { clearIcon?: ReactNode },
11 | clearIcon?: ReactNode,
12 | ) {
13 | if (process.env.NODE_ENV !== 'production' && clearIcon) {
14 | warning(false, '`clearIcon` will be removed in future. Please use `allowClear` instead.');
15 | }
16 |
17 | if (allowClear === false) {
18 | return null;
19 | }
20 |
21 | const config = allowClear && typeof allowClear === 'object' ? allowClear : {};
22 |
23 | return config.clearIcon || clearIcon || ;
24 | }
25 |
--------------------------------------------------------------------------------
/src/PickerInput/Selector/hooks/useRootProps.ts:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import { pickProps } from '../../../utils/miscUtil';
3 |
4 | const propNames = ['onMouseEnter', 'onMouseLeave'] as const;
5 |
6 | export default function useRootProps(props: React.HTMLAttributes) {
7 | return React.useMemo(() => pickProps(props, propNames), [props]);
8 | }
9 |
--------------------------------------------------------------------------------
/src/PickerInput/Selector/util.ts:
--------------------------------------------------------------------------------
1 | import type { FormatKey } from './MaskFormat';
2 |
3 | export function getMaskRange(key: string): [startVal: number, endVal: number, defaultVal?: number] {
4 | const PresetRange: Record = {
5 | YYYY: [0, 9999, new Date().getFullYear()],
6 | MM: [1, 12],
7 | DD: [1, 31],
8 | HH: [0, 23],
9 | mm: [0, 59],
10 | ss: [0, 59],
11 | SSS: [0, 999],
12 | };
13 |
14 | return PresetRange[key];
15 | }
--------------------------------------------------------------------------------
/src/PickerInput/context.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import type { GenerateConfig } from '../generate';
3 | import type { Components, Locale } from '../interface';
4 | import type { FilledClassNames, FilledStyles } from '../hooks/useSemantic';
5 |
6 | export interface PickerContextProps {
7 | prefixCls: string;
8 | locale: Locale;
9 | generateConfig: GenerateConfig;
10 | /** Customize button component */
11 | button?: Components['button'];
12 | input?: Components['input'];
13 | classNames: FilledClassNames;
14 | styles: FilledStyles;
15 | }
16 |
17 | const PickerContext = React.createContext(null!);
18 |
19 | export default PickerContext;
20 |
--------------------------------------------------------------------------------
/src/PickerInput/hooks/useCellRender.ts:
--------------------------------------------------------------------------------
1 | import { warning } from '@rc-component/util';
2 | import * as React from 'react';
3 | import type { CellRender, CellRenderInfo, SharedPickerProps } from '../../interface';
4 |
5 | export default function useCellRender(
6 | cellRender: SharedPickerProps['cellRender'],
7 | dateRender?: SharedPickerProps['dateRender'],
8 | monthCellRender?: SharedPickerProps['monthCellRender'],
9 | range?: CellRenderInfo['range'],
10 | ) {
11 | // ========================= Warn =========================
12 | if (process.env.NODE_ENV !== 'production') {
13 | warning(!dateRender, `'dateRender' is deprecated. Please use 'cellRender' instead.`);
14 | warning(!monthCellRender, `'monthCellRender' is deprecated. Please use 'cellRender' instead.`);
15 | }
16 |
17 | // ======================== Render ========================
18 | // Merged render
19 | const mergedCellRender = React.useMemo(() => {
20 | if (cellRender) {
21 | return cellRender;
22 | }
23 |
24 | return (current: DateType | number, info: CellRenderInfo) => {
25 | const date = current as DateType;
26 |
27 | if (dateRender && info.type === 'date') {
28 | return dateRender(date, info.today);
29 | }
30 | if (monthCellRender && info.type === 'month') {
31 | return monthCellRender(date, info.locale);
32 | }
33 | return info.originNode;
34 | };
35 | }, [cellRender, monthCellRender, dateRender]);
36 |
37 | // Cell render
38 | const onInternalCellRender: CellRender = React.useCallback(
39 | (date, info) => mergedCellRender(date, { ...info, range }),
40 | [mergedCellRender, range],
41 | );
42 |
43 | return onInternalCellRender;
44 | }
45 |
--------------------------------------------------------------------------------
/src/PickerInput/hooks/useDelayState.ts:
--------------------------------------------------------------------------------
1 | import { useEvent, useMergedState } from '@rc-component/util';
2 | import raf from '@rc-component/util/lib/raf';
3 | import React from 'react';
4 |
5 | /**
6 | * Will be `true` immediately for next effect.
7 | * But will be `false` for a delay of effect.
8 | */
9 | export default function useDelayState(
10 | value: T,
11 | defaultValue?: T,
12 | onChange?: (next: T) => void,
13 | ): [state: T, setState: (nextState: T, immediately?: boolean) => void] {
14 | const [state, setState] = useMergedState(defaultValue, { value });
15 |
16 | const nextValueRef = React.useRef(value);
17 |
18 | // ============================= Update =============================
19 | const rafRef = React.useRef();
20 | const cancelRaf = () => {
21 | raf.cancel(rafRef.current);
22 | };
23 |
24 | const doUpdate = useEvent(() => {
25 | setState(nextValueRef.current);
26 |
27 | if (onChange && state !== nextValueRef.current) {
28 | onChange(nextValueRef.current);
29 | }
30 | });
31 |
32 | const updateValue = useEvent((next: T, immediately?: boolean) => {
33 | cancelRaf();
34 |
35 | nextValueRef.current = next;
36 |
37 | if (next || immediately) {
38 | doUpdate();
39 | } else {
40 | rafRef.current = raf(doUpdate);
41 | }
42 | });
43 |
44 | React.useEffect(() => cancelRaf, []);
45 |
46 | return [state, updateValue];
47 | }
48 |
--------------------------------------------------------------------------------
/src/PickerInput/hooks/useDisabledBoundary.ts:
--------------------------------------------------------------------------------
1 | import { useEvent } from '@rc-component/util';
2 | import type { GenerateConfig } from '../../generate';
3 | import { isSame } from '../../utils/dateUtil';
4 | import type { DisabledDate, InternalMode, Locale } from '../../interface';
5 |
6 | export type IsInvalidBoundary = (
7 | currentDate: DateType,
8 | type: InternalMode,
9 | fromDate?: DateType,
10 | ) => boolean;
11 |
12 | /**
13 | * Merge `disabledDate` with `minDate` & `maxDate`.
14 | */
15 | export default function useDisabledBoundary(
16 | generateConfig: GenerateConfig,
17 | locale: Locale,
18 | disabledDate?: DisabledDate,
19 | minDate?: DateType,
20 | maxDate?: DateType,
21 | ) {
22 | const mergedDisabledDate = useEvent>((date, info) => {
23 | if (disabledDate && disabledDate(date, info)) {
24 | return true;
25 | }
26 |
27 | if (
28 | minDate &&
29 | generateConfig.isAfter(minDate, date) &&
30 | !isSame(generateConfig, locale, minDate, date, info.type)
31 | ) {
32 | return true;
33 | }
34 |
35 | if (
36 | maxDate &&
37 | generateConfig.isAfter(date, maxDate) &&
38 | !isSame(generateConfig, locale, maxDate, date, info.type)
39 | ) {
40 | return true;
41 | }
42 |
43 | return false;
44 | });
45 |
46 | return mergedDisabledDate;
47 | }
48 |
--------------------------------------------------------------------------------
/src/PickerInput/hooks/useFieldFormat.ts:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import type { FormatType, InternalMode, Locale, SharedPickerProps } from '../../interface';
3 | import { getRowFormat, toArray } from '../../utils/miscUtil';
4 |
5 | export function useFieldFormat(
6 | picker: InternalMode,
7 | locale: Locale,
8 | format?: SharedPickerProps['format'],
9 | ): [formatList: FormatType[], maskFormat?: string] {
10 | return React.useMemo(() => {
11 | const rawFormat = getRowFormat(picker, locale, format);
12 |
13 | const formatList = toArray(rawFormat);
14 |
15 | const firstFormat = formatList[0];
16 | const maskFormat =
17 | typeof firstFormat === 'object' && firstFormat.type === 'mask' ? firstFormat.format : null;
18 |
19 | return [
20 | // Format list
21 | formatList.map((config) =>
22 | typeof config === 'string' || typeof config === 'function' ? config : config.format,
23 | ),
24 | // Mask Format
25 | maskFormat,
26 | ];
27 | }, [picker, locale, format]);
28 | }
29 |
--------------------------------------------------------------------------------
/src/PickerInput/hooks/useFieldsInvalidate.ts:
--------------------------------------------------------------------------------
1 | import { fillIndex } from '../../utils/miscUtil';
2 | import * as React from 'react';
3 | import type useInvalidate from './useInvalidate';
4 |
5 | /**
6 | * Used to control each fields invalidate status
7 | */
8 | export default function useFieldsInvalidate(
9 | calendarValue: ValueType,
10 | isInvalidateDate: ReturnType>,
11 | allowEmpty: boolean[] = [],
12 | ) {
13 | const [fieldsInvalidates, setFieldsInvalidates] = React.useState<[boolean, boolean]>([
14 | false,
15 | false,
16 | ]);
17 |
18 | const onSelectorInvalid = (invalid: boolean, index: number) => {
19 | setFieldsInvalidates((ori) => fillIndex(ori, index, invalid));
20 | };
21 |
22 | /**
23 | * For the Selector Input to mark as `aria-disabled`
24 | */
25 | const submitInvalidates = React.useMemo(() => {
26 | return fieldsInvalidates.map((invalid, index) => {
27 | // If typing invalidate
28 | if (invalid) {
29 | return true;
30 | }
31 |
32 | const current = calendarValue[index];
33 |
34 | // Not check if all empty
35 | if (!current) {
36 | return false;
37 | }
38 |
39 | // Not allow empty
40 | if (!allowEmpty[index] && !current) {
41 | return true;
42 | }
43 |
44 | // Invalidate
45 | if (current && isInvalidateDate(current, { activeIndex: index })) {
46 | return true;
47 | }
48 |
49 | return false;
50 | }) as [boolean, boolean];
51 | }, [calendarValue, fieldsInvalidates, isInvalidateDate, allowEmpty]);
52 |
53 | return [submitInvalidates, onSelectorInvalid] as const;
54 | }
55 |
--------------------------------------------------------------------------------
/src/PickerInput/hooks/useInputReadOnly.ts:
--------------------------------------------------------------------------------
1 | import type { FormatType } from '../../interface';
2 |
3 | export default function useInputReadOnly(
4 | formatList: FormatType[],
5 | inputReadOnly?: boolean,
6 | multiple?: boolean,
7 | ) {
8 | if (typeof formatList[0] === 'function' || multiple) {
9 | return true;
10 | }
11 |
12 | return inputReadOnly;
13 | }
14 |
--------------------------------------------------------------------------------
/src/PickerInput/hooks/useInvalidate.ts:
--------------------------------------------------------------------------------
1 | import { useEvent } from '@rc-component/util';
2 | import type { GenerateConfig } from '../../generate';
3 | import type {
4 | PanelMode,
5 | RangeTimeProps,
6 | SharedPickerProps,
7 | SharedTimeProps,
8 | } from '../../interface';
9 |
10 | /**
11 | * Check if provided date is valid for the `disabledDate` & `showTime.disabledTime`.
12 | */
13 | export default function useInvalidate(
14 | generateConfig: GenerateConfig,
15 | picker: PanelMode,
16 | disabledDate?: SharedPickerProps['disabledDate'],
17 | showTime?: SharedTimeProps | RangeTimeProps,
18 | ) {
19 | // Check disabled date
20 | const isInvalidate = useEvent(
21 | (date: DateType, info?: { from?: DateType; activeIndex: number }) => {
22 | const outsideInfo = { type: picker, ...info };
23 | delete outsideInfo.activeIndex;
24 |
25 | if (
26 | // Date object is invalid
27 | !generateConfig.isValidate(date) ||
28 | // Date is disabled by `disabledDate`
29 | (disabledDate && disabledDate(date, outsideInfo))
30 | ) {
31 | return true;
32 | }
33 |
34 | if ((picker === 'date' || picker === 'time') && showTime) {
35 | const range = info && info.activeIndex === 1 ? 'end' : 'start';
36 | const { disabledHours, disabledMinutes, disabledSeconds, disabledMilliseconds } =
37 | showTime.disabledTime?.(date, range, { from: outsideInfo.from }) || {};
38 |
39 | const {
40 | disabledHours: legacyDisabledHours,
41 | disabledMinutes: legacyDisabledMinutes,
42 | disabledSeconds: legacyDisabledSeconds,
43 | } = showTime;
44 |
45 | const mergedDisabledHours = disabledHours || legacyDisabledHours;
46 | const mergedDisabledMinutes = disabledMinutes || legacyDisabledMinutes;
47 | const mergedDisabledSeconds = disabledSeconds || legacyDisabledSeconds;
48 |
49 | const hour = generateConfig.getHour(date);
50 | const minute = generateConfig.getMinute(date);
51 | const second = generateConfig.getSecond(date);
52 | const millisecond = generateConfig.getMillisecond(date);
53 |
54 | if (mergedDisabledHours && mergedDisabledHours().includes(hour)) {
55 | return true;
56 | }
57 |
58 | if (mergedDisabledMinutes && mergedDisabledMinutes(hour).includes(minute)) {
59 | return true;
60 | }
61 |
62 | if (mergedDisabledSeconds && mergedDisabledSeconds(hour, minute).includes(second)) {
63 | return true;
64 | }
65 |
66 | if (
67 | disabledMilliseconds &&
68 | disabledMilliseconds(hour, minute, second).includes(millisecond)
69 | ) {
70 | return true;
71 | }
72 | }
73 | return false;
74 | },
75 | );
76 |
77 | return isInvalidate;
78 | }
79 |
--------------------------------------------------------------------------------
/src/PickerInput/hooks/useLockEffect.ts:
--------------------------------------------------------------------------------
1 | import { useLayoutUpdateEffect } from '@rc-component/util/lib/hooks/useLayoutEffect';
2 | import raf from '@rc-component/util/lib/raf';
3 | import * as React from 'react';
4 |
5 | /**
6 | * Trigger `callback` immediately when `condition` is `true`.
7 | * But trigger `callback` in next frame when `condition` is `false`.
8 | */
9 | export default function useLockEffect(
10 | condition: boolean,
11 | callback: (next: boolean) => void,
12 | delayFrames = 1,
13 | ) {
14 | const callbackRef = React.useRef(callback);
15 | callbackRef.current = callback;
16 |
17 | useLayoutUpdateEffect(() => {
18 | if (condition) {
19 | callbackRef.current(condition);
20 | } else {
21 | const id = raf(() => {
22 | callbackRef.current(condition);
23 | }, delayFrames);
24 |
25 | return () => {
26 | raf.cancel(id);
27 | };
28 | }
29 | }, [condition]);
30 | }
31 |
--------------------------------------------------------------------------------
/src/PickerInput/hooks/useOpen.ts:
--------------------------------------------------------------------------------
1 | import type { OpenConfig } from '../../interface';
2 | import useDelayState from './useDelayState';
3 |
4 | /**
5 | * Control the open state.
6 | * Will not close if activeElement is on the popup.
7 | */
8 | export default function useOpen(
9 | open?: boolean,
10 | defaultOpen?: boolean,
11 | disabledList: boolean[] = [],
12 | onOpenChange?: (open: boolean) => void,
13 | ): [open: boolean, setOpen: (open: boolean, config?: OpenConfig) => void] {
14 | const mergedOpen = disabledList.every((disabled) => disabled) ? false : open;
15 |
16 | // Delay for handle the open state, in case fast shift from `open` -> `close` -> `open`
17 | // const [rafOpen, setRafOpen] = useLockState(open, defaultOpen || false, onOpenChange);
18 | const [rafOpen, setRafOpen] = useDelayState(mergedOpen, defaultOpen || false, onOpenChange);
19 |
20 | function setOpen(next: boolean, config: OpenConfig = {}) {
21 | if (!config.inherit || rafOpen) {
22 | setRafOpen(next, config.force);
23 | }
24 | }
25 |
26 | return [rafOpen, setOpen];
27 | }
28 |
--------------------------------------------------------------------------------
/src/PickerInput/hooks/usePickerRef.ts:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import type { PickerRef } from '../../interface';
3 |
4 | type PickerRefType = Omit & {
5 | focus: (options?: OptionType) => void;
6 | };
7 |
8 | export default function usePickerRef(ref: React.Ref>) {
9 | const selectorRef = React.useRef>();
10 |
11 | React.useImperativeHandle(ref, () => ({
12 | nativeElement: selectorRef.current?.nativeElement,
13 | focus: (options) => {
14 | selectorRef.current?.focus(options);
15 | },
16 | blur: () => {
17 | selectorRef.current?.blur();
18 | },
19 | }));
20 |
21 | return selectorRef;
22 | }
23 |
--------------------------------------------------------------------------------
/src/PickerInput/hooks/usePresets.ts:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import warning from '@rc-component/util/lib/warning';
3 | import type { ValueDate } from '../../interface';
4 |
5 | export default function usePresets(
6 | presets?: ValueDate[],
7 | legacyRanges?: Record DateType)>,
8 | ): ValueDate[] {
9 | return React.useMemo(() => {
10 | if (presets) {
11 | return presets;
12 | }
13 |
14 | if (legacyRanges) {
15 | warning(false, '`ranges` is deprecated. Please use `presets` instead.');
16 |
17 | return Object.entries(legacyRanges).map(([label, value]) => ({ label, value }));
18 | }
19 |
20 | return [];
21 | }, [presets, legacyRanges]);
22 | }
23 |
--------------------------------------------------------------------------------
/src/PickerInput/hooks/useRangeActive.ts:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import type { RangeValueType } from '../RangePicker';
3 | import useLockEffect from './useLockEffect';
4 |
5 | export type OperationType = 'input' | 'panel';
6 |
7 | export type NextActive = (nextValue: RangeValueType) => number | null;
8 |
9 | /**
10 | * When user first focus one input, any submit will trigger focus another one.
11 | * When second time focus one input, submit will not trigger focus again.
12 | * When click outside to close the panel, trigger event if it can trigger onChange.
13 | */
14 | export default function useRangeActive(
15 | disabled: boolean[],
16 | empty: boolean[] = [],
17 | mergedOpen: boolean = false,
18 | ): [
19 | focused: boolean,
20 | triggerFocus: (focused: boolean) => void,
21 | lastOperation: (type?: OperationType) => OperationType,
22 | activeIndex: number,
23 | setActiveIndex: (index: number) => void,
24 | nextActiveIndex: NextActive,
25 | activeList: number[],
26 | updateSubmitIndex: (index: number | null) => void,
27 | hasActiveSubmitValue: (index: number) => boolean,
28 | ] {
29 | const [activeIndex, setActiveIndex] = React.useState(0);
30 | const [focused, setFocused] = React.useState(false);
31 |
32 | const activeListRef = React.useRef([]);
33 | const submitIndexRef = React.useRef(null);
34 | const lastOperationRef = React.useRef(null);
35 |
36 | const updateSubmitIndex = (index: number | null) => {
37 | submitIndexRef.current = index;
38 | };
39 |
40 | const hasActiveSubmitValue = (index: number) => {
41 | return submitIndexRef.current === index;
42 | };
43 |
44 | const triggerFocus = (nextFocus: boolean) => {
45 | setFocused(nextFocus);
46 | };
47 |
48 | // ============================= Record =============================
49 | const lastOperation = (type?: OperationType) => {
50 | if (type) {
51 | lastOperationRef.current = type;
52 | }
53 | return lastOperationRef.current;
54 | };
55 |
56 | // ============================ Strategy ============================
57 | // Trigger when input enter or input blur or panel close
58 | const nextActiveIndex: NextActive = (nextValue: RangeValueType) => {
59 | const list = activeListRef.current;
60 | const filledActiveSet = new Set(list.filter((index) => nextValue[index] || empty[index]));
61 | const nextIndex = list[list.length - 1] === 0 ? 1 : 0;
62 |
63 | if (filledActiveSet.size >= 2 || disabled[nextIndex]) {
64 | return null;
65 | }
66 |
67 | return nextIndex;
68 | };
69 |
70 | // ============================= Effect =============================
71 | // Wait in case it's from the click outside to blur
72 | useLockEffect(focused || mergedOpen, () => {
73 | if (!focused) {
74 | activeListRef.current = [];
75 | updateSubmitIndex(null);
76 | }
77 | });
78 |
79 | React.useEffect(() => {
80 | if (focused) {
81 | activeListRef.current.push(activeIndex);
82 | }
83 | }, [focused, activeIndex]);
84 |
85 | return [
86 | focused,
87 | triggerFocus,
88 | lastOperation,
89 | activeIndex,
90 | setActiveIndex,
91 | nextActiveIndex,
92 | activeListRef.current,
93 | updateSubmitIndex,
94 | hasActiveSubmitValue,
95 | ];
96 | }
97 |
--------------------------------------------------------------------------------
/src/PickerInput/hooks/useRangeDisabledDate.ts:
--------------------------------------------------------------------------------
1 | import type { GenerateConfig } from '../../generate';
2 | import { isSame } from '../../utils/dateUtil';
3 | import type { DisabledDate, Locale } from '../../interface';
4 | import type { RangeValueType } from '../RangePicker';
5 | import { getFromDate } from '../../utils/miscUtil';
6 |
7 | /**
8 | * RangePicker need additional logic to handle the `disabled` case. e.g.
9 | * [disabled, enabled] should end date not before start date
10 | */
11 | export default function useRangeDisabledDate(
12 | values: RangeValueType,
13 | disabled: [boolean, boolean],
14 | activeIndexList: number[],
15 | generateConfig: GenerateConfig,
16 | locale: Locale,
17 | disabledDate?: DisabledDate,
18 | ) {
19 | const activeIndex = activeIndexList[activeIndexList.length - 1];
20 |
21 | const rangeDisabledDate: DisabledDate = (date, info) => {
22 | const [start, end] = values;
23 |
24 | const mergedInfo = {
25 | ...info,
26 | from: getFromDate(values, activeIndexList),
27 | };
28 |
29 | // ============================ Disabled ============================
30 | // Should not select days before the start date
31 | if (
32 | activeIndex === 1 &&
33 | disabled[0] &&
34 | start &&
35 | // Same date isOK
36 | !isSame(generateConfig, locale, start, date, mergedInfo.type) &&
37 | // Before start date
38 | generateConfig.isAfter(start, date)
39 | ) {
40 | return true;
41 | }
42 |
43 | // Should not select days after the end date
44 | if (
45 | activeIndex === 0 &&
46 | disabled[1] &&
47 | end &&
48 | // Same date isOK
49 | !isSame(generateConfig, locale, end, date, mergedInfo.type) &&
50 | // After end date
51 | generateConfig.isAfter(date, end)
52 | ) {
53 | return true;
54 | }
55 |
56 | // ============================= Origin =============================
57 | return disabledDate?.(date, mergedInfo);
58 | };
59 |
60 | return rangeDisabledDate;
61 | }
62 |
--------------------------------------------------------------------------------
/src/PickerInput/hooks/useShowNow.ts:
--------------------------------------------------------------------------------
1 | import type { InternalMode, PanelMode } from '../../interface';
2 |
3 | export default function useShowNow(
4 | picker: InternalMode,
5 | mode: PanelMode,
6 | showNow?: boolean,
7 | showToday?: boolean,
8 | rangePicker?: boolean,
9 | ) {
10 | if (mode !== 'date' && mode !== 'time') {
11 | return false;
12 | }
13 |
14 | if (showNow !== undefined) {
15 | return showNow;
16 | }
17 |
18 | // Compatible with old version `showToday`
19 | if (showToday !== undefined) {
20 | return showToday;
21 | }
22 |
23 | return !rangePicker && (picker === 'date' || picker === 'time');
24 | }
25 |
--------------------------------------------------------------------------------
/src/PickerPanel/DateTimePanel/index.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import useTimeInfo from '../../hooks/useTimeInfo';
3 | import type { SharedPanelProps } from '../../interface';
4 | import { fillTime } from '../../utils/dateUtil';
5 | import DatePanel from '../DatePanel';
6 | import TimePanel from '../TimePanel';
7 |
8 | export default function DateTimePanel(
9 | props: SharedPanelProps,
10 | ) {
11 | const { prefixCls, generateConfig, showTime, onSelect, value, pickerValue, onHover } = props;
12 |
13 | const panelPrefixCls = `${prefixCls}-datetime-panel`;
14 |
15 | // =============================== Time ===============================
16 | const [getValidTime] = useTimeInfo(generateConfig, showTime);
17 |
18 | // Merge the time info from `value` or `pickerValue`
19 | const mergeTime = (date: DateType) => {
20 | if (value) {
21 | return fillTime(generateConfig, date, value);
22 | }
23 |
24 | return fillTime(generateConfig, date, pickerValue);
25 | };
26 |
27 | // ============================== Hover ===============================
28 | const onDateHover = (date: DateType) => {
29 | onHover?.(date ? mergeTime(date) : date);
30 | };
31 |
32 | // ============================== Select ==============================
33 | const onDateSelect = (date: DateType) => {
34 | // Merge with current time
35 | const cloneDate = mergeTime(date);
36 |
37 | onSelect(getValidTime(cloneDate, cloneDate));
38 | };
39 |
40 | // ============================== Render ==============================
41 | return (
42 |
43 |
44 |
45 |
46 | );
47 | }
48 |
--------------------------------------------------------------------------------
/src/PickerPanel/MonthPanel/index.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import type { DisabledDate, SharedPanelProps } from '../../interface';
3 | import { formatValue } from '../../utils/dateUtil';
4 | import { PanelContext, useInfo } from '../context';
5 | import PanelBody from '../PanelBody';
6 | import PanelHeader from '../PanelHeader';
7 |
8 | export default function MonthPanel(
9 | props: SharedPanelProps,
10 | ) {
11 | const {
12 | prefixCls,
13 | locale,
14 | generateConfig,
15 | pickerValue,
16 | disabledDate,
17 | onPickerValueChange,
18 | onModeChange,
19 | } = props;
20 |
21 | const panelPrefixCls = `${prefixCls}-month-panel`;
22 |
23 | // ========================== Base ==========================
24 | const [info] = useInfo(props, 'month');
25 | const baseDate = generateConfig.setMonth(pickerValue, 0);
26 |
27 | // ========================= Month ==========================
28 | const monthsLocale: string[] =
29 | locale.shortMonths ||
30 | (generateConfig.locale.getShortMonths
31 | ? generateConfig.locale.getShortMonths(locale.locale)
32 | : []);
33 |
34 | // ========================= Cells ==========================
35 | const getCellDate = (date: DateType, offset: number) => {
36 | return generateConfig.addMonth(date, offset);
37 | };
38 |
39 | const getCellText = (date: DateType) => {
40 | const month = generateConfig.getMonth(date);
41 |
42 | return locale.monthFormat
43 | ? formatValue(date, {
44 | locale,
45 | format: locale.monthFormat,
46 | generateConfig,
47 | })
48 | : monthsLocale[month];
49 | };
50 |
51 | const getCellClassName = () => ({
52 | [`${prefixCls}-cell-in-view`]: true,
53 | });
54 |
55 | // ======================== Disabled ========================
56 | const mergedDisabledDate: DisabledDate = disabledDate
57 | ? (currentDate, disabledInfo) => {
58 | const startDate = generateConfig.setDate(currentDate, 1);
59 | const nextMonthStartDate = generateConfig.setMonth(
60 | startDate,
61 | generateConfig.getMonth(startDate) + 1,
62 | );
63 | const endDate = generateConfig.addDate(nextMonthStartDate, -1);
64 |
65 | return disabledDate(startDate, disabledInfo) && disabledDate(endDate, disabledInfo);
66 | }
67 | : null;
68 |
69 | // ========================= Header =========================
70 | const yearNode: React.ReactNode = (
71 |
87 | );
88 |
89 | // ========================= Render =========================
90 | return (
91 |
92 |
93 | {/* Header */}
94 |
generateConfig.addYear(pickerValue, distance)}
96 | onChange={onPickerValueChange}
97 | // Limitation
98 | getStart={(date) => generateConfig.setMonth(date, 0)}
99 | getEnd={(date) => generateConfig.setMonth(date, 11)}
100 | >
101 | {yearNode}
102 |
103 |
104 | {/* Body */}
105 |
117 |
118 |
119 | );
120 | }
121 |
--------------------------------------------------------------------------------
/src/PickerPanel/QuarterPanel/index.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import type { SharedPanelProps } from '../../interface';
3 | import { formatValue } from '../../utils/dateUtil';
4 | import { PanelContext, useInfo } from '../context';
5 | import PanelBody from '../PanelBody';
6 | import PanelHeader from '../PanelHeader';
7 |
8 | export default function QuarterPanel(
9 | props: SharedPanelProps,
10 | ) {
11 | const { prefixCls, locale, generateConfig, pickerValue, onPickerValueChange, onModeChange } =
12 | props;
13 |
14 | const panelPrefixCls = `${prefixCls}-quarter-panel`;
15 |
16 | // ========================== Base ==========================
17 | const [info] = useInfo(props, 'quarter');
18 | const baseDate = generateConfig.setMonth(pickerValue, 0);
19 |
20 | // ========================= Cells ==========================
21 | const getCellDate = (date: DateType, offset: number) => {
22 | return generateConfig.addMonth(date, offset * 3);
23 | };
24 |
25 | const getCellText = (date: DateType) => {
26 | return formatValue(date, {
27 | locale,
28 | format: locale.cellQuarterFormat,
29 | generateConfig,
30 | });
31 | };
32 |
33 | const getCellClassName = () => ({
34 | [`${prefixCls}-cell-in-view`]: true,
35 | });
36 |
37 | // ========================= Header =========================
38 | const yearNode: React.ReactNode = (
39 |
55 | );
56 |
57 | // ========================= Render =========================
58 | return (
59 |
60 |
61 | {/* Header */}
62 |
generateConfig.addYear(pickerValue, distance)}
64 | onChange={onPickerValueChange}
65 | // Limitation
66 | getStart={(date) => generateConfig.setMonth(date, 0)}
67 | getEnd={(date) => generateConfig.setMonth(date, 11)}
68 | >
69 | {yearNode}
70 |
71 |
72 | {/* Body */}
73 |
84 |
85 |
86 | );
87 | }
88 |
--------------------------------------------------------------------------------
/src/PickerPanel/TimePanel/TimePanelBody/useScrollTo.ts:
--------------------------------------------------------------------------------
1 | import { useEvent } from '@rc-component/util';
2 | import raf from '@rc-component/util/lib/raf';
3 | import isVisible from '@rc-component/util/lib/Dom/isVisible';
4 | import * as React from 'react';
5 |
6 | const SPEED_PTG = 1 / 3;
7 |
8 | export default function useScrollTo(
9 | ulRef: React.RefObject,
10 | value: number | string,
11 | ): [syncScroll: VoidFunction, clearScroll: VoidFunction, isScrolling: () => boolean] {
12 | // ========================= Scroll =========================
13 | const scrollingRef = React.useRef(false);
14 | const scrollRafRef = React.useRef(null);
15 | const scrollDistRef = React.useRef(null);
16 |
17 | const isScrolling = () => scrollingRef.current;
18 |
19 | const stopScroll = () => {
20 | raf.cancel(scrollRafRef.current);
21 | scrollingRef.current = false;
22 | };
23 |
24 | const scrollRafTimesRef = React.useRef();
25 |
26 | const startScroll = () => {
27 | const ul = ulRef.current;
28 | scrollDistRef.current = null;
29 | scrollRafTimesRef.current = 0;
30 |
31 | if (ul) {
32 | const targetLi = ul.querySelector(`[data-value="${value}"]`);
33 | const firstLi = ul.querySelector(`li`);
34 |
35 | const doScroll = () => {
36 | stopScroll();
37 | scrollingRef.current = true;
38 | scrollRafTimesRef.current += 1;
39 |
40 | const { scrollTop: currentTop } = ul;
41 |
42 | const firstLiTop = firstLi.offsetTop;
43 | const targetLiTop = targetLi.offsetTop;
44 | const targetTop = targetLiTop - firstLiTop;
45 |
46 | // Wait for element exist. 5 frames is enough
47 | if ((targetLiTop === 0 && targetLi !== firstLi) || !isVisible(ul)) {
48 | if (scrollRafTimesRef.current <= 5) {
49 | scrollRafRef.current = raf(doScroll);
50 | }
51 | return;
52 | }
53 |
54 | const nextTop = currentTop + (targetTop - currentTop) * SPEED_PTG;
55 | const dist = Math.abs(targetTop - nextTop);
56 |
57 | // Break if dist get larger, which means user is scrolling
58 | if (scrollDistRef.current !== null && scrollDistRef.current < dist) {
59 | stopScroll();
60 | return;
61 | }
62 | scrollDistRef.current = dist;
63 |
64 | // Stop when dist is less than 1
65 | if (dist <= 1) {
66 | ul.scrollTop = targetTop;
67 | stopScroll();
68 | return;
69 | }
70 |
71 | // IE not support `scrollTo`
72 | ul.scrollTop = nextTop;
73 |
74 | scrollRafRef.current = raf(doScroll);
75 | };
76 |
77 | if (targetLi && firstLi) {
78 | doScroll();
79 | }
80 | }
81 | };
82 |
83 | // ======================== Trigger =========================
84 | const syncScroll = useEvent(startScroll);
85 |
86 | return [syncScroll, stopScroll, isScrolling];
87 | }
88 |
--------------------------------------------------------------------------------
/src/PickerPanel/TimePanel/TimePanelBody/util.ts:
--------------------------------------------------------------------------------
1 | import type { GenerateConfig } from '../../../generate';
2 | import type { Unit } from './TimeColumn';
3 |
4 | export function findValidateTime(
5 | date: DateType,
6 | getHourUnits: () => Unit[],
7 | getMinuteUnits: (hour: number) => Unit[],
8 | getSecondUnits: (hour: number, minute: number) => Unit[],
9 | getMillisecondUnits: (hour: number, minute: number, second: number) => Unit[],
10 | generateConfig: GenerateConfig,
11 | ) {
12 | let nextDate = date;
13 |
14 | function alignValidate(getUnitValue: string, setUnitValue: string, units: Unit[]) {
15 | let nextValue = generateConfig[getUnitValue](nextDate);
16 | const nextUnit = units.find((unit) => unit.value === nextValue);
17 |
18 | if (!nextUnit || nextUnit.disabled) {
19 | // Find most closest unit
20 | const validateUnits = units.filter((unit) => !unit.disabled);
21 | const reverseEnabledUnits = [...validateUnits].reverse();
22 | const validateUnit =
23 | reverseEnabledUnits.find((unit) => unit.value <= nextValue) || validateUnits[0];
24 |
25 | if (validateUnit) {
26 | nextValue = validateUnit.value;
27 | nextDate = generateConfig[setUnitValue](nextDate, nextValue);
28 | }
29 | }
30 |
31 | return nextValue;
32 | }
33 |
34 | // Find validate hour
35 | const nextHour = alignValidate('getHour', 'setHour', getHourUnits());
36 |
37 | // Find validate minute
38 | const nextMinute = alignValidate('getMinute', 'setMinute', getMinuteUnits(nextHour));
39 |
40 | // Find validate second
41 | const nextSecond = alignValidate('getSecond', 'setSecond', getSecondUnits(nextHour, nextMinute));
42 |
43 | // Find validate millisecond
44 | alignValidate(
45 | 'getMillisecond',
46 | 'setMillisecond',
47 | getMillisecondUnits(nextHour, nextMinute, nextSecond),
48 | );
49 |
50 | return nextDate;
51 | }
52 |
--------------------------------------------------------------------------------
/src/PickerPanel/TimePanel/index.tsx:
--------------------------------------------------------------------------------
1 | import classNames from 'classnames';
2 | import * as React from 'react';
3 | import type { SharedPanelProps } from '../../interface';
4 | import { formatValue } from '../../utils/dateUtil';
5 | import { PanelContext, useInfo } from '../context';
6 | import PanelHeader from '../PanelHeader';
7 | import TimePanelBody from './TimePanelBody';
8 |
9 | export type TimePanelProps = SharedPanelProps;
10 |
11 | export default function TimePanel(props: TimePanelProps) {
12 | const {
13 | prefixCls,
14 | value,
15 | locale,
16 | generateConfig,
17 |
18 | // Format
19 | showTime,
20 | } = props;
21 |
22 | const { format } = showTime || {};
23 |
24 | const panelPrefixCls = `${prefixCls}-time-panel`;
25 |
26 | // ========================== Base ==========================
27 | const [info] = useInfo(props, 'time');
28 |
29 | // ========================= Render =========================
30 | return (
31 |
32 |
33 |
34 | {value
35 | ? formatValue(value, {
36 | locale,
37 | format,
38 | generateConfig,
39 | })
40 | : '\u00A0'}
41 |
42 |
43 |
44 |
45 | );
46 | }
47 |
--------------------------------------------------------------------------------
/src/PickerPanel/WeekPanel/index.tsx:
--------------------------------------------------------------------------------
1 | import classNames from 'classnames';
2 | import * as React from 'react';
3 | import type { SharedPanelProps } from '../../interface';
4 | import { isInRange, isSameWeek } from '../../utils/dateUtil';
5 | import DatePanel from '../DatePanel';
6 |
7 | export default function WeekPanel(
8 | props: SharedPanelProps,
9 | ) {
10 | const { prefixCls, generateConfig, locale, value, hoverValue, hoverRangeValue } = props;
11 |
12 | // =============================== Row ================================
13 | const localeName = locale.locale;
14 |
15 | const rowPrefixCls = `${prefixCls}-week-panel-row`;
16 |
17 | const rowClassName = (currentDate: DateType) => {
18 | const rangeCls = {};
19 |
20 | if (hoverRangeValue) {
21 | const [rangeStart, rangeEnd] = hoverRangeValue;
22 |
23 | const isRangeStart = isSameWeek(generateConfig, localeName, rangeStart, currentDate);
24 | const isRangeEnd = isSameWeek(generateConfig, localeName, rangeEnd, currentDate);
25 |
26 | rangeCls[`${rowPrefixCls}-range-start`] = isRangeStart;
27 | rangeCls[`${rowPrefixCls}-range-end`] = isRangeEnd;
28 | rangeCls[`${rowPrefixCls}-range-hover`] =
29 | !isRangeStart &&
30 | !isRangeEnd &&
31 | isInRange(generateConfig, rangeStart, rangeEnd, currentDate);
32 | }
33 |
34 | if (hoverValue) {
35 | rangeCls[`${rowPrefixCls}-hover`] = hoverValue.some((date) =>
36 | isSameWeek(generateConfig, localeName, currentDate, date),
37 | );
38 | }
39 |
40 | return classNames(
41 | rowPrefixCls,
42 | {
43 | [`${rowPrefixCls}-selected`]:
44 | !hoverRangeValue && isSameWeek(generateConfig, localeName, value, currentDate),
45 | },
46 |
47 | // Patch for hover range
48 | rangeCls,
49 | );
50 | };
51 |
52 | // ============================== Render ==============================
53 | return ;
54 | }
55 |
--------------------------------------------------------------------------------
/src/PickerPanel/YearPanel/index.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import type { DisabledDate, SharedPanelProps } from '../../interface';
3 | import { formatValue, isInRange, isSameYear } from '../../utils/dateUtil';
4 | import { PanelContext, useInfo } from '../context';
5 | import PanelBody from '../PanelBody';
6 | import PanelHeader from '../PanelHeader';
7 |
8 | export default function YearPanel(
9 | props: SharedPanelProps,
10 | ) {
11 | const {
12 | prefixCls,
13 | locale,
14 | generateConfig,
15 | pickerValue,
16 | disabledDate,
17 | onPickerValueChange,
18 | onModeChange,
19 | } = props;
20 |
21 | const panelPrefixCls = `${prefixCls}-year-panel`;
22 |
23 | // ========================== Base ==========================
24 | const [info] = useInfo(props, 'year');
25 | const getStartYear = (date: DateType) => {
26 | const startYear = Math.floor(generateConfig.getYear(date) / 10) * 10;
27 | return generateConfig.setYear(date, startYear);
28 | };
29 | const getEndYear = (date: DateType) => {
30 | const startYear = getStartYear(date);
31 | return generateConfig.addYear(startYear, 9);
32 | };
33 |
34 | const startYearDate = getStartYear(pickerValue);
35 | const endYearDate = getEndYear(pickerValue);
36 |
37 | const baseDate = generateConfig.addYear(startYearDate, -1);
38 |
39 | // ========================= Cells ==========================
40 | const getCellDate = (date: DateType, offset: number) => {
41 | return generateConfig.addYear(date, offset);
42 | };
43 |
44 | const getCellText = (date: DateType) => {
45 | return formatValue(date, {
46 | locale,
47 | format: locale.cellYearFormat,
48 | generateConfig,
49 | });
50 | };
51 |
52 | const getCellClassName = (date: DateType) => {
53 | return {
54 | [`${prefixCls}-cell-in-view`]:
55 | isSameYear(generateConfig, date, startYearDate) ||
56 | isSameYear(generateConfig, date, endYearDate) ||
57 | isInRange(generateConfig, startYearDate, endYearDate, date),
58 | };
59 | };
60 |
61 | // ======================== Disabled ========================
62 | const mergedDisabledDate: DisabledDate = disabledDate
63 | ? (currentDate, disabledInfo) => {
64 | // Start
65 | const startMonth = generateConfig.setMonth(currentDate, 0);
66 | const startDate = generateConfig.setDate(startMonth, 1);
67 |
68 | // End
69 | const endMonth = generateConfig.addYear(startDate, 1);
70 | const endDate = generateConfig.addDate(endMonth, -1);
71 | return disabledDate(startDate, disabledInfo) && disabledDate(endDate, disabledInfo);
72 | }
73 | : null;
74 |
75 | // ========================= Header =========================
76 | const yearNode: React.ReactNode = (
77 |
99 | );
100 |
101 | // ========================= Render =========================
102 | return (
103 |
104 |
105 | {/* Header */}
106 |
generateConfig.addYear(pickerValue, distance * 10)}
108 | onChange={onPickerValueChange}
109 | // Limitation
110 | getStart={getStartYear}
111 | getEnd={getEndYear}
112 | >
113 | {yearNode}
114 |
115 |
116 | {/* Body */}
117 |
129 |
130 |
131 | );
132 | }
133 |
--------------------------------------------------------------------------------
/src/PickerPanel/context.ts:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import type { PanelMode, SharedPanelProps } from '../interface';
3 | import type { FilledPanelClassNames, FilledPanelStyles } from '../hooks/useSemantic';
4 |
5 | export interface SharedPanelContextProps {
6 | classNames: FilledPanelClassNames;
7 | styles: FilledPanelStyles;
8 | }
9 |
10 | export const SharedPanelContext = React.createContext(null!);
11 |
12 | export interface PanelContextProps
13 | extends Pick<
14 | SharedPanelProps,
15 | | 'prefixCls'
16 | | 'cellRender'
17 | | 'generateConfig'
18 | | 'locale'
19 | | 'onSelect'
20 | | 'hoverValue'
21 | | 'hoverRangeValue'
22 | | 'onHover'
23 | | 'values'
24 | | 'pickerValue'
25 |
26 | // Limitation
27 | | 'disabledDate'
28 | | 'minDate'
29 | | 'maxDate'
30 |
31 | // Icon
32 | | 'prevIcon'
33 | | 'nextIcon'
34 | | 'superPrevIcon'
35 | | 'superNextIcon'
36 | > {
37 | /** Tell current panel type */
38 | panelType: PanelMode;
39 |
40 | // Shared
41 | now: DateType;
42 |
43 | classNames: FilledPanelClassNames;
44 | styles: FilledPanelStyles;
45 | }
46 |
47 | /** Used for each single Panel. e.g. DatePanel */
48 | export const PanelContext = React.createContext(null!);
49 |
50 | export function usePanelContext(): PanelContextProps {
51 | return React.useContext>(PanelContext);
52 | }
53 |
54 | /**
55 | * Get shared props for the SharedPanelProps interface.
56 | */
57 | export function useInfo(
58 | props: SharedPanelProps,
59 | panelType: PanelMode,
60 | ): [sharedProps: PanelContextProps, now: DateType] {
61 | // TODO: this is not good to get from each props.
62 | // Should move to `SharedPanelContext` instead.
63 | const {
64 | prefixCls,
65 | generateConfig,
66 | locale,
67 | disabledDate,
68 | minDate,
69 | maxDate,
70 | cellRender,
71 | hoverValue,
72 | hoverRangeValue,
73 | onHover,
74 | values,
75 | pickerValue,
76 | onSelect,
77 |
78 | // Icons
79 | prevIcon,
80 | nextIcon,
81 | superPrevIcon,
82 | superNextIcon,
83 | } = props;
84 |
85 | // ======================= Context ========================
86 | const { classNames, styles } = React.useContext(SharedPanelContext);
87 |
88 | // ========================= MISC =========================
89 | const now = generateConfig.getNow();
90 |
91 | // ========================= Info =========================
92 | const info = {
93 | now,
94 | values,
95 | pickerValue,
96 | prefixCls,
97 | classNames,
98 | styles,
99 | disabledDate,
100 | minDate,
101 | maxDate,
102 | cellRender,
103 | hoverValue,
104 | hoverRangeValue,
105 | onHover,
106 | locale,
107 | generateConfig,
108 | onSelect,
109 | panelType,
110 |
111 | // Icons
112 | prevIcon,
113 | nextIcon,
114 | superPrevIcon,
115 | superNextIcon,
116 | };
117 |
118 | return [info, now];
119 | }
120 |
121 | // ============================== Internal ==============================
122 | export interface PickerHackContextProps {
123 | hidePrev?: boolean;
124 | hideNext?: boolean;
125 | hideHeader?: boolean;
126 | onCellDblClick?: () => void;
127 | }
128 |
129 | /**
130 | * Internal usage for RangePicker to not to show the operation arrow
131 | */
132 | export const PickerHackContext = React.createContext({});
133 |
134 | if (process.env.NODE_ENV !== 'production') {
135 | PickerHackContext.displayName = 'PickerHackContext';
136 | }
137 |
--------------------------------------------------------------------------------
/src/PickerTrigger/index.tsx:
--------------------------------------------------------------------------------
1 | import Trigger from '@rc-component/trigger';
2 | import type { AlignType, BuildInPlacements } from '@rc-component/trigger/lib/interface';
3 | import classNames from 'classnames';
4 | import * as React from 'react';
5 | import { getRealPlacement } from '../utils/uiUtil';
6 | import PickerContext from '../PickerInput/context';
7 |
8 | const BUILT_IN_PLACEMENTS = {
9 | bottomLeft: {
10 | points: ['tl', 'bl'],
11 | offset: [0, 4],
12 | overflow: {
13 | adjustX: 1,
14 | adjustY: 1,
15 | },
16 | },
17 | bottomRight: {
18 | points: ['tr', 'br'],
19 | offset: [0, 4],
20 | overflow: {
21 | adjustX: 1,
22 | adjustY: 1,
23 | },
24 | },
25 | topLeft: {
26 | points: ['bl', 'tl'],
27 | offset: [0, -4],
28 | overflow: {
29 | adjustX: 0,
30 | adjustY: 1,
31 | },
32 | },
33 | topRight: {
34 | points: ['br', 'tr'],
35 | offset: [0, -4],
36 | overflow: {
37 | adjustX: 0,
38 | adjustY: 1,
39 | },
40 | },
41 | };
42 |
43 | export type PickerTriggerProps = {
44 | popupElement: React.ReactElement;
45 | popupStyle?: React.CSSProperties;
46 | children: React.ReactElement;
47 | transitionName?: string;
48 | getPopupContainer?: (node: HTMLElement) => HTMLElement;
49 | popupAlign?: AlignType;
50 | range?: boolean;
51 |
52 | // Placement
53 | popupClassName?: string;
54 | placement?: string;
55 | builtinPlacements?: BuildInPlacements;
56 | direction?: 'ltr' | 'rtl';
57 |
58 | // Visible
59 | visible: boolean;
60 | onClose: () => void;
61 | };
62 |
63 | function PickerTrigger({
64 | popupElement,
65 | popupStyle,
66 | popupClassName,
67 | popupAlign,
68 | transitionName,
69 | getPopupContainer,
70 | children,
71 | range,
72 | placement,
73 | builtinPlacements = BUILT_IN_PLACEMENTS,
74 | direction,
75 |
76 | // Visible
77 | visible,
78 | onClose,
79 | }: PickerTriggerProps) {
80 | const { prefixCls } = React.useContext(PickerContext);
81 | const dropdownPrefixCls = `${prefixCls}-dropdown`;
82 |
83 | const realPlacement = getRealPlacement(placement, direction === 'rtl');
84 |
85 | return (
86 | {
104 | if (!nextVisible) {
105 | onClose();
106 | }
107 | }}
108 | >
109 | {children}
110 |
111 | );
112 | }
113 |
114 | export default PickerTrigger;
115 |
--------------------------------------------------------------------------------
/src/PickerTrigger/util.ts:
--------------------------------------------------------------------------------
1 | import type { SharedPickerProps } from '../interface';
2 | import { pickProps } from '../utils/miscUtil';
3 |
4 | export function pickTriggerProps(props: Omit) {
5 | return pickProps(props, [
6 | 'placement',
7 | 'builtinPlacements',
8 | 'popupAlign',
9 | 'getPopupContainer',
10 | 'transitionName',
11 | 'direction',
12 | ]);
13 | }
14 |
--------------------------------------------------------------------------------
/src/generate/index.ts:
--------------------------------------------------------------------------------
1 | export type GenerateConfig = {
2 | // Get
3 | getWeekDay: (value: DateType) => number;
4 | getMillisecond: (value: DateType) => number;
5 | getSecond: (value: DateType) => number;
6 | getMinute: (value: DateType) => number;
7 | getHour: (value: DateType) => number;
8 | getDate: (value: DateType) => number;
9 | getMonth: (value: DateType) => number;
10 | getYear: (value: DateType) => number;
11 | getNow: () => DateType;
12 | getFixedDate: (fixed: string) => DateType;
13 | getEndDate: (value: DateType) => DateType;
14 |
15 | // Set
16 | addYear: (value: DateType, diff: number) => DateType;
17 | addMonth: (value: DateType, diff: number) => DateType;
18 | addDate: (value: DateType, diff: number) => DateType;
19 | setYear: (value: DateType, year: number) => DateType;
20 | setMonth: (value: DateType, month: number) => DateType;
21 | setDate: (value: DateType, date: number) => DateType;
22 | setHour: (value: DateType, hour: number) => DateType;
23 | setMinute: (value: DateType, minute: number) => DateType;
24 | setSecond: (value: DateType, second: number) => DateType;
25 | setMillisecond: (value: DateType, millisecond: number) => DateType;
26 |
27 | // Compare
28 | isAfter: (date1: DateType, date2: DateType) => boolean;
29 | isValidate: (date: DateType) => boolean;
30 |
31 | locale: {
32 | getWeekFirstDay: (locale: string) => number;
33 | getWeekFirstDate: (locale: string, value: DateType) => DateType;
34 | getWeek: (locale: string, value: DateType) => number;
35 |
36 | format: (locale: string, date: DateType, format: string) => string;
37 |
38 | /** Should only return validate date instance */
39 | parse: (locale: string, text: string, formats: string[]) => DateType | null;
40 |
41 | /** A proxy for getting locale with moment or other locale library */
42 | getShortWeekDays?: (locale: string) => string[];
43 | /** A proxy for getting locale with moment or other locale library */
44 | getShortMonths?: (locale: string) => string[];
45 | };
46 | };
47 |
--------------------------------------------------------------------------------
/src/hooks/useLocale.ts:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import type { Locale, SharedTimeProps } from '../interface';
3 |
4 | export function fillTimeFormat(
5 | showHour: boolean,
6 | showMinute: boolean,
7 | showSecond: boolean,
8 | showMillisecond: boolean,
9 | showMeridiem: boolean,
10 | ) {
11 | let timeFormat = '';
12 |
13 | // Base HH:mm:ss
14 | const cells = [];
15 |
16 | if (showHour) {
17 | cells.push(showMeridiem ? 'hh' : 'HH');
18 | }
19 | if (showMinute) {
20 | cells.push('mm');
21 | }
22 | if (showSecond) {
23 | cells.push('ss');
24 | }
25 |
26 | timeFormat = cells.join(':');
27 |
28 | // Millisecond
29 | if (showMillisecond) {
30 | timeFormat += '.SSS';
31 | }
32 |
33 | // Meridiem
34 | if (showMeridiem) {
35 | timeFormat += ' A';
36 | }
37 |
38 | return timeFormat;
39 | }
40 |
41 | /**
42 | * Used for `useFilledProps` since it already in the React.useMemo
43 | */
44 | function fillLocale(
45 | locale: Locale,
46 | showHour: boolean,
47 | showMinute: boolean,
48 | showSecond: boolean,
49 | showMillisecond: boolean,
50 | use12Hours: boolean,
51 | ): Locale {
52 | // Not fill `monthFormat` since `locale.shortMonths` handle this
53 | // Not fill `cellMeridiemFormat` since AM & PM by default
54 | const {
55 | // Input Field
56 | fieldDateTimeFormat,
57 | fieldDateFormat,
58 | fieldTimeFormat,
59 | fieldMonthFormat,
60 | fieldYearFormat,
61 | fieldWeekFormat,
62 | fieldQuarterFormat,
63 |
64 | // Header Format
65 | yearFormat,
66 | // monthFormat,
67 |
68 | // Cell format
69 | cellYearFormat,
70 | cellQuarterFormat,
71 | dayFormat,
72 | cellDateFormat,
73 |
74 | // cellMeridiemFormat,
75 | } = locale;
76 |
77 | const timeFormat = fillTimeFormat(showHour, showMinute, showSecond, showMillisecond, use12Hours);
78 |
79 | return {
80 | ...locale,
81 |
82 | fieldDateTimeFormat: fieldDateTimeFormat || `YYYY-MM-DD ${timeFormat}`,
83 | fieldDateFormat: fieldDateFormat || 'YYYY-MM-DD',
84 | fieldTimeFormat: fieldTimeFormat || timeFormat,
85 | fieldMonthFormat: fieldMonthFormat || 'YYYY-MM',
86 | fieldYearFormat: fieldYearFormat || 'YYYY',
87 | fieldWeekFormat: fieldWeekFormat || 'gggg-wo',
88 | fieldQuarterFormat: fieldQuarterFormat || 'YYYY-[Q]Q',
89 |
90 | yearFormat: yearFormat || 'YYYY',
91 |
92 | cellYearFormat: cellYearFormat || 'YYYY',
93 | cellQuarterFormat: cellQuarterFormat || '[Q]Q',
94 | cellDateFormat: cellDateFormat || dayFormat || 'D',
95 | };
96 | }
97 |
98 | /**
99 | * Fill locale format as start up
100 | */
101 | export default function useLocale(
102 | locale: Locale,
103 | showProps: Pick<
104 | SharedTimeProps,
105 | 'showHour' | 'showMinute' | 'showSecond' | 'showMillisecond' | 'use12Hours'
106 | >,
107 | ) {
108 | const { showHour, showMinute, showSecond, showMillisecond, use12Hours } = showProps;
109 | return React.useMemo(
110 | () => fillLocale(locale, showHour, showMinute, showSecond, showMillisecond, use12Hours),
111 | [locale, showHour, showMinute, showSecond, showMillisecond, use12Hours],
112 | );
113 | }
114 |
--------------------------------------------------------------------------------
/src/hooks/useSemantic.ts:
--------------------------------------------------------------------------------
1 | import { useMemo } from 'react';
2 | import type { SharedPickerProps } from '../interface';
3 |
4 | export type FilledPanelClassNames = NonNullable['popup'];
5 |
6 | export type FilledPanelStyles = NonNullable['popup'];
7 |
8 | export type FilledClassNames = NonNullable & {
9 | popup: FilledPanelClassNames;
10 | };
11 |
12 | export type FilledStyles = NonNullable & {
13 | popup: FilledPanelStyles;
14 | };
15 |
16 | /**
17 | * Convert `classNames` & `styles` to a fully filled object
18 | */
19 | export default function useSemantic(
20 | classNames?: SharedPickerProps['classNames'],
21 | styles?: SharedPickerProps['styles'],
22 | ) {
23 | return useMemo(() => {
24 | const mergedClassNames: FilledClassNames = {
25 | ...classNames,
26 | popup: classNames?.popup || {},
27 | };
28 |
29 | const mergedStyles: FilledStyles = {
30 | ...styles,
31 | popup: styles?.popup || {},
32 | };
33 |
34 | return [mergedClassNames, mergedStyles] as const;
35 | }, [classNames, styles]);
36 | }
37 |
--------------------------------------------------------------------------------
/src/hooks/useSyncState.ts:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 |
3 | /**
4 | * Sync value with state.
5 | * This should only used for internal which not affect outside calculation.
6 | * Since it's not safe for suspense.
7 | */
8 | export default function useSyncState(
9 | defaultValue: T,
10 | controlledValue?: T,
11 | ): [getter: (useControlledValueFirst?: boolean) => T, setter: (nextValue: T) => void, value: T] {
12 | const valueRef = React.useRef(defaultValue);
13 | const [, forceUpdate] = React.useState({});
14 |
15 | const getter = (useControlledValueFirst?: boolean) =>
16 | useControlledValueFirst && controlledValue !== undefined ? controlledValue : valueRef.current;
17 |
18 | const setter = (nextValue: T) => {
19 | valueRef.current = nextValue;
20 | forceUpdate({});
21 | };
22 |
23 | return [getter, setter, getter(true)];
24 | }
25 |
--------------------------------------------------------------------------------
/src/hooks/useToggleDates.ts:
--------------------------------------------------------------------------------
1 | import type { GenerateConfig } from '../generate';
2 | import { isSame } from '../utils/dateUtil';
3 | import type { InternalMode, Locale } from '../interface';
4 |
5 | /**
6 | * Toggles the presence of a value in an array.
7 | * If the value exists in the array, removed it.
8 | * Else add it.
9 | */
10 | export default function useToggleDates(
11 | generateConfig: GenerateConfig,
12 | locale: Locale,
13 | panelMode: InternalMode,
14 | ) {
15 | function toggleDates(list: DateType[], target: DateType) {
16 | const index = list.findIndex((date) => isSame(generateConfig, locale, date, target, panelMode));
17 |
18 | if (index === -1) {
19 | return [...list, target];
20 | }
21 |
22 | const sliceList = [...list];
23 | sliceList.splice(index, 1);
24 |
25 | return sliceList;
26 | }
27 |
28 | return toggleDates;
29 | }
30 |
--------------------------------------------------------------------------------
/src/index.tsx:
--------------------------------------------------------------------------------
1 | /**
2 | * What's new?
3 | * - Common
4 | * - [Break] Support special year format, all the year will follow the locale config.
5 | * - Blur all of field will trigger `onChange` if validate
6 | * - Support `preserveInvalidOnBlur` to not to clean input if invalid and remove `changeOnBlur`
7 | * - `pickerValue` is now full controlled
8 | * - `defaultPickerValue` will take effect on every field active with popup opening.
9 | * - [Break] clear button return the event with `onClick`
10 | *
11 | * - Locale
12 | * - Remove `dateFormat` since it's never used
13 | * - Remove `dateTimeFormat` since it's never used
14 | *
15 | * - Picker
16 | * - TimePicker support `changeOnScroll`
17 | * - TimePicker support `millisecond`
18 | * - Support cellMeridiemFormat for AM/PM
19 | * - Get correct `disabledHours` when set `use12Hours`
20 | * - Support `showWeek`
21 | *
22 | * - RangePicker
23 | * - [Break] RangePicker is now not limit the range of clicked field.
24 | * - Trigger `onCalendarChange` when type correct
25 | * - [Break] Not order `value` if given `value` is wrong order.
26 | * - Hover `presets` will show date in input field.
27 | * - [Break] RangePicker go to end field, `pickerValue` will follow the start field if not controlled.
28 | */
29 |
30 | import type { PickerRef, SharedTimeProps } from './interface';
31 | import RangePicker, { type RangePickerProps } from './PickerInput/RangePicker';
32 | import Picker, { type BasePickerProps, type PickerProps } from './PickerInput/SinglePicker';
33 | import PickerPanel, { type BasePickerPanelProps, type PickerPanelProps } from './PickerPanel';
34 |
35 | export { Picker, RangePicker, PickerPanel };
36 | export type {
37 | RangePickerProps,
38 | PickerProps,
39 | PickerPanelProps,
40 | PickerRef,
41 | BasePickerProps,
42 | BasePickerPanelProps,
43 | SharedTimeProps,
44 | };
45 | export default Picker;
46 |
--------------------------------------------------------------------------------
/src/locale/am_ET.ts:
--------------------------------------------------------------------------------
1 | import type { Locale } from '../interface';
2 |
3 | const locale: Locale = {
4 | locale: 'am_ET',
5 | today: 'ዛሬ',
6 | now: 'አሁን',
7 | backToToday: 'ወደ ዛሬ ተመለስ',
8 | ok: 'እሺ',
9 | clear: 'አንፃ',
10 | week: 'ሳምንት',
11 | month: 'ወር',
12 | year: 'ዓመት',
13 | timeSelect: 'ሰዓት ምረጥ',
14 | dateSelect: 'ቀን ምረጥ',
15 | weekSelect: 'ሳምንት ምረጥ',
16 | monthSelect: 'ወር ምረጥ',
17 | yearSelect: 'አመት ምረጥ',
18 | decadeSelect: 'አስርት አመታት ምረጥ',
19 | yearFormat: 'YYYY',
20 | dayFormat: 'D',
21 | monthBeforeYear: true,
22 | previousMonth: 'ያለፈው ወር (PageUp)',
23 | nextMonth: 'ቀጣይ ወር (PageDown)',
24 | previousYear: 'ያለፈው ዓመት (Control + left)',
25 | nextYear: 'ቀጣይ ዓመት (Control + right)',
26 | previousDecade: 'ያለፈው አስርት ዓመት',
27 | nextDecade: 'ቀጣይ አስርት ዓመት',
28 | previousCentury: 'ያለፈው ክፍለ ዘመን',
29 | nextCentury: 'ቀጣይ ክፍለ ዘመን',
30 | };
31 |
32 | export default locale;
33 |
--------------------------------------------------------------------------------
/src/locale/ar_EG.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'ar_EG',
7 | today: 'اليوم',
8 | now: 'الأن',
9 | backToToday: 'العودة إلى اليوم',
10 | ok: 'تأكيد',
11 | clear: 'مسح',
12 | week: 'الأسبوع',
13 | month: 'الشهر',
14 | year: 'السنة',
15 | timeSelect: 'اختيار الوقت',
16 | dateSelect: 'اختيار التاريخ',
17 | monthSelect: 'اختيار الشهر',
18 | yearSelect: 'اختيار السنة',
19 | decadeSelect: 'اختيار العقد',
20 | previousMonth: 'الشهر السابق (PageUp)',
21 | nextMonth: 'الشهر التالى(PageDown)',
22 | previousYear: 'العام السابق (Control + left)',
23 | nextYear: 'العام التالى (Control + right)',
24 | previousDecade: 'العقد السابق',
25 | nextDecade: 'العقد التالى',
26 | previousCentury: 'القرن السابق',
27 | nextCentury: 'القرن التالى',
28 | };
29 |
30 | export default locale;
31 |
--------------------------------------------------------------------------------
/src/locale/az_AZ.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'az_AZ',
7 | today: 'Bugün',
8 | now: 'İndi',
9 | backToToday: 'Bugünə qayıt',
10 | ok: 'Təsdiq',
11 | clear: 'Təmizlə',
12 | week: 'Həftə',
13 | month: 'Ay',
14 | year: 'İl',
15 | timeSelect: 'vaxtı seç',
16 | dateSelect: 'tarixi seç',
17 | weekSelect: 'Həftə seç',
18 | monthSelect: 'Ay seç',
19 | yearSelect: 'il seç',
20 | decadeSelect: 'Onillik seçin',
21 | previousMonth: 'Əvvəlki ay (PageUp)',
22 | nextMonth: 'Növbəti ay (PageDown)',
23 | previousYear: 'Sonuncu il (Control + left)',
24 | nextYear: 'Növbəti il (Control + right)',
25 | previousDecade: 'Sonuncu onillik',
26 | nextDecade: 'Növbəti onillik',
27 | previousCentury: 'Sonuncu əsr',
28 | nextCentury: 'Növbəti əsr',
29 | };
30 |
31 | export default locale;
32 |
--------------------------------------------------------------------------------
/src/locale/bg_BG.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'bg_BG',
7 | today: 'Днес',
8 | now: 'Сега',
9 | backToToday: 'Към днес',
10 | ok: 'Добре',
11 | clear: 'Изчистване',
12 | week: 'Седмица',
13 | month: 'Месец',
14 | year: 'Година',
15 | timeSelect: 'Избор на час',
16 | dateSelect: 'Избор на дата',
17 | monthSelect: 'Избор на месец',
18 | yearSelect: 'Избор на година',
19 | decadeSelect: 'Десетилетие',
20 | previousMonth: 'Предишен месец (PageUp)',
21 | nextMonth: 'Следващ месец (PageDown)',
22 | previousYear: 'Последна година (Control + left)',
23 | nextYear: 'Следваща година (Control + right)',
24 | previousDecade: 'Предишно десетилетие',
25 | nextDecade: 'Следващо десетилетие',
26 | previousCentury: 'Последен век',
27 | nextCentury: 'Следващ век',
28 | };
29 | export default locale;
30 |
--------------------------------------------------------------------------------
/src/locale/bn_BD.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'bn_BD',
7 | today: 'আজ',
8 | now: 'এখন',
9 | backToToday: 'আজকে ফিরে চলুন',
10 | ok: 'ওকে',
11 | clear: 'পরিস্কার',
12 | week: 'সপ্তাহ',
13 | month: 'মাস',
14 | year: 'বছর',
15 | timeSelect: 'সময় নির্বাচন',
16 | dateSelect: 'তারিখ নির্বাচন',
17 | weekSelect: 'সপ্তাহ পছন্দ করুন',
18 | monthSelect: 'মাস পছন্দ করুন',
19 | yearSelect: 'বছর পছন্দ করুন',
20 | decadeSelect: 'একটি দশক পছন্দ করুন',
21 | previousMonth: 'গত মাস (PageUp)',
22 | nextMonth: 'আগামী মাস (PageDown)',
23 | previousYear: 'গত বছর (Control + left)',
24 | nextYear: 'আগামী বছর (Control + right)',
25 | previousDecade: 'গত দশক',
26 | nextDecade: 'পরের দশক',
27 | previousCentury: 'গত শতাব্দী',
28 | nextCentury: 'পরের শতাব্দী',
29 | };
30 |
31 | export default locale;
32 |
--------------------------------------------------------------------------------
/src/locale/by_BY.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'by_BY',
7 | today: 'Сёння',
8 | now: 'Зараз',
9 | backToToday: 'Дадзеная дата',
10 | ok: 'OK',
11 | clear: 'Ачысціць',
12 | week: 'Тыдзень',
13 | month: 'Месяц',
14 | year: 'Год',
15 | timeSelect: 'Выбраць час',
16 | dateSelect: 'Выбраць дату',
17 | weekSelect: 'Выбраць тыдзень',
18 | monthSelect: 'Выбраць месяц',
19 | yearSelect: 'Выбраць год',
20 | decadeSelect: 'Выбраць дзесяцігоддзе',
21 |
22 | previousMonth: 'Папярэдні месяц (PageUp)',
23 | nextMonth: 'Наступны месяц (PageDown)',
24 | previousYear: 'Папярэдні год (Control + left)',
25 | nextYear: 'Наступны год (Control + right)',
26 | previousDecade: 'Папярэдняе дзесяцігоддзе',
27 | nextDecade: 'Наступнае дзесяцігоддзе',
28 | previousCentury: 'Папярэдні век',
29 | nextCentury: 'Наступны век',
30 | };
31 |
32 | export default locale;
33 |
--------------------------------------------------------------------------------
/src/locale/ca_ES.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'ca_ES',
7 | today: 'Avui',
8 | now: 'Ara',
9 | backToToday: 'Tornar a avui',
10 | ok: 'Acceptar',
11 | clear: 'Netejar',
12 | week: 'Setmana',
13 | month: 'Mes',
14 | year: 'Any',
15 | timeSelect: 'Seleccionar hora',
16 | dateSelect: 'Seleccionar data',
17 | monthSelect: 'Escollir un mes',
18 | yearSelect: 'Escollir un any',
19 | decadeSelect: 'Escollir una dècada',
20 | previousMonth: 'Mes anterior (PageUp)',
21 | nextMonth: 'Mes següent (PageDown)',
22 | previousYear: 'Any anterior (Control + left)',
23 | nextYear: 'Mes següent (Control + right)',
24 | previousDecade: 'Dècada anterior',
25 | nextDecade: 'Dècada següent',
26 | previousCentury: 'Segle anterior',
27 | nextCentury: 'Segle següent',
28 | };
29 |
30 | export default locale;
31 |
--------------------------------------------------------------------------------
/src/locale/common.ts:
--------------------------------------------------------------------------------
1 | import type { Locale } from '../interface';
2 |
3 | export const commonLocale: Partial = {
4 | yearFormat: 'YYYY',
5 | dayFormat: 'D',
6 | cellMeridiemFormat: 'A',
7 | monthBeforeYear: true,
8 | };
9 |
--------------------------------------------------------------------------------
/src/locale/cs_CZ.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'cs_CZ',
7 | today: 'Dnes',
8 | now: 'Nyní',
9 | backToToday: 'Zpět na dnešek',
10 | ok: 'OK',
11 | clear: 'Vymazat',
12 | week: 'Týden',
13 | month: 'Měsíc',
14 | year: 'Rok',
15 | timeSelect: 'Vybrat čas',
16 | dateSelect: 'Vybrat datum',
17 | monthSelect: 'Vyberte měsíc',
18 | yearSelect: 'Vyberte rok',
19 | decadeSelect: 'Vyberte dekádu',
20 |
21 | previousMonth: 'Předchozí měsíc (PageUp)',
22 | nextMonth: 'Následující (PageDown)',
23 | previousYear: 'Předchozí rok (Control + left)',
24 | nextYear: 'Následující rok (Control + right)',
25 | previousDecade: 'Předchozí dekáda',
26 | nextDecade: 'Následující dekáda',
27 | previousCentury: 'Předchozí století',
28 | nextCentury: 'Následující století',
29 | };
30 |
31 | export default locale;
32 |
--------------------------------------------------------------------------------
/src/locale/da_DK.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'da_DK',
7 | today: 'I dag',
8 | now: 'Nu',
9 | backToToday: 'Gå til i dag',
10 | ok: 'OK',
11 | clear: 'Ryd',
12 | week: 'Uge',
13 | month: 'Måned',
14 | year: 'År',
15 | timeSelect: 'Vælg tidspunkt',
16 | dateSelect: 'Vælg dato',
17 | monthSelect: 'Vælg måned',
18 | yearSelect: 'Vælg år',
19 | decadeSelect: 'Vælg årti',
20 |
21 | previousMonth: 'Forrige måned (Page Up)',
22 | nextMonth: 'Næste måned (Page Down)',
23 | previousYear: 'Forrige år (Ctrl-venstre pil)',
24 | nextYear: 'Næste år (Ctrl-højre pil)',
25 | previousDecade: 'Forrige årti',
26 | nextDecade: 'Næste årti',
27 | previousCentury: 'Forrige århundrede',
28 | nextCentury: 'Næste århundrede',
29 | };
30 |
31 | export default locale;
32 |
--------------------------------------------------------------------------------
/src/locale/de_DE.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'de_DE',
7 | today: 'Heute',
8 | now: 'Jetzt',
9 | backToToday: 'Zurück zu Heute',
10 | ok: 'OK',
11 | clear: 'Zurücksetzen',
12 | week: 'Woche',
13 | month: 'Monat',
14 | year: 'Jahr',
15 | timeSelect: 'Zeit wählen',
16 | dateSelect: 'Datum wählen',
17 | monthSelect: 'Wähle einen Monat',
18 | yearSelect: 'Wähle ein Jahr',
19 | decadeSelect: 'Wähle ein Jahrzehnt',
20 |
21 | previousMonth: 'Vorheriger Monat (PageUp)',
22 | nextMonth: 'Nächster Monat (PageDown)',
23 | previousYear: 'Vorheriges Jahr (Ctrl + left)',
24 | nextYear: 'Nächstes Jahr (Ctrl + right)',
25 | previousDecade: 'Vorheriges Jahrzehnt',
26 | nextDecade: 'Nächstes Jahrzehnt',
27 | previousCentury: 'Vorheriges Jahrhundert',
28 | nextCentury: 'Nächstes Jahrhundert',
29 | };
30 |
31 | export default locale;
32 |
--------------------------------------------------------------------------------
/src/locale/el_GR.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'el_GR',
7 | today: 'Σήμερα',
8 | now: 'Τώρα',
9 | backToToday: 'Πίσω στη σημερινή μέρα',
10 | ok: 'OK',
11 | clear: 'Καθαρισμός',
12 | week: 'Εβδομάδα',
13 | month: 'Μήνας',
14 | year: 'Έτος',
15 | timeSelect: 'Επιλογή ώρας',
16 | dateSelect: 'Επιλογή ημερομηνίας',
17 | monthSelect: 'Επιλογή μήνα',
18 | yearSelect: 'Επιλογή έτους',
19 | decadeSelect: 'Επιλογή δεκαετίας',
20 |
21 | previousMonth: 'Προηγούμενος μήνας (PageUp)',
22 | nextMonth: 'Επόμενος μήνας (PageDown)',
23 | previousYear: 'Προηγούμενο έτος (Control + αριστερά)',
24 | nextYear: 'Επόμενο έτος (Control + δεξιά)',
25 | previousDecade: 'Προηγούμενη δεκαετία',
26 | nextDecade: 'Επόμενη δεκαετία',
27 | previousCentury: 'Προηγούμενος αιώνας',
28 | nextCentury: 'Επόμενος αιώνας',
29 | };
30 |
31 | export default locale;
32 |
--------------------------------------------------------------------------------
/src/locale/en_GB.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'en_GB',
7 | today: 'Today',
8 | now: 'Now',
9 | backToToday: 'Back to today',
10 | ok: 'OK',
11 | clear: 'Clear',
12 | week: 'Week',
13 | month: 'Month',
14 | year: 'Year',
15 | timeSelect: 'Select time',
16 | dateSelect: 'Select date',
17 | monthSelect: 'Choose a month',
18 | yearSelect: 'Choose a year',
19 | decadeSelect: 'Choose a decade',
20 |
21 | previousMonth: 'Previous month (PageUp)',
22 | nextMonth: 'Next month (PageDown)',
23 | previousYear: 'Last year (Control + left)',
24 | nextYear: 'Next year (Control + right)',
25 | previousDecade: 'Last decade',
26 | nextDecade: 'Next decade',
27 | previousCentury: 'Last century',
28 | nextCentury: 'Next century',
29 | };
30 |
31 | export default locale;
32 |
--------------------------------------------------------------------------------
/src/locale/en_US.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'en_US',
7 | today: 'Today',
8 | now: 'Now',
9 | backToToday: 'Back to today',
10 | ok: 'OK',
11 | clear: 'Clear',
12 | week: 'Week',
13 | month: 'Month',
14 | year: 'Year',
15 | timeSelect: 'select time',
16 | dateSelect: 'select date',
17 | weekSelect: 'Choose a week',
18 | monthSelect: 'Choose a month',
19 | yearSelect: 'Choose a year',
20 | decadeSelect: 'Choose a decade',
21 |
22 | previousMonth: 'Previous month (PageUp)',
23 | nextMonth: 'Next month (PageDown)',
24 | previousYear: 'Last year (Control + left)',
25 | nextYear: 'Next year (Control + right)',
26 | previousDecade: 'Last decade',
27 | nextDecade: 'Next decade',
28 | previousCentury: 'Last century',
29 | nextCentury: 'Next century',
30 | };
31 |
32 | export default locale;
33 |
--------------------------------------------------------------------------------
/src/locale/es_ES.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'es_ES',
7 | today: 'Hoy',
8 | now: 'Ahora',
9 | backToToday: 'Volver a hoy',
10 | ok: 'Aceptar',
11 | clear: 'Limpiar',
12 | week: 'Semana',
13 | month: 'Mes',
14 | year: 'Año',
15 | timeSelect: 'Seleccionar hora',
16 | dateSelect: 'Seleccionar fecha',
17 | monthSelect: 'Elegir un mes',
18 | yearSelect: 'Elegir un año',
19 | decadeSelect: 'Elegir una década',
20 |
21 | previousMonth: 'Mes anterior (PageUp)',
22 | nextMonth: 'Mes siguiente (PageDown)',
23 | previousYear: 'Año anterior (Control + left)',
24 | nextYear: 'Año siguiente (Control + right)',
25 | previousDecade: 'Década anterior',
26 | nextDecade: 'Década siguiente',
27 | previousCentury: 'Siglo anterior',
28 | nextCentury: 'Siglo siguiente',
29 | };
30 |
31 | export default locale;
32 |
--------------------------------------------------------------------------------
/src/locale/es_MX.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'es_MX',
7 | today: 'Hoy',
8 | now: 'Ahora',
9 | backToToday: 'Volver a hoy',
10 | ok: 'Aceptar',
11 | clear: 'Limpiar',
12 | week: 'Semana',
13 | month: 'Mes',
14 | year: 'Año',
15 | timeSelect: 'elegir hora',
16 | dateSelect: 'elegir fecha',
17 | weekSelect: 'elegir semana',
18 | monthSelect: 'Seleccionar mes',
19 | yearSelect: 'Seleccionar año',
20 | decadeSelect: 'Seleccionar década',
21 |
22 | previousMonth: 'Mes anterior (PageUp)',
23 | nextMonth: 'Mes siguiente (PageDown)',
24 | previousYear: 'Año anterior (Control + Left)',
25 | nextYear: 'Año siguiente (Control + Right)',
26 | previousDecade: 'Década anterior',
27 | nextDecade: 'Década siguiente',
28 | previousCentury: 'Siglo anterior',
29 | nextCentury: 'Siglo siguiente',
30 | };
31 |
32 | export default locale;
33 |
--------------------------------------------------------------------------------
/src/locale/et_EE.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'et_EE',
7 | today: 'Täna',
8 | now: 'Praegu',
9 | backToToday: 'Tagasi tänase juurde',
10 | ok: 'OK',
11 | clear: 'Tühista',
12 | week: 'Nädal',
13 | month: 'Kuu',
14 | year: 'Aasta',
15 | timeSelect: 'Vali aeg',
16 | dateSelect: 'Vali kuupäev',
17 | monthSelect: 'Vali kuu',
18 | yearSelect: 'Vali aasta',
19 | decadeSelect: 'Vali dekaad',
20 |
21 | previousMonth: 'Eelmine kuu (PageUp)',
22 | nextMonth: 'Järgmine kuu (PageDown)',
23 | previousYear: 'Eelmine aasta (Control + left)',
24 | nextYear: 'Järgmine aasta (Control + right)',
25 | previousDecade: 'Eelmine dekaad',
26 | nextDecade: 'Järgmine dekaad',
27 | previousCentury: 'Eelmine sajand',
28 | nextCentury: 'Järgmine sajand',
29 | };
30 |
31 | export default locale;
32 |
--------------------------------------------------------------------------------
/src/locale/eu_ES.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'eu_ES',
7 | today: 'Gaur',
8 | now: 'Orain',
9 | backToToday: 'Gaur itzuli',
10 | ok: 'OK',
11 | clear: 'Garbitu',
12 | week: 'Asteko',
13 | month: 'Hilabete',
14 | year: 'Urte',
15 | timeSelect: 'Ordua aukeratu',
16 | dateSelect: 'Eguna aukeratu',
17 | weekSelect: 'Astea aukeratu',
18 | monthSelect: 'Hilabetea aukeratu',
19 | yearSelect: 'Urtea aukeratu',
20 | decadeSelect: 'Hamarkada aukeratu',
21 | monthBeforeYear: false,
22 | previousMonth: 'Aurreko hilabetea (RePag)',
23 | nextMonth: 'Urrengo hilabetea (AvPag)',
24 | previousYear: 'Aurreko urtea (Control + ezkerra)',
25 | nextYear: 'Urrento urtea (Control + eskuina)',
26 | previousDecade: 'Aurreko hamarkada',
27 | nextDecade: 'Urrengo hamarkada',
28 | previousCentury: 'Aurreko mendea',
29 | nextCentury: 'Urrengo mendea',
30 | };
31 |
32 | export default locale;
33 |
--------------------------------------------------------------------------------
/src/locale/fa_IR.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'fa_IR',
7 | today: 'امروز',
8 | now: 'اکنون',
9 | backToToday: 'بازگشت به روز',
10 | ok: 'باشه',
11 | clear: 'پاک کردن',
12 | week: 'هفته',
13 | month: 'ماه',
14 | year: 'سال',
15 | timeSelect: 'انتخاب زمان',
16 | dateSelect: 'انتخاب تاریخ',
17 | monthSelect: 'یک ماه را انتخاب کنید',
18 | yearSelect: 'یک سال را انتخاب کنید',
19 | decadeSelect: 'یک دهه را انتخاب کنید',
20 |
21 | previousMonth: 'ماه قبل (PageUp)',
22 | nextMonth: 'ماه بعد (PageDown)',
23 | previousYear: 'سال قبل (Control + left)',
24 | nextYear: 'سال بعد (Control + right)',
25 | previousDecade: 'دهه قبل',
26 | nextDecade: 'دهه بعد',
27 | previousCentury: 'قرن قبل',
28 | nextCentury: 'قرن بعد',
29 | };
30 |
31 | export default locale;
32 |
--------------------------------------------------------------------------------
/src/locale/fi_FI.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'fi_FI',
7 | today: 'Tänään',
8 | now: 'Nyt',
9 | backToToday: 'Tämä päivä',
10 | ok: 'OK',
11 | clear: 'Tyhjennä',
12 | week: 'Viikko',
13 | month: 'Kuukausi',
14 | year: 'Vuosi',
15 | timeSelect: 'Valise aika',
16 | dateSelect: 'Valitse päivä',
17 | monthSelect: 'Valitse kuukausi',
18 | yearSelect: 'Valitse vuosi',
19 | decadeSelect: 'Valitse vuosikymmen',
20 |
21 | previousMonth: 'Edellinen kuukausi (PageUp)',
22 | nextMonth: 'Seuraava kuukausi (PageDown)',
23 | previousYear: 'Edellinen vuosi (Control + left)',
24 | nextYear: 'Seuraava vuosi (Control + right)',
25 | previousDecade: 'Edellinen vuosikymmen',
26 | nextDecade: 'Seuraava vuosikymmen',
27 | previousCentury: 'Edellinen vuosisata',
28 | nextCentury: 'Seuraava vuosisata',
29 | };
30 |
31 | export default locale;
32 |
--------------------------------------------------------------------------------
/src/locale/fr_BE.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'fr_BE',
7 | today: "Aujourd'hui",
8 | now: 'Maintenant',
9 | backToToday: "Aujourd'hui",
10 | ok: 'OK',
11 | clear: 'Rétablir',
12 | week: 'Semaine',
13 | month: 'Mois',
14 | year: 'Année',
15 | timeSelect: "Sélectionner l'heure",
16 | dateSelect: "Sélectionner l'heure",
17 | monthSelect: 'Choisissez un mois',
18 | yearSelect: 'Choisissez une année',
19 | decadeSelect: 'Choisissez une décennie',
20 |
21 | previousMonth: 'Mois précédent (PageUp)',
22 | nextMonth: 'Mois suivant (PageDown)',
23 | previousYear: 'Année précédente (Ctrl + gauche)',
24 | nextYear: 'Année prochaine (Ctrl + droite)',
25 | previousDecade: 'Décennie précédente',
26 | nextDecade: 'Décennie suivante',
27 | previousCentury: 'Siècle précédent',
28 | nextCentury: 'Siècle suivant',
29 | };
30 |
31 | export default locale;
32 |
--------------------------------------------------------------------------------
/src/locale/fr_CA.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'fr_CA',
7 | today: "Aujourd'hui",
8 | now: 'Maintenant',
9 | backToToday: "Aujourd'hui",
10 | ok: 'OK',
11 | clear: 'Rétablir',
12 | week: 'Semaine',
13 | month: 'Mois',
14 | year: 'Année',
15 | timeSelect: "Sélectionner l'heure",
16 | dateSelect: 'Sélectionner la date',
17 | monthSelect: 'Choisissez un mois',
18 | yearSelect: 'Choisissez une année',
19 | decadeSelect: 'Choisissez une décennie',
20 |
21 | dayFormat: 'DD',
22 |
23 | previousMonth: 'Mois précédent (PageUp)',
24 | nextMonth: 'Mois suivant (PageDown)',
25 | previousYear: 'Année précédente (Ctrl + gauche)',
26 | nextYear: 'Année prochaine (Ctrl + droite)',
27 | previousDecade: 'Décennie précédente',
28 | nextDecade: 'Décennie suivante',
29 | previousCentury: 'Siècle précédent',
30 | nextCentury: 'Siècle suivant',
31 | };
32 |
33 | export default locale;
34 |
--------------------------------------------------------------------------------
/src/locale/fr_FR.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'fr_FR',
7 | today: "Aujourd'hui",
8 | now: 'Maintenant',
9 | backToToday: "Aujourd'hui",
10 | ok: 'OK',
11 | clear: 'Rétablir',
12 | week: 'Semaine',
13 | month: 'Mois',
14 | year: 'Année',
15 | timeSelect: "Sélectionner l'heure",
16 | dateSelect: 'Sélectionner la date',
17 | monthSelect: 'Choisissez un mois',
18 | yearSelect: 'Choisissez une année',
19 | decadeSelect: 'Choisissez une décennie',
20 |
21 | dayFormat: 'DD',
22 |
23 | previousMonth: 'Mois précédent (PageUp)',
24 | nextMonth: 'Mois suivant (PageDown)',
25 | previousYear: 'Année précédente (Ctrl + gauche)',
26 | nextYear: 'Année prochaine (Ctrl + droite)',
27 | previousDecade: 'Décennie précédente',
28 | nextDecade: 'Décennie suivante',
29 | previousCentury: 'Siècle précédent',
30 | nextCentury: 'Siècle suivant',
31 | };
32 |
33 | export default locale;
34 |
--------------------------------------------------------------------------------
/src/locale/ga_IE.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'ga_IE',
7 | today: 'inniu',
8 | now: 'anois',
9 | backToToday: 'Ar ais inniu',
10 | ok: 'ceart go leor',
11 | clear: 'soiléir',
12 | week: 'seachtain',
13 | month: 'mhí',
14 | year: 'bhliain',
15 | timeSelect: 'roghnaigh am',
16 | dateSelect: 'roghnaigh dáta',
17 | weekSelect: 'Roghnaigh seachtain',
18 | monthSelect: 'Roghnaigh mí',
19 | yearSelect: 'Roghnaigh bliain',
20 | decadeSelect: 'Roghnaigh deich mbliana',
21 |
22 | previousMonth: 'An mhí roimhe seo (PageUp)',
23 | nextMonth: 'An mhí seo chugainn (PageDown)',
24 | previousYear: 'Anuraidh (Control + left)',
25 | nextYear: 'An bhliain seo chugainn (Control + right)',
26 | previousDecade: 'Le deich mbliana anuas',
27 | nextDecade: 'Deich mbliana amach romhainn',
28 | previousCentury: 'An chéid seo caite',
29 | nextCentury: 'An chéad aois eile',
30 | };
31 |
32 | export default locale;
33 |
--------------------------------------------------------------------------------
/src/locale/gl_ES.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'gl_ES',
7 | today: 'Hoxe',
8 | now: 'Agora',
9 | backToToday: 'Voltar a hoxe',
10 | ok: 'Aceptar',
11 | clear: 'Limpar',
12 | week: 'Semana',
13 | month: 'Mes',
14 | year: 'Ano',
15 | timeSelect: 'Seleccionar hora',
16 | dateSelect: 'Seleccionar data',
17 | monthSelect: 'Elexir un mes',
18 | yearSelect: 'Elexir un año',
19 | decadeSelect: 'Elexir unha década',
20 |
21 | previousMonth: 'Mes anterior (PageUp)',
22 | nextMonth: 'Mes seguinte (PageDown)',
23 | previousYear: 'Ano anterior (Control + left)',
24 | nextYear: 'Ano seguinte (Control + right)',
25 | previousDecade: 'Década anterior',
26 | nextDecade: 'Década seguinte',
27 | previousCentury: 'Século anterior',
28 | nextCentury: 'Século seguinte',
29 | };
30 |
31 | export default locale;
32 |
--------------------------------------------------------------------------------
/src/locale/he_IL.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'he_IL',
7 | today: 'היום',
8 | now: 'עכשיו',
9 | backToToday: 'חזור להיום',
10 | ok: 'אישור',
11 | clear: 'איפוס',
12 | week: 'שבוע',
13 | month: 'חודש',
14 | year: 'שנה',
15 | timeSelect: 'בחר שעה',
16 | dateSelect: 'בחר תאריך',
17 | weekSelect: 'בחר שבוע',
18 | monthSelect: 'בחר חודש',
19 | yearSelect: 'בחר שנה',
20 | decadeSelect: 'בחר עשור',
21 |
22 | previousMonth: 'חודש קודם (PageUp)',
23 | nextMonth: 'חודש הבא (PageDown)',
24 | previousYear: 'שנה שעברה (Control + left)',
25 | nextYear: 'שנה הבאה (Control + right)',
26 | previousDecade: 'העשור הקודם',
27 | nextDecade: 'העשור הבא',
28 | previousCentury: 'המאה הקודמת',
29 | nextCentury: 'המאה הבאה',
30 | };
31 |
32 | export default locale;
33 |
--------------------------------------------------------------------------------
/src/locale/hi_IN.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'hi_IN',
7 | today: 'आज',
8 | now: 'अभी',
9 | backToToday: 'आज तक',
10 | ok: 'ठीक',
11 | clear: 'स्पष्ट',
12 | week: 'सप्ताह',
13 | month: 'महीना',
14 | year: 'साल',
15 | timeSelect: 'समय का चयन करें',
16 | dateSelect: 'तारीख़ चुनें',
17 | weekSelect: 'एक सप्ताह चुनें',
18 | monthSelect: 'एक महीना चुनें',
19 | yearSelect: 'एक वर्ष चुनें',
20 | decadeSelect: 'एक दशक चुनें',
21 |
22 | previousMonth: 'पिछला महीना (पेजअप)',
23 | nextMonth: 'अगले महीने (पेजडाउन)',
24 | previousYear: 'पिछले साल (Ctrl + बाएं)',
25 | nextYear: 'अगले साल (Ctrl + दाहिना)',
26 | previousDecade: 'पिछला दशक',
27 | nextDecade: 'अगले दशक',
28 | previousCentury: 'पीछ्ली शताब्दी',
29 | nextCentury: 'अगली सदी',
30 | };
31 |
32 | export default locale;
33 |
--------------------------------------------------------------------------------
/src/locale/hr_HR.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'hr_HR',
7 | today: 'Danas',
8 | now: 'Sad',
9 | backToToday: 'Natrag na danas',
10 | ok: 'OK',
11 | clear: 'Očisti',
12 | week: 'Sedmica',
13 | month: 'Mjesec',
14 | year: 'Godina',
15 | timeSelect: 'odaberite vrijeme',
16 | dateSelect: 'odaberite datum',
17 | weekSelect: 'Odaberite tjedan',
18 | monthSelect: 'Odaberite mjesec',
19 | yearSelect: 'Odaberite godinu',
20 | decadeSelect: 'Odaberite desetljeće',
21 |
22 | previousMonth: 'Prošli mjesec (PageUp)',
23 | nextMonth: 'Sljedeći mjesec (PageDown)',
24 | previousYear: 'Prošla godina (Control + left)',
25 | nextYear: 'Sljedeća godina (Control + right)',
26 | previousDecade: 'Prošlo desetljeće',
27 | nextDecade: 'Sljedeće desetljeće',
28 | previousCentury: 'Prošlo stoljeće',
29 | nextCentury: 'Sljedeće stoljeće',
30 | };
31 |
32 | export default locale;
33 |
--------------------------------------------------------------------------------
/src/locale/hu_HU.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'hu_HU',
7 | today: 'Ma', // 'Today',
8 | now: 'Most', // 'Now',
9 | backToToday: 'Vissza a mai napra', // 'Back to today',
10 | ok: 'OK',
11 | clear: 'Törlés', // 'Clear',
12 | week: 'Hét',
13 | month: 'Hónap', // 'Month',
14 | year: 'Év', // 'Year',
15 | timeSelect: 'Időpont kiválasztása', // 'Select time',
16 | dateSelect: 'Dátum kiválasztása', // 'Select date',
17 | monthSelect: 'Hónap kiválasztása', // 'Choose a month',
18 | yearSelect: 'Év kiválasztása', // 'Choose a year',
19 | decadeSelect: 'Évtized kiválasztása', // 'Choose a decade',
20 |
21 | dayFormat: 'DD', // 'D',
22 |
23 | previousMonth: 'Előző hónap (PageUp)', // 'Previous month (PageUp)',
24 | nextMonth: 'Következő hónap (PageDown)', // 'Next month (PageDown)',
25 | previousYear: 'Múlt év (Control + left)', // 'Last year (Control + left)',
26 | nextYear: 'Jövő év (Control + right)', // 'Next year (Control + right)',
27 | previousDecade: 'Előző évtized', // 'Last decade',
28 | nextDecade: 'Következő évtized', // 'Next decade',
29 | previousCentury: 'Múlt évszázad', // 'Last century',
30 | nextCentury: 'Jövő évszázad', // 'Next century',
31 | };
32 |
33 | export default locale;
34 |
--------------------------------------------------------------------------------
/src/locale/id_ID.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'id_ID',
7 | today: 'Hari ini',
8 | now: 'Sekarang',
9 | backToToday: 'Kembali ke hari ini',
10 | ok: 'Baik',
11 | clear: 'Bersih',
12 | week: 'Minggu',
13 | month: 'Bulan',
14 | year: 'Tahun',
15 | timeSelect: 'pilih waktu',
16 | dateSelect: 'pilih tanggal',
17 | weekSelect: 'Pilih satu minggu',
18 | monthSelect: 'Pilih satu bulan',
19 | yearSelect: 'Pilih satu tahun',
20 | decadeSelect: 'Pilih satu dekade',
21 |
22 | previousMonth: 'Bulan sebelumnya (PageUp)',
23 | nextMonth: 'Bulan selanjutnya (PageDown)',
24 | previousYear: 'Tahun lalu (Control + kiri)',
25 | nextYear: 'Tahun selanjutnya (Kontrol + kanan)',
26 | previousDecade: 'Dekade terakhir',
27 | nextDecade: 'Dekade berikutnya',
28 | previousCentury: 'Abad terakhir',
29 | nextCentury: 'Abad berikutnya',
30 | };
31 |
32 | export default locale;
33 |
--------------------------------------------------------------------------------
/src/locale/is_IS.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'is_IS',
7 | today: 'Í dag',
8 | now: 'Núna',
9 | backToToday: 'Til baka til dagsins í dag',
10 | ok: 'Í lagi',
11 | clear: 'Hreinsa',
12 | week: 'Vika',
13 | month: 'Mánuður',
14 | year: 'Ár',
15 | timeSelect: 'Velja tíma',
16 | dateSelect: 'Velja dag',
17 | monthSelect: 'Velja mánuð',
18 | yearSelect: 'Velja ár',
19 | decadeSelect: 'Velja áratug',
20 |
21 | previousMonth: 'Fyrri mánuður (PageUp)',
22 | nextMonth: 'Næsti mánuður (PageDown)',
23 | previousYear: 'Fyrra ár (Control + left)',
24 | nextYear: 'Næsta ár (Control + right)',
25 | previousDecade: 'Fyrri áratugur',
26 | nextDecade: 'Næsti áratugur',
27 | previousCentury: 'Fyrri öld',
28 | nextCentury: 'Næsta öld',
29 | };
30 |
31 | export default locale;
32 |
--------------------------------------------------------------------------------
/src/locale/it_IT.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'it_IT',
7 | today: 'Oggi',
8 | now: 'Adesso',
9 | backToToday: 'Torna ad oggi',
10 | ok: 'OK',
11 | clear: 'Cancella',
12 | week: 'Settimana',
13 | month: 'Mese',
14 | year: 'Anno',
15 | timeSelect: "Seleziona l'ora",
16 | dateSelect: 'Seleziona la data',
17 | monthSelect: 'Seleziona il mese',
18 | yearSelect: "Seleziona l'anno",
19 | decadeSelect: 'Seleziona il decennio',
20 |
21 | previousMonth: 'Il mese scorso (PageUp)',
22 | nextMonth: 'Il prossimo mese (PageDown)',
23 | previousYear: "L'anno scorso (Control + sinistra)",
24 | nextYear: "L'anno prossimo (Control + destra)",
25 | previousDecade: 'Ultimo decennio',
26 | nextDecade: 'Prossimo decennio',
27 | previousCentury: 'Secolo precedente',
28 | nextCentury: 'Prossimo secolo',
29 | shortWeekDays: ['Dom', 'Lun', 'Mar', 'Mer', 'Gio', 'Ven', 'Sab'],
30 | shortMonths: ['Gen', 'Feb', 'Mar', 'Apr', 'Mag', 'Giu', 'Lug', 'Ago', 'Set', 'Ott', 'Nov', 'Dic'],
31 | };
32 |
33 | export default locale;
34 |
--------------------------------------------------------------------------------
/src/locale/ja_JP.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'ja_JP',
7 | today: '今日',
8 | now: '現在時刻',
9 | backToToday: '今日に戻る',
10 | ok: '確定',
11 | timeSelect: '時間を選択',
12 | dateSelect: '日時を選択',
13 | weekSelect: '週を選択',
14 | clear: 'クリア',
15 | week: '週',
16 | month: '月',
17 | year: '年',
18 | previousMonth: '前月 (ページアップキー)',
19 | nextMonth: '翌月 (ページダウンキー)',
20 | monthSelect: '月を選択',
21 | yearSelect: '年を選択',
22 | decadeSelect: '年代を選択',
23 | yearFormat: 'YYYY年',
24 | previousYear: '前年 (Controlを押しながら左キー)',
25 | nextYear: '翌年 (Controlを押しながら右キー)',
26 | previousDecade: '前の年代',
27 | nextDecade: '次の年代',
28 | previousCentury: '前の世紀',
29 | nextCentury: '次の世紀',
30 | monthBeforeYear: false,
31 | };
32 |
33 | export default locale;
34 |
--------------------------------------------------------------------------------
/src/locale/ka_GE.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'ka_GE',
7 | today: 'დღეს',
8 | now: 'ახლა',
9 | backToToday: 'მიმდინარე თარიღი',
10 | ok: 'OK',
11 | clear: 'გასუფთავება',
12 | week: 'კვირა',
13 | month: 'თვე',
14 | year: 'წელი',
15 | timeSelect: 'დროის არჩევა',
16 | dateSelect: 'თარიღის არჩევა',
17 | weekSelect: 'კვირის არჩევა',
18 | monthSelect: 'თვის არჩევა',
19 | yearSelect: 'წლის არჩევა',
20 | decadeSelect: 'ათწლეულის არჩევა',
21 |
22 | previousMonth: 'წინა თვე (PageUp)',
23 | nextMonth: 'მომდევნო თვე (PageDown)',
24 | previousYear: 'წინა წელი (Control + left)',
25 | nextYear: 'მომდევნო წელი (Control + right)',
26 | previousDecade: 'წინა ათწლეული',
27 | nextDecade: 'მომდევნო ათწლეული',
28 | previousCentury: 'გასული საუკუნე',
29 | nextCentury: 'მომდევნო საუკუნე',
30 | };
31 |
32 | export default locale;
33 |
--------------------------------------------------------------------------------
/src/locale/kk_KZ.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'kk_KZ',
7 | today: 'Бүгін',
8 | now: 'Қазір',
9 | backToToday: 'Ағымдағы күн',
10 | ok: 'Таңдау',
11 | clear: 'Таза',
12 | week: 'Апта',
13 | month: 'Ай',
14 | year: 'Жыл',
15 | timeSelect: 'Уақытты таңдау',
16 | dateSelect: 'Күнді таңдау',
17 | monthSelect: 'Айды таңдаңыз',
18 | yearSelect: 'Жылды таңдаңыз',
19 | decadeSelect: 'Онжылды таңдаңыз',
20 |
21 | previousMonth: 'Алдыңғы ай (PageUp)',
22 | nextMonth: 'Келесі ай (PageDown)',
23 | previousYear: 'Алдыңғы жыл (Control + left)',
24 | nextYear: 'Келесі жыл (Control + right)',
25 | previousDecade: 'Алдыңғы онжылдық',
26 | nextDecade: 'Келесі онжылдық',
27 | previousCentury: 'Алдыңғы ғасыр',
28 | nextCentury: 'Келесі ғасыр',
29 | };
30 |
31 | export default locale;
32 |
--------------------------------------------------------------------------------
/src/locale/km_KH.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'km',
7 | today: 'ថ្ងៃនេះ',
8 | now: 'ឥឡូវនេះ',
9 | backToToday: 'ត្រលប់ទៅថ្ងៃនេះ',
10 | ok: 'កំណត់',
11 | timeSelect: 'រយៈពេលជ្រើសរើស',
12 | dateSelect: 'ជ្រើសរើសកាលបរិច្ឆេទ',
13 | weekSelect: 'ជ្រើសរើសសប្តាហ៍',
14 | clear: 'ច្បាស់',
15 | week: 'សប្តាហ៍',
16 | month: 'ខែ',
17 | year: 'ឆ្នាំ',
18 | previousMonth: 'ខែមុន (ឡើងទំព័រ)',
19 | nextMonth: 'ខែបន្ទាប់ (ប៊ូតុងចុះទំព័រ)',
20 | monthSelect: 'ជ្រើសរើសខែ',
21 | yearSelect: 'ជ្រើសរើសឆ្នាំ',
22 | decadeSelect: 'ជ្រើសរើសអាយុ',
23 |
24 | previousYear: 'ឆ្នាំមុន (Controlគ្រាប់ចុចបូកព្រួញខាងឆ្វេង)',
25 | nextYear: 'ឆ្នាំក្រោយ (Control គ្រាប់ចុចបូកព្រួញស្ដាំ)',
26 | previousDecade: 'ជំនាន់ចុងក្រោយ',
27 | nextDecade: 'ជំនាន់ក្រោយ',
28 | previousCentury: 'សតវត្សចុងក្រោយ',
29 | nextCentury: 'សតវត្សរ៍បន្ទាប់',
30 | monthBeforeYear: false,
31 | };
32 |
33 | export default locale;
34 |
--------------------------------------------------------------------------------
/src/locale/kmr_IQ.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'ku',
7 | today: 'Îro',
8 | now: 'Niha',
9 | backToToday: 'Vegere îro',
10 | ok: 'Temam',
11 | clear: 'Paqij bike',
12 | week: 'Sêbê',
13 | month: 'Meh',
14 | year: 'Sal',
15 | timeSelect: 'Demê hilbijêre',
16 | dateSelect: 'Dîrok hilbijêre',
17 | monthSelect: 'Meh hilbijêre',
18 | yearSelect: 'Sal hilbijêre',
19 | decadeSelect: 'Dehsal hilbijêre',
20 |
21 | previousMonth: 'Meha peş (PageUp))',
22 | nextMonth: 'Meha paş (PageDown)',
23 | previousYear: 'Sala peş (Control + şep)',
24 | nextYear: 'Sala paş (Control + rast)',
25 | previousDecade: 'Dehsalen peş',
26 | nextDecade: 'Dehsalen paş',
27 | previousCentury: 'Sedsalen peş',
28 | nextCentury: 'Sedsalen paş',
29 | };
30 |
31 | export default locale;
32 |
--------------------------------------------------------------------------------
/src/locale/kn_IN.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'kn_IN',
7 | today: 'ಇಂದು',
8 | now: 'ಈಗ',
9 | backToToday: 'ಇಂದು ಹಿಂದಿರುಗಿ',
10 | ok: 'ಸರಿ',
11 | clear: 'ಸ್ಪಷ್ಟ',
12 | week: 'ವಾರ',
13 | month: 'ತಿಂಗಳು',
14 | year: 'ವರ್ಷ',
15 | timeSelect: 'ಸಮಯ ಆಯ್ಕೆಮಾಡಿ',
16 | dateSelect: 'ದಿನಾಂಕವನ್ನು ಆಯ್ಕೆ ಮಾಡಿ',
17 | weekSelect: 'ಒಂದು ವಾರದ ಆರಿಸಿ',
18 | monthSelect: 'ಒಂದು ತಿಂಗಳು ಆಯ್ಕೆಮಾಡಿ',
19 | yearSelect: 'ಒಂದು ವರ್ಷ ಆರಿಸಿ',
20 | decadeSelect: 'ಒಂದು ದಶಕದ ಆಯ್ಕೆಮಾಡಿ',
21 |
22 | previousMonth: 'ಹಿಂದಿನ ತಿಂಗಳು (ಪೇಜ್ಅಪ್)',
23 | nextMonth: 'ಮುಂದಿನ ತಿಂಗಳು (ಪೇಜ್ಡೌನ್)',
24 | previousYear: 'ಕಳೆದ ವರ್ಷ (Ctrl + ಎಡ)',
25 | nextYear: 'ಮುಂದಿನ ವರ್ಷ (Ctrl + ಬಲ)',
26 | previousDecade: 'ಕಳೆದ ದಶಕ',
27 | nextDecade: 'ಮುಂದಿನ ದಶಕ',
28 | previousCentury: 'ಕಳೆದ ಶತಮಾನ',
29 | nextCentury: 'ಮುಂದಿನ ಶತಮಾನ',
30 | };
31 |
32 | export default locale;
33 |
--------------------------------------------------------------------------------
/src/locale/ko_KR.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'ko_KR',
7 | today: '오늘',
8 | now: '현재 시각',
9 | backToToday: '오늘로 돌아가기',
10 | ok: '확인',
11 | clear: '지우기',
12 | week: '주',
13 | month: '월',
14 | year: '년',
15 | timeSelect: '시간 선택',
16 | dateSelect: '날짜 선택',
17 | monthSelect: '달 선택',
18 | yearSelect: '연 선택',
19 | decadeSelect: '연대 선택',
20 | yearFormat: 'YYYY년',
21 | monthBeforeYear: false,
22 | previousMonth: '이전 달 (PageUp)',
23 | nextMonth: '다음 달 (PageDown)',
24 | previousYear: '이전 해 (Control + left)',
25 | nextYear: '다음 해 (Control + right)',
26 | previousDecade: '이전 연대',
27 | nextDecade: '다음 연대',
28 | previousCentury: '이전 세기',
29 | nextCentury: '다음 세기',
30 | };
31 |
32 | export default locale;
33 |
--------------------------------------------------------------------------------
/src/locale/lt_LT.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'lt_LT',
7 | today: 'Šiandien',
8 | now: 'Dabar',
9 | backToToday: 'Rodyti šiandien',
10 | ok: 'Gerai',
11 | clear: 'Išvalyti',
12 | week: 'Savaitė',
13 | month: 'Mėnesis',
14 | year: 'Metai',
15 | timeSelect: 'Pasirinkti laiką',
16 | dateSelect: 'Pasirinkti datą',
17 | weekSelect: 'Pasirinkti savaitę',
18 | monthSelect: 'Pasirinkti mėnesį',
19 | yearSelect: 'Pasirinkti metus',
20 | decadeSelect: 'Pasirinkti dešimtmetį',
21 |
22 | dayFormat: 'DD',
23 |
24 | previousMonth: 'Buvęs mėnesis (PageUp)',
25 | nextMonth: 'Kitas mėnesis (PageDown)',
26 | previousYear: 'Buvę metai (Control + left)',
27 | nextYear: 'Kiti metai (Control + right)',
28 | previousDecade: 'Buvęs dešimtmetis',
29 | nextDecade: 'Kitas dešimtmetis',
30 | previousCentury: 'Buvęs amžius',
31 | nextCentury: 'Kitas amžius',
32 | };
33 |
34 | export default locale;
35 |
--------------------------------------------------------------------------------
/src/locale/lv_LV.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'lv_LV',
7 | today: 'Šodien',
8 | now: 'Tagad',
9 | backToToday: 'Atpakaļ pie šodienas',
10 | ok: 'OK',
11 | clear: 'Skaidrs',
12 | week: 'Nedēļa',
13 | month: 'Mēnesis',
14 | year: 'Gads',
15 | timeSelect: 'Izvēlieties laiku',
16 | dateSelect: 'Izvēlieties datumu',
17 | monthSelect: 'Izvēlieties mēnesi',
18 | yearSelect: 'Izvēlieties gadu',
19 | decadeSelect: 'Izvēlieties desmit gadus',
20 |
21 | previousMonth: 'Iepriekšējais mēnesis (PageUp)',
22 | nextMonth: 'Nākammēnes (PageDown)',
23 | previousYear: 'Pagājušais gads (Control + left)',
24 | nextYear: 'Nākamgad (Control + right)',
25 | previousDecade: 'Pēdējā desmitgadē',
26 | nextDecade: 'Nākamā desmitgade',
27 | previousCentury: 'Pagājušajā gadsimtā',
28 | nextCentury: 'Nākamajā gadsimtā',
29 | };
30 |
31 | export default locale;
32 |
--------------------------------------------------------------------------------
/src/locale/mk_MK.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'mk_MK',
7 | today: 'Денес',
8 | now: 'Сега',
9 | backToToday: 'Назад до денес',
10 | ok: 'ОК',
11 | clear: 'Избриши',
12 | week: 'Недела',
13 | month: 'Месец',
14 | year: 'Година',
15 | timeSelect: 'Избери време',
16 | dateSelect: 'Избери датум',
17 | monthSelect: 'Избери месец',
18 | yearSelect: 'Избери година',
19 | decadeSelect: 'Избери деценија',
20 |
21 | previousMonth: 'Претходен месец (PageUp)',
22 | nextMonth: 'Нареден месец (PageDown)',
23 | previousYear: 'Претходна година (Control + left)',
24 | nextYear: 'Наредна година (Control + right)',
25 | previousDecade: 'Претходна деценија',
26 | nextDecade: 'Наредна деценија',
27 | previousCentury: 'Претходен век',
28 | nextCentury: 'Нареден век',
29 | };
30 |
31 | export default locale;
32 |
--------------------------------------------------------------------------------
/src/locale/ml_IN.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'ml_IN',
7 | today: 'ഇന്ന്',
8 | now: 'ഇപ്പോൾ',
9 | backToToday: 'ഇന്നത്തെ ദിവസത്തിലേക്ക് തിരിച്ചു പോകുക',
10 | ok: 'ശരിയാണ്',
11 | clear: 'നീക്കം ചെയ്യുക',
12 | week: 'ആഴ്ച',
13 | month: 'മാസം',
14 | year: 'വർഷം',
15 | timeSelect: 'സമയം തിരഞ്ഞെടുക്കുക',
16 | dateSelect: 'ദിവസം തിരഞ്ഞെടുക്കുക',
17 | weekSelect: 'വാരം തിരഞ്ഞെടുക്കുക',
18 | monthSelect: 'മാസം തിരഞ്ഞെടുക്കുക',
19 | yearSelect: 'വർഷം തിരഞ്ഞെടുക്കുക',
20 | decadeSelect: 'ദശാബ്ദം തിരഞ്ഞെടുക്കുക',
21 |
22 | previousMonth: 'കഴിഞ്ഞ മാസം (PageUp)',
23 | nextMonth: 'അടുത്ത മാസം (PageDown)',
24 | previousYear: 'കഴിഞ്ഞ വർഷം (Control + left)',
25 | nextYear: 'അടുത്ത വർഷം (Control + right)',
26 | previousDecade: 'കഴിഞ്ഞ ദശാബ്ദം',
27 | nextDecade: 'അടുത്ത ദശാബ്ദം',
28 | previousCentury: 'കഴിഞ്ഞ നൂറ്റാണ്ട്',
29 | nextCentury: 'അടുത്ത നൂറ്റാണ്ട്',
30 | };
31 |
32 | export default locale;
33 |
--------------------------------------------------------------------------------
/src/locale/mn_MN.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'mn_MN',
7 | today: 'Өнөөдөр',
8 | now: 'Одоо',
9 | backToToday: 'Өнөөдөрлүү буцах',
10 | ok: 'OK',
11 | clear: 'Цэвэрлэх',
12 | week: 'Долоо хоног',
13 | month: 'Сар',
14 | year: 'Жил',
15 | timeSelect: 'Цаг сонгох',
16 | dateSelect: 'Огноо сонгох',
17 | weekSelect: '7 хоног сонгох',
18 | monthSelect: 'Сар сонгох',
19 | yearSelect: 'Жил сонгох',
20 | decadeSelect: 'Арван сонгох',
21 |
22 | dayFormat: 'DD',
23 |
24 | previousMonth: 'Өмнөх сар (PageUp)',
25 | nextMonth: 'Дараа сар (PageDown)',
26 | previousYear: 'Өмнөх жил (Control + left)',
27 | nextYear: 'Дараа жил (Control + right)',
28 | previousDecade: 'Өмнөх арван',
29 | nextDecade: 'Дараа арван',
30 | previousCentury: 'Өмнөх зуун',
31 | nextCentury: 'Дараа зуун',
32 | };
33 |
34 | export default locale;
35 |
--------------------------------------------------------------------------------
/src/locale/ms_MY.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'ms_MY',
7 | today: 'Hari ini',
8 | now: 'Sekarang',
9 | backToToday: 'Kembali ke hari ini',
10 | ok: 'OK',
11 | timeSelect: 'Pilih masa',
12 | dateSelect: 'Pilih tarikh',
13 | weekSelect: 'Pilih minggu',
14 | clear: 'Padam',
15 | week: 'Minggu',
16 | month: 'Bulan',
17 | year: 'Tahun',
18 | previousMonth: 'Bulan lepas',
19 | nextMonth: 'Bulan depan',
20 | monthSelect: 'Pilih bulan',
21 | yearSelect: 'Pilih tahun',
22 | decadeSelect: 'Pilih dekad',
23 |
24 | previousYear: 'Tahun lepas (Ctrl+left)',
25 | nextYear: 'Tahun depan (Ctrl+right)',
26 | previousDecade: 'Dekad lepas',
27 | nextDecade: 'Dekad depan',
28 | previousCentury: 'Abad lepas',
29 | nextCentury: 'Abad depan',
30 |
31 | monthBeforeYear: false,
32 | };
33 |
34 | export default locale;
35 |
--------------------------------------------------------------------------------
/src/locale/my_MM.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'my_MM',
7 | today: 'ယနေ့',
8 | now: 'ယခု',
9 | backToToday: 'ယနေ့မတိုင်ခင်သို့',
10 | ok: 'OK',
11 | clear: 'ရှင်းမည်',
12 | week: 'အပတ်',
13 | month: 'လ',
14 | year: 'နှစ်',
15 | timeSelect: 'အချိန်ကိုရွေး',
16 | dateSelect: 'နေ့ကိုရွေး',
17 | weekSelect: 'သီတင်းပတ်ကိုရွေး',
18 | monthSelect: 'လကိုရွေး',
19 | yearSelect: 'နှစ်ကိုရွေး',
20 | decadeSelect: 'ဆယ်စုနှစ်ကိုရွေး',
21 |
22 | previousMonth: 'ယခင်လ (PageUp)',
23 | nextMonth: 'နောက်လ (PageDown)',
24 | previousYear: 'ယခင်နှစ် (Control + left)',
25 | nextYear: 'နောက်နှစ် (Control + right)',
26 | previousDecade: 'ယခင်ဆယ်စုနှစ်',
27 | nextDecade: 'နောက်ဆယ်စုနှစ်',
28 | previousCentury: 'ယခင်ရာစုနှစ်',
29 | nextCentury: 'နောက်ရာစုနှစ်',
30 | };
31 |
32 | export default locale;
33 |
--------------------------------------------------------------------------------
/src/locale/nb_NO.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'nb_NO',
7 | today: 'I dag',
8 | now: 'Nå',
9 | backToToday: 'Gå til i dag',
10 | ok: 'OK',
11 | clear: 'Annuller',
12 | week: 'Uke',
13 | month: 'Måned',
14 | year: 'År',
15 | timeSelect: 'Velg tidspunkt',
16 | dateSelect: 'Velg dato',
17 | weekSelect: 'Velg uke',
18 | monthSelect: 'Velg måned',
19 | yearSelect: 'Velg år',
20 | decadeSelect: 'Velg tiår',
21 |
22 | dayFormat: 'DD',
23 |
24 | previousMonth: 'Forrige måned (PageUp)',
25 | nextMonth: 'Neste måned (PageDown)',
26 | previousYear: 'Forrige år (Control + venstre)',
27 | nextYear: 'Neste år (Control + høyre)',
28 | previousDecade: 'Forrige tiår',
29 | nextDecade: 'Neste tiår',
30 | previousCentury: 'Forrige århundre',
31 | nextCentury: 'Neste århundre',
32 | };
33 |
34 | export default locale;
35 |
--------------------------------------------------------------------------------
/src/locale/ne_NP.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'ne_NP',
7 | today: 'आज',
8 | now: 'अब',
9 | backToToday: 'आज फर्कनुहोस्',
10 | ok: 'ठिक छ',
11 | clear: 'खाली गर्नुहोस्',
12 | week: 'हप्ता',
13 | month: 'महिना',
14 | year: 'वर्ष',
15 | timeSelect: 'समय चयन गर्नुहोस्',
16 | dateSelect: 'मिति चयन गर्नुहोस्',
17 | weekSelect: 'एक हप्ता छान्नुहोस्',
18 | monthSelect: 'एक महिना छान्नुहोस्',
19 | yearSelect: 'एक वर्ष छान्नुहोस्',
20 | decadeSelect: 'एक दशक छान्नुहोस्',
21 |
22 | previousMonth: 'अघिल्लो महिना (पृष्ठ माथि)',
23 | nextMonth: 'अर्को महिना (पृष्ठ तल)',
24 | previousYear: 'गत वर्ष (Control + left)',
25 | nextYear: 'आउने साल (Control + right)',
26 | previousDecade: 'पछिल्लो दशक',
27 | nextDecade: 'अर्को दशक',
28 | previousCentury: 'पछिल्लो शताब्दी',
29 | nextCentury: 'अर्को शताब्दी',
30 | };
31 |
32 | export default locale;
33 |
--------------------------------------------------------------------------------
/src/locale/nl_BE.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'nl_BE',
7 | today: 'Vandaag',
8 | now: 'Nu',
9 | backToToday: 'Terug naar vandaag',
10 | ok: 'OK',
11 | clear: 'Reset',
12 | week: 'Week',
13 | month: 'Maand',
14 | year: 'Jaar',
15 | timeSelect: 'Selecteer tijd',
16 | dateSelect: 'Selecteer datum',
17 | monthSelect: 'Kies een maand',
18 | yearSelect: 'Kies een jaar',
19 | decadeSelect: 'Kies een decennium',
20 |
21 | previousMonth: 'Vorige maand (PageUp)',
22 | nextMonth: 'Volgende maand (PageDown)',
23 | previousYear: 'Vorig jaar (Control + left)',
24 | nextYear: 'Volgend jaar (Control + right)',
25 | previousDecade: 'Vorig decennium',
26 | nextDecade: 'Volgend decennium',
27 | previousCentury: 'Vorige eeuw',
28 | nextCentury: 'Volgende eeuw',
29 | };
30 |
31 | export default locale;
32 |
--------------------------------------------------------------------------------
/src/locale/nl_NL.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'nl_NL',
7 | today: 'Vandaag',
8 | now: 'Nu',
9 | backToToday: 'Terug naar vandaag',
10 | ok: 'OK',
11 | clear: 'Reset',
12 | week: 'Week',
13 | month: 'Maand',
14 | year: 'Jaar',
15 | timeSelect: 'Selecteer tijd',
16 | dateSelect: 'Selecteer datum',
17 | monthSelect: 'Kies een maand',
18 | yearSelect: 'Kies een jaar',
19 | decadeSelect: 'Kies een decennium',
20 |
21 | previousMonth: 'Vorige maand (PageUp)',
22 | nextMonth: 'Volgende maand (PageDown)',
23 | previousYear: 'Vorig jaar (Control + left)',
24 | nextYear: 'Volgend jaar (Control + right)',
25 | previousDecade: 'Vorig decennium',
26 | nextDecade: 'Volgend decennium',
27 | previousCentury: 'Vorige eeuw',
28 | nextCentury: 'Volgende eeuw',
29 | };
30 |
31 | export default locale;
32 |
--------------------------------------------------------------------------------
/src/locale/pl_PL.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'pl_PL',
7 | today: 'Dzisiaj',
8 | now: 'Teraz',
9 | backToToday: 'Ustaw dzisiaj',
10 | ok: 'OK',
11 | clear: 'Wyczyść',
12 | week: 'Tydzień',
13 | month: 'Miesiąc',
14 | year: 'Rok',
15 | timeSelect: 'Ustaw czas',
16 | dateSelect: 'Ustaw datę',
17 | monthSelect: 'Wybierz miesiąc',
18 | yearSelect: 'Wybierz rok',
19 | decadeSelect: 'Wybierz dekadę',
20 |
21 | previousMonth: 'Poprzedni miesiąc (PageUp)',
22 | nextMonth: 'Następny miesiąc (PageDown)',
23 | previousYear: 'Ostatni rok (Ctrl + left)',
24 | nextYear: 'Następny rok (Ctrl + right)',
25 | previousDecade: 'Ostatnia dekada',
26 | nextDecade: 'Następna dekada',
27 | previousCentury: 'Ostatni wiek',
28 | nextCentury: 'Następny wiek',
29 | };
30 |
31 | export default locale;
32 |
--------------------------------------------------------------------------------
/src/locale/pt_BR.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'pt_BR',
7 | today: 'Hoje',
8 | now: 'Agora',
9 | backToToday: 'Voltar para hoje',
10 | ok: 'OK',
11 | clear: 'Limpar',
12 | week: 'Semana',
13 | month: 'Mês',
14 | year: 'Ano',
15 | timeSelect: 'Selecionar hora',
16 | dateSelect: 'Selecionar data',
17 | monthSelect: 'Escolher mês',
18 | yearSelect: 'Escolher ano',
19 | decadeSelect: 'Escolher década',
20 | monthBeforeYear: false,
21 | previousMonth: 'Mês anterior (PageUp)',
22 | nextMonth: 'Próximo mês (PageDown)',
23 | previousYear: 'Ano anterior (Control + esquerda)',
24 | nextYear: 'Próximo ano (Control + direita)',
25 | previousDecade: 'Década anterior',
26 | nextDecade: 'Próxima década',
27 | previousCentury: 'Século anterior',
28 | nextCentury: 'Próximo século',
29 | shortWeekDays: ['Dom', 'Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sáb'],
30 | shortMonths: ['Jan', 'Fev', 'Mar', 'Abr', 'Mai', 'Jun', 'Jul', 'Ago', 'Set', 'Out', 'Nov', 'Dez'],
31 | };
32 |
33 | export default locale;
34 |
--------------------------------------------------------------------------------
/src/locale/pt_PT.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'pt_PT',
7 | today: 'Hoje',
8 | now: 'Agora',
9 | backToToday: 'Hoje',
10 | ok: 'OK',
11 | clear: 'Limpar',
12 | week: 'Semana',
13 | month: 'Mês',
14 | year: 'Ano',
15 | timeSelect: 'Selecionar hora',
16 | dateSelect: 'Selecionar data',
17 | monthSelect: 'Selecionar mês',
18 | yearSelect: 'Selecionar ano',
19 | decadeSelect: 'Selecionar década',
20 |
21 | previousMonth: 'Mês anterior (PageUp)',
22 | nextMonth: 'Mês seguinte (PageDown)',
23 | previousYear: 'Ano anterior (Control + left)',
24 | nextYear: 'Ano seguinte (Control + right)',
25 | previousDecade: 'Década anterior',
26 | nextDecade: 'Década seguinte',
27 | previousCentury: 'Século anterior',
28 | nextCentury: 'Século seguinte',
29 | shortWeekDays: ['Dom', 'Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sáb'],
30 | shortMonths: ['Jan', 'Fev', 'Mar', 'Abr', 'Mai', 'Jun', 'Jul', 'Ago', 'Set', 'Out', 'Nov', 'Dez'],
31 | };
32 |
33 | export default locale;
34 |
--------------------------------------------------------------------------------
/src/locale/ro_RO.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'ro_RO',
7 | today: 'Azi',
8 | now: 'Acum',
9 | backToToday: 'Înapoi la azi',
10 | ok: 'OK',
11 | clear: 'Șterge',
12 | week: 'Săptămână',
13 | month: 'Lună',
14 | year: 'An',
15 | timeSelect: 'selectează timpul',
16 | dateSelect: 'selectează data',
17 | weekSelect: 'Alege o săptămână',
18 | monthSelect: 'Alege o lună',
19 | yearSelect: 'Alege un an',
20 | decadeSelect: 'Alege un deceniu',
21 |
22 | previousMonth: 'Luna anterioară (PageUp)',
23 | nextMonth: 'Luna următoare (PageDown)',
24 | previousYear: 'Anul anterior (Control + stânga)',
25 | nextYear: 'Anul următor (Control + dreapta)',
26 | previousDecade: 'Deceniul anterior',
27 | nextDecade: 'Deceniul următor',
28 | previousCentury: 'Secolul anterior',
29 | nextCentury: 'Secolul următor',
30 | };
31 |
32 | export default locale;
33 |
--------------------------------------------------------------------------------
/src/locale/ru_RU.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'ru_RU',
7 | today: 'Сегодня',
8 | now: 'Сейчас',
9 | backToToday: 'Текущая дата',
10 | ok: 'ОК',
11 | clear: 'Очистить',
12 | week: 'Неделя',
13 | month: 'Месяц',
14 | year: 'Год',
15 | timeSelect: 'Выбрать время',
16 | dateSelect: 'Выбрать дату',
17 | monthSelect: 'Выбрать месяц',
18 | yearSelect: 'Выбрать год',
19 | decadeSelect: 'Выбрать десятилетие',
20 |
21 | previousMonth: 'Предыдущий месяц (PageUp)',
22 | nextMonth: 'Следующий месяц (PageDown)',
23 | previousYear: 'Предыдущий год (Control + left)',
24 | nextYear: 'Следующий год (Control + right)',
25 | previousDecade: 'Предыдущее десятилетие',
26 | nextDecade: 'Следущее десятилетие',
27 | previousCentury: 'Предыдущий век',
28 | nextCentury: 'Следующий век',
29 | };
30 |
31 | export default locale;
32 |
--------------------------------------------------------------------------------
/src/locale/si_LK.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'si_LK',
7 | today: 'අද',
8 | now: 'දැන්',
9 | backToToday: 'අදට ආපසු',
10 | ok: 'හරි',
11 | clear: 'හිස් කරන්න',
12 | week: 'සතිය',
13 | month: 'මාසය',
14 | year: 'අවුරුද්ද',
15 | timeSelect: 'වේලාවක් තෝරන්න',
16 | dateSelect: 'දිනයක් තෝරන්න',
17 | weekSelect: 'සතියක් තෝරන්න',
18 | monthSelect: 'මාසයක් තෝරන්න',
19 | yearSelect: 'අවුරුද්දක් තෝරන්න',
20 | decadeSelect: 'දශකයක් තෝරන්න',
21 |
22 | monthBeforeYear: false,
23 | previousMonth: 'කලින් මාසය (පිටුව ඉහළට)',
24 | nextMonth: 'ඊළඟ මාසය (පිටුව පහළට)',
25 | previousYear: 'පසුගිය අවුරුද්ද (Control + වම)',
26 | nextYear: 'ඊළඟ අවුරුද්ද (Control + දකුණ)',
27 | previousDecade: 'පසුගිය දශකය',
28 | nextDecade: 'ඊළඟ දශකය',
29 | previousCentury: 'පසුගිය සියවස',
30 | nextCentury: 'ඊළඟ සියවස',
31 | };
32 |
33 | export default locale;
34 |
--------------------------------------------------------------------------------
/src/locale/sk_SK.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'sk_SK',
7 | today: 'Dnes',
8 | now: 'Teraz',
9 | backToToday: 'Späť na dnes',
10 | ok: 'OK',
11 | clear: 'Vymazať',
12 | week: 'Týždeň',
13 | month: 'Mesiac',
14 | year: 'Rok',
15 | timeSelect: 'Vybrať čas',
16 | dateSelect: 'Vybrať dátum',
17 | monthSelect: 'Vybrať mesiac',
18 | yearSelect: 'Vybrať rok',
19 | decadeSelect: 'Vybrať dekádu',
20 |
21 | previousMonth: 'Predchádzajúci mesiac (PageUp)',
22 | nextMonth: 'Nasledujúci mesiac (PageDown)',
23 | previousYear: 'Predchádzajúci rok (Control + left)',
24 | nextYear: 'Nasledujúci rok (Control + right)',
25 | previousDecade: 'Predchádzajúca dekáda',
26 | nextDecade: 'Nasledujúca dekáda',
27 | previousCentury: 'Predchádzajúce storočie',
28 | nextCentury: 'Nasledujúce storočie',
29 | };
30 |
31 | export default locale;
32 |
--------------------------------------------------------------------------------
/src/locale/sl_SI.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'sl_SI',
7 | today: 'Danes',
8 | now: 'Trenutno',
9 | backToToday: 'Nazaj na danes',
10 | ok: 'V redu',
11 | clear: 'Počisti',
12 | week: 'Teden',
13 | month: 'Mesec',
14 | year: 'Leto',
15 | timeSelect: 'Izberite čas',
16 | dateSelect: 'Izberite datum',
17 | monthSelect: 'Izberite mesec',
18 | yearSelect: 'Izberite leto',
19 | decadeSelect: 'Izberite desetletje',
20 |
21 | previousMonth: 'Prejšnji mesec (PageUp)',
22 | nextMonth: 'Naslednji mesec (PageDown)',
23 | previousYear: 'Prejšnje leto (Control + left)',
24 | nextYear: 'Naslednje leto (Control + right)',
25 | previousDecade: 'Prejšnje desetletje',
26 | nextDecade: 'Naslednje desetletje',
27 | previousCentury: 'Prejšnje stoletje',
28 | nextCentury: 'Naslednje stoletje',
29 | };
30 |
31 | export default locale;
32 |
--------------------------------------------------------------------------------
/src/locale/sr_Cyrl_RS.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'sr_Cyrl_RS',
7 | today: 'Данас',
8 | now: 'Сада',
9 | backToToday: 'Врати се на данас',
10 | ok: 'У реду',
11 | clear: 'Обриши',
12 | week: 'Недеља',
13 | month: 'Месец',
14 | year: 'Година',
15 | timeSelect: 'Изабери време',
16 | dateSelect: 'Изабери датум',
17 | monthSelect: 'Изабери месец',
18 | yearSelect: 'Изабери годину',
19 | decadeSelect: 'Изабери деценију',
20 |
21 | previousMonth: 'Претходни месец (PageUp)',
22 | nextMonth: 'Следећи месец (PageDown)',
23 | previousYear: 'Претходна година (Control + left)',
24 | nextYear: 'Следећа година (Control + right)',
25 | previousDecade: 'Претходна деценија',
26 | nextDecade: 'Следећа деценија',
27 | previousCentury: 'Претходни век',
28 | nextCentury: 'Следећи век',
29 | };
30 |
31 | export default locale;
32 |
--------------------------------------------------------------------------------
/src/locale/sr_RS.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'sr_RS',
7 | today: 'Danas',
8 | now: 'Sada',
9 | backToToday: 'Vrati se na danas',
10 | ok: 'U redu',
11 | clear: 'Obriši',
12 | week: 'Nedelja',
13 | month: 'Mesec',
14 | year: 'Godina',
15 | timeSelect: 'Izaberi vreme',
16 | dateSelect: 'Izaberi datum',
17 | monthSelect: 'Izaberi mesec',
18 | yearSelect: 'Izaberi godinu',
19 | decadeSelect: 'Izaberi deceniju',
20 |
21 | previousMonth: 'Prethodni mesec (PageUp)',
22 | nextMonth: 'Sledeći mesec (PageDown)',
23 | previousYear: 'Prethodna godina (Control + left)',
24 | nextYear: 'Sledeća godina (Control + right)',
25 | previousDecade: 'Prethodna decenija',
26 | nextDecade: 'Sledeća decenija',
27 | previousCentury: 'Prethodni vek',
28 | nextCentury: 'Sledeći vek',
29 | };
30 |
31 | export default locale;
32 |
--------------------------------------------------------------------------------
/src/locale/sv_SE.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'sv_SE',
7 | today: 'I dag',
8 | now: 'Nu',
9 | backToToday: 'Till idag',
10 | ok: 'OK',
11 | clear: 'Avbryt',
12 | week: 'Vecka',
13 | month: 'Månad',
14 | year: 'År',
15 | timeSelect: 'Välj tidpunkt',
16 | dateSelect: 'Välj datum',
17 | monthSelect: 'Välj månad',
18 | yearSelect: 'Välj år',
19 | decadeSelect: 'Välj årtionde',
20 |
21 | previousMonth: 'Förra månaden (PageUp)',
22 | nextMonth: 'Nästa månad (PageDown)',
23 | previousYear: 'Föreg år (Control + left)',
24 | nextYear: 'Nästa år (Control + right)',
25 | previousDecade: 'Föreg årtionde',
26 | nextDecade: 'Nästa årtionde',
27 | previousCentury: 'Föreg århundrade',
28 | nextCentury: 'Nästa århundrade',
29 | };
30 |
31 | export default locale;
32 |
--------------------------------------------------------------------------------
/src/locale/ta_IN.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'ta_IN',
7 | today: 'இன்று',
8 | now: 'இப்போது',
9 | backToToday: 'இன்றுக்கு திரும்பு',
10 | ok: 'சரி',
11 | clear: 'அழி',
12 | week: 'வாரம்',
13 | month: 'மாதம்',
14 | year: 'வருடம்',
15 | timeSelect: 'நேரத்தைத் தேர்ந்தெடு',
16 | dateSelect: 'தேதியைத் தேர்ந்தெடு',
17 | weekSelect: 'வாரத்தைத் தேர்வுசெய்க',
18 | monthSelect: 'மாதத்தைத் தேர்வுசெய்க',
19 | yearSelect: 'வருடத்தைத் தேர்வுசெய்க',
20 | decadeSelect: 'தசாப்தத்தைத் தேர்வுசெய்க',
21 |
22 | previousMonth: 'முந்தைய மாதம் (PageUp)',
23 | nextMonth: 'அடுத்த மாதம் (PageDown)',
24 | previousYear: 'முந்தைய வருடம் (Control + left)',
25 | nextYear: 'அடுத்த வருடம் (Control + right)',
26 | previousDecade: 'முந்தைய தசாப்தம்',
27 | nextDecade: 'அடுத்த தசாப்தம்',
28 | previousCentury: 'முந்தைய நூற்றாண்டு',
29 | nextCentury: 'அடுத்த நூற்றாண்டு',
30 | };
31 |
32 | export default locale;
33 |
--------------------------------------------------------------------------------
/src/locale/th_TH.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'th_TH',
7 | today: 'วันนี้',
8 | now: 'ตอนนี้',
9 | backToToday: 'กลับไปยังวันนี้',
10 | ok: 'ตกลง',
11 | clear: 'ลบล้าง',
12 | week: 'สัปดาห์',
13 | month: 'เดือน',
14 | year: 'ปี',
15 | timeSelect: 'เลือกเวลา',
16 | dateSelect: 'เลือกวัน',
17 | monthSelect: 'เลือกเดือน',
18 | yearSelect: 'เลือกปี',
19 | decadeSelect: 'เลือกทศวรรษ',
20 |
21 | previousMonth: 'เดือนก่อนหน้า (PageUp)',
22 | nextMonth: 'เดือนถัดไป (PageDown)',
23 | previousYear: 'ปีก่อนหน้า (Control + left)',
24 | nextYear: 'ปีถัดไป (Control + right)',
25 | previousDecade: 'ทศวรรษก่อนหน้า',
26 | nextDecade: 'ทศวรรษถัดไป',
27 | previousCentury: 'ศตวรรษก่อนหน้า',
28 | nextCentury: 'ศตวรรษถัดไป',
29 | };
30 |
31 | export default locale;
32 |
--------------------------------------------------------------------------------
/src/locale/tk_TK.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'tk_TK',
7 | today: 'Şugün',
8 | now: 'Şuwagt',
9 | backToToday: 'Şugüne gaýt',
10 | ok: 'Bolýar',
11 | clear: 'Arassala',
12 | month: 'Aý',
13 | week: 'Hepde',
14 | year: 'Ýyl',
15 | timeSelect: 'Wagt saýla',
16 | dateSelect: 'Gün saýla',
17 | monthSelect: 'Aý saýla',
18 | yearSelect: 'Ýyl saýla',
19 | decadeSelect: 'On ýyllygy saýla',
20 |
21 | previousMonth: 'Öňki aý (PageUp)',
22 | nextMonth: 'Soňky aý (PageDown)',
23 | previousYear: 'Öňki ýyl (Control + çep)',
24 | nextYear: 'Soňky ýyl (Control + sag)',
25 | previousDecade: 'Öňki on ýyl',
26 | nextDecade: 'Soňky on ýyl',
27 | previousCentury: 'Öňki asyr',
28 | nextCentury: 'Soňky asyr',
29 | };
30 |
31 | export default locale;
32 |
--------------------------------------------------------------------------------
/src/locale/tr_TR.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'tr_TR',
7 | today: 'Bugün',
8 | now: 'Şimdi',
9 | backToToday: 'Bugüne Geri Dön',
10 | ok: 'Tamam',
11 | clear: 'Temizle',
12 | week: 'Hafta',
13 | month: 'Ay',
14 | year: 'Yıl',
15 | timeSelect: 'Zaman Seç',
16 | dateSelect: 'Tarih Seç',
17 | monthSelect: 'Ay Seç',
18 | yearSelect: 'Yıl Seç',
19 | decadeSelect: 'On Yıl Seç',
20 |
21 | previousMonth: 'Önceki Ay (PageUp)',
22 | nextMonth: 'Sonraki Ay (PageDown)',
23 | previousYear: 'Önceki Yıl (Control + Sol)',
24 | nextYear: 'Sonraki Yıl (Control + Sağ)',
25 | previousDecade: 'Önceki On Yıl',
26 | nextDecade: 'Sonraki On Yıl',
27 | previousCentury: 'Önceki Yüzyıl',
28 | nextCentury: 'Sonraki Yüzyıl',
29 | shortWeekDays: ['Paz', 'Pzt', 'Sal', 'Çar', 'Per', 'Cum', 'Cmt'],
30 | shortMonths: ['Oca', 'Şub', 'Mar', 'Nis', 'May', 'Haz', 'Tem', 'Ağu', 'Eyl', 'Eki', 'Kas', 'Ara'],
31 | };
32 |
33 | export default locale;
34 |
--------------------------------------------------------------------------------
/src/locale/ug_CN.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'ug_CN',
7 | today: 'بۈگۈن',
8 | now: 'ھازىر',
9 | backToToday: 'بۈگۈنگە قايتىش',
10 | ok: 'مۇقىملاشتۇرۇش',
11 | timeSelect: 'ۋاقىت تاللاش',
12 | dateSelect: 'كۈن تاللاش',
13 | clear: 'تازىلاش',
14 | week: 'ھەپتە',
15 | month: 'ئاي',
16 | year: 'يىل',
17 | previousMonth: 'ئالدىنقى ئاي(ئالدىنقى بەت )',
18 | nextMonth: 'كېلەركى ئاي (كېلەركى بەت)',
19 | monthSelect: 'ئاي تاللاش',
20 | yearSelect: 'يىل تاللاش',
21 | decadeSelect: 'يىللارنى تاللاش',
22 | yearFormat: 'YYYY-يىلى',
23 | dayFormat: 'D-كۈنى',
24 | previousYear: 'ئالدىنقى يىلى (Controlبىلەن يۆنىلىش كونۇپكىسى)',
25 | nextYear: 'كېلەركى يىلى (Controlبىلەن يۆنىلىش كونۇپكىسى)',
26 | previousDecade: 'ئالدىنقى يىللار',
27 | nextDecade: 'كېيىنكى يىللار',
28 | previousCentury: 'ئالدىنقى ئەسىر',
29 | nextCentury: 'كېيىنكى ئەسىر',
30 | monthBeforeYear: false,
31 | };
32 |
33 | export default locale;
34 |
--------------------------------------------------------------------------------
/src/locale/uk_UA.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'uk_UA',
7 | today: 'Сьогодні',
8 | now: 'Зараз',
9 | backToToday: 'Поточна дата',
10 | ok: 'OK',
11 | clear: 'Очистити',
12 | week: 'Тиждень',
13 | month: 'Місяць',
14 | year: 'Рік',
15 | timeSelect: 'Обрати час',
16 | dateSelect: 'Обрати дату',
17 | monthSelect: 'Обрати місяць',
18 | yearSelect: 'Обрати рік',
19 | decadeSelect: 'Обрати десятиріччя',
20 |
21 | previousMonth: 'Попередній місяць (PageUp)',
22 | nextMonth: 'Наступний місяць (PageDown)',
23 | previousYear: 'Попередній рік (Control + left)',
24 | nextYear: 'Наступний рік (Control + right)',
25 | previousDecade: 'Попереднє десятиріччя',
26 | nextDecade: 'Наступне десятиріччя',
27 | previousCentury: 'Попереднє століття',
28 | nextCentury: 'Наступне століття',
29 | };
30 |
31 | export default locale;
32 |
--------------------------------------------------------------------------------
/src/locale/ur_PK.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'ur_PK',
7 | today: 'آج',
8 | now: 'ابھی',
9 | backToToday: 'آج واپس',
10 | ok: 'ٹھیک ہے',
11 | clear: 'صاف',
12 | week: 'ہفتہ',
13 | month: 'مہینہ',
14 | year: 'سال',
15 | timeSelect: 'وقت منتخب کریں',
16 | dateSelect: 'تاریخ منتخب کریں',
17 | weekSelect: 'ایک ہفتہ کا انتخاب کریں',
18 | monthSelect: 'ایک مہینہ کا انتخاب کریں',
19 | yearSelect: 'ایک سال کا انتخاب کریں',
20 | decadeSelect: 'ایک دہائی کا انتخاب کریں',
21 |
22 | previousMonth: 'پچھلے مہینے (PageUp)',
23 | nextMonth: 'اگلے مہینے (PageDown)',
24 | previousYear: 'گزشتہ سال (Control + left)',
25 | nextYear: 'اگلے سال (Control + right)',
26 | previousDecade: 'پچھلی دہائی',
27 | nextDecade: 'اگلی دہائی',
28 | previousCentury: 'پچھلی صدی',
29 | nextCentury: 'اگلی صدی',
30 | };
31 |
32 | export default locale;
33 |
--------------------------------------------------------------------------------
/src/locale/uz_UZ.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'uz_UZ',
7 | today: 'Bugun',
8 | now: 'Hozir',
9 | backToToday: 'Bugunga qaytish',
10 | ok: 'OK',
11 | clear: 'Toza',
12 | week: 'Xafta',
13 | month: 'Oy',
14 | year: 'Yil',
15 | timeSelect: 'vaqtni tanlang',
16 | dateSelect: 'sanani tanlang',
17 | weekSelect: 'Haftani tanlang',
18 | monthSelect: 'Oyni tanlang',
19 | yearSelect: 'Yilni tanlang',
20 | decadeSelect: "O'n yilni tanlang",
21 | previousMonth: 'Oldingi oy (PageUp)',
22 | nextMonth: 'Keyingi oy (PageDown)',
23 | previousYear: "O'tgan yili (Control + left)",
24 | nextYear: 'Keyingi yil (Control + right)',
25 | previousDecade: "Oxirgi o'n yil",
26 | nextDecade: "Keyingi o'n yil",
27 | previousCentury: "O'tgan asr",
28 | nextCentury: 'Keyingi asr',
29 | };
30 |
31 | export default locale;
32 |
--------------------------------------------------------------------------------
/src/locale/vi_VN.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'vi_VN',
7 | today: 'Hôm nay',
8 | now: 'Bây giờ',
9 | backToToday: 'Trở về hôm nay',
10 | ok: 'OK',
11 | clear: 'Xóa',
12 | week: 'Tuần',
13 | month: 'Tháng',
14 | year: 'Năm',
15 | timeSelect: 'Chọn thời gian',
16 | dateSelect: 'Chọn ngày',
17 | weekSelect: 'Chọn tuần',
18 | monthSelect: 'Chọn tháng',
19 | yearSelect: 'Chọn năm',
20 | decadeSelect: 'Chọn thập kỷ',
21 |
22 | previousMonth: 'Tháng trước (PageUp)',
23 | nextMonth: 'Tháng sau (PageDown)',
24 | previousYear: 'Năm trước (Control + left)',
25 | nextYear: 'Năm sau (Control + right)',
26 | previousDecade: 'Thập kỷ trước',
27 | nextDecade: 'Thập kỷ sau',
28 | previousCentury: 'Thế kỷ trước',
29 | nextCentury: 'Thế kỷ sau',
30 | };
31 |
32 | export default locale;
33 |
--------------------------------------------------------------------------------
/src/locale/zh_CN.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'zh_CN',
7 | today: '今天',
8 | now: '此刻',
9 | backToToday: '返回今天',
10 | ok: '确定',
11 | timeSelect: '选择时间',
12 | dateSelect: '选择日期',
13 | weekSelect: '选择周',
14 | clear: '清除',
15 | week: '周',
16 | month: '月',
17 | year: '年',
18 | previousMonth: '上个月 (翻页上键)',
19 | nextMonth: '下个月 (翻页下键)',
20 | monthSelect: '选择月份',
21 | yearSelect: '选择年份',
22 | decadeSelect: '选择年代',
23 |
24 | previousYear: '上一年 (Control键加左方向键)',
25 | nextYear: '下一年 (Control键加右方向键)',
26 | previousDecade: '上一年代',
27 | nextDecade: '下一年代',
28 | previousCentury: '上一世纪',
29 | nextCentury: '下一世纪',
30 |
31 | yearFormat: 'YYYY年',
32 | cellDateFormat: 'D',
33 | monthBeforeYear: false,
34 | };
35 |
36 | export default locale;
37 |
--------------------------------------------------------------------------------
/src/locale/zh_TW.ts:
--------------------------------------------------------------------------------
1 | import { commonLocale } from './common';
2 | import type { Locale } from '../interface';
3 |
4 | const locale: Locale = {
5 | ...commonLocale,
6 | locale: 'zh_TW',
7 |
8 | today: '今天',
9 | now: '此刻',
10 | backToToday: '返回今天',
11 | ok: '確定',
12 | timeSelect: '選擇時間',
13 | dateSelect: '選擇日期',
14 | weekSelect: '選擇周',
15 | clear: '清除',
16 | week: '週',
17 | month: '月',
18 | year: '年',
19 | previousMonth: '上個月 (翻頁上鍵)',
20 | nextMonth: '下個月 (翻頁下鍵)',
21 | monthSelect: '選擇月份',
22 | yearSelect: '選擇年份',
23 | decadeSelect: '選擇年代',
24 | yearFormat: 'YYYY年',
25 |
26 | previousYear: '上一年 (Control鍵加左方向鍵)',
27 | nextYear: '下一年 (Control鍵加右方向鍵)',
28 | previousDecade: '上一年代',
29 | nextDecade: '下一年代',
30 | previousCentury: '上一世紀',
31 | nextCentury: '下一世紀',
32 |
33 | cellDateFormat: 'D',
34 | monthBeforeYear: false,
35 | };
36 |
37 | export default locale;
38 |
--------------------------------------------------------------------------------
/src/utils/getClearIcon.tsx:
--------------------------------------------------------------------------------
1 | import type { ReactNode } from "react";
2 | import React from "react";
3 |
4 | export function getClearIcon(
5 | prefixCls: string,
6 | allowClear?: boolean | { clearIcon?: ReactNode },
7 | clearIcon?: ReactNode,
8 | ) {
9 |
10 | const mergedClearIcon = typeof allowClear === "object" ? allowClear.clearIcon : clearIcon;
11 |
12 | return (
13 | mergedClearIcon ||
14 | );
15 | }
16 |
--------------------------------------------------------------------------------
/src/utils/miscUtil.ts:
--------------------------------------------------------------------------------
1 | import type { InternalMode, Locale, SharedPickerProps } from '../interface';
2 |
3 | export function leftPad(str: string | number, length: number, fill: string = '0') {
4 | let current = String(str);
5 | while (current.length < length) {
6 | current = `${fill}${current}`;
7 | }
8 | return current;
9 | }
10 |
11 | /**
12 | * Convert `value` to array. Will provide `[]` if is null or undefined.
13 | */
14 | export function toArray(val: T | T[]): T[] {
15 | if (val === null || val === undefined) {
16 | return [];
17 | }
18 |
19 | return Array.isArray(val) ? val : [val];
20 | }
21 |
22 | export function fillIndex(ori: T, index: number, value: T[number]): T {
23 | const clone = [...ori] as T;
24 | clone[index] = value;
25 |
26 | return clone;
27 | }
28 |
29 | /** Pick props from the key list. Will filter empty value */
30 | export function pickProps(props: T, keys?: (keyof T)[] | readonly (keyof T)[]) {
31 | const clone = {} as T;
32 |
33 | const mergedKeys = (keys || Object.keys(props)) as typeof keys;
34 |
35 | mergedKeys.forEach((key) => {
36 | if (props[key] !== undefined) {
37 | clone[key] = props[key];
38 | }
39 | });
40 |
41 | return clone;
42 | }
43 |
44 | export function getRowFormat(
45 | picker: InternalMode,
46 | locale: Locale,
47 | format?: SharedPickerProps['format'],
48 | ) {
49 | if (format) {
50 | return format;
51 | }
52 |
53 | switch (picker) {
54 | // All from the `locale.fieldXXXFormat` first
55 | case 'time':
56 | return locale.fieldTimeFormat;
57 | case 'datetime':
58 | return locale.fieldDateTimeFormat;
59 | case 'month':
60 | return locale.fieldMonthFormat;
61 | case 'year':
62 | return locale.fieldYearFormat;
63 | case 'quarter':
64 | return locale.fieldQuarterFormat;
65 | case 'week':
66 | return locale.fieldWeekFormat;
67 |
68 | default:
69 | return locale.fieldDateFormat;
70 | }
71 | }
72 |
73 | export function getFromDate(
74 | calendarValues: DateType[],
75 | activeIndexList: number[],
76 | activeIndex?: number,
77 | ) {
78 | const mergedActiveIndex =
79 | activeIndex !== undefined ? activeIndex : activeIndexList[activeIndexList.length - 1];
80 | const firstValuedIndex = activeIndexList.find((index) => calendarValues[index]);
81 |
82 | return mergedActiveIndex !== firstValuedIndex ? calendarValues[firstValuedIndex] : undefined;
83 | }
84 |
--------------------------------------------------------------------------------
/src/utils/uiUtil.ts:
--------------------------------------------------------------------------------
1 | // ====================== Mode ======================
2 | export function getRealPlacement(placement: string, rtl: boolean) {
3 | if (placement !== undefined) {
4 | return placement;
5 | }
6 | return rtl ? 'bottomRight' : 'bottomLeft';
7 | }
8 |
--------------------------------------------------------------------------------
/src/utils/warnUtil.ts:
--------------------------------------------------------------------------------
1 | import type { DisabledTimes, PickerMode } from '../interface';
2 | import warning from '@rc-component/util/lib/warning';
3 |
4 | export interface WarningProps extends DisabledTimes {
5 | picker?: PickerMode;
6 | }
7 |
8 | export function legacyPropsWarning(props: WarningProps) {
9 | const { picker, disabledHours, disabledMinutes, disabledSeconds } = props;
10 |
11 | if (picker === 'time' && (disabledHours || disabledMinutes || disabledSeconds)) {
12 | warning(
13 | false,
14 | `'disabledHours', 'disabledMinutes', 'disabledSeconds' will be removed in the next major version, please use 'disabledTime' instead.`,
15 | );
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/tests/__snapshots__/picker.spec.tsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`Picker.Basic icon 1`] = `
4 |
7 |
13 |
16 |
19 |
20 |
24 |
27 |
28 |
29 | `;
30 |
31 | exports[`Picker.Basic inputRender 1`] = `
32 |
35 |
42 |
43 | `;
44 |
45 | exports[`Picker.Basic panelRender 1`] = `
46 |
60 | `;
61 |
62 | exports[`Picker.Basic pass data- & aria- & role 1`] = `
63 |
82 | `;
83 |
84 | exports[`Picker.Basic should render correctly in rtl 1`] = `
85 |
101 | `;
102 |
--------------------------------------------------------------------------------
/tests/blur.spec.tsx:
--------------------------------------------------------------------------------
1 | import { fireEvent, render } from '@testing-library/react';
2 | import React from 'react';
3 | import {
4 | closePicker,
5 | DayPicker,
6 | DayRangePicker,
7 | getMoment,
8 | openPicker,
9 | waitFakeTimer,
10 | } from './util/commonUtil';
11 |
12 | describe('Picker.ChangeOnBlur', () => {
13 | beforeEach(() => {
14 | jest.useFakeTimers().setSystemTime(getMoment('1990-09-03 00:00:00').valueOf());
15 | });
16 |
17 | afterEach(() => {
18 | jest.clearAllTimers();
19 | jest.useRealTimers();
20 | });
21 |
22 | it('Picker', async () => {
23 | const { container } = render();
24 |
25 | // Open
26 | openPicker(container);
27 |
28 | const inputEle = container.querySelector('input');
29 | fireEvent.change(inputEle, {
30 | target: {
31 | value: 'no valid',
32 | },
33 | });
34 |
35 | closePicker(container);
36 | await waitFakeTimer();
37 | expect(inputEle).toHaveValue('no valid');
38 | });
39 |
40 | it('RangePicker', async () => {
41 | const { container } = render();
42 |
43 | const startInputEle = container.querySelectorAll('input')[0];
44 | const endInputEle = container.querySelectorAll('input')[1];
45 |
46 | // Open
47 | openPicker(container);
48 | fireEvent.change(startInputEle, {
49 | target: {
50 | value: 'no valid 1',
51 | },
52 | });
53 |
54 | openPicker(container, 1);
55 | fireEvent.change(endInputEle, {
56 | target: {
57 | value: 'no valid 2',
58 | },
59 | });
60 |
61 | // Close
62 | closePicker(container, 1);
63 | await waitFakeTimer();
64 | expect(startInputEle).toHaveValue('no valid 1');
65 | expect(endInputEle).toHaveValue('no valid 2');
66 | });
67 | });
68 |
--------------------------------------------------------------------------------
/tests/components.spec.tsx:
--------------------------------------------------------------------------------
1 | import { render } from '@testing-library/react';
2 | import MockDate from 'mockdate';
3 | import React from 'react';
4 | import { DayPicker, DayRangePicker, getDay } from './util/commonUtil';
5 |
6 | describe('Picker.Components', () => {
7 | beforeAll(() => {
8 | MockDate.set(getDay('1990-09-03 00:00:00').toDate());
9 | });
10 |
11 | afterAll(() => {
12 | MockDate.reset();
13 | });
14 |
15 | [
16 | { name: 'RangePicker', component: DayRangePicker },
17 | { name: 'Picker', component: DayPicker },
18 | ].forEach(({ name, component }) => {
19 | it(name, () => {
20 | const Component = component as any;
21 | const Button: React.FC = (props) => ;
22 |
23 | render(
24 | ,
34 | );
35 |
36 | expect(document.querySelector('.rc-picker-footer').querySelectorAll('h1')).toHaveLength(1);
37 | });
38 | });
39 | });
40 |
--------------------------------------------------------------------------------
/tests/generateWithTZ.spec.tsx:
--------------------------------------------------------------------------------
1 | import MockDate from 'mockdate';
2 | import dayjsGenerateConfig from '../src/generate/dayjs';
3 |
4 | import dayjs from 'dayjs';
5 | import utc from 'dayjs/plugin/utc';
6 | import timezone from 'dayjs/plugin/timezone';
7 | import moment from 'moment-timezone';
8 |
9 | dayjs.extend(utc);
10 | dayjs.extend(timezone);
11 |
12 | const CN = 'Asia/Shanghai';
13 | const JP = 'Asia/Tokyo';
14 |
15 | beforeEach(() => {
16 | MockDate.set(new Date());
17 | dayjs.tz.setDefault(CN);
18 | moment.tz.setDefault(CN);
19 | });
20 |
21 | afterEach(() => {
22 | dayjs.tz.setDefault();
23 | moment.tz.setDefault();
24 | MockDate.reset();
25 | });
26 |
27 | describe('dayjs: getNow', () => {
28 | it('normal', () => {
29 | const D_now = dayjsGenerateConfig.getNow();
30 | const M_now = moment();
31 |
32 | expect(D_now.format()).toEqual(M_now.format());
33 | });
34 |
35 | it('should work normally in timezone', async () => {
36 | dayjs.tz.setDefault(JP);
37 | const D_now = dayjsGenerateConfig.getNow();
38 | const M_now = moment().tz(JP);
39 |
40 | expect(D_now.format()).toEqual(M_now.format());
41 | expect(D_now.get('hour') - D_now.utc().get('hour')).toEqual(9);
42 | });
43 | });
44 |
--------------------------------------------------------------------------------
/tests/internal.spec.tsx:
--------------------------------------------------------------------------------
1 | import { render } from '@testing-library/react';
2 | import React from 'react';
3 | import { DayPickerPanel, getMoment } from './util/commonUtil';
4 |
5 | // Note: Props tested in this file is safe to remove when refactor
6 | describe('Picker.Internal', () => {
7 | beforeEach(() => {
8 | jest.useFakeTimers().setSystemTime(getMoment('1990-09-03 00:00:00').valueOf());
9 | });
10 |
11 | afterEach(() => {
12 | jest.clearAllTimers();
13 | jest.useRealTimers();
14 | });
15 |
16 | it('hideHeader', async () => {
17 | const { container, rerender } = render();
18 | expect(container.querySelector('.rc-picker-header')).toBeTruthy();
19 |
20 | rerender();
21 | expect(container.querySelector('.rc-picker-header')).toBeFalsy();
22 | });
23 | });
24 |
--------------------------------------------------------------------------------
/tests/keyboard.spec.tsx:
--------------------------------------------------------------------------------
1 | import { act, fireEvent, render } from '@testing-library/react';
2 | import { resetWarned } from '@rc-component/util/lib/warning';
3 | import React from 'react';
4 | import { DateFnsSinglePicker, DayPicker, getMoment, isOpen, openPicker } from './util/commonUtil';
5 |
6 | // TODO: New keyboard interactive
7 | describe('Picker.Keyboard', () => {
8 | beforeEach(() => {
9 | resetWarned();
10 | document.body.innerHTML = '';
11 | jest.useFakeTimers().setSystemTime(getMoment('1990-09-03 00:00:00').valueOf());
12 | });
13 |
14 | afterEach(() => {
15 | jest.clearAllTimers();
16 | jest.useRealTimers();
17 | });
18 |
19 | it('type confirm', () => {
20 | const onChange = jest.fn();
21 | const onCalendarChange = jest.fn();
22 | const { container } = render(
23 | ,
24 | );
25 |
26 | const inputEle = container.querySelector('input');
27 |
28 | // Focus
29 | fireEvent.focus(inputEle);
30 | expect(isOpen()).toBeFalsy();
31 |
32 | // Key to open
33 | fireEvent.keyDown(inputEle, {
34 | key: 'Enter',
35 | });
36 | expect(isOpen()).toBeTruthy();
37 |
38 | // type date
39 | fireEvent.change(inputEle, {
40 | target: {
41 | value: '2000-03-03',
42 | },
43 | });
44 | expect(onCalendarChange).toHaveBeenCalledWith(expect.anything(), '2000-03-03', {});
45 |
46 | // Submit
47 | fireEvent.keyDown(inputEle, {
48 | key: 'Enter',
49 | });
50 | expect(onChange).toHaveBeenCalledWith(expect.anything(), '2000-03-03');
51 | });
52 |
53 | it('warning for legacy preventDefault', () => {
54 | const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
55 | const { container } = render(
56 | {
58 | preventDefault();
59 | }}
60 | />,
61 | );
62 |
63 | fireEvent.keyDown(container.querySelector('input'), {
64 | key: 'Escape',
65 | });
66 |
67 | expect(errorSpy).toHaveBeenCalledWith(
68 | 'Warning: `preventDefault` callback is deprecated. Please call `event.preventDefault` directly.',
69 | );
70 | });
71 |
72 | describe('esc to close popup', () => {
73 | it('should work', () => {
74 | const { container } = render();
75 |
76 | openPicker(container);
77 | fireEvent.keyDown(container.querySelector('input'), {
78 | key: 'Escape',
79 | });
80 |
81 | act(() => {
82 | jest.runAllTimers();
83 | });
84 |
85 | expect(isOpen()).toBeFalsy();
86 | });
87 |
88 | it('preventDefault should work', () => {
89 | const { container } = render( e.preventDefault()} />);
90 |
91 | openPicker(container);
92 | fireEvent.keyDown(container.querySelector('input'), {
93 | key: 'Escape',
94 | });
95 | expect(isOpen()).toBeTruthy();
96 | });
97 | });
98 |
99 | describe('typing date with date-fns', () => {
100 | it('should not parse date if not matching format', () => {
101 | const { container } = render();
102 | const input = container.querySelector('input');
103 |
104 | fireEvent.change(input, {
105 | target: {
106 | // Typing date partially. Picker should not try to parse it as a valid date
107 | value: '01/01/20',
108 | },
109 | });
110 |
111 | expect(input.value).toEqual('01/01/20');
112 | });
113 | });
114 | });
115 |
--------------------------------------------------------------------------------
/tests/loop.spec.tsx:
--------------------------------------------------------------------------------
1 | import { render } from '@testing-library/react';
2 | import dayjs from 'dayjs';
3 | import { resetWarned } from '@rc-component/util/lib/warning';
4 | import React from 'react';
5 | import zhCN from '../src/locale/zh_CN';
6 | import { DayRangePicker, getMoment } from './util/commonUtil';
7 |
8 | describe('Picker.Loop', () => {
9 | let errorSpy;
10 |
11 | beforeAll(() => {
12 | errorSpy = jest.spyOn(console, 'error').mockImplementation(() => null);
13 | });
14 |
15 | beforeEach(() => {
16 | errorSpy.mockReset();
17 | resetWarned();
18 | global.scrollCalled = false;
19 | jest.useFakeTimers().setSystemTime(getMoment('1990-09-03 00:00:00').valueOf());
20 | });
21 |
22 | afterEach(() => {
23 | jest.clearAllTimers();
24 | jest.useRealTimers();
25 | });
26 |
27 | it('no loop warning', () => {
28 | render();
29 |
30 | expect(errorSpy).not.toHaveBeenCalled();
31 | });
32 | });
33 |
--------------------------------------------------------------------------------
/tests/time.spec.tsx:
--------------------------------------------------------------------------------
1 | import { fireEvent, render } from '@testing-library/react';
2 | import { resetWarned } from '@rc-component/util/lib/warning';
3 | import React from 'react';
4 | import { DayPicker, getDay, openPicker, selectCell, findCell } from './util/commonUtil';
5 |
6 | describe('Picker.Time', () => {
7 | beforeEach(() => {
8 | resetWarned();
9 | jest.useFakeTimers().setSystemTime(getDay('1990-09-03 00:00:00').valueOf());
10 | });
11 |
12 | afterEach(() => {
13 | jest.clearAllTimers();
14 | jest.useRealTimers();
15 | });
16 |
17 | it('show columns for one of it is false', async () => {
18 | const { container } = render();
19 |
20 | openPicker(container);
21 | expect(document.querySelectorAll('.rc-picker-time-panel-column')).toHaveLength(2);
22 |
23 | // Select
24 | selectCell(3);
25 |
26 | expect(container.querySelector('input')).toHaveValue('1990-09-03 00:00');
27 | });
28 |
29 | it('hover to show placeholder', async () => {
30 | const { container } = render(
31 | ,
37 | );
38 | openPicker(container);
39 |
40 | const getColCell = (colIndex: number, cellIndex: number) => {
41 | const column = document.querySelectorAll('.rc-picker-time-panel-column')[colIndex];
42 | const cell = column.querySelectorAll('.rc-picker-time-panel-cell-inner')[cellIndex];
43 |
44 | return cell;
45 | };
46 |
47 | // Hour
48 | fireEvent.mouseEnter(getColCell(0, 3));
49 | expect(container.querySelector('input')).toHaveValue('1990-09-03 03:00:00.000 AM');
50 |
51 | // Let test for mouse leave
52 | fireEvent.mouseLeave(getColCell(0, 3));
53 | expect(container.querySelector('input')).toHaveValue('');
54 |
55 | // Minute
56 | fireEvent.mouseEnter(getColCell(1, 2));
57 | expect(container.querySelector('input')).toHaveValue('1990-09-03 12:02:00.000 AM');
58 |
59 | // Second
60 | fireEvent.mouseEnter(getColCell(2, 1));
61 | expect(container.querySelector('input')).toHaveValue('1990-09-03 12:00:01.000 AM');
62 |
63 | // Millisecond
64 | fireEvent.mouseEnter(getColCell(3, 1));
65 | expect(container.querySelector('input')).toHaveValue('1990-09-03 12:00:00.100 AM');
66 |
67 | // Meridiem
68 | fireEvent.mouseEnter(getColCell(4, 1));
69 | expect(container.querySelector('input')).toHaveValue('1990-09-03 12:00:00.000 PM');
70 | });
71 | });
72 |
--------------------------------------------------------------------------------
/tests/util.spec.tsx:
--------------------------------------------------------------------------------
1 | // Note: zombieJ refactoring
2 |
3 | import dayjs from 'dayjs';
4 | import dayGenerate from '../src/generate/dayjs';
5 | import { isInRange } from '../src/utils/dateUtil';
6 |
7 | global.error = console.error;
8 |
9 | describe('Picker.Util', () => {
10 | describe('isInRange', () => {
11 | it('not break with null', () => {
12 | expect(isInRange(dayGenerate, null, null, dayjs())).toBeFalsy();
13 | });
14 | });
15 | });
16 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "esnext",
4 | "moduleResolution": "node",
5 | "baseUrl": "./",
6 | "jsx": "react",
7 | "declaration": true,
8 | "skipLibCheck": true,
9 | "esModuleInterop": true,
10 | "paths": {
11 | "@/*": ["src/*"],
12 | "@@/*": [".dumi/tmp/*"],
13 | "@rc-component/picker": ["src/index.tsx"]
14 | }
15 | },
16 | "include": [
17 | ".dumirc.ts",
18 | "src/**/*.ts",
19 | "src/**/*.tsx",
20 | "docs/examples/*.tsx",
21 | "tests/**/*.ts",
22 | "tests/**/*.tsx",
23 | "typings.d.ts"
24 | ]
25 | }
26 |
--------------------------------------------------------------------------------
/typings.d.ts:
--------------------------------------------------------------------------------
1 | import 'dayjs/plugin/timezone';
2 |
3 | export {};
4 |
--------------------------------------------------------------------------------