├── .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 | [![npm version](https://img.shields.io/npm/v/@alireza-ab/vue3-persian-datepicker)](https://www.npmjs.com/package/@alireza-ab/vue3-persian-datepicker) 7 | [![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](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 | ![select date with vue persian datepicker](https://alireza-ab.ir/images/GIFs/selectWithArrow.gif) 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 | 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 | 38 | -------------------------------------------------------------------------------- /src/components/utils/components/PDPArrow.vue: -------------------------------------------------------------------------------- 1 | 30 | 31 | 44 | -------------------------------------------------------------------------------- /src/components/utils/components/PDPIcon.vue: -------------------------------------------------------------------------------- 1 | 6 | 18 | 19 | 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 | 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 | --------------------------------------------------------------------------------