├── .eslintrc.cjs ├── .github └── ISSUE_TEMPLATE │ ├── --all-other-issues.md │ ├── --bug-report.md │ └── --feature-request.md ├── .gitignore ├── README.md ├── env.d.ts ├── example ├── .eslintrc.cjs ├── .gitignore ├── .prettierrc.json ├── README.md ├── env.d.ts ├── index.html ├── package-lock.json ├── package.json ├── public │ └── favicon.ico ├── src │ ├── App.vue │ └── main.ts ├── tsconfig.app.json ├── tsconfig.json ├── tsconfig.node.json └── vite.config.ts ├── index.html ├── package-lock.json ├── package.json ├── postcss.config.cjs ├── src ├── Calendar.d.ts ├── components │ ├── BaseIcon.vue │ ├── Calendar.vue │ ├── CalendarDays.vue │ ├── CalendarFooter.vue │ ├── CalendarHalfDay.vue │ ├── CalendarHeader.vue │ ├── CalendarInput.vue │ ├── CalendarTooltip.vue │ ├── __tests__ │ │ ├── BaseIcon.spec.ts │ │ ├── Calendar.spec.ts │ │ ├── CalendarDays.spec.ts │ │ ├── CalendarHeader.spec.ts │ │ ├── CalendarInput.spec.ts │ │ ├── __snapshots__ │ │ │ ├── Calendar.spec.ts.snap │ │ │ └── CalendarDays.spec.ts.snap │ │ └── helpers.spec.ts │ ├── compose │ │ ├── index.ts │ │ ├── useBookingStyle.ts │ │ ├── useCheckIncheckOutHalfDay.ts │ │ ├── useCreateHalfDayDates.ts │ │ ├── useCreateMonth.ts │ │ ├── useCreateMultipleMonths.ts │ │ ├── useFlatBooking.ts │ │ ├── useGetFlattenedPeriods.ts │ │ ├── useGetNextBookingDate.ts │ │ ├── useGetPeriod.ts │ │ └── useToggleCalendar.ts │ ├── generateMonth.ts │ └── helpers.ts ├── index.ts ├── plugins │ └── day.ts └── types │ └── index.ts ├── tailwind.config.cjs ├── tsconfig.app.json ├── tsconfig.json ├── tsconfig.node.json ├── tsconfig.vite-config.json ├── tsconfig.vitest.json ├── types └── main.d.ts └── vite.config.ts /.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | /* eslint-env node */ 2 | require("@rushstack/eslint-patch/modern-module-resolution"); 3 | 4 | module.exports = { 5 | root: true, 6 | extends: [ 7 | "plugin:vue/vue3-essential", 8 | "eslint:recommended", 9 | "@vue/eslint-config-typescript/recommended", 10 | "@vue/eslint-config-prettier", 11 | ], 12 | }; 13 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/--all-other-issues.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "❗️All other issues" 3 | about: Please create all other issues here. 4 | title: "[QUESTION]" 5 | labels: question 6 | assignees: joffreyBerrier 7 | 8 | --- 9 | 10 | **If you have a question. Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Additional context** 14 | Add any other context or screenshots about the question request here. 15 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/--bug-report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "\U0001F6A8Bug report" 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/--feature-request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "\U0001F64BFeature request" 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | .DS_Store 12 | dist 13 | dist-ssr 14 | coverage 15 | *.local 16 | 17 | /cypress/videos/ 18 | /cypress/screenshots/ 19 | 20 | # Editor directories and files 21 | .vscode/ 22 | !.vscode/extensions.json 23 | .idea 24 | *.suo 25 | *.ntvs* 26 | *.njsproj 27 | *.sln 28 | *.sw? 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vue-datepicker 2.6.3 2 | 3 | 👊 An easy-to-use datePicker in Vue.js 👊 4 | 5 | https://github.com/joffreyBerrier/vue-datepicker/projects/1 6 | 7 | 🔥 Vue3 + Typescript + Tailwind + HeroIcon 🔥 8 | 9 | # Ready to Experiment? 10 | Download the repository and execute `npm run dev` to get started! 11 | 12 | ## Installation 13 | 14 | #### NPM / YARN 15 | 16 | Install the package: 17 | 18 | ``` 19 | npm install vue-calendar-3 --save 20 | yarn add vue-calendar-3 21 | ``` 22 | 23 | ```javascript 24 | import { Calendar } from "vue-calendar-3"; 25 | // If you using vite 26 | import "vue-calendar-3/style"; 27 | // If you not 28 | import "vue-calendar-3/dist/index.css"; 29 | 30 | export default { 31 | components: { 32 | Calendar, 33 | }, 34 | }; 35 | ``` 36 | 37 | ```html 38 | 46 | 47 | 50 | ``` 51 | 52 | ## Colors 53 | 54 | Use css variable 55 | 56 | ```css 57 | --calendar-wrapper: #fff; 58 | 59 | --calendar-tooltip-bg: #202020; 60 | --calendar-tooltip-border: #202020; 61 | --calendar-tooltip-text: #fff; 62 | 63 | --calendar-half-day-color: #757575; 64 | --calendar-half-day-color-active: #222; 65 | 66 | --calendar-text-color: #202020; 67 | 68 | --day-border: #fff; 69 | --day-checkIn-checkOut: #8ebbbb; 70 | --day-disabled: #aaa; 71 | --day-hovering-with-checkIn: #8ebbbb; 72 | --day-range-days: #daebeb; 73 | 74 | --calendar-disabled-opacity: 0.5; 75 | 76 | --calendar-mobile-header-border-bottom-days: #eee; 77 | 78 | --calendar-input-bg: #fff; 79 | --calendar-input-border: #f0f2f6; 80 | --calendar-input-shadow: 0 0 0 0.2rem #eee; 81 | 82 | --calendar-paginate-bg: #fff; 83 | --calendar-paginate-text-color: #202020; 84 | --calendar-paginate-border-color: #f0f2f6; 85 | 86 | --calendar-paginate-hover-bg: #fff; 87 | --calendar-paginate-hover-text: #202020; 88 | --calendar-paginate-hover-border: #202020; 89 | 90 | --calendar-paginate-disabled-bg: #ffffff; 91 | --calendar-paginate-disabled-border: #f0f2f6; 92 | --calendar-paginate-disabled-text: #f0f2f6; 93 | 94 | --day-today: #264646; 95 | ``` 96 | 97 | ## Data binding 98 | 99 | ### CheckIn 100 | 101 | - Type: `Date` 102 | - Default: `null` 103 | 104 | Example: `v-model:checkIn=""` 105 | 106 | ### CheckOut 107 | 108 | - Type: `Date` 109 | - Default: `null` 110 | 111 | Example: `v-model:checkOut=""` 112 | 113 | ## Props/Options 114 | 115 | ### SingleCalendar 116 | - Type: `Boolean` 117 | - Default: `false` 118 | 119 | Show single mode calendar 120 | 121 | ### alwaysVisible 122 | 123 | - Type: `Boolean` 124 | - Default: `false` 125 | 126 | Show calendar by default 127 | 128 | ### bookingColor 129 | 130 | - Type: `Object as PropType` 131 | - Default: `{}` 132 | 133 | Allows you to define colors for your bookings, the name of the key must be equal to your type key in the booking object 134 | 135 | Example: 136 | 137 | ```javascript 138 | bookingColor: { 139 | admin: "#9dc1c9", 140 | contract: "#a56a0b", 141 | }; 142 | ``` 143 | 144 | ### bookingDates 145 | 146 | - Type: `Array as PropType` 147 | - Default: `[]` 148 | 149 | Allows you to define a date range (Booking) 150 | 151 | Example: 152 | 153 | ```javascript 154 | bookingDates: [ 155 | { 156 | checkInDate: "2022-07-01", 157 | checkOutDate: "2022-07-10", 158 | type: "admin", 159 | }, 160 | { 161 | checkInDate: "2022-08-01", 162 | checkOutDate: "2022-08-20", 163 | type: "contract", 164 | }, 165 | ]; 166 | ``` 167 | 168 | ### disabledDaysAfterDayDate 169 | 170 | - Type: `Boolean` 171 | - Default: `false` 172 | 173 | Disabled days after the current date 174 | 175 | ### disabledDaysBeforeDayDate 176 | 177 | - Type: `Boolean` 178 | - Default: `true` 179 | 180 | Disabled days before the current date 181 | 182 | ### disabled 183 | 184 | - Type: `Boolean` 185 | - Default: `true` 186 | 187 | Disabled the click on input calendar 188 | 189 | ### hasFooter 190 | 191 | - Type: `Boolean` 192 | - Default: `false` 193 | 194 | Hidden / Show the default footer of the calendar 195 | 196 | ### hasHeader 197 | 198 | - Type: `Boolean` 199 | - Default: `false` 200 | 201 | Hidden / Show the default header of the calendar 202 | 203 | ### isAffixed 204 | 205 | - Type: `Boolean` 206 | - Default: `false` 207 | 208 | Add a calendar in a modal 209 | 210 | ### startDate 211 | 212 | - Type: `Date` 213 | - Default: `new Date(new Date().getFullYear() - 2, 0, 1)` 214 | 215 | Define the first Date in your calendar 216 | 217 | ### endDate 218 | 219 | - Type: `Date` 220 | - Default: `new Date(new Date().getFullYear() + 2, 0, 1)` 221 | 222 | Define the last Date in your calendar 223 | 224 | ### formatDate 225 | 226 | - Type: `String` 227 | - Default: `YYYY-MM-DD` 228 | 229 | Define the format of your date 230 | 231 | ### placeholder 232 | 233 | - Type: `Object as PropType` 234 | - Default: `{ checkIn: "Arrivée", checkOut: "Départ", }` 235 | 236 | Define the text of you input calendar 237 | 238 | ### position 239 | 240 | - Type: `String` 241 | - Default: `left` 242 | 243 | Define the position of the calendar (right or left) 244 | 245 | ### showYear 246 | 247 | - Type: `Boolean` 248 | - Default: `false` 249 | 250 | show the calendar in year mode 251 | 252 | ### showInputCalendar 253 | 254 | - Type: `Boolean` 255 | - Default: `false` 256 | 257 | hide / show the input calendar 258 | 259 | ### BookedDates 260 | 261 | - Type: `string[]` 262 | - Default: `[]` 263 | 264 | This data is an array of your booked dates, the date is already booked is appear it in disabled 265 | 266 | Example: 267 | 268 | ```javascript 269 | bookedDates: [ 270 | "2021-06-01", 271 | "2021-06-02", 272 | "2021-06-03", 273 | "2021-06-23", 274 | "2021-06-24", 275 | "2021-06-25", 276 | ]; 277 | ``` 278 | 279 | ### periodManagementRule 280 | 281 | - Type: `Boolean` 282 | - Default: `false` 283 | 284 | Active the period management rules : 285 | 286 | ### PeriodDates 287 | 288 | - Type: `Array` 289 | - Default: `[]` 290 | 291 | This data is an array of object of your periods 292 | 293 | #### The **startAt** 294 | 295 | Corresponds to the start of your periods with the format `YYYY-MM-DD` 296 | 297 | #### The **endAt** 298 | 299 | Corresponds to the start of your periods with the format `YYYY-MM-DD` 300 | 301 | **Each period correspond to different logic define by `periodType` and `minimumDuration`** 302 | 303 | #### The **periodType**: 304 | 305 | - Corresponds to the day you want to block the period, `nightly`,` weekly_by_saturday`, `weekly_by_sunday` or `weekly_by_monday` 306 | 307 | #### The **minimumDuration**: 308 | 309 | - Corresponds to the number of the days where you want to block the period. 310 | 311 | - If the periodType is `nightly` the count corresponds the number of days 312 | - If the periodType is `weekly_by_saturday`, `weekly_by_sunday` or `weekly_by_monday` the count corresponds to the number of weeks 313 | 314 | Example: 315 | 316 | ```javascript 317 | periodDates: [ 318 | // Nightly 319 | { 320 | startAt: "2021-08-01", 321 | endAt: "2021-08-31", 322 | minimumDuration: 4, 323 | periodType: "nightly", 324 | }, 325 | // Weekly Saturday 326 | { 327 | startAt: "2021-09-01", 328 | endAt: "2021-09-30", 329 | minimumDuration: 2, 330 | periodType: "weekly_by_saturday", 331 | }, 332 | // Weekly Sunday 333 | { 334 | startAt: "2021-11-01", 335 | endAt: "2021-11-29", 336 | minimumDuration: 1, 337 | periodType: "weekly_by_sunday", 338 | }, 339 | ]; 340 | ``` 341 | 342 | ### The **translations** 343 | ```js 344 | fr: {...}, 345 | en: { 346 | clearDates: "Clear dates", 347 | close: "Close", 348 | days: { 349 | monday: "Mo", 350 | tuesday: "Tu", 351 | wednesday: "We", 352 | thursday: "Th", 353 | friday: "Fr", 354 | saturday: "Sa", 355 | sunday: "Su", 356 | }, 357 | today: "Today", 358 | periodType: { 359 | weeklyBySaturday: "From Saturday to Saturday", 360 | weeklyBySunday: "From Sunday to Sunday", 361 | weeklyByMonday: "From Monday to Monday", 362 | nightly: "A minimum of %{minimumDuration} night is required", 363 | }, 364 | halfDay: { 365 | checkIn: "Possible end of stay", 366 | checkOut: "Possible start of stay", 367 | }, 368 | } 369 | ``` 370 | 371 | ℹ️ Now, please set the `locale` **props** to view your translations in action. 372 | 373 | 374 | ### Timezone 375 | 376 | - Type : `String` 377 | - Default: `Europe/Paris` 378 | 379 | Define the timezone of the Calendar for manage periods and disabled dates in the correct timezone 380 | 381 | ## Events 382 | 383 | * `clear-dates`: Fires when date is cleared 384 | * `close-date-picker`: Fires when the calendar is closed 385 | * `render-next-date`: Fires when date is paginate to the next month 386 | * `render-previous-date`: Fires when date is paginate to the previous month 387 | * `select-booking-date`: Fires when click on a booking 388 | * `update:checkIn`: Fires when click on a checkIn 389 | * `update:checkOut`: Fires when click on a checkOut 390 | 391 | ## Expose 392 | 393 | Expose allows you to access to different methods with a ref on the Calendar component 394 | 395 | ### Data 396 | * `activeIndex`: Get the index of pagination (use a computed for that) 397 | * `showCalendar`: Get the value of the calendar display 398 | 399 | ### Methods 400 | * `clearDates`: Allows you to clear the dates 401 | * `closeCalendar`: Allows you to close the calendar 402 | * `openCalendar`: Allows you to open the calendar 403 | * `toggleCalendar`: Allows you to toggle the calendar 404 | 405 | ## Slots 406 | ### Calendar Header 407 | 408 | * **Name**: `header` 409 | 410 | **Example:** 411 | ``` 412 |