├── .gitignore ├── LICENSE ├── README.md ├── babel.config.js ├── cypress.json ├── cypress ├── fixtures │ └── example.json ├── integration │ ├── arrow-keys.spec.js │ ├── events.spec.js │ ├── other-tests.spec.js │ ├── props.spec.js │ ├── select-date.spec.js │ ├── select-datetime.spec.js │ ├── select-time.spec.js │ ├── shortcut.spec.js │ └── slots.spec.js ├── plugins │ └── index.js └── support │ ├── commands.js │ └── index.js ├── dist ├── build.js ├── build.js.LICENSE.txt ├── build.js.map ├── datepicker.common.js ├── datepicker.common.js.LICENSE.txt ├── datepicker.min.js └── datepicker.min.js.LICENSE.txt ├── index.html ├── nuxt.js ├── package.json ├── src ├── App.vue ├── components │ ├── DatePicker.vue │ ├── assets │ │ └── sass │ │ │ ├── _variable.scss │ │ │ └── app.scss │ └── utils │ │ ├── components │ │ ├── ArrowIcon.vue │ │ ├── CalendarClockIcon.vue │ │ ├── CalendarIcon.vue │ │ ├── ClearIcon.vue │ │ └── ClockIcon.vue │ │ └── modules │ │ └── core.js └── main.js ├── test ├── App.vue ├── main.js ├── props.json └── slots.json ├── webpack.config.js └── yarn.lock /.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 | # Cypress additional files 24 | cypress/videos 25 | cypress/screenshots -------------------------------------------------------------------------------- /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 | # Vue 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/vue-persian-datepicker)](https://www.npmjs.com/package/@alireza-ab/vue-persian-datepicker) 7 | 8 | ## Features 9 | 10 | - **nuxt** support 11 | - **single and range selection** 12 | - select **date** and **time** 13 | - select with **keyboard** 14 | - customizable **style** 15 | - localization 16 | 17 | ## Documentation 18 | 19 | For full documentation and examples, visit [https://alireza-ab.ir/datepicker](https://alireza-ab.ir/datepicker) 20 | 21 | ![select date with vue persian datepicker](https://alireza-ab.ir/images/GIFs/selectWithArrow.gif) 22 | 23 | ### Install 24 | 25 | ```shell 26 | npm i @alireza-ab/vue-persian-datepicker 27 | ``` 28 | 29 | ### Usage 30 | 31 | ```js 32 | import datePicker from "@alireza-ab/vue-persian-datepicker"; 33 | 34 | new Vue({ 35 | components: { datePicker }, 36 | el: "#app", 37 | }); 38 | ``` 39 | 40 | ```html 41 | 42 | ``` 43 | 44 | ## License 45 | 46 | Vue Persian Datepicker is available under the [MIT](https://opensource.org/licenses/MIT) license. 47 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/cli-plugin-babel/preset' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /cypress.json: -------------------------------------------------------------------------------- 1 | { 2 | "baseUrl": "http://localhost:8081", 3 | "projectId": "32fyob" 4 | } 5 | -------------------------------------------------------------------------------- /cypress/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 | } -------------------------------------------------------------------------------- /cypress/integration/arrow-keys.spec.js: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | describe('arrow keys', () => { 4 | beforeEach(() => { 5 | cy.changeProps() 6 | cy.changeSlots() 7 | }) 8 | 9 | it('without select date', () => { 10 | cy.visit('/') 11 | cy.tab().type('{downarrow}{downarrow}{rightarrow}') 12 | cy.get('[data-column=1] .hover').should('contain.text', '31') 13 | cy.get('.pdp-input').type('{uparrow}') 14 | cy.get('[data-column=1] .hover').should('contain.text', '24') 15 | cy.get('.pdp-input').type('{rightarrow}{rightarrow}{rightarrow}{rightarrow}') 16 | cy.get('[data-column=1] .hover').should('contain.text', '20') 17 | cy.get('.pdp-input').type('{uparrow}') 18 | cy.get('[data-column=1] .hover').should('contain.text', '13') 19 | cy.get('.pdp-input').type('{leftarrow}') 20 | cy.get('[data-column=1] .hover').should('contain.text', '14') 21 | cy.get('.pdp-input').type('{uparrow}{uparrow}') 22 | cy.get('[data-column=0] .hover').should('contain.text', '31') 23 | cy.get('.pdp-input').type('{leftarrow}') 24 | cy.get('[data-column=1] .hover').should('contain.text', '1') 25 | cy.get('.pdp-input').type('{rightarrow}') 26 | cy.get('[data-column=0] .hover').should('contain.text', '31') 27 | cy.get('.pdp-input').type('{uparrow}{uparrow}{uparrow}{uparrow}{uparrow}') 28 | cy.get('[data-column=1] .hover').should('contain.text', '27') 29 | cy.get('.pdp-input').type('{uparrow}{uparrow}{uparrow}{uparrow}') 30 | cy.get('[data-column=0] .hover').should('contain.text', '30') 31 | cy.get('.pdp-input').type('{leftarrow}{leftarrow}') 32 | cy.get('[data-column=1] .hover').should('contain.text', '1') 33 | cy.get('.pdp-input').type('{uparrow}{rightarrow}{rightarrow}{rightarrow}{rightarrow}{rightarrow}{rightarrow}') 34 | cy.get('[data-column=0] .hover').should('contain.text', '19') 35 | cy.get('.pdp-input').type('{uparrow}{uparrow}{uparrow}') 36 | cy.get('[data-column=1] .hover').should('contain.text', '29') 37 | cy.get('.pdp-input').type('{uparrow}{uparrow}{uparrow}{uparrow}{uparrow}') 38 | cy.get('[data-column=1] .hover').should('contain.text', '1') 39 | cy.get('.pdp-input').type('{leftarrow}') 40 | cy.get('[data-column=1] .hover').should('contain.text', '2') 41 | }) 42 | 43 | it('with select date', () => { 44 | cy.visit('/') 45 | cy.tab().get('.pdp-year').first().click() 46 | cy.get('li').contains('1399').click() 47 | cy.tab().get('.pdp-month').first().click() 48 | cy.get('li').contains('فروردین').click() 49 | cy.get('.pdp-input').type('{downarrow}', { force: true }) 50 | cy.get('.hover').should('contain.text', '1') 51 | cy.get('.pdp-input').type('{downarrow}{downarrow}{rightarrow}{enter}') 52 | cy.get('.start-range').should('contain.text', '14') 53 | cy.get('.pdp-input').type('{downarrow}{downarrow}{downarrow}{downarrow}{rightarrow}{enter}') 54 | cy.get('.pdp-input').should('have.value', '1399/01/14 - 1399/02/10') 55 | cy.get('.pdp-input').focus().get('.end-range').should('contain.text', '10') 56 | cy.get('[data-column=0] .in-range').should('not.contain.text', '14').should('not.contain.text', '13') 57 | cy.get('[data-column=1] .in-range').should('not.contain.text', '10').should('not.contain.text', '11') 58 | cy.get('.pdp-input').type('{downarrow}{rightarrow}{rightarrow}{enter}') 59 | cy.get('.start-range').should('contain.text', '15') 60 | cy.get('.pdp-input').type('{uparrow}{uparrow}{uparrow}{enter}') 61 | cy.get('.start-range').should('contain.text', '25') 62 | cy.get('.pdp-input').type('{downarrow}{downarrow}{downarrow}{downarrow}{downarrow}{downarrow}{enter}') 63 | cy.get('.pdp-input').should('have.value', '1399/01/25 - 1399/03/05') 64 | cy.get('.pdp-input').focus().get('.end-range').should('contain.text', '5') 65 | cy.get('.pdp-arrow').first().click().click() 66 | cy.get('.pdp-input').type('{uparrow}{uparrow}{uparrow}{enter}', { force: true }) 67 | cy.get('.start-range').should('contain.text', '4') 68 | cy.get('.pdp-input').type('{downarrow}{downarrow}{downarrow}{downarrow}{leftarrow}{leftarrow}{enter}') 69 | cy.get('.pdp-input').should('have.value', '1399/01/04 - 1399/02/03') 70 | cy.get('.pdp-input').focus().get('.end-range').should('contain.text', '3') 71 | 72 | }) 73 | }) 74 | 75 | describe('arrow keys in "en" locale', () => { 76 | beforeEach(() => { 77 | cy.changeProps('locale', 'en') 78 | }) 79 | 80 | it('without select date', () => { 81 | cy.visit('/') 82 | cy.tab() 83 | .type('{downarrow}{downarrow}{leftarrow}') 84 | cy.get('[data-column=1] .hover').should('contain.text', '31') 85 | cy.get('.pdp-input').type('{uparrow}') 86 | cy.get('[data-column=1] .hover').should('contain.text', '24') 87 | cy.get('.pdp-input').type('{leftarrow}{leftarrow}{leftarrow}{leftarrow}') 88 | cy.get('[data-column=1] .hover').should('contain.text', '20') 89 | cy.get('.pdp-input').type('{uparrow}') 90 | cy.get('[data-column=1] .hover').should('contain.text', '13') 91 | cy.get('.pdp-input').type('{rightarrow}') 92 | cy.get('[data-column=1] .hover').should('contain.text', '14') 93 | cy.get('.pdp-input').type('{uparrow}{uparrow}') 94 | cy.get('[data-column=0] .hover').should('contain.text', '31') 95 | cy.get('.pdp-input').type('{rightarrow}') 96 | cy.get('[data-column=1] .hover').should('contain.text', '1') 97 | cy.get('.pdp-input').type('{leftarrow}') 98 | cy.get('[data-column=0] .hover').should('contain.text', '31') 99 | cy.get('.pdp-input').type('{uparrow}{uparrow}{uparrow}{uparrow}{uparrow}') 100 | cy.get('[data-column=1] .hover').should('contain.text', '26') 101 | cy.get('.pdp-input').type('{uparrow}{uparrow}{uparrow}{uparrow}') 102 | cy.get('[data-column=0] .hover').should('contain.text', '29') 103 | cy.get('.pdp-input').type('{rightarrow}{rightarrow}') 104 | cy.get('[data-column=0] .hover').should('contain.text', '31') 105 | cy.get('.pdp-input').type('{uparrow}{leftarrow}{leftarrow}{leftarrow}{leftarrow}{leftarrow}{leftarrow}') 106 | cy.get('[data-column=0] .hover').should('contain.text', '18') 107 | cy.get('.pdp-input').type('{uparrow}{uparrow}{uparrow}') 108 | cy.get('[data-column=1] .hover').should('contain.text', '27') 109 | cy.get('.pdp-input').type('{uparrow}{uparrow}{uparrow}{uparrow}{uparrow}') 110 | cy.get('[data-column=0] .hover').should('contain.text', '23') 111 | cy.get('.pdp-input').type('{rightarrow}') 112 | cy.get('[data-column=0] .hover').should('contain.text', '24') 113 | }) 114 | 115 | it('with select date', () => { 116 | cy.visit('/') 117 | cy.tab().get('.pdp-year').first().click() 118 | cy.get('li').contains('2020').click() 119 | cy.tab().get('.pdp-month').first().click() 120 | cy.get('li').contains('March').click() 121 | cy.get('.pdp-input').type('{downarrow}', { force: true }) 122 | cy.get('.hover').should('contain.text', '20') 123 | cy.get('.pdp-input').type('{downarrow}{downarrow}{leftarrow}{enter}') 124 | cy.get('.start-range').should('contain.text', '2') 125 | cy.get('.pdp-input').type('{downarrow}{downarrow}{downarrow}{downarrow}{leftarrow}{enter}') 126 | cy.get('.pdp-input').should('have.value', '2020-04-02 - 2020-04-29') 127 | cy.get('.pdp-input').focus().get('.end-range').should('contain.text', '29') 128 | cy.get('[data-column=1] .in-range').first().should('not.contain.text', '2').should('not.contain.text', '1') 129 | cy.get('[data-column=1] .in-range').last().should('not.contain.text', '29').should('not.contain.text', '30') 130 | cy.get('.pdp-input').type('{downarrow}{leftarrow}{leftarrow}{enter}') 131 | cy.get('.start-range').should('contain.text', '4') 132 | cy.get('.pdp-input').type('{uparrow}{uparrow}{uparrow}{enter}') 133 | cy.get('.start-range').should('contain.text', '13') 134 | cy.get('.pdp-input').type('{downarrow}{downarrow}{downarrow}{downarrow}{downarrow}{downarrow}{enter}') 135 | cy.get('.pdp-input').should('have.value', '2020-04-13 - 2020-05-25') 136 | cy.get('.pdp-input').focus().get('.end-range').should('contain.text', '25') 137 | cy.get('.pdp-arrow').first().click().click() 138 | cy.get('.pdp-input').type('{uparrow}{uparrow}{uparrow}{enter}', { force: true }) 139 | cy.get('.start-range').should('contain.text', '23') 140 | cy.get('.pdp-input').type('{downarrow}{downarrow}{downarrow}{downarrow}{rightarrow}{rightarrow}{enter}') 141 | cy.get('.pdp-input').should('have.value', '2020-03-23 - 2020-04-22') 142 | cy.get('.pdp-input').focus().get('.end-range').should('contain.text', '22') 143 | 144 | }) 145 | }) 146 | 147 | describe('arrow keys in "en" locale', () => { 148 | beforeEach(() => { 149 | cy.changeProps('locale', 'fa') 150 | cy.changeProps('disable', '1399/6/10') 151 | }) 152 | 153 | it('with select date', () => { 154 | cy.visit('/') 155 | cy.get('.pdp-input').focus().type('{downarrow}{downarrow}{enter}') 156 | cy.get('.start-range').should('contain.text', '1') 157 | cy.get('.pdp-input').type('{downarrow}{downarrow}{leftarrow}{leftarrow}{enter}') 158 | .type('{uparrow}{enter}{rightarrow}{enter}') 159 | cy.get('.pdp-input').should('have.value', '1399/06/01 - 1399/06/09') 160 | cy.get('.pdp-input').focus().get('.end-range').should('contain.text', '9') 161 | 162 | }) 163 | }) -------------------------------------------------------------------------------- /cypress/integration/events.spec.js: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | const types = ["date", "time", "datetime"]; 4 | 5 | describe("focus", () => { 6 | beforeEach(() => { 7 | cy.changeProps("from", undefined); 8 | cy.changeProps("to", undefined); 9 | cy.changeSlots(); 10 | }); 11 | 12 | for (let i = 0; i < types.length; i++) { 13 | it(`${types[i]} type`, () => { 14 | cy.changeProps("type", types[i]); 15 | cy.visit("/"); 16 | cy.get(".pdp-input").focus(); 17 | cy.get(".status").should("contain.text", "focus"); 18 | }); 19 | } 20 | }); 21 | 22 | describe("open", () => { 23 | for (let i = 0; i < types.length; i++) { 24 | it(`${types[i]} type`, () => { 25 | cy.changeProps("type", types[i]); 26 | cy.visit("/"); 27 | cy.get(".pdp-input").focus(); 28 | cy.get(".status").should("contain.text", "open"); 29 | }); 30 | } 31 | }); 32 | 33 | describe("blur", () => { 34 | for (let i = 0; i < types.length; i++) { 35 | it(`${types[i]} type`, () => { 36 | cy.changeProps("type", types[i]); 37 | cy.visit("/"); 38 | cy.get(".pdp-input").focus(); 39 | cy.get(".pdp-overlay").click({ force: true }); 40 | cy.get(".status").should("contain.text", "blur"); 41 | }); 42 | } 43 | }); 44 | 45 | describe("close", () => { 46 | for (let i = 0; i < types.length; i++) { 47 | it(`${types[i]} type`, () => { 48 | cy.changeProps("type", types[i]); 49 | cy.visit("/"); 50 | cy.get(".pdp-input").focus(); 51 | cy.get(".pdp-overlay").click({ force: true }); 52 | cy.get(".status").should("contain.text", "close"); 53 | }); 54 | } 55 | }); 56 | 57 | describe("input", () => { 58 | for (let i = 0; i < types.length; i++) { 59 | it(`${types[i]} type`, () => { 60 | cy.changeProps("type", types[i]); 61 | cy.visit("/"); 62 | cy.get(".pdp-input").type("1"); 63 | cy.get(".status").should("contain.text", "input"); 64 | }); 65 | } 66 | }); 67 | 68 | describe("select & submit", () => { 69 | for (let i = 0; i < types.length; i++) { 70 | it(`${types[i]} type`, () => { 71 | cy.changeProps("type", types[i]); 72 | cy.visit("/"); 73 | if (types[i] == "date") { 74 | cy.get(".pdp-input").type("1399/06/01{enter}"); 75 | cy.get(".status").should("contain.text", "select:1399/06/01"); 76 | cy.get(".pdp-input").type("1399/06/02{enter}"); 77 | cy.get(".status").should("contain.text", "select:1399/06/02"); 78 | cy.get(".status").should( 79 | "contain.text", 80 | "submit:1399/06/01,1399/06/02" 81 | ); 82 | } else if (types[i] == "time") { 83 | cy.get(".pdp-input").type("15:12{enter}"); 84 | cy.get(".status").should("contain.text", "select:15:12"); 85 | cy.get(".pdp-input").type("20:18{enter}"); 86 | cy.get(".status").should("contain.text", "select:20:18"); 87 | cy.get(".status").should("contain.text", "submit:15:12,20:18"); 88 | } else if (types[i] == "datetime") { 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").should("contain.text", "select:1399/06/02 15:12"); 93 | cy.get(".status").should( 94 | "contain.text", 95 | "submit:1399/06/01 20:18,1399/06/02 15:12" 96 | ); 97 | } 98 | }); 99 | } 100 | }); 101 | 102 | describe("clear", () => { 103 | for (let i = 0; i < types.length; i++) { 104 | it(`${types[i]} type`, () => { 105 | cy.changeProps("clearable", true); 106 | cy.changeProps("type", types[i]); 107 | cy.visit("/"); 108 | cy.get(".pdp-clear").click(); 109 | cy.get(".status").should("contain.text", "clear"); 110 | }); 111 | } 112 | }); 113 | -------------------------------------------------------------------------------- /cypress/integration/other-tests.spec.js: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | describe('others', () => { 4 | beforeEach(() => { 5 | cy.changeProps('from', undefined) 6 | cy.changeProps('to', undefined) 7 | cy.changeSlots() 8 | }) 9 | 10 | it('show top of input', () => { 11 | cy.visit('/') 12 | cy.get('.pdp').invoke('attr', 'style', 'margin-top:50rem;') 13 | cy.get('.pdp-input').focus() 14 | cy.wait(1000).then(() => { 15 | let pickerTop = cy.$$('.pdp-picker').offset().top; 16 | let inputTop = cy.$$('.pdp-input').offset().top; 17 | expect(pickerTop).lt(inputTop) 18 | }) 19 | }) 20 | 21 | it('scroll in year-select section', () => { 22 | cy.visit('/') 23 | cy.get('.pdp-input').focus() 24 | cy.get('.pdp-year').first().click() 25 | cy.wait(1000).then(() => { 26 | expect(cy.$$('.pdp-select-year').offset().top).not.equal(0) 27 | }) 28 | }) 29 | 30 | it('select range date and change locale', () => { 31 | cy.changeProps('from', '1399') 32 | cy.changeProps('to', '1399/6/31') 33 | cy.changeProps('locale', 'fa,en') 34 | cy.visit('/') 35 | cy.get('.pdp-input').focus() 36 | cy.contains('15').first().click() 37 | cy.contains('20').first().click() 38 | cy.get('.pdp-input').focus() 39 | cy.get('.pdp-header .top button').click() 40 | cy.contains('September') 41 | cy.get('.start-range').should('contain.text', '5') 42 | cy.get('.end-range').should('contain.text', '10') 43 | }) 44 | 45 | it('select single date and change locale', () => { 46 | cy.changeProps('from', '1399') 47 | cy.changeProps('to', '1399/6/31') 48 | cy.changeProps('locale', 'en,fa') 49 | cy.changeProps('mode', 'single') 50 | cy.visit('/') 51 | cy.get('.pdp-input').focus() 52 | cy.contains('10').first().click() 53 | cy.get('.pdp-input').focus() 54 | cy.get('.pdp-header .top button').click() 55 | cy.get('.pdp-month').should('contain.text', 'شهریور') 56 | cy.get('.start-range').should('contain.text', '20') 57 | }) 58 | 59 | it('disable dates and change locale', () => { 60 | cy.changeProps('locale', 'fa,en') 61 | cy.changeProps('disable', ['1399/10/5', '1399/9/20', '1399/7/1']) 62 | cy.visit('/') 63 | cy.get('.pdp-input').focus() 64 | cy.get('button.pdp-year').first().click() 65 | cy.get('li').contains('1399').click() 66 | cy.get('button.pdp-month').first().click() 67 | cy.get('.pdp-select-month > :nth-child(10)').click() 68 | cy.get('[data-column="0"] .pdp-day[value="5"]').should('have.attr', 'class').and('match', /disabled/) 69 | cy.get('.pdp-arrow').first().click() 70 | cy.get('[data-column="0"] .pdp-day[value="20"]').should('have.attr', 'class').and('match', /disabled/) 71 | cy.get('.pdp-arrow').first().click() 72 | cy.get('.pdp-arrow').first().click() 73 | cy.get('[data-column="0"] .pdp-day[value="1"]').should('have.attr', 'class').and('match', /disabled/) 74 | cy.get('.pdp-header .top button').click() 75 | cy.get('button.pdp-year').first().click() 76 | cy.get('li').contains('2020').click() 77 | cy.get('button.pdp-month').first().click() 78 | cy.get('li').contains('September').click() 79 | cy.get('[data-column="0"] .pdp-day[value="22"]').should('have.attr', 'class').and('match', /disabled/) 80 | cy.get('.pdp-arrow').last().click() 81 | cy.get('.pdp-arrow').last().click() 82 | cy.get('.pdp-arrow').last().click() 83 | cy.get('[data-column="0"] .pdp-day[value="10"]').should('have.attr', 'class').and('match', /disabled/) 84 | cy.get('[data-column="0"] .pdp-day[value="25"]').should('have.attr', 'class').and('match', /disabled/) 85 | }) 86 | 87 | it('disable datetimes and change locale', () => { 88 | cy.changeProps('type', 'datetime') 89 | cy.changeProps('disable', ['1399/10/5 10:10', '1399/10/5 10:11', '1399/10/5 10:12']) 90 | cy.visit('/') 91 | cy.get('.pdp-input').focus() 92 | cy.get('button.pdp-year').first().click() 93 | cy.get('li').contains('1399').click() 94 | cy.get('button.pdp-month').first().click() 95 | cy.get('.pdp-select-month > :nth-child(10)').click() 96 | cy.get('[data-column="0"] .pdp-day[value="5"]').click() 97 | cy.get('.pdp-input').focus() 98 | cy.selectTime(10, 10) 99 | cy.get('.pdp-time .pdp-moment > div').first().should('have.attr', 'class').and('match', /disabled/) 100 | cy.get('.pdp-time .pdp-moment button').eq(2).click() 101 | cy.get('.pdp-time .pdp-moment > div').first().should('have.attr', 'class').and('match', /disabled/) 102 | cy.get('.pdp-time .pdp-moment button').eq(2).click() 103 | cy.get('.pdp-time .pdp-moment > div').first().should('have.attr', 'class').and('match', /disabled/) 104 | cy.get('.pdp-header .top button').click() 105 | cy.get('button.pdp-year').first().click() 106 | cy.get('li').contains('2020').click() 107 | cy.get('button.pdp-month').first().click() 108 | cy.get('li').contains('September').click() 109 | cy.get('.pdp-arrow').last().click() 110 | cy.get('.pdp-arrow').last().click() 111 | cy.get('.pdp-arrow').last().click() 112 | cy.get('.pdp-time .pdp-moment > div').first().should('have.attr', 'class').and('match', /disabled/) 113 | cy.get('.pdp-time .pdp-moment button').eq(3).click() 114 | cy.get('.pdp-time .pdp-moment > div').first().should('have.attr', 'class').and('match', /disabled/) 115 | cy.get('.pdp-time .pdp-moment button').eq(3).click() 116 | cy.get('.pdp-time .pdp-moment > div').first().should('have.attr', 'class').and('match', /disabled/) 117 | }) 118 | 119 | it('select single datetime and change locale', () => { 120 | cy.changeProps('from', '1399') 121 | cy.changeProps('to', '1399/6/31') 122 | cy.changeProps('type', 'datetime') 123 | cy.changeProps('locale', 'en,fa') 124 | cy.visit('/') 125 | cy.get('.pdp-input').focus() 126 | cy.get('.pdp-day').contains('10').first().click() 127 | cy.get('.pdp-input').focus() 128 | cy.selectTime(10, 10) 129 | cy.get('.pdp-header .top button').click() 130 | cy.get('.pdp-month').should('contain.text', 'شهریور') 131 | cy.get('.start-range').should('contain.text', '20') 132 | cy.get('.pdp-time .pdp-moment > div .hour').first().should('contain.text', '10') 133 | cy.get('.pdp-time .pdp-moment > div .minute').first().should('contain.text', '10') 134 | }) 135 | 136 | it('select range datetime and change locale', () => { 137 | cy.changeProps('from', '1399') 138 | cy.changeProps('to', '1399/6/31') 139 | cy.changeProps('locale', 'fa,en') 140 | cy.changeProps('mode', 'range') 141 | cy.visit('/') 142 | cy.get('.pdp-input').focus() 143 | cy.get('.pdp-day').contains('15').first().click() 144 | cy.get('.pdp-day').contains('20').first().click() 145 | cy.get('.pdp-input').focus() 146 | cy.selectTime(10, 10) 147 | cy.selectTime(20, 20, 'last') 148 | cy.get('.pdp-header .top button').click() 149 | cy.contains('September') 150 | cy.get('.start-range').should('contain.text', '5') 151 | cy.get('.end-range').should('contain.text', '10') 152 | cy.get('.pdp-time .pdp-moment > div .hour').first().should('contain.text', '10') 153 | cy.get('.pdp-time .pdp-moment > div .minute').first().should('contain.text', '10') 154 | cy.get('.pdp-time .pdp-moment > div .hour').last().should('contain.text', '20') 155 | cy.get('.pdp-time .pdp-moment > div .minute').last().should('contain.text', '20') 156 | }) 157 | 158 | it('today button', () => { 159 | cy.changeProps('type', 'datetime') 160 | cy.visit('/') 161 | cy.selectDate() 162 | let date = new Date() 163 | cy.get('.pdp-input').focus() 164 | cy.get('.pdp-moment button:first-child').click({ multiple: true }) 165 | cy.get('.hour').last().should('contain.text', date.getHours()) 166 | cy.get('.minute').last().should('contain.text', date.getMinutes()) 167 | cy.get('.pdp-today').click() 168 | cy.get('.pdp-day.today').should('have.class', 'tada') 169 | cy.get('.hour').should('contain.text', date.getHours()) 170 | cy.get('.minute').should('contain.text', date.getMinutes()) 171 | }) 172 | }) 173 | -------------------------------------------------------------------------------- /cypress/integration/props.spec.js: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | describe('from and to props', () => { 4 | beforeEach(() => { 5 | cy.changeProps() 6 | cy.changeSlots() 7 | }) 8 | 9 | it('time - with click', () => { 10 | cy.changeProps('type', 'time') 11 | cy.changeProps('from', '10:10') 12 | cy.changeProps('to', '20:20') 13 | cy.visit('/') 14 | cy.get('.pdp-input').focus() 15 | for (let i = 1; i <= 24; i++) { 16 | cy.get('.pdp-moment button').eq(1).click() 17 | cy.get('.pdp-moment button').eq(3).click() 18 | cy.get('.pdp-moment button').eq(4).click() 19 | cy.get('.pdp-moment button').eq(6).click() 20 | } 21 | cy.get('.pdp-input').should('have.value', '10:10 - 20:20') 22 | }) 23 | 24 | it('time - with type', () => { 25 | cy.changeProps('type', 'time') 26 | cy.visit('/') 27 | cy.get('.pdp-input').type('8:10{enter}') 28 | cy.get('.pdp-input').should('have.value', '8:10') 29 | cy.get('.pdp-input').clear().type('10:10{enter}') 30 | cy.get('.pdp-input').should('have.value', '') 31 | cy.get('.pdp-input').type('21:20{enter}') 32 | cy.get('.pdp-input').should('have.value', '21:20') 33 | cy.get('.pdp-input').clear().type('20:20{enter}') 34 | cy.get('.pdp-input').should('have.value', '10:10 - 20:20') 35 | }) 36 | 37 | it('datetime - with click', () => { 38 | cy.changeProps('type', 'datetime') 39 | cy.changeProps('from', '1399/6/1 10:10') 40 | cy.changeProps('to', '1399/6/31 20:20') 41 | cy.visit('/') 42 | cy.get('.pdp-input').focus() 43 | cy.get('.pdp-day[value="1"]').first().click() 44 | cy.get('.pdp-day[value="31"]').first().click() 45 | cy.get('.pdp-input').focus() 46 | for (let i = 1; i <= 24; i++) { 47 | cy.get('.pdp-moment button').eq(1).click() 48 | cy.get('.pdp-moment button').eq(3).click() 49 | cy.get('.pdp-moment button').eq(4).click() 50 | cy.get('.pdp-moment button').eq(6).click() 51 | } 52 | cy.get('.pdp-input').should('have.value', '1399/06/01 10:10 - 1399/06/31 20:20') 53 | }) 54 | 55 | it('datetime - with type', () => { 56 | cy.visit('/') 57 | cy.get('.pdp-input').type('1399/6/1 8:10{enter}') 58 | cy.get('.pdp-input').should('have.value', '1399/6/1 8:10') 59 | cy.get('.pdp-input').clear().type('1399/6/1 10:10{enter}') 60 | cy.get('.pdp-input').should('have.value', '') 61 | cy.get('.pdp-input').type('1399/6/31 21:20{enter}') 62 | cy.get('.pdp-input').should('have.value', '1399/6/31 21:20') 63 | cy.get('.pdp-input').clear().type('1399/6/31 20:20{enter}') 64 | cy.get('.pdp-input').should('have.value', '1399/06/01 10:10 - 1399/06/31 20:20') 65 | }) 66 | 67 | it('click on dates', () => { 68 | cy.changeProps('type', 'date') 69 | cy.changeProps('from', '1399') 70 | cy.changeProps('to', '1399/6/31') 71 | cy.visit('/') 72 | cy.get('.pdp-input').focus() 73 | for (let i = 1; i <= 30; i++) { 74 | cy.get(`.pdp-days [value="${i}"]`).last().click() 75 | } 76 | cy.get('.pdp-input').should('have.value', '') 77 | }) 78 | 79 | it('click on arrows', () => { 80 | cy.visit('/') 81 | cy.get('.pdp-input').focus() 82 | cy.get('.pdp-arrow').last().click() 83 | cy.contains('شهریور') 84 | 85 | cy.visit('/') 86 | cy.get('.pdp-input').focus() 87 | for (let i = 0; i < 6; i++) { 88 | cy.get('.pdp-arrow').first().click() 89 | } 90 | cy.get('.pdp-month').should('not.have.text', 'اسفند') 91 | }) 92 | 93 | it('with arrow keys', () => { 94 | cy.visit('/') 95 | cy.get('.pdp-input') 96 | .type('{downarrow}{downarrow}{downarrow}{downarrow}{downarrow}{downarrow}') 97 | .type('{leftarrow}{leftarrow}{leftarrow}') 98 | cy.get('.hover').should('contain.text', '31') 99 | 100 | cy.get('.pdp-month').first().click() 101 | cy.contains('فروردین').click() 102 | cy.get('.pdp-input').focus().type('{downarrow}{rightarrow}') 103 | cy.get('.hover').should('contain.text', '1') 104 | }) 105 | 106 | it('with type the date', () => { 107 | cy.visit('/') 108 | cy.get('.pdp-input') 109 | .type('1398/12/29{enter}') 110 | .should('have.value', '1398/12/29') 111 | .clear() 112 | .type('1399/7/1{enter}') 113 | .should('have.value', '1399/7/1') 114 | }) 115 | }) 116 | 117 | describe('locale prop', () => { 118 | it('fa and en', () => { 119 | cy.changeProps('locale', 'fa,en') 120 | cy.visit('/') 121 | cy.get('.pdp-input').focus() 122 | cy.get('.pdp-header .top div').should('contain.text', 'تقویم شمسی') 123 | cy.get('.pdp-header .top button').click() 124 | cy.get('.pdp-header .top div').should('contain.text', 'Gregorian Calendar') 125 | }) 126 | 127 | it('en and fa', () => { 128 | cy.changeProps('locale', 'en,fa') 129 | cy.visit('/') 130 | cy.get('.pdp-input').focus() 131 | cy.get('.pdp-header .top div').should('contain.text', 'Gregorian Calendar') 132 | cy.get('.pdp-header .top button').click() 133 | cy.get('.pdp-header .top div').should('contain.text', 'تقویم شمسی') 134 | }) 135 | 136 | it('en', () => { 137 | cy.changeProps('locale', 'en') 138 | cy.visit('/') 139 | cy.get('.pdp-input').focus() 140 | cy.contains('September') 141 | 142 | }) 143 | 144 | it('fa', () => { 145 | cy.changeProps('locale', 'fa,en') 146 | cy.visit('/') 147 | cy.get('.pdp-input').focus() 148 | cy.contains('شهریور') 149 | }) 150 | }) 151 | 152 | describe('localeConfig prop', () => { 153 | it('change default properties', () => { 154 | cy.changeProps('locale-config', { 155 | fa: { 156 | inputFormat: 'jMM/jDD', 157 | translations: { 158 | label: "فارسی", 159 | }, 160 | }, 161 | en: { 162 | inputFormat: 'YYYY', 163 | translations: { 164 | label: "انگلیسی", 165 | }, 166 | }, 167 | }) 168 | cy.changeProps('locale', 'fa,en') 169 | cy.visit('/') 170 | cy.selectRangeDate(); 171 | cy.get('.pdp-input').should('have.value', '06/10 - 06/15') 172 | cy.get('.pdp-input').focus() 173 | cy.get('.pdp-header .top div').should('contain.text', 'تقویم شمسی') 174 | cy.get('.pdp-header .top button').should('contain.text', 'انگلیسی').click() 175 | cy.get('.pdp-input').should('have.value', '2020 - 2020') 176 | cy.get('.pdp-header .top div').should('contain.text', 'Gregorian Calendar') 177 | cy.get('.pdp-header .top button').should('contain.text', 'فارسی') 178 | }) 179 | 180 | it('add arabic language', () => { 181 | cy.changeProps('locale-config', { 182 | ar: { 183 | calendar: "gregorian", 184 | weekdays: ["ح ", "ن ", "ث ", "ر ", "خ ", "ج ", "س"], 185 | months: [ 186 | "الفروردین", 187 | "الاردیبهشت", 188 | "الخرداد", 189 | "التیر", 190 | "المرداد", 191 | "الشهریور", 192 | "المهر", 193 | "الآبان", 194 | "الآذر", 195 | "الدی", 196 | "البهمن", 197 | "الاسفند", 198 | ], 199 | dir: { 200 | input: "rtl", 201 | picker: "ltr", 202 | }, 203 | translations: { 204 | label: "قمری", 205 | text: "التقویم القمری", 206 | prevMonth: "الماه قبل", 207 | nextMonth: "الماه بعد", 208 | today: "یوم", 209 | submit: "التایید", 210 | }, 211 | inputFormat: { 212 | date: "date", 213 | datetime: "datetime", 214 | time: "time", 215 | }, 216 | displayFormat: { 217 | date: "?D ?MMMM", 218 | datetime: "?D ?MMMM HH:mm", 219 | time: "HH:mm", 220 | }, 221 | }, 222 | }) 223 | cy.changeProps('locale', 'fa,ar') 224 | cy.visit('/') 225 | cy.get('.pdp-input').focus() 226 | cy.get('.pdp-header .top button').should('contain.text', 'قمری').click() 227 | cy.get('.pdp-header .top div').should('contain.text', 'التقویم القمری') 228 | cy.get('.pdp-weekday').each(el => { 229 | ["ح ", "ن ", "ث ", "ر ", "خ ", "ج ", "س"].includes(el.text()) 230 | }) 231 | cy.get('.pdp-month').first().should('contain.text', 'الآذر') 232 | }) 233 | }) 234 | 235 | describe('formats', () => { 236 | it('format prop', () => { 237 | cy.changeProps('format', 'YYYY-MM-DD') 238 | cy.visit('/') 239 | cy.selectRangeDate() 240 | cy.get('.show').should('have.text', 'date is: [\n "2020-08-31",\n "2020-09-05"\n]') 241 | }) 242 | 243 | it('change format prop', () => { 244 | cy.changeProps('format', 'YY-M-D') 245 | cy.visit('/') 246 | cy.selectRangeDate() 247 | cy.get('.show').should('have.text', 'date is: [\n "20-8-31",\n "20-9-5"\n]') 248 | }) 249 | 250 | it('inputFormat prop', () => { 251 | cy.changeProps('input-format', 'jYYYY/jMM/jDD') 252 | cy.visit('/') 253 | cy.selectRangeDate() 254 | cy.get('.pdp-input').should('have.value', '1399/06/10 - 1399/06/15') 255 | }) 256 | 257 | it('change inputFormat prop', () => { 258 | cy.changeProps('input-format', 'jYY/jM/jD') 259 | cy.visit('/') 260 | cy.selectRangeDate() 261 | cy.get('.pdp-input').should('have.value', '99/6/10 - 99/6/15') 262 | }) 263 | 264 | it('displayFormat prop', () => { 265 | cy.changeProps('display-format', 'jD jMMMM') 266 | cy.visit('/') 267 | cy.selectRangeDate() 268 | cy.get('.pdp-input').focus() 269 | cy.get('.pdp-footer > div').contains('10 شهریور - 15 شهریور') 270 | }) 271 | 272 | it('change displayFormat prop', () => { 273 | cy.changeProps('display-format', 'jD jMMMM') 274 | cy.visit('/') 275 | cy.selectRangeDate() 276 | cy.get('.pdp-input').focus() 277 | cy.get('.pdp-footer > div').contains('10 شهریور - 15 شهریور') 278 | }) 279 | }) 280 | 281 | describe("type prop", () => { 282 | it('datetime', () => { 283 | cy.changeProps('type', 'datetime') 284 | cy.visit('/') 285 | cy.get('.pdp-input').focus() 286 | cy.get('.pdp-date').should('exist') 287 | cy.get('.pdp-time').should('exist') 288 | }) 289 | 290 | it('time', () => { 291 | cy.changeProps('from', undefined) 292 | cy.changeProps('to', undefined) 293 | cy.changeProps('type', 'time') 294 | cy.visit('/') 295 | cy.get('.pdp-input').focus() 296 | cy.get('.pdp-date').should('not.exist') 297 | cy.get('.pdp-time').should('exist') 298 | }) 299 | 300 | it('date', () => { 301 | cy.changeProps('from', '1399') 302 | cy.changeProps('to', '1399/6/31') 303 | cy.changeProps('type', 'date') 304 | cy.visit('/') 305 | cy.get('.pdp-input').focus() 306 | cy.get('.pdp-date').should('exist') 307 | cy.get('.pdp-time').should('not.exist') 308 | }) 309 | }) 310 | 311 | describe('show prop', () => { 312 | it('show prop', () => { 313 | cy.changeProps('show', false) 314 | cy.visit('/') 315 | cy.get('.pdp-picker').should('not.exist') 316 | cy.get('.show-picker').click() 317 | cy.get('.pdp-picker').should('exist') 318 | cy.get('.pdp-overlay').click({ force: true }) 319 | cy.get('.pdp-picker').should('not.exist') 320 | }) 321 | }) 322 | 323 | describe('label prop', () => { 324 | it('label not exist', () => { 325 | cy.visit('/') 326 | cy.get('.pdp-label').should('not.exist') 327 | }) 328 | it('label exist', () => { 329 | cy.changeProps('label', 'select date:') 330 | cy.visit('/') 331 | cy.get('.pdp-label').should('exist').should('contain.text', 'select date:') 332 | }) 333 | }) 334 | 335 | describe('clickOn prop', () => { 336 | it('with none value', () => { 337 | cy.changeProps('click-on', 'none') 338 | cy.visit('/') 339 | cy.get('.pdp-picker').should('not.exist') 340 | cy.get('.pdp-input').focus() 341 | cy.get('.pdp-picker').should('not.exist') 342 | 343 | cy.get('.pdp-input').click() 344 | cy.get('.pdp-picker').should('not.exist') 345 | 346 | cy.get('.pdp-icon').click() 347 | cy.get('.pdp-picker').should('not.exist') 348 | }) 349 | 350 | it('with icon value', () => { 351 | cy.changeProps('click-on', 'icon') 352 | cy.visit('/') 353 | cy.get('.pdp-picker').should('not.exist') 354 | cy.get('.pdp-input').focus() 355 | cy.get('.pdp-picker').should('not.exist') 356 | 357 | cy.get('.pdp-input').click() 358 | cy.get('.pdp-picker').should('not.exist') 359 | 360 | cy.get('.pdp-icon').click() 361 | cy.get('.pdp-picker').should('exist') 362 | cy.get('.pdp-overlay').click({ force: true }) 363 | cy.get('.pdp-picker').should('not.exist') 364 | }) 365 | 366 | it('with input value', () => { 367 | cy.changeProps('click-on', 'input') 368 | cy.visit('/') 369 | cy.get('.pdp-picker').should('not.exist') 370 | cy.get('.pdp-input').focus() 371 | cy.get('.pdp-picker').should('exist') 372 | cy.get('.pdp-overlay').click({ force: true }) 373 | cy.get('.pdp-picker').should('not.exist') 374 | 375 | cy.get('.pdp-input').click() 376 | cy.get('.pdp-picker').should('exist') 377 | cy.get('.pdp-overlay').click({ force: true }) 378 | cy.get('.pdp-picker').should('not.exist') 379 | 380 | cy.get('.pdp-icon').click() 381 | cy.get('.pdp-picker').should('not.exist') 382 | }) 383 | 384 | it('with all value', () => { 385 | cy.changeProps('click-on', 'all') 386 | cy.visit('/') 387 | cy.get('.pdp-picker').should('not.exist') 388 | cy.get('.pdp-input').focus() 389 | cy.get('.pdp-picker').should('exist') 390 | cy.get('.pdp-overlay').click({ force: true }) 391 | cy.get('.pdp-picker').should('not.exist') 392 | 393 | cy.get('.pdp-input').click() 394 | cy.get('.pdp-picker').should('exist') 395 | cy.get('.pdp-overlay').click({ force: true }) 396 | cy.get('.pdp-picker').should('not.exist') 397 | 398 | cy.get('.pdp-icon').click() 399 | cy.get('.pdp-picker').should('exist') 400 | cy.get('.pdp-overlay').click({ force: true }) 401 | cy.get('.pdp-picker').should('not.exist') 402 | }) 403 | }) 404 | 405 | describe('div class attribute', () => { 406 | it('remove class', () => { 407 | cy.changeProps('div-class', '') 408 | cy.visit('/') 409 | cy.get('.pdp-group').should('not.exist') 410 | }) 411 | 412 | it('replace class', () => { 413 | cy.changeProps('div-class', 'replace-class') 414 | cy.visit('/') 415 | cy.get('.replace-class').should('exist') 416 | }) 417 | 418 | it('add class', () => { 419 | cy.changeProps('div-class', 'pdp-group add-class') 420 | cy.visit('/') 421 | cy.get('.pdp-group').should('have.class', 'add-class') 422 | }) 423 | }) 424 | 425 | describe('input class attribute', () => { 426 | it('remove class', () => { 427 | cy.changeProps('input-class', '') 428 | cy.visit('/') 429 | cy.get('.pdp-input').should('not.exist') 430 | }) 431 | 432 | it('replace class', () => { 433 | cy.changeProps('input-class', 'replace-class') 434 | cy.visit('/') 435 | cy.get('.replace-class').should('exist') 436 | }) 437 | 438 | it('add class', () => { 439 | cy.changeProps('input-class', 'pdp-input add-class') 440 | cy.visit('/') 441 | cy.get('.pdp-input').should('have.class', 'add-class') 442 | }) 443 | }) 444 | 445 | describe('column prop', () => { 446 | let type = 'date' 447 | for (let i = 0; i < 2; i++) { 448 | for (let j = 1; j <= 3; j++) { 449 | it('number value in ' + type + ' type => ' + j, () => { 450 | cy.changeProps('column', j) 451 | cy.visit('/') 452 | cy.get('.pdp-input').focus() 453 | cy.get('.pdp-column').should('have.length', j) 454 | }) 455 | } 456 | if (i == 1) 457 | break 458 | beforeEach(() => { 459 | cy.changeProps('type', 'time') 460 | }) 461 | type = 'time' 462 | } 463 | 464 | let sizes = ['iphone-4', 'ipad-2', 'macbook-15'] 465 | beforeEach(() => { 466 | cy.changeProps('column', { '576': 1, '992': 2, '2000': 3 }) 467 | }) 468 | 469 | for (let i = 0; i < 2; i++) { 470 | it('object value in ' + type + ' type', () => { 471 | cy.visit('/') 472 | sizes.forEach((size, index) => { 473 | cy.viewport(size) 474 | cy.get('.pdp-input').focus() 475 | cy.get('.pdp-column').should('have.length', index + 1) 476 | }) 477 | }) 478 | if (i == 1) 479 | break 480 | beforeEach(() => { 481 | cy.changeProps('type', 'date') 482 | }) 483 | type = 'date' 484 | } 485 | }) 486 | 487 | describe('alternative field', () => { 488 | it('not exist', () => { 489 | cy.visit('/') 490 | cy.get('input[type="hidden"]').should('not.exist') 491 | }) 492 | 493 | it('exist - String', () => { 494 | cy.changeProps('alt-name', 'date') 495 | cy.visit('/') 496 | cy.get('input[type="hidden"]').should('exist') 497 | cy.selectRangeDate() 498 | cy.get('input[type="hidden"]').should('have.value', '20-8-31,20-9-5') 499 | }) 500 | 501 | it('exist - Array', () => { 502 | cy.changeProps('alt-name', 'date[]') 503 | cy.visit('/') 504 | cy.selectRangeDate() 505 | cy.get('input[type="hidden"]').first().should('have.value', '20-8-31') 506 | cy.get('input[type="hidden"]').last().should('have.value', '20-9-5') 507 | }) 508 | 509 | it('without alt-format', () => { 510 | cy.changeProps('format', 'YYYY MM') 511 | cy.visit('/') 512 | cy.selectRangeDate() 513 | cy.get('input[type="hidden"]').first().should('have.value', '2020 08') 514 | cy.get('input[type="hidden"]').last().should('have.value', '2020 09') 515 | }) 516 | 517 | it('with alt-format', () => { 518 | cy.changeProps('alt-format', 'MM YYYY DD') 519 | cy.visit('/') 520 | cy.selectRangeDate() 521 | cy.get('input[type="hidden"]').first().should('have.value', '08 2020 31') 522 | cy.get('input[type="hidden"]').last().should('have.value', '09 2020 05') 523 | }) 524 | }) 525 | 526 | describe('disable prop', () => { 527 | it('String in time type', () => { 528 | cy.changeProps('type', 'time') 529 | cy.changeProps('from', undefined) 530 | cy.changeProps('to', undefined) 531 | cy.changeProps('disable', '10:10') 532 | cy.visit('/') 533 | cy.get('.pdp-input').focus() 534 | cy.selectTime(10, 10) 535 | cy.get('.pdp-time .pdp-moment > div').first().should('have.attr', 'class').and('match', /disabled/) 536 | }) 537 | 538 | it('RegExp in time type', () => { 539 | cy.changeProps('disableR', '10:*') 540 | cy.visit('/') 541 | cy.get('.pdp-input').focus() 542 | cy.selectTime(10, 0) 543 | cy.get('.pdp-time .pdp-moment > div').first().should('have.attr', 'class').and('match', /disabled/) 544 | for (let i = 1; i <= 59; i++) { 545 | cy.get('.pdp-time .pdp-moment button').eq(3).click() 546 | cy.get('.pdp-time .pdp-moment > div').first().should('have.attr', 'class').and('match', /disabled/) 547 | } 548 | }) 549 | 550 | it('Array in time type', () => { 551 | cy.changeProps('disable', ['10:10', '10:11', '10:12']) 552 | cy.changeProps('disableR', undefined) 553 | cy.visit('/') 554 | cy.get('.pdp-input').focus() 555 | cy.selectTime(10, 10) 556 | cy.get('.pdp-time .pdp-moment > div').first().should('have.attr', 'class').and('match', /disabled/) 557 | cy.get('.pdp-time .pdp-moment button').eq(2).click() 558 | cy.get('.pdp-time .pdp-moment > div').first().should('have.attr', 'class').and('match', /disabled/) 559 | cy.get('.pdp-time .pdp-moment button').eq(2).click() 560 | cy.get('.pdp-time .pdp-moment > div').first().should('have.attr', 'class').and('match', /disabled/) 561 | }) 562 | 563 | it('Function in time type', () => { 564 | cy.changeProps('disableF', '(date)=>date.hour()==10') 565 | cy.visit('/') 566 | cy.get('.pdp-input').focus() 567 | cy.selectTime(10, 0) 568 | cy.get('.pdp-time .pdp-moment > div').first().should('have.attr', 'class').and('match', /disabled/) 569 | for (let i = 1; i <= 59; i++) { 570 | cy.get('.pdp-time .pdp-moment button').eq(3).click() 571 | cy.get('.pdp-time .pdp-moment > div').first().should('have.attr', 'class').and('match', /disabled/) 572 | } 573 | }) 574 | 575 | it('String in datetime type', () => { 576 | cy.changeProps('type', 'datetime') 577 | cy.changeProps('from', '1399') 578 | cy.changeProps('to', '1399/6/31') 579 | cy.changeProps('disableF', undefined) 580 | cy.changeProps('disable', '1399/6/15 10:10') 581 | cy.visit('/') 582 | cy.get('.pdp-input').focus() 583 | cy.get('.pdp-day[value="15"]').first().click() 584 | cy.selectTime(10, 10) 585 | cy.get('.pdp-time .pdp-moment > div').first().should('have.attr', 'class').and('match', /disabled/) 586 | }) 587 | 588 | it('RegExp in datetime type', () => { 589 | cy.changeProps('disableR', '1399/5/2 10:*') 590 | cy.visit('/') 591 | cy.get('.pdp-input').focus() 592 | cy.get('.pdp-arrow').first().click(); 593 | cy.get('.pdp-day[value="2"]').first().click() 594 | cy.selectTime(10, 0) 595 | cy.get('.pdp-time .pdp-moment > div').first().should('have.attr', 'class').and('match', /disabled/) 596 | for (let i = 1; i <= 59; i++) { 597 | cy.get('.pdp-time .pdp-moment > div').first().should('have.attr', 'class').and('match', /disabled/) 598 | } 599 | }) 600 | 601 | it('Array in datetime type', () => { 602 | cy.changeProps('disable', ['1399/6/10 10:10', '1399/6/10 10:11', '1399/6/10 10:12', '1399/6/11']) 603 | cy.changeProps('disableR', undefined) 604 | cy.visit('/') 605 | cy.get('.pdp-input').focus() 606 | cy.get('[data-column="0"] .pdp-day[value="11"]').should('have.attr', 'class').and('match', /disabled/) 607 | cy.get('[data-column="0"] .pdp-day[value="10"]').click() 608 | cy.selectTime(10, 10) 609 | cy.get('.pdp-time .pdp-moment > div').first().should('have.attr', 'class').and('match', /disabled/) 610 | cy.get('.pdp-time .pdp-moment button').eq(2).click() 611 | cy.get('.pdp-time .pdp-moment > div').first().should('have.attr', 'class').and('match', /disabled/) 612 | cy.get('.pdp-time .pdp-moment button').eq(2).click() 613 | cy.get('.pdp-time .pdp-moment > div').first().should('have.attr', 'class').and('match', /disabled/) 614 | }) 615 | 616 | it('Function in datetime type', () => { 617 | cy.changeProps('disableF', '(date)=>date.hour()==10') 618 | cy.visit('/') 619 | cy.get('.pdp-input').focus() 620 | cy.get('[data-column="0"] .pdp-day[value="10"]').click() 621 | cy.selectTime(10, 0) 622 | cy.get('.pdp-time .pdp-moment > div').first().should('have.attr', 'class').and('match', /disabled/) 623 | for (let i = 1; i <= 59; i++) { 624 | cy.get('.pdp-time .pdp-moment button').eq(3).click() 625 | cy.get('.pdp-time .pdp-moment > div').first().should('have.attr', 'class').and('match', /disabled/) 626 | } 627 | }) 628 | 629 | it('String in date type', () => { 630 | cy.changeProps('type', 'date') 631 | cy.changeProps('disableF', undefined) 632 | cy.changeProps('disable', '1399/6/15') 633 | cy.visit('/') 634 | cy.get('.pdp-input').focus() 635 | cy.get('.pdp-day[value="15"]').should('have.attr', 'class', 'pdp-day disabled') 636 | }) 637 | 638 | it('RegExp in date type', () => { 639 | cy.changeProps('disableR', '1399/5/*/') 640 | cy.visit('/') 641 | cy.get('.pdp-input').focus() 642 | cy.get('.pdp-arrow').first().click(); 643 | for (let i = 1; i <= 31; i++) { 644 | cy.get(`[data-column="0"] .pdp-day[value="${i}"]`).should('have.attr', 'class').and('match', /disabled/) 645 | } 646 | }) 647 | 648 | it('Array in date type', () => { 649 | cy.changeProps('disable', ['1399/6/10', '1399/6/15', '1399/6/20']) 650 | cy.changeProps('disableR', undefined) 651 | cy.visit('/') 652 | cy.get('.pdp-input').focus() 653 | cy.get('[data-column="0"] .pdp-day[value="10"]').should('have.attr', 'class').and('match', /disabled/) 654 | cy.get('[data-column="0"] .pdp-day[value="15"]').should('have.attr', 'class').and('match', /disabled/) 655 | cy.get('[data-column="0"] .pdp-day[value="20"]').should('have.attr', 'class').and('match', /disabled/) 656 | }) 657 | 658 | it('Function in date type', () => { 659 | cy.changeProps('disableF', '(date)=>date.date()==5') 660 | cy.visit('/') 661 | cy.get('.pdp-input').focus() 662 | for (let i = 0; i < 5; i++) { 663 | cy.get('[data-column="0"] .pdp-day[value="5"]').should('have.attr', 'class').and('match', /disabled/) 664 | cy.get('.pdp-arrow').first().click(); 665 | } 666 | }) 667 | }) 668 | 669 | describe('mode prop', () => { 670 | it('single in date type', () => { 671 | cy.changeProps('mode', 'single') 672 | cy.visit('/') 673 | cy.selectDate() 674 | cy.get('.pdp-input').should('have.value', '99/6/10') 675 | }) 676 | 677 | it('single in time type', () => { 678 | cy.changeProps('from', undefined) 679 | cy.changeProps('to', undefined) 680 | cy.changeProps('input-format', undefined) 681 | cy.changeProps('type', 'time') 682 | cy.visit('/') 683 | cy.get('.pdp-input').focus() 684 | cy.selectTime(10, 10) 685 | cy.get('.pdp-input').should('have.value', '10:10') 686 | }) 687 | 688 | it('range in time type', () => { 689 | cy.changeProps('mode', 'range') 690 | cy.visit('/') 691 | cy.get('.pdp-input').focus() 692 | cy.selectTime(10, 10) 693 | cy.selectTime(20, 20, 'last') 694 | cy.get('.pdp-input').should('have.value', '10:10 - 20:20') 695 | }) 696 | 697 | it('range in date type', () => { 698 | cy.changeProps('from', '1399') 699 | cy.changeProps('to', '1399/6/31') 700 | cy.changeProps('type', 'date') 701 | cy.changeProps('input-format', 'jYY/jM/jD') 702 | cy.visit('/') 703 | cy.selectRangeDate() 704 | cy.get('.pdp-input').should('have.value', '99/6/10 - 99/6/15') 705 | }) 706 | }) 707 | 708 | describe('clearable prop', () => { 709 | it('without clearable', () => { 710 | cy.visit('/') 711 | cy.get('.pdp-input').focus() 712 | cy.get('.pdp-clear').should('not.exist') 713 | }) 714 | it('with clearable', () => { 715 | cy.changeProps('clearable', true) 716 | cy.changeProps('mode', 'single') 717 | cy.visit('/') 718 | cy.selectDate() 719 | cy.get('.pdp-input').should('have.value', '99/6/10') 720 | cy.get('.pdp-clear').click() 721 | cy.get('.pdp-input').should('not.have.value') 722 | cy.changeProps('mode', 'range') 723 | cy.reload() 724 | cy.get('.pdp-input').focus() 725 | cy.get('.pdp-clear').should('exist') 726 | cy.selectRangeDate() 727 | cy.get('.pdp-input').should('have.value', '99/6/10 - 99/6/15') 728 | cy.get('.pdp-clear').click() 729 | cy.get('.pdp-input').should('not.have.value') 730 | }) 731 | }) 732 | 733 | describe('autoSubmit prop', () => { 734 | it('true value in date type', () => { 735 | cy.changeProps('auto-submit', true) 736 | cy.visit('/') 737 | cy.selectRangeDate() 738 | cy.get('.pdp-picker').should('not.exist') 739 | }) 740 | 741 | it('true value in time type', () => { 742 | cy.changeProps('type', 'time') 743 | cy.changeProps('format', undefined) 744 | cy.changeProps('from', undefined) 745 | cy.changeProps('to', undefined) 746 | cy.visit('/') 747 | cy.get('.pdp-input').focus() 748 | cy.selectTime(10, 10) 749 | cy.get('.status').should('contain.text', '10:10') 750 | }) 751 | 752 | it('false value in time type', () => { 753 | cy.changeProps('auto-submit', false) 754 | cy.visit('/') 755 | cy.get('.pdp-input').focus() 756 | cy.selectTime(10, 10) 757 | cy.selectTime(20, 20, 'last') 758 | cy.get('.pdp-submit').click() 759 | cy.get('.pdp-picker').should('not.exist') 760 | cy.get('.status').should('contain.text', '10:10,20:20') 761 | }) 762 | 763 | it('false value in date type', () => { 764 | cy.changeProps('format', 'YY-M-D') 765 | cy.changeProps('type', 'date') 766 | cy.visit('/') 767 | cy.selectRangeDate() 768 | cy.get('.pdp-picker').should('exist') 769 | cy.get('.pdp-submit').click() 770 | cy.get('.pdp-picker').should('not.exist') 771 | }) 772 | }) 773 | 774 | describe('change styles', () => { 775 | it('with styles prop', () => { 776 | cy.changeProps('styles', { 'primary-color': 'red', 'secondary-color': 'blue' }) 777 | cy.visit('/') 778 | cy.get('.pdp-input').focus() 779 | cy.get('.pdp-submit').should('have.css', 'background-color', 'rgb(255, 0, 0)') 780 | }) 781 | 782 | it('with style attribute', () => { 783 | cy.changeProps('styles', undefined) 784 | cy.changeProps('style', '--primary-color:red; --secondary-color: blue;') 785 | cy.visit('/') 786 | cy.get('.pdp-input').focus() 787 | cy.get('.pdp-submit').should('have.css', 'background-color', 'rgb(255, 0, 0)') 788 | }) 789 | 790 | it('with color prop', () => { 791 | cy.changeProps('style', undefined) 792 | cy.changeProps('color', 'red') 793 | cy.visit('/') 794 | cy.get('.pdp-input').focus() 795 | cy.get('.pdp-submit').should('have.css', 'background-color', 'rgb(199, 0, 76)') 796 | }) 797 | }) 798 | 799 | describe('modal prop', () => { 800 | it('modal mode', () => { 801 | cy.changeProps('modal', true) 802 | cy.visit('/') 803 | cy.get('.pdp-input').focus() 804 | cy.get('.pdp-modal').should('be.visible') 805 | }) 806 | }) 807 | 808 | describe('attributes', () => { 809 | it('required for input', () => { 810 | cy.changeProps('required', 'required') 811 | cy.visit('/') 812 | cy.get('.pdp-input').should('have.attr', 'required') 813 | }) 814 | 815 | it('placeholder for input', () => { 816 | cy.changeProps('placeholder', 'تاریخ تولد') 817 | cy.visit('/') 818 | cy.get('.pdp-input').should('have.attr', 'placeholder') 819 | }) 820 | 821 | it('readonly for input', () => { 822 | cy.changeProps('readonly', 'readonly') 823 | cy.visit('/') 824 | cy.get('.pdp-input').should('have.attr', 'readonly') 825 | }) 826 | 827 | it('disabled for input', () => { 828 | cy.changeProps('readonly', undefined) 829 | cy.changeProps('disabled', 'disabled') 830 | cy.visit('/') 831 | cy.get('.pdp-input').should('have.attr', 'disabled') 832 | }) 833 | 834 | it('id for input', () => { 835 | cy.changeProps('id', 'input') 836 | cy.visit('/') 837 | cy.get('.pdp-input').should('have.attr', 'id') 838 | }) 839 | 840 | it('id for label', () => { 841 | cy.changeProps('label-id', 'label') 842 | cy.visit('/') 843 | cy.get('.pdp-label').should('have.attr', 'id') 844 | }) 845 | 846 | it('id for div', () => { 847 | cy.changeProps('div-id', 'div') 848 | cy.visit('/') 849 | cy.get('.pdp-group').should('have.attr', 'id') 850 | }) 851 | 852 | it('id for picker', () => { 853 | cy.changeProps('picker-id', 'picker') 854 | cy.visit('/') 855 | cy.get('.pdp-icon').click() 856 | cy.get('.pdp-picker').should('have.attr', 'id') 857 | }) 858 | }) -------------------------------------------------------------------------------- /cypress/integration/select-date.spec.js: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | describe('select date - range', () => { 4 | beforeEach(() => { 5 | cy.changeProps() 6 | cy.changeSlots() 7 | }) 8 | 9 | it('with click on dates', () => { 10 | cy.visit('/') 11 | cy.get('.pdp-input').focus() 12 | cy.contains('10').click() 13 | cy.contains('15').click() 14 | cy.get('.pdp-input').should('have.value', '1399/06/10 - 1399/06/15') 15 | }) 16 | 17 | it('with arrow keys', () => { 18 | cy.visit('/') 19 | cy.tab() 20 | .type('{downarrow}{downarrow}{downarrow}{leftarrow}{leftarrow}{enter}') 21 | .type('{downarrow}{rightarrow}{rightarrow}{enter}') 22 | cy.get('.pdp-input').should('have.value', '1399/06/10 - 1399/06/15') 23 | }) 24 | 25 | it('with type the date', () => { 26 | cy.visit('/') 27 | cy.tab() 28 | .type('1399/06/10{enter}') 29 | .type('1399/06/15{enter}') 30 | cy.get('.pdp-input').should('have.value', '1399/06/10 - 1399/06/15') 31 | }) 32 | }) 33 | 34 | describe('select date - single', () => { 35 | 36 | beforeEach(() => { 37 | cy.changeProps('mode', 'single') 38 | }) 39 | 40 | it('with click on dates', () => { 41 | cy.visit('/') 42 | cy.get('.pdp-input').focus() 43 | cy.contains('10').click() 44 | cy.get('.pdp-input').should('have.value', '1399/06/10') 45 | }) 46 | 47 | it('with arrow keys', () => { 48 | cy.visit('/') 49 | cy.tab() 50 | .type('{downarrow}{downarrow}{downarrow}{leftarrow}{leftarrow}{enter}') 51 | cy.get('.pdp-input').should('have.value', '1399/06/10') 52 | }) 53 | 54 | it('with type the date', () => { 55 | cy.visit('/') 56 | cy.tab() 57 | .type('1399/06/10{enter}') 58 | cy.get('.pdp-input').should('have.value', '1399/06/10') 59 | }) 60 | }) 61 | 62 | describe('select date with disable date - single', () => { 63 | beforeEach(() => { 64 | cy.changeProps('disable', '1399/6/5') 65 | }) 66 | 67 | it('with click on dates', () => { 68 | cy.visit('/') 69 | cy.get('.pdp-input').focus() 70 | cy.contains('5').click() 71 | cy.get('.pdp-input').should('have.value', '') 72 | cy.contains('6').click() 73 | cy.get('.pdp-input').should('have.value', '1399/06/06') 74 | }) 75 | 76 | it('with arrow keys', () => { 77 | cy.visit('/') 78 | cy.tab() 79 | .type('{downarrow}{leftarrow}{leftarrow}{leftarrow}{leftarrow}{leftarrow}{enter}') 80 | cy.get('.pdp-input').should('have.value', '') 81 | cy.get('.pdp-input').type('{leftarrow}{enter}') 82 | cy.get('.pdp-input').should('have.value', '1399/06/06') 83 | }) 84 | 85 | it('with type the date', () => { 86 | cy.visit('/') 87 | cy.tab() 88 | .type('1399/06/05{enter}') 89 | cy.get('.pdp-input').should('have.value', '1399/06/05') 90 | cy.get('.pdp-input').clear().type('1399/06/06{enter}') 91 | cy.get('.pdp-input').should('have.value', '1399/06/06') 92 | cy.get('.pdp-input').focus() 93 | cy.get('.pdp-day.start-range').should('contain.text', '6') 94 | }) 95 | }) 96 | 97 | describe('select date with disable date - range', () => { 98 | beforeEach(() => { 99 | cy.changeProps('disable', '1399/6/5') 100 | cy.changeProps('mode', 'range') 101 | }) 102 | 103 | it('with click on dates', () => { 104 | cy.visit('/') 105 | cy.get('.pdp-input').focus() 106 | cy.contains('5').click() 107 | cy.get('.pdp-input').should('have.value', '') 108 | cy.get('.pdp-day[value="3"]').first().click() 109 | cy.get('.pdp-day.start-range').should('contain.text', '3') 110 | cy.get('.pdp-day[value="6"]').first().click() 111 | cy.get('.pdp-day[value="5"]').first().click() 112 | cy.get('.pdp-day[value="4"]').first().click() 113 | cy.get('.pdp-input').focus().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.visit('/') 119 | cy.tab() 120 | .type('{downarrow}{downarrow}{leftarrow}{leftarrow}{leftarrow}{leftarrow}{enter}') 121 | cy.get('.pdp-input').should('have.value', '') 122 | cy.get('.pdp-input').type('{rightarrow}{rightarrow}{enter}') 123 | cy.get('.pdp-day.start-range').should('contain.text', '3') 124 | cy.get('.pdp-input').type('{leftarrow}{leftarrow}{leftarrow}{enter}') 125 | cy.get('.pdp-input').type('{rightarrow}{enter}') 126 | cy.get('.pdp-input').type('{rightarrow}{enter}') 127 | cy.get('.pdp-input').focus() 128 | cy.get('.pdp-day.end-range').should('contain.text', '4') 129 | }) 130 | 131 | it('with type the date', () => { 132 | cy.visit('/') 133 | cy.tab() 134 | .type('1399/06/05{enter}') 135 | cy.get('.pdp-input').should('have.value', '1399/06/05') 136 | cy.get('.pdp-input').clear().type('1399/06/03{enter}') 137 | cy.get('.pdp-input').should('have.value', '') 138 | cy.get('.pdp-day.start-range').should('contain.text', '3') 139 | cy.get('.pdp-input').type('1399/06/06{enter}') 140 | cy.get('.pdp-input').should('have.value', '1399/06/06') 141 | cy.get('.pdp-input').clear().type('1399/06/05{enter}') 142 | cy.get('.pdp-input').should('have.value', '1399/06/05') 143 | cy.get('.pdp-input').clear().type('1399/06/04{enter}') 144 | cy.get('.pdp-input').should('have.value', '1399/06/03 - 1399/06/04') 145 | cy.get('.pdp-input').focus() 146 | cy.get('.pdp-day.end-range').should('contain.text', '4') 147 | }) 148 | }) 149 | 150 | describe('select date in en locale - range', () => { 151 | beforeEach(() => { 152 | cy.changeProps('locale', 'en') 153 | }) 154 | 155 | it('with click on dates', () => { 156 | cy.visit('/') 157 | cy.get('.pdp-input').focus() 158 | cy.contains('10').click() 159 | cy.contains('15').click() 160 | cy.get('.pdp-input').should('have.value', '2020-09-10 - 2020-09-15') 161 | }) 162 | 163 | it('with arrow keys', () => { 164 | cy.visit('/') 165 | cy.tab() 166 | .type('{downarrow}{downarrow}{downarrow}{leftarrow}{leftarrow}{enter}') 167 | .type('{downarrow}{rightarrow}{rightarrow}{enter}') 168 | cy.get('.pdp-input').should('have.value', '2020-09-06 - 2020-09-15') 169 | }) 170 | 171 | it('with type the date', () => { 172 | cy.visit('/') 173 | cy.tab() 174 | .type('2020-09-10{enter}') 175 | .type('2020-09-15{enter}') 176 | cy.get('.pdp-input').should('have.value', '2020-09-10 - 2020-09-15') 177 | }) 178 | }) 179 | 180 | describe('select date in en locale - single', () => { 181 | beforeEach(() => { 182 | cy.changeProps('mode', 'single') 183 | }) 184 | 185 | it('with click on dates', () => { 186 | cy.visit('/') 187 | cy.get('.pdp-input').focus() 188 | cy.contains('10').click() 189 | cy.get('.pdp-input').should('have.value', '2020-09-10') 190 | }) 191 | 192 | it('with arrow keys', () => { 193 | cy.visit('/') 194 | cy.tab() 195 | .type('{downarrow}{downarrow}{downarrow}{rightarrow}{rightarrow}{enter}') 196 | cy.get('.pdp-input').should('have.value', '2020-09-10') 197 | }) 198 | 199 | it('with type the date', () => { 200 | cy.visit('/') 201 | cy.tab() 202 | .type('2020-09-10{enter}') 203 | cy.get('.pdp-input').should('have.value', '2020-09-10') 204 | }) 205 | }) -------------------------------------------------------------------------------- /cypress/integration/select-datetime.spec.js: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | describe('select date and time - range', () => { 4 | beforeEach(() => { 5 | cy.changeProps() 6 | cy.changeSlots() 7 | cy.changeProps('type', 'datetime') 8 | }) 9 | 10 | it('with click', () => { 11 | cy.visit('/') 12 | cy.get('.pdp-input').focus() 13 | cy.contains('10').click() 14 | cy.contains('15').click() 15 | cy.get('.pdp-input').focus() 16 | let hour = new Date().getHours(); 17 | hour = 20 - hour; 18 | if (hour < 0) 19 | hour += 24 20 | for (let i = 0; i < hour; i++) { 21 | cy.get('.pdp-time .pdp-moment > div:first-child .hour button:first-child').click() 22 | } 23 | let minute = new Date().getMinutes(); 24 | minute = 18 - minute; 25 | if (minute < 0) 26 | minute += 60 27 | for (let i = 0; i < minute; i++) { 28 | cy.get('.pdp-time .pdp-moment > div:first-child .minute button:first-child').click() 29 | } 30 | hour = new Date().getHours(); 31 | hour = 15 - hour; 32 | hour -= 24 33 | for (let i = 0; i < Math.abs(hour); i++) { 34 | cy.get('.pdp-time .pdp-moment > div:last-child .hour button:last-child').click() 35 | } 36 | minute = new Date().getMinutes(); 37 | minute = 12 - minute; 38 | minute -= 60 39 | for (let i = 0; i < Math.abs(minute); i++) { 40 | cy.get('.pdp-time .pdp-moment > div:last-child .minute button:last-child').click() 41 | } 42 | cy.get('.pdp-input').should('have.value', '1399/06/10 20:18 - 1399/06/15 15:12') 43 | }) 44 | 45 | it('with keys', () => { 46 | cy.visit('/') 47 | cy.tab() 48 | .type('{downarrow}{downarrow}{downarrow}{leftarrow}{leftarrow}{enter}') 49 | .type('{downarrow}{rightarrow}{rightarrow}{enter}') 50 | let hour = new Date().getHours(); 51 | cy.get('.pdp-input').focus() 52 | hour = 20 - hour; 53 | if (hour < 0) 54 | hour += 24 55 | let button = cy.get('.pdp-moment button').first().focus() 56 | for (let i = 0; i < hour; i++) { 57 | button.type('{enter}') 58 | } 59 | let minute = new Date().getMinutes(); 60 | minute = 18 - minute; 61 | if (minute < 0) 62 | minute += 60 63 | button = cy.get('.pdp-moment button').eq(2).focus() 64 | for (let i = 0; i < minute; i++) { 65 | button.type('{enter}') 66 | } 67 | hour = new Date().getHours(); 68 | hour = 15 - hour; 69 | hour -= 24 70 | button = cy.get('.pdp-moment button').eq(5).focus() 71 | for (let i = 0; i < Math.abs(hour); i++) { 72 | button.type('{enter}') 73 | } 74 | minute = new Date().getMinutes(); 75 | minute = 12 - minute; 76 | minute -= 60 77 | button = cy.get('.pdp-moment button').eq(7).focus() 78 | for (let i = 0; i < Math.abs(minute); i++) { 79 | button.type('{enter}') 80 | } 81 | cy.get('.pdp-input').should('have.value', '1399/06/10 20:18 - 1399/06/15 15:12') 82 | }) 83 | 84 | it('with type', () => { 85 | cy.visit('/') 86 | cy.tab() 87 | .type('1399/06/10 20:18{enter}') 88 | .type('1399/06/15 15:12{enter}') 89 | cy.get('.pdp-input').should('have.value', '1399/06/10 20:18 - 1399/06/15 15:12') 90 | }) 91 | }) 92 | 93 | describe('select date and time - single', () => { 94 | beforeEach(() => { 95 | cy.changeProps('mode', 'single') 96 | }) 97 | 98 | it('with click', () => { 99 | cy.visit('/') 100 | cy.get('.pdp-input').focus() 101 | cy.contains('10').click() 102 | cy.get('.pdp-input').focus() 103 | let hour = new Date().getHours(); 104 | hour = 20 - hour; 105 | if (hour < 0) 106 | hour += 24 107 | for (let i = 0; i < hour; i++) { 108 | cy.get('.pdp-time .pdp-moment > div:first-child .hour button:first-child').click() 109 | } 110 | let minute = new Date().getMinutes(); 111 | minute = 18 - minute; 112 | if (minute < 0) 113 | minute += 60 114 | for (let i = 0; i < minute; i++) { 115 | cy.get('.pdp-time .pdp-moment > div:first-child .minute button:first-child').click() 116 | } 117 | cy.get('.pdp-input').should('have.value', '1399/06/10 20:18') 118 | }) 119 | 120 | it('with keys', () => { 121 | cy.visit('/') 122 | cy.tab().type('{downarrow}{downarrow}{downarrow}{leftarrow}{leftarrow}{enter}') 123 | cy.get('.pdp-input').focus() 124 | let hour = new Date().getHours(); 125 | hour = 20 - hour; 126 | if (hour < 0) 127 | hour += 24 128 | let button = cy.get('.pdp-moment button').first().focus() 129 | for (let i = 0; i < hour; i++) { 130 | button.type('{enter}') 131 | } 132 | let minute = new Date().getMinutes(); 133 | minute = 18 - minute; 134 | if (minute < 0) 135 | minute += 60 136 | button = cy.get('.pdp-moment button').eq(2).focus() 137 | for (let i = 0; i < minute; i++) { 138 | button.type('{enter}') 139 | } 140 | cy.get('.pdp-input').should('have.value', '1399/06/10 20:18') 141 | }) 142 | 143 | it('with type', () => { 144 | cy.visit('/') 145 | cy.tab() 146 | .type('1399/06/10 20:18{enter}') 147 | cy.get('.pdp-input').should('have.value', '1399/06/10 20:18') 148 | }) 149 | }) 150 | 151 | describe('select date and time with disable date - single', () => { 152 | beforeEach(() => { 153 | cy.changeProps('disable', '1399/6/5 20:18') 154 | }) 155 | 156 | it('with click', () => { 157 | cy.visit('/') 158 | cy.get('.pdp-input').focus() 159 | cy.contains('5').click() 160 | cy.get('.pdp-input').focus() 161 | let hour = new Date().getHours(); 162 | hour = 20 - hour; 163 | if (hour < 0) 164 | hour += 24 165 | for (let i = 0; i < hour; i++) { 166 | cy.get('.pdp-time .pdp-moment > div:first-child .hour button:first-child').click() 167 | } 168 | let minute = new Date().getMinutes(); 169 | minute = 18 - minute; 170 | if (minute < 0) 171 | minute += 60 172 | for (let i = 0; i < minute; i++) { 173 | cy.get('.pdp-time .pdp-moment > div:first-child .minute button:first-child').click() 174 | } 175 | cy.get('.pdp-time .pdp-moment > div').should('have.attr', 'class').and('match', /disabled/) 176 | cy.get('.pdp-input').should('have.value', '1399/06/05 20:17') 177 | cy.get('.pdp-time .pdp-moment > div:first-child .minute button:first-child').click() 178 | cy.get('.pdp-input').should('have.value', '1399/06/05 20:19') 179 | }) 180 | 181 | it('with keys', () => { 182 | cy.visit('/') 183 | cy.tab() 184 | .type('{downarrow}{leftarrow}{leftarrow}{leftarrow}{leftarrow}{leftarrow}{enter}') 185 | cy.get('.pdp-input').focus() 186 | let hour = new Date().getHours(); 187 | hour = 20 - hour; 188 | if (hour < 0) 189 | hour += 24 190 | let button = cy.get('.pdp-moment button').first().focus() 191 | for (let i = 0; i < hour; i++) { 192 | button.type('{enter}') 193 | } 194 | let minute = new Date().getMinutes(); 195 | minute = 18 - minute; 196 | if (minute < 0) 197 | minute += 60 198 | button = cy.get('.pdp-moment button').eq(2).focus() 199 | for (let i = 0; i < minute; i++) { 200 | button.type('{enter}') 201 | } 202 | cy.get('.pdp-time .pdp-moment > div').should('have.attr', 'class').and('match', /disabled/) 203 | cy.get('.pdp-input').should('have.value', '1399/06/05 20:17') 204 | cy.get('.pdp-moment button').eq(2).focus().type('{enter}') 205 | cy.get('.pdp-input').should('have.value', '1399/06/05 20:19') 206 | }) 207 | 208 | it('with type', () => { 209 | cy.visit('/') 210 | cy.tab() 211 | .type('1399/06/05 20:18{enter}') 212 | cy.get('.pdp-input').should('have.value', '1399/06/05 20:18') 213 | cy.get('.pdp-input').clear().type('1399/06/06 20:18{enter}') 214 | cy.get('.pdp-input').should('have.value', '1399/06/06 20:18') 215 | cy.get('.pdp-input').focus() 216 | cy.get('.pdp-day.start-range').should('contain.text', '6') 217 | cy.get('.hour').should('contain.text', '20') 218 | cy.get('.minute').should('contain.text', '18') 219 | }) 220 | }) 221 | 222 | describe('select date and time with disable date - range', () => { 223 | beforeEach(() => { 224 | cy.changeProps('disable', '1399/6/5 20:18') 225 | cy.changeProps('mode', 'range') 226 | }) 227 | 228 | it('with click', () => { 229 | cy.visit('/') 230 | cy.get('.pdp-input').focus() 231 | cy.contains('5').click() 232 | cy.get('.pdp-day.start-range').should('contain.text', '5') 233 | cy.get('.pdp-day[value="6"]').first().click() 234 | cy.get('.pdp-input').focus() 235 | cy.get('.pdp-day.end-range').should('contain.text', '6') 236 | let hour = new Date().getHours(); 237 | hour = 20 - hour; 238 | if (hour < 0) 239 | hour += 24 240 | for (let i = 0; i < hour; i++) { 241 | cy.get('.pdp-time .pdp-moment > div:first-child .hour button:first-child').click() 242 | } 243 | let minute = new Date().getMinutes(); 244 | minute = 18 - minute; 245 | if (minute < 0) 246 | minute += 60 247 | for (let i = 0; i < minute; i++) { 248 | cy.get('.pdp-time .pdp-moment > div:first-child .minute button:first-child').click() 249 | } 250 | cy.get('.pdp-time .pdp-moment > div:first-child').should('have.attr', 'class').and('match', /disabled/) 251 | cy.get('.pdp-input').should('contain.value', '1399/06/05 20:17 - 1399/06/06 ') 252 | cy.get('.pdp-time .pdp-moment > div:first-child .minute button:first-child').click() 253 | cy.get('.pdp-input').should('contain.value', '1399/06/05 20:19 - 1399/06/06 ') 254 | hour = new Date().getHours(); 255 | hour = 15 - hour; 256 | hour -= 24 257 | for (let i = 0; i < Math.abs(hour); i++) { 258 | cy.get('.pdp-time .pdp-moment > div:last-child .hour button:last-child').click() 259 | } 260 | minute = new Date().getMinutes(); 261 | minute = 12 - minute; 262 | minute -= 60 263 | for (let i = 0; i < Math.abs(minute); i++) { 264 | cy.get('.pdp-time .pdp-moment > div:last-child .minute button:last-child').click() 265 | } 266 | cy.get('.pdp-input').should('have.value', '1399/06/05 20:19 - 1399/06/06 15:12') 267 | }) 268 | 269 | it('with keys', () => { 270 | cy.visit('/') 271 | cy.tab().type('{downarrow}{downarrow}{leftarrow}{leftarrow}{leftarrow}{leftarrow}{enter}') 272 | cy.get('.pdp-day.start-range').should('contain.text', '5') 273 | cy.get('.pdp-input').type('{leftarrow}{leftarrow}{leftarrow}{enter}') 274 | cy.get('.pdp-input').focus() 275 | cy.get('.pdp-day.end-range').should('contain.text', '8') 276 | let hour = new Date().getHours(); 277 | hour = 20 - hour; 278 | if (hour < 0) 279 | hour += 24 280 | let button = cy.get('.pdp-moment button').first().focus() 281 | for (let i = 0; i < hour; i++) { 282 | button.type('{enter}') 283 | } 284 | let minute = new Date().getMinutes(); 285 | minute = 18 - minute; 286 | if (minute < 0) 287 | minute += 60 288 | button = cy.get('.pdp-moment button').eq(2).focus() 289 | for (let i = 0; i < minute; i++) { 290 | button.type('{enter}') 291 | } 292 | cy.get('.pdp-time .pdp-moment > div:first-child').should('have.attr', 'class').and('match', /disabled/) 293 | cy.get('.pdp-input').focus().should('contain.value', '1399/06/05 20:17 - 1399/06/08 ') 294 | cy.get('.pdp-moment button').eq(2).focus().type('{enter}') 295 | cy.get('.pdp-input').focus().should('contain.value', '1399/06/05 20:19 - 1399/06/08 ') 296 | hour = new Date().getHours(); 297 | hour = 15 - hour; 298 | hour -= 24 299 | button = cy.get('.pdp-moment button').eq(5).focus() 300 | for (let i = 0; i < Math.abs(hour); i++) { 301 | button.type('{enter}') 302 | } 303 | minute = new Date().getMinutes(); 304 | minute = 12 - minute; 305 | minute -= 60 306 | button = cy.get('.pdp-moment button').eq(7).focus() 307 | for (let i = 0; i < Math.abs(minute); i++) { 308 | button.type('{enter}') 309 | } 310 | cy.get('.pdp-input').focus().should('have.value', '1399/06/05 20:19 - 1399/06/08 15:12') 311 | }) 312 | 313 | it('with type', () => { 314 | cy.visit('/') 315 | cy.tab() 316 | .type('1399/06/05 20:18{enter}') 317 | cy.get('.pdp-input').should('have.value', '1399/06/05 20:18') 318 | cy.get('.pdp-input').clear().type('1399/06/03 20:18{enter}') 319 | cy.get('.pdp-input').should('have.value', '') 320 | cy.get('.pdp-day.start-range').should('contain.text', '3') 321 | cy.get('.hour').first().should('contain.text', '20') 322 | cy.get('.minute').first().should('contain.text', '18') 323 | cy.get('.pdp-input').clear().type('1399/06/05 20:18{enter}') 324 | cy.get('.pdp-input').should('have.value', '1399/06/05 20:18') 325 | cy.get('.pdp-input').clear().type('1399/06/04 20:18{enter}') 326 | cy.get('.pdp-input').should('have.value', '1399/06/03 20:18 - 1399/06/04 20:18') 327 | cy.get('.pdp-input').focus() 328 | cy.get('.pdp-day.end-range').should('contain.text', '4') 329 | cy.get('.hour').last().should('contain.text', '20') 330 | cy.get('.minute').last().should('contain.text', '18') 331 | 332 | }) 333 | }) 334 | 335 | describe('select date and time in en locale - range', () => { 336 | beforeEach(() => { 337 | cy.changeProps('locale', 'en') 338 | }) 339 | 340 | it('with click', () => { 341 | cy.visit('/') 342 | cy.get('.pdp-input').focus() 343 | cy.contains('10').click() 344 | cy.contains('15').click() 345 | cy.get('.pdp-input').focus() 346 | let hour = new Date().getHours(); 347 | hour = 20 - hour; 348 | if (hour < 0) 349 | hour += 24 350 | for (let i = 0; i < hour; i++) { 351 | cy.get('.pdp-time .pdp-moment > div:first-child .hour button:first-child').click() 352 | } 353 | let minute = new Date().getMinutes(); 354 | minute = 18 - minute; 355 | if (minute < 0) 356 | minute += 60 357 | for (let i = 0; i < minute; i++) { 358 | cy.get('.pdp-time .pdp-moment > div:first-child .minute button:first-child').click() 359 | } 360 | hour = new Date().getHours(); 361 | hour = 15 - hour; 362 | hour -= 24 363 | for (let i = 0; i < Math.abs(hour); i++) { 364 | cy.get('.pdp-time .pdp-moment > div:last-child .hour button:last-child').click() 365 | } 366 | minute = new Date().getMinutes(); 367 | minute = 12 - minute; 368 | minute -= 60 369 | for (let i = 0; i < Math.abs(minute); i++) { 370 | cy.get('.pdp-time .pdp-moment > div:last-child .minute button:last-child').click() 371 | } 372 | cy.get('.pdp-input').should('have.value', '2020-09-10 20:18 - 2020-09-15 15:12') 373 | }) 374 | 375 | it('with keys', () => { 376 | cy.visit('/') 377 | cy.tab() 378 | .type('{downarrow}{downarrow}{downarrow}{leftarrow}{leftarrow}{enter}') 379 | .type('{downarrow}{rightarrow}{rightarrow}{enter}') 380 | let hour = new Date().getHours(); 381 | cy.get('.pdp-input').focus() 382 | hour = 20 - hour; 383 | if (hour < 0) 384 | hour += 24 385 | let button = cy.get('.pdp-moment button').first().focus() 386 | for (let i = 0; i < hour; i++) { 387 | button.type('{enter}') 388 | } 389 | let minute = new Date().getMinutes(); 390 | minute = 18 - minute; 391 | if (minute < 0) 392 | minute += 60 393 | button = cy.get('.pdp-moment button').eq(2).focus() 394 | for (let i = 0; i < minute; i++) { 395 | button.type('{enter}') 396 | } 397 | hour = new Date().getHours(); 398 | hour = 15 - hour; 399 | hour -= 24 400 | button = cy.get('.pdp-moment button').eq(5).focus() 401 | for (let i = 0; i < Math.abs(hour); i++) { 402 | button.type('{enter}') 403 | } 404 | minute = new Date().getMinutes(); 405 | minute = 12 - minute; 406 | minute -= 60 407 | button = cy.get('.pdp-moment button').eq(7).focus() 408 | for (let i = 0; i < Math.abs(minute); i++) { 409 | button.type('{enter}') 410 | } 411 | cy.get('.pdp-input').should('have.value', '2020-09-06 20:18 - 2020-09-15 15:12') 412 | }) 413 | 414 | it('with type', () => { 415 | cy.visit('/') 416 | cy.tab() 417 | .type('2020-09-10 20:18{enter}') 418 | .type('2020-09-15 15:12{enter}') 419 | cy.get('.pdp-input').should('have.value', '2020-09-10 20:18 - 2020-09-15 15:12') 420 | }) 421 | }) 422 | 423 | describe('select date and time in en locale - single', () => { 424 | beforeEach(() => { 425 | cy.changeProps('mode', 'single') 426 | }) 427 | 428 | it('with click', () => { 429 | cy.visit('/') 430 | cy.get('.pdp-input').focus() 431 | cy.contains('10').click() 432 | cy.get('.pdp-input').focus() 433 | let hour = new Date().getHours(); 434 | hour = 20 - hour; 435 | if (hour < 0) 436 | hour += 24 437 | for (let i = 0; i < hour; i++) { 438 | cy.get('.pdp-time .pdp-moment > div:first-child .hour button:first-child').click() 439 | } 440 | let minute = new Date().getMinutes(); 441 | minute = 18 - minute; 442 | if (minute < 0) 443 | minute += 60 444 | for (let i = 0; i < minute; i++) { 445 | cy.get('.pdp-time .pdp-moment > div:first-child .minute button:first-child').click() 446 | } 447 | cy.get('.pdp-input').should('have.value', '2020-09-10 20:18') 448 | }) 449 | 450 | it('with keys', () => { 451 | cy.visit('/') 452 | cy.tab() 453 | .type('{downarrow}{downarrow}{downarrow}{rightarrow}{rightarrow}{enter}') 454 | cy.get('.pdp-input').focus() 455 | let hour = new Date().getHours(); 456 | hour = 20 - hour; 457 | if (hour < 0) 458 | hour += 24 459 | let button = cy.get('.pdp-moment button').first().focus() 460 | for (let i = 0; i < hour; i++) { 461 | button.type('{enter}') 462 | } 463 | let minute = new Date().getMinutes(); 464 | minute = 18 - minute; 465 | if (minute < 0) 466 | minute += 60 467 | button = cy.get('.pdp-moment button').eq(2).focus() 468 | for (let i = 0; i < minute; i++) { 469 | button.type('{enter}') 470 | } 471 | cy.get('.pdp-input').should('have.value', '2020-09-10 20:18') 472 | }) 473 | 474 | it('with type', () => { 475 | cy.visit('/') 476 | cy.tab() 477 | .type('2020-09-10 20:18{enter}') 478 | cy.get('.pdp-input').should('have.value', '2020-09-10 20:18') 479 | }) 480 | }) -------------------------------------------------------------------------------- /cypress/integration/select-time.spec.js: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | describe('select time - range', () => { 4 | beforeEach(() => { 5 | cy.changeProps() 6 | cy.changeSlots() 7 | cy.changeProps('type', 'time') 8 | cy.changeProps('from', undefined) 9 | cy.changeProps('to', undefined) 10 | }) 11 | 12 | it('with click on times', () => { 13 | cy.visit('/') 14 | cy.get('.pdp-input').focus() 15 | let hour = new Date().getHours(); 16 | hour = 20 - hour; 17 | if (hour < 0) 18 | hour += 24 19 | for (let i = 0; i < hour; i++) { 20 | cy.get(`.pdp-time .pdp-moment > div:last-child .hour button:first-child`).click() 21 | } 22 | let minute = new Date().getMinutes(); 23 | minute = 18 - minute; 24 | if (minute < 0) 25 | minute += 60 26 | for (let i = 0; i < minute; i++) { 27 | cy.get(`.pdp-time .pdp-moment > div:last-child .minute button:first-child`).click() 28 | } 29 | hour = new Date().getHours(); 30 | hour = 15 - hour; 31 | if (hour < 0) 32 | hour += 24 33 | for (let i = 0; i < hour; i++) { 34 | cy.get(`.pdp-time .pdp-moment > div:first-child .hour button:first-child`).click() 35 | } 36 | minute = new Date().getMinutes(); 37 | minute = 12 - minute; 38 | if (minute < 0) 39 | minute += 60 40 | for (let i = 0; i < minute; i++) { 41 | cy.get(`.pdp-time .pdp-moment > div:first-child .minute button:first-child`).click() 42 | } 43 | cy.get('.pdp-input').should('have.value', '15:12 - 20:18') 44 | }) 45 | 46 | it('with keys', () => { 47 | cy.visit('/') 48 | cy.tab() 49 | let hour = new Date().getHours(); 50 | hour = 20 - hour; 51 | if (hour < 0) 52 | hour += 24 53 | let button = cy.get('.pdp-moment button').eq(4).focus() 54 | for (let i = 0; i < hour; i++) { 55 | button.type('{enter}') 56 | } 57 | let minute = new Date().getMinutes(); 58 | minute = 18 - minute; 59 | if (minute < 0) 60 | minute += 60 61 | button = cy.get('.pdp-moment button').eq(6).focus() 62 | for (let i = 0; i < minute; i++) { 63 | button.type('{enter}') 64 | } 65 | hour = new Date().getHours(); 66 | hour = 15 - hour; 67 | if (hour < 0) 68 | 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().getMinutes(); 74 | minute = 12 - minute; 75 | if (minute < 0) 76 | minute += 60 77 | button = cy.get('.pdp-moment button').eq(2).focus() 78 | for (let i = 0; i < minute; i++) { 79 | button.type('{enter}') 80 | } 81 | cy.get('.pdp-input').should('have.value', '15:12 - 20:18') 82 | }) 83 | 84 | it('with type the time', () => { 85 | cy.visit('/') 86 | cy.tab().type('15:12{enter}').type('20:18{enter}') 87 | cy.get('.pdp-input').should('have.value', '15:12 - 20:18') 88 | }) 89 | }) 90 | 91 | describe('select time - single', () => { 92 | beforeEach(() => { 93 | cy.changeProps('mode', 'single') 94 | }) 95 | 96 | it('with click on times', () => { 97 | cy.visit('/') 98 | cy.get('.pdp-input').focus() 99 | let hour = new Date().getHours(); 100 | hour = 20 - hour; 101 | if (hour < 0) 102 | hour += 24 103 | for (let i = 0; i < hour; i++) { 104 | cy.get('.pdp-time .pdp-moment > div:first-child .hour button:first-child').click() 105 | } 106 | let minute = new Date().getMinutes(); 107 | minute = 18 - minute; 108 | if (minute < 0) 109 | minute += 60 110 | for (let i = 0; i < minute; i++) { 111 | cy.get('.pdp-time .pdp-moment > div:first-child .minute button:first-child').click() 112 | } 113 | cy.get('.pdp-input').should('have.value', '20:18') 114 | }) 115 | 116 | it('with keys', () => { 117 | cy.visit('/') 118 | cy.tab() 119 | let hour = new Date().getHours(); 120 | hour = 20 - hour; 121 | if (hour < 0) 122 | hour += 24 123 | let button = cy.get('.pdp-moment button').first().focus() 124 | for (let i = 0; i < hour; i++) { 125 | button.type('{enter}') 126 | } 127 | let minute = new Date().getMinutes(); 128 | minute = 18 - minute; 129 | if (minute < 0) 130 | minute += 60 131 | button = cy.get('.pdp-moment button').eq(2).focus() 132 | for (let i = 0; i < minute; i++) { 133 | button.type('{enter}') 134 | } 135 | cy.get('.pdp-input').should('have.value', '20:18') 136 | }) 137 | 138 | it('with type the time', () => { 139 | cy.visit('/') 140 | cy.tab() 141 | .type('20:18{enter}') 142 | cy.get('.pdp-input').should('have.value', '20:18') 143 | }) 144 | }) 145 | 146 | describe('select time with disable time - single', () => { 147 | beforeEach(() => { 148 | cy.changeProps('disable', '20:18') 149 | }) 150 | 151 | it('with click on times', () => { 152 | cy.visit('/') 153 | cy.get('.pdp-input').focus() 154 | let hour = new Date().getHours(); 155 | hour = 20 - hour; 156 | if (hour < 0) 157 | hour += 24 158 | for (let i = 0; i < hour; i++) { 159 | cy.get('.pdp-time .pdp-moment > div:first-child .hour button:first-child').click() 160 | } 161 | let minute = new Date().getMinutes(); 162 | minute = 18 - minute; 163 | if (minute < 0) 164 | minute += 60 165 | for (let i = 0; i < minute; i++) { 166 | cy.get('.pdp-time .pdp-moment > div:first-child .minute button:first-child').click() 167 | } 168 | cy.get('.pdp-time .pdp-moment > div').should('have.attr', 'class').and('match', /disabled/) 169 | cy.get('.pdp-input').should('have.value', '20:17') 170 | cy.get('.pdp-time .pdp-moment > div:first-child .minute button:first-child').click() 171 | cy.get('.pdp-input').should('have.value', '20:19') 172 | }) 173 | 174 | it('with keys', () => { 175 | cy.visit('/') 176 | cy.tab() 177 | let hour = new Date().getHours(); 178 | hour = 20 - hour; 179 | if (hour < 0) 180 | hour += 24 181 | let button = cy.get('.pdp-moment button').first().focus() 182 | for (let i = 0; i < hour; i++) { 183 | button.type('{enter}') 184 | } 185 | let minute = new Date().getMinutes(); 186 | minute = 18 - minute; 187 | if (minute < 0) 188 | minute += 60 189 | button = cy.get('.pdp-moment button').eq(2).focus() 190 | for (let i = 0; i < minute; i++) { 191 | button.type('{enter}') 192 | } 193 | 194 | cy.get('.pdp-time .pdp-moment > div').should('have.attr', 'class').and('match', /disabled/) 195 | cy.get('.pdp-input').should('have.value', '20:17') 196 | cy.get('.pdp-moment button').eq(2).focus().type('{enter}') 197 | cy.get('.pdp-input').should('have.value', '20:19') 198 | }) 199 | 200 | it('with type the time', () => { 201 | cy.visit('/') 202 | cy.tab() 203 | .type('20:18{enter}') 204 | cy.get('.pdp-input').should('have.value', '20:18') 205 | cy.get('.hour').should('not.contain.value', '20') 206 | cy.get('.minute').should('not.contain.value', '18') 207 | cy.get('.pdp-input').clear().type('20:19{enter}') 208 | cy.get('.pdp-input').should('have.value', '20:19') 209 | cy.get('.pdp-time').should('not.exist') 210 | }) 211 | }) 212 | 213 | describe('select time with disable time - range', () => { 214 | beforeEach(() => { 215 | cy.changeProps('disable', ['20:18', '15:12']) 216 | cy.changeProps('mode', 'range') 217 | }) 218 | 219 | it('with click on times', () => { 220 | cy.visit('/') 221 | cy.get('.pdp-input').focus() 222 | let hour = new Date().getHours(); 223 | hour = 20 - hour; 224 | if (hour < 0) 225 | hour += 24 226 | for (let i = 0; i < hour; i++) { 227 | cy.get('.pdp-time .pdp-moment > div:last-child .hour button:first-child').click() 228 | } 229 | let minute = new Date().getMinutes(); 230 | minute = 18 - minute; 231 | if (minute < 0) 232 | minute += 60 233 | for (let i = 0; i < minute; i++) { 234 | cy.get('.pdp-time .pdp-moment > div:last-child .minute button:first-child').click() 235 | } 236 | cy.get('.pdp-time .pdp-moment > div:last-child').should('have.attr', 'class').and('match', /disabled/) 237 | cy.get('.pdp-input').should('contain.value', ' - 20:17') 238 | cy.get('.pdp-time .pdp-moment > div:last-child .minute button:first-child').click() 239 | cy.get('.pdp-input').should('contain.value', ' - 20:19') 240 | hour = new Date().getHours(); 241 | hour = 15 - hour; 242 | if (hour < 0) 243 | hour += 24 244 | for (let i = 0; i < Math.abs(hour); i++) { 245 | cy.get('.pdp-time .pdp-moment > div:first-child .hour button:first-child').click() 246 | } 247 | minute = new Date().getMinutes(); 248 | minute = 12 - minute; 249 | if (minute < 0) 250 | minute += 60 251 | for (let i = 0; i < Math.abs(minute); i++) { 252 | cy.get('.pdp-time .pdp-moment > div:first-child .minute button:first-child').click() 253 | } 254 | cy.get('.pdp-time .pdp-moment > div:first-child').should('have.attr', 'class').and('match', /disabled/) 255 | cy.get('.pdp-input').should('have.value', '15:11 - 20:19') 256 | cy.get('.pdp-time .pdp-moment > div:first-child .minute button:first-child').click() 257 | cy.get('.pdp-input').should('have.value', '15:13 - 20:19') 258 | }) 259 | 260 | it('with keys', () => { 261 | cy.visit('/') 262 | cy.tab() 263 | let hour = new Date().getHours(); 264 | hour = 20 - hour; 265 | if (hour < 0) 266 | hour += 24 267 | let button = cy.get('.pdp-moment button').eq(4).focus() 268 | for (let i = 0; i < hour; i++) { 269 | button.type('{enter}') 270 | } 271 | let minute = new Date().getMinutes(); 272 | minute = 18 - minute; 273 | if (minute < 0) 274 | minute += 60 275 | button = cy.get('.pdp-moment button').eq(6).focus() 276 | for (let i = 0; i < minute; i++) { 277 | button.type('{enter}') 278 | } 279 | cy.get('.pdp-time .pdp-moment > div:last-child').should('have.attr', 'class').and('match', /disabled/) 280 | cy.get('.pdp-input').should('contain.value', ' - 20:17') 281 | cy.get('.pdp-moment button').eq(6).focus().type('{enter}') 282 | cy.get('.pdp-input').should('contain.value', ' - 20:19') 283 | hour = new Date().getHours(); 284 | hour = 15 - hour; 285 | if (hour < 0) 286 | hour += 24 287 | button = cy.get('.pdp-moment button').first().focus() 288 | for (let i = 0; i < Math.abs(hour); i++) { 289 | button.type('{enter}') 290 | } 291 | minute = new Date().getMinutes(); 292 | minute = 12 - minute; 293 | if (minute < 0) 294 | minute += 60 295 | button = cy.get('.pdp-moment button').eq(2).focus() 296 | for (let i = 0; i < Math.abs(minute); i++) { 297 | button.type('{enter}') 298 | } 299 | cy.get('.pdp-time .pdp-moment > div:first-child').should('have.attr', 'class').and('match', /disabled/) 300 | cy.get('.pdp-input').should('have.value', '15:11 - 20:19') 301 | cy.get('.pdp-moment button').eq(2).focus().type('{enter}') 302 | cy.get('.pdp-input').should('have.value', '15:13 - 20:19') 303 | }) 304 | 305 | it('with type the time', () => { 306 | cy.visit('/') 307 | cy.tab().type('15:12{enter}') 308 | cy.get('.pdp-input').should('have.value', '15:12') 309 | cy.get('.hour').should('not.contain.value', '15') 310 | cy.get('.minute').should('not.contain.value', '12') 311 | cy.get('.pdp-input').clear().type('15:13{enter}').type('20:18{enter}') 312 | cy.get('.pdp-input').should('have.value', '20:18') 313 | cy.get('.hour').should('not.contain.value', '20') 314 | cy.get('.minute').should('not.contain.value', '18') 315 | cy.get('.pdp-input').clear().type('20:17{enter}') 316 | cy.get('.pdp-input').should('have.value', '15:13 - 20:17') 317 | }) 318 | }) -------------------------------------------------------------------------------- /cypress/integration/shortcut.spec.js: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import PersianDate from "@alireza-ab/persian-date"; 4 | 5 | const date = new PersianDate([2021, 3, 30, 12]); 6 | 7 | beforeEach(() => { 8 | cy.clock(new Date(2021, 2, 30, 12)); 9 | }); 10 | 11 | describe("shortcut prop", () => { 12 | before(() => { 13 | cy.changeProps("from", undefined); 14 | cy.changeProps("to", undefined); 15 | cy.changeProps("shortcut", true); 16 | cy.changeSlots(); 17 | }); 18 | 19 | it("date - range", () => { 20 | cy.visit("/"); 21 | cy.get(".pdp-input").focus(); 22 | cy.get(".pdp-shortcut") 23 | .should("exist") 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 | .get(".pdp-shortcut") 36 | .contains("ماه بعد") 37 | .should("exist") 38 | .get(".pdp-shortcut") 39 | .contains("این ماه") 40 | .should("exist") 41 | .click(); 42 | cy.get(".pdp-input").should( 43 | "have.value", 44 | `${date 45 | .clone() 46 | .startOf("month") 47 | .toString()} - ${date 48 | .clone() 49 | .endOf("month") 50 | .toString()}` 51 | ); 52 | }); 53 | 54 | it("date - range in en locale", () => { 55 | cy.changeProps("locale", "en"); 56 | cy.visit("/"); 57 | cy.get(".pdp-input").focus(); 58 | cy.get(".pdp-shortcut") 59 | .should("exist") 60 | .contains("This Week") 61 | .should("exist") 62 | .get(".pdp-shortcut") 63 | .contains("Previous Week") 64 | .should("exist") 65 | .get(".pdp-shortcut") 66 | .contains("Next Week") 67 | .should("exist") 68 | .get(".pdp-shortcut") 69 | .contains("Previous Month") 70 | .should("exist") 71 | .get(".pdp-shortcut") 72 | .contains("Next Month") 73 | .should("exist") 74 | .get(".pdp-shortcut") 75 | .contains("This Month") 76 | .should("exist") 77 | .click(); 78 | cy.get(".pdp-input").should( 79 | "have.value", 80 | `${date 81 | .clone() 82 | .calendar("gregorian") 83 | .startOf("month") 84 | .toString()} - ${date 85 | .clone() 86 | .calendar("gregorian") 87 | .endOf("month") 88 | .toString()}` 89 | ); 90 | }); 91 | 92 | it("date - single", () => { 93 | cy.changeProps("locale", "fa"); 94 | cy.changeProps("mode", "single"); 95 | cy.visit("/"); 96 | cy.get(".pdp-input").focus(); 97 | cy.get(".pdp-shortcut") 98 | .should("exist") 99 | .contains("هم اکنون") 100 | .should("exist") 101 | .get(".pdp-shortcut") 102 | .contains("دیروز") 103 | .should("exist") 104 | .get(".pdp-shortcut") 105 | .contains("اول هفته") 106 | .should("exist") 107 | .get(".pdp-shortcut") 108 | .contains("آخر هفته") 109 | .should("exist") 110 | .get(".pdp-shortcut") 111 | .contains("فردا") 112 | .should("exist") 113 | .click(); 114 | cy.get(".pdp-input").should( 115 | "have.value", 116 | date 117 | .clone() 118 | .addDay() 119 | .toString() 120 | ); 121 | }); 122 | 123 | it("datetime - single", () => { 124 | cy.changeProps("type", "datetime"); 125 | cy.changeProps("mode", "single"); 126 | cy.visit("/"); 127 | cy.get(".pdp-input").focus(); 128 | cy.get(".pdp-shortcut") 129 | .should("exist") 130 | .contains("هم اکنون") 131 | .should("exist") 132 | .get(".pdp-shortcut") 133 | .contains("دیروز") 134 | .should("exist") 135 | .get(".pdp-shortcut") 136 | .contains("فردا") 137 | .should("exist") 138 | .get(".pdp-shortcut") 139 | .contains("اول هفته") 140 | .should("exist") 141 | .get(".pdp-shortcut") 142 | .contains("آخر هفته") 143 | .should("exist") 144 | .click(); 145 | 146 | cy.get(".pdp-input").should( 147 | "have.value", 148 | date 149 | .clone() 150 | .endOf("week") 151 | .toString("datetime") 152 | ); 153 | }); 154 | 155 | it("datetime - range", () => { 156 | cy.changeProps("mode", "range"); 157 | cy.visit("/"); 158 | cy.get(".pdp-input").focus(); 159 | cy.get(".pdp-shortcut") 160 | .should("exist") 161 | .contains("این هفته") 162 | .should("exist") 163 | .get(".pdp-shortcut") 164 | .contains("هفته قبل") 165 | .should("exist") 166 | .get(".pdp-shortcut") 167 | .contains("این ماه") 168 | .should("exist") 169 | .get(".pdp-shortcut") 170 | .contains("ماه قبل") 171 | .should("exist") 172 | .get(".pdp-shortcut") 173 | .contains("ماه بعد") 174 | .should("exist") 175 | .get(".pdp-shortcut") 176 | .contains("هفته بعد") 177 | .should("exist") 178 | .click(); 179 | 180 | cy.get(".pdp-input").should( 181 | "have.value", 182 | `${date 183 | .clone() 184 | .addWeek() 185 | .startOf("week") 186 | .toString("datetime")} - ${date 187 | .clone() 188 | .addWeek() 189 | .endOf("week") 190 | .toString("datetime")}` 191 | ); 192 | }); 193 | 194 | it("time - range", () => { 195 | cy.changeProps("type", "time"); 196 | cy.visit("/"); 197 | cy.get(".pdp-input").focus(); 198 | cy.get(".pdp-shortcut") 199 | .should("exist") 200 | .contains("این ساعت") 201 | .should("exist") 202 | .get(".pdp-shortcut") 203 | .contains("ساعت بعد") 204 | .should("exist") 205 | .get(".pdp-shortcut") 206 | .contains("تمام روز") 207 | .should("exist") 208 | .get(".pdp-shortcut") 209 | .contains("ساعت قبل") 210 | .should("exist") 211 | .click(); 212 | 213 | cy.get(".pdp-input").should( 214 | "have.value", 215 | `${date 216 | .clone() 217 | .subHour() 218 | .startOf("hour") 219 | .toString("time")} - ${date 220 | .clone() 221 | .subHour() 222 | .endOf("hour") 223 | .toString("time")}` 224 | ); 225 | }); 226 | 227 | it("time - single", () => { 228 | cy.changeProps("mode", "single"); 229 | cy.visit("/"); 230 | cy.get(".pdp-input").focus(); 231 | cy.get(".pdp-shortcut") 232 | .should("exist") 233 | .contains("یک ساعت قبل") 234 | .should("exist") 235 | .get(".pdp-shortcut") 236 | .contains("یک ساعت بعد") 237 | .should("exist") 238 | .get(".pdp-shortcut") 239 | .contains("نیمه شب") 240 | .should("exist") 241 | .get(".pdp-shortcut") 242 | .contains("نیمروز") 243 | .should("exist") 244 | .get(".pdp-shortcut") 245 | .contains("هم اکنون") 246 | .should("exist") 247 | .click(); 248 | 249 | cy.get(".pdp-input").should("have.value", date.clone().toString("time")); 250 | }); 251 | 252 | it("custom shortcut - range", () => { 253 | const stringDates = ["1400/01/10", "1400/01/20"]; 254 | const persianDates = [ 255 | date 256 | .clone() 257 | .subDay(2) 258 | .toString(), 259 | date 260 | .clone() 261 | .addDay(2) 262 | .toString(), 263 | ]; 264 | cy.changeProps("shortcut", { 265 | String: stringDates, 266 | PersianDate: persianDates, 267 | }); 268 | cy.changeProps("type", "date"); 269 | cy.changeProps("mode", "range"); 270 | cy.visit("/"); 271 | cy.get(".pdp-input") 272 | .focus() 273 | .get(".pdp-shortcut") 274 | .contains("String") 275 | .click(); 276 | cy.get(".pdp-input") 277 | .should("have.value", stringDates.join(" - ")) 278 | .focus() 279 | .get(".pdp-shortcut") 280 | .contains("PersianDate") 281 | .click(); 282 | cy.get(".pdp-input").should("have.value", persianDates.join(" - ")); 283 | }); 284 | 285 | it("custom shortcut - single", () => { 286 | const stringDates = ["1400/01/10"]; 287 | const persianDates = [ 288 | date 289 | .clone() 290 | .subDay(2) 291 | .toString(), 292 | ]; 293 | cy.changeProps("shortcut", { 294 | String: stringDates, 295 | PersianDate: persianDates, 296 | }); 297 | cy.changeProps("mode", "single"); 298 | cy.visit("/"); 299 | cy.get(".pdp-input") 300 | .focus() 301 | .get(".pdp-shortcut") 302 | .contains("String") 303 | .click(); 304 | cy.get(".pdp-input") 305 | .should("have.value", stringDates[0]) 306 | .focus() 307 | .get(".pdp-shortcut") 308 | .contains("PersianDate") 309 | .click(); 310 | cy.get(".pdp-input").should("have.value", persianDates[0]); 311 | }); 312 | 313 | it("date - single with disable", () => { 314 | cy.changeProps("shortcut", true); 315 | cy.changeProps( 316 | "from", 317 | date 318 | .clone() 319 | .addDay() 320 | .toString() 321 | ); 322 | cy.changeProps( 323 | "to", 324 | date 325 | .clone() 326 | .endOf("month") 327 | .toString() 328 | ); 329 | cy.changeProps( 330 | "disable", 331 | date 332 | .clone() 333 | .addDay() 334 | .toString() 335 | ); 336 | cy.visit("/"); 337 | cy.get(".pdp-input") 338 | .focus() 339 | .get(".pdp-shortcut") 340 | .should("have.length", 1) 341 | .contains("آخر هفته") 342 | .click(); 343 | cy.get(".pdp-input").should( 344 | "have.value", 345 | date 346 | .clone() 347 | .endOf("week") 348 | .toString() 349 | ); 350 | }); 351 | }); 352 | -------------------------------------------------------------------------------- /cypress/integration/slots.spec.js: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | describe('slots', () => { 4 | beforeEach(() => { 5 | cy.changeProps() 6 | cy.changeSlots() 7 | }) 8 | 9 | it('before', () => { 10 | cy.changeSlots('before', '') 11 | cy.visit('/') 12 | cy.get('label').should('contain.text', 'select date:') 13 | }) 14 | 15 | it('after', () => { 16 | cy.changeSlots('after', 'Please select date.') 17 | cy.visit('/') 18 | cy.get('small').should('contain.text', 'Please select date.') 19 | }) 20 | 21 | it('icon', () => { 22 | cy.changeSlots('icon', 'Date') 23 | cy.visit('/') 24 | cy.get('.pdp-icon').should('contain.text', 'Date') 25 | }) 26 | 27 | it('right arrow', () => { 28 | cy.changeSlots('right-arrow', 'ماه قبل') 29 | cy.visit('/') 30 | cy.get('.pdp-input').focus().get('.pdp-arrow').first().should('contain.text', 'ماه قبل') 31 | }) 32 | 33 | it('left arrow', () => { 34 | cy.changeSlots('left-arrow', 'ماه بعد') 35 | cy.visit('/') 36 | cy.get('.pdp-input').focus().get('.pdp-arrow').last().should('contain.text', 'ماه بعد') 37 | }) 38 | 39 | it('footer', () => { 40 | cy.changeSlots('footer', 'تاریخ انتخابی:') 41 | cy.visit('/') 42 | cy.get('.pdp-input').focus().get('.pdp-footer').should('contain.text', 'تاریخ انتخابی:') 43 | }) 44 | 45 | it('clear', () => { 46 | cy.changeSlots('clear', 'بستن') 47 | cy.changeProps('clearable', true) 48 | cy.visit('/') 49 | cy.get('.pdp-clear').should('contain.text', 'بستن') 50 | }) 51 | 52 | it('up arrow', () => { 53 | cy.changeProps('from', undefined) 54 | cy.changeProps('to', undefined) 55 | cy.changeProps('type', 'time') 56 | cy.changeSlots('up-arrow', 'افزایش') 57 | cy.visit('/') 58 | cy.get('.pdp-input').focus().get('.hour button:first-child,.minute button:first-child') 59 | .should('contain.text', 'افزایش') 60 | }) 61 | 62 | it('down arrow', () => { 63 | cy.changeProps('type', 'datetime') 64 | cy.changeSlots('down-arrow', 'کاهش') 65 | cy.visit('/') 66 | cy.get('.pdp-input').focus().get('.hour button:last-child,.minute button:last-child') 67 | .should('contain.text', 'کاهش') 68 | }) 69 | }) 70 | -------------------------------------------------------------------------------- /cypress/plugins/index.js: -------------------------------------------------------------------------------- 1 | /// 2 | // *********************************************************** 3 | // This example plugins/index.js can be used to load plugins 4 | // 5 | // You can change the location of this file or turn off loading 6 | // the plugins file with the 'pluginsFile' configuration option. 7 | // 8 | // You can read more here: 9 | // https://on.cypress.io/plugins-guide 10 | // *********************************************************** 11 | 12 | // This function is called when a project is opened or re-opened (e.g. due to 13 | // the project's config changing) 14 | 15 | /** 16 | * @type {Cypress.PluginConfig} 17 | */ 18 | module.exports = (on, config) => { 19 | // `on` is used to hook into various events Cypress emits 20 | // `config` is the resolved Cypress config 21 | } 22 | -------------------------------------------------------------------------------- /cypress/support/commands.js: -------------------------------------------------------------------------------- 1 | // *********************************************** 2 | // This example commands.js shows you how to 3 | // create various custom commands and overwrite 4 | // existing commands. 5 | // 6 | // For more comprehensive examples of custom 7 | // commands please read more here: 8 | // https://on.cypress.io/custom-commands 9 | // *********************************************** 10 | // 11 | // 12 | // -- This is a parent command -- 13 | // Cypress.Commands.add("login", (email, password) => { ... }) 14 | // 15 | // 16 | // -- This is a child command -- 17 | // Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... }) 18 | // 19 | // 20 | // -- This is a dual command -- 21 | // Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... }) 22 | // 23 | // 24 | // -- This will overwrite an existing command -- 25 | // Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) 26 | 27 | let props = { 28 | "from": "1399", 29 | "to": "1399/06/31" 30 | } 31 | 32 | let slots = {} 33 | 34 | Cypress.Commands.add('changeProps', (prop, value) => { 35 | if (prop) 36 | props[prop] = value 37 | cy.writeFile('test/props.json', props) 38 | }) 39 | 40 | Cypress.Commands.add('changeSlots', (slot, value) => { 41 | if (slot) 42 | slots[slot] = value 43 | cy.writeFile('test/slots.json', slots) 44 | }) 45 | 46 | Cypress.Commands.add('selectDate', () => { 47 | cy.get('.pdp-input').focus() 48 | cy.get('.pdp-day').contains('10').click() 49 | }) 50 | 51 | Cypress.Commands.add('selectRangeDate', () => { 52 | cy.get('.pdp-input').focus() 53 | cy.get('.pdp-day').contains('10').click() 54 | cy.get('.pdp-day').contains('15').click() 55 | }) 56 | 57 | Cypress.Commands.add('selectTime', (hour = 0, minute = 0, child = 'first') => { 58 | let nowHour = new Date().getHours(); 59 | nowHour = hour - nowHour; 60 | if (nowHour < 0) 61 | nowHour += 24 62 | let button = cy.get(`.pdp-time .pdp-moment > div:${child}-child .hour button:first-child`); 63 | for (let i = 0; i < nowHour; i++) { 64 | button.click() 65 | } 66 | let nowMinute = new Date().getMinutes(); 67 | nowMinute = minute - nowMinute; 68 | if (nowMinute < 0) 69 | nowMinute += 60 70 | button = cy.get(`.pdp-time .pdp-moment > div:${child}-child .minute button:first-child`); 71 | for (let i = 0; i < nowMinute; i++) { 72 | button.click() 73 | } 74 | }) -------------------------------------------------------------------------------- /cypress/support/index.js: -------------------------------------------------------------------------------- 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 commands.js using ES2015 syntax: 17 | import './commands' 18 | import 'cypress-plugin-tab' 19 | 20 | // Alternatively you can use CommonJS syntax: 21 | // require('./commands') -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vue Persian DatePicker 8 | 9 | 10 | 11 | 17 |
18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /nuxt.js: -------------------------------------------------------------------------------- 1 | import { join } from "path"; 2 | 3 | export default function (option) { 4 | if (option["PersianDate"]) { 5 | this.addModule("@alireza-ab/persian-date/nuxt"); 6 | } 7 | this.nuxt.hook("components:dirs", (dirs) => { 8 | dirs.push({ 9 | path: join(__dirname, "src/components"), 10 | pattern: "**/*.vue", 11 | }); 12 | }); 13 | } 14 | 15 | module.exports.meta = require("./package.json"); 16 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@alireza-ab/vue-persian-datepicker", 3 | "description": "A datepicker component for select persian date", 4 | "version": "2.3.2", 5 | "main": "./dist/datepicker.common.js", 6 | "unpkg": "./dist/datepicker.min.js", 7 | "scripts": { 8 | "serve": "webpack serve", 9 | "build:prod": "cross-env NODE_ENV=production webpack", 10 | "build:common": "cross-env NODE_ENV=common webpack", 11 | "build:unpkg": "cross-env NODE_ENV=unpkg webpack", 12 | "build:all": "npm run build:prod && npm run build:common && npm run build:unpkg", 13 | "cy:open": "cypress open", 14 | "cy:run": "cypress run", 15 | "cy:run-parallel": "cypress run --parallel --ci-build-id GITHUB_TOKEN --record --key de25f7c7-0bd0-4651-8063-eca94dfd3591", 16 | "serve:test": "cross-env NODE_ENV=test webpack serve --port 8081", 17 | "test": "npm run serve:test > /dev/null 2>&1 & npm run cy:run" 18 | }, 19 | "homepage": "https://alireza-ab.ir/datepicker", 20 | "bugs": { 21 | "url": "https://github.com/alireza-ab/vue-persian-datepicker/issues" 22 | }, 23 | "repository": { 24 | "type": "git", 25 | "url": "https://github.com/alireza-ab/vue-persian-datepicker.git" 26 | }, 27 | "keywords": [ 28 | "javascript", 29 | "js", 30 | "vuejs", 31 | "nuxtjs", 32 | "date", 33 | "persian", 34 | "jalali", 35 | "shamsi", 36 | "datepicker", 37 | "persian datepicker", 38 | "jalali datepicker", 39 | "shamsi datepicker", 40 | "range datepicker", 41 | "persian range datepicker", 42 | "vue datepicker", 43 | "vue persian datepicker", 44 | "vue persian range datepicker", 45 | "nuxt datepicker", 46 | "nuxt persian datepicker", 47 | "nuxt persian range datepicker" 48 | ], 49 | "files": [ 50 | "src", 51 | "dist", 52 | "nuxt.js" 53 | ], 54 | "author": "Alireza Alibeiki ", 55 | "license": "MIT", 56 | "dependencies": { 57 | "@alireza-ab/persian-date": "^2.6.2" 58 | }, 59 | "devDependencies": { 60 | "@babel/core": "^7.17.0", 61 | "@vue/cli-plugin-babel": "^4.5.15", 62 | "@webpack-cli/serve": "^1.6.1", 63 | "babel-loader": "^8.2.3", 64 | "core-js": "^3.21.0", 65 | "cross-env": "^7.0.3", 66 | "css-loader": "^6.6.0", 67 | "cypress": "^9.4.1", 68 | "cypress-plugin-tab": "^1.0.5", 69 | "postcss-loader": "^6.2.1", 70 | "sass": "^1.49.7", 71 | "sass-loader": "^12.4.0", 72 | "style-loader": "^3.3.1", 73 | "terser-webpack-plugin": "^5.3.1", 74 | "vue": "^2.6.14", 75 | "vue-loader": "^15.9.8", 76 | "vue-template-compiler": "^2.6.14", 77 | "webpack": "^5.68.0", 78 | "webpack-cli": "^4.9.2", 79 | "webpack-dev-server": "^3.11.2" 80 | }, 81 | "browserslist": [ 82 | "> 1%", 83 | "last 2 versions", 84 | "not dead" 85 | ] 86 | } 87 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 57 | 58 | 198 | 199 | 210 | -------------------------------------------------------------------------------- /src/components/DatePicker.vue: -------------------------------------------------------------------------------- 1 | 384 | 385 | 1548 | 1549 | 1552 | -------------------------------------------------------------------------------- /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 | @import "_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: $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: $radius; 30 | border-radius: var(--radius); 31 | border: 0.1rem solid white; /* should match background, can't be transparent */ 32 | background: $border-color; 33 | background: var(--border-color); 34 | } 35 | } 36 | 37 | @keyframes start { 38 | from { 39 | transform: scale(0.5); 40 | opacity: 0; 41 | } 42 | to { 43 | transform: 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: $radius !important; 102 | border-radius: var(--radius) !important; 103 | } 104 | 105 | &.pdp-range .pdp-picker.rtl .pdp-day.start-range { 106 | border-radius: 0 $radius $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: $radius 0 0 $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: $radius !important; 117 | border-radius: var(--radius) !important; 118 | } 119 | 120 | &.pdp-range .pdp-picker.ltr .pdp-day.start-range { 121 | border-radius: $radius 0 0 $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 $radius $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: $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 { 141 | border-top-right-radius: $radius; 142 | border-top-right-radius: var(--radius); 143 | border-bottom-right-radius: $radius; 144 | border-bottom-right-radius: var(--radius); 145 | margin-right: -1px; 146 | } 147 | 148 | input { 149 | border-top-left-radius: $radius; 150 | border-top-left-radius: var(--radius); 151 | border-bottom-left-radius: $radius; 152 | border-bottom-left-radius: var(--radius); 153 | } 154 | } 155 | 156 | .pdp-picker::after { 157 | right: 1.2rem; 158 | } 159 | } 160 | 161 | &.ltr { 162 | direction: ltr; 163 | text-align: left; 164 | 165 | .pdp-group { 166 | :first-child { 167 | border-top-left-radius: $radius; 168 | border-top-left-radius: var(--radius); 169 | border-bottom-left-radius: $radius; 170 | border-bottom-left-radius: var(--radius); 171 | margin-right: -1px; 172 | } 173 | 174 | input { 175 | border-top-right-radius: $radius; 176 | border-top-right-radius: var(--radius); 177 | border-bottom-right-radius: $radius; 178 | border-bottom-right-radius: var(--radius); 179 | font-family: sans-serif; 180 | } 181 | 182 | .pdp-clear { 183 | left: unset; 184 | right: 0.45rem; 185 | } 186 | } 187 | 188 | .pdp-picker::after { 189 | left: 1.2rem; 190 | } 191 | } 192 | 193 | &.pdp-modal { 194 | .pdp-overlay { 195 | background: rgba(0, 0, 0, 0.5) !important; 196 | } 197 | 198 | .pdp-picker { 199 | position: fixed; 200 | top: 50%; 201 | left: 50%; 202 | transform: translate(-50%, -50%); 203 | animation: startModal 0.1s; 204 | 205 | &::after { 206 | all: unset !important; 207 | } 208 | } 209 | } 210 | 211 | * { 212 | box-sizing: border-box; 213 | } 214 | 215 | svg { 216 | vertical-align: middle; 217 | } 218 | 219 | input, 220 | button { 221 | font-family: inherit; 222 | } 223 | 224 | .pdp-label { 225 | display: inline-block; 226 | margin-bottom: 0.5rem; 227 | } 228 | 229 | .pdp-group { 230 | position: relative; 231 | display: flex; 232 | align-items: stretch; 233 | width: 100%; 234 | 235 | .pdp-input { 236 | display: block; 237 | height: calc(1.5em + 0.75rem + 2px); 238 | padding: 0.375rem 0.75rem; 239 | font-size: 1rem; 240 | font-weight: 400; 241 | line-height: 1.5; 242 | background-clip: padding-box; 243 | border: 1px solid $border-color; 244 | border: 1px solid var(--border-color); 245 | transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; 246 | position: relative; 247 | flex: 1 1 auto; 248 | } 249 | 250 | .pdp-icon { 251 | padding: 0.375rem 0.75rem; 252 | line-height: 1.5; 253 | font-size: 1rem; 254 | color: $text-color; 255 | color: var(--text-color); 256 | background: $icon-background; 257 | background: var(--icon-background); 258 | border: 1px solid $border-color; 259 | border: 1px solid var(--border-color); 260 | } 261 | 262 | .pdp-clear { 263 | border: none; 264 | background-color: transparent; 265 | position: absolute; 266 | left: 0.45rem; 267 | top: 0.45rem; 268 | z-index: 1; 269 | cursor: pointer; 270 | padding: 0 0.5rem; 271 | } 272 | } 273 | 274 | .pdp-overlay { 275 | position: fixed; 276 | top: 0; 277 | bottom: 0; 278 | right: 0; 279 | left: 0; 280 | z-index: $z-index; 281 | z-index: var(--z-index); 282 | background: $overlay-color; 283 | background: var(--overlay-color); 284 | } 285 | 286 | .pdp-picker { 287 | display: flex; 288 | position: absolute; 289 | color: $text-color; 290 | color: var(--text-color); 291 | background: $background; 292 | background: var(--background); 293 | box-shadow: $main-box-shadow; 294 | box-shadow: var(--main-box-shadow); 295 | z-index: $z-index + 1; 296 | z-index: calc(var(--z-index) + 1); 297 | border-radius: $radius; 298 | border-radius: var(--radius); 299 | transition: all 1s ease; 300 | margin-top: 0.5rem; 301 | padding: 0.3rem 0.6rem; 302 | animation: start 0.1s; 303 | 304 | &.ltr { 305 | direction: ltr; 306 | 307 | .pdp-header .bottom { 308 | flex-direction: row-reverse; 309 | 310 | & > div { 311 | display: flex; 312 | flex-direction: row-reverse; 313 | } 314 | } 315 | 316 | .pdp-select-year, 317 | .pdp-days, 318 | .pdp-header .pdp-year, 319 | .pdp-footer small, 320 | .pdp-time { 321 | font-family: sans-serif !important; 322 | } 323 | 324 | .pdp-shortcut { 325 | border-right: unset; 326 | border-left: 1px solid $border-color; 327 | border-left: 1px solid var(--border-color); 328 | } 329 | } 330 | 331 | &.rtl { 332 | direction: rtl; 333 | } 334 | 335 | &.pdp-top { 336 | bottom: calc(1.5em + 0.75rem + 2px); 337 | margin-top: unset; 338 | margin-bottom: 0.5rem; 339 | 340 | &::after { 341 | bottom: unset; 342 | top: 100%; 343 | transform: rotate(180deg); 344 | } 345 | } 346 | 347 | &.pdp-left { 348 | left: 0; 349 | right: unset; 350 | 351 | &::after { 352 | right: unset; 353 | left: 1.2rem; 354 | } 355 | } 356 | 357 | &.pdp-right { 358 | left: unset; 359 | right: 0; 360 | 361 | &::after { 362 | left: unset; 363 | right: 1.2rem; 364 | } 365 | } 366 | 367 | @include little-flag(); 368 | 369 | ::selection { 370 | all: unset; 371 | } 372 | 373 | .pdp-auto { 374 | &, 375 | & > div { 376 | background: inherit; 377 | } 378 | } 379 | 380 | .pdp-select-year, 381 | .pdp-select-month { 382 | display: flex; 383 | flex-wrap: wrap; 384 | justify-content: center; 385 | align-items: center; 386 | font-size: 0.8rem; 387 | background: inherit; 388 | list-style: none; 389 | position: absolute; 390 | left: 0; 391 | right: 0; 392 | top: 3.5rem; 393 | bottom: 3.5rem; 394 | padding: 0; 395 | margin: 0; 396 | z-index: 1; 397 | animation: start 0.1s; 398 | overflow: auto; 399 | 400 | li { 401 | width: 5rem; 402 | height: 4rem; 403 | padding: 0.2rem; 404 | cursor: pointer; 405 | margin: 0.15rem; 406 | display: inline-flex; 407 | justify-content: center; 408 | align-items: center; 409 | flex: 30% 0; 410 | 411 | &:not(.disabled):hover { 412 | border-radius: $radius; 413 | border-radius: var(--radius); 414 | border: 2px solid $primary-color; 415 | border: 2px solid var(--primary-color); 416 | } 417 | 418 | &.disabled { 419 | text-shadow: unset; 420 | box-shadow: unset; 421 | cursor: default !important; 422 | opacity: $disabled-opacity; 423 | opacity: var(--disabled-opacity); 424 | } 425 | 426 | &.selected { 427 | border: 2px solid $primary-color; 428 | border: 2px solid var(--primary-color); 429 | border-radius: $radius; 430 | border-radius: var(--radius); 431 | background: $primary-color !important; 432 | background: var(--primary-color) !important; 433 | color: $background; 434 | color: var(--background); 435 | } 436 | } 437 | 438 | @include scrollbar(); 439 | } 440 | 441 | .pdp-header { 442 | & > div:first-child { 443 | border-bottom: 1px solid $border-color; 444 | border-bottom: 1px solid var(--border-color); 445 | margin-bottom: 0.5rem; 446 | } 447 | 448 | .top { 449 | padding: 0.75rem 0.3rem 1rem 0.3rem; 450 | display: flex; 451 | justify-content: space-between; 452 | font-size: 0.9rem; 453 | direction: rtl; 454 | 455 | button { 456 | border: 0; 457 | background: inherit; 458 | cursor: pointer; 459 | color: $primary-color; 460 | color: var(--primary-color); 461 | padding: 0 0.5rem; 462 | } 463 | } 464 | 465 | .bottom { 466 | padding: 0.3rem; 467 | display: flex; 468 | align-items: center; 469 | height: 3rem; 470 | direction: rtl; 471 | 472 | & > div { 473 | display: flex; 474 | flex-grow: 1; 475 | justify-content: space-around; 476 | 477 | .pdp-month, 478 | .pdp-year { 479 | color: $primary-color; 480 | color: var(--primary-color); 481 | font-size: 1rem; 482 | } 483 | } 484 | 485 | button { 486 | border: 0; 487 | background: inherit; 488 | cursor: pointer; 489 | 490 | &:focus { 491 | outline: 0; 492 | } 493 | } 494 | 495 | .pdp-arrow.disabled { 496 | opacity: $disabled-opacity; 497 | opacity: var(--disabled-opacity); 498 | } 499 | 500 | .pdp-arrow:not(.disabled):hover { 501 | opacity: $disabled-opacity; 502 | opacity: var(--disabled-opacity); 503 | } 504 | } 505 | } 506 | 507 | .pdp-main { 508 | position: relative; 509 | 510 | .pdp-date { 511 | display: flex; 512 | justify-content: center; 513 | 514 | .pdp-column { 515 | margin: 0 1rem; 516 | 517 | .pdp-week { 518 | background: inherit; 519 | margin-bottom: 0.3rem; 520 | display: flex; 521 | justify-content: space-around; 522 | 523 | .pdp-weekday { 524 | width: $day-dimensions; 525 | width: var(--day-dim$day-dimensions); 526 | height: $day-dimensions; 527 | height: var(--day-dim$day-dimensions); 528 | line-height: $day-dimensions; 529 | line-height: var(--day-dim$day-dimensions); 530 | font-size: 0.8rem; 531 | text-align: center; 532 | } 533 | } 534 | 535 | .pdp-days { 536 | background: inherit; 537 | 538 | .pdp-day { 539 | display: inline-flex; 540 | justify-content: center; 541 | align-items: center; 542 | margin: 0.1rem 0; 543 | font-size: 0.8rem; 544 | width: $day-dimensions; 545 | width: var(--day-dim$day-dimensions); 546 | height: $day-dimensions; 547 | height: var(--day-dim$day-dimensions); 548 | border-radius: $radius; 549 | border-radius: var(--radius); 550 | padding: 0; 551 | cursor: pointer; 552 | transition-property: background-color, box-shadow; 553 | transition-duration: 0.1s; 554 | contain: content; 555 | 556 | &.friday { 557 | color: $primary-color; 558 | color: var(--primary-color); 559 | } 560 | 561 | &.empty { 562 | visibility: hidden; 563 | } 564 | 565 | &.start-range, 566 | &.end-range { 567 | background: $primary-color; 568 | background: var(--primary-color); 569 | color: $background; 570 | color: var(--background); 571 | } 572 | 573 | &.disabled { 574 | box-shadow: unset; 575 | text-shadow: unset; 576 | cursor: default !important; 577 | border-color: transparent; 578 | opacity: $disabled-opacity; 579 | opacity: var(--disabled-opacity); 580 | } 581 | 582 | &.hover { 583 | background: $secondary-color !important; 584 | background: var(--secondary-color) !important; 585 | color: $hover-color; 586 | color: var(--hover-color); 587 | } 588 | 589 | &.in-range { 590 | background: $in-range-background; 591 | background: var(--in-range-background); 592 | color: $hover-color; 593 | color: var(--hover-color); 594 | border-radius: 0 !important; 595 | } 596 | 597 | &:not(.disabled):hover, 598 | &.today { 599 | border: 2px solid $primary-color; 600 | border: 2px solid var(--primary-color); 601 | } 602 | 603 | &.tada { 604 | animation: tada 1s; 605 | background: $secondary-color; 606 | background: var(--secondary-color); 607 | box-shadow: inset 0 4px 9px rgba(0, 0, 0, 0.24); 608 | color: #000; 609 | position: relative; 610 | z-index: 1; 611 | } 612 | } 613 | } 614 | } 615 | } 616 | 617 | .pdp-time { 618 | background: inherit; 619 | 620 | &:not(.inline) { 621 | position: absolute; 622 | top: 0; 623 | bottom: 0; 624 | right: 0; 625 | left: 0; 626 | } 627 | 628 | .pdp-column { 629 | display: flex; 630 | 631 | div { 632 | width: 16.6rem; 633 | } 634 | } 635 | 636 | .pdp-moment { 637 | margin-bottom: 1rem; 638 | font-size: calc(2rem * #{$time-scale}); 639 | font-size: calc(2rem * var(--time-scale)); 640 | display: flex; 641 | justify-content: space-around; 642 | height: 100%; 643 | 644 | &.column-direction { 645 | flex-direction: column; 646 | } 647 | 648 | > div { 649 | display: flex; 650 | justify-content: center; 651 | align-items: center; 652 | direction: ltr; 653 | width: 100%; 654 | padding: 1rem 0; 655 | 656 | &.disabled { 657 | opacity: $disabled-opacity; 658 | opacity: var(--disabled-opacity); 659 | } 660 | 661 | div { 662 | display: flex; 663 | flex-direction: column; 664 | align-items: center; 665 | padding: 0 0.8rem; 666 | 667 | button { 668 | border: none; 669 | background: none; 670 | cursor: pointer; 671 | 672 | svg { 673 | width: calc(8px * #{$time-scale}); 674 | width: calc(8px * var(--time-scale)); 675 | } 676 | } 677 | } 678 | } 679 | } 680 | } 681 | } 682 | 683 | .pdp-footer { 684 | text-align: center; 685 | min-height: 3rem; 686 | display: flex; 687 | align-items: center; 688 | justify-content: space-between; 689 | border-top: 1px solid $border-color; 690 | border-top: 1px solid var(--border-color); 691 | padding: 0.3rem; 692 | 693 | .pdp-today, 694 | .pdp-submit { 695 | font-size: 0.8rem; 696 | padding: 0.25rem 0.5rem; 697 | margin: 0 0.3rem; 698 | line-height: 1.5; 699 | color: $background; 700 | color: var(--background); 701 | text-decoration: none; 702 | border: none; 703 | border-radius: $radius; 704 | border-radius: var(--radius); 705 | background: $primary-color; 706 | background: var(--primary-color); 707 | cursor: pointer; 708 | 709 | &:hover { 710 | filter: brightness(0.9); 711 | } 712 | } 713 | 714 | > div { 715 | display: flex; 716 | } 717 | } 718 | 719 | .pdp-shortcut { 720 | margin: 0; 721 | padding: 0.5rem; 722 | list-style: none; 723 | display: flex; 724 | flex-direction: column; 725 | align-items: stretch; 726 | border-right: 1px solid $border-color; 727 | border-right: 1px solid var(--border-color); 728 | 729 | li { 730 | margin: 0; 731 | padding: 0.5rem 1rem; 732 | text-align: center; 733 | cursor: pointer; 734 | border-radius: $radius; 735 | border-radius: var(--radius); 736 | margin: 0.25rem 0; 737 | color: $hover-color; 738 | color: var(--hover-color); 739 | font-weight: 500; 740 | 741 | &:hover { 742 | background: $in-range-background; 743 | background: var(--in-range-background); 744 | } 745 | 746 | &.selected { 747 | background: $primary-color; 748 | background: var(--primary-color); 749 | color: $background; 750 | color: var(--background); 751 | } 752 | } 753 | } 754 | } 755 | 756 | .pdp-pointer { 757 | cursor: pointer; 758 | } 759 | 760 | .pdp-auto { 761 | margin: auto; 762 | position: relative; 763 | } 764 | } 765 | -------------------------------------------------------------------------------- /src/components/utils/components/ArrowIcon.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 44 | -------------------------------------------------------------------------------- /src/components/utils/components/CalendarClockIcon.vue: -------------------------------------------------------------------------------- 1 | 72 | 73 | 78 | -------------------------------------------------------------------------------- /src/components/utils/components/CalendarIcon.vue: -------------------------------------------------------------------------------- 1 | 34 | 35 | 40 | -------------------------------------------------------------------------------- /src/components/utils/components/ClearIcon.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 15 | -------------------------------------------------------------------------------- /src/components/utils/components/ClockIcon.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 20 | -------------------------------------------------------------------------------- /src/components/utils/modules/core.js: -------------------------------------------------------------------------------- 1 | import PersianDate from "@alireza-ab/persian-date" 2 | 3 | const Core = { 4 | langs: { 5 | fa: { 6 | calendar: "jalali", 7 | weekdays: ["ش", "ی", "د", "س", "چ", "پ", "ج"], 8 | months: [ 9 | "فروردین", 10 | "اردیبهشت", 11 | "خرداد", 12 | "تیر", 13 | "مرداد", 14 | "شهریور", 15 | "مهر", 16 | "آبان", 17 | "آذر", 18 | "دی", 19 | "بهمن", 20 | "اسفند", 21 | ], 22 | dir: { 23 | input: "rtl", 24 | picker: "rtl", 25 | }, 26 | translations: { 27 | label: "شمسی", 28 | text: "تقویم شمسی", 29 | prevMonth: "ماه قبل", 30 | nextMonth: "ماه بعد", 31 | now: "هم اکنون", 32 | submit: "تایید", 33 | /* use in shourcuts */ 34 | // date-single 35 | yesterday: "دیروز", 36 | tomorrow: "فردا", 37 | firstOfWeek: "اول هفته", 38 | lastOfWeek: "آخر هفته", 39 | // date-range 40 | thisWeek: "این هفته", 41 | prevWeek: "هفته قبل", 42 | nextWeek: "هفته بعد", 43 | thisMonth: "این ماه", 44 | // time-single 45 | oneHourAgo: "یک ساعت قبل", 46 | oneHourLater: "یک ساعت بعد", 47 | midnight: "نیمه شب", 48 | midday: "نیمروز", 49 | // time-range 50 | thisHour: "این ساعت", 51 | prevHour: "ساعت قبل", 52 | nextHour: "ساعت بعد", 53 | allDay: "تمام روز" 54 | }, 55 | inputFormat: "", 56 | displayFormat: "", 57 | }, 58 | en: { 59 | calendar: "gregorian", 60 | weekdays: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"], 61 | months: [ 62 | "January", 63 | "February", 64 | "March", 65 | "April", 66 | "May", 67 | "June", 68 | "July", 69 | "August", 70 | "September", 71 | "October", 72 | "November", 73 | "December", 74 | ], 75 | dir: { 76 | input: "rtl", 77 | picker: "ltr", 78 | }, 79 | translations: { 80 | label: "میلادی", 81 | text: "Gregorian Calendar", 82 | prevMonth: "Previous Month", 83 | nextMonth: "Next Month", 84 | now: "Now", 85 | submit: "Submit", 86 | /* use in shourcuts */ 87 | // date-single 88 | yesterday: "Yesterday", 89 | tomorrow: "Tomorrow", 90 | firstOfWeek: "First of Week", 91 | lastOfWeek: "Last of Week", 92 | // date-range 93 | thisWeek: "This Week", 94 | prevWeek: "Previous Week", 95 | nextWeek: "Next Week", 96 | thisMonth: "This Month", 97 | // time-single 98 | oneHourAgo: "One Hour ago", 99 | oneHourLater: "One Hour later", 100 | midnight: "Midnight", 101 | midday: "Midday", 102 | // time-range 103 | thisHour: "This Hour", 104 | prevHour: "Previous Hour", 105 | nextHour: "Next Hour", 106 | allDay: "All Day" 107 | }, 108 | inputFormat: "", 109 | displayFormat: "", 110 | }, 111 | }, 112 | mergeObject: function (original, changed) { 113 | let newObject = JSON.parse(JSON.stringify(original)); 114 | for (const key in changed) { 115 | if (original[key] && Object.prototype.toString.call(changed[key]) === "[object Object]") 116 | newObject[key] = this.mergeObject(original[key], changed[key]) 117 | else newObject[key] = changed[key]; 118 | } 119 | return newObject; 120 | }, 121 | setStyles: function (styles, root) { 122 | for (const name in styles) { 123 | root.style.setProperty("--" + name, styles[name]); 124 | } 125 | }, 126 | setColor: function (color, root) { 127 | if (!color) 128 | return; 129 | let colors = {} 130 | switch (color) { 131 | case "red": 132 | colors = { 133 | "primary-color": "#c7004c", 134 | "secondary-color": "#ffaaaa", 135 | "in-range-background": "#ffd2d2", 136 | } 137 | break; 138 | case "pink": 139 | colors = { 140 | "primary-color": "#e56ab3", 141 | "secondary-color": "#ef87be", 142 | "in-range-background": "#fcbcd7", 143 | } 144 | break; 145 | case "orange": 146 | colors = { 147 | "primary-color": "#ffa500", 148 | "secondary-color": "#ffbe47", 149 | "in-range-background": "#ffe0a6", 150 | } 151 | break; 152 | case "green": 153 | colors = { 154 | "primary-color": "#38a169", 155 | "secondary-color": "#89dda3", 156 | "in-range-background": "#c6f6d5", 157 | } 158 | break; 159 | case "purple": 160 | colors = { 161 | "primary-color": "#7825d0", 162 | "secondary-color": "#c196ed", 163 | "in-range-background": "#d4baf3", 164 | } 165 | break; 166 | case "gray": 167 | colors = { 168 | "primary-color": "#494848", 169 | "secondary-color": "#909090", 170 | "in-range-background": "#b4b4b4", 171 | } 172 | break; 173 | default: 174 | break; 175 | } 176 | this.setStyles(colors, root) 177 | }, 178 | getLastUnit: function (date, type) { 179 | const unitsCount = date.split(/[/ -.,:\\]/).length + (type == "time" ? 3 : 0); 180 | switch (unitsCount) { 181 | case 1: 182 | return "year"; 183 | case 2: 184 | return "month"; 185 | case 3: 186 | return "date"; 187 | case 4: 188 | return "hour"; 189 | case 5: 190 | return "minute"; 191 | case 6: 192 | return "second"; 193 | default: 194 | return "millisecond"; 195 | } 196 | }, 197 | isString: function (val) { 198 | return typeof val == "string"; 199 | }, 200 | isNumber: function (val) { 201 | return typeof val == "number"; 202 | }, 203 | isFunction: function (val) { 204 | return typeof val == "function"; 205 | }, 206 | isPersianDate: function (val) { 207 | return PersianDate.isPersianDate(val) 208 | }, 209 | } 210 | 211 | export { PersianDate, Core } -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | 4 | Vue.config.productionTip = false 5 | 6 | new Vue({ 7 | render: h => h(App), 8 | }).$mount('#app') 9 | -------------------------------------------------------------------------------- /test/App.vue: -------------------------------------------------------------------------------- 1 | 30 | 31 | 86 | 87 | 92 | -------------------------------------------------------------------------------- /test/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | 4 | Vue.config.productionTip = false 5 | 6 | new Vue({ 7 | render: h => h(App), 8 | }).$mount('#app') 9 | -------------------------------------------------------------------------------- /test/props.json: -------------------------------------------------------------------------------- 1 | { 2 | "clearable": true, 3 | "type": "datetime" 4 | } -------------------------------------------------------------------------------- /test/slots.json: -------------------------------------------------------------------------------- 1 | { 2 | "before": "", 3 | "after": "Please select date.", 4 | "icon": "Date", 5 | "right-arrow": "ماه قبل", 6 | "left-arrow": "ماه بعد", 7 | "footer": "تاریخ انتخابی:", 8 | "clear": "بستن", 9 | "up-arrow": "افزایش", 10 | "down-arrow": "کاهش" 11 | } -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const webpack = require("webpack"); 3 | const VueLoaderPlugin = require("vue-loader/lib/plugin"); 4 | const TerserPlugin = require("terser-webpack-plugin"); 5 | 6 | module.exports = { 7 | entry: process.env.NODE_ENV === "test" ? "./test/main.js" : "./src/main.js", 8 | output: { 9 | path: path.resolve(__dirname, "./dist"), 10 | publicPath: "/dist/", 11 | filename: "build.js", 12 | }, 13 | module: { 14 | rules: [ 15 | { 16 | test: /\.css$/, 17 | use: ["style-loader", "css-loader"], 18 | }, 19 | { 20 | test: /\.scss$/, 21 | use: ["style-loader", "css-loader", "sass-loader"], 22 | }, 23 | { 24 | test: /\.sass$/, 25 | use: ["style-loader", "css-loader", "sass-loader?indentedSyntax"], 26 | }, 27 | { 28 | test: /\.vue$/, 29 | loader: "vue-loader", 30 | options: { 31 | loaders: { 32 | scss: ["style-loader", "css-loader", "sass-loader"], 33 | sass: ["style-loader", "css-loader", "sass-loader?indentedSyntax"], 34 | }, 35 | }, 36 | }, 37 | { 38 | test: /\.js$/, 39 | loader: "babel-loader", 40 | exclude: /node_modules/, 41 | }, 42 | { 43 | test: /\.(png|jpg|gif|svg)$/, 44 | loader: "file-loader", 45 | options: { 46 | name: "[name].[ext]?[hash]", 47 | }, 48 | }, 49 | ], 50 | }, 51 | resolve: { 52 | alias: { 53 | vue$: "vue/dist/vue.esm.js", 54 | }, 55 | extensions: ["*", ".js", ".vue", ".json"], 56 | }, 57 | performance: { 58 | hints: false, 59 | }, 60 | optimization: { 61 | minimize: true, 62 | }, 63 | plugins: [new VueLoaderPlugin()], 64 | devtool: "eval-source-map", 65 | mode: "development", 66 | }; 67 | 68 | if (process.env.NODE_ENV === "production") { 69 | module.exports.devtool = "source-map"; 70 | // http://vue-loader.vuejs.org/en/workflow/production.html 71 | module.exports.plugins = (module.exports.plugins || []).concat([ 72 | new webpack.DefinePlugin({ 73 | "process.env.NODE_ENV": JSON.stringify("production"), 74 | }), 75 | new webpack.LoaderOptionsPlugin({ 76 | minimize: true, 77 | }), 78 | ]); 79 | module.exports.optimization.minimizer = [ 80 | new TerserPlugin({ 81 | terserOptions: { 82 | compress: {}, 83 | }, 84 | }), 85 | ]; 86 | } 87 | 88 | if (process.env.NODE_ENV === "common") { 89 | module.exports.devtool = "production"; 90 | module.exports.entry = "./src/components/DatePicker.vue"; 91 | 92 | module.exports.output = { 93 | path: path.resolve(__dirname, "./dist"), 94 | publicPath: "/dist/", 95 | filename: "datepicker.common.js", 96 | library: "datePicker", 97 | libraryTarget: "umd", 98 | }; 99 | 100 | module.exports.devtool = false; 101 | 102 | module.exports.plugins = (module.exports.plugins || []).concat([ 103 | new webpack.DefinePlugin({ 104 | "process.env.NODE_ENV": JSON.stringify("production"), 105 | }), 106 | new webpack.LoaderOptionsPlugin({ 107 | minimize: true, 108 | }), 109 | ]); 110 | 111 | module.exports.optimization.minimizer = [ 112 | new TerserPlugin({ 113 | terserOptions: { 114 | mangle: true, 115 | compress: {}, 116 | }, 117 | }), 118 | ]; 119 | } 120 | 121 | if (process.env.NODE_ENV === "unpkg") { 122 | module.exports.devtool = "production"; 123 | module.exports.entry = "./src/components/DatePicker.vue"; 124 | module.exports.output = { 125 | path: path.resolve(__dirname, "./dist"), 126 | publicPath: "/dist/", 127 | filename: "datepicker.min.js", 128 | library: "datePicker", 129 | libraryExport: "default", 130 | }; 131 | module.exports.devtool = false; 132 | module.exports.plugins = (module.exports.plugins || []).concat([ 133 | new webpack.DefinePlugin({ 134 | "process.env.NODE_ENV": JSON.stringify("production"), 135 | }), 136 | new webpack.LoaderOptionsPlugin({ 137 | minimize: true, 138 | }), 139 | ]); 140 | 141 | module.exports.optimization.minimizer = [ 142 | new TerserPlugin({ 143 | terserOptions: { 144 | mangle: true, 145 | warnings: false, 146 | compress: {}, 147 | }, 148 | }), 149 | ]; 150 | } 151 | --------------------------------------------------------------------------------