├── .gitignore
├── .prettierrc
├── LICENSE
├── README.md
├── build.config.ts
├── cypress.config.ts
├── eslint.config.mjs
├── index.html
├── package.json
├── pnpm-lock.yaml
├── rollup.config.mjs
├── src
├── App.vue
├── components
│ ├── DatePicker.vue
│ ├── assets
│ │ └── sass
│ │ │ ├── _variable.scss
│ │ │ └── app.scss
│ └── utils
│ │ ├── components
│ │ ├── PDPAlt.vue
│ │ ├── PDPArrow.vue
│ │ └── PDPIcon.vue
│ │ └── modules
│ │ ├── core.ts
│ │ └── types.ts
├── main.ts
├── nuxt
│ ├── composable
│ │ └── usePersianDate.ts
│ └── index.ts
├── shims-vue.d.ts
└── vite-env.d.ts
├── test
├── e2e
│ ├── arrow-keys.cy.ts
│ ├── events.cy.ts
│ ├── other-tests.cy.ts
│ ├── props
│ │ ├── all.cy.ts
│ │ ├── dual-input.cy.ts
│ │ └── shortcut.cy.ts
│ ├── select-date.cy.ts
│ ├── select-datetime.cy.ts
│ ├── select-time.cy.ts
│ └── slots.cy.ts
├── fixtures
│ └── example.json
└── support
│ ├── Test.vue
│ ├── e2e.ts
│ └── index.html
├── tsconfig.json
└── vite.config.ts
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 |
4 | # local env files
5 | .env.local
6 | .env.*.local
7 |
8 | # Log files
9 | npm-debug.log*
10 | yarn-debug.log*
11 | yarn-error.log*
12 | pnpm-debug.log*
13 |
14 | # Editor directories and files
15 | .idea
16 | .vscode
17 | *.suo
18 | *.ntvs*
19 | *.njsproj
20 | *.sln
21 | *.sw?
22 |
23 |
24 | # Dist files
25 | /dist
26 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "semi": true,
4 | "vueIndentScriptAndStyle": true
5 | }
6 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2020-present, Alireza Alibeiki (alireza-ab)
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Vue3 Persian Datepicker
2 |
3 | A datepicker component for select persian date.
4 | It's very customizable and easily for use.
5 |
6 | [](https://www.npmjs.com/package/@alireza-ab/vue3-persian-datepicker)
7 | [](http://commitizen.github.io/cz-cli/)
8 |
9 | If you want to use this component with vue2, visit [vue-persian-datepicker](https://github.com/alireza-ab/vue-persian-datepicker)
10 |
11 | ## Features
12 |
13 | - **nuxt** support
14 | - **single and range selection**
15 | - select **date** and **time**
16 | - select with **keyboard**
17 | - customizable **style**
18 | - localization
19 |
20 | ## Documentation
21 |
22 | For full documentation and examples, visit [https://alireza-ab.ir/datepicker](https://alireza-ab.ir/datepicker)
23 |
24 | 
25 |
26 | ### Install
27 |
28 | ```shell
29 | pnpm add @alireza-ab/vue3-persian-datepicker
30 | ```
31 |
32 | or
33 |
34 | ```shell
35 | npm i @alireza-ab/vue3-persian-datepicker
36 | ```
37 |
38 | ### Usage
39 |
40 | ```js
41 | import DatePicker from '@alireza-ab/vue3-persian-datepicker';
42 |
43 | Vue.createApp({
44 | components: { DatePicker },
45 | }).mount('#app');
46 | ```
47 |
48 | ```html
49 |
50 | ```
51 |
52 | ## License
53 |
54 | Vue Persian Datepicker is available under the [MIT](https://opensource.org/licenses/MIT) license.
55 |
--------------------------------------------------------------------------------
/build.config.ts:
--------------------------------------------------------------------------------
1 | import { defineBuildConfig } from 'unbuild';
2 |
3 | export default defineBuildConfig({
4 | entries: ['src/nuxt/index'],
5 | rollup: {
6 | emitCJS: true,
7 | cjsBridge: true,
8 | },
9 | failOnWarn: false,
10 | });
11 |
--------------------------------------------------------------------------------
/cypress.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'cypress';
2 |
3 | export default defineConfig({
4 | fixturesFolder: 'test/fixtures',
5 | screenshotsFolder: 'test/screenshots',
6 | videosFolder: 'test/videos',
7 | projectId: '32fyob',
8 | viewportWidth: 800,
9 | viewportHeight: 800,
10 | screenshotOnRunFailure: false,
11 | video: false,
12 |
13 | retries: {
14 | runMode: 3,
15 | openMode: 0,
16 | },
17 |
18 | component: {
19 | specPattern: 'test/**/*.cy.ts',
20 | supportFolder: 'test/support',
21 | supportFile: 'test/support/e2e.ts',
22 | indexHtmlFile: 'test/support/index.html',
23 | devServer: {
24 | framework: 'vue',
25 | bundler: 'vite',
26 | },
27 | },
28 | });
29 |
--------------------------------------------------------------------------------
/eslint.config.mjs:
--------------------------------------------------------------------------------
1 | import eslint from '@eslint/js';
2 | import eslintConfigPrettier from 'eslint-config-prettier';
3 | import eslintPluginVue from 'eslint-plugin-vue';
4 | import globals from 'globals';
5 | import typescriptEslint from 'typescript-eslint';
6 |
7 | export default typescriptEslint.config(
8 | { ignores: ['*.d.ts', '**/coverage', '**/dist'] },
9 | {
10 | extends: [
11 | eslint.configs.recommended,
12 | ...typescriptEslint.configs.recommended,
13 | ...eslintPluginVue.configs['flat/recommended'],
14 | ],
15 | files: ['**/*.{ts,vue}'],
16 | languageOptions: {
17 | ecmaVersion: 'latest',
18 | sourceType: 'module',
19 | globals: globals.browser,
20 | parserOptions: {
21 | parser: typescriptEslint.parser,
22 | },
23 | },
24 | rules: {
25 | '@typescript-eslint/no-non-null-assertion': 'off',
26 | '@typescript-eslint/no-namespace': 'off',
27 | 'vue/require-default-prop': 'off',
28 | 'vue/no-v-html': 'off',
29 | 'vue/attribute-hyphenation': 'off',
30 | 'vue/multi-word-component-names': 'off',
31 | },
32 | },
33 | eslintConfigPrettier,
34 | );
35 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Vite App
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@alireza-ab/vue3-persian-datepicker",
3 | "description": "A datepicker component for select date (vue 3)",
4 | "version": "1.0.5",
5 | "files": [
6 | "dist/*",
7 | "src/*"
8 | ],
9 | "main": "./dist/index-umd.js",
10 | "module": "./dist/index-es.js",
11 | "exports": {
12 | ".": {
13 | "types": "./dist/DatePicker.vue.d.ts",
14 | "import": "./dist/index-es.js",
15 | "require": "./dist/index-umd.js"
16 | },
17 | "./nuxt": {
18 | "import": "./dist/nuxt/index.mjs",
19 | "require": "./dist/nuxt/index.cjs"
20 | }
21 | },
22 | "type": "module",
23 | "scripts": {
24 | "dev": "vite",
25 | "build:lib": "rollup -c",
26 | "build:dts": "vue-tsc -d --emitDeclarationOnly src/components/DatePicker.vue --outDir dist",
27 | "build:nuxt": "unbuild",
28 | "build": "rm -rf dist && pnpm build:nuxt && pnpm build:lib && pnpm build:dts",
29 | "test": "cypress run --component",
30 | "test:open": "cypress open --component",
31 | "lint": "eslint",
32 | "pretty": "prettier -w -u .",
33 | "cz": "cz"
34 | },
35 | "homepage": "https://alireza-ab.ir/datepicker",
36 | "bugs": {
37 | "url": "https://github.com/alireza-ab/vue3-persian-datepicker/issues"
38 | },
39 | "repository": {
40 | "type": "git",
41 | "url": "https://github.com/alireza-ab/vue3-persian-datepicker.git"
42 | },
43 | "author": "Alireza Alibeiki ",
44 | "keywords": [
45 | "javascript",
46 | "js",
47 | "vue 3",
48 | "nuxt 3",
49 | "vuejs",
50 | "nuxtjs",
51 | "date",
52 | "persian",
53 | "jalali",
54 | "shamsi",
55 | "datepicker",
56 | "persian datepicker",
57 | "jalali datepicker",
58 | "shamsi datepicker",
59 | "range datepicker",
60 | "persian range datepicker",
61 | "vue datepicker",
62 | "vue persian datepicker",
63 | "vue persian range datepicker",
64 | "nuxt datepicker",
65 | "nuxt persian datepicker",
66 | "nuxt persian range datepicker"
67 | ],
68 | "dependencies": {
69 | "@alireza-ab/persian-date": "^2.6.2",
70 | "@nuxt/kit": "^3.15.0"
71 | },
72 | "devDependencies": {
73 | "@cypress/vue": "^6.0.1",
74 | "@typescript-eslint/eslint-plugin": "^8.19.0",
75 | "@typescript-eslint/parser": "^8.19.0",
76 | "@vitejs/plugin-vue": "^5.2.1",
77 | "@vue/compiler-sfc": "^3.5.13",
78 | "@vue/eslint-config-prettier": "^10.1.0",
79 | "@vue/eslint-config-typescript": "^14.2.0",
80 | "commitizen": "^4.3.1",
81 | "cypress": "^13.17.0",
82 | "cz-conventional-changelog": "^3.3.0",
83 | "eslint": "^9.17.0",
84 | "eslint-plugin-prettier": "^5.2.1",
85 | "eslint-plugin-vue": "^9.32.0",
86 | "globals": "^15.14.0",
87 | "prettier": "^3.4.2",
88 | "rollup-plugin-alias": "^2.2.0",
89 | "rollup-plugin-commonjs": "^10.1.0",
90 | "rollup-plugin-node-resolve": "^5.2.0",
91 | "rollup-plugin-postcss": "^4.0.2",
92 | "rollup-plugin-replace": "^2.2.0",
93 | "rollup-plugin-typescript2": "^0.36.0",
94 | "rollup-plugin-vue": "^6.0.0",
95 | "sass": "^1.83.0",
96 | "sass-loader": "^16.0.4",
97 | "typescript": "5.7.2",
98 | "unbuild": "^3.2.0",
99 | "vite": "^6.0.6",
100 | "vue": "^3.5.13",
101 | "vue-tsc": "^2.2.0",
102 | "yorkie": "^2.0.0"
103 | },
104 | "gitHooks": {
105 | "prepare-commit-msg": "exec < /dev/tty && cz --hook || true",
106 | "pre-commit": "pnpm pretty && pnpm lint"
107 | },
108 | "config": {
109 | "commitizen": {
110 | "path": "./node_modules/cz-conventional-changelog"
111 | }
112 | },
113 | "license": "MIT"
114 | }
115 |
--------------------------------------------------------------------------------
/rollup.config.mjs:
--------------------------------------------------------------------------------
1 | import vue from 'rollup-plugin-vue';
2 | import typescript from 'rollup-plugin-typescript2';
3 | import resolve from 'rollup-plugin-node-resolve';
4 | import commonjs from 'rollup-plugin-commonjs';
5 | import postcss from 'rollup-plugin-postcss';
6 | import replace from 'rollup-plugin-replace';
7 | import alias from 'rollup-plugin-alias';
8 |
9 | export default {
10 | input: `src/components/DatePicker.vue`,
11 | plugins: [
12 | vue({
13 | preprocessStyles: true,
14 | }),
15 | typescript({
16 | tsconfigOverride: {
17 | compilerOptions: {
18 | declaration: false,
19 | },
20 | exclude: ['src/nuxt'],
21 | },
22 | }),
23 | commonjs(),
24 | resolve({
25 | dedupe: ['vue'],
26 | }),
27 | replace({
28 | NODE_ENV: JSON.stringify('production'),
29 | 'process.env.NODE_ENV': JSON.stringify('production'),
30 | }),
31 | postcss(),
32 | alias({
33 | resolve: ['.js', '.ts', '.tsx'],
34 | entries: [{ find: 'vue', replacement: '@vue/runtime-dom' }],
35 | }),
36 | ],
37 | external: ['vue'],
38 | output: [
39 | {
40 | file: 'dist/index-umd.js',
41 | name: 'DatePicker',
42 | format: 'umd',
43 | exports: 'named',
44 | globals: {
45 | vue: 'Vue',
46 | },
47 | },
48 | {
49 | file: 'dist/index-es.js',
50 | format: 'es',
51 | exports: 'named',
52 | globals: {
53 | vue: 'Vue',
54 | },
55 | },
56 | ],
57 | };
58 |
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
9 |
19 |
--------------------------------------------------------------------------------
/src/components/assets/sass/_variable.scss:
--------------------------------------------------------------------------------
1 | $primary-color: #26baee;
2 |
3 | $secondary-color: #9fe8fa;
4 |
5 | $in-range-background: #c9f1fb;
6 |
7 | $radius: 0.25rem;
8 |
9 | $text-color: #495057;
10 |
11 | $hover-color: #000;
12 |
13 | $background: #fff;
14 |
15 | $border-color: #ced4da;
16 |
17 | $z-index: 1000;
18 |
19 | $disabled-opacity: 0.3;
20 |
21 | $icon-background: #e9ecef;
22 |
23 | $overlay-color: transparent;
24 |
25 | $main-box-shadow: 1px 1px 8px 1px rgba(116, 116, 116, 0.5);
26 |
27 | $day-dimensions: 2.08rem;
28 |
29 | $time-scale: 1;
30 |
31 | .pdp {
32 | --primary-color: #{$primary-color};
33 |
34 | --secondary-color: #{$secondary-color};
35 |
36 | --in-range-background: #{$in-range-background};
37 |
38 | --radius: #{$radius};
39 |
40 | --text-color: #{$text-color};
41 |
42 | --hover-color: #{$hover-color};
43 |
44 | --background: #{$background};
45 |
46 | --border-color: #{$border-color};
47 |
48 | --z-index: #{$z-index};
49 |
50 | --disabled-opacity: #{$disabled-opacity};
51 |
52 | --icon-background: #{$icon-background};
53 |
54 | --overlay-color: #{$overlay-color};
55 |
56 | --main-box-shadow: #{$main-box-shadow};
57 |
58 | --day-dimensions: #{$day-dimensions};
59 |
60 | --time-scale: #{$time-scale};
61 | }
62 |
--------------------------------------------------------------------------------
/src/components/assets/sass/app.scss:
--------------------------------------------------------------------------------
1 | @use '_variable';
2 |
3 | @mixin little-flag {
4 | &:after {
5 | content: '';
6 | position: absolute;
7 | bottom: 100%;
8 | //--- right of datepicker ---//
9 | // right: 1.2rem;
10 | //--- center of datepicker ---//
11 | /* left: 50%; transform: translateX(-50%); */
12 | //--- left of datepicker ---//
13 | /* left: 1.2rem; */
14 | border: solid transparent;
15 | border-bottom-color: variable.$background;
16 | border-bottom-color: var(--background);
17 | border-width: 0.4rem;
18 | }
19 | }
20 |
21 | @mixin scrollbar {
22 | &::-webkit-scrollbar {
23 | -webkit-appearance: none;
24 | }
25 | &::-webkit-scrollbar:vertical {
26 | width: 0.4rem;
27 | }
28 | &::-webkit-scrollbar-thumb {
29 | border-radius: variable.$radius;
30 | border-radius: var(--radius);
31 | border: 0.1rem solid white; /* should match background, can't be transparent */
32 | background: variable.$border-color;
33 | background: var(--border-color);
34 | }
35 | }
36 |
37 | @keyframes start {
38 | from {
39 | transform: inherit scale(0.5);
40 | opacity: 0;
41 | }
42 | to {
43 | transform: inherit scale(1);
44 | opacity: 1;
45 | }
46 | }
47 |
48 | @keyframes startModal {
49 | from {
50 | transform: translate(-50%, -50%) scale(0.5);
51 | opacity: 0;
52 | }
53 | to {
54 | transform: translate(-50%, -50%) scale(1);
55 | opacity: 1;
56 | }
57 | }
58 |
59 | @keyframes tada {
60 | 0% {
61 | transform: scale(1);
62 | }
63 | 10%,
64 | 20% {
65 | transform: scale(0.9) rotate(-3deg);
66 | }
67 | 30%,
68 | 50%,
69 | 70%,
70 | 90% {
71 | transform: scale(1.1) rotate(3deg);
72 | }
73 | 40%,
74 | 60%,
75 | 80% {
76 | transform: scale(1.1) rotate(-3deg);
77 | }
78 | 100% {
79 | transform: scale(1) rotate(0);
80 | }
81 | }
82 |
83 | @media (max-width: 700px) {
84 | .pdp-picker {
85 | flex-direction: column-reverse;
86 | }
87 |
88 | .pdp-shortcut {
89 | flex-direction: row !important;
90 | flex-wrap: wrap;
91 | justify-content: space-evenly;
92 | padding: 0 !important;
93 | border: none !important;
94 | }
95 | }
96 |
97 | .pdp {
98 | position: relative;
99 |
100 | &:not(.pdp-range) .pdp-day.start-range {
101 | border-radius: variable.$radius !important;
102 | border-radius: var(--radius) !important;
103 | }
104 |
105 | &.pdp-range .pdp-picker.rtl .pdp-day.start-range {
106 | border-radius: 0 variable.$radius variable.$radius 0 !important;
107 | border-radius: 0 var(--radius) var(--radius) 0 !important;
108 | }
109 |
110 | &.pdp-range .pdp-picker.rtl .pdp-day.end-range {
111 | border-radius: variable.$radius 0 0 variable.$radius !important;
112 | border-radius: var(--radius) 0 0 var(--radius) !important;
113 | }
114 |
115 | &.pdp-range .pdp-picker.rtl .pdp-day.end-range.start-range {
116 | border-radius: variable.$radius !important;
117 | border-radius: var(--radius) !important;
118 | }
119 |
120 | &.pdp-range .pdp-picker.ltr .pdp-day.start-range {
121 | border-radius: variable.$radius 0 0 variable.$radius !important;
122 | border-radius: var(--radius) 0 0 var(--radius) !important;
123 | }
124 |
125 | &.pdp-range .pdp-picker.ltr .pdp-day.end-range {
126 | border-radius: 0 variable.$radius variable.$radius 0 !important;
127 | border-radius: 0 var(--radius) var(--radius) 0 !important;
128 | }
129 |
130 | &.pdp-range .pdp-picker.ltr .pdp-day.end-range.start-range {
131 | border-radius: variable.$radius !important;
132 | border-radius: var(--radius) !important;
133 | }
134 |
135 | &.rtl {
136 | direction: rtl;
137 | text-align: right;
138 |
139 | .pdp-group {
140 | :first-child:not(.pdp-inside),
141 | .pdp-inside:first-child + input {
142 | border-top-right-radius: variable.$radius;
143 | border-top-right-radius: var(--radius);
144 | border-bottom-right-radius: variable.$radius;
145 | border-bottom-right-radius: var(--radius);
146 | margin-left: -1px;
147 | }
148 |
149 | input:last-of-type {
150 | border-top-left-radius: variable.$radius;
151 | border-top-left-radius: var(--radius);
152 | border-bottom-left-radius: variable.$radius;
153 | border-bottom-left-radius: var(--radius);
154 | }
155 |
156 | .pdp-icon.pdp-inside {
157 | &:nth-of-type(2) {
158 | right: 50%;
159 | }
160 | + input {
161 | padding-right: 3rem;
162 | }
163 | }
164 | }
165 |
166 | &.pdp-dual {
167 | .pdp-clear {
168 | &:nth-of-type(1) {
169 | left: calc(50% + 0.5rem) !important;
170 | }
171 | }
172 | }
173 |
174 | .pdp-picker::after {
175 | right: 1.2rem;
176 | }
177 | }
178 |
179 | &.ltr {
180 | direction: ltr;
181 | text-align: left;
182 |
183 | .pdp-group {
184 | :first-child:not(.pdp-inside),
185 | .pdp-inside:first-child + input {
186 | border-top-left-radius: variable.$radius;
187 | border-top-left-radius: var(--radius);
188 | border-bottom-left-radius: variable.$radius;
189 | border-bottom-left-radius: var(--radius);
190 | margin-right: -1px;
191 | }
192 |
193 | input:last-of-type {
194 | border-top-right-radius: variable.$radius;
195 | border-top-right-radius: var(--radius);
196 | border-bottom-right-radius: variable.$radius;
197 | border-bottom-right-radius: var(--radius);
198 | font-family: sans-serif;
199 | }
200 |
201 | .pdp-clear {
202 | left: unset;
203 | right: 0.5rem;
204 | }
205 |
206 | .pdp-icon.pdp-inside {
207 | &:nth-of-type(2) {
208 | left: 50%;
209 | }
210 | + input {
211 | padding-left: 3rem;
212 | }
213 | }
214 | }
215 |
216 | &.pdp-dual {
217 | .pdp-clear {
218 | &:nth-of-type(1) {
219 | right: calc(50% + 0.5rem) !important;
220 | }
221 | }
222 | }
223 |
224 | .pdp-picker::after {
225 | left: 1.2rem;
226 | }
227 | }
228 |
229 | &.pdp-dual {
230 | .pdp-picker {
231 | left: 50%;
232 | transform: translateX(-50%);
233 |
234 | &::after {
235 | right: unset;
236 | left: 50%;
237 | transform: translateX(-50%);
238 | }
239 | }
240 | }
241 |
242 | &.pdp-modal {
243 | .pdp-overlay {
244 | background: rgba(0, 0, 0, 0.5) !important;
245 | }
246 |
247 | .pdp-picker {
248 | position: fixed;
249 | top: 50%;
250 | left: 50%;
251 | transform: translate(-50%, -50%);
252 | animation: startModal 0.1s;
253 |
254 | &::after {
255 | all: unset !important;
256 | }
257 | }
258 | }
259 |
260 | * {
261 | box-sizing: border-box;
262 | }
263 |
264 | svg {
265 | vertical-align: middle;
266 | }
267 |
268 | input,
269 | button {
270 | font-family: inherit;
271 | }
272 |
273 | .pdp-label {
274 | display: inline-block;
275 | margin-bottom: 0.5rem;
276 | }
277 |
278 | .pdp-group {
279 | position: relative;
280 | display: flex;
281 | align-items: stretch;
282 | width: 100%;
283 |
284 | .pdp-input {
285 | display: block;
286 | height: calc(1.5em + 0.75rem + 2px);
287 | padding: 0.375rem 0.75rem;
288 | font-size: 1rem;
289 | font-weight: 400;
290 | line-height: 1.5;
291 | background-clip: padding-box;
292 | border: 1px solid variable.$border-color;
293 | border: 1px solid var(--border-color);
294 | transition:
295 | border-color 0.15s ease-in-out,
296 | box-shadow 0.15s ease-in-out;
297 | position: relative;
298 | flex: 1 1 auto;
299 | width: 100%;
300 |
301 | &.pdp-focus {
302 | outline: none;
303 | border-bottom: 2px solid variable.$primary-color;
304 | border-bottom: 2px solid var(--primary-color);
305 | }
306 | }
307 |
308 | .pdp-icon {
309 | padding: 0.375rem 0.75rem;
310 | line-height: 1.5;
311 | font-size: 1rem;
312 | color: variable.$text-color;
313 | color: var(--text-color);
314 | background: variable.$icon-background;
315 | background: var(--icon-background);
316 | border: 1px solid variable.$border-color;
317 | border: 1px solid var(--border-color);
318 | max-height: calc(1.5em + 0.75rem + 2px);
319 |
320 | &:nth-of-type(2) {
321 | margin-left: -1px;
322 | margin-right: -1px;
323 | }
324 |
325 | &.pdp-inside {
326 | background: transparent;
327 | border: none;
328 | position: absolute;
329 | z-index: 1;
330 | }
331 | }
332 |
333 | .pdp-clear {
334 | border: none;
335 | background-color: transparent;
336 | position: absolute;
337 | left: 0.5rem;
338 | top: 0;
339 | bottom: 0;
340 | z-index: 1;
341 | cursor: pointer;
342 | padding: 0 0.5rem;
343 | }
344 | }
345 |
346 | .pdp-overlay {
347 | position: fixed;
348 | top: 0;
349 | bottom: 0;
350 | right: 0;
351 | left: 0;
352 | z-index: variable.$z-index;
353 | z-index: var(--z-index);
354 | background: variable.$overlay-color;
355 | background: var(--overlay-color);
356 | }
357 |
358 | .pdp-picker {
359 | display: flex;
360 | position: absolute;
361 | color: variable.$text-color;
362 | color: var(--text-color);
363 | background: variable.$background;
364 | background: var(--background);
365 | box-shadow: variable.$main-box-shadow;
366 | box-shadow: var(--main-box-shadow);
367 | z-index: variable.$z-index + 1;
368 | z-index: calc(var(--z-index) + 1);
369 | border-radius: variable.$radius;
370 | border-radius: var(--radius);
371 | transition: all 1s ease;
372 | margin-top: 0.5rem;
373 | padding: 0.3rem 0.6rem;
374 | animation: start 0.1s;
375 |
376 | &.ltr {
377 | direction: ltr;
378 |
379 | .pdp-header .bottom {
380 | flex-direction: row-reverse;
381 |
382 | & > div {
383 | display: flex;
384 | flex-direction: row-reverse;
385 | }
386 | }
387 |
388 | .pdp-select-year,
389 | .pdp-days,
390 | .pdp-header .pdp-year,
391 | .pdp-footer small,
392 | .pdp-time {
393 | font-family: sans-serif !important;
394 | }
395 |
396 | .pdp-shortcut {
397 | border-right: unset;
398 | border-left: 1px solid variable.$border-color;
399 | border-left: 1px solid var(--border-color);
400 | }
401 | }
402 |
403 | &.rtl {
404 | direction: rtl;
405 | }
406 |
407 | &.pdp-top {
408 | bottom: calc(1.5em + 0.75rem + 2px);
409 | margin-top: unset;
410 | margin-bottom: 0.5rem;
411 |
412 | &::after {
413 | bottom: unset;
414 | top: 100%;
415 | transform: rotate(180deg);
416 | }
417 | }
418 |
419 | &.pdp-left {
420 | left: 0;
421 | right: unset;
422 |
423 | &::after {
424 | right: unset;
425 | left: 1.2rem;
426 | }
427 | }
428 |
429 | &.pdp-right {
430 | left: unset;
431 | right: 0;
432 |
433 | &::after {
434 | left: unset;
435 | right: 1.2rem;
436 | }
437 | }
438 |
439 | @include little-flag();
440 |
441 | ::selection {
442 | all: unset;
443 | }
444 |
445 | .pdp-auto {
446 | &,
447 | & > div {
448 | background: inherit;
449 | }
450 | }
451 |
452 | .pdp-select-year,
453 | .pdp-select-month {
454 | display: flex;
455 | flex-wrap: wrap;
456 | justify-content: center;
457 | align-items: center;
458 | font-size: 0.8rem;
459 | background: inherit;
460 | list-style: none;
461 | position: absolute;
462 | left: 0;
463 | right: 0;
464 | top: 3.5rem;
465 | bottom: 3.5rem;
466 | padding: 0;
467 | margin: 0;
468 | z-index: 1;
469 | animation: start 0.1s;
470 | overflow: auto;
471 |
472 | li {
473 | width: 5rem;
474 | height: 4rem;
475 | padding: 0.2rem;
476 | cursor: pointer;
477 | margin: 0.15rem;
478 | display: inline-flex;
479 | justify-content: center;
480 | align-items: center;
481 | flex: 30% 0;
482 |
483 | &:not(.disabled):hover {
484 | border-radius: variable.$radius;
485 | border-radius: var(--radius);
486 | border: 2px solid variable.$primary-color;
487 | border: 2px solid var(--primary-color);
488 | }
489 |
490 | &.disabled {
491 | text-shadow: unset;
492 | box-shadow: unset;
493 | cursor: default !important;
494 | opacity: variable.$disabled-opacity;
495 | opacity: var(--disabled-opacity);
496 | }
497 |
498 | &.selected {
499 | border: 2px solid variable.$primary-color;
500 | border: 2px solid var(--primary-color);
501 | border-radius: variable.$radius;
502 | border-radius: var(--radius);
503 | background: variable.$primary-color !important;
504 | background: var(--primary-color) !important;
505 | color: variable.$background;
506 | color: var(--background);
507 | }
508 | }
509 |
510 | @include scrollbar();
511 | }
512 |
513 | .pdp-header {
514 | & > div:first-child {
515 | border-bottom: 1px solid variable.$border-color;
516 | border-bottom: 1px solid var(--border-color);
517 | margin-bottom: 0.5rem;
518 | }
519 |
520 | .top {
521 | padding: 0.75rem 0.3rem 1rem 0.3rem;
522 | display: flex;
523 | justify-content: space-between;
524 | font-size: 0.9rem;
525 | direction: rtl;
526 |
527 | button {
528 | border: 0;
529 | background: inherit;
530 | cursor: pointer;
531 | color: variable.$primary-color;
532 | color: var(--primary-color);
533 | padding: 0 0.5rem;
534 | }
535 | }
536 |
537 | .bottom {
538 | padding: 0.3rem;
539 | display: flex;
540 | align-items: center;
541 | height: 3rem;
542 | direction: rtl;
543 |
544 | & > div {
545 | display: flex;
546 | flex-grow: 1;
547 | justify-content: space-around;
548 |
549 | .pdp-month,
550 | .pdp-year {
551 | color: variable.$primary-color;
552 | color: var(--primary-color);
553 | font-size: 1rem;
554 | }
555 | }
556 |
557 | button {
558 | border: 0;
559 | background: inherit;
560 | cursor: pointer;
561 |
562 | &:focus {
563 | outline: 0;
564 | }
565 | }
566 |
567 | .pdp-arrow.disabled {
568 | opacity: variable.$disabled-opacity;
569 | opacity: var(--disabled-opacity);
570 | }
571 |
572 | .pdp-arrow:not(.disabled):hover {
573 | opacity: variable.$disabled-opacity;
574 | opacity: var(--disabled-opacity);
575 | }
576 | }
577 | }
578 |
579 | .pdp-main {
580 | position: relative;
581 |
582 | .pdp-date {
583 | display: flex;
584 | justify-content: center;
585 |
586 | .pdp-column {
587 | margin: 0 1rem;
588 |
589 | .pdp-week {
590 | background: inherit;
591 | margin-bottom: 0.3rem;
592 | display: flex;
593 | justify-content: space-around;
594 |
595 | .pdp-weekday {
596 | width: variable.$day-dimensions;
597 | width: var(--day-dimensions);
598 | height: variable.$day-dimensions;
599 | height: var(--day-dimensions);
600 | line-height: variable.$day-dimensions;
601 | line-height: var(--day-dimensions);
602 | font-size: 0.8rem;
603 | text-align: center;
604 | }
605 | }
606 |
607 | .pdp-days {
608 | background: inherit;
609 |
610 | .pdp-day {
611 | display: inline-flex;
612 | justify-content: center;
613 | align-items: center;
614 | margin: 0.1rem 0;
615 | font-size: 0.8rem;
616 | width: variable.$day-dimensions;
617 | width: var(--day-dimensions);
618 | height: variable.$day-dimensions;
619 | height: var(--day-dimensions);
620 | border-radius: variable.$radius;
621 | border-radius: var(--radius);
622 | padding: 0;
623 | cursor: pointer;
624 | transition-property: background-color, box-shadow;
625 | transition-duration: 0.1s;
626 | contain: content;
627 |
628 | &.friday {
629 | color: variable.$primary-color;
630 | color: var(--primary-color);
631 | }
632 |
633 | &.empty {
634 | visibility: hidden;
635 | }
636 |
637 | &.start-range,
638 | &.end-range {
639 | background: variable.$primary-color;
640 | background: var(--primary-color);
641 | color: variable.$background;
642 | color: var(--background);
643 | }
644 |
645 | &.disabled {
646 | box-shadow: unset;
647 | text-shadow: unset;
648 | cursor: default !important;
649 | border-color: transparent;
650 | opacity: variable.$disabled-opacity;
651 | opacity: var(--disabled-opacity);
652 | }
653 |
654 | &.hover {
655 | background: variable.$secondary-color !important;
656 | background: var(--secondary-color) !important;
657 | color: variable.$hover-color;
658 | color: var(--hover-color);
659 | }
660 |
661 | &.in-range {
662 | background: variable.$in-range-background;
663 | background: var(--in-range-background);
664 | color: variable.$hover-color;
665 | color: var(--hover-color);
666 | border-radius: 0 !important;
667 | }
668 |
669 | &:not(.disabled):hover,
670 | &.today {
671 | border: 2px solid variable.$primary-color;
672 | border: 2px solid var(--primary-color);
673 | }
674 |
675 | &.tada {
676 | animation: tada 1s;
677 | background: variable.$secondary-color;
678 | background: var(--secondary-color);
679 | box-shadow: inset 0 4px 9px rgba(0, 0, 0, 0.24);
680 | color: #000;
681 | position: relative;
682 | z-index: 1;
683 | }
684 | }
685 | }
686 | }
687 | }
688 |
689 | .pdp-time {
690 | background: inherit;
691 |
692 | &:not(.inline) {
693 | position: absolute;
694 | top: 0;
695 | bottom: 0;
696 | right: 0;
697 | left: 0;
698 | }
699 |
700 | .pdp-column {
701 | display: flex;
702 |
703 | div {
704 | width: 16.6rem;
705 | }
706 | }
707 |
708 | .pdp-moment {
709 | margin-bottom: 1rem;
710 | font-size: calc(2rem * variable.$time-scale);
711 | font-size: calc(2rem * var(--time-scale));
712 | display: flex;
713 | justify-content: space-around;
714 | height: 100%;
715 |
716 | &.column-direction {
717 | flex-direction: column;
718 | }
719 |
720 | > div {
721 | display: flex;
722 | justify-content: center;
723 | align-items: center;
724 | direction: ltr;
725 | width: 100%;
726 | padding: 1rem 0;
727 |
728 | &.disabled {
729 | opacity: variable.$disabled-opacity;
730 | opacity: var(--disabled-opacity);
731 | }
732 |
733 | div {
734 | display: flex;
735 | flex-direction: column;
736 | align-items: center;
737 | padding: 0 0.8rem;
738 |
739 | button {
740 | border: none;
741 | background: none;
742 | cursor: pointer;
743 |
744 | svg {
745 | width: calc(8px * variable.$time-scale);
746 | width: calc(8px * var(--time-scale));
747 | }
748 | }
749 | }
750 | }
751 | }
752 | }
753 | }
754 |
755 | .pdp-footer {
756 | text-align: center;
757 | min-height: 3rem;
758 | display: flex;
759 | align-items: center;
760 | justify-content: space-between;
761 | border-top: 1px solid variable.$border-color;
762 | border-top: 1px solid var(--border-color);
763 | padding: 0.3rem;
764 |
765 | .pdp-today,
766 | .pdp-submit {
767 | font-size: 0.8rem;
768 | padding: 0.25rem 0.5rem;
769 | margin: 0 0.3rem;
770 | line-height: 1.5;
771 | color: variable.$background;
772 | color: var(--background);
773 | text-decoration: none;
774 | border: none;
775 | border-radius: variable.$radius;
776 | border-radius: var(--radius);
777 | background: variable.$primary-color;
778 | background: var(--primary-color);
779 | cursor: pointer;
780 |
781 | &:hover {
782 | filter: brightness(0.9);
783 | }
784 | }
785 |
786 | > div {
787 | display: flex;
788 | }
789 | }
790 |
791 | .pdp-shortcut {
792 | margin: 0;
793 | padding: 0.5rem;
794 | list-style: none;
795 | display: flex;
796 | flex-direction: column;
797 | align-items: stretch;
798 | border-right: 1px solid variable.$border-color;
799 | border-right: 1px solid var(--border-color);
800 |
801 | li {
802 | margin: 0;
803 | padding: 0.5rem 1rem;
804 | text-align: center;
805 | cursor: pointer;
806 | border-radius: variable.$radius;
807 | border-radius: var(--radius);
808 | margin: 0.25rem 0;
809 | color: variable.$hover-color;
810 | color: var(--hover-color);
811 | font-weight: 500;
812 |
813 | &:hover {
814 | background: variable.$in-range-background;
815 | background: var(--in-range-background);
816 | }
817 |
818 | &.selected {
819 | background: variable.$primary-color;
820 | background: var(--primary-color);
821 | color: variable.$background;
822 | color: var(--background);
823 | }
824 | }
825 | }
826 | }
827 |
828 | .pdp-pointer {
829 | cursor: pointer;
830 | }
831 |
832 | .pdp-auto {
833 | margin: auto;
834 | position: relative;
835 | }
836 | }
837 |
--------------------------------------------------------------------------------
/src/components/utils/components/PDPAlt.vue:
--------------------------------------------------------------------------------
1 |
20 |
21 |
22 |
23 |
30 |
31 |
37 |
38 |
--------------------------------------------------------------------------------
/src/components/utils/components/PDPArrow.vue:
--------------------------------------------------------------------------------
1 |
30 |
31 |
32 |
43 |
44 |
--------------------------------------------------------------------------------
/src/components/utils/components/PDPIcon.vue:
--------------------------------------------------------------------------------
1 |
6 |
18 |
19 |
20 |
32 |
65 |
136 |
149 |
150 |
--------------------------------------------------------------------------------
/src/components/utils/modules/core.ts:
--------------------------------------------------------------------------------
1 | import PersianDate from '@alireza-ab/persian-date';
2 | import { Obj, Units, Langs, Shortcuts } from './types';
3 |
4 | export const Core = {
5 | langs: {
6 | fa: {
7 | calendar: 'jalali',
8 | weekdays: ['ش', 'ی', 'د', 'س', 'چ', 'پ', 'ج'],
9 | months: [
10 | 'فروردین',
11 | 'اردیبهشت',
12 | 'خرداد',
13 | 'تیر',
14 | 'مرداد',
15 | 'شهریور',
16 | 'مهر',
17 | 'آبان',
18 | 'آذر',
19 | 'دی',
20 | 'بهمن',
21 | 'اسفند',
22 | ],
23 | dir: {
24 | input: 'rtl',
25 | picker: 'rtl',
26 | },
27 | translations: {
28 | label: 'شمسی',
29 | text: 'تقویم شمسی',
30 | prevMonth: 'ماه قبل',
31 | nextMonth: 'ماه بعد',
32 | now: 'هم اکنون',
33 | submit: 'تایید',
34 | /* use in shourcuts */
35 | // date-single
36 | yesterday: 'دیروز',
37 | tomorrow: 'فردا',
38 | firstOfWeek: 'اول هفته',
39 | lastOfWeek: 'آخر هفته',
40 | // date-range
41 | thisWeek: 'این هفته',
42 | prevWeek: 'هفته قبل',
43 | nextWeek: 'هفته بعد',
44 | thisMonth: 'این ماه',
45 | // time-single
46 | oneHourAgo: 'یک ساعت قبل',
47 | oneHourLater: 'یک ساعت بعد',
48 | midnight: 'نیمه شب',
49 | midday: 'نیمروز',
50 | // time-range
51 | thisHour: 'این ساعت',
52 | prevHour: 'ساعت قبل',
53 | nextHour: 'ساعت بعد',
54 | allDay: 'تمام روز',
55 | },
56 | inputFormat: '',
57 | displayFormat: '',
58 | },
59 | en: {
60 | calendar: 'gregorian',
61 | weekdays: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],
62 | months: [
63 | 'January',
64 | 'February',
65 | 'March',
66 | 'April',
67 | 'May',
68 | 'June',
69 | 'July',
70 | 'August',
71 | 'September',
72 | 'October',
73 | 'November',
74 | 'December',
75 | ],
76 | dir: {
77 | input: 'rtl',
78 | picker: 'ltr',
79 | },
80 | translations: {
81 | label: 'میلادی',
82 | text: 'Gregorian Calendar',
83 | prevMonth: 'Previous Month',
84 | nextMonth: 'Next Month',
85 | now: 'Now',
86 | submit: 'Submit',
87 | /* use in shourcuts */
88 | // date-single
89 | yesterday: 'Yesterday',
90 | tomorrow: 'Tomorrow',
91 | firstOfWeek: 'First of Week',
92 | lastOfWeek: 'Last of Week',
93 | // date-range
94 | thisWeek: 'This Week',
95 | prevWeek: 'Previous Week',
96 | nextWeek: 'Next Week',
97 | thisMonth: 'This Month',
98 | // time-single
99 | oneHourAgo: 'One Hour ago',
100 | oneHourLater: 'One Hour later',
101 | midnight: 'Midnight',
102 | midday: 'Midday',
103 | // time-range
104 | thisHour: 'This Hour',
105 | prevHour: 'Previous Hour',
106 | nextHour: 'Next Hour',
107 | allDay: 'All Day',
108 | },
109 | inputFormat: '',
110 | displayFormat: '',
111 | },
112 | } as Langs,
113 | mergeObject: function (original: Obj, changed: Obj | undefined): Obj {
114 | const newObject = JSON.parse(JSON.stringify(original));
115 | for (const key in changed) {
116 | if (
117 | original[key] &&
118 | Object.prototype.toString.call(changed[key]) === '[object Object]'
119 | )
120 | newObject[key] = this.mergeObject(
121 | original[key] as Obj,
122 | changed[key] as Obj,
123 | );
124 | else newObject[key] = changed[key];
125 | }
126 | return newObject;
127 | },
128 | setStyles: function (styles: Obj | undefined, root: HTMLElement): void {
129 | for (const name in styles) {
130 | root.style.setProperty('--' + name, styles[name] as string);
131 | }
132 | },
133 | setColor: function (color: string | undefined, root: HTMLElement): void {
134 | if (!color) return;
135 | let colors = {};
136 | switch (color) {
137 | case 'red':
138 | colors = {
139 | 'primary-color': '#c7004c',
140 | 'secondary-color': '#ffaaaa',
141 | 'in-range-background': '#ffd2d2',
142 | };
143 | break;
144 | case 'pink':
145 | colors = {
146 | 'primary-color': '#e56ab3',
147 | 'secondary-color': '#ef87be',
148 | 'in-range-background': '#fcbcd7',
149 | };
150 | break;
151 | case 'orange':
152 | colors = {
153 | 'primary-color': '#ffa500',
154 | 'secondary-color': '#ffbe47',
155 | 'in-range-background': '#ffe0a6',
156 | };
157 | break;
158 | case 'green':
159 | colors = {
160 | 'primary-color': '#38a169',
161 | 'secondary-color': '#89dda3',
162 | 'in-range-background': '#c6f6d5',
163 | };
164 | break;
165 | case 'purple':
166 | colors = {
167 | 'primary-color': '#7825d0',
168 | 'secondary-color': '#c196ed',
169 | 'in-range-background': '#d4baf3',
170 | };
171 | break;
172 | case 'gray':
173 | colors = {
174 | 'primary-color': '#494848',
175 | 'secondary-color': '#909090',
176 | 'in-range-background': '#b4b4b4',
177 | };
178 | break;
179 | default:
180 | break;
181 | }
182 | this.setStyles(colors, root);
183 | },
184 | getLastUnit: function (
185 | date: string,
186 | type: 'time' | 'datetime' | 'date',
187 | ): Units {
188 | const unitsCount =
189 | date.split(/[/ \-.,:\\]/).length + (type == 'time' ? 3 : 0);
190 | switch (unitsCount) {
191 | case 1:
192 | return 'year';
193 | case 2:
194 | return 'month';
195 | case 3:
196 | return 'date';
197 | case 4:
198 | return 'hour';
199 | case 5:
200 | return 'minute';
201 | case 6:
202 | return 'second';
203 | default:
204 | return 'millisecond';
205 | }
206 | },
207 | getShortcuts(
208 | date: PersianDate,
209 | part: string,
210 | translate: Record,
211 | ): Shortcuts {
212 | const c = (): PersianDate => date.clone();
213 | switch (part) {
214 | case 'date-single':
215 | return {
216 | [translate.now]: [c()],
217 | [translate.yesterday]: [c().subDay()],
218 | [translate.tomorrow]: [c().addDay()],
219 | [translate.firstOfWeek]: [c().startOf('week')],
220 | [translate.lastOfWeek]: [c().endOf('week')],
221 | };
222 | case 'date-range':
223 | return {
224 | [translate.thisWeek]: [c().startOf('week'), c().endOf('week')],
225 | [translate.prevWeek]: [
226 | c().subWeek().startOf('week'),
227 | c().subWeek().endOf('week'),
228 | ],
229 | [translate.nextWeek]: [
230 | c().addWeek().startOf('week'),
231 | c().addWeek().endOf('week'),
232 | ],
233 | [translate.thisMonth]: [c().startOf('month'), c().endOf('month')],
234 | [translate.prevMonth]: [
235 | c().subMonth().startOf('month'),
236 | c().subMonth().endOf('month'),
237 | ],
238 | [translate.nextMonth]: [
239 | c().addMonth().startOf('month'),
240 | c().addMonth().endOf('month'),
241 | ],
242 | };
243 | case 'time-single':
244 | return {
245 | [translate.now]: [c()],
246 | [translate.oneHourAgo]: [c().subHour()],
247 | [translate.oneHourLater]: [c().addHour()],
248 | [translate.midnight]: [c().startOf('date')],
249 | [translate.midday]: [c().time(12)],
250 | };
251 | case 'time-range':
252 | return {
253 | [translate.thisHour]: [c().startOf('hour'), c().endOf('hour')],
254 | [translate.prevHour]: [
255 | c().subHour().startOf('hour'),
256 | c().subHour().endOf('hour'),
257 | ],
258 | [translate.nextHour]: [
259 | c().addHour().startOf('hour'),
260 | c().addHour().endOf('hour'),
261 | ],
262 | [translate.allDay]: [c().startOf('date'), c().endOf('date')],
263 | };
264 | default:
265 | return {};
266 | }
267 | },
268 | isString: function (val: unknown): boolean {
269 | return typeof val == 'string';
270 | },
271 | isNumber: function (val: unknown): boolean {
272 | return typeof val == 'number';
273 | },
274 | isFunction: function (val: unknown): boolean {
275 | return typeof val == 'function';
276 | },
277 | isPersianDate: function (val: unknown): boolean {
278 | return PersianDate.isPersianDate(val);
279 | },
280 | };
281 |
282 | export { PersianDate };
283 |
--------------------------------------------------------------------------------
/src/components/utils/modules/types.ts:
--------------------------------------------------------------------------------
1 | import type PersianDate from '@alireza-ab/persian-date/typings/PersianDate';
2 | export { PersianDate };
3 |
4 | export type Obj<
5 | T = unknown,
6 | U extends string | number | symbol = string,
7 | > = Record;
8 | export type StrOrRegex = string | RegExp;
9 | export type FixedSizeArray = {
10 | [n: number]: T;
11 | length: N;
12 | };
13 | export type RecursivePartial = {
14 | [P in keyof T]?: T[P] extends (infer U)[]
15 | ? RecursivePartial[]
16 | : T[P] extends Record
17 | ? RecursivePartial
18 | : T[P];
19 | };
20 |
21 | export type Calendar = 'jalali' | 'gregorian';
22 | export type Dir = 'rtl' | 'ltr';
23 | export type Units =
24 | | 'year'
25 | | 'month'
26 | | 'date'
27 | | 'hour'
28 | | 'minute'
29 | | 'second'
30 | | 'millisecond';
31 | export type TypePart = 'date' | 'time';
32 | export type CalendarPart = 'year' | 'month';
33 |
34 | export type Attrs = {
35 | div: Obj;
36 | label: Obj;
37 | alt: Obj;
38 | picker: Obj;
39 | firstInput: Obj;
40 | secondInput: Obj;
41 | };
42 | export type MonthDays = Obj<
43 | {
44 | empty?: boolean;
45 | friday?: boolean;
46 | raw?: PersianDate;
47 | startRange?: boolean;
48 | endRange?: boolean;
49 | inRange?: boolean;
50 | disabled?: boolean;
51 | today?: boolean;
52 | val?: number;
53 | },
54 | number
55 | >;
56 | export type Months = Obj<
57 | {
58 | label: string;
59 | selected: boolean;
60 | disabled: boolean;
61 | },
62 | number
63 | >;
64 | export type DefaultDate = { from: string; to: string };
65 | export type Formats = {
66 | model: string;
67 | input: string;
68 | display: string;
69 | alt: string;
70 | };
71 | export type Shortcuts = Obj;
72 | export type Langs = {
73 | [locale: string]: {
74 | calendar: Calendar;
75 | weekdays: FixedSizeArray;
76 | months: FixedSizeArray;
77 | dir: {
78 | input: Dir;
79 | picker: Dir;
80 | };
81 | translations: {
82 | label: string;
83 | text: string;
84 | prevMonth: string;
85 | nextMonth: string;
86 | now: string;
87 | submit: string;
88 | /* use in shourcuts */
89 | // date-single
90 | yesterday: string;
91 | tomorrow: string;
92 | firstOfWeek: string;
93 | lastOfWeek: string;
94 | // date-range
95 | thisWeek: string;
96 | prevWeek: string;
97 | nextWeek: string;
98 | thisMonth: string;
99 | // time-single
100 | oneHourAgo: string;
101 | oneHourLater: string;
102 | midnight: string;
103 | midday: string;
104 | // time-range
105 | thisHour: string;
106 | prevHour: string;
107 | nextHour: string;
108 | allDay: string;
109 | };
110 | inputFormat: string;
111 | displayFormat: string;
112 | };
113 | };
114 | export type Styles = {
115 | 'primary-color': string;
116 | 'secondary-color': string;
117 | 'in-range-background': string;
118 | 'text-color': string;
119 | 'hover-color': string;
120 | 'border-color': string;
121 | 'icon-background': string;
122 | 'overlay-color': string;
123 | 'main-box-shadow': string;
124 | 'day-dimensions': string;
125 | 'z-index': string | number;
126 | 'disabled-opacity': string | number;
127 | 'time-scale': string | number;
128 | radius: string;
129 | background: string;
130 | };
131 | export type PickerPlace = { top?: boolean; right?: boolean; left?: boolean };
132 | export type Inputs = 'firstInput' | 'secondInput';
133 | export type Disable =
134 | | StrOrRegex
135 | | StrOrRegex[]
136 | | ((date: PersianDate) => boolean);
137 |
--------------------------------------------------------------------------------
/src/main.ts:
--------------------------------------------------------------------------------
1 | import { createApp } from 'vue';
2 | import App from './App.vue';
3 |
4 | createApp(App).mount('#app');
5 |
--------------------------------------------------------------------------------
/src/nuxt/composable/usePersianDate.ts:
--------------------------------------------------------------------------------
1 | import PersianDate from '@alireza-ab/persian-date';
2 |
3 | export default function (
4 | ...args: ConstructorParameters
5 | ): PersianDate {
6 | return new PersianDate(...args);
7 | }
8 |
--------------------------------------------------------------------------------
/src/nuxt/index.ts:
--------------------------------------------------------------------------------
1 | import {
2 | defineNuxtModule,
3 | createResolver,
4 | addImportsDir,
5 | addComponentsDir,
6 | } from '@nuxt/kit';
7 |
8 | export interface DatePickerNuxtOptions {
9 | PersianDate?: boolean;
10 | }
11 |
12 | export default defineNuxtModule({
13 | meta: {
14 | name: '@alireza-ab/vue3-persian-datepicker',
15 | configKey: 'datepicker',
16 | compatibility: {
17 | nuxt: '^3.0.0-rc',
18 | },
19 | },
20 | defaults: {
21 | PersianDate: false,
22 | },
23 | setup(options, nuxt) {
24 | const { include } = nuxt.options.vite.optimizeDeps!;
25 | nuxt.options.vite.optimizeDeps!.include = [
26 | ...(include || []),
27 | '@alireza-ab/persian-date',
28 | ];
29 |
30 | const { resolve } = createResolver(import.meta.url);
31 |
32 | if (options.PersianDate)
33 | addImportsDir(resolve('../../src/nuxt/composable'));
34 |
35 | addComponentsDir({
36 | path: resolve('../../src/components'),
37 | pattern: '**/*.vue',
38 | });
39 | },
40 | });
41 |
42 | declare module '@nuxt/schema' {
43 | interface NuxtConfig {
44 | datepicker?: DatePickerNuxtOptions;
45 | }
46 | interface NuxtOptions {
47 | datepicker?: DatePickerNuxtOptions;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/shims-vue.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.vue' {
2 | import { DefineComponent } from 'vue';
3 | type Obj = Record;
4 | const component: DefineComponent;
5 | export default component;
6 | }
7 |
--------------------------------------------------------------------------------
/src/vite-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/test/e2e/arrow-keys.cy.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
3 | describe('arrow keys', () => {
4 | before(() => {
5 | cy.changeProps();
6 | cy.changeSlots();
7 | });
8 |
9 | it('without select date', () => {
10 | cy.get('.pdp-input').focus().wait(1).type('{downarrow}{rightarrow}');
11 | cy.get('[data-column=1] .hover').should('contain.text', '31');
12 | cy.get('.pdp-input').type('{uparrow}');
13 | cy.get('[data-column=1] .hover').should('contain.text', '24');
14 | cy.get('.pdp-input').type(
15 | '{rightarrow}{rightarrow}{rightarrow}{rightarrow}',
16 | );
17 | cy.get('[data-column=1] .hover').should('contain.text', '20');
18 | cy.get('.pdp-input').type('{uparrow}');
19 | cy.get('[data-column=1] .hover').should('contain.text', '13');
20 | cy.get('.pdp-input').type('{leftarrow}');
21 | cy.get('[data-column=1] .hover').should('contain.text', '14');
22 | cy.get('.pdp-input').type('{uparrow}{uparrow}');
23 | cy.get('[data-column=0] .hover').should('contain.text', '31');
24 | cy.get('.pdp-input').type('{leftarrow}');
25 | cy.get('[data-column=1] .hover').should('contain.text', '1');
26 | cy.get('.pdp-input').type('{rightarrow}');
27 | cy.get('[data-column=0] .hover').should('contain.text', '31');
28 | cy.get('.pdp-input').type('{uparrow}{uparrow}{uparrow}{uparrow}{uparrow}');
29 | cy.get('[data-column=1] .hover').should('contain.text', '27');
30 | cy.get('.pdp-input').type('{uparrow}{uparrow}{uparrow}{uparrow}');
31 | cy.get('[data-column=0] .hover').should('contain.text', '30');
32 | cy.get('.pdp-input').type('{leftarrow}{leftarrow}');
33 | cy.get('[data-column=1] .hover').should('contain.text', '1');
34 | cy.get('.pdp-input').type(
35 | '{uparrow}{rightarrow}{rightarrow}{rightarrow}{rightarrow}{rightarrow}{rightarrow}',
36 | );
37 | cy.get('[data-column=0] .hover').should('contain.text', '19');
38 | cy.get('.pdp-input').type('{uparrow}{uparrow}{uparrow}');
39 | cy.get('[data-column=1] .hover').should('contain.text', '29');
40 | cy.get('.pdp-input').type('{uparrow}{uparrow}{uparrow}{uparrow}{uparrow}');
41 | cy.get('[data-column=1] .hover').should('contain.text', '1');
42 | cy.get('.pdp-input').type('{leftarrow}');
43 | cy.get('[data-column=1] .hover').should('contain.text', '2');
44 | });
45 |
46 | it('with select date', () => {
47 | cy.get('.pdp-input').focus().get('.pdp-year').first().click();
48 | cy.get('li').contains('1399').click();
49 | cy.get('.pdp-input').focus().get('.pdp-month').first().click();
50 | cy.get('li').contains('فروردین').click();
51 | cy.get('.pdp-input').type('{downarrow}', { force: true });
52 | cy.get('.hover').should('contain.text', '1');
53 | cy.get('.pdp-input').type('{downarrow}{downarrow}{rightarrow}{enter}');
54 | cy.get('.start-range').should('contain.text', '14');
55 | cy.get('.pdp-input')
56 | .type('{downarrow}{downarrow}{downarrow}{downarrow}{rightarrow}{enter}')
57 | .should('have.value', '1399/01/14 - 1399/02/10')
58 | .focus()
59 | .get('.end-range')
60 | .should('contain.text', '10');
61 | cy.get('[data-column=0] .in-range')
62 | .should('not.contain.text', '14')
63 | .should('not.contain.text', '13');
64 | cy.get('[data-column=1] .in-range')
65 | .should('not.contain.text', '10')
66 | .should('not.contain.text', '11');
67 | cy.get('.pdp-input').type('{downarrow}{rightarrow}{rightarrow}{enter}');
68 | cy.get('.start-range').should('contain.text', '15');
69 | cy.get('.pdp-input').type('{uparrow}{uparrow}{uparrow}{enter}').focus();
70 | cy.get('.start-range').should('contain.text', '25');
71 | cy.get('.end-range').should('contain.text', '15');
72 | cy.get('.pdp-input')
73 | .type(
74 | '{downarrow}{downarrow}{downarrow}{downarrow}{downarrow}{downarrow}{enter}',
75 | )
76 | .get('.start-range')
77 | .should('contain.text', '26');
78 | cy.get('.pdp-arrow').first().click().click();
79 | cy.get('.pdp-input')
80 | .type('{uparrow}{enter}', { force: true })
81 | .should('have.value', '1399/01/01 - 1399/03/26')
82 | .focus();
83 | cy.get('.start-range').should('contain.text', '1');
84 | });
85 | });
86 |
87 | describe('arrow keys in "en" locale', () => {
88 | before(() => {
89 | cy.changeProps('locale', 'en');
90 | });
91 |
92 | it('without select date', () => {
93 | cy.get('.pdp-input').focus().wait(1).type('{downarrow}{leftarrow}');
94 | cy.get('[data-column=1] .hover').should('contain.text', '31');
95 | cy.get('.pdp-input').type('{uparrow}');
96 | cy.get('[data-column=1] .hover').should('contain.text', '24');
97 | cy.get('.pdp-input').type('{leftarrow}{leftarrow}{leftarrow}{leftarrow}');
98 | cy.get('[data-column=1] .hover').should('contain.text', '20');
99 | cy.get('.pdp-input').type('{uparrow}');
100 | cy.get('[data-column=1] .hover').should('contain.text', '13');
101 | cy.get('.pdp-input').type('{rightarrow}');
102 | cy.get('[data-column=1] .hover').should('contain.text', '14');
103 | cy.get('.pdp-input').type('{uparrow}{uparrow}');
104 | cy.get('[data-column=0] .hover').should('contain.text', '31');
105 | cy.get('.pdp-input').type('{rightarrow}');
106 | cy.get('[data-column=1] .hover').should('contain.text', '1');
107 | cy.get('.pdp-input').type('{leftarrow}');
108 | cy.get('[data-column=0] .hover').should('contain.text', '31');
109 | cy.get('.pdp-input').type('{uparrow}{uparrow}{uparrow}{uparrow}{uparrow}');
110 | cy.get('[data-column=1] .hover').should('contain.text', '26');
111 | cy.get('.pdp-input').type('{uparrow}{uparrow}{uparrow}{uparrow}');
112 | cy.get('[data-column=0] .hover').should('contain.text', '29');
113 | cy.get('.pdp-input').type('{rightarrow}{rightarrow}');
114 | cy.get('[data-column=0] .hover').should('contain.text', '31');
115 | cy.get('.pdp-input').type(
116 | '{uparrow}{leftarrow}{leftarrow}{leftarrow}{leftarrow}{leftarrow}{leftarrow}',
117 | );
118 | cy.get('[data-column=0] .hover').should('contain.text', '18');
119 | cy.get('.pdp-input').type('{uparrow}{uparrow}{uparrow}');
120 | cy.get('[data-column=1] .hover').should('contain.text', '27');
121 | cy.get('.pdp-input').type('{uparrow}{uparrow}{uparrow}{uparrow}{uparrow}');
122 | cy.get('[data-column=0] .hover').should('contain.text', '23');
123 | cy.get('.pdp-input').type('{rightarrow}');
124 | cy.get('[data-column=0] .hover').should('contain.text', '24');
125 | });
126 |
127 | it('with select date', () => {
128 | cy.get('.pdp-input').focus().get('.pdp-year').first().click();
129 | cy.get('li').contains('2020').click();
130 | cy.get('.pdp-input').focus().get('.pdp-month').first().click();
131 | cy.get('li').contains('March').click();
132 | cy.get('.pdp-input').type('{downarrow}', { force: true });
133 | cy.get('.hover').should('contain.text', '20');
134 | cy.get('.pdp-input').type('{downarrow}{downarrow}{leftarrow}{enter}');
135 | cy.get('.start-range').should('contain.text', '2');
136 | cy.get('.pdp-input')
137 | .type('{downarrow}{downarrow}{downarrow}{downarrow}{leftarrow}{enter}')
138 | .should('have.value', '2020-04-02 - 2020-04-29')
139 | .focus()
140 | .get('.end-range')
141 | .should('contain.text', '29');
142 | cy.get('[data-column=1] .in-range')
143 | .first()
144 | .should('not.contain.text', '2')
145 | .should('not.contain.text', '1');
146 | cy.get('[data-column=1] .in-range')
147 | .last()
148 | .should('not.contain.text', '29')
149 | .should('not.contain.text', '30');
150 | cy.get('.pdp-input').type('{downarrow}{leftarrow}{leftarrow}{enter}');
151 | cy.get('.start-range').should('contain.text', '4');
152 | cy.get('.pdp-input')
153 | .type('{uparrow}{uparrow}{uparrow}{enter}')
154 | .should('have.value', '2020-04-13 - 2020-05-04')
155 | .focus();
156 | cy.get('.start-range').should('contain.text', '13');
157 | cy.get('.pdp-input').type(
158 | '{downarrow}{downarrow}{downarrow}{downarrow}{downarrow}{downarrow}{enter}',
159 | );
160 | cy.get('.start-range').should('contain.text', '25');
161 | cy.get('.pdp-arrow').first().click().click();
162 | cy.get('.pdp-input')
163 | .type(
164 | '{downarrow}{downarrow}{downarrow}{downarrow}{rightarrow}{rightarrow}{enter}',
165 | { force: true },
166 | )
167 | .should('have.value', '2020-04-12 - 2020-05-25')
168 | .focus()
169 | .get('.start-range')
170 | .should('contain.text', '12');
171 | });
172 | });
173 |
174 | describe('arrow keys with disabel date', () => {
175 | before(() => {
176 | cy.changeProps({ locale: 'fa', disable: '1399/6/10' });
177 | });
178 |
179 | it('with select date', () => {
180 | cy.get('.pdp-input').focus().wait(1).type('{downarrow}{enter}');
181 | cy.get('.start-range').should('contain.text', '1');
182 | cy.get('.pdp-input')
183 | .type('{downarrow}{downarrow}{leftarrow}{leftarrow}{enter}')
184 | .type('{uparrow}{enter}{rightarrow}{enter}')
185 | .should('have.value', '1399/06/01 - 1399/06/09')
186 | .focus()
187 | .get('.end-range')
188 | .should('contain.text', '9');
189 | });
190 | });
191 |
--------------------------------------------------------------------------------
/test/e2e/events.cy.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
3 | const focusEvent = () => {
4 | cy.get('.pdp-input').focus();
5 | cy.get('.status').should('contain.text', 'focus');
6 | };
7 | const blurEvent = () => {
8 | cy.get('.pdp-input').focus();
9 | cy.get('.pdp-overlay').click({ force: true });
10 | cy.get('.status').should('contain.text', 'blur');
11 | };
12 | const inputEvent = () => {
13 | cy.get('.pdp-input').type('1');
14 | cy.get('.status').should('contain.text', 'input');
15 | };
16 | const openEvent = () => {
17 | cy.get('.pdp-input').focus();
18 | cy.get('.status').should('contain.text', 'open');
19 | };
20 | const closeEvent = () => {
21 | cy.get('.pdp-input').focus();
22 | cy.get('.pdp-overlay').click({ force: true });
23 | cy.get('.status').should('contain.text', 'close');
24 | };
25 | const clearEvent = () => {
26 | cy.get('.pdp-clear').click();
27 | cy.get('.status').should('contain.text', 'clear');
28 | };
29 |
30 | before(() => {
31 | cy.changeProps('clearable', true, true);
32 | cy.changeSlots();
33 | });
34 |
35 | describe('date type', () => {
36 | before(() => {
37 | cy.changeProps('type', 'date');
38 | });
39 |
40 | it('focus', focusEvent);
41 | it('blur', blurEvent);
42 | it('input', inputEvent);
43 | it('open', openEvent);
44 | it('close', closeEvent);
45 | it('clear', clearEvent);
46 | it('select & submit', () => {
47 | cy.get('.pdp-input').type('1399/06/01{enter}');
48 | cy.get('.status').should('contain.text', 'select:1399/06/01');
49 | cy.get('.pdp-input').type('1399/06/02{enter}');
50 | cy.get('.status')
51 | .should('contain.text', 'select:1399/06/02')
52 | .should('contain.text', 'submit:1399/06/01,1399/06/02');
53 | });
54 | });
55 |
56 | describe('time type', () => {
57 | before(() => {
58 | cy.changeProps('type', 'time');
59 | });
60 |
61 | it('focus', focusEvent);
62 | it('blur', blurEvent);
63 | it('input', inputEvent);
64 | it('open', openEvent);
65 | it('close', closeEvent);
66 | it('clear', clearEvent);
67 | it('select & submit', () => {
68 | cy.get('.pdp-input').type('15:12{enter}');
69 | cy.get('.status').should('contain.text', 'select:15:12');
70 | cy.get('.pdp-input').type('20:18{enter}');
71 | cy.get('.status')
72 | .should('contain.text', 'select:20:18')
73 | .should('contain.text', 'submit:15:12,20:18');
74 | });
75 | });
76 |
77 | describe('datetime type', () => {
78 | before(() => {
79 | cy.changeProps('type', 'datetime');
80 | });
81 |
82 | it('focus', focusEvent);
83 | it('blur', blurEvent);
84 | it('input', inputEvent);
85 | it('open', openEvent);
86 | it('close', closeEvent);
87 | it('clear', clearEvent);
88 | it('select & submit', () => {
89 | cy.get('.pdp-input').type('1399/06/01 20:18{enter}');
90 | cy.get('.status').should('contain.text', 'select:1399/06/01 20:18');
91 | cy.get('.pdp-input').type('1399/06/02 15:12{enter}');
92 | cy.get('.status')
93 | .should('contain.text', 'select:1399/06/02 15:12')
94 | .should('contain.text', 'submit:1399/06/01 20:18,1399/06/02 15:12');
95 | });
96 | });
97 |
--------------------------------------------------------------------------------
/test/e2e/other-tests.cy.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
3 | before(() => {
4 | cy.changeProps(null, null, true);
5 | cy.changeSlots();
6 | });
7 |
8 | describe('scroll in year-select section', () => {
9 | it('test', () => {
10 | cy.get('.pdp-input').focus();
11 | cy.get('.pdp-year')
12 | .first()
13 | .click()
14 | .wait(1)
15 | .then(() => {
16 | expect(cy.$$('.pdp-select-year').scrollTop()).not.equal(0);
17 | });
18 | });
19 | });
20 |
21 | describe('select range date and change locale', () => {
22 | before(() => {
23 | cy.changeProps({ from: '1399', to: '1399/6/31', locale: 'fa,en' });
24 | });
25 |
26 | it('test', () => {
27 | cy.get('.pdp-input').focus();
28 | cy.contains('15').first().click();
29 | cy.contains('20').first().click();
30 | cy.get('.pdp-input').focus();
31 | cy.get('.pdp-header .top button').click();
32 | cy.contains('September');
33 | cy.get('.start-range').should('contain.text', '5');
34 | cy.get('.end-range').should('contain.text', '10');
35 | });
36 | });
37 |
38 | describe('select single date and change locale', () => {
39 | before(() => {
40 | cy.changeProps({ locale: 'en,fa', mode: 'single' });
41 | });
42 |
43 | it('test', () => {
44 | cy.get('.pdp-input').focus();
45 | cy.contains('10').first().click();
46 | cy.get('.pdp-input').focus();
47 | cy.get('.pdp-header .top button').click();
48 | cy.get('.pdp-month').should('contain.text', 'شهریور');
49 | cy.get('.start-range').should('contain.text', '20');
50 | });
51 | });
52 |
53 | describe('disable dates and change locale', () => {
54 | before(() => {
55 | cy.changeProps(
56 | { locale: 'fa,en', disable: ['1399/10/5', '1399/9/20', '1399/7/1'] },
57 | null,
58 | true,
59 | );
60 | });
61 | it('test', () => {
62 | cy.get('.pdp-input').focus();
63 | cy.get('button.pdp-year').first().click();
64 | cy.get('li').contains('1399').click();
65 | cy.get('button.pdp-month').first().click();
66 | cy.get('.pdp-select-month > :nth-child(10)').click();
67 | cy.get('[data-column="0"] .pdp-day[value="5"]')
68 | .should('have.attr', 'class')
69 | .and('match', /disabled/);
70 | cy.get('.pdp-arrow').first().click();
71 | cy.get('[data-column="0"] .pdp-day[value="20"]')
72 | .should('have.attr', 'class')
73 | .and('match', /disabled/);
74 | cy.get('.pdp-arrow').first().click().click();
75 | cy.get('[data-column="0"] .pdp-day[value="1"]')
76 | .should('have.attr', 'class')
77 | .and('match', /disabled/);
78 | cy.get('.pdp-header .top button').click();
79 | cy.get('button.pdp-year').first().click();
80 | cy.get('li').contains('2020').click();
81 | cy.get('button.pdp-month').first().click();
82 | cy.get('li').contains('September').click();
83 | cy.get('[data-column="0"] .pdp-day[value="22"]')
84 | .should('have.attr', 'class')
85 | .and('match', /disabled/);
86 | cy.get('.pdp-arrow').last().click().click().click();
87 | cy.get('[data-column="0"] .pdp-day[value="10"]')
88 | .should('have.attr', 'class')
89 | .and('match', /disabled/);
90 | cy.get('[data-column="0"] .pdp-day[value="25"]')
91 | .should('have.attr', 'class')
92 | .and('match', /disabled/);
93 | });
94 | });
95 |
96 | describe('disable datetimes and change locale', () => {
97 | before(() => {
98 | cy.changeProps({
99 | type: 'datetime',
100 | disable: ['1399/10/5 15:52', '1399/10/5 15:53', '1399/10/5 15:54'],
101 | });
102 | });
103 |
104 | it('test', () => {
105 | cy.get('.pdp-input').focus();
106 | cy.get('button.pdp-year').first().click();
107 | cy.get('li').contains('1399').click();
108 | cy.get('button.pdp-month').first().click();
109 | cy.get('.pdp-select-month > :nth-child(10)').click();
110 | cy.get('[data-column="0"] .pdp-day[value="5"]').click();
111 | cy.get('.pdp-input').focus();
112 | cy.selectTime(15, 52);
113 | cy.get('.pdp-time .pdp-moment > div')
114 | .first()
115 | .should('have.attr', 'class')
116 | .and('match', /disabled/);
117 | cy.get('.pdp-time .pdp-moment button').eq(2).click();
118 | cy.get('.pdp-time .pdp-moment > div')
119 | .first()
120 | .should('have.attr', 'class')
121 | .and('match', /disabled/);
122 | cy.get('.pdp-time .pdp-moment button').eq(2).click();
123 | cy.get('.pdp-time .pdp-moment > div')
124 | .first()
125 | .should('have.attr', 'class')
126 | .and('match', /disabled/);
127 | cy.get('.pdp-header .top button').click();
128 | cy.get('button.pdp-year').first().click();
129 | cy.get('li').contains('2020').click();
130 | cy.get('button.pdp-month').first().click();
131 | cy.get('li').contains('September').click();
132 | cy.get('.pdp-arrow').last().click().click().click();
133 | cy.get('.pdp-time .pdp-moment > div')
134 | .first()
135 | .should('have.attr', 'class')
136 | .and('match', /disabled/);
137 | cy.get('.pdp-time .pdp-moment button').eq(3).click();
138 | cy.get('.pdp-time .pdp-moment > div')
139 | .first()
140 | .should('have.attr', 'class')
141 | .and('match', /disabled/);
142 | cy.get('.pdp-time .pdp-moment button').eq(3).click();
143 | cy.get('.pdp-time .pdp-moment > div')
144 | .first()
145 | .should('have.attr', 'class')
146 | .and('match', /disabled/);
147 | });
148 | });
149 |
150 | describe('select single datetime and change locale', () => {
151 | before(() => {
152 | cy.changeProps({ from: '1399', to: '1399/6/31', locale: 'en,fa' });
153 | });
154 |
155 | it('test', () => {
156 | cy.get('.pdp-input').focus();
157 | cy.get('.pdp-day').contains('10').first().click();
158 | cy.get('.pdp-input').focus();
159 | cy.selectTime(15, 52);
160 | cy.get('.pdp-header .top button').click();
161 | cy.get('.pdp-month').should('contain.text', 'شهریور');
162 | cy.get('.start-range').should('contain.text', '20');
163 | cy.get('.pdp-time .pdp-moment > div .hour')
164 | .first()
165 | .should('contain.text', '15');
166 | cy.get('.pdp-time .pdp-moment > div .minute')
167 | .first()
168 | .should('contain.text', '52');
169 | });
170 | });
171 |
172 | describe('select range datetime and change locale', () => {
173 | before(() => {
174 | cy.changeProps({ locale: 'fa,en', mode: 'range', type: 'datetime' });
175 | });
176 |
177 | it('test', () => {
178 | cy.get('.pdp-input').focus();
179 | cy.get('.pdp-day').contains('15').first().click();
180 | cy.get('.pdp-day').contains('20').first().click();
181 | cy.get('.pdp-input').focus();
182 | cy.selectTime(15, 52);
183 | cy.selectTime(20, 48, 'last');
184 | cy.get('.pdp-header .top button').click();
185 | cy.contains('September');
186 | cy.get('.start-range').should('contain.text', '5');
187 | cy.get('.end-range').should('contain.text', '10');
188 | cy.get('.pdp-time .pdp-moment > div .hour')
189 | .first()
190 | .should('contain.text', '15');
191 | cy.get('.pdp-time .pdp-moment > div .minute')
192 | .first()
193 | .should('contain.text', '52');
194 | cy.get('.pdp-time .pdp-moment > div .hour')
195 | .last()
196 | .should('contain.text', '20');
197 | cy.get('.pdp-time .pdp-moment > div .minute')
198 | .last()
199 | .should('contain.text', '48');
200 | });
201 | });
202 |
203 | describe('today button', () => {
204 | before(() => {
205 | cy.changeProps({ from: undefined, to: undefined });
206 | });
207 |
208 | it('test', () => {
209 | cy.selectDate();
210 | const date = new Date(2021, 2, 30, 12);
211 | cy.get('.pdp-input').focus();
212 | cy.get('.pdp-moment > :first-child button:first-child').click({
213 | multiple: true,
214 | });
215 | cy.get('.hour').last().should('contain.text', date.getHours());
216 | cy.get('.minute').last().should('contain.text', date.getMinutes());
217 | cy.get('.pdp-today').click();
218 | cy.get('.pdp-day.today').should('have.class', 'tada');
219 | cy.get('.hour').should('contain.text', date.getHours());
220 | cy.get('.minute').should('contain.text', date.getMinutes());
221 | });
222 | });
223 |
224 | describe('model with value', () => {
225 | context('range mode - datetime type', () => {
226 | before(() => {
227 | cy.changeProps({ model: ['2020-8-31 20:18', '2020-9-10 10:20'] });
228 | });
229 | it('test', () => {
230 | cy.get('.pdp-input')
231 | .should('have.value', '1399/06/10 20:18 - 1399/06/20 10:20')
232 | .focus();
233 | cy.get('.start-range').should('contain.text', '10');
234 | cy.get('.end-range').should('contain.text', '20');
235 | cy.get('.pdp-moment div:first-child .hour').should('contain.text', '20');
236 | cy.get('.pdp-moment div:first-child .minute').should(
237 | 'contain.text',
238 | '18',
239 | );
240 | cy.get('.pdp-moment div:last-child .hour').should('contain.text', '10');
241 | cy.get('.pdp-moment div:last-child .minute').should('contain.text', '20');
242 | });
243 | });
244 |
245 | context('range mode - date type', () => {
246 | before(() => {
247 | cy.changeProps({ type: 'date', model: ['2020-8-31', '2020-9-10'] });
248 | });
249 |
250 | it('test', () => {
251 | cy.get('.pdp-input')
252 | .should('have.value', '1399/06/10 - 1399/06/20')
253 | .focus();
254 | cy.get('.start-range').should('contain.text', '10');
255 | cy.get('.end-range').should('contain.text', '20');
256 | });
257 | });
258 |
259 | context('range mode - time type', () => {
260 | before(() => {
261 | cy.changeProps({ type: 'time', model: ['10:20', '20:18'] });
262 | });
263 |
264 | it('test', () => {
265 | cy.get('.pdp-input').should('have.value', '10:20 - 20:18').focus();
266 | cy.get('.pdp-moment div:first-child .hour').should('contain.text', '10');
267 | cy.get('.pdp-moment div:first-child .minute').should(
268 | 'contain.text',
269 | '20',
270 | );
271 | cy.get('.pdp-moment div:last-child .hour').should('contain.text', '20');
272 | cy.get('.pdp-moment div:last-child .minute').should('contain.text', '18');
273 | });
274 | });
275 |
276 | context('single mode - time type', () => {
277 | before(() => {
278 | cy.changeProps({ mode: 'single', model: '10:20' });
279 | });
280 |
281 | it('test', () => {
282 | cy.get('.pdp-input').should('have.value', '10:20').focus();
283 | cy.get('.pdp-moment div .hour').should('contain.text', '10');
284 | cy.get('.pdp-moment div .minute').should('contain.text', '20');
285 | });
286 | });
287 |
288 | context('single mode - date type', () => {
289 | before(() => {
290 | cy.changeProps({ type: 'date', model: '2020-8-31' });
291 | });
292 |
293 | it('test', () => {
294 | cy.get('.pdp-input').should('have.value', '1399/06/10').focus();
295 | cy.get('.start-range').should('contain.text', '10');
296 | });
297 | });
298 |
299 | context('single mode - datetime type', () => {
300 | before(() => {
301 | cy.changeProps({ type: 'datetime', model: '2020-8-31 20:18' });
302 | });
303 |
304 | it('test', () => {
305 | cy.get('.pdp-input').should('have.value', '1399/06/10 20:18').focus();
306 | cy.get('.start-range').should('contain.text', '10');
307 | cy.get('.pdp-moment div .hour').should('contain.text', '20');
308 | cy.get('.pdp-moment div .minute').should('contain.text', '18');
309 | });
310 | });
311 | });
312 |
313 | describe('show top of input and focus line', () => {
314 | it('test', () => {
315 | cy.get('.pdp').invoke('attr', 'style', 'margin-top:50rem;');
316 | cy.get('.pdp-input').focus();
317 | cy.wait(1).then(() => {
318 | const input = cy.$$('.pdp-input');
319 | const inputTop = input.offset().top;
320 | const pickerTop = cy.$$('.pdp-picker').offset().top;
321 | input.hasClass('pdp-focus');
322 | expect(pickerTop).lt(inputTop);
323 | });
324 | });
325 | });
326 |
--------------------------------------------------------------------------------
/test/e2e/props/all.cy.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
3 | describe('from and to props', () => {
4 | context('time', () => {
5 | before(() => {
6 | cy.changeProps({ from: '10:10', to: '20:20', type: 'time' }, null, true);
7 | cy.changeSlots();
8 | });
9 |
10 | it('with click', () => {
11 | cy.get('.pdp-input')
12 | .focus()
13 | .selectTime(20, 20, 'last')
14 | .selectTime(14, 10);
15 | cy.get('.pdp-input').should('have.value', '14:10 - 20:20');
16 | });
17 |
18 | it('with type', () => {
19 | cy.get('.pdp-input')
20 | .type('8:10{enter}')
21 | .should('have.value', '8:10')
22 | .clear()
23 | .type('10:10{enter}')
24 | .should('have.value', '')
25 | .type('21:20{enter}')
26 | .should('have.value', '21:20')
27 | .clear()
28 | .type('20:20{enter}')
29 | .should('have.value', '10:10 - 20:20');
30 | });
31 | });
32 |
33 | context('datetime', () => {
34 | before(() => {
35 | cy.changeProps({
36 | from: '1399/6/1 10:10',
37 | to: '1399/6/31 20:20',
38 | type: 'datetime',
39 | });
40 | });
41 |
42 | it('with click', () => {
43 | cy.get('.pdp-input').focus();
44 | cy.get('.pdp-day[value="1"]').first().click();
45 | cy.get('.pdp-day[value="31"]').first().click();
46 | cy.get('.pdp-input')
47 | .focus()
48 | .selectTime(20, 20, 'last')
49 | .selectTime(14, 10);
50 | cy.get('.pdp-input').should(
51 | 'have.value',
52 | '1399/06/01 14:10 - 1399/06/31 20:20',
53 | );
54 | });
55 |
56 | it('with type', () => {
57 | cy.get('.pdp-input')
58 | .type('1399/6/1 8:10{enter}')
59 | .should('have.value', '1399/6/1 8:10')
60 | .clear()
61 | .type('1399/6/1 10:10{enter}')
62 | .should('have.value', '')
63 | .type('1399/6/31 21:20{enter}')
64 | .should('have.value', '1399/6/31 21:20')
65 | .clear()
66 | .type('1399/6/31 20:20{enter}')
67 | .should('have.value', '1399/06/01 10:10 - 1399/06/31 20:20');
68 | });
69 | });
70 |
71 | context('date', () => {
72 | before(() => {
73 | cy.changeProps({ from: '1399', to: '1399/6/31', type: 'date' });
74 | });
75 |
76 | it('click on dates', () => {
77 | cy.get('.pdp-input').focus();
78 | for (let i = 1; i <= 30; i++) {
79 | cy.get(`.pdp-days [value="${i}"]`).last().click();
80 | }
81 | cy.get('.pdp-input').should('have.value', '');
82 | });
83 |
84 | it('click on arrows', () => {
85 | cy.get('.pdp-input').focus();
86 | cy.get('.pdp-arrow').last().click();
87 | cy.contains('شهریور');
88 |
89 | cy.get('.pdp-input').focus();
90 | const arrow = cy.get('.pdp-arrow').first();
91 | for (let i = 0; i < 6; i++) {
92 | arrow.click();
93 | }
94 | cy.get('.pdp-month').should('not.have.text', 'اسفند');
95 | });
96 |
97 | it('with arrow keys', () => {
98 | cy.get('.pdp-input')
99 | .type(
100 | '{downarrow}{downarrow}{downarrow}{downarrow}{downarrow}{downarrow}',
101 | )
102 | .type('{leftarrow}{leftarrow}{leftarrow}');
103 | cy.get('.hover').should('contain.text', '31');
104 |
105 | cy.get('.pdp-month').first().click();
106 | cy.contains('فروردین').click();
107 | cy.get('.pdp-input').focus().type('{downarrow}{rightarrow}');
108 | cy.get('.hover').should('contain.text', '1');
109 | });
110 |
111 | it('with type the date', () => {
112 | cy.get('.pdp-input')
113 | .type('1398/12/29{enter}')
114 | .should('have.value', '1398/12/29')
115 | .clear()
116 | .type('1399/7/1{enter}')
117 | .should('have.value', '1399/7/1');
118 | });
119 | });
120 | });
121 |
122 | describe('locale prop', () => {
123 | context('fa and en', () => {
124 | before(() => {
125 | cy.changeProps('locale', 'fa,en');
126 | });
127 |
128 | it('test', () => {
129 | cy.get('.pdp-input').focus();
130 | cy.get('.pdp-header .top div').should('contain.text', 'تقویم شمسی');
131 | cy.get('.pdp-header .top button').click();
132 | cy.get('.pdp-header .top div').should(
133 | 'contain.text',
134 | 'Gregorian Calendar',
135 | );
136 | });
137 | });
138 |
139 | context('en and fa', () => {
140 | before(() => {
141 | cy.changeProps('locale', 'en,fa');
142 | });
143 |
144 | it('test', () => {
145 | cy.get('.pdp-input').focus();
146 | cy.get('.pdp-header .top div').should(
147 | 'contain.text',
148 | 'Gregorian Calendar',
149 | );
150 | cy.get('.pdp-header .top button').click();
151 | cy.get('.pdp-header .top div').should('contain.text', 'تقویم شمسی');
152 | });
153 | });
154 |
155 | context('en', () => {
156 | before(() => {
157 | cy.changeProps('locale', 'en');
158 | });
159 |
160 | it('test', () => {
161 | cy.get('.pdp-input').focus();
162 | cy.contains('September');
163 | });
164 | });
165 |
166 | context('fa', () => {
167 | before(() => {
168 | cy.changeProps('locale', 'fa');
169 | });
170 |
171 | it('test', () => {
172 | cy.get('.pdp-input').focus();
173 | cy.contains('شهریور');
174 | });
175 | });
176 | });
177 |
178 | describe('localeConfig prop', () => {
179 | context('change default properties', () => {
180 | before(() => {
181 | cy.changeProps({
182 | 'locale-config': {
183 | fa: {
184 | inputFormat: 'jMM/jDD',
185 | translations: {
186 | label: 'فارسی',
187 | },
188 | },
189 | en: {
190 | inputFormat: 'YYYY',
191 | translations: {
192 | label: 'انگلیسی',
193 | },
194 | },
195 | },
196 | locale: 'fa,en',
197 | });
198 | });
199 |
200 | it('test', () => {
201 | cy.selectRangeDate();
202 | cy.get('.pdp-input').should('have.value', '06/10 - 06/15').focus();
203 | cy.get('.pdp-header .top div').should('contain.text', 'تقویم شمسی');
204 | cy.get('.pdp-header .top button')
205 | .should('contain.text', 'انگلیسی')
206 | .click();
207 | cy.get('.pdp-input').should('have.value', '2020 - 2020');
208 | cy.get('.pdp-header .top div').should(
209 | 'contain.text',
210 | 'Gregorian Calendar',
211 | );
212 | cy.get('.pdp-header .top button').should('contain.text', 'فارسی');
213 | });
214 | });
215 |
216 | context('add arabic language', () => {
217 | before(() => {
218 | cy.changeProps({
219 | 'locale-config': {
220 | ar: {
221 | calendar: 'gregorian',
222 | weekdays: ['ح ', 'ن ', 'ث ', 'ر ', 'خ ', 'ج ', 'س'],
223 | months: [
224 | 'الفروردین',
225 | 'الاردیبهشت',
226 | 'الخرداد',
227 | 'التیر',
228 | 'المرداد',
229 | 'الشهریور',
230 | 'المهر',
231 | 'الآبان',
232 | 'الآذر',
233 | 'الدی',
234 | 'البهمن',
235 | 'الاسفند',
236 | ],
237 | dir: {
238 | input: 'rtl',
239 | picker: 'ltr',
240 | },
241 | translations: {
242 | label: 'قمری',
243 | text: 'التقویم القمری',
244 | prevMonth: 'الماه قبل',
245 | nextMonth: 'الماه بعد',
246 | today: 'یوم',
247 | submit: 'التایید',
248 | },
249 | inputFormat: {
250 | date: 'date',
251 | datetime: 'datetime',
252 | time: 'time',
253 | },
254 | displayFormat: {
255 | date: '?D ?MMMM',
256 | datetime: '?D ?MMMM HH:mm',
257 | time: 'HH:mm',
258 | },
259 | },
260 | },
261 | locale: 'fa,ar',
262 | });
263 | });
264 |
265 | it('test', () => {
266 | cy.get('.pdp-input').focus();
267 | cy.get('.pdp-header .top button').should('contain.text', 'قمری').click();
268 | cy.get('.pdp-header .top div').should('contain.text', 'التقویم القمری');
269 | cy.get('.pdp-weekday').each((el) => {
270 | ['ح ', 'ن ', 'ث ', 'ر ', 'خ ', 'ج ', 'س'].includes(el.text());
271 | });
272 | cy.get('.pdp-month').first().should('contain.text', 'الآذر');
273 | });
274 | });
275 | });
276 |
277 | describe('formats', () => {
278 | context('with default values', () => {
279 | it('format prop', () => {
280 | cy.selectRangeDate();
281 | cy.get('.show').should(
282 | 'have.text',
283 | 'date/time is: [\n "2020-08-31",\n "2020-09-05"\n]',
284 | );
285 | });
286 |
287 | it('inputFormat prop', () => {
288 | cy.selectRangeDate();
289 | cy.get('.pdp-input').should('have.value', '1399/06/10 - 1399/06/15');
290 | });
291 |
292 | it('displayFormat prop', () => {
293 | cy.selectRangeDate();
294 | cy.get('.pdp-input').focus();
295 | cy.get('.pdp-footer > div').should('have.text', '10 شهریور - 15 شهریور');
296 | });
297 | });
298 |
299 | context('change values', () => {
300 | before(() => {
301 | cy.changeProps({
302 | format: 'YY-M-D',
303 | 'input-format': 'jYY/jM/jD',
304 | 'display-format': 'jD-jMMMM',
305 | });
306 | });
307 |
308 | it('change format prop', () => {
309 | cy.selectRangeDate();
310 | cy.get('.show').should(
311 | 'have.text',
312 | 'date/time is: [\n "20-8-31",\n "20-9-5"\n]',
313 | );
314 | });
315 |
316 | it('change inputFormat prop', () => {
317 | cy.selectRangeDate();
318 | cy.get('.pdp-input').should('have.value', '99/6/10 - 99/6/15');
319 | });
320 |
321 | it('change displayFormat prop', () => {
322 | cy.selectRangeDate();
323 | cy.get('.pdp-input').focus();
324 | cy.get('.pdp-footer > div').should('have.text', '10-شهریور - 15-شهریور');
325 | });
326 | });
327 | });
328 |
329 | describe('type prop', () => {
330 | context('datetime', () => {
331 | before(() => {
332 | cy.changeProps('type', 'datetime');
333 | });
334 |
335 | it('test', () => {
336 | cy.get('.pdp-input').focus();
337 | cy.get('.pdp-date').should('exist');
338 | cy.get('.pdp-time').should('exist');
339 | });
340 | });
341 | context('time', () => {
342 | before(() => {
343 | cy.changeProps({ from: undefined, to: undefined, type: 'time' });
344 | });
345 |
346 | it('test', () => {
347 | cy.get('.pdp-input').focus();
348 | cy.get('.pdp-date').should('not.exist');
349 | cy.get('.pdp-time').should('exist');
350 | });
351 | });
352 | context('date', () => {
353 | before(() => {
354 | cy.changeProps({ from: '1399', to: '1399/6/31', type: 'date' });
355 | });
356 |
357 | it('test', () => {
358 | cy.get('.pdp-input').focus();
359 | cy.get('.pdp-date').should('exist');
360 | cy.get('.pdp-time').should('not.exist');
361 | });
362 | });
363 | });
364 |
365 | describe('show prop', () => {
366 | before(() => {
367 | cy.changeProps('show', false);
368 | });
369 |
370 | it('show prop', () => {
371 | cy.get('.pdp-picker').should('not.exist');
372 | cy.get('.show-picker').click();
373 | cy.get('.pdp-picker').should('exist');
374 | cy.get('.pdp-overlay').click({ force: true });
375 | cy.get('.pdp-picker').should('not.exist');
376 | });
377 |
378 | after(() => {
379 | cy.changeProps('show', false);
380 | });
381 | });
382 |
383 | describe('label prop', () => {
384 | context('label not exist', () => {
385 | it('test', () => {
386 | cy.get('.pdp-label').should('not.exist');
387 | });
388 | });
389 |
390 | context('label exist', () => {
391 | before(() => {
392 | cy.changeProps('label', 'select date:');
393 | });
394 |
395 | it('test', () => {
396 | cy.get('.pdp-label')
397 | .should('exist')
398 | .should('contain.text', 'select date:');
399 | });
400 | });
401 | });
402 |
403 | describe('clickOn prop', () => {
404 | context('with none value', () => {
405 | before(() => {
406 | cy.changeProps('click-on', 'none');
407 | });
408 |
409 | it('test', () => {
410 | cy.get('.pdp-picker').should('not.exist');
411 | cy.get('.pdp-input').focus();
412 | cy.get('.pdp-picker').should('not.exist');
413 |
414 | cy.get('.pdp-input').click();
415 | cy.get('.pdp-picker').should('not.exist');
416 |
417 | cy.get('.pdp-icon').click();
418 | cy.get('.pdp-picker').should('not.exist');
419 | });
420 | });
421 |
422 | context('with icon value', () => {
423 | before(() => {
424 | cy.changeProps('click-on', 'icon');
425 | });
426 |
427 | it('test', () => {
428 | cy.get('.pdp-picker').should('not.exist');
429 | cy.get('.pdp-input').focus();
430 | cy.get('.pdp-picker').should('not.exist');
431 |
432 | cy.get('.pdp-input').click();
433 | cy.get('.pdp-picker').should('not.exist');
434 |
435 | cy.get('.pdp-icon').click();
436 | cy.get('.pdp-picker').should('exist');
437 | cy.get('.pdp-overlay').click({ force: true });
438 | cy.get('.pdp-picker').should('not.exist');
439 | });
440 | });
441 |
442 | context('with input value', () => {
443 | before(() => {
444 | cy.changeProps('click-on', 'input');
445 | });
446 |
447 | it('test', () => {
448 | cy.get('.pdp-picker').should('not.exist');
449 | cy.get('.pdp-input').focus();
450 | cy.get('.pdp-picker').should('exist');
451 | cy.get('.pdp-overlay').click({ force: true });
452 | cy.get('.pdp-picker').should('not.exist');
453 |
454 | cy.get('.pdp-input').click();
455 | cy.get('.pdp-picker').should('exist');
456 | cy.get('.pdp-overlay').click({ force: true });
457 | cy.get('.pdp-picker').should('not.exist');
458 |
459 | cy.get('.pdp-icon').click();
460 | cy.get('.pdp-picker').should('not.exist');
461 | });
462 | });
463 |
464 | context('with all value', () => {
465 | before(() => {
466 | cy.changeProps('click-on', 'all');
467 | });
468 |
469 | it('test', () => {
470 | cy.get('.pdp-picker').should('not.exist');
471 | cy.get('.pdp-input').focus();
472 | cy.get('.pdp-picker').should('exist');
473 | cy.get('.pdp-overlay').click({ force: true });
474 | cy.get('.pdp-picker').should('not.exist');
475 |
476 | cy.get('.pdp-input').click();
477 | cy.get('.pdp-picker').should('exist');
478 | cy.get('.pdp-overlay').click({ force: true });
479 | cy.get('.pdp-picker').should('not.exist');
480 |
481 | cy.get('.pdp-icon').click();
482 | cy.get('.pdp-picker').should('exist');
483 | cy.get('.pdp-overlay').click({ force: true });
484 | cy.get('.pdp-picker').should('not.exist');
485 | });
486 | });
487 | });
488 |
489 | describe('icon', () => {
490 | before(() => {
491 | cy.changeProps('icon-inside', true);
492 | });
493 |
494 | it('iconInside prop', () => {
495 | cy.get('.pdp-icon')
496 | .should('have.attr', 'class')
497 | .and('match', /pdp-inside/);
498 | });
499 | });
500 |
501 | describe('div class attribute', () => {
502 | context('remove class', () => {
503 | before(() => {
504 | cy.changeProps('div-class', '');
505 | });
506 |
507 | it('test', () => {
508 | cy.get('.pdp-group').should('not.exist');
509 | });
510 | });
511 |
512 | context('replace class', () => {
513 | before(() => {
514 | cy.changeProps('div-class', 'replace-class');
515 | });
516 |
517 | it('test', () => {
518 | cy.get('.replace-class').should('exist');
519 | });
520 | });
521 |
522 | context('add class', () => {
523 | before(() => {
524 | cy.changeProps('div-class', 'pdp-group add-class');
525 | });
526 |
527 | it('test', () => {
528 | cy.get('.pdp-group').should('have.class', 'add-class');
529 | });
530 | });
531 | });
532 |
533 | describe('input class attribute', () => {
534 | context('remove class', () => {
535 | before(() => {
536 | cy.changeProps('firstInput-class', '');
537 | });
538 |
539 | it('test', () => {
540 | cy.get('.pdp-input').should('not.exist');
541 | });
542 | });
543 |
544 | context('replace class', () => {
545 | before(() => {
546 | cy.changeProps('firstInput-class', 'replace-class');
547 | });
548 |
549 | it('test', () => {
550 | cy.get('.replace-class').should('exist');
551 | });
552 | });
553 |
554 | context('add class', () => {
555 | before(() => {
556 | cy.changeProps('firstInput-class', 'pdp-input add-class');
557 | });
558 |
559 | it('test', () => {
560 | cy.get('.pdp-input').should('have.class', 'add-class');
561 | });
562 | });
563 | });
564 |
565 | describe('column prop', () => {
566 | const types = ['date', 'time', 'datetime'];
567 | const sizes = ['iphone-4', 'ipad-2', 'macbook-15'];
568 |
569 | before(() => {
570 | cy.changeProps({ from: undefined, to: undefined });
571 | });
572 |
573 | types.forEach((type) => {
574 | context(type + ' type', () => {
575 | Cypress._.times(3, (i) => {
576 | i = +i + 1;
577 | context('number value => ' + i, () => {
578 | before(() => {
579 | cy.changeProps({ column: i, type });
580 | });
581 |
582 | it('test', () => {
583 | cy.get('.pdp-input').focus();
584 | if (type === 'time')
585 | cy.get('.pdp-column div').should('have.length', i);
586 | else cy.get('.pdp-column').should('have.length', i);
587 | });
588 | });
589 | });
590 |
591 | context('object value', () => {
592 | before(() => {
593 | cy.changeProps('column', { '576': 1, '992': 2, '2000': 3 });
594 | });
595 |
596 | it('test', () => {
597 | sizes.forEach((size, index) => {
598 | cy.viewport(size as Cypress.ViewportPreset);
599 | cy.get('.pdp-input').focus();
600 | if (type === 'time')
601 | cy.get('.pdp-column div').should('have.length', index + 1);
602 | else cy.get('.pdp-column').should('have.length', index + 1);
603 | });
604 | });
605 | });
606 | });
607 | });
608 | });
609 |
610 | describe('alternative field', () => {
611 | context('not exist', () => {
612 | it('test', () => {
613 | cy.get('input[type="hidden"]').should('not.exist');
614 | });
615 | });
616 |
617 | context('exist - String', () => {
618 | before(() => {
619 | cy.changeProps('alt-name', 'date');
620 | });
621 |
622 | it('test', () => {
623 | cy.get('input[type="hidden"]').should('exist');
624 | cy.selectRangeDate();
625 | cy.get('input[type="hidden"]').should('have.value', '21-3-30,21-4-4');
626 | });
627 | });
628 |
629 | context('exist - Array', () => {
630 | before(() => {
631 | cy.changeProps('alt-name', 'date[]');
632 | });
633 |
634 | it('test', () => {
635 | cy.selectRangeDate();
636 | cy.get('input[type="hidden"]').first().should('have.value', '21-3-30');
637 | cy.get('input[type="hidden"]').last().should('have.value', '21-4-4');
638 | });
639 | });
640 |
641 | context('without alt-format', () => {
642 | before(() => {
643 | cy.changeProps('format', 'YYYY MM');
644 | });
645 |
646 | it('test', () => {
647 | cy.selectRangeDate();
648 | cy.get('input[type="hidden"]').first().should('have.value', '2021 03');
649 | cy.get('input[type="hidden"]').last().should('have.value', '2021 04');
650 | });
651 | });
652 |
653 | context('with alt-format', () => {
654 | before(() => {
655 | cy.changeProps('alt-format', 'MM YYYY DD');
656 | });
657 |
658 | it('test', () => {
659 | cy.selectRangeDate();
660 | cy.get('input[type="hidden"]').first().should('have.value', '03 2021 30');
661 | cy.get('input[type="hidden"]').last().should('have.value', '04 2021 04');
662 | });
663 | });
664 | });
665 |
666 | describe('disable prop', () => {
667 | context('String in time type', () => {
668 | before(() => {
669 | cy.changeProps({
670 | from: undefined,
671 | to: undefined,
672 | type: 'time',
673 | disable: '15:52',
674 | });
675 | });
676 |
677 | it('test', () => {
678 | cy.get('.pdp-input').focus();
679 | cy.selectTime(15, 52);
680 | cy.get('.pdp-time .pdp-moment > div')
681 | .first()
682 | .should('have.attr', 'class')
683 | .and('match', /disabled/);
684 | });
685 | });
686 |
687 | context('RegExp in time type', () => {
688 | before(() => {
689 | cy.changeProps('disableR', '15:*');
690 | });
691 |
692 | it('test', () => {
693 | cy.get('.pdp-input').focus();
694 | cy.selectTime(15, 0);
695 | cy.get('.pdp-time .pdp-moment > div')
696 | .first()
697 | .should('have.attr', 'class')
698 | .and('match', /disabled/);
699 | cy.get('.pdp-time .pdp-moment button').eq(3).as('momentButtonThree');
700 | cy.get('.pdp-time .pdp-moment > div').first().as('momentFirstDiv');
701 | for (let i = 1; i <= 59; i++) {
702 | cy.get('@momentButtonThree').click();
703 | cy.get('@momentFirstDiv')
704 | .should('have.attr', 'class')
705 | .and('match', /disabled/);
706 | }
707 | });
708 | });
709 |
710 | context('Array in time type', () => {
711 | before(() => {
712 | cy.changeProps({
713 | disableR: undefined,
714 | disable: ['15:52', '15:53', '15:54'],
715 | });
716 | });
717 |
718 | it('test', () => {
719 | cy.get('.pdp-input').focus();
720 | cy.selectTime(15, 52);
721 | cy.get('.pdp-time .pdp-moment > div')
722 | .first()
723 | .should('have.attr', 'class')
724 | .and('match', /disabled/);
725 | cy.get('.pdp-time .pdp-moment button').eq(2).click();
726 | cy.get('.pdp-time .pdp-moment > div')
727 | .first()
728 | .should('have.attr', 'class')
729 | .and('match', /disabled/);
730 | cy.get('.pdp-time .pdp-moment button').eq(2).click();
731 | cy.get('.pdp-time .pdp-moment > div')
732 | .first()
733 | .should('have.attr', 'class')
734 | .and('match', /disabled/);
735 | });
736 | });
737 |
738 | context('Function in time type', () => {
739 | before(() => {
740 | cy.changeProps('disableF', '(date)=>date.hour()==15');
741 | });
742 |
743 | it('test', () => {
744 | cy.get('.pdp-input').focus();
745 | cy.selectTime(15, 0);
746 | cy.get('.pdp-time .pdp-moment > div')
747 | .first()
748 | .should('have.attr', 'class')
749 | .and('match', /disabled/);
750 | cy.get('.pdp-time .pdp-moment button').eq(3).as('momentButtonThree');
751 | cy.get('.pdp-time .pdp-moment > div').first().as('momentFirstDiv');
752 | for (let i = 1; i <= 59; i++) {
753 | cy.get('@momentButtonThree').click();
754 | cy.get('@momentFirstDiv')
755 | .should('have.attr', 'class')
756 | .and('match', /disabled/);
757 | }
758 | });
759 | });
760 |
761 | context('String in datetime type', () => {
762 | before(() => {
763 | cy.changeProps({
764 | from: '1399',
765 | to: '1399/6/31',
766 | type: 'datetime',
767 | disableF: undefined,
768 | disable: '1399/6/15 15:52',
769 | });
770 | });
771 |
772 | it('test', () => {
773 | cy.get('.pdp-input').focus();
774 | cy.get('.pdp-day[value="15"]').first().click();
775 | cy.selectTime(15, 52);
776 | cy.get('.pdp-time .pdp-moment > div')
777 | .first()
778 | .should('have.attr', 'class')
779 | .and('match', /disabled/);
780 | });
781 | });
782 |
783 | context('RegExp in datetime type', () => {
784 | before(() => {
785 | cy.changeProps('disableR', '1399/5/2 15:*');
786 | });
787 |
788 | it('test', () => {
789 | cy.get('.pdp-input').focus();
790 | cy.get('.pdp-arrow').first().click();
791 | cy.get('.pdp-day[value="2"]').first().click();
792 | cy.selectTime(15, 0);
793 | cy.get('.pdp-time .pdp-moment > div')
794 | .first()
795 | .should('have.attr', 'class')
796 | .and('match', /disabled/);
797 | cy.get('.pdp-time .pdp-moment > div').first().as('momentFirstDiv');
798 | for (let i = 1; i <= 59; i++) {
799 | cy.get('@momentFirstDiv')
800 | .should('have.attr', 'class')
801 | .and('match', /disabled/);
802 | }
803 | });
804 | });
805 |
806 | context('Array in datetime type', () => {
807 | before(() => {
808 | cy.changeProps({
809 | disableR: undefined,
810 | disable: [
811 | '1399/6/10 15:52',
812 | '1399/6/10 15:53',
813 | '1399/6/10 15:54',
814 | '1399/6/11',
815 | ],
816 | });
817 | });
818 |
819 | it('test', () => {
820 | cy.get('.pdp-input').focus();
821 | cy.get('[data-column="0"] .pdp-day[value="11"]')
822 | .should('have.attr', 'class')
823 | .and('match', /disabled/);
824 | cy.get('[data-column="0"] .pdp-day[value="10"]').click();
825 | cy.selectTime(15, 52);
826 | cy.get('.pdp-time .pdp-moment > div')
827 | .first()
828 | .should('have.attr', 'class')
829 | .and('match', /disabled/);
830 | cy.get('.pdp-time .pdp-moment button').eq(2).click();
831 | cy.get('.pdp-time .pdp-moment > div')
832 | .first()
833 | .should('have.attr', 'class')
834 | .and('match', /disabled/);
835 | cy.get('.pdp-time .pdp-moment button').eq(2).click();
836 | cy.get('.pdp-time .pdp-moment > div')
837 | .first()
838 | .should('have.attr', 'class')
839 | .and('match', /disabled/);
840 | });
841 | });
842 |
843 | context('Function in datetime type', () => {
844 | before(() => {
845 | cy.changeProps('disableF', '(date)=>date.hour()==15');
846 | });
847 |
848 | it('test', () => {
849 | cy.get('.pdp-input').focus();
850 | cy.get('[data-column="0"] .pdp-day[value="10"]').click();
851 | cy.selectTime(15, 0);
852 | cy.get('.pdp-time .pdp-moment > div')
853 | .first()
854 | .should('have.attr', 'class')
855 | .and('match', /disabled/);
856 | cy.get('.pdp-time .pdp-moment button').eq(3).as('momentButtonThree');
857 | cy.get('.pdp-time .pdp-moment > div').first().as('momentFirstDiv');
858 | for (let i = 1; i <= 59; i++) {
859 | cy.get('@momentButtonThree').click();
860 | cy.get('@momentFirstDiv')
861 | .should('have.attr', 'class')
862 | .and('match', /disabled/);
863 | }
864 | });
865 | });
866 |
867 | context('String in date type', () => {
868 | before(() => {
869 | cy.changeProps({
870 | type: 'date',
871 | disableF: undefined,
872 | disable: '1399/6/15',
873 | });
874 | });
875 |
876 | it('test', () => {
877 | cy.get('.pdp-input').focus();
878 | cy.get('.pdp-day[value="15"]').should(
879 | 'have.attr',
880 | 'class',
881 | 'pdp-day disabled',
882 | );
883 | });
884 | });
885 |
886 | context('RegExp in date type', () => {
887 | before(() => {
888 | cy.changeProps('disableR', '1399/5/*/');
889 | });
890 |
891 | it('test', () => {
892 | cy.get('.pdp-input').focus();
893 | cy.get('.pdp-arrow').first().click();
894 | for (let i = 1; i <= 31; i++) {
895 | cy.get(`[data-column="0"] .pdp-day[value="${i}"]`)
896 | .should('have.attr', 'class')
897 | .and('match', /disabled/);
898 | }
899 | });
900 | });
901 |
902 | context('Array in date type', () => {
903 | before(() => {
904 | cy.changeProps({
905 | disableR: undefined,
906 | disable: ['1399/6/10', '1399/6/15', '1399/6/20'],
907 | });
908 | });
909 |
910 | it('test', () => {
911 | cy.get('.pdp-input').focus();
912 | cy.get('[data-column="0"] .pdp-day[value="10"]')
913 | .should('have.attr', 'class')
914 | .and('match', /disabled/);
915 | cy.get('[data-column="0"] .pdp-day[value="15"]')
916 | .should('have.attr', 'class')
917 | .and('match', /disabled/);
918 | cy.get('[data-column="0"] .pdp-day[value="20"]')
919 | .should('have.attr', 'class')
920 | .and('match', /disabled/);
921 | });
922 | });
923 |
924 | context('Function in date type', () => {
925 | before(() => {
926 | cy.changeProps('disableF', '(date)=>date.date()==5');
927 | });
928 |
929 | it('test', () => {
930 | cy.get('.pdp-input').focus();
931 | cy.get('[data-column="0"] .pdp-day[value="5"]').as('fifthDay');
932 | cy.get('.pdp-arrow').first().as('firstArrow');
933 | for (let i = 0; i < 5; i++) {
934 | cy.get('@fifthDay')
935 | .should('have.attr', 'class')
936 | .and('match', /disabled/);
937 | cy.get('@firstArrow').click();
938 | }
939 | });
940 | });
941 | });
942 |
943 | describe('mode prop', () => {
944 | context('single in date type', () => {
945 | before(() => {
946 | cy.changeProps('mode', 'single');
947 | });
948 |
949 | it('test', () => {
950 | cy.selectDate();
951 | cy.get('.pdp-input').should('have.value', '99/6/10');
952 | });
953 | });
954 |
955 | context('single in time type', () => {
956 | before(() => {
957 | cy.changeProps({
958 | from: undefined,
959 | to: undefined,
960 | 'input-format': undefined,
961 | type: 'time',
962 | });
963 | });
964 |
965 | it('test', () => {
966 | cy.get('.pdp-input').focus();
967 | cy.selectTime(15, 52);
968 | cy.get('.pdp-input').should('have.value', '15:52');
969 | });
970 | });
971 |
972 | context('range in time type', () => {
973 | before(() => {
974 | cy.changeProps('mode', 'range');
975 | });
976 |
977 | it('test', () => {
978 | cy.get('.pdp-input').focus();
979 | cy.selectTime(6, 52);
980 | cy.selectTime(20, 48, 'last');
981 | cy.get('.pdp-input').should('have.value', '06:52 - 20:48');
982 | });
983 | });
984 |
985 | context('range in date type', () => {
986 | before(() => {
987 | cy.changeProps({
988 | from: '1399',
989 | to: '1399/6/31',
990 | 'input-format': 'jYY/jM/jD',
991 | type: 'date',
992 | });
993 | });
994 |
995 | it('test', () => {
996 | cy.selectRangeDate();
997 | cy.get('.pdp-input').should('have.value', '99/6/10 - 99/6/15');
998 | });
999 | });
1000 | });
1001 |
1002 | describe('clearable prop', () => {
1003 | context('without clearable', () => {
1004 | it('test', () => {
1005 | cy.get('.pdp-input').focus();
1006 | cy.get('.pdp-clear').should('not.exist');
1007 | });
1008 | });
1009 | context('with clearable', () => {
1010 | before(() => {
1011 | cy.changeProps({ clearable: true, mode: 'single' });
1012 | });
1013 |
1014 | it('test', () => {
1015 | cy.selectDate();
1016 | cy.get('.pdp-input').should('have.value', '99/6/10');
1017 | cy.get('.pdp-clear').click();
1018 | cy.get('.pdp-input').should('not.have.value');
1019 | cy.changeProps('mode', 'range');
1020 | cy.get('.pdp-input').focus();
1021 | cy.get('.pdp-clear').should('exist');
1022 | cy.selectRangeDate();
1023 | cy.get('.pdp-input').should('have.value', '99/6/10 - 99/6/15');
1024 | cy.get('.pdp-clear').click();
1025 | cy.get('.pdp-input').should('not.have.value');
1026 | });
1027 | });
1028 | });
1029 |
1030 | describe('autoSubmit prop', () => {
1031 | context('true value in date type', () => {
1032 | before(() => {
1033 | cy.changeProps('auto-submit', true);
1034 | });
1035 |
1036 | it('test', () => {
1037 | cy.selectRangeDate();
1038 | cy.get('.pdp-picker').should('not.exist');
1039 | });
1040 | });
1041 |
1042 | context('true value in time type', () => {
1043 | before(() => {
1044 | cy.changeProps({
1045 | from: undefined,
1046 | to: undefined,
1047 | type: 'time',
1048 | format: undefined,
1049 | });
1050 | });
1051 |
1052 | it('test', () => {
1053 | cy.get('.pdp-input').focus();
1054 | cy.selectTime(15, 52);
1055 | cy.get('.status').should('contain.text', '15:52');
1056 | });
1057 | });
1058 |
1059 | context('false value in time type', () => {
1060 | before(() => {
1061 | cy.changeProps('auto-submit', false);
1062 | });
1063 |
1064 | it('test', () => {
1065 | cy.get('.pdp-input').focus();
1066 | cy.selectTime(6, 52);
1067 | cy.selectTime(20, 48, 'last');
1068 | cy.get('.pdp-submit').click();
1069 | cy.get('.pdp-picker').should('not.exist');
1070 | cy.get('.status').should('contain.text', '06:52,20:48');
1071 | });
1072 | });
1073 |
1074 | context('false value in date type', () => {
1075 | before(() => {
1076 | cy.changeProps({ type: 'date', format: 'YY-M-D' });
1077 | });
1078 |
1079 | it('test', () => {
1080 | cy.selectRangeDate();
1081 | cy.get('.pdp-picker').should('exist');
1082 | cy.get('.pdp-submit').click();
1083 | cy.get('.pdp-picker').should('not.exist');
1084 | });
1085 | });
1086 | });
1087 |
1088 | describe('change styles', () => {
1089 | context('with styles prop', () => {
1090 | before(() => {
1091 | cy.changeProps('styles', {
1092 | 'primary-color': 'red',
1093 | 'secondary-color': 'blue',
1094 | });
1095 | });
1096 |
1097 | it('test', () => {
1098 | cy.get('.pdp-input').focus();
1099 | cy.get('.pdp-submit').should(
1100 | 'have.css',
1101 | 'background-color',
1102 | 'rgb(255, 0, 0)',
1103 | );
1104 | });
1105 | });
1106 |
1107 | context('with color prop', () => {
1108 | before(() => {
1109 | cy.changeProps({ styles: undefined, color: 'red' });
1110 | });
1111 |
1112 | it('test', () => {
1113 | cy.get('.pdp-input').focus();
1114 | cy.get('.pdp-submit').should(
1115 | 'have.css',
1116 | 'background-color',
1117 | 'rgb(199, 0, 76)',
1118 | );
1119 | });
1120 | });
1121 | });
1122 |
1123 | describe('modal prop', () => {
1124 | before(() => {
1125 | cy.changeProps('modal', true);
1126 | });
1127 |
1128 | it('modal mode', () => {
1129 | cy.get('.pdp-input').focus();
1130 | cy.get('.pdp-modal').should('be.visible');
1131 | });
1132 | });
1133 |
1134 | describe('attributes', () => {
1135 | before(() => {
1136 | cy.changeProps({
1137 | required: true,
1138 | placeholder: 'تاریخ تولد',
1139 | readonly: true,
1140 | disabled: true,
1141 | id: 'input',
1142 | 'label-id': 'label',
1143 | 'div-id': 'div',
1144 | 'picker-id': 'picker',
1145 | });
1146 | });
1147 |
1148 | it('check attributes', () => {
1149 | cy.get('.pdp-icon').click();
1150 | cy.get('.pdp-input').should('have.attr', 'required');
1151 | cy.get('.pdp-input').should('have.attr', 'readonly');
1152 | cy.get('.pdp-input').should('have.attr', 'disabled');
1153 | cy.get('.pdp-input').should('have.attr', 'placeholder', 'تاریخ تولد');
1154 | cy.get('.pdp-input').should('have.attr', 'id', 'input');
1155 | cy.get('.pdp-label').should('have.attr', 'id', 'label');
1156 | cy.get('.pdp-group').should('have.attr', 'id', 'div');
1157 | cy.get('.pdp-picker').should('have.attr', 'id', 'picker');
1158 | });
1159 | });
1160 |
--------------------------------------------------------------------------------
/test/e2e/props/dual-input.cy.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
3 | describe('time type', () => {
4 | before(() => {
5 | cy.changeProps({ type: 'time', 'dual-input': true }, null, true);
6 | cy.changeSlots();
7 | });
8 |
9 | it('select second input', () => {
10 | cy.get('.pdp')
11 | .should('have.attr', 'class')
12 | .and('match', /pdp-dual/);
13 | cy.get('.pdp-input')
14 | .last()
15 | .focus()
16 | .should('have.attr', 'class')
17 | .and('match', /pdp-focus/);
18 | cy.get('.status').should('contain.text', 'focus:2');
19 | cy.selectTime(20, 48, 'last');
20 | cy.selectTime(15, 52);
21 | cy.get('.pdp-input').last().should('have.value', '20:48');
22 | cy.get('.pdp-input').first().should('have.value', '15:52');
23 | });
24 | });
25 |
26 | describe('datetime type', () => {
27 | before(() => {
28 | cy.changeProps({ type: 'datetime', from: '1399', to: '1399/06/31' });
29 | });
30 |
31 | context('select second input', () => {
32 | it('test', () => {
33 | cy.get('.pdp')
34 | .should('have.attr', 'class')
35 | .and('match', /pdp-dual/);
36 | cy.get('.pdp-input')
37 | .last()
38 | .focus()
39 | .should('have.attr', 'class')
40 | .and('match', /pdp-focus/);
41 | cy.get('.status').should('contain.text', 'focus:2');
42 | cy.get('.pdp-day').contains('20').click();
43 | cy.selectTime(20, 48, 'last');
44 | cy.get('.pdp-day').contains('10').click();
45 | cy.get('.pdp-input')
46 | .first()
47 | .focus()
48 | .should('have.attr', 'class')
49 | .and('match', /pdp-focus/);
50 | cy.get('.status').should('contain.text', 'focus:1');
51 | cy.selectTime(15, 52);
52 | cy.get('.pdp-input').last().should('have.value', '1399/06/20 20:48');
53 | cy.get('.pdp-input').first().should('have.value', '1399/06/10 15:52');
54 | });
55 | });
56 |
57 | context('"en" locale', () => {
58 | before(() => {
59 | cy.changeProps({ locale: 'en' });
60 | });
61 | it('test', () => {
62 | cy.get('.pdp')
63 | .should('have.attr', 'class')
64 | .and('match', /pdp-dual/);
65 | cy.get('.pdp-input')
66 | .first()
67 | .focus()
68 | .should('have.attr', 'class')
69 | .and('match', /pdp-focus/);
70 | cy.get('.pdp-day').contains('10').click();
71 | cy.selectTime(15, 52);
72 | cy.get('.pdp-input')
73 | .last()
74 | .should('have.attr', 'class')
75 | .and('match', /pdp-focus/);
76 | cy.get('.pdp-day').contains('20').click();
77 | cy.get('.pdp-input').last().focus();
78 | cy.selectTime(20, 48, 'last');
79 | cy.get('.pdp-input').first().should('have.value', '2020-09-10 15:52');
80 | cy.get('.pdp-input').last().should('have.value', '2020-09-20 20:48');
81 | });
82 | });
83 | });
84 |
85 | describe('date type', () => {
86 | before(() => {
87 | cy.changeProps({ type: 'date', clearable: true });
88 | });
89 |
90 | context('"en" locale', () => {
91 | it('test', () => {
92 | cy.get('.pdp')
93 | .should('have.attr', 'class')
94 | .and('match', /pdp-dual/);
95 | cy.get('.pdp-input')
96 | .first()
97 | .focus()
98 | .should('have.attr', 'class')
99 | .and('match', /pdp-focus/);
100 | cy.get('.pdp-day').contains('10').click();
101 | cy.get('.pdp-input')
102 | .last()
103 | .should('have.attr', 'class')
104 | .and('match', /pdp-focus/);
105 | cy.get('.pdp-day').contains('20').click();
106 | cy.get('.pdp-input').first().should('have.value', '2020-09-10');
107 | cy.get('.pdp-input').last().should('have.value', '2020-09-20');
108 | });
109 | });
110 |
111 | context('select second input', () => {
112 | before(() => {
113 | cy.changeProps('locale', 'fa');
114 | });
115 |
116 | it('test', () => {
117 | cy.get('.pdp')
118 | .should('have.attr', 'class')
119 | .and('match', /pdp-dual/);
120 | cy.get('.pdp-input')
121 | .last()
122 | .focus()
123 | .should('have.attr', 'class')
124 | .and('match', /pdp-focus/);
125 | cy.get('.status').should('contain.text', 'focus:2');
126 | cy.get('.pdp-day').contains('20').click();
127 | cy.get('.pdp-day').contains('10').click();
128 | cy.get('.pdp-input').last().should('have.value', '1399/06/20');
129 | cy.get('.pdp-input').first().should('have.value', '1399/06/10');
130 | });
131 | });
132 |
133 | context('clearable', () => {
134 | it('test', () => {
135 | cy.get('.pdp-input').first().focus();
136 | cy.get('.pdp-day').contains('10').click();
137 | cy.get('.pdp-day').contains('20').click();
138 | cy.get('.pdp-input').first().should('have.value', '1399/06/10');
139 | cy.get('.pdp-input').last().should('have.value', '1399/06/20');
140 | cy.get('.pdp-clear').first().click();
141 | cy.get('.pdp-input').first().should('have.value', '');
142 | cy.get('.pdp-input').last().should('have.value', '1399/06/20');
143 | cy.get('.pdp-clear').last().click();
144 | cy.get('.pdp-input').last().should('have.value', '');
145 | cy.get('.pdp-input').first().focus();
146 | cy.get('.pdp-day').contains('10').click();
147 | cy.get('.pdp-day').contains('20').click();
148 | cy.get('.pdp-input').first().should('have.value', '1399/06/10');
149 | cy.get('.pdp-input').last().should('have.value', '1399/06/20');
150 | cy.get('.pdp-clear').last().click();
151 | cy.get('.pdp-input').first().should('have.value', '1399/06/10');
152 | cy.get('.pdp-input').last().should('have.value', '');
153 | });
154 | });
155 | });
156 |
157 | describe('attributes', () => {
158 | before(() => {
159 | cy.changeProps({
160 | placeholder: 'first',
161 | 'secondInput-placeholder': 'second',
162 | mode: 'single',
163 | });
164 | });
165 |
166 | it('select second input', () => {
167 | cy.get('.pdp')
168 | .should('have.attr', 'class')
169 | .and('match', /pdp-dual/);
170 | cy.get('.pdp-input').first().should('have.attr', 'placeholder', 'first');
171 | cy.get('.pdp-input')
172 | .last()
173 | .should('have.attr', 'placeholder', 'second')
174 | .should('have.attr', 'disabled');
175 | });
176 | });
177 |
--------------------------------------------------------------------------------
/test/e2e/props/shortcut.cy.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
3 | import PersianDate from '@alireza-ab/persian-date';
4 |
5 | const date = new PersianDate([2021, 3, 30, 12]);
6 |
7 | before(() => {
8 | cy.changeProps('shortcut', true, true);
9 | cy.changeSlots();
10 | });
11 |
12 | context('date', () => {
13 | describe('range (fa)', () => {
14 | it('test', () => {
15 | cy.get('.pdp-input').focus();
16 | cy.get('.pdp-shortcut')
17 | .should('exist')
18 | .contains('این هفته')
19 | .should('exist')
20 | .get('.pdp-shortcut')
21 | .contains('هفته قبل')
22 | .should('exist')
23 | .get('.pdp-shortcut')
24 | .contains('هفته بعد')
25 | .should('exist')
26 | .get('.pdp-shortcut')
27 | .contains('ماه قبل')
28 | .should('exist')
29 | .get('.pdp-shortcut')
30 | .contains('ماه بعد')
31 | .should('exist')
32 | .get('.pdp-shortcut')
33 | .contains('این ماه')
34 | .should('exist')
35 | .click();
36 | cy.get('.pdp-input').should(
37 | 'have.value',
38 | `${date.clone().startOf('month').toString()} - ${date
39 | .clone()
40 | .endOf('month')
41 | .toString()}`,
42 | );
43 | });
44 | });
45 |
46 | describe('range (en)', () => {
47 | before(() => {
48 | cy.changeProps('locale', 'en');
49 | });
50 | it('test', () => {
51 | cy.get('.pdp-input').focus();
52 | cy.get('.pdp-shortcut')
53 | .should('exist')
54 | .contains('This Week')
55 | .should('exist')
56 | .get('.pdp-shortcut')
57 | .contains('Previous Week')
58 | .should('exist')
59 | .get('.pdp-shortcut')
60 | .contains('Next Week')
61 | .should('exist')
62 | .get('.pdp-shortcut')
63 | .contains('Previous Month')
64 | .should('exist')
65 | .get('.pdp-shortcut')
66 | .contains('Next Month')
67 | .should('exist')
68 | .get('.pdp-shortcut')
69 | .contains('This Month')
70 | .should('exist')
71 | .click();
72 | cy.get('.pdp-input').should(
73 | 'have.value',
74 | `${date
75 | .clone()
76 | .calendar('gregorian')
77 | .startOf('month')
78 | .toString()} - ${date
79 | .clone()
80 | .calendar('gregorian')
81 | .endOf('month')
82 | .toString()}`,
83 | );
84 | });
85 | });
86 |
87 | describe('single (en)', () => {
88 | before(() => {
89 | cy.changeProps({ mode: 'single' });
90 | });
91 | it('test', () => {
92 | cy.get('.pdp-input').focus();
93 | cy.get('.pdp-shortcut')
94 | .should('exist')
95 | .contains('Now')
96 | .should('exist')
97 | .get('.pdp-shortcut')
98 | .contains('Tomorrow')
99 | .should('exist')
100 | .get('.pdp-shortcut')
101 | .contains('First of Week')
102 | .should('exist')
103 | .get('.pdp-shortcut')
104 | .contains('Last of Week')
105 | .should('exist')
106 | .get('.pdp-shortcut')
107 | .contains('Yesterday')
108 | .should('exist')
109 | .click();
110 | cy.get('.pdp-input').should(
111 | 'have.value',
112 | date.clone().calendar('gregorian').subDay().toString(),
113 | );
114 | });
115 | });
116 |
117 | describe('single (fa)', () => {
118 | before(() => {
119 | cy.changeProps({ locale: 'fa' });
120 | });
121 | it('test', () => {
122 | cy.get('.pdp-input').focus();
123 | cy.get('.pdp-shortcut')
124 | .should('exist')
125 | .contains('هم اکنون')
126 | .should('exist')
127 | .get('.pdp-shortcut')
128 | .contains('دیروز')
129 | .should('exist')
130 | .get('.pdp-shortcut')
131 | .contains('اول هفته')
132 | .should('exist')
133 | .get('.pdp-shortcut')
134 | .contains('آخر هفته')
135 | .should('exist')
136 | .get('.pdp-shortcut')
137 | .contains('فردا')
138 | .should('exist')
139 | .click();
140 | cy.get('.pdp-input').should(
141 | 'have.value',
142 | date.clone().addDay().toString(),
143 | );
144 | });
145 | });
146 | });
147 |
148 | context('datetime', () => {
149 | describe('single (fa)', () => {
150 | before(() => {
151 | cy.changeProps({ type: 'datetime' });
152 | });
153 | it('test', () => {
154 | cy.get('.pdp-input').focus();
155 | cy.get('.pdp-shortcut')
156 | .should('exist')
157 | .contains('هم اکنون')
158 | .should('exist')
159 | .get('.pdp-shortcut')
160 | .contains('دیروز')
161 | .should('exist')
162 | .get('.pdp-shortcut')
163 | .contains('فردا')
164 | .should('exist')
165 | .get('.pdp-shortcut')
166 | .contains('اول هفته')
167 | .should('exist')
168 | .get('.pdp-shortcut')
169 | .contains('آخر هفته')
170 | .should('exist')
171 | .click();
172 |
173 | cy.get('.pdp-input').should(
174 | 'have.value',
175 | date.clone().endOf('week').toString('datetime'),
176 | );
177 | });
178 | });
179 |
180 | describe('single (en)', () => {
181 | before(() => {
182 | cy.changeProps({ locale: 'en' });
183 | });
184 | it('test', () => {
185 | cy.get('.pdp-input').focus();
186 | cy.get('.pdp-shortcut')
187 | .should('exist')
188 | .contains('Now')
189 | .should('exist')
190 | .get('.pdp-shortcut')
191 | .contains('Yesterday')
192 | .should('exist')
193 | .get('.pdp-shortcut')
194 | .contains('Tomorrow')
195 | .should('exist')
196 | .get('.pdp-shortcut')
197 | .contains('Last of Week')
198 | .should('exist')
199 | .get('.pdp-shortcut')
200 | .contains('First of Week')
201 | .should('exist')
202 | .click();
203 |
204 | cy.get('.pdp-input').should(
205 | 'have.value',
206 | date.clone().calendar('gregorian').startOf('week').toString('datetime'),
207 | );
208 | });
209 | });
210 |
211 | describe('range (en)', () => {
212 | before(() => {
213 | cy.changeProps('mode', 'range');
214 | });
215 | it('test', () => {
216 | cy.get('.pdp-input').focus();
217 | cy.get('.pdp-shortcut')
218 | .should('exist')
219 | .contains('This Week')
220 | .should('exist')
221 | .get('.pdp-shortcut')
222 | .contains('Next Week')
223 | .should('exist')
224 | .get('.pdp-shortcut')
225 | .contains('This Month')
226 | .should('exist')
227 | .get('.pdp-shortcut')
228 | .contains('Previous Month')
229 | .should('exist')
230 | .get('.pdp-shortcut')
231 | .contains('Next Month')
232 | .should('exist')
233 | .get('.pdp-shortcut')
234 | .contains('Previous Week')
235 | .should('exist')
236 | .click();
237 |
238 | cy.get('.pdp-input').should(
239 | 'have.value',
240 | `${date
241 | .clone()
242 | .calendar('gregorian')
243 | .subWeek()
244 | .startOf('week')
245 | .toString('datetime')} - ${date
246 | .clone()
247 | .calendar('gregorian')
248 | .subWeek()
249 | .endOf('week')
250 | .toString('datetime')}`,
251 | );
252 | });
253 | });
254 |
255 | describe('range (fa)', () => {
256 | before(() => {
257 | cy.changeProps('locale', 'fa');
258 | });
259 | it('test', () => {
260 | cy.get('.pdp-input').focus();
261 | cy.get('.pdp-shortcut')
262 | .should('exist')
263 | .contains('این هفته')
264 | .should('exist')
265 | .get('.pdp-shortcut')
266 | .contains('هفته قبل')
267 | .should('exist')
268 | .get('.pdp-shortcut')
269 | .contains('این ماه')
270 | .should('exist')
271 | .get('.pdp-shortcut')
272 | .contains('ماه قبل')
273 | .should('exist')
274 | .get('.pdp-shortcut')
275 | .contains('ماه بعد')
276 | .should('exist')
277 | .get('.pdp-shortcut')
278 | .contains('هفته بعد')
279 | .should('exist')
280 | .click();
281 |
282 | cy.get('.pdp-input').should(
283 | 'have.value',
284 | `${date.clone().addWeek().startOf('week').toString('datetime')} - ${date
285 | .clone()
286 | .addWeek()
287 | .endOf('week')
288 | .toString('datetime')}`,
289 | );
290 | });
291 | });
292 | });
293 |
294 | context('time', () => {
295 | describe('range (fa)', () => {
296 | before(() => {
297 | cy.changeProps('type', 'time');
298 | });
299 | it('test', () => {
300 | cy.get('.pdp-input').focus();
301 | cy.get('.pdp-shortcut')
302 | .should('exist')
303 | .contains('این ساعت')
304 | .should('exist')
305 | .get('.pdp-shortcut')
306 | .contains('ساعت بعد')
307 | .should('exist')
308 | .get('.pdp-shortcut')
309 | .contains('تمام روز')
310 | .should('exist')
311 | .get('.pdp-shortcut')
312 | .contains('ساعت قبل')
313 | .should('exist')
314 | .click();
315 |
316 | cy.get('.pdp-input').should(
317 | 'have.value',
318 | `${date.clone().subHour().startOf('hour').toString('time')} - ${date
319 | .clone()
320 | .subHour()
321 | .endOf('hour')
322 | .toString('time')}`,
323 | );
324 | });
325 | });
326 |
327 | describe('range (en)', () => {
328 | before(() => {
329 | cy.changeProps('locale', 'en');
330 | });
331 | it('test', () => {
332 | cy.get('.pdp-input').focus();
333 | cy.get('.pdp-shortcut')
334 | .should('exist')
335 | .contains('This Hour')
336 | .should('exist')
337 | .get('.pdp-shortcut')
338 | .contains('Previous Hour')
339 | .should('exist')
340 | .get('.pdp-shortcut')
341 | .contains('All Day')
342 | .should('exist')
343 | .get('.pdp-shortcut')
344 | .contains('Next Hour')
345 | .should('exist')
346 | .click();
347 |
348 | cy.get('.pdp-input').should(
349 | 'have.value',
350 | `${date.clone().addHour().startOf('hour').toString('time')} - ${date
351 | .clone()
352 | .addHour()
353 | .endOf('hour')
354 | .toString('time')}`,
355 | );
356 | });
357 | });
358 |
359 | describe('single (en)', () => {
360 | before(() => {
361 | cy.changeProps('mode', 'single');
362 | });
363 | it('test', () => {
364 | cy.get('.pdp-input').focus();
365 | cy.get('.pdp-shortcut')
366 | .should('exist')
367 | .contains('One Hour ago')
368 | .should('exist')
369 | .get('.pdp-shortcut')
370 | .contains('One Hour later')
371 | .should('exist')
372 | .get('.pdp-shortcut')
373 | .contains('Midnight')
374 | .should('exist')
375 | .get('.pdp-shortcut')
376 | .contains('Now')
377 | .should('exist')
378 | .get('.pdp-shortcut')
379 | .contains('Midday')
380 | .should('exist')
381 | .click();
382 |
383 | cy.get('.pdp-input').should(
384 | 'have.value',
385 | date.clone().time('12:00').toString('time'),
386 | );
387 | });
388 | });
389 |
390 | describe('single (fa)', () => {
391 | before(() => {
392 | cy.changeProps('locale', 'fa');
393 | });
394 | it('test', () => {
395 | cy.get('.pdp-input').focus();
396 | cy.get('.pdp-shortcut')
397 | .should('exist')
398 | .contains('یک ساعت قبل')
399 | .should('exist')
400 | .get('.pdp-shortcut')
401 | .contains('یک ساعت بعد')
402 | .should('exist')
403 | .get('.pdp-shortcut')
404 | .contains('نیمه شب')
405 | .should('exist')
406 | .get('.pdp-shortcut')
407 | .contains('نیمروز')
408 | .should('exist')
409 | .get('.pdp-shortcut')
410 | .contains('هم اکنون')
411 | .should('exist')
412 | .click();
413 |
414 | cy.get('.pdp-input').should('have.value', date.clone().toString('time'));
415 | });
416 | });
417 | });
418 |
419 | context('custom shortcut', () => {
420 | describe('range', () => {
421 | const stringDates = ['1400/01/10', '1400/01/20'];
422 | const persianDates = [
423 | date.clone().subDay(2).toString(),
424 | date.clone().addDay(2).toString(),
425 | ];
426 | before(() => {
427 | cy.changeProps({
428 | shortcut: {
429 | String: stringDates,
430 | PersianDate: persianDates,
431 | },
432 | type: 'date',
433 | mode: 'range',
434 | });
435 | });
436 | it('test', () => {
437 | cy.get('.pdp-input')
438 | .focus()
439 | .get('.pdp-shortcut')
440 | .contains('String')
441 | .click();
442 | cy.get('.pdp-input')
443 | .should('have.value', stringDates.join(' - '))
444 | .focus()
445 | .get('.pdp-shortcut')
446 | .contains('PersianDate')
447 | .click();
448 | cy.get('.pdp-input').should('have.value', persianDates.join(' - '));
449 | });
450 | });
451 |
452 | describe('single', () => {
453 | const stringDates = ['1400/01/10'];
454 | const persianDates = [date.clone().subDay(2).toString()];
455 | before(() => {
456 | cy.changeProps({
457 | shortcut: {
458 | String: stringDates,
459 | PersianDate: persianDates,
460 | },
461 | mode: 'single',
462 | });
463 | });
464 | it('test', () => {
465 | cy.get('.pdp-input')
466 | .focus()
467 | .get('.pdp-shortcut')
468 | .contains('String')
469 | .click();
470 | cy.get('.pdp-input')
471 | .should('have.value', stringDates[0])
472 | .focus()
473 | .get('.pdp-shortcut')
474 | .contains('PersianDate')
475 | .click();
476 | cy.get('.pdp-input').should('have.value', persianDates[0]);
477 | });
478 | });
479 | });
480 |
481 | context('date with disable', () => {
482 | before(() => {
483 | cy.changeProps({
484 | shortcut: true,
485 | type: 'date',
486 | from: date.clone().addDay().toString(),
487 | to: date.clone().endOf('month').toString(),
488 | disable: date.clone().addDay().toString(),
489 | });
490 | });
491 |
492 | describe('single', () => {
493 | it('test', () => {
494 | cy.get('.pdp-input')
495 | .focus()
496 | .get('.pdp-shortcut')
497 | .should('have.length', 1)
498 | .contains('آخر هفته')
499 | .click();
500 | cy.get('.pdp-input').should(
501 | 'have.value',
502 | date.clone().endOf('week').toString(),
503 | );
504 | });
505 | });
506 |
507 | describe('range', () => {
508 | before(() => {
509 | cy.changeProps('mode', 'range');
510 | });
511 |
512 | it('test', () => {
513 | cy.get('.pdp-input')
514 | .focus()
515 | .get('.pdp-shortcut')
516 | .should('have.length', 1)
517 | .contains('هفته بعد')
518 | .click();
519 | cy.get('.pdp-input').should(
520 | 'have.value',
521 | `${date.clone().addWeek().startOf('week').toString()} - ${date
522 | .clone()
523 | .addWeek()
524 | .endOf('week')
525 | .toString()}`,
526 | );
527 | });
528 | });
529 | });
530 |
--------------------------------------------------------------------------------
/test/e2e/select-date.cy.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
3 | describe('select date - range', () => {
4 | before(() => {
5 | cy.changeProps();
6 | cy.changeSlots();
7 | });
8 |
9 | it('with click on dates', () => {
10 | cy.get('.pdp-input').focus();
11 | cy.contains('10').click();
12 | cy.contains('15').click();
13 | cy.get('.pdp-input').should('have.value', '1399/06/10 - 1399/06/15');
14 | });
15 |
16 | it('with arrow keys', () => {
17 | cy.get('.pdp-input')
18 | .focus()
19 | .wait(1)
20 | .type('{downarrow}{downarrow}{leftarrow}{leftarrow}{enter}')
21 | .type('{downarrow}{rightarrow}{rightarrow}{enter}')
22 | .should('have.value', '1399/06/10 - 1399/06/15');
23 | });
24 |
25 | it('with type the date', () => {
26 | cy.get('.pdp-input')
27 | .focus()
28 | .type('1399/06/10{enter}')
29 | .type('1399/06/15{enter}')
30 | .should('have.value', '1399/06/10 - 1399/06/15');
31 | });
32 | });
33 |
34 | describe('select date - single', () => {
35 | before(() => {
36 | cy.changeProps('mode', 'single');
37 | });
38 |
39 | it('with click on dates', () => {
40 | cy.get('.pdp-input').focus();
41 | cy.contains('10').click();
42 | cy.get('.pdp-input').should('have.value', '1399/06/10');
43 | });
44 |
45 | it('with arrow keys', () => {
46 | cy.get('.pdp-input')
47 | .focus()
48 | .wait(1)
49 | .type('{downarrow}{downarrow}{leftarrow}{leftarrow}{enter}')
50 | .should('have.value', '1399/06/10');
51 | });
52 |
53 | it('with type the date', () => {
54 | cy.get('.pdp-input')
55 | .focus()
56 | .type('1399/06/10{enter}')
57 | .should('have.value', '1399/06/10');
58 | });
59 | });
60 |
61 | describe('select date with disable date - single', () => {
62 | before(() => {
63 | cy.changeProps('disable', '1399/6/5');
64 | });
65 |
66 | it('with click on dates', () => {
67 | cy.get('.pdp-input').focus();
68 | cy.contains('5').click();
69 | cy.get('.pdp-input').should('have.value', '');
70 | cy.contains('6').click();
71 | cy.get('.pdp-input').should('have.value', '1399/06/06');
72 | });
73 |
74 | it('with arrow keys', () => {
75 | cy.get('.pdp-input')
76 | .focus()
77 | .wait(1)
78 | .type('{leftarrow}{leftarrow}{leftarrow}{leftarrow}{leftarrow}{enter}')
79 | .should('have.value', '')
80 | .type('{leftarrow}{enter}')
81 | .should('have.value', '1399/06/06');
82 | });
83 |
84 | it('with type the date', () => {
85 | cy.get('.pdp-input')
86 | .focus()
87 | .type('1399/06/05{enter}')
88 | .should('have.value', '1399/06/05')
89 | .clear()
90 | .type('1399/06/06{enter}')
91 | .should('have.value', '1399/06/06')
92 | .focus();
93 | cy.get('.pdp-day.start-range').should('contain.text', '6');
94 | });
95 | });
96 |
97 | describe('select date with disable date - range', () => {
98 | before(() => {
99 | cy.changeProps({ disable: '1399/6/5', mode: 'range' });
100 | });
101 |
102 | it('with click on dates', () => {
103 | cy.get('.pdp-input').focus();
104 | cy.contains('5').click();
105 | cy.get('.pdp-input').should('have.value', '');
106 | cy.get('.pdp-day[value="3"]').first().click();
107 | cy.get('.pdp-day.start-range').should('contain.text', '3');
108 | cy.get('.pdp-day[value="6"]').first().click();
109 | cy.get('.pdp-day[value="5"]').first().click();
110 | cy.get('.pdp-day[value="4"]').first().click();
111 | cy.get('.pdp-input')
112 | .focus()
113 | .should('have.value', '1399/06/03 - 1399/06/04');
114 | cy.get('.pdp-day.end-range').should('contain.text', '4');
115 | });
116 |
117 | it('with arrow keys', () => {
118 | cy.get('.pdp-input')
119 | .focus()
120 | .wait(1)
121 | .type('{downarrow}{leftarrow}{leftarrow}{leftarrow}{leftarrow}{enter}')
122 | .should('have.value', '')
123 | .type('{rightarrow}{rightarrow}{enter}');
124 | cy.get('.pdp-day.start-range').should('contain.text', '3');
125 | cy.get('.pdp-input')
126 | .type('{leftarrow}{leftarrow}{leftarrow}{enter}')
127 | .type('{rightarrow}{enter}')
128 | .type('{rightarrow}{enter}')
129 | .focus();
130 | cy.get('.pdp-day.end-range').should('contain.text', '4');
131 | });
132 |
133 | it('with type the date', () => {
134 | cy.get('.pdp-input')
135 | .focus()
136 | .type('1399/06/05{enter}')
137 | .should('have.value', '1399/06/05')
138 | .clear()
139 | .type('1399/06/03{enter}')
140 | .should('have.value', '');
141 | cy.get('.pdp-day.start-range').should('contain.text', '3');
142 | cy.get('.pdp-input')
143 | .type('1399/06/06{enter}')
144 | .should('have.value', '1399/06/06')
145 | .clear()
146 | .type('1399/06/05{enter}')
147 | .should('have.value', '1399/06/05')
148 | .clear()
149 | .type('1399/06/04{enter}')
150 | .should('have.value', '1399/06/03 - 1399/06/04')
151 | .focus();
152 | cy.get('.pdp-day.end-range').should('contain.text', '4');
153 | });
154 | });
155 |
156 | describe('select date in en locale - range', () => {
157 | before(() => {
158 | cy.changeProps('locale', 'en');
159 | });
160 |
161 | it('with click on dates', () => {
162 | cy.get('.pdp-input').focus();
163 | cy.contains('10').click();
164 | cy.contains('15').click();
165 | cy.get('.pdp-input').should('have.value', '2020-09-10 - 2020-09-15');
166 | });
167 |
168 | it('with arrow keys', () => {
169 | cy.get('.pdp-input')
170 | .focus()
171 | .wait(1)
172 | .type('{downarrow}{downarrow}{leftarrow}{leftarrow}{enter}')
173 | .type('{downarrow}{rightarrow}{rightarrow}{enter}')
174 | .should('have.value', '2020-09-06 - 2020-09-15');
175 | });
176 |
177 | it('with type the date', () => {
178 | cy.get('.pdp-input')
179 | .focus()
180 | .type('2020-09-10{enter}')
181 | .type('2020-09-15{enter}')
182 | .should('have.value', '2020-09-10 - 2020-09-15');
183 | });
184 | });
185 |
186 | describe('select date in en locale - single', () => {
187 | before(() => {
188 | cy.changeProps('mode', 'single');
189 | });
190 |
191 | it('with click on dates', () => {
192 | cy.get('.pdp-input').focus();
193 | cy.contains('10').click();
194 | cy.get('.pdp-input').should('have.value', '2020-09-10');
195 | });
196 |
197 | it('with arrow keys', () => {
198 | cy.get('.pdp-input')
199 | .focus()
200 | .wait(1)
201 | .type('{downarrow}{downarrow}{rightarrow}{rightarrow}{enter}')
202 | .should('have.value', '2020-09-10');
203 | });
204 |
205 | it('with type the date', () => {
206 | cy.get('.pdp-input')
207 | .focus()
208 | .type('2020-09-10{enter}')
209 | .should('have.value', '2020-09-10');
210 | });
211 | });
212 |
--------------------------------------------------------------------------------
/test/e2e/select-datetime.cy.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
3 | describe('select date and time - range', () => {
4 | before(() => {
5 | cy.changeProps('type', 'datetime');
6 | cy.changeSlots();
7 | });
8 |
9 | it('with click', () => {
10 | cy.get('.pdp-input').focus();
11 | cy.contains('10').click();
12 | cy.contains('15').click();
13 | cy.get('.pdp-input').focus();
14 | let hour = new Date(2021, 2, 30, 12).getHours();
15 | hour = 20 - hour;
16 | if (hour < 0) hour += 24;
17 | let button = cy.get(
18 | '.pdp-time .pdp-moment > div:first-child .hour button:first-child',
19 | );
20 | for (let i = 0; i < hour; i++) {
21 | button.click();
22 | }
23 | let minute = new Date(2021, 2, 30, 12).getMinutes();
24 | minute = 18 - minute;
25 | if (minute < 0) minute += 60;
26 | button = cy.get(
27 | '.pdp-time .pdp-moment > div:first-child .minute button:first-child',
28 | );
29 | for (let i = 0; i < minute; i++) {
30 | button.click();
31 | }
32 | hour = new Date(2021, 2, 30, 12).getHours();
33 | hour = 15 - hour;
34 | hour -= 24;
35 | button = cy.get(
36 | '.pdp-time .pdp-moment > div:last-child .hour button:last-child',
37 | );
38 | for (let i = 0; i < Math.abs(hour); i++) {
39 | button.click();
40 | }
41 | minute = new Date(2021, 2, 30, 12).getMinutes();
42 | minute = 12 - minute;
43 | minute -= 60;
44 | button = cy.get(
45 | '.pdp-time .pdp-moment > div:last-child .minute button:last-child',
46 | );
47 | for (let i = 0; i < Math.abs(minute); i++) {
48 | button.click();
49 | }
50 | cy.get('.pdp-input').should(
51 | 'have.value',
52 | '1399/06/10 20:18 - 1399/06/15 15:12',
53 | );
54 | });
55 |
56 | it('with keys', () => {
57 | cy.get('.pdp-input')
58 | .focus()
59 | .wait(1)
60 | .type('{downarrow}{downarrow}{leftarrow}{leftarrow}{enter}')
61 | .type('{downarrow}{rightarrow}{rightarrow}{enter}');
62 | let hour = new Date(2021, 2, 30, 12).getHours();
63 | cy.get('.pdp-input').focus();
64 | hour = 20 - hour;
65 | if (hour < 0) hour += 24;
66 | let button = cy.get('.pdp-moment button').first().focus();
67 | for (let i = 0; i < hour; i++) {
68 | button.type('{enter}');
69 | }
70 | let minute = new Date(2021, 2, 30, 12).getMinutes();
71 | minute = 18 - minute;
72 | if (minute < 0) minute += 60;
73 | button = cy.get('.pdp-moment button').eq(2).focus();
74 | for (let i = 0; i < minute; i++) {
75 | button.type('{enter}');
76 | }
77 | hour = new Date(2021, 2, 30, 12).getHours();
78 | hour = 15 - hour;
79 | hour -= 24;
80 | button = cy.get('.pdp-moment button').eq(5).focus();
81 | for (let i = 0; i < Math.abs(hour); i++) {
82 | button.type('{enter}');
83 | }
84 | minute = new Date(2021, 2, 30, 12).getMinutes();
85 | minute = 12 - minute;
86 | minute -= 60;
87 | button = cy.get('.pdp-moment button').eq(7).focus();
88 | for (let i = 0; i < Math.abs(minute); i++) {
89 | button.type('{enter}');
90 | }
91 | cy.get('.pdp-input').should(
92 | 'have.value',
93 | '1399/06/10 20:18 - 1399/06/15 15:12',
94 | );
95 | });
96 |
97 | it('with type', () => {
98 | cy.get('.pdp-input')
99 | .focus()
100 | .type('1399/06/10 20:18{enter}')
101 | .type('1399/06/15 15:12{enter}')
102 | .should('have.value', '1399/06/10 20:18 - 1399/06/15 15:12');
103 | });
104 | });
105 |
106 | describe('select date and time - single', () => {
107 | before(() => {
108 | cy.changeProps('mode', 'single');
109 | });
110 |
111 | it('with click', () => {
112 | cy.get('.pdp-input').focus();
113 | cy.contains('10').click();
114 | cy.get('.pdp-input').focus();
115 | let hour = new Date(2021, 2, 30, 12).getHours();
116 | hour = 20 - hour;
117 | if (hour < 0) hour += 24;
118 | let button = cy.get(
119 | '.pdp-time .pdp-moment > div:first-child .hour button:first-child',
120 | );
121 | for (let i = 0; i < hour; i++) {
122 | button.click();
123 | }
124 | let minute = new Date(2021, 2, 30, 12).getMinutes();
125 | minute = 18 - minute;
126 | if (minute < 0) minute += 60;
127 | button = cy.get(
128 | '.pdp-time .pdp-moment > div:first-child .minute button:first-child',
129 | );
130 | for (let i = 0; i < minute; i++) {
131 | button.click();
132 | }
133 | cy.get('.pdp-input').should('have.value', '1399/06/10 20:18');
134 | });
135 |
136 | it('with keys', () => {
137 | cy.get('.pdp-input')
138 | .focus()
139 | .wait(1)
140 | .type('{downarrow}{downarrow}{leftarrow}{leftarrow}{enter}')
141 | .focus();
142 | let hour = new Date(2021, 2, 30, 12).getHours();
143 | hour = 20 - hour;
144 | if (hour < 0) hour += 24;
145 | let button = cy.get('.pdp-moment button').first().focus();
146 | for (let i = 0; i < hour; i++) {
147 | button.type('{enter}');
148 | }
149 | let minute = new Date(2021, 2, 30, 12).getMinutes();
150 | minute = 18 - minute;
151 | if (minute < 0) minute += 60;
152 | button = cy.get('.pdp-moment button').eq(2).focus();
153 | for (let i = 0; i < minute; i++) {
154 | button.type('{enter}');
155 | }
156 | cy.get('.pdp-input').should('have.value', '1399/06/10 20:18');
157 | });
158 |
159 | it('with type', () => {
160 | cy.get('.pdp-input')
161 | .focus()
162 | .type('1399/06/10 20:18{enter}')
163 | .should('have.value', '1399/06/10 20:18');
164 | });
165 | });
166 |
167 | describe('select date and time with disable date - single', () => {
168 | before(() => {
169 | cy.changeProps('disable', '1399/6/5 20:18');
170 | });
171 |
172 | it('with click', () => {
173 | cy.get('.pdp-input').focus();
174 | cy.contains('5').click();
175 | cy.get('.pdp-input').focus();
176 | let hour = new Date(2021, 2, 30, 12).getHours();
177 | hour = 20 - hour;
178 | if (hour < 0) hour += 24;
179 | let button = cy.get(
180 | '.pdp-time .pdp-moment > div:first-child .hour button:first-child',
181 | );
182 | for (let i = 0; i < hour; i++) {
183 | button.click();
184 | }
185 | let minute = new Date(2021, 2, 30, 12).getMinutes();
186 | minute = 18 - minute;
187 | if (minute < 0) minute += 60;
188 | button = cy.get(
189 | '.pdp-time .pdp-moment > div:first-child .minute button:first-child',
190 | );
191 | for (let i = 0; i < minute; i++) {
192 | button.click();
193 | }
194 | cy.get('.pdp-time .pdp-moment > div')
195 | .should('have.attr', 'class')
196 | .and('match', /disabled/);
197 | cy.get('.pdp-input').should('have.value', '1399/06/05 20:17');
198 | cy.get(
199 | '.pdp-time .pdp-moment > div:first-child .minute button:first-child',
200 | ).click();
201 | cy.get('.pdp-input').should('have.value', '1399/06/05 20:19');
202 | });
203 |
204 | it('with keys', () => {
205 | cy.get('.pdp-input')
206 | .focus()
207 | .wait(1)
208 | .type('{leftarrow}{leftarrow}{leftarrow}{leftarrow}{leftarrow}{enter}')
209 | .focus();
210 | let hour = new Date(2021, 2, 30, 12).getHours();
211 | hour = 20 - hour;
212 | if (hour < 0) hour += 24;
213 | let button = cy.get('.pdp-moment button').first().focus();
214 | for (let i = 0; i < hour; i++) {
215 | button.type('{enter}');
216 | }
217 | let minute = new Date(2021, 2, 30, 12).getMinutes();
218 | minute = 18 - minute;
219 | if (minute < 0) minute += 60;
220 | button = cy.get('.pdp-moment button').eq(2).focus();
221 | for (let i = 0; i < minute; i++) {
222 | button.type('{enter}');
223 | }
224 | cy.get('.pdp-time .pdp-moment > div')
225 | .should('have.attr', 'class')
226 | .and('match', /disabled/);
227 | cy.get('.pdp-input').should('have.value', '1399/06/05 20:17');
228 | cy.get('.pdp-moment button').eq(2).focus().type('{enter}');
229 | cy.get('.pdp-input').should('have.value', '1399/06/05 20:19');
230 | });
231 |
232 | it('with type', () => {
233 | cy.get('.pdp-input')
234 | .focus()
235 | .type('1399/06/05 20:18{enter}')
236 | .should('have.value', '1399/06/05 20:18')
237 | .clear()
238 | .type('1399/06/06 20:18{enter}')
239 | .should('have.value', '1399/06/06 20:18')
240 | .focus();
241 | cy.get('.pdp-day.start-range').should('contain.text', '6');
242 | cy.get('.hour').should('contain.text', '20');
243 | cy.get('.minute').should('contain.text', '18');
244 | });
245 | });
246 |
247 | describe('select date and time with disable date - range', () => {
248 | before(() => {
249 | cy.changeProps({ disable: '1399/6/5 20:18', mode: 'range' });
250 | });
251 |
252 | it('with click', () => {
253 | cy.get('.pdp-input').focus();
254 | cy.contains('5').click();
255 | cy.get('.pdp-day.start-range').should('contain.text', '5');
256 | cy.get('.pdp-day[value="6"]').first().click();
257 | cy.get('.pdp-input').focus();
258 | cy.get('.pdp-day.end-range').should('contain.text', '6');
259 | let hour = new Date(2021, 2, 30, 12).getHours();
260 | hour = 20 - hour;
261 | if (hour < 0) hour += 24;
262 | let button = cy.get(
263 | '.pdp-time .pdp-moment > div:first-child .hour button:first-child',
264 | );
265 | for (let i = 0; i < hour; i++) {
266 | button.click();
267 | }
268 | let minute = new Date(2021, 2, 30, 12).getMinutes();
269 | minute = 18 - minute;
270 | if (minute < 0) minute += 60;
271 | button = cy.get(
272 | '.pdp-time .pdp-moment > div:first-child .minute button:first-child',
273 | );
274 | for (let i = 0; i < minute; i++) {
275 | button.click();
276 | }
277 | cy.get('.pdp-time .pdp-moment > div:first-child')
278 | .should('have.attr', 'class')
279 | .and('match', /disabled/);
280 | cy.get('.pdp-input').should(
281 | 'contain.value',
282 | '1399/06/05 20:17 - 1399/06/06 ',
283 | );
284 | cy.get(
285 | '.pdp-time .pdp-moment > div:first-child .minute button:first-child',
286 | ).click();
287 | cy.get('.pdp-input').should(
288 | 'contain.value',
289 | '1399/06/05 20:19 - 1399/06/06 ',
290 | );
291 | hour = new Date(2021, 2, 30, 12).getHours();
292 | hour = 15 - hour;
293 | hour -= 24;
294 | button = cy.get(
295 | '.pdp-time .pdp-moment > div:last-child .hour button:last-child',
296 | );
297 | for (let i = 0; i < Math.abs(hour); i++) {
298 | button.click();
299 | }
300 | minute = new Date(2021, 2, 30, 12).getMinutes();
301 | minute = 12 - minute;
302 | minute -= 60;
303 | button = cy.get(
304 | '.pdp-time .pdp-moment > div:last-child .minute button:last-child',
305 | );
306 | for (let i = 0; i < Math.abs(minute); i++) {
307 | button.click();
308 | }
309 | cy.get('.pdp-input').should(
310 | 'have.value',
311 | '1399/06/05 20:19 - 1399/06/06 15:12',
312 | );
313 | });
314 |
315 | it('with keys', () => {
316 | cy.get('.pdp-input')
317 | .focus()
318 | .wait(1)
319 | .type('{downarrow}{leftarrow}{leftarrow}{leftarrow}{leftarrow}{enter}');
320 | cy.get('.pdp-day.start-range').should('contain.text', '5');
321 | cy.get('.pdp-input')
322 | .type('{leftarrow}{leftarrow}{leftarrow}{enter}')
323 | .focus();
324 | cy.get('.pdp-day.end-range').should('contain.text', '8');
325 | let hour = new Date(2021, 2, 30, 12).getHours();
326 | hour = 20 - hour;
327 | if (hour < 0) hour += 24;
328 | let button = cy.get('.pdp-moment button').first().focus();
329 | for (let i = 0; i < hour; i++) {
330 | button.type('{enter}');
331 | }
332 | let minute = new Date(2021, 2, 30, 12).getMinutes();
333 | minute = 18 - minute;
334 | if (minute < 0) minute += 60;
335 | button = cy.get('.pdp-moment button').eq(2).focus();
336 | for (let i = 0; i < minute; i++) {
337 | button.type('{enter}');
338 | }
339 | cy.get('.pdp-time .pdp-moment > div:first-child')
340 | .should('have.attr', 'class')
341 | .and('match', /disabled/);
342 | cy.get('.pdp-input')
343 | .focus()
344 | .should('contain.value', '1399/06/05 20:17 - 1399/06/08 ');
345 | cy.get('.pdp-moment button').eq(2).focus().type('{enter}');
346 | cy.get('.pdp-input')
347 | .focus()
348 | .should('contain.value', '1399/06/05 20:19 - 1399/06/08 ');
349 | hour = new Date(2021, 2, 30, 12).getHours();
350 | hour = 15 - hour;
351 | hour -= 24;
352 | button = cy.get('.pdp-moment button').eq(5).focus();
353 | for (let i = 0; i < Math.abs(hour); i++) {
354 | button.type('{enter}');
355 | }
356 | minute = new Date(2021, 2, 30, 12).getMinutes();
357 | minute = 12 - minute;
358 | minute -= 60;
359 | button = cy.get('.pdp-moment button').eq(7).focus();
360 | for (let i = 0; i < Math.abs(minute); i++) {
361 | button.type('{enter}');
362 | }
363 | cy.get('.pdp-input')
364 | .focus()
365 | .should('have.value', '1399/06/05 20:19 - 1399/06/08 15:12');
366 | });
367 |
368 | it('with type', () => {
369 | cy.get('.pdp-input')
370 | .focus()
371 | .type('1399/06/05 20:18{enter}')
372 | .should('have.value', '1399/06/05 20:18')
373 | .clear()
374 | .type('1399/06/03 20:18{enter}')
375 | .should('have.value', '');
376 | cy.get('.pdp-day.start-range').should('contain.text', '3');
377 | cy.get('.hour').first().should('contain.text', '20');
378 | cy.get('.minute').first().should('contain.text', '18');
379 | cy.get('.pdp-input')
380 | .clear()
381 | .type('1399/06/05 20:18{enter}')
382 | .should('have.value', '1399/06/05 20:18')
383 | .clear()
384 | .type('1399/06/04 20:18{enter}')
385 | .should('have.value', '1399/06/03 20:18 - 1399/06/04 20:18')
386 | .focus();
387 | cy.get('.pdp-day.end-range').should('contain.text', '4');
388 | cy.get('.hour').last().should('contain.text', '20');
389 | cy.get('.minute').last().should('contain.text', '18');
390 | });
391 | });
392 |
393 | describe('select date and time in en locale - range', () => {
394 | before(() => {
395 | cy.changeProps('locale', 'en');
396 | });
397 |
398 | it('with click', () => {
399 | cy.get('.pdp-input').focus();
400 | cy.contains('10').click();
401 | cy.contains('15').click();
402 | cy.get('.pdp-input').focus();
403 | let hour = new Date(2021, 2, 30, 12).getHours();
404 | hour = 20 - hour;
405 | if (hour < 0) hour += 24;
406 | let button = cy.get(
407 | '.pdp-time .pdp-moment > div:first-child .hour button:first-child',
408 | );
409 | for (let i = 0; i < hour; i++) {
410 | button.click();
411 | }
412 | let minute = new Date(2021, 2, 30, 12).getMinutes();
413 | minute = 18 - minute;
414 | if (minute < 0) minute += 60;
415 | button = cy.get(
416 | '.pdp-time .pdp-moment > div:first-child .minute button:first-child',
417 | );
418 | for (let i = 0; i < minute; i++) {
419 | button.click();
420 | }
421 | hour = new Date(2021, 2, 30, 12).getHours();
422 | hour = 15 - hour;
423 | hour -= 24;
424 | button = cy.get(
425 | '.pdp-time .pdp-moment > div:last-child .hour button:last-child',
426 | );
427 | for (let i = 0; i < Math.abs(hour); i++) {
428 | button.click();
429 | }
430 | minute = new Date(2021, 2, 30, 12).getMinutes();
431 | minute = 12 - minute;
432 | minute -= 60;
433 | button = cy.get(
434 | '.pdp-time .pdp-moment > div:last-child .minute button:last-child',
435 | );
436 | for (let i = 0; i < Math.abs(minute); i++) {
437 | button.click();
438 | }
439 | cy.get('.pdp-input').should(
440 | 'have.value',
441 | '2020-09-10 20:18 - 2020-09-15 15:12',
442 | );
443 | });
444 |
445 | it('with keys', () => {
446 | cy.get('.pdp-input')
447 | .focus()
448 | .wait(1)
449 | .type('{downarrow}{downarrow}{leftarrow}{leftarrow}{enter}')
450 | .type('{downarrow}{rightarrow}{rightarrow}{enter}');
451 | let hour = new Date(2021, 2, 30, 12).getHours();
452 | cy.get('.pdp-input').focus();
453 | hour = 20 - hour;
454 | if (hour < 0) hour += 24;
455 | let button = cy.get('.pdp-moment button').first().focus();
456 | for (let i = 0; i < hour; i++) {
457 | button.type('{enter}');
458 | }
459 | let minute = new Date(2021, 2, 30, 12).getMinutes();
460 | minute = 18 - minute;
461 | if (minute < 0) minute += 60;
462 | button = cy.get('.pdp-moment button').eq(2).focus();
463 | for (let i = 0; i < minute; i++) {
464 | button.type('{enter}');
465 | }
466 | hour = new Date(2021, 2, 30, 12).getHours();
467 | hour = 15 - hour;
468 | hour -= 24;
469 | button = cy.get('.pdp-moment button').eq(5).focus();
470 | for (let i = 0; i < Math.abs(hour); i++) {
471 | button.type('{enter}');
472 | }
473 | minute = new Date(2021, 2, 30, 12).getMinutes();
474 | minute = 12 - minute;
475 | minute -= 60;
476 | button = cy.get('.pdp-moment button').eq(7).focus();
477 | for (let i = 0; i < Math.abs(minute); i++) {
478 | button.type('{enter}');
479 | }
480 | cy.get('.pdp-input').should(
481 | 'have.value',
482 | '2020-09-06 20:18 - 2020-09-15 15:12',
483 | );
484 | });
485 |
486 | it('with type', () => {
487 | cy.get('.pdp-input')
488 | .focus()
489 | .type('2020-09-10 20:18{enter}')
490 | .type('2020-09-15 15:12{enter}')
491 | .should('have.value', '2020-09-10 20:18 - 2020-09-15 15:12');
492 | });
493 | });
494 |
495 | describe('select date and time in en locale - single', () => {
496 | before(() => {
497 | cy.changeProps('mode', 'single');
498 | });
499 |
500 | it('with click', () => {
501 | cy.get('.pdp-input').focus();
502 | cy.contains('10').click();
503 | cy.get('.pdp-input').focus();
504 | let hour = new Date(2021, 2, 30, 12).getHours();
505 | hour = 20 - hour;
506 | if (hour < 0) hour += 24;
507 | let button = cy.get(
508 | '.pdp-time .pdp-moment > div:first-child .hour button:first-child',
509 | );
510 | for (let i = 0; i < hour; i++) {
511 | button.click();
512 | }
513 | let minute = new Date(2021, 2, 30, 12).getMinutes();
514 | minute = 18 - minute;
515 | if (minute < 0) minute += 60;
516 | button = cy.get(
517 | '.pdp-time .pdp-moment > div:first-child .minute button:first-child',
518 | );
519 | for (let i = 0; i < minute; i++) {
520 | button.click();
521 | }
522 | cy.get('.pdp-input').should('have.value', '2020-09-10 20:18');
523 | });
524 |
525 | it('with keys', () => {
526 | cy.get('.pdp-input')
527 | .focus()
528 | .wait(1)
529 | .type('{downarrow}{downarrow}{rightarrow}{rightarrow}{enter}')
530 | .focus();
531 | let hour = new Date(2021, 2, 30, 12).getHours();
532 | hour = 20 - hour;
533 | if (hour < 0) hour += 24;
534 | let button = cy.get('.pdp-moment button').first().focus();
535 | for (let i = 0; i < hour; i++) {
536 | button.type('{enter}');
537 | }
538 | let minute = new Date(2021, 2, 30, 12).getMinutes();
539 | minute = 18 - minute;
540 | if (minute < 0) minute += 60;
541 | button = cy.get('.pdp-moment button').eq(2).focus();
542 | for (let i = 0; i < minute; i++) {
543 | button.type('{enter}');
544 | }
545 | cy.get('.pdp-input').should('have.value', '2020-09-10 20:18');
546 | });
547 |
548 | it('with type', () => {
549 | cy.get('.pdp-input')
550 | .focus()
551 | .type('2020-09-10 20:18{enter}')
552 | .should('have.value', '2020-09-10 20:18');
553 | });
554 | });
555 |
--------------------------------------------------------------------------------
/test/e2e/select-time.cy.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
3 | describe('select time - range', () => {
4 | before(() => {
5 | cy.changeProps({ type: 'time' }, null, true);
6 | cy.changeSlots();
7 | });
8 |
9 | it('with click on times', () => {
10 | cy.get('.pdp-input').focus();
11 | let hour = new Date(2021, 2, 30, 12).getHours();
12 | hour = 20 - hour;
13 | if (hour < 0) hour += 24;
14 | let button = cy.get(
15 | `.pdp-time .pdp-moment > div:last-child .hour button:first-child`,
16 | );
17 | for (let i = 0; i < hour; i++) {
18 | button.click();
19 | }
20 | let minute = new Date(2021, 2, 30, 12).getMinutes();
21 | minute = 18 - minute;
22 | if (minute < 0) minute += 60;
23 | button = cy.get(
24 | `.pdp-time .pdp-moment > div:last-child .minute button:first-child`,
25 | );
26 | for (let i = 0; i < minute; i++) {
27 | button.click();
28 | }
29 | hour = new Date(2021, 2, 30, 12).getHours();
30 | hour = 15 - hour;
31 | if (hour < 0) hour += 24;
32 | button = cy.get(
33 | `.pdp-time .pdp-moment > div:first-child .hour button:first-child`,
34 | );
35 | for (let i = 0; i < hour; i++) {
36 | button.click();
37 | }
38 | minute = new Date(2021, 2, 30, 12).getMinutes();
39 | minute = 12 - minute;
40 | if (minute < 0) minute += 60;
41 | button = cy.get(
42 | `.pdp-time .pdp-moment > div:first-child .minute button:first-child`,
43 | );
44 | for (let i = 0; i < minute; i++) {
45 | button.click();
46 | }
47 | cy.get('.pdp-input').should('have.value', '15:12 - 20:18');
48 | });
49 |
50 | it('with keys', () => {
51 | cy.get('.pdp-input').focus();
52 | let hour = new Date(2021, 2, 30, 12).getHours();
53 | hour = 20 - hour;
54 | if (hour < 0) hour += 24;
55 | let button = cy.get('.pdp-moment button').eq(4).focus();
56 | for (let i = 0; i < hour; i++) {
57 | button.type('{enter}');
58 | }
59 | let minute = new Date(2021, 2, 30, 12).getMinutes();
60 | minute = 18 - minute;
61 | if (minute < 0) minute += 60;
62 | button = cy.get('.pdp-moment button').eq(6).focus();
63 | for (let i = 0; i < minute; i++) {
64 | button.type('{enter}');
65 | }
66 | hour = new Date(2021, 2, 30, 12).getHours();
67 | hour = 15 - hour;
68 | if (hour < 0) hour += 24;
69 | button = cy.get('.pdp-moment button').first().focus();
70 | for (let i = 0; i < hour; i++) {
71 | button.type('{enter}');
72 | }
73 | minute = new Date(2021, 2, 30, 12).getMinutes();
74 | minute = 12 - minute;
75 | if (minute < 0) minute += 60;
76 | button = cy.get('.pdp-moment button').eq(2).focus();
77 | for (let i = 0; i < minute; i++) {
78 | button.type('{enter}');
79 | }
80 | cy.get('.pdp-input').should('have.value', '15:12 - 20:18');
81 | });
82 |
83 | it('with type the time', () => {
84 | cy.get('.pdp-input')
85 | .focus()
86 | .type('15:12{enter}')
87 | .type('20:18{enter}')
88 | .should('have.value', '15:12 - 20:18');
89 | });
90 | });
91 |
92 | describe('select time - single', () => {
93 | before(() => {
94 | cy.changeProps('mode', 'single');
95 | });
96 |
97 | it('with click on times', () => {
98 | cy.get('.pdp-input').focus();
99 | let hour = new Date(2021, 2, 30, 12).getHours();
100 | hour = 20 - hour;
101 | if (hour < 0) hour += 24;
102 | let button = cy.get(
103 | '.pdp-time .pdp-moment > div:first-child .hour button:first-child',
104 | );
105 | for (let i = 0; i < hour; i++) {
106 | button.click();
107 | }
108 | let minute = new Date(2021, 2, 30, 12).getMinutes();
109 | minute = 18 - minute;
110 | if (minute < 0) minute += 60;
111 | button = cy.get(
112 | '.pdp-time .pdp-moment > div:first-child .minute button:first-child',
113 | );
114 | for (let i = 0; i < minute; i++) {
115 | button.click();
116 | }
117 | cy.get('.pdp-input').should('have.value', '20:18');
118 | });
119 |
120 | it('with keys', () => {
121 | cy.get('.pdp-input').focus();
122 | let hour = new Date(2021, 2, 30, 12).getHours();
123 | hour = 20 - hour;
124 | if (hour < 0) hour += 24;
125 | let button = cy.get('.pdp-moment button').first().focus();
126 | for (let i = 0; i < hour; i++) {
127 | button.type('{enter}');
128 | }
129 | let minute = new Date(2021, 2, 30, 12).getMinutes();
130 | minute = 18 - minute;
131 | if (minute < 0) minute += 60;
132 | button = cy.get('.pdp-moment button').eq(2).focus();
133 | for (let i = 0; i < minute; i++) {
134 | button.type('{enter}');
135 | }
136 | cy.get('.pdp-input').should('have.value', '20:18');
137 | });
138 |
139 | it('with type the time', () => {
140 | cy.get('.pdp-input')
141 | .focus()
142 | .type('20:18{enter}')
143 | .should('have.value', '20:18');
144 | });
145 | });
146 |
147 | describe('select time with disable time - single', () => {
148 | before(() => {
149 | cy.changeProps('disable', '20:18');
150 | });
151 |
152 | it('with click on times', () => {
153 | cy.get('.pdp-input').focus();
154 | let hour = new Date(2021, 2, 30, 12).getHours();
155 | hour = 20 - hour;
156 | if (hour < 0) hour += 24;
157 | let button = cy.get(
158 | '.pdp-time .pdp-moment > div:first-child .hour button:first-child',
159 | );
160 | for (let i = 0; i < hour; i++) {
161 | button.click();
162 | }
163 | let minute = new Date(2021, 2, 30, 12).getMinutes();
164 | minute = 18 - minute;
165 | if (minute < 0) minute += 60;
166 | button = cy.get(
167 | '.pdp-time .pdp-moment > div:first-child .minute button:first-child',
168 | );
169 | for (let i = 0; i < minute; i++) {
170 | button.click();
171 | }
172 | cy.get('.pdp-time .pdp-moment > div')
173 | .should('have.attr', 'class')
174 | .and('match', /disabled/);
175 | cy.get('.pdp-input').should('have.value', '20:17');
176 | cy.get(
177 | '.pdp-time .pdp-moment > div:first-child .minute button:first-child',
178 | ).click();
179 | cy.get('.pdp-input').should('have.value', '20:19');
180 | });
181 |
182 | it('with keys', () => {
183 | cy.get('.pdp-input').focus();
184 | let hour = new Date(2021, 2, 30, 12).getHours();
185 | hour = 20 - hour;
186 | if (hour < 0) hour += 24;
187 | let button = cy.get('.pdp-moment button').first().focus();
188 | for (let i = 0; i < hour; i++) {
189 | button.type('{enter}');
190 | }
191 | let minute = new Date(2021, 2, 30, 12).getMinutes();
192 | minute = 18 - minute;
193 | if (minute < 0) minute += 60;
194 | button = cy.get('.pdp-moment button').eq(2).focus();
195 | for (let i = 0; i < minute; i++) {
196 | button.type('{enter}');
197 | }
198 |
199 | cy.get('.pdp-time .pdp-moment > div')
200 | .should('have.attr', 'class')
201 | .and('match', /disabled/);
202 | cy.get('.pdp-input').should('have.value', '20:17');
203 | cy.get('.pdp-moment button').eq(2).focus().type('{enter}');
204 | cy.get('.pdp-input').should('have.value', '20:19');
205 | });
206 |
207 | it('with type the time', () => {
208 | cy.get('.pdp-input')
209 | .focus()
210 | .type('20:18{enter}')
211 | .should('have.value', '20:18');
212 | cy.get('.hour').should('not.contain.value', '20');
213 | cy.get('.minute').should('not.contain.value', '18');
214 | cy.get('.pdp-input')
215 | .clear()
216 | .type('20:19{enter}')
217 | .should('have.value', '20:19');
218 | cy.get('.pdp-time').should('not.exist');
219 | });
220 | });
221 |
222 | describe('select time with disable time - range', () => {
223 | before(() => {
224 | cy.changeProps({ disable: ['20:18', '15:12'], mode: 'range' });
225 | });
226 |
227 | it('with click on times', () => {
228 | cy.get('.pdp-input').focus();
229 | let hour = new Date(2021, 2, 30, 12).getHours();
230 | hour = 20 - hour;
231 | if (hour < 0) hour += 24;
232 | let button = cy.get(
233 | '.pdp-time .pdp-moment > div:last-child .hour button:first-child',
234 | );
235 | for (let i = 0; i < hour; i++) {
236 | button.click();
237 | }
238 | let minute = new Date(2021, 2, 30, 12).getMinutes();
239 | minute = 18 - minute;
240 | if (minute < 0) minute += 60;
241 | button = cy.get(
242 | '.pdp-time .pdp-moment > div:last-child .minute button:first-child',
243 | );
244 | for (let i = 0; i < minute; i++) {
245 | button.click();
246 | }
247 | cy.get('.pdp-time .pdp-moment > div:last-child')
248 | .should('have.attr', 'class')
249 | .and('match', /disabled/);
250 | cy.get('.pdp-input').should('contain.value', ' - 20:17');
251 | cy.get(
252 | '.pdp-time .pdp-moment > div:last-child .minute button:first-child',
253 | ).click();
254 | cy.get('.pdp-input').should('contain.value', ' - 20:19');
255 | hour = new Date(2021, 2, 30, 12).getHours();
256 | hour = 15 - hour;
257 | if (hour < 0) hour += 24;
258 | button = cy.get(
259 | '.pdp-time .pdp-moment > div:first-child .hour button:first-child',
260 | );
261 | for (let i = 0; i < Math.abs(hour); i++) {
262 | button.click();
263 | }
264 | minute = new Date(2021, 2, 30, 12).getMinutes();
265 | minute = 12 - minute;
266 | if (minute < 0) minute += 60;
267 | button = cy.get(
268 | '.pdp-time .pdp-moment > div:first-child .minute button:first-child',
269 | );
270 | for (let i = 0; i < Math.abs(minute); i++) {
271 | button.click();
272 | }
273 | cy.get('.pdp-time .pdp-moment > div:first-child')
274 | .should('have.attr', 'class')
275 | .and('match', /disabled/);
276 | cy.get('.pdp-input').should('have.value', '15:11 - 20:19');
277 | cy.get(
278 | '.pdp-time .pdp-moment > div:first-child .minute button:first-child',
279 | ).click();
280 | cy.get('.pdp-input').should('have.value', '15:13 - 20:19');
281 | });
282 |
283 | it('with keys', () => {
284 | cy.get('.pdp-input').focus();
285 | let hour = new Date(2021, 2, 30, 12).getHours();
286 | hour = 20 - hour;
287 | if (hour < 0) hour += 24;
288 | let button = cy.get('.pdp-moment button').eq(4).focus();
289 | for (let i = 0; i < hour; i++) {
290 | button.type('{enter}');
291 | }
292 | let minute = new Date(2021, 2, 30, 12).getMinutes();
293 | minute = 18 - minute;
294 | if (minute < 0) minute += 60;
295 | button = cy.get('.pdp-moment button').eq(6).focus();
296 | for (let i = 0; i < minute; i++) {
297 | button.type('{enter}');
298 | }
299 | cy.get('.pdp-time .pdp-moment > div:last-child')
300 | .should('have.attr', 'class')
301 | .and('match', /disabled/);
302 | cy.get('.pdp-input').should('contain.value', ' - 20:17');
303 | cy.get('.pdp-moment button').eq(6).focus().type('{enter}');
304 | cy.get('.pdp-input').should('contain.value', ' - 20:19');
305 | hour = new Date(2021, 2, 30, 12).getHours();
306 | hour = 15 - hour;
307 | if (hour < 0) hour += 24;
308 | button = cy.get('.pdp-moment button').first().focus();
309 | for (let i = 0; i < Math.abs(hour); i++) {
310 | button.type('{enter}');
311 | }
312 | minute = new Date(2021, 2, 30, 12).getMinutes();
313 | minute = 12 - minute;
314 | if (minute < 0) minute += 60;
315 | button = cy.get('.pdp-moment button').eq(2).focus();
316 | for (let i = 0; i < Math.abs(minute); i++) {
317 | button.type('{enter}');
318 | }
319 | cy.get('.pdp-time .pdp-moment > div:first-child')
320 | .should('have.attr', 'class')
321 | .and('match', /disabled/);
322 | cy.get('.pdp-input').should('have.value', '15:11 - 20:19');
323 | cy.get('.pdp-moment button').eq(2).focus().type('{enter}');
324 | cy.get('.pdp-input').should('have.value', '15:13 - 20:19');
325 | });
326 |
327 | it('with type the time', () => {
328 | cy.get('.pdp-input')
329 | .focus()
330 | .type('15:12{enter}')
331 | .should('have.value', '15:12');
332 | cy.get('.hour').should('not.contain.value', '15');
333 | cy.get('.minute').should('not.contain.value', '12');
334 | cy.get('.pdp-input')
335 | .clear()
336 | .type('15:13{enter}')
337 | .type('20:18{enter}')
338 | .should('have.value', '20:18');
339 | cy.get('.hour').should('not.contain.value', '20');
340 | cy.get('.minute').should('not.contain.value', '18');
341 | cy.get('.pdp-input').clear().type('20:17{enter}');
342 | cy.get('.pdp-input').should('have.value', '15:13 - 20:17');
343 | });
344 | });
345 |
--------------------------------------------------------------------------------
/test/e2e/slots.cy.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
3 | describe('slots', () => {
4 | before(() => {
5 | cy.changeProps('clearable', true, true);
6 | cy.changeSlots(
7 | {
8 | before: '',
9 | after: 'Please select date.',
10 | icon: 'Date',
11 | 'right-arrow': 'ماه قبل',
12 | 'left-arrow': 'ماه بعد',
13 | footer: 'تاریخ انتخابی:',
14 | clear: 'بستن',
15 | 'up-arrow': 'افزایش',
16 | 'down-arrow': 'کاهش',
17 | },
18 | null,
19 | true,
20 | );
21 | });
22 |
23 | it('before', () => {
24 | cy.get('label').should('contain.text', 'select date:');
25 | });
26 |
27 | it('after', () => {
28 | cy.get('small').should('contain.text', 'Please select date.');
29 | });
30 |
31 | it('icon', () => {
32 | cy.get('.pdp-icon').should('contain.text', 'Date');
33 | });
34 |
35 | it('right arrow', () => {
36 | cy.get('.pdp-input')
37 | .focus()
38 | .get('.pdp-arrow')
39 | .first()
40 | .should('contain.text', 'ماه قبل');
41 | });
42 |
43 | it('left arrow', () => {
44 | cy.get('.pdp-input')
45 | .focus()
46 | .get('.pdp-arrow')
47 | .last()
48 | .should('contain.text', 'ماه بعد');
49 | });
50 |
51 | it('footer', () => {
52 | cy.get('.pdp-input')
53 | .focus()
54 | .get('.pdp-footer')
55 | .should('contain.text', 'تاریخ انتخابی:');
56 | });
57 |
58 | it('clear', () => {
59 | cy.get('.pdp-clear').should('contain.text', 'بستن');
60 | });
61 |
62 | context('up arrow', () => {
63 | before(() => {
64 | cy.changeProps('type', 'time');
65 | });
66 |
67 | it('test', () => {
68 | cy.get('.pdp-input')
69 | .focus()
70 | .get('.hour button:first-child,.minute button:first-child')
71 | .should('contain.text', 'افزایش');
72 | });
73 | });
74 |
75 | context('down arrow', () => {
76 | before(() => {
77 | cy.changeProps('type', 'datetime');
78 | });
79 |
80 | it('test', () => {
81 | cy.get('.pdp-input')
82 | .focus()
83 | .get('.hour button:last-child,.minute button:last-child')
84 | .should('contain.text', 'کاهش');
85 | });
86 | });
87 | });
88 |
--------------------------------------------------------------------------------
/test/fixtures/example.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Using fixtures to represent data",
3 | "email": "hello@cypress.io",
4 | "body": "Fixtures are a great way to mock data for responses to routes"
5 | }
6 |
--------------------------------------------------------------------------------
/test/support/Test.vue:
--------------------------------------------------------------------------------
1 |
68 |
69 |
70 |
71 |
88 |
89 |
90 |
91 |
92 |
93 |
date/time is: {{ model }}
94 |
95 |
96 |
97 |
{{ status }}
98 |
99 |
100 |
101 |
106 |
--------------------------------------------------------------------------------
/test/support/e2e.ts:
--------------------------------------------------------------------------------
1 | // ***********************************************************
2 | // This example support/index.js is processed and
3 | // loaded automatically before your test files.
4 | //
5 | // This is a great place to put global configuration and
6 | // behavior that modifies Cypress.
7 | //
8 | // You can change the location of this file or turn off
9 | // automatically serving support files with the
10 | // 'supportFile' configuration option.
11 | //
12 | // You can read more here:
13 | // https://on.cypress.io/configuration
14 | // ***********************************************************
15 |
16 | import { Obj } from '../../src/components/utils/modules/types';
17 | import { mount } from '@cypress/vue';
18 | import Test from './Test.vue';
19 |
20 | declare global {
21 | namespace Cypress {
22 | interface Chainable {
23 | changeProps(prop: Obj, value: null, replace?: boolean): void;
24 | changeProps(prop: string, value: unknown, replace?: boolean): void;
25 | changeSlots(slot: Obj, value: null, replace?: boolean): void;
26 | changeSlots(slot: string, value: unknown, replace?: boolean): void;
27 |
28 | selectDate(): void;
29 | selectRangeDate(): void;
30 | selectTime(
31 | hour?: number,
32 | minute?: number,
33 | child?: 'first' | 'last',
34 | ): void;
35 |
36 | getProps(): Obj;
37 | getSlots(): Obj;
38 | }
39 | }
40 | }
41 |
42 | // *********************** Variable ***********************
43 | let props: Obj = {
44 | from: '1399',
45 | to: '1399/06/31',
46 | };
47 | let slots: Obj = {};
48 |
49 | // *********************** Commands ***********************
50 | Cypress.Commands.add('selectDate', () => {
51 | cy.get('.pdp-input').focus();
52 | cy.get('.pdp-day').contains('10').click();
53 | });
54 | Cypress.Commands.add('selectRangeDate', () => {
55 | cy.get('.pdp-input').focus();
56 | cy.get('.pdp-day').contains('10').click();
57 | cy.get('.pdp-day').contains('15').click();
58 | });
59 | Cypress.Commands.add('selectTime', (hour = 0, minute = 0, child = 'first') => {
60 | let nowHour = new Date(2021, 2, 30, 12).getHours();
61 | nowHour = hour - nowHour;
62 | if (nowHour < 0) nowHour += 24;
63 | let button = cy.get(
64 | `.pdp-time .pdp-moment > div:${child}-child .hour button:first-child`,
65 | );
66 | for (let i = 0; i < nowHour; i++) {
67 | button.click();
68 | }
69 | let nowMinute = new Date(2021, 2, 30, 12).getMinutes();
70 | nowMinute = minute - nowMinute;
71 | if (nowMinute < 0) nowMinute += 60;
72 | button = cy.get(
73 | `.pdp-time .pdp-moment > div:${child}-child .minute button:first-child`,
74 | );
75 | for (let i = 0; i < nowMinute; i++) {
76 | button.click();
77 | }
78 | });
79 | Cypress.Commands.add('changeProps', (prop, value, replace = false) => {
80 | if (replace) {
81 | props = {};
82 | }
83 | if (prop) {
84 | if (typeof prop == 'string') {
85 | props[prop] = value;
86 | } else {
87 | Object.assign(props, prop);
88 | }
89 | }
90 | });
91 | Cypress.Commands.add('changeSlots', (slot, value, replace = false) => {
92 | if (replace) {
93 | slots = {};
94 | }
95 | if (slot) {
96 | if (typeof slot == 'string') {
97 | slots[slot] = value;
98 | } else {
99 | Object.assign(slots, slot);
100 | }
101 | }
102 | });
103 |
104 | // *********************** Test ***********************
105 | beforeEach(() => {
106 | cy.clock(new Date(2021, 2, 30, 12)).then(() => {
107 | mount(Test, {
108 | propsData: {
109 | props,
110 | slots,
111 | },
112 | });
113 | });
114 | });
115 |
--------------------------------------------------------------------------------
/test/support/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Components App
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "esnext",
4 | "module": "esnext",
5 | "moduleResolution": "node",
6 | "strict": true,
7 | "jsx": "preserve",
8 | "sourceMap": true,
9 | "resolveJsonModule": true,
10 | "esModuleInterop": true,
11 | "lib": ["esnext", "dom"],
12 | "types": ["cypress"],
13 | "declaration": true,
14 | "declarationDir": "dist"
15 | },
16 | "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.vue"]
17 | }
18 |
--------------------------------------------------------------------------------
/vite.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite';
2 | import vue from '@vitejs/plugin-vue';
3 |
4 | // https://vitejs.dev/config/
5 | export default defineConfig({
6 | plugins: [vue()],
7 | build: {
8 | lib: {
9 | entry: 'src/components/DatePicker.vue',
10 | name: 'DatePicker',
11 | fileName: (format) => `index-${format}.js`,
12 | },
13 | rollupOptions: {
14 | external: ['vue'],
15 | output: {
16 | globals: {
17 | vue: 'Vue',
18 | },
19 | },
20 | },
21 | // rollupOptions: {
22 | // input: 'src/components/DatePicker.vue',
23 | // output: [
24 | // {
25 | // // file: 'index.common.js',
26 | // format: 'cjs',
27 | // inlineDynamicImports: true,
28 | // manualChunks: undefined,
29 | // },
30 | // {
31 | // // file: 'index.esm.js',
32 | // format: 'es',
33 | // inlineDynamicImports: true,
34 | // manualChunks: undefined,
35 | // },
36 | // ],
37 | // plugins: [common({}), resolve({})],
38 | // },
39 | },
40 | css: {
41 | preprocessorOptions: {
42 | scss: {
43 | api: 'modern-compiler',
44 | },
45 | },
46 | },
47 | });
48 |
--------------------------------------------------------------------------------